@clearlydev/nx-archweave 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +265 -2
- package/dist/bin/review-verdict.js +330 -0
- package/dist/eslint/fsd-boundaries.d.ts +119 -0
- package/dist/eslint/fsd-boundaries.js +144 -0
- package/dist/eslint/index.d.ts +78 -0
- package/dist/eslint/index.js +256 -0
- package/dist/eslint/tsconfig-aliases.d.ts +18 -0
- package/dist/eslint/tsconfig-aliases.js +114 -0
- package/dist/generators/add-agent-rules/generator.js +550 -0
- package/dist/generators/add-agent-rules/render.js +46 -0
- package/dist/generators/add-backend/generator.js +784 -0
- package/dist/generators/add-backend/render.js +102 -0
- package/dist/generators/add-fsd-lite/generator.js +553 -0
- package/dist/generators/add-fsd-lite/render.js +72 -0
- package/dist/generators/add-github-templates/files/en/codeowners/.github/CODEOWNERS.template +4 -0
- package/dist/generators/add-github-templates/files/en/issue/.github/ISSUE_TEMPLATE/bug-report.yml.template +28 -0
- package/dist/generators/add-github-templates/files/en/issue/.github/ISSUE_TEMPLATE/feature-request.yml.template +17 -0
- package/dist/generators/add-github-templates/files/en/pr/.github/PULL_REQUEST_TEMPLATE.md.template +12 -0
- package/dist/generators/add-github-templates/files/ko/codeowners/.github/CODEOWNERS.template +4 -0
- package/dist/generators/add-github-templates/files/ko/issue/.github/ISSUE_TEMPLATE/bug-report.yml.template +28 -0
- package/dist/generators/add-github-templates/files/ko/issue/.github/ISSUE_TEMPLATE/feature-request.yml.template +17 -0
- package/dist/generators/add-github-templates/files/ko/pr/.github/PULL_REQUEST_TEMPLATE.md.template +12 -0
- package/dist/generators/add-github-templates/generator.js +125 -0
- package/dist/generators/add-github-templates/render.js +26 -0
- package/dist/generators/add-integration/generator.js +818 -0
- package/dist/generators/add-integration/render.js +34 -0
- package/dist/generators/add-review/generator.js +921 -0
- package/dist/generators/add-review/render.js +96 -0
- package/dist/generators/allow-builds/generator.js +436 -0
- package/dist/generators/allow-builds/render.js +82 -0
- package/dist/generators/doctor/generator.js +2431 -0
- package/dist/generators/doctor/integration-report.js +70 -0
- package/dist/generators/doctor/render.js +10 -0
- package/dist/generators/entity/generator.js +395 -0
- package/dist/generators/feature/generator.js +395 -0
- package/dist/generators/init/generator.js +3211 -0
- package/dist/generators/init/render.js +125 -0
- package/dist/generators/init/validation.js +74 -0
- package/dist/generators/install-integration/generator.js +1233 -0
- package/dist/generators/install-integration/render.js +128 -0
- package/dist/generators/page/generator.js +395 -0
- package/dist/generators/record-integration/generator.js +852 -0
- package/dist/generators/record-integration/render.js +31 -0
- package/dist/generators/shared/dry-run.js +12 -0
- package/dist/generators/shared/frontend-app.js +57 -0
- package/dist/generators/shared/generator.js +395 -0
- package/dist/generators/shared/project-type.js +39 -0
- package/dist/generators/shared/record-pipeline.js +34 -0
- package/dist/generators/shared/run-nx.js +24 -0
- package/dist/generators/shared/template-files.js +38 -0
- package/dist/generators/shared/toolkit-config-file.js +110 -0
- package/dist/generators/slice/core.js +185 -0
- package/dist/generators/slice/files/index/index.ts.template +14 -0
- package/dist/generators/slice/files/module/__name__.spec.ts.template +11 -0
- package/dist/generators/slice/files/module/__name__.ts.template +11 -0
- package/dist/generators/slice/files/segment/index.ts.template +20 -0
- package/dist/generators/slice/render.js +70 -0
- package/dist/generators/widget/generator.js +395 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +680 -0
- package/dist/lib/nx-plugin.d.ts +2 -0
- package/dist/lib/nx-plugin.js +7 -0
- package/dist/runtime/integrations-composition-root.js +20 -0
- package/dist/runtime/node-command-runner.js +81 -0
- package/generators.json +85 -0
- package/package.json +95 -4
- package/src/generators/add-agent-rules/schema.json +43 -0
- package/src/generators/add-backend/schema.json +39 -0
- package/src/generators/add-fsd-lite/schema.json +43 -0
- package/src/generators/add-github-templates/schema.json +35 -0
- package/src/generators/add-integration/schema.json +35 -0
- package/src/generators/add-review/schema.json +72 -0
- package/src/generators/allow-builds/schema.json +20 -0
- package/src/generators/doctor/schema.json +20 -0
- package/src/generators/entity/schema.json +37 -0
- package/src/generators/feature/schema.json +37 -0
- package/src/generators/init/schema.json +98 -0
- package/src/generators/install-integration/schema.json +35 -0
- package/src/generators/page/schema.json +53 -0
- package/src/generators/record-integration/schema.json +26 -0
- package/src/generators/shared/schema.json +32 -0
- package/src/generators/widget/schema.json +45 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export function renderAddFsdLiteReport(report) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
if (report.aborted) {
|
|
4
|
+
lines.push('add-fsd-lite aborted — nothing was written.');
|
|
5
|
+
const refusal = report.appRefusal;
|
|
6
|
+
if (refusal !== null) {
|
|
7
|
+
lines.push('');
|
|
8
|
+
lines.push(" FSD layers live inside the frontend app's source root (e.g. apps/web/src), and no app could be picked:");
|
|
9
|
+
if (refusal.reason === 'project-not-found') {
|
|
10
|
+
lines.push(` --project=${refusal.project} names no project in this workspace.`);
|
|
11
|
+
}
|
|
12
|
+
else if (refusal.reason === 'ambiguous-frontend') {
|
|
13
|
+
lines.push(' more than one frontend app was found — rerun with --project=<one of them>:');
|
|
14
|
+
for (const name of refusal.candidates)
|
|
15
|
+
lines.push(` - ${name}`);
|
|
16
|
+
}
|
|
17
|
+
else if (refusal.reason === 'invalid-project-json') {
|
|
18
|
+
lines.push(` a project.json could not be parsed (${refusal.detail}) — fix it, then rerun.`);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
lines.push(' the workspace has no frontend application — create one (e.g. nx g @nx/react:app) or pass --project.');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return lines.join('\n');
|
|
25
|
+
}
|
|
26
|
+
if (report.dryRun) {
|
|
27
|
+
lines.push('add-fsd-lite dry-run — no files were written.');
|
|
28
|
+
lines.push('');
|
|
29
|
+
}
|
|
30
|
+
lines.push(`FSD layers (in ${report.project}, ${report.sourceRoot}):`);
|
|
31
|
+
if (report.layerGuide !== null)
|
|
32
|
+
lines.push(report.layerGuide);
|
|
33
|
+
lines.push('');
|
|
34
|
+
const where = report.eslintPath ?? `${report.project}'s eslint.config.mjs`;
|
|
35
|
+
switch (report.eslint) {
|
|
36
|
+
case 'applied':
|
|
37
|
+
lines.push(`ESLint: archweave/fsd-boundaries (${report.enforcement}) written to ${where}`);
|
|
38
|
+
break;
|
|
39
|
+
case 'already-applied':
|
|
40
|
+
lines.push(`ESLint: archweave/fsd-boundaries already wired in ${where} — no change`);
|
|
41
|
+
break;
|
|
42
|
+
case 'degraded-unrecognized':
|
|
43
|
+
lines.push(`ESLint: ${report.eslintPath === null ? `no ESLint config found for ${report.project}` : `${where} was NOT recognized — left untouched`}.`);
|
|
44
|
+
lines.push(' Add the rule yourself (then the layer rules are actually enforced):');
|
|
45
|
+
break;
|
|
46
|
+
case 'snippet-only':
|
|
47
|
+
lines.push(`ESLint: report-only (pass --applyEslint to write the rule into ${where}).`);
|
|
48
|
+
break;
|
|
49
|
+
case 'not-applied':
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
if (report.snippet !== null)
|
|
53
|
+
lines.push(report.snippet);
|
|
54
|
+
if (report.steiger !== null) {
|
|
55
|
+
const st = report.steiger;
|
|
56
|
+
lines.push('');
|
|
57
|
+
lines.push('steiger (official FSD linter, opt-in):');
|
|
58
|
+
lines.push(` ${st.configPath}: ${st.config === 'created' ? 'created' : st.config === 'unchanged' ? 'unchanged' : 'kept — an existing config with other content is never replaced'}`);
|
|
59
|
+
lines.push(st.target === 'added'
|
|
60
|
+
? ` target ${'fsd-check'}: added to ${st.targetPath}`
|
|
61
|
+
: st.target === 'present'
|
|
62
|
+
? ` target ${'fsd-check'}: already present in ${st.targetPath}`
|
|
63
|
+
: ' target fsd-check: NOT added — no parseable project.json / package.json for the app');
|
|
64
|
+
lines.push(st.dependencies === 'added'
|
|
65
|
+
? ` devDependencies: steiger + @feature-sliced/steiger-plugin added to package.json — run \`${st.installCommand}\``
|
|
66
|
+
: st.dependencies === 'present'
|
|
67
|
+
? ' devDependencies: already present'
|
|
68
|
+
: ' devDependencies: NOT added — the root package.json could not be parsed');
|
|
69
|
+
lines.push(` run it with: ${st.runCommand} (steiger needs Node >= 22.18)`);
|
|
70
|
+
}
|
|
71
|
+
return lines.join('\n');
|
|
72
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a problem so we can reproduce and fix it.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: reproduction
|
|
7
|
+
attributes:
|
|
8
|
+
label: Steps to reproduce
|
|
9
|
+
description: List the exact steps that trigger the problem.
|
|
10
|
+
placeholder: |
|
|
11
|
+
1. ...
|
|
12
|
+
2. ...
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: expected
|
|
17
|
+
attributes:
|
|
18
|
+
label: Expected behavior
|
|
19
|
+
description: What did you expect to happen?
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: actual
|
|
24
|
+
attributes:
|
|
25
|
+
label: Actual behavior
|
|
26
|
+
description: What actually happened instead?
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Propose a new feature or improvement.
|
|
3
|
+
body:
|
|
4
|
+
- type: textarea
|
|
5
|
+
id: problem
|
|
6
|
+
attributes:
|
|
7
|
+
label: What problem does this solve?
|
|
8
|
+
description: Describe the problem or limitation you're running into.
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: proposal
|
|
13
|
+
attributes:
|
|
14
|
+
label: Proposed solution
|
|
15
|
+
description: Describe the behavior or implementation you'd like to see.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: 버그 리포트
|
|
2
|
+
description: 재현하고 수정할 수 있도록 문제를 신고합니다.
|
|
3
|
+
labels: ["bug"]
|
|
4
|
+
body:
|
|
5
|
+
- type: textarea
|
|
6
|
+
id: reproduction
|
|
7
|
+
attributes:
|
|
8
|
+
label: 재현 방법
|
|
9
|
+
description: 문제를 일으키는 정확한 단계를 나열하세요.
|
|
10
|
+
placeholder: |
|
|
11
|
+
1. ...
|
|
12
|
+
2. ...
|
|
13
|
+
validations:
|
|
14
|
+
required: true
|
|
15
|
+
- type: textarea
|
|
16
|
+
id: expected
|
|
17
|
+
attributes:
|
|
18
|
+
label: 예상 동작
|
|
19
|
+
description: 어떤 동작을 예상했나요?
|
|
20
|
+
validations:
|
|
21
|
+
required: true
|
|
22
|
+
- type: textarea
|
|
23
|
+
id: actual
|
|
24
|
+
attributes:
|
|
25
|
+
label: 실제 동작
|
|
26
|
+
description: 실제로는 어떤 일이 일어났나요?
|
|
27
|
+
validations:
|
|
28
|
+
required: true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: 기능 요청
|
|
2
|
+
description: 새로운 기능이나 개선 사항을 제안합니다.
|
|
3
|
+
body:
|
|
4
|
+
- type: textarea
|
|
5
|
+
id: problem
|
|
6
|
+
attributes:
|
|
7
|
+
label: 어떤 문제를 해결하나요?
|
|
8
|
+
description: 지금 겪고 있는 문제나 한계를 설명하세요.
|
|
9
|
+
validations:
|
|
10
|
+
required: true
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: proposal
|
|
13
|
+
attributes:
|
|
14
|
+
label: 제안하는 해결 방법
|
|
15
|
+
description: 원하는 동작이나 구현 방향을 설명하세요.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// src/generators/add-github-templates/generator.ts
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
// src/generators/shared/dry-run.ts
|
|
5
|
+
function resolveDryRun(options) {
|
|
6
|
+
return process.env["NX_DRY_RUN"] === "true" || (options.dryRun ?? false);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/generators/shared/toolkit-config-file.ts
|
|
10
|
+
var TOOLKIT_CONFIG_PATH = "toolkit.config.json";
|
|
11
|
+
function readToolkitConfigFile(tree) {
|
|
12
|
+
const raw = tree.read(TOOLKIT_CONFIG_PATH, "utf-8");
|
|
13
|
+
if (raw === null) return { raw: null, parsed: null };
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(raw);
|
|
16
|
+
return {
|
|
17
|
+
raw,
|
|
18
|
+
parsed: typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed : null
|
|
19
|
+
};
|
|
20
|
+
} catch {
|
|
21
|
+
return { raw, parsed: null };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function readToolkitConfig(tree) {
|
|
25
|
+
return readToolkitConfigFile(tree).parsed;
|
|
26
|
+
}
|
|
27
|
+
function resolveLocaleOption(option, config) {
|
|
28
|
+
if (option) return option;
|
|
29
|
+
const locale = config?.["locale"];
|
|
30
|
+
return locale === "ko" || locale === "en" ? locale : "en";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/generators/shared/template-files.ts
|
|
34
|
+
import { existsSync } from "node:fs";
|
|
35
|
+
import { fileURLToPath } from "node:url";
|
|
36
|
+
import { generateFiles } from "@nx/devkit";
|
|
37
|
+
import { createTree } from "@nx/devkit/testing";
|
|
38
|
+
function generatorFilesDir(generator, fromUrl) {
|
|
39
|
+
for (const relative of [`../${generator}/files`, `./generators/${generator}/files`]) {
|
|
40
|
+
const dir = fileURLToPath(new URL(relative, fromUrl));
|
|
41
|
+
if (existsSync(dir)) return dir;
|
|
42
|
+
}
|
|
43
|
+
throw new Error(`The "${generator}" generator's template files are missing next to ${fileURLToPath(fromUrl)}`);
|
|
44
|
+
}
|
|
45
|
+
function renderTemplateFiles(srcFolder, target, substitutions) {
|
|
46
|
+
const scratch = createTree();
|
|
47
|
+
const seeded = new Set(scratch.listChanges().map((change) => change.path));
|
|
48
|
+
generateFiles(scratch, srcFolder, target, substitutions);
|
|
49
|
+
return scratch.listChanges().flatMap(
|
|
50
|
+
(change) => change.type === "CREATE" && change.content !== null && !seeded.has(change.path) ? [{ filePath: change.path, content: change.content.toString("utf-8") }] : []
|
|
51
|
+
).sort((a, b) => a.filePath.localeCompare(b.filePath));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/generators/add-github-templates/render.ts
|
|
55
|
+
var ACTION_LINES = {
|
|
56
|
+
created: "created",
|
|
57
|
+
unchanged: "unchanged (already matches the generated version)",
|
|
58
|
+
skipped: "left as-is (a different file already exists there \u2014 never overwritten)"
|
|
59
|
+
};
|
|
60
|
+
function renderAddGithubTemplatesReport(report) {
|
|
61
|
+
const lines = [];
|
|
62
|
+
if (report.files.length === 0) {
|
|
63
|
+
lines.push("add-github-templates: nothing selected (issue/pr/codeowners all false) \u2014 no files to install.");
|
|
64
|
+
return lines.join("\n");
|
|
65
|
+
}
|
|
66
|
+
if (report.dryRun) {
|
|
67
|
+
lines.push("add-github-templates dry-run \u2014 no files were written.");
|
|
68
|
+
lines.push("");
|
|
69
|
+
for (const file of report.files) {
|
|
70
|
+
lines.push(`${file.filePath}:`);
|
|
71
|
+
lines.push(file.content);
|
|
72
|
+
lines.push("");
|
|
73
|
+
}
|
|
74
|
+
lines.push("Effective decision:");
|
|
75
|
+
}
|
|
76
|
+
for (const file of report.files) {
|
|
77
|
+
lines.push(` ${file.filePath}: ${ACTION_LINES[file.action]}`);
|
|
78
|
+
}
|
|
79
|
+
return lines.join("\n");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/generators/add-github-templates/generator.ts
|
|
83
|
+
var BUG_REPORT_PATH = ".github/ISSUE_TEMPLATE/bug-report.yml";
|
|
84
|
+
var FEATURE_REQUEST_PATH = ".github/ISSUE_TEMPLATE/feature-request.yml";
|
|
85
|
+
var PULL_REQUEST_TEMPLATE_PATH = ".github/PULL_REQUEST_TEMPLATE.md";
|
|
86
|
+
var CODEOWNERS_PATH = ".github/CODEOWNERS";
|
|
87
|
+
function composeGithubTemplates(groups, locale) {
|
|
88
|
+
const files = generatorFilesDir("add-github-templates", import.meta.url);
|
|
89
|
+
return ["issue", "pr", "codeowners"].filter((group) => groups[group]).flatMap((group) => renderTemplateFiles(join(files, locale, group), ".", {}));
|
|
90
|
+
}
|
|
91
|
+
function runAddGithubTemplates(tree, options) {
|
|
92
|
+
const locale = resolveLocaleOption(options.locale, readToolkitConfig(tree));
|
|
93
|
+
const plan = composeGithubTemplates(
|
|
94
|
+
{ issue: options.issue ?? false, pr: options.pr ?? true, codeowners: options.codeowners ?? false },
|
|
95
|
+
locale
|
|
96
|
+
);
|
|
97
|
+
const dryRun = options.dryRun ?? false;
|
|
98
|
+
const files = plan.map(({ filePath, content }) => {
|
|
99
|
+
const existing = tree.read(filePath, "utf-8");
|
|
100
|
+
let action;
|
|
101
|
+
if (existing === null) {
|
|
102
|
+
action = "created";
|
|
103
|
+
if (!dryRun) tree.write(filePath, content);
|
|
104
|
+
} else if (existing === content) {
|
|
105
|
+
action = "unchanged";
|
|
106
|
+
} else {
|
|
107
|
+
action = "skipped";
|
|
108
|
+
}
|
|
109
|
+
return { filePath, action, content };
|
|
110
|
+
});
|
|
111
|
+
return { dryRun, files };
|
|
112
|
+
}
|
|
113
|
+
async function addGithubTemplatesGenerator(tree, options) {
|
|
114
|
+
console.log(renderAddGithubTemplatesReport(runAddGithubTemplates(tree, { ...options, dryRun: resolveDryRun(options) })));
|
|
115
|
+
}
|
|
116
|
+
var generator_default = addGithubTemplatesGenerator;
|
|
117
|
+
export {
|
|
118
|
+
BUG_REPORT_PATH,
|
|
119
|
+
CODEOWNERS_PATH,
|
|
120
|
+
FEATURE_REQUEST_PATH,
|
|
121
|
+
PULL_REQUEST_TEMPLATE_PATH,
|
|
122
|
+
addGithubTemplatesGenerator,
|
|
123
|
+
generator_default as default,
|
|
124
|
+
runAddGithubTemplates
|
|
125
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const ACTION_LINES = {
|
|
2
|
+
created: 'created',
|
|
3
|
+
unchanged: 'unchanged (already matches the generated version)',
|
|
4
|
+
skipped: 'left as-is (a different file already exists there — never overwritten)',
|
|
5
|
+
};
|
|
6
|
+
export function renderAddGithubTemplatesReport(report) {
|
|
7
|
+
const lines = [];
|
|
8
|
+
if (report.files.length === 0) {
|
|
9
|
+
lines.push('add-github-templates: nothing selected (issue/pr/codeowners all false) — no files to install.');
|
|
10
|
+
return lines.join('\n');
|
|
11
|
+
}
|
|
12
|
+
if (report.dryRun) {
|
|
13
|
+
lines.push('add-github-templates dry-run — no files were written.');
|
|
14
|
+
lines.push('');
|
|
15
|
+
for (const file of report.files) {
|
|
16
|
+
lines.push(`${file.filePath}:`);
|
|
17
|
+
lines.push(file.content);
|
|
18
|
+
lines.push('');
|
|
19
|
+
}
|
|
20
|
+
lines.push('Effective decision:');
|
|
21
|
+
}
|
|
22
|
+
for (const file of report.files) {
|
|
23
|
+
lines.push(` ${file.filePath}: ${ACTION_LINES[file.action]}`);
|
|
24
|
+
}
|
|
25
|
+
return lines.join('\n');
|
|
26
|
+
}
|