@ethlete/query 6.0.0-next.6 ā 6.0.0-next.60
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/CHANGELOG.md +939 -0
- package/fesm2022/ethlete-query-devtools-contract.mjs +1 -0
- package/fesm2022/ethlete-query-ngrx-toolkit.mjs +411 -0
- package/fesm2022/ethlete-query-ngrx-toolkit.mjs.map +1 -0
- package/fesm2022/ethlete-query-testing.mjs +548 -169
- package/fesm2022/ethlete-query-testing.mjs.map +1 -1
- package/fesm2022/ethlete-query.mjs +14680 -7172
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/generators/deprecate-legacy-queries/migration.js +85 -0
- package/generators/deprecate-legacy-queries/schema.json +26 -0
- package/generators/generators.json +30 -0
- package/generators/migrate-from-ngrx-toolkit/args-assignability.js +140 -0
- package/generators/migrate-from-ngrx-toolkit/consumers.js +521 -0
- package/generators/migrate-from-ngrx-toolkit/creators.js +301 -0
- package/generators/migrate-from-ngrx-toolkit/facade.js +295 -0
- package/generators/migrate-from-ngrx-toolkit/feature.js +513 -0
- package/generators/migrate-from-ngrx-toolkit/migration.js +140 -0
- package/generators/migrate-from-ngrx-toolkit/report.js +154 -0
- package/generators/migrate-from-ngrx-toolkit/schema.json +42 -0
- package/generators/migrate-from-ngrx-toolkit/store-removal.js +633 -0
- package/generators/migrate-from-ngrx-toolkit/ts-edits.js +128 -0
- package/generators/migrate-query-client-features/migration.js +144 -0
- package/generators/migrate-query-client-features/report.js +136 -0
- package/generators/migrate-query-client-features/schema.json +26 -0
- package/generators/migrate-query-opt-in-features/migration.js +195 -0
- package/generators/migrate-query-opt-in-features/report.js +143 -0
- package/generators/migrate-query-opt-in-features/schema.json +31 -0
- package/generators/migrate-to-query-v3/auth-provider-scaffold.js +160 -0
- package/generators/migrate-to-query-v3/cleanup-migration.js +247 -125
- package/generators/migrate-to-query-v3/http-client-check.js +93 -0
- package/generators/migrate-to-query-v3/legacy-prepare-migration.js +129 -40
- package/generators/migrate-to-query-v3/legacy-query-creator-migration.js +274 -152
- package/generators/migrate-to-query-v3/migration-scope.js +40 -0
- package/generators/migrate-to-query-v3/migration.js +19 -10
- package/generators/migrate-to-query-v3/module-graph.js +165 -0
- package/generators/migrate-to-query-v3/query-client-migration.js +342 -160
- package/generators/migrate-to-query-v3/rename-symbols.js +233 -0
- package/generators/migrate-to-query-v3/report.js +40 -7
- package/generators/migrate-to-query-v3/schema.json +12 -0
- package/generators/migrate-to-query-v3/shared.js +97 -3
- package/generators/move-devtools-contract-imports/migration.js +155 -0
- package/generators/move-devtools-contract-imports/moved-names.js +153 -0
- package/generators/move-devtools-contract-imports/schema.json +26 -0
- package/generators/prep-for-query-v3/migration.js +465 -65
- package/generators/report-legacy-query-apis/migration.js +256 -0
- package/generators/report-legacy-query-apis/schema.json +25 -0
- package/migrations/query-field-default-types.md +43 -0
- package/migrations/search-query-field-string.md +43 -0
- package/migrations.json +87 -0
- package/package.json +34 -14
- package/types/ethlete-query-devtools-contract.d.ts +2 -0
- package/types/ethlete-query-ngrx-toolkit.d.ts +131 -0
- package/types/ethlete-query-testing.d.ts +295 -160
- package/types/ethlete-query.d.ts +9755 -3682
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import { formatFiles } from '@nx/devkit';
|
|
2
|
-
import {
|
|
2
|
+
import { migrateDevtoolsUsage, migrateEmptyPrepareCalls, replaceAnyQueryWithLegacy, reportRemovedExperimentalQueryHelpers, } from './cleanup-migration.js';
|
|
3
|
+
import { reportDefaultHeaderUsages, reportMissingHttpClientProviders } from './http-client-check.js';
|
|
3
4
|
import { migrateLegacyPrepareCalls } from './legacy-prepare-migration.js';
|
|
4
5
|
import { createNewQueryCreators, updateLegacyCreatorImportsAndUsages } from './legacy-query-creator-migration.js';
|
|
6
|
+
import { createMigrationScope } from './migration-scope.js';
|
|
5
7
|
import { generateProviderAliases, generateQueryCreators, migrateQueryClients, updateImportsAcrossWorkspace, } from './query-client-migration.js';
|
|
6
8
|
import { QueryV3MigrationReport } from './report.js';
|
|
7
9
|
export default async function migrate(tree, schema) {
|
|
8
10
|
console.log('\nš Starting query v3 migration...');
|
|
11
|
+
const scope = createMigrationScope(tree, schema);
|
|
12
|
+
console.log(` Scope: ${scope.describe()}`);
|
|
9
13
|
const report = new QueryV3MigrationReport();
|
|
10
|
-
const { queryClientFiles, variableRenames } = migrateQueryClients(tree, report);
|
|
14
|
+
const { queryClientFiles, variableRenames } = migrateQueryClients(tree, report, scope);
|
|
11
15
|
if (queryClientFiles.size > 0) {
|
|
12
16
|
generateProviderAliases(tree, queryClientFiles);
|
|
13
17
|
generateQueryCreators(tree, queryClientFiles);
|
|
14
|
-
createNewQueryCreators(tree, queryClientFiles, report);
|
|
15
|
-
updateLegacyCreatorImportsAndUsages(tree);
|
|
18
|
+
createNewQueryCreators(tree, queryClientFiles, report, scope);
|
|
19
|
+
updateLegacyCreatorImportsAndUsages(tree, scope, report);
|
|
16
20
|
}
|
|
17
21
|
if (variableRenames.size > 0) {
|
|
18
|
-
updateImportsAcrossWorkspace(tree, variableRenames);
|
|
22
|
+
updateImportsAcrossWorkspace(tree, variableRenames, scope, report);
|
|
19
23
|
}
|
|
20
|
-
replaceAnyQueryWithLegacy(tree);
|
|
21
|
-
|
|
22
|
-
migrateEmptyPrepareCalls(tree);
|
|
23
|
-
migrateLegacyPrepareCalls(tree, report);
|
|
24
|
-
|
|
24
|
+
replaceAnyQueryWithLegacy(tree, scope);
|
|
25
|
+
migrateDevtoolsUsage(tree, scope, report);
|
|
26
|
+
migrateEmptyPrepareCalls(tree, scope, report);
|
|
27
|
+
migrateLegacyPrepareCalls(tree, report, scope);
|
|
28
|
+
reportRemovedExperimentalQueryHelpers(tree, scope, report);
|
|
29
|
+
if (queryClientFiles.size > 0) {
|
|
30
|
+
reportMissingHttpClientProviders(tree, report, scope);
|
|
31
|
+
reportDefaultHeaderUsages(tree, report, scope);
|
|
32
|
+
}
|
|
33
|
+
report.writeToTree(tree, scope.isScoped ? scope.describe() : undefined);
|
|
25
34
|
report.printSummary();
|
|
26
35
|
if (!schema.skipFormat) {
|
|
27
36
|
await formatFiles(tree);
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { createSourceFile } from './shared.js';
|
|
3
|
+
const MAX_BARREL_DEPTH = 8;
|
|
4
|
+
const normalizePath = (path) => {
|
|
5
|
+
const segments = [];
|
|
6
|
+
for (const segment of path.split('/')) {
|
|
7
|
+
if (segment === '' || segment === '.')
|
|
8
|
+
continue;
|
|
9
|
+
if (segment === '..') {
|
|
10
|
+
segments.pop();
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
segments.push(segment);
|
|
14
|
+
}
|
|
15
|
+
return segments.join('/');
|
|
16
|
+
};
|
|
17
|
+
const dirName = (path) => path.slice(0, Math.max(0, path.lastIndexOf('/')));
|
|
18
|
+
const readTsConfig = (tree) => {
|
|
19
|
+
const paths = new Map();
|
|
20
|
+
let baseUrl = null;
|
|
21
|
+
for (const configPath of ['tsconfig.base.json', 'tsconfig.json']) {
|
|
22
|
+
const raw = tree.read(configPath, 'utf-8');
|
|
23
|
+
if (!raw)
|
|
24
|
+
continue;
|
|
25
|
+
try {
|
|
26
|
+
// tsconfig files are JSONC in practice; the TS parser is the only thing that reliably reads
|
|
27
|
+
// them, comments and trailing commas included.
|
|
28
|
+
const parsed = ts.parseConfigFileTextToJson(configPath, raw).config;
|
|
29
|
+
const configBaseUrl = parsed?.compilerOptions?.baseUrl;
|
|
30
|
+
if (baseUrl === null && typeof configBaseUrl === 'string')
|
|
31
|
+
baseUrl = normalizePath(configBaseUrl);
|
|
32
|
+
Object.entries(parsed?.compilerOptions?.paths ?? {}).forEach(([key, targets]) => {
|
|
33
|
+
if (!paths.has(key))
|
|
34
|
+
paths.set(key, targets);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// A tsconfig we cannot parse just means fewer resolvable aliases, not a failed migration.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return { paths, baseUrl };
|
|
42
|
+
};
|
|
43
|
+
/** The part of `specifier` the `*` of `pattern` stands for, `''` for an exact match, or `null`. */
|
|
44
|
+
const matchPathAlias = (pattern, specifier) => {
|
|
45
|
+
const wildcardIndex = pattern.indexOf('*');
|
|
46
|
+
if (wildcardIndex === -1)
|
|
47
|
+
return pattern === specifier ? '' : null;
|
|
48
|
+
const prefix = pattern.slice(0, wildcardIndex);
|
|
49
|
+
const patternSuffix = pattern.slice(wildcardIndex + 1);
|
|
50
|
+
if (!specifier.startsWith(prefix) || !specifier.endsWith(patternSuffix))
|
|
51
|
+
return null;
|
|
52
|
+
return specifier.slice(prefix.length, specifier.length - patternSuffix.length);
|
|
53
|
+
};
|
|
54
|
+
const JS_EXTENSION = /\.(m?)js$/;
|
|
55
|
+
/** The files a specifier could point at, most specific first. */
|
|
56
|
+
const candidateFiles = (base) => {
|
|
57
|
+
if (base.endsWith('.ts'))
|
|
58
|
+
return [base];
|
|
59
|
+
const jsExtension = JS_EXTENSION.exec(base);
|
|
60
|
+
if (jsExtension) {
|
|
61
|
+
const stem = base.slice(0, -jsExtension[0].length);
|
|
62
|
+
return [`${stem}.${jsExtension[1]}ts`, `${stem}.ts`, `${stem}.d.ts`, `${base}/index.ts`];
|
|
63
|
+
}
|
|
64
|
+
return [`${base}.ts`, `${base}/index.ts`, `${base}.d.ts`];
|
|
65
|
+
};
|
|
66
|
+
export const createModuleGraph = (tree) => {
|
|
67
|
+
const { paths: tsConfigPaths, baseUrl } = readTsConfig(tree);
|
|
68
|
+
const findCandidate = (base) => candidateFiles(base).find((candidate) => tree.exists(candidate)) ?? null;
|
|
69
|
+
const declaringFileCache = new Map();
|
|
70
|
+
const resolveEntryFile = (fromFile, specifier) => {
|
|
71
|
+
if (specifier.startsWith('.'))
|
|
72
|
+
return findCandidate(normalizePath(`${dirName(fromFile)}/${specifier}`));
|
|
73
|
+
for (const [pattern, targets] of tsConfigPaths.entries()) {
|
|
74
|
+
const wildcard = matchPathAlias(pattern, specifier);
|
|
75
|
+
if (wildcard === null)
|
|
76
|
+
continue;
|
|
77
|
+
for (const target of targets) {
|
|
78
|
+
const candidate = findCandidate(normalizePath(`${baseUrl ?? ''}/${target.replace('*', wildcard)}`));
|
|
79
|
+
if (candidate)
|
|
80
|
+
return candidate;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return baseUrl === null ? null : findCandidate(normalizePath(`${baseUrl}/${specifier}`));
|
|
84
|
+
};
|
|
85
|
+
const declaresSymbol = (sourceFile, symbolName) => {
|
|
86
|
+
let declares = false;
|
|
87
|
+
const isExported = (node) => ts.canHaveModifiers(node) &&
|
|
88
|
+
ts.getModifiers(node)?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword);
|
|
89
|
+
ts.forEachChild(sourceFile, (node) => {
|
|
90
|
+
if (declares)
|
|
91
|
+
return;
|
|
92
|
+
if (ts.isVariableStatement(node) && isExported(node)) {
|
|
93
|
+
declares = node.declarationList.declarations.some((declaration) => ts.isIdentifier(declaration.name) && declaration.name.text === symbolName);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if ((ts.isFunctionDeclaration(node) ||
|
|
97
|
+
ts.isClassDeclaration(node) ||
|
|
98
|
+
ts.isInterfaceDeclaration(node) ||
|
|
99
|
+
ts.isTypeAliasDeclaration(node) ||
|
|
100
|
+
ts.isEnumDeclaration(node)) &&
|
|
101
|
+
isExported(node) &&
|
|
102
|
+
node.name?.text === symbolName) {
|
|
103
|
+
declares = true;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return declares;
|
|
107
|
+
};
|
|
108
|
+
const findDeclaringFileIn = (entryFile, symbolName, depth, seen) => {
|
|
109
|
+
if (depth > MAX_BARREL_DEPTH || seen.has(`${entryFile}#${symbolName}`))
|
|
110
|
+
return null;
|
|
111
|
+
seen.add(`${entryFile}#${symbolName}`);
|
|
112
|
+
const content = tree.read(entryFile, 'utf-8');
|
|
113
|
+
if (!content)
|
|
114
|
+
return null;
|
|
115
|
+
const sourceFile = createSourceFile(content, entryFile);
|
|
116
|
+
if (declaresSymbol(sourceFile, symbolName))
|
|
117
|
+
return entryFile;
|
|
118
|
+
const starExports = [];
|
|
119
|
+
for (const node of sourceFile.statements) {
|
|
120
|
+
if (!ts.isExportDeclaration(node) || !node.moduleSpecifier || !ts.isStringLiteral(node.moduleSpecifier)) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const nextEntry = resolveEntryFile(entryFile, node.moduleSpecifier.text);
|
|
124
|
+
if (!nextEntry)
|
|
125
|
+
continue;
|
|
126
|
+
if (!node.exportClause) {
|
|
127
|
+
starExports.push(nextEntry);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (!ts.isNamedExports(node.exportClause))
|
|
131
|
+
continue;
|
|
132
|
+
for (const element of node.exportClause.elements) {
|
|
133
|
+
if (element.name.text !== symbolName)
|
|
134
|
+
continue;
|
|
135
|
+
const originalName = element.propertyName?.text ?? symbolName;
|
|
136
|
+
const found = findDeclaringFileIn(nextEntry, originalName, depth + 1, seen);
|
|
137
|
+
if (found)
|
|
138
|
+
return found;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const starExport of starExports) {
|
|
142
|
+
const found = findDeclaringFileIn(starExport, symbolName, depth + 1, seen);
|
|
143
|
+
if (found)
|
|
144
|
+
return found;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
resolveFile: resolveEntryFile,
|
|
150
|
+
pathAliases: () => [...tsConfigPaths.keys()],
|
|
151
|
+
isWorkspaceSpecifier: (specifier) => specifier.startsWith('.') ||
|
|
152
|
+
[...tsConfigPaths.keys()].some((pattern) => matchPathAlias(pattern, specifier) !== null),
|
|
153
|
+
findDeclaringFile: (fromFile, specifier, symbolName) => {
|
|
154
|
+
const cacheKey = `${fromFile}|${specifier}|${symbolName}`;
|
|
155
|
+
const cached = declaringFileCache.get(cacheKey);
|
|
156
|
+
if (cached !== undefined)
|
|
157
|
+
return cached;
|
|
158
|
+
const entryFile = resolveEntryFile(fromFile, specifier);
|
|
159
|
+
const declaringFile = entryFile ? findDeclaringFileIn(entryFile, symbolName, 0, new Set()) : null;
|
|
160
|
+
declaringFileCache.set(cacheKey, declaringFile);
|
|
161
|
+
return declaringFile;
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=module-graph.js.map
|