@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
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ import { runMigration } from '../scripts/migrate.js';
3
+ function parseArgs(argv) {
4
+ const options = { files: [] };
5
+ const files = [];
6
+ for (let index = 0; index < argv.length; index += 1) {
7
+ const argument = argv[index];
8
+ switch (argument) {
9
+ case '--project':
10
+ case '--tsconfig':
11
+ options.tsConfigFilePath = argv[++index];
12
+ break;
13
+ case '--root':
14
+ options.rootDir = argv[++index];
15
+ break;
16
+ case '--config':
17
+ options.configFilePath = argv[++index];
18
+ break;
19
+ case '--dry-run':
20
+ options.write = false;
21
+ break;
22
+ case '--write':
23
+ options.write = true;
24
+ break;
25
+ case '--check':
26
+ options.check = true;
27
+ break;
28
+ case '--json':
29
+ if (argv[index + 1] && !argv[index + 1].startsWith('-'))
30
+ options.jsonFilePath = argv[++index];
31
+ else
32
+ options.json = true;
33
+ break;
34
+ case '--fail-on-manual':
35
+ options.failOnManual = true;
36
+ break;
37
+ case '--no-eslint':
38
+ options.eslint = false;
39
+ break;
40
+ case '--collection-name':
41
+ options.collectionName = argv[++index];
42
+ break;
43
+ case '--parent-mount':
44
+ options.parentMount = argv[++index];
45
+ break;
46
+ case '--parent-names':
47
+ options.parentNames = argv[++index].split(',').filter(Boolean);
48
+ break;
49
+ case '--help':
50
+ printHelp();
51
+ process.exit(0);
52
+ break;
53
+ default:
54
+ if (argument.startsWith('-'))
55
+ throw new Error(`Unknown argument: ${argument}`);
56
+ files.push(argument);
57
+ }
58
+ }
59
+ options.files = files;
60
+ return options;
61
+ }
62
+ function printHelp() {
63
+ console.log(`Usage: craft-migrate [files...] [options]
64
+
65
+ Runs the primitive, service and route migrations in that order.
66
+
67
+ Options:
68
+ --project, --tsconfig <path> Application tsconfig.
69
+ --root <dir> Source root. Defaults to cwd.
70
+ --config <path> craft-dev-tools.config.ts override.
71
+ --dry-run Analyze without writing (default).
72
+ --write Write migrated files.
73
+ --check Fail while supported legacy code remains.
74
+ --json [path] Print the combined report, or write it to path.
75
+ --fail-on-manual Fail when manual diagnostics are emitted.
76
+ --no-eslint Do not run ESLint --fix after writes.
77
+ --collection-name <name> Override the inferred root routes name.
78
+ --parent-mount <path> Pin a route collection to its parent mount.
79
+ --parent-names <a,b> Named providers inherited by the route collection.
80
+ `);
81
+ }
82
+ runMigration(parseArgs(process.argv.slice(2)))
83
+ .then((result) => {
84
+ process.exitCode = result.exitCode;
85
+ })
86
+ .catch((error) => {
87
+ console.error(error);
88
+ process.exitCode = 1;
89
+ });
90
+ //# sourceMappingURL=craft-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"craft-migrate.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/bin/craft-migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env node
2
+ import { __awaiter } from "tslib";
3
+ import { createInterface } from 'node:readline/promises';
4
+ import { stdin as input, stdout as output } from 'node:process';
5
+ import { listAngularProjects, runRouteAdd, runRouteSplit, } from '../scripts/routes/route-command.js';
6
+ function main(argv) {
7
+ return __awaiter(this, void 0, void 0, function* () {
8
+ var _a, _b;
9
+ if (argv[0] !== 'route' || !['add', 'split'].includes((_a = argv[1]) !== null && _a !== void 0 ? _a : '')) {
10
+ printHelp();
11
+ return argv.includes('--help') ? 0 : 1;
12
+ }
13
+ const command = argv[1];
14
+ const parsed = parseArgs(argv.slice(2));
15
+ if (parsed.help) {
16
+ printHelp();
17
+ return 0;
18
+ }
19
+ const common = {
20
+ rootDir: parsed.values['root'],
21
+ project: parsed.values['project'],
22
+ parent: parsed.values['parent'],
23
+ dryRun: parsed.flags.has('dry-run'),
24
+ yes: parsed.flags.has('yes'),
25
+ json: parsed.flags.has('json'),
26
+ };
27
+ const readline = createInterface({ input, output });
28
+ try {
29
+ if (!common.project && !common.yes) {
30
+ const projects = listAngularProjects(common.rootDir);
31
+ if (projects.length > 1) {
32
+ output.write(projects
33
+ .map((project, index) => `${index + 1}. ${project}`)
34
+ .join('\n') + '\n');
35
+ const selected = Number(yield readline.question('Angular project number: '));
36
+ common.project = projects[selected - 1];
37
+ if (!common.project)
38
+ throw new Error('Invalid project selection.');
39
+ }
40
+ }
41
+ const confirm = (_plan) => __awaiter(this, void 0, void 0, function* () { return /^y(?:es)?$/i.test(yield readline.question('Apply this plan? [y/N] ')); });
42
+ let result;
43
+ if (command === 'add') {
44
+ const options = Object.assign(Object.assign({}, common), { path: (_b = parsed.positionals[0]) !== null && _b !== void 0 ? _b : (yield readline.question('Route path: ')), component: parsed.values['component'], createComponent: parsed.values['create-component'], featureFile: parsed.values['feature-file'], redirectTo: parsed.values['redirect-to'], confirm });
45
+ if (!options.component &&
46
+ !options.createComponent &&
47
+ !options.redirectTo) {
48
+ const kind = (yield readline.question('Target: [e]xisting component, [c]reate component, [r]edirect? ')).toLowerCase();
49
+ if (kind.startsWith('e')) {
50
+ options.component = yield readline.question('Component <file#Class>: ');
51
+ }
52
+ else if (kind.startsWith('c')) {
53
+ options.createComponent = yield readline.question('Angular component name/path: ');
54
+ }
55
+ else if (kind.startsWith('r')) {
56
+ options.redirectTo = yield readline.question('Redirect target: ');
57
+ }
58
+ }
59
+ result = yield runRouteAdd(options);
60
+ }
61
+ else {
62
+ const parent = common.parent;
63
+ const prefix = parsed.values['prefix'];
64
+ const target = parsed.values['target'];
65
+ if (!parent || !prefix || !target) {
66
+ throw new Error('route split requires --parent, --prefix, and --target.');
67
+ }
68
+ const options = Object.assign(Object.assign({}, common), { parent,
69
+ prefix,
70
+ target,
71
+ confirm });
72
+ result = yield runRouteSplit(options);
73
+ }
74
+ printResult(result, common.json === true);
75
+ return result.exitCode;
76
+ }
77
+ finally {
78
+ readline.close();
79
+ }
80
+ });
81
+ }
82
+ function parseArgs(argv) {
83
+ const values = {};
84
+ const flags = new Set();
85
+ const positionals = [];
86
+ let help = false;
87
+ const valueOptions = new Set([
88
+ 'root',
89
+ 'project',
90
+ 'parent',
91
+ 'component',
92
+ 'create-component',
93
+ 'feature-file',
94
+ 'redirect-to',
95
+ 'prefix',
96
+ 'target',
97
+ ]);
98
+ const flagOptions = new Set(['dry-run', 'yes', 'json']);
99
+ for (let index = 0; index < argv.length; index += 1) {
100
+ const argument = argv[index];
101
+ if (argument === '--help' || argument === '-h') {
102
+ help = true;
103
+ }
104
+ else if (argument.startsWith('--')) {
105
+ const name = argument.slice(2);
106
+ if (valueOptions.has(name)) {
107
+ const value = argv[++index];
108
+ if (!value || value.startsWith('--')) {
109
+ throw new Error(`Missing value for --${name}.`);
110
+ }
111
+ values[name] = value;
112
+ }
113
+ else if (flagOptions.has(name)) {
114
+ flags.add(name);
115
+ }
116
+ else {
117
+ throw new Error(`Unknown option --${name}.`);
118
+ }
119
+ }
120
+ else {
121
+ positionals.push(argument);
122
+ }
123
+ }
124
+ return { values, flags, positionals, help };
125
+ }
126
+ function printResult(result, json) {
127
+ if (json) {
128
+ console.log(JSON.stringify(result, null, 2));
129
+ return;
130
+ }
131
+ for (const diagnostic of result.diagnostics) {
132
+ console.error(`${diagnostic.code}: ${diagnostic.message}`);
133
+ }
134
+ if (result.changedFiles.length > 0) {
135
+ console.log(`Changed:\n${result.changedFiles.map((file) => ` ${file}`).join('\n')}`);
136
+ }
137
+ }
138
+ function printHelp() {
139
+ console.log(`Usage:
140
+ craft route add [path] [options]
141
+ craft route split --parent <file#collection> --prefix <path> --target <file>
142
+
143
+ Options:
144
+ --root <dir> Workspace root (defaults to cwd)
145
+ --project <name|tsconfig> Angular project or tsconfig
146
+ --parent <file#collection> Parent craftRoutes collection
147
+ --component <file#Class> Existing routed component
148
+ --create-component <name> Generate with the local Angular CLI or Nx
149
+ --feature-file <file> Create/use an explicit lazy feature collection
150
+ --redirect-to <path> Add a static redirect
151
+ --prefix <path> Static prefix moved by route split
152
+ --target <file> New lazy collection written by route split
153
+ --dry-run Print the plan without writing
154
+ --yes Apply without confirmation
155
+ --json Emit machine-readable output
156
+ `);
157
+ }
158
+ main(process.argv.slice(2))
159
+ .then((exitCode) => {
160
+ process.exitCode = exitCode;
161
+ })
162
+ .catch((error) => {
163
+ console.error(error instanceof Error ? error.message : error);
164
+ process.exitCode = 1;
165
+ });
166
+ //# sourceMappingURL=craft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"craft.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/bin/craft.ts"],"names":[],"mappings":"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"}
@@ -1,125 +1,8 @@
1
- module.exports = {
2
- meta: {
3
- type: 'problem',
4
- docs: {
5
- description:
6
- "Ensure craftComputed(name, ...) is called with a string literal first argument that matches the declared variable or class property name.",
7
- },
8
- fixable: 'code',
9
- schema: [],
10
- messages: {
11
- missingName:
12
- "craftComputed must be called with a string literal name matching '{{declaredName}}' as the first argument.",
13
- mismatchedName:
14
- "craftComputed first argument '{{actual}}' must match the declared name '{{declaredName}}'.",
15
- },
16
- },
17
- create(context) {
18
- const sourceCode = context.sourceCode ?? context.getSourceCode();
19
-
20
- return {
21
- CallExpression(node) {
22
- if (
23
- node.callee.type !== 'Identifier' ||
24
- node.callee.name !== 'craftComputed'
25
- ) {
26
- return;
27
- }
28
-
29
- const declaredName = getDeclaredName(node);
30
- if (!declaredName) {
31
- return;
32
- }
33
-
34
- const firstArg = node.arguments[0];
35
-
36
- if (!firstArg) {
37
- context.report({
38
- node,
39
- messageId: 'missingName',
40
- data: { declaredName },
41
- fix(fixer) {
42
- const openParen = sourceCode.getTokenAfter(
43
- node.callee,
44
- (token) => token.type === 'Punctuator' && token.value === '(',
45
- );
46
- if (!openParen) return null;
47
- return fixer.insertTextAfter(openParen, `'${declaredName}'`);
48
- },
49
- });
50
- return;
51
- }
52
-
53
- if (isStringLiteral(firstArg)) {
54
- const actual = getStringLiteralValue(firstArg);
55
- if (actual === declaredName) {
56
- return;
57
- }
58
- context.report({
59
- node: firstArg,
60
- messageId: 'mismatchedName',
61
- data: { declaredName, actual },
62
- fix(fixer) {
63
- return fixer.replaceText(firstArg, `'${declaredName}'`);
64
- },
65
- });
66
- return;
67
- }
68
-
69
- context.report({
70
- node: firstArg,
71
- messageId: 'missingName',
72
- data: { declaredName },
73
- fix(fixer) {
74
- return fixer.insertTextBefore(firstArg, `'${declaredName}', `);
75
- },
76
- });
77
- },
78
- };
79
- },
80
- };
81
-
82
- function getDeclaredName(callNode) {
83
- const parent = callNode.parent;
84
- if (!parent) return undefined;
85
-
86
- if (
87
- parent.type === 'VariableDeclarator' &&
88
- parent.init === callNode &&
89
- parent.id.type === 'Identifier'
90
- ) {
91
- return parent.id.name;
92
- }
93
-
94
- if (
95
- parent.type === 'PropertyDefinition' &&
96
- parent.value === callNode &&
97
- !parent.computed &&
98
- parent.key.type === 'Identifier'
99
- ) {
100
- return parent.key.name;
101
- }
102
-
103
- return undefined;
104
- }
105
-
106
- function isStringLiteral(node) {
107
- if (node.type === 'Literal' && typeof node.value === 'string') {
108
- return true;
109
- }
110
- if (
111
- node.type === 'TemplateLiteral' &&
112
- node.expressions.length === 0 &&
113
- node.quasis.length === 1
114
- ) {
115
- return true;
116
- }
117
- return false;
118
- }
119
-
120
- function getStringLiteralValue(node) {
121
- if (node.type === 'Literal') {
122
- return node.value;
123
- }
124
- return node.quasis[0].value.cooked;
125
- }
1
+ const { createNameMatchRule } = require('./craft-name-match-utils.cjs');
2
+
3
+ module.exports = createNameMatchRule({
4
+ calleeName: 'craftComputed',
5
+ description:
6
+ "Ensure craftComputed(name, ...) is called with a string literal first argument that matches the declared variable or class property name.",
7
+ supportsObjectConfigForm: false,
8
+ });
@@ -1,166 +1,8 @@
1
- module.exports = {
2
- meta: {
3
- type: 'problem',
4
- docs: {
5
- description:
6
- "Ensure craftMethod(name, ...) is called with a string literal first argument (or { name } object) that matches the declared variable or class property name.",
7
- },
8
- fixable: 'code',
9
- schema: [],
10
- messages: {
11
- missingName:
12
- "craftMethod must be called with a string literal name matching '{{declaredName}}' as the first argument.",
13
- mismatchedName:
14
- "craftMethod first argument '{{actual}}' must match the declared name '{{declaredName}}'.",
15
- },
16
- },
17
- create(context) {
18
- const sourceCode = context.sourceCode ?? context.getSourceCode();
19
-
20
- return {
21
- CallExpression(node) {
22
- if (
23
- node.callee.type !== 'Identifier' ||
24
- node.callee.name !== 'craftMethod'
25
- ) {
26
- return;
27
- }
28
-
29
- const declaredName = getDeclaredName(node);
30
- if (!declaredName) {
31
- return;
32
- }
33
-
34
- const firstArg = node.arguments[0];
35
-
36
- if (!firstArg) {
37
- context.report({
38
- node,
39
- messageId: 'missingName',
40
- data: { declaredName },
41
- fix(fixer) {
42
- const openParen = sourceCode.getTokenAfter(
43
- node.callee,
44
- (token) => token.type === 'Punctuator' && token.value === '(',
45
- );
46
- if (!openParen) return null;
47
- return fixer.insertTextAfter(openParen, `'${declaredName}'`);
48
- },
49
- });
50
- return;
51
- }
52
-
53
- // Handle object config form: { name: 'methodName', providers: [...] }
54
- if (firstArg.type === 'ObjectExpression') {
55
- const nameProp = firstArg.properties.find(
56
- (p) =>
57
- p.type === 'Property' &&
58
- !p.computed &&
59
- p.key.type === 'Identifier' &&
60
- p.key.name === 'name',
61
- );
62
- if (!nameProp) {
63
- context.report({
64
- node: firstArg,
65
- messageId: 'missingName',
66
- data: { declaredName },
67
- });
68
- return;
69
- }
70
- const nameValue = nameProp.value;
71
- if (isStringLiteral(nameValue)) {
72
- const actual = getStringLiteralValue(nameValue);
73
- if (actual === declaredName) {
74
- return;
75
- }
76
- context.report({
77
- node: nameValue,
78
- messageId: 'mismatchedName',
79
- data: { declaredName, actual },
80
- fix(fixer) {
81
- return fixer.replaceText(nameValue, `'${declaredName}'`);
82
- },
83
- });
84
- } else {
85
- context.report({
86
- node: nameValue,
87
- messageId: 'mismatchedName',
88
- data: { declaredName, actual: sourceCode.getText(nameValue) },
89
- });
90
- }
91
- return;
92
- }
93
-
94
- if (isStringLiteral(firstArg)) {
95
- const actual = getStringLiteralValue(firstArg);
96
- if (actual === declaredName) {
97
- return;
98
- }
99
- context.report({
100
- node: firstArg,
101
- messageId: 'mismatchedName',
102
- data: { declaredName, actual },
103
- fix(fixer) {
104
- return fixer.replaceText(firstArg, `'${declaredName}'`);
105
- },
106
- });
107
- return;
108
- }
109
-
110
- context.report({
111
- node: firstArg,
112
- messageId: 'missingName',
113
- data: { declaredName },
114
- fix(fixer) {
115
- return fixer.insertTextBefore(firstArg, `'${declaredName}', `);
116
- },
117
- });
118
- },
119
- };
120
- },
121
- };
122
-
123
- function getDeclaredName(callNode) {
124
- const parent = callNode.parent;
125
- if (!parent) return undefined;
126
-
127
- if (
128
- parent.type === 'VariableDeclarator' &&
129
- parent.init === callNode &&
130
- parent.id.type === 'Identifier'
131
- ) {
132
- return parent.id.name;
133
- }
134
-
135
- if (
136
- parent.type === 'PropertyDefinition' &&
137
- parent.value === callNode &&
138
- !parent.computed &&
139
- parent.key.type === 'Identifier'
140
- ) {
141
- return parent.key.name;
142
- }
143
-
144
- return undefined;
145
- }
146
-
147
- function isStringLiteral(node) {
148
- if (node.type === 'Literal' && typeof node.value === 'string') {
149
- return true;
150
- }
151
- if (
152
- node.type === 'TemplateLiteral' &&
153
- node.expressions.length === 0 &&
154
- node.quasis.length === 1
155
- ) {
156
- return true;
157
- }
158
- return false;
159
- }
160
-
161
- function getStringLiteralValue(node) {
162
- if (node.type === 'Literal') {
163
- return node.value;
164
- }
165
- return node.quasis[0].value.cooked;
166
- }
1
+ const { createNameMatchRule } = require('./craft-name-match-utils.cjs');
2
+
3
+ module.exports = createNameMatchRule({
4
+ calleeName: 'craftMethod',
5
+ description:
6
+ "Ensure craftMethod(name, ...) is called with a string literal first argument (or { name } object) that matches the declared variable or class property name.",
7
+ supportsObjectConfigForm: true,
8
+ });