@craft-ts/dev-tools 0.7.0-beta.13 → 0.7.0-beta.16

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 (89) hide show
  1. package/README.md +60 -10
  2. package/package.json +8 -2
  3. package/src/bin/agent-selector.d.ts +22 -0
  4. package/src/bin/agent-selector.js +100 -0
  5. package/src/bin/agent-selector.js.map +1 -0
  6. package/src/bin/craft-graph.js +74 -8
  7. package/src/bin/craft-graph.js.map +1 -1
  8. package/src/bin/craft.d.ts +22 -0
  9. package/src/bin/craft.js +231 -28
  10. package/src/bin/craft.js.map +1 -1
  11. package/src/eslint-rules/anchor-has-href.cjs +37 -3
  12. package/src/eslint-rules/craft-computed-name-match.cjs +26 -5
  13. package/src/eslint-rules/craft-name-match-utils.cjs +18 -9
  14. package/src/eslint-rules/hyperscript-walk.cjs +3 -3
  15. package/src/eslint-rules/index.cjs +46 -1
  16. package/src/eslint-rules/no-auth-token-in-local-storage.cjs +17 -0
  17. package/src/eslint-rules/no-craft-computed-side-effects.cjs +12 -5
  18. package/src/eslint-rules/no-craft-service-component-same-file.cjs +138 -0
  19. package/src/eslint-rules/no-effect-import-in-frontend.cjs +52 -0
  20. package/src/eslint-rules/no-effect-in-params.cjs +31 -1
  21. package/src/eslint-rules/no-explicit-effect-type.cjs +137 -0
  22. package/src/eslint-rules/no-free-has.cjs +47 -0
  23. package/src/eslint-rules/no-heading-level-skip.cjs +6 -6
  24. package/src/eslint-rules/no-raw-class.cjs +76 -0
  25. package/src/eslint-rules/no-raw-css-value.cjs +163 -0
  26. package/src/eslint-rules/no-raw-user-url.cjs +114 -0
  27. package/src/eslint-rules/no-trust-forwarded-headers.cjs +43 -0
  28. package/src/eslint-rules/no-unsafe-html.cjs +93 -0
  29. package/src/eslint-rules/no-unsafe-transfer-state.cjs +54 -0
  30. package/src/eslint-rules/prefer-craft-template-blocks.cjs +8 -8
  31. package/src/eslint-rules/prefer-direct-yieldable-callback.cjs +57 -14
  32. package/src/eslint-rules/prefer-inline-effect-insertion.cjs +263 -0
  33. package/src/eslint-rules/prefer-inline-route-providers.cjs +138 -0
  34. package/src/eslint-rules/recommended-config.cjs +6 -0
  35. package/src/eslint-rules/require-reactive-template-bindings.cjs +8 -8
  36. package/src/eslint-rules/require-route-security-policy.cjs +87 -0
  37. package/src/eslint-rules/require-server-function-timeout.cjs +39 -0
  38. package/src/eslint-rules/security-config.cjs +14 -0
  39. package/src/eslint-rules/security-rule-utils.cjs +21 -0
  40. package/src/eslint-rules/style-file-boundary.cjs +75 -0
  41. package/src/eslint-rules/sync-effect-body.cjs +343 -0
  42. package/src/index.d.ts +4 -0
  43. package/src/index.js +4 -0
  44. package/src/index.js.map +1 -1
  45. package/src/scripts/architecture-graph.js +8 -2
  46. package/src/scripts/architecture-graph.js.map +1 -1
  47. package/src/scripts/create/create-project.d.ts +60 -1
  48. package/src/scripts/create/create-project.js +2082 -184
  49. package/src/scripts/create/create-project.js.map +1 -1
  50. package/src/scripts/data-flow-graph.d.ts +1 -1
  51. package/src/scripts/effect-dependency-graph.d.ts +1 -1
  52. package/src/scripts/security-check.d.ts +30 -0
  53. package/src/scripts/security-check.js +223 -0
  54. package/src/scripts/security-check.js.map +1 -0
  55. package/src/scripts/style-architecture.d.ts +56 -0
  56. package/src/scripts/style-architecture.js +142 -0
  57. package/src/scripts/style-architecture.js.map +1 -0
  58. package/src/scripts/style-graph.d.ts +99 -0
  59. package/src/scripts/style-graph.js +179 -0
  60. package/src/scripts/style-graph.js.map +1 -0
  61. package/src/scripts/style-report.d.ts +55 -0
  62. package/src/scripts/style-report.js +67 -0
  63. package/src/scripts/style-report.js.map +1 -0
  64. package/src/scripts/template/migrate-template.js +1 -1
  65. package/src/scripts/template/migrate-template.js.map +1 -1
  66. package/src/scripts/angular-brand-codemod.ts +0 -3985
  67. package/src/scripts/architecture/migrate-architecture.ts +0 -653
  68. package/src/scripts/architecture-graph.ts +0 -3136
  69. package/src/scripts/components/migrate-components.ts +0 -227
  70. package/src/scripts/components/migration-diagnostic.ts +0 -8
  71. package/src/scripts/create/create-project.ts +0 -849
  72. package/src/scripts/data-flow-graph.ts +0 -240
  73. package/src/scripts/dependency-graph.ts +0 -5908
  74. package/src/scripts/effect-dependency-graph.ts +0 -630
  75. package/src/scripts/migrate.ts +0 -162
  76. package/src/scripts/migration-workspace.ts +0 -93
  77. package/src/scripts/primitives/migrate-named-primitives.ts +0 -627
  78. package/src/scripts/primitives/migrate-primitive-generators.ts +0 -410
  79. package/src/scripts/primitives/migrate-primitives.ts +0 -655
  80. package/src/scripts/primitives/migrate-yieldable-reactive-reads.ts +0 -499
  81. package/src/scripts/primitives/migration-diagnostic.ts +0 -15
  82. package/src/scripts/routes/migrate-routes.ts +0 -895
  83. package/src/scripts/routes/migration-diagnostic.ts +0 -25
  84. package/src/scripts/routes/route-command.ts +0 -1807
  85. package/src/scripts/routes/verify-routes.ts +0 -1511
  86. package/src/scripts/services/config.ts +0 -60
  87. package/src/scripts/services/migrate-services.ts +0 -1348
  88. package/src/scripts/services/migration-diagnostic.ts +0 -28
  89. package/src/scripts/template/migrate-template.ts +0 -418
