dotcom-tool-kit 1.0.0 → 1.2.1

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
@@ -2,33 +2,42 @@
2
2
 
3
3
  const c = require('ansi-colors')
4
4
  const argv = require('minimist')(process.argv.slice(2), {
5
- boolean: ['help', 'install']
5
+ boolean: ['help', 'install'],
6
+ '--': true
6
7
  })
7
8
 
8
9
  const { runTasks, showHelp, installHooks } = require('../lib')
9
10
  const { styles } = require('../lib/messages')
10
11
 
11
12
  async function main() {
12
- try {
13
- if(argv.install) {
14
- await installHooks()
15
- } else if(argv.help || argv._.length === 0) {
16
- await showHelp(argv._)
13
+ try {
14
+ if (argv.install) {
15
+ await installHooks()
16
+ } else if (argv.help || argv._.length === 0) {
17
+ await showHelp(argv._)
18
+ } else {
19
+ if (argv['--'].length > 0) {
20
+ // The `--` in a command such as `dotcom-tool-kit test:staged --`
21
+ // delineates between hooks and file patterns. For example, when the
22
+ // lint-staged task is run it will identify the files that are staged
23
+ // and match its glob patterns and append them to the command, so that
24
+ // the command becomes something like `dotcom-tool-kit test:staged --
25
+ // index.js`. When this command is executed it runs the configured task
26
+ // where the file path arguments would then be extracted.
27
+ await runTasks(argv._, argv['--'])
17
28
  } 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)
29
+ await runTasks(argv._)
28
30
  }
31
+ }
32
+ } catch (error) {
33
+ if (error.details) {
34
+ console.error(styles.error(error.message) + '\n\n' + error.details)
35
+ } else {
36
+ console.error(error.stack)
37
+ }
29
38
 
30
- process.exitCode = error.exitCode || 1
31
- }
39
+ process.exitCode = error.exitCode || 1
40
+ }
32
41
  }
33
42
 
34
43
  main()
package/lib/config.d.ts CHANGED
@@ -1,7 +1,6 @@
1
- import type { TaskClass } from '@dotcom-tool-kit/task';
2
- import type { HookTask, HookClass } from './hook';
3
- import { Plugin } from './plugin';
1
+ import type { HookTask } from './hook';
4
2
  import { Conflict } from './conflict';
3
+ import type { TaskClass, Hook, Plugin } from '@dotcom-tool-kit/types';
5
4
  export interface PluginOptions {
6
5
  options: Record<string, unknown>;
7
6
  plugin: Plugin;
@@ -22,7 +21,7 @@ export interface Config {
22
21
  [id: string]: PluginOptions | Conflict<PluginOptions> | undefined;
23
22
  };
24
23
  hooks: {
25
- [id: string]: HookClass | Conflict<HookClass>;
24
+ [id: string]: Hook | Conflict<Hook>;
26
25
  };
27
26
  }
28
27
  export interface ValidConfig extends Config {
@@ -36,18 +35,15 @@ export interface ValidConfig extends Config {
36
35
  [id: string]: PluginOptions;
37
36
  };
38
37
  hooks: {
39
- [id: string]: HookClass;
38
+ [id: string]: Hook;
40
39
  };
41
40
  }
42
- export declare function validateConfig(config: Config, { checkInstall }?: {
43
- checkInstall?: boolean | undefined;
44
- }): Promise<ValidConfig>;
41
+ export declare function validateConfig(config: Config): Promise<ValidConfig>;
42
+ export declare function checkInstall(config: ValidConfig): Promise<void>;
45
43
  export declare function loadConfig(options?: {
46
44
  validate?: true;
47
- checkInstall?: boolean;
48
45
  }): Promise<ValidConfig>;
49
46
  export declare function loadConfig(options?: {
50
47
  validate?: false;
51
- checkInstall?: boolean;
52
48
  }): Promise<Config>;
53
49
  //# 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,CA2FvG;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":"AAEA,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,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;AAC/E,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA"}
package/lib/config.js CHANGED
@@ -1,6 +1,6 @@
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
5
  const path_1 = (0, tslib_1.__importDefault)(require("path"));
6
6
  const plugin_1 = require("./plugin");
