dotcom-tool-kit 4.0.3 → 4.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/install.js CHANGED
@@ -13,7 +13,6 @@ const base_1 = require("@dotcom-tool-kit/base");
13
13
  const validated_1 = require("@dotcom-tool-kit/validated");
14
14
  const reduce_installations_1 = require("./plugin/reduce-installations");
15
15
  const conflict_1 = require("@dotcom-tool-kit/conflict");
16
- const schemas_1 = require("@dotcom-tool-kit/schemas");
17
16
  const messages_1 = require("./messages");
18
17
  const entry_point_1 = require("./plugin/entry-point");
19
18
  const init_1 = require("./init");
@@ -40,9 +39,9 @@ const loadHookEntrypoints = async (logger, config) => {
40
39
  };
41
40
  const loadHookInstallations = async (logger, config) => {
42
41
  const hookClassResults = await loadHookEntrypoints(logger, config);
43
- const installationResults = await hookClassResults
42
+ const installationResults = (await hookClassResults
44
43
  .map((hookClasses) => (0, reduce_installations_1.reducePluginHookInstallations)(logger, config, hookClasses, config.plugins['app root']))
45
- .awaitValue();
44
+ .awaitValue()).flatMap((installation) => installation);
46
45
  const installationsWithoutConflicts = installationResults.flatMap((installations) => {
47
46
  const conflicts = (0, conflict_1.findConflicts)(installations);
48
47
  if (conflicts.length) {
@@ -53,11 +52,7 @@ const loadHookInstallations = async (logger, config) => {
53
52
  return (0, validated_1.valid)((0, conflict_1.withoutConflicts)(installations));
54
53
  });
55
54
  return installationsWithoutConflicts.map((installations) => {
56
- return installations.map(({ hookConstructor, forHook, options }) => {
57
- const schema = schemas_1.HookSchemas[forHook];
58
- const parsedOptions = schema ? schema.parse(options) : {};
59
- return new hookConstructor(logger, forHook, parsedOptions);
60
- });
55
+ return installations.map(({ hookConstructor, forHook, options }) => new hookConstructor(logger, forHook, options));
61
56
  });
62
57
  };
63
58
  exports.loadHookInstallations = loadHookInstallations;
package/lib/messages.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare const formatInvalidOption: ([id, error]: InvalidOption) => string
12
12
  export declare const formatInvalidPluginOptions: (invalidOptions: InvalidOption[]) => string;
13
13
  export declare const formatUnusedPluginOptions: (unusedOptions: string[], definedPlugins: string[]) => string;
14
14
  export declare const formatUnusedTaskOptions: (unusedOptions: string[], definedTasks: string[]) => string;
15
+ export declare const formatUnusedHookOptions: (unusedOptions: string[], definedHooks: string[]) => string;
15
16
  export declare const formatUninstalledHooks: (uninstalledHooks: Hook<z.ZodTypeAny, unknown>[]) => string;
16
17
  type Missing = {
17
18
  command: CommandTask;
@@ -1 +1 @@
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,mBAAmB,kCAAiC,MACI,CAAA;AAErE,eAAO,MAAM,0BAA0B,mBACrB,aAAa,EAAE,KAC9B,MAKF,CAAA;AAED,eAAO,MAAM,yBAAyB,kBACrB,MAAM,EAAE,kBACP,MAAM,EAAE,KACvB,MAaF,CAAA;AAED,eAAO,MAAM,uBAAuB,kBACnB,MAAM,EAAE,gBACT,MAAM,EAAE,KACrB,MAaF,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"}
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,mBAAmB,kCAAiC,MACI,CAAA;AAErE,eAAO,MAAM,0BAA0B,mBACrB,aAAa,EAAE,KAC9B,MAKF,CAAA;AAED,eAAO,MAAM,yBAAyB,kBACrB,MAAM,EAAE,kBACP,MAAM,EAAE,KACvB,MAaF,CAAA;AAED,eAAO,MAAM,uBAAuB,kBACnB,MAAM,EAAE,gBACT,MAAM,EAAE,KACrB,MAaF,CAAA;AAED,eAAO,MAAM,uBAAuB,kBACnB,MAAM,EAAE,gBACT,MAAM,EAAE,KACrB,MAaF,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,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.indentReasons = exports.formatPluginTree = exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUnusedTaskOptions = exports.formatUnusedPluginOptions = exports.formatInvalidPluginOptions = exports.formatInvalidOption = exports.formatTaskOptionConflicts = exports.formatPluginOptionConflicts = exports.formatCommandTaskConflicts = exports.formatHookConflicts = exports.formatTaskConflicts = void 0;
3
+ exports.indentReasons = exports.formatPluginTree = exports.formatMissingTasks = exports.formatUninstalledHooks = exports.formatUnusedHookOptions = exports.formatUnusedTaskOptions = exports.formatUnusedPluginOptions = exports.formatInvalidPluginOptions = exports.formatInvalidOption = 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
6
  const formatTaskConflict = ([key, conflict]) => `- ${logger_1.styles.task(key ?? 'unknown task')} ${logger_1.styles.dim('from plugins')} ${conflict.conflicting
@@ -19,14 +19,14 @@ ${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 formatCommandTaskConflict = (conflict) => `${logger_1.styles.hook(conflict.conflicting[0].id)}:
22
+ const formatCommandTaskConflict = (conflict) => `${logger_1.styles.command(conflict.conflicting[0].id)}:
23
23
  ${conflict.conflicting
24
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
27
  const formatCommandTaskConflicts = (conflicts) => `${logger_1.styles.heading('These commands are configured to run different tasks by multiple plugins')}:
28
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.
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-plugin-conflicts.md')} for more details.
30
30
 
31
31
  `;
32
32
  exports.formatCommandTaskConflicts = formatCommandTaskConflicts;
@@ -86,6 +86,19 @@ ${definedTasks.length > 0
86
86
  : `You don't have currently any plugins installed that provide tasks. You'll need to install some plugins before options can be set.`}.
87
87
  `;
88
88
  exports.formatUnusedTaskOptions = formatUnusedTaskOptions;
89
+ const formatUnusedHookOptions = (unusedOptions, definedHooks) => `Options are defined in your Tool Kit configuration for hooks that don't exist:
90
+
91
+ ${unusedOptions.map((optionName) => `- ${logger_1.styles.hook(optionName)}`).join('\n')}
92
+
93
+ They could be misspelt, or defined by a Tool Kit plugin that isn't installed in this app.
94
+
95
+ ${definedHooks.length > 0
96
+ ? `Hooks that are defined and can have options set are: ${definedHooks
97
+ .map((hook) => logger_1.styles.hook(hook))
98
+ .join(', ')}`
99
+ : `You don't have currently any plugins installed that provide hooks. You'll need to install some plugins before options can be set.`}.
100
+ `;
101
+ exports.formatUnusedHookOptions = formatUnusedHookOptions;
89
102
  const formatUninstalledHooks = (uninstalledHooks) => `These hooks aren't installed into your app:
90
103
 
91
104
  ${uninstalledHooks.map((hook) => `- ${logger_1.styles.hook(hook.id || 'unknown event')}`).join('\n')}
@@ -93,8 +106,8 @@ ${uninstalledHooks.map((hook) => `- ${logger_1.styles.hook(hook.id || 'unknown e
93
106
  Run ${logger_1.styles.task('dotcom-tool-kit --install')} to install these hooks.
94
107
  `;
95
108
  exports.formatUninstalledHooks = formatUninstalledHooks;
96
- 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)})`)}`;
97
- const formatMissingTasks = (missingTasks, tasks) => `These tasks don't exist, but are configured to run from hooks:
109
+ const formatMissingTask = (missing) => `- ${missing.tasks.map((task) => logger_1.styles.task(task.task)).join(', ')} ${logger_1.styles.dim(`(assigned to ${logger_1.styles.command(missing.command.id)} by ${formatPlugin(missing.command.plugin)})`)}`;
110
+ const formatMissingTasks = (missingTasks, tasks) => `These tasks don't exist, but are configured to run from commands:
98
111
 
99
112
  ${missingTasks.map(formatMissingTask).join('\n')}
100
113
 
@@ -1,7 +1,8 @@
1
1
  import type { Logger } from 'winston';
2
2
  import type { HookClass, HookInstallation } from '@dotcom-tool-kit/base';
3
- import type { Plugin } from '@dotcom-tool-kit/plugin';
4
3
  import type { ValidConfig } from '@dotcom-tool-kit/config';
5
4
  import { Conflict } from '@dotcom-tool-kit/conflict';
6
- export declare function reducePluginHookInstallations(logger: Logger, config: ValidConfig, hookClasses: Record<string, HookClass>, plugin: Plugin): Promise<(HookInstallation | Conflict<HookInstallation>)[]>;
5
+ import type { Plugin } from '@dotcom-tool-kit/plugin';
6
+ import { Validated } from '@dotcom-tool-kit/validated';
7
+ export declare function reducePluginHookInstallations(logger: Logger, config: ValidConfig, hookClasses: Record<string, HookClass>, plugin: Plugin): Promise<Validated<(HookInstallation | Conflict<HookInstallation>)[]>>;
7
8
  //# sourceMappingURL=reduce-installations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reduce-installations.d.ts","sourceRoot":"","sources":["../../src/plugin/reduce-installations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAE1D,OAAO,EAAE,QAAQ,EAAc,MAAM,2BAA2B,CAAA;AAgChE,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACtC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAwC5D"}
1
+ {"version":3,"file":"reduce-installations.d.ts","sourceRoot":"","sources":["../../src/plugin/reduce-installations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAGrC,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAc,MAAM,2BAA2B,CAAA;AAEhE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAErD,OAAO,EAAE,SAAS,EAAmC,MAAM,4BAA4B,CAAA;AAiCvF,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,EACtC,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,CAAC,CAAC,gBAAgB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,CAgEvE"}
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.reducePluginHookInstallations = void 0;
4
- const schemas_1 = require("@dotcom-tool-kit/schemas");
5
- const conflict_1 = require("@dotcom-tool-kit/conflict");
6
4
  const lodash_1 = require("lodash");
5
+ const conflict_1 = require("@dotcom-tool-kit/conflict");
6
+ const logger_1 = require("@dotcom-tool-kit/logger");
7
+ const schemas_1 = require("@dotcom-tool-kit/schemas");
8
+ const validated_1 = require("@dotcom-tool-kit/validated");
9
+ const messages_1 = require("../messages");
7
10
  const extractForHook = (installation) => (0, conflict_1.isConflict)(installation) ? installation.conflicting[0].forHook : installation.forHook;
8
11
  // this function recursively collects all the hook installation requests from all plugins,
9
12
  // and merges them into a single, flat array of HookInstallation objects and/or Conflicts.
@@ -32,28 +35,42 @@ const extractForHook = (installation) => (0, conflict_1.isConflict)(installation
32
35
  // the resulting installations and/or conflicts from `Hook.mergeChildInstallations` and `p`
33
36
  async function reducePluginHookInstallations(logger, config, hookClasses, plugin) {
34
37
  if (!plugin.rcFile || config.resolutionTrackers.reducedInstallationPlugins.has(plugin.id)) {
35
- return [];
38
+ return (0, validated_1.valid)([]);
36
39
  }
37
40
  config.resolutionTrackers.reducedInstallationPlugins.add(plugin.id);
38
- const rawChildInstallations = await Promise.all((plugin.children ?? []).map((child) => reducePluginHookInstallations(logger, config, hookClasses, child))).then((installations) => installations.flat());
39
- const childInstallations = Object.entries((0, lodash_1.groupBy)(rawChildInstallations, extractForHook)).flatMap(([forHook, installations]) => {
41
+ const rawChildInstallations = (0, validated_1.reduceValidated)(await Promise.all((plugin.children ?? []).map((child) => reducePluginHookInstallations(logger, config, hookClasses, child)))).map((installations) => installations.flat());
42
+ if (!rawChildInstallations.valid) {
43
+ return rawChildInstallations;
44
+ }
45
+ const childInstallations = Object.entries((0, lodash_1.groupBy)(rawChildInstallations.value, extractForHook)).flatMap(([forHook, installations]) => {
40
46
  const hookClass = hookClasses[forHook];
41
47
  return hookClass.mergeChildInstallations(plugin, installations);
42
48
  });
43
49
  if (plugin.rcFile.options.hooks.length === 0) {
44
- return childInstallations;
50
+ return (0, validated_1.valid)(childInstallations);
51
+ }
52
+ const unusedHookOptions = plugin.rcFile.options.hooks
53
+ .flatMap(Object.keys)
54
+ .filter((hookId) => !(hookId in hookClasses))
55
+ .map((hookId) => logger_1.styles.hook(hookId));
56
+ if (unusedHookOptions.length > 0) {
57
+ return (0, validated_1.invalid)([(0, messages_1.formatUnusedHookOptions)(unusedHookOptions, Object.keys(hookClasses))]);
45
58
  }
46
- return plugin.rcFile.options.hooks.flatMap((hookEntry) => Object.entries(hookEntry).flatMap(([id, configHookOptions]) => {
59
+ const validatedInstallations = plugin.rcFile.options.hooks.flatMap((hookEntry) => Object.entries(hookEntry).map(([id, configHookOptions]) => {
47
60
  const hookClass = hookClasses[id];
48
- const parsedOptions = schemas_1.HookSchemas[id].parse(configHookOptions);
61
+ const parsedOptions = schemas_1.HookSchemas[id]?.safeParse(configHookOptions);
62
+ if (parsedOptions && !parsedOptions.success) {
63
+ return (0, validated_1.invalid)([(0, messages_1.formatInvalidOption)([logger_1.styles.hook(id), parsedOptions.error])]);
64
+ }
49
65
  const installation = {
50
- options: parsedOptions,
66
+ options: parsedOptions ?? configHookOptions,
51
67
  plugin,
52
68
  forHook: id,
53
69
  hookConstructor: hookClass
54
70
  };
55
71
  const childInstallationsForHook = childInstallations.filter((childInstallation) => id === extractForHook(childInstallation));
56
- return hookClass.overrideChildInstallations(plugin, installation, childInstallationsForHook);
72
+ return (0, validated_1.valid)(hookClass.overrideChildInstallations(plugin, installation, childInstallationsForHook));
57
73
  }));
74
+ return (0, validated_1.reduceValidated)(validatedInstallations).map((installations) => installations.flat());
58
75
  }
59
76
  exports.reducePluginHookInstallations = reducePluginHookInstallations;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dotcom-tool-kit",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
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",