@codependix/nx 0.0.2 → 0.0.3

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.
@@ -4,12 +4,22 @@ import { Injectable as t, Module as n } from "@nestjs/common";
4
4
  import { existsSync as r, readFileSync as i } from "node:fs";
5
5
  import a from "node:path";
6
6
  import { spawn as o } from "node:child_process";
7
- import { createRequire as s } from "node:module";
7
+ import { randomUUID as s } from "node:crypto";
8
+ import { createRequire as c } from "node:module";
9
+ import { pathToFileURL as l } from "node:url";
8
10
  //#region \0rolldown/runtime.js
9
- var c = Object.defineProperty, __name = (e, t) => c(e, "name", {
11
+ var u = Object.defineProperty, __name = (e, t) => u(e, "name", {
10
12
  value: t,
11
13
  configurable: !0
12
- }), l = "**/{project.json,codependix.config.*}", u = "project.json", d = "{projectRoot}/codependix.config.*", f = "__codependixPluginContext", p = "@codependix/nx", m = "codependix-gate", h = ["codependix.config.ts", "configuration/codependix.config.ts"], g = "@codependix/cli", _ = "workspace:", v = ["package.json", "src/**/*"];
14
+ }), d = "**/{project.json,codependix.config.*}", f = "project.json", p = "{projectRoot}/codependix.config.*", m = "__codependixPluginContext", h = "@codependix/nx", g = "codependix-gate", _ = ["codependix.config.ts", "configuration/codependix.config.ts"], v = "@codependix/cli", y = "workspace:", b = [
15
+ "file:",
16
+ "link:",
17
+ "portal:",
18
+ y
19
+ ], x = ["package.json", "src/**/!(*.test.*|*.spec.*)"], S = "{workspaceRoot}/tsconfig.json", C = "tsconfig.json", w = {
20
+ outside: "it lies outside the workspace",
21
+ unresolved: "it resolves to no file"
22
+ };
13
23
  //#endregion
14
24
  //#region \0@oxc-project+runtime@0.153.0/helpers/esm/decorateMetadata.js
