nx-lifecycle 1.0.0 → 1.1.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 (48) hide show
  1. package/README.md +42 -4
  2. package/WHY-NX-LIFECYCLE.md +1 -1
  3. package/dist/bin.d.ts +1 -605
  4. package/dist/bin.js +1 -15
  5. package/dist/cli.d.ts +1 -5
  6. package/dist/cli.js +9 -22
  7. package/dist/commands/explain-command.d.ts +12 -0
  8. package/dist/commands/explain-command.js +57 -0
  9. package/dist/commands/lib/types.d.ts +0 -3
  10. package/dist/commands/lifecycle-command.d.ts +1 -11
  11. package/dist/commands/lifecycle-command.js +13 -22
  12. package/dist/executors/lifecycle/index.d.ts +1 -4
  13. package/dist/executors/lifecycle/index.js +1 -4
  14. package/dist/executors/lifecycle/lifecycle.d.ts +8 -9
  15. package/dist/executors/lifecycle/lifecycle.js +13 -20
  16. package/dist/lifecycle/explain.d.ts +68 -0
  17. package/dist/lifecycle/explain.js +160 -0
  18. package/dist/lifecycle/lifecycle-internal.d.ts +4 -12
  19. package/dist/lifecycle/lifecycle-internal.js +92 -109
  20. package/dist/lifecycle/normalizer.d.ts +13 -7
  21. package/dist/lifecycle/normalizer.js +29 -36
  22. package/dist/lifecycle/processor.d.ts +1 -3
  23. package/dist/lifecycle/processor.js +0 -2
  24. package/dist/plugin/index.d.ts +1 -277
  25. package/dist/plugin/index.js +1 -3
  26. package/dist/plugin/lifecycle-plugin.d.ts +18 -15
  27. package/dist/plugin/lifecycle-plugin.js +76 -89
  28. package/dist/plugin/schema.d.ts +2 -279
  29. package/dist/plugin/schema.js +0 -2
  30. package/dist/schemas/nx-json.d.ts +2 -153
  31. package/dist/schemas/nx-json.js +0 -2
  32. package/dist/schemas/project-json.d.ts +2 -153
  33. package/dist/schemas/project-json.js +0 -2
  34. package/package.json +16 -13
  35. package/dist/commands/index.d.ts +0 -755
  36. package/dist/commands/index.js +0 -14
  37. package/dist/commands/lib/dependencies.d.ts +0 -10
  38. package/dist/commands/lib/dependencies.js +0 -12
  39. package/dist/executors/lifecycle/container.d.ts +0 -603
  40. package/dist/executors/lifecycle/container.js +0 -8
  41. package/dist/lifecycle/dependencies.d.ts +0 -16
  42. package/dist/lifecycle/dependencies.js +0 -14
  43. package/dist/lifecycle/index.d.ts +0 -756
  44. package/dist/lifecycle/index.js +0 -25
  45. package/dist/plugin/container.d.ts +0 -855
  46. package/dist/plugin/container.js +0 -13
  47. package/dist/plugin/dependencies.d.ts +0 -860
  48. package/dist/plugin/dependencies.js +0 -9
