dotcom-tool-kit 3.5.0 → 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.
Files changed (77) hide show
  1. package/bin/run +11 -1
  2. package/lib/config/hash.d.ts +6 -0
  3. package/lib/config/hash.d.ts.map +1 -0
  4. package/lib/config/hash.js +43 -0
  5. package/lib/config/validate-plugins.d.ts +4 -0
  6. package/lib/config/validate-plugins.d.ts.map +1 -0
  7. package/lib/config/validate-plugins.js +9 -0
  8. package/lib/config.d.ts +2 -54
  9. package/lib/config.d.ts.map +1 -1
  10. package/lib/config.js +62 -113
  11. package/lib/fetch.d.ts +2 -0
  12. package/lib/fetch.d.ts.map +1 -0
  13. package/lib/fetch.js +19 -0
  14. package/lib/help.d.ts +1 -1
  15. package/lib/help.d.ts.map +1 -1
  16. package/lib/help.js +72 -39
  17. package/lib/index.d.ts +3 -4
  18. package/lib/index.d.ts.map +1 -1
  19. package/lib/index.js +12 -99
  20. package/lib/init.d.ts +4 -0
  21. package/lib/init.d.ts.map +1 -0
  22. package/lib/init.js +16 -0
  23. package/lib/install.d.ts +6 -1
  24. package/lib/install.d.ts.map +1 -1
  25. package/lib/install.js +69 -13
  26. package/lib/messages.d.ts +14 -13
  27. package/lib/messages.d.ts.map +1 -1
  28. package/lib/messages.js +38 -27
  29. package/lib/plugin/entry-point.d.ts +7 -0
  30. package/lib/plugin/entry-point.d.ts.map +1 -0
  31. package/lib/plugin/entry-point.js +46 -0
  32. package/lib/plugin/is-descendent.d.ts +3 -0
  33. package/lib/plugin/is-descendent.d.ts.map +1 -0
  34. package/lib/plugin/is-descendent.js +15 -0
  35. package/lib/plugin/merge-commands.d.ts +5 -0
  36. package/lib/plugin/merge-commands.d.ts.map +1 -0
  37. package/lib/plugin/merge-commands.js +59 -0
  38. package/lib/plugin/merge-hooks.d.ts +4 -0
  39. package/lib/plugin/merge-hooks.d.ts.map +1 -0
  40. package/lib/plugin/merge-hooks.js +29 -0
  41. package/lib/plugin/merge-inits.d.ts +4 -0
  42. package/lib/plugin/merge-inits.d.ts.map +1 -0
  43. package/lib/plugin/merge-inits.js +13 -0
  44. package/lib/plugin/merge-plugin-options.d.ts +4 -0
  45. package/lib/plugin/merge-plugin-options.d.ts.map +1 -0
  46. package/lib/plugin/merge-plugin-options.js +46 -0
  47. package/lib/plugin/merge-task-options.d.ts +4 -0
  48. package/lib/plugin/merge-task-options.d.ts.map +1 -0
  49. package/lib/plugin/merge-task-options.js +43 -0
  50. package/lib/plugin/merge-tasks.d.ts +4 -0
  51. package/lib/plugin/merge-tasks.d.ts.map +1 -0
  52. package/lib/plugin/merge-tasks.js +27 -0
  53. package/lib/plugin/options.d.ts +7 -0
  54. package/lib/plugin/options.d.ts.map +1 -0
  55. package/lib/plugin/options.js +170 -0
  56. package/lib/plugin/reduce-installations.d.ts +7 -0
  57. package/lib/plugin/reduce-installations.d.ts.map +1 -0
  58. package/lib/plugin/reduce-installations.js +59 -0
  59. package/lib/plugin.d.ts +4 -3
  60. package/lib/plugin.d.ts.map +1 -1
  61. package/lib/plugin.js +56 -217
  62. package/lib/rc-file.d.ts +4 -9
  63. package/lib/rc-file.d.ts.map +1 -1
  64. package/lib/rc-file.js +80 -20
  65. package/lib/tasks.d.ts +3 -0
  66. package/lib/tasks.d.ts.map +1 -0
  67. package/lib/tasks.js +92 -0
  68. package/package.json +28 -22
  69. package/lib/conflict.d.ts +0 -9
  70. package/lib/conflict.d.ts.map +0 -1
  71. package/lib/conflict.js +0 -27
  72. package/lib/hook.d.ts +0 -7
  73. package/lib/hook.d.ts.map +0 -1
  74. package/lib/hook.js +0 -2
  75. package/lib/postInstall.d.ts +0 -7
  76. package/lib/postInstall.d.ts.map +0 -1
  77. package/lib/postInstall.js +0 -53
package/lib/index.js CHANGED
@@ -1,102 +1,14 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.installHooks = exports.showHelp = exports.listPlugins = exports.runTasks = exports.shouldDisableNativeFetch = void 0;
7
- const error_1 = require("@dotcom-tool-kit/error");
3
+ exports.printConfig = exports.listPlugins = exports.shouldDisableNativeFetch = exports.runTasks = void 0;
4
+ const tslib_1 = require("tslib");
8
5
  const config_1 = require("./config");
9
- const options_1 = require("@dotcom-tool-kit/options");
10
- const logger_1 = require("@dotcom-tool-kit/logger");
6
+ const util_1 = tslib_1.__importDefault(require("util"));
11
7
  const messages_1 = require("./messages");
