@weapp-vite/volar 2.0.4 → 2.0.6
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/index.cjs +296 -273
- package/dist/index.d.ts +2 -4
- package/dist/index.mjs +280 -250
- package/dist/schema.d.ts +26 -0
- package/package.json +7 -6
- package/dist/index.d.mts +0 -8
package/dist/index.cjs
CHANGED
|
@@ -1,300 +1,323 @@
|
|
|
1
|
-
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name2 in all)
|
|
10
|
-
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
11
|
-
};
|
|
12
8
|
var __copyProps = (to, from, except, desc) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
+
key = keys[i];
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
+
get: ((k) => from[k]).bind(null, key),
|
|
13
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
__export(index_exports, {
|
|
33
|
-
default: () => index_default
|
|
34
|
-
});
|
|
35
|
-
module.exports = __toCommonJS(index_exports);
|
|
36
|
-
var import_node_module = require("module");
|
|
37
|
-
var import_node_path = __toESM(require("path"));
|
|
38
|
-
var import_node_process = __toESM(require("process"));
|
|
39
|
-
|
|
40
|
-
// package.json
|
|
18
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
+
value: mod,
|
|
20
|
+
enumerable: true
|
|
21
|
+
}) : target, mod));
|
|
22
|
+
//#endregion
|
|
23
|
+
let node_module = require("node:module");
|
|
24
|
+
let node_path = require("node:path");
|
|
25
|
+
node_path = __toESM(node_path);
|
|
26
|
+
let node_process = require("node:process");
|
|
27
|
+
node_process = __toESM(node_process);
|
|
28
|
+
let _weapp_core_schematics = require("@weapp-core/schematics");
|
|
29
|
+
//#region package.json
|
|
41
30
|
var name = "@weapp-vite/volar";
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/schema.ts
|
|
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
|
+
*/
|
|
45
44
|
function getSchemaForType(type) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
return definition.schema;
|
|
45
|
+
const definition = _weapp_core_schematics.JSON_SCHEMA_DEFINITIONS.find((d) => d.typeName === type);
|
|
46
|
+
if (!definition) return null;
|
|
47
|
+
return definition.schema;
|
|
51
48
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/index.ts
|
|
51
|
+
const BLOCK_TYPE = "json";
|
|
52
|
+
const JS_LANG = "js";
|
|
53
|
+
const JSONC_LANG = "jsonc";
|
|
54
|
+
const JSON_LANG = "json";
|
|
55
|
+
const JSON5_LANG = "json5";
|
|
56
|
+
const PLUGIN_VERSION = 2.2;
|
|
57
|
+
const TS_LANG = "ts";
|
|
58
|
+
const BACKSLASH_RE = /\\/g;
|
|
59
|
+
const NON_SPACE_RE = /\S/;
|
|
60
|
+
const WXS_MODULE_RE = /<wxs[\s\S]*?module\s*=\s*(?:"([^"]+)"|'([^']+)')[\s\S]*?\/?>/gi;
|
|
61
|
+
const FULL_CAPABILITIES = {
|
|
62
|
+
verification: true,
|
|
63
|
+
completion: true,
|
|
64
|
+
semantic: true,
|
|
65
|
+
navigation: true,
|
|
66
|
+
structure: true,
|
|
67
|
+
format: true
|
|
68
68
|
};
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
69
|
+
const VOID_CAPABILITIES = {
|
|
70
|
+
verification: false,
|
|
71
|
+
completion: false,
|
|
72
|
+
semantic: false,
|
|
73
|
+
navigation: false,
|
|
74
|
+
structure: false,
|
|
75
|
+
format: false
|
|
76
76
|
};
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
);
|
|
80
|
-
var hasSchematicsTypes = false;
|
|
77
|
+
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"));
|
|
78
|
+
let hasSchematicsTypes = false;
|
|
81
79
|
try {
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
require$1.resolve("@weapp-core/schematics");
|
|
81
|
+
hasSchematicsTypes = true;
|
|
84
82
|
} catch {
|
|
85
|
-
|
|
83
|
+
hasSchematicsTypes = false;
|
|
84
|
+
}
|
|
85
|
+
function parseVueSfc(content, filename = "component.vue") {
|
|
86
|
+
try {
|
|
87
|
+
return require$1("@vue/compiler-sfc").parse(content, { filename });
|
|
88
|
+
} catch {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function collectWxsModuleNames(templateContent) {
|
|
93
|
+
if (!templateContent) return [];
|
|
94
|
+
const names = /* @__PURE__ */ new Set();
|
|
95
|
+
for (const match of templateContent.matchAll(WXS_MODULE_RE)) {
|
|
96
|
+
const name = match[1] ?? match[2];
|
|
97
|
+
if (name) names.add(name);
|
|
98
|
+
}
|
|
99
|
+
return [...names];
|
|
100
|
+
}
|
|
101
|
+
function createWxsModuleDeclarations(moduleNames) {
|
|
102
|
+
if (!moduleNames.length) return "";
|
|
103
|
+
return moduleNames.map((name) => `const ${name} = {} as Record<string, (...args: any[]) => any>`).join("\n");
|
|
104
|
+
}
|
|
105
|
+
function appendWxsDeclarations(code, moduleNames) {
|
|
106
|
+
const declarations = createWxsModuleDeclarations(moduleNames);
|
|
107
|
+
if (!declarations) return code;
|
|
108
|
+
return code ? `${code}\n\n${declarations}\n` : `${declarations}\n`;
|
|
109
|
+
}
|
|
110
|
+
function createSyntheticScriptSetup(moduleNames) {
|
|
111
|
+
const content = createWxsModuleDeclarations(moduleNames);
|
|
112
|
+
if (!content) return;
|
|
113
|
+
return {
|
|
114
|
+
type: "script",
|
|
115
|
+
content,
|
|
116
|
+
loc: {
|
|
117
|
+
source: `<script setup lang="ts">\n${content}\n<\/script>`,
|
|
118
|
+
start: {
|
|
119
|
+
column: 1,
|
|
120
|
+
line: 1,
|
|
121
|
+
offset: 0
|
|
122
|
+
},
|
|
123
|
+
end: {
|
|
124
|
+
column: 1,
|
|
125
|
+
line: 1,
|
|
126
|
+
offset: 0
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
attrs: {
|
|
130
|
+
setup: true,
|
|
131
|
+
lang: "ts"
|
|
132
|
+
},
|
|
133
|
+
lang: "ts",
|
|
134
|
+
setup: true,
|
|
135
|
+
name: "scriptSetup"
|
|
136
|
+
};
|
|
86
137
|
}
|
|
87
138
|
function normalizeFilename(filename) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
return filename.replace(/\\/g, "/");
|
|
139
|
+
if (!filename) return "";
|
|
140
|
+
return filename.replace(BACKSLASH_RE, "/");
|
|
92
141
|
}
|
|
93
142
|
function inferConfigType(filename) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (normalized.includes("/components/")) {
|
|
102
|
-
return "Component";
|
|
103
|
-
}
|
|
104
|
-
if (normalized.includes("/theme/")) {
|
|
105
|
-
return "Theme";
|
|
106
|
-
}
|
|
107
|
-
if (normalized.includes("/sitemap")) {
|
|
108
|
-
return "Sitemap";
|
|
109
|
-
}
|
|
110
|
-
return "Page";
|
|
143
|
+
const normalized = normalizeFilename(filename);
|
|
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";
|
|
111
150
|
}
|
|
112
151
|
function normalizeLang(lang) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (lower === "txt") {
|
|
118
|
-
return JSON_LANG;
|
|
119
|
-
}
|
|
120
|
-
return lower;
|
|
152
|
+
if (!lang) return JSON_LANG;
|
|
153
|
+
const lower = lang.toLowerCase();
|
|
154
|
+
if (lower === "txt") return JSON_LANG;
|
|
155
|
+
return lower;
|
|
121
156
|
}
|
|
122
157
|
function findExportDefaultExpression(code, tsModule, lang) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
expression,
|
|
140
|
-
expressionStart,
|
|
141
|
-
expressionEnd,
|
|
142
|
-
leading,
|
|
143
|
-
trailing
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return null;
|
|
158
|
+
const scriptKind = lang === TS_LANG ? tsModule.ScriptKind.TS : tsModule.ScriptKind.JS;
|
|
159
|
+
const sourceFile = tsModule.createSourceFile(`config.${lang}`, code, tsModule.ScriptTarget.Latest, true, scriptKind);
|
|
160
|
+
for (const statement of sourceFile.statements) if (tsModule.isExportAssignment(statement)) {
|
|
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
|
+
};
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
148
173
|
}
|
|
149
174
|
function injectSchemaIntoJsonObject(content, schemaId) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const isEmptyObject = nextCharIndex >= 0 && content[nextCharIndex] === "}";
|
|
162
|
-
const schemaLine = ` "$schema": "${schemaId}"`;
|
|
163
|
-
const injected = isEmptyObject ? `{
|
|
164
|
-
${schemaLine}
|
|
165
|
-
}` : `{
|
|
166
|
-
${schemaLine},${content.slice(leftBraceIndex + 1)}`;
|
|
167
|
-
if (trimmed === content) {
|
|
168
|
-
return injected;
|
|
169
|
-
}
|
|
170
|
-
const leading = content.slice(0, content.indexOf(trimmed));
|
|
171
|
-
const trailing = content.slice(content.indexOf(trimmed) + trimmed.length);
|
|
172
|
-
return `${leading}${injected}${trailing}`;
|
|
175
|
+
const trimmed = content.trim();
|
|
176
|
+
if (!trimmed.startsWith("{")) return content;
|
|
177
|
+
const leftBraceIndex = content.indexOf("{");
|
|
178
|
+
if (leftBraceIndex < 0) return content;
|
|
179
|
+
const firstNonSpace = content.slice(leftBraceIndex + 1).match(NON_SPACE_RE);
|
|
180
|
+
const nextCharIndex = firstNonSpace ? leftBraceIndex + 1 + firstNonSpace.index : -1;
|
|
181
|
+
const isEmptyObject = nextCharIndex >= 0 && content[nextCharIndex] === "}";
|
|
182
|
+
const schemaLine = ` "$schema": "${schemaId}"`;
|
|
183
|
+
const injected = isEmptyObject ? `{\n${schemaLine}\n}` : `{\n${schemaLine},${content.slice(leftBraceIndex + 1)}`;
|
|
184
|
+
if (trimmed === content) return injected;
|
|
185
|
+
return `${content.slice(0, content.indexOf(trimmed))}${injected}${content.slice(content.indexOf(trimmed) + trimmed.length)}`;
|
|
173
186
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Volar 语言插件:为 weapp 配置块提供类型与 schema 提示。
|
|
189
|
+
*/
|
|
190
|
+
const plugin = (ctx) => {
|
|
191
|
+
let tsModule = ctx?.modules?.typescript;
|
|
192
|
+
if (!tsModule) try {
|
|
193
|
+
tsModule = require$1("typescript");
|
|
194
|
+
} catch {
|
|
195
|
+
tsModule = void 0;
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
name,
|
|
199
|
+
version: PLUGIN_VERSION,
|
|
200
|
+
order: -1,
|
|
201
|
+
parseSFC2(fileName, languageId, content) {
|
|
202
|
+
if (languageId !== "vue") return;
|
|
203
|
+
const parsed = parseVueSfc(content, fileName);
|
|
204
|
+
if (!parsed) return;
|
|
205
|
+
const descriptor = parsed.descriptor;
|
|
206
|
+
const wxsModuleNames = collectWxsModuleNames(descriptor.template?.content);
|
|
207
|
+
if (!wxsModuleNames.length) return parsed;
|
|
208
|
+
if (descriptor.scriptSetup) descriptor.scriptSetup.content = appendWxsDeclarations(descriptor.scriptSetup.content, wxsModuleNames);
|
|
209
|
+
else descriptor.scriptSetup = createSyntheticScriptSetup(wxsModuleNames);
|
|
210
|
+
return parsed;
|
|
211
|
+
},
|
|
212
|
+
getEmbeddedCodes(_, sfc) {
|
|
213
|
+
const names = [];
|
|
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;
|
|
233
|
+
},
|
|
234
|
+
resolveEmbeddedCode(fileName, sfc, embeddedCode) {
|
|
235
|
+
const match = embeddedCode.id.match(new RegExp(`^${BLOCK_TYPE}_(\\d+)$`));
|
|
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
|
+
]);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
299
321
|
};
|
|
300
|
-
|
|
322
|
+
//#endregion
|
|
323
|
+
module.exports = plugin;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import { VueLanguagePlugin } from '@vue/language-core';
|
|
2
|
-
|
|
1
|
+
import type { VueLanguagePlugin } from '@vue/language-core';
|
|
3
2
|
/**
|
|
4
3
|
* Volar 语言插件:为 weapp 配置块提供类型与 schema 提示。
|
|
5
4
|
*/
|
|
6
5
|
declare const plugin: VueLanguagePlugin;
|
|
7
|
-
|
|
8
|
-
export = plugin;
|
|
6
|
+
export default plugin;
|
package/dist/index.mjs
CHANGED
|
@@ -1,269 +1,299 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import process from "process";
|
|
5
|
-
|
|
6
|
-
// package.json
|
|
7
|
-
var name = "@weapp-vite/volar";
|
|
8
|
-
|
|
9
|
-
// src/schema.ts
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
10
4
|
import { JSON_SCHEMA_DEFINITIONS } from "@weapp-core/schematics";
|
|
5
|
+
//#region package.json
|
|
6
|
+
var name = "@weapp-vite/volar";
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/schema.ts
|
|
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
|
+
*/
|
|
11
20
|
function getSchemaForType(type) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
return definition.schema;
|
|
21
|
+
const definition = JSON_SCHEMA_DEFINITIONS.find((d) => d.typeName === type);
|
|
22
|
+
if (!definition) return null;
|
|
23
|
+
return definition.schema;
|
|
17
24
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/index.ts
|
|
27
|
+
const BLOCK_TYPE = "json";
|
|
28
|
+
const JS_LANG = "js";
|
|
29
|
+
const JSONC_LANG = "jsonc";
|
|
30
|
+
const JSON_LANG = "json";
|
|
31
|
+
const JSON5_LANG = "json5";
|
|
32
|
+
const PLUGIN_VERSION = 2.2;
|
|
33
|
+
const TS_LANG = "ts";
|
|
34
|
+
const BACKSLASH_RE = /\\/g;
|
|
35
|
+
const NON_SPACE_RE = /\S/;
|
|
36
|
+
const WXS_MODULE_RE = /<wxs[\s\S]*?module\s*=\s*(?:"([^"]+)"|'([^']+)')[\s\S]*?\/?>/gi;
|
|
37
|
+
const FULL_CAPABILITIES = {
|
|
38
|
+
verification: true,
|
|
39
|
+
completion: true,
|
|
40
|
+
semantic: true,
|
|
41
|
+
navigation: true,
|
|
42
|
+
structure: true,
|
|
43
|
+
format: true
|
|
34
44
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
const VOID_CAPABILITIES = {
|
|
46
|
+
verification: false,
|
|
47
|
+
completion: false,
|
|
48
|
+
semantic: false,
|
|
49
|
+
navigation: false,
|
|
50
|
+
structure: false,
|
|
51
|
+
format: false
|
|
42
52
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
);
|
|
46
|
-
var hasSchematicsTypes = false;
|
|
53
|
+
const require = createRequire(typeof module !== "undefined" && module.filename ? module.filename : path.join(process.cwd(), "weapp-vite-volar.cjs"));
|
|
54
|
+
let hasSchematicsTypes = false;
|
|
47
55
|
try {
|
|
48
|
-
|
|
49
|
-
|
|
56
|
+
require.resolve("@weapp-core/schematics");
|
|
57
|
+
hasSchematicsTypes = true;
|
|
50
58
|
} catch {
|
|
51
|
-
|
|
59
|
+
hasSchematicsTypes = false;
|
|
60
|
+
}
|
|
61
|
+
function parseVueSfc(content, filename = "component.vue") {
|
|
62
|
+
try {
|
|
63
|
+
return require("@vue/compiler-sfc").parse(content, { filename });
|
|
64
|
+
} catch {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function collectWxsModuleNames(templateContent) {
|
|
69
|
+
if (!templateContent) return [];
|
|
70
|
+
const names = /* @__PURE__ */ new Set();
|
|
71
|
+
for (const match of templateContent.matchAll(WXS_MODULE_RE)) {
|
|
72
|
+
const name = match[1] ?? match[2];
|
|
73
|
+
if (name) names.add(name);
|
|
74
|
+
}
|
|
75
|
+
return [...names];
|
|
76
|
+
}
|
|
77
|
+
function createWxsModuleDeclarations(moduleNames) {
|
|
78
|
+
if (!moduleNames.length) return "";
|
|
79
|
+
return moduleNames.map((name) => `const ${name} = {} as Record<string, (...args: any[]) => any>`).join("\n");
|
|
80
|
+
}
|
|
81
|
+
function appendWxsDeclarations(code, moduleNames) {
|
|
82
|
+
const declarations = createWxsModuleDeclarations(moduleNames);
|
|
83
|
+
if (!declarations) return code;
|
|
84
|
+
return code ? `${code}\n\n${declarations}\n` : `${declarations}\n`;
|
|
85
|
+
}
|
|
86
|
+
function createSyntheticScriptSetup(moduleNames) {
|
|
87
|
+
const content = createWxsModuleDeclarations(moduleNames);
|
|
88
|
+
if (!content) return;
|
|
89
|
+
return {
|
|
90
|
+
type: "script",
|
|
91
|
+
content,
|
|
92
|
+
loc: {
|
|
93
|
+
source: `<script setup lang="ts">\n${content}\n<\/script>`,
|
|
94
|
+
start: {
|
|
95
|
+
column: 1,
|
|
96
|
+
line: 1,
|
|
97
|
+
offset: 0
|
|
98
|
+
},
|
|
99
|
+
end: {
|
|
100
|
+
column: 1,
|
|
101
|
+
line: 1,
|
|
102
|
+
offset: 0
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
attrs: {
|
|
106
|
+
setup: true,
|
|
107
|
+
lang: "ts"
|
|
108
|
+
},
|
|
109
|
+
lang: "ts",
|
|
110
|
+
setup: true,
|
|
111
|
+
name: "scriptSetup"
|
|
112
|
+
};
|
|
52
113
|
}
|
|
53
114
|
function normalizeFilename(filename) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
return filename.replace(/\\/g, "/");
|
|
115
|
+
if (!filename) return "";
|
|
116
|
+
return filename.replace(BACKSLASH_RE, "/");
|
|
58
117
|
}
|
|
59
118
|
function inferConfigType(filename) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (normalized.includes("/components/")) {
|
|
68
|
-
return "Component";
|
|
69
|
-
}
|
|
70
|
-
if (normalized.includes("/theme/")) {
|
|
71
|
-
return "Theme";
|
|
72
|
-
}
|
|
73
|
-
if (normalized.includes("/sitemap")) {
|
|
74
|
-
return "Sitemap";
|
|
75
|
-
}
|
|
76
|
-
return "Page";
|
|
119
|
+
const normalized = normalizeFilename(filename);
|
|
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";
|
|
77
126
|
}
|
|
78
127
|
function normalizeLang(lang) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (lower === "txt") {
|
|
84
|
-
return JSON_LANG;
|
|
85
|
-
}
|
|
86
|
-
return lower;
|
|
128
|
+
if (!lang) return JSON_LANG;
|
|
129
|
+
const lower = lang.toLowerCase();
|
|
130
|
+
if (lower === "txt") return JSON_LANG;
|
|
131
|
+
return lower;
|
|
87
132
|
}
|
|
88
133
|
function findExportDefaultExpression(code, tsModule, lang) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
expression,
|
|
106
|
-
expressionStart,
|
|
107
|
-
expressionEnd,
|
|
108
|
-
leading,
|
|
109
|
-
trailing
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return null;
|
|
134
|
+
const scriptKind = lang === TS_LANG ? tsModule.ScriptKind.TS : tsModule.ScriptKind.JS;
|
|
135
|
+
const sourceFile = tsModule.createSourceFile(`config.${lang}`, code, tsModule.ScriptTarget.Latest, true, scriptKind);
|
|
136
|
+
for (const statement of sourceFile.statements) if (tsModule.isExportAssignment(statement)) {
|
|
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
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return null;
|
|
114
149
|
}
|
|
115
150
|
function injectSchemaIntoJsonObject(content, schemaId) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const isEmptyObject = nextCharIndex >= 0 && content[nextCharIndex] === "}";
|
|
128
|
-
const schemaLine = ` "$schema": "${schemaId}"`;
|
|
129
|
-
const injected = isEmptyObject ? `{
|
|
130
|
-
${schemaLine}
|
|
131
|
-
}` : `{
|
|
132
|
-
${schemaLine},${content.slice(leftBraceIndex + 1)}`;
|
|
133
|
-
if (trimmed === content) {
|
|
134
|
-
return injected;
|
|
135
|
-
}
|
|
136
|
-
const leading = content.slice(0, content.indexOf(trimmed));
|
|
137
|
-
const trailing = content.slice(content.indexOf(trimmed) + trimmed.length);
|
|
138
|
-
return `${leading}${injected}${trailing}`;
|
|
151
|
+
const trimmed = content.trim();
|
|
152
|
+
if (!trimmed.startsWith("{")) return content;
|
|
153
|
+
const leftBraceIndex = content.indexOf("{");
|
|
154
|
+
if (leftBraceIndex < 0) return content;
|
|
155
|
+
const firstNonSpace = content.slice(leftBraceIndex + 1).match(NON_SPACE_RE);
|
|
156
|
+
const nextCharIndex = firstNonSpace ? leftBraceIndex + 1 + firstNonSpace.index : -1;
|
|
157
|
+
const isEmptyObject = nextCharIndex >= 0 && content[nextCharIndex] === "}";
|
|
158
|
+
const schemaLine = ` "$schema": "${schemaId}"`;
|
|
159
|
+
const injected = isEmptyObject ? `{\n${schemaLine}\n}` : `{\n${schemaLine},${content.slice(leftBraceIndex + 1)}`;
|
|
160
|
+
if (trimmed === content) return injected;
|
|
161
|
+
return `${content.slice(0, content.indexOf(trimmed))}${injected}${content.slice(content.indexOf(trimmed) + trimmed.length)}`;
|
|
139
162
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Volar 语言插件:为 weapp 配置块提供类型与 schema 提示。
|
|
165
|
+
*/
|
|
166
|
+
const plugin = (ctx) => {
|
|
167
|
+
let tsModule = ctx?.modules?.typescript;
|
|
168
|
+
if (!tsModule) try {
|
|
169
|
+
tsModule = require("typescript");
|
|
170
|
+
} catch {
|
|
171
|
+
tsModule = void 0;
|
|
172
|
+
}
|
|
173
|
+
return {
|
|
174
|
+
name,
|
|
175
|
+
version: PLUGIN_VERSION,
|
|
176
|
+
order: -1,
|
|
177
|
+
parseSFC2(fileName, languageId, content) {
|
|
178
|
+
if (languageId !== "vue") return;
|
|
179
|
+
const parsed = parseVueSfc(content, fileName);
|
|
180
|
+
if (!parsed) return;
|
|
181
|
+
const descriptor = parsed.descriptor;
|
|
182
|
+
const wxsModuleNames = collectWxsModuleNames(descriptor.template?.content);
|
|
183
|
+
if (!wxsModuleNames.length) return parsed;
|
|
184
|
+
if (descriptor.scriptSetup) descriptor.scriptSetup.content = appendWxsDeclarations(descriptor.scriptSetup.content, wxsModuleNames);
|
|
185
|
+
else descriptor.scriptSetup = createSyntheticScriptSetup(wxsModuleNames);
|
|
186
|
+
return parsed;
|
|
187
|
+
},
|
|
188
|
+
getEmbeddedCodes(_, sfc) {
|
|
189
|
+
const names = [];
|
|
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;
|
|
209
|
+
},
|
|
210
|
+
resolveEmbeddedCode(fileName, sfc, embeddedCode) {
|
|
211
|
+
const match = embeddedCode.id.match(new RegExp(`^${BLOCK_TYPE}_(\\d+)$`));
|
|
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
|
+
]);
|
|
295
|
+
}
|
|
296
|
+
};
|
|
269
297
|
};
|
|
298
|
+
//#endregion
|
|
299
|
+
export { plugin as default };
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface JsonSchema {
|
|
2
|
+
$schema?: string;
|
|
3
|
+
$id?: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
type: string;
|
|
7
|
+
properties?: Record<string, any>;
|
|
8
|
+
required?: string[];
|
|
9
|
+
additionalProperties?: boolean | any;
|
|
10
|
+
items?: any;
|
|
11
|
+
definitions?: Record<string, any>;
|
|
12
|
+
enum?: string[];
|
|
13
|
+
minimum?: number;
|
|
14
|
+
maximum?: number;
|
|
15
|
+
minItems?: number;
|
|
16
|
+
maxItems?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 根据文件类型获取对应的 JSON Schema
|
|
20
|
+
* Schema 定义来自 @weapp-core/schematics,使用 Zod 维护单一数据源
|
|
21
|
+
*/
|
|
22
|
+
export declare function getSchemaForType(type: 'App' | 'Page' | 'Component' | 'Plugin' | 'Sitemap' | 'Theme'): JsonSchema | null;
|
|
23
|
+
/**
|
|
24
|
+
* 为配置块生成 schema 注释
|
|
25
|
+
*/
|
|
26
|
+
export declare function generateSchemaComment(type: 'App' | 'Page' | 'Component' | 'Plugin' | 'Sitemap' | 'Theme'): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weapp-vite/volar",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
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",
|
|
@@ -25,14 +25,14 @@
|
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"exports": {
|
|
27
27
|
".": {
|
|
28
|
-
"types": "./dist/index.d.
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
29
|
"import": "./dist/index.mjs",
|
|
30
30
|
"require": "./dist/index.cjs"
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
33
|
"main": "./dist/index.cjs",
|
|
34
34
|
"module": "./dist/index.mjs",
|
|
35
|
-
"types": "./dist/index.d.
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
36
|
"files": [
|
|
37
37
|
"dist"
|
|
38
38
|
],
|
|
@@ -40,13 +40,14 @@
|
|
|
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.3"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
|
-
"dev": "
|
|
47
|
-
"build": "
|
|
46
|
+
"dev": "tsdown -w --sourcemap",
|
|
47
|
+
"build": "tsdown --no-dts && tsc -p tsconfig.build.json",
|
|
48
48
|
"test": "vitest run",
|
|
49
49
|
"test:dev": "vitest",
|
|
50
|
+
"typecheck": "tsc --noEmit",
|
|
50
51
|
"release": "pnpm publish",
|
|
51
52
|
"lint": "eslint .",
|
|
52
53
|
"lint:fix": "eslint . --fix"
|