@immense/vue-pom-generator 1.0.36 → 1.0.37

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
@@ -4484,8 +4484,9 @@ function getWidgetInstancesForView(componentName, dataTestIdSet, availableClassI
4484
4484
  } else {
4485
4485
  continue;
4486
4486
  }
4487
- if (!availableClassIdentifiers.has(className))
4487
+ if (!availableClassIdentifiers.has(className)) {
4488
4488
  continue;
4489
+ }
4489
4490
  const viewPrefix = `${componentName}-`;
4490
4491
  const descriptorRaw = stem.startsWith(viewPrefix) ? stem.slice(viewPrefix.length) : stem;
4491
4492
  const descriptorPascal = toPascalCaseLocal(descriptorRaw);
@@ -4554,32 +4555,31 @@ function getConstructor(childrenComponent, componentHierarchyMap, attachmentsFor
4554
4555
  return `${content}
4555
4556
  `;
4556
4557
  }
4557
- function getGenerationMetrics(componentHierarchyMap) {
4558
- let selectorCount = 0;
4559
- let generatedMethodCount = 0;
4560
- for (const deps of componentHierarchyMap.values()) {
4561
- selectorCount += deps.dataTestIdSet?.size ?? 0;
4562
- generatedMethodCount += deps.generatedMethods?.size ?? 0;
4558
+ function summarizeHierarchyMap(componentHierarchyMap) {
4559
+ let interactiveComponentCount = 0;
4560
+ let dataTestIdCount = 0;
4561
+ for (const dependencies of componentHierarchyMap.values()) {
4562
+ const selectorCount = dependencies.dataTestIdSet?.size ?? 0;
4563
+ if (selectorCount > 0) {
4564
+ interactiveComponentCount += 1;
4565
+ dataTestIdCount += selectorCount;
4566
+ }
4563
4567
  }
4564
4568
  return {
4565
4569
  entryCount: componentHierarchyMap.size,
4566
- selectorCount,
4567
- generatedMethodCount
4570
+ interactiveComponentCount,
4571
+ dataTestIdCount
4568
4572
  };
4569
4573
  }
4570
- function isLessRich(current, previous) {
4571
- if (current.entryCount !== previous.entryCount) {
4572
- return current.entryCount < previous.entryCount;
4574
+ function isLessRich(candidate, previous) {
4575
+ if (candidate.dataTestIdCount !== previous.dataTestIdCount) {
4576
+ return candidate.dataTestIdCount < previous.dataTestIdCount;
4573
4577
  }
4574
- if (current.selectorCount !== previous.selectorCount) {
4575
- return current.selectorCount < previous.selectorCount;
4578
+ if (candidate.interactiveComponentCount !== previous.interactiveComponentCount) {
4579
+ return candidate.interactiveComponentCount < previous.interactiveComponentCount;
4576
4580
  }
4577
- return current.generatedMethodCount < previous.generatedMethodCount;
4578
- }
4579
- function getGenerationMetricsKey(projectRoot, outDir) {
4580
- return path.resolve(projectRoot, outDir ?? "./pom");
4581
+ return candidate.entryCount < previous.entryCount;
4581
4582
  }
4582
- const buildGenerationMetricsByOutputKey = /* @__PURE__ */ new Map();
4583
4583
  function createBuildProcessorPlugin(options) {
4584
4584
  const {
4585
4585
  componentHierarchyMap,
@@ -4604,6 +4604,11 @@ function createBuildProcessorPlugin(options) {
4604
4604
  routerModuleShims,
4605
4605
  loggerRef
4606
4606
  } = options;
4607
+ let lastGeneratedMetrics = {
4608
+ entryCount: 0,
4609
+ interactiveComponentCount: 0,
4610
+ dataTestIdCount: 0
4611
+ };
4607
4612
  return {
4608
4613
  name: "vue-pom-generator-build",
4609
4614
  // This plugin exists to generate code on build output; it is not needed during dev-server HMR.
@@ -4656,17 +4661,18 @@ function createBuildProcessorPlugin(options) {
4656
4661
  }
4657
4662
  this.addWatchFile(pointerPath);
4658
4663
  },
4659
- buildEnd() {
4660
- const metrics = getGenerationMetrics(componentHierarchyMap);
4661
- if (metrics.entryCount <= 0 || metrics.selectorCount <= 0) {
4664
+ async buildEnd(error) {
4665
+ if (error) {
4662
4666
  return;
4663
4667
  }
4664
- const generationMetricsKey = getGenerationMetricsKey(projectRootRef.current, outDir);
4665
- const previousMetrics = buildGenerationMetricsByOutputKey.get(generationMetricsKey);
4666
- if (previousMetrics && isLessRich(metrics, previousMetrics)) {
4668
+ const metrics = summarizeHierarchyMap(componentHierarchyMap);
4669
+ if (metrics.dataTestIdCount <= 0) {
4667
4670
  return;
4668
4671
  }
4669
- generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
4672
+ if (isLessRich(metrics, lastGeneratedMetrics)) {
4673
+ return;
4674
+ }
4675
+ await generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
4670
4676
  outDir,
4671
4677
  emitLanguages,
4672
4678
  csharp,
@@ -4683,8 +4689,8 @@ function createBuildProcessorPlugin(options) {
4683
4689
  viewsDir,
4684
4690
  scanDirs
4685
4691
  });
4686
- buildGenerationMetricsByOutputKey.set(generationMetricsKey, metrics);
4687
- loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.selectorCount} selectors)`);
4692
+ lastGeneratedMetrics = metrics;
4693
+ loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.interactiveComponentCount} interactive components, ${metrics.dataTestIdCount} selectors)`);
4688
4694
  },
4689
4695
  closeBundle() {
4690
4696
  loggerRef.current.info("build complete");
@@ -5773,7 +5779,6 @@ Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to "overwrit
5773
5779
  }
5774
5780
  };
5775
5781
  }
5776
- const devStartupMetricsByOutputKey = /* @__PURE__ */ new Map();
5777
5782
  function createDevProcessorPlugin(options) {
5778
5783
  const {
5779
5784
  nativeWrappers,
@@ -5939,11 +5944,7 @@ function createDevProcessorPlugin(options) {
5939
5944
  nativeWrappers,
5940
5945
  excludedComponents,
5941
5946
  getViewsDirAbs(),
5942
- {
5943
- existingIdBehavior: "preserve",
5944
- testIdAttribute,
5945
- wrapperSearchRoots: getWrapperSearchRoots()
5946
- }
5947
+ { existingIdBehavior: "preserve", testIdAttribute, wrapperSearchRoots: getWrapperSearchRoots() }
5947
5948
  )
5948
5949
  ]
5949
5950
  });
@@ -5975,21 +5976,6 @@ function createDevProcessorPlugin(options) {
5975
5976
  logInfo(`initial compile: ${compiledCount}/${totalVueFiles} files in ${formatMs(t1 - t0)} (components=${snapshotHierarchy.size})`);
5976
5977
  };
5977
5978
  const generateAggregatedFromSnapshot = (reason) => {
5978
- const metrics = getGenerationMetrics(snapshotHierarchy);
5979
- if (metrics.entryCount <= 0 || metrics.selectorCount <= 0) {
5980
- logInfo(`generate(${reason}): skipped empty snapshot (components=${metrics.entryCount}, selectors=${metrics.selectorCount})`);
5981
- return;
5982
- }
5983
- const generationMetricsKey = getGenerationMetricsKey(projectRootRef.current, outDir);
5984
- if (reason === "startup") {
5985
- const previousMetrics = devStartupMetricsByOutputKey.get(generationMetricsKey);
5986
- if (previousMetrics && isLessRich(metrics, previousMetrics)) {
5987
- logInfo(
5988
- `generate(${reason}): skipped smaller snapshot (components=${metrics.entryCount}, selectors=${metrics.selectorCount})`
5989
- );
5990
- return;
5991
- }
5992
- }
5993
5979
  const t0 = performance.now();
5994
5980
  generateFiles(snapshotHierarchy, snapshotVuePathMap, normalizedBasePagePath, {
5995
5981
  outDir,
@@ -6004,15 +5990,10 @@ function createDevProcessorPlugin(options) {
6004
5990
  testIdAttribute,
6005
5991
  vueRouterFluentChaining: routerAwarePoms,
6006
5992
  routerEntry: resolvedRouterEntry,
6007
- routerType,
6008
- viewsDir,
6009
- scanDirs
5993
+ routerType
6010
5994
  });
6011
- if (reason === "startup") {
6012
- devStartupMetricsByOutputKey.set(generationMetricsKey, metrics);
6013
- }
6014
5995
  const t1 = performance.now();
6015
- logInfo(`generate(${reason}): components=${metrics.entryCount} selectors=${metrics.selectorCount} in ${formatMs(t1 - t0)}`);
5996
+ logInfo(`generate(${reason}): components=${snapshotHierarchy.size} in ${formatMs(t1 - t0)}`);
6016
5997
  };
6017
5998
  const initialBuildPromise = (async () => {
6018
5999
  const t0 = performance.now();
@@ -6259,6 +6240,7 @@ function createSupportPlugins(options) {
6259
6240
  basePageClassPath,
6260
6241
  outDir,
6261
6242
  emitLanguages,
6243
+ csharp,
6262
6244
  generateFixtures,
6263
6245
  customPomAttachments,
6264
6246
  customPomDir,
@@ -6623,7 +6605,7 @@ function createVuePluginWithTestIds(options) {
6623
6605
  };
6624
6606
  }
6625
6607
  };
6626
- return { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin };
6608
+ return { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin, templateCompilerOptions };
6627
6609
  }
6628
6610
  function assertNonEmptyString(value, name) {
6629
6611
  if (!value || !value.trim()) {
@@ -6668,6 +6650,58 @@ function assertRouterModuleShims(value, name) {
6668
6650
  function resolveFromProjectRoot(projectRoot, maybePath) {
6669
6651
  return path.isAbsolute(maybePath) ? maybePath : path.resolve(projectRoot, maybePath);
6670
6652
  }
6653
+ const sharedGeneratorStateRegistry = /* @__PURE__ */ new Map();
6654
+ function toArray(value) {
6655
+ return Array.isArray(value) ? value : [];
6656
+ }
6657
+ function getSharedGeneratorState(key) {
6658
+ let state = sharedGeneratorStateRegistry.get(key);
6659
+ if (!state) {
6660
+ state = {
6661
+ componentTestIds: /* @__PURE__ */ new Map(),
6662
+ elementMetadata: /* @__PURE__ */ new Map(),
6663
+ semanticNameMap: /* @__PURE__ */ new Map(),
6664
+ componentHierarchyMap: /* @__PURE__ */ new Map(),
6665
+ vueFilesPathMap: /* @__PURE__ */ new Map()
6666
+ };
6667
+ sharedGeneratorStateRegistry.set(key, state);
6668
+ }
6669
+ return state;
6670
+ }
6671
+ function applyTemplateCompilerOptionsToResolvedVuePlugin(config, templateCompilerOptions, mode) {
6672
+ const viteVuePlugin = (config.plugins ?? []).find((plugin) => plugin.name === "vite:vue");
6673
+ if (!viteVuePlugin?.api) {
6674
+ if (mode === "external") {
6675
+ throw new Error(
6676
+ '[vue-pom-generator] vuePluginOwnership="external" requires the resolved Vite Vue plugin, but none was found. Add vue() to your Vite plugins before spreading createVuePomGeneratorPlugins(...).'
6677
+ );
6678
+ }
6679
+ throw new Error("[vue-pom-generator] Nuxt mode requires the resolved Vite Vue plugin, but none was found.");
6680
+ }
6681
+ const currentOptions = viteVuePlugin.api.options ?? {};
6682
+ const currentTemplate = currentOptions.template ?? {};
6683
+ const currentCompilerOptions = currentTemplate.compilerOptions ?? {};
6684
+ const mergedNodeTransforms = [
6685
+ ...toArray(currentCompilerOptions.nodeTransforms),
6686
+ ...toArray(templateCompilerOptions.nodeTransforms)
6687
+ ];
6688
+ const mergedExpressionPlugins = Array.from(/* @__PURE__ */ new Set([
6689
+ ...toArray(currentCompilerOptions.expressionPlugins),
6690
+ ...toArray(templateCompilerOptions.expressionPlugins)
6691
+ ]));
6692
+ viteVuePlugin.api.options = {
6693
+ ...currentOptions,
6694
+ template: {
6695
+ ...currentTemplate,
6696
+ compilerOptions: {
6697
+ ...currentCompilerOptions,
6698
+ ...templateCompilerOptions,
6699
+ ...mergedExpressionPlugins.length > 0 ? { expressionPlugins: mergedExpressionPlugins } : {},
6700
+ nodeTransforms: mergedNodeTransforms
6701
+ }
6702
+ }
6703
+ };
6704
+ }
6671
6705
  function assertNotVitePluginInstance(options) {
6672
6706
  const candidate = options;
6673
6707
  const pluginLikeKeys = [
@@ -6686,7 +6720,7 @@ function assertNotVitePluginInstance(options) {
6686
6720
  return;
6687
6721
  }
6688
6722
  throw new TypeError(
6689
- `[vue-pom-generator] Invalid options: received an object that looks like a Vite plugin (found key: "${pluginLikeKey}"). Do not pass vue() into createVuePomGeneratorPlugins(...). Pass Vue plugin options via { vueOptions: { ... } } instead.`
6723
+ `[vue-pom-generator] Invalid options: received an object that looks like a Vite plugin (found key: "${pluginLikeKey}"). Do not pass vue() into createVuePomGeneratorPlugins(...). Pass Vue plugin options via { vueOptions: { ... } } instead, or add vue() separately in Vite and use { vuePluginOwnership: "external" }.`
6690
6724
  );
6691
6725
  }
6692
6726
  function createVuePomGeneratorPlugins(options = {}) {
@@ -6710,6 +6744,12 @@ function createVuePomGeneratorPlugins(options = {}) {
6710
6744
  const routerEntry = generationOptions?.router?.entry;
6711
6745
  const routerType = generationOptions?.router?.type ?? "vue-router";
6712
6746
  const routerModuleShims = generationOptions?.router?.moduleShims;
6747
+ const isNuxt = routerType === "nuxt";
6748
+ if (isNuxt && options.vuePluginOwnership === "internal") {
6749
+ throw new Error('[vue-pom-generator] Nuxt projects must use the resolved app-owned vite:vue plugin. Omit vuePluginOwnership or set it to "external".');
6750
+ }
6751
+ const vuePluginOwnership = isNuxt ? "external" : options.vuePluginOwnership ?? "internal";
6752
+ const usesExternalVuePlugin = vuePluginOwnership === "external";
6713
6753
  const csharp = generationOptions?.csharp;
6714
6754
  const generateFixtures = generationOptions?.playwright?.fixtures;
6715
6755
  const customPoms = generationOptions?.playwright?.customPoms;
@@ -6718,6 +6758,17 @@ function createVuePomGeneratorPlugins(options = {}) {
6718
6758
  const resolvedCustomPomImportAliases = customPoms?.importAliases;
6719
6759
  const resolvedCustomPomImportCollisionBehavior = customPoms?.importNameCollisionBehavior ?? "error";
6720
6760
  const basePageClassPathOverride = generationOptions?.basePageClassPath;
6761
+ const sharedStateKey = JSON.stringify({
6762
+ cwd: process.cwd(),
6763
+ viewsDir,
6764
+ scanDirs,
6765
+ wrapperSearchRoots,
6766
+ outDir,
6767
+ testIdAttribute,
6768
+ routerType,
6769
+ vuePluginOwnership
6770
+ });
6771
+ const sharedState = getSharedGeneratorState(sharedStateKey);
6721
6772
  const projectRootRef = { current: process.cwd() };
6722
6773
  const loggerRef = {
6723
6774
  current: createLogger({ verbosity })
@@ -6738,18 +6789,17 @@ function createVuePomGeneratorPlugins(options = {}) {
6738
6789
  assertNonEmptyString(routerEntry, "[vue-pom-generator] generation.router.entry");
6739
6790
  }
6740
6791
  }
6792
+ if (usesExternalVuePlugin) {
6793
+ applyTemplateCompilerOptionsToResolvedVuePlugin(config, templateCompilerOptions, isNuxt ? "nuxt" : vuePluginOwnership);
6794
+ }
6741
6795
  loggerRef.current.info(`projectRoot=${projectRootRef.current}`);
6742
6796
  loggerRef.current.info(`Active plugins: ${config.plugins.map((p) => p.name).filter((n) => n.includes("vue-pom")).join(", ")}`);
6743
6797
  }
6744
6798
  };
6745
6799
  const getViewsDirAbs = () => resolveFromProjectRoot(projectRootRef.current, viewsDir);
6746
6800
  const getWrapperSearchRootsAbs = () => wrapperSearchRoots.map((root) => resolveFromProjectRoot(projectRootRef.current, root));
6747
- const componentTestIds = /* @__PURE__ */ new Map();
6748
- const elementMetadata = /* @__PURE__ */ new Map();
6749
- const semanticNameMap = /* @__PURE__ */ new Map();
6750
- const componentHierarchyMap = /* @__PURE__ */ new Map();
6751
- const vueFilesPathMap = /* @__PURE__ */ new Map();
6752
- const { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin } = createVuePluginWithTestIds({
6801
+ const { componentTestIds, elementMetadata, semanticNameMap, componentHierarchyMap, vueFilesPathMap } = sharedState;
6802
+ const { metadataCollectorPlugin, internalVuePlugin, templateCompilerOptions } = createVuePluginWithTestIds({
6753
6803
  vueOptions,
6754
6804
  existingIdBehavior,
6755
6805
  nameCollisionBehavior,
@@ -6793,14 +6843,15 @@ function createVuePomGeneratorPlugins(options = {}) {
6793
6843
  routerType,
6794
6844
  routerModuleShims
6795
6845
  });
6796
- const isNuxt = routerType === "nuxt";
6797
6846
  if (isNuxt) {
6798
6847
  loggerRef.current.info("Nuxt environment detected. Skipping internal @vitejs/plugin-vue to avoid conflicts.");
6848
+ } else if (usesExternalVuePlugin) {
6849
+ loggerRef.current.info('vuePluginOwnership="external" enabled. Patching the resolved vite:vue plugin instead of creating an internal one.');
6799
6850
  }
6800
6851
  const resultPlugins = [
6801
6852
  configPlugin,
6802
6853
  metadataCollectorPlugin,
6803
- ...isNuxt ? [nuxtVueBridgePlugin] : [internalVuePlugin],
6854
+ ...usesExternalVuePlugin ? [] : [internalVuePlugin],
6804
6855
  ...supportPlugins
6805
6856
  ];
6806
6857
  if (!generationEnabled) {
@@ -6808,7 +6859,7 @@ function createVuePomGeneratorPlugins(options = {}) {
6808
6859
  return [
6809
6860
  configPlugin,
6810
6861
  metadataCollectorPlugin,
6811
- ...isNuxt ? [nuxtVueBridgePlugin] : [internalVuePlugin],
6862
+ ...usesExternalVuePlugin ? [] : [internalVuePlugin],
6812
6863
  virtualModules
6813
6864
  ];
6814
6865
  }