12
- // function that plugins can check if they need to implement their own logic to
13
- // disable Node 18's native fetch
14
- const shouldDisableNativeFetch = () => {
15
- // disable Node 18's native fetch if the Node runtime supports it (older
16
- // runtimes don't support the flag, implying they also don't use native
17
- // fetch) and the user hasn't opted out of the behaviour
18
- return (
19
- /* eslint-disable-next-line @typescript-eslint/no-non-null-assertion --
20
- * the root plugin has default options and it always exists so is always
21
- * defined
22
- **/
23
- !(0, options_1.getOptions)('app root').allowNativeFetch &&
24
- process.allowedNodeEnvironmentFlags.has('--no-experimental-fetch'));
25
- };
26
- exports.shouldDisableNativeFetch = shouldDisableNativeFetch;
27
- async function runTasks(logger, hooks, files) {
28
- const config = await (0, config_1.loadConfig)(logger);
29
- const availableHooks = Object.keys(config.hooks)
30
- .sort()
31
- .map((id) => `- ${id}`)
32
- .join('\n');
33
- const missingHooks = hooks.filter((id) => !config.hooks[id]);
34
- if (missingHooks.length > 0) {
35
- const error = new error_1.ToolKitError(`hooks ${missingHooks} do not exist`);
36
- error.details = `maybe you need to install a plugin to handle these hooks, or configure them in your Tool Kit configuration.
37
-
38
- hooks that are available are:
39
- ${availableHooks}`;
40
- throw error;
41
- }
42
- for (const pluginOptions of Object.values(config.options)) {
43
- if (pluginOptions.forPlugin) {
44
- (0, options_1.setOptions)(pluginOptions.forPlugin.id, pluginOptions.options);
45
- }
46
- }
47
- await (0, config_1.checkInstall)(config);
48
- if ((0, exports.shouldDisableNativeFetch)()) {
49
- process.execArgv.push('--no-experimental-fetch');
50
- }
51
- for (const hook of hooks) {
52
- const errors = [];
53
- if (!config.hookTasks[hook]) {
54
- logger.warn(`no task configured for ${hook}: skipping assignment...`);
55
- continue;
56
- }
57
- const assignment = config.hookTasks[hook];
58
- for (const id of assignment.tasks) {
59
- const Task = config.tasks[id];
60
- const options = Task.plugin ? (0, options_1.getOptions)(Task.plugin.id) : {};
61
- /* eslint-disable-next-line @typescript-eslint/no-explicit-any --
62
- * `Task` is an abstract class. Here we know it's a concrete subclass
63
- * but typescript doesn't, so cast it to any.
64
- **/
65
- const task = new Task(logger, options);
66
- logger.info(logger_1.styles.taskHeader(`running ${logger_1.styles.task(id)} task`));
67
- try {
68
- await task.run(files);
69
- }
70
- catch (error) {
71
- // if there's an exit code, that's a request from the task to exit early
72
- if (error instanceof error_1.ToolKitError && error.exitCode) {
73
- throw error;
74
- }
75
- // if not, we allow subsequent hook tasks to run on error
76
- errors.push({
77
- hook,
78
- task: id,
79
- error: error
80
- });
81
- }
82
- }
83
- if (errors.length > 0) {
84
- const error = new error_1.ToolKitError(`error running tasks for ${logger_1.styles.hook(hook)}`);
85
- error.details = errors
86
- .map(({ task, error }) => `${logger_1.styles.heading(`${logger_1.styles.task(task)}:`)}
87
-
88
- ${error.message}${error instanceof error_1.ToolKitError
89
- ? `
90
-
91
- ${error.details}`
92
- : ''}`)
93
- .join(`${logger_1.styles.dim(logger_1.styles.ruler())}\n`);
94
- error.exitCode = errors.length + 1;
95
- throw error;
96
- }
97
- }
98
- }
99
- exports.runTasks = runTasks;
8
+ var tasks_1 = require("./tasks");
9
+ Object.defineProperty(exports, "runTasks", { enumerable: true, get: function () { return tasks_1.runTasks; } });
10
+ var fetch_1 = require("./fetch");
11
+ Object.defineProperty(exports, "shouldDisableNativeFetch", { enumerable: true, get: function () { return fetch_1.shouldDisableNativeFetch; } });
100
12
  async function listPlugins(logger) {
101
13
  const config = await (0, config_1.loadConfig)(logger, { validate: false });
102
14
  const rootPlugin = config.plugins['app root'];
@@ -105,7 +17,8 @@ async function listPlugins(logger) {
105
17
  }
106
18
  }
107
19
  exports.listPlugins = listPlugins;
108
- var help_1 = require("./help");
109
- Object.defineProperty(exports, "showHelp", { enumerable: true, get: function () { return __importDefault(help_1).default; } });
110
- var install_1 = require("./install");
111
- Object.defineProperty(exports, "installHooks", { enumerable: true, get: function () { return __importDefault(install_1).default; } });
20
+ async function printConfig(logger) {
21
+ const config = await (0, config_1.loadConfig)(logger, { validate: false });
22
+ logger.info(util_1.default.inspect(config, { depth: null, colors: true }));
23
+ }
24
+ exports.printConfig = printConfig;
package/lib/init.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { ValidConfig } from '@dotcom-tool-kit/config';
2
+ import type { Logger } from 'winston';
3
+ export declare function runInit(logger: Logger, config: ValidConfig): Promise<void>;
4
+ //# 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,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAG1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAWrC,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAKhF"}
package/lib/init.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runInit = void 0;
4
+ const base_1 = require("@dotcom-tool-kit/base");
5
+ const validated_1 = require("@dotcom-tool-kit/validated");
6
+ const entry_point_1 = require("./plugin/entry-point");
7
+ const loadInitEntrypoints = async (logger, config) => {
8
+ const initClassResults = (0, validated_1.reduceValidated)(await Promise.all(config.inits.map((entryPoint) => (0, entry_point_1.importEntryPoint)(base_1.Init, entryPoint))));
9
+ return initClassResults.map((initClasses) => initClasses.map((initClass) => new initClass(logger)));
10
+ };
11
+ async function runInit(logger, config) {
12
+ const initResults = await loadInitEntrypoints(logger, config);
13
+ const inits = initResults.unwrap('plugin initialisation classes were invalid!');
14
+ await Promise.all(inits.map(async (init) => init.init()));
15
+ }
16
+ exports.runInit = runInit;
package/lib/install.d.ts CHANGED
@@ -1,4 +1,9 @@
1
+ import type { z } from 'zod';
1
2
  import type { Logger } from 'winston';
