@clearlydev/nx-archweave 0.3.2 → 0.4.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 (47) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/review-verdict.js +8 -249
  3. package/dist/eslint/index.js +28 -321
  4. package/dist/generators/_chunks/chunk-2WSX5YNB.js +274 -0
  5. package/dist/generators/_chunks/chunk-34V6HAJT.js +55 -0
  6. package/dist/generators/_chunks/chunk-3A6RZUCZ.js +114 -0
  7. package/dist/generators/_chunks/chunk-47T7NOPP.js +30 -0
  8. package/dist/generators/_chunks/chunk-4FJ7CLEU.js +189 -0
  9. package/dist/generators/_chunks/chunk-5MI3O4VZ.js +99 -0
  10. package/dist/generators/_chunks/chunk-6ZTIUBB2.js +139 -0
  11. package/dist/generators/_chunks/chunk-AIJCJ7JK.js +203 -0
  12. package/dist/generators/_chunks/chunk-ALSXKTLM.js +1098 -0
  13. package/dist/generators/_chunks/chunk-AQHV7DJS.js +656 -0
  14. package/dist/generators/_chunks/chunk-C2VVUWBA.js +386 -0
  15. package/dist/generators/_chunks/chunk-EXYZLL7A.js +234 -0
  16. package/dist/generators/_chunks/chunk-FQHFT5IH.js +50 -0
  17. package/dist/generators/_chunks/chunk-H222FPLK.js +80 -0
  18. package/dist/generators/_chunks/chunk-IIDOBI42.js +616 -0
  19. package/dist/generators/_chunks/chunk-L2RZ2LBO.js +132 -0
  20. package/dist/generators/_chunks/chunk-MQNQJOWA.js +217 -0
  21. package/dist/generators/_chunks/chunk-QQNDYJTR.js +243 -0
  22. package/dist/generators/_chunks/chunk-SFXU6IUS.js +0 -0
  23. package/dist/generators/_chunks/chunk-SNBIVIMI.js +89 -0
  24. package/dist/generators/_chunks/chunk-TUN34LAQ.js +8 -0
  25. package/dist/generators/_chunks/chunk-TXAQ2GJC.js +20 -0
  26. package/dist/generators/_chunks/chunk-U6LAFHSF.js +49 -0
  27. package/dist/generators/_chunks/chunk-URV6FLUH.js +73 -0
  28. package/dist/generators/_chunks/chunk-YNMLB4DL.js +25 -0
  29. package/dist/generators/_chunks/chunk-YY2UESLM.js +282 -0
  30. package/dist/generators/add-agent-rules/generator.js +11 -842
  31. package/dist/generators/add-backend/generator.js +11 -906
  32. package/dist/generators/add-fsd-lite/generator.js +12 -801
  33. package/dist/generators/add-github-templates/generator.js +13 -116
  34. package/dist/generators/add-integration/generator.js +15 -743
  35. package/dist/generators/add-review/generator.js +12 -1231
  36. package/dist/generators/allow-builds/generator.js +7 -71
  37. package/dist/generators/doctor/generator.js +106 -2044
  38. package/dist/generators/entity/generator.js +15 -604
  39. package/dist/generators/feature/generator.js +15 -604
  40. package/dist/generators/init/generator.js +68 -3376
  41. package/dist/generators/install-integration/generator.js +35 -871
  42. package/dist/generators/page/generator.js +15 -604
  43. package/dist/generators/record-integration/generator.js +12 -778
  44. package/dist/generators/shared/generator.js +15 -604
  45. package/dist/generators/widget/generator.js +15 -604
  46. package/dist/index.js +5 -663
  47. package/package.json +1 -1
