@open-mercato/cli 0.6.3-develop.3604.1.abcb8d1963 → 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.
@@ -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 GENERATED_MODULE_SPECIFIER_PREFIXES = ["@/", "@open-mercato/", "../../src/modules/", "./"];
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 sanitizeGeneratedModuleSpecifier(importPath) {
643
- const prefix = GENERATED_MODULE_SPECIFIER_PREFIXES.find((candidate) => importPath.startsWith(candidate));
644
- if (!prefix) {
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
- const suffix = importPath.slice(prefix.length);
648
- if (!suffix) {
647
+ }
648
+ function sanitizeGeneratedModuleSpecifier(importPath) {
649
+ if (!importPath) {
649
650
  throw new Error(`Unsafe generated module specifier: ${importPath}`);
650
651
  }
651
- const segments = suffix.split("/").map((segment) => sanitizeGeneratedModuleSpecifierSegment(segment, importPath));
652
- return `${prefix}${segments.join("/")}`;
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 };