@weapp-tailwindcss/env 0.1.0 → 0.2.1
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/README.md +30 -6
- package/README.zh-CN.md +30 -6
- package/dist/index.cjs +488 -101
- package/dist/index.d.cts +35 -15
- package/dist/index.d.ts +35 -15
- package/dist/index.js +484 -100
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
|
|
2
|
+
// \0rolldown/runtime.js
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -20,13 +20,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
20
20
|
value: mod,
|
|
21
21
|
enumerable: true
|
|
22
22
|
}) : target, mod));
|
|
23
|
-
//#endregion
|
|
24
23
|
let node_process = require("node:process");
|
|
25
24
|
node_process = __toESM(node_process, 1);
|
|
26
25
|
let node_path = require("node:path");
|
|
27
26
|
node_path = __toESM(node_path, 1);
|
|
28
27
|
let node_fs = require("node:fs");
|
|
29
|
-
|
|
28
|
+
// src/environment.ts
|
|
30
29
|
function getProcessEnv() {
|
|
31
30
|
return {
|
|
32
31
|
MPX_CLI_MODE: node_process.default.env["MPX_CLI_MODE"],
|
|
@@ -39,8 +38,7 @@ function getProcessEnv() {
|
|
|
39
38
|
WEAPP_TW_TARGET: node_process.default.env["WEAPP_TW_TARGET"]
|
|
40
39
|
};
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
//#region src/hbuilderx.ts
|
|
41
|
+
// src/hbuilderx.ts
|
|
44
42
|
const KNOWN_MAC_HBUILDERX_PLUGIN_DIRS = ["/Applications/HBuilderX.app/Contents/HBuilderX/plugins/uniapp-cli-vite", "/Applications/HBuilderX.app/Contents/HBuilderX/plugins/uniapp-cli"];
|
|
45
43
|
const HBUILDERX_PLUGIN_CWD_RE = /[\\/]HBuilderX(?:\.[^\\/]*)?(?:[\\/]Contents[\\/]HBuilderX)?[\\/]plugins[\\/]uniapp-cli(?:-vite)?(?:[\\/]|$)/i;
|
|
46
44
|
function hasKnownHBuilderXPluginPrefix(normalizedCwd) {
|
|
@@ -61,23 +59,74 @@ function isRunningInHBuilderX(options = {}) {
|
|
|
61
59
|
if (!(nodePath == null || nodePath.trim().length === 0)) return false;
|
|
62
60
|
return matchesHBuilderXPluginCwd(options.cwd ?? node_process.default.cwd());
|
|
63
61
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
62
|
+
// src/matching.ts
|
|
63
|
+
function evidence(source, key, value, file) {
|
|
64
|
+
return {
|
|
65
|
+
source,
|
|
66
|
+
key,
|
|
67
|
+
...value !== void 0 ? { value } : {},
|
|
68
|
+
...file !== void 0 ? { path: file } : {}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function collectMatches(matches, all) {
|
|
72
|
+
const result = [];
|
|
73
|
+
for (const candidate of matches) {
|
|
74
|
+
result.push(candidate);
|
|
75
|
+
if (!all) break;
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
function detectionReport(candidates) {
|
|
80
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
81
|
+
for (const candidate of candidates) {
|
|
82
|
+
const existing = grouped.get(candidate.appType);
|
|
83
|
+
if (existing) existing.evidence.push(...candidate.evidence);
|
|
84
|
+
else grouped.set(candidate.appType, {
|
|
85
|
+
...candidate,
|
|
86
|
+
evidence: [...candidate.evidence]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
const unique = [...grouped.values()];
|
|
90
|
+
const appType = unique[0]?.appType;
|
|
91
|
+
const family = (value) => value.startsWith("uni-app") ? "uni-app" : value;
|
|
92
|
+
return {
|
|
93
|
+
appType,
|
|
94
|
+
candidates: unique,
|
|
95
|
+
conflicts: appType === void 0 ? [] : unique.filter((candidate) => family(candidate.appType) !== family(appType)).map((candidate) => candidate.appType)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// src/platform.ts
|
|
99
|
+
const MPX_TO_UNI_PLATFORM = /* @__PURE__ */ new Map([
|
|
100
|
+
["ali", "mp-alipay"],
|
|
101
|
+
["dd", "mp-dingtalk"],
|
|
102
|
+
["jd", "mp-jd"],
|
|
103
|
+
["qq", "mp-qq"],
|
|
104
|
+
["swan", "mp-baidu"],
|
|
105
|
+
["tt", "mp-toutiao"],
|
|
106
|
+
["wx", "mp-weixin"]
|
|
107
|
+
]);
|
|
108
|
+
const TARO_TO_CANONICAL_PLATFORM = /* @__PURE__ */ new Map([["harmony-hybrid", "web"]]);
|
|
109
|
+
const MINI_PROGRAM_PLATFORMS = new Map([
|
|
110
|
+
...[...MPX_TO_UNI_PLATFORM].filter(([alias]) => alias !== "ali" && alias !== "dd"),
|
|
111
|
+
["alipay", "mp-alipay"],
|
|
112
|
+
["baidu", "mp-baidu"],
|
|
113
|
+
["weapp", "mp-weixin"],
|
|
114
|
+
["wechat", "mp-weixin"]
|
|
115
|
+
]);
|
|
116
|
+
const CANONICAL_PLATFORMS = new Map([
|
|
117
|
+
...[...MPX_TO_UNI_PLATFORM.values()].map((value) => [value, value]),
|
|
118
|
+
["web", "web"],
|
|
119
|
+
["h5", "web"],
|
|
120
|
+
["app", "app"],
|
|
121
|
+
["app-plus", "app-plus"],
|
|
122
|
+
["app-android", "app-android"],
|
|
123
|
+
["app-ios", "app-ios"],
|
|
124
|
+
["app-harmony", "app-harmony"]
|
|
76
125
|
]);
|
|
77
126
|
function normalizePlatform(value) {
|
|
78
127
|
return value?.trim().toLowerCase() || void 0;
|
|
79
128
|
}
|
|
80
|
-
function resolvePlatformInfo(value) {
|
|
129
|
+
function resolvePlatformInfo(value, appType) {
|
|
81
130
|
const normalized = normalizePlatform(value);
|
|
82
131
|
const isAppAndroid = normalized === "app-android";
|
|
83
132
|
const isAppIos = normalized === "app-ios";
|
|
@@ -89,21 +138,29 @@ function resolvePlatformInfo(value) {
|
|
|
89
138
|
isAppAndroid,
|
|
90
139
|
isAppHarmony,
|
|
91
140
|
isAppIos,
|
|
92
|
-
isMp: normalized?.startsWith("mp-") === true || (normalized ? MINI_PROGRAM_PLATFORMS.has(normalized) : false),
|
|
93
|
-
isWeb: normalized?.startsWith("web") === true || normalized === "h5"
|
|
141
|
+
isMp: normalized?.startsWith("mp-") === true || (normalized ? MINI_PROGRAM_PLATFORMS.has(normalized) || appType === "mpx" && MPX_TO_UNI_PLATFORM.has(normalized) : false),
|
|
142
|
+
isWeb: normalized?.startsWith("web") === true || normalized === "h5" || appType === "taro" && normalized !== void 0 && TARO_TO_CANONICAL_PLATFORM.get(normalized) === "web"
|
|
94
143
|
};
|
|
95
144
|
}
|
|
96
145
|
function resolvePlatform(value) {
|
|
97
146
|
return resolvePlatformInfo(value);
|
|
98
147
|
}
|
|
99
148
|
function resolveTaroPlatform(value = getProcessEnv().TARO_ENV) {
|
|
100
|
-
return
|
|
149
|
+
return resolvePlatformInfo(value, "taro");
|
|
150
|
+
}
|
|
151
|
+
/** 读取 Taro 环境快照;省略快照时才使用调用时的进程环境。 */
|
|
152
|
+
function resolveTaroPlatformFromEnv(env = getProcessEnv()) {
|
|
153
|
+
return resolvePlatformInfo(env.TARO_ENV, "taro");
|
|
101
154
|
}
|
|
102
155
|
function resolveMpxPlatformValue(env = getProcessEnv()) {
|
|
103
156
|
return env.MPX_CURRENT_TARGET_MODE ?? env.MPX_CLI_MODE;
|
|
104
157
|
}
|
|
105
158
|
function resolveMpxPlatform(value = resolveMpxPlatformValue()) {
|
|
106
|
-
return
|
|
159
|
+
return resolvePlatformInfo(value, "mpx");
|
|
160
|
+
}
|
|
161
|
+
/** 读取 MPX 环境快照,保留 current mode 的空字符串优先级。 */
|
|
162
|
+
function resolveMpxPlatformFromEnv(env = getProcessEnv()) {
|
|
163
|
+
return resolvePlatformInfo(resolveMpxPlatformValue(env), "mpx");
|
|
107
164
|
}
|
|
108
165
|
function resolveUniPlatform(value = getProcessEnv().UNI_PLATFORM) {
|
|
109
166
|
return resolvePlatform(value);
|
|
@@ -121,141 +178,468 @@ function resolveUniPlatformsFromEnv(env = getProcessEnv()) {
|
|
|
121
178
|
uniUtsPlatform: resolvePlatform(env.UNI_UTS_PLATFORM)
|
|
122
179
|
};
|
|
123
180
|
}
|
|
124
|
-
const MPX_TO_UNI_PLATFORM = {
|
|
125
|
-
ali: "mp-alipay",
|
|
126
|
-
dd: "mp-dingtalk",
|
|
127
|
-
jd: "mp-jd",
|
|
128
|
-
qq: "mp-qq",
|
|
129
|
-
swan: "mp-baidu",
|
|
130
|
-
tt: "mp-toutiao",
|
|
131
|
-
wx: "mp-weixin"
|
|
132
|
-
};
|
|
133
181
|
function normalizeFrameworkStylePlatform(platform, appType) {
|
|
134
182
|
const normalized = platform?.trim().toLowerCase();
|
|
135
183
|
if (!normalized) return;
|
|
136
|
-
if (appType === "mpx") return MPX_TO_UNI_PLATFORM
|
|
184
|
+
if (appType === "mpx") return MPX_TO_UNI_PLATFORM.get(normalized) ?? normalized;
|
|
137
185
|
return normalized;
|
|
138
186
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
187
|
+
function resolvePlatformIdentity(platform, appType) {
|
|
188
|
+
const normalized = normalizePlatform(platform);
|
|
189
|
+
return {
|
|
190
|
+
raw: platform,
|
|
191
|
+
normalized,
|
|
192
|
+
canonical: normalized ? (appType === "mpx" ? MPX_TO_UNI_PLATFORM.get(normalized) : void 0) ?? (appType === "taro" ? TARO_TO_CANONICAL_PLATFORM.get(normalized) : void 0) ?? MINI_PROGRAM_PLATFORMS.get(normalized) ?? CANONICAL_PLATFORMS.get(normalized) : void 0
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
// src/detect-env.ts
|
|
196
|
+
function* matchEnvironment(env, options = {}) {
|
|
197
|
+
for (const key of ["WEAPP_TW_TARGET", "WEAPP_TAILWINDCSS_TARGET"]) {
|
|
198
|
+
const value = env[key];
|
|
199
|
+
if (value === "weapp-vite") yield {
|
|
200
|
+
appType: "weapp-vite",
|
|
201
|
+
evidence: [evidence("env", key, value)]
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
const taro = env.TARO_ENV;
|
|
205
|
+
if (taro) yield {
|
|
206
|
+
appType: "taro",
|
|
207
|
+
evidence: [evidence("env", "TARO_ENV", taro)]
|
|
208
|
+
};
|
|
209
|
+
for (const key of ["MPX_CLI_MODE", "MPX_CURRENT_TARGET_MODE"]) {
|
|
210
|
+
const value = env[key];
|
|
211
|
+
if (value) yield {
|
|
212
|
+
appType: "mpx",
|
|
213
|
+
evidence: [evidence("env", key, value)]
|
|
214
|
+
};
|
|
215
|
+
}
|
|
145
216
|
const { uniPlatform, uniUtsPlatform } = resolveUniPlatformsFromEnv(env);
|
|
146
|
-
if (uniUtsPlatform.normalized)
|
|
147
|
-
|
|
217
|
+
if (uniUtsPlatform.normalized) yield {
|
|
218
|
+
appType: "uni-app-x",
|
|
219
|
+
evidence: [evidence("env", "UNI_UTS_PLATFORM", uniUtsPlatform.raw)]
|
|
220
|
+
};
|
|
221
|
+
if (uniPlatform.normalized) yield {
|
|
222
|
+
appType: "uni-app-vite",
|
|
223
|
+
evidence: [evidence("env", "UNI_PLATFORM", uniPlatform.raw)]
|
|
224
|
+
};
|
|
148
225
|
if (isRunningInHBuilderX({
|
|
149
226
|
cwd: options.cwd,
|
|
150
227
|
env
|
|
151
|
-
}))
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
]
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
228
|
+
})) yield {
|
|
229
|
+
appType: options.hbuilderxVite === false ? "uni-app" : "uni-app-vite",
|
|
230
|
+
evidence: [evidence("hbuilderx", "cwd", options.cwd ?? node_process.default.cwd())]
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function detectAppTypeFromEnv(env = getProcessEnv(), options = {}) {
|
|
234
|
+
return collectMatches(matchEnvironment(env, options), false)[0]?.appType;
|
|
235
|
+
}
|
|
236
|
+
// src/script-command.ts
|
|
237
|
+
const ASSIGNMENT_RE = /^[A-Z_]\w*=/iu;
|
|
238
|
+
const COMMAND_TYPES = /* @__PURE__ */ new Map([
|
|
239
|
+
["mpx", "mpx"],
|
|
240
|
+
["mpx-cli-service", "mpx"],
|
|
241
|
+
["taro", "taro"],
|
|
242
|
+
["uni", "uni-app-vite"],
|
|
243
|
+
["weapp-vite", "weapp-vite"]
|
|
244
|
+
]);
|
|
245
|
+
const PNPM_VALUE_OPTIONS = /* @__PURE__ */ new Set([
|
|
246
|
+
"-C",
|
|
247
|
+
"--dir",
|
|
248
|
+
"-F",
|
|
249
|
+
"--filter",
|
|
250
|
+
"--filter-prod",
|
|
251
|
+
"--reporter"
|
|
252
|
+
]);
|
|
253
|
+
const PNPM_FLAGS = /* @__PURE__ */ new Set([
|
|
254
|
+
"-w",
|
|
255
|
+
"--workspace-root",
|
|
256
|
+
"-r",
|
|
257
|
+
"--recursive",
|
|
258
|
+
"-s",
|
|
259
|
+
"--silent"
|
|
260
|
+
]);
|
|
261
|
+
const NPX_VALUE_OPTIONS = /* @__PURE__ */ new Set([
|
|
262
|
+
"-p",
|
|
263
|
+
"--package",
|
|
264
|
+
"--cache",
|
|
265
|
+
"--userconfig"
|
|
266
|
+
]);
|
|
267
|
+
const NPX_FLAGS = /* @__PURE__ */ new Set([
|
|
268
|
+
"-y",
|
|
269
|
+
"--yes",
|
|
270
|
+
"--no",
|
|
271
|
+
"--no-install",
|
|
272
|
+
"-q",
|
|
273
|
+
"--quiet"
|
|
274
|
+
]);
|
|
275
|
+
const ENV_VALUE_OPTIONS = /* @__PURE__ */ new Set([
|
|
276
|
+
"-u",
|
|
277
|
+
"--unset",
|
|
278
|
+
"-C",
|
|
279
|
+
"--chdir"
|
|
280
|
+
]);
|
|
281
|
+
function readExpansionEnd(script, start, opening, closing) {
|
|
282
|
+
let depth = 1;
|
|
283
|
+
let quote;
|
|
284
|
+
for (let index = start + 2; index < script.length; index++) {
|
|
285
|
+
const character = script[index];
|
|
286
|
+
if (character === "\\" && quote !== "'") index++;
|
|
287
|
+
else if (quote) {
|
|
288
|
+
if (character === quote) quote = void 0;
|
|
289
|
+
} else if (character === "\"" || character === "'" || character === "`") quote = character;
|
|
290
|
+
else if (character === opening) depth++;
|
|
291
|
+
else if (character === closing && --depth === 0) return index;
|
|
292
|
+
}
|
|
293
|
+
return -1;
|
|
294
|
+
}
|
|
295
|
+
function tokenizeCommands(script) {
|
|
296
|
+
const commands = [];
|
|
297
|
+
let command = [];
|
|
298
|
+
let value = "";
|
|
299
|
+
let active = false;
|
|
300
|
+
let quoted = false;
|
|
301
|
+
let shellAssignment = false;
|
|
302
|
+
let protectedPrefix = false;
|
|
303
|
+
let quote;
|
|
304
|
+
function flushToken() {
|
|
305
|
+
if (active) {
|
|
306
|
+
command.push({
|
|
307
|
+
value,
|
|
308
|
+
quoted,
|
|
309
|
+
shellAssignment
|
|
310
|
+
});
|
|
311
|
+
value = "";
|
|
312
|
+
active = false;
|
|
313
|
+
quoted = false;
|
|
314
|
+
shellAssignment = false;
|
|
315
|
+
protectedPrefix = false;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
function flushCommand() {
|
|
319
|
+
flushToken();
|
|
320
|
+
if (command.length) {
|
|
321
|
+
commands.push(command);
|
|
322
|
+
command = [];
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
for (let index = 0; index < script.length; index++) {
|
|
326
|
+
const character = script[index];
|
|
327
|
+
const next = script[index + 1];
|
|
328
|
+
if (character === "\\" && quote !== "'" && next && /[\s"'\\$`;&|]/u.test(next) || character === "^" && !quote && next && /[\s"^;&|]/u.test(next)) {
|
|
329
|
+
if (next !== "\n" && next !== "\r") {
|
|
330
|
+
protectedPrefix = true;
|
|
331
|
+
value += next;
|
|
332
|
+
active = true;
|
|
333
|
+
} else if (next === "\r" && script[index + 2] === "\n") index++;
|
|
334
|
+
index++;
|
|
335
|
+
} else if (character === "$" && (next === "(" || next === "{") && quote !== "'") {
|
|
336
|
+
const end = readExpansionEnd(script, index, next, next === "(" ? ")" : "}");
|
|
337
|
+
if (end === -1) return [];
|
|
338
|
+
value += script.slice(index, end + 1);
|
|
339
|
+
protectedPrefix = true;
|
|
340
|
+
active = true;
|
|
341
|
+
index = end;
|
|
342
|
+
} else if (quote) {
|
|
343
|
+
if (character === quote) quote = void 0;
|
|
344
|
+
else value += character;
|
|
345
|
+
} else if (character === "\"" || character === "'" || character === "`") {
|
|
346
|
+
quote = character;
|
|
347
|
+
quoted = true;
|
|
348
|
+
protectedPrefix = true;
|
|
349
|
+
active = true;
|
|
350
|
+
if (character === "`") value += character;
|
|
351
|
+
} else if (character === "<" && next === "<") return [];
|
|
352
|
+
else if ((character === ">" || character === "<") && next === "&" || character === "&" && next === ">") {
|
|
353
|
+
value += character + next;
|
|
354
|
+
active = true;
|
|
355
|
+
index++;
|
|
356
|
+
} else if (character === "#" && !active) while (script[index + 1] && script[index + 1] !== "\n") index++;
|
|
357
|
+
else if (character === ";" || character === "&" || character === "|" || character === "\n" || character === "\r") flushCommand();
|
|
358
|
+
else if (/\s/u.test(character)) flushToken();
|
|
359
|
+
else {
|
|
360
|
+
if (character === "=" && !protectedPrefix && ASSIGNMENT_RE.test(`${value}=`)) shellAssignment = true;
|
|
361
|
+
value += character;
|
|
362
|
+
active = true;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (quote) return [];
|
|
366
|
+
flushCommand();
|
|
367
|
+
return commands;
|
|
368
|
+
}
|
|
369
|
+
function executableName(value, allowVersion = false) {
|
|
370
|
+
if (allowVersion && value.startsWith("@")) return value;
|
|
371
|
+
const name = node_path.default.win32.basename(node_path.default.posix.basename(value));
|
|
372
|
+
const executable = /\.(?:cmd|bat|exe)$/iu.test(name) ? name.replace(/\.(?:cmd|bat|exe)$/iu, "").toLowerCase() : name;
|
|
373
|
+
return allowVersion ? executable.replace(/@[^@]+$/u, "") : executable;
|
|
374
|
+
}
|
|
375
|
+
function skipAssignments(tokens, index, shellPosition = false) {
|
|
376
|
+
while (tokens[index] && (shellPosition ? tokens[index].shellAssignment : ASSIGNMENT_RE.test(tokens[index].value))) index++;
|
|
377
|
+
return index;
|
|
378
|
+
}
|
|
379
|
+
function skipOptions(tokens, index, flags, valueOptions) {
|
|
380
|
+
while (tokens[index]?.value.startsWith("-")) {
|
|
381
|
+
const value = tokens[index].value;
|
|
382
|
+
if (value === "--") return index + 1;
|
|
383
|
+
if (flags.has(value)) index++;
|
|
384
|
+
else if (valueOptions.has(value)) {
|
|
385
|
+
if (!tokens[index + 1]) return tokens.length;
|
|
386
|
+
index += 2;
|
|
387
|
+
} else if (value.includes("=") && valueOptions.has(value.slice(0, value.indexOf("=")))) index++;
|
|
388
|
+
else return tokens.length;
|
|
389
|
+
}
|
|
390
|
+
return index;
|
|
391
|
+
}
|
|
392
|
+
function collectCommands(script, detected, depth = 0) {
|
|
393
|
+
if (depth > 8) return;
|
|
394
|
+
for (const tokens of tokenizeCommands(script)) {
|
|
395
|
+
let index = skipAssignments(tokens, 0, true);
|
|
396
|
+
let allowVersion = false;
|
|
397
|
+
while (tokens[index]) {
|
|
398
|
+
const name = executableName(tokens[index].value, allowVersion);
|
|
399
|
+
const appType = COMMAND_TYPES.get(name);
|
|
400
|
+
if (appType) {
|
|
401
|
+
detected.add(appType);
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
404
|
+
allowVersion = false;
|
|
405
|
+
index++;
|
|
406
|
+
if (name === "cross-env" || name === "cross-env-shell") {
|
|
407
|
+
index = skipAssignments(tokens, index);
|
|
408
|
+
const payload = tokens[index];
|
|
409
|
+
if (name === "cross-env-shell" && payload?.quoted) {
|
|
410
|
+
collectCommands(payload.value, detected, depth + 1);
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
} else if (name === "env") {
|
|
414
|
+
index = skipOptions(tokens, index, /* @__PURE__ */ new Set(["-i", "--ignore-environment"]), ENV_VALUE_OPTIONS);
|
|
415
|
+
index = skipAssignments(tokens, index);
|
|
416
|
+
} else if (name === "pnpm") {
|
|
417
|
+
index = skipOptions(tokens, index, PNPM_FLAGS, PNPM_VALUE_OPTIONS);
|
|
418
|
+
if (tokens[index]?.value === "exec" || tokens[index]?.value === "dlx") {
|
|
419
|
+
const dlx = tokens[index].value === "dlx";
|
|
420
|
+
index++;
|
|
421
|
+
index = skipOptions(tokens, index, dlx ? NPX_FLAGS : PNPM_FLAGS, dlx ? NPX_VALUE_OPTIONS : PNPM_VALUE_OPTIONS);
|
|
422
|
+
allowVersion = dlx;
|
|
423
|
+
}
|
|
424
|
+
} else if (name === "npx") {
|
|
425
|
+
index = skipOptions(tokens, index, NPX_FLAGS, NPX_VALUE_OPTIONS);
|
|
426
|
+
allowVersion = true;
|
|
427
|
+
} else break;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* 仅识别脚本中明确的命令位置,不执行脚本或推断任意参数中的框架名称。
|
|
433
|
+
*/
|
|
434
|
+
function detectFrameworkCommands(script) {
|
|
435
|
+
const detected = /* @__PURE__ */ new Set();
|
|
436
|
+
collectCommands(script, detected);
|
|
437
|
+
return [...detected];
|
|
438
|
+
}
|
|
439
|
+
// src/package.ts
|
|
440
|
+
const FRAMEWORK_PRIORITY = [
|
|
441
|
+
"weapp-vite",
|
|
442
|
+
"mpx",
|
|
443
|
+
"taro",
|
|
444
|
+
"uni-app-x",
|
|
445
|
+
"uni-app-vite",
|
|
446
|
+
"uni-app"
|
|
447
|
+
];
|
|
448
|
+
const DEPENDENCY_FIELDS = [
|
|
449
|
+
"dependencies",
|
|
450
|
+
"devDependencies",
|
|
451
|
+
"peerDependencies",
|
|
452
|
+
"optionalDependencies"
|
|
453
|
+
];
|
|
454
|
+
function matchesDependency(appType, name) {
|
|
455
|
+
switch (appType) {
|
|
456
|
+
case "weapp-vite": return name === "weapp-vite" || name.startsWith("@weapp-vite/");
|
|
457
|
+
case "mpx": return name.startsWith("@mpxjs/");
|
|
458
|
+
case "taro": return name.startsWith("@tarojs/");
|
|
459
|
+
case "uni-app-x": return name === "@dcloudio/uni-uts-v1" || name === "@weapp-tailwindcss/debug-uni-app-x";
|
|
460
|
+
case "uni-app-vite": return name === "@dcloudio/vite-plugin-uni";
|
|
461
|
+
case "uni-app": return name === "@dcloudio/vue-cli-plugin-uni" || name === "@dcloudio/uni-app";
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function packageMatcher(pkg, file) {
|
|
465
|
+
let scripts;
|
|
466
|
+
return (appType, all) => {
|
|
467
|
+
const result = [];
|
|
468
|
+
for (const field of DEPENDENCY_FIELDS) for (const [name, version] of Object.entries(pkg[field] ?? {})) if (matchesDependency(appType, name)) {
|
|
469
|
+
result.push(evidence("dependency", `${field}.${name}`, version, file));
|
|
470
|
+
if (!all) return result;
|
|
471
|
+
}
|
|
472
|
+
if (appType === "uni-app" && Object.hasOwn(pkg, "uni-app")) {
|
|
473
|
+
result.push(evidence("package-field", "uni-app", void 0, file));
|
|
474
|
+
if (!all) return result;
|
|
475
|
+
}
|
|
476
|
+
if (appType === "uni-app-x") return result;
|
|
477
|
+
scripts ??= Object.entries(pkg.scripts ?? {}).map(([name, value]) => ({
|
|
478
|
+
name,
|
|
479
|
+
value,
|
|
480
|
+
commands: detectFrameworkCommands(value)
|
|
481
|
+
}));
|
|
482
|
+
for (const script of scripts) {
|
|
483
|
+
const commandType = appType === "uni-app" ? "uni-app-vite" : appType;
|
|
484
|
+
if (script.commands.includes(commandType)) {
|
|
485
|
+
result.push(evidence("script", `scripts.${script.name}`, script.value, file));
|
|
486
|
+
if (!all) return result;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return result;
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
function* matchPackageJson(pkg, all, file) {
|
|
493
|
+
const match = packageMatcher(pkg, file);
|
|
494
|
+
for (const appType of FRAMEWORK_PRIORITY) {
|
|
495
|
+
const evidence = match(appType, all);
|
|
496
|
+
if (evidence.length) yield {
|
|
497
|
+
appType,
|
|
498
|
+
evidence
|
|
499
|
+
};
|
|
500
|
+
}
|
|
173
501
|
}
|
|
174
502
|
function isWeappVitePackage(pkg) {
|
|
175
|
-
|
|
176
|
-
return dependencyNames.has("weapp-vite") || hasDependencyPrefix(dependencyNames, "@weapp-vite/") || hasScriptMatch(pkg, WEAPP_VITE_SCRIPT_RE);
|
|
503
|
+
return packageMatcher(pkg)("weapp-vite", false).length > 0;
|
|
177
504
|
}
|
|
178
505
|
function isMpxPackage(pkg) {
|
|
179
|
-
return
|
|
506
|
+
return packageMatcher(pkg)("mpx", false).length > 0;
|
|
180
507
|
}
|
|
181
508
|
function isTaroPackage(pkg) {
|
|
182
|
-
return
|
|
509
|
+
return packageMatcher(pkg)("taro", false).length > 0;
|
|
183
510
|
}
|
|
184
511
|
function isUniAppVitePackage(pkg) {
|
|
185
|
-
return
|
|
512
|
+
return packageMatcher(pkg)("uni-app-vite", false).length > 0;
|
|
186
513
|
}
|
|
187
514
|
function isUniAppXPackage(pkg) {
|
|
188
|
-
|
|
189
|
-
return dependencyNames.has("@dcloudio/uni-uts-v1") || dependencyNames.has("@weapp-tailwindcss/debug-uni-app-x");
|
|
515
|
+
return packageMatcher(pkg)("uni-app-x", false).length > 0;
|
|
190
516
|
}
|
|
191
517
|
function isUniAppPackage(pkg) {
|
|
192
|
-
|
|
193
|
-
return dependencyNames.has("@dcloudio/vue-cli-plugin-uni") || dependencyNames.has("@dcloudio/uni-app") || Object.hasOwn(pkg, "uni-app") || hasScriptMatch(pkg, UNI_APP_SCRIPT_RE);
|
|
518
|
+
return packageMatcher(pkg)("uni-app", false).length > 0;
|
|
194
519
|
}
|
|
195
520
|
function isUniAppXManifest(manifest) {
|
|
196
521
|
return Boolean(manifest && Object.hasOwn(manifest, "uni-app-x"));
|
|
197
522
|
}
|
|
198
523
|
function detectAppTypeFromPackageJson(pkg) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
524
|
+
return collectMatches(matchPackageJson(pkg, false), false)[0]?.appType;
|
|
525
|
+
}
|
|
526
|
+
// src/manifest.ts
|
|
527
|
+
/** 仅移除字符串外的注释,其余语法仍交给严格 JSON 解析。 */
|
|
528
|
+
function parseManifestJson(source) {
|
|
529
|
+
const characters = source.split("");
|
|
530
|
+
let inString = false;
|
|
531
|
+
for (let index = 0; index < source.length; index++) {
|
|
532
|
+
const character = source[index];
|
|
533
|
+
if (inString) {
|
|
534
|
+
if (character === "\\") index++;
|
|
535
|
+
else if (character === "\"") inString = false;
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
if (character === "\"") {
|
|
539
|
+
inString = true;
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
if (character !== "/") continue;
|
|
543
|
+
if (source[index + 1] === "/") {
|
|
544
|
+
characters[index] = " ";
|
|
545
|
+
characters[++index] = " ";
|
|
546
|
+
while (index + 1 < source.length && source[index + 1] !== "\n" && source[index + 1] !== "\r") characters[++index] = " ";
|
|
547
|
+
} else if (source[index + 1] === "*") {
|
|
548
|
+
characters[index] = " ";
|
|
549
|
+
characters[++index] = " ";
|
|
550
|
+
let closed = false;
|
|
551
|
+
while (++index < source.length) {
|
|
552
|
+
if (source[index] === "*" && source[index + 1] === "/") {
|
|
553
|
+
characters[index] = " ";
|
|
554
|
+
characters[++index] = " ";
|
|
555
|
+
closed = true;
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
558
|
+
if (source[index] !== "\n" && source[index] !== "\r") characters[index] = " ";
|
|
559
|
+
}
|
|
560
|
+
if (!closed) throw new SyntaxError("manifest.json 中存在未闭合的块注释");
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
return JSON.parse(characters.join(""));
|
|
564
|
+
}
|
|
565
|
+
// src/project.ts
|
|
208
566
|
const PACKAGE_JSON_FILE = "package.json";
|
|
209
567
|
const MANIFEST_JSON_FILE = "manifest.json";
|
|
210
568
|
const MPX_MARKERS = [["src", "app.mpx"], ["app.mpx"]];
|
|
211
|
-
function tryReadJson(file) {
|
|
569
|
+
function tryReadJson(file, parse = JSON.parse) {
|
|
212
570
|
if (!(0, node_fs.existsSync)(file)) return;
|
|
213
571
|
try {
|
|
214
|
-
return
|
|
572
|
+
return parse((0, node_fs.readFileSync)(file, "utf8"));
|
|
215
573
|
} catch {}
|
|
216
574
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
575
|
+
function manifestMatches(manifest, file) {
|
|
576
|
+
return isUniAppXManifest(manifest) ? [{
|
|
577
|
+
appType: "uni-app-x",
|
|
578
|
+
evidence: [evidence("manifest", "uni-app-x", void 0, file)]
|
|
579
|
+
}] : [];
|
|
219
580
|
}
|
|
220
|
-
function
|
|
581
|
+
function matchRoot(root, searchUp, all) {
|
|
221
582
|
const resolvedRoot = node_path.default.resolve(root);
|
|
222
|
-
if (!(0, node_fs.existsSync)(resolvedRoot)) return;
|
|
223
|
-
const
|
|
224
|
-
|
|
583
|
+
if (!(0, node_fs.existsSync)(resolvedRoot)) return [];
|
|
584
|
+
const markers = [];
|
|
585
|
+
for (const segments of MPX_MARKERS) {
|
|
586
|
+
const file = node_path.default.join(resolvedRoot, ...segments);
|
|
587
|
+
if ((0, node_fs.existsSync)(file)) {
|
|
588
|
+
markers.push(evidence("marker", "app.mpx", void 0, file));
|
|
589
|
+
if (!all) break;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
if (markers.length) return [{
|
|
593
|
+
appType: "mpx",
|
|
594
|
+
evidence: markers
|
|
595
|
+
}];
|
|
225
596
|
let current = resolvedRoot;
|
|
226
597
|
while (true) {
|
|
227
|
-
|
|
228
|
-
const
|
|
598
|
+
const manifestFile = node_path.default.join(current, MANIFEST_JSON_FILE);
|
|
599
|
+
const manifest = manifestMatches(tryReadJson(manifestFile, parseManifestJson), manifestFile);
|
|
600
|
+
if (manifest.length) return manifest;
|
|
601
|
+
const packageFile = node_path.default.join(current, PACKAGE_JSON_FILE);
|
|
602
|
+
const pkg = tryReadJson(packageFile);
|
|
229
603
|
if (pkg) {
|
|
230
|
-
const
|
|
231
|
-
if (
|
|
604
|
+
const candidates = collectMatches(matchPackageJson(pkg, all, packageFile), all);
|
|
605
|
+
if (candidates.length) return candidates;
|
|
232
606
|
}
|
|
233
607
|
if (!searchUp) break;
|
|
234
608
|
const parent = node_path.default.dirname(current);
|
|
235
609
|
if (parent === current) break;
|
|
236
610
|
current = parent;
|
|
237
611
|
}
|
|
612
|
+
return [];
|
|
238
613
|
}
|
|
239
|
-
function
|
|
240
|
-
|
|
614
|
+
function matchAppType(options, all) {
|
|
615
|
+
const manifest = manifestMatches(options.manifest);
|
|
616
|
+
if (manifest.length) return manifest;
|
|
241
617
|
if (options.packageJson) {
|
|
242
|
-
const
|
|
243
|
-
if (
|
|
618
|
+
const candidates = collectMatches(matchPackageJson(options.packageJson, all), all);
|
|
619
|
+
if (candidates.length) return candidates;
|
|
244
620
|
}
|
|
245
621
|
if (options.root) {
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
622
|
+
const candidates = matchRoot(options.root, options.searchUp ?? true, all);
|
|
623
|
+
if (candidates.length) return candidates;
|
|
248
624
|
}
|
|
249
625
|
const env = options.env ?? (options.detectEnv ? getProcessEnv() : void 0);
|
|
250
|
-
if (env) return
|
|
626
|
+
if (!env) return [];
|
|
627
|
+
return collectMatches(matchEnvironment(env, {
|
|
251
628
|
cwd: options.cwd ?? options.root ?? (options.detectEnv ? node_process.default.cwd() : void 0),
|
|
252
629
|
hbuilderxVite: options.hbuilderxVite
|
|
253
|
-
});
|
|
630
|
+
}), all);
|
|
631
|
+
}
|
|
632
|
+
function detectAppType(options = {}) {
|
|
633
|
+
return matchAppType(options, false)[0]?.appType;
|
|
634
|
+
}
|
|
635
|
+
/** 解释首次命中阶段的框架候选与冲突,不扩大项目搜索范围。 */
|
|
636
|
+
function detectAppTypeReport(options = {}) {
|
|
637
|
+
return detectionReport(matchAppType(options, true));
|
|
254
638
|
}
|
|
255
|
-
//#endregion
|
|
256
639
|
exports.detectAppType = detectAppType;
|
|
257
640
|
exports.detectAppTypeFromEnv = detectAppTypeFromEnv;
|
|
258
641
|
exports.detectAppTypeFromPackageJson = detectAppTypeFromPackageJson;
|
|
642
|
+
exports.detectAppTypeReport = detectAppTypeReport;
|
|
259
643
|
exports.isMpxPackage = isMpxPackage;
|
|
260
644
|
exports.isRunningInHBuilderX = isRunningInHBuilderX;
|
|
261
645
|
exports.isTaroPackage = isTaroPackage;
|
|
@@ -266,8 +650,11 @@ exports.isUniAppXPackage = isUniAppXPackage;
|
|
|
266
650
|
exports.isWeappVitePackage = isWeappVitePackage;
|
|
267
651
|
exports.normalizeFrameworkStylePlatform = normalizeFrameworkStylePlatform;
|
|
268
652
|
exports.resolveMpxPlatform = resolveMpxPlatform;
|
|
653
|
+
exports.resolveMpxPlatformFromEnv = resolveMpxPlatformFromEnv;
|
|
269
654
|
exports.resolvePlatform = resolvePlatform;
|
|
655
|
+
exports.resolvePlatformIdentity = resolvePlatformIdentity;
|
|
270
656
|
exports.resolveTaroPlatform = resolveTaroPlatform;
|
|
657
|
+
exports.resolveTaroPlatformFromEnv = resolveTaroPlatformFromEnv;
|
|
271
658
|
exports.resolveUniAppXPlatform = resolveUniAppXPlatform;
|
|
272
659
|
exports.resolveUniPlatform = resolveUniPlatform;
|
|
273
660
|
exports.resolveUniPlatformsFromEnv = resolveUniPlatformsFromEnv;
|