@weapp-vite/volar 2.0.6 → 2.0.8
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/constants.d.ts +31 -0
- package/dist/index.cjs +331 -183
- package/dist/index.mjs +331 -183
- package/dist/jsonBlock.d.ts +24 -0
- package/dist/scriptSetup.d.ts +38 -0
- package/package.json +2 -2
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const BLOCK_TYPE = "json";
|
|
2
|
+
export declare const JS_LANG = "js";
|
|
3
|
+
export declare const JSONC_LANG = "jsonc";
|
|
4
|
+
export declare const JSON_LANG = "json";
|
|
5
|
+
export declare const JSON5_LANG = "json5";
|
|
6
|
+
export declare const PLUGIN_VERSION: 2.2;
|
|
7
|
+
export declare const TS_LANG = "ts";
|
|
8
|
+
export declare const TS_SCRIPT_KIND_JS = 1;
|
|
9
|
+
export declare const TS_SCRIPT_KIND_TS = 3;
|
|
10
|
+
export declare const TS_SCRIPT_TARGET_LATEST = 99;
|
|
11
|
+
export declare const BACKSLASH_RE: RegExp;
|
|
12
|
+
export declare const DEFINE_OPTIONS_NAME = "defineOptions";
|
|
13
|
+
export declare const IDENTIFIER_NAME_RE: RegExp;
|
|
14
|
+
export declare const NON_SPACE_RE: RegExp;
|
|
15
|
+
export declare const WXS_MODULE_RE: RegExp;
|
|
16
|
+
export declare const FULL_CAPABILITIES: {
|
|
17
|
+
readonly verification: true;
|
|
18
|
+
readonly completion: true;
|
|
19
|
+
readonly semantic: true;
|
|
20
|
+
readonly navigation: true;
|
|
21
|
+
readonly structure: true;
|
|
22
|
+
readonly format: true;
|
|
23
|
+
};
|
|
24
|
+
export declare const VOID_CAPABILITIES: {
|
|
25
|
+
readonly verification: false;
|
|
26
|
+
readonly completion: false;
|
|
27
|
+
readonly semantic: false;
|
|
28
|
+
readonly navigation: false;
|
|
29
|
+
readonly structure: false;
|
|
30
|
+
readonly format: false;
|
|
31
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -29,33 +29,13 @@ let _weapp_core_schematics = require("@weapp-core/schematics");
|
|
|
29
29
|
//#region package.json
|
|
30
30
|
var name = "@weapp-vite/volar";
|
|
31
31
|
//#endregion
|
|
32
|
-
//#region src/
|
|
33
|
-
/**
|
|
34
|
-
* 为小程序配置生成 JSON Schema
|
|
35
|
-
* 为支持 JSON Schema 的编辑器提供验证和自动补全
|
|
36
|
-
*
|
|
37
|
-
* 注意:JSON Schema 定义由 @weapp-core/schematics 统一维护
|
|
38
|
-
* 使用 Zod 定义并自动生成,确保单一数据源
|
|
39
|
-
*/
|
|
40
|
-
/**
|
|
41
|
-
* 根据文件类型获取对应的 JSON Schema
|
|
42
|
-
* Schema 定义来自 @weapp-core/schematics,使用 Zod 维护单一数据源
|
|
43
|
-
*/
|
|
44
|
-
function getSchemaForType(type) {
|
|
45
|
-
const definition = _weapp_core_schematics.JSON_SCHEMA_DEFINITIONS.find((d) => d.typeName === type);
|
|
46
|
-
if (!definition) return null;
|
|
47
|
-
return definition.schema;
|
|
48
|
-
}
|
|
49
|
-
//#endregion
|
|
50
|
-
//#region src/index.ts
|
|
32
|
+
//#region src/constants.ts
|
|
51
33
|
const BLOCK_TYPE = "json";
|
|
52
|
-
const JS_LANG = "js";
|
|
53
34
|
const JSONC_LANG = "jsonc";
|
|
54
35
|
const JSON_LANG = "json";
|
|
55
|
-
const JSON5_LANG = "json5";
|
|
56
36
|
const PLUGIN_VERSION = 2.2;
|
|
57
|
-
const TS_LANG = "ts";
|
|
58
37
|
const BACKSLASH_RE = /\\/g;
|
|
38
|
+
const IDENTIFIER_NAME_RE = /^[$_\p{ID_Start}][$\u200C\u200D\p{ID_Continue}]*$/u;
|
|
59
39
|
const NON_SPACE_RE = /\S/;
|
|
60
40
|
const WXS_MODULE_RE = /<wxs[\s\S]*?module\s*=\s*(?:"([^"]+)"|'([^']+)')[\s\S]*?\/?>/gi;
|
|
61
41
|
const FULL_CAPABILITIES = {
|
|
@@ -74,21 +54,185 @@ const VOID_CAPABILITIES = {
|
|
|
74
54
|
structure: false,
|
|
75
55
|
format: false
|
|
76
56
|
};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
57
|
+
//#endregion
|
|
58
|
+
//#region src/schema.ts
|
|
59
|
+
/**
|
|
60
|
+
* 为小程序配置生成 JSON Schema
|
|
61
|
+
* 为支持 JSON Schema 的编辑器提供验证和自动补全
|
|
62
|
+
*
|
|
63
|
+
* 注意:JSON Schema 定义由 @weapp-core/schematics 统一维护
|
|
64
|
+
* 使用 Zod 定义并自动生成,确保单一数据源
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* 根据文件类型获取对应的 JSON Schema
|
|
68
|
+
* Schema 定义来自 @weapp-core/schematics,使用 Zod 维护单一数据源
|
|
69
|
+
*/
|
|
70
|
+
function getSchemaForType(type) {
|
|
71
|
+
const definition = _weapp_core_schematics.JSON_SCHEMA_DEFINITIONS.find((d) => d.typeName === type);
|
|
72
|
+
if (!definition) return null;
|
|
73
|
+
return definition.schema;
|
|
84
74
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/jsonBlock.ts
|
|
77
|
+
function normalizeFilename(filename) {
|
|
78
|
+
if (!filename) return "";
|
|
79
|
+
return filename.replace(BACKSLASH_RE, "/");
|
|
80
|
+
}
|
|
81
|
+
function inferConfigType(filename) {
|
|
82
|
+
const normalized = normalizeFilename(filename);
|
|
83
|
+
if (normalized.endsWith("/app.vue")) return "App";
|
|
84
|
+
if (normalized.includes("/plugin/")) return "Plugin";
|
|
85
|
+
if (normalized.includes("/components/")) return "Component";
|
|
86
|
+
if (normalized.includes("/theme/")) return "Theme";
|
|
87
|
+
if (normalized.includes("/sitemap")) return "Sitemap";
|
|
88
|
+
return "Page";
|
|
89
|
+
}
|
|
90
|
+
function normalizeLang(lang) {
|
|
91
|
+
if (!lang) return JSON_LANG;
|
|
92
|
+
const lower = lang.toLowerCase();
|
|
93
|
+
if (lower === "txt") return JSON_LANG;
|
|
94
|
+
return lower;
|
|
95
|
+
}
|
|
96
|
+
function getEmbeddedCodesFromCustomBlocks(sfc) {
|
|
97
|
+
const names = [];
|
|
98
|
+
for (let i = 0; i < sfc.customBlocks.length; i++) {
|
|
99
|
+
const block = sfc.customBlocks[i];
|
|
100
|
+
if (block.type === "json") {
|
|
101
|
+
const normalizedLang = normalizeLang(block.lang);
|
|
102
|
+
if (normalizedLang === "js" || normalizedLang === "ts") {
|
|
103
|
+
names.push({
|
|
104
|
+
id: `${BLOCK_TYPE}_${i}`,
|
|
105
|
+
lang: "ts"
|
|
106
|
+
});
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const embeddedLang = normalizedLang === "json" || normalizedLang === "jsonc" || normalizedLang === "json5" ? JSONC_LANG : JSON_LANG;
|
|
110
|
+
names.push({
|
|
111
|
+
id: `${BLOCK_TYPE}_${i}`,
|
|
112
|
+
lang: embeddedLang
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return names;
|
|
117
|
+
}
|
|
118
|
+
function findExportDefaultExpression(code, tsModule, lang) {
|
|
119
|
+
const scriptKind = lang === "ts" ? 3 : 1;
|
|
120
|
+
const sourceFile = tsModule.createSourceFile(`config.${lang}`, code, 99, true, scriptKind);
|
|
121
|
+
for (const statement of sourceFile.statements) if (tsModule.isExportAssignment(statement)) {
|
|
122
|
+
const expressionStart = statement.expression.getStart(sourceFile);
|
|
123
|
+
const expressionEnd = statement.expression.getEnd();
|
|
124
|
+
const leading = code.slice(0, statement.getStart(sourceFile));
|
|
125
|
+
return {
|
|
126
|
+
expression: code.slice(expressionStart, expressionEnd),
|
|
127
|
+
expressionStart,
|
|
128
|
+
expressionEnd,
|
|
129
|
+
leading,
|
|
130
|
+
trailing: code.slice(statement.getEnd())
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
function injectSchemaIntoJsonObject(content, schemaId) {
|
|
136
|
+
const trimmed = content.trim();
|
|
137
|
+
if (!trimmed.startsWith("{")) return content;
|
|
138
|
+
const leftBraceIndex = content.indexOf("{");
|
|
139
|
+
if (leftBraceIndex < 0) return content;
|
|
140
|
+
const firstNonSpace = content.slice(leftBraceIndex + 1).match(NON_SPACE_RE);
|
|
141
|
+
const nextCharIndex = firstNonSpace ? leftBraceIndex + 1 + firstNonSpace.index : -1;
|
|
142
|
+
const isEmptyObject = nextCharIndex >= 0 && content[nextCharIndex] === "}";
|
|
143
|
+
const schemaLine = ` "$schema": "${schemaId}"`;
|
|
144
|
+
const injected = isEmptyObject ? `{\n${schemaLine}\n}` : `{\n${schemaLine},${content.slice(leftBraceIndex + 1)}`;
|
|
145
|
+
if (trimmed === content) return injected;
|
|
146
|
+
return `${content.slice(0, content.indexOf(trimmed))}${injected}${content.slice(content.indexOf(trimmed) + trimmed.length)}`;
|
|
147
|
+
}
|
|
148
|
+
function resolveEmbeddedJsonBlock(fileName, sfc, embeddedCode, tsModule, hasSchematicsTypes) {
|
|
149
|
+
const match = embeddedCode.id.match(new RegExp(`^${BLOCK_TYPE}_(\\d+)$`));
|
|
150
|
+
if (!match) return;
|
|
151
|
+
const index = Number.parseInt(match[1]);
|
|
152
|
+
const block = sfc.customBlocks[index];
|
|
153
|
+
if (!block) return;
|
|
154
|
+
const normalizedLang = normalizeLang(block.lang);
|
|
155
|
+
const configType = inferConfigType(fileName);
|
|
156
|
+
if (!hasSchematicsTypes) {
|
|
157
|
+
embeddedCode.content.push([
|
|
158
|
+
block.content,
|
|
159
|
+
block.name,
|
|
160
|
+
0,
|
|
161
|
+
FULL_CAPABILITIES
|
|
162
|
+
]);
|
|
89
163
|
return;
|
|
90
164
|
}
|
|
165
|
+
if (normalizedLang === "js" || normalizedLang === "ts") {
|
|
166
|
+
const parsed = tsModule && findExportDefaultExpression(block.content, tsModule, normalizedLang);
|
|
167
|
+
if (parsed) {
|
|
168
|
+
const typeImport = `import type { ${configType} as __WeappConfig } from '@weapp-core/schematics'\n`;
|
|
169
|
+
embeddedCode.content.push([
|
|
170
|
+
`${typeImport}const __weapp_defineConfig = <T extends __WeappConfig>(config: T) => config
|
|
171
|
+
|
|
172
|
+
`,
|
|
173
|
+
void 0,
|
|
174
|
+
0,
|
|
175
|
+
VOID_CAPABILITIES
|
|
176
|
+
]);
|
|
177
|
+
if (parsed.leading) embeddedCode.content.push([
|
|
178
|
+
parsed.leading,
|
|
179
|
+
block.name,
|
|
180
|
+
0,
|
|
181
|
+
FULL_CAPABILITIES
|
|
182
|
+
]);
|
|
183
|
+
embeddedCode.content.push([
|
|
184
|
+
"export default __weapp_defineConfig(",
|
|
185
|
+
void 0,
|
|
186
|
+
parsed.expressionStart,
|
|
187
|
+
VOID_CAPABILITIES
|
|
188
|
+
]);
|
|
189
|
+
embeddedCode.content.push([
|
|
190
|
+
parsed.expression,
|
|
191
|
+
block.name,
|
|
192
|
+
parsed.expressionStart,
|
|
193
|
+
FULL_CAPABILITIES
|
|
194
|
+
]);
|
|
195
|
+
embeddedCode.content.push([
|
|
196
|
+
")",
|
|
197
|
+
void 0,
|
|
198
|
+
parsed.expressionEnd,
|
|
199
|
+
VOID_CAPABILITIES
|
|
200
|
+
]);
|
|
201
|
+
if (parsed.trailing) embeddedCode.content.push([
|
|
202
|
+
parsed.trailing,
|
|
203
|
+
block.name,
|
|
204
|
+
parsed.expressionEnd,
|
|
205
|
+
FULL_CAPABILITIES
|
|
206
|
+
]);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
embeddedCode.content.push([
|
|
210
|
+
block.content,
|
|
211
|
+
block.name,
|
|
212
|
+
0,
|
|
213
|
+
FULL_CAPABILITIES
|
|
214
|
+
]);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const schema = getSchemaForType(configType);
|
|
218
|
+
if (schema && schema.$id && !block.content.includes("$schema")) {
|
|
219
|
+
embeddedCode.content.push([
|
|
220
|
+
injectSchemaIntoJsonObject(block.content, schema.$id),
|
|
221
|
+
block.name,
|
|
222
|
+
0,
|
|
223
|
+
FULL_CAPABILITIES
|
|
224
|
+
]);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
embeddedCode.content.push([
|
|
228
|
+
block.content,
|
|
229
|
+
block.name,
|
|
230
|
+
0,
|
|
231
|
+
FULL_CAPABILITIES
|
|
232
|
+
]);
|
|
91
233
|
}
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/scriptSetup.ts
|
|
92
236
|
function collectWxsModuleNames(templateContent) {
|
|
93
237
|
if (!templateContent) return [];
|
|
94
238
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -107,6 +251,10 @@ function appendWxsDeclarations(code, moduleNames) {
|
|
|
107
251
|
if (!declarations) return code;
|
|
108
252
|
return code ? `${code}\n\n${declarations}\n` : `${declarations}\n`;
|
|
109
253
|
}
|
|
254
|
+
function appendScriptSetupDeclarations(code, declarations) {
|
|
255
|
+
if (!declarations) return code;
|
|
256
|
+
return code ? `${code}\n\n${declarations}\n` : `${declarations}\n`;
|
|
257
|
+
}
|
|
110
258
|
function createSyntheticScriptSetup(moduleNames) {
|
|
111
259
|
const content = createWxsModuleDeclarations(moduleNames);
|
|
112
260
|
if (!content) return;
|
|
@@ -135,54 +283,151 @@ function createSyntheticScriptSetup(moduleNames) {
|
|
|
135
283
|
name: "scriptSetup"
|
|
136
284
|
};
|
|
137
285
|
}
|
|
138
|
-
function
|
|
139
|
-
if (!
|
|
140
|
-
|
|
286
|
+
function syncScriptBlockSource(block) {
|
|
287
|
+
if (!block) return;
|
|
288
|
+
const attrs = Object.entries(block.attrs ?? {}).filter(([, value]) => value != null).map(([key, value]) => value === true ? key : `${key}="${String(value)}"`).join(" ");
|
|
289
|
+
const openTag = attrs ? `<script ${attrs}>` : "<script>";
|
|
290
|
+
block.loc.source = `${openTag}\n${block.content}\n<\/script>`;
|
|
141
291
|
}
|
|
142
|
-
function
|
|
143
|
-
|
|
144
|
-
if (normalized.endsWith("/app.vue")) return "App";
|
|
145
|
-
if (normalized.includes("/plugin/")) return "Plugin";
|
|
146
|
-
if (normalized.includes("/components/")) return "Component";
|
|
147
|
-
if (normalized.includes("/theme/")) return "Theme";
|
|
148
|
-
if (normalized.includes("/sitemap")) return "Sitemap";
|
|
149
|
-
return "Page";
|
|
292
|
+
function isIdentifierName(name) {
|
|
293
|
+
return IDENTIFIER_NAME_RE.test(name);
|
|
150
294
|
}
|
|
151
|
-
function
|
|
152
|
-
if (
|
|
153
|
-
const lower = lang.toLowerCase();
|
|
154
|
-
if (lower === "txt") return JSON_LANG;
|
|
155
|
-
return lower;
|
|
295
|
+
function getPropertyNameText(node, tsModule) {
|
|
296
|
+
if (tsModule.isIdentifier(node) || tsModule.isStringLiteral(node) || tsModule.isNumericLiteral(node)) return node.text;
|
|
156
297
|
}
|
|
157
|
-
function
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const expressionStart = statement.expression.getStart(sourceFile);
|
|
162
|
-
const expressionEnd = statement.expression.getEnd();
|
|
163
|
-
const leading = code.slice(0, statement.getStart(sourceFile));
|
|
164
|
-
return {
|
|
165
|
-
expression: code.slice(expressionStart, expressionEnd),
|
|
166
|
-
expressionStart,
|
|
167
|
-
expressionEnd,
|
|
168
|
-
leading,
|
|
169
|
-
trailing: code.slice(statement.getEnd())
|
|
170
|
-
};
|
|
298
|
+
function collectBindingNames(name, tsModule, bindings) {
|
|
299
|
+
if (tsModule.isIdentifier(name)) {
|
|
300
|
+
bindings.add(name.text);
|
|
301
|
+
return;
|
|
171
302
|
}
|
|
172
|
-
|
|
303
|
+
for (const element of name.elements) if (tsModule.isBindingElement(element)) collectBindingNames(element.name, tsModule, bindings);
|
|
173
304
|
}
|
|
174
|
-
function
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
305
|
+
function collectTopLevelBindingNames(code, tsModule, lang) {
|
|
306
|
+
const scriptKind = lang === "ts" ? 3 : 1;
|
|
307
|
+
const sourceFile = tsModule.createSourceFile(`bindings.${lang}`, code, 99, true, scriptKind);
|
|
308
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
309
|
+
for (const statement of sourceFile.statements) {
|
|
310
|
+
if (tsModule.isVariableStatement(statement)) {
|
|
311
|
+
for (const declaration of statement.declarationList.declarations) collectBindingNames(declaration.name, tsModule, bindings);
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if ((tsModule.isFunctionDeclaration(statement) || tsModule.isClassDeclaration(statement) || tsModule.isEnumDeclaration(statement)) && statement.name) {
|
|
315
|
+
bindings.add(statement.name.text);
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
if (tsModule.isImportDeclaration(statement) && statement.importClause) {
|
|
319
|
+
const { importClause } = statement;
|
|
320
|
+
if (importClause.name) bindings.add(importClause.name.text);
|
|
321
|
+
if (importClause.namedBindings) if (tsModule.isNamespaceImport(importClause.namedBindings)) bindings.add(importClause.namedBindings.name.text);
|
|
322
|
+
else for (const element of importClause.namedBindings.elements) bindings.add(element.name.text);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return bindings;
|
|
326
|
+
}
|
|
327
|
+
function unwrapParenthesizedExpression(node, tsModule) {
|
|
328
|
+
let current = node;
|
|
329
|
+
while (tsModule.isParenthesizedExpression(current)) current = current.expression;
|
|
330
|
+
return current;
|
|
331
|
+
}
|
|
332
|
+
function findReturnedObjectLiteral(node, tsModule) {
|
|
333
|
+
if (tsModule.isObjectLiteralExpression(node)) return node;
|
|
334
|
+
if (!tsModule.isBlock(node)) return;
|
|
335
|
+
for (const statement of node.statements) {
|
|
336
|
+
if (!tsModule.isReturnStatement(statement) || !statement.expression) continue;
|
|
337
|
+
const expression = unwrapParenthesizedExpression(statement.expression, tsModule);
|
|
338
|
+
if (tsModule.isObjectLiteralExpression(expression)) return expression;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
function extractDefineOptionsObjectLiteral(node, tsModule) {
|
|
342
|
+
if (!tsModule.isIdentifier(node.expression) || node.expression.text !== "defineOptions") return;
|
|
343
|
+
const [firstArg] = node.arguments;
|
|
344
|
+
if (!firstArg) return;
|
|
345
|
+
const arg = unwrapParenthesizedExpression(firstArg, tsModule);
|
|
346
|
+
if (tsModule.isObjectLiteralExpression(arg)) return arg;
|
|
347
|
+
if (tsModule.isArrowFunction(arg) || tsModule.isFunctionExpression(arg)) return findReturnedObjectLiteral(arg.body, tsModule);
|
|
348
|
+
}
|
|
349
|
+
function collectObjectLiteralKeys(node, tsModule) {
|
|
350
|
+
const keys = [];
|
|
351
|
+
for (const property of node.properties) {
|
|
352
|
+
if (!tsModule.isPropertyAssignment(property) && !tsModule.isMethodDeclaration(property) && !tsModule.isShorthandPropertyAssignment(property) && !tsModule.isGetAccessorDeclaration(property)) continue;
|
|
353
|
+
const key = getPropertyNameText(property.name, tsModule);
|
|
354
|
+
if (key && isIdentifierName(key)) keys.push(key);
|
|
355
|
+
}
|
|
356
|
+
return keys;
|
|
357
|
+
}
|
|
358
|
+
function collectDefineOptionsTemplateBindings(code, tsModule, lang) {
|
|
359
|
+
const scriptKind = lang === "ts" ? 3 : 1;
|
|
360
|
+
const sourceFile = tsModule.createSourceFile(`script-setup.${lang}`, code, 99, true, scriptKind);
|
|
361
|
+
const valueBindings = /* @__PURE__ */ new Set();
|
|
362
|
+
const functionBindings = /* @__PURE__ */ new Set();
|
|
363
|
+
const visit = (node) => {
|
|
364
|
+
if (tsModule.isCallExpression(node)) {
|
|
365
|
+
const optionsObject = extractDefineOptionsObjectLiteral(node, tsModule);
|
|
366
|
+
if (optionsObject) for (const property of optionsObject.properties) {
|
|
367
|
+
const sectionName = tsModule.isPropertyAssignment(property) || tsModule.isMethodDeclaration(property) ? getPropertyNameText(property.name, tsModule) : void 0;
|
|
368
|
+
if (!sectionName) continue;
|
|
369
|
+
if (sectionName === "methods") {
|
|
370
|
+
const methodsObject = tsModule.isPropertyAssignment(property) ? unwrapParenthesizedExpression(property.initializer, tsModule) : void 0;
|
|
371
|
+
if (methodsObject && tsModule.isObjectLiteralExpression(methodsObject)) for (const name of collectObjectLiteralKeys(methodsObject, tsModule)) functionBindings.add(name);
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
if (sectionName === "properties" || sectionName === "computed") {
|
|
375
|
+
const objectValue = tsModule.isPropertyAssignment(property) ? unwrapParenthesizedExpression(property.initializer, tsModule) : void 0;
|
|
376
|
+
if (objectValue && tsModule.isObjectLiteralExpression(objectValue)) for (const name of collectObjectLiteralKeys(objectValue, tsModule)) valueBindings.add(name);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (sectionName === "data") {
|
|
380
|
+
let dataObject;
|
|
381
|
+
if (tsModule.isMethodDeclaration(property)) dataObject = findReturnedObjectLiteral(property.body ?? tsModule.factory.createBlock([], false), tsModule);
|
|
382
|
+
else if (tsModule.isPropertyAssignment(property)) {
|
|
383
|
+
const initializer = unwrapParenthesizedExpression(property.initializer, tsModule);
|
|
384
|
+
if (tsModule.isArrowFunction(initializer) || tsModule.isFunctionExpression(initializer)) dataObject = findReturnedObjectLiteral(initializer.body, tsModule);
|
|
385
|
+
}
|
|
386
|
+
if (dataObject) for (const name of collectObjectLiteralKeys(dataObject, tsModule)) valueBindings.add(name);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
tsModule.forEachChild(node, visit);
|
|
391
|
+
};
|
|
392
|
+
visit(sourceFile);
|
|
393
|
+
return {
|
|
394
|
+
values: [...valueBindings],
|
|
395
|
+
functions: [...functionBindings]
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function createDefineOptionsTemplateDeclarations(code, tsModule, lang) {
|
|
399
|
+
const topLevelBindings = collectTopLevelBindingNames(code, tsModule, lang);
|
|
400
|
+
const bindings = collectDefineOptionsTemplateBindings(code, tsModule, lang);
|
|
401
|
+
const declarations = [];
|
|
402
|
+
for (const name of bindings.values) {
|
|
403
|
+
if (topLevelBindings.has(name)) continue;
|
|
404
|
+
declarations.push(`const ${name}: any = null as any`);
|
|
405
|
+
}
|
|
406
|
+
for (const name of bindings.functions) {
|
|
407
|
+
if (topLevelBindings.has(name)) continue;
|
|
408
|
+
declarations.push(`const ${name}: (...args: any[]) => any = null as any`);
|
|
409
|
+
}
|
|
410
|
+
return declarations.join("\n");
|
|
411
|
+
}
|
|
412
|
+
function resolveScriptSetupLang(lang) {
|
|
413
|
+
return lang === "js" ? "js" : "ts";
|
|
414
|
+
}
|
|
415
|
+
//#endregion
|
|
416
|
+
//#region src/index.ts
|
|
417
|
+
const require$1 = (0, node_module.createRequire)(typeof module !== "undefined" && module.filename ? module.filename : node_path.default.join(node_process.default.cwd(), "weapp-vite-volar.cjs"));
|
|
418
|
+
let hasSchematicsTypes = false;
|
|
419
|
+
try {
|
|
420
|
+
require$1.resolve("@weapp-core/schematics");
|
|
421
|
+
hasSchematicsTypes = true;
|
|
422
|
+
} catch {
|
|
423
|
+
hasSchematicsTypes = false;
|
|
424
|
+
}
|
|
425
|
+
function parseVueSfc(content, filename = "component.vue") {
|
|
426
|
+
try {
|
|
427
|
+
return require$1("@vue/compiler-sfc").parse(content, { filename });
|
|
428
|
+
} catch {
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
186
431
|
}
|
|
187
432
|
/**
|
|
188
433
|
* Volar 语言插件:为 weapp 配置块提供类型与 schema 提示。
|
|
@@ -204,118 +449,21 @@ const plugin = (ctx) => {
|
|
|
204
449
|
if (!parsed) return;
|
|
205
450
|
const descriptor = parsed.descriptor;
|
|
206
451
|
const wxsModuleNames = collectWxsModuleNames(descriptor.template?.content);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
452
|
+
const scriptSetup = descriptor.scriptSetup;
|
|
453
|
+
const scriptSetupLang = resolveScriptSetupLang(scriptSetup?.lang);
|
|
454
|
+
const defineOptionsDeclarations = scriptSetup?.content && tsModule ? createDefineOptionsTemplateDeclarations(scriptSetup.content, tsModule, scriptSetupLang) : "";
|
|
455
|
+
if (!wxsModuleNames.length && !defineOptionsDeclarations) return parsed;
|
|
456
|
+
if (descriptor.scriptSetup) {
|
|
457
|
+
descriptor.scriptSetup.content = appendScriptSetupDeclarations(appendWxsDeclarations(descriptor.scriptSetup.content, wxsModuleNames), defineOptionsDeclarations);
|
|
458
|
+
syncScriptBlockSource(descriptor.scriptSetup);
|
|
459
|
+
} else descriptor.scriptSetup = createSyntheticScriptSetup(wxsModuleNames);
|
|
210
460
|
return parsed;
|
|
211
461
|
},
|
|
212
462
|
getEmbeddedCodes(_, sfc) {
|
|
213
|
-
|
|
214
|
-
for (let i = 0; i < sfc.customBlocks.length; i++) {
|
|
215
|
-
const block = sfc.customBlocks[i];
|
|
216
|
-
if (block.type === BLOCK_TYPE) {
|
|
217
|
-
const normalizedLang = normalizeLang(block.lang);
|
|
218
|
-
if (normalizedLang === JS_LANG || normalizedLang === TS_LANG) {
|
|
219
|
-
names.push({
|
|
220
|
-
id: `${BLOCK_TYPE}_${i}`,
|
|
221
|
-
lang: TS_LANG
|
|
222
|
-
});
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
const embeddedLang = normalizedLang === JSON_LANG || normalizedLang === JSONC_LANG || normalizedLang === JSON5_LANG ? JSONC_LANG : JSON_LANG;
|
|
226
|
-
names.push({
|
|
227
|
-
id: `${BLOCK_TYPE}_${i}`,
|
|
228
|
-
lang: embeddedLang
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return names;
|
|
463
|
+
return getEmbeddedCodesFromCustomBlocks(sfc);
|
|
233
464
|
},
|
|
234
465
|
resolveEmbeddedCode(fileName, sfc, embeddedCode) {
|
|
235
|
-
|
|
236
|
-
if (!match) return;
|
|
237
|
-
const index = Number.parseInt(match[1]);
|
|
238
|
-
const block = sfc.customBlocks[index];
|
|
239
|
-
if (!block) return;
|
|
240
|
-
const normalizedLang = normalizeLang(block.lang);
|
|
241
|
-
const configType = inferConfigType(fileName);
|
|
242
|
-
if (!hasSchematicsTypes) {
|
|
243
|
-
embeddedCode.content.push([
|
|
244
|
-
block.content,
|
|
245
|
-
block.name,
|
|
246
|
-
0,
|
|
247
|
-
FULL_CAPABILITIES
|
|
248
|
-
]);
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
if (normalizedLang === JS_LANG || normalizedLang === TS_LANG) {
|
|
252
|
-
const parsed = tsModule && findExportDefaultExpression(block.content, tsModule, normalizedLang);
|
|
253
|
-
if (parsed && hasSchematicsTypes) {
|
|
254
|
-
const typeImport = `import type { ${configType} as __WeappConfig } from '@weapp-core/schematics'\n`;
|
|
255
|
-
embeddedCode.content.push([
|
|
256
|
-
`${typeImport}const __weapp_defineConfig = <T extends __WeappConfig>(config: T) => config
|
|
257
|
-
|
|
258
|
-
`,
|
|
259
|
-
void 0,
|
|
260
|
-
0,
|
|
261
|
-
VOID_CAPABILITIES
|
|
262
|
-
]);
|
|
263
|
-
if (parsed.leading) embeddedCode.content.push([
|
|
264
|
-
parsed.leading,
|
|
265
|
-
block.name,
|
|
266
|
-
0,
|
|
267
|
-
FULL_CAPABILITIES
|
|
268
|
-
]);
|
|
269
|
-
embeddedCode.content.push([
|
|
270
|
-
"export default __weapp_defineConfig(",
|
|
271
|
-
void 0,
|
|
272
|
-
parsed.expressionStart,
|
|
273
|
-
VOID_CAPABILITIES
|
|
274
|
-
]);
|
|
275
|
-
embeddedCode.content.push([
|
|
276
|
-
parsed.expression,
|
|
277
|
-
block.name,
|
|
278
|
-
parsed.expressionStart,
|
|
279
|
-
FULL_CAPABILITIES
|
|
280
|
-
]);
|
|
281
|
-
embeddedCode.content.push([
|
|
282
|
-
")",
|
|
283
|
-
void 0,
|
|
284
|
-
parsed.expressionEnd,
|
|
285
|
-
VOID_CAPABILITIES
|
|
286
|
-
]);
|
|
287
|
-
if (parsed.trailing) embeddedCode.content.push([
|
|
288
|
-
parsed.trailing,
|
|
289
|
-
block.name,
|
|
290
|
-
parsed.expressionEnd,
|
|
291
|
-
FULL_CAPABILITIES
|
|
292
|
-
]);
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
embeddedCode.content.push([
|
|
296
|
-
block.content,
|
|
297
|
-
block.name,
|
|
298
|
-
0,
|
|
299
|
-
FULL_CAPABILITIES
|
|
300
|
-
]);
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
const schema = getSchemaForType(configType);
|
|
304
|
-
if (schema && schema.$id && !block.content.includes("$schema")) {
|
|
305
|
-
embeddedCode.content.push([
|
|
306
|
-
injectSchemaIntoJsonObject(block.content, schema.$id),
|
|
307
|
-
block.name,
|
|
308
|
-
0,
|
|
309
|
-
FULL_CAPABILITIES
|
|
310
|
-
]);
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
embeddedCode.content.push([
|
|
314
|
-
block.content,
|
|
315
|
-
block.name,
|
|
316
|
-
0,
|
|
317
|
-
FULL_CAPABILITIES
|
|
318
|
-
]);
|
|
466
|
+
resolveEmbeddedJsonBlock(fileName, sfc, embeddedCode, tsModule, hasSchematicsTypes);
|
|
319
467
|
}
|
|
320
468
|
};
|
|
321
469
|
};
|
package/dist/index.mjs
CHANGED
|
@@ -5,33 +5,13 @@ import { JSON_SCHEMA_DEFINITIONS } from "@weapp-core/schematics";
|
|
|
5
5
|
//#region package.json
|
|
6
6
|
var name = "@weapp-vite/volar";
|
|
7
7
|
//#endregion
|
|
8
|
-
//#region src/
|
|
9
|
-
/**
|
|
10
|
-
* 为小程序配置生成 JSON Schema
|
|
11
|
-
* 为支持 JSON Schema 的编辑器提供验证和自动补全
|
|
12
|
-
*
|
|
13
|
-
* 注意:JSON Schema 定义由 @weapp-core/schematics 统一维护
|
|
14
|
-
* 使用 Zod 定义并自动生成,确保单一数据源
|
|
15
|
-
*/
|
|
16
|
-
/**
|
|
17
|
-
* 根据文件类型获取对应的 JSON Schema
|
|
18
|
-
* Schema 定义来自 @weapp-core/schematics,使用 Zod 维护单一数据源
|
|
19
|
-
*/
|
|
20
|
-
function getSchemaForType(type) {
|
|
21
|
-
const definition = JSON_SCHEMA_DEFINITIONS.find((d) => d.typeName === type);
|
|
22
|
-
if (!definition) return null;
|
|
23
|
-
return definition.schema;
|
|
24
|
-
}
|
|
25
|
-
//#endregion
|
|
26
|
-
//#region src/index.ts
|
|
8
|
+
//#region src/constants.ts
|
|
27
9
|
const BLOCK_TYPE = "json";
|
|
28
|
-
const JS_LANG = "js";
|
|
29
10
|
const JSONC_LANG = "jsonc";
|
|
30
11
|
const JSON_LANG = "json";
|
|
31
|
-
const JSON5_LANG = "json5";
|
|
32
12
|
const PLUGIN_VERSION = 2.2;
|
|
33
|
-
const TS_LANG = "ts";
|
|
34
13
|
const BACKSLASH_RE = /\\/g;
|
|
14
|
+
const IDENTIFIER_NAME_RE = /^[$_\p{ID_Start}][$\u200C\u200D\p{ID_Continue}]*$/u;
|
|
35
15
|
const NON_SPACE_RE = /\S/;
|
|
36
16
|
const WXS_MODULE_RE = /<wxs[\s\S]*?module\s*=\s*(?:"([^"]+)"|'([^']+)')[\s\S]*?\/?>/gi;
|
|
37
17
|
const FULL_CAPABILITIES = {
|
|
@@ -50,21 +30,185 @@ const VOID_CAPABILITIES = {
|
|
|
50
30
|
structure: false,
|
|
51
31
|
format: false
|
|
52
32
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/schema.ts
|
|
35
|
+
/**
|
|
36
|
+
* 为小程序配置生成 JSON Schema
|
|
37
|
+
* 为支持 JSON Schema 的编辑器提供验证和自动补全
|
|
38
|
+
*
|
|
39
|
+
* 注意:JSON Schema 定义由 @weapp-core/schematics 统一维护
|
|
40
|
+
* 使用 Zod 定义并自动生成,确保单一数据源
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* 根据文件类型获取对应的 JSON Schema
|
|
44
|
+
* Schema 定义来自 @weapp-core/schematics,使用 Zod 维护单一数据源
|
|
45
|
+
*/
|
|
46
|
+
function getSchemaForType(type) {
|
|
47
|
+
const definition = JSON_SCHEMA_DEFINITIONS.find((d) => d.typeName === type);
|
|
48
|
+
if (!definition) return null;
|
|
49
|
+
return definition.schema;
|
|
60
50
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region src/jsonBlock.ts
|
|
53
|
+
function normalizeFilename(filename) {
|
|
54
|
+
if (!filename) return "";
|
|
55
|
+
return filename.replace(BACKSLASH_RE, "/");
|
|
56
|
+
}
|
|
57
|
+
function inferConfigType(filename) {
|
|
58
|
+
const normalized = normalizeFilename(filename);
|
|
59
|
+
if (normalized.endsWith("/app.vue")) return "App";
|
|
60
|
+
if (normalized.includes("/plugin/")) return "Plugin";
|
|
61
|
+
if (normalized.includes("/components/")) return "Component";
|
|
62
|
+
if (normalized.includes("/theme/")) return "Theme";
|
|
63
|
+
if (normalized.includes("/sitemap")) return "Sitemap";
|
|
64
|
+
return "Page";
|
|
65
|
+
}
|
|
66
|
+
function normalizeLang(lang) {
|
|
67
|
+
if (!lang) return JSON_LANG;
|
|
68
|
+
const lower = lang.toLowerCase();
|
|
69
|
+
if (lower === "txt") return JSON_LANG;
|
|
70
|
+
return lower;
|
|
71
|
+
}
|
|
72
|
+
function getEmbeddedCodesFromCustomBlocks(sfc) {
|
|
73
|
+
const names = [];
|
|
74
|
+
for (let i = 0; i < sfc.customBlocks.length; i++) {
|
|
75
|
+
const block = sfc.customBlocks[i];
|
|
76
|
+
if (block.type === "json") {
|
|
77
|
+
const normalizedLang = normalizeLang(block.lang);
|
|
78
|
+
if (normalizedLang === "js" || normalizedLang === "ts") {
|
|
79
|
+
names.push({
|
|
80
|
+
id: `${BLOCK_TYPE}_${i}`,
|
|
81
|
+
lang: "ts"
|
|
82
|
+
});
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const embeddedLang = normalizedLang === "json" || normalizedLang === "jsonc" || normalizedLang === "json5" ? JSONC_LANG : JSON_LANG;
|
|
86
|
+
names.push({
|
|
87
|
+
id: `${BLOCK_TYPE}_${i}`,
|
|
88
|
+
lang: embeddedLang
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return names;
|
|
93
|
+
}
|
|
94
|
+
function findExportDefaultExpression(code, tsModule, lang) {
|
|
95
|
+
const scriptKind = lang === "ts" ? 3 : 1;
|
|
96
|
+
const sourceFile = tsModule.createSourceFile(`config.${lang}`, code, 99, true, scriptKind);
|
|
97
|
+
for (const statement of sourceFile.statements) if (tsModule.isExportAssignment(statement)) {
|
|
98
|
+
const expressionStart = statement.expression.getStart(sourceFile);
|
|
99
|
+
const expressionEnd = statement.expression.getEnd();
|
|
100
|
+
const leading = code.slice(0, statement.getStart(sourceFile));
|
|
101
|
+
return {
|
|
102
|
+
expression: code.slice(expressionStart, expressionEnd),
|
|
103
|
+
expressionStart,
|
|
104
|
+
expressionEnd,
|
|
105
|
+
leading,
|
|
106
|
+
trailing: code.slice(statement.getEnd())
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
function injectSchemaIntoJsonObject(content, schemaId) {
|
|
112
|
+
const trimmed = content.trim();
|
|
113
|
+
if (!trimmed.startsWith("{")) return content;
|
|
114
|
+
const leftBraceIndex = content.indexOf("{");
|
|
115
|
+
if (leftBraceIndex < 0) return content;
|
|
116
|
+
const firstNonSpace = content.slice(leftBraceIndex + 1).match(NON_SPACE_RE);
|
|
117
|
+
const nextCharIndex = firstNonSpace ? leftBraceIndex + 1 + firstNonSpace.index : -1;
|
|
118
|
+
const isEmptyObject = nextCharIndex >= 0 && content[nextCharIndex] === "}";
|
|
119
|
+
const schemaLine = ` "$schema": "${schemaId}"`;
|
|
120
|
+
const injected = isEmptyObject ? `{\n${schemaLine}\n}` : `{\n${schemaLine},${content.slice(leftBraceIndex + 1)}`;
|
|
121
|
+
if (trimmed === content) return injected;
|
|
122
|
+
return `${content.slice(0, content.indexOf(trimmed))}${injected}${content.slice(content.indexOf(trimmed) + trimmed.length)}`;
|
|
123
|
+
}
|
|
124
|
+
function resolveEmbeddedJsonBlock(fileName, sfc, embeddedCode, tsModule, hasSchematicsTypes) {
|
|
125
|
+
const match = embeddedCode.id.match(new RegExp(`^${BLOCK_TYPE}_(\\d+)$`));
|
|
126
|
+
if (!match) return;
|
|
127
|
+
const index = Number.parseInt(match[1]);
|
|
128
|
+
const block = sfc.customBlocks[index];
|
|
129
|
+
if (!block) return;
|
|
130
|
+
const normalizedLang = normalizeLang(block.lang);
|
|
131
|
+
const configType = inferConfigType(fileName);
|
|
132
|
+
if (!hasSchematicsTypes) {
|
|
133
|
+
embeddedCode.content.push([
|
|
134
|
+
block.content,
|
|
135
|
+
block.name,
|
|
136
|
+
0,
|
|
137
|
+
FULL_CAPABILITIES
|
|
138
|
+
]);
|
|
65
139
|
return;
|
|
66
140
|
}
|
|
141
|
+
if (normalizedLang === "js" || normalizedLang === "ts") {
|
|
142
|
+
const parsed = tsModule && findExportDefaultExpression(block.content, tsModule, normalizedLang);
|
|
143
|
+
if (parsed) {
|
|
144
|
+
const typeImport = `import type { ${configType} as __WeappConfig } from '@weapp-core/schematics'\n`;
|
|
145
|
+
embeddedCode.content.push([
|
|
146
|
+
`${typeImport}const __weapp_defineConfig = <T extends __WeappConfig>(config: T) => config
|
|
147
|
+
|
|
148
|
+
`,
|
|
149
|
+
void 0,
|
|
150
|
+
0,
|
|
151
|
+
VOID_CAPABILITIES
|
|
152
|
+
]);
|
|
153
|
+
if (parsed.leading) embeddedCode.content.push([
|
|
154
|
+
parsed.leading,
|
|
155
|
+
block.name,
|
|
156
|
+
0,
|
|
157
|
+
FULL_CAPABILITIES
|
|
158
|
+
]);
|
|
159
|
+
embeddedCode.content.push([
|
|
160
|
+
"export default __weapp_defineConfig(",
|
|
161
|
+
void 0,
|
|
162
|
+
parsed.expressionStart,
|
|
163
|
+
VOID_CAPABILITIES
|
|
164
|
+
]);
|
|
165
|
+
embeddedCode.content.push([
|
|
166
|
+
parsed.expression,
|
|
167
|
+
block.name,
|
|
168
|
+
parsed.expressionStart,
|
|
169
|
+
FULL_CAPABILITIES
|
|
170
|
+
]);
|
|
171
|
+
embeddedCode.content.push([
|
|
172
|
+
")",
|
|
173
|
+
void 0,
|
|
174
|
+
parsed.expressionEnd,
|
|
175
|
+
VOID_CAPABILITIES
|
|
176
|
+
]);
|
|
177
|
+
if (parsed.trailing) embeddedCode.content.push([
|
|
178
|
+
parsed.trailing,
|
|
179
|
+
block.name,
|
|
180
|
+
parsed.expressionEnd,
|
|
181
|
+
FULL_CAPABILITIES
|
|
182
|
+
]);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
embeddedCode.content.push([
|
|
186
|
+
block.content,
|
|
187
|
+
block.name,
|
|
188
|
+
0,
|
|
189
|
+
FULL_CAPABILITIES
|
|
190
|
+
]);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const schema = getSchemaForType(configType);
|
|
194
|
+
if (schema && schema.$id && !block.content.includes("$schema")) {
|
|
195
|
+
embeddedCode.content.push([
|
|
196
|
+
injectSchemaIntoJsonObject(block.content, schema.$id),
|
|
197
|
+
block.name,
|
|
198
|
+
0,
|
|
199
|
+
FULL_CAPABILITIES
|
|
200
|
+
]);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
embeddedCode.content.push([
|
|
204
|
+
block.content,
|
|
205
|
+
block.name,
|
|
206
|
+
0,
|
|
207
|
+
FULL_CAPABILITIES
|
|
208
|
+
]);
|
|
67
209
|
}
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/scriptSetup.ts
|
|
68
212
|
function collectWxsModuleNames(templateContent) {
|
|
69
213
|
if (!templateContent) return [];
|
|
70
214
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -83,6 +227,10 @@ function appendWxsDeclarations(code, moduleNames) {
|
|
|
83
227
|
if (!declarations) return code;
|
|
84
228
|
return code ? `${code}\n\n${declarations}\n` : `${declarations}\n`;
|
|
85
229
|
}
|
|
230
|
+
function appendScriptSetupDeclarations(code, declarations) {
|
|
231
|
+
if (!declarations) return code;
|
|
232
|
+
return code ? `${code}\n\n${declarations}\n` : `${declarations}\n`;
|
|
233
|
+
}
|
|
86
234
|
function createSyntheticScriptSetup(moduleNames) {
|
|
87
235
|
const content = createWxsModuleDeclarations(moduleNames);
|
|
88
236
|
if (!content) return;
|
|
@@ -111,54 +259,151 @@ function createSyntheticScriptSetup(moduleNames) {
|
|
|
111
259
|
name: "scriptSetup"
|
|
112
260
|
};
|
|
113
261
|
}
|
|
114
|
-
function
|
|
115
|
-
if (!
|
|
116
|
-
|
|
262
|
+
function syncScriptBlockSource(block) {
|
|
263
|
+
if (!block) return;
|
|
264
|
+
const attrs = Object.entries(block.attrs ?? {}).filter(([, value]) => value != null).map(([key, value]) => value === true ? key : `${key}="${String(value)}"`).join(" ");
|
|
265
|
+
const openTag = attrs ? `<script ${attrs}>` : "<script>";
|
|
266
|
+
block.loc.source = `${openTag}\n${block.content}\n<\/script>`;
|
|
117
267
|
}
|
|
118
|
-
function
|
|
119
|
-
|
|
120
|
-
if (normalized.endsWith("/app.vue")) return "App";
|
|
121
|
-
if (normalized.includes("/plugin/")) return "Plugin";
|
|
122
|
-
if (normalized.includes("/components/")) return "Component";
|
|
123
|
-
if (normalized.includes("/theme/")) return "Theme";
|
|
124
|
-
if (normalized.includes("/sitemap")) return "Sitemap";
|
|
125
|
-
return "Page";
|
|
268
|
+
function isIdentifierName(name) {
|
|
269
|
+
return IDENTIFIER_NAME_RE.test(name);
|
|
126
270
|
}
|
|
127
|
-
function
|
|
128
|
-
if (
|
|
129
|
-
const lower = lang.toLowerCase();
|
|
130
|
-
if (lower === "txt") return JSON_LANG;
|
|
131
|
-
return lower;
|
|
271
|
+
function getPropertyNameText(node, tsModule) {
|
|
272
|
+
if (tsModule.isIdentifier(node) || tsModule.isStringLiteral(node) || tsModule.isNumericLiteral(node)) return node.text;
|
|
132
273
|
}
|
|
133
|
-
function
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const expressionStart = statement.expression.getStart(sourceFile);
|
|
138
|
-
const expressionEnd = statement.expression.getEnd();
|
|
139
|
-
const leading = code.slice(0, statement.getStart(sourceFile));
|
|
140
|
-
return {
|
|
141
|
-
expression: code.slice(expressionStart, expressionEnd),
|
|
142
|
-
expressionStart,
|
|
143
|
-
expressionEnd,
|
|
144
|
-
leading,
|
|
145
|
-
trailing: code.slice(statement.getEnd())
|
|
146
|
-
};
|
|
274
|
+
function collectBindingNames(name, tsModule, bindings) {
|
|
275
|
+
if (tsModule.isIdentifier(name)) {
|
|
276
|
+
bindings.add(name.text);
|
|
277
|
+
return;
|
|
147
278
|
}
|
|
148
|
-
|
|
279
|
+
for (const element of name.elements) if (tsModule.isBindingElement(element)) collectBindingNames(element.name, tsModule, bindings);
|
|
149
280
|
}
|
|
150
|
-
function
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
281
|
+
function collectTopLevelBindingNames(code, tsModule, lang) {
|
|
282
|
+
const scriptKind = lang === "ts" ? 3 : 1;
|
|
283
|
+
const sourceFile = tsModule.createSourceFile(`bindings.${lang}`, code, 99, true, scriptKind);
|
|
284
|
+
const bindings = /* @__PURE__ */ new Set();
|
|
285
|
+
for (const statement of sourceFile.statements) {
|
|
286
|
+
if (tsModule.isVariableStatement(statement)) {
|
|
287
|
+
for (const declaration of statement.declarationList.declarations) collectBindingNames(declaration.name, tsModule, bindings);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if ((tsModule.isFunctionDeclaration(statement) || tsModule.isClassDeclaration(statement) || tsModule.isEnumDeclaration(statement)) && statement.name) {
|
|
291
|
+
bindings.add(statement.name.text);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
if (tsModule.isImportDeclaration(statement) && statement.importClause) {
|
|
295
|
+
const { importClause } = statement;
|
|
296
|
+
if (importClause.name) bindings.add(importClause.name.text);
|
|
297
|
+
if (importClause.namedBindings) if (tsModule.isNamespaceImport(importClause.namedBindings)) bindings.add(importClause.namedBindings.name.text);
|
|
298
|
+
else for (const element of importClause.namedBindings.elements) bindings.add(element.name.text);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return bindings;
|
|
302
|
+
}
|
|
303
|
+
function unwrapParenthesizedExpression(node, tsModule) {
|
|
304
|
+
let current = node;
|
|
305
|
+
while (tsModule.isParenthesizedExpression(current)) current = current.expression;
|
|
306
|
+
return current;
|
|
307
|
+
}
|
|
308
|
+
function findReturnedObjectLiteral(node, tsModule) {
|
|
309
|
+
if (tsModule.isObjectLiteralExpression(node)) return node;
|
|
310
|
+
if (!tsModule.isBlock(node)) return;
|
|
311
|
+
for (const statement of node.statements) {
|
|
312
|
+
if (!tsModule.isReturnStatement(statement) || !statement.expression) continue;
|
|
313
|
+
const expression = unwrapParenthesizedExpression(statement.expression, tsModule);
|
|
314
|
+
if (tsModule.isObjectLiteralExpression(expression)) return expression;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function extractDefineOptionsObjectLiteral(node, tsModule) {
|
|
318
|
+
if (!tsModule.isIdentifier(node.expression) || node.expression.text !== "defineOptions") return;
|
|
319
|
+
const [firstArg] = node.arguments;
|
|
320
|
+
if (!firstArg) return;
|
|
321
|
+
const arg = unwrapParenthesizedExpression(firstArg, tsModule);
|
|
322
|
+
if (tsModule.isObjectLiteralExpression(arg)) return arg;
|
|
323
|
+
if (tsModule.isArrowFunction(arg) || tsModule.isFunctionExpression(arg)) return findReturnedObjectLiteral(arg.body, tsModule);
|
|
324
|
+
}
|
|
325
|
+
function collectObjectLiteralKeys(node, tsModule) {
|
|
326
|
+
const keys = [];
|
|
327
|
+
for (const property of node.properties) {
|
|
328
|
+
if (!tsModule.isPropertyAssignment(property) && !tsModule.isMethodDeclaration(property) && !tsModule.isShorthandPropertyAssignment(property) && !tsModule.isGetAccessorDeclaration(property)) continue;
|
|
329
|
+
const key = getPropertyNameText(property.name, tsModule);
|
|
330
|
+
if (key && isIdentifierName(key)) keys.push(key);
|
|
331
|
+
}
|
|
332
|
+
return keys;
|
|
333
|
+
}
|
|
334
|
+
function collectDefineOptionsTemplateBindings(code, tsModule, lang) {
|
|
335
|
+
const scriptKind = lang === "ts" ? 3 : 1;
|
|
336
|
+
const sourceFile = tsModule.createSourceFile(`script-setup.${lang}`, code, 99, true, scriptKind);
|
|
337
|
+
const valueBindings = /* @__PURE__ */ new Set();
|
|
338
|
+
const functionBindings = /* @__PURE__ */ new Set();
|
|
339
|
+
const visit = (node) => {
|
|
340
|
+
if (tsModule.isCallExpression(node)) {
|
|
341
|
+
const optionsObject = extractDefineOptionsObjectLiteral(node, tsModule);
|
|
342
|
+
if (optionsObject) for (const property of optionsObject.properties) {
|
|
343
|
+
const sectionName = tsModule.isPropertyAssignment(property) || tsModule.isMethodDeclaration(property) ? getPropertyNameText(property.name, tsModule) : void 0;
|
|
344
|
+
if (!sectionName) continue;
|
|
345
|
+
if (sectionName === "methods") {
|
|
346
|
+
const methodsObject = tsModule.isPropertyAssignment(property) ? unwrapParenthesizedExpression(property.initializer, tsModule) : void 0;
|
|
347
|
+
if (methodsObject && tsModule.isObjectLiteralExpression(methodsObject)) for (const name of collectObjectLiteralKeys(methodsObject, tsModule)) functionBindings.add(name);
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (sectionName === "properties" || sectionName === "computed") {
|
|
351
|
+
const objectValue = tsModule.isPropertyAssignment(property) ? unwrapParenthesizedExpression(property.initializer, tsModule) : void 0;
|
|
352
|
+
if (objectValue && tsModule.isObjectLiteralExpression(objectValue)) for (const name of collectObjectLiteralKeys(objectValue, tsModule)) valueBindings.add(name);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (sectionName === "data") {
|
|
356
|
+
let dataObject;
|
|
357
|
+
if (tsModule.isMethodDeclaration(property)) dataObject = findReturnedObjectLiteral(property.body ?? tsModule.factory.createBlock([], false), tsModule);
|
|
358
|
+
else if (tsModule.isPropertyAssignment(property)) {
|
|
359
|
+
const initializer = unwrapParenthesizedExpression(property.initializer, tsModule);
|
|
360
|
+
if (tsModule.isArrowFunction(initializer) || tsModule.isFunctionExpression(initializer)) dataObject = findReturnedObjectLiteral(initializer.body, tsModule);
|
|
361
|
+
}
|
|
362
|
+
if (dataObject) for (const name of collectObjectLiteralKeys(dataObject, tsModule)) valueBindings.add(name);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
tsModule.forEachChild(node, visit);
|
|
367
|
+
};
|
|
368
|
+
visit(sourceFile);
|
|
369
|
+
return {
|
|
370
|
+
values: [...valueBindings],
|
|
371
|
+
functions: [...functionBindings]
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function createDefineOptionsTemplateDeclarations(code, tsModule, lang) {
|
|
375
|
+
const topLevelBindings = collectTopLevelBindingNames(code, tsModule, lang);
|
|
376
|
+
const bindings = collectDefineOptionsTemplateBindings(code, tsModule, lang);
|
|
377
|
+
const declarations = [];
|
|
378
|
+
for (const name of bindings.values) {
|
|
379
|
+
if (topLevelBindings.has(name)) continue;
|
|
380
|
+
declarations.push(`const ${name}: any = null as any`);
|
|
381
|
+
}
|
|
382
|
+
for (const name of bindings.functions) {
|
|
383
|
+
if (topLevelBindings.has(name)) continue;
|
|
384
|
+
declarations.push(`const ${name}: (...args: any[]) => any = null as any`);
|
|
385
|
+
}
|
|
386
|
+
return declarations.join("\n");
|
|
387
|
+
}
|
|
388
|
+
function resolveScriptSetupLang(lang) {
|
|
389
|
+
return lang === "js" ? "js" : "ts";
|
|
390
|
+
}
|
|
391
|
+
//#endregion
|
|
392
|
+
//#region src/index.ts
|
|
393
|
+
const require = createRequire(typeof module !== "undefined" && module.filename ? module.filename : path.join(process.cwd(), "weapp-vite-volar.cjs"));
|
|
394
|
+
let hasSchematicsTypes = false;
|
|
395
|
+
try {
|
|
396
|
+
require.resolve("@weapp-core/schematics");
|
|
397
|
+
hasSchematicsTypes = true;
|
|
398
|
+
} catch {
|
|
399
|
+
hasSchematicsTypes = false;
|
|
400
|
+
}
|
|
401
|
+
function parseVueSfc(content, filename = "component.vue") {
|
|
402
|
+
try {
|
|
403
|
+
return require("@vue/compiler-sfc").parse(content, { filename });
|
|
404
|
+
} catch {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
162
407
|
}
|
|
163
408
|
/**
|
|
164
409
|
* Volar 语言插件:为 weapp 配置块提供类型与 schema 提示。
|
|
@@ -180,118 +425,21 @@ const plugin = (ctx) => {
|
|
|
180
425
|
if (!parsed) return;
|
|
181
426
|
const descriptor = parsed.descriptor;
|
|
182
427
|
const wxsModuleNames = collectWxsModuleNames(descriptor.template?.content);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
428
|
+
const scriptSetup = descriptor.scriptSetup;
|
|
429
|
+
const scriptSetupLang = resolveScriptSetupLang(scriptSetup?.lang);
|
|
430
|
+
const defineOptionsDeclarations = scriptSetup?.content && tsModule ? createDefineOptionsTemplateDeclarations(scriptSetup.content, tsModule, scriptSetupLang) : "";
|
|
431
|
+
if (!wxsModuleNames.length && !defineOptionsDeclarations) return parsed;
|
|
432
|
+
if (descriptor.scriptSetup) {
|
|
433
|
+
descriptor.scriptSetup.content = appendScriptSetupDeclarations(appendWxsDeclarations(descriptor.scriptSetup.content, wxsModuleNames), defineOptionsDeclarations);
|
|
434
|
+
syncScriptBlockSource(descriptor.scriptSetup);
|
|
435
|
+
} else descriptor.scriptSetup = createSyntheticScriptSetup(wxsModuleNames);
|
|
186
436
|
return parsed;
|
|
187
437
|
},
|
|
188
438
|
getEmbeddedCodes(_, sfc) {
|
|
189
|
-
|
|
190
|
-
for (let i = 0; i < sfc.customBlocks.length; i++) {
|
|
191
|
-
const block = sfc.customBlocks[i];
|
|
192
|
-
if (block.type === BLOCK_TYPE) {
|
|
193
|
-
const normalizedLang = normalizeLang(block.lang);
|
|
194
|
-
if (normalizedLang === JS_LANG || normalizedLang === TS_LANG) {
|
|
195
|
-
names.push({
|
|
196
|
-
id: `${BLOCK_TYPE}_${i}`,
|
|
197
|
-
lang: TS_LANG
|
|
198
|
-
});
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
const embeddedLang = normalizedLang === JSON_LANG || normalizedLang === JSONC_LANG || normalizedLang === JSON5_LANG ? JSONC_LANG : JSON_LANG;
|
|
202
|
-
names.push({
|
|
203
|
-
id: `${BLOCK_TYPE}_${i}`,
|
|
204
|
-
lang: embeddedLang
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return names;
|
|
439
|
+
return getEmbeddedCodesFromCustomBlocks(sfc);
|
|
209
440
|
},
|
|
210
441
|
resolveEmbeddedCode(fileName, sfc, embeddedCode) {
|
|
211
|
-
|
|
212
|
-
if (!match) return;
|
|
213
|
-
const index = Number.parseInt(match[1]);
|
|
214
|
-
const block = sfc.customBlocks[index];
|
|
215
|
-
if (!block) return;
|
|
216
|
-
const normalizedLang = normalizeLang(block.lang);
|
|
217
|
-
const configType = inferConfigType(fileName);
|
|
218
|
-
if (!hasSchematicsTypes) {
|
|
219
|
-
embeddedCode.content.push([
|
|
220
|
-
block.content,
|
|
221
|
-
block.name,
|
|
222
|
-
0,
|
|
223
|
-
FULL_CAPABILITIES
|
|
224
|
-
]);
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
if (normalizedLang === JS_LANG || normalizedLang === TS_LANG) {
|
|
228
|
-
const parsed = tsModule && findExportDefaultExpression(block.content, tsModule, normalizedLang);
|
|
229
|
-
if (parsed && hasSchematicsTypes) {
|
|
230
|
-
const typeImport = `import type { ${configType} as __WeappConfig } from '@weapp-core/schematics'\n`;
|
|
231
|
-
embeddedCode.content.push([
|
|
232
|
-
`${typeImport}const __weapp_defineConfig = <T extends __WeappConfig>(config: T) => config
|
|
233
|
-
|
|
234
|
-
`,
|
|
235
|
-
void 0,
|
|
236
|
-
0,
|
|
237
|
-
VOID_CAPABILITIES
|
|
238
|
-
]);
|
|
239
|
-
if (parsed.leading) embeddedCode.content.push([
|
|
240
|
-
parsed.leading,
|
|
241
|
-
block.name,
|
|
242
|
-
0,
|
|
243
|
-
FULL_CAPABILITIES
|
|
244
|
-
]);
|
|
245
|
-
embeddedCode.content.push([
|
|
246
|
-
"export default __weapp_defineConfig(",
|
|
247
|
-
void 0,
|
|
248
|
-
parsed.expressionStart,
|
|
249
|
-
VOID_CAPABILITIES
|
|
250
|
-
]);
|
|
251
|
-
embeddedCode.content.push([
|
|
252
|
-
parsed.expression,
|
|
253
|
-
block.name,
|
|
254
|
-
parsed.expressionStart,
|
|
255
|
-
FULL_CAPABILITIES
|
|
256
|
-
]);
|
|
257
|
-
embeddedCode.content.push([
|
|
258
|
-
")",
|
|
259
|
-
void 0,
|
|
260
|
-
parsed.expressionEnd,
|
|
261
|
-
VOID_CAPABILITIES
|
|
262
|
-
]);
|
|
263
|
-
if (parsed.trailing) embeddedCode.content.push([
|
|
264
|
-
parsed.trailing,
|
|
265
|
-
block.name,
|
|
266
|
-
parsed.expressionEnd,
|
|
267
|
-
FULL_CAPABILITIES
|
|
268
|
-
]);
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
embeddedCode.content.push([
|
|
272
|
-
block.content,
|
|
273
|
-
block.name,
|
|
274
|
-
0,
|
|
275
|
-
FULL_CAPABILITIES
|
|
276
|
-
]);
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
const schema = getSchemaForType(configType);
|
|
280
|
-
if (schema && schema.$id && !block.content.includes("$schema")) {
|
|
281
|
-
embeddedCode.content.push([
|
|
282
|
-
injectSchemaIntoJsonObject(block.content, schema.$id),
|
|
283
|
-
block.name,
|
|
284
|
-
0,
|
|
285
|
-
FULL_CAPABILITIES
|
|
286
|
-
]);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
embeddedCode.content.push([
|
|
290
|
-
block.content,
|
|
291
|
-
block.name,
|
|
292
|
-
0,
|
|
293
|
-
FULL_CAPABILITIES
|
|
294
|
-
]);
|
|
442
|
+
resolveEmbeddedJsonBlock(fileName, sfc, embeddedCode, tsModule, hasSchematicsTypes);
|
|
295
443
|
}
|
|
296
444
|
};
|
|
297
445
|
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type ts from 'typescript';
|
|
2
|
+
export declare function normalizeFilename(filename?: string): string;
|
|
3
|
+
export declare function inferConfigType(filename?: string): "App" | "Page" | "Component" | "Plugin" | "Sitemap" | "Theme";
|
|
4
|
+
export declare function normalizeLang(lang?: string): string;
|
|
5
|
+
export declare function getEmbeddedCodesFromCustomBlocks(sfc: {
|
|
6
|
+
customBlocks: ReadonlyArray<{
|
|
7
|
+
type: string;
|
|
8
|
+
lang?: string;
|
|
9
|
+
}>;
|
|
10
|
+
}): {
|
|
11
|
+
id: string;
|
|
12
|
+
lang: string;
|
|
13
|
+
}[];
|
|
14
|
+
export declare function resolveEmbeddedJsonBlock(fileName: string, sfc: {
|
|
15
|
+
customBlocks: ReadonlyArray<{
|
|
16
|
+
type: string;
|
|
17
|
+
lang?: string;
|
|
18
|
+
content: string;
|
|
19
|
+
name?: string;
|
|
20
|
+
}>;
|
|
21
|
+
}, embeddedCode: {
|
|
22
|
+
id: string;
|
|
23
|
+
content: any[];
|
|
24
|
+
}, tsModule: typeof ts | undefined, hasSchematicsTypes: boolean): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type ts from 'typescript';
|
|
2
|
+
export declare function collectWxsModuleNames(templateContent?: string): string[];
|
|
3
|
+
export declare function createWxsModuleDeclarations(moduleNames: string[]): string;
|
|
4
|
+
export declare function appendWxsDeclarations(code: string, moduleNames: string[]): string;
|
|
5
|
+
export declare function appendScriptSetupDeclarations(code: string, declarations: string): string;
|
|
6
|
+
export declare function createSyntheticScriptSetup(moduleNames: string[]): {
|
|
7
|
+
type: string;
|
|
8
|
+
content: string;
|
|
9
|
+
loc: {
|
|
10
|
+
source: string;
|
|
11
|
+
start: {
|
|
12
|
+
column: number;
|
|
13
|
+
line: number;
|
|
14
|
+
offset: number;
|
|
15
|
+
};
|
|
16
|
+
end: {
|
|
17
|
+
column: number;
|
|
18
|
+
line: number;
|
|
19
|
+
offset: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
attrs: {
|
|
23
|
+
setup: boolean;
|
|
24
|
+
lang: string;
|
|
25
|
+
};
|
|
26
|
+
lang: string;
|
|
27
|
+
setup: boolean;
|
|
28
|
+
name: string;
|
|
29
|
+
} | undefined;
|
|
30
|
+
export declare function syncScriptBlockSource(block: {
|
|
31
|
+
content: string;
|
|
32
|
+
attrs?: Record<string, string | true>;
|
|
33
|
+
loc: {
|
|
34
|
+
source: string;
|
|
35
|
+
};
|
|
36
|
+
} | null | undefined): void;
|
|
37
|
+
export declare function createDefineOptionsTemplateDeclarations(code: string, tsModule: typeof ts, lang: string): string;
|
|
38
|
+
export declare function resolveScriptSetupLang(lang?: string): "js" | "ts";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weapp-vite/volar",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.8",
|
|
4
4
|
"description": "Volar plugin for weapp-vite - Provides IntelliSense and type checking for WeChat mini-program config blocks",
|
|
5
5
|
"author": "ice breaker <1324318532@qq.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"node": "^20.19.0 || >=22.12.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@weapp-core/schematics": "6.0.
|
|
43
|
+
"@weapp-core/schematics": "6.0.4"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"dev": "tsdown -w --sourcemap",
|