@vobs/vite-plugin 1.2.1 → 1.3.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/dist/html-component.cjs +31 -8
- package/dist/html-component.cjs.map +1 -1
- package/dist/html-component.js +6 -5
- package/dist/html-component.js.map +1 -1
- package/dist/index.cjs +78 -1161
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +38 -1148
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.test.ts +48 -0
- package/src/index.ts +38 -4
package/dist/index.cjs
CHANGED
|
@@ -1,1153 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var
|
|
4
|
-
var path = require('path');
|
|
5
|
-
var ts = require('typescript');
|
|
6
|
-
var error = require('@vobs/runtime/error');
|
|
7
|
-
var parse5 = require('parse5');
|
|
8
|
-
|
|
9
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
-
|
|
11
|
-
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
12
|
-
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
|
13
|
-
|
|
1
|
+
var __VOBS_CJS_FILE_URL = require("url").pathToFileURL(__filename).href;
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
14
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
9
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
addRuntimeImport(name) {
|
|
52
|
-
resolveHelperName(state, name);
|
|
53
|
-
},
|
|
54
|
-
helperRef: /* @__PURE__ */ __name((name) => helperRef(state, name), "helperRef")
|
|
55
|
-
};
|
|
56
|
-
for (const plugin of plugins) plugin.analyze?.(sourceFile, context);
|
|
57
|
-
for (const plugin of plugins) {
|
|
58
|
-
sourceFile = plugin.transform?.program?.(sourceFile, context) ?? sourceFile;
|
|
59
|
-
}
|
|
60
|
-
for (const plugin of plugins) sourceFile = transformPluginNodes(sourceFile, plugin, context);
|
|
61
|
-
const statements = sourceFile.statements.map(
|
|
62
|
-
(statement) => ts__default.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement)
|
|
63
|
-
);
|
|
64
|
-
const templateDeclarations = createTemplateDeclarations(state);
|
|
65
|
-
const resultFile = ts__default.default.factory.updateSourceFile(sourceFile, [
|
|
66
|
-
...createRuntimeImports(state),
|
|
67
|
-
...templateDeclarations,
|
|
68
|
-
...statements
|
|
69
|
-
]);
|
|
70
|
-
const generated = ts__default.default.createPrinter().printFile(resultFile);
|
|
71
|
-
return {
|
|
72
|
-
code: generated,
|
|
73
|
-
map: buildSourceMap(state, filename, code, generated, resultFile),
|
|
74
|
-
diagnostics: [...diagnostics, ...state.diagnostics]
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
__name(compileWithSourceMap, "compileWithSourceMap");
|
|
78
|
-
function toCompilerDiagnostic(diagnostic, sourceFile, filename) {
|
|
79
|
-
const start = diagnostic.start ?? 0;
|
|
80
|
-
const length = diagnostic.length ?? 1;
|
|
81
|
-
const message = ts__default.default.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
82
|
-
const { line, column, codeFrame } = buildCodeFrame(sourceFile, start, length);
|
|
83
|
-
return {
|
|
84
|
-
code: `VOBS_C${String(diagnostic.code).padStart(3, "0")}`,
|
|
85
|
-
severity: diagnostic.category === ts__default.default.DiagnosticCategory.Warning ? "warning" : "error",
|
|
86
|
-
message,
|
|
87
|
-
location: { file: filename, line, column },
|
|
88
|
-
codeFrame
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
__name(toCompilerDiagnostic, "toCompilerDiagnostic");
|
|
92
|
-
function buildCodeFrame(sourceFile, start, length) {
|
|
93
|
-
const position = sourceFile.getLineAndCharacterOfPosition(start);
|
|
94
|
-
const lineText = sourceFile.text.split(/\r?\n/u)[position.line] ?? "";
|
|
95
|
-
const markerLength = Math.max(1, Math.min(length, Math.max(1, lineText.length - position.character)));
|
|
96
|
-
return {
|
|
97
|
-
line: position.line + 1,
|
|
98
|
-
column: position.character + 1,
|
|
99
|
-
codeFrame: `${position.line + 1} | ${lineText}
|
|
100
|
-
${" ".repeat(String(position.line + 1).length + 3 + position.character)}${"^".repeat(markerLength)}`
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
__name(buildCodeFrame, "buildCodeFrame");
|
|
104
|
-
function reportUnsupportedTag(state, tagName) {
|
|
105
|
-
const sourceFile = tagName.getSourceFile() ?? state.sourceFile;
|
|
106
|
-
if (!sourceFile) return;
|
|
107
|
-
const label = tagName.getText();
|
|
108
|
-
const kindNote = tagName.kind === ts__default.default.SyntaxKind.JsxNamespacedName ? "\uFF08JSX \u547D\u540D\u7A7A\u95F4\u6807\u7B7E\uFF09" : "";
|
|
109
|
-
const { line, column, codeFrame } = buildCodeFrame(sourceFile, tagName.getStart(sourceFile), tagName.getWidth(sourceFile));
|
|
110
|
-
state.diagnostics.push({
|
|
111
|
-
code: "VOBS_C101",
|
|
112
|
-
severity: "error",
|
|
113
|
-
message: `\u4E0D\u652F\u6301\u7684 JSX \u6807\u7B7E\u5F62\u6001\uFF1A<${label}>${kindNote}\u3002\u7EC4\u4EF6\u5FC5\u987B\u662F\u5927\u5199\u5F00\u5934\u7684\u6807\u8BC6\u7B26\uFF0CDOM \u5143\u7D20\u5FC5\u987B\u662F\u5C0F\u5199\u6807\u7B7E\u540D\u3002`,
|
|
114
|
-
location: { file: state.filename, line, column },
|
|
115
|
-
codeFrame,
|
|
116
|
-
fix: `\u628A <${label}> \u6539\u4E3A <Component /> \u5F62\u5F0F\u7684\u7EC4\u4EF6\u6216\u5C0F\u5199 DOM \u6807\u7B7E\uFF1BFragment \u8BF7\u4F7F\u7528 <Fragment> \u6216 <>...</>\u3002`
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
__name(reportUnsupportedTag, "reportUnsupportedTag");
|
|
120
|
-
function buildSourceMap(state, filename, source, generated, resultFile) {
|
|
121
|
-
const reparsed = ts__default.default.createSourceFile(filename, generated, ts__default.default.ScriptTarget.Latest, true, ts__default.default.ScriptKind.TSX);
|
|
122
|
-
const segments = [];
|
|
123
|
-
walkPairedTrees(state, resultFile, reparsed, reparsed, segments);
|
|
124
|
-
segments.sort((a, b) => a.genLine - b.genLine || a.genCol - b.genCol);
|
|
125
|
-
return {
|
|
126
|
-
version: 3,
|
|
127
|
-
file: filename,
|
|
128
|
-
sources: [filename],
|
|
129
|
-
sourcesContent: [source],
|
|
130
|
-
names: [],
|
|
131
|
-
mappings: encodeMappings(segments, generated.split("\n").length)
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
__name(buildSourceMap, "buildSourceMap");
|
|
135
|
-
function statementLists(node) {
|
|
136
|
-
if (ts__default.default.isSourceFile(node) || ts__default.default.isBlock(node) || ts__default.default.isModuleBlock(node)) return node.statements;
|
|
137
|
-
if (ts__default.default.isCaseClause(node) || ts__default.default.isDefaultClause(node)) return node.statements;
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
__name(statementLists, "statementLists");
|
|
141
|
-
function walkPairedTrees(state, original, generated, reparsed, segments) {
|
|
142
|
-
const originalStatements = statementLists(original);
|
|
143
|
-
const generatedStatements = statementLists(generated);
|
|
144
|
-
if (originalStatements && generatedStatements) {
|
|
145
|
-
if (originalStatements.length !== generatedStatements.length) return;
|
|
146
|
-
for (let index = 0; index < originalStatements.length; index++) {
|
|
147
|
-
const originalStatement = originalStatements[index];
|
|
148
|
-
const generatedStatement = generatedStatements[index];
|
|
149
|
-
recordSegment(state, originalStatement, generatedStatement, reparsed, segments);
|
|
150
|
-
walkPairedTrees(state, originalStatement, generatedStatement, reparsed, segments);
|
|
151
|
-
}
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
const originalChildren = [];
|
|
155
|
-
const generatedChildren = [];
|
|
156
|
-
ts__default.default.forEachChild(original, (node) => {
|
|
157
|
-
originalChildren.push(node);
|
|
158
|
-
});
|
|
159
|
-
ts__default.default.forEachChild(generated, (node) => {
|
|
160
|
-
generatedChildren.push(node);
|
|
161
|
-
});
|
|
162
|
-
if (originalChildren.length !== generatedChildren.length) return;
|
|
163
|
-
for (let index = 0; index < originalChildren.length; index++) {
|
|
164
|
-
walkPairedTrees(state, originalChildren[index], generatedChildren[index], reparsed, segments);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
__name(walkPairedTrees, "walkPairedTrees");
|
|
168
|
-
function recordSegment(state, originalStatement, generatedStatement, reparsed, segments) {
|
|
169
|
-
const source = state.statementSources.get(originalStatement) ?? positionOfOriginalStatement(state, originalStatement);
|
|
170
|
-
if (!source) return;
|
|
171
|
-
const position = reparsed.getLineAndCharacterOfPosition(generatedStatement.getStart(reparsed));
|
|
172
|
-
segments.push({
|
|
173
|
-
genLine: position.line,
|
|
174
|
-
genCol: position.character,
|
|
175
|
-
srcLine: source.line,
|
|
176
|
-
srcCol: source.column
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
__name(recordSegment, "recordSegment");
|
|
180
|
-
function positionOfOriginalStatement(state, statement) {
|
|
181
|
-
if (statement.pos < 0 || !state.sourceFile) return null;
|
|
182
|
-
const { line, character } = state.sourceFile.getLineAndCharacterOfPosition(
|
|
183
|
-
statement.getStart(state.sourceFile)
|
|
184
|
-
);
|
|
185
|
-
return { line, column: character };
|
|
186
|
-
}
|
|
187
|
-
__name(positionOfOriginalStatement, "positionOfOriginalStatement");
|
|
188
|
-
function encodeMappings(segments, lineCount) {
|
|
189
|
-
const lines = Array.from({ length: lineCount }, () => []);
|
|
190
|
-
let prevGenLine = -1;
|
|
191
|
-
let prevGenCol = 0;
|
|
192
|
-
let prevSrcLine = 0;
|
|
193
|
-
let prevSrcCol = 0;
|
|
194
|
-
for (const segment of segments) {
|
|
195
|
-
if (segment.genLine !== prevGenLine) {
|
|
196
|
-
prevGenCol = 0;
|
|
197
|
-
prevGenLine = segment.genLine;
|
|
198
|
-
}
|
|
199
|
-
const values = [
|
|
200
|
-
segment.genCol - prevGenCol,
|
|
201
|
-
0,
|
|
202
|
-
segment.srcLine - prevSrcLine,
|
|
203
|
-
segment.srcCol - prevSrcCol
|
|
204
|
-
];
|
|
205
|
-
lines[segment.genLine].push(values.map(encodeVlq).join(""));
|
|
206
|
-
prevGenCol = segment.genCol;
|
|
207
|
-
prevSrcLine = segment.srcLine;
|
|
208
|
-
prevSrcCol = segment.srcCol;
|
|
209
|
-
}
|
|
210
|
-
return lines.map((line) => line.join(",")).join(";");
|
|
211
|
-
}
|
|
212
|
-
__name(encodeMappings, "encodeMappings");
|
|
213
|
-
var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
214
|
-
function encodeVlq(value) {
|
|
215
|
-
let encoded = value < 0 ? -value << 1 | 1 : value << 1;
|
|
216
|
-
let result = "";
|
|
217
|
-
do {
|
|
218
|
-
let digit = encoded & 31;
|
|
219
|
-
encoded >>>= 5;
|
|
220
|
-
if (encoded > 0) digit |= 32;
|
|
221
|
-
result += base64Chars[digit];
|
|
222
|
-
} while (encoded > 0);
|
|
223
|
-
return result;
|
|
224
|
-
}
|
|
225
|
-
__name(encodeVlq, "encodeVlq");
|
|
226
|
-
function validatePlugins(plugins) {
|
|
227
|
-
const names = /* @__PURE__ */ new Set();
|
|
228
|
-
for (const plugin of plugins) {
|
|
229
|
-
if (!plugin.name) throw new error.VobsError({ code: "VOBS_C007", layer: "compiler", message: "\u7F16\u8BD1\u5668\u63D2\u4EF6\u5FC5\u987B\u63D0\u4F9B name", fix: "\u4E3A\u63D2\u4EF6\u6DFB\u52A0\u7A33\u5B9A\u4E14\u552F\u4E00\u7684 name\u3002" });
|
|
230
|
-
if (names.has(plugin.name)) throw new error.VobsError({ code: "VOBS_C007", layer: "compiler", message: `\u68C0\u6D4B\u5230\u91CD\u590D\u63D2\u4EF6: ${plugin.name}`, fix: "\u4E3A\u6BCF\u4E2A\u7F16\u8BD1\u5668\u63D2\u4EF6\u4F7F\u7528\u552F\u4E00\u7684 name\u3002" });
|
|
231
|
-
names.add(plugin.name);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
__name(validatePlugins, "validatePlugins");
|
|
235
|
-
function transformPluginNodes(sourceFile, plugin, context) {
|
|
236
|
-
const transformNode = plugin.transform?.node ?? plugin.transformNode;
|
|
237
|
-
if (!transformNode) return sourceFile;
|
|
238
|
-
const transformer = /* @__PURE__ */ __name((transformContext) => (root) => {
|
|
239
|
-
const visit = /* @__PURE__ */ __name((node) => {
|
|
240
|
-
const replacement = transformNode(node, context);
|
|
241
|
-
if (replacement === null) return void 0;
|
|
242
|
-
return ts__default.default.visitEachChild(replacement ?? node, visit, transformContext);
|
|
243
|
-
}, "visit");
|
|
244
|
-
return ts__default.default.visitNode(root, visit);
|
|
245
|
-
}, "transformer");
|
|
246
|
-
const result = ts__default.default.transform(sourceFile, [transformer]);
|
|
247
|
-
try {
|
|
248
|
-
return result.transformed[0];
|
|
249
|
-
} finally {
|
|
250
|
-
result.dispose();
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
__name(transformPluginNodes, "transformPluginNodes");
|
|
254
|
-
function collectDeclaredNames(sourceFile) {
|
|
255
|
-
const names = /* @__PURE__ */ new Set();
|
|
256
|
-
const visit = /* @__PURE__ */ __name((node) => {
|
|
257
|
-
if (ts__default.default.isIdentifier(node) && isBindingName(node)) names.add(node.text);
|
|
258
|
-
ts__default.default.forEachChild(node, visit);
|
|
259
|
-
}, "visit");
|
|
260
|
-
visit(sourceFile);
|
|
261
|
-
return names;
|
|
262
|
-
}
|
|
263
|
-
__name(collectDeclaredNames, "collectDeclaredNames");
|
|
264
|
-
function collectStateAliases(sourceFile) {
|
|
265
|
-
const aliases = /* @__PURE__ */ new Set();
|
|
266
|
-
for (const statement of sourceFile.statements) {
|
|
267
|
-
if (!ts__default.default.isImportDeclaration(statement) || !ts__default.default.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
268
|
-
const module = statement.moduleSpecifier.text;
|
|
269
|
-
if (module !== "@vobs/reactivity" && module !== "@vobs/vobs") continue;
|
|
270
|
-
const clause = statement.importClause;
|
|
271
|
-
if (!clause?.namedBindings || !ts__default.default.isNamedImports(clause.namedBindings)) continue;
|
|
272
|
-
for (const element of clause.namedBindings.elements) {
|
|
273
|
-
if (element.propertyName ? element.propertyName.text === "state" : element.name.text === "state") {
|
|
274
|
-
aliases.add(element.name.text);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
return aliases;
|
|
279
|
-
}
|
|
280
|
-
__name(collectStateAliases, "collectStateAliases");
|
|
281
|
-
function collectLocallyDeclaredNames(sourceFile) {
|
|
282
|
-
const names = /* @__PURE__ */ new Set();
|
|
283
|
-
const visit = /* @__PURE__ */ __name((node) => {
|
|
284
|
-
if (ts__default.default.isImportDeclaration(node)) return;
|
|
285
|
-
if (ts__default.default.isIdentifier(node) && isBindingName(node)) names.add(node.text);
|
|
286
|
-
ts__default.default.forEachChild(node, visit);
|
|
287
|
-
}, "visit");
|
|
288
|
-
visit(sourceFile);
|
|
289
|
-
return names;
|
|
290
|
-
}
|
|
291
|
-
__name(collectLocallyDeclaredNames, "collectLocallyDeclaredNames");
|
|
292
|
-
function isBindingName(node) {
|
|
293
|
-
const parent = node.parent;
|
|
294
|
-
if (!parent) return false;
|
|
295
|
-
if (ts__default.default.isPropertyAccessExpression(parent) && parent.name === node) return false;
|
|
296
|
-
if (ts__default.default.isQualifiedName(parent) && parent.right === node) return false;
|
|
297
|
-
if (ts__default.default.isJsxAttribute(parent)) return false;
|
|
298
|
-
return parent.name === node;
|
|
299
|
-
}
|
|
300
|
-
__name(isBindingName, "isBindingName");
|
|
301
|
-
function resolveHelperName(state, name) {
|
|
302
|
-
const existing = state.helperAliases.get(name);
|
|
303
|
-
if (existing) return existing;
|
|
304
|
-
let alias = name;
|
|
305
|
-
if (state.takenNames.has(alias)) {
|
|
306
|
-
alias = `_vobs_${name}`;
|
|
307
|
-
let suffix = 1;
|
|
308
|
-
while (state.takenNames.has(alias)) alias = `_vobs_${name}_${suffix++}`;
|
|
309
|
-
}
|
|
310
|
-
state.helperAliases.set(name, alias);
|
|
311
|
-
return alias;
|
|
312
|
-
}
|
|
313
|
-
__name(resolveHelperName, "resolveHelperName");
|
|
314
|
-
function helperRef(state, name) {
|
|
315
|
-
return ts__default.default.factory.createIdentifier(resolveHelperName(state, name));
|
|
316
|
-
}
|
|
317
|
-
__name(helperRef, "helperRef");
|
|
318
|
-
function createRuntimeImports(state) {
|
|
319
|
-
const modules = /* @__PURE__ */ new Map();
|
|
320
|
-
for (const [name, alias] of state.helperAliases) {
|
|
321
|
-
const module = name === "insertResourceBoundary" ? "@vobs/resource" : "@vobs/vobs";
|
|
322
|
-
const imported = modules.get(module) ?? [];
|
|
323
|
-
imported.push(ts__default.default.factory.createImportSpecifier(
|
|
324
|
-
false,
|
|
325
|
-
alias === name ? void 0 : ts__default.default.factory.createIdentifier(name),
|
|
326
|
-
ts__default.default.factory.createIdentifier(alias)
|
|
327
|
-
));
|
|
328
|
-
modules.set(module, imported);
|
|
329
|
-
}
|
|
330
|
-
return [...modules.entries()].map(([module, imported]) => ts__default.default.factory.createImportDeclaration(
|
|
331
|
-
void 0,
|
|
332
|
-
ts__default.default.factory.createImportClause(
|
|
333
|
-
false,
|
|
334
|
-
void 0,
|
|
335
|
-
ts__default.default.factory.createNamedImports(imported)
|
|
336
|
-
),
|
|
337
|
-
ts__default.default.factory.createStringLiteral(module)
|
|
338
|
-
));
|
|
339
|
-
}
|
|
340
|
-
__name(createRuntimeImports, "createRuntimeImports");
|
|
341
|
-
function rebuildImport(state, node) {
|
|
342
|
-
if (!ts__default.default.isStringLiteral(node.moduleSpecifier)) return node;
|
|
343
|
-
return tagStatement(state, ts__default.default.factory.createImportDeclaration(
|
|
344
|
-
node.modifiers,
|
|
345
|
-
node.importClause,
|
|
346
|
-
ts__default.default.factory.createStringLiteral(node.moduleSpecifier.text),
|
|
347
|
-
node.attributes
|
|
348
|
-
), node);
|
|
349
|
-
}
|
|
350
|
-
__name(rebuildImport, "rebuildImport");
|
|
351
|
-
function transformStatement(state, node) {
|
|
352
|
-
if (ts__default.default.isFunctionDeclaration(node) && node.body) {
|
|
353
|
-
return tagStatement(state, ts__default.default.factory.updateFunctionDeclaration(
|
|
354
|
-
node,
|
|
355
|
-
node.modifiers,
|
|
356
|
-
node.asteriskToken,
|
|
357
|
-
node.name,
|
|
358
|
-
node.typeParameters,
|
|
359
|
-
node.parameters,
|
|
360
|
-
node.type,
|
|
361
|
-
transformBlock(state, node.body)
|
|
362
|
-
), node);
|
|
363
|
-
}
|
|
364
|
-
if (ts__default.default.isVariableStatement(node)) return transformVariableStatement(state, node);
|
|
365
|
-
if (ts__default.default.isExportAssignment(node) && containsJsx(node.expression)) {
|
|
366
|
-
return tagStatement(state, ts__default.default.factory.updateExportAssignment(node, node.modifiers, transformEmbeddedExpression(state, node.expression)), node);
|
|
367
|
-
}
|
|
368
|
-
if (ts__default.default.isExpressionStatement(node) && containsJsx(node.expression)) {
|
|
369
|
-
return tagStatement(state, ts__default.default.factory.updateExpressionStatement(node, transformEmbeddedExpression(state, node.expression)), node);
|
|
370
|
-
}
|
|
371
|
-
if (ts__default.default.isReturnStatement(node) && node.expression && containsJsx(node.expression)) {
|
|
372
|
-
return tagStatement(state, ts__default.default.factory.updateReturnStatement(node, transformEmbeddedExpression(state, node.expression)), node);
|
|
373
|
-
}
|
|
374
|
-
return node;
|
|
375
|
-
}
|
|
376
|
-
__name(transformStatement, "transformStatement");
|
|
377
|
-
function transformVariableStatement(state, node) {
|
|
378
|
-
let changed = false;
|
|
379
|
-
const declarations = node.declarationList.declarations.map((declaration) => {
|
|
380
|
-
const initializer = declaration.initializer;
|
|
381
|
-
if (!initializer) return declaration;
|
|
382
|
-
let nextInitializer = inferStateDebugName(state, declaration, initializer) ?? initializer;
|
|
383
|
-
if (containsJsx(nextInitializer)) {
|
|
384
|
-
nextInitializer = transformEmbeddedExpression(state, nextInitializer);
|
|
385
|
-
}
|
|
386
|
-
if (nextInitializer === initializer) return declaration;
|
|
387
|
-
changed = true;
|
|
388
|
-
return ts__default.default.factory.updateVariableDeclaration(
|
|
389
|
-
declaration,
|
|
390
|
-
declaration.name,
|
|
391
|
-
declaration.exclamationToken,
|
|
392
|
-
declaration.type,
|
|
393
|
-
nextInitializer
|
|
394
|
-
);
|
|
395
|
-
});
|
|
396
|
-
if (!changed) return node;
|
|
397
|
-
return tagStatement(state, ts__default.default.factory.updateVariableStatement(
|
|
398
|
-
node,
|
|
399
|
-
node.modifiers,
|
|
400
|
-
ts__default.default.factory.updateVariableDeclarationList(node.declarationList, declarations)
|
|
401
|
-
), node);
|
|
402
|
-
}
|
|
403
|
-
__name(transformVariableStatement, "transformVariableStatement");
|
|
404
|
-
function inferStateDebugName(state, declaration, initializer) {
|
|
405
|
-
if (state.stateAliases.size === 0) return void 0;
|
|
406
|
-
if (!ts__default.default.isIdentifier(declaration.name)) return void 0;
|
|
407
|
-
let call = initializer;
|
|
408
|
-
while (ts__default.default.isParenthesizedExpression(call) || ts__default.default.isAsExpression(call) || ts__default.default.isTypeAssertionExpression(call) || ts__default.default.isSatisfiesExpression(call)) {
|
|
409
|
-
call = call.expression;
|
|
410
|
-
}
|
|
411
|
-
if (!ts__default.default.isCallExpression(call)) return void 0;
|
|
412
|
-
const callee = call.expression;
|
|
413
|
-
if (!ts__default.default.isIdentifier(callee) || !state.stateAliases.has(callee.text)) return void 0;
|
|
414
|
-
if (state.localBindings.has(callee.text)) return void 0;
|
|
415
|
-
if (call.arguments.length !== 1) return void 0;
|
|
416
|
-
return ts__default.default.factory.createCallExpression(callee, call.typeArguments, [
|
|
417
|
-
...call.arguments,
|
|
418
|
-
ts__default.default.factory.createStringLiteral(declaration.name.text)
|
|
419
|
-
]);
|
|
420
|
-
}
|
|
421
|
-
__name(inferStateDebugName, "inferStateDebugName");
|
|
422
|
-
function containsJsx(expression) {
|
|
423
|
-
let found = false;
|
|
424
|
-
const visit = /* @__PURE__ */ __name((node) => {
|
|
425
|
-
if (isJsxExpression(node)) {
|
|
426
|
-
found = true;
|
|
427
|
-
return;
|
|
428
|
-
}
|
|
429
|
-
ts__default.default.forEachChild(node, visit);
|
|
430
|
-
}, "visit");
|
|
431
|
-
visit(expression);
|
|
432
|
-
return found;
|
|
433
|
-
}
|
|
434
|
-
__name(containsJsx, "containsJsx");
|
|
435
|
-
function transformBlock(state, block) {
|
|
436
|
-
const statements = block.statements.map((statement) => {
|
|
437
|
-
if (!ts__default.default.isReturnStatement(statement) || !statement.expression) return transformStatement(state, statement);
|
|
438
|
-
const expression = ts__default.default.isParenthesizedExpression(statement.expression) ? statement.expression.expression : statement.expression;
|
|
439
|
-
return isJsxExpression(expression) ? tagStatement(state, ts__default.default.factory.updateReturnStatement(statement, transformJsxExpression(state, expression)), statement) : statement;
|
|
440
|
-
});
|
|
441
|
-
return ts__default.default.factory.updateBlock(block, statements);
|
|
442
|
-
}
|
|
443
|
-
__name(transformBlock, "transformBlock");
|
|
444
|
-
function isJsxExpression(node) {
|
|
445
|
-
return ts__default.default.isJsxElement(node) || ts__default.default.isJsxSelfClosingElement(node) || ts__default.default.isJsxFragment(node);
|
|
446
|
-
}
|
|
447
|
-
__name(isJsxExpression, "isJsxExpression");
|
|
448
|
-
function transformJsxExpression(state, node) {
|
|
449
|
-
if (ts__default.default.isJsxFragment(node)) return transformFragment(state, node.children);
|
|
450
|
-
if (ts__default.default.isJsxElement(node)) {
|
|
451
|
-
return transformElement(state, node, node.openingElement.tagName, node.openingElement.attributes, node.children);
|
|
452
|
-
}
|
|
453
|
-
return transformElement(state, node, node.tagName, node.attributes, []);
|
|
454
|
-
}
|
|
455
|
-
__name(transformJsxExpression, "transformJsxExpression");
|
|
456
|
-
function transformElement(state, node, tagName, attributes, children) {
|
|
457
|
-
if (isFragmentTag(tagName)) return transformFragment(state, children);
|
|
458
|
-
if (!ts__default.default.isIdentifier(tagName)) {
|
|
459
|
-
reportUnsupportedTag(state, tagName);
|
|
460
|
-
}
|
|
461
|
-
if (ts__default.default.isIdentifier(tagName) && tagName.text === "ResourceBoundary") {
|
|
462
|
-
return transformResourceBoundary(state, node, attributes, children);
|
|
463
|
-
}
|
|
464
|
-
if (ts__default.default.isIdentifier(tagName) && tagName.text === "AsyncBoundary") {
|
|
465
|
-
return transformAsyncBoundary(state, node, attributes, children);
|
|
466
|
-
}
|
|
467
|
-
if (ts__default.default.isIdentifier(tagName) && tagName.text === "ErrorBoundary") {
|
|
468
|
-
return transformErrorBoundary(state, node, attributes, children);
|
|
469
|
-
}
|
|
470
|
-
if (ts__default.default.isIdentifier(tagName) && tagName.text === "Profiler") {
|
|
471
|
-
return transformProfiler(state, node, attributes, children);
|
|
472
|
-
}
|
|
473
|
-
if (ts__default.default.isIdentifier(tagName) && /^[A-Z]/.test(tagName.text)) {
|
|
474
|
-
const args = [
|
|
475
|
-
ts__default.default.factory.createCallExpression(helperRef(state, "resolveComponent"), void 0, [
|
|
476
|
-
tagName,
|
|
477
|
-
ts__default.default.factory.createStringLiteral(state.filename),
|
|
478
|
-
ts__default.default.factory.createStringLiteral(tagName.text)
|
|
479
|
-
]),
|
|
480
|
-
createComponentProps(state, attributes, children)
|
|
481
|
-
];
|
|
482
|
-
if (state.sourceLocation) args.push(createSourceLocation(tagName));
|
|
483
|
-
return ts__default.default.factory.createCallExpression(helperRef(state, "createComponent"), void 0, args);
|
|
484
|
-
}
|
|
485
|
-
if (isStaticElement(tagName, attributes, children)) {
|
|
486
|
-
return ts__default.default.factory.createCallExpression(
|
|
487
|
-
helperRef(state, "cloneTemplate"),
|
|
488
|
-
void 0,
|
|
489
|
-
[registerTemplate(state, serializeStaticHtml(node))]
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
const elementName = tagName.getText();
|
|
493
|
-
const elementId = nextIdentifier(state, "_el");
|
|
494
|
-
const statements = [
|
|
495
|
-
createConstStatement(
|
|
496
|
-
state,
|
|
497
|
-
elementId,
|
|
498
|
-
ts__default.default.factory.createCallExpression(
|
|
499
|
-
helperRef(state, "createElement"),
|
|
500
|
-
void 0,
|
|
501
|
-
[ts__default.default.factory.createStringLiteral(elementName)]
|
|
502
|
-
),
|
|
503
|
-
node
|
|
504
|
-
)
|
|
505
|
-
];
|
|
506
|
-
appendAttributes(state, statements, elementId, attributes);
|
|
507
|
-
appendChildren(state, statements, elementId, children);
|
|
508
|
-
statements.push(tagStatement(state, ts__default.default.factory.createReturnStatement(elementId), node));
|
|
509
|
-
return ts__default.default.factory.createCallExpression(
|
|
510
|
-
ts__default.default.factory.createArrowFunction(
|
|
511
|
-
void 0,
|
|
512
|
-
void 0,
|
|
513
|
-
[],
|
|
514
|
-
void 0,
|
|
515
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
516
|
-
ts__default.default.factory.createBlock(statements, true)
|
|
517
|
-
),
|
|
518
|
-
void 0,
|
|
519
|
-
[]
|
|
520
|
-
);
|
|
521
|
-
}
|
|
522
|
-
__name(transformElement, "transformElement");
|
|
523
|
-
function isFragmentTag(tagName) {
|
|
524
|
-
return tagName.getText() === "Fragment" || tagName.getText() === "Vobs.Fragment";
|
|
525
|
-
}
|
|
526
|
-
__name(isFragmentTag, "isFragmentTag");
|
|
527
|
-
function transformFragment(state, children) {
|
|
528
|
-
const parent = nextIdentifier(state, "_fragmentParent");
|
|
529
|
-
const anchor = nextIdentifier(state, "_fragmentAnchor");
|
|
530
|
-
const statements = [];
|
|
531
|
-
appendChildren(state, statements, parent, children, anchor);
|
|
532
|
-
return ts__default.default.factory.createCallExpression(
|
|
533
|
-
helperRef(state, "createFragment"),
|
|
534
|
-
void 0,
|
|
535
|
-
[ts__default.default.factory.createArrowFunction(
|
|
536
|
-
void 0,
|
|
537
|
-
void 0,
|
|
538
|
-
[
|
|
539
|
-
ts__default.default.factory.createParameterDeclaration(void 0, void 0, parent),
|
|
540
|
-
ts__default.default.factory.createParameterDeclaration(void 0, void 0, anchor)
|
|
541
|
-
],
|
|
542
|
-
void 0,
|
|
543
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
544
|
-
ts__default.default.factory.createBlock(statements, true)
|
|
545
|
-
)]
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
__name(transformFragment, "transformFragment");
|
|
549
|
-
function transformResourceBoundary(state, node, attributes, children) {
|
|
550
|
-
const resource = getAttributeExpression(attributes, "resource");
|
|
551
|
-
if (!resource) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "ResourceBoundary \u5FC5\u987B\u63D0\u4F9B resource \u5C5E\u6027", fix: "\u4E3A ResourceBoundary \u6DFB\u52A0 resource={resource}\u3002" });
|
|
552
|
-
const options = [
|
|
553
|
-
ts__default.default.factory.createPropertyAssignment("resource", transformEmbeddedExpression(state, resource)),
|
|
554
|
-
ts__default.default.factory.createPropertyAssignment("children", createBoundaryFactory(state, children))
|
|
555
|
-
];
|
|
556
|
-
appendBoundaryOptionalProperty(state, options, attributes, "loading");
|
|
557
|
-
appendBoundaryOptionalProperty(state, options, attributes, "empty");
|
|
558
|
-
appendBoundaryOptionalProperty(state, options, attributes, "fallback");
|
|
559
|
-
return createBoundaryFragment(state, node, "insertResourceBoundary", options);
|
|
560
|
-
}
|
|
561
|
-
__name(transformResourceBoundary, "transformResourceBoundary");
|
|
562
|
-
function transformErrorBoundary(state, node, attributes, children) {
|
|
563
|
-
const fallback = getAttributeExpression(attributes, "fallback");
|
|
564
|
-
if (!fallback) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "ErrorBoundary \u5FC5\u987B\u63D0\u4F9B fallback \u5C5E\u6027", fix: "\u4E3A ErrorBoundary \u6DFB\u52A0 fallback={(error, retry) => ...}\u3002" });
|
|
565
|
-
return createBoundaryFragment(state, node, "insertErrorBoundary", [
|
|
566
|
-
ts__default.default.factory.createPropertyAssignment("children", createBoundaryFactory(state, children)),
|
|
567
|
-
ts__default.default.factory.createPropertyAssignment("fallback", transformEmbeddedExpression(state, fallback))
|
|
568
|
-
]);
|
|
569
|
-
}
|
|
570
|
-
__name(transformErrorBoundary, "transformErrorBoundary");
|
|
571
|
-
function transformAsyncBoundary(state, node, attributes, children) {
|
|
572
|
-
const promise = getAttributeExpression(attributes, "promise");
|
|
573
|
-
if (!promise) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "AsyncBoundary \u5FC5\u987B\u63D0\u4F9B promise \u5C5E\u6027", fix: "\u4E3A AsyncBoundary \u6DFB\u52A0 promise={promise}\u3002" });
|
|
574
|
-
const options = [
|
|
575
|
-
ts__default.default.factory.createPropertyAssignment("promise", transformEmbeddedExpression(state, promise)),
|
|
576
|
-
ts__default.default.factory.createPropertyAssignment("children", createAsyncFactory(state, children))
|
|
577
|
-
];
|
|
578
|
-
appendBoundaryOptionalProperty(state, options, attributes, "loading");
|
|
579
|
-
appendBoundaryOptionalProperty(state, options, attributes, "fallback");
|
|
580
|
-
const resetKey = getAttributeExpression(attributes, "resetKey");
|
|
581
|
-
if (resetKey) options.push(ts__default.default.factory.createPropertyAssignment("resetKey", createGetter(resetKey)));
|
|
582
|
-
return createBoundaryFragment(state, node, "insertAsyncBoundary", options);
|
|
583
|
-
}
|
|
584
|
-
__name(transformAsyncBoundary, "transformAsyncBoundary");
|
|
585
|
-
function transformProfiler(state, node, attributes, children) {
|
|
586
|
-
const idAttribute = attributes.properties.find((attribute) => ts__default.default.isJsxAttribute(attribute) && attribute.name.getText() === "id");
|
|
587
|
-
const id = idAttribute && ts__default.default.isJsxAttribute(idAttribute) && idAttribute.initializer && ts__default.default.isStringLiteral(idAttribute.initializer) ? ts__default.default.factory.createStringLiteral(idAttribute.initializer.text) : idAttribute && ts__default.default.isJsxAttribute(idAttribute) && idAttribute.initializer && ts__default.default.isJsxExpression(idAttribute.initializer) ? idAttribute.initializer.expression : null;
|
|
588
|
-
if (!id) throw new error.VobsError({ code: "VOBS_C002", layer: "compiler", message: "Profiler \u5FC5\u987B\u63D0\u4F9B id \u5C5E\u6027", fix: '\u4E3A Profiler \u6DFB\u52A0 id="ComponentName"\u3002' });
|
|
589
|
-
const options = [
|
|
590
|
-
ts__default.default.factory.createPropertyAssignment("id", transformEmbeddedExpression(state, id)),
|
|
591
|
-
ts__default.default.factory.createPropertyAssignment("children", createBoundaryFactory(state, children))
|
|
592
|
-
];
|
|
593
|
-
appendBoundaryOptionalProperty(state, options, attributes, "onRender");
|
|
594
|
-
return createBoundaryFragment(state, node, "insertProfiler", options);
|
|
595
|
-
}
|
|
596
|
-
__name(transformProfiler, "transformProfiler");
|
|
597
|
-
function createBoundaryFragment(state, node, helper, options) {
|
|
598
|
-
const parent = nextIdentifier(state, "_boundaryParent");
|
|
599
|
-
const anchor = nextIdentifier(state, "_boundaryAnchor");
|
|
600
|
-
return ts__default.default.factory.createCallExpression(
|
|
601
|
-
helperRef(state, "createFragment"),
|
|
602
|
-
void 0,
|
|
603
|
-
[ts__default.default.factory.createArrowFunction(
|
|
604
|
-
void 0,
|
|
605
|
-
void 0,
|
|
606
|
-
[
|
|
607
|
-
ts__default.default.factory.createParameterDeclaration(void 0, void 0, parent),
|
|
608
|
-
ts__default.default.factory.createParameterDeclaration(void 0, void 0, anchor)
|
|
609
|
-
],
|
|
610
|
-
void 0,
|
|
611
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
612
|
-
ts__default.default.factory.createBlock([callStatement(state, helper, [
|
|
613
|
-
parent,
|
|
614
|
-
anchor,
|
|
615
|
-
ts__default.default.factory.createObjectLiteralExpression(options, true)
|
|
616
|
-
], node)], true)
|
|
617
|
-
)]
|
|
618
|
-
);
|
|
619
|
-
}
|
|
620
|
-
__name(createBoundaryFragment, "createBoundaryFragment");
|
|
621
|
-
function createBoundaryFactory(state, children) {
|
|
622
|
-
const content = transformFragment(state, children);
|
|
623
|
-
return ts__default.default.factory.createArrowFunction(
|
|
624
|
-
void 0,
|
|
625
|
-
void 0,
|
|
626
|
-
[],
|
|
627
|
-
void 0,
|
|
628
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
629
|
-
content
|
|
630
|
-
);
|
|
631
|
-
}
|
|
632
|
-
__name(createBoundaryFactory, "createBoundaryFactory");
|
|
633
|
-
function createAsyncFactory(state, children) {
|
|
634
|
-
const value = ts__default.default.factory.createIdentifier("value");
|
|
635
|
-
const expressionChild = children.length === 1 && children[0].kind === ts__default.default.SyntaxKind.JsxExpression ? children[0].expression : void 0;
|
|
636
|
-
if (expressionChild && ts__default.default.isArrowFunction(expressionChild)) {
|
|
637
|
-
const transformed = transformEmbeddedExpression(state, expressionChild);
|
|
638
|
-
return transformed;
|
|
639
|
-
}
|
|
640
|
-
const content = transformFragment(state, children);
|
|
641
|
-
return ts__default.default.factory.createArrowFunction(void 0, void 0, [
|
|
642
|
-
ts__default.default.factory.createParameterDeclaration(void 0, void 0, value)
|
|
643
|
-
], void 0, ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken), content);
|
|
644
|
-
}
|
|
645
|
-
__name(createAsyncFactory, "createAsyncFactory");
|
|
646
|
-
function appendBoundaryOptionalProperty(state, properties, attributes, name) {
|
|
647
|
-
const expression = getAttributeExpression(attributes, name);
|
|
648
|
-
if (expression) {
|
|
649
|
-
const transformed = transformEmbeddedExpression(state, expression);
|
|
650
|
-
const value = isJsxExpression(unwrapExpression(expression)) ? createGetter(transformed) : transformed;
|
|
651
|
-
properties.push(ts__default.default.factory.createPropertyAssignment(name, value));
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
__name(appendBoundaryOptionalProperty, "appendBoundaryOptionalProperty");
|
|
655
|
-
function getAttributeExpression(attributes, name) {
|
|
656
|
-
for (const attribute of attributes.properties) {
|
|
657
|
-
if (!ts__default.default.isJsxAttribute(attribute) || attribute.name.getText() !== name) continue;
|
|
658
|
-
if (attribute.initializer && ts__default.default.isJsxExpression(attribute.initializer)) {
|
|
659
|
-
return attribute.initializer.expression ?? null;
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
return null;
|
|
663
|
-
}
|
|
664
|
-
__name(getAttributeExpression, "getAttributeExpression");
|
|
665
|
-
function transformEmbeddedExpression(state, expression) {
|
|
666
|
-
const result = ts__default.default.transform(expression, [(context) => (root) => {
|
|
667
|
-
const visit = /* @__PURE__ */ __name((node) => {
|
|
668
|
-
if (ts__default.default.isJsxElement(node) || ts__default.default.isJsxSelfClosingElement(node) || ts__default.default.isJsxFragment(node)) {
|
|
669
|
-
return transformJsxExpression(state, node);
|
|
670
|
-
}
|
|
671
|
-
return ts__default.default.visitEachChild(node, visit, context);
|
|
672
|
-
}, "visit");
|
|
673
|
-
return ts__default.default.visitNode(root, visit);
|
|
674
|
-
}]);
|
|
675
|
-
try {
|
|
676
|
-
return result.transformed[0];
|
|
677
|
-
} finally {
|
|
678
|
-
result.dispose();
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
__name(transformEmbeddedExpression, "transformEmbeddedExpression");
|
|
682
|
-
function isStaticElement(tagName, attributes, children) {
|
|
683
|
-
if (!ts__default.default.isIdentifier(tagName) || !/^[a-z]/.test(tagName.text)) return false;
|
|
684
|
-
for (const attribute of attributes.properties) {
|
|
685
|
-
if (ts__default.default.isJsxSpreadAttribute(attribute)) return false;
|
|
686
|
-
if (!ts__default.default.isJsxAttribute(attribute)) return false;
|
|
687
|
-
const name = attribute.name.getText();
|
|
688
|
-
if (name === "key" || name === "ref" || name.startsWith("on")) return false;
|
|
689
|
-
if (isPropertyAttribute(name)) return false;
|
|
690
|
-
const initializer = attribute.initializer;
|
|
691
|
-
if (initializer && !ts__default.default.isStringLiteral(initializer)) return false;
|
|
692
|
-
}
|
|
693
|
-
for (const child of children) {
|
|
694
|
-
if (ts__default.default.isJsxText(child)) continue;
|
|
695
|
-
if (ts__default.default.isJsxElement(child) || ts__default.default.isJsxSelfClosingElement(child)) {
|
|
696
|
-
const nested = ts__default.default.isJsxElement(child) ? { tagName: child.openingElement.tagName, attributes: child.openingElement.attributes, children: child.children } : { tagName: child.tagName, attributes: child.attributes, children: [] };
|
|
697
|
-
if (!isStaticElement(nested.tagName, nested.attributes, nested.children)) return false;
|
|
698
|
-
continue;
|
|
699
|
-
}
|
|
700
|
-
return false;
|
|
701
|
-
}
|
|
702
|
-
return true;
|
|
703
|
-
}
|
|
704
|
-
__name(isStaticElement, "isStaticElement");
|
|
705
|
-
function serializeStaticHtml(node) {
|
|
706
|
-
const { tagName, attributes, children } = ts__default.default.isJsxElement(node) ? { tagName: node.openingElement.tagName, attributes: node.openingElement.attributes, children: node.children } : { tagName: node.tagName, attributes: node.attributes, children: [] };
|
|
707
|
-
return serializeStaticElement(tagName, attributes, children);
|
|
708
|
-
}
|
|
709
|
-
__name(serializeStaticHtml, "serializeStaticHtml");
|
|
710
|
-
function serializeStaticElement(tagName, attributes, children) {
|
|
711
|
-
const name = tagName.getText();
|
|
712
|
-
let html = `<${name}`;
|
|
713
|
-
for (const attribute of attributes.properties) {
|
|
714
|
-
if (!ts__default.default.isJsxAttribute(attribute)) continue;
|
|
715
|
-
const attributeName = attribute.name.getText() === "className" ? "class" : attribute.name.getText();
|
|
716
|
-
const initializer = attribute.initializer;
|
|
717
|
-
if (!initializer) {
|
|
718
|
-
html += ` ${attributeName}=""`;
|
|
719
|
-
continue;
|
|
720
|
-
}
|
|
721
|
-
if (ts__default.default.isStringLiteral(initializer)) {
|
|
722
|
-
html += ` ${attributeName}="${escapeHtmlAttribute(initializer.text)}"`;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
html += ">";
|
|
726
|
-
for (const child of children) {
|
|
727
|
-
if (ts__default.default.isJsxText(child)) {
|
|
728
|
-
const text = child.text.replace(/\s+/g, " ").trimStart();
|
|
729
|
-
if (text.trim()) html += escapeHtmlText(text);
|
|
730
|
-
continue;
|
|
731
|
-
}
|
|
732
|
-
if (ts__default.default.isJsxElement(child)) {
|
|
733
|
-
html += serializeStaticElement(
|
|
734
|
-
child.openingElement.tagName,
|
|
735
|
-
child.openingElement.attributes,
|
|
736
|
-
child.children
|
|
737
|
-
);
|
|
738
|
-
continue;
|
|
739
|
-
}
|
|
740
|
-
if (ts__default.default.isJsxSelfClosingElement(child)) {
|
|
741
|
-
html += serializeStaticElement(child.tagName, child.attributes, []);
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
html += `</${name}>`;
|
|
745
|
-
return html;
|
|
746
|
-
}
|
|
747
|
-
__name(serializeStaticElement, "serializeStaticElement");
|
|
748
|
-
function escapeHtmlAttribute(value) {
|
|
749
|
-
return value.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<");
|
|
750
|
-
}
|
|
751
|
-
__name(escapeHtmlAttribute, "escapeHtmlAttribute");
|
|
752
|
-
function escapeHtmlText(value) {
|
|
753
|
-
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
754
|
-
}
|
|
755
|
-
__name(escapeHtmlText, "escapeHtmlText");
|
|
756
|
-
function registerTemplate(state, html) {
|
|
757
|
-
const existing = state.templates.get(html);
|
|
758
|
-
if (existing) return existing;
|
|
759
|
-
const identifier = nextIdentifier(state, "_tpl");
|
|
760
|
-
state.templates.set(html, identifier);
|
|
761
|
-
return identifier;
|
|
762
|
-
}
|
|
763
|
-
__name(registerTemplate, "registerTemplate");
|
|
764
|
-
function createTemplateDeclarations(state) {
|
|
765
|
-
return [...state.templates.entries()].map(
|
|
766
|
-
([html, identifier]) => ts__default.default.factory.createVariableStatement(void 0, ts__default.default.factory.createVariableDeclarationList([
|
|
767
|
-
ts__default.default.factory.createVariableDeclaration(identifier, void 0, void 0, ts__default.default.factory.createCallExpression(
|
|
768
|
-
helperRef(state, "createTemplate"),
|
|
769
|
-
void 0,
|
|
770
|
-
[ts__default.default.factory.createStringLiteral(html)]
|
|
771
|
-
))
|
|
772
|
-
], ts__default.default.NodeFlags.Const))
|
|
773
|
-
);
|
|
774
|
-
}
|
|
775
|
-
__name(createTemplateDeclarations, "createTemplateDeclarations");
|
|
776
|
-
function appendAttributes(state, statements, element, attributes) {
|
|
777
|
-
const staticProps = [];
|
|
778
|
-
const hasSpread = attributes.properties.some((attribute) => ts__default.default.isJsxSpreadAttribute(attribute));
|
|
779
|
-
for (const attribute of attributes.properties) {
|
|
780
|
-
if (ts__default.default.isJsxSpreadAttribute(attribute)) {
|
|
781
|
-
statements.push(callStatement(state, "spreadProps", [element, transformEmbeddedExpression(state, attribute.expression)], attribute));
|
|
782
|
-
continue;
|
|
783
|
-
}
|
|
784
|
-
if (!ts__default.default.isJsxAttribute(attribute)) continue;
|
|
785
|
-
const name = attribute.name.getText();
|
|
786
|
-
if (name === "key") continue;
|
|
787
|
-
if (name === "ref") {
|
|
788
|
-
const initializer2 = attribute.initializer;
|
|
789
|
-
if (initializer2 && ts__default.default.isJsxExpression(initializer2) && initializer2.expression) {
|
|
790
|
-
statements.push(callStatement(state, "setRef", [element, transformEmbeddedExpression(state, initializer2.expression)], attribute));
|
|
791
|
-
}
|
|
792
|
-
continue;
|
|
793
|
-
}
|
|
794
|
-
const initializer = attribute.initializer;
|
|
795
|
-
if (name.startsWith("on") && initializer && ts__default.default.isJsxExpression(initializer) && initializer.expression) {
|
|
796
|
-
statements.push(callStatement(state, "addEventListener", [
|
|
797
|
-
element,
|
|
798
|
-
ts__default.default.factory.createStringLiteral(name.slice(2).toLowerCase()),
|
|
799
|
-
initializer.expression
|
|
800
|
-
], attribute));
|
|
801
|
-
continue;
|
|
802
|
-
}
|
|
803
|
-
if (!initializer) {
|
|
804
|
-
if (hasSpread) {
|
|
805
|
-
statements.push(callStatement(state, isPropertyAttribute(name) ? "setProperty" : "setAttribute", [element, ts__default.default.factory.createStringLiteral(isPropertyAttribute(name) ? name : name === "className" ? "class" : name), isPropertyAttribute(name) ? ts__default.default.factory.createTrue() : ts__default.default.factory.createStringLiteral("")], attribute));
|
|
806
|
-
continue;
|
|
807
|
-
}
|
|
808
|
-
if (isPropertyAttribute(name)) staticProps.push(createStaticProperty(name, ts__default.default.factory.createTrue()));
|
|
809
|
-
else staticProps.push(createStaticProperty(name === "className" ? "class" : name, ts__default.default.factory.createStringLiteral("")));
|
|
810
|
-
continue;
|
|
811
|
-
}
|
|
812
|
-
if (ts__default.default.isStringLiteral(initializer)) {
|
|
813
|
-
if (hasSpread) {
|
|
814
|
-
statements.push(callStatement(state, isPropertyAttribute(name) ? "setProperty" : "setAttribute", [element, ts__default.default.factory.createStringLiteral(isPropertyAttribute(name) ? name : name === "className" ? "class" : name), ts__default.default.factory.createStringLiteral(initializer.text)], attribute));
|
|
815
|
-
continue;
|
|
816
|
-
}
|
|
817
|
-
staticProps.push(createStaticProperty(
|
|
818
|
-
isPropertyAttribute(name) ? name : name === "className" ? "class" : name,
|
|
819
|
-
ts__default.default.factory.createStringLiteral(initializer.text)
|
|
820
|
-
));
|
|
821
|
-
continue;
|
|
822
|
-
}
|
|
823
|
-
const attributeName = name === "className" ? "class" : name;
|
|
824
|
-
const propertyAttribute = isPropertyAttribute(name);
|
|
825
|
-
if (ts__default.default.isJsxExpression(initializer) && initializer.expression) {
|
|
826
|
-
statements.push(callStatement(state, propertyAttribute ? "bindProperty" : "bindAttribute", [
|
|
827
|
-
element,
|
|
828
|
-
ts__default.default.factory.createStringLiteral(propertyAttribute ? name : attributeName),
|
|
829
|
-
createGetter(initializer.expression)
|
|
830
|
-
], attribute));
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
if (staticProps.length) statements.splice(1, 0, callStatement(state, "setStaticProps", [
|
|
834
|
-
element,
|
|
835
|
-
ts__default.default.factory.createObjectLiteralExpression(staticProps, true)
|
|
836
|
-
], attributes));
|
|
837
|
-
}
|
|
838
|
-
__name(appendAttributes, "appendAttributes");
|
|
839
|
-
function createStaticProperty(name, value) {
|
|
840
|
-
return ts__default.default.factory.createPropertyAssignment(ts__default.default.factory.createStringLiteral(name), value);
|
|
841
|
-
}
|
|
842
|
-
__name(createStaticProperty, "createStaticProperty");
|
|
843
|
-
function isPropertyAttribute(name) {
|
|
844
|
-
return name === "value" || name === "checked" || name === "selected" || name === "disabled" || name === "multiple" || name === "readOnly" || name === "required" || name === "autofocus" || name === "hidden" || name === "tabIndex";
|
|
845
|
-
}
|
|
846
|
-
__name(isPropertyAttribute, "isPropertyAttribute");
|
|
847
|
-
function appendChildren(state, statements, element, children, anchor = ts__default.default.factory.createNull()) {
|
|
848
|
-
for (const child of children) {
|
|
849
|
-
if (ts__default.default.isJsxText(child)) {
|
|
850
|
-
const text = child.text.replace(/\s+/g, " ").trimStart();
|
|
851
|
-
if (text.trim()) {
|
|
852
|
-
statements.push(callStatement(state, "insertBefore", [
|
|
853
|
-
element,
|
|
854
|
-
ts__default.default.factory.createCallExpression(helperRef(state, "createText"), void 0, [
|
|
855
|
-
ts__default.default.factory.createStringLiteral(text)
|
|
856
|
-
]),
|
|
857
|
-
anchor
|
|
858
|
-
], child));
|
|
859
|
-
}
|
|
860
|
-
continue;
|
|
861
|
-
}
|
|
862
|
-
if (ts__default.default.isJsxElement(child) || ts__default.default.isJsxSelfClosingElement(child) || ts__default.default.isJsxFragment(child)) {
|
|
863
|
-
statements.push(callStatement(state, "insertBefore", [
|
|
864
|
-
element,
|
|
865
|
-
transformJsxExpression(state, child),
|
|
866
|
-
anchor
|
|
867
|
-
], child));
|
|
868
|
-
continue;
|
|
869
|
-
}
|
|
870
|
-
if (child.kind === ts__default.default.SyntaxKind.JsxExpression) {
|
|
871
|
-
const expression = child.expression;
|
|
872
|
-
if (!expression) continue;
|
|
873
|
-
const list = transformListExpression(state, element, expression, anchor);
|
|
874
|
-
if (list) {
|
|
875
|
-
statements.push(callStatement(state, "insertList", list, child));
|
|
876
|
-
continue;
|
|
877
|
-
}
|
|
878
|
-
const dynamic = transformDynamicExpression(state, expression);
|
|
879
|
-
if (dynamic) {
|
|
880
|
-
statements.push(callStatement(state, "insertDynamic", [element, anchor, dynamic], child));
|
|
881
|
-
continue;
|
|
882
|
-
}
|
|
883
|
-
if (!containsJsx(expression) && !ts__default.default.isIdentifier(expression)) {
|
|
884
|
-
const textId = nextIdentifier(state, "_text");
|
|
885
|
-
statements.push(createConstStatement(state, textId, ts__default.default.factory.createCallExpression(helperRef(state, "createText"), void 0, [ts__default.default.factory.createStringLiteral("")]), child));
|
|
886
|
-
statements.push(callStatement(state, "insertBefore", [element, textId, anchor], child));
|
|
887
|
-
statements.push(callStatement(state, "bindText", [textId, createGetter(expression)], child));
|
|
888
|
-
continue;
|
|
889
|
-
}
|
|
890
|
-
const value = transformEmbeddedExpression(state, expression);
|
|
891
|
-
statements.push(callStatement(state, "insertDynamicValue", [element, anchor, createGetter(value)], child));
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
__name(appendChildren, "appendChildren");
|
|
896
|
-
function createComponentProps(state, attributes, children) {
|
|
897
|
-
const properties = [];
|
|
898
|
-
for (const attribute of attributes.properties) {
|
|
899
|
-
if (ts__default.default.isJsxSpreadAttribute(attribute)) {
|
|
900
|
-
properties.push(ts__default.default.factory.createSpreadAssignment(attribute.expression));
|
|
901
|
-
continue;
|
|
902
|
-
}
|
|
903
|
-
const name = propertyName(attribute.name.getText());
|
|
904
|
-
if (attribute.name.getText() === "key") continue;
|
|
905
|
-
const initializer = attribute.initializer;
|
|
906
|
-
if (!initializer) {
|
|
907
|
-
properties.push(ts__default.default.factory.createPropertyAssignment(name, ts__default.default.factory.createTrue()));
|
|
908
|
-
} else if (ts__default.default.isStringLiteral(initializer)) {
|
|
909
|
-
properties.push(ts__default.default.factory.createPropertyAssignment(name, ts__default.default.factory.createStringLiteral(initializer.text)));
|
|
910
|
-
} else if (ts__default.default.isJsxExpression(initializer) && initializer.expression) {
|
|
911
|
-
properties.push(createGetterProperty(name, transformEmbeddedExpression(state, initializer.expression)));
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
const childExpressions = children.flatMap((child) => childToComponentExpression(state, child));
|
|
915
|
-
if (childExpressions.length === 1) {
|
|
916
|
-
properties.push(createGetterProperty("children", childExpressions[0]));
|
|
917
|
-
} else if (childExpressions.length > 1) {
|
|
918
|
-
properties.push(createGetterProperty("children", ts__default.default.factory.createArrayLiteralExpression(childExpressions)));
|
|
919
|
-
}
|
|
920
|
-
return ts__default.default.factory.createObjectLiteralExpression(properties, true);
|
|
921
|
-
}
|
|
922
|
-
__name(createComponentProps, "createComponentProps");
|
|
923
|
-
function createSourceLocation(node) {
|
|
924
|
-
const sourceFile = node.getSourceFile();
|
|
925
|
-
const position = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
926
|
-
return ts__default.default.factory.createObjectLiteralExpression([
|
|
927
|
-
ts__default.default.factory.createPropertyAssignment("file", ts__default.default.factory.createStringLiteral(sourceFile.fileName)),
|
|
928
|
-
ts__default.default.factory.createPropertyAssignment("line", ts__default.default.factory.createNumericLiteral(position.line + 1)),
|
|
929
|
-
ts__default.default.factory.createPropertyAssignment("column", ts__default.default.factory.createNumericLiteral(position.character + 1))
|
|
930
|
-
], true);
|
|
931
|
-
}
|
|
932
|
-
__name(createSourceLocation, "createSourceLocation");
|
|
933
|
-
function transformDynamicExpression(state, expression) {
|
|
934
|
-
if (ts__default.default.isBinaryExpression(expression) && expression.operatorToken.kind === ts__default.default.SyntaxKind.AmpersandAmpersandToken) {
|
|
935
|
-
const right = unwrapExpression(expression.right);
|
|
936
|
-
if (!isJsxExpression(right)) return null;
|
|
937
|
-
return createGetter(ts__default.default.factory.createConditionalExpression(
|
|
938
|
-
expression.left,
|
|
939
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.QuestionToken),
|
|
940
|
-
transformJsxExpression(state, right),
|
|
941
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.ColonToken),
|
|
942
|
-
ts__default.default.factory.createNull()
|
|
943
|
-
));
|
|
944
|
-
}
|
|
945
|
-
if (ts__default.default.isConditionalExpression(expression)) {
|
|
946
|
-
const whenTrue = transformDynamicBranch(state, expression.whenTrue);
|
|
947
|
-
const whenFalse = transformDynamicBranch(state, expression.whenFalse);
|
|
948
|
-
if (!whenTrue && !whenFalse) return null;
|
|
949
|
-
return createGetter(ts__default.default.factory.createConditionalExpression(
|
|
950
|
-
expression.condition,
|
|
951
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.QuestionToken),
|
|
952
|
-
whenTrue ?? ts__default.default.factory.createNull(),
|
|
953
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.ColonToken),
|
|
954
|
-
whenFalse ?? ts__default.default.factory.createNull()
|
|
955
|
-
));
|
|
956
|
-
}
|
|
957
|
-
return null;
|
|
958
|
-
}
|
|
959
|
-
__name(transformDynamicExpression, "transformDynamicExpression");
|
|
960
|
-
function transformDynamicBranch(state, expression) {
|
|
961
|
-
const branch = unwrapExpression(expression);
|
|
962
|
-
if (isJsxExpression(branch)) return transformJsxExpression(state, branch);
|
|
963
|
-
if (branch.kind === ts__default.default.SyntaxKind.NullKeyword || branch.kind === ts__default.default.SyntaxKind.FalseKeyword) return branch;
|
|
964
|
-
return null;
|
|
965
|
-
}
|
|
966
|
-
__name(transformDynamicBranch, "transformDynamicBranch");
|
|
967
|
-
function transformListExpression(state, parent, expression, anchor) {
|
|
968
|
-
if (!ts__default.default.isCallExpression(expression) || expression.arguments.length !== 1) return null;
|
|
969
|
-
if (!ts__default.default.isPropertyAccessExpression(expression.expression) || expression.expression.name.text !== "map") return null;
|
|
970
|
-
const callback = expression.arguments[0];
|
|
971
|
-
if (!ts__default.default.isArrowFunction(callback) && !ts__default.default.isFunctionExpression(callback)) return null;
|
|
972
|
-
const body = unwrapExpression(callback.body);
|
|
973
|
-
if (!isJsxExpression(body) || ts__default.default.isJsxFragment(body)) return null;
|
|
974
|
-
const key = findKeyExpression(body);
|
|
975
|
-
const renderItem = transformListCallback(callback, transformJsxExpression(state, body));
|
|
976
|
-
const args = [
|
|
977
|
-
parent,
|
|
978
|
-
anchor,
|
|
979
|
-
createGetter(expression.expression.expression),
|
|
980
|
-
renderItem
|
|
981
|
-
];
|
|
982
|
-
if (key) args.push(createKeyCallback(callback, key));
|
|
983
|
-
return args;
|
|
984
|
-
}
|
|
985
|
-
__name(transformListExpression, "transformListExpression");
|
|
986
|
-
function transformListCallback(callback, body) {
|
|
987
|
-
if (ts__default.default.isArrowFunction(callback)) {
|
|
988
|
-
return ts__default.default.factory.updateArrowFunction(
|
|
989
|
-
callback,
|
|
990
|
-
callback.modifiers,
|
|
991
|
-
callback.typeParameters,
|
|
992
|
-
callback.parameters,
|
|
993
|
-
callback.type,
|
|
994
|
-
callback.equalsGreaterThanToken,
|
|
995
|
-
body
|
|
996
|
-
);
|
|
997
|
-
}
|
|
998
|
-
return ts__default.default.factory.updateFunctionExpression(
|
|
999
|
-
callback,
|
|
1000
|
-
callback.modifiers,
|
|
1001
|
-
callback.asteriskToken,
|
|
1002
|
-
callback.name,
|
|
1003
|
-
callback.typeParameters,
|
|
1004
|
-
callback.parameters,
|
|
1005
|
-
callback.type,
|
|
1006
|
-
ts__default.default.factory.createBlock([ts__default.default.factory.createReturnStatement(body)], true)
|
|
1007
|
-
);
|
|
1008
|
-
}
|
|
1009
|
-
__name(transformListCallback, "transformListCallback");
|
|
1010
|
-
function createKeyCallback(callback, key) {
|
|
1011
|
-
return ts__default.default.factory.createArrowFunction(
|
|
1012
|
-
void 0,
|
|
1013
|
-
void 0,
|
|
1014
|
-
callback.parameters,
|
|
1015
|
-
void 0,
|
|
1016
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
1017
|
-
key
|
|
1018
|
-
);
|
|
1019
|
-
}
|
|
1020
|
-
__name(createKeyCallback, "createKeyCallback");
|
|
1021
|
-
function findKeyExpression(node) {
|
|
1022
|
-
const attributes = ts__default.default.isJsxElement(node) ? node.openingElement.attributes : node.attributes;
|
|
1023
|
-
for (const attribute of attributes.properties) {
|
|
1024
|
-
if (!ts__default.default.isJsxAttribute(attribute) || attribute.name.getText() !== "key") continue;
|
|
1025
|
-
if (attribute.initializer && ts__default.default.isJsxExpression(attribute.initializer)) {
|
|
1026
|
-
return attribute.initializer.expression ?? null;
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
return null;
|
|
1030
|
-
}
|
|
1031
|
-
__name(findKeyExpression, "findKeyExpression");
|
|
1032
|
-
function unwrapExpression(node) {
|
|
1033
|
-
return ts__default.default.isParenthesizedExpression(node) ? node.expression : node;
|
|
1034
|
-
}
|
|
1035
|
-
__name(unwrapExpression, "unwrapExpression");
|
|
1036
|
-
function childToComponentExpression(state, child) {
|
|
1037
|
-
if (ts__default.default.isJsxText(child)) {
|
|
1038
|
-
const text = child.text.replace(/\s+/g, " ").trim();
|
|
1039
|
-
return text ? [ts__default.default.factory.createStringLiteral(text)] : [];
|
|
1040
|
-
}
|
|
1041
|
-
if (ts__default.default.isJsxElement(child) || ts__default.default.isJsxSelfClosingElement(child) || ts__default.default.isJsxFragment(child)) {
|
|
1042
|
-
return [transformJsxExpression(state, child)];
|
|
1043
|
-
}
|
|
1044
|
-
if (child.kind === ts__default.default.SyntaxKind.JsxExpression) {
|
|
1045
|
-
const expression = child.expression;
|
|
1046
|
-
return expression ? [transformEmbeddedExpression(state, expression)] : [];
|
|
1047
|
-
}
|
|
1048
|
-
return [];
|
|
1049
|
-
}
|
|
1050
|
-
__name(childToComponentExpression, "childToComponentExpression");
|
|
1051
|
-
function propertyName(name) {
|
|
1052
|
-
return /^[$A-Z_a-z][$\w]*$/u.test(name) ? ts__default.default.factory.createIdentifier(name) : ts__default.default.factory.createStringLiteral(name);
|
|
1053
|
-
}
|
|
1054
|
-
__name(propertyName, "propertyName");
|
|
1055
|
-
function createGetter(expression) {
|
|
1056
|
-
return ts__default.default.factory.createArrowFunction(
|
|
1057
|
-
void 0,
|
|
1058
|
-
void 0,
|
|
1059
|
-
[],
|
|
1060
|
-
void 0,
|
|
1061
|
-
ts__default.default.factory.createToken(ts__default.default.SyntaxKind.EqualsGreaterThanToken),
|
|
1062
|
-
expression
|
|
1063
|
-
);
|
|
1064
|
-
}
|
|
1065
|
-
__name(createGetter, "createGetter");
|
|
1066
|
-
function createGetterProperty(name, expression) {
|
|
1067
|
-
return ts__default.default.factory.createGetAccessorDeclaration(
|
|
1068
|
-
void 0,
|
|
1069
|
-
typeof name === "string" ? propertyName(name) : name,
|
|
1070
|
-
[],
|
|
1071
|
-
void 0,
|
|
1072
|
-
ts__default.default.factory.createBlock([ts__default.default.factory.createReturnStatement(expression)], true)
|
|
1073
|
-
);
|
|
1074
|
-
}
|
|
1075
|
-
__name(createGetterProperty, "createGetterProperty");
|
|
1076
|
-
function callStatement(state, name, args, source) {
|
|
1077
|
-
const statement = ts__default.default.factory.createExpressionStatement(
|
|
1078
|
-
ts__default.default.factory.createCallExpression(helperRef(state, name), void 0, args)
|
|
1079
|
-
);
|
|
1080
|
-
return source ? tagStatement(state, statement, source) : statement;
|
|
1081
|
-
}
|
|
1082
|
-
__name(callStatement, "callStatement");
|
|
1083
|
-
function createConstStatement(state, name, initializer, source) {
|
|
1084
|
-
const statement = ts__default.default.factory.createVariableStatement(
|
|
1085
|
-
void 0,
|
|
1086
|
-
ts__default.default.factory.createVariableDeclarationList([
|
|
1087
|
-
ts__default.default.factory.createVariableDeclaration(name, void 0, void 0, initializer)
|
|
1088
|
-
], ts__default.default.NodeFlags.Const)
|
|
1089
|
-
);
|
|
1090
|
-
return source ? tagStatement(state, statement, source) : statement;
|
|
1091
|
-
}
|
|
1092
|
-
__name(createConstStatement, "createConstStatement");
|
|
1093
|
-
function tagStatement(state, statement, source) {
|
|
1094
|
-
const position = positionOfNode(state, source);
|
|
1095
|
-
if (position) state.statementSources.set(statement, position);
|
|
1096
|
-
return statement;
|
|
1097
|
-
}
|
|
1098
|
-
__name(tagStatement, "tagStatement");
|
|
1099
|
-
function positionOfNode(state, node) {
|
|
1100
|
-
const sourceFile = node.getSourceFile() ?? state.sourceFile;
|
|
1101
|
-
if (!sourceFile || node.pos < 0) return null;
|
|
1102
|
-
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
1103
|
-
return { line, column: character };
|
|
1104
|
-
}
|
|
1105
|
-
__name(positionOfNode, "positionOfNode");
|
|
1106
|
-
function nextIdentifier(state, prefix) {
|
|
1107
|
-
let name;
|
|
1108
|
-
do {
|
|
1109
|
-
name = `${prefix}${state.generatedId++}`;
|
|
1110
|
-
} while (state.takenNames.has(name));
|
|
1111
|
-
return ts__default.default.factory.createIdentifier(name);
|
|
1112
|
-
}
|
|
1113
|
-
__name(nextIdentifier, "nextIdentifier");
|
|
1114
|
-
function createI18nExtractor(options = {}) {
|
|
1115
|
-
const names = new Set(options.functions ?? ["t"]);
|
|
1116
|
-
const keys = /* @__PURE__ */ new Set();
|
|
1117
|
-
const plugin = {
|
|
1118
|
-
name: "i18n-extractor",
|
|
1119
|
-
analyze(program, context) {
|
|
1120
|
-
const visit = /* @__PURE__ */ __name((node) => {
|
|
1121
|
-
if (ts__default.default.isCallExpression(node) && isTranslationCall(node.expression, names)) {
|
|
1122
|
-
const key = readStaticKey(node.arguments[0]);
|
|
1123
|
-
if (key) {
|
|
1124
|
-
keys.add(key);
|
|
1125
|
-
options.onKey?.(key, context.filename);
|
|
1126
|
-
}
|
|
1127
|
-
}
|
|
1128
|
-
ts__default.default.forEachChild(node, visit);
|
|
1129
|
-
}, "visit");
|
|
1130
|
-
visit(program);
|
|
1131
|
-
}
|
|
1132
|
-
};
|
|
1133
|
-
return {
|
|
1134
|
-
plugin,
|
|
1135
|
-
getKeys: /* @__PURE__ */ __name(() => [...keys].sort(), "getKeys"),
|
|
1136
|
-
reset: /* @__PURE__ */ __name(() => keys.clear(), "reset")
|
|
1137
|
-
};
|
|
1138
|
-
}
|
|
1139
|
-
__name(createI18nExtractor, "createI18nExtractor");
|
|
1140
|
-
function isTranslationCall(expression, names) {
|
|
1141
|
-
if (ts__default.default.isIdentifier(expression)) return names.has(expression.text);
|
|
1142
|
-
return ts__default.default.isPropertyAccessExpression(expression) && names.has(expression.name.text);
|
|
1143
|
-
}
|
|
1144
|
-
__name(isTranslationCall, "isTranslationCall");
|
|
1145
|
-
function readStaticKey(argument) {
|
|
1146
|
-
if (!argument) return void 0;
|
|
1147
|
-
if (ts__default.default.isStringLiteral(argument) || ts__default.default.isNoSubstitutionTemplateLiteral(argument)) return argument.text;
|
|
1148
|
-
return void 0;
|
|
1149
|
-
}
|
|
1150
|
-
__name(readStaticKey, "readStaticKey");
|
|
10
|
+
var __export = (target, all) => {
|
|
11
|
+
for (var name in all)
|
|
12
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
13
|
+
};
|
|
14
|
+
var __copyProps = (to, from, except, desc) => {
|
|
15
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
16
|
+
for (let key of __getOwnPropNames(from))
|
|
17
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
18
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
23
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
24
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
25
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
26
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
27
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
28
|
+
mod
|
|
29
|
+
));
|
|
30
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
+
|
|
32
|
+
// packages/vite-plugin/src/index.ts
|
|
33
|
+
var src_exports = {};
|
|
34
|
+
__export(src_exports, {
|
|
35
|
+
vobsPlugin: () => vobsPlugin
|
|
36
|
+
});
|
|
37
|
+
module.exports = __toCommonJS(src_exports);
|
|
38
|
+
var import_promises = require("fs/promises");
|
|
39
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
40
|
+
var import_compiler = require("@vobs/compiler");
|
|
41
|
+
var import_error = require("@vobs/runtime/error");
|
|
42
|
+
|
|
43
|
+
// packages/vite-plugin/src/html-component.ts
|
|
44
|
+
var import_parse5 = require("parse5");
|
|
1151
45
|
var blockedTags = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "base", "meta", "link", "style"]);
|
|
1152
46
|
var blockedAttributes = /^(?:on[a-z]+|srcdoc|style)$/iu;
|
|
1153
47
|
var urlAttributes = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "poster", "xlink:href"]);
|
|
@@ -1166,7 +60,7 @@ var safePropertyNames = /* @__PURE__ */ new Set([
|
|
|
1166
60
|
"tabindex"
|
|
1167
61
|
]);
|
|
1168
62
|
function compileHtmlComponent(source, options = {}) {
|
|
1169
|
-
const fragment =
|
|
63
|
+
const fragment = (0, import_parse5.parseFragment)(source);
|
|
1170
64
|
const body = compileChildren(fragment, options.filename ?? "component.html");
|
|
1171
65
|
const result = body.length === 1 ? body[0] : `createFragment((parent, anchor) => {${body.map((code) => `insertBefore(parent, ${code}, anchor);`).join("")}})`;
|
|
1172
66
|
return `import { addEventListener, bindAttribute, bindProperty, bindText, createElement, createFragment, createText, insertBefore, insertDynamic, setAttribute } from '@vobs/vobs';
|
|
@@ -1282,33 +176,45 @@ function vobsPlugin(options = {}) {
|
|
|
1282
176
|
const include = options.include ?? /\.tsx(?:$|\?)/;
|
|
1283
177
|
const htmlModules = /* @__PURE__ */ new Set();
|
|
1284
178
|
let productionBuild = false;
|
|
179
|
+
let hmrStateEnabled = (options.hmr ?? true) && (options.hmrState ?? true);
|
|
1285
180
|
return {
|
|
1286
181
|
name: "vobs",
|
|
1287
182
|
enforce: "pre",
|
|
1288
183
|
configResolved(config) {
|
|
1289
184
|
productionBuild = config.command === "build";
|
|
185
|
+
hmrStateEnabled = (options.hmr ?? true) && !productionBuild && (options.hmrState ?? true);
|
|
1290
186
|
},
|
|
1291
187
|
resolveId(source, importer) {
|
|
1292
188
|
if (!importer || !isHtmlComponent(source, options.html) || !isRelativeModule(source)) return null;
|
|
1293
189
|
const cleanImporter = importer.split(/[?#]/u, 1)[0];
|
|
1294
190
|
const cleanSource = source.split(/[?#]/u, 1)[0];
|
|
1295
|
-
const resolved =
|
|
191
|
+
const resolved = import_node_path.default.resolve(import_node_path.default.dirname(cleanImporter), cleanSource);
|
|
1296
192
|
htmlModules.add(resolved);
|
|
1297
193
|
return resolved;
|
|
1298
194
|
},
|
|
1299
195
|
async load(id) {
|
|
1300
196
|
if (!htmlModules.has(id)) return null;
|
|
1301
|
-
return compileHtmlComponent(await
|
|
197
|
+
return compileHtmlComponent(await (0, import_promises.readFile)(id, "utf8"), { filename: id });
|
|
1302
198
|
},
|
|
1303
199
|
transform(code, id) {
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
const
|
|
1307
|
-
|
|
200
|
+
const cleanId = id.split(/[?#]/u, 1)[0];
|
|
201
|
+
const isTsx = cleanId.endsWith(".tsx");
|
|
202
|
+
const isStateTs = isStateModulePath(cleanId);
|
|
203
|
+
if (!isTsx && !isStateTs) return null;
|
|
204
|
+
if (options.include) {
|
|
205
|
+
include.lastIndex = 0;
|
|
206
|
+
if (!include.test(id)) return null;
|
|
207
|
+
}
|
|
208
|
+
if (!isTsx && (!hmrStateEnabled || !isStatefulModule(code))) return null;
|
|
209
|
+
const extractor = options.extractI18n ? (0, import_compiler.createI18nExtractor)({ onKey: options.extractI18n }) : void 0;
|
|
210
|
+
const hmr = options.hmr ?? !productionBuild;
|
|
211
|
+
const result = (0, import_compiler.compileWithSourceMap)(code, {
|
|
1308
212
|
...options.compiler,
|
|
1309
213
|
// 生产构建默认剔除组件源码位置(错误定位走 source map);显式配置优先。
|
|
1310
214
|
sourceLocation: options.compiler?.sourceLocation ?? !productionBuild,
|
|
1311
215
|
filename: id,
|
|
216
|
+
// HMR 模块标识必须跨 ?t= 查询稳定(registry 复用语义依赖它),用干净路径。
|
|
217
|
+
hmrModuleId: hmr ? cleanId : options.compiler?.hmrModuleId,
|
|
1312
218
|
plugins: [
|
|
1313
219
|
...options.compiler?.plugins ?? [],
|
|
1314
220
|
...extractor ? [extractor.plugin] : []
|
|
@@ -1316,7 +222,7 @@ function vobsPlugin(options = {}) {
|
|
|
1316
222
|
});
|
|
1317
223
|
const diagnostic = result.diagnostics.find((item) => item.severity === "error");
|
|
1318
224
|
if (diagnostic) {
|
|
1319
|
-
throw new
|
|
225
|
+
throw new import_error.VobsError({
|
|
1320
226
|
code: diagnostic.code,
|
|
1321
227
|
layer: "compiler",
|
|
1322
228
|
message: diagnostic.message,
|
|
@@ -1325,8 +231,7 @@ function vobsPlugin(options = {}) {
|
|
|
1325
231
|
fix: diagnostic.fix
|
|
1326
232
|
});
|
|
1327
233
|
}
|
|
1328
|
-
const
|
|
1329
|
-
const hmrCode = hmr ? createHmrCode(id) : "";
|
|
234
|
+
const hmrCode = hmr ? createHmrCode(cleanId) : "";
|
|
1330
235
|
return {
|
|
1331
236
|
code: `${result.code}${hmrCode}`,
|
|
1332
237
|
map: result.map
|
|
@@ -1335,6 +240,17 @@ function vobsPlugin(options = {}) {
|
|
|
1335
240
|
};
|
|
1336
241
|
}
|
|
1337
242
|
__name(vobsPlugin, "vobsPlugin");
|
|
243
|
+
function isStatefulModule(code) {
|
|
244
|
+
return /\bimport\s+(?:type\s+)?\{[^}]*\bstate\b[^}]*\}\s*from\s*['"]@vobs\/(?:reactivity|vobs)['"]/u.test(code) && /(?<![\w$.])state\s*\(/u.test(code);
|
|
245
|
+
}
|
|
246
|
+
__name(isStatefulModule, "isStatefulModule");
|
|
247
|
+
function isStateModulePath(cleanId) {
|
|
248
|
+
if (!cleanId.endsWith(".ts")) return false;
|
|
249
|
+
if (cleanId.endsWith(".d.ts")) return false;
|
|
250
|
+
if (cleanId.includes("node_modules")) return false;
|
|
251
|
+
return true;
|
|
252
|
+
}
|
|
253
|
+
__name(isStateModulePath, "isStateModulePath");
|
|
1338
254
|
function isRelativeModule(source) {
|
|
1339
255
|
return source.startsWith("./") || source.startsWith("../");
|
|
1340
256
|
}
|
|
@@ -1360,7 +276,8 @@ if (import.meta.hot) {
|
|
|
1360
276
|
`;
|
|
1361
277
|
}
|
|
1362
278
|
__name(createHmrCode, "createHmrCode");
|
|
1363
|
-
|
|
1364
|
-
exports
|
|
1365
|
-
|
|
279
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
280
|
+
0 && (module.exports = {
|
|
281
|
+
vobsPlugin
|
|
282
|
+
});
|
|
1366
283
|
//# sourceMappingURL=index.cjs.map
|