@immense/vue-pom-generator 1.0.64 → 1.0.65
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 +20 -37
- package/dist/index.cjs +39 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +39 -15
- package/dist/index.mjs.map +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,48 +1,31 @@
|
|
|
1
|
-
●
|
|
1
|
+
● ## v1.0.65
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
### Highlights
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- Fixed parsing of guarded handler expressions (e.g., `@click="condition && handler"`)
|
|
6
|
+
- Improved semantic name resolution for wrapped and conditional event handlers
|
|
7
|
+
- Enhanced Vue compiler AST traversal to handle logical expressions (`&&` operators)
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
### Changes
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
build-plugin, vue-plugin) now support TypeScript expression syntax
|
|
11
|
+
**Parser Improvements**
|
|
12
|
+
- Added support for `LogicalExpression` nodes in handler attribute parsing
|
|
13
|
+
- Introduced `unwrapSemanticHelperCall` to handle Vue compiler helpers (`_unref`,
|
|
14
|
+
`_withModifiers`, etc.)
|
|
15
|
+
- Refactored `resolveSemanticName` to recursively unwrap nested expressions and guarded calls
|
|
16
|
+
- Handler names now correctly extracted from conditional expressions like `isValid &&
|
|
17
|
+
submitForm`
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
**Testing**
|
|
20
|
+
- Added test coverage for guarded handler scenarios
|
|
21
|
+
- Updated transform and utils test suites to validate new parsing logic
|
|
19
22
|
|
|
20
|
-
###
|
|
21
|
-
- Added `expressionPlugins: ["typescript"]` to all `compilerDom.compile()` call sites
|
|
22
|
-
(dev-plugin, build-plugin, vue-plugin)
|
|
23
|
-
- Vue plugin merges expression plugins with user-supplied `userCompilerOptions` to preserve
|
|
24
|
-
custom configuration
|
|
23
|
+
### Pull Requests Included
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
- Submit buttons with dynamic inner text (e.g., ternary expressions like `{{ isNew ? 'Create' :
|
|
28
|
-
'Save' }}`) now honor `missingSemanticNameBehavior: "ignore"` option
|
|
29
|
-
- Falls back to literal `"submit"` identifier when semantic name cannot be derived, generating
|
|
30
|
-
`SubmitButton` / `clickSubmit()` POM surface
|
|
31
|
-
- Default behavior (throwing on missing semantic name) remains unchanged
|
|
25
|
+
No pull request was created for this fix; it was committed directly to `main`.
|
|
32
26
|
|
|
33
27
|
### Testing
|
|
34
|
-
- Added 3 regression tests for TypeScript expression parsing and submit-button fallback behavior
|
|
35
|
-
- Test suite: 163 → 166 tests passing
|
|
36
|
-
- All validation passes: typecheck, eslint, build
|
|
37
28
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
- fix: parse TypeScript template expressions + allow submit-button fallback
|
|
41
|
-
[#20](https://github.com/immense/vue-pom-generator/pull/20)
|
|
42
|
-
|
|
43
|
-
## Testing
|
|
44
|
-
|
|
45
|
-
Validated on Nuxt 4 + Vue 3 + TypeScript codebase. Three new regression tests added covering
|
|
46
|
-
TypeScript expression parsing and submit-button fallback scenarios. Full test suite passes (166
|
|
47
|
-
tests).
|
|
29
|
+
Validated with expanded unit test coverage in `tests/transform.test.ts` and
|
|
30
|
+
`tests/utils-coverage.test.ts`.
|
|
48
31
|
|
package/dist/index.cjs
CHANGED
|
@@ -1895,6 +1895,12 @@ function nodeHandlerAttributeInfo(node) {
|
|
|
1895
1895
|
const n = node2;
|
|
1896
1896
|
return typeof n.computed === "boolean" && typeof n.key === "object" && n.key !== null && typeof n.value === "object" && n.value !== null;
|
|
1897
1897
|
};
|
|
1898
|
+
const isLogicalExpressionNode = (node2) => {
|
|
1899
|
+
if (!isNodeType2(node2, "LogicalExpression"))
|
|
1900
|
+
return false;
|
|
1901
|
+
const n = node2;
|
|
1902
|
+
return typeof n.operator === "string" && typeof n.left === "object" && n.left !== null && typeof n.right === "object" && n.right !== null;
|
|
1903
|
+
};
|
|
1898
1904
|
const getLastIdentifierFromMemberChain = (node2) => {
|
|
1899
1905
|
if (!node2)
|
|
1900
1906
|
return null;
|
|
@@ -2065,48 +2071,66 @@ function nodeHandlerAttributeInfo(node) {
|
|
|
2065
2071
|
const semanticNameHint2 = suffix ? `${toPascalCase(name)}${suffix}` : toPascalCase(name);
|
|
2066
2072
|
return semanticNameHint2;
|
|
2067
2073
|
};
|
|
2074
|
+
const unwrapSemanticHelperCall = (candidateExpr) => {
|
|
2075
|
+
if (!isCallExpressionNode(candidateExpr)) {
|
|
2076
|
+
return null;
|
|
2077
|
+
}
|
|
2078
|
+
const calleeName = getLastIdentifierFromMemberChain(candidateExpr.callee);
|
|
2079
|
+
if (calleeName !== "_unref" && calleeName !== "unref" && calleeName !== "_withModifiers" && calleeName !== "withModifiers") {
|
|
2080
|
+
return null;
|
|
2081
|
+
}
|
|
2082
|
+
const firstArg = candidateExpr.arguments[0];
|
|
2083
|
+
return typeof firstArg === "object" && firstArg !== null ? firstArg : null;
|
|
2084
|
+
};
|
|
2068
2085
|
const resolveSemanticName = (candidateExpr) => {
|
|
2069
2086
|
if (!candidateExpr) {
|
|
2070
2087
|
return null;
|
|
2071
2088
|
}
|
|
2089
|
+
const unwrappedHelperCandidate = unwrapSemanticHelperCall(candidateExpr);
|
|
2090
|
+
if (unwrappedHelperCandidate) {
|
|
2091
|
+
return resolveSemanticName(unwrappedHelperCandidate);
|
|
2092
|
+
}
|
|
2072
2093
|
const direct = getLastIdentifierFromMemberChain(candidateExpr);
|
|
2073
2094
|
if (direct) {
|
|
2074
2095
|
return toPascalCase(direct);
|
|
2075
2096
|
}
|
|
2097
|
+
const directCall = tryFromCallExpression(candidateExpr);
|
|
2098
|
+
if (directCall) {
|
|
2099
|
+
return directCall;
|
|
2100
|
+
}
|
|
2101
|
+
if (isAssignmentExpressionNode(candidateExpr)) {
|
|
2102
|
+
const lhs = getAssignmentTargetName(candidateExpr.left);
|
|
2103
|
+
if (lhs) {
|
|
2104
|
+
const rhs = stableWordFromValue(candidateExpr.right);
|
|
2105
|
+
return `Set${toPascalCase(lhs)}${rhs ?? ""}`;
|
|
2106
|
+
}
|
|
2107
|
+
}
|
|
2108
|
+
if (isLogicalExpressionNode(candidateExpr) && candidateExpr.operator === "&&") {
|
|
2109
|
+
return resolveSemanticName(candidateExpr.right);
|
|
2110
|
+
}
|
|
2076
2111
|
if (isArrowFunctionExpressionNode(candidateExpr)) {
|
|
2077
2112
|
const body = candidateExpr.body;
|
|
2078
|
-
const directCall = tryFromCallExpression(body);
|
|
2079
|
-
if (directCall) {
|
|
2080
|
-
return directCall;
|
|
2081
|
-
}
|
|
2082
|
-
if (isAssignmentExpressionNode(body)) {
|
|
2083
|
-
const lhs = getAssignmentTargetName(body.left);
|
|
2084
|
-
if (lhs) {
|
|
2085
|
-
const rhs = stableWordFromValue(body.right);
|
|
2086
|
-
return `Set${toPascalCase(lhs)}${rhs ?? ""}`;
|
|
2087
|
-
}
|
|
2088
|
-
}
|
|
2089
2113
|
if (isBlockStatementNode(body)) {
|
|
2090
2114
|
const stmts = body.body ?? [];
|
|
2091
2115
|
if (stmts.length > 0) {
|
|
2092
2116
|
const firstStmt = stmts[0];
|
|
2093
2117
|
if (isReturnStatementNode(firstStmt)) {
|
|
2094
|
-
const fromReturn =
|
|
2118
|
+
const fromReturn = resolveSemanticName(firstStmt.argument ?? null);
|
|
2095
2119
|
if (fromReturn) {
|
|
2096
2120
|
return fromReturn;
|
|
2097
2121
|
}
|
|
2098
2122
|
}
|
|
2099
2123
|
if (isExpressionStatementNode(firstStmt)) {
|
|
2100
|
-
const fromExpr =
|
|
2124
|
+
const fromExpr = resolveSemanticName(firstStmt.expression ?? null);
|
|
2101
2125
|
if (fromExpr) {
|
|
2102
2126
|
return fromExpr;
|
|
2103
2127
|
}
|
|
2104
2128
|
}
|
|
2105
2129
|
}
|
|
2106
2130
|
}
|
|
2107
|
-
const bodyName =
|
|
2131
|
+
const bodyName = resolveSemanticName(body);
|
|
2108
2132
|
if (bodyName) {
|
|
2109
|
-
return
|
|
2133
|
+
return bodyName;
|
|
2110
2134
|
}
|
|
2111
2135
|
}
|
|
2112
2136
|
return null;
|