@open-mercato/cli 0.4.9-develop.1038.2d16936bed → 0.4.9-develop.1045.7bcda4435a

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.
@@ -103,12 +103,20 @@ function resolveModuleFile(roots, imps, relativePath) {
103
103
  if (!hasApp && !hasPkg) return null;
104
104
  const fromApp = hasApp;
105
105
  const absolutePath = fromApp ? appFile : pkgFile;
106
- const importSuffix = relativePath.replace(/\.ts$/, "");
106
+ const importSuffix = relativePath.replace(/\.tsx?$/, "");
107
107
  const importPath = `${fromApp ? imps.appBase : imps.pkgBase}/${importSuffix}`;
108
108
  return { absolutePath, fromApp, importPath };
109
109
  }
110
+ function resolveFirstModuleFile(roots, imps, relativePaths) {
111
+ for (const relativePath of relativePaths) {
112
+ const resolved = resolveModuleFile(roots, imps, relativePath);
113
+ if (resolved) return resolved;
114
+ }
115
+ return null;
116
+ }
110
117
  export {
111
118
  SCAN_CONFIGS,
119
+ resolveFirstModuleFile,
112
120
  resolveModuleFile,
113
121
  scanModuleDir
114
122
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/generators/scanner.ts"],
4
- "sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type ScannedFile = {\n relPath: string\n fromApp: boolean\n}\n\nexport type ScanConfig = {\n folder: string\n include: (name: string) => boolean\n skipDirs?: (name: string) => boolean\n sort?: (a: string, b: string) => number\n}\n\nexport type ModuleRoots = {\n appBase: string\n pkgBase: string\n}\n\nexport type ModuleImports = {\n appBase: string\n pkgBase: string\n}\n\nexport type ResolvedFile = {\n absolutePath: string\n fromApp: boolean\n importPath: string\n}\n\nfunction walkDir(\n dir: string,\n include: (name: string) => boolean,\n rel: string[] = [],\n skipDirs?: (name: string) => boolean\n): string[] {\n const found: string[] = []\n if (!fs.existsSync(dir)) return found\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n if (entry.name === '__tests__' || entry.name === '__mocks__') continue\n if (skipDirs && skipDirs(entry.name)) continue\n found.push(...walkDir(path.join(dir, entry.name), include, [...rel, entry.name], skipDirs))\n } else if (entry.isFile() && include(entry.name)) {\n found.push([...rel, entry.name].join('/'))\n }\n }\n return found\n}\n\nconst isDynamic = (p: string) => /\\/(\\[|\\[\\[\\.\\.\\.)/.test(p) || /^\\[/.test(p)\n\nfunction staticBeforeDynamicSort(a: string, b: string): number {\n const ad = isDynamic(a) ? 1 : 0\n const bd = isDynamic(b) ? 1 : 0\n if (ad !== bd) return ad - bd\n return a.localeCompare(b)\n}\n\nfunction isDynamicRoute(p: string): boolean {\n return p.split('/').some((seg) => /\\[|\\[\\[\\.\\.\\./.test(seg))\n}\n\nfunction apiRouteSort(a: string, b: string): number {\n const ad = isDynamicRoute(a) ? 1 : 0\n const bd = isDynamicRoute(b) ? 1 : 0\n if (ad !== bd) return ad - bd\n return a.localeCompare(b)\n}\n\nconst isTestFile = (name: string) => /\\.(test|spec)\\.ts$/.test(name)\nconst isTsFile = (name: string) => name.endsWith('.ts') && !isTestFile(name)\nconst isTsxFile = (name: string) => name.endsWith('.tsx')\nconst isRouteTs = (name: string) => name === 'route.ts'\nconst isWidgetFile = (name: string) => /^widget\\.(t|j)sx?$/.test(name)\nconst methodNames = new Set(['get', 'post', 'put', 'patch', 'delete'])\n\nexport const SCAN_CONFIGS = {\n frontendPages: {\n folder: 'frontend',\n include: isTsxFile,\n sort: staticBeforeDynamicSort,\n },\n backendPages: {\n folder: 'backend',\n include: isTsxFile,\n sort: staticBeforeDynamicSort,\n },\n apiRoutes: {\n folder: 'api',\n include: isRouteTs,\n sort: apiRouteSort,\n },\n apiPlainFiles: {\n folder: 'api',\n include: (name: string) => name.endsWith('.ts') && name !== 'route.ts' && !isTestFile(name),\n skipDirs: (name: string) => methodNames.has(name.toLowerCase()),\n },\n subscribers: {\n folder: 'subscribers',\n include: isTsFile,\n },\n workers: {\n folder: 'workers',\n include: isTsFile,\n },\n dashboardWidgets: {\n folder: 'widgets/dashboard',\n include: isWidgetFile,\n sort: (a: string, b: string) => a.localeCompare(b),\n },\n injectionWidgets: {\n folder: 'widgets/injection',\n include: isWidgetFile,\n sort: (a: string, b: string) => a.localeCompare(b),\n },\n} as const satisfies Record<string, ScanConfig>\n\nexport function scanModuleDir(roots: ModuleRoots, config: ScanConfig): ScannedFile[] {\n const folderSegments = config.folder ? config.folder.split('/') : []\n const appDir = path.join(roots.appBase, ...folderSegments)\n const pkgDir = path.join(roots.pkgBase, ...folderSegments)\n if (!fs.existsSync(appDir) && !fs.existsSync(pkgDir)) return []\n\n const found: string[] = []\n if (fs.existsSync(pkgDir)) found.push(...walkDir(pkgDir, config.include, [], config.skipDirs))\n if (fs.existsSync(appDir)) found.push(...walkDir(appDir, config.include, [], config.skipDirs))\n\n let files = Array.from(new Set(found))\n if (config.sort) {\n files.sort(config.sort)\n }\n\n return files.map((relPath) => {\n const appFile = path.join(appDir, ...relPath.split('/'))\n const fromApp = fs.existsSync(appFile)\n return { relPath, fromApp }\n })\n}\n\nexport function resolveModuleFile(\n roots: ModuleRoots,\n imps: ModuleImports,\n relativePath: string\n): ResolvedFile | null {\n const segments = relativePath.split('/')\n const appFile = path.join(roots.appBase, ...segments)\n const pkgFile = path.join(roots.pkgBase, ...segments)\n const hasApp = fs.existsSync(appFile)\n const hasPkg = fs.existsSync(pkgFile)\n if (!hasApp && !hasPkg) return null\n\n const fromApp = hasApp\n const absolutePath = fromApp ? appFile : pkgFile\n const importSuffix = relativePath.replace(/\\.ts$/, '')\n const importPath = `${fromApp ? imps.appBase : imps.pkgBase}/${importSuffix}`\n return { absolutePath, fromApp, importPath }\n}\n"],
5
- "mappings": "AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AA8BjB,SAAS,QACP,KACA,SACA,MAAgB,CAAC,GACjB,UACU;AACV,QAAM,QAAkB,CAAC;AACzB,MAAI,CAAC,GAAG,WAAW,GAAG,EAAG,QAAO;AAChC,aAAW,SAAS,GAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC,GAAG;AAChE,QAAI,MAAM,YAAY,GAAG;AACvB,UAAI,MAAM,SAAS,eAAe,MAAM,SAAS,YAAa;AAC9D,UAAI,YAAY,SAAS,MAAM,IAAI,EAAG;AACtC,YAAM,KAAK,GAAG,QAAQ,KAAK,KAAK,KAAK,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,KAAK,MAAM,IAAI,GAAG,QAAQ,CAAC;AAAA,IAC5F,WAAW,MAAM,OAAO,KAAK,QAAQ,MAAM,IAAI,GAAG;AAChD,YAAM,KAAK,CAAC,GAAG,KAAK,MAAM,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,IAC3C;AAAA,EACF;AACA,SAAO;AACT;AAEA,MAAM,YAAY,CAAC,MAAc,oBAAoB,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC;AAE5E,SAAS,wBAAwB,GAAW,GAAmB;AAC7D,QAAM,KAAK,UAAU,CAAC,IAAI,IAAI;AAC9B,QAAM,KAAK,UAAU,CAAC,IAAI,IAAI;AAC9B,MAAI,OAAO,GAAI,QAAO,KAAK;AAC3B,SAAO,EAAE,cAAc,CAAC;AAC1B;AAEA,SAAS,eAAe,GAAoB;AAC1C,SAAO,EAAE,MAAM,GAAG,EAAE,KAAK,CAAC,QAAQ,gBAAgB,KAAK,GAAG,CAAC;AAC7D;AAEA,SAAS,aAAa,GAAW,GAAmB;AAClD,QAAM,KAAK,eAAe,CAAC,IAAI,IAAI;AACnC,QAAM,KAAK,eAAe,CAAC,IAAI,IAAI;AACnC,MAAI,OAAO,GAAI,QAAO,KAAK;AAC3B,SAAO,EAAE,cAAc,CAAC;AAC1B;AAEA,MAAM,aAAa,CAAC,SAAiB,qBAAqB,KAAK,IAAI;AACnE,MAAM,WAAW,CAAC,SAAiB,KAAK,SAAS,KAAK,KAAK,CAAC,WAAW,IAAI;AAC3E,MAAM,YAAY,CAAC,SAAiB,KAAK,SAAS,MAAM;AACxD,MAAM,YAAY,CAAC,SAAiB,SAAS;AAC7C,MAAM,eAAe,CAAC,SAAiB,qBAAqB,KAAK,IAAI;AACrE,MAAM,cAAc,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,SAAS,QAAQ,CAAC;AAE9D,MAAM,eAAe;AAAA,EAC1B,eAAe;AAAA,IACb,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA,cAAc;AAAA,IACZ,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA,WAAW;AAAA,IACT,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA,eAAe;AAAA,IACb,QAAQ;AAAA,IACR,SAAS,CAAC,SAAiB,KAAK,SAAS,KAAK,KAAK,SAAS,cAAc,CAAC,WAAW,IAAI;AAAA,IAC1F,UAAU,CAAC,SAAiB,YAAY,IAAI,KAAK,YAAY,CAAC;AAAA,EAChE;AAAA,EACA,aAAa;AAAA,IACX,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,kBAAkB;AAAA,IAChB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM,CAAC,GAAW,MAAc,EAAE,cAAc,CAAC;AAAA,EACnD;AAAA,EACA,kBAAkB;AAAA,IAChB,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM,CAAC,GAAW,MAAc,EAAE,cAAc,CAAC;AAAA,EACnD;AACF;AAEO,SAAS,cAAc,OAAoB,QAAmC;AACnF,QAAM,iBAAiB,OAAO,SAAS,OAAO,OAAO,MAAM,GAAG,IAAI,CAAC;AACnE,QAAM,SAAS,KAAK,KAAK,MAAM,SAAS,GAAG,cAAc;AACzD,QAAM,SAAS,KAAK,KAAK,MAAM,SAAS,GAAG,cAAc;AACzD,MAAI,CAAC,GAAG,WAAW,MAAM,KAAK,CAAC,GAAG,WAAW,MAAM,EAAG,QAAO,CAAC;AAE9D,QAAM,QAAkB,CAAC;AACzB,MAAI,GAAG,WAAW,MAAM,EAAG,OAAM,KAAK,GAAG,QAAQ,QAAQ,OAAO,SAAS,CAAC,GAAG,OAAO,QAAQ,CAAC;AAC7F,MAAI,GAAG,WAAW,MAAM,EAAG,OAAM,KAAK,GAAG,QAAQ,QAAQ,OAAO,SAAS,CAAC,GAAG,OAAO,QAAQ,CAAC;AAE7F,MAAI,QAAQ,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC;AACrC,MAAI,OAAO,MAAM;AACf,UAAM,KAAK,OAAO,IAAI;AAAA,EACxB;AAEA,SAAO,MAAM,IAAI,CAAC,YAAY;AAC5B,UAAM,UAAU,KAAK,KAAK,QAAQ,GAAG,QAAQ,MAAM,GAAG,CAAC;AACvD,UAAM,UAAU,GAAG,WAAW,OAAO;AACrC,WAAO,EAAE,SAAS,QAAQ;AAAA,EAC5B,CAAC;AACH;AAEO,SAAS,kBACd,OACA,MACA,cACqB;AACrB,QAAM,WAAW,aAAa,MAAM,GAAG;AACvC,QAAM,UAAU,KAAK,KAAK,MAAM,SAAS,GAAG,QAAQ;AACpD,QAAM,UAAU,KAAK,KAAK,MAAM,SAAS,GAAG,QAAQ;AACpD,QAAM,SAAS,GAAG,WAAW,OAAO;AACpC,QAAM,SAAS,GAAG,WAAW,OAAO;AACpC,MAAI,CAAC,UAAU,CAAC,OAAQ,QAAO;AAE/B,QAAM,UAAU;AAChB,QAAM,eAAe,UAAU,UAAU;AACzC,QAAM,eAAe,aAAa,QAAQ,SAAS,EAAE;AACrD,QAAM,aAAa,GAAG,UAAU,KAAK,UAAU,KAAK,OAAO,IAAI,YAAY;AAC3E,SAAO,EAAE,cAAc,SAAS,WAAW;AAC7C;",
4
+ "sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\n\nexport type ScannedFile = {\n relPath: string\n fromApp: boolean\n}\n\nexport type ScanConfig = {\n folder: string\n include: (name: string) => boolean\n skipDirs?: (name: string) => boolean\n sort?: (a: string, b: string) => number\n}\n\nexport type ModuleRoots = {\n appBase: string\n pkgBase: string\n}\n\nexport type ModuleImports = {\n appBase: string\n pkgBase: string\n}\n\nexport type ResolvedFile = {\n absolutePath: string\n fromApp: boolean\n importPath: string\n}\n\nfunction walkDir(\n dir: string,\n include: (name: string) => boolean,\n rel: string[] = [],\n skipDirs?: (name: string) => boolean\n): string[] {\n const found: string[] = []\n if (!fs.existsSync(dir)) return found\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n if (entry.name === '__tests__' || entry.name === '__mocks__') continue\n if (skipDirs && skipDirs(entry.name)) continue\n found.push(...walkDir(path.join(dir, entry.name), include, [...rel, entry.name], skipDirs))\n } else if (entry.isFile() && include(entry.name)) {\n found.push([...rel, entry.name].join('/'))\n }\n }\n return found\n}\n\nconst isDynamic = (p: string) => /\\/(\\[|\\[\\[\\.\\.\\.)/.test(p) || /^\\[/.test(p)\n\nfunction staticBeforeDynamicSort(a: string, b: string): number {\n const ad = isDynamic(a) ? 1 : 0\n const bd = isDynamic(b) ? 1 : 0\n if (ad !== bd) return ad - bd\n return a.localeCompare(b)\n}\n\nfunction isDynamicRoute(p: string): boolean {\n return p.split('/').some((seg) => /\\[|\\[\\[\\.\\.\\./.test(seg))\n}\n\nfunction apiRouteSort(a: string, b: string): number {\n const ad = isDynamicRoute(a) ? 1 : 0\n const bd = isDynamicRoute(b) ? 1 : 0\n if (ad !== bd) return ad - bd\n return a.localeCompare(b)\n}\n\nconst isTestFile = (name: string) => /\\.(test|spec)\\.ts$/.test(name)\nconst isTsFile = (name: string) => name.endsWith('.ts') && !isTestFile(name)\nconst isTsxFile = (name: string) => name.endsWith('.tsx')\nconst isRouteTs = (name: string) => name === 'route.ts'\nconst isWidgetFile = (name: string) => /^widget\\.(t|j)sx?$/.test(name)\nconst methodNames = new Set(['get', 'post', 'put', 'patch', 'delete'])\n\nexport const SCAN_CONFIGS = {\n frontendPages: {\n folder: 'frontend',\n include: isTsxFile,\n sort: staticBeforeDynamicSort,\n },\n backendPages: {\n folder: 'backend',\n include: isTsxFile,\n sort: staticBeforeDynamicSort,\n },\n apiRoutes: {\n folder: 'api',\n include: isRouteTs,\n sort: apiRouteSort,\n },\n apiPlainFiles: {\n folder: 'api',\n include: (name: string) => name.endsWith('.ts') && name !== 'route.ts' && !isTestFile(name),\n skipDirs: (name: string) => methodNames.has(name.toLowerCase()),\n },\n subscribers: {\n folder: 'subscribers',\n include: isTsFile,\n },\n workers: {\n folder: 'workers',\n include: isTsFile,\n },\n dashboardWidgets: {\n folder: 'widgets/dashboard',\n include: isWidgetFile,\n sort: (a: string, b: string) => a.localeCompare(b),\n },\n injectionWidgets: {\n folder: 'widgets/injection',\n include: isWidgetFile,\n sort: (a: string, b: string) => a.localeCompare(b),\n },\n} as const satisfies Record<string, ScanConfig>\n\nexport function scanModuleDir(roots: ModuleRoots, config: ScanConfig): ScannedFile[] {\n const folderSegments = config.folder ? config.folder.split('/') : []\n const appDir = path.join(roots.appBase, ...folderSegments)\n const pkgDir = path.join(roots.pkgBase, ...folderSegments)\n if (!fs.existsSync(appDir) && !fs.existsSync(pkgDir)) return []\n\n const found: string[] = []\n if (fs.existsSync(pkgDir)) found.push(...walkDir(pkgDir, config.include, [], config.skipDirs))\n if (fs.existsSync(appDir)) found.push(...walkDir(appDir, config.include, [], config.skipDirs))\n\n let files = Array.from(new Set(found))\n if (config.sort) {\n files.sort(config.sort)\n }\n\n return files.map((relPath) => {\n const appFile = path.join(appDir, ...relPath.split('/'))\n const fromApp = fs.existsSync(appFile)\n return { relPath, fromApp }\n })\n}\n\nexport function resolveModuleFile(\n roots: ModuleRoots,\n imps: ModuleImports,\n relativePath: string\n): ResolvedFile | null {\n const segments = relativePath.split('/')\n const appFile = path.join(roots.appBase, ...segments)\n const pkgFile = path.join(roots.pkgBase, ...segments)\n const hasApp = fs.existsSync(appFile)\n const hasPkg = fs.existsSync(pkgFile)\n if (!hasApp && !hasPkg) return null\n\n const fromApp = hasApp\n const absolutePath = fromApp ? appFile : pkgFile\n const importSuffix = relativePath.replace(/\\.tsx?$/, '')\n const importPath = `${fromApp ? imps.appBase : imps.pkgBase}/${importSuffix}`\n return { absolutePath, fromApp, importPath }\n}\n\nexport function resolveFirstModuleFile(\n roots: ModuleRoots,\n imps: ModuleImports,\n relativePaths: string[],\n): ResolvedFile | null {\n for (const relativePath of relativePaths) {\n const resolved = resolveModuleFile(roots, imps, relativePath)\n if (resolved) return resolved\n }\n return null\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -984,6 +984,8 @@ async function clearStaleEphemeralEnvironmentLock(logPrefix) {
984
984
  function buildReusableEnvironment(baseUrl, captureScreenshots) {
985
985
  return buildEnvironment({
986
986
  BASE_URL: baseUrl,
987
+ APP_URL: baseUrl,
988
+ NEXT_PUBLIC_APP_URL: baseUrl,
987
989
  NODE_ENV: "production",
988
990
  JWT_SECRET: process.env.JWT_SECRET ?? "om-ephemeral-integration-jwt-secret",
989
991
  OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? "om-ephemeral-integration-mfa-setup-secret",
@@ -2044,6 +2046,8 @@ async function startEphemeralEnvironment(options) {
2044
2046
  const commandEnvironment = buildEnvironment({
2045
2047
  DATABASE_URL: databaseUrl,
2046
2048
  BASE_URL: applicationBaseUrl,
2049
+ APP_URL: applicationBaseUrl,
2050
+ NEXT_PUBLIC_APP_URL: applicationBaseUrl,
2047
2051
  JWT_SECRET: process.env.JWT_SECRET ?? "om-ephemeral-integration-jwt-secret",
2048
2052
  OM_SECURITY_MFA_SETUP_SECRET: process.env.OM_SECURITY_MFA_SETUP_SECRET ?? "om-ephemeral-integration-mfa-setup-secret",
2049
2053
  NODE_ENV: "production",