@craft-ng/dev-tools 0.5.0-beta.5 → 0.5.1-beta.0
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 +132 -23
- package/package.json +6 -2
- package/src/bin/craft-migrate-primitives.d.ts +2 -0
- package/src/bin/craft-migrate-primitives.js +71 -0
- package/src/bin/craft-migrate-primitives.js.map +1 -0
- package/src/bin/craft-migrate-routes.d.ts +2 -0
- package/src/bin/craft-migrate-routes.js +77 -0
- package/src/bin/craft-migrate-routes.js.map +1 -0
- package/src/bin/craft-migrate-services.d.ts +2 -0
- package/src/bin/craft-migrate-services.js +75 -0
- package/src/bin/craft-migrate-services.js.map +1 -0
- package/src/bin/craft-migrate.d.ts +2 -0
- package/src/bin/craft-migrate.js +90 -0
- package/src/bin/craft-migrate.js.map +1 -0
- package/src/eslint-rules/index.cjs +2 -0
- package/src/eslint-rules/require-exception-component-di-check.cjs +66 -10
- package/src/eslint-rules/require-lazy-load-with-retry.cjs +148 -0
- package/src/index.d.ts +8 -0
- package/src/index.js +8 -0
- package/src/index.js.map +1 -1
- package/src/scripts/angular-brand-codemod.d.ts +17 -0
- package/src/scripts/angular-brand-codemod.js +44 -8
- package/src/scripts/angular-brand-codemod.js.map +1 -1
- package/src/scripts/angular-brand-codemod.spec.ts +3 -3
- package/src/scripts/angular-brand-codemod.ts +78 -7
- package/src/scripts/migrate.d.ts +32 -0
- package/src/scripts/migrate.js +67 -0
- package/src/scripts/migrate.js.map +1 -0
- package/src/scripts/migrate.ts +128 -0
- package/src/scripts/migration-workspace.d.ts +2 -0
- package/src/scripts/migration-workspace.js +72 -0
- package/src/scripts/migration-workspace.js.map +1 -0
- package/src/scripts/migration-workspace.ts +93 -0
- package/src/scripts/primitives/migrate-primitives.d.ts +27 -0
- package/src/scripts/primitives/migrate-primitives.js +354 -0
- package/src/scripts/primitives/migrate-primitives.js.map +1 -0
- package/src/scripts/primitives/migrate-primitives.spec.ts +279 -0
- package/src/scripts/primitives/migrate-primitives.ts +543 -0
- package/src/scripts/primitives/migration-diagnostic.d.ts +8 -0
- package/src/scripts/primitives/migration-diagnostic.js +2 -0
- package/src/scripts/primitives/migration-diagnostic.js.map +1 -0
- package/src/scripts/primitives/migration-diagnostic.ts +13 -0
- package/src/scripts/routes/migrate-routes.d.ts +34 -0
- package/src/scripts/routes/migrate-routes.js +669 -0
- package/src/scripts/routes/migrate-routes.js.map +1 -0
- package/src/scripts/routes/migrate-routes.spec.ts +264 -0
- package/src/scripts/routes/migrate-routes.ts +897 -0
- package/src/scripts/routes/migration-diagnostic.d.ts +16 -0
- package/src/scripts/routes/migration-diagnostic.js +2 -0
- package/src/scripts/routes/migration-diagnostic.js.map +1 -0
- package/src/scripts/routes/migration-diagnostic.ts +25 -0
- package/src/scripts/services/config.d.ts +2 -0
- package/src/scripts/services/config.js +39 -0
- package/src/scripts/services/config.js.map +1 -0
- package/src/scripts/services/config.ts +60 -0
- package/src/scripts/services/migrate-services.d.ts +29 -0
- package/src/scripts/services/migrate-services.js +895 -0
- package/src/scripts/services/migrate-services.js.map +1 -0
- package/src/scripts/services/migrate-services.spec.ts +719 -0
- package/src/scripts/services/migrate-services.ts +1282 -0
- package/src/scripts/services/migration-diagnostic.d.ts +8 -0
- package/src/scripts/services/migration-diagnostic.js +2 -0
- package/src/scripts/services/migration-diagnostic.js.map +1 -0
- package/src/scripts/services/migration-diagnostic.ts +27 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/scripts/migrate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import {
|
|
4
|
+
runPrimitivesMigration,
|
|
5
|
+
type MigratePrimitivesResult,
|
|
6
|
+
} from './primitives/migrate-primitives.js';
|
|
7
|
+
import {
|
|
8
|
+
runRoutesMigration,
|
|
9
|
+
type MigrateRoutesResult,
|
|
10
|
+
} from './routes/migrate-routes.js';
|
|
11
|
+
import {
|
|
12
|
+
runServicesMigration,
|
|
13
|
+
type MigrateServicesResult,
|
|
14
|
+
} from './services/migrate-services.js';
|
|
15
|
+
|
|
16
|
+
export type MigrateOptions = {
|
|
17
|
+
rootDir?: string;
|
|
18
|
+
tsConfigFilePath?: string;
|
|
19
|
+
configFilePath?: string;
|
|
20
|
+
files?: readonly string[];
|
|
21
|
+
write?: boolean;
|
|
22
|
+
check?: boolean;
|
|
23
|
+
json?: boolean;
|
|
24
|
+
jsonFilePath?: string;
|
|
25
|
+
failOnManual?: boolean;
|
|
26
|
+
eslint?: boolean;
|
|
27
|
+
collectionName?: string;
|
|
28
|
+
parentMount?: string;
|
|
29
|
+
parentNames?: readonly string[];
|
|
30
|
+
log?: (message: string) => void;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type MigrateResult = {
|
|
34
|
+
primitives: MigratePrimitivesResult;
|
|
35
|
+
services: MigrateServicesResult;
|
|
36
|
+
routes: MigrateRoutesResult;
|
|
37
|
+
changedFiles: string[];
|
|
38
|
+
diagnostics: {
|
|
39
|
+
primitives: MigratePrimitivesResult['diagnostics'];
|
|
40
|
+
services: MigrateServicesResult['diagnostics'];
|
|
41
|
+
routes: MigrateRoutesResult['diagnostics'];
|
|
42
|
+
};
|
|
43
|
+
exitCode: number;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export async function runMigration(
|
|
47
|
+
options: MigrateOptions = {},
|
|
48
|
+
): Promise<MigrateResult> {
|
|
49
|
+
const log = options.log ?? console.log;
|
|
50
|
+
const stepLog = options.json ? () => undefined : log;
|
|
51
|
+
const shared = {
|
|
52
|
+
rootDir: options.rootDir,
|
|
53
|
+
tsConfigFilePath: options.tsConfigFilePath,
|
|
54
|
+
files: options.files,
|
|
55
|
+
write: options.write,
|
|
56
|
+
check: options.check,
|
|
57
|
+
failOnManual: options.failOnManual,
|
|
58
|
+
log: stepLog,
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
if (!options.json) log('1/3 Migrating primitives and Signal Forms...');
|
|
62
|
+
const primitives = await runPrimitivesMigration({
|
|
63
|
+
...shared,
|
|
64
|
+
eslint: options.eslint,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!options.json) log('2/3 Migrating Angular services...');
|
|
68
|
+
const services = await runServicesMigration({
|
|
69
|
+
...shared,
|
|
70
|
+
configFilePath: options.configFilePath,
|
|
71
|
+
eslint: options.eslint,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (!options.json) log('3/3 Migrating Angular routes...');
|
|
75
|
+
const routes = await runRoutesMigration({
|
|
76
|
+
...shared,
|
|
77
|
+
collectionName: options.collectionName,
|
|
78
|
+
parentMount: options.parentMount,
|
|
79
|
+
parentNames: options.parentNames,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const result: MigrateResult = {
|
|
83
|
+
primitives,
|
|
84
|
+
services,
|
|
85
|
+
routes,
|
|
86
|
+
changedFiles: [
|
|
87
|
+
...new Set([
|
|
88
|
+
...primitives.changedFiles,
|
|
89
|
+
...services.changedFiles,
|
|
90
|
+
...routes.changedFiles,
|
|
91
|
+
]),
|
|
92
|
+
],
|
|
93
|
+
diagnostics: {
|
|
94
|
+
primitives: primitives.diagnostics,
|
|
95
|
+
services: services.diagnostics,
|
|
96
|
+
routes: routes.diagnostics,
|
|
97
|
+
},
|
|
98
|
+
exitCode: Math.max(
|
|
99
|
+
primitives.exitCode,
|
|
100
|
+
services.exitCode,
|
|
101
|
+
routes.exitCode,
|
|
102
|
+
),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (options.jsonFilePath) {
|
|
106
|
+
const path = resolve(options.jsonFilePath);
|
|
107
|
+
await mkdir(dirname(path), { recursive: true });
|
|
108
|
+
await writeFile(path, `${JSON.stringify(result, null, 2)}\n`, 'utf8');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (options.json) log(JSON.stringify(result, null, 2));
|
|
112
|
+
else {
|
|
113
|
+
const manualCount =
|
|
114
|
+
primitives.diagnostics.length +
|
|
115
|
+
services.diagnostics.length +
|
|
116
|
+
routes.diagnostics.length;
|
|
117
|
+
log(
|
|
118
|
+
`Migration complete: ${result.changedFiles.length} changed file(s), ${manualCount} manual diagnostic(s).`,
|
|
119
|
+
);
|
|
120
|
+
if (manualCount > 0) {
|
|
121
|
+
log(
|
|
122
|
+
'Review the diagnostics, then run the project type-check, tests and production build.',
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { Node, SyntaxKind } from 'ts-morph';
|
|
4
|
+
const ESLINT_CONFIG_NAMES = [
|
|
5
|
+
'eslint.config.js',
|
|
6
|
+
'eslint.config.mjs',
|
|
7
|
+
'eslint.config.cjs',
|
|
8
|
+
'eslint.config.ts',
|
|
9
|
+
'eslint.config.mts',
|
|
10
|
+
'eslint.config.cts',
|
|
11
|
+
];
|
|
12
|
+
export function migrateEslintConfig(project, searchFromDir) {
|
|
13
|
+
var _a, _b;
|
|
14
|
+
const filePath = findUp(searchFromDir, ESLINT_CONFIG_NAMES);
|
|
15
|
+
if (!filePath)
|
|
16
|
+
return undefined;
|
|
17
|
+
const sourceFile = (_a = project.getSourceFile(filePath)) !== null && _a !== void 0 ? _a : project.addSourceFileAtPath(filePath);
|
|
18
|
+
const rulesObjects = sourceFile
|
|
19
|
+
.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
|
|
20
|
+
.filter((property) => property.getName() === 'rules')
|
|
21
|
+
.map((property) => ({
|
|
22
|
+
config: property.getFirstAncestorByKind(SyntaxKind.ObjectLiteralExpression),
|
|
23
|
+
rules: property.getInitializer(),
|
|
24
|
+
}))
|
|
25
|
+
.filter((entry) => Boolean(entry.config && Node.isObjectLiteralExpression(entry.rules)));
|
|
26
|
+
const rulesEntry = (_b = rulesObjects.find((entry) => {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
return /\*\*\/\*\.ts|\.tsx|\[jt\]s/.test((_b = (_a = entry.config.getProperty('files')) === null || _a === void 0 ? void 0 : _a.getText()) !== null && _b !== void 0 ? _b : '');
|
|
29
|
+
})) !== null && _b !== void 0 ? _b : rulesObjects.at(-1);
|
|
30
|
+
const rules = rulesEntry && Node.isObjectLiteralExpression(rulesEntry.rules)
|
|
31
|
+
? rulesEntry.rules
|
|
32
|
+
: undefined;
|
|
33
|
+
if (!rules)
|
|
34
|
+
return undefined;
|
|
35
|
+
const changedReturnTypeRule = setRule(rules, '@typescript-eslint/explicit-function-return-type', "'off'");
|
|
36
|
+
const changedEmptyObjectRule = setRule(rules, '@typescript-eslint/no-empty-object-type', "['error', { allowObjectTypes: 'always' }]");
|
|
37
|
+
return changedReturnTypeRule || changedEmptyObjectRule ? sourceFile : undefined;
|
|
38
|
+
}
|
|
39
|
+
function setRule(rules, ruleName, initializer) {
|
|
40
|
+
var _a;
|
|
41
|
+
const existing = rules.getProperty((property) => Node.isPropertyAssignment(property) &&
|
|
42
|
+
getPropertyName(property.getNameNode()) === ruleName);
|
|
43
|
+
if (Node.isPropertyAssignment(existing)) {
|
|
44
|
+
if (((_a = existing.getInitializer()) === null || _a === void 0 ? void 0 : _a.getText()) === initializer)
|
|
45
|
+
return false;
|
|
46
|
+
existing.setInitializer(initializer);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
rules.addPropertyAssignment({ name: `'${ruleName}'`, initializer });
|
|
50
|
+
}
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
function getPropertyName(node) {
|
|
54
|
+
return Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)
|
|
55
|
+
? node.getLiteralValue()
|
|
56
|
+
: node.getText();
|
|
57
|
+
}
|
|
58
|
+
function findUp(startDir, names) {
|
|
59
|
+
let current = resolve(startDir);
|
|
60
|
+
while (true) {
|
|
61
|
+
for (const name of names) {
|
|
62
|
+
const candidate = join(current, name);
|
|
63
|
+
if (existsSync(candidate))
|
|
64
|
+
return candidate;
|
|
65
|
+
}
|
|
66
|
+
const parent = dirname(current);
|
|
67
|
+
if (parent === current)
|
|
68
|
+
return undefined;
|
|
69
|
+
current = parent;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=migration-workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-workspace.js","sourceRoot":"","sources":["../../../../../libs/dev-tools/src/scripts/migration-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { Node, Project, SourceFile, SyntaxKind } from 'ts-morph';
|
|
4
|
+
|
|
5
|
+
const ESLINT_CONFIG_NAMES = [
|
|
6
|
+
'eslint.config.js',
|
|
7
|
+
'eslint.config.mjs',
|
|
8
|
+
'eslint.config.cjs',
|
|
9
|
+
'eslint.config.ts',
|
|
10
|
+
'eslint.config.mts',
|
|
11
|
+
'eslint.config.cts',
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
export function migrateEslintConfig(
|
|
15
|
+
project: Project,
|
|
16
|
+
searchFromDir: string,
|
|
17
|
+
): SourceFile | undefined {
|
|
18
|
+
const filePath = findUp(searchFromDir, ESLINT_CONFIG_NAMES);
|
|
19
|
+
if (!filePath) return undefined;
|
|
20
|
+
const sourceFile =
|
|
21
|
+
project.getSourceFile(filePath) ?? project.addSourceFileAtPath(filePath);
|
|
22
|
+
const rulesObjects = sourceFile
|
|
23
|
+
.getDescendantsOfKind(SyntaxKind.PropertyAssignment)
|
|
24
|
+
.filter((property) => property.getName() === 'rules')
|
|
25
|
+
.map((property) => ({
|
|
26
|
+
config: property.getFirstAncestorByKind(SyntaxKind.ObjectLiteralExpression),
|
|
27
|
+
rules: property.getInitializer(),
|
|
28
|
+
}))
|
|
29
|
+
.filter(
|
|
30
|
+
(entry): entry is { config: NonNullable<typeof entry.config>; rules: NonNullable<typeof entry.rules> } =>
|
|
31
|
+
Boolean(entry.config && Node.isObjectLiteralExpression(entry.rules)),
|
|
32
|
+
);
|
|
33
|
+
const rulesEntry =
|
|
34
|
+
rulesObjects.find((entry) =>
|
|
35
|
+
/\*\*\/\*\.ts|\.tsx|\[jt\]s/.test(
|
|
36
|
+
entry.config.getProperty('files')?.getText() ?? '',
|
|
37
|
+
),
|
|
38
|
+
) ?? rulesObjects.at(-1);
|
|
39
|
+
const rules =
|
|
40
|
+
rulesEntry && Node.isObjectLiteralExpression(rulesEntry.rules)
|
|
41
|
+
? rulesEntry.rules
|
|
42
|
+
: undefined;
|
|
43
|
+
if (!rules) return undefined;
|
|
44
|
+
const changedReturnTypeRule = setRule(
|
|
45
|
+
rules,
|
|
46
|
+
'@typescript-eslint/explicit-function-return-type',
|
|
47
|
+
"'off'",
|
|
48
|
+
);
|
|
49
|
+
const changedEmptyObjectRule = setRule(
|
|
50
|
+
rules,
|
|
51
|
+
'@typescript-eslint/no-empty-object-type',
|
|
52
|
+
"['error', { allowObjectTypes: 'always' }]",
|
|
53
|
+
);
|
|
54
|
+
return changedReturnTypeRule || changedEmptyObjectRule ? sourceFile : undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function setRule(
|
|
58
|
+
rules: import('ts-morph').ObjectLiteralExpression,
|
|
59
|
+
ruleName: string,
|
|
60
|
+
initializer: string,
|
|
61
|
+
): boolean {
|
|
62
|
+
const existing = rules.getProperty(
|
|
63
|
+
(property) =>
|
|
64
|
+
Node.isPropertyAssignment(property) &&
|
|
65
|
+
getPropertyName(property.getNameNode()) === ruleName,
|
|
66
|
+
);
|
|
67
|
+
if (Node.isPropertyAssignment(existing)) {
|
|
68
|
+
if (existing.getInitializer()?.getText() === initializer) return false;
|
|
69
|
+
existing.setInitializer(initializer);
|
|
70
|
+
} else {
|
|
71
|
+
rules.addPropertyAssignment({ name: `'${ruleName}'`, initializer });
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getPropertyName(node: Node): string {
|
|
77
|
+
return Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)
|
|
78
|
+
? node.getLiteralValue()
|
|
79
|
+
: node.getText();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function findUp(startDir: string, names: readonly string[]): string | undefined {
|
|
83
|
+
let current = resolve(startDir);
|
|
84
|
+
while (true) {
|
|
85
|
+
for (const name of names) {
|
|
86
|
+
const candidate = join(current, name);
|
|
87
|
+
if (existsSync(candidate)) return candidate;
|
|
88
|
+
}
|
|
89
|
+
const parent = dirname(current);
|
|
90
|
+
if (parent === current) return undefined;
|
|
91
|
+
current = parent;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { PrimitiveMigrationDiagnostic } from './migration-diagnostic.js';
|
|
2
|
+
export type MigratePrimitivesOptions = {
|
|
3
|
+
rootDir?: string;
|
|
4
|
+
tsConfigFilePath?: string;
|
|
5
|
+
files?: readonly string[];
|
|
6
|
+
write?: boolean;
|
|
7
|
+
check?: boolean;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
jsonFilePath?: string;
|
|
10
|
+
failOnManual?: boolean;
|
|
11
|
+
eslint?: boolean;
|
|
12
|
+
log?: (message: string) => void;
|
|
13
|
+
};
|
|
14
|
+
export type MigratedPrimitiveFile = {
|
|
15
|
+
filePath: string;
|
|
16
|
+
changed: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type MigratePrimitivesResult = {
|
|
19
|
+
changedFiles: string[];
|
|
20
|
+
files: MigratedPrimitiveFile[];
|
|
21
|
+
diagnostics: PrimitiveMigrationDiagnostic[];
|
|
22
|
+
remainingAngularSignals: number;
|
|
23
|
+
remainingSignalForms: number;
|
|
24
|
+
eslintRan: boolean;
|
|
25
|
+
exitCode: number;
|
|
26
|
+
};
|
|
27
|
+
export declare function runPrimitivesMigration(options?: MigratePrimitivesOptions): Promise<MigratePrimitivesResult>;
|