@dotcom-tool-kit/base 4.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/base.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { typeSymbol } from './symbols';
2
+ import { Validated } from '@dotcom-tool-kit/validated';
3
+ export declare abstract class Base {
4
+ static version: string;
5
+ version: string;
6
+ static get [typeSymbol](): symbol;
7
+ get [typeSymbol](): symbol;
8
+ static is<T extends Base>(objectToCheck: any): objectToCheck is T;
9
+ static isCompatible<T extends Base>(objectToCheck: unknown): Validated<T>;
10
+ }
11
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAGA,OAAO,EAAc,UAAU,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,SAAS,EAAkB,MAAM,4BAA4B,CAAA;AAOtE,8BAAsB,IAAI;IACxB,MAAM,CAAC,OAAO,SAAU;IACxB,OAAO,SAAU;IAEjB,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAEhC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,CAEzB;IAGD,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,aAAa,EAAE,GAAG,GAAG,aAAa,IAAI,CAAC;IAIjE,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,IAAI,EAAE,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC;CA6B1E"}
package/lib/base.js ADDED
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Base = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const logger_1 = require("@dotcom-tool-kit/logger");
6
+ const path_1 = tslib_1.__importDefault(require("path"));
7
+ const fs_1 = tslib_1.__importDefault(require("fs"));
8
+ const symbols_1 = require("./symbols");
9
+ const validated_1 = require("@dotcom-tool-kit/validated");
10
+ const semver_1 = tslib_1.__importDefault(require("semver"));
11
+ const packageJsonPath = path_1.default.resolve(__dirname, '../package.json');
12
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf8'));
13
+ const version = packageJson.version;
14
+ class Base {
15
+ constructor() {
16
+ this.version = version;
17
+ }
18
+ static get [symbols_1.typeSymbol]() {
19
+ return symbols_1.baseSymbol;
20
+ }
21
+ get [symbols_1.typeSymbol]() {
22
+ return symbols_1.baseSymbol;
23
+ }
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ static is(objectToCheck) {
26
+ return objectToCheck[symbols_1.typeSymbol] === this[symbols_1.typeSymbol];
27
+ }
28
+ static isCompatible(objectToCheck) {
29
+ if (!this.is(objectToCheck)) {
30
+ return (0, validated_1.invalid)([
31
+ `${logger_1.styles.plugin('@dotcom-tool-kit/base')} type symbol is missing, make sure that this object derives from the ${logger_1.styles.code('Task')} or ${logger_1.styles.code('Hook')} class defined by the plugin`
32
+ ]);
33
+ }
34
+ // an 'objectToCheck' from a plugin is compatible with this CLI if its
35
+ // version is semver-compatible with the @dotcom-tool-kit/base included by
36
+ // the CLI (which is what's calling this). so, prepend ^ to our version,
37
+ // and check our version satisfies that.
38
+ // this lets e.g. a CLI that includes types@2.2.0 load any plugin
39
+ // that depends on any higher minor version of types.
40
+ const range = `^${this.version}`;
41
+ if (semver_1.default.satisfies(objectToCheck.version, range)) {
42
+ return (0, validated_1.valid)(objectToCheck);
43
+ }
44
+ else {
45
+ return (0, validated_1.invalid)([
46
+ `object is from an outdated version of ${logger_1.styles.plugin('@dotcom-tool-kit/base')}, make sure you're using at least version ${logger_1.styles.heading(this.version)} of the plugin`
47
+ ]);
48
+ }
49
+ }
50
+ }
51
+ exports.Base = Base;
52
+ Base.version = version;
package/lib/hook.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ import type { Logger } from 'winston';
2
+ import { Base } from './base';
3
+ import { typeSymbol } from './symbols';
4
+ import type { z } from 'zod';
5
+ import type { Plugin } from '@dotcom-tool-kit/plugin';
6
+ import { Conflict } from '@dotcom-tool-kit/conflict';
7
+ export interface HookInstallation<Options = Record<string, unknown>> {
8
+ options: Options;
9
+ plugin: Plugin;
10
+ forHook: string;
11
+ hookConstructor: HookConstructor;
12
+ }
13
+ export declare abstract class Hook<Options extends z.ZodTypeAny = z.ZodTypeAny, State = void> extends Base {
14
+ id: string;
15
+ options: z.output<Options>;
16
+ logger: Logger;
17
+ installGroup?: string;
18
+ static get [typeSymbol](): symbol;
19
+ get [typeSymbol](): symbol;
20
+ static mergeChildInstallations(plugin: Plugin, childInstallations: (HookInstallation | Conflict<HookInstallation>)[]): (HookInstallation | Conflict<HookInstallation>)[];
21
+ static overrideChildInstallations(plugin: Plugin, parentInstallation: HookInstallation, _childInstallations: (HookInstallation | Conflict<HookInstallation>)[]): (HookInstallation | Conflict<HookInstallation>)[];
22
+ constructor(logger: Logger, id: string, options: z.output<Options>);
23
+ abstract isInstalled(): Promise<boolean>;
24
+ abstract install(state?: State): Promise<State>;
25
+ commitInstall(_state: State): Promise<void>;
26
+ }
27
+ export type HookConstructor = {
28
+ new (logger: Logger, id: string, options: z.output<z.ZodTypeAny>): Hook<z.ZodTypeAny, unknown>;
29
+ };
30
+ export type HookClass = HookConstructor & typeof Hook;
31
+ //# sourceMappingURL=hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAc,UAAU,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,QAAQ,EAAc,MAAM,2BAA2B,CAAA;AAEhE,MAAM,WAAW,gBAAgB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACjE,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,eAAe,CAAA;CACjC;AAED,8BAAsB,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI,CAAE,SAAQ,IAAI;IAsC7D,EAAE,EAAE,MAAM;IAAS,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IArChF,MAAM,EAAE,MAAM,CAAA;IAKd,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAEhC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,CAEzB;IAED,MAAM,CAAC,uBAAuB,CAC5B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,GACpE,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE;IAWpD,MAAM,CAAC,0BAA0B,CAC/B,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,gBAAgB,EACpC,mBAAmB,EAAE,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,GACrE,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE;gBAIxC,MAAM,EAAE,MAAM,EAAS,EAAE,EAAE,MAAM,EAAS,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;IAKhF,QAAQ,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IACxC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACzC,aAAa,CAAC,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlD;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;CAC/F,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,OAAO,IAAI,CAAA"}
package/lib/hook.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Hook = void 0;
4
+ const base_1 = require("./base");
5
+ const symbols_1 = require("./symbols");
6
+ const conflict_1 = require("@dotcom-tool-kit/conflict");
7
+ class Hook extends base_1.Base {
8
+ static get [symbols_1.typeSymbol]() {
9
+ return symbols_1.hookSymbol;
10
+ }
11
+ get [symbols_1.typeSymbol]() {
12
+ return symbols_1.hookSymbol;
13
+ }
14
+ static mergeChildInstallations(plugin, childInstallations) {
15
+ return [
16
+ {
17
+ plugin,
18
+ conflicting: childInstallations.flatMap((installation) => (0, conflict_1.isConflict)(installation) ? installation.conflicting : installation)
19
+ }
20
+ ];
21
+ }
22
+ static overrideChildInstallations(plugin, parentInstallation, _childInstallations) {
23
+ return [parentInstallation];
24
+ }
25
+ constructor(logger, id, options) {
26
+ super();
27
+ this.id = id;
28
+ this.options = options;
29
+ this.logger = logger.child({ hook: this.constructor.name });
30
+ }
31
+ async commitInstall(_state) {
32
+ return;
33
+ }
34
+ }
35
+ exports.Hook = Hook;
package/lib/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './base';
2
+ export * from './hook';
3
+ export * from './init';
4
+ export * from './task';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA;AACtB,cAAc,QAAQ,CAAA"}
package/lib/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./base"), exports);
5
+ tslib_1.__exportStar(require("./hook"), exports);
6
+ tslib_1.__exportStar(require("./init"), exports);
7
+ tslib_1.__exportStar(require("./task"), exports);
package/lib/init.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { Logger } from 'winston';
2
+ import { typeSymbol } from './symbols';
3
+ import { Base } from './base';
4
+ export declare abstract class Init extends Base {
5
+ logger: Logger;
6
+ constructor(logger: Logger);
7
+ static get [typeSymbol](): symbol;
8
+ get [typeSymbol](): symbol;
9
+ abstract init(): Promise<void>;
10
+ }
11
+ export type InitConstructor = {
12
+ new (logger: Logger): Init;
13
+ };
14
+ export type InitClass = InitConstructor & typeof Init;
15
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAc,UAAU,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAE7B,8BAAsB,IAAK,SAAQ,IAAI;IACrC,MAAM,EAAE,MAAM,CAAA;gBAEF,MAAM,EAAE,MAAM;IAK1B,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAEhC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,CAEzB;IAED,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAC/B;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,OAAO,IAAI,CAAA"}
package/lib/init.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Init = void 0;
4
+ const symbols_1 = require("./symbols");
5
+ const base_1 = require("./base");
6
+ class Init extends base_1.Base {
7
+ constructor(logger) {
8
+ super();
9
+ this.logger = logger.child({ hook: this.constructor.name });
10
+ }
11
+ static get [symbols_1.typeSymbol]() {
12
+ return symbols_1.initSymbol;
13
+ }
14
+ get [symbols_1.typeSymbol]() {
15
+ return symbols_1.initSymbol;
16
+ }
17
+ }
18
+ exports.Init = Init;
@@ -0,0 +1,6 @@
1
+ export declare const typeSymbol: unique symbol;
2
+ export declare const baseSymbol: unique symbol;
3
+ export declare const taskSymbol: unique symbol;
4
+ export declare const hookSymbol: unique symbol;
5
+ export declare const initSymbol: unique symbol;
6
+ //# sourceMappingURL=symbols.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../src/symbols.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,UAAU,eAAuC,CAAA;AAG9D,eAAO,MAAM,UAAU,eAA4C,CAAA;AACnE,eAAO,MAAM,UAAU,eAA4C,CAAA;AACnE,eAAO,MAAM,UAAU,eAA4C,CAAA;AACnE,eAAO,MAAM,UAAU,eAA4C,CAAA"}
package/lib/symbols.js ADDED
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ // uses Symbol.for, not Symbol, so that they're compatible across different
3
+ // @dotcom-tool-kit/base instances
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.initSymbol = exports.hookSymbol = exports.taskSymbol = exports.baseSymbol = exports.typeSymbol = void 0;
6
+ // TODO these symbols say '@dotcom-tool-kit/types' because they used to live
7
+ // in that package. changing that would be a backwards compatibility nightmare
8
+ // used as the name for the property we use to identify classes
9
+ exports.typeSymbol = Symbol.for('@dotcom-tool-kit/types');
10
+ // used to identify the Base, Task and Hook classes
11
+ exports.baseSymbol = Symbol.for('@dotcom-tool-kit/types/base');
12
+ exports.taskSymbol = Symbol.for('@dotcom-tool-kit/types/task');
13
+ exports.hookSymbol = Symbol.for('@dotcom-tool-kit/types/hook');
14
+ exports.initSymbol = Symbol.for('@dotcom-tool-kit/types/init');
package/lib/task.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import type { z } from 'zod';
2
+ import { Base } from './base';
3
+ import { typeSymbol } from './symbols';
4
+ import type { Logger } from 'winston';
5
+ type Default<T, D> = T extends undefined ? D : T;
6
+ export declare abstract class Task<Options extends {
7
+ plugin?: z.ZodTypeAny;
8
+ task?: z.ZodTypeAny;
9
+ } = Record<never, never>> extends Base {
10
+ id: string;
11
+ pluginOptions: z.output<Default<Options['plugin'], z.ZodObject<Record<string, never>>>>;
12
+ options: z.output<Default<Options['task'], z.ZodObject<Record<string, never>>>>;
13
+ static get [typeSymbol](): symbol;
14
+ get [typeSymbol](): symbol;
15
+ logger: Logger;
16
+ constructor(logger: Logger, id: string, pluginOptions: z.output<Default<Options['plugin'], z.ZodObject<Record<string, never>>>>, options: z.output<Default<Options['task'], z.ZodObject<Record<string, never>>>>);
17
+ abstract run(files?: string[]): Promise<void>;
18
+ }
19
+ export type TaskConstructor = {
20
+ new <O extends {
21
+ plugin: z.ZodTypeAny;
22
+ task: z.ZodTypeAny;
23
+ }>(logger: Logger, id: string, pluginOptions: Partial<z.infer<O['plugin']>>, options: Partial<z.infer<O['task']>>): Task<O>;
24
+ };
25
+ export type TaskClass = TaskConstructor & typeof Task;
26
+ export {};
27
+ //# sourceMappingURL=task.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../src/task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAC7B,OAAO,EAAc,UAAU,EAAE,MAAM,WAAW,CAAA;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,KAAK,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,CAAC,GAAG,CAAC,CAAA;AAEhD,8BAAsB,IAAI,CACxB,OAAO,SAAS;IACd,MAAM,CAAC,EAAE,CAAC,CAAC,UAAU,CAAA;IACrB,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAA;CACpB,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CACxB,SAAQ,IAAI;IAaH,EAAE,EAAE,MAAM;IACV,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACvF,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAdxF,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAEhC;IAED,IAAI,CAAC,UAAU,CAAC,IAAI,MAAM,CAEzB;IAED,MAAM,EAAE,MAAM,CAAA;gBAGZ,MAAM,EAAE,MAAM,EACP,EAAE,EAAE,MAAM,EACV,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,EACvF,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAMxF,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAC9C;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,CAAC,SAAS;QAAE,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC;QAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAA;KAAE,EACzD,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAC5C,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GACnC,IAAI,CAAC,CAAC,CAAC,CAAA;CACX,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,OAAO,IAAI,CAAA"}
package/lib/task.js ADDED
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Task = void 0;
4
+ const base_1 = require("./base");
5
+ const symbols_1 = require("./symbols");
6
+ class Task extends base_1.Base {
7
+ static get [symbols_1.typeSymbol]() {
8
+ return symbols_1.taskSymbol;
9
+ }
10
+ get [symbols_1.typeSymbol]() {
11
+ return symbols_1.taskSymbol;
12
+ }
13
+ constructor(logger, id, pluginOptions, options) {
14
+ super();
15
+ this.id = id;
16
+ this.pluginOptions = pluginOptions;
17
+ this.options = options;
18
+ this.logger = logger.child({ task: id });
19
+ }
20
+ }
21
+ exports.Task = Task;
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@dotcom-tool-kit/base",
3
+ "version": "4.0.0-beta.0",
4
+ "description": "",
5
+ "main": "lib",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "dependencies": {
13
+ "@dotcom-tool-kit/conflict": "2.0.0-beta.0",
14
+ "@dotcom-tool-kit/validated": "2.0.0-beta.0",
15
+ "semver": "^7.5.4",
16
+ "winston": "^3.11.0"
17
+ },
18
+ "devDependencies": {
19
+ "@dotcom-tool-kit/logger": "4.0.0-beta.0",
20
+ "@dotcom-tool-kit/plugin": "2.0.0-beta.0",
21
+ "winston": "^3.11.0",
22
+ "zod": "^3.22.4"
23
+ },
24
+ "peerDependencies": {
25
+ "zod": "^3.22.4"
26
+ }
27
+ }
package/src/base.ts ADDED
@@ -0,0 +1,58 @@
1
+ import { styles as s } from '@dotcom-tool-kit/logger'
2
+ import path from 'path'
3
+ import fs from 'fs'
4
+ import { baseSymbol, typeSymbol } from './symbols'
5
+ import { Validated, invalid, valid } from '@dotcom-tool-kit/validated'
6
+ import semver from 'semver'
7
+
8
+ const packageJsonPath = path.resolve(__dirname, '../package.json')
9
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))
10
+ const version: string = packageJson.version
11
+
12
+ export abstract class Base {
13
+ static version = version
14
+ version = version
15
+
16
+ static get [typeSymbol](): symbol {
17
+ return baseSymbol
18
+ }
19
+
20
+ get [typeSymbol](): symbol {
21
+ return baseSymbol
22
+ }
23
+
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ static is<T extends Base>(objectToCheck: any): objectToCheck is T {
26
+ return objectToCheck[typeSymbol] === this[typeSymbol]
27
+ }
28
+
29
+ static isCompatible<T extends Base>(objectToCheck: unknown): Validated<T> {
30
+ if (!this.is(objectToCheck)) {
31
+ return invalid([
32
+ `${s.plugin(
33
+ '@dotcom-tool-kit/base'
34
+ )} type symbol is missing, make sure that this object derives from the ${s.code('Task')} or ${s.code(
35
+ 'Hook'
36
+ )} class defined by the plugin`
37
+ ])
38
+ }
39
+
40
+ // an 'objectToCheck' from a plugin is compatible with this CLI if its
41
+ // version is semver-compatible with the @dotcom-tool-kit/base included by
42
+ // the CLI (which is what's calling this). so, prepend ^ to our version,
43
+ // and check our version satisfies that.
44
+
45
+ // this lets e.g. a CLI that includes types@2.2.0 load any plugin
46
+ // that depends on any higher minor version of types.
47
+ const range = `^${this.version}`
48
+ if (semver.satisfies(objectToCheck.version, range)) {
49
+ return valid(objectToCheck as T)
50
+ } else {
51
+ return invalid([
52
+ `object is from an outdated version of ${s.plugin(
53
+ '@dotcom-tool-kit/base'
54
+ )}, make sure you're using at least version ${s.heading(this.version)} of the plugin`
55
+ ])
56
+ }
57
+ }
58
+ }
package/src/hook.ts ADDED
@@ -0,0 +1,69 @@
1
+ import type { Logger } from 'winston'
2
+ import { Base } from './base'
3
+ import { hookSymbol, typeSymbol } from './symbols'
4
+ import type { z } from 'zod'
5
+ import type { Plugin } from '@dotcom-tool-kit/plugin'
6
+ import { Conflict, isConflict } from '@dotcom-tool-kit/conflict'
7
+
8
+ export interface HookInstallation<Options = Record<string, unknown>> {
9
+ options: Options
10
+ plugin: Plugin
11
+ forHook: string
12
+ hookConstructor: HookConstructor
13
+ }
14
+
15
+ export abstract class Hook<Options extends z.ZodTypeAny = z.ZodTypeAny, State = void> extends Base {
16
+ logger: Logger
17
+ // This field is used to collect hooks that share state when running their
18
+ // install methods. All hooks in the same group will run their install method
19
+ // one after the other, and then their commitInstall method will be run with
20
+ // the collected state.
21
+ installGroup?: string
22
+
23
+ static get [typeSymbol](): symbol {
24
+ return hookSymbol
25
+ }
26
+
27
+ get [typeSymbol](): symbol {
28
+ return hookSymbol
29
+ }
30
+
31
+ static mergeChildInstallations(
32
+ plugin: Plugin,
33
+ childInstallations: (HookInstallation | Conflict<HookInstallation>)[]
34
+ ): (HookInstallation | Conflict<HookInstallation>)[] {
35
+ return [
36
+ {
37
+ plugin,
38
+ conflicting: childInstallations.flatMap((installation) =>
39
+ isConflict(installation) ? installation.conflicting : installation
40
+ )
41
+ }
42
+ ]
43
+ }
44
+
45
+ static overrideChildInstallations(
46
+ plugin: Plugin,
47
+ parentInstallation: HookInstallation,
48
+ _childInstallations: (HookInstallation | Conflict<HookInstallation>)[]
49
+ ): (HookInstallation | Conflict<HookInstallation>)[] {
50
+ return [parentInstallation]
51
+ }
52
+
53
+ constructor(logger: Logger, public id: string, public options: z.output<Options>) {
54
+ super()
55
+ this.logger = logger.child({ hook: this.constructor.name })
56
+ }
57
+
58
+ abstract isInstalled(): Promise<boolean>
59
+ abstract install(state?: State): Promise<State>
60
+ async commitInstall(_state: State): Promise<void> {
61
+ return
62
+ }
63
+ }
64
+
65
+ export type HookConstructor = {
66
+ new (logger: Logger, id: string, options: z.output<z.ZodTypeAny>): Hook<z.ZodTypeAny, unknown>
67
+ }
68
+
69
+ export type HookClass = HookConstructor & typeof Hook
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './base'
2
+ export * from './hook'
3
+ export * from './init'
4
+ export * from './task'
package/src/init.ts ADDED
@@ -0,0 +1,28 @@
1
+ import type { Logger } from 'winston'
2
+ import { initSymbol, typeSymbol } from './symbols'
3
+ import { Base } from './base'
4
+
5
+ export abstract class Init extends Base {
6
+ logger: Logger
7
+
8
+ constructor(logger: Logger) {
9
+ super()
10
+ this.logger = logger.child({ hook: this.constructor.name })
11
+ }
12
+
13
+ static get [typeSymbol](): symbol {
14
+ return initSymbol
15
+ }
16
+
17
+ get [typeSymbol](): symbol {
18
+ return initSymbol
19
+ }
20
+
21
+ abstract init(): Promise<void>
22
+ }
23
+
24
+ export type InitConstructor = {
25
+ new (logger: Logger): Init
26
+ }
27
+
28
+ export type InitClass = InitConstructor & typeof Init
package/src/symbols.ts ADDED
@@ -0,0 +1,14 @@
1
+ // uses Symbol.for, not Symbol, so that they're compatible across different
2
+ // @dotcom-tool-kit/base instances
3
+
4
+ // TODO these symbols say '@dotcom-tool-kit/types' because they used to live
5
+ // in that package. changing that would be a backwards compatibility nightmare
6
+
7
+ // used as the name for the property we use to identify classes
8
+ export const typeSymbol = Symbol.for('@dotcom-tool-kit/types')
9
+
10
+ // used to identify the Base, Task and Hook classes
11
+ export const baseSymbol = Symbol.for('@dotcom-tool-kit/types/base')
12
+ export const taskSymbol = Symbol.for('@dotcom-tool-kit/types/task')
13
+ export const hookSymbol = Symbol.for('@dotcom-tool-kit/types/hook')
14
+ export const initSymbol = Symbol.for('@dotcom-tool-kit/types/init')
package/src/task.ts ADDED
@@ -0,0 +1,46 @@
1
+ import type { z } from 'zod'
2
+ import { Base } from './base'
3
+ import { taskSymbol, typeSymbol } from './symbols'
4
+ import type { Logger } from 'winston'
5
+
6
+ type Default<T, D> = T extends undefined ? D : T
7
+
8
+ export abstract class Task<
9
+ Options extends {
10
+ plugin?: z.ZodTypeAny
11
+ task?: z.ZodTypeAny
12
+ } = Record<never, never>
13
+ > extends Base {
14
+ static get [typeSymbol](): symbol {
15
+ return taskSymbol
16
+ }
17
+
18
+ get [typeSymbol](): symbol {
19
+ return taskSymbol
20
+ }
21
+
22
+ logger: Logger
23
+
24
+ constructor(
25
+ logger: Logger,
26
+ public id: string,
27
+ public pluginOptions: z.output<Default<Options['plugin'], z.ZodObject<Record<string, never>>>>,
28
+ public options: z.output<Default<Options['task'], z.ZodObject<Record<string, never>>>>
29
+ ) {
30
+ super()
31
+ this.logger = logger.child({ task: id })
32
+ }
33
+
34
+ abstract run(files?: string[]): Promise<void>
35
+ }
36
+
37
+ export type TaskConstructor = {
38
+ new <O extends { plugin: z.ZodTypeAny; task: z.ZodTypeAny }>(
39
+ logger: Logger,
40
+ id: string,
41
+ pluginOptions: Partial<z.infer<O['plugin']>>,
42
+ options: Partial<z.infer<O['task']>>
43
+ ): Task<O>
44
+ }
45
+
46
+ export type TaskClass = TaskConstructor & typeof Task
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "../../tsconfig.settings.json",
3
+ "references": [
4
+ {
5
+ "path": "../conflict"
6
+ },
7
+ {
8
+ "path": "../logger"
9
+ },
10
+ {
11
+ "path": "../plugin"
12
+ },
13
+ {
14
+ "path": "../validated"
15
+ }
16
+ ],
17
+ "compilerOptions": {
18
+ "outDir": "lib",
19
+ "rootDir": "src"
20
+ }
21
+ }