@@ -1,240 +0,0 @@
1
- import {
2
- Node,
3
- SyntaxKind,
4
- type CallExpression,
5
- type SourceFile,
6
- type VariableDeclaration,
7
- } from 'ts-morph';
8
- import type {
9
- DependencyGraphEdge,
10
- DependencyGraphNode,
11
- DependencyGraphProof,
12
- } from './dependency-graph';
13
-
14
- export interface DataClassificationNodeDetails {
15
- readonly classification: string;
16
- readonly source: 'schema-annotation';
17
- readonly schemaName: string;
18
- }
19
-
20
- export interface ExternalOutputNodeDetails {
21
- readonly boundary: 'server-function-response';
22
- readonly serverFunctionId?: string;
23
- readonly schemaName?: string;
24
- readonly classifications: readonly string[];
25
- }
26
-
27
- export interface DataFlowRelationDetails {
28
- readonly classification: string;
29
- readonly resolution: 'static' | 'unknown';
30
- }
31
-
32
- declare module './dependency-graph' {
33
- interface DependencyGraphNodeRegistry {
34
- 'data-classification': DataClassificationNodeDetails;
35
- 'external-output': ExternalOutputNodeDetails;
36
- }
37
-
38
- interface DependencyGraphEdgeRegistry {
39
- 'exposes-data': DataFlowRelationDetails;
40
- 'flows-data': DataFlowRelationDetails;
41
- }
42
- }
43
-
44
- type SchemaInfo = {
45
- readonly declaration: VariableDeclaration;
46
- readonly filePath: string;
47
- readonly name: string;
48
- readonly classifications: Set<string>;
49
- };
50
-
51
- const classificationId = (filePath: string, name: string, value: string) =>
52
- `data-classification:${filePath}#${name}:${value}`;
53
-
54
- const outputId = (filePath: string, line: number) =>
55
- `external-output:${filePath}:${line}`;
56
-
57
- /**
58
- * Extracts schema annotations and server-function response boundaries. The
59
- * propagation is intentionally conservative: only statically named schema
60
- * variables are followed, and no transform is assumed to remove sensitivity.
61
- */
62
- export function collectDataFlowGraph(
63
- sourceFiles: readonly SourceFile[],
64
- ): { nodes: DependencyGraphNode[]; edges: DependencyGraphEdge[] } {
65
- const nodes = new Map<string, DependencyGraphNode>();
66
- const edges = new Map<string, DependencyGraphEdge>();
67
- const schemas = new Map<string, SchemaInfo>();
68
- const schemaByName = new Map<string, SchemaInfo[]>();
69
-
70
- const addNode = (node: DependencyGraphNode) => {
71
- if (!nodes.has(node.id)) nodes.set(node.id, node);
72
- };
73
- const addEdge = (edge: DependencyGraphEdge) => {
74
- const key = `${edge.from}:${edge.kind}:${edge.to}`;
75
- if (!edges.has(key)) edges.set(key, edge);
76
- };
77
- const proof = (node: Node, pattern: string): DependencyGraphProof => ({
78
- filePath: node.getSourceFile().getFilePath(),
79
- line: node.getStartLineNumber(),
80
- pattern,
81
- });
82
-
83
- for (const sourceFile of sourceFiles) {
84
- for (const declaration of sourceFile.getVariableDeclarations()) {
85
- const initializer = declaration.getInitializer();
86
- if (!initializer || !containsSchema(initializer)) continue;
87
- const name = declaration.getName();
88
- const info: SchemaInfo = {
89
- declaration,
90
- filePath: sourceFile.getFilePath(),
91
- name,
92
- classifications: new Set(findSchemaAnnotations(initializer)),
93
- };
94
- schemas.set(`${sourceFile.getFilePath()}#${name}`, info);
95
- schemaByName.set(name, [...(schemaByName.get(name) ?? []), info]);
96
- }
97
- }
98
-
99
- const classifications = new Map<string, { schema: SchemaInfo; value: string; node: Node }>();
100
- for (const info of schemas.values()) {
101
- for (const value of info.classifications) {
102
- const annotation = findSchemaAnnotation(info.declaration.getInitializer(), value);
103
- if (!annotation) continue;
104
- classifications.set(`${info.filePath}#${info.name}:${value}`, {
105
- schema: info,
106
- value,
107
- node: annotation,
108
- });
109
- addNode({
110
- id: classificationId(info.filePath, info.name, value),
111
- kind: 'data-classification',
112
- label: `${info.name} [${value}]`,
113
- filePath: info.filePath,
114
- line: info.declaration.getStartLineNumber(),
115
- details: {
116
- classification: value,
117
- source: 'schema-annotation',
118
- schemaName: info.name,
119
- },
120
- });
121
- }
122
- }
123
-
124
- const classificationsFor = (info: SchemaInfo, seen = new Set<string>()): Set<string> => {
125
- const key = `${info.filePath}#${info.name}`;
126
- if (seen.has(key)) return new Set();
127
- const nextSeen = new Set([...seen, key]);
128
- const result = new Set(info.classifications);
129
- const initializer = info.declaration.getInitializer();
130
- if (!initializer) return result;
131
- for (const identifier of initializer.getDescendantsOfKind(SyntaxKind.Identifier)) {
132
- for (const target of schemaByName.get(identifier.getText()) ?? []) {
133
- for (const value of classificationsFor(target, nextSeen)) result.add(value);
134
- }
135
- }
136
- return result;
137
- };
138
-
139
- for (const sourceFile of sourceFiles) {
140
- if (!sourceFile.getBaseName().endsWith('.fn-serveur.ts')) continue;
141
- const serverFunction = sourceFile
142
- .getDescendantsOfKind(SyntaxKind.CallExpression)
143
- .find((call) => call.getExpression().getText() === 'serverFunction');
144
- if (!serverFunction) continue;
145
- const id = serverFunction
146
- .getArguments()[0]
147
- ?.asKind(SyntaxKind.StringLiteral)
148
- ?.getLiteralValue();
149
- const options = serverFunction
150
- .getArguments()[2]
151
- ?.asKind(SyntaxKind.ObjectLiteralExpression);
152
- const output = options
153
- ?.getProperty('output')
154
- ?.asKind(SyntaxKind.PropertyAssignment)
155
- ?.getInitializer();
156
- if (!output) continue;
157
- const schemaName = output.asKind(SyntaxKind.Identifier)?.getText();
158
- const schema = schemaName
159
- ? [...(schemaByName.get(schemaName) ?? [])][0]
160
- : undefined;
161
- const values = schema ? [...classificationsFor(schema)] : [];
162
- const outputNode: DependencyGraphNode = {
163
- id: outputId(sourceFile.getFilePath(), serverFunction.getStartLineNumber()),
164
- kind: 'external-output',
165
- label: `${id ?? 'server-function'} response`,
166
- filePath: sourceFile.getFilePath(),
167
- line: serverFunction.getStartLineNumber(),
168
- details: {
169
- boundary: 'server-function-response',
170
- ...(id === undefined ? {} : { serverFunctionId: id }),
171
- ...(schemaName === undefined ? {} : { schemaName }),
172
- classifications: values,
173
- },
174
- };
175
- addNode(outputNode);
176
-
177
- for (const value of values) {
178
- const source = [...classifications.values()].find(
179
- (candidate) => candidate.value === value &&
180
- classificationsFor(candidate.schema).has(value),
181
- );
182
- if (!source) continue;
183
- addEdge({
184
- from: classificationId(source.schema.filePath, source.schema.name, value),
185
- to: outputNode.id,
186
- kind: 'exposes-data',
187
- evidence: 'ast',
188
- details: { classification: value, resolution: 'static' },
189
- proof: proof(output, `server function output: ${schemaName ?? 'unknown schema'}`),
190
- });
191
- }
192
- }
193
-
194
- return { nodes: [...nodes.values()], edges: [...edges.values()] };
195
- }
196
-
197
- function containsSchema(node: Node): boolean {
198
- return [
199
- ...(Node.isCallExpression(node) ? [node] : []),
200
- ...node.getDescendantsOfKind(SyntaxKind.CallExpression),
201
- ].some((call) => call.getExpression().getText().startsWith('Schema.'));
202
- }
203
-
204
- function findSchemaAnnotations(node: Node): string[] {
205
- const values = new Set<string>();
206
- for (const call of [
207
- ...(Node.isCallExpression(node) ? [node] : []),
208
- ...node.getDescendantsOfKind(SyntaxKind.CallExpression),
209
- ]) {
210
- const value = readSensitivity(call);
211
- if (value) values.add(value);
212
- }
213
- return [...values];
214
- }
215
-
216
- function findSchemaAnnotation(node: Node | undefined, value: string): Node | undefined {
217
- if (!node) return undefined;
218
- return [
219
- ...(Node.isCallExpression(node) ? [node] : []),
220
- ...node.getDescendantsOfKind(SyntaxKind.CallExpression),
221
- ].find((call) => readSensitivity(call) === value);
222
- }
223
-
224
- function readSensitivity(call: CallExpression): string | undefined {
225
- // Effect expose l'annotation en méthode (`Schema.String.annotate({ … })`) ;
226
- // `annotations` reste accepté pour les variantes qui l'orthographient ainsi.
227
- const callee = call.getExpression().getText();
228
- if (!callee.endsWith('annotate') && !callee.endsWith('annotations')) {
229
- return undefined;
230
- }
231
- const object = call
232
- .getArguments()[0]
233
- ?.asKind(SyntaxKind.ObjectLiteralExpression);
234
- return object
235
- ?.getProperty('sensitivity')
236
- ?.asKind(SyntaxKind.PropertyAssignment)
237
- ?.getInitializer()
238
- ?.asKind(SyntaxKind.StringLiteral)
239
- ?.getLiteralValue();
240
- }