@@ -20,7 +20,7 @@ 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 } = {}) {
23
+ async function validateConfig(config) {
24
24
  const hookTaskConflicts = (0, conflict_1.findConflicts)(Object.values(config.hookTasks));
25
25
  const hookConflicts = (0, conflict_1.findConflicts)(Object.values(config.hooks));
26
26
  const taskConflicts = (0, conflict_1.findConflicts)(Object.values(config.tasks));
@@ -53,7 +53,6 @@ async function validateConfig(config, { checkInstall = true } = {}) {
53
53
  }
54
54
  }
55
55
  const configuredHookTasks = (0, conflict_1.withoutConflicts)(Object.values(config.hookTasks));
56
- const definedHooks = (0, conflict_1.withoutConflicts)(Object.values(config.hooks));
57
56
  const definedHookIds = new Set(Object.keys(config.hooks));
58
57
  const undefinedHookTasks = configuredHookTasks.filter((hookTask) => {
59
58
  // we only care about undefined hooks that were configured by the app, not default config from plugins
@@ -65,6 +64,13 @@ async function validateConfig(config, { checkInstall = true } = {}) {
65
64
  shouldThrow = true;
66
65
  error.details += (0, messages_1.formatUndefinedHookTasks)(undefinedHookTasks, Array.from(definedHookIds));
67
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));
73
+ }
68
74
  const missingTasks = configuredHookTasks
69
75
  .map((hook) => ({
70
76
  hook,
@@ -75,28 +81,34 @@ async function validateConfig(config, { checkInstall = true } = {}) {
75
81
  shouldThrow = true;
76
82
  error.details += (0, messages_1.formatMissingTasks)(missingTasks, Object.keys(config.tasks));
77
83
  }
78
- if (checkInstall) {
79
- const uninstalledHooks = await asyncFilter(definedHooks, async (Hook) => {
80
- const hook = new Hook();
81
- return !(await hook.check());
82
- });
83
- if (uninstalledHooks.length > 0) {
84
- shouldThrow = true;
85
- error.details += (0, messages_1.formatUninstalledHooks)(uninstalledHooks);
86
- }
87
- }
88
84
  if (shouldThrow) {
89
85
  throw error;
90
86
  }
91
87
  return config;
92
88
  }
93
89
  exports.validateConfig = validateConfig;
94
- 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({ validate = true } = {}) {
95
103
  // start loading config and child plugins, starting from the consumer app directory
96
104
  const config = await (0, plugin_1.loadPluginConfig)({
97
105
  id: 'app root',
98
106
  root: process.cwd()
99
107
  }, createConfig());
100
- return validate ? validateConfig(config, { checkInstall }) : config;
108
+ return validate ? validateConfig(config) : config;
101
109
  }
102
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.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":"AAIA,wBAA8B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmErE"}
package/lib/help.js CHANGED
@@ -1,12 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const config_1 = require("./config");
4
+ const options_1 = require("@dotcom-tool-kit/options");
4
5
  const messages_1 = require("./messages");
5
6
  async function showHelp(hooks) {
6
7
  const config = await (0, config_1.loadConfig)();
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
18
  console.log(`
12
19
  🧰 ${messages_1.styles.title(`welcome to ${messages_1.styles.app('Tool Kit')}!`)}
@@ -16,16 +23,19 @@ Tool Kit is modern, maintainable & modular developer tooling for FT.com projects
16
23
  ${messages_1.styles.URL('https://github.com/financial-times/dotcom-tool-kit')}
17
24
 
18
25
  ${messages_1.styles.ruler()}
19
- ${Object.keys(config.hooks).length === 0 ? `there are no hooks available. you'll need to install plugins that define hooks to be able to run Tool Kit tasks.` : messages_1.styles.dim(hooks.length === 0
20
- ? 'available hooks'
21
- : `help for ${hooks.length - missingHooks.length} ${hooks.length - missingHooks.length > 1 ? 'hooks' : 'hook'}`)}:
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
+ : messages_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];
36
+ /* eslint-disable @typescript-eslint/no-explicit-any -- Object.constructor does not consider static properties */
27
37
  console.log(`${messages_1.styles.heading(hook)}
28
- ${Hook.description ? Hook.description + '\n' : ''}
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
@@ -34,6 +44,7 @@ ${tasks.tasks
34
44
  : messages_1.styles.dim('no tasks configured to run on this hook.')}
35
45
  ${messages_1.styles.ruler()}
36
46
  `);
47
+ /*eslint-enable @typescript-eslint/no-explicit-any */
37
48
  }
38
49
  }