@@ -1,21 +1,24 @@
1
- import type { CreateDependencies, CreateNodes } from '@nx/devkit';
2
- import type { AssertProjectJson } from '#schemas';
3
- import type { PluginLogger, ReadJsonFile } from './dependencies.js';
4
- import type { AssertLifecyclePluginOptions, LifecyclePluginOptions } from './schema.js';
1
+ import type { CreateDependenciesContext, CreateNodes } from '@nx/devkit';
2
+ import type { LifecyclePlan } from '../lifecycle/processor.js';
3
+ import type { LifecyclePluginOptions } from './schema.js';
5
4
  /**
6
- * Nx plugin that infers lifecycle targets, instead of writing them to `nx.json` and `project.json`.
7
- *
8
- * `createNodes` adds the anchor, hook and stage targets to every project with a `project.json`,
9
- * and wires the bound targets declared there.
5
+ * Validates plugin options, with errors Nx prints, and plans the lifecycle from them.
10
6
  *
7
+ * @param options - plugin options from `nx.json`
8
+ * @returns lifecycle targets and bindings
9
+ * @throws {Error} when options are invalid, or stages and bindings are inconsistent
10
+ */
11
+ export declare const planPluginOptions: (options: LifecyclePluginOptions | undefined) => LifecyclePlan;
12
+ export declare const createNodes: CreateNodes<LifecyclePluginOptions>;
13
+ /**
11
14
  * Nx applies `nx.json` `targetDefaults` and `project.json` on top of inferred targets,
12
15
  * replacing `dependsOn` rather than merging it.
13
- * `createDependencies` runs on the merged configuration, and fails if a bound target lost its wiring.
16
+ * This runs on the merged configuration, and fails if a bound target lost its wiring.
17
+ *
18
+ * @param options - plugin options from `nx.json`
19
+ * @param context - merged project configurations
20
+ * @returns no extra dependencies
21
+ * @throws {Error} when options are invalid, or a bound target lost its wiring
14
22
  */
15
- export declare class LifecyclePlugin {
16
- #private;
17
- readonly createNodes: CreateNodes<LifecyclePluginOptions>;
18
- readonly createDependencies: (...args: Parameters<CreateDependencies<LifecyclePluginOptions>>) => [];
19
- constructor(assertOptions: AssertLifecyclePluginOptions, readJsonFile: ReadJsonFile, assertProjectJson: AssertProjectJson, logger: PluginLogger);
20
- }
23
+ export declare const createDependencies: (options: LifecyclePluginOptions | undefined, context: CreateDependenciesContext) => [];
21
24
  //# sourceMappingURL=lifecycle-plugin.d.ts.map
@@ -1,8 +1,10 @@
1
1
  import Path from 'node:path';
2
- import { createNodesFromFiles } from '@nx/devkit';
2
+ import { createNodesFromFiles, logger, readJsonFile } from '@nx/devkit';
3
3
  import { deepEqual } from 'fast-equals';
4
+ import { assertProjectJson } from '#schemas';
4
5
  import { NOOP_EXECUTOR } from '../lifecycle/constants.js';
5
6
  import { planLifecycle } from '../lifecycle/processor.js';
