@haetae/core
@haetae/core
provides every core feature for Haetae.
For instance, it handles the config file, your command's env
and run
, etc.
If you want to use Haetae by programmatic API, you probably need this package.
Dependents
Installation
Unlike other @haetae/*
packages, @haetae/core
doesn't have peerDependencies
.
Just purely installing @haetae/core
itself is enough.
Are you developing a library(e.g. plugin) for Haetae?
It might be more suitable to specify @haetae/core
as peerDependencies
than dependencies
.
# As dependencies
npm install @haetae/core
# As devDependencies
npm install --save-dev @haetae/core
API
pkg
Refer to introduction#pkg.
SetCurrentCommandOptions
An argument interface of the function setCurrentCommand
.
interface SetCurrentCommandOptions {
command: string
}
setCurrentCommand
A setter for the current command name, which is a module-level state.
Set it before calling other APIs that require it (as a default parameter).
Type
(options: SetCurrentCommandOptions) => void
Options?
command
: A name of the command to run for current execution.
getCurrentCommand
A getter for the current command name, which is a module-level state.
Type
() => string
defaultConfigFiles
An array of string constants for default config file name.
This is used when the config file path is not given or given as a directory.
Type
[
'haetae.config.js',
'haetae.config.mjs',
'haetae.config.ts',
'haetae.config.mts',
]
SetConfigFilenameOptions
An argument interface of the function setConfigFilename
.
interface SetConfigFilenameOptions {
filename?: string
cwd?: string
checkExistence?: boolean
}
setConfigFilename
A setter for the config file name, which is a module-level state.
Set it before calling other APIs that require a config file.
Type
(options?: SetConfigFilenameOptions) => Promise<void>
Options?
filename?
: A config file path.cwd?
: A directory to join or start the search from. (default:process.cwd()
(opens in a new tab))checkExistence?
: Whether to check iffilename
exists. No effect whenfilename
is not given. (default:true
)
When filename
is given
filename
can be either an absolute or relative path.
If relative, filename
will be joined with cwd
.
If filename
does not exist on the filesystem, it throws an error when checkExistence
is true
.
When filename
is not given
It will try finding the config file (one of defaultConfigFiles
)
by walking up parent directories recursively, starting from cwd
.
- If not found, it throws an error.
- If multiple files (of
defaultConfigFiles
) exist,- A file closer to
cwd
is chosen. - If distances from
cwd
are equal, the priority order is the same asdefaultConfigFiles
.
- A file closer to
getConfigFilename
Path Principles
A getter for the config file name, which is a module-level state.
Type
() => string
getConfigDirname
Path Principles
A getter for the config file's directory name, which is a derived module-level state.
Throws an error if the config file is not yet set.
Type
() => string
HaetaeRecord
interface HaetaeRecord<D extends Rec = Rec, E extends Rec = Rec> {
data: D
env: E
time: number
}
HaetaeCommandEnv
<E extends Rec>() => void | PromiseOr<E>
HaetaePreCommandEnv
type HaetaePreCommandEnv<E extends Rec> =
| HaetaeCommandEnv<E>
| PromiseOr<E | void>
HaetaeCommandRun
<D extends Rec>() => void | PromiseOr<D | void>
HaetaePreCommand
interface HaetaePreCommand<D extends Rec, E extends Rec> {
run: HaetaeCommandRun<D>
env?: HaetaePreCommandEnv<E>
}
HaetaeCommand
interface HaetaeCommand<D extends Rec, E extends Rec> {
run: HaetaeCommandRun<D>
env: HaetaeCommandEnv<E>
}
RootEnv
<E extends Rec>(envFromCommand: E) => PromiseOr<E>
RootRecordData
<A extends Rec, R extends Rec = A>(recordDataFromCommand: A) => PromiseOr<R>
HaetaePreConfig
An interface of user-given config schema.
Also an argument interface of the function configure
.
interface HaetaePreConfig {
commands: Record<string, HaetaePreCommand<Rec, Rec>>
env?: RootEnv<Rec>
recordData?: RootRecordData<Rec>
store?: StoreConnector
}
HaetaeConfig
An interface of normalized config schema.
Also a return type of function configure
.
interface HaetaeConfig<D extends Rec, E extends Rec> {
commands: Record<string, HaetaeCommand<D, E>>
env: RootEnv<E>
recordData: RootRecordData<D>
}
configure
Path Principles
configure
validates and transform the user-provided config(e.g. haetae.config.js
) into normalized config.
Idempotent function
configure(obj)
is eqaul to configure(configure(obj))
.
Type
<D extends Rec, E extends Rec>(options: HaetaePreConfig) => HaetaeConfig<D, E>
Options
commands
: Your commands as an object.env?
: An env-to-env transformer. (default:(arg) => arg
)recordData?
: A recordData-to-recordData transformer. (default:(arg) => arg
)store?
: A store connector. (default:localStore()
)
Type-check for your config
The below example is 100% valid.
The exported raw json will be processed by configure
internally.
But you'd not get a type-check from the IDE.
export default { /* ... */ }
With configure
, type-check is enabled. Your IDE is Happy! 😊
import { core } from 'haetae'
export default core.configure({ /* ... */ })
Normalization
Schema of HaetaeConfig
(return type) is roughly similar to
that of HaetaePreConfig
(argument type).
The return value is a normalized result of a user-given (argument) config.
Omitted options from a user-given config HaetaePreConfig
are to be set
as their default values in HaetaeConfig
.
GetConfigOptions
An argument interface of the function getConfig
.
interface GetConfigOptions {
filename?: string
}
getConfig
Memoized
A function to get config object by config file path.
Type
<D extends Rec, E extends Rec>(options?: GetConfigOptions)
=> Promise<HaetaeConfig<D, E>>
Options?
filename?
: A path to the config file. If given as a relative path,process.cwd()
(opens in a new tab) is joined in front of it. If given as an absolute path, it's used as-is. (default:getConfigFilename()
)
ReserveRecordDataOptions
An option interface of the function reserveRecordData
.
interface ReserveRecordDataOptions {
dryRun?: boolean
}
reserveRecordData
A function to reserve Record Data.
This changes module-level state, the Reserved Record Data.
It returns a result of the Reserved Record Data.
Type
<D extends Rec>(recordData: Rec, options?: ReserveRecordDataOptions) => D
Options?
dryRun?
: Iftrue
, the argrecordData
is not reserved, but a return value is given as if it's applied. (default:false
)
InvokeEnvOptions
An argument interface of the function invokeEnv
.
interface InvokeEnvOptions<E extends Rec> {
command?: string
config?: HaetaeConfig<Rec, E>
applyRootEnv?: boolean
}
invokeEnv
Memoized
A function to invoke(execute) user-defined env
of the given command
.
Type
<E extends Rec>(options?: CommandFromConfig<Rec, E>) => Promise<E>
Options?
command?
: A command name to invokeenv
of. (default:getCurrentCommand()
)config?
: A config object. (default:await getConfig()
applyRootEnv?
: Whether to apply root env. (default:true
)
InvokeRunOptions
An argument interface of the function invokeRun
.
interface InvokeRunOptions<D extends Rec> {
command?: string
config?: HaetaeConfig<D, Rec>
applyReservedRecordData?: boolean
applyRootRecordData?: boolean
}
invokeRun
A function to invoke (execute) user-defined run
of the given command
.
Type
<D extends Rec>(options?: CommandFromConfig<D, Rec>) => Promise<D>
Options?
command?
: A command name to invokeenv
of. (default:getCurrentCommand()
)config?
: A config object. (default:await getConfig()
applyReservedRecordData?
: Whether to apply reserved Record Data. (default:true
)applyRootRecordData?
: Whether to apply root Record Data. (default:true
)
compareEnvs
A function to calculate a hash of an env object.
The object is serialized by a deterministic method no matter how deep it is,
and calculated as a hash by SHA-1.
Type
(env: Rec) => string
Arguments
env
: Anenv
object to calculate a hash of.
FormRecordOptions
An argument interface of the function formRecord
.
interface FormRecordOptions<D extends Rec, E extends Rec> {
data?: D
env?: E
time?: number
}
formRecord
A function to create a new record object.
This only returns an object, not saves it.
Type
<D extends Rec, E extends Rec>(options?: FormRecordOptions<D, E>)
=> Promise<HaetaeRecord<D, E>>
Options?
data?
: A Record Data. (default:await invokeRun()
env?
: A resolved env object. (default:await invokeEnv()
time?
: Unix timestamp (opens in a new tab) by milliseconds. (default:Date.now()
(opens in a new tab))
AddRecordOptions
An argument interface of the function addRecord
.
interface AddRecordOptions<D extends Rec, E extends Rec> {
command?: string
record?: HaetaeRecord<D, E>
}
AddRecord
A type of function addRecord
.
<D extends Rec, E extends Rec>(
options?: AddRecordOptions<D, E>,
) => PromiseOr<HaetaeRecord<D, E>>
addRecord
A function to add a new record to the store.
The record is to be persisted to the store.
Type
AddRecord
Options?
command?
: A command name to add a new record. (default:getCurrentCommand()
)record?
: A new record object to add.
(default:await formRecord({ data: await invokeRun({ command }), env: await invokeEnv({ command }) })
)
GetRecordOptions
An argument interface of a function getRecord
.
interface GetRecordOptions<E extends Rec> {
command?: string
env?: E
}
GetRecord
A type of function getRecord
.
<D extends Rec = Rec, E extends Rec = Rec>(
options?: GetRecordOptions<E>,
) => PromiseOr<HaetaeRecord<D, E> | undefined>
getRecord
A function to get a record of a given command, corresponding to the given env.
undefined
is returned when there's no record.
Type
GetRecord
Options?
command?
: A command name to get records of. (default:getCurrentCommand()
)env?
: A resolved env object. (default:await invokeEnv({ command })
)
StoreConnector
An interface of store connector.
interface StoreConnector {
addRecord: AddRecord
getRecord: GetRecord
}
LocalStoreConnector
An interface of local store connector.
interface LocalStoreConnector extends StoreConnector {
initNewStore<D extends Rec, E extends Rec>(): LocalStore<D, E>
loadStore<D extends Rec, E extends Rec>(
options?: LoadStoreOptions,
): Promise<LocalStore<D, E>>
saveStore(store: LocalStore): Promise<void>
localStore: {
filename: string
recordRemoval: {
age: number
count: number
}
}
}
LocalStoreOptions
An argument interface of a function localStore
.
interface LocalStoreOptions {
filename?: string
recordRemoval?: {
age?: number | string
count?: number
leaveOnlyLastestPerEnv?: boolean
}
}
localStore
A function to create a Store Connector that reads and writes to a local file.
Type
(options?: LocalStoreOptions): LocalStoreConnector
Options?
filename?
: The store file. (default:core.getConfigDirname() + '/.haetae/store.json'
recordRemoval.age?
: Age threshold by milliseconds (e.g.90 * 24 * 60 * 60 * 1000
=> 90 days). vercel/ms (opens in a new tab)-compatible string is allowed (e.g.'90 days'
=> 90 days). Records whose age is older than this value are to be removed when callingaddRecord
. (default:Number.POSITIVE_INFINITY
)recordRemoval.count?
: The number of total records to keep. When the number of records becomes larger than this value, old records are removed to satisfy the threshold when callingaddRecord
. This task is executed afterrecordRemoval.age
is used. (default:Number.POSITIVE_INFINITY
)recordRemoval.leaveOnlyLastestPerEnv?
: Iftrue
, only the last records perenv
exist in the store file. This is useful if you only depend on the latest record perenv
. (default:true
)
LocalStoreConnector.initNewStore
Initializes an empty store. It just returns an object. It does not save it as a file.
Type
<D extends Rec, E extends Rec>() => LocalStore<D, E>
LoadStoreOptions
An argument interface of the function LocalStoreConnector.loadStore
.
interface LoadStoreOptions {
initWhenNotFound?: boolean
}
LocalStore
An interface for the local store file.
interface LocalStore<D extends Rec = Rec, E extends Rec = Rec> {
version: string
commands: {
[command: string]: HaetaeRecord<D, E>[]
}
}
LocalStoreConnector.loadStore
Memoized
A function to load a store object from the file.
Type
<D extends Rec, E extends Rec>(options?: LoadStoreOptions<D, E>)
=> Promise<LocalStore<D, E>>
Options?
initWhenNotFound?
: Whether to throw an error or just initialize a new store object whenfilename
does not exist in the filesystem. Iftrue
,LocalStoreConnector.initNewStore()
is returned, and the filesystem is not affected. (default:true
)
LocalStoreConnector.saveStore
A function to save a store object to a file.
Memoization cache of LocalStoreConnector.loadStore
would be clear automatically.
Type
(store: LocalStore) => Promise<void>
Options?
store?
: A store object to save. (default:await addRecord()
)