@@ -0,0 +1,203 @@
1
+ import {
2
+ SEGMENT_NAME_PATTERN,
3
+ isEssenceSegmentName,
4
+ isUsableSliceApiName,
5
+ profileById,
6
+ resolveFrontendApp,
7
+ resolveSlicePublicApiName
8
+ } from "./chunk-2WSX5YNB.js";
9
+ import {
10
+ generatorFilesDir,
11
+ renderTemplateFiles
12
+ } from "./chunk-YNMLB4DL.js";
13
+ import {
14
+ RECORDED_FRONTENDS,
15
+ readToolkitConfig,
16
+ recordedFrontends,
17
+ resolveLocaleOption
18
+ } from "./chunk-EXYZLL7A.js";
19
+
20
+ // src/generators/slice/core.ts
21
+ import { join } from "node:path";
22
+ function composeSlice(input) {
23
+ const files = generatorFilesDir("slice", import.meta.url);
24
+ const directory = `${input.sourceRoot}/${input.layerDirName}/${input.group === void 0 ? "" : `${input.group}/`}${input.name}`;
25
+ const shared = input.layer === "shared";
26
+ const values = {
27
+ name: input.name,
28
+ publicApiName: input.publicApiName,
29
+ layer: input.layer,
30
+ locale: input.locale,
31
+ modulePath: shared ? `./${input.name}` : `./model/${input.name}`
32
+ };
33
+ const module = renderTemplateFiles(join(files, "module"), shared ? directory : `${directory}/model`, values).filter((file) => input.withSpec !== false || !file.filePath.endsWith(".spec.ts")).sort((a, b) => Number(a.filePath.endsWith(".spec.ts")) - Number(b.filePath.endsWith(".spec.ts")));
34
+ const segments = shared ? [] : Array.from(new Set(input.segments)).filter((segment) => segment !== "model").flatMap((segment) => renderTemplateFiles(join(files, "segment"), `${directory}/${segment}`, { ...values, segment }));
35
+ return {
36
+ directory,
37
+ publicApiName: input.publicApiName,
38
+ files: [...renderTemplateFiles(join(files, "index"), directory, values), ...module, ...segments]
39
+ };
40
+ }
41
+ var KEBAB_CASE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
42
+ function layerDirNameFor(layer, frontend) {
43
+ return profileById(frontend).layerDirs[layer] ?? layer;
44
+ }
45
+ function layerDirFor(layer, sourceRoot, frontend = "react-vite") {
46
+ return `${sourceRoot}/${layerDirNameFor(layer, frontend)}`;
47
+ }
48
+ function resolveFrontendForApp(option, config, detected) {
49
+ if (option !== void 0) return option;
50
+ const recorded = config?.["frontend"];
51
+ if (typeof recorded === "string" && RECORDED_FRONTENDS.includes(recorded) && recorded !== "none") {
52
+ return recorded;
53
+ }
54
+ return detected;
55
+ }
56
+ function listFilesUnder(tree, dir, prefix = "") {
57
+ return tree.children(dir).flatMap((child) => {
58
+ const path = `${dir}/${child}`;
59
+ return tree.isFile(path) ? [`${prefix}${child}`] : listFilesUnder(tree, path, `${prefix}${child}/`);
60
+ });
61
+ }
62
+ function computeSliceAction(tree, plan) {
63
+ if (!tree.exists(plan.directory)) return "created";
64
+ const expectedNames = plan.files.map((f) => f.filePath.slice(plan.directory.length + 1)).sort();
65
+ const actualNames = listFilesUnder(tree, plan.directory).sort();
66
+ if (actualNames.length !== expectedNames.length || !actualNames.every((n, i) => n === expectedNames[i])) {
67
+ return "skipped";
68
+ }
69
+ const allMatch = plan.files.every((f) => tree.read(f.filePath, "utf-8") === f.content);
70
+ return allMatch ? "unchanged" : "skipped";
71
+ }
72
+ function refusal(reason, dryRun, layer, name, app, extra = {}) {
73
+ const layerDir = layerDirFor(layer, app.sourceRoot);
74
+ return {
75
+ dryRun,
76
+ layer,
77
+ name,
78
+ project: app.project,
79
+ layerDir,
80
+ directory: `${layerDir}/${name}`,
81
+ publicApiName: null,
82
+ refused: true,
83
+ refusalReason: reason,
84
+ action: null,
85
+ files: [],
86
+ ...extra
87
+ };
88
+ }
89
+ function runFsdSlice(tree, layer, options) {
90
+ const dryRun = options.dryRun ?? false;
91
+ const unresolved = { project: null, sourceRoot: "<app>/src" };
92
+ if (!KEBAB_CASE.test(options.name)) {
93
+ return refusal("invalid-name", dryRun, layer, options.name, unresolved);
94
+ }
95
+ if (!isUsableSliceApiName(resolveSlicePublicApiName(options.name, options.publicApiName))) {
96
+ return refusal("invalid-public-api-name", dryRun, layer, options.name, unresolved);
97
+ }
98
+ if (layer === "shared" && isEssenceSegmentName(options.name)) {
99
+ return refusal("segment-by-essence", dryRun, layer, options.name, unresolved);
100
+ }
101
+ const segments = Array.from(new Set(options.segments ?? []));
102
+ if (segments.length > 0 && layer === "shared") {
103
+ return refusal("segments-on-shared", dryRun, layer, options.name, unresolved);
104
+ }
105
+ const badSegment = segments.find((segment) => !SEGMENT_NAME_PATTERN.test(segment));
106
+ if (badSegment !== void 0) return refusal("invalid-segment", dryRun, layer, options.name, unresolved, { detail: badSegment });
107
+ const essenceSegment = segments.find((segment) => isEssenceSegmentName(segment));
108
+ if (essenceSegment !== void 0) return refusal("segment-by-essence", dryRun, layer, options.name, unresolved, { detail: essenceSegment });
109
+ if (options.group !== void 0 && layer === "shared") return refusal("group-on-shared", dryRun, layer, options.name, unresolved);
110
+ if (options.group !== void 0 && (!KEBAB_CASE.test(options.group) || SEGMENT_FOLDERS.includes(options.group) || isEssenceSegmentName(options.group))) {
111
+ return refusal("invalid-group", dryRun, layer, options.name, unresolved, { detail: options.group });
112
+ }
113
+ const app = resolveFrontendApp(tree, options.project);
114
+ if (app.kind === "not-found") return refusal("project-not-found", dryRun, layer, options.name, { project: app.project, sourceRoot: unresolved.sourceRoot });
115
+ if (app.kind === "ambiguous") {
116
+ return refusal("ambiguous-frontend", dryRun, layer, options.name, unresolved, { candidates: app.candidates, recordedFrontends: recordedFrontends(readToolkitConfig(tree)) });
117
+ }
118
+ if (app.kind === "invalid-project-json") return refusal("invalid-project-json", dryRun, layer, options.name, unresolved, { detail: app.detail });
119
+ if (app.kind === "none") return refusal("no-frontend-app", dryRun, layer, options.name, unresolved, { candidates: app.otherProjects });
120
+ const config = readToolkitConfig(tree);
121
+ const frontend = resolveFrontendForApp(options.frontend, config, app.framework);
122
+ const layerDir = layerDirFor(layer, app.sourceRoot, frontend);
123
+ const locale = resolveLocaleOption(options.locale, config);
124
+ const requested = options.unitTestRunner !== void 0 && options.unitTestRunner !== "auto" ? options.unitTestRunner : recordedUnitTestRunner(config);
125
+ const runner = requested ?? detectUnitTestRunner(tree, app.root);
126
+ const plan = composeSlice({
127
+ layer,
128
+ name: options.name,
129
+ publicApiName: resolveSlicePublicApiName(options.name, options.publicApiName),
130
+ locale,
131
+ sourceRoot: app.sourceRoot,
132
+ layerDirName: layerDirNameFor(layer, frontend),
133
+ segments,
134
+ group: options.group,
135
+ withSpec: runner !== "none"
136
+ });
137
+ const action = computeSliceAction(tree, plan);
138
+ if (action === "created" && !dryRun) {
139
+ for (const file of plan.files) tree.write(file.filePath, file.content);
140
+ }
141
+ return {
142
+ dryRun,
143
+ layer,
144
+ name: options.name,
145
+ project: app.project,
146
+ layerDir,
147
+ directory: plan.directory,
148
+ publicApiName: plan.publicApiName,
149
+ refused: false,
150
+ refusalReason: null,
151
+ action,
152
+ files: plan.files,
153
+ ...runner === "none" ? { specSkipped: requested === "none" ? "none-requested" : "no-test-runner" } : {}
154
+ };
155
+ }
156
+ var SEGMENT_FOLDERS = ["ui", "model", "api", "lib", "config"];
157
+ function recordedUnitTestRunner(config) {
158
+ const fsd = config?.["fsd"];
159
+ const value = typeof fsd === "object" && fsd !== null ? fsd["unitTestRunner"] : void 0;
160
+ return value === "jest" || value === "vitest" || value === "none" ? value : void 0;
161
+ }
162
+ function hasDependency(tree, manifest, name) {
163
+ const raw = tree.read(manifest, "utf-8");
164
+ if (raw === null) return false;
165
+ try {
166
+ const parsed = JSON.parse(raw);
167
+ return parsed["dependencies"]?.[name] !== void 0 || parsed["devDependencies"]?.[name] !== void 0;
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+ function detectUnitTestRunner(tree, projectRoot) {
173
+ const prefix = projectRoot === "" || projectRoot === "." ? "" : `${projectRoot}/`;
174
+ const project = tree.read(`${prefix}project.json`, "utf-8");
175
+ if (project !== null) {
176
+ try {
177
+ const targets = JSON.parse(project).targets ?? {};
178
+ for (const target of Object.values(targets)) {
179
+ if (target?.executor?.startsWith("@nx/jest:")) return "jest";
180
+ if (target?.executor?.startsWith("@nx/vite:test") || target?.executor?.startsWith("@nx/vitest:")) return "vitest";
181
+ }
182
+ } catch {
183
+ }
184
+ }
185
+ for (const dir of prefix === "" ? [""] : [prefix, ""]) {
186
+ if (["ts", "mts", "cts", "js", "mjs", "cjs"].some((ext) => tree.exists(`${dir}jest.config.${ext}`))) return "jest";
187
+ if (["ts", "mts", "js", "mjs"].some((ext) => tree.exists(`${dir}vitest.config.${ext}`) || tree.exists(`${dir}vitest.workspace.${ext}`))) return "vitest";
188
+ for (const ext of ["ts", "mts", "js", "mjs"]) {
189
+ const vite = tree.read(`${dir}vite.config.${ext}`, "utf-8");
190
+ if (vite !== null && /\btest\s*:/.test(vite)) return "vitest";
191
+ }
192
+ }
193
+ for (const manifest of prefix === "" ? ["package.json"] : [`${prefix}package.json`, "package.json"]) {
194
+ if (hasDependency(tree, manifest, "vitest")) return "vitest";
195
+ if (hasDependency(tree, manifest, "jest")) return "jest";
196
+ }
197
+ return "none";
198
+ }
199
+
200
+ export {
201
+ runFsdSlice,
202
+ detectUnitTestRunner
203
+ };