2
- import { ValidConfig } from './config';
3
+ import type { ValidConfig } from '@dotcom-tool-kit/config';
4
+ import { Hook } from '@dotcom-tool-kit/base';
5
+ import { Validated } from '@dotcom-tool-kit/validated';
6
+ export declare const loadHookInstallations: (logger: Logger, config: ValidConfig) => Promise<Validated<Hook<z.ZodType, unknown>[]>>;
7
+ export declare function checkInstall(logger: Logger, config: ValidConfig): Promise<void>;
3
8
  export default function installHooks(logger: Logger): Promise<ValidConfig>;
4
9
  //# sourceMappingURL=install.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAc,WAAW,EAAE,MAAM,UAAU,CAAA;AAalD,wBAA8B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAyD/E"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAI5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGrC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,IAAI,EAAa,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,SAAS,EAAmC,MAAM,4BAA4B,CAAA;AAyCvF,eAAO,MAAM,qBAAqB,WACxB,MAAM,UACN,WAAW,KAClB,QAAQ,UAAU,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC,CA+B/C,CAAA;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBrF;AAED,wBAA8B,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAuD/E"}
package/lib/install.js CHANGED
@@ -1,12 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkInstall = exports.loadHookInstallations = void 0;
3
4
  const tslib_1 = require("tslib");
4
5
  const error_1 = require("@dotcom-tool-kit/error");
5
6
  const options_1 = require("@dotcom-tool-kit/options");
6
7
  const groupBy_1 = tslib_1.__importDefault(require("lodash/groupBy"));
7
8
  const config_1 = require("./config");
