@weapp-vite/miniprogram-automator 1.2.18 → 1.2.19
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.mjs
CHANGED
|
@@ -943,7 +943,7 @@ var Connection = class Connection extends EventEmitter {
|
|
|
943
943
|
//#endregion
|
|
944
944
|
//#region src/headless.ts
|
|
945
945
|
async function launchHeadlessAutomator(options) {
|
|
946
|
-
return await (await import("./launch-
|
|
946
|
+
return await (await import("./launch-CMN_emd-.mjs")).launch({ projectPath: options.projectPath });
|
|
947
947
|
}
|
|
948
948
|
//#endregion
|
|
949
949
|
//#region src/launcher/portLease.ts
|
|
@@ -1098,7 +1098,7 @@ function resolveWechatDevtoolsBootstrapArgs(args) {
|
|
|
1098
1098
|
}
|
|
1099
1099
|
//#endregion
|
|
1100
1100
|
//#region package.json
|
|
1101
|
-
var version = "1.2.
|
|
1101
|
+
var version = "1.2.19";
|
|
1102
1102
|
//#endregion
|
|
1103
1103
|
//#region src/Native.ts
|
|
1104
1104
|
/** Native 的实现。 */
|
|
@@ -12634,13 +12634,13 @@ const BLOCKED_MEMBER_KEYS = /* @__PURE__ */ new Set([
|
|
|
12634
12634
|
"prototype"
|
|
12635
12635
|
]);
|
|
12636
12636
|
const NUMERIC_DOT_PATH_RE = /\.(\d+)(?=[.[\s,}\]]|$)/g;
|
|
12637
|
-
function isMustacheOnly$
|
|
12637
|
+
function isMustacheOnly$2(value) {
|
|
12638
12638
|
const trimmed = value.trim();
|
|
12639
12639
|
return trimmed.startsWith("{{") && trimmed.endsWith("}}") && !trimmed.includes("{{", 2);
|
|
12640
12640
|
}
|
|
12641
12641
|
function unwrapMustacheExpression(expression) {
|
|
12642
12642
|
const normalized = expression.trim();
|
|
12643
|
-
if (isMustacheOnly$
|
|
12643
|
+
if (isMustacheOnly$2(normalized)) return normalized.slice(2, -2).trim();
|
|
12644
12644
|
return normalized;
|
|
12645
12645
|
}
|
|
12646
12646
|
function parseTemplateExpression(expression) {
|
|
@@ -12845,6 +12845,26 @@ function flushComponentAttachments(instances, attach) {
|
|
|
12845
12845
|
return pending.length > 0;
|
|
12846
12846
|
}
|
|
12847
12847
|
//#endregion
|
|
12848
|
+
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/discardedReady.ts
|
|
12849
|
+
const discardedReady = /* @__PURE__ */ new WeakMap();
|
|
12850
|
+
/** 初始模板分支被 props 替换时,微信仍发送 ready,但不发送 attached 或 detached。 */
|
|
12851
|
+
function scheduleDiscardedComponentReady(cache, scopeId, instance) {
|
|
12852
|
+
const pending = discardedReady.get(cache) ?? /* @__PURE__ */ new Map();
|
|
12853
|
+
pending.set(scopeId, instance);
|
|
12854
|
+
discardedReady.set(cache, pending);
|
|
12855
|
+
}
|
|
12856
|
+
function flushDiscardedComponentReady(cache, pageScopeId, ready) {
|
|
12857
|
+
const pending = discardedReady.get(cache);
|
|
12858
|
+
if (!pending) return;
|
|
12859
|
+
const current = [...pending].filter(([scopeId]) => scopeId.startsWith(`${pageScopeId}/`));
|
|
12860
|
+
for (const [scopeId, instance] of current) {
|
|
12861
|
+
pending.delete(scopeId);
|
|
12862
|
+
instance.__ready__ = true;
|
|
12863
|
+
}
|
|
12864
|
+
for (const [, instance] of current) ready(instance);
|
|
12865
|
+
if (!pending.size) discardedReady.delete(cache);
|
|
12866
|
+
}
|
|
12867
|
+
//#endregion
|
|
12848
12868
|
//#region ../../mpcore/packages/simulator/src/runtime/pageLifecycle.ts
|
|
12849
12869
|
const loadingPages = /* @__PURE__ */ new WeakSet();
|
|
12850
12870
|
function isPageBeforeReady(page) {
|
|
@@ -13045,6 +13065,20 @@ function resolveSelectorQueryScopeSnapshot(scope, snapshots) {
|
|
|
13045
13065
|
return null;
|
|
13046
13066
|
}
|
|
13047
13067
|
//#endregion
|
|
13068
|
+
//#region ../../mpcore/packages/simulator/src/runtime/componentInstance/selection.ts
|
|
13069
|
+
function hasExportBehavior(definition, visited = /* @__PURE__ */ new Set()) {
|
|
13070
|
+
if (visited.has(definition)) return false;
|
|
13071
|
+
visited.add(definition);
|
|
13072
|
+
return (Array.isArray(definition.behaviors) ? definition.behaviors : []).some((behavior) => behavior === "wx://component-export" || behavior !== null && typeof behavior === "object" && hasExportBehavior(behavior, visited));
|
|
13073
|
+
}
|
|
13074
|
+
/** 原生选择器尊重组件导出行为;测试桥接继续保留完整组件实例。 */
|
|
13075
|
+
function resolveNativeComponentSelection(instance) {
|
|
13076
|
+
if (!instance) return null;
|
|
13077
|
+
const definition = instance.__definition__;
|
|
13078
|
+
if (!definition || !hasExportBehavior(definition) || typeof instance.export !== "function") return instance;
|
|
13079
|
+
return instance.export();
|
|
13080
|
+
}
|
|
13081
|
+
//#endregion
|
|
13048
13082
|
//#region ../../mpcore/packages/simulator/src/runtime/moduleResolution.ts
|
|
13049
13083
|
function resolveMiniProgramModule(importer, request, miniprogramRootPath, hasFile) {
|
|
13050
13084
|
function resolveFile(basePath) {
|
|
@@ -13079,6 +13113,21 @@ function resolveMiniProgramComponent(ownerFilePath, request, miniprogramRootPath
|
|
|
13079
13113
|
return npmPath ? relative(miniprogramRootPath, npmPath).slice(0, -3) : localPath;
|
|
13080
13114
|
}
|
|
13081
13115
|
//#endregion
|
|
13116
|
+
//#region ../../mpcore/packages/simulator/src/view/nodeDataset.ts
|
|
13117
|
+
const DATASET_NAME_RE = /-([a-z])/g;
|
|
13118
|
+
function isDatasetAttribute(attributeName) {
|
|
13119
|
+
return attributeName.startsWith("data-") && !attributeName.startsWith("data-sim-");
|
|
13120
|
+
}
|
|
13121
|
+
function toDatasetKey(attributeName) {
|
|
13122
|
+
return attributeName.slice(5).replace(DATASET_NAME_RE, (_match, char) => char.toUpperCase());
|
|
13123
|
+
}
|
|
13124
|
+
function collectNodeDataset(node) {
|
|
13125
|
+
if (node.dataset) return { ...node.dataset };
|
|
13126
|
+
const dataset = {};
|
|
13127
|
+
for (const [key, value] of Object.entries(node.attribs ?? {})) if (isDatasetAttribute(key)) dataset[toDatasetKey(key)] = value;
|
|
13128
|
+
return dataset;
|
|
13129
|
+
}
|
|
13130
|
+
//#endregion
|
|
13082
13131
|
//#region ../../mpcore/packages/simulator/src/view/templateImports.ts
|
|
13083
13132
|
function createImportedTemplateState(root, filePath, loadImport, loadWxs) {
|
|
13084
13133
|
const documents = /* @__PURE__ */ new Map();
|
|
@@ -13108,7 +13157,8 @@ function createImportedTemplateState(root, filePath, loadImport, loadWxs) {
|
|
|
13108
13157
|
return;
|
|
13109
13158
|
}
|
|
13110
13159
|
if (child.name === "import" && child.attribs?.src) {
|
|
13111
|
-
const
|
|
13160
|
+
const source = child.attribs.src;
|
|
13161
|
+
const imported = loadImport(owner, source.endsWith(".wxml") ? source : `${source}.wxml`);
|
|
13112
13162
|
const importedDocument = collect(imported.root, imported.filePath);
|
|
13113
13163
|
for (const [name, definition] of importedDocument.exports) state.definitions.set(name, definition);
|
|
13114
13164
|
}
|
|
@@ -16936,7 +16986,6 @@ function parseWxsTemplateDocument(templateSource) {
|
|
|
16936
16986
|
//#endregion
|
|
16937
16987
|
//#region ../../mpcore/packages/simulator/src/runtime/render/shared.ts
|
|
16938
16988
|
const TEMPLATE_INTERPOLATION_RE$1 = /\{\{([^{}]+)\}\}/g;
|
|
16939
|
-
const DATASET_NAME_RE$3 = /-([a-z])/g;
|
|
16940
16989
|
const LEADING_SLASH_RE$4 = /^\/+/;
|
|
16941
16990
|
const EVENT_BINDING_ATTRS = [
|
|
16942
16991
|
"bindtap",
|
|
@@ -16955,19 +17004,16 @@ const STRUCTURAL_ATTRS = [
|
|
|
16955
17004
|
];
|
|
16956
17005
|
const CLASS_SPLIT_RE = /\s+/;
|
|
16957
17006
|
const JS_FILE_RE = /\.js$/;
|
|
16958
|
-
function isMustacheOnly(value) {
|
|
17007
|
+
function isMustacheOnly$1(value) {
|
|
16959
17008
|
const trimmed = value.trim();
|
|
16960
17009
|
return trimmed.startsWith("{{") && trimmed.endsWith("}}") && !trimmed.includes("{{", 2);
|
|
16961
17010
|
}
|
|
16962
|
-
function
|
|
16963
|
-
|
|
16964
|
-
}
|
|
16965
|
-
function collectDataset$3(node, source) {
|
|
17011
|
+
function collectDataset(node, source) {
|
|
17012
|
+
if (node.dataset) return collectNodeDataset(node);
|
|
16966
17013
|
const dataset = {};
|
|
16967
17014
|
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
16968
|
-
if (!
|
|
16969
|
-
|
|
16970
|
-
dataset[toDatasetKey$3(key)] = String(resolvedValue ?? "");
|
|
17015
|
+
if (!isDatasetAttribute(key)) continue;
|
|
17016
|
+
dataset[toDatasetKey(key)] = source && isMustacheOnly$1(value) ? resolveTemplateExpression(source, value) : value;
|
|
16971
17017
|
}
|
|
16972
17018
|
return dataset;
|
|
16973
17019
|
}
|
|
@@ -16981,13 +17027,14 @@ function cloneNode(node) {
|
|
|
16981
17027
|
return {
|
|
16982
17028
|
...node,
|
|
16983
17029
|
attribs: node.attribs ? { ...node.attribs } : void 0,
|
|
17030
|
+
dataset: node.dataset ? { ...node.dataset } : void 0,
|
|
16984
17031
|
children: node.children?.map((child) => cloneNode(child))
|
|
16985
17032
|
};
|
|
16986
17033
|
}
|
|
16987
17034
|
function resolveValueByPath$1(source, expression) {
|
|
16988
17035
|
return resolveTemplateExpression(source, expression) ?? "";
|
|
16989
17036
|
}
|
|
16990
|
-
function resolveRawValueByPath(source, expression) {
|
|
17037
|
+
function resolveRawValueByPath$1(source, expression) {
|
|
16991
17038
|
return resolveTemplateExpression(source, expression);
|
|
16992
17039
|
}
|
|
16993
17040
|
function interpolateTemplate$1(input, data) {
|
|
@@ -17030,16 +17077,16 @@ function isTagNode(node) {
|
|
|
17030
17077
|
return node.type === "tag" && typeof node.name === "string";
|
|
17031
17078
|
}
|
|
17032
17079
|
function resolveAttributeValue(value, scope) {
|
|
17033
|
-
if (isMustacheOnly(value)) {
|
|
17080
|
+
if (isMustacheOnly$1(value)) {
|
|
17034
17081
|
const expression = value.trim().slice(2, -2);
|
|
17035
|
-
return
|
|
17082
|
+
return resolveRawValueByPath$1(wxsScopeData(scope), expression);
|
|
17036
17083
|
}
|
|
17037
17084
|
return interpolateTemplate$1(value, wxsScopeData(scope));
|
|
17038
17085
|
}
|
|
17039
17086
|
function resolveComponentAttributeValue(value, scope) {
|
|
17040
|
-
if (isMustacheOnly(value)) {
|
|
17087
|
+
if (isMustacheOnly$1(value)) {
|
|
17041
17088
|
const expression = value.trim().slice(2, -2);
|
|
17042
|
-
return resolveRawValueByPath(wxsScopeData(scope), expression) ?? null;
|
|
17089
|
+
return resolveRawValueByPath$1(wxsScopeData(scope), expression) ?? null;
|
|
17043
17090
|
}
|
|
17044
17091
|
return interpolateTemplate$1(value, wxsScopeData(scope));
|
|
17045
17092
|
}
|
|
@@ -17051,18 +17098,25 @@ function applyNodeBindings(node, scope) {
|
|
|
17051
17098
|
node.attribs ??= {};
|
|
17052
17099
|
node.attribs["data-sim-scope"] = scope.getScopeId();
|
|
17053
17100
|
for (const key of STRUCTURAL_ATTRS) delete node.attribs[key];
|
|
17101
|
+
let dataset;
|
|
17054
17102
|
for (const [key, value] of Object.entries({ ...node.attribs })) {
|
|
17055
17103
|
if (EVENT_BINDING_ATTRS.includes(key)) {
|
|
17056
17104
|
node.attribs["data-sim-tap"] = value;
|
|
17057
17105
|
continue;
|
|
17058
17106
|
}
|
|
17059
|
-
|
|
17107
|
+
const resolvedValue = typeof value === "string" ? resolveAttributeValue(value, scope) : value;
|
|
17108
|
+
node.attribs[key] = String(resolvedValue ?? "");
|
|
17109
|
+
if (isDatasetAttribute(key)) {
|
|
17110
|
+
dataset ??= {};
|
|
17111
|
+
dataset[toDatasetKey(key)] = resolvedValue;
|
|
17112
|
+
}
|
|
17060
17113
|
}
|
|
17114
|
+
node.dataset = dataset;
|
|
17061
17115
|
}
|
|
17062
17116
|
function evaluateConditionalBranch(node, scope) {
|
|
17063
17117
|
const condition = node.attribs?.["wx:if"] ?? node.attribs?.["wx:elif"];
|
|
17064
17118
|
if (condition == null) return true;
|
|
17065
|
-
return Boolean(resolveRawValueByPath(wxsScopeData(scope), condition));
|
|
17119
|
+
return Boolean(resolveRawValueByPath$1(wxsScopeData(scope), condition));
|
|
17066
17120
|
}
|
|
17067
17121
|
function createLoopScope(scope, itemName, indexName, item, index) {
|
|
17068
17122
|
return {
|
|
@@ -17138,7 +17192,7 @@ function collectComponentEventBindings(hostNode) {
|
|
|
17138
17192
|
return collectMiniProgramEventBindings(hostNode.attribs);
|
|
17139
17193
|
}
|
|
17140
17194
|
function buildComponentTrigger(componentScopeId, context, hostNode) {
|
|
17141
|
-
const hostDataset = collectDataset
|
|
17195
|
+
const hostDataset = collectDataset(hostNode);
|
|
17142
17196
|
const hostId = hostNode.attribs?.id ?? "";
|
|
17143
17197
|
return (instance, eventName, detail, triggerOptions) => {
|
|
17144
17198
|
const originScope = context.componentScopes.get(componentScopeId);
|
|
@@ -17200,7 +17254,7 @@ function createComponentScope(clonedNode, scope, componentScopeId, componentInst
|
|
|
17200
17254
|
alias: clonedNode.name,
|
|
17201
17255
|
classList: String(clonedNode.attribs?.class ?? "").split(CLASS_SPLIT_RE).map((item) => item.trim()).filter(Boolean),
|
|
17202
17256
|
data: { ...componentInstance.data },
|
|
17203
|
-
dataset: collectDataset
|
|
17257
|
+
dataset: collectDataset(clonedNode, wxsScopeData(scope)),
|
|
17204
17258
|
eventBindings: collectComponentEventBindings(clonedNode),
|
|
17205
17259
|
getMethod: (methodName) => {
|
|
17206
17260
|
const method = componentInstance?.[methodName];
|
|
@@ -17223,7 +17277,7 @@ function resolveComponentProperties(clonedNode, scope, definition) {
|
|
|
17223
17277
|
if (key.startsWith("bind") || key.startsWith("generic:")) continue;
|
|
17224
17278
|
const camelizedKey = key.replace(/-([a-z])/g, (_match, char) => char.toUpperCase());
|
|
17225
17279
|
const propertyKey = key in declaredProperties || !(camelizedKey in declaredProperties) ? key : camelizedKey;
|
|
17226
|
-
if (isMustacheOnly(String(value))) bindingExpressions[propertyKey] = String(value).trim().slice(2, -2).trim();
|
|
17280
|
+
if (isMustacheOnly$1(String(value))) bindingExpressions[propertyKey] = String(value).trim().slice(2, -2).trim();
|
|
17227
17281
|
nextProperties[propertyKey] = resolveComponentAttributeValue(String(value), scope);
|
|
17228
17282
|
}
|
|
17229
17283
|
return {
|
|
@@ -17231,7 +17285,7 @@ function resolveComponentProperties(clonedNode, scope, definition) {
|
|
|
17231
17285
|
bindingExpressions
|
|
17232
17286
|
};
|
|
17233
17287
|
}
|
|
17234
|
-
function createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId) {
|
|
17288
|
+
function createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId, beforeCreated) {
|
|
17235
17289
|
const componentProperties = Object.keys(componentEntry.definition.methods ?? {}).some((key) => key.startsWith("__weapp_vite_")) || Object.hasOwn(componentEntry.definition.properties ?? {}, "__wvSlotOwnerId") ? Object.fromEntries(Object.keys(componentEntry.definition.properties ?? {}).filter((key) => Object.hasOwn(nextProperties, key)).map((key) => [key, nextProperties[key]])) : nextProperties;
|
|
17236
17290
|
const componentInstance = createComponentInstance({
|
|
17237
17291
|
definition: componentEntry.definition,
|
|
@@ -17243,10 +17297,11 @@ function createRuntimeComponentInstance(componentScopeId, context, clonedNode, c
|
|
|
17243
17297
|
componentInstance.createIntersectionObserver = (options) => context.session.createIntersectionObserver(componentInstance, options);
|
|
17244
17298
|
componentInstance.createMediaQueryObserver = () => context.session.createMediaQueryObserver(componentInstance);
|
|
17245
17299
|
componentInstance.createSelectorQuery = () => context.moduleLoader.wx.createSelectorQuery().in(componentInstance);
|
|
17246
|
-
componentInstance.selectComponent = (selector) => context.session.selectComponentWithin(componentScopeId, selector);
|
|
17247
|
-
componentInstance.selectAllComponents = (selector) => context.session.selectAllComponentsWithin(componentScopeId, selector);
|
|
17300
|
+
componentInstance.selectComponent = (selector) => resolveNativeComponentSelection(context.session.selectComponentWithin(componentScopeId, selector));
|
|
17301
|
+
componentInstance.selectAllComponents = (selector) => context.session.selectAllComponentsWithin(componentScopeId, selector).map(resolveNativeComponentSelection);
|
|
17248
17302
|
componentInstance.selectOwnerComponent = () => ownerScopeId ? context.componentCache.get(ownerScopeId) ?? null : null;
|
|
17249
17303
|
context.componentCache.set(componentScopeId, componentInstance);
|
|
17304
|
+
beforeCreated?.(componentInstance);
|
|
17250
17305
|
runComponentLifecycle(componentInstance, "created");
|
|
17251
17306
|
componentInstance.__propertySnapshots = Object.fromEntries(Object.entries(componentInstance.properties).map(([key, propertyValue]) => [key, cloneValue$1(propertyValue)]));
|
|
17252
17307
|
syncComponentProperties(componentInstance, componentInstance.__definition__ ?? componentEntry.definition, componentProperties, {}, []);
|
|
@@ -17267,7 +17322,7 @@ function expandNodeByFor(node, scope) {
|
|
|
17267
17322
|
scope,
|
|
17268
17323
|
instanceSuffix: ""
|
|
17269
17324
|
}];
|
|
17270
|
-
const items = resolveLoopEntries(resolveRawValueByPath(wxsScopeData(scope), forExpression));
|
|
17325
|
+
const items = resolveLoopEntries(resolveRawValueByPath$1(wxsScopeData(scope), forExpression));
|
|
17271
17326
|
const itemName = node.attribs?.["wx:for-item"]?.trim() || "item";
|
|
17272
17327
|
const indexName = node.attribs?.["wx:for-index"]?.trim() || "index";
|
|
17273
17328
|
return items.map(([index, item]) => ({
|
|
@@ -17382,12 +17437,16 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17382
17437
|
const componentScopeId = `${instancePath}/${clonedNode.name}`;
|
|
17383
17438
|
const ownerScopeId = scope.getScopeId().includes("/") ? scope.getScopeId() : void 0;
|
|
17384
17439
|
const { nextProperties, bindingExpressions } = resolveComponentProperties(clonedNode, scope, componentEntry.definition);
|
|
17440
|
+
const genericComponents = resolveComponentGenerics(context, clonedNode, ownerJsonPath, ownerFilePath, componentEntry.filePath);
|
|
17441
|
+
const slots = collectComponentSlots(clonedNode, scope, ownerJsonPath, ownerFilePath, componentScopeId, templateRenderState);
|
|
17385
17442
|
let componentInstance = context.componentCache.get(componentScopeId);
|
|
17386
|
-
if (!componentInstance) componentInstance = createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId)
|
|
17443
|
+
if (!componentInstance) componentInstance = createRuntimeComponentInstance(componentScopeId, context, clonedNode, componentEntry, nextProperties, ownerScopeId, (instance) => {
|
|
17444
|
+
const initialScope = createComponentScope(clonedNode, scope, componentScopeId, instance, genericComponents, slots);
|
|
17445
|
+
context.componentScopes.set(componentScopeId, initialScope);
|
|
17446
|
+
renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, initialScope, componentScopeId, /* @__PURE__ */ new Set());
|
|
17447
|
+
});
|
|
17387
17448
|
else syncComponentProperties(componentInstance, componentInstance.__definition__ ?? componentEntry.definition, nextProperties, bindingExpressions, context.changedPageKeys);
|
|
17388
17449
|
seenComponentScopes.add(componentScopeId);
|
|
17389
|
-
const genericComponents = resolveComponentGenerics(context, clonedNode, ownerJsonPath, ownerFilePath, componentEntry.filePath);
|
|
17390
|
-
const slots = collectComponentSlots(clonedNode, scope, ownerJsonPath, ownerFilePath, componentScopeId, templateRenderState);
|
|
17391
17450
|
const componentScope = createComponentScope(clonedNode, scope, componentScopeId, componentInstance, genericComponents, slots);
|
|
17392
17451
|
context.componentScopes.set(componentScopeId, componentScope);
|
|
17393
17452
|
const renderedComponentRoot = renderRuntimeComponentTemplate(context, componentEntry, renderNodeTree, componentScope, componentScopeId, seenComponentScopes);
|
|
@@ -17397,6 +17456,10 @@ function renderNodeTree(node, scope, context, ownerJsonPath, ownerFilePath, inst
|
|
|
17397
17456
|
...clonedNode.attribs,
|
|
17398
17457
|
...renderedComponentRoot.attribs
|
|
17399
17458
|
};
|
|
17459
|
+
if (clonedNode.dataset || renderedComponentRoot.dataset) renderedComponentRoot.dataset = {
|
|
17460
|
+
...clonedNode.dataset,
|
|
17461
|
+
...renderedComponentRoot.dataset
|
|
17462
|
+
};
|
|
17400
17463
|
renderedComponentRoot.attribs["data-sim-component"] = clonedNode.name;
|
|
17401
17464
|
renderedComponentRoot.attribs["data-sim-node"] = instancePath;
|
|
17402
17465
|
renderedComponentRoot.attribs["data-sim-scope"] = componentScopeId;
|
|
@@ -17440,7 +17503,8 @@ function renderRuntimePageTree(context, page) {
|
|
|
17440
17503
|
const pageAttaching = isComponentPageAttaching(page);
|
|
17441
17504
|
const attached = !pageAttaching && flushComponentAttachments([...seenComponentScopes].map((scopeId) => context.componentCache.get(scopeId)), (instance) => runComponentLifecycle(instance, "attached"));
|
|
17442
17505
|
const removed = [...context.componentCache].filter(([scopeId]) => scopeId.startsWith(`${pageScopeId}/`) && !seenComponentScopes.has(scopeId));
|
|
17443
|
-
for (const [, instance] of removed) runComponentLifecycle(instance, "detached");
|
|
17506
|
+
for (const [scopeId, instance] of removed) if (isComponentAttached(instance)) runComponentLifecycle(instance, "detached");
|
|
17507
|
+
else scheduleDiscardedComponentReady(context.componentCache, scopeId, instance);
|
|
17444
17508
|
const instances = [...seenComponentScopes].map((scopeId) => context.componentCache.get(scopeId));
|
|
17445
17509
|
const relationsChanged = !pageAttaching && !hasPendingComponentAttachments(instances) && syncComponentRelations(context.componentCache, seenComponentScopes, pageScopeId);
|
|
17446
17510
|
for (const [scopeId] of removed) {
|
|
@@ -17448,6 +17512,7 @@ function renderRuntimePageTree(context, page) {
|
|
|
17448
17512
|
context.componentScopes.delete(scopeId);
|
|
17449
17513
|
}
|
|
17450
17514
|
if (pageAttached || attached || relationsChanged) return renderRuntimePageTree(context, page);
|
|
17515
|
+
if (!isPageBeforeReady(page)) flushDiscardedComponentReady(context.componentCache, pageScopeId, (instance) => runComponentLifecycle(instance, "ready"));
|
|
17451
17516
|
if (!isPageBeforeReady(page) && flushComponentReady(instances, (instance) => {
|
|
17452
17517
|
runComponentLifecycle(instance, "ready");
|
|
17453
17518
|
if (instance !== context.componentCache.get(customTabBarScopeId(route))) instance.__definition__?.pageLifetimes?.show?.call(instance);
|
|
@@ -37714,23 +37779,11 @@ function queryXPathElements(root, expression) {
|
|
|
37714
37779
|
}
|
|
37715
37780
|
//#endregion
|
|
37716
37781
|
//#region ../../mpcore/packages/simulator/src/view/nodeHandle.ts
|
|
37717
|
-
const DATASET_NAME_RE$2 = /-([a-z])/g;
|
|
37718
37782
|
function escapeText$1(text) {
|
|
37719
37783
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">");
|
|
37720
37784
|
}
|
|
37721
|
-
function toDatasetKey$2(attributeName) {
|
|
37722
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE$2, (_match, char) => char.toUpperCase());
|
|
37723
|
-
}
|
|
37724
|
-
function collectDataset$2(node) {
|
|
37725
|
-
const dataset = {};
|
|
37726
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
37727
|
-
if (!key.startsWith("data-") || key.startsWith("data-sim-")) continue;
|
|
37728
|
-
dataset[toDatasetKey$2(key)] = value;
|
|
37729
|
-
}
|
|
37730
|
-
return dataset;
|
|
37731
|
-
}
|
|
37732
37785
|
function createEventPayload$1(node, eventName, event) {
|
|
37733
|
-
const dataset =
|
|
37786
|
+
const dataset = collectNodeDataset(node);
|
|
37734
37787
|
const nodeId = node.attribs?.id ?? "";
|
|
37735
37788
|
return {
|
|
37736
37789
|
bubbles: false,
|
|
@@ -37818,7 +37871,7 @@ var HeadlessTestingNodeHandle = class HeadlessTestingNodeHandle {
|
|
|
37818
37871
|
}
|
|
37819
37872
|
async dataset() {
|
|
37820
37873
|
this.assertActive();
|
|
37821
|
-
return
|
|
37874
|
+
return collectNodeDataset(this.node);
|
|
37822
37875
|
}
|
|
37823
37876
|
async scope() {
|
|
37824
37877
|
this.assertActive();
|
|
@@ -37893,13 +37946,19 @@ var HeadlessTestingNodeHandle = class HeadlessTestingNodeHandle {
|
|
|
37893
37946
|
//#region ../../mpcore/packages/simulator/src/view/render.ts
|
|
37894
37947
|
const LEADING_SLASH_RE$2 = /^\/+/;
|
|
37895
37948
|
const TEMPLATE_INTERPOLATION_RE = /\{\{([^{}]+)\}\}/g;
|
|
37896
|
-
function
|
|
37949
|
+
function resolveRawValueByPath(source, expression) {
|
|
37897
37950
|
const normalized = expression.trim();
|
|
37898
|
-
if (!normalized) return
|
|
37951
|
+
if (!normalized) return;
|
|
37899
37952
|
const segments = normalized.split(".").filter(Boolean);
|
|
37900
37953
|
let current = source;
|
|
37901
|
-
for (const segment of segments)
|
|
37902
|
-
|
|
37954
|
+
for (const segment of segments) {
|
|
37955
|
+
if (current == null || typeof current !== "object" && typeof current !== "function") return;
|
|
37956
|
+
current = Reflect.get(current, segment);
|
|
37957
|
+
}
|
|
37958
|
+
return current;
|
|
37959
|
+
}
|
|
37960
|
+
function resolveValueByPath(source, expression) {
|
|
37961
|
+
return resolveRawValueByPath(source, expression) ?? "";
|
|
37903
37962
|
}
|
|
37904
37963
|
function interpolateTemplate(input, data) {
|
|
37905
37964
|
return input.replace(TEMPLATE_INTERPOLATION_RE, (_match, expression) => {
|
|
@@ -37907,6 +37966,10 @@ function interpolateTemplate(input, data) {
|
|
|
37907
37966
|
return typeof value === "string" ? value : String(value);
|
|
37908
37967
|
});
|
|
37909
37968
|
}
|
|
37969
|
+
function isMustacheOnly(value) {
|
|
37970
|
+
const trimmed = value.trim();
|
|
37971
|
+
return trimmed.startsWith("{{") && trimmed.endsWith("}}") && !trimmed.includes("{{", 2);
|
|
37972
|
+
}
|
|
37910
37973
|
function visitDom(node, visitor) {
|
|
37911
37974
|
visitor(node);
|
|
37912
37975
|
for (const child of node.children ?? []) visitDom(child, visitor);
|
|
@@ -37914,7 +37977,18 @@ function visitDom(node, visitor) {
|
|
|
37914
37977
|
function interpolateDomTree(root, data) {
|
|
37915
37978
|
visitDom(root, (node) => {
|
|
37916
37979
|
if (typeof node.data === "string") node.data = interpolateTemplateText(node.data, data);
|
|
37917
|
-
if (node.attribs)
|
|
37980
|
+
if (node.attribs) {
|
|
37981
|
+
let dataset;
|
|
37982
|
+
for (const [key, value] of Object.entries(node.attribs)) {
|
|
37983
|
+
const resolvedValue = isMustacheOnly(value) ? resolveRawValueByPath(data, value.trim().slice(2, -2)) : interpolateTemplate(value, data);
|
|
37984
|
+
node.attribs[key] = String(resolvedValue ?? "");
|
|
37985
|
+
if (isDatasetAttribute(key)) {
|
|
37986
|
+
dataset ??= {};
|
|
37987
|
+
dataset[toDatasetKey(key)] = resolvedValue;
|
|
37988
|
+
}
|
|
37989
|
+
}
|
|
37990
|
+
node.dataset = dataset;
|
|
37991
|
+
}
|
|
37918
37992
|
});
|
|
37919
37993
|
}
|
|
37920
37994
|
function escapeText(text) {
|
|
@@ -37948,21 +38022,9 @@ function renderPageTree(project, page) {
|
|
|
37948
38022
|
}
|
|
37949
38023
|
//#endregion
|
|
37950
38024
|
//#region ../../mpcore/packages/simulator/src/view/selectorQuery.ts
|
|
37951
|
-
const DATASET_NAME_RE$1 = /-([a-z])/g;
|
|
37952
38025
|
const LEADING_MARK_PREFIX_RE = /^mark[:\-]?/;
|
|
37953
38026
|
const MARK_NAME_RE = /[:\-]([a-z])/g;
|
|
37954
38027
|
const NUMERIC_LIKE_VALUE_RE$1 = /-?\d+(?:\.\d+)?/;
|
|
37955
|
-
function toDatasetKey$1(attributeName) {
|
|
37956
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE$1, (_match, char) => char.toUpperCase());
|
|
37957
|
-
}
|
|
37958
|
-
function collectDataset$1(node) {
|
|
37959
|
-
const dataset = {};
|
|
37960
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
37961
|
-
if (!key.startsWith("data-") || key.startsWith("data-sim-")) continue;
|
|
37962
|
-
dataset[toDatasetKey$1(key)] = value;
|
|
37963
|
-
}
|
|
37964
|
-
return dataset;
|
|
37965
|
-
}
|
|
37966
38028
|
function toMarkKey(attributeName) {
|
|
37967
38029
|
return attributeName.replace(LEADING_MARK_PREFIX_RE, "").replace(MARK_NAME_RE, (_match, char) => char.toUpperCase());
|
|
37968
38030
|
}
|
|
@@ -38039,7 +38101,7 @@ function resolvePropertyValue(node, propertyName) {
|
|
|
38039
38101
|
if (!normalizedPropertyName) return;
|
|
38040
38102
|
if (normalizedPropertyName === "id") return node.attribs?.id ?? "";
|
|
38041
38103
|
if (normalizedPropertyName === "class") return node.attribs?.class ?? "";
|
|
38042
|
-
if (normalizedPropertyName === "dataset") return
|
|
38104
|
+
if (normalizedPropertyName === "dataset") return collectNodeDataset(node);
|
|
38043
38105
|
return node.attribs?.[normalizedPropertyName];
|
|
38044
38106
|
}
|
|
38045
38107
|
function pickProperties(node, propertyNames) {
|
|
@@ -38056,7 +38118,7 @@ function pickComputedStyle(node, propertyNames) {
|
|
|
38056
38118
|
function resolveFieldsResult(node, fields, options) {
|
|
38057
38119
|
const result = {};
|
|
38058
38120
|
if (fields.id) result.id = node.attribs?.id ?? "";
|
|
38059
|
-
if (fields.dataset) result.dataset =
|
|
38121
|
+
if (fields.dataset) result.dataset = collectNodeDataset(node);
|
|
38060
38122
|
if (fields.mark) result.mark = collectMark(node);
|
|
38061
38123
|
if (fields.rect || fields.size) {
|
|
38062
38124
|
const rect = resolveRect$1(node, options.root.name === "page" ? options.windowInfo : void 0);
|
|
@@ -38761,20 +38823,8 @@ function createHeadlessMediaQueryObserver(driver, onDisconnect) {
|
|
|
38761
38823
|
}
|
|
38762
38824
|
//#endregion
|
|
38763
38825
|
//#region ../../mpcore/packages/simulator/src/view/videoContext.ts
|
|
38764
|
-
const DATASET_NAME_RE = /-([a-z])/g;
|
|
38765
|
-
function toDatasetKey(attributeName) {
|
|
38766
|
-
return attributeName.slice(5).replace(DATASET_NAME_RE, (_match, char) => char.toUpperCase());
|
|
38767
|
-
}
|
|
38768
|
-
function collectDataset(node) {
|
|
38769
|
-
const dataset = {};
|
|
38770
|
-
for (const [key, value] of Object.entries(node.attribs ?? {})) {
|
|
38771
|
-
if (!key.startsWith("data-") || key.startsWith("data-sim-")) continue;
|
|
38772
|
-
dataset[toDatasetKey(key)] = value;
|
|
38773
|
-
}
|
|
38774
|
-
return dataset;
|
|
38775
|
-
}
|
|
38776
38826
|
function createEventPayload(node, eventName, detail) {
|
|
38777
|
-
const dataset =
|
|
38827
|
+
const dataset = collectNodeDataset(node);
|
|
38778
38828
|
const nodeId = node.attribs?.id ?? "";
|
|
38779
38829
|
return {
|
|
38780
38830
|
bubbles: false,
|
|
@@ -39290,6 +39340,110 @@ function deriveMenuButtonBoundingClientRect(systemInfo) {
|
|
|
39290
39340
|
};
|
|
39291
39341
|
}
|
|
39292
39342
|
//#endregion
|
|
39343
|
+
//#region ../../mpcore/packages/simulator/src/runtime/request/task.ts
|
|
39344
|
+
/** mock 与显式网络桥接共用终止状态;终止后不再分发 headers/chunk。 */
|
|
39345
|
+
function createRequestTask(option, onAbort = () => {}) {
|
|
39346
|
+
const headers = /* @__PURE__ */ new Set();
|
|
39347
|
+
const chunks = /* @__PURE__ */ new Set();
|
|
39348
|
+
let settled = false;
|
|
39349
|
+
function finish(result, success) {
|
|
39350
|
+
if (settled) return;
|
|
39351
|
+
settled = true;
|
|
39352
|
+
headers.clear();
|
|
39353
|
+
chunks.clear();
|
|
39354
|
+
try {
|
|
39355
|
+
if (success) option.success?.(result);
|
|
39356
|
+
else option.fail?.(result);
|
|
39357
|
+
} finally {
|
|
39358
|
+
option.complete?.(result);
|
|
39359
|
+
}
|
|
39360
|
+
}
|
|
39361
|
+
return {
|
|
39362
|
+
task: {
|
|
39363
|
+
abort() {
|
|
39364
|
+
if (settled) return;
|
|
39365
|
+
const error = Object.assign(/* @__PURE__ */ new Error("request:fail abort"), { errMsg: "request:fail abort" });
|
|
39366
|
+
try {
|
|
39367
|
+
finish(error, false);
|
|
39368
|
+
} finally {
|
|
39369
|
+
onAbort();
|
|
39370
|
+
}
|
|
39371
|
+
},
|
|
39372
|
+
onHeadersReceived(callback) {
|
|
39373
|
+
headers.add(callback);
|
|
39374
|
+
},
|
|
39375
|
+
offHeadersReceived(callback) {
|
|
39376
|
+
if (callback) headers.delete(callback);
|
|
39377
|
+
else headers.clear();
|
|
39378
|
+
},
|
|
39379
|
+
onChunkReceived(callback) {
|
|
39380
|
+
chunks.add(callback);
|
|
39381
|
+
},
|
|
39382
|
+
offChunkReceived(callback) {
|
|
39383
|
+
if (callback) chunks.delete(callback);
|
|
39384
|
+
else chunks.clear();
|
|
39385
|
+
}
|
|
39386
|
+
},
|
|
39387
|
+
get settled() {
|
|
39388
|
+
return settled;
|
|
39389
|
+
},
|
|
39390
|
+
headers(result) {
|
|
39391
|
+
if (settled) return;
|
|
39392
|
+
for (const callback of Array.from(headers)) if (!settled && headers.has(callback)) callback(result);
|
|
39393
|
+
},
|
|
39394
|
+
chunk(data) {
|
|
39395
|
+
if (settled || !option.enableChunked) return;
|
|
39396
|
+
for (const callback of Array.from(chunks)) if (!settled && chunks.has(callback)) callback({ data: data.slice(0) });
|
|
39397
|
+
},
|
|
39398
|
+
succeed(result) {
|
|
39399
|
+
finish(result, true);
|
|
39400
|
+
},
|
|
39401
|
+
fail(error) {
|
|
39402
|
+
finish(Object.assign(error, { errMsg: "errMsg" in error ? error.errMsg : error.message }), false);
|
|
39403
|
+
}
|
|
39404
|
+
};
|
|
39405
|
+
}
|
|
39406
|
+
//#endregion
|
|
39407
|
+
//#region ../../mpcore/packages/simulator/src/runtime/request/mock.ts
|
|
39408
|
+
/** 仅模拟已声明的分块;不进行网络访问,也不把完整 response 拆成假分块。 */
|
|
39409
|
+
function createChunkedMockRequest(option, mock, response, scheduler, onSuccess) {
|
|
39410
|
+
let timer;
|
|
39411
|
+
const request = createRequestTask(option, () => scheduler.clearTimeout(timer));
|
|
39412
|
+
const chunks = (mock.chunks ?? []).map((chunk) => ({
|
|
39413
|
+
...chunk,
|
|
39414
|
+
data: chunk.data.slice(0)
|
|
39415
|
+
}));
|
|
39416
|
+
let index = 0;
|
|
39417
|
+
function next() {
|
|
39418
|
+
if (request.settled) return;
|
|
39419
|
+
const chunk = chunks[index++];
|
|
39420
|
+
if (chunk) timer = scheduler.setTimeout(() => {
|
|
39421
|
+
request.chunk(chunk.data);
|
|
39422
|
+
next();
|
|
39423
|
+
}, Math.max(0, chunk.delay ?? 0));
|
|
39424
|
+
else timer = scheduler.setTimeout(() => {
|
|
39425
|
+
if (request.settled) return;
|
|
39426
|
+
if (mock.error) request.fail(new Error(mock.error));
|
|
39427
|
+
else {
|
|
39428
|
+
onSuccess();
|
|
39429
|
+
request.succeed({
|
|
39430
|
+
...response,
|
|
39431
|
+
data: ""
|
|
39432
|
+
});
|
|
39433
|
+
}
|
|
39434
|
+
}, 0);
|
|
39435
|
+
}
|
|
39436
|
+
timer = scheduler.setTimeout(() => {
|
|
39437
|
+
request.headers({
|
|
39438
|
+
cookies: response.cookies,
|
|
39439
|
+
header: response.header,
|
|
39440
|
+
statusCode: response.statusCode
|
|
39441
|
+
});
|
|
39442
|
+
next();
|
|
39443
|
+
}, Math.max(0, mock.delay ?? 0));
|
|
39444
|
+
return request.task;
|
|
39445
|
+
}
|
|
39446
|
+
//#endregion
|
|
39293
39447
|
//#region ../../mpcore/packages/simulator/src/runtime/wxState.ts
|
|
39294
39448
|
const STORAGE_LIMIT_SIZE = 10240;
|
|
39295
39449
|
const DEFAULT_MODAL_CANCEL_COLOR = "#000000";
|
|
@@ -40611,6 +40765,7 @@ function createHeadlessWxState(scheduler = nativeScheduler, options = {}) {
|
|
|
40611
40765
|
request(option) {
|
|
40612
40766
|
const matchedMock = requestMocks.find((mock) => matchesRequestMock(mock, option));
|
|
40613
40767
|
if (!matchedMock) {
|
|
40768
|
+
const request = createRequestTask(option);
|
|
40614
40769
|
const logEntry = {
|
|
40615
40770
|
data: cloneValue(option.data),
|
|
40616
40771
|
header: { ...option.header ?? {} },
|
|
@@ -40621,9 +40776,8 @@ function createHeadlessWxState(scheduler = nativeScheduler, options = {}) {
|
|
|
40621
40776
|
requestLogs.push(logEntry);
|
|
40622
40777
|
const error = /* @__PURE__ */ new Error(`No request mock matched in headless runtime: ${normalizeMethod(option.method)} ${option.url}`);
|
|
40623
40778
|
if (options.strictMocks) throw error;
|
|
40624
|
-
|
|
40625
|
-
|
|
40626
|
-
return createNoopTask();
|
|
40779
|
+
request.fail(error);
|
|
40780
|
+
return request.task;
|
|
40627
40781
|
}
|
|
40628
40782
|
const response = resolveRequestResponse(matchedMock, option);
|
|
40629
40783
|
const requestLogEntry = {
|
|
@@ -40635,20 +40789,31 @@ function createHeadlessWxState(scheduler = nativeScheduler, options = {}) {
|
|
|
40635
40789
|
url: option.url
|
|
40636
40790
|
};
|
|
40637
40791
|
const delay = Number.isFinite(matchedMock.delay) ? Math.max(0, Math.trunc(matchedMock.delay ?? 0)) : 0;
|
|
40792
|
+
if (option.enableChunked) return createChunkedMockRequest(option, matchedMock, response, scheduler, () => {
|
|
40793
|
+
requestLogs.push({
|
|
40794
|
+
...requestLogEntry,
|
|
40795
|
+
response: {
|
|
40796
|
+
...response,
|
|
40797
|
+
data: ""
|
|
40798
|
+
}
|
|
40799
|
+
});
|
|
40800
|
+
});
|
|
40801
|
+
const request = createRequestTask(option);
|
|
40638
40802
|
if (delay <= 0) {
|
|
40639
40803
|
requestLogs.push(requestLogEntry);
|
|
40640
|
-
|
|
40641
|
-
|
|
40642
|
-
return createNoopTask();
|
|
40804
|
+
request.succeed(response);
|
|
40805
|
+
return request.task;
|
|
40643
40806
|
}
|
|
40644
|
-
|
|
40807
|
+
const delayed = runDelayedTask(delay, () => {
|
|
40645
40808
|
requestLogs.push(requestLogEntry);
|
|
40646
|
-
|
|
40647
|
-
option.complete?.(response);
|
|
40809
|
+
request.succeed(response);
|
|
40648
40810
|
}, (error) => {
|
|
40649
|
-
|
|
40650
|
-
option.complete?.();
|
|
40811
|
+
request.fail(error);
|
|
40651
40812
|
}, "request:fail abort");
|
|
40813
|
+
return {
|
|
40814
|
+
...request.task,
|
|
40815
|
+
abort: delayed.abort
|
|
40816
|
+
};
|
|
40652
40817
|
},
|
|
40653
40818
|
removeSavedFile(option) {
|
|
40654
40819
|
return removeSavedFile(option.filePath);
|
|
@@ -40865,7 +41030,7 @@ function matchesComponentSelector(scope, selector) {
|
|
|
40865
41030
|
if (dataAttrMatch) {
|
|
40866
41031
|
const [, key, value] = dataAttrMatch;
|
|
40867
41032
|
const datasetKey = key.replace(DATASET_KEY_RE, (_match, char) => char.toUpperCase());
|
|
40868
|
-
return scope.dataset
|
|
41033
|
+
return scope.dataset != null && Object.hasOwn(scope.dataset, datasetKey) && String(scope.dataset[datasetKey] ?? "") === value;
|
|
40869
41034
|
}
|
|
40870
41035
|
return scope.alias === part;
|
|
40871
41036
|
});
|
|
@@ -41683,8 +41848,8 @@ var HeadlessSession = class {
|
|
|
41683
41848
|
});
|
|
41684
41849
|
pageInstance.createIntersectionObserver = (options) => this.createIntersectionObserver(pageInstance, options);
|
|
41685
41850
|
pageInstance.createMediaQueryObserver = () => this.createMediaQueryObserver(pageInstance);
|
|
41686
|
-
pageInstance.selectComponent = (selector) => this.selectComponent(selector);
|
|
41687
|
-
pageInstance.selectAllComponents = (selector) => this.selectAllComponents(selector);
|
|
41851
|
+
pageInstance.selectComponent = (selector) => resolveNativeComponentSelection(this.selectComponent(selector));
|
|
41852
|
+
pageInstance.selectAllComponents = (selector) => this.selectAllComponents(selector).map(resolveNativeComponentSelection);
|
|
41688
41853
|
pageInstance.getTabBar = () => {
|
|
41689
41854
|
if (this.currentPageInstance === pageInstance) this.renderCurrentPage();
|
|
41690
41855
|
return this.componentCache.get(customTabBarScopeId(pageInstance.route)) ?? null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weapp-vite/miniprogram-automator",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.19",
|
|
5
5
|
"description": "完全兼容微信 miniprogram-automator 的现代化替代实现",
|
|
6
6
|
"author": "ice breaker <1324318532@qq.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"node": "^20.19.0 || >=22.12.0"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@weapp-vite/qr": "1.1.
|
|
47
|
+
"@weapp-vite/qr": "1.1.4",
|
|
48
48
|
"obug": "^3.0.0",
|
|
49
49
|
"ws": "^8.21.3"
|
|
50
50
|
},
|