generated from boneskull/boneskull-template
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: centralize component types into subpath
- Separate component types from their schemas. Schemas should not be used outside of `midnight-smoker`; types can. - Rename `NormalizePackageJson` to `PackageJson` since it's the only type we care about. - Fix `readSmokerPkgJson()` to return a `PackageJson`
- Loading branch information
Showing
97 changed files
with
1,013 additions
and
788 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# `midnight-smoker/defs`: Core Types for Plugins | ||
|
||
This directory contains the types of _components_; a plugin is a collection of components. Plugin authors will find these types helpful. | ||
|
||
Note that this directory should not contain any Zod schemas! The schemas are not public use, and should be considered an implementation detail. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/** | ||
* Declares the {@link Executor} interface | ||
* | ||
* An implementation of `Executor` can then transform commands as needed. | ||
* | ||
* @packageDocumentation | ||
*/ | ||
|
||
import {type ExecOptions, type ExecOutput} from '#schema/exec-result'; | ||
import {type StaticPkgManagerSpec} from '#schema/static-pkg-manager-spec'; | ||
import {type SpawnOptions as NodeOptions} from 'node:child_process'; | ||
|
||
/** | ||
* Options to pass along to the underlying child process spawner | ||
*/ | ||
export type {NodeOptions}; | ||
|
||
export type {ExecOptions, ExecOutput, StaticPkgManagerSpec}; | ||
|
||
/** | ||
* Options for an {@link Executor} | ||
*/ | ||
|
||
export type ExecutorOpts = ExecOptions | undefined; | ||
|
||
/** | ||
* An `Executor` is responsible for invoking package manager commands. | ||
* | ||
* A package manager calls its `Executor` instance with the proper arguments to | ||
* run. | ||
* | ||
* An `Executor` can be thought of as the final "transform" before the package | ||
* manager process gets spawned. | ||
* | ||
* @remarks | ||
* This can be thought of as a wrapper around `exec()` from | ||
* `midnight-smoker/util`, allowing greater control over the spawned process and | ||
* its return value. | ||
* @param spec - The package manager spec | ||
* @param args - The arguments to the package manager executable, likely | ||
* including a command | ||
* @param options - Options for the `Executor` | ||
* @param nodeOptions - Options for `child_process.spawn()` by way of `exec()` | ||
*/ | ||
export type Executor = ( | ||
spec: StaticPkgManagerSpec, | ||
args: string[], | ||
options?: ExecutorOpts, | ||
) => Promise<ExecOutput>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,256 @@ | ||
/** | ||
* Contains the schema and type def for a {@link PkgManager}, which is a | ||
* component that a plugin can provide. | ||
* | ||
* A `PkgManager` is an adapter for a package manager executable at a given | ||
* version (or range). | ||
* | ||
* @module midnight-smoker/defs/pkg-manager | ||
*/ | ||
|
||
import {type ExecOutput, type Executor} from '#defs/executor'; | ||
import {type RunScriptResult} from '#schema/run-script-result'; | ||
import {type StaticPkgManagerSpec} from '#schema/static-pkg-manager-spec'; | ||
import {type RawPkgManagerVersionData} from '#schema/version'; | ||
import {type WorkspaceInfo} from '#schema/workspace-info'; | ||
import {type Range} from 'semver'; | ||
import {type Merge, type SetOptional} from 'type-fest'; | ||
|
||
/** | ||
* The context for a package manager. | ||
* | ||
* This is the base chunk of state that a {@link PkgManager} gets to work with. | ||
* Each operation function will receive this context object or a more specific | ||
* one which extends this. | ||
*/ | ||
export type PkgManagerContext = Merge< | ||
{ | ||
executor: Executor; | ||
spec: StaticPkgManagerSpec; | ||
tmpdir: string; | ||
useWorkspaces?: boolean; | ||
workspaceInfo: WorkspaceInfo[]; | ||
}, | ||
PkgManagerOpts | ||
>; | ||
|
||
/** | ||
* A Package Manager definition which is an adapter for a package manager | ||
* executable. | ||
* | ||
* `midnight-smoker` only cares about a select few operations (packing, | ||
* installation, and running a script), but they all must be provided. | ||
* | ||
* A `PkgManager` is defined via a plugin, and is considered a Component. Its | ||
* `ComponentKind` is `PkgManager`. | ||
* | ||
* This can be a plain object or a singleton-like instance of some class. If a | ||
* class is used, it's the responsibility of the plugin author to instantiate. | ||
*/ | ||
export type PkgManager = { | ||
/** | ||
* Whatever else the plugin author needs in here is fine; it is ignored by | ||
* `midnight-smoker` | ||
*/ | ||
[x: string]: unknown; | ||
|
||
/** | ||
* The name of the package manager's executable. End-users will refer to this | ||
* when choosing a package manager | ||
*/ | ||
bin: string; | ||
|
||
/** | ||
* Description of the package manager | ||
*/ | ||
description?: string; | ||
|
||
/** | ||
* A function that installs a package. It receives a context object and | ||
* returns a the raw {@link ExecResult}, returned by its | ||
* {@link PkgManagerContext.executor Executor}. | ||
*/ | ||
install: PkgManagerInstallFn; | ||
|
||
/** | ||
* The name of the lockfile for this package manager. Used for auto-detection | ||
* of package manager | ||
*/ | ||
lockfile?: string; | ||
|
||
/** | ||
* The human-readable name for display | ||
*/ | ||
name: string; | ||
|
||
/** | ||
* A function that packs a package into a tarball into a | ||
* {@link PkgManagerContext.tmpdir temp dir} (the path to which is determined | ||
* by `midnight-smoker`). It receives a context object and returns an | ||
* {@link InstallManifest}. | ||
*/ | ||
pack: PkgManagerPackFn; | ||
|
||
/** | ||
* A function that runs a script against a package. It receives a context | ||
* object and returns a {@link RunScriptResult}. | ||
*/ | ||
runScript: PkgManagerRunScriptFn; | ||
|
||
/** | ||
* A "setup" lifecycle function which is called before any operations are run. | ||
* It receives the context object, which it can mutate. | ||
*/ | ||
setup?: PkgManagerSetupFn; | ||
|
||
/** | ||
* The range of versions supported by this package manager; used to determine | ||
* if the `PkgManager` can handle a given version | ||
*/ | ||
supportedVersionRange: PkgManagerSupportedVersionRange; | ||
|
||
/** | ||
* A "teardown" lifecycle function which is called after all operations are | ||
* run. It receives the context object, which it can mutate. | ||
*/ | ||
teardown?: PkgManagerTeardownFn; | ||
|
||
/** | ||
* An array of versions or an object containing versions and tags, | ||
* representing known package manager versions | ||
* | ||
* This is needed to validate user input. | ||
*/ | ||
versions: RawPkgManagerVersionData; | ||
}; | ||
|
||
/** | ||
* The context object for {@link PkgManagerInstallFn}. | ||
* | ||
* The `PkgManagerInstallFn` will use the | ||
* {@link PkgManagerInstallContext.installManifest installManifest property} to | ||
* determine what to install. Usually, this will be a tarball which was created | ||
* by {@link PkgManagerPackFn}. | ||
*/ | ||
export type PkgManagerInstallContext = { | ||
installManifest: InstallManifest; | ||
signal: AbortSignal; | ||
} & PkgManagerContext; | ||
|
||
/** | ||
* Installs a package given the {@link PkgManagerInstallContext context object}. | ||
*/ | ||
export type PkgManagerInstallFn = ( | ||
context: PkgManagerInstallContext, | ||
) => Promise<ExecOutput>; | ||
|
||
/** | ||
* Extra options for package manager operations. | ||
*/ | ||
export type PkgManagerOpts = { | ||
/** | ||
* If `true`, ignore missing scripts in {@link PkgManagerRunScriptFn}. | ||
*/ | ||
loose?: boolean; | ||
|
||
/** | ||
* If `true`, the package manager should pipe its STDERR/STDOUT to the console | ||
*/ | ||
verbose?: boolean; | ||
}; | ||
|
||
/** | ||
* The context object for {@link PkgManagerPackFn}. | ||
* | ||
* The `PkgManagerPackFn` will use the properties from {@link WorkspaceInfo} to | ||
* determine what to pack; {@link PkgManagerContext.tmpdir tmpdir} is the target | ||
* directory. | ||
*/ | ||
export type PkgManagerPackContext = { | ||
signal: AbortSignal; | ||
timeout?: number; | ||
} & PkgManagerContext & | ||
WorkspaceInfo; | ||
|
||
/** | ||
* Packs a package into a tarball given a {@link PkgManagerPackContext context} | ||
* object | ||
*/ | ||
export type PkgManagerPackFn = ( | ||
context: PkgManagerPackContext, | ||
) => Promise<InstallManifest>; | ||
|
||
/** | ||
* The context object for {@link PkgManagerRunScriptFn}. | ||
* | ||
* The `PkgManagerRunScriptFn` will use the | ||
* {@link PkgManagerRunScriptContext.manifest RunScriptManifest} to determine | ||
* what scripts to run within the installed packages (and where). | ||
*/ | ||
export type PkgManagerRunScriptContext = { | ||
manifest: RunScriptManifest; | ||
signal: AbortSignal; | ||
} & PkgManagerContext; | ||
|
||
/** | ||
* Runs a script against a package given a {@link PkgManagerRunScriptContext} | ||
* object. | ||
*/ | ||
export type PkgManagerRunScriptFn = ( | ||
context: PkgManagerRunScriptContext, | ||
) => Promise<RunScriptResult>; | ||
|
||
/** | ||
* A "lifeycle" function that sets up a package manager. | ||
*/ | ||
export type PkgManagerSetupFn = | ||
| ((context: PkgManagerContext) => Promise<void>) | ||
| ((context: PkgManagerContext) => void); | ||
|
||
/** | ||
* A value which indicates what version or versions a package manager can | ||
* support. | ||
* | ||
* Must be parseable by `semver`. | ||
*/ | ||
export type PkgManagerSupportedVersionRange = Range | string; | ||
|
||
/** | ||
* A "lifeycle" function that tears down a package manager. | ||
* | ||
* Use this to dispose of resources or clean up after a package manager. | ||
* `midnight-smoker` will handle the temporary directory. | ||
*/ | ||
export type PkgManagerTeardownFn = | ||
| ((context: PkgManagerContext) => Promise<void>) | ||
| ((context: PkgManagerContext) => void); | ||
|
||
export type InstallManifest = Readonly< | ||
{ | ||
cwd: string; | ||
installPath?: string; | ||
isAdditional?: boolean; | ||
pkgSpec: string; | ||
} & SetOptional< | ||
WorkspaceInfo, | ||
'localPath' | 'pkgJson' | 'pkgJsonPath' | 'rawPkgJson' | ||
> | ||
>; | ||
|
||
/** | ||
* An install manifest referencing a workspace (_not_ an additional dependency) | ||
*/ | ||
|
||
export type WorkspaceInstallManifest = Merge< | ||
InstallManifest, | ||
{ | ||
installPath: string; | ||
isAdditional?: false; | ||
localPath: string; | ||
} | ||
>; | ||
|
||
export type RunScriptManifest = { | ||
cwd: string; | ||
script: string; | ||
} & WorkspaceInfo; |
6 changes: 6 additions & 0 deletions
6
...oker/src/plugin/static-plugin-metadata.ts → packages/midnight-smoker/src/defs/plugin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.