@craft-ng/dev-tools 0.5.0-beta.5 → 0.6.0-beta.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.
Files changed (94) hide show
  1. package/README.md +198 -23
  2. package/generators.json +26 -0
  3. package/package.json +23 -2
  4. package/src/bin/craft-migrate-primitives.d.ts +2 -0
  5. package/src/bin/craft-migrate-primitives.js +71 -0
  6. package/src/bin/craft-migrate-primitives.js.map +1 -0
  7. package/src/bin/craft-migrate-routes.d.ts +2 -0
  8. package/src/bin/craft-migrate-routes.js +77 -0
  9. package/src/bin/craft-migrate-routes.js.map +1 -0
  10. package/src/bin/craft-migrate-services.d.ts +2 -0
  11. package/src/bin/craft-migrate-services.js +75 -0
  12. package/src/bin/craft-migrate-services.js.map +1 -0
  13. package/src/bin/craft-migrate.d.ts +2 -0
  14. package/src/bin/craft-migrate.js +90 -0
  15. package/src/bin/craft-migrate.js.map +1 -0
  16. package/src/bin/craft.d.ts +2 -0
  17. package/src/bin/craft.js +166 -0
  18. package/src/bin/craft.js.map +1 -0
  19. package/src/eslint-rules/craft-computed-name-match.cjs +8 -125
  20. package/src/eslint-rules/craft-method-name-match.cjs +8 -166
  21. package/src/eslint-rules/craft-name-match-utils.cjs +179 -0
  22. package/src/eslint-rules/craft-signal-source-name-match.cjs +8 -0
  23. package/src/eslint-rules/craft-source-name-match.cjs +8 -0
  24. package/src/eslint-rules/global-exception-registry-match.cjs +78 -13
  25. package/src/eslint-rules/index.cjs +10 -2
  26. package/src/eslint-rules/require-cascade-route-di-check.cjs +223 -0
  27. package/src/eslint-rules/require-exception-component-di-check.cjs +66 -10
  28. package/src/eslint-rules/require-lazy-load-with-retry.cjs +148 -0
  29. package/src/eslint-rules/require-primitive-generator-unwrap.cjs +267 -0
  30. package/src/generators/route/compat.d.ts +3 -0
  31. package/src/generators/route/compat.js +6 -0
  32. package/src/generators/route/compat.js.map +1 -0
  33. package/src/generators/route/generator.d.ts +31 -0
  34. package/src/generators/route/generator.js +434 -0
  35. package/src/generators/route/generator.js.map +1 -0
  36. package/src/generators/route/schema.json +50 -0
  37. package/src/generators/route/split-schema.json +19 -0
  38. package/src/index.d.ts +9 -0
  39. package/src/index.js +9 -0
  40. package/src/index.js.map +1 -1
  41. package/src/scripts/angular-brand-codemod.d.ts +17 -0
  42. package/src/scripts/angular-brand-codemod.js +44 -8
  43. package/src/scripts/angular-brand-codemod.js.map +1 -1
  44. package/src/scripts/angular-brand-codemod.spec.ts +3 -3
  45. package/src/scripts/angular-brand-codemod.ts +78 -7
  46. package/src/scripts/migrate.d.ts +32 -0
  47. package/src/scripts/migrate.js +67 -0
  48. package/src/scripts/migrate.js.map +1 -0
  49. package/src/scripts/migrate.ts +128 -0
  50. package/src/scripts/migration-workspace.d.ts +2 -0
  51. package/src/scripts/migration-workspace.js +72 -0
  52. package/src/scripts/migration-workspace.js.map +1 -0
  53. package/src/scripts/migration-workspace.ts +93 -0
  54. package/src/scripts/primitives/migrate-primitive-generators.d.ts +27 -0
  55. package/src/scripts/primitives/migrate-primitive-generators.js +315 -0
  56. package/src/scripts/primitives/migrate-primitive-generators.js.map +1 -0
  57. package/src/scripts/primitives/migrate-primitive-generators.ts +402 -0
  58. package/src/scripts/primitives/migrate-primitives.d.ts +27 -0
  59. package/src/scripts/primitives/migrate-primitives.js +386 -0
  60. package/src/scripts/primitives/migrate-primitives.js.map +1 -0
  61. package/src/scripts/primitives/migrate-primitives.spec.ts +322 -0
  62. package/src/scripts/primitives/migrate-primitives.ts +601 -0
  63. package/src/scripts/primitives/migration-diagnostic.d.ts +8 -0
  64. package/src/scripts/primitives/migration-diagnostic.js +2 -0
  65. package/src/scripts/primitives/migration-diagnostic.js.map +1 -0
  66. package/src/scripts/primitives/migration-diagnostic.ts +14 -0
  67. package/src/scripts/routes/migrate-routes.d.ts +34 -0
  68. package/src/scripts/routes/migrate-routes.js +669 -0
  69. package/src/scripts/routes/migrate-routes.js.map +1 -0
  70. package/src/scripts/routes/migrate-routes.spec.ts +264 -0
  71. package/src/scripts/routes/migrate-routes.ts +895 -0
  72. package/src/scripts/routes/migration-diagnostic.d.ts +16 -0
  73. package/src/scripts/routes/migration-diagnostic.js +2 -0
  74. package/src/scripts/routes/migration-diagnostic.js.map +1 -0
  75. package/src/scripts/routes/migration-diagnostic.ts +25 -0
  76. package/src/scripts/routes/route-command.d.ts +75 -0
  77. package/src/scripts/routes/route-command.js +1187 -0
  78. package/src/scripts/routes/route-command.js.map +1 -0
  79. package/src/scripts/routes/route-command.spec.ts +553 -0
  80. package/src/scripts/routes/route-command.ts +1790 -0
  81. package/src/scripts/services/config.d.ts +2 -0
  82. package/src/scripts/services/config.js +39 -0
  83. package/src/scripts/services/config.js.map +1 -0
  84. package/src/scripts/services/config.ts +60 -0
  85. package/src/scripts/services/migrate-services.d.ts +29 -0
  86. package/src/scripts/services/migrate-services.js +929 -0
  87. package/src/scripts/services/migrate-services.js.map +1 -0
  88. package/src/scripts/services/migrate-services.spec.ts +761 -0
  89. package/src/scripts/services/migrate-services.ts +1333 -0
  90. package/src/scripts/services/migration-diagnostic.d.ts +8 -0
  91. package/src/scripts/services/migration-diagnostic.js +2 -0
  92. package/src/scripts/services/migration-diagnostic.js.map +1 -0
  93. package/src/scripts/services/migration-diagnostic.ts +28 -0
  94. package/src/eslint-rules/require-track-on-dependent-primitives.cjs +0 -219