15
25
  function __decorateMetadata(e, t) {
@@ -25,7 +35,7 @@ function __decorate(e, t, n, r) {
25
35
  }
26
36
  //#endregion
27
37
  //#region packages/ic-suite/codependix/codependix-nx/src/modules/plugin/plugin.service.ts
28
- var y = class PluginService {
38
+ var T = class PluginService {
29
39
  constructor() {}
30
40
  isUnknownArray(e) {
31
41
  return Array.isArray(e);
@@ -35,7 +45,7 @@ var y = class PluginService {
35
45
  return typeof t == "string" && t !== "" ? t : void 0;
36
46
  }
37
47
  selectProjectRoots(e) {
38
- return e.filter((e) => a.basename(e) === u).map((e) => a.dirname(e)).filter((e) => e !== ".");
48
+ return e.filter((e) => a.basename(e) === f).map((e) => a.dirname(e)).filter((e) => e !== ".");
39
49
  }
40
50
  toRecord(e) {
41
51
  return typeof e == "object" && e ? { ...e } : {};
@@ -46,12 +56,12 @@ var y = class PluginService {
46
56
  options: e.options
47
57
  }), n = { [t.gateTargetName]: {
48
58
  cache: !0,
49
- executor: `${p}:gate`,
59
+ executor: `${h}:gate`,
50
60
  inputs: [
51
61
  "default",
52
62
  "^default",
53
63
  `{workspaceRoot}/${t.configurationPath}`,
54
- d,
64
+ p,
55
65
  ...e.toolInputs
56
66
  ],
57
67
  options: {}
@@ -70,7 +80,7 @@ var y = class PluginService {
70
80
  configurationPath: this.readString({
71
81
  key: "configurationPath",
72
82
  record: t
73
- }) ?? h.find((t) => e.exists(t)) ?? h[0],
83
+ }) ?? _.find((t) => e.exists(t)) ?? _[0],
74
84
  gateTargetName: this.readString({
75
85
  key: "gateTargetName",
76
86
  record: t
@@ -78,33 +88,51 @@ var y = class PluginService {
78
88
  };
79
89
  }
80
90
  };
81
- y = __decorate([t(), __decorateMetadata("design:paramtypes", [])], y);
91
+ T = __decorate([t(), __decorateMetadata("design:paramtypes", [])], T);
82
92
  //#endregion
83
93
  //#region packages/ic-suite/codependix/codependix-nx/src/modules/plugin/plugin.module.ts
84
- var b = class PluginModule {};
85
- b = __decorate([n({
94
+ var E = class PluginModule {};
95
+ E = __decorate([n({
86
96
  controllers: [],
87
- exports: [y],
97
+ exports: [T],
88
98
  imports: [],
89
- providers: [y]
90
- })], b);
99
+ providers: [T]
100
+ })], E);
91
101
  //#endregion
92
102
  //#region packages/ic-suite/codependix/codependix-nx/src/modules/gate/gate.constants.ts
93
- var x = "@swc-node/register/esm-register", S = "@codependix/cli/main", C = "nx.json", w = class GateService {
103
+ var D = "@codependix/nx/loader", O = "@codependix/cli/main", k = "nx.json", A = class GateService {
94
104
  pluginService;
95
105
  constructor(e) {
96
106
  this.pluginService = e;
97
107
  }
108
+ judgesOwnProject(e) {
109
+ let { project: t } = e.task.target, n = this.readTaskOptions(e), r = this.resolveSelection({
110
+ options: {
111
+ projects: this.toNameList(n.projects),
112
+ tags: this.toNameList(n.tags)
113
+ },
114
+ projectName: t
115
+ });
116
+ return r.tags.length === 0 && r.projects.length === 1 && r.projects[0] === t;
117
+ }
98
118
  readNameList(e) {
99
119
  return (e ?? []).flatMap((e) => e.split(",")).map((e) => e.trim()).filter((e) => e !== "");
100
120
  }
101
121
  readNxConfiguration(e) {
102
122
  try {
103
- return JSON.parse(i(a.join(e, C), "utf8"));
123
+ return JSON.parse(i(a.join(e, k), "utf8"));
104
124
  } catch {
105
125
  return;
106
126
  }
107
127
  }
128
+ readTaskOptions(e) {
129
+ let { configuration: t, project: n, target: r } = e.task.target, i = this.toRecord(e.context.projectsConfigurations.projects[n]?.targets?.[r]), a = this.toRecord(i.configurations);
130
+ return {
131
+ ...this.toRecord(i.options),
132
+ ...this.toRecord(t === void 0 ? void 0 : a[t]),
133
+ ...e.task.overrides
134
+ };
135
+ }
108
136
  async spawnCommandLine(e) {
109
137
  return await new Promise((t, n) => {
110
138
  let r = o(process.execPath, e.argv, {
@@ -120,10 +148,16 @@ var x = "@swc-node/register/esm-register", S = "@codependix/cli/main", C = "nx.j
120
148
  });
121
149
  });
122
150
  }
151
+ toNameList(e) {
152
+ return (Array.isArray(e) ? e : [e]).filter((e) => typeof e == "string" || typeof e == "number").map(String);
153
+ }
154
+ toRecord(e) {
155
+ return typeof e == "object" && e ? { ...e } : {};
156
+ }
123
157
  buildCommandArguments(e) {
124
158
  return [
125
159
  "--import",
126
- e.loaderSpecifier,
160
+ e.loaderUrl,
127
161
  e.cliEntryPath,
128
162
  "map",
129
163
  "--directory",
@@ -137,6 +171,15 @@ var x = "@swc-node/register/esm-register", S = "@codependix/cli/main", C = "nx.j
137
171
  ...e.dependencies ? [] : ["--no-dependencies"]
138
172
  ];
139
173
  }
174
+ async hashTask(e) {
175
+ return this.judgesOwnProject(e) ? await e.context.hasher.hashTask(e.task, e.context.taskGraph, e.context.env ?? process.env) : {
176
+ details: {
177
+ command: `${e.task.id} judges projects its inputs do not cover`,
178
+ nodes: {}
179
+ },
180
+ value: s()
181
+ };
182
+ }
140
183
  resolveConfigurationPath(e) {
141
184
  return e.configurationPath !== void 0 && e.configurationPath !== "" ? e.configurationPath : this.pluginService.resolvePluginOptions({
142
185
  exists: (t) => r(a.join(e.workspaceRoot, t)),
@@ -158,13 +201,13 @@ var x = "@swc-node/register/esm-register", S = "@codependix/cli/main", C = "nx.j
158
201
  async run(e) {
159
202
  let t = this.buildCommandArguments({
160
203
  ...this.resolveSelection(e),
161
- cliEntryPath: s(import.meta.url).resolve(S),
204
+ cliEntryPath: c(import.meta.url).resolve(O),
162
205
  configurationPath: this.resolveConfigurationPath({
163
206
  configurationPath: e.options.configurationPath,
164
207
  workspaceRoot: e.workspaceRoot
165
208
  }),
166
209
  dependencies: e.options.dependencies !== !1,
167
- loaderSpecifier: x,
210
+ loaderUrl: l(c(import.meta.url).resolve(D)).href,
168
211
  workspaceRoot: e.workspaceRoot
169
212
  });
170
213
  return await this.spawnCommandLine({
@@ -173,39 +216,39 @@ var x = "@swc-node/register/esm-register", S = "@codependix/cli/main", C = "nx.j
173
216
  });
174
217
  }
175
218
  };
176
- w = __decorate([t(), __decorateMetadata("design:paramtypes", [y === void 0 ? Object : y])], w);
219
+ A = __decorate([t(), __decorateMetadata("design:paramtypes", [T === void 0 ? Object : T])], A);
177
220
  //#endregion
178
221
  //#region packages/ic-suite/codependix/codependix-nx/src/modules/gate/gate.module.ts
179
- var T = class GateModule {};
180
- T = __decorate([n({
222
+ var j = class GateModule {};
223
+ j = __decorate([n({
181
224
  controllers: [],
182
- exports: [w],
183
- imports: [b],
184
- providers: [w]
185
- })], T);
225
+ exports: [A],
226
+ imports: [E],
227
+ providers: [A]
228
+ })], j);
186
229
  //#endregion
187
230
  //#region packages/ic-suite/codependix/codependix-nx/src/main.module.ts
188
- var E = class MainModule {};
189
- E = __decorate([n({
231
+ var M = class MainModule {};
232
+ M = __decorate([n({
190
233
  controllers: [],
191
- exports: [T, b],
192
- imports: [T, b],
234
+ exports: [j, E],
235
+ imports: [j, E],
193
236
  providers: []
194
- })], E);
237
+ })], M);
195
238
  //#endregion
196
239
  //#region packages/ic-suite/codependix/codependix-nx/src/modules/plugin/plugin-context.utilities.ts
197
240
  async function resolveGateService() {
198
- return (await resolvePluginContext()).get(w);
241
+ return (await resolvePluginContext()).get(A);
199
242
  }
200
243
  async function resolvePluginService() {
201
- return (await resolvePluginContext()).get(y);
244
+ return (await resolvePluginContext()).get(T);
202
245
  }
203
246
  async function resolvePluginContext() {
204
247
  let t = globalThis;
205
- return t[f] ??= e.createApplicationContext(E, {
248
+ return t[m] ??= e.createApplicationContext(M, {
206
249
  abortOnError: !1,
207
250
  logger: !1
208
- }), await t[f];
251
+ }), await t[m];
209
252
  }
210
253
  //#endregion
211
- export { w as a, g as c, l as d, v as f, T as i, p as l, __name as m, resolvePluginService as n, b as o, _ as p, E as r, y as s, resolveGateService as t, m as u };
254
+ export { S as _, A as a, v as c, b as d, C as f, y as g, x as h, j as i, h as l, w as m, resolvePluginService as n, E as o, d as p, M as r, T as s, resolveGateService as t, g as u, __name as v };
@@ -1,4 +1,4 @@
1
- import { t as e } from "../../../plugin-context.utilities-Bre57JBa.js";
1
+ import { t as e } from "../../../plugin-context.utilities-BR1ONpzC.js";
2
2
  //#region packages/ic-suite/codependix/codependix-nx/src/executors/gate/executor.ts
3
3
  async function gateExecutor(t, n) {
4
4
  return { success: await (await e()).run({
@@ -0,0 +1,25 @@
1
+ import { Hash } from '@nx/devkit';
2
+ import { HasherContext } from '@nx/devkit';
3
+ import { Task } from '@nx/devkit';
4
+
5
+ /**
6
+ * Hashes one gate task for Nx's cache.
7
+ *
8
+ * Nx consults an executor's hasher instead of hashing the target's inputs
9
+ * itself, which is the one place a run's own options can change whether it
10
+ * is cacheable at all: `cache` is fixed per target, before any option is
11
+ * read. A gate judging its own project is hashed exactly as Nx would; one
12
+ * whose `projects` or `tags` select any other project is never replayed.
13
+ */
14
+ declare function gateHasher(task: Task, context: GateHasherContext): Promise<Hash>;
15
+ export default gateHasher;
16
+
17
+ /**
18
+ * What Nx hands an executor's hasher: its declared context, plus the task's
19
+ * own environment, which it passes without declaring.
20
+ */
21
+ declare type GateHasherContext = HasherContext & {
22
+ readonly env?: NodeJS.ProcessEnv | undefined;
23
+ };
24
+
25
+ export { }
@@ -0,0 +1,10 @@
1
+ import { t as e } from "../../../plugin-context.utilities-BR1ONpzC.js";
2
+ //#region packages/ic-suite/codependix/codependix-nx/src/executors/gate/hasher.ts
3
+ async function gateHasher(t, n) {
4
+ return await (await e()).hashTask({
5
+ context: n,
6
+ task: t
7
+ });
8
+ }
9
+ //#endregion
10
+ export { gateHasher as default };
@@ -1,4 +1,7 @@
1
1
  import { CreateNodes } from '@nx/devkit';
2
+ import { Hash } from '@nx/devkit';
3
+ import { HasherContext } from '@nx/devkit';
4
+ import { Task } from '@nx/devkit';
2
5
 
3
6
  /** Arguments for building the command line one gate runs. */
4
7
  declare interface BuildCommandArguments extends GateSelection {
@@ -6,8 +9,8 @@ declare interface BuildCommandArguments extends GateSelection {
6
9
  readonly cliEntryPath: string;
7
10
  readonly configurationPath: string;
8
11
  readonly dependencies: boolean;
9
- /** What `node --import` registers the TypeScript loader from. */
10
- readonly loaderSpecifier: string;
12
+ /** File URL of the module `node --import` registers the loader from. */
13
+ readonly loaderUrl: string;
11
14
  readonly workspaceRoot: string;
12
15
  }
13
16
 
@@ -38,6 +41,14 @@ export declare interface CodependixPluginOptions {
38
41
  */
39
42
  export declare const DEFAULT_GATE_TARGET_NAME = "codependix-gate";
40
43
 
44
+ /**
45
+ * What Nx hands an executor's hasher: its declared context, plus the task's
46
+ * own environment, which it passes without declaring.
47
+ */
48
+ declare type GateHasherContext = HasherContext & {
49
+ readonly env?: NodeJS.ProcessEnv | undefined;
50
+ };
51
+
41
52
  /** Provides the run behind the gate executor. */
42
53
  export declare class GateModule {
43
54
  }
@@ -72,6 +83,14 @@ export declare interface GateSelection {
72
83
  export declare class GateService {
73
84
  private readonly pluginService;
74
85
  constructor(pluginService: PluginService);
86
+ /**
87
+ * Whether a gate task judges exactly the project it belongs to.
88
+ *
89
+ * Read from the options the executor will actually run with — the target's
90
+ * own, then the configuration's, then the command line's — through the
91
+ * same selection the run makes, so the two can never disagree.
92
+ */
93
+ private judgesOwnProject;
75
94
  /**
76
95
  * Reads a list of names out of an executor's options.
77
96
  *
@@ -88,6 +107,11 @@ export declare class GateService {
88
107
  * conventional paths, which a workspace with no registration gets anyway.
89
108
  */
90
109
  private readNxConfiguration;
110
+ /**
111
+ * The options one gate task runs with, merged as Nx merges them: the
112
+ * target's, then the named configuration's, then the command line's.
113
+ */
114
+ private readTaskOptions;
91
115
  /**
92
116
  * Starts the command line and settles on whether it exited zero.
93
117
  *
@@ -97,6 +121,13 @@ export declare class GateService {
97
121
  * verdict was reached, so none may be recorded as a pass.
98
122
  */
99
123
  private spawnCommandLine;
124
+ /**
125
+ * Reads a name list from an untrusted option: a list from configuration,
126
+ * or the single string, or number, a command line parses it into.
127
+ */
128
+ private toNameList;
129
+ /** Copies an untrusted value into a record, or an empty one. */
130
+ private toRecord;
100
131
  /**
101
132
  * Builds the `node` arguments one gate runs.
102
133
  *
@@ -106,6 +137,17 @@ export declare class GateService {
106
137
  * dependency's own gate rather than every gate downstream of it.
107
138
  */
108
139
  buildCommandArguments(args: BuildCommandArguments): string[];
140
+ /**
141
+ * Hashes one gate task for Nx's cache — or, when it judges any project but
142
+ * its own, gives it a hash no run shares, so its verdict is never replayed.
143
+ *
144
+ * A gate's inputs cover its own project and that project's dependencies.
145
+ * One handed `projects` or `tags` judges projects those inputs need not
146
+ * reach, so a hash built from them could replay a pass after an edit to
147
+ * the very project that now fails. A gate judging its own project is
148
+ * hashed exactly as Nx would hash it without this hasher.
149
+ */
150
+ hashTask(args: HashGateTaskArguments): Promise<Hash>;
109
151
  /**
110
152
  * Resolves the configuration path one gate runs with.
111
153
  *
@@ -134,6 +176,12 @@ export declare class GateService {
134
176
  run(args: RunGateArguments): Promise<boolean>;
135
177
  }
136
178
 
179
+ /** Arguments for hashing one gate task. */
180
+ declare interface HashGateTaskArguments {
181
+ readonly context: GateHasherContext;
182
+ readonly task: Task;
183
+ }
184
+
137
185
  /**
138
186
  * One cache input of an inferred target: a file glob, or the npm packages an
139
187
  * installed command line is versioned by.
@@ -160,7 +208,10 @@ declare interface InferTargetsArguments {
160
208
  readonly options: unknown;
161
209
  /** Every file Nx matched, workspace-root relative. */
162
210
  readonly projectConfigurationFiles: readonly string[];
163
- /** The command line's own inputs, from `resolveToolInputs`. */
211
+ /**
212
+ * The command line's own inputs and its loader's tsconfig chain, from
213
+ * `resolveToolInputs` and `resolveTsconfigInputs`.
214
+ */
164
215
  readonly toolInputs: readonly InferredInput[];
165
216
  readonly workspaceRoot: string;
166
217
  }
@@ -212,8 +263,9 @@ export declare class PluginService {
212
263
  * sources through `^default`; the workspace configuration holds the rules,
213
264
  * so editing it invalidates every gate; the project's own configuration is
214
265
  * the one file only this project's gate reads; and the command line's own
215
- * code decides every verdict, through the `toolInputs` the caller resolved
216
- * with `resolveToolInputs`. No `configurations` are
266
+ * code and its loader's tsconfig chain decide every verdict, through the
267
+ * `toolInputs` the caller resolved with `resolveToolInputs` and
268
+ * `resolveTsconfigInputs`. No `configurations` are
217
269
  * declared, so an aggregator run with `--configuration=check` falls through
218
270
  * to the defaults rather than failing for a configuration this target lacks.
219
271
  */
package/dist/src/index.js CHANGED
@@ -1,78 +1,214 @@
1
- import { a as e, c as t, d as n, f as r, i, l as a, n as o, o as s, p as c, r as l, s as u, t as d, u as f } from "../plugin-context.utilities-Bre57JBa.js";
2
- import { readFileSync as p, realpathSync as m } from "node:fs";
3
- import h from "node:path";
4
- import { createRequire as g } from "node:module";
1
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, o as d, p as f, r as p, s as m, t as h, u as g } from "../plugin-context.utilities-BR1ONpzC.js";
2
+ import { existsSync as _, readFileSync as v, realpathSync as y, statSync as b } from "node:fs";
3
+ import x from "node:path";
4
+ import { createRequire as S } from "node:module";
5
+ import { logger as C, readJsonFile as w } from "@nx/devkit";
5
6
  //#region packages/ic-suite/codependix/codependix-nx/src/modules/plugin/plugin-inputs.utilities.ts
7
+ function isInsideWorkspace(e) {
8
+ let t = x.relative(y(e.workspaceRoot), e.directory);
9
+ return !(t.startsWith("..") || x.isAbsolute(t) || t.split(x.sep).includes("node_modules"));
10
+ }
11
+ function readDependencies(e) {
12
+ let t = readManifest(e);
13
+ return Object.entries({
14
+ ...toRecord(t.dependencies),
15
+ ...toRecord(t.devDependencies)
16
+ });
17
+ }
6
18
  function resolveToolInputs(e) {
7
19
  try {
8
- let t = locateCommandLine();
9
- return toWorkspacePath({
10
- directory: t,
11
- workspaceRoot: e
12
- }) === void 0 ? resolveExternalInputs(t) : resolveWorkspaceInputs({
13
- cliDirectory: t,
14
- workspaceRoot: e
20
+ let t = locatePackage({
21
+ fromFile: e.resolveFrom ?? import.meta.url,
22
+ name: n
15
23
  });
16
- } catch {
17
- return [];
24
+ return t === void 0 ? (warnUnresolved({
25
+ logger: e.logger,
26
+ names: [n]
27
+ }), []) : isInsideWorkspace({
28
+ directory: t,
29
+ workspaceRoot: e.workspaceRoot
30
+ }) ? resolveWorkspaceInputs({
31
+ ...e,
32
+ cliDirectory: t
33
+ }) : resolveExternalInputs(t);
34
+ } catch (t) {
35
+ return e.logger.warn(`🕸️ Skipped the cache inputs of ${n}, so a change to it will not invalidate a cached codependix gate: ${String(t)}`), [];
18
36
  }
19
37
  }
20
38
  function collectWorkspacePackages(e) {
21
- e.visited.add(e.packageDirectory);
22
- let t = readDependencies(e.packageDirectory).filter(([, e]) => String(e).startsWith(c)).map(([t]) => locateDependency({
23
- fromDirectory: e.packageDirectory,
24
- name: t
25
- })).filter((t) => !e.visited.has(t));
26
- for (let n of t) collectWorkspacePackages({
27
- packageDirectory: n,
28
- visited: e.visited
29
- });
30
- return e.visited;
31
- }
32
- function locateCommandLine() {
33
- return h.dirname(m(g(import.meta.url).resolve(`${t}/package.json`)));
39
+ let t = /* @__PURE__ */ new Set([e]), n = /* @__PURE__ */ new Set(), r = [e];
40
+ for (let e = r.pop(); e !== void 0; e = r.pop()) {
41
+ let i = readDependencies(e).filter(([, e]) => String(e).startsWith(a)).map(([e]) => e);
42
+ for (let a of i) {
43
+ let i = locatePackage({
44
+ fromFile: x.join(e, "package.json"),
45
+ name: a
46
+ });
47
+ i === void 0 ? n.add(a) : t.has(i) || (t.add(i), r.push(i));
48
+ }
49
+ }
50
+ return {
51
+ directories: t,
52
+ unresolved: [...n].toSorted()
53
+ };
34
54
  }
35
- function locateDependency(e) {
36
- return h.dirname(m(g(h.join(e.fromDirectory, "package.json")).resolve(`${e.name}/package.json`)));
55
+ function locatePackage(e) {
56
+ let t;
57
+ try {
58
+ t = x.dirname(y(S(e.fromFile).resolve(e.name)));
59
+ } catch {
60
+ return;
61
+ }
62
+ for (;; t = x.dirname(t)) {
63
+ if (readManifest(t).name === e.name) return t;
64
+ if (x.dirname(t) === t) return;
65
+ }
37
66
  }
38
- function readDependencies(e) {
39
- let t = toRecord(JSON.parse(p(h.join(e, "package.json"), "utf8")));
40
- return [...Object.entries(toRecord(t.dependencies)), ...Object.entries(toRecord(t.devDependencies))];
67
+ function readManifest(e) {
68
+ let t = x.join(e, "package.json");
69
+ try {
70
+ let e = _(t) ? JSON.parse(v(t, "utf8")) : void 0;
71
+ return typeof e == "object" && e ? { ...e } : {};
72
+ } catch {
73
+ return {};
74
+ }
41
75
  }
42
76
  function resolveExternalInputs(e) {
43
- let n = readDependencies(e).map(([e]) => e).filter((e) => e.startsWith("@codependix/"));
44
- return [{ externalDependencies: [t, ...n].toSorted() }];
77
+ let t = readDependencies(e).map(([e]) => e).filter((e) => e.startsWith("@codependix/"));
78
+ return [{ externalDependencies: [n, ...t].toSorted() }];
45
79
  }
46
80
  function resolveWorkspaceInputs(e) {
47
- let t = m(e.workspaceRoot);
48
- return [...collectWorkspacePackages({
49
- packageDirectory: e.cliDirectory,
50
- visited: /* @__PURE__ */ new Set()
51
- })].flatMap((e) => r.map((n) => `{workspaceRoot}/${h.relative(t, e)}/${n}`)).toSorted();
81
+ let t = y(e.workspaceRoot), { directories: n, unresolved: r } = collectWorkspacePackages(e.cliDirectory);
82
+ return r.length > 0 && warnUnresolved({
83
+ logger: e.logger,
84
+ names: r
85
+ }), [...n].flatMap((e) => o.map((n) => `{workspaceRoot}/${x.relative(t, e)}/${n}`)).toSorted();
52
86
  }
53
87
  function toRecord(e) {
54
88
  return typeof e == "object" && e ? { ...e } : {};
55
89
  }
56
- function toWorkspacePath(e) {
57
- let t = h.relative(m(e.workspaceRoot), e.directory);
58
- return t.startsWith("..") || h.isAbsolute(t) || t.split(h.sep).includes("node_modules") ? void 0 : t;
90
+ function warnUnresolved(e) {
91
+ e.logger.warn(`🕸️ Skipped the cache inputs of ${e.names.join(", ")}, which could not be resolved, so a change to ${e.names.length === 1 ? "it" : "them"} will not invalidate a cached codependix gate.`);
92
+ }
93
+ //#endregion
94
+ //#region packages/ic-suite/codependix/codependix-nx/src/modules/plugin/plugin-tsconfig.utilities.ts
95
+ function resolveTsconfigInputs(t) {
96
+ try {
97
+ let e = y(t.workspaceRoot), { files: n, packages: r } = followExtendsChain({
98
+ logger: t.logger,
99
+ workspaceRoot: e
100
+ }), i = [...n].map((t) => `{workspaceRoot}/${x.relative(e, t).split(x.sep).join("/")}`).toSorted();
101
+ return r.size === 0 ? i : [...i, { externalDependencies: [...r].toSorted() }];
102
+ } catch (n) {
103
+ return t.logger.warn(`🕸️ Skipped following the bases the root tsconfig.json extends, so a change to one will not invalidate a cached codependix gate: ${String(n)}`), [e];
104
+ }
105
+ }
106
+ function describeSkippedBase(e) {
107
+ return e.kind === "undeclared" ? `the root package.json does not declare ${e.name} from a registry` : l[e.kind];
108
+ }
109
+ function followExtendsChain(e) {
110
+ let t = x.join(e.workspaceRoot, "tsconfig.json"), n = readRegistryDependencies(e.workspaceRoot), r = /* @__PURE__ */ new Set([t]), i = /* @__PURE__ */ new Set(), a = _(t) ? [t] : [];
111
+ for (let t = a.pop(); t !== void 0; t = a.pop()) for (let o of readExtends({
112
+ ...e,
113
+ file: t
114
+ })) {
115
+ let s = resolveExtendedBase({
116
+ ...e,
117
+ declared: n,
118
+ file: t,
119
+ specifier: o
120
+ });
121
+ s.kind === "file" ? r.has(s.file) || (r.add(s.file), a.push(s.file)) : s.kind === "package" ? i.add(s.name) : warnSkipped({
122
+ ...e,
123
+ base: s,
124
+ file: t,
125
+ specifier: o
126
+ });
127
+ }
128
+ return {
129
+ files: r,
130
+ packages: i
131
+ };
132
+ }
133
+ function readExtends(e) {
134
+ try {
135
+ return [w(e.file, { expectComments: !0 }).extends].flat().filter((e) => typeof e == "string");
136
+ } catch (t) {
137
+ return e.logger.warn(`🕸️ Skipped the bases ${x.relative(e.workspaceRoot, e.file)} extends, which could not be read, so a change to one will not invalidate a cached codependix gate: ${String(t)}`), [];
138
+ }
139
+ }
140
+ function readInstalledPackageName(e) {
141
+ let t = e.split(x.sep), n = t.lastIndexOf("node_modules") + 1, r = t[n];
142
+ if (n !== 0 && r !== void 0) return t.slice(n, r.startsWith("@") ? n + 2 : n + 1).join("/");
143
+ }
144
+ function readRegistryDependencies(e) {
145
+ return new Set(readDependencies(e).filter(([, e]) => !r.some((t) => String(e).startsWith(t))).map(([e]) => e));
146
+ }
147
+ function resolveExtendedBase(e) {
148
+ let t = e.specifier.replaceAll("\\", "/"), n = x.isAbsolute(t) || t.startsWith("./") || t.startsWith("../") ? resolvePathBase({
149
+ file: e.file,
150
+ specifier: t
151
+ }) : resolvePackageBase({
152
+ file: e.file,
153
+ specifier: t
154
+ });
155
+ if (n === void 0) return { kind: "unresolved" };
156
+ if (isInsideWorkspace({
157
+ directory: n,
158
+ workspaceRoot: e.workspaceRoot
159
+ })) return {
160
+ file: n,
161
+ kind: "file"
162
+ };
163
+ let r = readInstalledPackageName(n);
164
+ return r === void 0 ? { kind: "outside" } : e.declared.has(r) ? {
165
+ kind: "package",
166
+ name: r
167
+ } : {
168
+ kind: "undeclared",
169
+ name: r
170
+ };
171
+ }
172
+ function resolvePackageBase(e) {
173
+ let { specifier: t } = e, n = t.split("/").length > (t.startsWith("@") ? 2 : 1) ? [t, `${t}.json`] : [`${t}/${i}`, t], r = S(e.file), [a] = n.flatMap((e) => {
174
+ try {
175
+ let t = y(r.resolve(e));
176
+ return t.endsWith(".json") ? [t] : [];
177
+ } catch {
178
+ return [];
179
+ }
180
+ });
181
+ return a;
182
+ }
183
+ function resolvePathBase(e) {
184
+ let t = x.resolve(x.dirname(e.file), e.specifier), n = b(t, { throwIfNoEntry: !1 })?.isFile() === !0 || t.endsWith(".json") ? t : `${t}.json`;
185
+ return _(n) ? y(n) : n;
186
+ }
187
+ function warnSkipped(e) {
188
+ e.logger.warn(`🕸️ Skipped the cache input of ${e.specifier}, which ${x.relative(e.workspaceRoot, e.file)} extends, because ${describeSkippedBase(e.base)}, so a change to it will not invalidate a cached codependix gate.`);
59
189
  }
60
190
  //#endregion
61
191
  //#region packages/ic-suite/codependix/codependix-nx/src/index.ts
62
- var _ = {
63
- createNodes: [n, async (e, t, n) => {
64
- let r = (await o()).inferTargets({
192
+ var T = {
193
+ createNodes: [f, async (e, t, n) => {
194
+ let r = (await u()).inferTargets({
65
195
  options: t,
66
196
  projectConfigurationFiles: e,
67
- toolInputs: resolveToolInputs(n.workspaceRoot),
197
+ toolInputs: [...resolveToolInputs({
198
+ logger: C,
199
+ workspaceRoot: n.workspaceRoot
200
+ }), ...resolveTsconfigInputs({
201
+ logger: C,
202
+ workspaceRoot: n.workspaceRoot
203
+ })],
68
204
  workspaceRoot: n.workspaceRoot
69
205
  });
70
- return e.map((e) => {
71
- let t = h.dirname(e), n = r.get(t);
72
- return [e, n === void 0 ? {} : { projects: { [t]: { targets: n } } }];
73
- }).filter(([, e]) => Object.keys(e).length > 0);
206
+ return e.flatMap((e) => {
207
+ let t = x.dirname(e), n = r.get(t);
208
+ return n === void 0 ? [] : [[e, { projects: { [t]: { targets: n } } }]];
209
+ });
74
210
  }],
75
211
  name: "@codependix/nx"
76
212
  };
77
213
  //#endregion
78
- export { a as CODEPENDIX_NX_PLUGIN_NAME, f as DEFAULT_GATE_TARGET_NAME, i as GateModule, e as GateService, l as MainModule, s as PluginModule, u as PluginService, _ as default, d as resolveGateService, o as resolvePluginService };
214
+ export { c as CODEPENDIX_NX_PLUGIN_NAME, g as DEFAULT_GATE_TARGET_NAME, s as GateModule, t as GateService, p as MainModule, d as PluginModule, m as PluginService, T as default, h as resolveGateService, u as resolvePluginService };