@codependix/nx 0.0.2 β†’ 0.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/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";
5
- //#region packages/ic-suite/codependix/codependix-nx/src/modules/plugin/plugin-inputs.utilities.ts
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-Cp-6dCat.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";
6
+ //#region projects/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 projects/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
- //#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({
191
+ //#region projects/ic-suite/codependix/codependix-nx/src/index.ts
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 };
package/executors.json CHANGED
@@ -3,7 +3,8 @@
3
3
  "executors": {
4
4
  "gate": {
5
5
  "description": "Fail a project whose dependency graphs break a codependix boundary rule charged to it, built over the project and its Nx dependencies.",
6
- "implementation": "./src/executors/gate/executor",
6
+ "hasher": "@codependix/nx/src/executors/gate/hasher",
7
+ "implementation": "@codependix/nx/src/executors/gate/executor",
7
8
  "schema": "./src/executors/gate/schema.json"
8
9
  }
9
10
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "url": "https://github.com/organizzolini/codebase/issues"
5
5
  },
6
6
  "dependencies": {
7
- "@codependix/cli": "0.0.17",
7
+ "@codependix/cli": "0.0.19",
8
8
  "@nestjs/common": "^11.1.21 || ^12.0.1",
9
9
  "@nestjs/core": "^11.1.21 || ^12.0.1",
10
10
  "@nx/devkit": "^23.0.0",
@@ -30,6 +30,7 @@
30
30
  "default": "./dist/src/index.js"
31
31
  },
32
32
  "./executors.json": "./executors.json",
33
+ "./loader": "./src/executors/gate/loader.mjs",
33
34
  "./package.json": "./package.json",
34
35
  "./src/executors/*": "./dist/src/executors/*.js"
35
36
  },
@@ -38,9 +39,11 @@
38
39
  "dist",
39
40
  "executors.json",
40
41
  "LICENSE",
41
- "README.md"
42
+ "README.md",
43
+ "src/executors/*/schema.json",
44
+ "src/executors/gate/loader.mjs"
42
45
  ],
43
- "homepage": "https://github.com/organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-nx#readme",
46
+ "homepage": "https://github.com/organizzolini/codebase/tree/main/projects/ic-suite/codependix/codependix-nx#readme",
44
47
  "keywords": [
45
48
  "architecture-linter",
46
49
  "boundaries",
@@ -55,12 +58,15 @@
55
58
  "nx": {
56
59
  "executors": "./executors.json"
57
60
  },
61
+ "peerDependencies": {
62
+ "typescript": "^6.0.3"
63
+ },
58
64
  "publishConfig": {
59
65
  "access": "public",
60
66
  "registry": "https://registry.npmjs.org"
61
67
  },
62
68
  "repository": {
63
- "directory": "packages/ic-suite/codependix/codependix-nx",
69
+ "directory": "projects/ic-suite/codependix/codependix-nx",
64
70
  "type": "git",
65
71
  "url": "git+https://github.com/organizzolini/codebase.git"
66
72
  },
@@ -70,5 +76,5 @@
70
76
  "strict": true
71
77
  },
72
78
  "types": "./dist/src/index.d.ts",
73
- "version": "0.0.2"
79
+ "version": "0.0.4"
74
80
  }
@@ -0,0 +1,20 @@
1
+ // Registers the `@swc-node/register` hooks the codependix command line runs
2
+ // under, resolved from this plugin's own dependencies. The gate hands
3
+ // `node --import` this module's file URL.
4
+
5
+ // The hook's own `@swc-node/register/esm-register` cannot stand in for it:
6
+ // that registers `@swc-node/register/esm` relative to the working directory β€”
7
+ // the consumer's workspace root, which need not have the hook installed, and
8
+ // under pnpm cannot see this plugin's copy of it. Resolving from this module's
9
+ // URL reaches the copy this plugin depends on wherever it is installed. The
10
+ // hooks still read `tsconfig.json` from the working directory.
11
+
12
+ // `module.register` is deprecated (DEP0205) in favor of `module.registerHooks`,
13
+ // which runs synchronous hooks in-thread and so cannot run swc's asynchronous
14
+ // ones: there is no replacement to move to. This file is JavaScript, shipped
15
+ // as written, so the type-aware `no-deprecated` lint never reads the call. If
16
+ // a Node release removes `register`, every gate fails loudly rather than
17
+ // passing. Node 26 prints DEP0205 on each gate's child process.
18
+ import { register } from "node:module";
19
+
20
+ register("@swc-node/register/esm", import.meta.url);
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "description": "Fail a project whose dependency graphs break a codependix boundary rule charged to it, built over the project and its Nx dependencies.",
4
+ "properties": {
5
+ "configurationPath": {
6
+ "description": "Path to the codependix configuration file, relative to the workspace root. The path this plugin is registered with in nx.json when omitted.",
7
+ "type": "string"
8
+ },
9
+ "dependencies": {
10
+ "default": true,
11
+ "description": "Build the graphs over the judged projects' Nx dependency closure. False builds over the judged projects alone.",
12
+ "type": "boolean"
13
+ },
14
+ "projects": {
15
+ "description": "Nx project names to judge, replacing the project this target belongs to.",
16
+ "items": { "type": "string" },
17
+ "type": "array"
18
+ },
19
+ "tags": {
20
+ "description": "Nx project tags to judge, selecting every project carrying ANY of them.",
21
+ "items": { "type": "string" },
22
+ "type": "array"
23
+ }
24
+ },
25
+ "required": [],
26
+ "title": "Codependix gate",
27
+ "type": "object"
28
+ }