@tanstack/router-generator 1.166.29 → 1.166.30
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/dist/cjs/config.cjs +0 -1
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/config.d.cts +0 -3
- package/dist/cjs/generator.cjs +1 -44
- package/dist/cjs/generator.cjs.map +1 -1
- package/dist/cjs/index.cjs +0 -2
- package/dist/cjs/index.d.cts +1 -2
- package/dist/cjs/template.cjs +15 -12
- package/dist/cjs/template.cjs.map +1 -1
- package/dist/cjs/transform/transform.cjs +283 -266
- package/dist/cjs/transform/transform.cjs.map +1 -1
- package/dist/cjs/transform/transform.d.cts +1 -3
- package/dist/cjs/transform/types.d.cts +1 -7
- package/dist/cjs/utils.cjs +0 -16
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +0 -24
- package/dist/esm/config.d.ts +0 -3
- package/dist/esm/config.js +0 -1
- package/dist/esm/config.js.map +1 -1
- package/dist/esm/generator.js +2 -45
- package/dist/esm/generator.js.map +1 -1
- package/dist/esm/index.d.ts +1 -2
- package/dist/esm/index.js +1 -2
- package/dist/esm/template.js +15 -12
- package/dist/esm/template.js.map +1 -1
- package/dist/esm/transform/transform.d.ts +1 -3
- package/dist/esm/transform/transform.js +280 -265
- package/dist/esm/transform/transform.js.map +1 -1
- package/dist/esm/transform/types.d.ts +1 -7
- package/dist/esm/utils.d.ts +0 -24
- package/dist/esm/utils.js +1 -15
- package/dist/esm/utils.js.map +1 -1
- package/package.json +4 -4
- package/src/config.ts +0 -1
- package/src/generator.ts +0 -66
- package/src/index.ts +1 -7
- package/src/template.ts +16 -36
- package/src/transform/transform.ts +633 -446
- package/src/transform/types.ts +1 -8
- package/src/utils.ts +5 -43
- package/dist/cjs/transform/utils.cjs +0 -34
- package/dist/cjs/transform/utils.cjs.map +0 -1
- package/dist/cjs/transform/utils.d.cts +0 -2
- package/dist/esm/transform/utils.d.ts +0 -2
- package/dist/esm/transform/utils.js +0 -34
- package/dist/esm/transform/utils.js.map +0 -1
- package/src/transform/utils.ts +0 -42
|
@@ -1,299 +1,316 @@
|
|
|
1
|
-
require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let magic_string = require("magic-string");
|
|
3
|
+
magic_string = require_runtime.__toESM(magic_string);
|
|
4
|
+
let _babel_types = require("@babel/types");
|
|
5
|
+
_babel_types = require_runtime.__toESM(_babel_types);
|
|
4
6
|
let _tanstack_router_utils = require("@tanstack/router-utils");
|
|
5
|
-
let recast = require("recast");
|
|
6
|
-
let source_map = require("source-map");
|
|
7
7
|
//#region src/transform/transform.ts
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
let appliedChanges = false;
|
|
8
|
+
var routeConstructors = ["createFileRoute", "createLazyFileRoute"];
|
|
9
|
+
function transform({ ctx, source, node }) {
|
|
11
10
|
let ast;
|
|
12
11
|
try {
|
|
13
|
-
ast = (0,
|
|
14
|
-
|
|
15
|
-
parser: { parse(code) {
|
|
16
|
-
return (0, _tanstack_router_utils.parseAst)({
|
|
17
|
-
code,
|
|
18
|
-
tokens: true
|
|
19
|
-
});
|
|
20
|
-
} }
|
|
21
|
-
});
|
|
22
|
-
} catch (e) {
|
|
23
|
-
console.error("Error parsing code", ctx.routeId, source, e);
|
|
12
|
+
ast = (0, _tanstack_router_utils.parseAst)({ code: source });
|
|
13
|
+
} catch (error) {
|
|
24
14
|
return {
|
|
25
15
|
result: "error",
|
|
26
|
-
error
|
|
16
|
+
error
|
|
27
17
|
};
|
|
28
18
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (identifier.name === "createFileRoute" && ctx.lazy) {
|
|
60
|
-
identifier.name = "createLazyFileRoute";
|
|
61
|
-
appliedChanges = true;
|
|
62
|
-
} else if (identifier.name === "createLazyFileRoute" && !ctx.lazy) {
|
|
63
|
-
identifier.name = "createFileRoute";
|
|
64
|
-
appliedChanges = true;
|
|
65
|
-
}
|
|
66
|
-
} else throw new Error(`expected "Route" export to be initialized by a CallExpression`);
|
|
67
|
-
routeExportHandled = true;
|
|
19
|
+
const exportedRouteNames = getExportedRouteNames(ast.program.body);
|
|
20
|
+
if (exportedRouteNames.size === 0) return { result: "no-route-export" };
|
|
21
|
+
const { calls: routeCalls, hasUnsupportedRouteId, hasMalformedRouteCall } = findExportedRouteCalls(ast.program.body, exportedRouteNames);
|
|
22
|
+
if (routeCalls.length === 0 && hasMalformedRouteCall) return {
|
|
23
|
+
result: "error",
|
|
24
|
+
error: /* @__PURE__ */ new Error(`expected Route export in ${ctx.routeId} to use createFileRoute('/path')({...}) or createLazyFileRoute('/path')({...})`)
|
|
25
|
+
};
|
|
26
|
+
if (routeCalls.length === 0 && hasUnsupportedRouteId) return {
|
|
27
|
+
result: "error",
|
|
28
|
+
error: /* @__PURE__ */ new Error(`expected route id to be a string literal or plain template literal in ${ctx.routeId}`)
|
|
29
|
+
};
|
|
30
|
+
if (routeCalls.length === 0) return { result: "not-modified" };
|
|
31
|
+
if (routeCalls.length > 1) return {
|
|
32
|
+
result: "error",
|
|
33
|
+
error: /* @__PURE__ */ new Error(`expected exactly one createFileRoute/createLazyFileRoute call in ${ctx.routeId}`)
|
|
34
|
+
};
|
|
35
|
+
const routeCall = routeCalls[0];
|
|
36
|
+
const routeIdQuote = getRouteIdQuote(source, routeCall.routeIdArg);
|
|
37
|
+
const createFileRouteProps = getCreateFileRouteProps(routeCall.optionsArg);
|
|
38
|
+
if (createFileRouteProps) node.createFileRouteProps = createFileRouteProps;
|
|
39
|
+
const expectedCallee = getExpectedRouteConstructor(ctx.lazy);
|
|
40
|
+
const expectedRouteId = `${routeIdQuote}${ctx.routeId}${routeIdQuote}`;
|
|
41
|
+
const currentRouteId = source.slice(routeCall.routeIdArg.start, routeCall.routeIdArg.end);
|
|
42
|
+
const targetModule = `@tanstack/${ctx.target}-router`;
|
|
43
|
+
const imports = parseTargetImports(ast.program.body, source, targetModule);
|
|
44
|
+
const s = new magic_string.default(source);
|
|
45
|
+
let modified = false;
|
|
46
|
+
if (routeCall.callee.name !== expectedCallee) {
|
|
47
|
+
s.update(routeCall.callee.start, routeCall.callee.end, expectedCallee);
|
|
48
|
+
modified = true;
|
|
68
49
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (n.declaration?.type === "VariableDeclaration") {
|
|
73
|
-
const decl = n.declaration.declarations[0];
|
|
74
|
-
if (decl && decl.type === "VariableDeclarator" && decl.id.type === "Identifier") {
|
|
75
|
-
if (decl.id.name === "Route") onExportFound(decl);
|
|
76
|
-
}
|
|
77
|
-
} else if (n.declaration === null && n.specifiers) {
|
|
78
|
-
for (const spec of n.specifiers) if (typeof spec.exported.name === "string") {
|
|
79
|
-
if (spec.exported.name === "Route") {
|
|
80
|
-
const variableName = spec.local?.name || spec.exported.name;
|
|
81
|
-
for (const decl of program.body) if (decl.type === "VariableDeclaration" && decl.declarations[0]) {
|
|
82
|
-
const variable = decl.declarations[0];
|
|
83
|
-
if (variable.type === "VariableDeclarator" && variable.id.type === "Identifier" && variable.id.name === variableName) {
|
|
84
|
-
onExportFound(variable);
|
|
85
|
-
break;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (routeExportHandled) break;
|
|
50
|
+
if (currentRouteId !== expectedRouteId) {
|
|
51
|
+
s.update(routeCall.routeIdArg.start, routeCall.routeIdArg.end, expectedRouteId);
|
|
52
|
+
modified = true;
|
|
93
53
|
}
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
54
|
+
if (updateRouteImports({
|
|
55
|
+
imports,
|
|
56
|
+
source,
|
|
57
|
+
s,
|
|
58
|
+
targetModule,
|
|
59
|
+
required: expectedCallee,
|
|
60
|
+
lineEnding: getLineEnding(source)
|
|
61
|
+
})) modified = true;
|
|
62
|
+
if (!modified) return { result: "not-modified" };
|
|
63
|
+
return {
|
|
64
|
+
result: "modified",
|
|
65
|
+
output: s.toString()
|
|
98
66
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}];
|
|
113
|
-
} else {
|
|
114
|
-
imports.required = [{
|
|
115
|
-
source: targetModule,
|
|
116
|
-
specifiers: [{ imported: "createFileRoute" }]
|
|
117
|
-
}];
|
|
118
|
-
imports.banned = [{
|
|
119
|
-
source: targetModule,
|
|
120
|
-
specifiers: [{ imported: "createLazyFileRoute" }]
|
|
121
|
-
}];
|
|
67
|
+
}
|
|
68
|
+
function getExportedRouteNames(body) {
|
|
69
|
+
const exportedRouteNames = /* @__PURE__ */ new Set();
|
|
70
|
+
for (const statement of body) {
|
|
71
|
+
if (!_babel_types.isExportNamedDeclaration(statement) || statement.source) continue;
|
|
72
|
+
if (_babel_types.isVariableDeclaration(statement.declaration)) {
|
|
73
|
+
for (const declarator of statement.declaration.declarations) if (_babel_types.isIdentifier(declarator.id) && declarator.id.name === "Route") exportedRouteNames.add("Route");
|
|
74
|
+
}
|
|
75
|
+
for (const specifier of statement.specifiers) {
|
|
76
|
+
if (!_babel_types.isExportSpecifier(specifier) || getExportedName(specifier.exported) !== "Route") continue;
|
|
77
|
+
const localName = getLocalBindingName(specifier.local);
|
|
78
|
+
if (localName) exportedRouteNames.add(localName);
|
|
79
|
+
}
|
|
122
80
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
81
|
+
return exportedRouteNames;
|
|
82
|
+
}
|
|
83
|
+
function findExportedRouteCalls(body, exportedRouteNames) {
|
|
84
|
+
const calls = [];
|
|
85
|
+
let hasUnsupportedRouteId = false;
|
|
86
|
+
let hasMalformedRouteCall = false;
|
|
87
|
+
for (const statement of body) {
|
|
88
|
+
const declaration = getVariableDeclaration(statement);
|
|
89
|
+
if (!declaration) continue;
|
|
90
|
+
for (const declarator of declaration.declarations) {
|
|
91
|
+
if (!_babel_types.isIdentifier(declarator.id) || !exportedRouteNames.has(declarator.id.name)) continue;
|
|
92
|
+
const init = getRouteConstructorInit(declarator.init);
|
|
93
|
+
if (!init) {
|
|
94
|
+
if (isDirectRouteConstructorCall(declarator.init)) hasMalformedRouteCall = true;
|
|
95
|
+
continue;
|
|
132
96
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
importKind: n.importKind
|
|
97
|
+
const routeIdArg = init.innerCall.arguments[0];
|
|
98
|
+
if (isSupportedRouteId(routeIdArg)) calls.push({
|
|
99
|
+
callee: init.callee,
|
|
100
|
+
routeIdArg,
|
|
101
|
+
optionsArg: init.outerCall.arguments[0]
|
|
139
102
|
});
|
|
140
|
-
|
|
141
|
-
const bannedImports = imports.banned.filter(filterImport)[0];
|
|
142
|
-
if (!requiredImports && !bannedImports) continue;
|
|
143
|
-
const importSpecifiersToRemove = [];
|
|
144
|
-
if (n.specifiers) {
|
|
145
|
-
for (const spec of n.specifiers) {
|
|
146
|
-
if (!requiredImports && !bannedImports) break;
|
|
147
|
-
if (spec.type === "ImportSpecifier" && typeof spec.imported.name === "string") {
|
|
148
|
-
if (requiredImports) {
|
|
149
|
-
const requiredImportIndex = requiredImports.specifiers.findIndex((imp) => imp.imported === spec.imported.name);
|
|
150
|
-
if (requiredImportIndex !== -1) {
|
|
151
|
-
requiredImports.specifiers.splice(requiredImportIndex, 1);
|
|
152
|
-
if (requiredImports.specifiers.length === 0) {
|
|
153
|
-
imports.required = imports.required.splice(imports.required.indexOf(requiredImports), 1);
|
|
154
|
-
requiredImports = void 0;
|
|
155
|
-
}
|
|
156
|
-
} else importStatementCandidates.push(n);
|
|
157
|
-
}
|
|
158
|
-
if (bannedImports) {
|
|
159
|
-
if (bannedImports.specifiers.findIndex((imp) => imp.imported === spec.imported.name) !== -1) importSpecifiersToRemove.push(spec);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (importSpecifiersToRemove.length > 0) {
|
|
164
|
-
appliedChanges = true;
|
|
165
|
-
n.specifiers = n.specifiers.filter((spec) => !importSpecifiersToRemove.includes(spec));
|
|
166
|
-
if (n.specifiers.length === 0) importDeclarationsToRemove.push(n);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
103
|
+
else hasUnsupportedRouteId = true;
|
|
169
104
|
}
|
|
170
105
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
106
|
+
return {
|
|
107
|
+
calls,
|
|
108
|
+
hasUnsupportedRouteId,
|
|
109
|
+
hasMalformedRouteCall
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function getVariableDeclaration(statement) {
|
|
113
|
+
const declaration = _babel_types.isExportNamedDeclaration(statement) ? statement.declaration : statement;
|
|
114
|
+
return _babel_types.isVariableDeclaration(declaration) ? declaration : null;
|
|
115
|
+
}
|
|
116
|
+
function getExportedName(node) {
|
|
117
|
+
return _babel_types.isIdentifier(node) ? node.name : node.value;
|
|
118
|
+
}
|
|
119
|
+
function getLocalBindingName(node) {
|
|
120
|
+
return _babel_types.isIdentifier(node) ? node.name : null;
|
|
121
|
+
}
|
|
122
|
+
function getRouteConstructorInit(expression) {
|
|
123
|
+
if (!expression || !_babel_types.isCallExpression(expression)) return null;
|
|
124
|
+
if (!_babel_types.isCallExpression(expression.callee)) return null;
|
|
125
|
+
const innerCall = expression.callee;
|
|
126
|
+
if (!_babel_types.isIdentifier(innerCall.callee) || !isRouteConstructor(innerCall.callee)) return null;
|
|
127
|
+
return {
|
|
128
|
+
callee: innerCall.callee,
|
|
129
|
+
outerCall: expression,
|
|
130
|
+
innerCall
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function isDirectRouteConstructorCall(expression) {
|
|
134
|
+
return !!expression && _babel_types.isCallExpression(expression) && _babel_types.isIdentifier(expression.callee) && isRouteConstructor(expression.callee);
|
|
135
|
+
}
|
|
136
|
+
function isRouteConstructor(callee) {
|
|
137
|
+
return routeConstructors.includes(callee.name);
|
|
138
|
+
}
|
|
139
|
+
function isSupportedRouteId(arg) {
|
|
140
|
+
return !!arg && (_babel_types.isStringLiteral(arg) || _babel_types.isTemplateLiteral(arg) && arg.expressions.length === 0);
|
|
141
|
+
}
|
|
142
|
+
function getRouteIdQuote(source, arg) {
|
|
143
|
+
const raw = source.slice(arg.start, arg.end);
|
|
144
|
+
if (raw.startsWith("'")) return "'";
|
|
145
|
+
if (raw.startsWith("\"")) return "\"";
|
|
146
|
+
return "`";
|
|
147
|
+
}
|
|
148
|
+
function getCreateFileRouteProps(arg) {
|
|
149
|
+
if (!arg || !_babel_types.isObjectExpression(arg)) return;
|
|
150
|
+
const props = /* @__PURE__ */ new Set();
|
|
151
|
+
for (const property of arg.properties) {
|
|
152
|
+
if (!_babel_types.isObjectProperty(property) || property.computed) continue;
|
|
153
|
+
if (_babel_types.isIdentifier(property.key)) {
|
|
154
|
+
props.add(property.key.name);
|
|
155
|
+
continue;
|
|
188
156
|
}
|
|
157
|
+
if (_babel_types.isStringLiteral(property.key)) props.add(property.key.value);
|
|
158
|
+
}
|
|
159
|
+
return props;
|
|
160
|
+
}
|
|
161
|
+
function parseTargetImports(body, source, targetModule) {
|
|
162
|
+
const imports = [];
|
|
163
|
+
for (const statement of body) {
|
|
164
|
+
if (!_babel_types.isImportDeclaration(statement) || statement.importKind === "type" || statement.source.value !== targetModule) continue;
|
|
165
|
+
const rawSource = source.slice(statement.source.start, statement.source.end);
|
|
166
|
+
const importStatement = source.slice(statement.start, statement.end);
|
|
167
|
+
imports.push({
|
|
168
|
+
declaration: statement,
|
|
169
|
+
defaultImport: statement.specifiers.find((specifier) => _babel_types.isImportDefaultSpecifier(specifier))?.local.name,
|
|
170
|
+
namespace: statement.specifiers.find((specifier) => _babel_types.isImportNamespaceSpecifier(specifier))?.local.name,
|
|
171
|
+
named: statement.specifiers.filter((specifier) => _babel_types.isImportSpecifier(specifier)).map((specifier) => ({
|
|
172
|
+
imported: _babel_types.isIdentifier(specifier.imported) ? specifier.imported.name : specifier.imported.value,
|
|
173
|
+
local: specifier.local.name,
|
|
174
|
+
importKind: specifier.importKind ?? void 0
|
|
175
|
+
})),
|
|
176
|
+
moduleName: statement.source.value,
|
|
177
|
+
quote: rawSource[0],
|
|
178
|
+
semicolon: importStatement.trimEnd().endsWith(";")
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return imports;
|
|
182
|
+
}
|
|
183
|
+
function updateRouteImports({ imports, source, s, targetModule, required, lineEnding }) {
|
|
184
|
+
const analysis = analyzeRouteImports(imports, required);
|
|
185
|
+
if (analysis.kind === "ok") return false;
|
|
186
|
+
if (analysis.kind === "rename") {
|
|
187
|
+
s.update(analysis.imported.start, analysis.imported.end, analysis.next);
|
|
188
|
+
s.update(analysis.local.start, analysis.local.end, analysis.next);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
return normalizeRouteImports({
|
|
192
|
+
imports,
|
|
193
|
+
source,
|
|
194
|
+
s,
|
|
195
|
+
targetModule,
|
|
196
|
+
required,
|
|
197
|
+
lineEnding
|
|
189
198
|
});
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
199
|
+
}
|
|
200
|
+
function analyzeRouteImports(imports, required) {
|
|
201
|
+
const opposite = getOtherRouteConstructor(required);
|
|
202
|
+
let requiredCount = 0;
|
|
203
|
+
let oppositeCount = 0;
|
|
204
|
+
let renameCandidate;
|
|
205
|
+
for (const declaration of imports) for (const specifier of declaration.declaration.specifiers) {
|
|
206
|
+
if (!_babel_types.isImportSpecifier(specifier)) continue;
|
|
207
|
+
const imported = specifier.imported;
|
|
208
|
+
if (!_babel_types.isIdentifier(imported)) return { kind: "normalize" };
|
|
209
|
+
if (!isRouteConstructorName(imported.name)) continue;
|
|
210
|
+
if (specifier.local.name !== imported.name) return { kind: "normalize" };
|
|
211
|
+
if (imported.name === required) {
|
|
212
|
+
requiredCount++;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (imported.name === opposite) {
|
|
216
|
+
oppositeCount++;
|
|
217
|
+
renameCandidate = {
|
|
218
|
+
imported,
|
|
219
|
+
local: specifier.local,
|
|
220
|
+
next: required
|
|
221
|
+
};
|
|
195
222
|
}
|
|
196
223
|
}
|
|
197
|
-
if (
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
});
|
|
202
|
-
let transformedCode = printResult.code;
|
|
203
|
-
if (printResult.map) transformedCode = await fixTransformedOutputText({
|
|
204
|
-
originalCode: source,
|
|
205
|
-
transformedCode,
|
|
206
|
-
sourceMap: printResult.map,
|
|
207
|
-
preferredQuote
|
|
208
|
-
});
|
|
209
|
-
return {
|
|
210
|
-
result: "modified",
|
|
211
|
-
output: transformedCode
|
|
224
|
+
if (requiredCount === 1 && oppositeCount === 0) return { kind: "ok" };
|
|
225
|
+
if (requiredCount === 0 && oppositeCount === 1 && renameCandidate) return {
|
|
226
|
+
kind: "rename",
|
|
227
|
+
...renameCandidate
|
|
212
228
|
};
|
|
229
|
+
return { kind: "normalize" };
|
|
213
230
|
}
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
for (let col = 0; col < line.length; col++) {
|
|
223
|
-
const mapped = consumer.originalPositionFor({
|
|
224
|
-
line: transformedLineNum,
|
|
225
|
-
column: col
|
|
226
|
-
});
|
|
227
|
-
if (mapped.line != null && mapped.line > 0) {
|
|
228
|
-
origLineText = originalLines[mapped.line - 1];
|
|
229
|
-
break;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
if (origLineText !== void 0) {
|
|
233
|
-
if (origLineText === line) return origLineText;
|
|
234
|
-
return fixLine(line, {
|
|
235
|
-
originalLine: origLineText,
|
|
236
|
-
useOriginalSemicolon: true,
|
|
237
|
-
useOriginalQuotes: true,
|
|
238
|
-
fallbackQuote: preferredQuote
|
|
239
|
-
});
|
|
240
|
-
} else return fixLine(line, {
|
|
241
|
-
originalLine: null,
|
|
242
|
-
useOriginalSemicolon: false,
|
|
243
|
-
useOriginalQuotes: false,
|
|
244
|
-
fallbackQuote: preferredQuote,
|
|
245
|
-
fallbackSemicolon: defaultUsesSemicolons
|
|
231
|
+
function normalizeRouteImports({ imports, source, s, targetModule, required, lineEnding }) {
|
|
232
|
+
const owner = imports.find((declaration) => hasNamedImport(declaration.named, required)) ?? imports.find((declaration) => !declaration.namespace);
|
|
233
|
+
let modified = false;
|
|
234
|
+
for (const declaration of imports) {
|
|
235
|
+
const named = normalizeNamedImports({
|
|
236
|
+
named: declaration.named,
|
|
237
|
+
required,
|
|
238
|
+
isOwner: declaration === owner
|
|
246
239
|
});
|
|
247
|
-
|
|
240
|
+
if (sameNamedImports(declaration.named, named)) continue;
|
|
241
|
+
const replacement = renderImportDeclaration({
|
|
242
|
+
...declaration,
|
|
243
|
+
named
|
|
244
|
+
});
|
|
245
|
+
if (replacement === null) {
|
|
246
|
+
s.remove(declaration.declaration.start, getRemovalEnd(source, declaration.declaration.end));
|
|
247
|
+
modified = true;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
s.update(declaration.declaration.start, declaration.declaration.end, replacement);
|
|
251
|
+
modified = true;
|
|
252
|
+
}
|
|
253
|
+
if (!owner) {
|
|
254
|
+
const quote = imports[0]?.quote ?? "'";
|
|
255
|
+
const semicolon = imports[0]?.semicolon ?? false;
|
|
256
|
+
s.prepend(`import { ${required} } from ${quote}${targetModule}${quote}${semicolon ? ";" : ""}${lineEnding}`);
|
|
257
|
+
modified = true;
|
|
258
|
+
}
|
|
259
|
+
return modified;
|
|
248
260
|
}
|
|
249
|
-
function
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
if (
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
if (!fallbackSemicolon && hasSemicolon) result = result.replace(/;\s*$/, "");
|
|
261
|
-
if (fallbackSemicolon && !hasSemicolon && result.trim()) result += ";";
|
|
261
|
+
function normalizeNamedImports({ named, required, isOwner }) {
|
|
262
|
+
const banned = getOtherRouteConstructor(required);
|
|
263
|
+
const nextNamed = [];
|
|
264
|
+
const seen = /* @__PURE__ */ new Set();
|
|
265
|
+
for (const specifier of named) {
|
|
266
|
+
if (specifier.imported === banned) continue;
|
|
267
|
+
if (specifier.local === required && (specifier.imported !== required || !isOwner)) continue;
|
|
268
|
+
const key = `${specifier.importKind ?? "value"}:${specifier.imported}:${specifier.local}`;
|
|
269
|
+
if (seen.has(key)) continue;
|
|
270
|
+
seen.add(key);
|
|
271
|
+
nextNamed.push(specifier);
|
|
262
272
|
}
|
|
263
|
-
|
|
273
|
+
if (isOwner && !hasNamedImport(nextNamed, required)) nextNamed.push({
|
|
274
|
+
imported: required,
|
|
275
|
+
local: required
|
|
276
|
+
});
|
|
277
|
+
return nextNamed;
|
|
264
278
|
}
|
|
265
|
-
function
|
|
266
|
-
|
|
267
|
-
if (!originalQuote) originalQuote = fallbackQuote;
|
|
268
|
-
return fixQuotesToPreferred(line, originalQuote);
|
|
279
|
+
function getExpectedRouteConstructor(lazy) {
|
|
280
|
+
return lazy ? "createLazyFileRoute" : "createFileRoute";
|
|
269
281
|
}
|
|
270
|
-
function
|
|
271
|
-
return
|
|
272
|
-
return `${quote}${content.replaceAll(quote, `\\${quote}`)}${quote}`;
|
|
273
|
-
});
|
|
282
|
+
function getOtherRouteConstructor(constructor) {
|
|
283
|
+
return constructor === "createFileRoute" ? "createLazyFileRoute" : "createFileRoute";
|
|
274
284
|
}
|
|
275
|
-
function
|
|
276
|
-
|
|
277
|
-
return match ? match[1] : null;
|
|
285
|
+
function hasNamedImport(named, required) {
|
|
286
|
+
return named.some((specifier) => specifier.imported === required && specifier.local === required && specifier.importKind !== "type");
|
|
278
287
|
}
|
|
279
|
-
function
|
|
280
|
-
|
|
281
|
-
const total = lines.length;
|
|
282
|
-
return lines.filter((l) => l.endsWith(";")).length > total / 2;
|
|
288
|
+
function sameNamedImports(left, right) {
|
|
289
|
+
return left.length === right.length && left.every((specifier, index) => specifier.imported === right[index].imported && specifier.local === right[index].local && specifier.importKind === right[index].importKind);
|
|
283
290
|
}
|
|
284
|
-
function
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return "\"
|
|
291
|
+
function isRouteConstructorName(value) {
|
|
292
|
+
return routeConstructors.includes(value);
|
|
293
|
+
}
|
|
294
|
+
function renderImportDeclaration(importDeclaration) {
|
|
295
|
+
const parts = [];
|
|
296
|
+
if (importDeclaration.defaultImport) parts.push(importDeclaration.defaultImport);
|
|
297
|
+
if (importDeclaration.namespace) parts.push(`* as ${importDeclaration.namespace}`);
|
|
298
|
+
if (importDeclaration.named.length > 0) parts.push(`{ ${importDeclaration.named.map((specifier) => `${specifier.importKind === "type" ? "type " : ""}${specifier.imported === specifier.local ? specifier.imported : `${specifier.imported} as ${specifier.local}`}`).join(", ")} }`);
|
|
299
|
+
if (parts.length === 0) return null;
|
|
300
|
+
return `import ${parts.join(", ")} from ${importDeclaration.quote}${importDeclaration.moduleName}${importDeclaration.quote}${importDeclaration.semicolon ? ";" : ""}`;
|
|
301
|
+
}
|
|
302
|
+
function getLineEnding(source) {
|
|
303
|
+
if (source.includes("\r\n")) return "\r\n";
|
|
304
|
+
if (source.includes("\n")) return "\n";
|
|
305
|
+
if (source.includes("\r")) return "\r";
|
|
306
|
+
return "\n";
|
|
307
|
+
}
|
|
308
|
+
function getRemovalEnd(source, end) {
|
|
309
|
+
let pos = end;
|
|
310
|
+
while (pos < source.length && (source[pos] === " " || source[pos] === " ")) pos++;
|
|
311
|
+
if (source[pos] === "\r" && source[pos + 1] === "\n") return pos + 2;
|
|
312
|
+
if (source[pos] === "\n" || source[pos] === "\r") return pos + 1;
|
|
313
|
+
return end;
|
|
297
314
|
}
|
|
298
315
|
//#endregion
|
|
299
316
|
exports.transform = transform;
|