@immense/vue-pom-generator 1.0.35 → 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/README.md +27 -3
- package/RELEASE_NOTES.md +29 -13
- package/class-generation/index.ts +2 -2
- package/dist/class-generation/index.d.ts.map +1 -1
- package/dist/index.cjs +139 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +139 -70
- package/dist/index.mjs.map +1 -1
- package/dist/plugin/create-vue-pom-generator-plugins.d.ts.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-plugins.d.ts.map +1 -1
- package/dist/plugin/types.d.ts +17 -5
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/vue-plugin.d.ts +1 -0
- package/dist/plugin/vue-plugin.d.ts.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -147,13 +147,35 @@ export default defineConfig(() => {
|
|
|
147
147
|
|
|
148
148
|
Notes:
|
|
149
149
|
|
|
150
|
-
- `vuePomGenerator(...)`
|
|
151
|
-
- Do not pass `vue()` into `createVuePomGeneratorPlugins(...)`; pass Vue options via `vueOptions`.
|
|
150
|
+
- `vuePomGenerator(...)` wires `@vitejs/plugin-vue` internally by default for standard Vue apps.
|
|
151
|
+
- Do not pass `vue()` into `createVuePomGeneratorPlugins(...)`; pass Vue plugin options via `vueOptions`.
|
|
152
|
+
- When the app should own `vue()` explicitly, set `vuePluginOwnership: "external"` and add `vue()` separately in your Vite config.
|
|
152
153
|
|
|
153
154
|
- **Injection is enabled by plugin inclusion** (there is no longer an `injection.enabled` flag).
|
|
154
155
|
- **Generation is enabled by default** and can be disabled via `generation: false`.
|
|
155
156
|
- **Router-aware POM helpers are enabled** when `generation.router.entry` is provided (the generator will introspect your router).
|
|
156
157
|
|
|
158
|
+
### External Vue plugin ownership
|
|
159
|
+
|
|
160
|
+
If your app should own the core Vue Vite plugin explicitly, add `vue()` yourself and let this package patch the resolved plugin:
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
import vue from "@vitejs/plugin-vue";
|
|
164
|
+
import { defineConfig } from "vite";
|
|
165
|
+
import { defineVuePomGeneratorConfig, vuePomGenerator } from "@immense/vue-pom-generator";
|
|
166
|
+
|
|
167
|
+
const pomConfig = defineVuePomGeneratorConfig({
|
|
168
|
+
vuePluginOwnership: "external",
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
export default defineConfig({
|
|
172
|
+
plugins: [
|
|
173
|
+
vue(),
|
|
174
|
+
...vuePomGenerator(pomConfig),
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
157
179
|
### `generation.router`
|
|
158
180
|
|
|
159
181
|
Controls router introspection for `:to` analysis and navigation helper generation.
|
|
@@ -204,7 +226,9 @@ When you want CI/builds to fail on explicit test ids, pair `existingIdBehavior:
|
|
|
204
226
|
|
|
205
227
|
### ESLint cleanup rule: remove existing test-id attributes
|
|
206
228
|
|
|
207
|
-
Use the `remove-existing-test-id-attributes` rule to strip explicit test-id
|
|
229
|
+
Use the `remove-existing-test-id-attributes` rule to strip explicit test-id usage from `.vue` files before or while enforcing `existingIdBehavior: "error"`.
|
|
230
|
+
|
|
231
|
+
The fixer handles both template attributes like `data-testid="save-button"` and object-literal keys such as `inputAttr: { 'data-testid': 'save-button' }` inside Vue SFC expressions/scripts.
|
|
208
232
|
|
|
209
233
|
Add this to your ESLint flat-config file, typically `eslint.config.ts` (or `eslint.config.js` / `eslint.config.mjs` at the project root):
|
|
210
234
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,28 +1,44 @@
|
|
|
1
|
-
● # Release Notes: v1.0.
|
|
1
|
+
● # Release Notes: v1.0.37
|
|
2
2
|
|
|
3
3
|
## Highlights
|
|
4
|
-
|
|
5
|
-
- Added
|
|
6
|
-
|
|
4
|
+
|
|
5
|
+
- Added support for external Vue plugin ownership, enabling better plugin architecture
|
|
6
|
+
extensibility
|
|
7
|
+
- Stabilized generator plugin refactor with improved plugin handling and configuration
|
|
8
|
+
- Enhanced build plugin with expanded functionality (72+ lines added)
|
|
9
|
+
- Refactored test suite with improved coverage and organization
|
|
10
|
+
- Added automated PR release-notes preview comments to development workflow
|
|
7
11
|
|
|
8
12
|
## Changes
|
|
9
13
|
|
|
10
|
-
###
|
|
11
|
-
-
|
|
14
|
+
### Plugin System
|
|
15
|
+
- Added external Vue plugin ownership support for more flexible plugin architecture
|
|
16
|
+
- Refactored `create-vue-pom-generator-plugins.ts` with 134 lines of improvements
|
|
17
|
+
- Enhanced `build-plugin.ts` with additional capabilities and refinements
|
|
18
|
+
- Simplified `dev-plugin.ts` by removing ~34 lines of redundant code
|
|
19
|
+
- Updated plugin types with new interfaces and type definitions
|
|
20
|
+
|
|
21
|
+
### Documentation
|
|
22
|
+
- Expanded README.md with 30+ lines of additional documentation
|
|
12
23
|
|
|
13
24
|
### Testing
|
|
14
|
-
-
|
|
25
|
+
- Restructured `options.test.ts` with 163 lines of changes for better test coverage and clarity
|
|
15
26
|
|
|
16
|
-
###
|
|
17
|
-
-
|
|
27
|
+
### Code Quality
|
|
28
|
+
- Improved class generation logic
|
|
29
|
+
- Refined Vue plugin integration points
|
|
18
30
|
|
|
19
31
|
## Breaking Changes
|
|
20
|
-
|
|
32
|
+
|
|
33
|
+
None identified.
|
|
21
34
|
|
|
22
35
|
## Pull Requests Included
|
|
23
|
-
|
|
24
|
-
|
|
36
|
+
|
|
37
|
+
- [#1](https://github.com/immense/vue-pom-generator/pull/1) Add PR release-notes preview
|
|
38
|
+
comments (@dkattan)
|
|
25
39
|
|
|
26
40
|
## Testing
|
|
27
|
-
|
|
41
|
+
|
|
42
|
+
Test suite refactored and expanded in `tests/options.test.ts` with improved organization and
|
|
43
|
+
coverage.
|
|
28
44
|
|
|
@@ -233,7 +233,6 @@ function generateExtraClickMethodContent(spec: PomExtraClickMethodSpec): string
|
|
|
233
233
|
if (labelNeedsTemplate) {
|
|
234
234
|
lines.push(` const label = ${labelExpr};`);
|
|
235
235
|
}
|
|
236
|
-
|
|
237
236
|
const rootArg = rootNeedsTemplate ? "rootTestId" : rootExpr;
|
|
238
237
|
const labelArg = labelNeedsTemplate ? "label" : labelExpr;
|
|
239
238
|
lines.push(` await this.clickWithinTestIdByLabel(${rootArg}, ${labelArg}, ${annotationArg}, ${waitArg});`);
|
|
@@ -1896,8 +1895,9 @@ function getWidgetInstancesForView(
|
|
|
1896
1895
|
continue;
|
|
1897
1896
|
}
|
|
1898
1897
|
|
|
1899
|
-
if (!availableClassIdentifiers.has(className))
|
|
1898
|
+
if (!availableClassIdentifiers.has(className)) {
|
|
1900
1899
|
continue;
|
|
1900
|
+
}
|
|
1901
1901
|
|
|
1902
1902
|
// Prefer stripping the view prefix (e.g. PreferencesPage-) for cleaner member names.
|
|
1903
1903
|
const viewPrefix = `${componentName}-`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../class-generation/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oCAAoC,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,sBAAsB,EAAoE,MAAM,UAAU,CAAC;AAQpH,OAAO,EAAE,oCAAoC,EAAE,CAAC;AA8ChD,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../class-generation/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oCAAoC,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EAAE,sBAAsB,EAAoE,MAAM,UAAU,CAAC;AAQpH,OAAO,EAAE,oCAAoC,EAAE,CAAC;AA8ChD,UAAU,SAAS;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAuPD,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAE1D;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhD;;;;;OAKG;IACH,oCAAoC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAEzD;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,KAAK,CAAC;QAC3B,SAAS,EAAE,MAAM,CAAC;QAClB,YAAY,EAAE,MAAM,CAAC;QACrB,wBAAwB,EAAE,MAAM,EAAE,CAAC;QAEnC;;;WAGG;QACH,QAAQ,CAAC,EAAE,OAAO,GAAG,YAAY,GAAG,MAAM,CAAC;KAC5C,CAAC,CAAC;IAEH,yEAAyE;IACzE,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,uDAAuD;IACvD,aAAa,CAAC,EAAE,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAC;IAEvC,6BAA6B;IAC7B,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;IAEF,6EAA6E;IAC7E,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,mDAAmD;IACnD,UAAU,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAEnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CAClD;AAwCD,wBAAsB,aAAa,CACjC,qBAAqB,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC1D,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACpC,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE,oBAAyB,iBAkFnC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1005,6 +1005,18 @@ function nodeHandlerAttributeInfo(node) {
|
|
|
1005
1005
|
}
|
|
1006
1006
|
return null;
|
|
1007
1007
|
};
|
|
1008
|
+
const getRootIdentifierFromMemberChain = (node2) => {
|
|
1009
|
+
if (!node2) {
|
|
1010
|
+
return null;
|
|
1011
|
+
}
|
|
1012
|
+
if (isIdentifierNode(node2)) {
|
|
1013
|
+
return node2.name;
|
|
1014
|
+
}
|
|
1015
|
+
if (isMemberExpressionNode(node2)) {
|
|
1016
|
+
return getRootIdentifierFromMemberChain(node2.object);
|
|
1017
|
+
}
|
|
1018
|
+
return null;
|
|
1019
|
+
};
|
|
1008
1020
|
const getAssignmentTargetName = (lhs) => {
|
|
1009
1021
|
if (!lhs) {
|
|
1010
1022
|
return null;
|
|
@@ -1059,7 +1071,10 @@ function nodeHandlerAttributeInfo(node) {
|
|
|
1059
1071
|
}
|
|
1060
1072
|
if (isMemberExpressionNode(arg)) {
|
|
1061
1073
|
const stableName = getLastIdentifierFromMemberChain(arg);
|
|
1062
|
-
|
|
1074
|
+
const rootName = getRootIdentifierFromMemberChain(arg);
|
|
1075
|
+
const firstChar = (rootName ?? "").charAt(0);
|
|
1076
|
+
const isConstantLikeRoot = firstChar !== "" && firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase();
|
|
1077
|
+
if (stableName && isConstantLikeRoot) {
|
|
1063
1078
|
return toPascalCase(stableName.slice(0, 24));
|
|
1064
1079
|
}
|
|
1065
1080
|
}
|
|
@@ -1077,12 +1092,15 @@ function nodeHandlerAttributeInfo(node) {
|
|
|
1077
1092
|
const first = args.length > 0 ? args[0] : null;
|
|
1078
1093
|
if (!isObjectExpressionNode(first)) {
|
|
1079
1094
|
const parts2 = [];
|
|
1080
|
-
for (const arg of args.slice(0,
|
|
1095
|
+
for (const arg of args.slice(0, 4)) {
|
|
1081
1096
|
const w = stableWordFromValue(arg ?? null);
|
|
1082
1097
|
if (!w) {
|
|
1083
|
-
|
|
1098
|
+
continue;
|
|
1084
1099
|
}
|
|
1085
1100
|
parts2.push(w);
|
|
1101
|
+
if (parts2.length >= 2) {
|
|
1102
|
+
break;
|
|
1103
|
+
}
|
|
1086
1104
|
}
|
|
1087
1105
|
if (parts2.length === 0) {
|
|
1088
1106
|
return null;
|
|
@@ -4507,8 +4525,9 @@ function getWidgetInstancesForView(componentName, dataTestIdSet, availableClassI
|
|
|
4507
4525
|
} else {
|
|
4508
4526
|
continue;
|
|
4509
4527
|
}
|
|
4510
|
-
if (!availableClassIdentifiers.has(className))
|
|
4528
|
+
if (!availableClassIdentifiers.has(className)) {
|
|
4511
4529
|
continue;
|
|
4530
|
+
}
|
|
4512
4531
|
const viewPrefix = `${componentName}-`;
|
|
4513
4532
|
const descriptorRaw = stem.startsWith(viewPrefix) ? stem.slice(viewPrefix.length) : stem;
|
|
4514
4533
|
const descriptorPascal = toPascalCaseLocal(descriptorRaw);
|
|
@@ -4577,32 +4596,31 @@ function getConstructor(childrenComponent, componentHierarchyMap, attachmentsFor
|
|
|
4577
4596
|
return `${content}
|
|
4578
4597
|
`;
|
|
4579
4598
|
}
|
|
4580
|
-
function
|
|
4581
|
-
let
|
|
4582
|
-
let
|
|
4583
|
-
for (const
|
|
4584
|
-
selectorCount
|
|
4585
|
-
|
|
4599
|
+
function summarizeHierarchyMap(componentHierarchyMap) {
|
|
4600
|
+
let interactiveComponentCount = 0;
|
|
4601
|
+
let dataTestIdCount = 0;
|
|
4602
|
+
for (const dependencies of componentHierarchyMap.values()) {
|
|
4603
|
+
const selectorCount = dependencies.dataTestIdSet?.size ?? 0;
|
|
4604
|
+
if (selectorCount > 0) {
|
|
4605
|
+
interactiveComponentCount += 1;
|
|
4606
|
+
dataTestIdCount += selectorCount;
|
|
4607
|
+
}
|
|
4586
4608
|
}
|
|
4587
4609
|
return {
|
|
4588
4610
|
entryCount: componentHierarchyMap.size,
|
|
4589
|
-
|
|
4590
|
-
|
|
4611
|
+
interactiveComponentCount,
|
|
4612
|
+
dataTestIdCount
|
|
4591
4613
|
};
|
|
4592
4614
|
}
|
|
4593
|
-
function isLessRich(
|
|
4594
|
-
if (
|
|
4595
|
-
return
|
|
4615
|
+
function isLessRich(candidate, previous) {
|
|
4616
|
+
if (candidate.dataTestIdCount !== previous.dataTestIdCount) {
|
|
4617
|
+
return candidate.dataTestIdCount < previous.dataTestIdCount;
|
|
4596
4618
|
}
|
|
4597
|
-
if (
|
|
4598
|
-
return
|
|
4619
|
+
if (candidate.interactiveComponentCount !== previous.interactiveComponentCount) {
|
|
4620
|
+
return candidate.interactiveComponentCount < previous.interactiveComponentCount;
|
|
4599
4621
|
}
|
|
4600
|
-
return
|
|
4601
|
-
}
|
|
4602
|
-
function getGenerationMetricsKey(projectRoot, outDir) {
|
|
4603
|
-
return path.resolve(projectRoot, outDir ?? "./pom");
|
|
4622
|
+
return candidate.entryCount < previous.entryCount;
|
|
4604
4623
|
}
|
|
4605
|
-
const buildGenerationMetricsByOutputKey = /* @__PURE__ */ new Map();
|
|
4606
4624
|
function createBuildProcessorPlugin(options) {
|
|
4607
4625
|
const {
|
|
4608
4626
|
componentHierarchyMap,
|
|
@@ -4627,6 +4645,11 @@ function createBuildProcessorPlugin(options) {
|
|
|
4627
4645
|
routerModuleShims,
|
|
4628
4646
|
loggerRef
|
|
4629
4647
|
} = options;
|
|
4648
|
+
let lastGeneratedMetrics = {
|
|
4649
|
+
entryCount: 0,
|
|
4650
|
+
interactiveComponentCount: 0,
|
|
4651
|
+
dataTestIdCount: 0
|
|
4652
|
+
};
|
|
4630
4653
|
return {
|
|
4631
4654
|
name: "vue-pom-generator-build",
|
|
4632
4655
|
// This plugin exists to generate code on build output; it is not needed during dev-server HMR.
|
|
@@ -4679,17 +4702,18 @@ function createBuildProcessorPlugin(options) {
|
|
|
4679
4702
|
}
|
|
4680
4703
|
this.addWatchFile(pointerPath);
|
|
4681
4704
|
},
|
|
4682
|
-
buildEnd() {
|
|
4683
|
-
|
|
4684
|
-
|
|
4705
|
+
async buildEnd(error) {
|
|
4706
|
+
if (error) {
|
|
4707
|
+
return;
|
|
4708
|
+
}
|
|
4709
|
+
const metrics = summarizeHierarchyMap(componentHierarchyMap);
|
|
4710
|
+
if (metrics.dataTestIdCount <= 0) {
|
|
4685
4711
|
return;
|
|
4686
4712
|
}
|
|
4687
|
-
|
|
4688
|
-
const previousMetrics = buildGenerationMetricsByOutputKey.get(generationMetricsKey);
|
|
4689
|
-
if (previousMetrics && isLessRich(metrics, previousMetrics)) {
|
|
4713
|
+
if (isLessRich(metrics, lastGeneratedMetrics)) {
|
|
4690
4714
|
return;
|
|
4691
4715
|
}
|
|
4692
|
-
generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
|
|
4716
|
+
await generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
|
|
4693
4717
|
outDir,
|
|
4694
4718
|
emitLanguages,
|
|
4695
4719
|
csharp,
|
|
@@ -4706,8 +4730,8 @@ function createBuildProcessorPlugin(options) {
|
|
|
4706
4730
|
viewsDir,
|
|
4707
4731
|
scanDirs
|
|
4708
4732
|
});
|
|
4709
|
-
|
|
4710
|
-
loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.
|
|
4733
|
+
lastGeneratedMetrics = metrics;
|
|
4734
|
+
loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.interactiveComponentCount} interactive components, ${metrics.dataTestIdCount} selectors)`);
|
|
4711
4735
|
},
|
|
4712
4736
|
closeBundle() {
|
|
4713
4737
|
loggerRef.current.info("build complete");
|
|
@@ -5796,7 +5820,6 @@ Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to "overwrit
|
|
|
5796
5820
|
}
|
|
5797
5821
|
};
|
|
5798
5822
|
}
|
|
5799
|
-
const devStartupMetricsByOutputKey = /* @__PURE__ */ new Map();
|
|
5800
5823
|
function createDevProcessorPlugin(options) {
|
|
5801
5824
|
const {
|
|
5802
5825
|
nativeWrappers,
|
|
@@ -5962,11 +5985,7 @@ function createDevProcessorPlugin(options) {
|
|
|
5962
5985
|
nativeWrappers,
|
|
5963
5986
|
excludedComponents,
|
|
5964
5987
|
getViewsDirAbs(),
|
|
5965
|
-
{
|
|
5966
|
-
existingIdBehavior: "preserve",
|
|
5967
|
-
testIdAttribute,
|
|
5968
|
-
wrapperSearchRoots: getWrapperSearchRoots()
|
|
5969
|
-
}
|
|
5988
|
+
{ existingIdBehavior: "preserve", testIdAttribute, wrapperSearchRoots: getWrapperSearchRoots() }
|
|
5970
5989
|
)
|
|
5971
5990
|
]
|
|
5972
5991
|
});
|
|
@@ -5998,21 +6017,6 @@ function createDevProcessorPlugin(options) {
|
|
|
5998
6017
|
logInfo(`initial compile: ${compiledCount}/${totalVueFiles} files in ${formatMs(t1 - t0)} (components=${snapshotHierarchy.size})`);
|
|
5999
6018
|
};
|
|
6000
6019
|
const generateAggregatedFromSnapshot = (reason) => {
|
|
6001
|
-
const metrics = getGenerationMetrics(snapshotHierarchy);
|
|
6002
|
-
if (metrics.entryCount <= 0 || metrics.selectorCount <= 0) {
|
|
6003
|
-
logInfo(`generate(${reason}): skipped empty snapshot (components=${metrics.entryCount}, selectors=${metrics.selectorCount})`);
|
|
6004
|
-
return;
|
|
6005
|
-
}
|
|
6006
|
-
const generationMetricsKey = getGenerationMetricsKey(projectRootRef.current, outDir);
|
|
6007
|
-
if (reason === "startup") {
|
|
6008
|
-
const previousMetrics = devStartupMetricsByOutputKey.get(generationMetricsKey);
|
|
6009
|
-
if (previousMetrics && isLessRich(metrics, previousMetrics)) {
|
|
6010
|
-
logInfo(
|
|
6011
|
-
`generate(${reason}): skipped smaller snapshot (components=${metrics.entryCount}, selectors=${metrics.selectorCount})`
|
|
6012
|
-
);
|
|
6013
|
-
return;
|
|
6014
|
-
}
|
|
6015
|
-
}
|
|
6016
6020
|
const t0 = node_perf_hooks.performance.now();
|
|
6017
6021
|
generateFiles(snapshotHierarchy, snapshotVuePathMap, normalizedBasePagePath, {
|
|
6018
6022
|
outDir,
|
|
@@ -6027,15 +6031,10 @@ function createDevProcessorPlugin(options) {
|
|
|
6027
6031
|
testIdAttribute,
|
|
6028
6032
|
vueRouterFluentChaining: routerAwarePoms,
|
|
6029
6033
|
routerEntry: resolvedRouterEntry,
|
|
6030
|
-
routerType
|
|
6031
|
-
viewsDir,
|
|
6032
|
-
scanDirs
|
|
6034
|
+
routerType
|
|
6033
6035
|
});
|
|
6034
|
-
if (reason === "startup") {
|
|
6035
|
-
devStartupMetricsByOutputKey.set(generationMetricsKey, metrics);
|
|
6036
|
-
}
|
|
6037
6036
|
const t1 = node_perf_hooks.performance.now();
|
|
6038
|
-
logInfo(`generate(${reason}): components=${
|
|
6037
|
+
logInfo(`generate(${reason}): components=${snapshotHierarchy.size} in ${formatMs(t1 - t0)}`);
|
|
6039
6038
|
};
|
|
6040
6039
|
const initialBuildPromise = (async () => {
|
|
6041
6040
|
const t0 = node_perf_hooks.performance.now();
|
|
@@ -6282,6 +6281,7 @@ function createSupportPlugins(options) {
|
|
|
6282
6281
|
basePageClassPath,
|
|
6283
6282
|
outDir,
|
|
6284
6283
|
emitLanguages,
|
|
6284
|
+
csharp,
|
|
6285
6285
|
generateFixtures,
|
|
6286
6286
|
customPomAttachments,
|
|
6287
6287
|
customPomDir,
|
|
@@ -6646,7 +6646,7 @@ function createVuePluginWithTestIds(options) {
|
|
|
6646
6646
|
};
|
|
6647
6647
|
}
|
|
6648
6648
|
};
|
|
6649
|
-
return { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin };
|
|
6649
|
+
return { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin, templateCompilerOptions };
|
|
6650
6650
|
}
|
|
6651
6651
|
function assertNonEmptyString(value, name) {
|
|
6652
6652
|
if (!value || !value.trim()) {
|
|
@@ -6691,6 +6691,58 @@ function assertRouterModuleShims(value, name) {
|
|
|
6691
6691
|
function resolveFromProjectRoot(projectRoot, maybePath) {
|
|
6692
6692
|
return path.isAbsolute(maybePath) ? maybePath : path.resolve(projectRoot, maybePath);
|
|
6693
6693
|
}
|
|
6694
|
+
const sharedGeneratorStateRegistry = /* @__PURE__ */ new Map();
|
|
6695
|
+
function toArray(value) {
|
|
6696
|
+
return Array.isArray(value) ? value : [];
|
|
6697
|
+
}
|
|
6698
|
+
function getSharedGeneratorState(key) {
|
|
6699
|
+
let state = sharedGeneratorStateRegistry.get(key);
|
|
6700
|
+
if (!state) {
|
|
6701
|
+
state = {
|
|
6702
|
+
componentTestIds: /* @__PURE__ */ new Map(),
|
|
6703
|
+
elementMetadata: /* @__PURE__ */ new Map(),
|
|
6704
|
+
semanticNameMap: /* @__PURE__ */ new Map(),
|
|
6705
|
+
componentHierarchyMap: /* @__PURE__ */ new Map(),
|
|
6706
|
+
vueFilesPathMap: /* @__PURE__ */ new Map()
|
|
6707
|
+
};
|
|
6708
|
+
sharedGeneratorStateRegistry.set(key, state);
|
|
6709
|
+
}
|
|
6710
|
+
return state;
|
|
6711
|
+
}
|
|
6712
|
+
function applyTemplateCompilerOptionsToResolvedVuePlugin(config, templateCompilerOptions, mode) {
|
|
6713
|
+
const viteVuePlugin = (config.plugins ?? []).find((plugin) => plugin.name === "vite:vue");
|
|
6714
|
+
if (!viteVuePlugin?.api) {
|
|
6715
|
+
if (mode === "external") {
|
|
6716
|
+
throw new Error(
|
|
6717
|
+
'[vue-pom-generator] vuePluginOwnership="external" requires the resolved Vite Vue plugin, but none was found. Add vue() to your Vite plugins before spreading createVuePomGeneratorPlugins(...).'
|
|
6718
|
+
);
|
|
6719
|
+
}
|
|
6720
|
+
throw new Error("[vue-pom-generator] Nuxt mode requires the resolved Vite Vue plugin, but none was found.");
|
|
6721
|
+
}
|
|
6722
|
+
const currentOptions = viteVuePlugin.api.options ?? {};
|
|
6723
|
+
const currentTemplate = currentOptions.template ?? {};
|
|
6724
|
+
const currentCompilerOptions = currentTemplate.compilerOptions ?? {};
|
|
6725
|
+
const mergedNodeTransforms = [
|
|
6726
|
+
...toArray(currentCompilerOptions.nodeTransforms),
|
|
6727
|
+
...toArray(templateCompilerOptions.nodeTransforms)
|
|
6728
|
+
];
|
|
6729
|
+
const mergedExpressionPlugins = Array.from(/* @__PURE__ */ new Set([
|
|
6730
|
+
...toArray(currentCompilerOptions.expressionPlugins),
|
|
6731
|
+
...toArray(templateCompilerOptions.expressionPlugins)
|
|
6732
|
+
]));
|
|
6733
|
+
viteVuePlugin.api.options = {
|
|
6734
|
+
...currentOptions,
|
|
6735
|
+
template: {
|
|
6736
|
+
...currentTemplate,
|
|
6737
|
+
compilerOptions: {
|
|
6738
|
+
...currentCompilerOptions,
|
|
6739
|
+
...templateCompilerOptions,
|
|
6740
|
+
...mergedExpressionPlugins.length > 0 ? { expressionPlugins: mergedExpressionPlugins } : {},
|
|
6741
|
+
nodeTransforms: mergedNodeTransforms
|
|
6742
|
+
}
|
|
6743
|
+
}
|
|
6744
|
+
};
|
|
6745
|
+
}
|
|
6694
6746
|
function assertNotVitePluginInstance(options) {
|
|
6695
6747
|
const candidate = options;
|
|
6696
6748
|
const pluginLikeKeys = [
|
|
@@ -6709,7 +6761,7 @@ function assertNotVitePluginInstance(options) {
|
|
|
6709
6761
|
return;
|
|
6710
6762
|
}
|
|
6711
6763
|
throw new TypeError(
|
|
6712
|
-
`[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.`
|
|
6764
|
+
`[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" }.`
|
|
6713
6765
|
);
|
|
6714
6766
|
}
|
|
6715
6767
|
function createVuePomGeneratorPlugins(options = {}) {
|
|
@@ -6733,6 +6785,12 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6733
6785
|
const routerEntry = generationOptions?.router?.entry;
|
|
6734
6786
|
const routerType = generationOptions?.router?.type ?? "vue-router";
|
|
6735
6787
|
const routerModuleShims = generationOptions?.router?.moduleShims;
|
|
6788
|
+
const isNuxt = routerType === "nuxt";
|
|
6789
|
+
if (isNuxt && options.vuePluginOwnership === "internal") {
|
|
6790
|
+
throw new Error('[vue-pom-generator] Nuxt projects must use the resolved app-owned vite:vue plugin. Omit vuePluginOwnership or set it to "external".');
|
|
6791
|
+
}
|
|
6792
|
+
const vuePluginOwnership = isNuxt ? "external" : options.vuePluginOwnership ?? "internal";
|
|
6793
|
+
const usesExternalVuePlugin = vuePluginOwnership === "external";
|
|
6736
6794
|
const csharp = generationOptions?.csharp;
|
|
6737
6795
|
const generateFixtures = generationOptions?.playwright?.fixtures;
|
|
6738
6796
|
const customPoms = generationOptions?.playwright?.customPoms;
|
|
@@ -6741,6 +6799,17 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6741
6799
|
const resolvedCustomPomImportAliases = customPoms?.importAliases;
|
|
6742
6800
|
const resolvedCustomPomImportCollisionBehavior = customPoms?.importNameCollisionBehavior ?? "error";
|
|
6743
6801
|
const basePageClassPathOverride = generationOptions?.basePageClassPath;
|
|
6802
|
+
const sharedStateKey = JSON.stringify({
|
|
6803
|
+
cwd: process.cwd(),
|
|
6804
|
+
viewsDir,
|
|
6805
|
+
scanDirs,
|
|
6806
|
+
wrapperSearchRoots,
|
|
6807
|
+
outDir,
|
|
6808
|
+
testIdAttribute,
|
|
6809
|
+
routerType,
|
|
6810
|
+
vuePluginOwnership
|
|
6811
|
+
});
|
|
6812
|
+
const sharedState = getSharedGeneratorState(sharedStateKey);
|
|
6744
6813
|
const projectRootRef = { current: process.cwd() };
|
|
6745
6814
|
const loggerRef = {
|
|
6746
6815
|
current: createLogger({ verbosity })
|
|
@@ -6761,18 +6830,17 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6761
6830
|
assertNonEmptyString(routerEntry, "[vue-pom-generator] generation.router.entry");
|
|
6762
6831
|
}
|
|
6763
6832
|
}
|
|
6833
|
+
if (usesExternalVuePlugin) {
|
|
6834
|
+
applyTemplateCompilerOptionsToResolvedVuePlugin(config, templateCompilerOptions, isNuxt ? "nuxt" : vuePluginOwnership);
|
|
6835
|
+
}
|
|
6764
6836
|
loggerRef.current.info(`projectRoot=${projectRootRef.current}`);
|
|
6765
6837
|
loggerRef.current.info(`Active plugins: ${config.plugins.map((p) => p.name).filter((n) => n.includes("vue-pom")).join(", ")}`);
|
|
6766
6838
|
}
|
|
6767
6839
|
};
|
|
6768
6840
|
const getViewsDirAbs = () => resolveFromProjectRoot(projectRootRef.current, viewsDir);
|
|
6769
6841
|
const getWrapperSearchRootsAbs = () => wrapperSearchRoots.map((root) => resolveFromProjectRoot(projectRootRef.current, root));
|
|
6770
|
-
const componentTestIds
|
|
6771
|
-
const
|
|
6772
|
-
const semanticNameMap = /* @__PURE__ */ new Map();
|
|
6773
|
-
const componentHierarchyMap = /* @__PURE__ */ new Map();
|
|
6774
|
-
const vueFilesPathMap = /* @__PURE__ */ new Map();
|
|
6775
|
-
const { metadataCollectorPlugin, internalVuePlugin, nuxtVueBridgePlugin } = createVuePluginWithTestIds({
|
|
6842
|
+
const { componentTestIds, elementMetadata, semanticNameMap, componentHierarchyMap, vueFilesPathMap } = sharedState;
|
|
6843
|
+
const { metadataCollectorPlugin, internalVuePlugin, templateCompilerOptions } = createVuePluginWithTestIds({
|
|
6776
6844
|
vueOptions,
|
|
6777
6845
|
existingIdBehavior,
|
|
6778
6846
|
nameCollisionBehavior,
|
|
@@ -6816,14 +6884,15 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6816
6884
|
routerType,
|
|
6817
6885
|
routerModuleShims
|
|
6818
6886
|
});
|
|
6819
|
-
const isNuxt = routerType === "nuxt";
|
|
6820
6887
|
if (isNuxt) {
|
|
6821
6888
|
loggerRef.current.info("Nuxt environment detected. Skipping internal @vitejs/plugin-vue to avoid conflicts.");
|
|
6889
|
+
} else if (usesExternalVuePlugin) {
|
|
6890
|
+
loggerRef.current.info('vuePluginOwnership="external" enabled. Patching the resolved vite:vue plugin instead of creating an internal one.');
|
|
6822
6891
|
}
|
|
6823
6892
|
const resultPlugins = [
|
|
6824
6893
|
configPlugin,
|
|
6825
6894
|
metadataCollectorPlugin,
|
|
6826
|
-
...
|
|
6895
|
+
...usesExternalVuePlugin ? [] : [internalVuePlugin],
|
|
6827
6896
|
...supportPlugins
|
|
6828
6897
|
];
|
|
6829
6898
|
if (!generationEnabled) {
|
|
@@ -6831,7 +6900,7 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6831
6900
|
return [
|
|
6832
6901
|
configPlugin,
|
|
6833
6902
|
metadataCollectorPlugin,
|
|
6834
|
-
...
|
|
6903
|
+
...usesExternalVuePlugin ? [] : [internalVuePlugin],
|
|
6835
6904
|
virtualModules
|
|
6836
6905
|
];
|
|
6837
6906
|
}
|