dotcom-tool-kit 1.0.0-beta.9 → 1.0.2-beta.2

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/bin/run CHANGED
@@ -1,34 +1,45 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const c = require('ansi-colors')
4
3
  const argv = require('minimist')(process.argv.slice(2), {
5
- boolean: ['help', 'install']
4
+ boolean: ['help', 'install'],
5
+ '--': true
6
6
  })
7
7
 
8
8
  const { runTasks, showHelp, installHooks } = require('../lib')
9
- const { styles } = require('../lib/messages')
9
+ const { rootLogger, styles } = require('@dotcom-tool-kit/logger')
10
10
 
11
11
  async function main() {
12
- try {
13
- if(argv.install) {
14
- await installHooks()
15
- } else if(argv.help || argv._.length === 0) {
16
- await showHelp(argv._)
12
+ try {
13
+ if (argv.install) {
14
+ await installHooks(rootLogger)
15
+ } else if (argv.help || argv._.length === 0) {
16
+ await showHelp(rootLogger, argv._)
17
+ } else {
18
+ if (argv['--'].length > 0) {
19
+ // The `--` in a command such as `dotcom-tool-kit test:staged --`
20
+ // delineates between hooks and file patterns. For example, when the
21
+ // lint-staged task is run it will identify the files that are staged
22
+ // and match its glob patterns and append them to the command, so that
23
+ // the command becomes something like `dotcom-tool-kit test:staged --
24
+ // index.js`. When this command is executed it runs the configured task
25
+ // where the file path arguments would then be extracted.
26
+ await runTasks(rootLogger, argv._, argv['--'])
17
27
  } else {
18
- await runTasks(argv._)
19
- }
20
- } catch(error) {
21
- if(error.details) {
22
- console.error(
23
- styles.error(error.message) + '\n\n' +
24
- error.details
25
- )
26
- } else {
27
- console.error(error.stack)
28
+ await runTasks(rootLogger, argv._)
28
29
  }
30
+ }
31
+ } catch (error) {
32
+ if (error.details) {
33
+ rootLogger.error('', { skipformat: true })
34
+ rootLogger.error(error.message)
35
+ rootLogger.error(styles.ruler(), { skipformat: true })
36
+ rootLogger.error(error.details, { skipformat: true })
37
+ } else {
38
+ rootLogger.error(error.stack)
39
+ }
29
40
 
30
- process.exitCode = error.exitCode || 1
31
- }
41
+ process.exitCode = error.exitCode || 1
42
+ }
32
43
  }
33
44
 
34
45
  main()
package/lib/config.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import type { TaskClass } from '@dotcom-tool-kit/task';
2
- import type { HookTask, HookClass } from './hook';
3
- import { Plugin } from './plugin';
1
+ import type { Logger } from 'winston';
2
+ import type { HookTask } from './hook';
4
3
  import { Conflict } from './conflict';
4
+ import type { TaskClass, Hook, Plugin } from '@dotcom-tool-kit/types';
5
5
  export interface PluginOptions {
6
6
  options: Record<string, unknown>;
7
7
  plugin: Plugin;
@@ -22,7 +22,7 @@ export interface Config {
22
22
  [id: string]: PluginOptions | Conflict<PluginOptions> | undefined;
23
23
  };
24
24
  hooks: {
25
- [id: string]: HookClass | Conflict<HookClass>;
25
+ [id: string]: Hook | Conflict<Hook>;
26
26
  };
27
27
  }
28
28
  export interface ValidConfig extends Config {
@@ -36,18 +36,15 @@ export interface ValidConfig extends Config {
36
36
  [id: string]: PluginOptions;
37
37
  };
38
38
  hooks: {
39
- [id: string]: HookClass;
39
+ [id: string]: Hook;
40
40
  };
41
41
  }
42
- export declare function validateConfig(config: Config, { checkInstall }?: {
43
- checkInstall?: boolean | undefined;
44
- }): Promise<ValidConfig>;
45
- export declare function loadConfig(options?: {
42
+ export declare function validateConfig(config: Config): Promise<ValidConfig>;
43
+ export declare function checkInstall(config: ValidConfig): Promise<void>;
44
+ export declare function loadConfig(logger: Logger, options?: {
46
45
  validate?: true;
47
- checkInstall?: boolean;
48
46
  }): Promise<ValidConfig>;
49
- export declare function loadConfig(options?: {
47
+ export declare function loadConfig(logger: Logger, options?: {
50
48
  validate?: false;
51
- checkInstall?: boolean;
52
49
  }): Promise<Config>;
53
50
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACjD,OAAO,EAAoB,MAAM,EAAE,MAAM,UAAU,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAmC,MAAM,YAAY,CAAA;AAYtE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACjC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;KAAE,CAAA;IACxD,SAAS,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;IAC1D,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,SAAS,CAAA;KAAE,CAAA;IAC9E,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;KAAE,CAAA;CACzD;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IAClC,SAAS,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAA;IACrC,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,CAAA;IACxC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;CACnC;AAmBD,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,YAAmB,EAAE;;CAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CA0EvG;AAED,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AACvG,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEtC,OAAO,EAAE,QAAQ,EAA+C,MAAM,YAAY,CAAA;AAElF,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAYrE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACjC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;KAAE,CAAA;IACxD,SAAS,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAA;IAC1D,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,SAAS,CAAA;KAAE,CAAA;IAC9E,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;KAAE,CAAA;CAC/C;AAED,MAAM,WAAW,WAAY,SAAQ,MAAM;IACzC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IAClC,SAAS,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAAA;KAAE,CAAA;IACrC,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,CAAA;KAAE,CAAA;IACxC,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CAC9B;AAmBD,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAyFzE;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAWrE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AAC/F,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA"}
package/lib/config.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadConfig = exports.validateConfig = void 0;
3
+ exports.loadConfig = exports.checkInstall = exports.validateConfig = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const path_1 = tslib_1.__importDefault(require("path"));
5
+ const path_1 = (0, tslib_1.__importDefault)(require("path"));
6
6
  const plugin_1 = require("./plugin");
7
7
  const conflict_1 = require("./conflict");
8
8
  const error_1 = require("@dotcom-tool-kit/error");
@@ -20,39 +20,56 @@ async function asyncFilter(items, predicate) {
20
20
  const results = await Promise.all(items.map(async (item) => ({ item, keep: await predicate(item) })));
21
21
  return results.filter(({ keep }) => keep).map(({ item }) => item);
22
22
  }
23
- async function validateConfig(config, { checkInstall = true } = {}) {
24
- const hookTaskConflicts = conflict_1.findConflicts(Object.values(config.hookTasks));
25
- const hookConflicts = conflict_1.findConflicts(Object.values(config.hooks));
26
- const taskConflicts = conflict_1.findConflicts(Object.values(config.tasks));
27
- const optionConflicts = conflict_1.findConflicts(Object.values(config.options));
23
+ async function validateConfig(config) {
24
+ const hookTaskConflicts = (0, conflict_1.findConflicts)(Object.values(config.hookTasks));
25
+ const hookConflicts = (0, conflict_1.findConflicts)(Object.values(config.hooks));
26
+ const taskConflicts = (0, conflict_1.findConflicts)(Object.values(config.tasks));
27
+ const optionConflicts = (0, conflict_1.findConflicts)(Object.values(config.options));
28
+ const definedHookTaskConflicts = hookTaskConflicts.filter((conflict) => {
29
+ return conflict.conflicting[0].id in config.hooks;
30
+ });
28
31
  let shouldThrow = false;
29
- const error = new error_1.ToolKitError('There are problems with your Tool Kit configuration.');
32
+ const error = new error_1.ToolKitConflictError('There are problems with your Tool Kit configuration.', hookTaskConflicts.map((conflict) => ({
33
+ hook: conflict.conflicting[0].id,
34
+ conflictingTasks: conflict.conflicting.flatMap((hook) => hook.tasks.map((task) => ({ task, plugin: hook.plugin.id })))
35
+ })));
30
36
  error.details = '';
31
37
  if (hookConflicts.length > 0 ||
32
- hookTaskConflicts.length > 0 ||
38
+ definedHookTaskConflicts.length > 0 ||
33
39
  taskConflicts.length > 0 ||
34
40
  optionConflicts.length > 0) {
35
41
  shouldThrow = true;
36
42
  if (hookConflicts.length) {
37
- error.details += messages_1.formatHookConflicts(hookConflicts);
43
+ error.details += (0, messages_1.formatHookConflicts)(hookConflicts);
38
44
  }
39
- if (hookTaskConflicts.length) {
40
- error.details += messages_1.formatHookTaskConflicts(hookTaskConflicts);
45
+ if (definedHookTaskConflicts.length) {
46
+ error.details += (0, messages_1.formatHookTaskConflicts)(definedHookTaskConflicts);
41
47
  }
42
48
  if (taskConflicts.length) {
43
- error.details += messages_1.formatTaskConflicts(taskConflicts);
49
+ error.details += (0, messages_1.formatTaskConflicts)(taskConflicts);
44
50
  }
45
51
  if (optionConflicts.length) {
46
- error.details += messages_1.formatOptionConflicts(optionConflicts);
52
+ error.details += (0, messages_1.formatOptionConflicts)(optionConflicts);
47
53
  }
48
54
  }
49
- const configuredHookTasks = conflict_1.withoutConflicts(Object.values(config.hookTasks));
50
- const definedHooks = conflict_1.withoutConflicts(Object.values(config.hooks));
55
+ const configuredHookTasks = (0, conflict_1.withoutConflicts)(Object.values(config.hookTasks));
51
56
  const definedHookIds = new Set(Object.keys(config.hooks));
52
- const undefinedHookTasks = configuredHookTasks.filter((hook) => !definedHookIds.has(hook.id));
57
+ const undefinedHookTasks = configuredHookTasks.filter((hookTask) => {
58
+ // we only care about undefined hooks that were configured by the app, not default config from plugins
59
+ const fromApp = hookTask.plugin.root === process.cwd();
60
+ const hookDefined = definedHookIds.has(hookTask.id);
61
+ return fromApp && !hookDefined;
62
+ });
53
63
  if (undefinedHookTasks.length > 0) {
54
64
  shouldThrow = true;
55
- error.details += messages_1.formatUndefinedHookTasks(undefinedHookTasks, Array.from(definedHookIds));
65
+ error.details += (0, messages_1.formatUndefinedHookTasks)(undefinedHookTasks, Array.from(definedHookIds));
66
+ }
67
+ const unusedOptions = Object.entries(config.options)
68
+ .filter(([, option]) => option && !(0, conflict_1.isConflict)(option) && !option.forPlugin && option.plugin.root === process.cwd())
69
+ .map(([id]) => id);
70
+ if (unusedOptions.length > 0) {
71
+ shouldThrow = true;
72
+ error.details += (0, messages_1.formatUnusedOptions)(unusedOptions, Object.keys(config.plugins));
56
73
  }
57
74
  const missingTasks = configuredHookTasks
58
75
  .map((hook) => ({
@@ -62,17 +79,7 @@ async function validateConfig(config, { checkInstall = true } = {}) {
62
79
  .filter(({ tasks }) => tasks.length > 0);
63
80
  if (missingTasks.length > 0) {
64
81
  shouldThrow = true;
65
- error.details += messages_1.formatMissingTasks(missingTasks, Object.keys(config.tasks));
66
- }
67
- if (checkInstall) {
68
- const uninstalledHooks = await asyncFilter(definedHooks, async (Hook) => {
69
- const hook = new Hook();
70
- return !(await hook.check());
71
- });
72
- if (uninstalledHooks.length > 0) {
73
- shouldThrow = true;
74
- error.details += messages_1.formatUninstalledHooks(uninstalledHooks);
75
- }
82
+ error.details += (0, messages_1.formatMissingTasks)(missingTasks, Object.keys(config.tasks));
76
83
  }
77
84
  if (shouldThrow) {
78
85
  throw error;
@@ -80,12 +87,28 @@ async function validateConfig(config, { checkInstall = true } = {}) {
80
87
  return config;
81
88
  }
82
89
  exports.validateConfig = validateConfig;
83
- async function loadConfig({ validate = true, checkInstall = true } = {}) {
90
+ async function checkInstall(config) {
91
+ const definedHooks = (0, conflict_1.withoutConflicts)(Object.values(config.hooks));
92
+ const uninstalledHooks = await asyncFilter(definedHooks, async (hook) => {
93
+ return !(await hook.check());
94
+ });
95
+ if (uninstalledHooks.length > 0) {
96
+ const error = new error_1.ToolKitError('There are problems with your Tool Kit installation.');
97
+ error.details = (0, messages_1.formatUninstalledHooks)(uninstalledHooks);
98
+ throw error;
99
+ }
100
+ }
101
+ exports.checkInstall = checkInstall;
102
+ async function loadConfig(logger, { validate = true } = {}) {
84
103
  // start loading config and child plugins, starting from the consumer app directory
85
- const config = await plugin_1.loadPluginConfig({
104
+ const config = await (0, plugin_1.loadPluginConfig)(logger, {
86
105
  id: 'app root',
87
106
  root: process.cwd()
88
107
  }, createConfig());
89
- return validate ? validateConfig(config, { checkInstall }) : config;
108
+ return validate ? validateConfig(config) : config;
90
109
  }
91
110
  exports.loadConfig = loadConfig;
111
+ // abstract class TestBase {}
112
+ // class Test extends TestBase {}
113
+ // const testBase = TestBase
114
+ // const test = new testBase()
package/lib/conflict.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Plugin } from './plugin';
1
+ import type { Plugin } from '@dotcom-tool-kit/types';
2
2
  export interface Conflict<T> {
3
3
  plugin: Plugin;
4
4
  conflicting: T[];
@@ -1 +1 @@
1
- {"version":3,"file":"conflict.d.ts","sourceRoot":"","sources":["../src/conflict.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,CAAC,EAAE,CAAA;CACjB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,CAElE;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAU7E;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAUtE"}
1
+ {"version":3,"file":"conflict.d.ts","sourceRoot":"","sources":["../src/conflict.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAEpD,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,CAAC,EAAE,CAAA;CACjB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAAC,CAAC,CAAC,CAElE;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,EAAE,CAU7E;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAUtE"}
package/lib/help.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export default function showHelp(hooks: string[]): Promise<void>;
1
+ import type { Logger } from 'winston';
2
+ export default function showHelp(logger: Logger, hooks: string[]): Promise<void>;
2
3
  //# sourceMappingURL=help.d.ts.map
package/lib/help.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAGA,wBAA8B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDrE"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAErC,wBAA8B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiErF"}
package/lib/help.js CHANGED
@@ -1,43 +1,54 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const config_1 = require("./config");
4
- const messages_1 = require("./messages");
5
- async function showHelp(hooks) {
6
- const config = await config_1.loadConfig({ checkInstall: false });
4
+ const options_1 = require("@dotcom-tool-kit/options");
5
+ const logger_1 = require("@dotcom-tool-kit/logger");
6
+ async function showHelp(logger, hooks) {
7
+ const config = await (0, config_1.loadConfig)(logger);
7
8
  if (hooks.length === 0) {
8
9
  hooks = Object.keys(config.hooks).sort();
9
10
  }
11
+ for (const pluginOptions of Object.values(config.options)) {
12
+ if (pluginOptions.forPlugin) {
13
+ (0, options_1.setOptions)(pluginOptions.forPlugin.id, pluginOptions.options);
14
+ }
15
+ }
16
+ await (0, config_1.checkInstall)(config);
10
17
  const missingHooks = hooks.filter((hook) => !config.hooks[hook]);
11
- console.log(`
12
- 🧰 ${messages_1.styles.title(`welcome to ${messages_1.styles.app('Tool Kit')}!`)}
18
+ logger.info(`
19
+ 🧰 ${logger_1.styles.title(`welcome to ${logger_1.styles.app('Tool Kit')}!`)}
13
20
 
14
21
  Tool Kit is modern, maintainable & modular developer tooling for FT.com projects.
15
22
 
16
- ${messages_1.styles.URL('https://github.com/financial-times/dotcom-tool-kit')}
23
+ ${logger_1.styles.URL('https://github.com/financial-times/dotcom-tool-kit')}
17
24
 
18
- ${messages_1.styles.ruler()}
19
- ${messages_1.styles.dim(hooks.length === 0
20
- ? 'available hooks'
21
- : `help for ${hooks.length - missingHooks.length} ${hooks.length - missingHooks.length > 1 ? 'hooks' : 'hook'}`)}:
25
+ ${logger_1.styles.ruler()}
26
+ ${Object.keys(config.hooks).length === 0
27
+ ? `there are no hooks available. you'll need to install plugins that define hooks to be able to run Tool Kit tasks.`
28
+ : logger_1.styles.dim(hooks.length === 0
29
+ ? 'available hooks'
30
+ : `help for ${hooks.length - missingHooks.length} ${hooks.length - missingHooks.length > 1 ? 'hooks' : 'hook'}`)}:
22
31
  `);
23
32
  for (const hook of hooks) {
24
33
  const Hook = config.hooks[hook];
25
34
  if (Hook) {
26
35
  const tasks = config.hookTasks[hook];
27
- console.log(`${messages_1.styles.heading(hook)}
28
- ${Hook.description ? Hook.description + '\n' : ''}
36
+ /* eslint-disable @typescript-eslint/no-explicit-any -- Object.constructor does not consider static properties */
37
+ logger.info(`${logger_1.styles.heading(hook)}
38
+ ${Hook.constructor.description ? Hook.constructor.description + '\n' : ''}
29
39
  ${tasks && tasks.tasks.length
30
40
  ? `runs ${tasks.tasks.length > 1 ? 'these tasks' : 'this task'}:
31
41
  ${tasks.tasks
32
- .map((task) => `- ${messages_1.styles.task(task)} ${messages_1.styles.dim(config.tasks[task].description)}`)
42
+ .map((task) => `- ${logger_1.styles.task(task)} ${logger_1.styles.dim(config.tasks[task].description)}`)
33
43
  .join('\n')}`
34
- : messages_1.styles.dim('no tasks configured to run on this hook.')}
35
- ${messages_1.styles.ruler()}
44
+ : logger_1.styles.dim('no tasks configured to run on this hook.')}
45
+ ${logger_1.styles.ruler()}
36
46
  `);
47
+ /*eslint-enable @typescript-eslint/no-explicit-any */
37
48
  }
38
49
  }
39
50
  if (missingHooks.length) {
40
- console.warn(messages_1.styles.warning(`no such ${missingHooks.length > 1 ? 'hooks' : 'hook'} ${missingHooks.map(messages_1.styles.hook).join(', ')}`));
51
+ logger.warn(`no such ${missingHooks.length > 1 ? 'hooks' : 'hook'} ${missingHooks.map(logger_1.styles.hook).join(', ')}`);
41
52
  }
42
53
  }
43
54
  exports.default = showHelp;
package/lib/hook.d.ts CHANGED
@@ -1,17 +1,7 @@
1
- import type { Plugin } from './plugin';
1
+ import type { Plugin } from '@dotcom-tool-kit/types';
2
2
  export interface HookTask {
3
3
  id: string;
4
4
  plugin: Plugin;
5
5
  tasks: string[];
6
6
  }
7
- export interface HookClass {
8
- id?: string;
9
- plugin?: Plugin;
10
- description?: string;
11
- new (): Hook;
12
- }
13
- export interface Hook {
14
- check(): Promise<boolean>;
15
- install(): Promise<void>;
16
- }
17
7
  //# sourceMappingURL=hook.d.ts.map
package/lib/hook.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEtC,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,IAAI,CAAA;CACb;AAED,MAAM,WAAW,IAAI;IACnB,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACzB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAEpD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB"}
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- export declare function runTasks(hooks: string[]): Promise<void>;
1
+ import type { Logger } from 'winston';
2
+ export declare function runTasks(logger: Logger, hooks: string[], files?: string[]): Promise<void>;
2
3
  export { default as showHelp } from './help';
3
4
  export { default as installHooks } from './install';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC7D;AAED,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAQrC,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8E/F;AAED,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,WAAW,CAAA"}
package/lib/index.js CHANGED
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.installHooks = exports.showHelp = exports.runTasks = void 0;
7
7
  const error_1 = require("@dotcom-tool-kit/error");
8
8
  const config_1 = require("./config");
9
- const messages_1 = require("./messages");
10
- async function runTasks(hooks) {
11
- var _a;
12
- const config = await config_1.loadConfig();
9
+ const options_1 = require("@dotcom-tool-kit/options");
10
+ const logger_1 = require("@dotcom-tool-kit/logger");
11
+ async function runTasks(logger, hooks, files) {
12
+ const config = await (0, config_1.loadConfig)(logger);
13
13
  const availableHooks = Object.keys(config.hooks)
14
14
  .sort()
15
15
  .map((id) => `- ${id}`)
@@ -23,20 +23,51 @@ hooks that are available are:
23
23
  ${availableHooks}`;
24
24
  throw error;
25
25
  }
26
+ for (const pluginOptions of Object.values(config.options)) {
27
+ if (pluginOptions.forPlugin) {
28
+ (0, options_1.setOptions)(pluginOptions.forPlugin.id, pluginOptions.options);
29
+ }
30
+ }
31
+ await (0, config_1.checkInstall)(config);
26
32
  for (const hook of hooks) {
33
+ const errors = [];
27
34
  if (!config.hookTasks[hook]) {
28
- console.warn(messages_1.styles.warning(`no task configured for ${hook}: skipping assignment...}`));
35
+ logger.warn(`no task configured for ${hook}: skipping assignment...`);
29
36
  continue;
30
37
  }
31
38
  const assignment = config.hookTasks[hook];
32
39
  for (const id of assignment.tasks) {
33
40
  const Task = config.tasks[id];
34
- const options = Task.plugin ? (_a = config.options[Task.plugin.id]) === null || _a === void 0 ? void 0 : _a.options : {};
41
+ const options = Task.plugin ? (0, options_1.getOptions)(Task.plugin.id) : {};
35
42
  // `Task` is an abstract class. here we know it's a concrete subclass
36
43
  // but typescript doesn't, so cast it to any.
37
44
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
- const task = new Task(options);
39
- await task.run();
45
+ const task = new Task(logger, options);
46
+ try {
47
+ await task.run(files);
48
+ }
49
+ catch (error) {
50
+ // allow subsequent hook tasks to run on error
51
+ errors.push({
52
+ hook,
53
+ task: id,
54
+ error
55
+ });
56
+ }
57
+ }
58
+ if (errors.length > 0) {
59
+ const error = new error_1.ToolKitError(`error running tasks for ${logger_1.styles.hook(hook)}`);
60
+ error.details = errors
61
+ .map(({ hook, task, error }) => `${logger_1.styles.heading(`${logger_1.styles.task(task)}:`)}
62
+
63
+ ${error.message}${error instanceof error_1.ToolKitError
64
+ ? `
65
+
66
+ ${error.details}`
67
+ : ''}`)
68
+ .join(`${logger_1.styles.dim(logger_1.styles.ruler())}\n`);
69
+ error.exitCode = errors.length + 1;
70
+ throw error;
40
71
  }
41
72
  }
42
73
  }
package/lib/install.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export default function installHooks(): Promise<void>;
1
+ import type { Logger } from 'winston';
2
+ import { Config } from './config';
3
+ export default function installHooks(logger: Logger): Promise<Config>;
2
4
  //# sourceMappingURL=install.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAGA,wBAA8B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAyB1D"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,MAAM,EAAc,MAAM,UAAU,CAAA;AAE7C,wBAA8B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmC1E"}
package/lib/install.js CHANGED
@@ -1,28 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const config_1 = require("./config");
4
3
  const error_1 = require("@dotcom-tool-kit/error");
5
- async function installHooks() {
6
- const config = await config_1.loadConfig({ checkInstall: false });
7
- const tasks = Object.values(config.hooks).map((Hook) => async () => {
8
- const hook = new Hook();
4
+ const options_1 = require("@dotcom-tool-kit/options");
5
+ const config_1 = require("./config");
6
+ async function installHooks(logger) {
7
+ const config = await (0, config_1.loadConfig)(logger);
8
+ const tasks = Object.values(config.hooks).map((hook) => async () => {
9
9
  if (!(await hook.check())) {
10
10
  await hook.install();
11
11
  }
12
12
  });
13
+ for (const pluginOptions of Object.values(config.options)) {
14
+ if (pluginOptions.forPlugin) {
15
+ (0, options_1.setOptions)(pluginOptions.forPlugin.id, pluginOptions.options);
16
+ }
17
+ }
13
18
  const errors = [];
14
19
  for (const task of tasks) {
15
20
  try {
16
21
  await task();
17
22
  }
18
23
  catch (err) {
19
- errors.push(err);
24
+ if (err instanceof Error) {
25
+ errors.push(err);
26
+ }
27
+ else {
28
+ throw err;
29
+ }
20
30
  }
21
31
  }
22
32
  if (errors.length) {
23
33
  const error = new error_1.ToolKitError('could not automatically install hooks:');
24
- error.details = errors.map((error) => error.message).join('\n\n');
34
+ error.details = errors.map((error) => `- ${error.message}`).join('\n');
25
35
  throw error;
26
36
  }
37
+ return config;
27
38
  }
28
39
  exports.default = installHooks;
package/lib/messages.d.ts CHANGED
@@ -1,31 +1,18 @@
1
- import colours from 'ansi-colors';
2
1
  import type { PluginOptions } from './config';
3
2
  import type { Conflict } from './conflict';
4
- import type { HookTask, HookClass } from './hook';
5
- import type { TaskClass } from '@dotcom-tool-kit/task';
6
- declare const s: {
7
- hook: colours.StyleFunction;
8
- task: colours.StyleFunction;
9
- plugin: colours.StyleFunction;
10
- URL: colours.StyleFunction;
11
- app: colours.StyleFunction;
12
- heading: colours.StyleFunction;
13
- dim: colours.StyleFunction;
14
- title: colours.StyleFunction;
15
- error: (string: string) => string;
16
- warning: (string: string) => string;
17
- ruler: () => string;
18
- };
19
- export { s as styles };
3
+ import type { HookTask } from './hook';
4
+ import type { Hook, TaskClass } from '@dotcom-tool-kit/types';
20
5
  export declare const formatTaskConflicts: (conflicts: Conflict<TaskClass>[]) => string;
21
- export declare const formatHookConflicts: (conflicts: Conflict<HookClass>[]) => string;
6
+ export declare const formatHookConflicts: (conflicts: Conflict<Hook>[]) => string;
22
7
  export declare const formatHookTaskConflicts: (conflicts: Conflict<HookTask>[]) => string;
23
8
  export declare const formatOptionConflicts: (conflicts: Conflict<PluginOptions>[]) => string;
24
9
  export declare const formatUndefinedHookTasks: (undefinedHooks: HookTask[], definedHooks: string[]) => string;
25
- export declare const formatUninstalledHooks: (uninstalledHooks: HookClass[]) => string;
10
+ export declare const formatUnusedOptions: (unusedOptions: string[], definedPlugins: string[]) => string;
11
+ export declare const formatUninstalledHooks: (uninstalledHooks: Hook[]) => string;
26
12
  declare type Missing = {
27
13
  hook: HookTask;
28
14
  tasks: string[];
29
15
  };
30
16
  export declare const formatMissingTasks: (missingTasks: Missing[], tasks: string[]) => string;
17
+ export {};
31
18
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,aAAa,CAAA;AAEjC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAEjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAItD,QAAA,MAAM,CAAC;;;;;;;;;oBASW,MAAM,KAAG,MAAM;sBACb,MAAM,KAAG,MAAM;iBACtB,MAAM;CAClB,CAAA;AAED,OAAO,EAAE,CAAC,IAAI,MAAM,EAAE,CAAA;AAStB,eAAO,MAAM,mBAAmB,cAAe,SAAS,SAAS,CAAC,EAAE,KAAG,MAKE,CAAA;AASzE,eAAO,MAAM,mBAAmB,cAAe,SAAS,SAAS,CAAC,EAAE,KAAG,MAKE,CAAA;AAazE,eAAO,MAAM,uBAAuB,cAAe,SAAS,QAAQ,CAAC,EAAE,KAAG,MAQzE,CAAA;AAOD,eAAO,MAAM,qBAAqB,cAAe,SAAS,aAAa,CAAC,EAAE,KAAG,MAU5E,CAAA;AAMD,eAAO,MAAM,wBAAwB,mBACnB,QAAQ,EAAE,gBACZ,MAAM,EAAE,KACrB,MAOF,CAAA;AAED,eAAO,MAAM,sBAAsB,qBACf,SAAS,EAAE,KAC5B,MAKF,CAAA;AAED,aAAK,OAAO,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAOlD,eAAO,MAAM,kBAAkB,iBACf,OAAO,EAAE,SAChB,MAAM,EAAE,KACd,MAOF,CAAA"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAC7C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEtC,OAAO,KAAK,EAAU,IAAI,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AASrE,eAAO,MAAM,mBAAmB,cAAe,SAAS,SAAS,CAAC,EAAE,KAAG,MAKE,CAAA;AASzE,eAAO,MAAM,mBAAmB,cAAe,SAAS,IAAI,CAAC,EAAE,KAAG,MAKO,CAAA;AAazE,eAAO,MAAM,uBAAuB,cAAe,SAAS,QAAQ,CAAC,EAAE,KAAG,MAQzE,CAAA;AAOD,eAAO,MAAM,qBAAqB,cAAe,SAAS,aAAa,CAAC,EAAE,KAAG,MAU5E,CAAA;AAMD,eAAO,MAAM,wBAAwB,mBACnB,QAAQ,EAAE,gBACZ,MAAM,EAAE,KACrB,MAWF,CAAA;AAED,eAAO,MAAM,mBAAmB,kBACf,MAAM,EAAE,kBACP,MAAM,EAAE,KACvB,MAWF,CAAA;AAED,eAAO,MAAM,sBAAsB,qBACf,IAAI,EAAE,KACvB,MAKF,CAAA;AAED,aAAK,OAAO,GAAG;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAOlD,eAAO,MAAM,kBAAkB,iBACf,OAAO,EAAE,SAChB,MAAM,EAAE,KACd,MAOF,CAAA"}
package/lib/messages.js CHANGED
@@ -1,86 +1,82 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUndefinedHookTasks = exports.formatOptionConflicts = exports.formatHookTaskConflicts = exports.formatHookConflicts = exports.formatTaskConflicts = exports.styles = void 0;
4
- const tslib_1 = require("tslib");
5
- const ansi_colors_1 = tslib_1.__importDefault(require("ansi-colors"));
6
- // consistent styling use cases for terminal colours
7
- // don't use ansi-colors directly, define a style please
8
- const s = {
9
- hook: ansi_colors_1.default.magenta,
10
- task: ansi_colors_1.default.blueBright,
11
- plugin: ansi_colors_1.default.cyan,
12
- URL: ansi_colors_1.default.cyan.underline,
13
- app: ansi_colors_1.default.green,
14
- heading: ansi_colors_1.default.bold,
15
- dim: ansi_colors_1.default.grey,
16
- title: ansi_colors_1.default.bold.underline,
17
- error: (string) => `${ansi_colors_1.default.red.bold('‼︎')} ${s.title(string)}`,
18
- warning: (string) => `${ansi_colors_1.default.yellow.bold('⚠︎')} ${s.title(string)}`,
19
- ruler: () => s.dim('─'.repeat(process.stdout.columns / 2))
20
- };
21
- exports.styles = s;
22
- const formatTaskConflict = (conflict) => `- ${s.task(conflict.conflicting[0].id || 'unknown task')} ${s.dim('from plugins')} ${conflict.conflicting
23
- .map((task) => s.plugin(task.plugin ? task.plugin.id : 'unknown plugin'))
24
- .join(s.dim(', '))}`;
25
- const formatTaskConflicts = (conflicts) => `${s.heading('There are multiple plugins that include the same tasks')}:
3
+ exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUnusedOptions = exports.formatUndefinedHookTasks = exports.formatOptionConflicts = exports.formatHookTaskConflicts = exports.formatHookConflicts = exports.formatTaskConflicts = void 0;
4
+ const logger_1 = require("@dotcom-tool-kit/logger");
5
+ const formatTaskConflict = (conflict) => `- ${logger_1.styles.task(conflict.conflicting[0].id || 'unknown task')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
6
+ .map((task) => logger_1.styles.plugin(task.plugin ? task.plugin.id : 'unknown plugin'))
7
+ .join(logger_1.styles.dim(', '))}`;
8
+ const formatTaskConflicts = (conflicts) => `${logger_1.styles.heading('There are multiple plugins that include the same tasks')}:
26
9
  ${conflicts.map(formatTaskConflict).join('\n')}
27
10
 
28
11
  You must resolve this conflict by removing all but one of these plugins.`;
29
12
  exports.formatTaskConflicts = formatTaskConflicts;
30
- const formatHookConflict = (conflict) => `- ${s.hook(conflict.conflicting[0].id || 'unknown event')} ${s.dim('from plugins')} ${conflict.conflicting
31
- .map((task) => s.plugin(task.plugin ? task.plugin.id : 'unknown plugin'))
32
- .join(s.dim(', '))}`;
33
- const formatHookConflicts = (conflicts) => `${s.heading('There are multiple plugins that include the same hooks')}:
13
+ const formatHookConflict = (conflict) => `- ${logger_1.styles.hook(conflict.conflicting[0].id || 'unknown event')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
14
+ .map((task) => logger_1.styles.plugin(task.plugin ? task.plugin.id : 'unknown plugin'))
15
+ .join(logger_1.styles.dim(', '))}`;
16
+ const formatHookConflicts = (conflicts) => `${logger_1.styles.heading('There are multiple plugins that include the same hooks')}:
34
17
  ${conflicts.map(formatHookConflict).join('\n')}
35
18
 
36
19
  You must resolve this conflict by removing all but one of these plugins.`;
37
20
  exports.formatHookConflicts = formatHookConflicts;
38
- const formatHookTaskConflict = (conflict) => `${s.hook(conflict.conflicting[0].id)}:
21
+ const formatHookTaskConflict = (conflict) => `${logger_1.styles.hook(conflict.conflicting[0].id)}:
39
22
  ${conflict.conflicting
40
- .map((hook) => `- ${hook.tasks.map(s.task).join(s.dim(', '))} ${s.dim('by plugin')} ${s.plugin(hook.plugin.id)}`)
23
+ .map((hook) => `- ${hook.tasks.map(logger_1.styles.task).join(logger_1.styles.dim(', '))} ${logger_1.styles.dim('by plugin')} ${logger_1.styles.plugin(hook.plugin.id)}`)
41
24
  .join('\n')}
42
25
  `;
43
- const formatHookTaskConflicts = (conflicts) => `${s.heading('These hooks are configured to run different tasks by multiple plugins')}:
26
+ const formatHookTaskConflicts = (conflicts) => `${logger_1.styles.heading('These hooks are configured to run different tasks by multiple plugins')}:
44
27
  ${conflicts.map(formatHookTaskConflict).join('\n')}
45
- You must resolve this conflict by explicitly configuring which task to run for these hooks. See ${s.URL('https://github.com/financial-times/dotcom-tool-kit/tree/main/docs/resolving-hook-conflicts.md')} for more details.
28
+ You must resolve this conflict by explicitly configuring which task to run for these hooks. See ${logger_1.styles.URL('https://github.com/financial-times/dotcom-tool-kit/tree/main/docs/resolving-hook-conflicts.md')} for more details.
46
29
 
47
30
  `;
48
31
  exports.formatHookTaskConflicts = formatHookTaskConflicts;
49
- const formatOptionConflict = (conflict) => `${s.plugin(conflict.conflicting[0].forPlugin.id)}, configured by:
50
- ${conflict.conflicting.map((option) => `- ${s.plugin(option.plugin.id)}`)}`;
51
- const formatOptionConflicts = (conflicts) => `${s.heading('These plugins have conflicting options')}:
32
+ const formatOptionConflict = (conflict) => `${logger_1.styles.plugin(conflict.conflicting[0].forPlugin.id)}, configured by:
33
+ ${conflict.conflicting.map((option) => `- ${logger_1.styles.plugin(option.plugin.id)}`)}`;
34
+ const formatOptionConflicts = (conflicts) => `${logger_1.styles.heading('These plugins have conflicting options')}:
52
35
 
53
36
  ${conflicts.map(formatOptionConflict).join('\n')}
54
37
 
55
- You must resolve this conflict by providing options in your app's Tool Kit configuration for these plugins, or installing a use-case plugin that provides these options. See ${s.URL('https://github.com/financial-times/dotcom-tool-kit/tree/main/readme.md#options')} for more details.
38
+ You must resolve this conflict by providing options in your app's Tool Kit configuration for these plugins, or installing a use-case plugin that provides these options. See ${logger_1.styles.URL('https://github.com/financial-times/dotcom-tool-kit/tree/main/readme.md#options')} for more details.
56
39
 
57
40
  `;
58
41
  exports.formatOptionConflicts = formatOptionConflicts;
59
- const formatPlugin = (plugin) => plugin.id === 'app root' ? s.app('your app') : `plugin ${s.plugin(plugin.id)}`;
42
+ const formatPlugin = (plugin) => plugin.id === 'app root' ? logger_1.styles.app('your app') : `plugin ${logger_1.styles.plugin(plugin.id)}`;
60
43
  // TODO text similarity "did you mean...?"
61
- const formatUndefinedHookTasks = (undefinedHooks, definedHooks) => `These hooks don't exist, but are configured to run tasks:
44
+ const formatUndefinedHookTasks = (undefinedHooks, definedHooks) => `Hooks must be defined by a plugin before you can configure a task to run for them. In your Tool Kit configuration you've configured hooks that aren't defined:
62
45
 
63
- ${undefinedHooks.map((hook) => `- ${s.hook(hook.id)} assigned by ${formatPlugin(hook.plugin)}`).join('\n')}
46
+ ${undefinedHooks.map((hook) => `- ${logger_1.styles.hook(hook.id)}`).join('\n')}
64
47
 
65
- They could be misspelt, or defined by a Tool Kit plugin that isn't used by this app.
48
+ They could be misspelt, or defined by a Tool Kit plugin that isn't installed in this app.
66
49
 
67
- Available hooks are: ${definedHooks.map(s.hook).join(', ')}.
50
+ ${definedHooks.length > 0
51
+ ? `Hooks that are defined and available for tasks are: ${definedHooks.map(logger_1.styles.hook).join(', ')}`
52
+ : `There are no hooks defined by this app's plugins. You probably need to install some plugins to define hooks.`}.
68
53
  `;
69
54
  exports.formatUndefinedHookTasks = formatUndefinedHookTasks;
55
+ const formatUnusedOptions = (unusedOptions, definedPlugins) => `Options are defined in your Tool Kit configuration for plugins that don't exist:
56
+
57
+ ${unusedOptions.map((optionName) => `- ${logger_1.styles.plugin(optionName)}`).join('\n')}
58
+
59
+ They could be misspelt, or defined by a Tool Kit plugin that isn't installed in this app.
60
+
61
+ ${definedPlugins.length > 0
62
+ ? `Plugins that are defined and can have options set are: ${definedPlugins.map(logger_1.styles.plugin).join(', ')}`
63
+ : `There are no plugins installed currently. You'll need to install some plugins before options can be set.`}.
64
+ `;
65
+ exports.formatUnusedOptions = formatUnusedOptions;
70
66
  const formatUninstalledHooks = (uninstalledHooks) => `These hooks aren't installed into your app:
71
67
 
72
- ${uninstalledHooks.map((hook) => `- ${s.hook(hook.id || 'unknown event')}`).join('\n')}
68
+ ${uninstalledHooks.map((hook) => `- ${logger_1.styles.hook(hook.id || 'unknown event')}`).join('\n')}
73
69
 
74
- Run ${s.task('dotcom-tool-kit --install')} to install these hooks.
70
+ Run ${logger_1.styles.task('dotcom-tool-kit --install')} to install these hooks.
75
71
  `;
76
72
  exports.formatUninstalledHooks = formatUninstalledHooks;
77
- const formatMissingTask = (missing) => `- ${missing.tasks.map(s.task).join(', ')} ${s.dim(`(assigned to ${s.hook(missing.hook.id)} by ${formatPlugin(missing.hook.plugin)})`)}`;
73
+ const formatMissingTask = (missing) => `- ${missing.tasks.map(logger_1.styles.task).join(', ')} ${logger_1.styles.dim(`(assigned to ${logger_1.styles.hook(missing.hook.id)} by ${formatPlugin(missing.hook.plugin)})`)}`;
78
74
  const formatMissingTasks = (missingTasks, tasks) => `These tasks don't exist, but are configured to run from hooks:
79
75
 
80
76
  ${missingTasks.map(formatMissingTask).join('\n')}
81
77
 
82
78
  They could be misspelt, or defined by a Tool Kit plugin that isn't used by this app.
83
79
 
84
- Available tasks are: ${tasks.map(s.task).join(', ')}.
80
+ Available tasks are: ${tasks.map(logger_1.styles.task).join(', ')}.
85
81
  `;
86
82
  exports.formatMissingTasks = formatMissingTasks;
package/lib/plugin.d.ts CHANGED
@@ -1,16 +1,7 @@
1
- import type { TaskClass } from '@dotcom-tool-kit/task';
2
- import type { HookClass } from './hook';
1
+ import type { Logger } from 'winston';
3
2
  import { Config } from './config';
4
- export interface Plugin {
5
- id: string;
6
- root: string;
7
- parent?: Plugin;
8
- tasks?: TaskClass[];
9
- hooks?: {
10
- [id: string]: HookClass;
11
- };
12
- }
13
- export declare function loadPluginConfig(plugin: Plugin, config: Config): Promise<Config>;
14
- export declare function loadPlugin(id: string, config: Config, parent?: Plugin): Promise<Plugin>;
15
- export declare function loadPlugins(plugins: string[], config: Config, parent?: Plugin): Promise<Plugin[]>;
3
+ import { Plugin } from '@dotcom-tool-kit/types';
4
+ export declare function loadPluginConfig(logger: Logger, plugin: Plugin, config: Config): Promise<Config>;
5
+ export declare function loadPlugin(logger: Logger, id: string, config: Config, parent?: Plugin): Promise<Plugin>;
6
+ export declare function loadPlugins(logger: Logger, plugins: string[], config: Config, parent?: Plugin): Promise<Plugin[]>;
16
7
  //# sourceMappingURL=plugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,QAAQ,CAAA;AAEjD,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAA;AAGhD,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,SAAS,EAAE,CAAA;IACnB,KAAK,CAAC,EAAE;QACN,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;KACxB,CAAA;CACF;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6FtF;AAED,wBAAsB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2E7F;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEjG"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGrC,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAA;AAKhD,OAAO,EAA2B,MAAM,EAAa,MAAM,wBAAwB,CAAA;AAEnF,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA6FtG;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAkFjB;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,CAAC,CAEnB"}
package/lib/plugin.js CHANGED
@@ -2,18 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadPlugins = exports.loadPlugin = exports.loadPluginConfig = void 0;
4
4
  const tslib_1 = require("tslib");
5
- const import_from_1 = tslib_1.__importDefault(require("import-from"));
6
- const resolve_from_1 = tslib_1.__importDefault(require("resolve-from"));
7
- const lodash_mergewith_1 = tslib_1.__importDefault(require("lodash.mergewith"));
5
+ const import_from_1 = (0, tslib_1.__importDefault)(require("import-from"));
6
+ const resolve_from_1 = (0, tslib_1.__importDefault)(require("resolve-from"));
7
+ const lodash_mergewith_1 = (0, tslib_1.__importDefault)(require("lodash.mergewith"));
8
8
  const conflict_1 = require("./conflict");
9
9
  const rc_file_1 = require("./rc-file");
10
- async function loadPluginConfig(plugin, config) {
11
- const { plugins = [], hooks = {}, options = {} } = await rc_file_1.loadToolKitRC(plugin.root);
10
+ const error_1 = require("@dotcom-tool-kit/error");
11
+ const logger_1 = require("@dotcom-tool-kit/logger");
12
+ const types_1 = require("@dotcom-tool-kit/types");
13
+ async function loadPluginConfig(logger, plugin, config) {
14
+ const { plugins = [], hooks = {}, options = {} } = await (0, rc_file_1.loadToolKitRC)(plugin.root);
12
15
  // load any plugins requested by this plugin
13
- await loadPlugins(plugins, config, plugin);
16
+ await loadPlugins(logger, plugins, config, plugin);
14
17
  // load plugin hook tasks. do this after loading child plugins, so
15
18
  // parent hooks get assigned after child hooks and can override them
16
- lodash_mergewith_1.default(config.hookTasks, hooks,
19
+ (0, lodash_mergewith_1.default)(config.hookTasks, hooks,
17
20
  // handle conflicts between hooks from different plugins
18
21
  (existingHookTask, configHookTask, id) => {
19
22
  const newHookTask = {
@@ -30,7 +33,7 @@ async function loadPluginConfig(plugin, config) {
30
33
  // return a conflict either listing this hook and the siblings,
31
34
  // or merging in a previously-generated hook
32
35
  if (existingFromSibling) {
33
- const conflicting = conflict_1.isConflict(existingHookTask) ? existingHookTask.conflicting : [existingHookTask];
36
+ const conflicting = (0, conflict_1.isConflict)(existingHookTask) ? existingHookTask.conflicting : [existingHookTask];
34
37
  const conflict = {
35
38
  plugin,
36
39
  conflicting: conflicting.concat(newHookTask)
@@ -43,7 +46,7 @@ async function loadPluginConfig(plugin, config) {
43
46
  });
44
47
  // merge options from this plugin's config with any options we've collected already
45
48
  // TODO this is almost the exact same code as for hooks, refactor
46
- lodash_mergewith_1.default(config.options, options, (existingOptions, configOptions, id) => {
49
+ (0, lodash_mergewith_1.default)(config.options, options, (existingOptions, configOptions, id) => {
47
50
  const pluginOptions = {
48
51
  options: configOptions,
49
52
  plugin,
@@ -58,7 +61,7 @@ async function loadPluginConfig(plugin, config) {
58
61
  // return a conflict either listing these options and the sibling's,
59
62
  // or merging in previously-generated options
60
63
  if (existingFromSibling) {
61
- const conflicting = conflict_1.isConflict(existingOptions) ? existingOptions.conflicting : [existingOptions];
64
+ const conflicting = (0, conflict_1.isConflict)(existingOptions) ? existingOptions.conflicting : [existingOptions];
62
65
  const conflict = {
63
66
  plugin,
64
67
  conflicting: conflicting.concat(pluginOptions)
@@ -72,15 +75,25 @@ async function loadPluginConfig(plugin, config) {
72
75
  return config;
73
76
  }
74
77
  exports.loadPluginConfig = loadPluginConfig;
75
- async function loadPlugin(id, config, parent) {
78
+ async function loadPlugin(logger, id, config, parent) {
76
79
  // don't load duplicate plugins
77
80
  if (id in config.plugins) {
78
81
  return config.plugins[id];
79
82
  }
80
83
  const root = parent ? parent.root : process.cwd();
81
84
  // load plugin relative to the parent plugin
82
- const pluginRoot = resolve_from_1.default(root, id);
83
- const basePlugin = import_from_1.default(root, id);
85
+ const pluginRoot = (0, resolve_from_1.default)(root, id);
86
+ const rawPlugin = (0, import_from_1.default)(root, id);
87
+ let basePlugin;
88
+ try {
89
+ basePlugin = (0, types_1.instantiatePlugin)(rawPlugin, logger);
90
+ }
91
+ catch (error) {
92
+ if (error instanceof error_1.ToolKitError) {
93
+ error.details = `the package ${logger_1.styles.plugin(id)} at ${logger_1.styles.filepath(pluginRoot)} is not a valid plugin`;
94
+ }
95
+ throw error;
96
+ }
84
97
  const plugin = {
85
98
  ...basePlugin,
86
99
  id,
@@ -89,13 +102,13 @@ async function loadPlugin(id, config, parent) {
89
102
  };
90
103
  config.plugins[id] = plugin;
91
104
  // add plugin tasks to our task registry, handling any conflicts
92
- lodash_mergewith_1.default(config.tasks, Object.fromEntries((plugin.tasks || []).map((task) => [task.name, task])), (existingTask, newTask, taskId) => {
105
+ (0, lodash_mergewith_1.default)(config.tasks, Object.fromEntries((plugin.tasks || []).map((task) => [task.name, task])), (existingTask, newTask, taskId) => {
93
106
  newTask.plugin = plugin;
94
107
  newTask.id = taskId;
95
108
  if (!existingTask) {
96
109
  return newTask;
97
110
  }
98
- const conflicting = conflict_1.isConflict(existingTask) ? existingTask.conflicting : [existingTask];
111
+ const conflicting = (0, conflict_1.isConflict)(existingTask) ? existingTask.conflicting : [existingTask];
99
112
  return {
100
113
  plugin,
101
114
  conflicting: conflicting.concat(newTask)
@@ -103,23 +116,23 @@ async function loadPlugin(id, config, parent) {
103
116
  });
104
117
  // add hooks to the registry, handling any conflicts
105
118
  // TODO refactor with command conflict handler
106
- lodash_mergewith_1.default(config.hooks, plugin.hooks, (existingHook, newHook, hookId) => {
119
+ (0, lodash_mergewith_1.default)(config.hooks, plugin.hooks, (existingHook, newHook, hookId) => {
107
120
  newHook.id = hookId;
108
121
  newHook.plugin = plugin;
109
122
  if (!existingHook) {
110
123
  return newHook;
111
124
  }
112
- const conflicting = conflict_1.isConflict(existingHook) ? existingHook.conflicting : [existingHook];
125
+ const conflicting = (0, conflict_1.isConflict)(existingHook) ? existingHook.conflicting : [existingHook];
113
126
  return {
114
127
  plugin,
115
128
  conflicting: conflicting.concat(newHook)
116
129
  };
117
130
  });
118
- await loadPluginConfig(plugin, config);
131
+ await loadPluginConfig(logger, plugin, config);
119
132
  return plugin;
120
133
  }
121
134
  exports.loadPlugin = loadPlugin;
122
- function loadPlugins(plugins, config, parent) {
123
- return Promise.all(plugins.map((plugin) => loadPlugin(plugin, config, parent)));
135
+ function loadPlugins(logger, plugins, config, parent) {
136
+ return Promise.all(plugins.map((plugin) => loadPlugin(logger, plugin, config, parent)));
124
137
  }
125
138
  exports.loadPlugins = loadPlugins;
package/lib/rc-file.d.ts CHANGED
@@ -1,3 +1,10 @@
1
+ export declare const explorer: {
2
+ readonly search: (searchFrom?: string | undefined) => Promise<import("cosmiconfig/dist/types").CosmiconfigResult>;
3
+ readonly load: (filepath: string) => Promise<import("cosmiconfig/dist/types").CosmiconfigResult>;
4
+ readonly clearLoadCache: () => void;
5
+ readonly clearSearchCache: () => void;
6
+ readonly clearCaches: () => void;
7
+ };
1
8
  export interface RCFile {
2
9
  plugins: string[];
3
10
  hooks: {
@@ -1 +1 @@
1
- {"version":3,"file":"rc-file.d.ts","sourceRoot":"","sources":["../src/rc-file.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;CACnD;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKjE"}
1
+ {"version":3,"file":"rc-file.d.ts","sourceRoot":"","sources":["../src/rc-file.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,QAAQ;;;;;;CAA6D,CAAA;AAElF,MAAM,WAAW,MAAM;IACrB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,KAAK,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,CAAA;KAAE,CAAA;IAC1C,OAAO,EAAE;QAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAA;CACnD;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAKjE"}
package/lib/rc-file.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadToolKitRC = void 0;
3
+ exports.loadToolKitRC = exports.explorer = void 0;
4
4
  const cosmiconfig_1 = require("cosmiconfig");
5
- const explorer = cosmiconfig_1.cosmiconfig('toolkit', { ignoreEmptySearchPlaces: false });
5
+ exports.explorer = (0, cosmiconfig_1.cosmiconfig)('toolkit', { ignoreEmptySearchPlaces: false });
6
6
  async function loadToolKitRC(root) {
7
- const result = await explorer.search(root);
7
+ const result = await exports.explorer.search(root);
8
8
  if (!result || !result.config)
9
9
  return { plugins: [], hooks: {}, options: {} };
10
10
  return result.config;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "dotcom-tool-kit",
3
- "version": "1.0.0-beta.9",
3
+ "version": "1.0.2-beta.2",
4
4
  "description": "modern, maintainable, modular developer tooling for FT.com projects",
5
5
  "author": "FT.com Platforms Team <platforms-team.customer-products@ft.com>",
6
6
  "license": "MIT",
7
7
  "repository": {
8
8
  "type": "git",
9
9
  "url": "https://github.com/financial-times/dotcom-tool-kit.git",
10
- "directory": "packages/cli"
10
+ "directory": "core/cli"
11
11
  },
12
12
  "homepage": "https://github.com/financial-times/dotcom-tool-kit",
13
13
  "bugs": "https://github.com/financial-times/dotcom-tool-kit/issues",
@@ -17,22 +17,24 @@
17
17
  "dotcom-tool-kit": "./bin/run"
18
18
  },
19
19
  "scripts": {
20
- "test": "jest --silent"
20
+ "test": "cd ../../ ; npx jest --silent --projects core/cli"
21
21
  },
22
22
  "devDependencies": {
23
- "@dotcom-tool-kit/task": "file:../task",
24
- "@jest/globals": "^26.6.2",
23
+ "@jest/globals": "^27.4.6",
25
24
  "@types/lodash.mergewith": "^4.6.6",
25
+ "@types/node": "^12.20.24",
26
26
  "chai": "^4.3.4",
27
27
  "globby": "^10.0.2",
28
- "jest": "^26.6.3",
29
- "ts-jest": "^26.5.6",
30
- "ts-node": "^8.10.2"
28
+ "ts-node": "^8.10.2",
29
+ "winston": "^3.5.1"
31
30
  },
32
31
  "dependencies": {
33
- "@dotcom-tool-kit/error": "^1.0.0-beta.9",
34
- "@dotcom-tool-kit/wait-for-ok": "^1.0.0-beta.9",
35
- "ansi-colors": "^4.1.1",
32
+ "@dotcom-tool-kit/error": "^1.0.2-beta.2",
33
+ "@dotcom-tool-kit/hook": "^1.0.2-beta.2",
34
+ "@dotcom-tool-kit/logger": "^1.0.2-beta.2",
35
+ "@dotcom-tool-kit/options": "^1.0.2-beta.2",
36
+ "@dotcom-tool-kit/types": "^1.0.2-beta.2",
37
+ "@dotcom-tool-kit/wait-for-ok": "^1.0.2-beta.2",
36
38
  "cosmiconfig": "^7.0.0",
37
39
  "import-from": "^3.0.0",
38
40
  "lodash.mergewith": "^4.6.2",
@@ -47,5 +49,8 @@
47
49
  "/bin",
48
50
  "/lib",
49
51
  "/npm-shrinkwrap.json"
50
- ]
52
+ ],
53
+ "volta": {
54
+ "extends": "../../package.json"
55
+ }
51
56
  }