@codependix/configuration 0.0.0-stage → 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.
@@ -0,0 +1,489 @@
1
+ import { z as e } from "zod";
2
+ import { Injectable as t, Module as n } from "@nestjs/common";
3
+ import r from "prompts";
4
+ import { existsSync as i } from "node:fs";
5
+ import { readFile as a } from "node:fs/promises";
6
+ import o from "node:path";
7
+ import { fileURLToPath as s } from "node:url";
8
+ import { createJiti as c } from "jiti";
9
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/configuration/configuration.constants.ts
10
+ var l = class extends Error {
11
+ constructor(e) {
12
+ super(`Unsupported configuration file type: ${e}`), this.name = "UnknownConfigurationFileTypeError";
13
+ }
14
+ }, u = [
15
+ "fileImports",
16
+ "nestjsModules",
17
+ "nxProjects"
18
+ ], d = [
19
+ "both",
20
+ "json",
21
+ "markdown",
22
+ "none"
23
+ ], f = /* @__PURE__ */ new Set([
24
+ ".cjs",
25
+ ".cts",
26
+ ".js",
27
+ ".json",
28
+ ".mjs",
29
+ ".mts",
30
+ ".ts"
31
+ ]), p = [
32
+ "codependix.config.ts",
33
+ "codependix.config.mts",
34
+ "codependix.config.cts",
35
+ "codependix.config.js",
36
+ "codependix.config.mjs",
37
+ "codependix.config.cjs",
38
+ "codependix.config.json"
39
+ ], m = "none", h = "README.md", g = [], _ = [".git", "pnpm-workspace.yaml"], v = e.object({
40
+ id: e.array(e.string().min(1)).min(1).optional(),
41
+ path: e.array(e.string().min(1)).min(1).optional(),
42
+ project: e.array(e.string().min(1)).min(1).optional(),
43
+ tags: e.array(e.string().min(1)).min(1).optional()
44
+ }).refine((e) => Object.values(e).some((e) => e !== void 0), { message: "A selector needs at least one of id, path, project, or tags — otherwise nothing says which nodes it means." }), y = e.object({ implicit: e.boolean().optional() }), b = e.union([e.object({
45
+ edges: y.optional(),
46
+ from: v,
47
+ kind: e.enum(["allow", "forbid"]),
48
+ message: e.string().min(1).optional(),
49
+ name: e.string().min(1),
50
+ to: v
51
+ }), e.object({
52
+ kind: e.literal("acyclic"),
53
+ message: e.string().min(1).optional(),
54
+ name: e.string().min(1),
55
+ nodes: v.optional()
56
+ })]), x = e.object({
57
+ python: e.array(b).optional(),
58
+ typescript: e.array(b).optional()
59
+ }), S = e.object({
60
+ fileImports: x.optional(),
61
+ nestjsModules: e.array(b).optional(),
62
+ nxProjects: e.array(b).optional()
63
+ }), C = e.object({
64
+ json: e.object({ path: e.string().min(1) }).optional(),
65
+ markdown: e.object({
66
+ anchor: e.string().min(1).optional(),
67
+ path: e.string().min(1).optional()
68
+ }).optional(),
69
+ target: e.enum(d).optional()
70
+ }).superRefine((e, t) => {
71
+ let n = e.target ?? "none", r = n === "both" || n === "json", i = n === "both" || n === "markdown";
72
+ r && e.json === void 0 && t.addIssue({
73
+ code: "custom",
74
+ message: `A "${n}" export target needs a json destination.`
75
+ }), i && e.markdown === void 0 && t.addIssue({
76
+ code: "custom",
77
+ message: `A "${n}" export target needs a markdown destination.`
78
+ }), e.markdown !== void 0 && e.markdown.anchor === void 0 && e.markdown.path === void 0 && t.addIssue({
79
+ code: "custom",
80
+ message: "A markdown destination needs an anchor, a path, or both — otherwise nothing names where the export goes."
81
+ });
82
+ }), w = e.object({
83
+ fileImports: C.optional(),
84
+ nestjsModules: C.optional(),
85
+ nxProjects: C.optional()
86
+ }), T = e.object({
87
+ fileImports: C.optional(),
88
+ nestjsModules: C.optional(),
89
+ nxProjects: C.optional()
90
+ }), E = e.object({
91
+ boundaries: S.optional(),
92
+ exclude: e.array(e.string()).optional(),
93
+ include: e.array(e.string()).optional(),
94
+ projectGraph: e.string().optional(),
95
+ workspace: T.optional()
96
+ }), D = "boundaries", O = "reports", k = [D, O], A = ",", j = [
97
+ D,
98
+ O,
99
+ "write"
100
+ ], M = "A run mode (--check or --write)", N = class extends Error {
101
+ constructor(e) {
102
+ super(`Configuration file not found: ${e}`), this.name = "ConfigurationFileNotFoundError";
103
+ }
104
+ }, P = class extends Error {
105
+ constructor(e) {
106
+ super(e), this.name = "InputError";
107
+ }
108
+ }, F = (e) => new P(`${e} is required, and stdin is not a terminal so it cannot be asked for.`), I = (e) => new P(`${e} was not chosen.`);
109
+ //#endregion
110
+ //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorateMetadata.js
111
+ function L(e, t) {
112
+ if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
113
+ }
114
+ //#endregion
115
+ //#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
116
+ function R(e, t, n, r) {
117
+ var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
118
+ if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
119
+ else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
120
+ return i > 3 && a && Object.defineProperty(t, n, a), a;
121
+ }
122
+ //#endregion
123
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/input/input.service.ts
124
+ var z = class {
125
+ constructor() {}
126
+ promptRunner = r;
127
+ assertCanPrompt(e) {
128
+ if (!process.stdin.isTTY) throw F(e);
129
+ }
130
+ parseCommaDelimitedOption(e) {
131
+ return e === void 0 ? [] : e.split(",").map((e) => e.trim()).filter(Boolean);
132
+ }
133
+ parseFlagOption(e) {
134
+ return e ?? !0;
135
+ }
136
+ parseOptionalOption(e) {
137
+ let t = e?.trim();
138
+ return t === void 0 || t.length === 0 ? void 0 : t;
139
+ }
140
+ parsePathOption(e) {
141
+ return this.parseOptionalOption(e) ?? process.cwd();
142
+ }
143
+ async promptForSelect(e) {
144
+ this.assertCanPrompt(e.subject);
145
+ let t = (await this.promptRunner({
146
+ choices: e.choices.map((e) => ({
147
+ title: e,
148
+ value: e
149
+ })),
150
+ message: e.message,
151
+ name: "value",
152
+ type: "select"
153
+ })).value;
154
+ if (t === void 0) throw I(e.subject);
155
+ let n = e.choices.find((e) => e === t);
156
+ if (n === void 0) throw Error(`Prompt did not resolve to one of: ${e.choices.join(", ")}.`);
157
+ return n;
158
+ }
159
+ };
160
+ z = R([t(), L("design:paramtypes", [])], z);
161
+ //#endregion
162
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/input/input.module.ts
163
+ var B = class {};
164
+ B = R([n({
165
+ controllers: [],
166
+ exports: [z],
167
+ imports: [],
168
+ providers: [z]
169
+ })], B);
170
+ //#endregion
171
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/override-resolution/override-resolution.constants.ts
172
+ var V = (e) => `${e.flag} overrides a value the configuration does not declare. Add \`${e.field}\` to the configuration this run reads, then use ${e.flag} to change it.`, H = class {
173
+ constructor() {}
174
+ resolveOverride(e) {
175
+ let { authored: t, configured: n, field: r, flag: i, override: a } = e;
176
+ if (a === void 0 || a.length === 0) return n;
177
+ if (t === void 0) throw new P(V({
178
+ field: r,
179
+ flag: i
180
+ }));
181
+ return [...a];
182
+ }
183
+ applyOverrides(e) {
184
+ let { authored: t, overrides: n, resolved: r } = e;
185
+ return n === void 0 ? r : {
186
+ ...r,
187
+ exclude: this.resolveOverride({
188
+ authored: t.exclude,
189
+ configured: r.exclude,
190
+ field: "exclude",
191
+ flag: "--exclude",
192
+ override: n.exclude
193
+ }),
194
+ include: this.resolveOverride({
195
+ authored: t.include,
196
+ configured: r.include,
197
+ field: "include",
198
+ flag: "--include",
199
+ override: n.include
200
+ })
201
+ };
202
+ }
203
+ };
204
+ H = R([t(), L("design:paramtypes", [])], H);
205
+ //#endregion
206
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/override-resolution/override-resolution.module.ts
207
+ var U = class {};
208
+ U = R([n({
209
+ controllers: [],
210
+ exports: [H],
211
+ imports: [],
212
+ providers: [H]
213
+ })], U);
214
+ //#endregion
215
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/configuration/configuration-loader.service.ts
216
+ var W = class {
217
+ constructor() {}
218
+ readDefaultExport(e) {
219
+ if (typeof e != "object" || !e) return {};
220
+ let t = e.default;
221
+ return typeof t == "object" && t ? t : e;
222
+ }
223
+ findConfigurationFile(e) {
224
+ let t = o.resolve(e);
225
+ for (;;) {
226
+ for (let e of p) {
227
+ let n = o.join(t, e);
228
+ if (i(n)) return n;
229
+ }
230
+ let e = o.dirname(t);
231
+ if (e === t) return;
232
+ t = e;
233
+ }
234
+ }
235
+ findProjectConfigurationFile(e) {
236
+ for (let t of p) {
237
+ let n = o.join(e, t);
238
+ if (i(n)) return n;
239
+ }
240
+ }
241
+ findWorkspaceRoot() {
242
+ let e = o.resolve(process.cwd());
243
+ for (;;) {
244
+ let t = e;
245
+ if (_.some((e) => i(o.join(t, e)))) return e;
246
+ let n = o.dirname(e);
247
+ if (n === e) return;
248
+ e = n;
249
+ }
250
+ }
251
+ async loadConfigurationModule(e) {
252
+ if (e.extension === ".json") return JSON.parse(await a(e.configurationPath, "utf8"));
253
+ let t = c(s(import.meta.url));
254
+ return this.readDefaultExport(await t.import(e.configurationPath, { default: !0 }));
255
+ }
256
+ async parseConfigurationFile(e) {
257
+ let t = o.extname(e).toLowerCase();
258
+ if (!f.has(t)) throw new l(e);
259
+ let n = await this.loadConfigurationModule({
260
+ configurationPath: e,
261
+ extension: t
262
+ });
263
+ return E.parse(n);
264
+ }
265
+ async readAuthoredConfiguration(e) {
266
+ let t = o.resolve(e.searchDirectory ?? process.cwd()), n = e.configurationPath === void 0 ? this.findConfigurationFile(t) : this.resolveConfigurationPath(e.configurationPath);
267
+ return n === void 0 ? {} : this.parseConfigurationFile(n);
268
+ }
269
+ resolveConfigurationPath(e) {
270
+ let t = o.resolve(e);
271
+ if (i(t)) return t;
272
+ let n = this.findWorkspaceRoot();
273
+ if (n === void 0) throw new N(t);
274
+ let r = o.resolve(n, e);
275
+ if (!i(r)) throw new N(t);
276
+ return r;
277
+ }
278
+ };
279
+ W = R([t(), L("design:paramtypes", [])], W);
280
+ //#endregion
281
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/configuration/flag-resolution.service.ts
282
+ var G = class {
283
+ inputService;
284
+ constructor(e) {
285
+ this.inputService = e;
286
+ }
287
+ describeAcceptedCheckNames(e) {
288
+ return `${e}. It takes a comma-separated set drawn from ${k.map((e) => `"${e}"`).join(" and ")}, as in "--check ${k.join(",")}".`;
289
+ }
290
+ emptyMode() {
291
+ return {
292
+ checksBoundaries: !1,
293
+ checksReports: !1,
294
+ writes: !1
295
+ };
296
+ }
297
+ async promptForMode() {
298
+ let e = await this.inputService.promptForSelect({
299
+ choices: j,
300
+ message: "Check declared boundaries, check every configured export is current, or write them?",
301
+ subject: M
302
+ });
303
+ return {
304
+ errors: [],
305
+ mode: {
306
+ checksBoundaries: e === D,
307
+ checksReports: e === O,
308
+ writes: e === "write"
309
+ }
310
+ };
311
+ }
312
+ readCheckNames(e, t) {
313
+ if (e === void 0) return /* @__PURE__ */ new Set();
314
+ let n = e === !0 ? [] : e.split(",").map((e) => e.trim()).filter((e) => e !== "");
315
+ return n.length === 0 ? (t.push(this.describeAcceptedCheckNames("--check needs a value")), /* @__PURE__ */ new Set()) : this.validateCheckNames(n, t);
316
+ }
317
+ validateCheckNames(e, t) {
318
+ let n = /* @__PURE__ */ new Set();
319
+ for (let r of e) {
320
+ if (k.includes(r)) {
321
+ n.add(r);
322
+ continue;
323
+ }
324
+ t.push(this.describeAcceptedCheckNames(`--check does not accept "${r}"`));
325
+ }
326
+ return n;
327
+ }
328
+ async selectMode(e) {
329
+ let t = [], n = this.readCheckNames(e.check, t), r = e.write === !0;
330
+ return t.length > 0 ? {
331
+ errors: t,
332
+ mode: this.emptyMode()
333
+ } : n.size === 0 && !r ? this.promptForMode() : (r && n.has("reports") && t.push(`--write cannot be combined with --check ${O}: an export cannot be stale in the run that just wrote it. Drop one of them, or run --write and --check ${O} separately.`), {
334
+ errors: t,
335
+ mode: {
336
+ checksBoundaries: n.has(D),
337
+ checksReports: n.has(O),
338
+ writes: r
339
+ }
340
+ });
341
+ }
342
+ touchesFiles(e) {
343
+ return e.checksReports || e.writes;
344
+ }
345
+ };
346
+ G = R([t(), L("design:paramtypes", [z === void 0 ? Object : z])], G);
347
+ //#endregion
348
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/configuration/configuration.service.ts
349
+ var K = class {
350
+ configurationLoaderService;
351
+ flagResolutionService;
352
+ inputService;
353
+ overrideResolutionService;
354
+ constructor(e, t, n, r) {
355
+ this.configurationLoaderService = e, this.flagResolutionService = t, this.inputService = n, this.overrideResolutionService = r;
356
+ }
357
+ isProjectNamedOnCommandLine(e) {
358
+ let { selection: t } = e.configuration;
359
+ return this.matchesAnyName(e.projectName, e.projectRoot, t.projects) || (e.projectTags ?? []).some((e) => t.tags.includes(e));
360
+ }
361
+ matchesAnyGlob(e, t) {
362
+ return t.some((t) => o.matchesGlob(e, t));
363
+ }
364
+ matchesAnyName(e, t, n) {
365
+ return this.matchesAnyGlob(e, n) || t !== void 0 && this.matchesAnyGlob(t, n);
366
+ }
367
+ resolveBoundaries(e) {
368
+ return {
369
+ fileImports: {
370
+ python: e?.fileImports?.python ?? [],
371
+ typescript: e?.fileImports?.typescript ?? []
372
+ },
373
+ nestjsModules: e?.nestjsModules ?? [],
374
+ nxProjects: e?.nxProjects ?? []
375
+ };
376
+ }
377
+ resolveGraphOutput(e) {
378
+ let t = e?.target ?? "none", n = e?.markdown;
379
+ return {
380
+ json: e?.json === void 0 ? void 0 : { path: e.json.path },
381
+ markdown: n === void 0 ? void 0 : {
382
+ anchor: n.anchor,
383
+ path: n.path ?? "README.md"
384
+ },
385
+ target: t
386
+ };
387
+ }
388
+ resolveSelection(e) {
389
+ return {
390
+ projects: this.splitSelectionArgument(e?.projects),
391
+ tags: this.splitSelectionArgument(e?.tags)
392
+ };
393
+ }
394
+ splitSelectionArgument(e) {
395
+ return (e ?? "").split(",").map((e) => e.trim()).filter((e) => e.length > 0);
396
+ }
397
+ isProjectIncluded(e) {
398
+ let { configuration: t, projectName: n, projectRoot: r } = e, i = this.matchesAnyName(n, r, t.include) || this.isProjectNamedOnCommandLine(e), a = this.matchesAnyName(n, r, t.exclude);
399
+ return i && !a;
400
+ }
401
+ isProjectSelected(e) {
402
+ let { selection: t } = e.configuration;
403
+ return t.projects.length === 0 && t.tags.length === 0 || this.isProjectNamedOnCommandLine(e);
404
+ }
405
+ async loadConfiguration(e = {}) {
406
+ let t = await this.configurationLoaderService.readAuthoredConfiguration(e);
407
+ return this.overrideResolutionService.applyOverrides({
408
+ authored: t,
409
+ overrides: e.overrides,
410
+ resolved: this.resolveConfiguration(t, e.selection)
411
+ });
412
+ }
413
+ async loadProjectConfiguration(e) {
414
+ let t = o.resolve(e.projectRoot), n = this.configurationLoaderService.findProjectConfigurationFile(t);
415
+ if (n === void 0) return;
416
+ let r = o.extname(n).toLowerCase();
417
+ if (!f.has(r)) throw new l(n);
418
+ let i = await this.configurationLoaderService.loadConfigurationModule({
419
+ configurationPath: n,
420
+ extension: r
421
+ });
422
+ return w.parse(i);
423
+ }
424
+ parseCommaDelimitedOption(e) {
425
+ return this.inputService.parseCommaDelimitedOption(e);
426
+ }
427
+ parseFlagOption(e) {
428
+ return this.inputService.parseFlagOption(e);
429
+ }
430
+ parseOptionalOption(e) {
431
+ return this.inputService.parseOptionalOption(e);
432
+ }
433
+ parsePathOption(e) {
434
+ return this.inputService.parsePathOption(e);
435
+ }
436
+ resolveConfiguration(e, t) {
437
+ return {
438
+ boundaries: this.resolveBoundaries(e.boundaries),
439
+ exclude: e.exclude ?? [],
440
+ include: e.include ?? [...g],
441
+ projectGraph: e.projectGraph,
442
+ selection: this.resolveSelection(t),
443
+ workspace: e.workspace ?? {}
444
+ };
445
+ }
446
+ resolveForProject(e) {
447
+ let { configuration: t, graphType: n, projectConfiguration: r, projectName: i, projectRoot: a, projectTags: o } = e;
448
+ return !this.isProjectIncluded({
449
+ configuration: t,
450
+ projectName: i,
451
+ projectRoot: a,
452
+ projectTags: o
453
+ }) || r === void 0 ? {
454
+ json: void 0,
455
+ markdown: void 0,
456
+ target: "none"
457
+ } : this.resolveGraphOutput(r[n]);
458
+ }
459
+ resolveForWorkspace(e, t) {
460
+ return this.resolveGraphOutput(e.workspace[t]);
461
+ }
462
+ async selectMode(e) {
463
+ return this.flagResolutionService.selectMode(e);
464
+ }
465
+ touchesFiles(e) {
466
+ return this.flagResolutionService.touchesFiles(e);
467
+ }
468
+ };
469
+ K = R([t(), L("design:paramtypes", [
470
+ W === void 0 ? Object : W,
471
+ G === void 0 ? Object : G,
472
+ z === void 0 ? Object : z,
473
+ H === void 0 ? Object : H
474
+ ])], K);
475
+ //#endregion
476
+ //#region packages/ic-suite/codependix/codependix-configuration/src/modules/configuration/configuration.module.ts
477
+ var q = class {};
478
+ q = R([n({
479
+ controllers: [],
480
+ exports: [K],
481
+ imports: [B, U],
482
+ providers: [
483
+ W,
484
+ K,
485
+ G
486
+ ]
487
+ })], q);
488
+ //#endregion
489
+ export { D as CHECK_BOUNDARIES, k as CHECK_NAMES, O as CHECK_REPORTS, A as CHECK_SEPARATOR, d as CODEPENDIX_EXPORT_TARGETS, u as CODEPENDIX_GRAPH_TYPES, p as CONFIGURATION_FILE_NAMES, N as ConfigurationFileNotFoundError, q as ConfigurationModule, K as ConfigurationService, m as DEFAULT_EXPORT_TARGET, g as DEFAULT_INCLUDE_GLOBS, h as DEFAULT_MARKDOWN_PATH, P as InputError, _ as REPOSITORY_ROOT_MARKERS, j as RUN_MODE_CHOICES, M as RUN_MODE_SUBJECT, l as UnknownConfigurationFileTypeError, E as codependixConfigurationSchema, w as codependixProjectConfigurationSchema, F as missingInputError, I as promptCancelledError };
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
+ "author": "Jimmy Paolini",
3
+ "bugs": {
4
+ "url": "https://github.com/organizzolini/codebase/issues"
5
+ },
6
+ "dependencies": {
7
+ "@codependix/core": "0.0.3",
8
+ "@nestjs/common": "^11.1.21 || ^12.0.1",
9
+ "jiti": "^2.7.0",
10
+ "prompts": "^2.4.2",
11
+ "reflect-metadata": "^0.2.2",
12
+ "zod": "^4.4.3"
13
+ },
14
+ "description": "Configuration reader, glob resolution, and boundary constraint definitions for Codependix",
15
+ "devDependencies": {
16
+ "@golevelup/ts-vitest": "^4.0.0",
17
+ "@nestjs/testing": "^12.0.1",
18
+ "@nx/eslint-plugin": "^23.0.0",
19
+ "@swc/helpers": "^0.5.21",
20
+ "@types/node": "^26.5.1",
21
+ "@types/prompts": "^2.4.9",
22
+ "@vitest/coverage-v8": "^5.0.0",
23
+ "typescript": "^6.0.3",
24
+ "vitest": "^5.0.0"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/src/index.d.ts",
29
+ "default": "./dist/src/index.js"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "LICENSE",
36
+ "README.md"
37
+ ],
38
+ "homepage": "https://github.com/organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-configuration#readme",
39
+ "keywords": [
40
+ "boundaries",
41
+ "codependix",
42
+ "configuration",
43
+ "constraints",
44
+ "rules"
45
+ ],
46
+ "license": "MIT",
47
+ "main": "./dist/src/index.js",
2
48
  "name": "@codependix/configuration",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
49
+ "publishConfig": {
50
+ "access": "public",
51
+ "registry": "https://registry.npmjs.org"
52
+ },
53
+ "repository": {
54
+ "directory": "packages/ic-suite/codependix/codependix-configuration",
55
+ "type": "git",
56
+ "url": "git+https://github.com/organizzolini/codebase.git"
57
+ },
58
+ "type": "module",
59
+ "typeCoverage": {
60
+ "atLeast": 100,
61
+ "strict": true
62
+ },
63
+ "types": "./dist/src/index.d.ts",
64
+ "version": "0.0.3"
6
65
  }