@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/coreAPI
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) => voidOptions?
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
() => stringdefaultConfigFiles
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 iffilenameexists. No effect whenfilenameis 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
cwdis chosen. - If distances from
cwdare 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
() => stringgetConfigDirname
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
() => stringHaetaeRecord
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) => DOptions?
dryRun?: Iftrue, the argrecordDatais 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 invokeenvof. (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 invokeenvof. (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) => stringArguments
env: Anenvobject 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
AddRecordOptions?
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
GetRecordOptions?
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): LocalStoreConnectorOptions?
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.ageis used. (default:Number.POSITIVE_INFINITY)recordRemoval.leaveOnlyLastestPerEnv?: Iftrue, only the last records perenvexist 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 whenfilenamedoes 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())