@craft-ng/dev-tools 0.5.1-beta.0 → 0.6.0-beta.2
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 +66 -0
- package/generators.json +26 -0
- package/package.json +18 -1
- package/src/bin/craft.d.ts +2 -0
- package/src/bin/craft.js +166 -0
- package/src/bin/craft.js.map +1 -0
- package/src/eslint-rules/craft-computed-name-match.cjs +8 -125
- package/src/eslint-rules/craft-method-name-match.cjs +8 -166
- package/src/eslint-rules/craft-name-match-utils.cjs +179 -0
- package/src/eslint-rules/craft-signal-source-name-match.cjs +8 -0
- package/src/eslint-rules/craft-source-name-match.cjs +8 -0
- package/src/eslint-rules/global-exception-registry-match.cjs +78 -13
- package/src/eslint-rules/index.cjs +8 -2
- package/src/eslint-rules/require-cascade-route-di-check.cjs +223 -0
- package/src/eslint-rules/require-primitive-generator-unwrap.cjs +267 -0
- package/src/generators/route/compat.d.ts +3 -0
- package/src/generators/route/compat.js +6 -0
- package/src/generators/route/compat.js.map +1 -0
- package/src/generators/route/generator.d.ts +31 -0
- package/src/generators/route/generator.js +434 -0
- package/src/generators/route/generator.js.map +1 -0
- package/src/generators/route/schema.json +50 -0
- package/src/generators/route/split-schema.json +19 -0
- package/src/index.d.ts +1 -0
- package/src/index.js +1 -0
- package/src/index.js.map +1 -1
- package/src/scripts/primitives/migrate-primitive-generators.d.ts +27 -0
- package/src/scripts/primitives/migrate-primitive-generators.js +315 -0
- package/src/scripts/primitives/migrate-primitive-generators.js.map +1 -0
- package/src/scripts/primitives/migrate-primitive-generators.ts +402 -0
- package/src/scripts/primitives/migrate-primitives.js +36 -4
- package/src/scripts/primitives/migrate-primitives.js.map +1 -1
- package/src/scripts/primitives/migrate-primitives.spec.ts +43 -0
- package/src/scripts/primitives/migrate-primitives.ts +62 -4
- package/src/scripts/primitives/migration-diagnostic.d.ts +1 -1
- package/src/scripts/primitives/migration-diagnostic.ts +1 -0
- package/src/scripts/routes/migrate-routes.js +4 -4
- package/src/scripts/routes/migrate-routes.js.map +1 -1
- package/src/scripts/routes/migrate-routes.ts +4 -6
- package/src/scripts/routes/route-command.d.ts +75 -0
- package/src/scripts/routes/route-command.js +1187 -0
- package/src/scripts/routes/route-command.js.map +1 -0
- package/src/scripts/routes/route-command.spec.ts +553 -0
- package/src/scripts/routes/route-command.ts +1790 -0
- package/src/scripts/services/migrate-services.js +45 -11
- package/src/scripts/services/migrate-services.js.map +1 -1
- package/src/scripts/services/migrate-services.spec.ts +46 -4
- package/src/scripts/services/migrate-services.ts +64 -13
- package/src/scripts/services/migration-diagnostic.d.ts +1 -1
- package/src/scripts/services/migration-diagnostic.ts +1 -0
- package/src/eslint-rules/require-track-on-dependent-primitives.cjs +0 -219
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
const DEFAULT_PRIMITIVES = [
|
|
2
|
-
'mutation',
|
|
3
|
-
'query',
|
|
4
|
-
'asyncProcess',
|
|
5
|
-
'state',
|
|
6
|
-
'craftMethod',
|
|
7
|
-
];
|
|
8
|
-
|
|
9
|
-
module.exports = {
|
|
10
|
-
meta: {
|
|
11
|
-
type: 'problem',
|
|
12
|
-
docs: {
|
|
13
|
-
description:
|
|
14
|
-
'Require primitives that carry dependencies to be yielded with `yield* track(...)` inside a craftService so their dependencies are detected.',
|
|
15
|
-
},
|
|
16
|
-
fixable: 'code',
|
|
17
|
-
schema: [
|
|
18
|
-
{
|
|
19
|
-
type: 'object',
|
|
20
|
-
properties: {
|
|
21
|
-
primitives: {
|
|
22
|
-
type: 'array',
|
|
23
|
-
items: { type: 'string' },
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
additionalProperties: false,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
messages: {
|
|
30
|
-
requireTrack:
|
|
31
|
-
"'{{name}}(...)' uses dependencies (it yields) and must be yielded with `yield* track({{name}}(...))` so the enclosing craftService tracks them.",
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
create(context) {
|
|
35
|
-
const options = context.options[0] ?? {};
|
|
36
|
-
const primitives = new Set(options.primitives ?? DEFAULT_PRIMITIVES);
|
|
37
|
-
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
38
|
-
|
|
39
|
-
return {
|
|
40
|
-
CallExpression(node) {
|
|
41
|
-
if (
|
|
42
|
-
node.callee.type !== 'Identifier' ||
|
|
43
|
-
!primitives.has(node.callee.name)
|
|
44
|
-
) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!isInsideCraftService(node)) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// `yield* track(...)` is only legal when the directly enclosing factory
|
|
53
|
-
// is a generator. Non-generator factories (e.g. `(inputs) => {...}`)
|
|
54
|
-
// cannot yield, so the rule does not apply there.
|
|
55
|
-
if (!isInsideGeneratorFactory(node)) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// "Has dependencies" heuristic: the primitive config yields something.
|
|
60
|
-
if (!argumentsContainYield(node)) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (isAlreadyTracked(node)) {
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const primitiveName = node.callee.name;
|
|
69
|
-
|
|
70
|
-
context.report({
|
|
71
|
-
node,
|
|
72
|
-
messageId: 'requireTrack',
|
|
73
|
-
data: { name: primitiveName },
|
|
74
|
-
fix(fixer) {
|
|
75
|
-
const fixes = [
|
|
76
|
-
fixer.replaceText(
|
|
77
|
-
node,
|
|
78
|
-
`yield* track(${sourceCode.getText(node)})`,
|
|
79
|
-
),
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
const importFix = createTrackImportFix(fixer, sourceCode);
|
|
83
|
-
if (importFix) {
|
|
84
|
-
fixes.push(importFix);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return fixes;
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
function isInsideCraftService(node) {
|
|
96
|
-
let current = node.parent;
|
|
97
|
-
while (current) {
|
|
98
|
-
if (
|
|
99
|
-
current.type === 'CallExpression' &&
|
|
100
|
-
current.callee.type === 'Identifier' &&
|
|
101
|
-
current.callee.name === 'craftService'
|
|
102
|
-
) {
|
|
103
|
-
return true;
|
|
104
|
-
}
|
|
105
|
-
current = current.parent;
|
|
106
|
-
}
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function isInsideGeneratorFactory(node) {
|
|
111
|
-
let current = node.parent;
|
|
112
|
-
while (current) {
|
|
113
|
-
if (
|
|
114
|
-
current.type === 'FunctionDeclaration' ||
|
|
115
|
-
current.type === 'FunctionExpression' ||
|
|
116
|
-
current.type === 'ArrowFunctionExpression'
|
|
117
|
-
) {
|
|
118
|
-
return current.generator === true;
|
|
119
|
-
}
|
|
120
|
-
current = current.parent;
|
|
121
|
-
}
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function isAlreadyTracked(node) {
|
|
126
|
-
// Being the argument of a `track(...)` call is enough to consider the
|
|
127
|
-
// primitive handled — this keeps the autofix idempotent regardless of how the
|
|
128
|
-
// surrounding `yield*` is shaped.
|
|
129
|
-
const parent = node.parent;
|
|
130
|
-
return (
|
|
131
|
-
parent &&
|
|
132
|
-
parent.type === 'CallExpression' &&
|
|
133
|
-
parent.callee.type === 'Identifier' &&
|
|
134
|
-
parent.callee.name === 'track' &&
|
|
135
|
-
parent.arguments[0] === node
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function argumentsContainYield(callNode) {
|
|
140
|
-
for (const argument of callNode.arguments) {
|
|
141
|
-
if (containsYield(argument)) {
|
|
142
|
-
return true;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
function containsYield(node) {
|
|
149
|
-
if (!node || typeof node.type !== 'string') {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (node.type === 'YieldExpression') {
|
|
154
|
-
return true;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
for (const key of Object.keys(node)) {
|
|
158
|
-
if (key === 'parent') {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const value = node[key];
|
|
163
|
-
if (Array.isArray(value)) {
|
|
164
|
-
for (const item of value) {
|
|
165
|
-
if (item && typeof item.type === 'string' && containsYield(item)) {
|
|
166
|
-
return true;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
} else if (value && typeof value.type === 'string') {
|
|
170
|
-
if (containsYield(value)) {
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return false;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function createTrackImportFix(fixer, sourceCode) {
|
|
180
|
-
const program = sourceCode.ast;
|
|
181
|
-
let craftImport;
|
|
182
|
-
|
|
183
|
-
for (const statement of program.body) {
|
|
184
|
-
if (
|
|
185
|
-
statement.type === 'ImportDeclaration' &&
|
|
186
|
-
statement.source.value === '@craft-ng/core'
|
|
187
|
-
) {
|
|
188
|
-
const alreadyImported = statement.specifiers.some(
|
|
189
|
-
(specifier) =>
|
|
190
|
-
specifier.type === 'ImportSpecifier' &&
|
|
191
|
-
specifier.imported.type === 'Identifier' &&
|
|
192
|
-
specifier.imported.name === 'track',
|
|
193
|
-
);
|
|
194
|
-
if (alreadyImported) {
|
|
195
|
-
return undefined;
|
|
196
|
-
}
|
|
197
|
-
craftImport = statement;
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
if (!craftImport) {
|
|
203
|
-
return fixer.insertTextBefore(
|
|
204
|
-
program.body[0] ?? program,
|
|
205
|
-
"import { track } from '@craft-ng/core';\n",
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const namedSpecifiers = craftImport.specifiers.filter(
|
|
210
|
-
(specifier) => specifier.type === 'ImportSpecifier',
|
|
211
|
-
);
|
|
212
|
-
|
|
213
|
-
if (namedSpecifiers.length === 0) {
|
|
214
|
-
return undefined;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const lastSpecifier = namedSpecifiers[namedSpecifiers.length - 1];
|
|
218
|
-
return fixer.insertTextAfter(lastSpecifier, ', track');
|
|
219
|
-
}
|