@open-mercato/cli 0.6.3-develop.3602.1.8287bc577d → 0.6.3-develop.3609.1.01983ef87a
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/lib/generators/module-registry.js +66 -9
- package/dist/lib/generators/module-registry.js.map +3 -3
- package/dist/lib/testing/integration.js +13 -4
- package/dist/lib/testing/integration.js.map +2 -2
- package/package.json +5 -5
- package/src/lib/generators/__tests__/module-subset.test.ts +142 -0
- package/src/lib/generators/module-registry.ts +84 -10
- package/src/lib/testing/integration.ts +13 -4
|
@@ -630,8 +630,9 @@ function requiresRuntimePageMetadataFromSourceFile(sourceFile) {
|
|
|
630
630
|
function toLiteral(value) {
|
|
631
631
|
return JSON.stringify(value).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
632
632
|
}
|
|
633
|
-
const
|
|
633
|
+
const GENERATED_MODULE_RELATIVE_PREFIXES = ["@/", "../../src/modules/", "./"];
|
|
634
634
|
const GENERATED_MODULE_SPECIFIER_SEGMENT = /^[A-Za-z0-9_.\-[\]()']+$/;
|
|
635
|
+
const NPM_PACKAGE_NAME_SEGMENT = /^[A-Za-z0-9~][A-Za-z0-9_.~-]*$/;
|
|
635
636
|
function sanitizeGeneratedModuleSpecifierSegment(segment, importPath) {
|
|
636
637
|
const match = GENERATED_MODULE_SPECIFIER_SEGMENT.exec(segment);
|
|
637
638
|
if (!match || segment === "." || segment === "..") {
|
|
@@ -639,17 +640,64 @@ function sanitizeGeneratedModuleSpecifierSegment(segment, importPath) {
|
|
|
639
640
|
}
|
|
640
641
|
return match[0];
|
|
641
642
|
}
|
|
642
|
-
function
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
throw new Error(`Unsafe generated module specifier prefix: ${importPath}`);
|
|
643
|
+
function sanitizeNpmPackageNameSegment(segment, importPath) {
|
|
644
|
+
if (!NPM_PACKAGE_NAME_SEGMENT.test(segment) || segment === "." || segment === "..") {
|
|
645
|
+
throw new Error(`Unsafe generated module specifier: ${importPath}`);
|
|
646
646
|
}
|
|
647
|
-
|
|
648
|
-
|
|
647
|
+
}
|
|
648
|
+
function sanitizeGeneratedModuleSpecifier(importPath) {
|
|
649
|
+
if (!importPath) {
|
|
649
650
|
throw new Error(`Unsafe generated module specifier: ${importPath}`);
|
|
650
651
|
}
|
|
651
|
-
const
|
|
652
|
-
|
|
652
|
+
const relativePrefix = GENERATED_MODULE_RELATIVE_PREFIXES.find(
|
|
653
|
+
(candidate) => importPath.startsWith(candidate)
|
|
654
|
+
);
|
|
655
|
+
if (relativePrefix) {
|
|
656
|
+
const suffix = importPath.slice(relativePrefix.length);
|
|
657
|
+
if (!suffix) {
|
|
658
|
+
throw new Error(`Unsafe generated module specifier: ${importPath}`);
|
|
659
|
+
}
|
|
660
|
+
const segments2 = suffix.split("/").map((segment) => sanitizeGeneratedModuleSpecifierSegment(segment, importPath));
|
|
661
|
+
return `${relativePrefix}${segments2.join("/")}`;
|
|
662
|
+
}
|
|
663
|
+
if (importPath.startsWith("@")) {
|
|
664
|
+
const firstSlash2 = importPath.indexOf("/");
|
|
665
|
+
if (firstSlash2 < 2) {
|
|
666
|
+
throw new Error(`Unsafe generated module specifier prefix: ${importPath}`);
|
|
667
|
+
}
|
|
668
|
+
const scope = importPath.slice(1, firstSlash2);
|
|
669
|
+
sanitizeNpmPackageNameSegment(scope, importPath);
|
|
670
|
+
const rest = importPath.slice(firstSlash2 + 1);
|
|
671
|
+
if (!rest) {
|
|
672
|
+
throw new Error(`Unsafe generated module specifier: ${importPath}`);
|
|
673
|
+
}
|
|
674
|
+
const secondSlash = rest.indexOf("/");
|
|
675
|
+
const name2 = secondSlash >= 0 ? rest.slice(0, secondSlash) : rest;
|
|
676
|
+
sanitizeNpmPackageNameSegment(name2, importPath);
|
|
677
|
+
const subpath2 = secondSlash >= 0 ? rest.slice(secondSlash + 1) : "";
|
|
678
|
+
if (!subpath2) {
|
|
679
|
+
return `@${scope}/${name2}`;
|
|
680
|
+
}
|
|
681
|
+
const segments2 = subpath2.split("/").map((segment) => sanitizeGeneratedModuleSpecifierSegment(segment, importPath));
|
|
682
|
+
return `@${scope}/${name2}/${segments2.join("/")}`;
|
|
683
|
+
}
|
|
684
|
+
const firstSlash = importPath.indexOf("/");
|
|
685
|
+
const name = firstSlash >= 0 ? importPath.slice(0, firstSlash) : importPath;
|
|
686
|
+
sanitizeNpmPackageNameSegment(name, importPath);
|
|
687
|
+
const subpath = firstSlash >= 0 ? importPath.slice(firstSlash + 1) : "";
|
|
688
|
+
if (!subpath) {
|
|
689
|
+
return name;
|
|
690
|
+
}
|
|
691
|
+
const segments = subpath.split("/").map((segment) => sanitizeGeneratedModuleSpecifierSegment(segment, importPath));
|
|
692
|
+
return `${name}/${segments.join("/")}`;
|
|
693
|
+
}
|
|
694
|
+
function verifyThirdPartyModuleShape(entry, pkgBase) {
|
|
695
|
+
const from = entry.from;
|
|
696
|
+
if (!from || from === "@app" || from.startsWith("@open-mercato/")) return;
|
|
697
|
+
if (fs.existsSync(pkgBase)) return;
|
|
698
|
+
throw new Error(
|
|
699
|
+
`Module '${entry.id}' is registered with from: '${from}' but no Open Mercato module shape was found at '${pkgBase}'. Ensure the package ships a 'modules/${entry.id}' subtree (either under 'dist/modules/' or 'src/modules/'), or correct the 'from' value in src/modules.ts.`
|
|
700
|
+
);
|
|
653
701
|
}
|
|
654
702
|
function buildImportStatement(importClause, importPath) {
|
|
655
703
|
return `import ${importClause} from ${toLiteral(sanitizeGeneratedModuleSpecifier(importPath))}`;
|
|
@@ -1937,6 +1985,9 @@ async function generateModuleRegistry(options) {
|
|
|
1937
1985
|
const legacySubscribersOutFile = path.join(outputDir, "subscribers.generated.ts");
|
|
1938
1986
|
const legacySubscribersChecksumFile = path.join(outputDir, "subscribers.generated.checksum");
|
|
1939
1987
|
const enabled = resolver.loadEnabledModules();
|
|
1988
|
+
for (const entry of enabled) {
|
|
1989
|
+
verifyThirdPartyModuleShape(entry, resolver.getModulePaths(entry).pkgBase);
|
|
1990
|
+
}
|
|
1940
1991
|
const extensions = loadGeneratorExtensions();
|
|
1941
1992
|
const pluginRegistry = /* @__PURE__ */ new Map();
|
|
1942
1993
|
const pluginState = /* @__PURE__ */ new Map();
|
|
@@ -2475,6 +2526,9 @@ async function generateModuleRegistryApp(options) {
|
|
|
2475
2526
|
const enabledIdsOutFile = path.join(outputDir, "enabled-module-ids.generated.ts");
|
|
2476
2527
|
const enabledIdsChecksumFile = path.join(outputDir, "enabled-module-ids.generated.checksum");
|
|
2477
2528
|
const enabled = resolver.loadEnabledModules();
|
|
2529
|
+
for (const entry of enabled) {
|
|
2530
|
+
verifyThirdPartyModuleShape(entry, resolver.getModulePaths(entry).pkgBase);
|
|
2531
|
+
}
|
|
2478
2532
|
const imports = [];
|
|
2479
2533
|
const moduleDecls = [];
|
|
2480
2534
|
const importIdRef = { value: 0 };
|
|
@@ -2767,6 +2821,9 @@ async function generateModuleRegistryCli(options) {
|
|
|
2767
2821
|
const legacyOutFile = path.join(outputDir, "cli-modules.generated.ts");
|
|
2768
2822
|
const legacyChecksumFile = path.join(outputDir, "cli-modules.generated.checksum");
|
|
2769
2823
|
const enabled = resolver.loadEnabledModules();
|
|
2824
|
+
for (const entry of enabled) {
|
|
2825
|
+
verifyThirdPartyModuleShape(entry, resolver.getModulePaths(entry).pkgBase);
|
|
2826
|
+
}
|
|
2770
2827
|
const imports = [];
|
|
2771
2828
|
const moduleDecls = [];
|
|
2772
2829
|
const importIdRef = { value: 0 };
|