@immense/vue-pom-generator 1.0.42 → 1.0.43
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 +21 -22
- package/dist/index.cjs +285 -145
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +286 -146
- 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 +12 -2
- package/dist/plugin/support/build-plugin.d.ts.map +1 -1
- package/dist/plugin/support/dev-plugin.d.ts +2 -0
- package/dist/plugin/support/dev-plugin.d.ts.map +1 -1
- package/dist/plugin/support-plugins.d.ts +2 -0
- package/dist/plugin/support-plugins.d.ts.map +1 -1
- package/dist/tests/build-serve-parity.test.d.ts +2 -0
- package/dist/tests/build-serve-parity.test.d.ts.map +1 -0
- package/package.json +1 -1
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
●
|
|
2
|
-
2026-04-06T17:25:31-05:00), only PR #6 falls within this window. PRs #1 and #4 were merged
|
|
3
|
-
earlier (February and April 1st respectively) and should not be included in v1.0.42.
|
|
1
|
+
● ## Highlights
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Snapshot maps are rebuilt atomically to prevent partial state after compilation failures
|
|
10
|
-
- Dev server behavior now matches build-mode semantics for strict snapshot errors
|
|
11
|
-
- Added regression test coverage for strict collision failures during dev startup
|
|
3
|
+
- Fixed dev-mode POM generation to achieve parity with build mode behavior
|
|
4
|
+
- Added comprehensive regression test suite (284 lines) covering build–serve parity scenarios
|
|
5
|
+
- Enhanced plugin system to ensure consistent POM generation across development and production
|
|
6
|
+
environments
|
|
12
7
|
|
|
13
8
|
## Changes
|
|
14
9
|
|
|
15
|
-
**
|
|
16
|
-
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
**Bug Fixes**
|
|
11
|
+
- Resolved discrepancies between dev-mode and build-mode POM generation (#5)
|
|
12
|
+
|
|
13
|
+
**Testing & Quality**
|
|
14
|
+
- Added build–serve parity regression tests to prevent future inconsistencies (#7)
|
|
15
|
+
- New test file: `tests/build-serve-parity.test.ts` with comprehensive coverage
|
|
20
16
|
|
|
21
|
-
**
|
|
22
|
-
-
|
|
17
|
+
**Plugin System**
|
|
18
|
+
- Extended build plugin functionality with improved POM generation logic
|
|
19
|
+
- Enhanced dev plugin to match build-mode behavior
|
|
20
|
+
- Updated support plugins for better parity handling
|
|
23
21
|
|
|
24
22
|
## Breaking Changes
|
|
25
23
|
|
|
@@ -27,12 +25,13 @@
|
|
|
27
25
|
|
|
28
26
|
## Pull Requests Included
|
|
29
27
|
|
|
30
|
-
- #
|
|
31
|
-
(
|
|
28
|
+
- [#7](https://github.com/immense/vue-pom-generator/pull/7) test: add build–serve parity
|
|
29
|
+
regression tests (by @mayfieldiv)
|
|
30
|
+
- [#5](https://github.com/immense/vue-pom-generator/pull/5) fix: dev-mode POM generation parity
|
|
31
|
+
with build mode (by @mayfieldiv)
|
|
32
32
|
|
|
33
33
|
## Testing
|
|
34
34
|
|
|
35
|
-
Added
|
|
36
|
-
|
|
37
|
-
```
|
|
35
|
+
Added 284 lines of regression tests ensuring build–serve parity. Tests validate consistent POM
|
|
36
|
+
generation behavior across development and production modes.
|
|
38
37
|
|
package/dist/index.cjs
CHANGED
|
@@ -26,13 +26,13 @@ const path = require("node:path");
|
|
|
26
26
|
const process = require("node:process");
|
|
27
27
|
const node_url = require("node:url");
|
|
28
28
|
const fs = require("node:fs");
|
|
29
|
+
const compilerDom = require("@vue/compiler-dom");
|
|
30
|
+
const compilerSfc = require("@vue/compiler-sfc");
|
|
29
31
|
const parser = require("@babel/parser");
|
|
30
32
|
const jsdom = require("jsdom");
|
|
31
33
|
const compilerCore = require("@vue/compiler-core");
|
|
32
34
|
const types = require("@babel/types");
|
|
33
35
|
const node_perf_hooks = require("node:perf_hooks");
|
|
34
|
-
const compilerDom = require("@vue/compiler-dom");
|
|
35
|
-
const compilerSfc = require("@vue/compiler-sfc");
|
|
36
36
|
const virtualImport = require("vite-plugin-virtual");
|
|
37
37
|
const vue = require("@vitejs/plugin-vue");
|
|
38
38
|
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
@@ -4768,148 +4768,6 @@ function getConstructor(childrenComponent, componentHierarchyMap, attachmentsFor
|
|
|
4768
4768
|
return `${content}
|
|
4769
4769
|
`;
|
|
4770
4770
|
}
|
|
4771
|
-
function summarizeHierarchyMap(componentHierarchyMap) {
|
|
4772
|
-
let interactiveComponentCount = 0;
|
|
4773
|
-
let dataTestIdCount = 0;
|
|
4774
|
-
for (const dependencies of componentHierarchyMap.values()) {
|
|
4775
|
-
const selectorCount = dependencies.dataTestIdSet?.size ?? 0;
|
|
4776
|
-
if (selectorCount > 0) {
|
|
4777
|
-
interactiveComponentCount += 1;
|
|
4778
|
-
dataTestIdCount += selectorCount;
|
|
4779
|
-
}
|
|
4780
|
-
}
|
|
4781
|
-
return {
|
|
4782
|
-
entryCount: componentHierarchyMap.size,
|
|
4783
|
-
interactiveComponentCount,
|
|
4784
|
-
dataTestIdCount
|
|
4785
|
-
};
|
|
4786
|
-
}
|
|
4787
|
-
function isLessRich(candidate, previous) {
|
|
4788
|
-
if (candidate.dataTestIdCount !== previous.dataTestIdCount) {
|
|
4789
|
-
return candidate.dataTestIdCount < previous.dataTestIdCount;
|
|
4790
|
-
}
|
|
4791
|
-
if (candidate.interactiveComponentCount !== previous.interactiveComponentCount) {
|
|
4792
|
-
return candidate.interactiveComponentCount < previous.interactiveComponentCount;
|
|
4793
|
-
}
|
|
4794
|
-
return candidate.entryCount < previous.entryCount;
|
|
4795
|
-
}
|
|
4796
|
-
function createBuildProcessorPlugin(options) {
|
|
4797
|
-
const {
|
|
4798
|
-
componentHierarchyMap,
|
|
4799
|
-
vueFilesPathMap,
|
|
4800
|
-
viewsDir,
|
|
4801
|
-
scanDirs,
|
|
4802
|
-
basePageClassPath,
|
|
4803
|
-
normalizedBasePagePath,
|
|
4804
|
-
outDir,
|
|
4805
|
-
emitLanguages,
|
|
4806
|
-
csharp,
|
|
4807
|
-
generateFixtures,
|
|
4808
|
-
customPomAttachments,
|
|
4809
|
-
projectRootRef,
|
|
4810
|
-
customPomDir,
|
|
4811
|
-
customPomImportAliases,
|
|
4812
|
-
customPomImportNameCollisionBehavior,
|
|
4813
|
-
testIdAttribute,
|
|
4814
|
-
routerAwarePoms,
|
|
4815
|
-
resolvedRouterEntry,
|
|
4816
|
-
routerType,
|
|
4817
|
-
routerModuleShims,
|
|
4818
|
-
loggerRef
|
|
4819
|
-
} = options;
|
|
4820
|
-
let lastGeneratedMetrics = {
|
|
4821
|
-
entryCount: 0,
|
|
4822
|
-
interactiveComponentCount: 0,
|
|
4823
|
-
dataTestIdCount: 0
|
|
4824
|
-
};
|
|
4825
|
-
return {
|
|
4826
|
-
name: "vue-pom-generator-build",
|
|
4827
|
-
// This plugin exists to generate code on build output; it is not needed during dev-server HMR.
|
|
4828
|
-
apply: "build",
|
|
4829
|
-
enforce: "pre",
|
|
4830
|
-
async buildStart() {
|
|
4831
|
-
if (!routerAwarePoms) {
|
|
4832
|
-
setRouteNameToComponentNameMap(/* @__PURE__ */ new Map());
|
|
4833
|
-
setResolveToComponentNameFn(() => null);
|
|
4834
|
-
return;
|
|
4835
|
-
}
|
|
4836
|
-
let result;
|
|
4837
|
-
if (routerType === "nuxt") {
|
|
4838
|
-
result = await introspectNuxtPages(projectRootRef.current);
|
|
4839
|
-
} else {
|
|
4840
|
-
if (!resolvedRouterEntry)
|
|
4841
|
-
throw new Error("[vue-pom-generator] router.entry is required when router introspection is enabled.");
|
|
4842
|
-
result = await parseRouterFileFromCwd(resolvedRouterEntry, {
|
|
4843
|
-
moduleShims: routerModuleShims,
|
|
4844
|
-
componentNaming: {
|
|
4845
|
-
projectRoot: projectRootRef.current,
|
|
4846
|
-
viewsDirAbs: path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir),
|
|
4847
|
-
scanDirs
|
|
4848
|
-
}
|
|
4849
|
-
});
|
|
4850
|
-
}
|
|
4851
|
-
const { routeNameMap, routePathMap } = result;
|
|
4852
|
-
setRouteNameToComponentNameMap(routeNameMap);
|
|
4853
|
-
setResolveToComponentNameFn((to) => {
|
|
4854
|
-
if (typeof to === "string") {
|
|
4855
|
-
return routePathMap.get(to) ?? null;
|
|
4856
|
-
}
|
|
4857
|
-
const maybe = to;
|
|
4858
|
-
if (typeof maybe.name === "string" && maybe.name.length) {
|
|
4859
|
-
const key = toPascalCase(maybe.name);
|
|
4860
|
-
return routeNameMap.get(key) ?? null;
|
|
4861
|
-
}
|
|
4862
|
-
if (typeof maybe.path === "string" && maybe.path.length) {
|
|
4863
|
-
return routePathMap.get(maybe.path) ?? null;
|
|
4864
|
-
}
|
|
4865
|
-
return null;
|
|
4866
|
-
});
|
|
4867
|
-
if (!fs.existsSync(basePageClassPath)) {
|
|
4868
|
-
this.error(`BasePage.ts not found at ${basePageClassPath}. Ensure it is included in the build.`);
|
|
4869
|
-
}
|
|
4870
|
-
this.addWatchFile(basePageClassPath);
|
|
4871
|
-
const pointerPath = path.resolve(path.dirname(basePageClassPath), "Pointer.ts");
|
|
4872
|
-
if (!fs.existsSync(pointerPath)) {
|
|
4873
|
-
this.error(`Pointer.ts not found at ${pointerPath}. Ensure it is included in the build.`);
|
|
4874
|
-
}
|
|
4875
|
-
this.addWatchFile(pointerPath);
|
|
4876
|
-
},
|
|
4877
|
-
async buildEnd(error) {
|
|
4878
|
-
if (error) {
|
|
4879
|
-
return;
|
|
4880
|
-
}
|
|
4881
|
-
const metrics = summarizeHierarchyMap(componentHierarchyMap);
|
|
4882
|
-
if (metrics.dataTestIdCount <= 0) {
|
|
4883
|
-
return;
|
|
4884
|
-
}
|
|
4885
|
-
if (isLessRich(metrics, lastGeneratedMetrics)) {
|
|
4886
|
-
return;
|
|
4887
|
-
}
|
|
4888
|
-
await generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
|
|
4889
|
-
outDir,
|
|
4890
|
-
emitLanguages,
|
|
4891
|
-
csharp,
|
|
4892
|
-
generateFixtures,
|
|
4893
|
-
customPomAttachments,
|
|
4894
|
-
projectRoot: projectRootRef.current,
|
|
4895
|
-
customPomDir,
|
|
4896
|
-
customPomImportAliases,
|
|
4897
|
-
customPomImportNameCollisionBehavior,
|
|
4898
|
-
testIdAttribute,
|
|
4899
|
-
vueRouterFluentChaining: routerAwarePoms,
|
|
4900
|
-
routerEntry: resolvedRouterEntry,
|
|
4901
|
-
routerType,
|
|
4902
|
-
viewsDir,
|
|
4903
|
-
scanDirs
|
|
4904
|
-
});
|
|
4905
|
-
lastGeneratedMetrics = metrics;
|
|
4906
|
-
loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.interactiveComponentCount} interactive components, ${metrics.dataTestIdCount} selectors)`);
|
|
4907
|
-
},
|
|
4908
|
-
closeBundle() {
|
|
4909
|
-
loggerRef.current.info("build complete");
|
|
4910
|
-
}
|
|
4911
|
-
};
|
|
4912
|
-
}
|
|
4913
4771
|
const TESTID_CLICK_EVENT_NAME = "__testid_event__";
|
|
4914
4772
|
const TESTID_CLICK_EVENT_STRICT_FLAG = "__testid_click_event_strict__";
|
|
4915
4773
|
const CLICK_EVENT_NAME = TESTID_CLICK_EVENT_NAME;
|
|
@@ -5992,6 +5850,265 @@ Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to "overwrit
|
|
|
5992
5850
|
}
|
|
5993
5851
|
};
|
|
5994
5852
|
}
|
|
5853
|
+
function summarizeHierarchyMap(componentHierarchyMap) {
|
|
5854
|
+
let interactiveComponentCount = 0;
|
|
5855
|
+
let dataTestIdCount = 0;
|
|
5856
|
+
for (const dependencies of componentHierarchyMap.values()) {
|
|
5857
|
+
const selectorCount = dependencies.dataTestIdSet?.size ?? 0;
|
|
5858
|
+
if (selectorCount > 0) {
|
|
5859
|
+
interactiveComponentCount += 1;
|
|
5860
|
+
dataTestIdCount += selectorCount;
|
|
5861
|
+
}
|
|
5862
|
+
}
|
|
5863
|
+
return {
|
|
5864
|
+
entryCount: componentHierarchyMap.size,
|
|
5865
|
+
interactiveComponentCount,
|
|
5866
|
+
dataTestIdCount
|
|
5867
|
+
};
|
|
5868
|
+
}
|
|
5869
|
+
function isLessRich(candidate, previous) {
|
|
5870
|
+
if (candidate.dataTestIdCount !== previous.dataTestIdCount) {
|
|
5871
|
+
return candidate.dataTestIdCount < previous.dataTestIdCount;
|
|
5872
|
+
}
|
|
5873
|
+
if (candidate.interactiveComponentCount !== previous.interactiveComponentCount) {
|
|
5874
|
+
return candidate.interactiveComponentCount < previous.interactiveComponentCount;
|
|
5875
|
+
}
|
|
5876
|
+
return candidate.entryCount < previous.entryCount;
|
|
5877
|
+
}
|
|
5878
|
+
function createBuildProcessorPlugin(options) {
|
|
5879
|
+
const {
|
|
5880
|
+
componentHierarchyMap,
|
|
5881
|
+
vueFilesPathMap,
|
|
5882
|
+
viewsDir,
|
|
5883
|
+
scanDirs,
|
|
5884
|
+
basePageClassPath,
|
|
5885
|
+
normalizedBasePagePath,
|
|
5886
|
+
outDir,
|
|
5887
|
+
emitLanguages,
|
|
5888
|
+
csharp,
|
|
5889
|
+
generateFixtures,
|
|
5890
|
+
customPomAttachments,
|
|
5891
|
+
projectRootRef,
|
|
5892
|
+
customPomDir,
|
|
5893
|
+
customPomImportAliases,
|
|
5894
|
+
customPomImportNameCollisionBehavior,
|
|
5895
|
+
testIdAttribute,
|
|
5896
|
+
nameCollisionBehavior,
|
|
5897
|
+
existingIdBehavior,
|
|
5898
|
+
nativeWrappers,
|
|
5899
|
+
excludedComponents,
|
|
5900
|
+
getWrapperSearchRoots,
|
|
5901
|
+
routerAwarePoms,
|
|
5902
|
+
resolvedRouterEntry,
|
|
5903
|
+
routerType,
|
|
5904
|
+
routerModuleShims,
|
|
5905
|
+
loggerRef
|
|
5906
|
+
} = options;
|
|
5907
|
+
let lastGeneratedMetrics = {
|
|
5908
|
+
entryCount: 0,
|
|
5909
|
+
interactiveComponentCount: 0,
|
|
5910
|
+
dataTestIdCount: 0
|
|
5911
|
+
};
|
|
5912
|
+
const getViewsDirAbs = () => path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir);
|
|
5913
|
+
const getScriptInfo = (source, filename) => {
|
|
5914
|
+
try {
|
|
5915
|
+
const { descriptor } = compilerSfc.parse(source, { filename });
|
|
5916
|
+
if (!descriptor.script && !descriptor.scriptSetup)
|
|
5917
|
+
return { bindings: void 0, isScriptSetup: false };
|
|
5918
|
+
const scriptBlock = compilerSfc.compileScript(descriptor, { id: filename });
|
|
5919
|
+
return { bindings: scriptBlock.bindings, isScriptSetup: !!descriptor.scriptSetup };
|
|
5920
|
+
} catch {
|
|
5921
|
+
return { bindings: void 0, isScriptSetup: false };
|
|
5922
|
+
}
|
|
5923
|
+
};
|
|
5924
|
+
const supplementHierarchyFromFilesystem = () => {
|
|
5925
|
+
const walkFilesRecursive = (rootDir) => {
|
|
5926
|
+
const out = [];
|
|
5927
|
+
const stack = [rootDir];
|
|
5928
|
+
while (stack.length) {
|
|
5929
|
+
const dir = stack.pop();
|
|
5930
|
+
if (!dir) continue;
|
|
5931
|
+
let entries = [];
|
|
5932
|
+
try {
|
|
5933
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
5934
|
+
} catch {
|
|
5935
|
+
continue;
|
|
5936
|
+
}
|
|
5937
|
+
for (const ent of entries) {
|
|
5938
|
+
if (ent.isDirectory()) {
|
|
5939
|
+
if (ent.name === "node_modules" || ent.name === ".git" || ent.name === "dist")
|
|
5940
|
+
continue;
|
|
5941
|
+
stack.push(path.join(dir, ent.name));
|
|
5942
|
+
continue;
|
|
5943
|
+
}
|
|
5944
|
+
if (ent.isFile() && ent.name.endsWith(".vue")) {
|
|
5945
|
+
out.push(path.join(dir, ent.name));
|
|
5946
|
+
}
|
|
5947
|
+
}
|
|
5948
|
+
}
|
|
5949
|
+
return out;
|
|
5950
|
+
};
|
|
5951
|
+
let supplemented = 0;
|
|
5952
|
+
for (const dir of scanDirs) {
|
|
5953
|
+
const absDir = path.resolve(projectRootRef.current, dir);
|
|
5954
|
+
if (!fs.existsSync(absDir))
|
|
5955
|
+
continue;
|
|
5956
|
+
for (const filePath of walkFilesRecursive(absDir)) {
|
|
5957
|
+
const absolutePath = path.resolve(filePath);
|
|
5958
|
+
const componentName = resolveComponentNameFromPath({
|
|
5959
|
+
filename: absolutePath,
|
|
5960
|
+
projectRoot: projectRootRef.current,
|
|
5961
|
+
viewsDirAbs: getViewsDirAbs(),
|
|
5962
|
+
scanDirs,
|
|
5963
|
+
extraRoots: [process.cwd()]
|
|
5964
|
+
});
|
|
5965
|
+
if (componentHierarchyMap.has(componentName))
|
|
5966
|
+
continue;
|
|
5967
|
+
let sfc = "";
|
|
5968
|
+
try {
|
|
5969
|
+
sfc = fs.readFileSync(absolutePath, "utf8");
|
|
5970
|
+
} catch {
|
|
5971
|
+
continue;
|
|
5972
|
+
}
|
|
5973
|
+
const { descriptor } = compilerSfc.parse(sfc, { filename: absolutePath });
|
|
5974
|
+
const template = descriptor.template?.content ?? "";
|
|
5975
|
+
if (!template.trim()) {
|
|
5976
|
+
vueFilesPathMap.set(componentName, absolutePath);
|
|
5977
|
+
componentHierarchyMap.set(componentName, {
|
|
5978
|
+
filePath: absolutePath,
|
|
5979
|
+
childrenComponentSet: /* @__PURE__ */ new Set(),
|
|
5980
|
+
usedComponentSet: /* @__PURE__ */ new Set(),
|
|
5981
|
+
dataTestIdSet: /* @__PURE__ */ new Set(),
|
|
5982
|
+
isView: false,
|
|
5983
|
+
methodsContent: ""
|
|
5984
|
+
});
|
|
5985
|
+
supplemented++;
|
|
5986
|
+
continue;
|
|
5987
|
+
}
|
|
5988
|
+
const { bindings: bindingMetadata, isScriptSetup } = getScriptInfo(sfc, absolutePath);
|
|
5989
|
+
vueFilesPathMap.set(componentName, absolutePath);
|
|
5990
|
+
try {
|
|
5991
|
+
compilerDom__namespace.compile(template, {
|
|
5992
|
+
filename: absolutePath,
|
|
5993
|
+
prefixIdentifiers: true,
|
|
5994
|
+
inline: isScriptSetup,
|
|
5995
|
+
bindingMetadata,
|
|
5996
|
+
nodeTransforms: [
|
|
5997
|
+
createTestIdTransform(
|
|
5998
|
+
componentName,
|
|
5999
|
+
componentHierarchyMap,
|
|
6000
|
+
nativeWrappers,
|
|
6001
|
+
excludedComponents,
|
|
6002
|
+
getViewsDirAbs(),
|
|
6003
|
+
{
|
|
6004
|
+
existingIdBehavior: existingIdBehavior ?? "preserve",
|
|
6005
|
+
testIdAttribute,
|
|
6006
|
+
nameCollisionBehavior,
|
|
6007
|
+
warn: (message) => loggerRef.current.warn(message),
|
|
6008
|
+
vueFilesPathMap,
|
|
6009
|
+
wrapperSearchRoots: getWrapperSearchRoots()
|
|
6010
|
+
}
|
|
6011
|
+
)
|
|
6012
|
+
]
|
|
6013
|
+
});
|
|
6014
|
+
} catch {
|
|
6015
|
+
}
|
|
6016
|
+
supplemented++;
|
|
6017
|
+
}
|
|
6018
|
+
}
|
|
6019
|
+
if (supplemented > 0) {
|
|
6020
|
+
loggerRef.current.info(`supplemented ${supplemented} components from filesystem walk (not in build graph)`);
|
|
6021
|
+
}
|
|
6022
|
+
};
|
|
6023
|
+
return {
|
|
6024
|
+
name: "vue-pom-generator-build",
|
|
6025
|
+
// This plugin exists to generate code on build output; it is not needed during dev-server HMR.
|
|
6026
|
+
apply: "build",
|
|
6027
|
+
enforce: "pre",
|
|
6028
|
+
async buildStart() {
|
|
6029
|
+
if (!routerAwarePoms) {
|
|
6030
|
+
setRouteNameToComponentNameMap(/* @__PURE__ */ new Map());
|
|
6031
|
+
setResolveToComponentNameFn(() => null);
|
|
6032
|
+
return;
|
|
6033
|
+
}
|
|
6034
|
+
let result;
|
|
6035
|
+
if (routerType === "nuxt") {
|
|
6036
|
+
result = await introspectNuxtPages(projectRootRef.current);
|
|
6037
|
+
} else {
|
|
6038
|
+
if (!resolvedRouterEntry)
|
|
6039
|
+
throw new Error("[vue-pom-generator] router.entry is required when router introspection is enabled.");
|
|
6040
|
+
result = await parseRouterFileFromCwd(resolvedRouterEntry, {
|
|
6041
|
+
moduleShims: routerModuleShims,
|
|
6042
|
+
componentNaming: {
|
|
6043
|
+
projectRoot: projectRootRef.current,
|
|
6044
|
+
viewsDirAbs: path.isAbsolute(viewsDir) ? viewsDir : path.resolve(projectRootRef.current, viewsDir),
|
|
6045
|
+
scanDirs
|
|
6046
|
+
}
|
|
6047
|
+
});
|
|
6048
|
+
}
|
|
6049
|
+
const { routeNameMap, routePathMap } = result;
|
|
6050
|
+
setRouteNameToComponentNameMap(routeNameMap);
|
|
6051
|
+
setResolveToComponentNameFn((to) => {
|
|
6052
|
+
if (typeof to === "string") {
|
|
6053
|
+
return routePathMap.get(to) ?? null;
|
|
6054
|
+
}
|
|
6055
|
+
const maybe = to;
|
|
6056
|
+
if (typeof maybe.name === "string" && maybe.name.length) {
|
|
6057
|
+
const key = toPascalCase(maybe.name);
|
|
6058
|
+
return routeNameMap.get(key) ?? null;
|
|
6059
|
+
}
|
|
6060
|
+
if (typeof maybe.path === "string" && maybe.path.length) {
|
|
6061
|
+
return routePathMap.get(maybe.path) ?? null;
|
|
6062
|
+
}
|
|
6063
|
+
return null;
|
|
6064
|
+
});
|
|
6065
|
+
if (!fs.existsSync(basePageClassPath)) {
|
|
6066
|
+
this.error(`BasePage.ts not found at ${basePageClassPath}. Ensure it is included in the build.`);
|
|
6067
|
+
}
|
|
6068
|
+
this.addWatchFile(basePageClassPath);
|
|
6069
|
+
const pointerPath = path.resolve(path.dirname(basePageClassPath), "Pointer.ts");
|
|
6070
|
+
if (!fs.existsSync(pointerPath)) {
|
|
6071
|
+
this.error(`Pointer.ts not found at ${pointerPath}. Ensure it is included in the build.`);
|
|
6072
|
+
}
|
|
6073
|
+
this.addWatchFile(pointerPath);
|
|
6074
|
+
},
|
|
6075
|
+
async buildEnd(error) {
|
|
6076
|
+
if (error) {
|
|
6077
|
+
return;
|
|
6078
|
+
}
|
|
6079
|
+
supplementHierarchyFromFilesystem();
|
|
6080
|
+
const metrics = summarizeHierarchyMap(componentHierarchyMap);
|
|
6081
|
+
if (metrics.dataTestIdCount <= 0) {
|
|
6082
|
+
return;
|
|
6083
|
+
}
|
|
6084
|
+
if (isLessRich(metrics, lastGeneratedMetrics)) {
|
|
6085
|
+
return;
|
|
6086
|
+
}
|
|
6087
|
+
await generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {
|
|
6088
|
+
outDir,
|
|
6089
|
+
emitLanguages,
|
|
6090
|
+
csharp,
|
|
6091
|
+
generateFixtures,
|
|
6092
|
+
customPomAttachments,
|
|
6093
|
+
projectRoot: projectRootRef.current,
|
|
6094
|
+
customPomDir,
|
|
6095
|
+
customPomImportAliases,
|
|
6096
|
+
customPomImportNameCollisionBehavior,
|
|
6097
|
+
testIdAttribute,
|
|
6098
|
+
vueRouterFluentChaining: routerAwarePoms,
|
|
6099
|
+
routerEntry: resolvedRouterEntry,
|
|
6100
|
+
routerType,
|
|
6101
|
+
viewsDir,
|
|
6102
|
+
scanDirs
|
|
6103
|
+
});
|
|
6104
|
+
lastGeneratedMetrics = metrics;
|
|
6105
|
+
loggerRef.current.info(`generated POMs (${metrics.entryCount} entries, ${metrics.interactiveComponentCount} interactive components, ${metrics.dataTestIdCount} selectors)`);
|
|
6106
|
+
},
|
|
6107
|
+
closeBundle() {
|
|
6108
|
+
loggerRef.current.info("build complete");
|
|
6109
|
+
}
|
|
6110
|
+
};
|
|
6111
|
+
}
|
|
5995
6112
|
function createDevProcessorPlugin(options) {
|
|
5996
6113
|
const {
|
|
5997
6114
|
nativeWrappers,
|
|
@@ -6011,6 +6128,7 @@ function createDevProcessorPlugin(options) {
|
|
|
6011
6128
|
customPomImportAliases,
|
|
6012
6129
|
customPomImportNameCollisionBehavior,
|
|
6013
6130
|
nameCollisionBehavior = "suffix",
|
|
6131
|
+
existingIdBehavior,
|
|
6014
6132
|
testIdAttribute,
|
|
6015
6133
|
routerAwarePoms,
|
|
6016
6134
|
resolvedRouterEntry,
|
|
@@ -6088,6 +6206,17 @@ function createDevProcessorPlugin(options) {
|
|
|
6088
6206
|
});
|
|
6089
6207
|
return descriptor.template?.content ?? "";
|
|
6090
6208
|
};
|
|
6209
|
+
const getScriptInfo = (source, filename) => {
|
|
6210
|
+
try {
|
|
6211
|
+
const { descriptor } = compilerSfc.parse(source, { filename });
|
|
6212
|
+
if (!descriptor.script && !descriptor.scriptSetup)
|
|
6213
|
+
return { bindings: void 0, isScriptSetup: false };
|
|
6214
|
+
const scriptBlock = compilerSfc.compileScript(descriptor, { id: filename });
|
|
6215
|
+
return { bindings: scriptBlock.bindings, isScriptSetup: !!descriptor.scriptSetup };
|
|
6216
|
+
} catch {
|
|
6217
|
+
return { bindings: void 0, isScriptSetup: false };
|
|
6218
|
+
}
|
|
6219
|
+
};
|
|
6091
6220
|
const walkFilesRecursive = (rootDir) => {
|
|
6092
6221
|
const out = [];
|
|
6093
6222
|
const stack = [rootDir];
|
|
@@ -6147,9 +6276,12 @@ function createDevProcessorPlugin(options) {
|
|
|
6147
6276
|
const template = extractTemplateFromSfc(sfc, absolutePath);
|
|
6148
6277
|
if (!template.trim())
|
|
6149
6278
|
return { componentName, ms: node_perf_hooks.performance.now() - started, compiled: true };
|
|
6279
|
+
const { bindings: bindingMetadata, isScriptSetup } = getScriptInfo(sfc, absolutePath);
|
|
6150
6280
|
compilerDom__namespace.compile(template, {
|
|
6151
6281
|
filename: absolutePath,
|
|
6152
6282
|
prefixIdentifiers: true,
|
|
6283
|
+
inline: isScriptSetup,
|
|
6284
|
+
bindingMetadata,
|
|
6153
6285
|
nodeTransforms: [
|
|
6154
6286
|
createTestIdTransform(
|
|
6155
6287
|
componentName,
|
|
@@ -6158,7 +6290,7 @@ function createDevProcessorPlugin(options) {
|
|
|
6158
6290
|
excludedComponents,
|
|
6159
6291
|
getViewsDirAbs(),
|
|
6160
6292
|
{
|
|
6161
|
-
existingIdBehavior: "preserve",
|
|
6293
|
+
existingIdBehavior: existingIdBehavior ?? "preserve",
|
|
6162
6294
|
nameCollisionBehavior,
|
|
6163
6295
|
testIdAttribute,
|
|
6164
6296
|
warn: (message) => loggerRef.current.warn(message),
|
|
@@ -6400,6 +6532,7 @@ function createSupportPlugins(options) {
|
|
|
6400
6532
|
scanDirs,
|
|
6401
6533
|
getWrapperSearchRoots,
|
|
6402
6534
|
nameCollisionBehavior = "suffix",
|
|
6535
|
+
existingIdBehavior,
|
|
6403
6536
|
outDir,
|
|
6404
6537
|
emitLanguages,
|
|
6405
6538
|
csharp,
|
|
@@ -6453,6 +6586,11 @@ function createSupportPlugins(options) {
|
|
|
6453
6586
|
customPomImportAliases,
|
|
6454
6587
|
customPomImportNameCollisionBehavior,
|
|
6455
6588
|
testIdAttribute,
|
|
6589
|
+
nameCollisionBehavior,
|
|
6590
|
+
existingIdBehavior,
|
|
6591
|
+
nativeWrappers,
|
|
6592
|
+
excludedComponents,
|
|
6593
|
+
getWrapperSearchRoots,
|
|
6456
6594
|
routerAwarePoms,
|
|
6457
6595
|
routerType,
|
|
6458
6596
|
resolvedRouterEntry,
|
|
@@ -6477,6 +6615,7 @@ function createSupportPlugins(options) {
|
|
|
6477
6615
|
customPomImportAliases,
|
|
6478
6616
|
customPomImportNameCollisionBehavior,
|
|
6479
6617
|
nameCollisionBehavior,
|
|
6618
|
+
existingIdBehavior,
|
|
6480
6619
|
testIdAttribute,
|
|
6481
6620
|
routerAwarePoms,
|
|
6482
6621
|
routerType,
|
|
@@ -7058,6 +7197,7 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
7058
7197
|
scanDirs,
|
|
7059
7198
|
getWrapperSearchRoots: getWrapperSearchRootsAbs,
|
|
7060
7199
|
nameCollisionBehavior,
|
|
7200
|
+
existingIdBehavior,
|
|
7061
7201
|
outDir,
|
|
7062
7202
|
emitLanguages,
|
|
7063
7203
|
csharp,
|