@immense/vue-pom-generator 1.0.31 → 1.0.33
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/RELEASE_NOTES.md +27 -41
- package/class-generation/index.ts +19 -3
- package/dist/class-generation/index.d.ts.map +1 -1
- package/dist/index.cjs +252 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +252 -26
- package/dist/index.mjs.map +1 -1
- package/dist/plugin/support/build-plugin.d.ts.map +1 -1
- package/dist/plugin/support/dev-plugin.d.ts.map +1 -1
- package/dist/plugin/support/generation-metrics.d.ts +10 -0
- package/dist/plugin/support/generation-metrics.d.ts.map +1 -0
- package/dist/plugin/vue-plugin.d.ts +1 -0
- package/dist/plugin/vue-plugin.d.ts.map +1 -1
- package/dist/tests/generation-metrics.test.d.ts +2 -0
- package/dist/tests/generation-metrics.test.d.ts.map +1 -0
- package/dist/transform.d.ts.map +1 -1
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1818,6 +1818,12 @@ function applyResolvedDataTestId(args) {
|
|
|
1818
1818
|
const existingIdBehavior = args.existingIdBehavior ?? "preserve";
|
|
1819
1819
|
const nameCollisionBehavior = args.nameCollisionBehavior ?? "suffix";
|
|
1820
1820
|
const warn = args.warn;
|
|
1821
|
+
const getBestKeyAccessCandidates = (expr) => {
|
|
1822
|
+
if (!expr) {
|
|
1823
|
+
return [];
|
|
1824
|
+
}
|
|
1825
|
+
return expr.split("??").map((part) => part.trim()).filter(Boolean);
|
|
1826
|
+
};
|
|
1821
1827
|
let dataTestId = args.preferredGeneratedValue;
|
|
1822
1828
|
let fromExisting = false;
|
|
1823
1829
|
const existing = tryGetExistingElementDataTestId(args.element, testIdAttribute);
|
|
@@ -1840,6 +1846,7 @@ Bulk cleanup: run ESLint with the @immense/vue-pom-generator/remove-existing-tes
|
|
|
1840
1846
|
if (existingIdBehavior === "preserve") {
|
|
1841
1847
|
if (existing.isDynamic) {
|
|
1842
1848
|
if (existing.template) {
|
|
1849
|
+
const existingTemplate = existing.template;
|
|
1843
1850
|
if ((existing.templateExpressionCount ?? 0) !== 1) {
|
|
1844
1851
|
throw new Error(
|
|
1845
1852
|
`[vue-pom-generator] Existing ${attrLabel} is a template literal with multiple interpolations and cannot be preserved safely.
|
|
@@ -1850,8 +1857,8 @@ Existing ${attrLabel}: ${JSON.stringify(existing.value)}
|
|
|
1850
1857
|
Fix: reduce the template to a single key-based interpolation, or remove the explicit ${attrLabel} so it can be auto-generated.`
|
|
1851
1858
|
);
|
|
1852
1859
|
}
|
|
1853
|
-
const hasExact = args.bestKeyPlaceholder &&
|
|
1854
|
-
const hasVarAccess = args.bestKeyVariable
|
|
1860
|
+
const hasExact = args.bestKeyPlaceholder && existingTemplate.includes(args.bestKeyPlaceholder);
|
|
1861
|
+
const hasVarAccess = getBestKeyAccessCandidates(args.bestKeyVariable).some((candidate) => existingTemplate.includes(candidate));
|
|
1855
1862
|
if (!hasExact && !hasVarAccess && args.bestKeyPlaceholder) {
|
|
1856
1863
|
throw new Error(
|
|
1857
1864
|
`[vue-pom-generator] Existing ${attrLabel} appears to be missing the key placeholder needed to keep it unique.
|
|
@@ -3842,14 +3849,18 @@ function generateViewObjectModelContent(componentName, dependencies, componentHi
|
|
|
3842
3849
|
}
|
|
3843
3850
|
return false;
|
|
3844
3851
|
};
|
|
3852
|
+
const customPomClassIdentifierMap = options.customPomClassIdentifierMap ?? {};
|
|
3853
|
+
const customPomAvailableClassIdentifiers = options.customPomAvailableClassIdentifiers ?? /* @__PURE__ */ new Set();
|
|
3845
3854
|
const attachmentsForThisClass = customPomAttachments.filter((a) => {
|
|
3855
|
+
if (!Object.prototype.hasOwnProperty.call(customPomClassIdentifierMap, a.className))
|
|
3856
|
+
return false;
|
|
3846
3857
|
const scope = a.attachTo ?? "views";
|
|
3847
3858
|
const scopeOk = isView ? scope === "views" || scope === "both" : scope === "components" || scope === "both";
|
|
3848
3859
|
if (!scopeOk)
|
|
3849
3860
|
return false;
|
|
3850
3861
|
return a.attachWhenUsesComponents.some((c) => hasChildComponent(c));
|
|
3851
3862
|
}).map((a) => ({
|
|
3852
|
-
className:
|
|
3863
|
+
className: customPomClassIdentifierMap[a.className],
|
|
3853
3864
|
propertyName: a.propertyName
|
|
3854
3865
|
}));
|
|
3855
3866
|
let content = "";
|
|
@@ -3889,7 +3900,7 @@ function generateViewObjectModelContent(componentName, dependencies, componentHi
|
|
|
3889
3900
|
content += `
|
|
3890
3901
|
export class ${className} extends BasePage {
|
|
3891
3902
|
`;
|
|
3892
|
-
const widgetInstances = isView ? getWidgetInstancesForView(componentName, dependencies.dataTestIdSet) : [];
|
|
3903
|
+
const widgetInstances = isView ? getWidgetInstancesForView(componentName, dependencies.dataTestIdSet, customPomAvailableClassIdentifiers) : [];
|
|
3893
3904
|
const componentRefsForInstances = isView ? usedComponentSet?.size ? usedComponentSet : childrenComponentSet : childrenComponentSet;
|
|
3894
3905
|
if (isView && (componentRefsForInstances.size > 0 || attachmentsForThisClass.length > 0 || widgetInstances.length > 0)) {
|
|
3895
3906
|
content += getComponentInstances(componentRefsForInstances, componentHierarchyMap, attachmentsForThisClass, widgetInstances);
|
|
@@ -4047,6 +4058,7 @@ Fix by setting generation.playwright.customPoms.importAliases["${exportName}"] t
|
|
|
4047
4058
|
return customPomClassIdentifierMap2;
|
|
4048
4059
|
};
|
|
4049
4060
|
const customPomClassIdentifierMap = addCustomPomImports();
|
|
4061
|
+
const customPomAvailableClassIdentifiers = new Set(Object.values(customPomClassIdentifierMap ?? {}));
|
|
4050
4062
|
const referencedTargets = /* @__PURE__ */ new Set();
|
|
4051
4063
|
for (const [, deps] of items) {
|
|
4052
4064
|
for (const dt of deps.dataTestIdSet) {
|
|
@@ -4199,6 +4211,7 @@ Fix by setting generation.playwright.customPoms.importAliases["${exportName}"] t
|
|
|
4199
4211
|
aggregated: true,
|
|
4200
4212
|
customPomAttachments: options.customPomAttachments ?? [],
|
|
4201
4213
|
customPomClassIdentifierMap,
|
|
4214
|
+
customPomAvailableClassIdentifiers,
|
|
4202
4215
|
testIdAttribute: options.testIdAttribute,
|
|
4203
4216
|
vueRouterFluentChaining: options.vueRouterFluentChaining,
|
|
4204
4217
|
routeMetaByComponent: options.routeMetaByComponent
|
|
@@ -4293,7 +4306,7 @@ function toPascalCaseLocal(str) {
|
|
|
4293
4306
|
return preserveInternalCaps ? upperFirst(word) : upperFirst(word.toLowerCase());
|
|
4294
4307
|
}).join("");
|
|
4295
4308
|
}
|
|
4296
|
-
function getWidgetInstancesForView(componentName, dataTestIdSet) {
|
|
4309
|
+
function getWidgetInstancesForView(componentName, dataTestIdSet, availableClassIdentifiers) {
|
|
4297
4310
|
const out = [];
|
|
4298
4311
|
const usedPropNames = /* @__PURE__ */ new Set();
|
|
4299
4312
|
const ensureUnique = (base) => {
|
|
@@ -4324,6 +4337,8 @@ function getWidgetInstancesForView(componentName, dataTestIdSet) {
|
|
|
4324
4337
|
} else {
|
|
4325
4338
|
continue;
|
|
4326
4339
|
}
|
|
4340
|
+
if (!availableClassIdentifiers.has(className))
|
|
4341
|
+
continue;
|
|
4327
4342
|
const viewPrefix = `${componentName}-`;
|
|
4328
4343
|
const descriptorRaw = stem.startsWith(viewPrefix) ? stem.slice(viewPrefix.length) : stem;
|
|
4329
4344
|
const descriptorPascal = toPascalCaseLocal(descriptorRaw);
|
|
@@ -4392,6 +4407,32 @@ function getConstructor(childrenComponent, componentHierarchyMap, attachmentsFor
|
|
|
4392
4407
|
return `${content}
|
|
4393
4408
|
`;
|
|
4394
4409
|
}
|
|
4410
|
+
function getGenerationMetrics(componentHierarchyMap) {
|
|
4411
|
+
let selectorCount = 0;
|
|
4412
|
+
let generatedMethodCount = 0;
|
|
4413
|
+
for (const deps of componentHierarchyMap.values()) {
|
|
4414
|
+
selectorCount += deps.dataTestIdSet?.size ?? 0;
|
|
4415
|
+
generatedMethodCount += deps.generatedMethods?.size ?? 0;
|
|
4416
|
+
}
|
|
4417
|
+
return {
|
|
4418
|
+
entryCount: componentHierarchyMap.size,
|
|
4419
|
+
selectorCount,
|
|
4420
|
+
generatedMethodCount
|
|
4421
|
+
};
|
|
4422
|
+
}
|
|
4423
|
+
function isLessRich(current, previous) {
|
|
4424
|
+
if (current.entryCount !== previous.entryCount) {
|
|
4425
|
+
return current.entryCount < previous.entryCount;
|
|
4426
|
+
}
|
|
4427
|
+
if (current.selectorCount !== previous.selectorCount) {
|
|
4428
|
+
return current.selectorCount < previous.selectorCount;
|
|
4429
|
+
}
|
|
4430
|
+
return current.generatedMethodCount < previous.generatedMethodCount;
|
|
4431
|
+
}
|
|
4432
|
+
function getGenerationMetricsKey(projectRoot, outDir) {
|
|
4433
|
+
return path.resolve(projectRoot, outDir ?? "./pom");
|
|
4434
|
+
}
|
|
4435
|
+
const buildGenerationMetricsByOutputKey = /* @__PURE__ */ new Map();
|
|
4395
4436
|
function createBuildProcessorPlugin(options) {
|
|
4396
4437
|
const {
|
|
4397
4438
|
componentHierarchyMap,
|
|
@@ -4414,7 +4455,6 @@ function createBuildProcessorPlugin(options) {
|
|
|
4414
4455
|
routerModuleShims,
|
|
4415
4456
|
loggerRef
|
|
4416
4457
|
} = options;
|
|
4417
|
-
let lastGeneratedEntryCount = 0;
|
|
4418
4458
|
return {
|
|
4419
4459
|
name: "vue-pom-generator-build",
|
|
4420
4460
|
// This plugin exists to generate code on build output; it is not needed during dev-server HMR.
|
|
@@ -4461,11 +4501,13 @@ function createBuildProcessorPlugin(options) {
|
|
|
4461
4501
|
this.addWatchFile(pointerPath);
|
|
4462
4502
|
},
|
|
4463
4503
|
buildEnd() {
|
|
4464
|
-
const
|
|
4465
|
-
if (entryCount <= 0) {
|
|
4504
|
+
const metrics = getGenerationMetrics(componentHierarchyMap);
|
|
4505
|
+
if (metrics.entryCount <= 0 || metrics.selectorCount <= 0) {
|
|
4466
4506
|
return;
|
|
4467
4507
|
}
|
|
4468
|
-
|
|
4508
|
+
const generationMetricsKey = getGenerationMetricsKey(projectRootRef.current, outDir);
|
|
4509
|
+
const previousMetrics = buildGenerationMetricsByOutputKey.get(generationMetricsKey);
|
|
4510
|
+
if (previousMetrics && isLessRich(metrics, previousMetrics)) {
|
|
4469
4511
|
return;
|
|
4470
4512
|
}
|
|
4471
4513
|
generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
|
|
@@ -4483,8 +4525,8 @@ function createBuildProcessorPlugin(options) {
|
|
|
4483
4525
|
routerEntry: resolvedRouterEntry,
|
|
4484
4526
|
routerType
|
|
4485
4527
|
});
|
|
4486
|
-
|
|
4487
|
-
loggerRef.current.info(`generated POMs (${entryCount} entries)`);
|
|
4528
|
+
buildGenerationMetricsByOutputKey.set(generationMetricsKey, metrics);
|
|
4529
|
+
loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.selectorCount} selectors)`);
|
|
4488
4530
|
},
|
|
4489
4531
|
closeBundle() {
|
|
4490
4532
|
loggerRef.current.info("build complete");
|
|
@@ -4522,6 +4564,89 @@ function toKebabCaseTag(tag) {
|
|
|
4522
4564
|
}
|
|
4523
4565
|
return result;
|
|
4524
4566
|
}
|
|
4567
|
+
function getStaticAttributeContent(element, name) {
|
|
4568
|
+
const attr = element.props.find((prop) => {
|
|
4569
|
+
return prop.type === NodeTypes.ATTRIBUTE && prop.name === name;
|
|
4570
|
+
});
|
|
4571
|
+
return attr?.value?.content?.trim() || null;
|
|
4572
|
+
}
|
|
4573
|
+
function getNativeHtmlControlRole(element) {
|
|
4574
|
+
const tag = (element.tag || "").toLowerCase();
|
|
4575
|
+
const type = (getStaticAttributeContent(element, "type") || "").toLowerCase();
|
|
4576
|
+
if (tag === "textarea") {
|
|
4577
|
+
return "input";
|
|
4578
|
+
}
|
|
4579
|
+
if (tag === "select") {
|
|
4580
|
+
return "select";
|
|
4581
|
+
}
|
|
4582
|
+
if (tag !== "input") {
|
|
4583
|
+
return null;
|
|
4584
|
+
}
|
|
4585
|
+
if (type === "radio") {
|
|
4586
|
+
return "radio";
|
|
4587
|
+
}
|
|
4588
|
+
if (type === "checkbox") {
|
|
4589
|
+
return "checkbox";
|
|
4590
|
+
}
|
|
4591
|
+
return "input";
|
|
4592
|
+
}
|
|
4593
|
+
function normalizeControlLabelText(value) {
|
|
4594
|
+
const normalized = (value ?? "").replace(/\*/g, " ").replace(/\s+/g, " ").trim();
|
|
4595
|
+
return normalized || null;
|
|
4596
|
+
}
|
|
4597
|
+
function getLabelNodeText(labelNode) {
|
|
4598
|
+
for (const child of labelNode.children || []) {
|
|
4599
|
+
if (child.type === NodeTypes.TEXT) {
|
|
4600
|
+
const normalized2 = normalizeControlLabelText(child.content);
|
|
4601
|
+
if (normalized2) {
|
|
4602
|
+
return normalized2;
|
|
4603
|
+
}
|
|
4604
|
+
continue;
|
|
4605
|
+
}
|
|
4606
|
+
if (child.type !== NodeTypes.ELEMENT) {
|
|
4607
|
+
continue;
|
|
4608
|
+
}
|
|
4609
|
+
if (getNativeHtmlControlRole(child)) {
|
|
4610
|
+
continue;
|
|
4611
|
+
}
|
|
4612
|
+
const normalized = normalizeControlLabelText(getInnerText(child));
|
|
4613
|
+
if (normalized) {
|
|
4614
|
+
return normalized;
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
return normalizeControlLabelText(getInnerText(labelNode));
|
|
4618
|
+
}
|
|
4619
|
+
function getAssociatedLabelText(element, hierarchyMap2) {
|
|
4620
|
+
let parent = hierarchyMap2.get(element) || null;
|
|
4621
|
+
while (parent) {
|
|
4622
|
+
if (parent.tag === "label") {
|
|
4623
|
+
return getLabelNodeText(parent);
|
|
4624
|
+
}
|
|
4625
|
+
parent = hierarchyMap2.get(parent) || null;
|
|
4626
|
+
}
|
|
4627
|
+
const id = getStaticAttributeContent(element, "id");
|
|
4628
|
+
if (!id) {
|
|
4629
|
+
return null;
|
|
4630
|
+
}
|
|
4631
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
4632
|
+
for (const child of hierarchyMap2.keys()) {
|
|
4633
|
+
candidates.add(child);
|
|
4634
|
+
}
|
|
4635
|
+
for (const maybeParent of hierarchyMap2.values()) {
|
|
4636
|
+
if (maybeParent) {
|
|
4637
|
+
candidates.add(maybeParent);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
4640
|
+
for (const candidate of candidates) {
|
|
4641
|
+
if (candidate.tag !== "label") {
|
|
4642
|
+
continue;
|
|
4643
|
+
}
|
|
4644
|
+
if (getStaticAttributeContent(candidate, "for") === id) {
|
|
4645
|
+
return getLabelNodeText(candidate);
|
|
4646
|
+
}
|
|
4647
|
+
}
|
|
4648
|
+
return null;
|
|
4649
|
+
}
|
|
4525
4650
|
function normalizeSearchRoots(wrapperSearchRoots) {
|
|
4526
4651
|
const normalized = /* @__PURE__ */ new Set();
|
|
4527
4652
|
for (const root of wrapperSearchRoots) {
|
|
@@ -5189,7 +5314,9 @@ function createTestIdTransform(componentName, componentHierarchyMap, nativeWrapp
|
|
|
5189
5314
|
}
|
|
5190
5315
|
}
|
|
5191
5316
|
const getBestAvailableKeyValue = () => {
|
|
5192
|
-
const
|
|
5317
|
+
const parentNode = context.parent && typeof context.parent === "object" ? context.parent : null;
|
|
5318
|
+
const isDirectVForChild = parentNode?.type === NodeTypes.FOR;
|
|
5319
|
+
const vForKey = (isDirectVForChild ? getKeyDirectiveValue(element, context) : null) || getContainedInVForDirectiveKeyValue(context, element, hierarchyMap);
|
|
5193
5320
|
if (vForKey) return vForKey;
|
|
5194
5321
|
return getContainedInSlotDataKeyValue(element, hierarchyMap);
|
|
5195
5322
|
};
|
|
@@ -5346,6 +5473,50 @@ Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to "overwrit
|
|
|
5346
5473
|
});
|
|
5347
5474
|
return;
|
|
5348
5475
|
}
|
|
5476
|
+
const nativeHtmlRole = getNativeHtmlControlRole(element);
|
|
5477
|
+
if (nativeHtmlRole) {
|
|
5478
|
+
const rawIdentifier = getStaticAttributeContent(element, "id") || getStaticAttributeContent(element, "name");
|
|
5479
|
+
const labelText = getAssociatedLabelText(element, hierarchyMap);
|
|
5480
|
+
const { vModel, modelValue } = getModelBindingValues(element);
|
|
5481
|
+
const bindingHint = modelValue || vModel || null;
|
|
5482
|
+
const labelToken = labelText ? toPascalCase(labelText) : "";
|
|
5483
|
+
const bindingToken = bindingHint ? toPascalCase(bindingHint) : "";
|
|
5484
|
+
let identifierToken = null;
|
|
5485
|
+
let semanticNameHint2;
|
|
5486
|
+
if (nativeHtmlRole === "radio" || nativeHtmlRole === "checkbox") {
|
|
5487
|
+
if (rawIdentifier) {
|
|
5488
|
+
identifierToken = rawIdentifier;
|
|
5489
|
+
semanticNameHint2 = rawIdentifier;
|
|
5490
|
+
} else if (bindingToken && labelToken) {
|
|
5491
|
+
identifierToken = `${bindingToken}${labelToken}`;
|
|
5492
|
+
semanticNameHint2 = `${bindingHint || bindingToken} ${labelText || labelToken}`;
|
|
5493
|
+
} else if (labelToken) {
|
|
5494
|
+
identifierToken = labelToken;
|
|
5495
|
+
semanticNameHint2 = labelText || labelToken;
|
|
5496
|
+
} else if (bindingToken) {
|
|
5497
|
+
identifierToken = bindingToken;
|
|
5498
|
+
semanticNameHint2 = bindingHint || bindingToken;
|
|
5499
|
+
}
|
|
5500
|
+
} else if (rawIdentifier) {
|
|
5501
|
+
identifierToken = rawIdentifier;
|
|
5502
|
+
semanticNameHint2 = rawIdentifier;
|
|
5503
|
+
} else if (labelToken) {
|
|
5504
|
+
identifierToken = labelToken;
|
|
5505
|
+
semanticNameHint2 = labelText || labelToken;
|
|
5506
|
+
} else if (bindingToken) {
|
|
5507
|
+
identifierToken = bindingToken;
|
|
5508
|
+
semanticNameHint2 = bindingHint || bindingToken;
|
|
5509
|
+
}
|
|
5510
|
+
if (identifierToken) {
|
|
5511
|
+
const preferredGeneratedValue = bestKeyPlaceholder ? templateAttributeValue(`${componentName}-${bestKeyPlaceholder}-${identifierToken}-${nativeHtmlRole}`) : staticAttributeValue(`${componentName}-${identifierToken}-${nativeHtmlRole}`);
|
|
5512
|
+
applyResolvedDataTestIdForElement({
|
|
5513
|
+
preferredGeneratedValue,
|
|
5514
|
+
nativeRoleOverride: nativeHtmlRole,
|
|
5515
|
+
semanticNameHint: semanticNameHint2 || conditionalHint || void 0
|
|
5516
|
+
});
|
|
5517
|
+
return;
|
|
5518
|
+
}
|
|
5519
|
+
}
|
|
5349
5520
|
const innerText = getInnerText(element) || null;
|
|
5350
5521
|
const toDirective = nodeHasToDirective(element);
|
|
5351
5522
|
if (toDirective) {
|
|
@@ -5464,6 +5635,7 @@ function resolveComponentNameFromPath(options) {
|
|
|
5464
5635
|
}
|
|
5465
5636
|
return toPascalCase(path.parse(absFilename).name);
|
|
5466
5637
|
}
|
|
5638
|
+
const devStartupMetricsByOutputKey = /* @__PURE__ */ new Map();
|
|
5467
5639
|
function createDevProcessorPlugin(options) {
|
|
5468
5640
|
const {
|
|
5469
5641
|
nativeWrappers,
|
|
@@ -5657,6 +5829,21 @@ function createDevProcessorPlugin(options) {
|
|
|
5657
5829
|
logInfo(`initial compile: ${compiledCount}/${totalVueFiles} files in ${formatMs(t1 - t0)} (components=${snapshotHierarchy.size})`);
|
|
5658
5830
|
};
|
|
5659
5831
|
const generateAggregatedFromSnapshot = (reason) => {
|
|
5832
|
+
const metrics = getGenerationMetrics(snapshotHierarchy);
|
|
5833
|
+
if (metrics.entryCount <= 0 || metrics.selectorCount <= 0) {
|
|
5834
|
+
logInfo(`generate(${reason}): skipped empty snapshot (components=${metrics.entryCount}, selectors=${metrics.selectorCount})`);
|
|
5835
|
+
return;
|
|
5836
|
+
}
|
|
5837
|
+
const generationMetricsKey = getGenerationMetricsKey(projectRootRef.current, outDir);
|
|
5838
|
+
if (reason === "startup") {
|
|
5839
|
+
const previousMetrics = devStartupMetricsByOutputKey.get(generationMetricsKey);
|
|
5840
|
+
if (previousMetrics && isLessRich(metrics, previousMetrics)) {
|
|
5841
|
+
logInfo(
|
|
5842
|
+
`generate(${reason}): skipped smaller snapshot (components=${metrics.entryCount}, selectors=${metrics.selectorCount})`
|
|
5843
|
+
);
|
|
5844
|
+
return;
|
|
5845
|
+
}
|
|
5846
|
+
}
|
|
5660
5847
|
const t0 = performance.now();
|
|
5661
5848
|
generateFiles(snapshotHierarchy, snapshotVuePathMap, normalizedBasePagePath, {
|
|
5662
5849
|
outDir,
|
|
@@ -5673,8 +5860,11 @@ function createDevProcessorPlugin(options) {
|
|
|
5673
5860
|
routerEntry: resolvedRouterEntry,
|
|
5674
5861
|
routerType
|
|
5675
5862
|
});
|
|
5863
|
+
if (reason === "startup") {
|
|
5864
|
+
devStartupMetricsByOutputKey.set(generationMetricsKey, metrics);
|
|
5865
|
+
}
|
|
5676
5866
|
const t1 = performance.now();
|
|
5677
|
-
logInfo(`generate(${reason}): components=${
|
|
5867
|
+
logInfo(`generate(${reason}): components=${metrics.entryCount} selectors=${metrics.selectorCount} in ${formatMs(t1 - t0)}`);
|
|
5678
5868
|
};
|
|
5679
5869
|
const initialBuildPromise = (async () => {
|
|
5680
5870
|
const t0 = performance.now();
|
|
@@ -6195,20 +6385,21 @@ function createVuePluginWithTestIds(options) {
|
|
|
6195
6385
|
}
|
|
6196
6386
|
];
|
|
6197
6387
|
};
|
|
6388
|
+
const runtimeNodeTransform = (node, context) => {
|
|
6389
|
+
const filename = context.filename;
|
|
6390
|
+
if (!filename || !filename.endsWith(".vue") || !isFileInScope(filename)) {
|
|
6391
|
+
return;
|
|
6392
|
+
}
|
|
6393
|
+
const transforms = getNodeTransforms(filename);
|
|
6394
|
+
const ourTransform = transforms[transforms.length - 1];
|
|
6395
|
+
return ourTransform(node, context);
|
|
6396
|
+
};
|
|
6198
6397
|
const templateCompilerOptions = {
|
|
6199
6398
|
...userCompilerOptions,
|
|
6200
6399
|
prefixIdentifiers: true,
|
|
6201
6400
|
nodeTransforms: [
|
|
6202
6401
|
...userNodeTransforms,
|
|
6203
|
-
|
|
6204
|
-
const filename = context.filename;
|
|
6205
|
-
if (!filename || !filename.endsWith(".vue") || !isFileInScope(filename)) {
|
|
6206
|
-
return;
|
|
6207
|
-
}
|
|
6208
|
-
const transforms = getNodeTransforms(filename);
|
|
6209
|
-
const ourTransform = transforms[transforms.length - 1];
|
|
6210
|
-
return ourTransform(node, context);
|
|
6211
|
-
}
|
|
6402
|
+
runtimeNodeTransform
|
|
6212
6403
|
]
|
|
6213
6404
|
};
|
|
6214
6405
|
const metadataCollectorPlugin = {
|
|
@@ -6247,7 +6438,42 @@ function createVuePluginWithTestIds(options) {
|
|
|
6247
6438
|
...vueOptions,
|
|
6248
6439
|
template
|
|
6249
6440
|
});
|
|
6250
|
-
|
|
6441
|
+
const nuxtVueBridgePlugin = {
|
|
6442
|
+
name: "vue-pom-generator-nuxt-vue-bridge",
|
|
6443
|
+
apply: "serve",
|
|
6444
|
+
configResolved(config) {
|
|
6445
|
+
const viteVuePlugin = config.plugins.find((plugin) => {
|
|
6446
|
+
return typeof plugin === "object" && plugin !== null && "name" in plugin && plugin.name === "vite:vue" && "api" in plugin;
|
|
6447
|
+
});
|
|
6448
|
+
const api = viteVuePlugin?.api;
|
|
6449
|
+
if (!api) {
|
|
6450
|
+
loggerRef.current.warn("[vue-pom-generator] Nuxt bridge could not find vite:vue plugin to patch.");
|
|
6451
|
+
return;
|
|
6452
|
+
}
|
|
6453
|
+
const currentOptions = api.options ?? {};
|
|
6454
|
+
const currentTemplate = currentOptions.template ?? {};
|
|
6455
|
+
const currentCompilerOptions = currentTemplate.compilerOptions ?? {};
|
|
6456
|
+
const currentNodeTransforms = currentCompilerOptions.nodeTransforms ?? [];
|
|
6457
|
+
if (currentNodeTransforms.includes(runtimeNodeTransform)) {
|
|
6458
|
+
return;
|
|
6459
|
+
}
|
|
6460
|
+
api.options = {
|
|
6461
|
+
...currentOptions,
|
|
6462
|
+
template: {
|
|
6463
|
+
...currentTemplate,
|
|
6464
|
+
compilerOptions: {
|
|
6465
|
+
...currentCompilerOptions,
|
|
6466
|
+
prefixIdentifiers: true,
|
|
6467
|
+
nodeTransforms: [
|
|
6468
|
+
...currentNodeTransforms,
|
|
6469
|
+
runtimeNodeTransform
|
|
6470
|
+
]
|
|
6471
|
+
}
|
|
6472
|
+
}
|
|
6473
|
+
};
|
|
6474
|
+
}
|
|
6475
|
+
};
|
|
6476
|
+
return { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin };
|
|
6251
6477
|
}
|
|
6252
6478
|
function assertNonEmptyString(value, name) {
|
|
6253
6479
|
if (!value || !value.trim()) {
|
|
@@ -6373,7 +6599,7 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6373
6599
|
const semanticNameMap = /* @__PURE__ */ new Map();
|
|
6374
6600
|
const componentHierarchyMap = /* @__PURE__ */ new Map();
|
|
6375
6601
|
const vueFilesPathMap = /* @__PURE__ */ new Map();
|
|
6376
|
-
const { metadataCollectorPlugin, internalVuePlugin } = createVuePluginWithTestIds({
|
|
6602
|
+
const { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin } = createVuePluginWithTestIds({
|
|
6377
6603
|
vueOptions,
|
|
6378
6604
|
existingIdBehavior,
|
|
6379
6605
|
nameCollisionBehavior,
|
|
@@ -6424,7 +6650,7 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6424
6650
|
const resultPlugins = [
|
|
6425
6651
|
configPlugin,
|
|
6426
6652
|
metadataCollectorPlugin,
|
|
6427
|
-
...isNuxt ? [] : [internalVuePlugin],
|
|
6653
|
+
...isNuxt ? [nuxtVueBridgePlugin] : [internalVuePlugin],
|
|
6428
6654
|
...supportPlugins
|
|
6429
6655
|
];
|
|
6430
6656
|
if (!generationEnabled) {
|
|
@@ -6432,7 +6658,7 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6432
6658
|
return [
|
|
6433
6659
|
configPlugin,
|
|
6434
6660
|
metadataCollectorPlugin,
|
|
6435
|
-
...isNuxt ? [] : [internalVuePlugin],
|
|
6661
|
+
...isNuxt ? [nuxtVueBridgePlugin] : [internalVuePlugin],
|
|
6436
6662
|
virtualModules
|
|
6437
6663
|
];
|
|
6438
6664
|
}
|