@craft-ts/dev-tools 0.7.0-beta.13 → 0.7.0-beta.15
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/README.md +64 -10
- package/package.json +8 -2
- package/src/bin/agent-selector.d.ts +22 -0
- package/src/bin/agent-selector.js +100 -0
- package/src/bin/agent-selector.js.map +1 -0
- package/src/bin/craft-graph.js +74 -8
- package/src/bin/craft-graph.js.map +1 -1
- package/src/bin/craft.d.ts +23 -0
- package/src/bin/craft.js +245 -28
- package/src/bin/craft.js.map +1 -1
- package/src/eslint-rules/anchor-has-href.cjs +37 -3
- package/src/eslint-rules/craft-computed-name-match.cjs +26 -5
- package/src/eslint-rules/craft-name-match-utils.cjs +18 -9
- package/src/eslint-rules/hyperscript-walk.cjs +3 -3
- package/src/eslint-rules/index.cjs +46 -1
- package/src/eslint-rules/no-auth-token-in-local-storage.cjs +17 -0
- package/src/eslint-rules/no-craft-computed-side-effects.cjs +12 -5
- package/src/eslint-rules/no-craft-service-component-same-file.cjs +138 -0
- package/src/eslint-rules/no-effect-import-in-frontend.cjs +52 -0
- package/src/eslint-rules/no-effect-in-params.cjs +31 -1
- package/src/eslint-rules/no-explicit-effect-type.cjs +137 -0
- package/src/eslint-rules/no-free-has.cjs +47 -0
- package/src/eslint-rules/no-heading-level-skip.cjs +6 -6
- package/src/eslint-rules/no-raw-class.cjs +76 -0
- package/src/eslint-rules/no-raw-css-value.cjs +163 -0
- package/src/eslint-rules/no-raw-user-url.cjs +114 -0
- package/src/eslint-rules/no-trust-forwarded-headers.cjs +43 -0
- package/src/eslint-rules/no-unsafe-html.cjs +93 -0
- package/src/eslint-rules/no-unsafe-transfer-state.cjs +54 -0
- package/src/eslint-rules/prefer-craft-template-blocks.cjs +8 -8
- package/src/eslint-rules/prefer-direct-yieldable-callback.cjs +57 -14
- package/src/eslint-rules/prefer-inline-effect-insertion.cjs +263 -0
- package/src/eslint-rules/prefer-inline-route-providers.cjs +138 -0
- package/src/eslint-rules/recommended-config.cjs +6 -0
- package/src/eslint-rules/require-reactive-template-bindings.cjs +8 -8
- package/src/eslint-rules/require-route-security-policy.cjs +87 -0
- package/src/eslint-rules/require-server-function-timeout.cjs +39 -0
- package/src/eslint-rules/security-config.cjs +14 -0
- package/src/eslint-rules/security-rule-utils.cjs +21 -0
- package/src/eslint-rules/style-file-boundary.cjs +75 -0
- package/src/eslint-rules/sync-effect-body.cjs +343 -0
- package/src/index.d.ts +4 -0
- package/src/index.js +4 -0
- package/src/index.js.map +1 -1
- package/src/scripts/architecture-graph.js +8 -2
- package/src/scripts/architecture-graph.js.map +1 -1
- package/src/scripts/create/create-project.d.ts +71 -1
- package/src/scripts/create/create-project.js +1937 -176
- package/src/scripts/create/create-project.js.map +1 -1
- package/src/scripts/data-flow-graph.d.ts +1 -1
- package/src/scripts/effect-dependency-graph.d.ts +1 -1
- package/src/scripts/security-check.d.ts +30 -0
- package/src/scripts/security-check.js +223 -0
- package/src/scripts/security-check.js.map +1 -0
- package/src/scripts/style-architecture.d.ts +56 -0
- package/src/scripts/style-architecture.js +142 -0
- package/src/scripts/style-architecture.js.map +1 -0
- package/src/scripts/style-graph.d.ts +99 -0
- package/src/scripts/style-graph.js +179 -0
- package/src/scripts/style-graph.js.map +1 -0
- package/src/scripts/style-report.d.ts +55 -0
- package/src/scripts/style-report.js +67 -0
- package/src/scripts/style-report.js.map +1 -0
- package/src/scripts/template/migrate-template.js +1 -1
- package/src/scripts/template/migrate-template.js.map +1 -1
- package/src/scripts/angular-brand-codemod.ts +0 -3985
- package/src/scripts/architecture/migrate-architecture.ts +0 -653
- package/src/scripts/architecture-graph.ts +0 -3136
- package/src/scripts/components/migrate-components.ts +0 -227
- package/src/scripts/components/migration-diagnostic.ts +0 -8
- package/src/scripts/create/create-project.ts +0 -849
- package/src/scripts/data-flow-graph.ts +0 -240
- package/src/scripts/dependency-graph.ts +0 -5908
- package/src/scripts/effect-dependency-graph.ts +0 -630
- package/src/scripts/migrate.ts +0 -162
- package/src/scripts/migration-workspace.ts +0 -93
- package/src/scripts/primitives/migrate-named-primitives.ts +0 -627
- package/src/scripts/primitives/migrate-primitive-generators.ts +0 -410
- package/src/scripts/primitives/migrate-primitives.ts +0 -655
- package/src/scripts/primitives/migrate-yieldable-reactive-reads.ts +0 -499
- package/src/scripts/primitives/migration-diagnostic.ts +0 -15
- package/src/scripts/routes/migrate-routes.ts +0 -895
- package/src/scripts/routes/migration-diagnostic.ts +0 -25
- package/src/scripts/routes/route-command.ts +0 -1807
- package/src/scripts/routes/verify-routes.ts +0 -1511
- package/src/scripts/services/config.ts +0 -60
- package/src/scripts/services/migrate-services.ts +0 -1348
- package/src/scripts/services/migration-diagnostic.ts +0 -28
- package/src/scripts/template/migrate-template.ts +0 -418
package/README.md
CHANGED
|
@@ -15,20 +15,67 @@ For coding agents, also install
|
|
|
15
15
|
|
|
16
16
|
## Create a project
|
|
17
17
|
|
|
18
|
-
Create a framework-independent CraftTS application from scratch.
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
Create a framework-independent CraftTS application from scratch. Runtime axes,
|
|
19
|
+
i18n, design-system, typed-CSS, server-function, workspace and reference
|
|
20
|
+
choices are normalized into one effective configuration:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npx craft create my-app
|
|
24
|
-
npx craft create my-app --effect=v4 --agents=codex,cursor,
|
|
25
|
-
npx craft create my-app --effect=none --agents=none
|
|
23
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create my-app
|
|
24
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create my-app --effect=v4 --agents=codex,cursor,gemini
|
|
25
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create my-app --effect=none --agents=none
|
|
26
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create my-app --effect=none --i18n=none --design-system=none --no-typed-css
|
|
27
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create my-app --frontend-runtime=effect --backend-runtime=effect --i18n=strict
|
|
28
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create my-app --frontend-runtime=plain --backend-runtime=effect
|
|
29
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create apps/my-app --workspace=nx --references=craft-ts --reference-mode=context
|
|
30
|
+
npx --yes --package @craft-ts/dev-tools@beta craft create apps/my-app --references=craft-ts --reference-mode=source
|
|
26
31
|
```
|
|
27
32
|
|
|
33
|
+
In a terminal, creation is interactive by default. The frontend and backend
|
|
34
|
+
runtimes are selected independently, so `plain` frontend + `effect` backend is
|
|
35
|
+
available for server functions. The prompts also cover i18n locales, the
|
|
36
|
+
workspace, CraftTS/EffectTS source references, and their resolution
|
|
37
|
+
mode. All closed configuration values use keyboard menus: `↑`/`↓` to move
|
|
38
|
+
and `Enter` to confirm; locales and agent integrations additionally use
|
|
39
|
+
`Space` for multi-selection. Codex is selected by default. Pass
|
|
40
|
+
`--yes` after `create` to disable all prompts, or pass
|
|
41
|
+
`--agents=codex,cursor` / `--agents=none` for scripted agent selection.
|
|
42
|
+
|
|
43
|
+
In interactive mode, reference sources are cloned by default; answer `n` to
|
|
44
|
+
opt out. In non-interactive mode, request them explicitly with
|
|
45
|
+
`--references=craft-ts` or `--references=all`.
|
|
46
|
+
|
|
47
|
+
New standalone projects are initialized with Git (without an initial commit)
|
|
48
|
+
and receive a `.gitignore` covering `node_modules/`, build outputs, test
|
|
49
|
+
reports, and local references. If the destination is already inside another
|
|
50
|
+
Git repository, no nested repository is created.
|
|
51
|
+
|
|
52
|
+
Canonical options include `--frontend-runtime=plain|effect`,
|
|
53
|
+
`--backend-runtime=none|promise|effect`, `--effect-scope=none|frontend|backend|both`,
|
|
54
|
+
`--i18n=strict|loose|none`, `--design-system=basic|none`,
|
|
55
|
+
`--typed-css`/`--no-typed-css`, `--workspace=standalone|nx`, and
|
|
56
|
+
`--references=none|craft-ts|all` with `--reference-mode=context|local|source`.
|
|
57
|
+
`--effect=v4|none`, `--locales` and `--default-locale` remain compatible aliases.
|
|
58
|
+
`--json` includes the complete effective configuration.
|
|
59
|
+
|
|
60
|
+
With references enabled, `.references/manifest.json` records the requested ref
|
|
61
|
+
and resolved SHA. `context` keeps npm dependencies portable; `local` is for
|
|
62
|
+
build artifacts from the checked-out references. `source` keeps the scoped
|
|
63
|
+
`@craft-ts/...` imports but resolves them directly to the cloned CraftTS source
|
|
64
|
+
through TypeScript paths and Vite aliases; the CraftTS clone itself does not
|
|
65
|
+
get a `node_modules`. Refresh clones with
|
|
66
|
+
`npm run update:references` (or the generated `update:craft-ts`/
|
|
67
|
+
`update:effect-ts` scripts).
|
|
68
|
+
|
|
69
|
+
`local` builds CraftTS with its Nx library targets and builds the MCP/log
|
|
70
|
+
workspaces individually; CraftTS has no root `npm run build` script.
|
|
71
|
+
|
|
28
72
|
The starter includes a routed page, a typed API call, flat-config ESLint, unit
|
|
29
|
-
tests, a graph-wide `architecture/` suite, Playwright E2E tests,
|
|
30
|
-
|
|
31
|
-
|
|
73
|
+
tests, a graph-wide `architecture/` suite, Playwright E2E tests, development
|
|
74
|
+
logs forwarded to a local JSONL server, `.mcp.json` for Craft/log/page MCP
|
|
75
|
+
servers, a browser type-check indicator, and a GitHub Actions workflow with an
|
|
76
|
+
explicit `npm run typecheck` gate. `codex`, `cursor`, `claude-code`, and the
|
|
77
|
+
`gemini` (with `cloud-code` kept as a compatibility alias) installs the
|
|
78
|
+
corresponding Gemini project instructions.
|
|
32
79
|
|
|
33
80
|
## Project configuration
|
|
34
81
|
|
|
@@ -137,7 +184,14 @@ The rules cover, among other things:
|
|
|
137
184
|
- yieldable reads, writes, methods, and resource triggers;
|
|
138
185
|
- transport access through `CraftHttpClient`;
|
|
139
186
|
- typed route loading, dependency proofs, and exception handling;
|
|
140
|
-
- pure computed values, browser boundaries, and accessibility contracts
|
|
187
|
+
- pure computed values, browser boundaries, and accessibility contracts;
|
|
188
|
+
- the security preset, included in `recommended` and `effect`: unchecked DOM
|
|
189
|
+
URLs, raw HTML, dynamic code, implicit SSR transfer, server functions
|
|
190
|
+
without limits or explicit per-function error exposure, forwarded headers, and
|
|
191
|
+
authentication material in browser storage.
|
|
192
|
+
|
|
193
|
+
Apply the preset alone — on a library or a tooling folder that does not take
|
|
194
|
+
`recommended` — with `craftRules.configs.security`.
|
|
141
195
|
|
|
142
196
|
Run `eslint --fix` after changing generated dependency aliases or route
|
|
143
197
|
metadata. Keep the generated aliases and proofs in the source file so the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@craft-ts/dev-tools",
|
|
3
|
-
"version": "0.7.0-beta.
|
|
3
|
+
"version": "0.7.0-beta.15",
|
|
4
4
|
"description": "Development tools for craft-ts: ESLint configs, ESLint rules, and codemods",
|
|
5
5
|
"author": "Romain Geffrault",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"types": "./src/eslint-rules/index.d.cts",
|
|
25
25
|
"default": "./src/eslint-rules/index.cjs"
|
|
26
26
|
},
|
|
27
|
+
"./style-report": {
|
|
28
|
+
"types": "./src/scripts/style-report.d.ts",
|
|
29
|
+
"default": "./src/scripts/style-report.js"
|
|
30
|
+
},
|
|
27
31
|
"./template-migration": {
|
|
28
32
|
"types": "./src/template-migration.d.ts",
|
|
29
33
|
"default": "./src/template-migration.js"
|
|
@@ -60,6 +64,8 @@
|
|
|
60
64
|
"files": [
|
|
61
65
|
"generators.json",
|
|
62
66
|
"src/**/*",
|
|
67
|
+
"!src/**/*.ts",
|
|
68
|
+
"src/**/*.d.ts",
|
|
63
69
|
"README.md",
|
|
64
70
|
"!src/**/*.spec.ts",
|
|
65
71
|
"!src/**/*.spec.js",
|
|
@@ -74,7 +80,7 @@
|
|
|
74
80
|
"tslib": "^2.3.0",
|
|
75
81
|
"ts-morph": "^24.0.0",
|
|
76
82
|
"ts-node": "^10.9.2",
|
|
77
|
-
"typescript": "
|
|
83
|
+
"typescript": "7.0.2"
|
|
78
84
|
},
|
|
79
85
|
"peerDependencies": {
|
|
80
86
|
"@angular-eslint/eslint-plugin": ">=21.0.0",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CreateAgent } from '../scripts/create/create-project.js';
|
|
2
|
+
export declare const CREATE_AGENT_OPTIONS: readonly {
|
|
3
|
+
readonly value: CreateAgent;
|
|
4
|
+
readonly label: string;
|
|
5
|
+
}[];
|
|
6
|
+
export type InteractiveOption<Value extends string> = {
|
|
7
|
+
readonly value: Value;
|
|
8
|
+
readonly label: string;
|
|
9
|
+
};
|
|
10
|
+
export type AgentSelectorInput = NodeJS.ReadStream & {
|
|
11
|
+
setRawMode(mode: boolean): NodeJS.ReadStream;
|
|
12
|
+
};
|
|
13
|
+
type AgentSelectorOutput = Pick<NodeJS.WriteStream, 'write'>;
|
|
14
|
+
export declare function selectOptionInteractively<Value extends string>(options: readonly InteractiveOption<Value>[], title: string, initialValue: Value, input?: AgentSelectorInput, output?: AgentSelectorOutput): Promise<Value>;
|
|
15
|
+
export declare function selectOptionsInteractively<Value extends string>(options: readonly InteractiveOption<Value>[], title: string, initialSelection: readonly Value[], input?: AgentSelectorInput, output?: AgentSelectorOutput, minimumSelection?: number): Promise<readonly Value[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Let a user select the integrations for which project skills are generated.
|
|
18
|
+
* The input is deliberately kept injectable so the keyboard state machine can
|
|
19
|
+
* be exercised without spawning a terminal in tests.
|
|
20
|
+
*/
|
|
21
|
+
export declare function selectAgentsInteractively(input?: AgentSelectorInput, output?: AgentSelectorOutput, initialSelection?: readonly CreateAgent[]): Promise<readonly CreateAgent[]>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { emitKeypressEvents } from 'node:readline';
|
|
2
|
+
export const CREATE_AGENT_OPTIONS = [
|
|
3
|
+
{ value: 'codex', label: 'Codex' },
|
|
4
|
+
{ value: 'cursor', label: 'Cursor' },
|
|
5
|
+
{ value: 'claude-code', label: 'Claude Code' },
|
|
6
|
+
{ value: 'cloud-code', label: 'Gemini CLI' },
|
|
7
|
+
];
|
|
8
|
+
function selectValuesInteractively(options, title, initialSelection, multiple, input, output, minimumSelection = 0) {
|
|
9
|
+
const selected = new Set(initialSelection);
|
|
10
|
+
let cursor = Math.max(0, options.findIndex((option) => selected.has(option.value)));
|
|
11
|
+
let rendered = false;
|
|
12
|
+
const render = () => {
|
|
13
|
+
if (rendered)
|
|
14
|
+
output.write(`\u001b[${options.length + 1}A`);
|
|
15
|
+
output.write(`${title}\n`);
|
|
16
|
+
for (const [index, option] of options.entries()) {
|
|
17
|
+
const pointer = index === cursor ? '❯' : ' ';
|
|
18
|
+
const marker = multiple ? `${selected.has(option.value) ? '[x]' : '[ ]'} ` : '';
|
|
19
|
+
output.write(`${pointer} ${marker}${option.label}\n`);
|
|
20
|
+
}
|
|
21
|
+
rendered = true;
|
|
22
|
+
};
|
|
23
|
+
return new Promise((resolve, reject) => {
|
|
24
|
+
const wasRaw = input.isRaw ?? false;
|
|
25
|
+
const finish = (result) => {
|
|
26
|
+
input.removeListener('keypress', onKeypress);
|
|
27
|
+
input.setRawMode(wasRaw);
|
|
28
|
+
input.pause();
|
|
29
|
+
output.write('\n');
|
|
30
|
+
resolve(result);
|
|
31
|
+
};
|
|
32
|
+
const cancel = () => {
|
|
33
|
+
input.removeListener('keypress', onKeypress);
|
|
34
|
+
input.setRawMode(wasRaw);
|
|
35
|
+
input.pause();
|
|
36
|
+
output.write('\n');
|
|
37
|
+
reject(new Error('Interactive selection cancelled.'));
|
|
38
|
+
};
|
|
39
|
+
const onKeypress = (_input, key) => {
|
|
40
|
+
if (key.ctrl && key.name === 'c') {
|
|
41
|
+
cancel();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (key.name === 'up') {
|
|
45
|
+
cursor = (cursor - 1 + options.length) % options.length;
|
|
46
|
+
render();
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (key.name === 'down') {
|
|
50
|
+
cursor = (cursor + 1) % options.length;
|
|
51
|
+
render();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (multiple && key.name === 'space') {
|
|
55
|
+
const value = options[cursor].value;
|
|
56
|
+
if (selected.has(value)) {
|
|
57
|
+
if (selected.size > minimumSelection)
|
|
58
|
+
selected.delete(value);
|
|
59
|
+
}
|
|
60
|
+
else
|
|
61
|
+
selected.add(value);
|
|
62
|
+
render();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (key.name === 'return' || key.name === 'enter') {
|
|
66
|
+
finish(multiple
|
|
67
|
+
? options.map((option) => option.value).filter((value) => selected.has(value))
|
|
68
|
+
: [options[cursor].value]);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
try {
|
|
72
|
+
emitKeypressEvents(input);
|
|
73
|
+
input.setRawMode(true);
|
|
74
|
+
input.setEncoding('utf8');
|
|
75
|
+
input.resume();
|
|
76
|
+
input.on('keypress', onKeypress);
|
|
77
|
+
render();
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
cancel();
|
|
81
|
+
reject(error);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
export function selectOptionInteractively(options, title, initialValue, input = process.stdin, output = process.stdout) {
|
|
86
|
+
return selectValuesInteractively(options, title, [initialValue], false, input, output)
|
|
87
|
+
.then(([value]) => value);
|
|
88
|
+
}
|
|
89
|
+
export function selectOptionsInteractively(options, title, initialSelection, input = process.stdin, output = process.stdout, minimumSelection = 0) {
|
|
90
|
+
return selectValuesInteractively(options, title, initialSelection, true, input, output, minimumSelection);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Let a user select the integrations for which project skills are generated.
|
|
94
|
+
* The input is deliberately kept injectable so the keyboard state machine can
|
|
95
|
+
* be exercised without spawning a terminal in tests.
|
|
96
|
+
*/
|
|
97
|
+
export function selectAgentsInteractively(input = process.stdin, output = process.stdout, initialSelection = ['codex']) {
|
|
98
|
+
return selectOptionsInteractively(CREATE_AGENT_OPTIONS, 'Select agent skills (↑/↓ move, Space toggle, Enter confirm):', initialSelection, input, output);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=agent-selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-selector.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/bin/agent-selector.ts"],"names":[],"mappings":"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"}
|
package/src/bin/craft-graph.js
CHANGED
|
@@ -1,5 +1,56 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
2
3
|
import { writeDependencyGraph, } from '../scripts/dependency-graph.js';
|
|
4
|
+
import { styleDebt, styleImpact, styleMatrix, } from '../scripts/style-report.js';
|
|
5
|
+
const DEFAULT_STYLE_DUMP = 'tmp/craft-style-graph.json';
|
|
6
|
+
/**
|
|
7
|
+
* The style questions answer from the dump alone.
|
|
8
|
+
*
|
|
9
|
+
* They deliberately do **not** build the TypeScript program: the whole point of
|
|
10
|
+
* asking "what does this token change affect?" is to answer it in the time it
|
|
11
|
+
* takes to decide whether to run the visual suite. A question that costs a full
|
|
12
|
+
* typecheck gets asked once and then never again.
|
|
13
|
+
*/
|
|
14
|
+
function runStyleQuery(argv) {
|
|
15
|
+
const impacted = [];
|
|
16
|
+
let dumpPath = DEFAULT_STYLE_DUMP;
|
|
17
|
+
let mode;
|
|
18
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
19
|
+
switch (argv[index]) {
|
|
20
|
+
case '--impacted':
|
|
21
|
+
mode = 'impacted';
|
|
22
|
+
impacted.push(argv[++index]);
|
|
23
|
+
break;
|
|
24
|
+
case '--style-matrix':
|
|
25
|
+
mode = 'matrix';
|
|
26
|
+
break;
|
|
27
|
+
case '--style-debt':
|
|
28
|
+
mode = 'debt';
|
|
29
|
+
break;
|
|
30
|
+
case '--style-dump':
|
|
31
|
+
dumpPath = argv[++index];
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!mode)
|
|
38
|
+
return false;
|
|
39
|
+
let dump;
|
|
40
|
+
try {
|
|
41
|
+
dump = JSON.parse(readFileSync(dumpPath, 'utf8'));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new Error(`craft-graph: no style dump at '${dumpPath}'. It is written by the build plugin — give craftStyle({ dumpPath }) a path, run a build, or point at it with --style-dump.`);
|
|
45
|
+
}
|
|
46
|
+
const report = mode === 'impacted'
|
|
47
|
+
? styleImpact(dump, impacted)
|
|
48
|
+
: mode === 'matrix'
|
|
49
|
+
? styleMatrix(dump)
|
|
50
|
+
: styleDebt(dump);
|
|
51
|
+
console.log(JSON.stringify(report, null, 2));
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
3
54
|
function parseArgs(argv) {
|
|
4
55
|
const options = {
|
|
5
56
|
rootDir: process.cwd(),
|
|
@@ -34,6 +85,9 @@ function parseArgs(argv) {
|
|
|
34
85
|
case '--include':
|
|
35
86
|
options.include = [...(options.include ?? []), argv[++index]];
|
|
36
87
|
break;
|
|
88
|
+
case '--style-dump':
|
|
89
|
+
index += 1;
|
|
90
|
+
break;
|
|
37
91
|
case '--help':
|
|
38
92
|
case '-h':
|
|
39
93
|
printHelp();
|
|
@@ -59,14 +113,26 @@ Options:
|
|
|
59
113
|
json/both/all also write a .architecture.ts catalog.
|
|
60
114
|
html creates one self-contained visualizer file.
|
|
61
115
|
--include <text> Restrict analysis to source paths containing text.
|
|
116
|
+
|
|
117
|
+
Style queries, answered from the emitted dump without building the program:
|
|
118
|
+
--impacted <--x> Sheet classes a change to that custom property
|
|
119
|
+
can be seen in. Repeatable. Falls back to "all"
|
|
120
|
+
— and says so — for a name the graph does not know.
|
|
121
|
+
--style-matrix What the application costs to capture.
|
|
122
|
+
--style-debt Escape hatches, unmet obligations, dangling
|
|
123
|
+
variables, and the components nobody styles.
|
|
124
|
+
--style-dump <path> Defaults to ${DEFAULT_STYLE_DUMP}.
|
|
62
125
|
`);
|
|
63
126
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
127
|
+
const argv = process.argv.slice(2);
|
|
128
|
+
if (!runStyleQuery(argv)) {
|
|
129
|
+
writeDependencyGraph(parseArgs(argv))
|
|
130
|
+
.then((graph) => {
|
|
131
|
+
console.log(`Craft graph written: ${graph.nodes.length} nodes, ${graph.edges.length} edges.`);
|
|
132
|
+
})
|
|
133
|
+
.catch((error) => {
|
|
134
|
+
console.error(error instanceof Error ? error.message : error);
|
|
135
|
+
process.exitCode = 1;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
72
138
|
//# sourceMappingURL=craft-graph.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"craft-graph.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/bin/craft-graph.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,oBAAoB,GAErB,MAAM,gCAAgC,CAAC;AAExC,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,OAAO,GAAgC;QAC3C,OAAO,EAAE,OAAO,CAAC,GAAG,EAAE;QACtB,UAAU,EAAE,wBAAwB;QACpC,MAAM,EAAE,MAAM;KACf,CAAC;IACF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,WAAW,CAAC;YACjB,KAAK,YAAY;gBACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBACzC,MAAM;YACR,KAAK,QAAQ;gBACX,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBAChC,MAAM;YACR,KAAK,OAAO;gBACV,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBACnC,MAAM;YACR,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,CAAC,CAAC;gBAC7B,IACE,MAAM,KAAK,MAAM;oBACjB,MAAM,KAAK,SAAS;oBACpB,MAAM,KAAK,MAAM;oBACjB,MAAM,KAAK,MAAM;oBACjB,MAAM,KAAK,KAAK,EAChB,CAAC;oBACD,MAAM,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"craft-graph.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/bin/craft-graph.ts"],"names":[],"mappings":"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"}
|
package/src/bin/craft.d.ts
CHANGED
|
@@ -1,2 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
type CreateArgs = {
|
|
3
|
+
directory?: string;
|
|
4
|
+
effect?: string;
|
|
5
|
+
frontendRuntime?: 'plain' | 'effect';
|
|
6
|
+
backendRuntime?: 'none' | 'promise' | 'effect';
|
|
7
|
+
effectScope?: 'none' | 'frontend' | 'backend' | 'both';
|
|
8
|
+
agents?: string;
|
|
9
|
+
locales?: string;
|
|
10
|
+
defaultLocale?: string;
|
|
11
|
+
i18n?: 'strict' | 'loose' | 'none';
|
|
12
|
+
designSystem?: 'basic' | 'none';
|
|
13
|
+
typedCss?: boolean;
|
|
14
|
+
workspace?: 'standalone' | 'nx';
|
|
15
|
+
references?: 'none' | 'craft-ts' | 'all';
|
|
16
|
+
referenceMode?: 'context' | 'local' | 'source';
|
|
17
|
+
craftTsRef?: string;
|
|
18
|
+
effectTsRef?: string;
|
|
19
|
+
cloneCraftTs?: boolean;
|
|
20
|
+
cloneEffectTs?: boolean;
|
|
21
|
+
flags: Set<string>;
|
|
22
|
+
help: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare function parseCreateArgs(argv: string[]): CreateArgs;
|
|
2
25
|
export {};
|