8
- const postInstall_1 = require("./postInstall");
9
- // implementation of the Array.every method that supports asynchronous predicates
9
+ const hash_1 = require("./config/hash");
10
+ const base_1 = require("@dotcom-tool-kit/base");
11
+ const validated_1 = require("@dotcom-tool-kit/validated");
12
+ const reduce_installations_1 = require("./plugin/reduce-installations");
13
+ const conflict_1 = require("@dotcom-tool-kit/conflict");
14
+ const schemas_1 = require("@dotcom-tool-kit/schemas");
15
+ const messages_1 = require("./messages");
16
+ const entry_point_1 = require("./plugin/entry-point");
17
+ const init_1 = require("./init");
18
+ // implementation of the Array#every method that supports asynchronous predicates
10
19
  async function asyncEvery(arr, pred) {
11
20
  for (const val of arr) {
12
21
  if (!(await pred(val))) {
@@ -15,21 +24,74 @@ async function asyncEvery(arr, pred) {
15
24
  }
16
25
  return true;
17
26
  }
27
+ // implementation of the Array#filter method that supports asynchronous predicates
28
+ async function asyncFilter(items, predicate) {
29
+ const results = await Promise.all(items.map(async (item) => ({ item, keep: await predicate(item) })));
30
+ return results.filter(({ keep }) => keep).map(({ item }) => item);
31
+ }
32
+ const loadHookEntrypoints = async (logger, config) => {
33
+ const hookResultEntries = (0, validated_1.reduceValidated)(await Promise.all(Object.entries(config.hooks).map(async ([hookName, entryPoint]) => {
34
+ const hookResult = await (0, entry_point_1.importEntryPoint)(base_1.Hook, entryPoint);
35
+ return hookResult.map((hookClass) => [hookName, hookClass]);
36
+ })));
37
+ return hookResultEntries.map((hookEntries) => Object.fromEntries(hookEntries));
38
+ };
39
+ const loadHookInstallations = async (logger, config) => {
40
+ const hookClassResults = await loadHookEntrypoints(logger, config);
41
+ const installationResults = await hookClassResults
42
+ .map((hookClasses) => (0, reduce_installations_1.reducePluginHookInstallations)(logger, config, hookClasses, config.plugins['app root']))
43
+ .awaitValue();
44
+ const installationsWithoutConflicts = installationResults.flatMap((installations) => {
45
+ const conflicts = (0, conflict_1.findConflicts)(installations);
46
+ if (conflicts.length) {
47
+ return (0, validated_1.invalid)(conflicts.map(
48
+ // TODO:20240429:IM format a more helpful error message here
49
+ (conflict) => `conflicts between ${conflict.conflicting.map((installation) => installation.forHook).join(', ')}`));
50
+ }
51
+ return (0, validated_1.valid)((0, conflict_1.withoutConflicts)(installations));
52
+ });
53
+ return installationsWithoutConflicts.map((installations) => {
54
+ return installations.map(({ hookConstructor, forHook, options }) => {
55
+ const schema = schemas_1.HookSchemas[forHook];
56
+ const parsedOptions = schema ? schema.parse(options) : {};
57
+ return new hookConstructor(logger, forHook, parsedOptions);
58
+ });
59
+ });
60
+ };
61
+ exports.loadHookInstallations = loadHookInstallations;
62
+ async function checkInstall(logger, config) {
63
+ if (!(await (0, hash_1.hasConfigChanged)(logger, config))) {
64
+ return;
65
+ }
66
+ const hooks = (await (0, exports.loadHookInstallations)(logger, config)).unwrap('hooks are invalid');
67
+ const uninstalledHooks = await asyncFilter(hooks, async (hook) => {
68
+ return !(await hook.isInstalled());
69
+ });
70
+ if (uninstalledHooks.length > 0) {
71
+ const error = new error_1.ToolKitError('There are problems with your Tool Kit installation.');
72
+ error.details = (0, messages_1.formatUninstalledHooks)(uninstalledHooks);
73
+ throw error;
74
+ }
75
+ await (0, hash_1.updateHashes)(config);
76
+ }
77
+ exports.checkInstall = checkInstall;
18
78
  async function installHooks(logger) {
19
79
  const config = await (0, config_1.loadConfig)(logger);
20
- for (const pluginOptions of Object.values(config.options)) {
80
+ for (const pluginOptions of Object.values(config.pluginOptions)) {
21
81
  if (pluginOptions.forPlugin) {
22
82
  (0, options_1.setOptions)(pluginOptions.forPlugin.id, pluginOptions.options);
23
83
  }
24
84
  }
85
+ await (0, init_1.runInit)(logger, config);
25
86
  const errors = [];
87
+ const hooks = (await (0, exports.loadHookInstallations)(logger, config)).unwrap('hooks are invalid');
26
88
  // group hooks without an installGroup separately so that their check()
27
89
  // method runs independently
28
- const groups = (0, groupBy_1.default)(config.hooks, (hook) => hook.installGroup ?? '__' + hook.id);
90
+ const groups = (0, groupBy_1.default)(hooks, (hook) => hook.installGroup ?? '__' + hook.id);
29
91
  for (const group of Object.values(groups)) {
30
92
  try {
31
- const allChecksPassed = await asyncEvery(group, (hook) => hook.check());
32
- if (!allChecksPassed) {
93
+ const allHooksInstalled = await asyncEvery(group, (hook) => hook.isInstalled());
94
+ if (!allHooksInstalled) {
33
95
  let state = undefined;
34
96
  for (const hook of group) {
35
97
  state = await hook.install(state);
@@ -58,18 +120,12 @@ async function installHooks(logger) {
58
120
  }
59
121
  }
60
122
  }
61
- // HACK: achieve backwards compatibility with older versions of the circleci
62
- // plugin that required a postinstall function to run instead of the new
63
- // commitInstall method. remove in major update of cli.
64
- const usesNewCircleCIGroup = Object.keys(groups).includes('circleci');
65
- if (!usesNewCircleCIGroup) {
66
- await (0, postInstall_1.postInstall)(logger);
67
- }
68
123
  if (errors.length) {
69
124
  const error = new error_1.ToolKitError('could not automatically install hooks:');
70
125
  error.details = errors.map((error) => `- ${error.message}`).join('\n');
71
126
  throw error;
72
127
  }
128
+ await (0, hash_1.updateHashes)(config);
73
129
  return config;
74
130
  }
75
131
  exports.default = installHooks;
package/lib/messages.d.ts CHANGED
@@ -1,22 +1,23 @@
1
- import type { PluginOptions } from './config';
2
- import type { Conflict } from './conflict';
3
- import type { HookTask } from './hook';
4
- import type { Plugin, Hook, TaskClass } from '@dotcom-tool-kit/types';
1
+ import type { Hook } from '@dotcom-tool-kit/base';
2
+ import type { CommandTask, EntryPoint, Plugin, OptionsForPlugin, OptionsForTask } from '@dotcom-tool-kit/plugin';
5
3
  import type { z } from 'zod';
6
- export declare const formatTaskConflicts: (conflicts: Conflict<TaskClass>[]) => string;
7
- export declare const formatHookConflicts: (conflicts: Conflict<Hook<unknown>>[]) => string;
8
- export declare const formatHookTaskConflicts: (conflicts: Conflict<HookTask>[]) => string;
9
- export declare const formatOptionConflicts: (conflicts: Conflict<PluginOptions>[]) => string;
10
- export declare const formatUndefinedHookTasks: (undefinedHooks: HookTask[], definedHooks: string[]) => string;
4
+ import type { Conflict } from '@dotcom-tool-kit/conflict';
5
+ export declare const formatTaskConflicts: (conflicts: [string, Conflict<EntryPoint>][]) => string;
6
+ export declare const formatHookConflicts: (conflicts: [string, Conflict<EntryPoint>][]) => string;
7
+ export declare const formatCommandTaskConflicts: (conflicts: Conflict<CommandTask>[]) => string;
8
+ export declare const formatPluginOptionConflicts: (conflicts: Conflict<OptionsForPlugin>[]) => string;
9
+ export declare const formatTaskOptionConflicts: (conflicts: Conflict<OptionsForTask>[]) => string;
11
10
  export type InvalidOption = [string, z.ZodError];
12
11
  export declare const formatInvalidOptions: (invalidOptions: InvalidOption[]) => string;
13
- export declare const formatUnusedOptions: (unusedOptions: string[], definedPlugins: string[]) => string;
14
- export declare const formatUninstalledHooks: (uninstalledHooks: Hook<unknown>[]) => string;
12
+ export declare const formatUnusedPluginOptions: (unusedOptions: string[], definedPlugins: string[]) => string;
13
+ export declare const formatUnusedTaskOptions: (unusedOptions: string[], definedTasks: string[]) => string;
14
+ export declare const formatUninstalledHooks: (uninstalledHooks: Hook<z.ZodTypeAny, unknown>[]) => string;
15
15
  type Missing = {
16
- hook: HookTask;
17
- tasks: string[];
16
+ command: CommandTask;
17
+ tasks: OptionsForTask[];
18
18
  };
19
19
  export declare const formatMissingTasks: (missingTasks: Missing[], tasks: string[]) => string;
20
20
  export declare function formatPluginTree(plugin: Plugin): string[];
21
+ export declare const indentReasons: (reasons: string) => string;
21
22
  export {};
22
23
  //# sourceMappingURL=messages.d.ts.map
@@ -1 +1 @@
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,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AACrE,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAU5B,eAAO,MAAM,mBAAmB,cAAe,SAAS,SAAS,CAAC,EAAE,KAAG,MAKE,CAAA;AASzE,eAAO,MAAM,mBAAmB,cAAe,SAAS,KAAK,OAAO,CAAC,CAAC,EAAE,KAAG,MAKF,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,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;AAEhD,eAAO,MAAM,oBAAoB,mBACf,aAAa,EAAE,KAC9B,MAOF,CAAA;AAED,eAAO,MAAM,mBAAmB,kBACf,MAAM,EAAE,kBACP,MAAM,EAAE,KACvB,MAWF,CAAA;AAED,eAAO,MAAM,sBAAsB,qBACf,KAAK,OAAO,CAAC,EAAE,KAChC,MAKF,CAAA;AAED,KAAK,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;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../src/messages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,MAAM,EACN,gBAAgB,EAChB,cAAc,EACf,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAA;AAOzD,eAAO,MAAM,mBAAmB,cAAe,CAAC,MAAM,EAAE,SAAS,UAAU,CAAC,CAAC,EAAE,KAAG,MAKT,CAAA;AAOzE,eAAO,MAAM,mBAAmB,cAAe,CAAC,MAAM,EAAE,SAAS,UAAU,CAAC,CAAC,EAAE,KAAG,MAKT,CAAA;AAezE,eAAO,MAAM,0BAA0B,cAAe,SAAS,WAAW,CAAC,EAAE,KAAG,MAQ/E,CAAA;AAOD,eAAO,MAAM,2BAA2B,cAAe,SAAS,gBAAgB,CAAC,EAAE,KAAG,MAUrF,CAAA;AAOD,eAAO,MAAM,yBAAyB,cAAe,SAAS,cAAc,CAAC,EAAE,KAAG,MAUjF,CAAA;AAKD,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAA;AAEhD,eAAO,MAAM,oBAAoB,mBACf,aAAa,EAAE,KAC9B,MAOF,CAAA;AAED,eAAO,MAAM,yBAAyB,kBACrB,MAAM,EAAE,kBACP,MAAM,EAAE,KACvB,MAWF,CAAA;AAED,eAAO,MAAM,uBAAuB,kBACnB,MAAM,EAAE,gBACT,MAAM,EAAE,KACrB,MAWF,CAAA;AAED,eAAO,MAAM,sBAAsB,qBACf,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,KAC9C,MAKF,CAAA;AAED,KAAK,OAAO,GAAG;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,cAAc,EAAE,CAAA;CAAE,CAAA;AAOhE,eAAO,MAAM,kBAAkB,iBACf,OAAO,EAAE,SAChB,MAAM,EAAE,KACd,MAOF,CAAA;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAezD;AAED,eAAO,MAAM,aAAa,YAAa,MAAM,KAAG,MAAwC,CAAA"}
package/lib/messages.js CHANGED
@@ -1,58 +1,56 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatPluginTree = exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUnusedOptions = exports.formatInvalidOptions = exports.formatUndefinedHookTasks = exports.formatOptionConflicts = exports.formatHookTaskConflicts = exports.formatHookConflicts = exports.formatTaskConflicts = void 0;
3
+ exports.indentReasons = exports.formatPluginTree = exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUnusedTaskOptions = exports.formatUnusedPluginOptions = exports.formatInvalidOptions = exports.formatTaskOptionConflicts = exports.formatPluginOptionConflicts = exports.formatCommandTaskConflicts = exports.formatHookConflicts = exports.formatTaskConflicts = void 0;
4
4
  const logger_1 = require("@dotcom-tool-kit/logger");
5
5
  const zod_validation_error_1 = require("zod-validation-error");
6
- const formatTaskConflict = (conflict) => `- ${logger_1.styles.task(conflict.conflicting[0].id || 'unknown task')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
7
- .map((task) => logger_1.styles.plugin(task.plugin ? task.plugin.id : 'unknown plugin'))
6
+ const formatTaskConflict = ([key, conflict]) => `- ${logger_1.styles.task(key ?? 'unknown task')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
7
+ .map((entryPoint) => logger_1.styles.plugin(entryPoint.plugin.id ?? 'unknown plugin'))
8
8
  .join(logger_1.styles.dim(', '))}`;
9
9
  const formatTaskConflicts = (conflicts) => `${logger_1.styles.heading('There are multiple plugins that include the same tasks')}:
10
10
  ${conflicts.map(formatTaskConflict).join('\n')}
11
11
 
12
12
  You must resolve this conflict by removing all but one of these plugins.`;
13
13
  exports.formatTaskConflicts = formatTaskConflicts;
14
- const formatHookConflict = (conflict) => `- ${logger_1.styles.hook(conflict.conflicting[0].id || 'unknown event')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
15
- .map((task) => logger_1.styles.plugin(task.plugin ? task.plugin.id : 'unknown plugin'))
14
+ const formatHookConflict = ([key, conflict]) => `- ${logger_1.styles.hook(key ?? 'unknown hook')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
15
+ .map((entryPoint) => logger_1.styles.plugin(entryPoint.plugin.id ?? 'unknown plugin'))
16
16
  .join(logger_1.styles.dim(', '))}`;
17
17
  const formatHookConflicts = (conflicts) => `${logger_1.styles.heading('There are multiple plugins that include the same hooks')}:
18
18
  ${conflicts.map(formatHookConflict).join('\n')}
19
19
 
20
20
  You must resolve this conflict by removing all but one of these plugins.`;
21
21
  exports.formatHookConflicts = formatHookConflicts;
22
- const formatHookTaskConflict = (conflict) => `${logger_1.styles.hook(conflict.conflicting[0].id)}:
22
+ const formatCommandTaskConflict = (conflict) => `${logger_1.styles.hook(conflict.conflicting[0].id)}:
23
23
  ${conflict.conflicting
24
- .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)}`)
24
+ .map((command) => `- ${command.tasks.map((task) => logger_1.styles.task(task.task)).join(logger_1.styles.dim(', '))} ${logger_1.styles.dim('by plugin')} ${logger_1.styles.plugin(command.plugin.id)}`)
25
25
  .join('\n')}
26
26
  `;
27
- const formatHookTaskConflicts = (conflicts) => `${logger_1.styles.heading('These hooks are configured to run different tasks by multiple plugins')}:
28
- ${conflicts.map(formatHookTaskConflict).join('\n')}
29
- 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.
27
+ const formatCommandTaskConflicts = (conflicts) => `${logger_1.styles.heading('These commands are configured to run different tasks by multiple plugins')}:
28
+ ${conflicts.map(formatCommandTaskConflict).join('\n')}
29
+ You must resolve this conflict by explicitly configuring which task to run for these commands. See ${logger_1.styles.URL('https://github.com/financial-times/dotcom-tool-kit/tree/main/docs/resolving-hook-conflicts.md')} for more details.
30
30
 
31
31
  `;
32
- exports.formatHookTaskConflicts = formatHookTaskConflicts;
33
- const formatOptionConflict = (conflict) => `${logger_1.styles.plugin(conflict.conflicting[0].forPlugin.id)}, configured by:
32
+ exports.formatCommandTaskConflicts = formatCommandTaskConflicts;
33
+ const formatPluginOptionConflict = (conflict) => `${logger_1.styles.plugin(conflict.conflicting[0].forPlugin.id)}, configured by:
34
34
  ${conflict.conflicting.map((option) => `- ${logger_1.styles.plugin(option.plugin.id)}`)}`;
35
- const formatOptionConflicts = (conflicts) => `${logger_1.styles.heading('These plugins have conflicting options')}:
35
+ const formatPluginOptionConflicts = (conflicts) => `${logger_1.styles.heading('These plugins have conflicting options')}:
36
36
 
37
- ${conflicts.map(formatOptionConflict).join('\n')}
37
+ ${conflicts.map(formatPluginOptionConflict).join('\n')}
38
38
 
39
39
  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.
40
40
 
41
41
  `;
42
- exports.formatOptionConflicts = formatOptionConflicts;
43
- const formatPlugin = (plugin) => plugin.id === 'app root' ? logger_1.styles.app('your app') : `plugin ${logger_1.styles.plugin(plugin.id)}`;
44
- // TODO text similarity "did you mean...?"
45
- 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:
42
+ exports.formatPluginOptionConflicts = formatPluginOptionConflicts;
43
+ const formatTaskOptionConflict = (conflict) => `${logger_1.styles.task(conflict.conflicting[0].task)}, configured by:
44
+ ${conflict.conflicting.map((option) => `- ${logger_1.styles.plugin(option.plugin.id)}`)}`;
45
+ const formatTaskOptionConflicts = (conflicts) => `${logger_1.styles.heading('These tasks have conflicting options')}:
46
46
 
47
- ${undefinedHooks.map((hook) => `- ${logger_1.styles.hook(hook.id)}`).join('\n')}
47
+ ${conflicts.map(formatTaskOptionConflict).join('\n')}
48
48
 
49
- They could be misspelt, or defined by a Tool Kit plugin that isn't installed in this app.
49
+ You must resolve this conflict by providing options in your app's Tool Kit configuration for these tasks, 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.
50
50
 
51
- ${definedHooks.length > 0
52
- ? `Hooks that are defined and available for tasks are: ${definedHooks.map(logger_1.styles.hook).join(', ')}`
53
- : `There are no hooks defined by this app's plugins. You probably need to install some plugins to define hooks.`}.
54
51
  `;
55
- exports.formatUndefinedHookTasks = formatUndefinedHookTasks;
52
+ exports.formatTaskOptionConflicts = formatTaskOptionConflicts;
53
+ const formatPlugin = (plugin) => plugin.id === 'app root' ? logger_1.styles.app('your app') : `plugin ${logger_1.styles.plugin(plugin.id)}`;
56
54
  const formatInvalidOptions = (invalidOptions) => `Options are defined in your Tool Kit configuration that are the wrong types:
57
55
 
58
56
  ${invalidOptions
@@ -62,7 +60,7 @@ ${invalidOptions
62
60
  Please update the options so that they are the expected types. You can refer to the README for the plugin for examples and descriptions of the options used.
63
61
  `;
64
62
  exports.formatInvalidOptions = formatInvalidOptions;
65
- const formatUnusedOptions = (unusedOptions, definedPlugins) => `Options are defined in your Tool Kit configuration for plugins that don't exist:
63
+ const formatUnusedPluginOptions = (unusedOptions, definedPlugins) => `Options are defined in your Tool Kit configuration for plugins that don't exist:
66
64
 
67
65
  ${unusedOptions.map((optionName) => `- ${logger_1.styles.plugin(optionName)}`).join('\n')}
68
66
 
@@ -72,7 +70,18 @@ ${definedPlugins.length > 0
72
70
  ? `Plugins that are defined and can have options set are: ${definedPlugins.map(logger_1.styles.plugin).join(', ')}`
73
71
  : `There are no plugins installed currently. You'll need to install some plugins before options can be set.`}.
74
72
  `;
75
- exports.formatUnusedOptions = formatUnusedOptions;
73
+ exports.formatUnusedPluginOptions = formatUnusedPluginOptions;
74
+ const formatUnusedTaskOptions = (unusedOptions, definedTasks) => `Options are defined in your Tool Kit configuration for tasks that don't exist:
75
+
76
+ ${unusedOptions.map((optionName) => `- ${logger_1.styles.task(optionName)}`).join('\n')}
77
+
78
+ They could be misspelt, or defined by a Tool Kit plugin that isn't installed in this app.
79
+
80
+ ${definedTasks.length > 0
81
+ ? `Task that are defined and can have options set are: ${definedTasks.map(logger_1.styles.task).join(', ')}`
82
+ : `You don't have currently any plugins installed that provide tasks. You'll need to install some plugins before options can be set.`}.
83
+ `;
84
+ exports.formatUnusedTaskOptions = formatUnusedTaskOptions;
76
85
  const formatUninstalledHooks = (uninstalledHooks) => `These hooks aren't installed into your app:
77
86
 
78
87
  ${uninstalledHooks.map((hook) => `- ${logger_1.styles.hook(hook.id || 'unknown event')}`).join('\n')}
@@ -80,7 +89,7 @@ ${uninstalledHooks.map((hook) => `- ${logger_1.styles.hook(hook.id || 'unknown e
80
89
  Run ${logger_1.styles.task('dotcom-tool-kit --install')} to install these hooks.
81
90
  `;
82
91
  exports.formatUninstalledHooks = formatUninstalledHooks;
83
- 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)})`)}`;
92
+ const formatMissingTask = (missing) => `- ${missing.tasks.map((task) => logger_1.styles.task(task.task)).join(', ')} ${logger_1.styles.dim(`(assigned to ${logger_1.styles.hook(missing.command.id)} by ${formatPlugin(missing.command.plugin)})`)}`;
84
93
  const formatMissingTasks = (missingTasks, tasks) => `These tasks don't exist, but are configured to run from hooks:
85
94
 
86
95
  ${missingTasks.map(formatMissingTask).join('\n')}
@@ -103,3 +112,5 @@ function formatPluginTree(plugin) {
103
112
  ];
104
113
  }
105
114
  exports.formatPluginTree = formatPluginTree;
115
+ const indentReasons = (reasons) => reasons.replace(/\n/g, '\n ');
116
+ exports.indentReasons = indentReasons;
@@ -0,0 +1,7 @@
1
+ import type { Base } from '@dotcom-tool-kit/base';
2
+ import type { EntryPoint } from '@dotcom-tool-kit/plugin';
3
+ import { Validated } from '@dotcom-tool-kit/validated';
4
+ export declare function importEntryPoint<T extends {
5
+ name: string;
6
+ } & Omit<typeof Base, 'new'>>(type: T, entryPoint: EntryPoint): Promise<Validated<T>>;
7
+ //# sourceMappingURL=entry-point.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry-point.d.ts","sourceRoot":"","sources":["../../src/plugin/entry-point.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAA;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,SAAS,EAAW,MAAM,4BAA4B,CAAA;AAU/D,wBAAsB,gBAAgB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,KAAK,CAAC,EAC1F,IAAI,EAAE,CAAC,EACP,UAAU,EAAE,UAAU,GACrB,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CA4CvB"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.importEntryPoint = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const logger_1 = require("@dotcom-tool-kit/logger");
6
+ const validated_1 = require("@dotcom-tool-kit/validated");
7
+ const resolve_from_1 = tslib_1.__importDefault(require("resolve-from"));
8
+ const lodash_1 = require("lodash");
9
+ const messages_1 = require("../messages");
10
+ const isPlainObjectGuard = (value) => (0, lodash_1.isPlainObject)(value);
11
+ // the subclasses of Base have different constructor signatures so we need to omit
12
+ // the constructor from the type bound here so you can actually pass in a subclass
13
+ async function importEntryPoint(type, entryPoint) {
14
+ const resolvedPath = resolve_from_1.default.silent(entryPoint.plugin.root, entryPoint.modulePath);
15
+ if (!resolvedPath) {
16
+ return (0, validated_1.invalid)([
17
+ `could not find entrypoint ${logger_1.styles.filepath(entryPoint.modulePath)} in plugin ${logger_1.styles.plugin(entryPoint.plugin.id)}`
18
+ ]);
19
+ }
20
+ let pluginModule;
21
+ try {
22
+ pluginModule = await Promise.resolve(`${resolvedPath}`).then(s => tslib_1.__importStar(require(s)));
23
+ }
24
+ catch (e) {
25
+ const err = e;
26
+ return (0, validated_1.invalid)([
27
+ `an error was thrown when loading entrypoint ${logger_1.styles.filepath(entryPoint.modulePath)} in plugin ${logger_1.styles.plugin(entryPoint.plugin.id)}:\n ${logger_1.styles.code((0, messages_1.indentReasons)(err.toString()))}`
28
+ ]);
29
+ }
30
+ if (isPlainObjectGuard(pluginModule) &&
31
+ 'default' in pluginModule &&
32
+ typeof pluginModule.default === 'function') {
33
+ const name = pluginModule.default.name;
34
+ return type
35
+ .isCompatible(pluginModule.default)
36
+ .mapError((reasons) => [
37
+ `the ${type.name.toLowerCase()} ${logger_1.styles.hook(name)} is not a compatible instance of ${logger_1.styles.code(type.name)}:\n - ${reasons.join('\n - ')}`
38
+ ]);
39
+ }
40
+ else {
41
+ return (0, validated_1.invalid)([
42
+ `entrypoint ${logger_1.styles.filepath(entryPoint.modulePath)} in plugin ${logger_1.styles.plugin(entryPoint.plugin.id)} does not have a ${logger_1.styles.code('default')} export`
43
+ ]);
44
+ }
45
+ }
46
+ exports.importEntryPoint = importEntryPoint;
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from '@dotcom-tool-kit/plugin';
2
+ export declare function isDescendent(possibleAncestor: Plugin, possibleDescendent: Plugin): boolean;
3
+ //# sourceMappingURL=is-descendent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"is-descendent.d.ts","sourceRoot":"","sources":["../../src/plugin/is-descendent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAErD,wBAAgB,YAAY,CAAC,gBAAgB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAQ1F"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDescendent = void 0;
4
+ function isDescendent(possibleAncestor, possibleDescendent) {
5
+ if (!possibleDescendent.parent) {
6
+ return false;
7
+ }
8
+ else if (possibleDescendent.parent === possibleAncestor) {
9
+ return true;
10
+ }
11
+ else {
12
+ return isDescendent(possibleAncestor, possibleDescendent.parent);
13
+ }
14
+ }
15
+ exports.isDescendent = isDescendent;
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from '@dotcom-tool-kit/plugin';
2
+ import type { ValidPluginsConfig } from '@dotcom-tool-kit/config';
3
+ import { Logger } from 'winston';
4
+ export declare const mergeCommands: (config: ValidPluginsConfig, plugin: Plugin, logger: Logger) => void;
5
+ //# sourceMappingURL=merge-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge-commands.d.ts","sourceRoot":"","sources":["../../src/plugin/merge-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAClE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAGjE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAIhC,eAAO,MAAM,aAAa,WAAY,kBAAkB,UAAU,MAAM,UAAU,MAAM,SA4DvF,CAAA"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeCommands = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const conflict_1 = require("@dotcom-tool-kit/conflict");
6
+ const is_descendent_1 = require("./is-descendent");
7
+ const logger_1 = require("@dotcom-tool-kit/logger");
8
+ const path_1 = tslib_1.__importDefault(require("path"));
9
+ const mergeCommands = (config, plugin, logger) => {
10
+ if (plugin.rcFile) {
11
+ let commands = plugin.rcFile.commands;
12
+ // TODO:KB:20240410 remove this legacy hooks field handling and the associated
13
+ // field in the type definitions in a future major version
14
+ if (plugin.rcFile.hooks) {
15
+ commands = plugin.rcFile.hooks;
16
+ logger.warn(`${logger_1.styles.code('hooks')} is deprecated in ${logger_1.styles.filepath('.toolkitrc.yml')}. please rename ${logger_1.styles.code('hooks')} to ${logger_1.styles.code('commands')} in ${logger_1.styles.filepath(path_1.default.join(plugin.root, '.toolkitrc.yml'))}.`);
17
+ }
18
+ for (const [id, configCommandTask] of Object.entries(commands)) {
19
+ // handle conflicts between commands from different plugins
20
+ const existingCommandTask = config.commandTasks[id];
21
+ const newCommandTask = {
22
+ id,
23
+ plugin,
24
+ tasks: (Array.isArray(configCommandTask) ? configCommandTask : [configCommandTask]).flatMap((commandTask) => {
25
+ if (typeof commandTask === 'string') {
26
+ return [{ task: commandTask, options: {}, plugin }];
27
+ }
28
+ return Object.entries(commandTask).map(([task, options]) => ({ task, options, plugin }));
29
+ })
30
+ };
31
+ if (existingCommandTask) {
32
+ const existingFromDescendent = (0, is_descendent_1.isDescendent)(plugin, existingCommandTask.plugin);
33
+ // plugins can only override command tasks from their descendents, otherwise that's a conflict
34
+ // return a conflict either listing this command and the siblings,
35
+ // or merging in a previously-generated command
36
+ if (!existingFromDescendent) {
37
+ const conflicting = (0, conflict_1.isConflict)(existingCommandTask)
38
+ ? existingCommandTask.conflicting
39
+ : [existingCommandTask];
40
+ const conflict = {
41
+ plugin,
42
+ conflicting: conflicting.concat(newCommandTask)
43
+ };
44
+ config.commandTasks[id] = conflict;
45
+ }
46
+ else {
47
+ // if we're here, any existing command is from a child plugin,
48
+ // so the parent always overrides it
49
+ config.commandTasks[id] = newCommandTask;
50
+ }
51
+ }
52
+ else {
53
+ // this command task might not have been set yet, in which case use the new one
54
+ config.commandTasks[id] = newCommandTask;
55
+ }
56
+ }
57
+ }
58
+ };
59
+ exports.mergeCommands = mergeCommands;
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from '@dotcom-tool-kit/plugin';
2
+ import type { ValidPluginsConfig } from '@dotcom-tool-kit/config';
3
+ export declare const mergeHooks: (config: ValidPluginsConfig, plugin: Plugin) => void;
4
+ //# sourceMappingURL=merge-hooks.d.ts.map