@immense/vue-pom-generator 1.0.30 → 1.0.31
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 +7 -7
- package/RELEASE_NOTES.md +39 -26
- package/class-generation/index.ts +9 -0
- package/dist/index.cjs +197 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +198 -26
- package/dist/index.mjs.map +1 -1
- package/dist/plugin/types.d.ts +4 -4
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { pathToFileURL, fileURLToPath } from "node:url";
|
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import { JSDOM } from "jsdom";
|
|
6
6
|
import { NodeTypes, stringifyExpression, ConstantTypes, createSimpleExpression } from "@vue/compiler-core";
|
|
7
|
-
import { isArrayExpression, isStringLiteral, isTemplateLiteral, isAssignmentExpression, isIdentifier, isMemberExpression, isCallExpression, isExpressionStatement, isOptionalMemberExpression, isObjectExpression, isFile,
|
|
7
|
+
import { isArrayExpression, isStringLiteral, isTemplateLiteral, isAssignmentExpression, isIdentifier, isMemberExpression, isCallExpression, isExpressionStatement, isArrowFunctionExpression, isOptionalMemberExpression, isObjectExpression, isFile, isBlockStatement, isOptionalCallExpression, isLogicalExpression, isConditionalExpression, isSequenceExpression, isAssignmentPattern, isRestElement, isObjectPattern, isObjectProperty, isProgram, VISITOR_KEYS, isBooleanLiteral, isNumericLiteral, isNullLiteral } from "@babel/types";
|
|
8
8
|
import { parseExpression, parse } from "@babel/parser";
|
|
9
9
|
import { performance } from "node:perf_hooks";
|
|
10
10
|
import * as compilerDom from "@vue/compiler-dom";
|
|
@@ -565,6 +565,124 @@ function getTemplateSlotScope(node) {
|
|
|
565
565
|
}
|
|
566
566
|
return null;
|
|
567
567
|
}
|
|
568
|
+
function isSimpleScopeIdentifier(value) {
|
|
569
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(value);
|
|
570
|
+
}
|
|
571
|
+
function buildSlotScopeFallbackKeyExpression(identifier) {
|
|
572
|
+
return `${identifier}.key ?? ${identifier}.data?.id ?? ${identifier}.id ?? ${identifier}.value ?? ${identifier}`;
|
|
573
|
+
}
|
|
574
|
+
function tryGetBindingIdentifierName(node) {
|
|
575
|
+
if (!node) {
|
|
576
|
+
return null;
|
|
577
|
+
}
|
|
578
|
+
if (isIdentifier(node)) {
|
|
579
|
+
return node.name;
|
|
580
|
+
}
|
|
581
|
+
if (isAssignmentPattern(node)) {
|
|
582
|
+
return tryGetBindingIdentifierName(node.left);
|
|
583
|
+
}
|
|
584
|
+
if (isRestElement(node)) {
|
|
585
|
+
return tryGetBindingIdentifierName(node.argument);
|
|
586
|
+
}
|
|
587
|
+
return null;
|
|
588
|
+
}
|
|
589
|
+
function getSlotScopeObjectPropertyKeyName(node) {
|
|
590
|
+
if (isIdentifier(node)) {
|
|
591
|
+
return node.name;
|
|
592
|
+
}
|
|
593
|
+
if (isStringLiteral(node)) {
|
|
594
|
+
return node.value;
|
|
595
|
+
}
|
|
596
|
+
return null;
|
|
597
|
+
}
|
|
598
|
+
function tryGetSlotScopeKeyCandidate(node) {
|
|
599
|
+
if (!node) {
|
|
600
|
+
return null;
|
|
601
|
+
}
|
|
602
|
+
if (isIdentifier(node)) {
|
|
603
|
+
return {
|
|
604
|
+
priority: 2,
|
|
605
|
+
expression: buildSlotScopeFallbackKeyExpression(node.name)
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
if (isAssignmentPattern(node)) {
|
|
609
|
+
return tryGetSlotScopeKeyCandidate(node.left);
|
|
610
|
+
}
|
|
611
|
+
if (isRestElement(node)) {
|
|
612
|
+
return tryGetSlotScopeKeyCandidate(node.argument);
|
|
613
|
+
}
|
|
614
|
+
if (!isObjectPattern(node)) {
|
|
615
|
+
return null;
|
|
616
|
+
}
|
|
617
|
+
let best = null;
|
|
618
|
+
for (const property of node.properties) {
|
|
619
|
+
let candidate = null;
|
|
620
|
+
if (isRestElement(property)) {
|
|
621
|
+
candidate = tryGetSlotScopeKeyCandidate(property.argument);
|
|
622
|
+
if (candidate) {
|
|
623
|
+
candidate = { ...candidate, priority: Math.max(candidate.priority, 2) };
|
|
624
|
+
}
|
|
625
|
+
} else if (isObjectProperty(property)) {
|
|
626
|
+
const keyName = getSlotScopeObjectPropertyKeyName(property.key);
|
|
627
|
+
const bindingName = tryGetBindingIdentifierName(property.value) ?? tryGetBindingIdentifierName(property.key);
|
|
628
|
+
if (bindingName) {
|
|
629
|
+
if (keyName === "key" || bindingName === "key") {
|
|
630
|
+
candidate = {
|
|
631
|
+
priority: 0,
|
|
632
|
+
expression: bindingName
|
|
633
|
+
};
|
|
634
|
+
} else {
|
|
635
|
+
candidate = {
|
|
636
|
+
priority: keyName === "data" ? 1 : 2,
|
|
637
|
+
expression: buildSlotScopeFallbackKeyExpression(bindingName)
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if (candidate && (!best || candidate.priority < best.priority)) {
|
|
643
|
+
best = candidate;
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return best;
|
|
647
|
+
}
|
|
648
|
+
function tryGetTemplateSlotScopeKeyExpression(scope) {
|
|
649
|
+
const trimmed = scope.trim();
|
|
650
|
+
if (!trimmed) {
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
if (isSimpleScopeIdentifier(trimmed)) {
|
|
654
|
+
return buildSlotScopeFallbackKeyExpression(trimmed);
|
|
655
|
+
}
|
|
656
|
+
try {
|
|
657
|
+
const parsed = parse(`(${trimmed}) => {}`, {
|
|
658
|
+
sourceType: "module",
|
|
659
|
+
plugins: ["typescript"]
|
|
660
|
+
});
|
|
661
|
+
const statement = parsed.program.body[0];
|
|
662
|
+
if (statement && isExpressionStatement(statement) && isArrowFunctionExpression(statement.expression)) {
|
|
663
|
+
return tryGetSlotScopeKeyCandidate(statement.expression.params[0])?.expression ?? null;
|
|
664
|
+
}
|
|
665
|
+
} catch {
|
|
666
|
+
}
|
|
667
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
668
|
+
const inner = trimmed.slice(1, -1).trim();
|
|
669
|
+
let cutIdx = -1;
|
|
670
|
+
const commaIdx = inner.indexOf(",");
|
|
671
|
+
const colonIdx = inner.indexOf(":");
|
|
672
|
+
if (commaIdx !== -1 && colonIdx !== -1) {
|
|
673
|
+
cutIdx = Math.min(commaIdx, colonIdx);
|
|
674
|
+
} else if (commaIdx !== -1) {
|
|
675
|
+
cutIdx = commaIdx;
|
|
676
|
+
} else if (colonIdx !== -1) {
|
|
677
|
+
cutIdx = colonIdx;
|
|
678
|
+
}
|
|
679
|
+
const first = (cutIdx === -1 ? inner : inner.slice(0, cutIdx)).trim();
|
|
680
|
+
if (first && isSimpleScopeIdentifier(first)) {
|
|
681
|
+
return buildSlotScopeFallbackKeyExpression(first);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
return trimmed;
|
|
685
|
+
}
|
|
568
686
|
function nodeHasToDirective(node) {
|
|
569
687
|
const toDirective = findDirectiveByName(node, "bind", "to");
|
|
570
688
|
if (toDirective?.exp) {
|
|
@@ -640,25 +758,7 @@ function getContainedInSlotDataKeyValue(node, hierarchyMap2) {
|
|
|
640
758
|
if (parent.type === NodeTypes.ELEMENT && parent.tag === "template") {
|
|
641
759
|
const scope = getTemplateSlotScope(parent);
|
|
642
760
|
if (scope) {
|
|
643
|
-
|
|
644
|
-
if (key.startsWith("{") && key.endsWith("}")) {
|
|
645
|
-
const inner = key.slice(1, -1).trim();
|
|
646
|
-
let cutIdx = -1;
|
|
647
|
-
const commaIdx = inner.indexOf(",");
|
|
648
|
-
const colonIdx = inner.indexOf(":");
|
|
649
|
-
if (commaIdx !== -1 && colonIdx !== -1) {
|
|
650
|
-
cutIdx = Math.min(commaIdx, colonIdx);
|
|
651
|
-
} else if (commaIdx !== -1) {
|
|
652
|
-
cutIdx = commaIdx;
|
|
653
|
-
} else if (colonIdx !== -1) {
|
|
654
|
-
cutIdx = colonIdx;
|
|
655
|
-
}
|
|
656
|
-
const first = (cutIdx === -1 ? inner : inner.slice(0, cutIdx)).trim();
|
|
657
|
-
if (first) {
|
|
658
|
-
key = first;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
return key;
|
|
761
|
+
return tryGetTemplateSlotScopeKeyExpression(scope);
|
|
662
762
|
}
|
|
663
763
|
}
|
|
664
764
|
parent = getParent(hierarchyMap2, parent);
|
|
@@ -1309,11 +1409,11 @@ function getStableClickHandlerNameFromExpression(exp) {
|
|
|
1309
1409
|
return extractNameFromCallee(callee);
|
|
1310
1410
|
}
|
|
1311
1411
|
if (isAssignmentExpression(exp)) {
|
|
1312
|
-
const left = exp.left;
|
|
1313
|
-
if (
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1412
|
+
const left = getAssignmentTargetNameFromBabel(exp.left);
|
|
1413
|
+
if (left) {
|
|
1414
|
+
const right = getStableAssignmentValueSuffixFromBabel(exp.right);
|
|
1415
|
+
return `Set${toPascalCase(left)}${right}`;
|
|
1416
|
+
}
|
|
1317
1417
|
return "";
|
|
1318
1418
|
}
|
|
1319
1419
|
if (isOptionalMemberExpression(exp)) {
|
|
@@ -1388,6 +1488,71 @@ function extractMemberPropertyName(member) {
|
|
|
1388
1488
|
}
|
|
1389
1489
|
return "";
|
|
1390
1490
|
}
|
|
1491
|
+
function getLastIdentifierFromMemberChainBabel(node) {
|
|
1492
|
+
if (!node) {
|
|
1493
|
+
return "";
|
|
1494
|
+
}
|
|
1495
|
+
if (isIdentifier(node)) {
|
|
1496
|
+
return node.name;
|
|
1497
|
+
}
|
|
1498
|
+
if (isMemberExpression(node) || isOptionalMemberExpression(node)) {
|
|
1499
|
+
if (!node.computed) {
|
|
1500
|
+
if (isIdentifier(node.property)) {
|
|
1501
|
+
return node.property.name;
|
|
1502
|
+
}
|
|
1503
|
+
} else if (isStringLiteral(node.property)) {
|
|
1504
|
+
return node.property.value;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
return "";
|
|
1508
|
+
}
|
|
1509
|
+
function getAssignmentTargetNameFromBabel(node) {
|
|
1510
|
+
if (!node) {
|
|
1511
|
+
return "";
|
|
1512
|
+
}
|
|
1513
|
+
if (isIdentifier(node)) {
|
|
1514
|
+
return node.name;
|
|
1515
|
+
}
|
|
1516
|
+
if (isMemberExpression(node) || isOptionalMemberExpression(node)) {
|
|
1517
|
+
if (!node.computed && isIdentifier(node.property) && node.property.name === "value") {
|
|
1518
|
+
return getLastIdentifierFromMemberChainBabel(node.object);
|
|
1519
|
+
}
|
|
1520
|
+
return getLastIdentifierFromMemberChainBabel(node);
|
|
1521
|
+
}
|
|
1522
|
+
return "";
|
|
1523
|
+
}
|
|
1524
|
+
function getStableAssignmentValueSuffixFromBabel(node) {
|
|
1525
|
+
if (!node) {
|
|
1526
|
+
return "";
|
|
1527
|
+
}
|
|
1528
|
+
if (isBooleanLiteral(node)) {
|
|
1529
|
+
return node.value ? "True" : "False";
|
|
1530
|
+
}
|
|
1531
|
+
if (isNumericLiteral(node)) {
|
|
1532
|
+
return `Value${String(node.value)}`;
|
|
1533
|
+
}
|
|
1534
|
+
if (isNullLiteral(node)) {
|
|
1535
|
+
return "Null";
|
|
1536
|
+
}
|
|
1537
|
+
if (isStringLiteral(node)) {
|
|
1538
|
+
const cleaned = (node.value ?? "").trim();
|
|
1539
|
+
return cleaned ? toPascalCase(cleaned.slice(0, 24)) : "";
|
|
1540
|
+
}
|
|
1541
|
+
if (isTemplateLiteral(node) && node.expressions.length === 0) {
|
|
1542
|
+
const value = node.quasis.map((q) => q.value?.cooked ?? "").join("").trim();
|
|
1543
|
+
return value ? toPascalCase(value.slice(0, 24)) : "";
|
|
1544
|
+
}
|
|
1545
|
+
if (isMemberExpression(node) || isOptionalMemberExpression(node)) {
|
|
1546
|
+
const name = getLastIdentifierFromMemberChainBabel(node);
|
|
1547
|
+
return name ? toPascalCase(name.slice(0, 24)) : "";
|
|
1548
|
+
}
|
|
1549
|
+
if (isIdentifier(node)) {
|
|
1550
|
+
const firstChar = node.name.charAt(0);
|
|
1551
|
+
const isUpperAlpha = firstChar !== "" && firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase();
|
|
1552
|
+
return isUpperAlpha ? toPascalCase(node.name.slice(0, 24)) : "";
|
|
1553
|
+
}
|
|
1554
|
+
return "";
|
|
1555
|
+
}
|
|
1391
1556
|
function isCompilerGeneratedReferenceRoot(name) {
|
|
1392
1557
|
return name.startsWith("_") || name.startsWith("$");
|
|
1393
1558
|
}
|
|
@@ -3199,6 +3364,10 @@ function escapeGitAttributesPattern(value) {
|
|
|
3199
3364
|
}
|
|
3200
3365
|
return output;
|
|
3201
3366
|
}
|
|
3367
|
+
function pathUsesGeneratedHeuristic(filePath) {
|
|
3368
|
+
const normalized = path.normalize(filePath);
|
|
3369
|
+
return normalized.split(path.sep).includes("__generated__");
|
|
3370
|
+
}
|
|
3202
3371
|
function buildManagedGitAttributesBlock(entries) {
|
|
3203
3372
|
return [
|
|
3204
3373
|
GENERATED_GITATTRIBUTES_BLOCK_START,
|
|
@@ -3246,6 +3415,9 @@ function buildGeneratedGitAttributesFiles(generatedFilePaths) {
|
|
|
3246
3415
|
if (path.basename(resolvedFilePath) === ".gitattributes") {
|
|
3247
3416
|
continue;
|
|
3248
3417
|
}
|
|
3418
|
+
if (pathUsesGeneratedHeuristic(resolvedFilePath)) {
|
|
3419
|
+
continue;
|
|
3420
|
+
}
|
|
3249
3421
|
const dir = path.dirname(resolvedFilePath);
|
|
3250
3422
|
const entry = `${escapeGitAttributesPattern(path.basename(resolvedFilePath))} linguist-generated`;
|
|
3251
3423
|
const entries = entriesByDir.get(dir) ?? /* @__PURE__ */ new Set();
|
|
@@ -6156,7 +6328,7 @@ function createVuePomGeneratorPlugins(options = {}) {
|
|
|
6156
6328
|
const excludedComponents = injection.excludeComponents ?? [];
|
|
6157
6329
|
const testIdAttribute = (injection.attribute ?? "data-testid").trim() || "data-testid";
|
|
6158
6330
|
const existingIdBehavior = injection.existingIdBehavior ?? "preserve";
|
|
6159
|
-
const outDir = (generationOptions?.outDir ?? "tests/playwright/
|
|
6331
|
+
const outDir = (generationOptions?.outDir ?? "tests/playwright/__generated__").trim();
|
|
6160
6332
|
const emitLanguages = generationOptions?.emit && generationOptions.emit.length ? generationOptions.emit : ["ts"];
|
|
6161
6333
|
const nameCollisionBehavior = generationOptions?.nameCollisionBehavior ?? "suffix";
|
|
6162
6334
|
const routerEntry = generationOptions?.router?.entry;
|