@jay-framework/plugin-validator 0.20.0 → 0.21.0
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/index.js +146 -12
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -451,6 +451,14 @@ async function validateSchema(context, result) {
|
|
|
451
451
|
location: "plugin.yaml",
|
|
452
452
|
suggestion: 'Specify the exported member name from the module (e.g., "moodTracker")'
|
|
453
453
|
});
|
|
454
|
+
} else {
|
|
455
|
+
validateHandlerRef(
|
|
456
|
+
contract.component,
|
|
457
|
+
`Contract "${contract.name}" component`,
|
|
458
|
+
`plugin.yaml contracts[${index}]`,
|
|
459
|
+
context,
|
|
460
|
+
result
|
|
461
|
+
);
|
|
454
462
|
}
|
|
455
463
|
});
|
|
456
464
|
}
|
|
@@ -483,6 +491,24 @@ async function validateSchema(context, result) {
|
|
|
483
491
|
suggestion: 'Specify prefix for dynamic contract names (e.g., "cms")'
|
|
484
492
|
});
|
|
485
493
|
}
|
|
494
|
+
if (config.component) {
|
|
495
|
+
validateHandlerRef(
|
|
496
|
+
config.component,
|
|
497
|
+
`dynamic_contracts[${prefix}] component`,
|
|
498
|
+
`plugin.yaml dynamic_contracts`,
|
|
499
|
+
context,
|
|
500
|
+
result
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
if (config.generator) {
|
|
504
|
+
validateHandlerRef(
|
|
505
|
+
config.generator,
|
|
506
|
+
`dynamic_contracts[${prefix}] generator`,
|
|
507
|
+
`plugin.yaml dynamic_contracts`,
|
|
508
|
+
context,
|
|
509
|
+
result
|
|
510
|
+
);
|
|
511
|
+
}
|
|
486
512
|
}
|
|
487
513
|
}
|
|
488
514
|
if (!manifest.contracts && !manifest.dynamic_contracts) {
|
|
@@ -553,6 +579,23 @@ async function validateSchema(context, result) {
|
|
|
553
579
|
});
|
|
554
580
|
}
|
|
555
581
|
}
|
|
582
|
+
if (manifest.actions) {
|
|
583
|
+
for (const entry of manifest.actions) {
|
|
584
|
+
const exportName = typeof entry === "string" ? entry : entry.name;
|
|
585
|
+
if (exportName) {
|
|
586
|
+
validateHandlerRef(
|
|
587
|
+
exportName,
|
|
588
|
+
`Action "${exportName}"`,
|
|
589
|
+
"plugin.yaml actions",
|
|
590
|
+
context,
|
|
591
|
+
result
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
if (manifest.init) {
|
|
597
|
+
validateHandlerRef(manifest.init, "Init handler", "plugin.yaml init", context, result);
|
|
598
|
+
}
|
|
556
599
|
if (manifest.routes) {
|
|
557
600
|
if (!Array.isArray(manifest.routes)) {
|
|
558
601
|
result.errors.push({
|
|
@@ -584,6 +627,14 @@ async function validateSchema(context, result) {
|
|
|
584
627
|
location: "plugin.yaml",
|
|
585
628
|
suggestion: "Specify the exported member name for the page component"
|
|
586
629
|
});
|
|
630
|
+
} else {
|
|
631
|
+
validateHandlerRef(
|
|
632
|
+
route.component,
|
|
633
|
+
`Route "${route.path}" component`,
|
|
634
|
+
`plugin.yaml routes`,
|
|
635
|
+
context,
|
|
636
|
+
result
|
|
637
|
+
);
|
|
587
638
|
}
|
|
588
639
|
if (route.jayHtml) {
|
|
589
640
|
validateDocFile(
|
|
@@ -623,22 +674,105 @@ async function validateSchema(context, result) {
|
|
|
623
674
|
suggestion: "Specify the relative path to the validator handler module"
|
|
624
675
|
});
|
|
625
676
|
}
|
|
626
|
-
if (validator.handler
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
location: "plugin.yaml validators",
|
|
635
|
-
suggestion: `Create the validator handler at ${handlerPath}.ts`
|
|
636
|
-
});
|
|
637
|
-
}
|
|
677
|
+
if (validator.handler) {
|
|
678
|
+
validateHandlerRef(
|
|
679
|
+
validator.handler,
|
|
680
|
+
`Validator "${validator.name}" handler`,
|
|
681
|
+
"plugin.yaml validators",
|
|
682
|
+
context,
|
|
683
|
+
result
|
|
684
|
+
);
|
|
638
685
|
}
|
|
639
686
|
});
|
|
640
687
|
}
|
|
641
688
|
}
|
|
689
|
+
if (manifest.setup) {
|
|
690
|
+
if (manifest.setup.handler) {
|
|
691
|
+
validateHandlerRef(
|
|
692
|
+
manifest.setup.handler,
|
|
693
|
+
"Setup handler",
|
|
694
|
+
"plugin.yaml setup.handler",
|
|
695
|
+
context,
|
|
696
|
+
result
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
if (manifest.setup.references) {
|
|
700
|
+
validateHandlerRef(
|
|
701
|
+
manifest.setup.references,
|
|
702
|
+
"References handler",
|
|
703
|
+
"plugin.yaml setup.references",
|
|
704
|
+
context,
|
|
705
|
+
result
|
|
706
|
+
);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
function checkExportExists(exportName, context) {
|
|
711
|
+
const packageJsonPath = path.join(context.pluginPath, "package.json");
|
|
712
|
+
if (!fs.existsSync(packageJsonPath))
|
|
713
|
+
return true;
|
|
714
|
+
let mainPath;
|
|
715
|
+
try {
|
|
716
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
717
|
+
if (packageJson.exports?.["."]) {
|
|
718
|
+
const entry = packageJson.exports["."];
|
|
719
|
+
const entryPath = typeof entry === "string" ? entry : entry.default || entry.import;
|
|
720
|
+
if (entryPath)
|
|
721
|
+
mainPath = path.join(context.pluginPath, entryPath);
|
|
722
|
+
}
|
|
723
|
+
if (!mainPath && packageJson.main) {
|
|
724
|
+
mainPath = path.join(context.pluginPath, packageJson.main);
|
|
725
|
+
}
|
|
726
|
+
} catch {
|
|
727
|
+
return true;
|
|
728
|
+
}
|
|
729
|
+
if (!mainPath || !fs.existsSync(mainPath))
|
|
730
|
+
return true;
|
|
731
|
+
try {
|
|
732
|
+
const content = fs.readFileSync(mainPath, "utf-8");
|
|
733
|
+
const patterns = [
|
|
734
|
+
new RegExp(`export\\s*\\{[^}]*\\b${exportName}\\b[^}]*\\}`, "m"),
|
|
735
|
+
new RegExp(`export\\s+(?:async\\s+)?function\\s+${exportName}\\b`),
|
|
736
|
+
new RegExp(`export\\s+(?:const|let|var)\\s+${exportName}\\b`)
|
|
737
|
+
];
|
|
738
|
+
return patterns.some((p) => p.test(content));
|
|
739
|
+
} catch {
|
|
740
|
+
return true;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
function isRelativePath(value) {
|
|
744
|
+
return value.startsWith("./") || value.startsWith("../");
|
|
745
|
+
}
|
|
746
|
+
function validateHandlerRef(value, label, location, context, result) {
|
|
747
|
+
if (context.isNpmPackage) {
|
|
748
|
+
if (isRelativePath(value)) {
|
|
749
|
+
result.errors.push({
|
|
750
|
+
type: "export-mismatch",
|
|
751
|
+
message: `${label} "${value}" is a relative path, but NPM plugins must use an export name`,
|
|
752
|
+
location,
|
|
753
|
+
suggestion: `Export the function from the package entry point and use the export name instead of a path`
|
|
754
|
+
});
|
|
755
|
+
} else if (!checkExportExists(value, context)) {
|
|
756
|
+
result.errors.push({
|
|
757
|
+
type: "export-mismatch",
|
|
758
|
+
message: `${label} "${value}" is not exported from the package`,
|
|
759
|
+
location,
|
|
760
|
+
suggestion: `Add "export { ${value} } from '...'" to the package entry point`
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
} else if (isRelativePath(value)) {
|
|
764
|
+
const handlerPath = path.join(context.pluginPath, value);
|
|
765
|
+
const extensions = ["", ".ts", ".js", "/index.ts", "/index.js"];
|
|
766
|
+
const found = extensions.some((ext) => fs.existsSync(handlerPath + ext));
|
|
767
|
+
if (!found) {
|
|
768
|
+
result.errors.push({
|
|
769
|
+
type: "file-missing",
|
|
770
|
+
message: `${label} not found: ${value}`,
|
|
771
|
+
location,
|
|
772
|
+
suggestion: `Create the handler at ${handlerPath}.ts`
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
}
|
|
642
776
|
}
|
|
643
777
|
function resolveContractFile(contractSpec, context) {
|
|
644
778
|
if (context.isNpmPackage) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/plugin-validator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "Validation tool for Jay Stack plugins",
|
|
@@ -25,15 +25,15 @@
|
|
|
25
25
|
"test:watch": ":"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@jay-framework/compiler-jay-html": "^0.
|
|
29
|
-
"@jay-framework/compiler-shared": "^0.
|
|
30
|
-
"@jay-framework/editor-protocol": "^0.
|
|
31
|
-
"@jay-framework/typescript-bridge": "^0.
|
|
28
|
+
"@jay-framework/compiler-jay-html": "^0.21.0",
|
|
29
|
+
"@jay-framework/compiler-shared": "^0.21.0",
|
|
30
|
+
"@jay-framework/editor-protocol": "^0.21.0",
|
|
31
|
+
"@jay-framework/typescript-bridge": "^0.21.0",
|
|
32
32
|
"chalk": "^4.1.2",
|
|
33
33
|
"yaml": "^2.3.4"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@jay-framework/dev-environment": "^0.
|
|
36
|
+
"@jay-framework/dev-environment": "^0.21.0",
|
|
37
37
|
"@types/node": "^22.15.21",
|
|
38
38
|
"rimraf": "^5.0.5",
|
|
39
39
|
"tsup": "^8.0.1",
|