7
+ import { assertLifecyclePluginOptions } from './schema.js';
6
8
  const describeTarget = ({ kind, name, stage })=>{
7
9
  if (kind === 'anchor') {
8
10
  return `Start of the ${stage} stage. Waits for the dependencies of the stage`;
@@ -54,105 +56,90 @@ const validateProject = ({ targets = {} }, { lifecycleTargets, registeredTargets
54
56
  }
55
57
  return errors;
56
58
  };
57
- export class LifecyclePlugin {
58
- #assertOptions;
59
- #readJsonFile;
60
- #assertProjectJson;
61
- #logger;
62
- createNodes;
63
- createDependencies;
64
- constructor(assertOptions, readJsonFile, assertProjectJson, logger){
65
- this.#assertOptions = assertOptions;
66
- this.#readJsonFile = readJsonFile;
67
- this.#assertProjectJson = assertProjectJson;
68
- this.#logger = logger;
69
- this.createNodes = [
70
- '**/project.json',
71
- this.#createNodes.bind(this)
72
- ];
73
- this.createDependencies = this.#createDependencies.bind(this);
59
+ export const planPluginOptions = (options)=>{
60
+ try {
61
+ assertLifecyclePluginOptions(options);
62
+ } catch (err) {
63
+ const issues = err.cause;
64
+ throw new Error([
65
+ 'Invalid nx-lifecycle plugin options in nx.json:',
66
+ ...issues.map(({ instancePath, message })=>`- options${instancePath} ${message}`)
67
+ ].join('\n'), {
68
+ cause: err
69
+ });
74
70
  }
75
- #plan(options) {
76
- try {
77
- this.#assertOptions(options);
78
- } catch (err) {
79
- const issues = err.cause;
80
- throw new Error([
81
- 'Invalid nx-lifecycle plugin options in nx.json:',
82
- ...issues.map(({ instancePath, message })=>`- options${instancePath} ${message}`)
83
- ].join('\n'), {
84
- cause: err
85
- });
86
- }
87
- return planLifecycle(options);
88
- }
89
- async #createNodes(projectJsonPaths, options, context) {
90
- const plan = this.#plan(options);
91
- return createNodesFromFiles((projectJsonPath)=>this.#createProjectNode(projectJsonPath, plan, context), projectJsonPaths, options, context);
71
+ return planLifecycle(options);
72
+ };
73
+ const createProjectNode = (projectJsonPath, { lifecycleTargets, registeredTargets }, context)=>{
74
+ const projectJson = readJsonFile(Path.join(context.workspaceRoot, projectJsonPath));
75
+ assertProjectJson(projectJson);
76
+ const declaredTargets = projectJson.targets ?? {};
77
+ const targets = {};
78
+ for (const [targetName, lifecycleTarget] of lifecycleTargets){
79
+ targets[targetName] = {
80
+ executor: NOOP_EXECUTOR,
81
+ dependsOn: [
82
+ ...lifecycleTarget.dependsOn
83
+ ],
84
+ metadata: {
85
+ description: describeTarget(lifecycleTarget)
86
+ }
87
+ };
92
88
  }
93
- #createProjectNode(projectJsonPath, { lifecycleTargets, registeredTargets }, context) {
94
- const projectJson = this.#readJsonFile(Path.join(context.workspaceRoot, projectJsonPath));
95
- this.#assertProjectJson(projectJson);
96
- const declaredTargets = projectJson.targets ?? {};
97
- const targets = {};
98
- for (const [targetName, lifecycleTarget] of lifecycleTargets){
89
+ for (const [targetName, lifecycleTarget] of registeredTargets){
90
+ if (targetName in declaredTargets) {
91
+ targets[lifecycleTarget.name].dependsOn.push(targetName);
99
92
  targets[targetName] = {
100
- executor: NOOP_EXECUTOR,
101
93
  dependsOn: [
102
- ...lifecycleTarget.dependsOn
103
- ],
104
- metadata: {
105
- description: describeTarget(lifecycleTarget)
106
- }
94
+ lifecycleTarget.previousHook
95
+ ]
107
96
  };
108
97
  }
109
- for (const [targetName, lifecycleTarget] of registeredTargets){
110
- if (targetName in declaredTargets) {
111
- targets[lifecycleTarget.name].dependsOn.push(targetName);
112
- targets[targetName] = {
113
- dependsOn: [
114
- lifecycleTarget.previousHook
115
- ]
116
- };
117
- }
118
- }
119
- return {
120
- projects: {
121
- [Path.dirname(projectJsonPath)]: {
122
- targets
123
- }
124
- }
125
- };
126
98
  }
127
- #createDependencies(options, context) {
128
- const plan = this.#plan(options);
129
- const errors = new Map();
130
- const definedTargets = new Set();
131
- for (const [projectName, project] of Object.entries(context.projects)){
132
- for (const error of validateProject(project, plan)){
133
- const projectNames = errors.get(error) ?? [];
134
- projectNames.push(projectName);
135
- errors.set(error, projectNames);
136
- }
137
- for (const targetName of Object.keys(project.targets ?? {})){
138
- definedTargets.add(targetName);
99
+ return {
100
+ projects: {
101
+ [Path.dirname(projectJsonPath)]: {
102
+ targets
139
103
  }
140
104
  }
141
- if (errors.size > 0) {
142
- throw new Error([
143
- 'nx-lifecycle targets are not wired as configured:',
144
- ...[
145
- ...errors
146
- ].map(([error, projectNames])=>`- ${error}\n Projects: ${projectNames.join(', ')}`)
147
- ].join('\n'));
105
+ };
106
+ };
107
+ const createLifecycleNodes = async (projectJsonPaths, options, context)=>{
108
+ const lifecyclePlan = planPluginOptions(options);
109
+ return createNodesFromFiles((projectJsonPath)=>createProjectNode(projectJsonPath, lifecyclePlan, context), projectJsonPaths, options, context);
110
+ };
111
+ export const createNodes = [
112
+ '**/project.json',
113
+ createLifecycleNodes
114
+ ];
115
+ export const createDependencies = (options, context)=>{
116
+ const lifecyclePlan = planPluginOptions(options);
117
+ const errors = new Map();
118
+ const definedTargets = new Set();
119
+ for (const [projectName, project] of Object.entries(context.projects)){
120
+ for (const error of validateProject(project, lifecyclePlan)){
121
+ const projectNames = errors.get(error) ?? [];
122
+ projectNames.push(projectName);
123
+ errors.set(error, projectNames);
148
124
  }
149
- for (const targetName of plan.registeredTargets.keys()){
150
- if (!definedTargets.has(targetName)) {
151
- this.#logger.warn(`Bound target ${targetName} is not defined in any project. Is it a typo?`);
152
- }
125
+ for (const targetName of Object.keys(project.targets ?? {})){
126
+ definedTargets.add(targetName);
153
127
  }
154
- return [];
155
128
  }
156
- }
129
+ if (errors.size > 0) {
130
+ throw new Error([
131
+ 'nx-lifecycle targets are not wired as configured:',
132
+ ...[
133
+ ...errors
134
+ ].map(([error, projectNames])=>`- ${error}\n Projects: ${projectNames.join(', ')}`)
135
+ ].join('\n'));
136
+ }
137
+ for (const targetName of lifecyclePlan.registeredTargets.keys()){
138
+ if (!definedTargets.has(targetName)) {
139
+ logger.warn(`Bound target ${targetName} is not defined in any project. Is it a typo?`);
140
+ }
141
+ }
142
+ return [];
143
+ };
157
144
 
158
145
  //# sourceMappingURL=lifecycle-plugin.js.map
@@ -1,4 +1,5 @@
1
1
  import type { SchemaType } from 'juniper';
2
+ import type { JuniperValidator } from 'juniper-validator';
2
3
  declare const lifecyclePluginOptionsSchema: import("juniper").ObjectSchema<{
3
4
  stages: import("juniper").ObjectSchema<{}, never, import("juniper").ObjectSchema<{
4
5
  dependsOn: import("juniper").ArraySchema<string | (Partial<{
@@ -70,284 +71,6 @@ declare const lifecyclePluginOptionsSchema: import("juniper").ObjectSchema<{
70
71
  bindings: import("juniper").ObjectSchema<{}, never, import("juniper").StringSchema<string, false>, import("juniper").EmptyIndex, unknown, false>;
71
72
  }, "bindings" | "stages", false, import("juniper").EmptyIndex, unknown, false>;
72
73
  export type LifecyclePluginOptions = SchemaType<typeof lifecyclePluginOptionsSchema>;
73
- export declare const assertLifecyclePluginOptions: (x: unknown) => asserts x is Partial<{
74
- stages: Record<string, Partial<{
75
- dependsOn: (string | (Partial<{
76
- dependencies: boolean;
77
- projects: never;
78
- }> & Partial<{
79
- target: string;
80
- params: string;
81
- }> & Required<Pick<{
82
- target: string;
83
- params: string;
84
- }, "target">>) | (string & Partial<{
85
- dependencies: boolean;
86
- projects: never;
87
- }> & Partial<{
88
- target: string;
89
- params: string;
90
- }> & Required<Pick<{
91
- target: string;
92
- params: string;
93
- }, "target">>) | (Partial<{
94
- dependencies: boolean;
95
- projects: never;
96
- }> & Partial<{
97
- target: string;
98
- params: string;
99
- }> & Required<Pick<{
100
- target: string;
101
- params: string;
102
- }, "target">> & string) | (Partial<{
103
- dependencies: never;
104
- projects: string | string[];
105
- }> & Required<Pick<{
106
- dependencies: never;
107
- projects: string | string[];
108
- }, "projects">> & Partial<{
109
- target: string;
110
- params: string;
111
- }> & Required<Pick<{
112
- target: string;
113
- params: string;
114
- }, "target">>) | (string & Partial<{
115
- dependencies: never;
116
- projects: string | string[];
117
- }> & Required<Pick<{
118
- dependencies: never;
119
- projects: string | string[];
120
- }, "projects">> & Partial<{
121
- target: string;
122
- params: string;
123
- }> & Required<Pick<{
124
- target: string;
125
- params: string;
126
- }, "target">>) | (Partial<{
127
- dependencies: never;
128
- projects: string | string[];
129
- }> & Required<Pick<{
130
- dependencies: never;
131
- projects: string | string[];
132
- }, "projects">> & Partial<{
133
- target: string;
134
- params: string;
135
- }> & Required<Pick<{
136
- target: string;
137
- params: string;
138
- }, "target">> & string))[];
139
- hooks: string[];
140
- }>>;
141
- bindings: Record<string, string>;
142
- }> & Required<Pick<{
143
- stages: Record<string, Partial<{
144
- dependsOn: (string | (Partial<{
145
- dependencies: boolean;
146
- projects: never;
147
- }> & Partial<{
148
- target: string;
149
- params: string;
150
- }> & Required<Pick<{
151
- target: string;
152
- params: string;
153
- }, "target">>) | (string & Partial<{
154
- dependencies: boolean;
155
- projects: never;
156
- }> & Partial<{
157
- target: string;
158
- params: string;
159
- }> & Required<Pick<{
160
- target: string;
161
- params: string;
162
- }, "target">>) | (Partial<{
163
- dependencies: boolean;
164
- projects: never;
165
- }> & Partial<{
166
- target: string;
167
- params: string;
168
- }> & Required<Pick<{
169
- target: string;
170
- params: string;
171
- }, "target">> & string) | (Partial<{
172
- dependencies: never;
173
- projects: string | string[];
174
- }> & Required<Pick<{
175
- dependencies: never;
176
- projects: string | string[];
177
- }, "projects">> & Partial<{
178
- target: string;
179
- params: string;
180
- }> & Required<Pick<{
181
- target: string;
182
- params: string;
183
- }, "target">>) | (string & Partial<{
184
- dependencies: never;
185
- projects: string | string[];
186
- }> & Required<Pick<{
187
- dependencies: never;
188
- projects: string | string[];
189
- }, "projects">> & Partial<{
190
- target: string;
191
- params: string;
192
- }> & Required<Pick<{
193
- target: string;
194
- params: string;
195
- }, "target">>) | (Partial<{
196
- dependencies: never;
197
- projects: string | string[];
198
- }> & Required<Pick<{
199
- dependencies: never;
200
- projects: string | string[];
201
- }, "projects">> & Partial<{
202
- target: string;
203
- params: string;
204
- }> & Required<Pick<{
205
- target: string;
206
- params: string;
207
- }, "target">> & string))[];
208
- hooks: string[];
209
- }>>;
210
- bindings: Record<string, string>;
211
- }, "bindings" | "stages">>;
212
- export type AssertLifecyclePluginOptions = typeof assertLifecyclePluginOptions;
213
- export declare const assertLifecyclePluginOptionsId: import("haywire").HaywireId<(x: unknown) => asserts x is Partial<{
214
- stages: Record<string, Partial<{
215
- dependsOn: (string | (Partial<{
216
- dependencies: boolean;
217
- projects: never;
218
- }> & Partial<{
219
- target: string;
220
- params: string;
221
- }> & Required<Pick<{
222
- target: string;
223
- params: string;
224
- }, "target">>) | (string & Partial<{
225
- dependencies: boolean;
226
- projects: never;
227
- }> & Partial<{
228
- target: string;
229
- params: string;
230
- }> & Required<Pick<{
231
- target: string;
232
- params: string;
233
- }, "target">>) | (Partial<{
234
- dependencies: boolean;
235
- projects: never;
236
- }> & Partial<{
237
- target: string;
238
- params: string;
239
- }> & Required<Pick<{
240
- target: string;
241
- params: string;
242
- }, "target">> & string) | (Partial<{
243
- dependencies: never;
244
- projects: string | string[];
245
- }> & Required<Pick<{
246
- dependencies: never;
247
- projects: string | string[];
248
- }, "projects">> & Partial<{
249
- target: string;
250
- params: string;
251
- }> & Required<Pick<{
252
- target: string;
253
- params: string;
254
- }, "target">>) | (string & Partial<{
255
- dependencies: never;
256
- projects: string | string[];
257
- }> & Required<Pick<{
258
- dependencies: never;
259
- projects: string | string[];
260
- }, "projects">> & Partial<{
261
- target: string;
262
- params: string;
263
- }> & Required<Pick<{
264
- target: string;
265
- params: string;
266
- }, "target">>) | (Partial<{
267
- dependencies: never;
268
- projects: string | string[];
269
- }> & Required<Pick<{
270
- dependencies: never;
271
- projects: string | string[];
272
- }, "projects">> & Partial<{
273
- target: string;
274
- params: string;
275
- }> & Required<Pick<{
276
- target: string;
277
- params: string;
278
- }, "target">> & string))[];
279
- hooks: string[];
280
- }>>;
281
- bindings: Record<string, string>;
282
- }> & Required<Pick<{
283
- stages: Record<string, Partial<{
284
- dependsOn: (string | (Partial<{
285
- dependencies: boolean;
286
- projects: never;
287
- }> & Partial<{
288
- target: string;
289
- params: string;
290
- }> & Required<Pick<{
291
- target: string;
292
- params: string;
293
- }, "target">>) | (string & Partial<{
294
- dependencies: boolean;
295
- projects: never;
296
- }> & Partial<{
297
- target: string;
298
- params: string;
299
- }> & Required<Pick<{
300
- target: string;
301
- params: string;
302
- }, "target">>) | (Partial<{
303
- dependencies: boolean;
304
- projects: never;
305
- }> & Partial<{
306
- target: string;
307
- params: string;
308
- }> & Required<Pick<{
309
- target: string;
310
- params: string;
311
- }, "target">> & string) | (Partial<{
312
- dependencies: never;
313
- projects: string | string[];
314
- }> & Required<Pick<{
315
- dependencies: never;
316
- projects: string | string[];
317
- }, "projects">> & Partial<{
318
- target: string;
319
- params: string;
320
- }> & Required<Pick<{
321
- target: string;
322
- params: string;
323
- }, "target">>) | (string & Partial<{
324
- dependencies: never;
325
- projects: string | string[];
326
- }> & Required<Pick<{
327
- dependencies: never;
328
- projects: string | string[];
329
- }, "projects">> & Partial<{
330
- target: string;
331
- params: string;
332
- }> & Required<Pick<{
333
- target: string;
334
- params: string;
335
- }, "target">>) | (Partial<{
336
- dependencies: never;
337
- projects: string | string[];
338
- }> & Required<Pick<{
339
- dependencies: never;
340
- projects: string | string[];
341
- }, "projects">> & Partial<{
342
- target: string;
343
- params: string;
344
- }> & Required<Pick<{
345
- target: string;
346
- params: string;
347
- }, "target">> & string))[];
348
- hooks: string[];
349
- }>>;
350
- bindings: Record<string, string>;
351
- }, "bindings" | "stages">>, null, null, false, false, false, false, false>;
74
+ export declare const assertLifecyclePluginOptions: JuniperValidator<LifecyclePluginOptions>['assert'];
352
75
  export {};
353
76
  //# sourceMappingURL=schema.d.ts.map
@@ -1,4 +1,3 @@
1
- import { identifier } from 'haywire';
2
1
  import { objectSchema } from 'juniper';
3
2
  import { makeValidator } from 'juniper-validator';
4
3
  import { bindingsSchema, stagesSchema } from '../lifecycle/schema.js';
@@ -16,6 +15,5 @@ const lifecyclePluginOptionsSchema = objectSchema({
16
15
  additionalProperties: false
17
16
  });
18
17
  export const assertLifecyclePluginOptions = makeValidator(lifecyclePluginOptionsSchema).assert;
19
- export const assertLifecyclePluginOptionsId = identifier();
20
18
 
21
19
  //# sourceMappingURL=schema.js.map