39
50
  if (missingHooks.length) {
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,4 @@
1
- export declare function runTasks(hooks: string[]): Promise<void>;
1
+ export declare function runTasks(hooks: string[], files?: string[]): Promise<void>;
2
2
  export { default as showHelp } from './help';
3
3
  export { default as installHooks } from './install';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAsE7D;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":"AAYA,wBAAsB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8E/E;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
@@ -7,8 +7,8 @@ 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
9
  const messages_1 = require("./messages");
10
- async function runTasks(hooks) {
11
- var _a;
10
+ const options_1 = require("@dotcom-tool-kit/options");
11
+ async function runTasks(hooks, files) {
12
12
  const config = await (0, config_1.loadConfig)();
13
13
  const availableHooks = Object.keys(config.hooks)
14
14
  .sort()
@@ -23,6 +23,12 @@ 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) {
27
33
  const errors = [];
28
34
  if (!config.hookTasks[hook]) {
@@ -32,13 +38,13 @@ ${availableHooks}`;
32
38
  const assignment = config.hookTasks[hook];
33
39
  for (const id of assignment.tasks) {
34
40
  const Task = config.tasks[id];
35
- 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) : {};
36
42
  // `Task` is an abstract class. here we know it's a concrete subclass
37
43
  // but typescript doesn't, so cast it to any.
38
44
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
39
45
  const task = new Task(options);
40
46
  try {
41
- await task.run();
47
+ await task.run(files);
42
48
  }
43
49
  catch (error) {
44
50
  // allow subsequent hook tasks to run on error
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAc,MAAM,UAAU,CAAA;AAE7C,wBAA8B,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CA+B5D"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAc,MAAM,UAAU,CAAA;AAE7C,wBAA8B,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAmC5D"}
package/lib/install.js CHANGED
@@ -1,15 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const error_1 = require("@dotcom-tool-kit/error");
4
+ const options_1 = require("@dotcom-tool-kit/options");
4
5
  const config_1 = require("./config");
5
6
  async function installHooks() {
6
- const config = await (0, config_1.loadConfig)({ checkInstall: false });
7
- const tasks = Object.values(config.hooks).map((Hook) => async () => {
8
- const hook = new Hook();
7
+ const config = await (0, config_1.loadConfig)();
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 {
package/lib/messages.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import colours from 'ansi-colors';
2
2
  import type { PluginOptions } from './config';
3
3
  import type { Conflict } from './conflict';
4
- import type { HookTask, HookClass } from './hook';
5
- import type { TaskClass } from '@dotcom-tool-kit/task';
4
+ import type { HookTask } from './hook';
5
+ import type { Hook, TaskClass } from '@dotcom-tool-kit/types';
6
6
  declare const s: {
7
7
  hook: colours.StyleFunction;
8
8
  task: colours.StyleFunction;
@@ -21,11 +21,12 @@ declare const s: {
21
21
  };
22
22
  export { s as styles };
23
23
  export declare const formatTaskConflicts: (conflicts: Conflict<TaskClass>[]) => string;
24
- export declare const formatHookConflicts: (conflicts: Conflict<HookClass>[]) => string;
24
+ export declare const formatHookConflicts: (conflicts: Conflict<Hook>[]) => string;
25
25
  export declare const formatHookTaskConflicts: (conflicts: Conflict<HookTask>[]) => string;
26
26
  export declare const formatOptionConflicts: (conflicts: Conflict<PluginOptions>[]) => string;
27
27
  export declare const formatUndefinedHookTasks: (undefinedHooks: HookTask[], definedHooks: string[]) => string;
28
- export declare const formatUninstalledHooks: (uninstalledHooks: HookClass[]) => string;
28
+ export declare const formatUnusedOptions: (unusedOptions: string[], definedPlugins: string[]) => string;
29
+ export declare const formatUninstalledHooks: (uninstalledHooks: Hook[]) => string;
29
30
  declare type Missing = {
30
31
  hook: HookTask;
31
32
  tasks: string[];
@@ -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;;;;;;;;;;;;oBAYW,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,MAWF,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,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,MAAM,QAAQ,CAAA;AACtC,OAAO,KAAK,EAAU,IAAI,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAIrE,QAAA,MAAM,CAAC;;;;;;;;;;;;oBAYW,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,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,6 +1,6 @@
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;
3
+ exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUnusedOptions = exports.formatUndefinedHookTasks = exports.formatOptionConflicts = exports.formatHookTaskConflicts = exports.formatHookConflicts = exports.formatTaskConflicts = exports.styles = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const ansi_colors_1 = (0, tslib_1.__importDefault)(require("ansi-colors"));
6
6
  // consistent styling use cases for terminal colours
@@ -72,6 +72,17 @@ ${definedHooks.length > 0
72
72
  : `There are no hooks defined by this app's plugins. You probably need to install some plugins to define hooks.`}.
73
73
  `;
74
74
  exports.formatUndefinedHookTasks = formatUndefinedHookTasks;
75
+ const formatUnusedOptions = (unusedOptions, definedPlugins) => `Options are defined in your Tool Kit configuration for plugins that don't exist:
76
+
77
+ ${unusedOptions.map((optionName) => `- ${s.plugin(optionName)}`).join('\n')}
78
+
79
+ They could be misspelt, or defined by a Tool Kit plugin that isn't installed in this app.
80
+
81
+ ${definedPlugins.length > 0
82
+ ? `Plugins that are defined and can have options set are: ${definedPlugins.map(s.plugin).join(', ')}`
83
+ : `There are no plugins installed currently. You'll need to install some plugins before options can be set.`}.
84
+ `;
85
+ exports.formatUnusedOptions = formatUnusedOptions;
75
86
  const formatUninstalledHooks = (uninstalledHooks) => `These hooks aren't installed into your app:
76
87
 
77
88
  ${uninstalledHooks.map((hook) => `- ${s.hook(hook.id || 'unknown event')}`).join('\n')}
package/lib/plugin.d.ts CHANGED
@@ -1,15 +1,5 @@
1
- import type { TaskClass } from '@dotcom-tool-kit/task';
2
- import type { HookClass } from './hook';
3
1
  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
- }
2
+ import { Plugin } from '@dotcom-tool-kit/types';
13
3
  export declare function loadPluginConfig(plugin: Plugin, config: Config): Promise<Config>;
14
4
  export declare function loadPlugin(id: string, config: Config, parent?: Plugin): Promise<Plugin>;
15
5
  export declare function loadPlugins(plugins: string[], config: Config, parent?: Plugin): Promise<Plugin[]>;
@@ -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":"AAKA,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,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,CAkF7F;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEjG"}
package/lib/plugin.js CHANGED
@@ -6,7 +6,10 @@ const import_from_1 = (0, tslib_1.__importDefault)(require("import-from"));
6
6
  const resolve_from_1 = (0, tslib_1.__importDefault)(require("resolve-from"));
7
7
  const lodash_mergewith_1 = (0, tslib_1.__importDefault)(require("lodash.mergewith"));
8
8
  const conflict_1 = require("./conflict");
9
+ const messages_1 = require("./messages");
9
10
  const rc_file_1 = require("./rc-file");
11
+ const error_1 = require("@dotcom-tool-kit/error");
12
+ const types_1 = require("@dotcom-tool-kit/types");
10
13
  async function loadPluginConfig(plugin, config) {
11
14
  const { plugins = [], hooks = {}, options = {} } = await (0, rc_file_1.loadToolKitRC)(plugin.root);
12
15
  // load any plugins requested by this plugin
@@ -80,7 +83,17 @@ async function loadPlugin(id, config, parent) {
80
83
  const root = parent ? parent.root : process.cwd();
81
84
  // load plugin relative to the parent plugin
82
85
  const pluginRoot = (0, resolve_from_1.default)(root, id);
83
- const basePlugin = (0, import_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);
90
+ }
91
+ catch (error) {
92
+ if (error instanceof error_1.ToolKitError) {
93
+ error.details = `the package ${messages_1.styles.plugin(id)} at ${messages_1.styles.filepath(pluginRoot)} is not a valid plugin`;
94
+ }
95
+ throw error;
96
+ }
84
97
  const plugin = {
85
98
  ...basePlugin,
86
99
  id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotcom-tool-kit",
3
- "version": "1.0.0",
3
+ "version": "1.2.1",
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",
@@ -20,7 +20,6 @@
20
20
  "test": "cd ../../ ; npx jest --silent --projects packages/cli"
21
21
  },
22
22
  "devDependencies": {
23
- "@dotcom-tool-kit/task": "file:../task",
24
23
  "@jest/globals": "^26.6.2",
25
24
  "@types/lodash.mergewith": "^4.6.6",
26
25
  "@types/node": "^12.20.24",
@@ -29,8 +28,11 @@
29
28
  "ts-node": "^8.10.2"
30
29
  },
31
30
  "dependencies": {
32
- "@dotcom-tool-kit/error": "^1.0.0",
33
- "@dotcom-tool-kit/wait-for-ok": "^1.0.0",
31
+ "@dotcom-tool-kit/error": "^1.2.1",
32
+ "@dotcom-tool-kit/hook": "^1.2.1",
33
+ "@dotcom-tool-kit/options": "^1.2.1",
34
+ "@dotcom-tool-kit/types": "^1.2.1",
35
+ "@dotcom-tool-kit/wait-for-ok": "^1.2.1",
34
36
  "ansi-colors": "^4.1.1",
35
37
  "cosmiconfig": "^7.0.0",
36
38
  "import-from": "^3.0.0",