@@ -1,4 +1,4 @@
1
- /** Generates O(1) DI checks for renderComponent/errorComponent/withErrorComponent. */
1
+ /** Generates O(1) DI checks for route, exception, and route-load error components. */
2
2
  module.exports = {
3
3
  meta: { type: 'problem', fixable: 'code', schema: [] },
4
4
  create(context) {
@@ -6,7 +6,11 @@ module.exports = {
6
6
  return {
7
7
  'Program:exit'(program) {
8
8
  const text = source.getText();
9
- if (!/renderComponent|errorComponent|withErrorComponent/.test(text))
9
+ if (
10
+ !/renderComponent|errorComponent|withErrorComponent|withRouteLoadError|provideRouteLoadErrorComponent/.test(
11
+ text,
12
+ )
13
+ )
10
14
  return;
11
15
 
12
16
  const cascade = readCascadeContext(text);
@@ -14,25 +18,34 @@ module.exports = {
14
18
  walk(program, (node) => {
15
19
  if (isCall(node, 'craftRoutes')) {
16
20
  collectRouteChecks(node, source, cascade, checks);
17
- } else if (isCall(node, 'withErrorComponent')) {
21
+ } else if (
22
+ isCall(node, 'withErrorComponent') ||
23
+ isCall(node, 'withRouteLoadError')
24
+ ) {
18
25
  const descriptor = node.arguments[0];
19
26
  const deps = readProperty(descriptor, 'componentDeps', source);
20
27
  if (deps) {
28
+ const routeLoad = isCall(node, 'withRouteLoadError');
21
29
  checks.push({
22
30
  deps,
23
- names: joinNames(cascade.names, ['CraftGlobalError']),
31
+ names: joinNames(
32
+ cascade.names,
33
+ routeLoad
34
+ ? ['CraftRouteLoadError', 'CraftRouteLoadRecovery']
35
+ : ['CraftGlobalError'],
36
+ ),
24
37
  values: cascade.values,
25
- label: 'global error component',
38
+ label: routeLoad
39
+ ? 'global route load error component'
40
+ : 'global error component',
26
41
  });
27
42
  }
28
43
  }
29
44
  });
30
45
 
46
+ const existingChecks = readExistingCheckDeps(text);
31
47
  const missing = checks.filter(
32
- (check) =>
33
- !text.includes(
34
- `RouteExceptionComponentCheckedDI<\n ${check.deps},`,
35
- ),
48
+ (check) => !existingChecks.has(normalizeTypeText(check.deps)),
36
49
  );
37
50
  if (missing.length === 0) return;
38
51
 
@@ -84,6 +97,29 @@ function collectRouteChecks(call, source, cascade, checks) {
84
97
  });
85
98
  }
86
99
 
100
+ const providers = propertyValue(def, 'providers');
101
+ if (providers?.type === 'ArrayExpression') {
102
+ for (const provider of providers.elements) {
103
+ if (!isCall(provider, 'provideRouteLoadErrorComponent')) continue;
104
+ const deps = readProperty(
105
+ provider.arguments[0],
106
+ 'componentDeps',
107
+ source,
108
+ );
109
+ if (!deps) continue;
110
+ checks.push({
111
+ deps,
112
+ names: joinNames(cascade.names, [
113
+ ...baseNames,
114
+ 'CraftRouteLoadError',
115
+ 'CraftRouteLoadRecovery',
116
+ ]),
117
+ values: cascade.values,
118
+ label: `route load error component: ${path}`,
119
+ });
120
+ }
121
+ }
122
+
87
123
  const handlers = routeCall
88
124
  ? routeCall.arguments[2]
89
125
  : propertyValue(def, 'handleExceptions');
@@ -193,10 +229,30 @@ function ensureImports(text) {
193
229
  );
194
230
  }
195
231
 
232
+ function readExistingCheckDeps(text) {
233
+ const deps = new Set();
234
+ const regex = /RouteExceptionComponentCheckedDI<\s*([\s\S]*?),\s*(?:'[^']*'|never)/g;
235
+ let match;
236
+ while ((match = regex.exec(text))) {
237
+ deps.add(normalizeTypeText(match[1]));
238
+ }
239
+ return deps;
240
+ }
241
+
242
+ function normalizeTypeText(text) {
243
+ return String(text).replace(/\s+/g, '');
244
+ }
245
+
196
246
  function readProperty(node, name, source) {
197
247
  const value = propertyValue(node, name);
198
- return value ? source.getText(value) : undefined;
248
+ return value ? readTypeText(value, source) : undefined;
249
+ }
250
+
251
+ function readTypeText(node, source) {
252
+ if (node?.type === 'TSAsExpression') return source.getText(node.typeAnnotation);
253
+ return source.getText(node);
199
254
  }
255
+
200
256
  function propertyValue(node, name) {
201
257
  if (node?.type !== 'ObjectExpression') return undefined;
202
258
  return node.properties.find(
@@ -0,0 +1,148 @@
1
+ 'use strict';
2
+
3
+ const LAZY_PROPERTIES = new Set([
4
+ 'loadComponent',
5
+ 'loadChildren',
6
+ ]);
7
+
8
+ module.exports = {
9
+ meta: {
10
+ type: 'problem',
11
+ docs: {
12
+ description:
13
+ 'Require lazy route imports to use the withRetry helper so browser-cached module failures can be retried.',
14
+ },
15
+ fixable: 'code',
16
+ schema: [],
17
+ },
18
+ create(context) {
19
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
20
+ const importsByLoader = new Map();
21
+
22
+ return {
23
+ ImportExpression(node) {
24
+ const loader = enclosingLazyLoader(node);
25
+ if (!loader || isWrappedWithRetry(node)) return;
26
+
27
+ const imports = importsByLoader.get(loader) ?? [];
28
+ imports.push(node);
29
+ importsByLoader.set(loader, imports);
30
+ },
31
+ 'Program:exit'() {
32
+ for (const [loader, imports] of importsByLoader) {
33
+ context.report({
34
+ node: imports[0],
35
+ message:
36
+ 'Lazy route imports must be wrapped with withRetry(import(...)).',
37
+ fix(fixer) {
38
+ const parameterFixes = addWithRetryParameter(
39
+ fixer,
40
+ sourceCode,
41
+ loader,
42
+ );
43
+ if (!parameterFixes) return null;
44
+
45
+ return [
46
+ ...parameterFixes,
47
+ ...imports.flatMap((moduleImport) => [
48
+ fixer.insertTextBefore(moduleImport, 'withRetry('),
49
+ fixer.insertTextAfter(moduleImport, ')'),
50
+ ]),
51
+ ];
52
+ },
53
+ });
54
+ }
55
+ },
56
+ };
57
+ },
58
+ };
59
+
60
+ function enclosingLazyLoader(node) {
61
+ let current = node.parent;
62
+ while (current) {
63
+ if (
64
+ (current.type === 'ArrowFunctionExpression' ||
65
+ current.type === 'FunctionExpression') &&
66
+ current.parent?.type === 'Property' &&
67
+ LAZY_PROPERTIES.has(propertyName(current.parent)) &&
68
+ isInsideCraftRoute(current.parent)
69
+ ) {
70
+ return current;
71
+ }
72
+ if (current.type === 'Property' || current.type === 'Program') return null;
73
+ current = current.parent;
74
+ }
75
+ return null;
76
+ }
77
+
78
+ function isInsideCraftRoute(node) {
79
+ let current = node.parent;
80
+ while (current) {
81
+ if (
82
+ current.type === 'CallExpression' &&
83
+ current.callee.type === 'Identifier' &&
84
+ (current.callee.name === 'craftRoute' ||
85
+ current.callee.name === 'craftRoutes')
86
+ ) {
87
+ return true;
88
+ }
89
+ if (current.type === 'Program') return false;
90
+ current = current.parent;
91
+ }
92
+ return false;
93
+ }
94
+
95
+ function propertyName(property) {
96
+ if (property.computed) return undefined;
97
+ if (property.key.type === 'Identifier') return property.key.name;
98
+ if (property.key.type === 'Literal') return property.key.value;
99
+ return undefined;
100
+ }
101
+
102
+ function isWrappedWithRetry(node) {
103
+ return (
104
+ node.parent?.type === 'CallExpression' &&
105
+ node.parent.callee.type === 'Identifier' &&
106
+ node.parent.callee.name === 'withRetry' &&
107
+ node.parent.arguments[0] === node
108
+ );
109
+ }
110
+
111
+ function addWithRetryParameter(fixer, sourceCode, loader) {
112
+ if (loader.params.length === 0) {
113
+ const arrow = sourceCode.getTokenBefore(loader.body, {
114
+ filter: (token) => token.value === '=>',
115
+ });
116
+ if (!arrow) return null;
117
+
118
+ const closeParen = sourceCode.getTokenBefore(arrow);
119
+ const openParen = closeParen && sourceCode.getTokenBefore(closeParen);
120
+ if (openParen?.value !== '(' || closeParen?.value !== ')') return null;
121
+ return [
122
+ fixer.replaceTextRange(
123
+ [openParen.range[1], closeParen.range[0]],
124
+ '{ withRetry }',
125
+ ),
126
+ ];
127
+ }
128
+
129
+ if (loader.params.length !== 1 || loader.params[0].type !== 'ObjectPattern') {
130
+ return null;
131
+ }
132
+
133
+ const pattern = loader.params[0];
134
+ if (
135
+ pattern.properties.some(
136
+ (property) =>
137
+ property.type === 'Property' &&
138
+ property.key.type === 'Identifier' &&
139
+ property.key.name === 'withRetry',
140
+ )
141
+ ) {
142
+ return [];
143
+ }
144
+
145
+ const closingBrace = sourceCode.getLastToken(pattern);
146
+ const prefix = pattern.properties.length > 0 ? ', ' : '';
147
+ return [fixer.insertTextBefore(closingBrace, `${prefix}withRetry`)];
148
+ }
@@ -0,0 +1,267 @@
1
+ const DEFAULT_PRIMITIVES = [
2
+ 'state',
3
+ 'query',
4
+ 'mutation',
5
+ 'asyncProcess',
6
+ 'queryParam',
7
+ ];
8
+
9
+ const FACTORY_HOST_CALLEES = new Set(['craftService', 'toCraftService']);
10
+
11
+ module.exports = {
12
+ meta: {
13
+ type: 'problem',
14
+ docs: {
15
+ description:
16
+ 'Require craft primitive invocations (which return a generator) to be consumed with `yield*` inside a generator factory or `craftUse(...)` elsewhere.',
17
+ },
18
+ fixable: 'code',
19
+ schema: [
20
+ {
21
+ type: 'object',
22
+ properties: {
23
+ primitives: {
24
+ type: 'array',
25
+ items: { type: 'string' },
26
+ },
27
+ },
28
+ additionalProperties: false,
29
+ },
30
+ ],
31
+ messages: {
32
+ requireUnwrap:
33
+ "'{{name}}(...)' returns a primitive generator that must be consumed: use `yield* {{name}}(...)` inside a generator factory, or `craftUse({{name}}(...))` elsewhere.",
34
+ },
35
+ },
36
+ create(context) {
37
+ const options = context.options[0] ?? {};
38
+ const primitives = new Set(options.primitives ?? DEFAULT_PRIMITIVES);
39
+ const sourceCode = context.sourceCode ?? context.getSourceCode();
40
+
41
+ return {
42
+ CallExpression(node) {
43
+ if (
44
+ node.callee.type !== 'Identifier' ||
45
+ !primitives.has(node.callee.name) ||
46
+ // Creation calls always take a config; destructured readers such as
47
+ // `({ state }) => state().page` are argument-less.
48
+ node.arguments.length === 0
49
+ ) {
50
+ return;
51
+ }
52
+
53
+ if (!resolvesToImport(node.callee, sourceCode, context)) {
54
+ return;
55
+ }
56
+
57
+ if (
58
+ isConsumed(node) ||
59
+ isDirectFactoryReturn(node) ||
60
+ isTrackedTypeOnlyPosition(node)
61
+ ) {
62
+ return;
63
+ }
64
+
65
+ const primitiveName = node.callee.name;
66
+
67
+ context.report({
68
+ node,
69
+ messageId: 'requireUnwrap',
70
+ data: { name: primitiveName },
71
+ fix(fixer) {
72
+ const text = sourceCode.getText(node);
73
+
74
+ if (isInsideGeneratorFunction(node)) {
75
+ const wrapped = needsYieldParens(node)
76
+ ? `(yield* ${text})`
77
+ : `yield* ${text}`;
78
+ return [fixer.replaceText(node, wrapped)];
79
+ }
80
+
81
+ const fixes = [fixer.replaceText(node, `craftUse(${text})`)];
82
+ const importFix = createCraftUseImportFix(fixer, sourceCode);
83
+ if (importFix) {
84
+ fixes.push(importFix);
85
+ }
86
+ return fixes;
87
+ },
88
+ });
89
+ },
90
+ };
91
+ },
92
+ };
93
+
94
+ function resolvesToImport(identifier, sourceCode, context) {
95
+ const scope = sourceCode.getScope
96
+ ? sourceCode.getScope(identifier)
97
+ : context.getScope();
98
+ let current = scope;
99
+ while (current) {
100
+ const variable = current.variables.find(
101
+ (candidate) => candidate.name === identifier.name,
102
+ );
103
+ if (variable) {
104
+ if (variable.defs.length === 0) {
105
+ return false;
106
+ }
107
+ return variable.defs.every((def) => def.type === 'ImportBinding');
108
+ }
109
+ current = current.upper;
110
+ }
111
+ // Unresolved (globals) — not an import of the primitive.
112
+ return false;
113
+ }
114
+
115
+ function isConsumed(node) {
116
+ const parent = skipParens(node.parent);
117
+ if (!parent) {
118
+ return false;
119
+ }
120
+ if (parent.type === 'YieldExpression') {
121
+ return true;
122
+ }
123
+ return (
124
+ parent.type === 'CallExpression' &&
125
+ parent.callee.type === 'Identifier' &&
126
+ parent.callee.name === 'craftUse' &&
127
+ skipParensDown(parent.arguments[0]) === node
128
+ );
129
+ }
130
+
131
+ function isDirectFactoryReturn(node) {
132
+ const arrow = skipParens(node.parent);
133
+ if (!arrow || arrow.type !== 'ArrowFunctionExpression') {
134
+ return false;
135
+ }
136
+ if (skipParensDown(arrow.body) !== node) {
137
+ return false;
138
+ }
139
+ return isFactoryHostArrow(arrow);
140
+ }
141
+
142
+ function isFactoryHostArrow(arrow) {
143
+ const parent = arrow.parent;
144
+ if (
145
+ parent &&
146
+ parent.type === 'CallExpression' &&
147
+ parent.callee.type === 'Identifier' &&
148
+ FACTORY_HOST_CALLEES.has(parent.callee.name)
149
+ ) {
150
+ return parent.arguments.includes(arrow);
151
+ }
152
+ return (
153
+ parent &&
154
+ parent.type === 'Property' &&
155
+ parent.key &&
156
+ ((parent.key.type === 'Identifier' && parent.key.name === 'queryParams') ||
157
+ (parent.key.type === 'Literal' && parent.key.value === 'queryParams')) &&
158
+ parent.value === arrow
159
+ );
160
+ }
161
+
162
+ // `mockHttpRequestForRoute` / type-only fixtures sometimes reference a
163
+ // primitive purely for inference through `typeof`; those never run.
164
+ function isTrackedTypeOnlyPosition(node) {
165
+ let current = node.parent;
166
+ while (current) {
167
+ if (
168
+ current.type === 'TSTypeQuery' ||
169
+ current.type === 'TSTypeReference' ||
170
+ current.type === 'TSTypeAnnotation'
171
+ ) {
172
+ return true;
173
+ }
174
+ current = current.parent;
175
+ }
176
+ return false;
177
+ }
178
+
179
+ function isInsideGeneratorFunction(node) {
180
+ let current = node.parent;
181
+ while (current) {
182
+ if (current.type === 'ArrowFunctionExpression') {
183
+ return false;
184
+ }
185
+ if (
186
+ current.type === 'FunctionDeclaration' ||
187
+ current.type === 'FunctionExpression'
188
+ ) {
189
+ return current.generator === true;
190
+ }
191
+ current = current.parent;
192
+ }
193
+ return false;
194
+ }
195
+
196
+ function needsYieldParens(node) {
197
+ const parent = node.parent;
198
+ if (!parent) {
199
+ return false;
200
+ }
201
+ return (
202
+ parent.type === 'SpreadElement' ||
203
+ parent.type === 'MemberExpression' ||
204
+ parent.type === 'BinaryExpression' ||
205
+ parent.type === 'ConditionalExpression' ||
206
+ parent.type === 'TemplateLiteral' ||
207
+ (parent.type === 'CallExpression' && parent.callee === node)
208
+ );
209
+ }
210
+
211
+ function skipParens(node) {
212
+ let current = node;
213
+ while (current && current.type === 'ParenthesizedExpression') {
214
+ current = current.parent;
215
+ }
216
+ return current;
217
+ }
218
+
219
+ function skipParensDown(node) {
220
+ let current = node;
221
+ while (current && current.type === 'ParenthesizedExpression') {
222
+ current = current.expression;
223
+ }
224
+ return current;
225
+ }
226
+
227
+ function createCraftUseImportFix(fixer, sourceCode) {
228
+ const program = sourceCode.ast;
229
+ let craftImport;
230
+
231
+ for (const statement of program.body) {
232
+ if (
233
+ statement.type === 'ImportDeclaration' &&
234
+ statement.source.value === '@craft-ng/core'
235
+ ) {
236
+ const alreadyImported = statement.specifiers.some(
237
+ (specifier) =>
238
+ specifier.type === 'ImportSpecifier' &&
239
+ specifier.imported.type === 'Identifier' &&
240
+ specifier.imported.name === 'craftUse',
241
+ );
242
+ if (alreadyImported) {
243
+ return undefined;
244
+ }
245
+ craftImport = statement;
246
+ break;
247
+ }
248
+ }
249
+
250
+ if (!craftImport) {
251
+ return fixer.insertTextBefore(
252
+ program.body[0] ?? program,
253
+ "import { craftUse } from '@craft-ng/core';\n",
254
+ );
255
+ }
256
+
257
+ const namedSpecifiers = craftImport.specifiers.filter(
258
+ (specifier) => specifier.type === 'ImportSpecifier',
259
+ );
260
+
261
+ if (namedSpecifiers.length === 0) {
262
+ return undefined;
263
+ }
264
+
265
+ const lastSpecifier = namedSpecifiers[namedSpecifiers.length - 1];
266
+ return fixer.insertTextAfter(lastSpecifier, ', craftUse');
267
+ }
@@ -0,0 +1,3 @@
1
+ export declare const routeSchematic: (generatorOptions: import("./schema.js").RouteGeneratorSchema) => (tree: any, context: any) => Promise<any>;
2
+ export declare const routeSplitSchematic: (generatorOptions: import("./schema.js").RouteSplitGeneratorSchema) => (tree: any, context: any) => Promise<any>;
3
+ export default routeSchematic;
@@ -0,0 +1,6 @@
1
+ import { convertNxGenerator } from '@nx/devkit';
2
+ import { routeGenerator, routeSplitGenerator } from './generator.js';
3
+ export const routeSchematic = convertNxGenerator(routeGenerator);
4
+ export const routeSplitSchematic = convertNxGenerator(routeSplitGenerator);
5
+ export default routeSchematic;
6
+ //# sourceMappingURL=compat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compat.js","sourceRoot":"","sources":["../../../../../../libs/dev-tools/src/generators/route/compat.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErE,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAC;AACjE,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;AAE3E,eAAe,cAAc,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { type GeneratorCallback, type Tree } from '@nx/devkit';
2
+ import type { RouteGeneratorSchema, RouteSplitGeneratorSchema } from './schema.js';
3
+ export declare function routeGenerator(tree: Tree, options: RouteGeneratorSchema): Promise<GeneratorCallback | void>;
4
+ type ConfiguredRouteTargetOptions = Pick<RouteGeneratorSchema, 'component' | 'createComponent' | 'redirectTo'>;
5
+ type ComponentCreationTarget = {
6
+ name: string;
7
+ path: string;
8
+ };
9
+ type ResolvedRouteTargetOptions = {
10
+ component?: string;
11
+ createComponent?: ComponentCreationTarget;
12
+ redirectTo?: string;
13
+ };
14
+ type RouteQuestion = (prompt: string) => Promise<string>;
15
+ type RouteParentOption = {
16
+ collectionName: string;
17
+ filePath: string;
18
+ routesName: string;
19
+ };
20
+ export declare function resolveRouteParentOption(parents: RouteParentOption[], interactive: {
21
+ configuredParent?: string;
22
+ rootDir: string;
23
+ routePath: string;
24
+ ask?: RouteQuestion;
25
+ }): Promise<string | undefined>;
26
+ export declare function resolveRouteTargetOptions(options: ConfiguredRouteTargetOptions, interactive: {
27
+ componentBase: string;
28
+ ask?: RouteQuestion;
29
+ }): Promise<ResolvedRouteTargetOptions>;
30
+ export declare function routeSplitGenerator(tree: Tree, options: RouteSplitGeneratorSchema): Promise<GeneratorCallback | void>;
31
+ export default routeGenerator;