wireweaver 0.1.1 → 0.1.2
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/vite-plugin.cjs +57 -8
- package/dist/vite-plugin.js +57 -8
- package/package.json +1 -1
package/dist/vite-plugin.cjs
CHANGED
|
@@ -395,7 +395,8 @@ function discoverInterfaceImplementations(root, extraScanDirs = []) {
|
|
|
395
395
|
scanSourceFilesForImplementations(root, implementations, allClassHeritage, beanReturnTypes, false);
|
|
396
396
|
for (const dir of extraScanDirs) {
|
|
397
397
|
const packageRoot = findPackageRoot(dir);
|
|
398
|
-
|
|
398
|
+
const componentNames = collectComponentClassNames(dir);
|
|
399
|
+
scanSourceFilesForImplementations(dir, implementations, allClassHeritage, beanReturnTypes, true, packageRoot, componentNames);
|
|
399
400
|
}
|
|
400
401
|
for (const typeName of beanReturnTypes) {
|
|
401
402
|
const entries = allClassHeritage.get(typeName);
|
|
@@ -411,7 +412,7 @@ function discoverInterfaceImplementations(root, extraScanDirs = []) {
|
|
|
411
412
|
}
|
|
412
413
|
return implementations;
|
|
413
414
|
}
|
|
414
|
-
function scanSourceFilesForImplementations(root, implementations, allClassHeritage, beanReturnTypes, allowNodeModules, packageRoot) {
|
|
415
|
+
function scanSourceFilesForImplementations(root, implementations, allClassHeritage, beanReturnTypes, allowNodeModules, packageRoot, componentNames = /* @__PURE__ */ new Set()) {
|
|
415
416
|
for (const sourceFile of getScanSourceFiles(root, allowNodeModules)) {
|
|
416
417
|
import_typescript.default.forEachChild(sourceFile, (node) => {
|
|
417
418
|
if (import_typescript.default.isClassDeclaration(node) && node.name) {
|
|
@@ -426,7 +427,7 @@ function scanSourceFilesForImplementations(root, implementations, allClassHerita
|
|
|
426
427
|
heritageEntries.push({ interfaceName, filePath: sourceFile.fileName, importSpecifier });
|
|
427
428
|
allClassHeritage.set(node.name.text, heritageEntries);
|
|
428
429
|
}
|
|
429
|
-
if (!hasServiceDecorator(node)) continue;
|
|
430
|
+
if (!hasServiceDecorator(node) && !componentNames.has(node.name.text)) continue;
|
|
430
431
|
const existing = implementations.get(interfaceName) ?? [];
|
|
431
432
|
if (existing.some((impl) => impl.className === node.name.text && normalizeFilePath(impl.filePath) === normalizeFilePath(sourceFile.fileName))) {
|
|
432
433
|
continue;
|
|
@@ -537,14 +538,17 @@ function buildImportInsertions(code, sourceFile, importsToInject, sideEffectImpo
|
|
|
537
538
|
if (unresolved.length === 0) continue;
|
|
538
539
|
const existing = findImportByModule(sourceFile, importPath);
|
|
539
540
|
if (existing && existing.importClause?.namedBindings && import_typescript.default.isNamedImports(existing.importClause.namedBindings)) {
|
|
540
|
-
const
|
|
541
|
+
const namedImports = existing.importClause.namedBindings;
|
|
542
|
+
const existingNames = new Set(namedImports.elements.map((element) => element.name.text));
|
|
541
543
|
const missing = unresolved.filter((name) => !existingNames.has(name));
|
|
542
544
|
if (missing.length === 0) continue;
|
|
543
|
-
const
|
|
545
|
+
const hasElements = namedImports.elements.length > 0;
|
|
546
|
+
const insertionPoint2 = namedImports.getEnd() - 1;
|
|
547
|
+
const prefix = hasElements ? ", " : "";
|
|
544
548
|
replacements.push({
|
|
545
|
-
start:
|
|
546
|
-
end:
|
|
547
|
-
text: `${
|
|
549
|
+
start: insertionPoint2,
|
|
550
|
+
end: insertionPoint2,
|
|
551
|
+
text: `${prefix}${missing.sort().join(", ")}`
|
|
548
552
|
});
|
|
549
553
|
continue;
|
|
550
554
|
}
|
|
@@ -651,6 +655,51 @@ function resolveExtraScanDirs(root, extraScanDirs) {
|
|
|
651
655
|
if (!extraScanDirs || extraScanDirs.length === 0) return [];
|
|
652
656
|
return extraScanDirs.map((dir) => (0, import_node_path.isAbsolute)(dir) ? dir : (0, import_node_path.resolve)(root, dir));
|
|
653
657
|
}
|
|
658
|
+
function collectComponentClassNames(dir) {
|
|
659
|
+
const names = /* @__PURE__ */ new Set();
|
|
660
|
+
const stage3 = /_([A-Za-z_$][\w$]*)_decorators\s*=\s*\[([^\]]*)\]/g;
|
|
661
|
+
const legacy = /__decorate\(\s*\[([^\]]*?)\]\s*,\s*([A-Za-z_$][\w$]*)/g;
|
|
662
|
+
function containsComponentDecorator(decoratorList) {
|
|
663
|
+
return /\b(Component|Service)\s*\(/.test(decoratorList);
|
|
664
|
+
}
|
|
665
|
+
function walk(current) {
|
|
666
|
+
let entries;
|
|
667
|
+
try {
|
|
668
|
+
entries = (0, import_node_fs.readdirSync)(current);
|
|
669
|
+
} catch {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
for (const name of entries) {
|
|
673
|
+
const fullPath = (0, import_node_path.join)(current, name);
|
|
674
|
+
let isDir = false;
|
|
675
|
+
try {
|
|
676
|
+
isDir = (0, import_node_fs.statSync)(fullPath).isDirectory();
|
|
677
|
+
} catch {
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
if (isDir) {
|
|
681
|
+
if (name === "node_modules") continue;
|
|
682
|
+
walk(fullPath);
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
if (!/\.(js|cjs|mjs)$/.test(name)) continue;
|
|
686
|
+
let content;
|
|
687
|
+
try {
|
|
688
|
+
content = (0, import_node_fs.readFileSync)(fullPath, "utf-8");
|
|
689
|
+
} catch {
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
for (const match of content.matchAll(stage3)) {
|
|
693
|
+
if (containsComponentDecorator(match[2])) names.add(match[1]);
|
|
694
|
+
}
|
|
695
|
+
for (const match of content.matchAll(legacy)) {
|
|
696
|
+
if (containsComponentDecorator(match[1])) names.add(match[2]);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
walk(dir);
|
|
701
|
+
return names;
|
|
702
|
+
}
|
|
654
703
|
function findPackageRoot(startDir) {
|
|
655
704
|
let current = startDir;
|
|
656
705
|
while (true) {
|
package/dist/vite-plugin.js
CHANGED
|
@@ -358,7 +358,8 @@ function discoverInterfaceImplementations(root, extraScanDirs = []) {
|
|
|
358
358
|
scanSourceFilesForImplementations(root, implementations, allClassHeritage, beanReturnTypes, false);
|
|
359
359
|
for (const dir of extraScanDirs) {
|
|
360
360
|
const packageRoot = findPackageRoot(dir);
|
|
361
|
-
|
|
361
|
+
const componentNames = collectComponentClassNames(dir);
|
|
362
|
+
scanSourceFilesForImplementations(dir, implementations, allClassHeritage, beanReturnTypes, true, packageRoot, componentNames);
|
|
362
363
|
}
|
|
363
364
|
for (const typeName of beanReturnTypes) {
|
|
364
365
|
const entries = allClassHeritage.get(typeName);
|
|
@@ -374,7 +375,7 @@ function discoverInterfaceImplementations(root, extraScanDirs = []) {
|
|
|
374
375
|
}
|
|
375
376
|
return implementations;
|
|
376
377
|
}
|
|
377
|
-
function scanSourceFilesForImplementations(root, implementations, allClassHeritage, beanReturnTypes, allowNodeModules, packageRoot) {
|
|
378
|
+
function scanSourceFilesForImplementations(root, implementations, allClassHeritage, beanReturnTypes, allowNodeModules, packageRoot, componentNames = /* @__PURE__ */ new Set()) {
|
|
378
379
|
for (const sourceFile of getScanSourceFiles(root, allowNodeModules)) {
|
|
379
380
|
ts.forEachChild(sourceFile, (node) => {
|
|
380
381
|
if (ts.isClassDeclaration(node) && node.name) {
|
|
@@ -389,7 +390,7 @@ function scanSourceFilesForImplementations(root, implementations, allClassHerita
|
|
|
389
390
|
heritageEntries.push({ interfaceName, filePath: sourceFile.fileName, importSpecifier });
|
|
390
391
|
allClassHeritage.set(node.name.text, heritageEntries);
|
|
391
392
|
}
|
|
392
|
-
if (!hasServiceDecorator(node)) continue;
|
|
393
|
+
if (!hasServiceDecorator(node) && !componentNames.has(node.name.text)) continue;
|
|
393
394
|
const existing = implementations.get(interfaceName) ?? [];
|
|
394
395
|
if (existing.some((impl) => impl.className === node.name.text && normalizeFilePath(impl.filePath) === normalizeFilePath(sourceFile.fileName))) {
|
|
395
396
|
continue;
|
|
@@ -500,14 +501,17 @@ function buildImportInsertions(code, sourceFile, importsToInject, sideEffectImpo
|
|
|
500
501
|
if (unresolved.length === 0) continue;
|
|
501
502
|
const existing = findImportByModule(sourceFile, importPath);
|
|
502
503
|
if (existing && existing.importClause?.namedBindings && ts.isNamedImports(existing.importClause.namedBindings)) {
|
|
503
|
-
const
|
|
504
|
+
const namedImports = existing.importClause.namedBindings;
|
|
505
|
+
const existingNames = new Set(namedImports.elements.map((element) => element.name.text));
|
|
504
506
|
const missing = unresolved.filter((name) => !existingNames.has(name));
|
|
505
507
|
if (missing.length === 0) continue;
|
|
506
|
-
const
|
|
508
|
+
const hasElements = namedImports.elements.length > 0;
|
|
509
|
+
const insertionPoint2 = namedImports.getEnd() - 1;
|
|
510
|
+
const prefix = hasElements ? ", " : "";
|
|
507
511
|
replacements.push({
|
|
508
|
-
start:
|
|
509
|
-
end:
|
|
510
|
-
text: `${
|
|
512
|
+
start: insertionPoint2,
|
|
513
|
+
end: insertionPoint2,
|
|
514
|
+
text: `${prefix}${missing.sort().join(", ")}`
|
|
511
515
|
});
|
|
512
516
|
continue;
|
|
513
517
|
}
|
|
@@ -614,6 +618,51 @@ function resolveExtraScanDirs(root, extraScanDirs) {
|
|
|
614
618
|
if (!extraScanDirs || extraScanDirs.length === 0) return [];
|
|
615
619
|
return extraScanDirs.map((dir) => isAbsolute(dir) ? dir : resolvePath(root, dir));
|
|
616
620
|
}
|
|
621
|
+
function collectComponentClassNames(dir) {
|
|
622
|
+
const names = /* @__PURE__ */ new Set();
|
|
623
|
+
const stage3 = /_([A-Za-z_$][\w$]*)_decorators\s*=\s*\[([^\]]*)\]/g;
|
|
624
|
+
const legacy = /__decorate\(\s*\[([^\]]*?)\]\s*,\s*([A-Za-z_$][\w$]*)/g;
|
|
625
|
+
function containsComponentDecorator(decoratorList) {
|
|
626
|
+
return /\b(Component|Service)\s*\(/.test(decoratorList);
|
|
627
|
+
}
|
|
628
|
+
function walk(current) {
|
|
629
|
+
let entries;
|
|
630
|
+
try {
|
|
631
|
+
entries = readdirSync(current);
|
|
632
|
+
} catch {
|
|
633
|
+
return;
|
|
634
|
+
}
|
|
635
|
+
for (const name of entries) {
|
|
636
|
+
const fullPath = joinPath(current, name);
|
|
637
|
+
let isDir = false;
|
|
638
|
+
try {
|
|
639
|
+
isDir = statSync(fullPath).isDirectory();
|
|
640
|
+
} catch {
|
|
641
|
+
continue;
|
|
642
|
+
}
|
|
643
|
+
if (isDir) {
|
|
644
|
+
if (name === "node_modules") continue;
|
|
645
|
+
walk(fullPath);
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
if (!/\.(js|cjs|mjs)$/.test(name)) continue;
|
|
649
|
+
let content;
|
|
650
|
+
try {
|
|
651
|
+
content = readFileSync(fullPath, "utf-8");
|
|
652
|
+
} catch {
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
655
|
+
for (const match of content.matchAll(stage3)) {
|
|
656
|
+
if (containsComponentDecorator(match[2])) names.add(match[1]);
|
|
657
|
+
}
|
|
658
|
+
for (const match of content.matchAll(legacy)) {
|
|
659
|
+
if (containsComponentDecorator(match[1])) names.add(match[2]);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
walk(dir);
|
|
664
|
+
return names;
|
|
665
|
+
}
|
|
617
666
|
function findPackageRoot(startDir) {
|
|
618
667
|
let current = startDir;
|
|
619
668
|
while (true) {
|
package/package.json
CHANGED