@open-mercato/cli 0.4.6-develop-e321a4e2a1 → 0.4.6-main-24e64eef39
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/entity-ids.js +1 -1
- package/dist/lib/generators/entity-ids.js.map +2 -2
- package/dist/lib/generators/module-registry.js +0 -63
- package/dist/lib/generators/module-registry.js.map +2 -2
- package/dist/lib/testing/integration.js +2 -2
- package/dist/lib/testing/integration.js.map +2 -2
- package/dist/lib/utils.js +2 -2
- package/dist/lib/utils.js.map +2 -2
- package/package.json +2 -2
- package/src/lib/generators/entity-ids.ts +1 -1
- package/src/lib/generators/module-registry.ts +0 -57
- package/src/lib/testing/integration.ts +2 -2
- package/src/lib/utils.ts +2 -2
package/dist/lib/utils.js
CHANGED
|
@@ -48,7 +48,7 @@ function collectStructureEntries(target, base, acc) {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
function calculateStructureChecksum(paths) {
|
|
51
|
-
const normalized = Array.from(new Set(paths.map((p) => path.resolve(p)))).sort(
|
|
51
|
+
const normalized = Array.from(new Set(paths.map((p) => path.resolve(p)))).sort();
|
|
52
52
|
const entries = [];
|
|
53
53
|
for (const target of normalized) {
|
|
54
54
|
if (!fs.existsSync(target)) {
|
|
@@ -123,7 +123,7 @@ function toVar(s) {
|
|
|
123
123
|
return s.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
124
124
|
}
|
|
125
125
|
function toSnake(s) {
|
|
126
|
-
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/\W+/g, "_").replace(/_{2,}/g, "_").replace(
|
|
126
|
+
return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/\W+/g, "_").replace(/_{2,}/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
|
|
127
127
|
}
|
|
128
128
|
async function moduleHasExport(filePath, exportName) {
|
|
129
129
|
try {
|
package/dist/lib/utils.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/lib/utils.ts"],
|
|
4
|
-
"sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport crypto from 'node:crypto'\nimport { pathToFileURL } from 'node:url'\n\nexport type ChecksumRecord = {\n content: string\n structure: string\n}\n\nexport interface GeneratorResult {\n filesWritten: string[]\n filesUnchanged: string[]\n errors: string[]\n}\n\nexport function calculateChecksum(content: string): string {\n return crypto.createHash('md5').update(content).digest('hex')\n}\n\nexport function readChecksumRecord(filePath: string): ChecksumRecord | null {\n if (!fs.existsSync(filePath)) {\n return null\n }\n try {\n const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8')) as Partial<ChecksumRecord>\n if (parsed && typeof parsed.content === 'string' && typeof parsed.structure === 'string') {\n return { content: parsed.content, structure: parsed.structure }\n }\n } catch {\n // Invalid checksum file\n }\n return null\n}\n\nexport function writeChecksumRecord(filePath: string, record: ChecksumRecord): void {\n fs.writeFileSync(filePath, JSON.stringify(record) + '\\n')\n}\n\nfunction collectStructureEntries(target: string, base: string, acc: string[]): void {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(target, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))\n } catch (err) {\n acc.push(`error:${path.relative(base, target)}:${(err as Error).message}`)\n return\n }\n\n for (const entry of entries) {\n const fullPath = path.join(target, entry.name)\n const rel = path.relative(base, fullPath)\n try {\n const stat = fs.statSync(fullPath)\n if (entry.isDirectory()) {\n acc.push(`dir:${rel}:${stat.mtimeMs}`)\n collectStructureEntries(fullPath, base, acc)\n } else if (entry.isFile()) {\n acc.push(`file:${rel}:${stat.size}:${stat.mtimeMs}`)\n } else {\n acc.push(`other:${rel}:${stat.mtimeMs}`)\n }\n } catch {\n // File was deleted between readdir and stat - skip it\n continue\n }\n }\n}\n\nexport function calculateStructureChecksum(paths: string[]): string {\n const normalized = Array.from(new Set(paths.map((p) => path.resolve(p)))).sort(
|
|
5
|
-
"mappings": "AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,YAAY;AACnB,SAAS,qBAAqB;AAavB,SAAS,kBAAkB,SAAyB;AACzD,SAAO,OAAO,WAAW,KAAK,EAAE,OAAO,OAAO,EAAE,OAAO,KAAK;AAC9D;AAEO,SAAS,mBAAmB,UAAyC;AAC1E,MAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;AAC5B,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,GAAG,aAAa,UAAU,MAAM,CAAC;AAC3D,QAAI,UAAU,OAAO,OAAO,YAAY,YAAY,OAAO,OAAO,cAAc,UAAU;AACxF,aAAO,EAAE,SAAS,OAAO,SAAS,WAAW,OAAO,UAAU;AAAA,IAChE;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEO,SAAS,oBAAoB,UAAkB,QAA8B;AAClF,KAAG,cAAc,UAAU,KAAK,UAAU,MAAM,IAAI,IAAI;AAC1D;AAEA,SAAS,wBAAwB,QAAgB,MAAc,KAAqB;AAClF,MAAI;AACJ,MAAI;AACF,cAAU,GAAG,YAAY,QAAQ,EAAE,eAAe,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAAA,EACvG,SAAS,KAAK;AACZ,QAAI,KAAK,SAAS,KAAK,SAAS,MAAM,MAAM,CAAC,IAAK,IAAc,OAAO,EAAE;AACzE;AAAA,EACF;AAEA,aAAW,SAAS,SAAS;AAC3B,UAAM,WAAW,KAAK,KAAK,QAAQ,MAAM,IAAI;AAC7C,UAAM,MAAM,KAAK,SAAS,MAAM,QAAQ;AACxC,QAAI;AACF,YAAM,OAAO,GAAG,SAAS,QAAQ;AACjC,UAAI,MAAM,YAAY,GAAG;AACvB,YAAI,KAAK,OAAO,GAAG,IAAI,KAAK,OAAO,EAAE;AACrC,gCAAwB,UAAU,MAAM,GAAG;AAAA,MAC7C,WAAW,MAAM,OAAO,GAAG;AACzB,YAAI,KAAK,QAAQ,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK,OAAO,EAAE;AAAA,MACrD,OAAO;AACL,YAAI,KAAK,SAAS,GAAG,IAAI,KAAK,OAAO,EAAE;AAAA,MACzC;AAAA,IACF,QAAQ;AAEN;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,2BAA2B,OAAyB;AAClE,QAAM,aAAa,MAAM,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK
|
|
4
|
+
"sourcesContent": ["import fs from 'node:fs'\nimport path from 'node:path'\nimport crypto from 'node:crypto'\nimport { pathToFileURL } from 'node:url'\n\nexport type ChecksumRecord = {\n content: string\n structure: string\n}\n\nexport interface GeneratorResult {\n filesWritten: string[]\n filesUnchanged: string[]\n errors: string[]\n}\n\nexport function calculateChecksum(content: string): string {\n return crypto.createHash('md5').update(content).digest('hex')\n}\n\nexport function readChecksumRecord(filePath: string): ChecksumRecord | null {\n if (!fs.existsSync(filePath)) {\n return null\n }\n try {\n const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8')) as Partial<ChecksumRecord>\n if (parsed && typeof parsed.content === 'string' && typeof parsed.structure === 'string') {\n return { content: parsed.content, structure: parsed.structure }\n }\n } catch {\n // Invalid checksum file\n }\n return null\n}\n\nexport function writeChecksumRecord(filePath: string, record: ChecksumRecord): void {\n fs.writeFileSync(filePath, JSON.stringify(record) + '\\n')\n}\n\nfunction collectStructureEntries(target: string, base: string, acc: string[]): void {\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(target, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))\n } catch (err) {\n acc.push(`error:${path.relative(base, target)}:${(err as Error).message}`)\n return\n }\n\n for (const entry of entries) {\n const fullPath = path.join(target, entry.name)\n const rel = path.relative(base, fullPath)\n try {\n const stat = fs.statSync(fullPath)\n if (entry.isDirectory()) {\n acc.push(`dir:${rel}:${stat.mtimeMs}`)\n collectStructureEntries(fullPath, base, acc)\n } else if (entry.isFile()) {\n acc.push(`file:${rel}:${stat.size}:${stat.mtimeMs}`)\n } else {\n acc.push(`other:${rel}:${stat.mtimeMs}`)\n }\n } catch {\n // File was deleted between readdir and stat - skip it\n continue\n }\n }\n}\n\nexport function calculateStructureChecksum(paths: string[]): string {\n const normalized = Array.from(new Set(paths.map((p) => path.resolve(p)))).sort()\n const entries: string[] = []\n for (const target of normalized) {\n if (!fs.existsSync(target)) {\n entries.push(`missing:${target}`)\n continue\n }\n const stat = fs.statSync(target)\n entries.push(`${stat.isDirectory() ? 'dir' : 'file'}:${target}:${stat.mtimeMs}`)\n if (stat.isDirectory()) collectStructureEntries(target, target, entries)\n }\n return calculateChecksum(entries.join('\\n'))\n}\n\nexport function writeIfChanged(\n filePath: string,\n content: string,\n checksumPath?: string,\n structureChecksum?: string\n): boolean {\n const newChecksum = calculateChecksum(content)\n\n if (checksumPath) {\n const existingRecord = readChecksumRecord(checksumPath)\n const newRecord: ChecksumRecord = {\n content: newChecksum,\n structure: structureChecksum || '',\n }\n\n const shouldWrite =\n !existingRecord ||\n existingRecord.content !== newRecord.content ||\n (structureChecksum && existingRecord.structure !== newRecord.structure)\n\n if (shouldWrite) {\n ensureDir(filePath)\n fs.writeFileSync(filePath, content)\n writeChecksumRecord(checksumPath, newRecord)\n return true\n }\n return false\n }\n\n // Simple comparison without checksum file\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, 'utf8')\n if (existing === content) {\n return false\n }\n }\n\n ensureDir(filePath)\n fs.writeFileSync(filePath, content)\n return true\n}\n\nexport function ensureDir(filePath: string): void {\n fs.mkdirSync(path.dirname(filePath), { recursive: true })\n}\n\n// Allowed path substrings for safe deletion. Include both POSIX and Windows separators.\nconst ALLOWED_RIMRAF_PATTERNS = [\n '/generated/',\n '/dist/',\n '/.mercato/',\n '/entities/',\n '\\\\generated\\\\',\n '\\\\dist\\\\',\n '\\\\.mercato\\\\',\n '\\\\entities\\\\',\n]\n\nexport function rimrafDir(dir: string, opts?: { allowedPatterns?: string[] }): void {\n if (!fs.existsSync(dir)) return\n\n // Safety check: only allow deletion within known safe directories\n const resolved = path.resolve(dir)\n const allowed = opts?.allowedPatterns ?? ALLOWED_RIMRAF_PATTERNS\n\n // Normalize resolved path to support matching against both POSIX and Windows patterns\n const normalized = {\n posix: resolved.replace(/\\\\/g, '/'),\n win: resolved.replace(/\\//g, '\\\\'),\n }\n\n if (!allowed.some((pattern) => normalized.posix.includes(pattern) || normalized.win.includes(pattern))) {\n throw new Error(`Refusing to delete directory outside allowed paths: ${resolved}. Allowed patterns: ${allowed.join(', ')}`)\n }\n\n for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {\n const p = path.join(dir, entry.name)\n if (entry.isDirectory()) rimrafDir(p, opts)\n else fs.unlinkSync(p)\n }\n fs.rmdirSync(dir)\n}\n\nexport function toVar(s: string): string {\n return s.replace(/[^a-zA-Z0-9_]/g, '_')\n}\n\nexport function toSnake(s: string): string {\n return s\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/\\W+/g, '_')\n .replace(/_{2,}/g, '_')\n .replace(/^_+|_+$/g, '')\n .toLowerCase()\n}\n\nexport async function moduleHasExport(filePath: string, exportName: string): Promise<boolean> {\n try {\n // On Windows, absolute paths must be file:// URLs for ESM imports\n // But package imports (starting with @ or not starting with . or /) should be used as-is\n const isAbsolutePath = path.isAbsolute(filePath)\n const importUrl = isAbsolutePath ? pathToFileURL(filePath).href : filePath\n const mod = await import(importUrl)\n return mod != null && Object.prototype.hasOwnProperty.call(mod, exportName)\n } catch {\n return false\n }\n}\n\nexport function logGenerationResult(label: string, changed: boolean): void {\n if (changed) {\n console.log(`Generated ${label}`)\n }\n}\n\nexport function createGeneratorResult(): GeneratorResult {\n return {\n filesWritten: [],\n filesUnchanged: [],\n errors: [],\n }\n}\n\nexport function writeGeneratedFile(options: {\n outFile: string\n checksumFile: string\n content: string\n structureChecksum: string\n result: GeneratorResult\n quiet?: boolean\n}): void {\n const { outFile, checksumFile, content, structureChecksum, result, quiet } = options\n const checksum = { content: calculateChecksum(content), structure: structureChecksum }\n const existing = readChecksumRecord(checksumFile)\n const shouldWrite =\n !existing ||\n existing.content !== checksum.content ||\n existing.structure !== checksum.structure\n if (shouldWrite) {\n fs.mkdirSync(path.dirname(outFile), { recursive: true })\n fs.writeFileSync(outFile, content)\n writeChecksumRecord(checksumFile, checksum)\n result.filesWritten.push(outFile)\n } else {\n result.filesUnchanged.push(outFile)\n }\n if (!quiet) logGenerationResult(path.relative(process.cwd(), outFile), shouldWrite)\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/cli",
|
|
3
|
-
"version": "0.4.6-
|
|
3
|
+
"version": "0.4.6-main-24e64eef39",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"@mikro-orm/core": "^6.6.2",
|
|
59
59
|
"@mikro-orm/migrations": "^6.6.2",
|
|
60
60
|
"@mikro-orm/postgresql": "^6.6.2",
|
|
61
|
-
"@open-mercato/shared": "0.4.6-
|
|
61
|
+
"@open-mercato/shared": "0.4.6-main-24e64eef39",
|
|
62
62
|
"pg": "8.16.3",
|
|
63
63
|
"testcontainers": "^11.12.0",
|
|
64
64
|
"typescript": "^5.9.3"
|
|
@@ -129,7 +129,7 @@ function writePerEntityFieldFiles(outRoot: string, fieldsByEntity: EntityFieldMa
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
function writeEntityFieldsRegistry(generatedRoot: string, fieldsByEntity: EntityFieldMap): void {
|
|
132
|
-
const entities = Object.keys(fieldsByEntity).sort(
|
|
132
|
+
const entities = Object.keys(fieldsByEntity).sort()
|
|
133
133
|
|
|
134
134
|
// Always write the file, even if empty, to prevent TypeScript import errors
|
|
135
135
|
const imports = entities.length > 0
|
|
@@ -407,10 +407,6 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
407
407
|
const transFieldsChecksumFile = path.join(outputDir, 'translations-fields.generated.checksum')
|
|
408
408
|
const enrichersOutFile = path.join(outputDir, 'enrichers.generated.ts')
|
|
409
409
|
const enrichersChecksumFile = path.join(outputDir, 'enrichers.generated.checksum')
|
|
410
|
-
const interceptorsOutFile = path.join(outputDir, 'interceptors.generated.ts')
|
|
411
|
-
const interceptorsChecksumFile = path.join(outputDir, 'interceptors.generated.checksum')
|
|
412
|
-
const componentOverridesOutFile = path.join(outputDir, 'component-overrides.generated.ts')
|
|
413
|
-
const componentOverridesChecksumFile = path.join(outputDir, 'component-overrides.generated.checksum')
|
|
414
410
|
const inboxActionsOutFile = path.join(outputDir, 'inbox-actions.generated.ts')
|
|
415
411
|
const inboxActionsChecksumFile = path.join(outputDir, 'inbox-actions.generated.checksum')
|
|
416
412
|
|
|
@@ -444,10 +440,6 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
444
440
|
const transFieldsImports: string[] = []
|
|
445
441
|
const enricherConfigs: string[] = []
|
|
446
442
|
const enricherImports: string[] = []
|
|
447
|
-
const interceptorConfigs: string[] = []
|
|
448
|
-
const interceptorImports: string[] = []
|
|
449
|
-
const componentOverrideConfigs: string[] = []
|
|
450
|
-
const componentOverrideImports: string[] = []
|
|
451
443
|
const inboxActionsConfigs: string[] = []
|
|
452
444
|
const inboxActionsImports: string[] = []
|
|
453
445
|
|
|
@@ -660,26 +652,6 @@ export async function generateModuleRegistry(options: ModuleRegistryOptions): Pr
|
|
|
660
652
|
configExpr: (n, id) => `{ moduleId: '${id}', enrichers: ((${n} as any).enrichers ?? (${n} as any).default ?? []) }`,
|
|
661
653
|
})
|
|
662
654
|
|
|
663
|
-
// 10c. API interceptors: api/interceptors.ts
|
|
664
|
-
processStandaloneConfig({
|
|
665
|
-
roots, imps, modId, importIdRef,
|
|
666
|
-
relativePath: 'api/interceptors.ts',
|
|
667
|
-
prefix: 'INTERCEPTORS',
|
|
668
|
-
standaloneImports: interceptorImports,
|
|
669
|
-
standaloneConfigs: interceptorConfigs,
|
|
670
|
-
configExpr: (n, id) => `{ moduleId: '${id}', interceptors: ((${n} as any).interceptors ?? (${n} as any).default ?? []) }`,
|
|
671
|
-
})
|
|
672
|
-
|
|
673
|
-
// 10d. Component overrides: widgets/components.ts
|
|
674
|
-
processStandaloneConfig({
|
|
675
|
-
roots, imps, modId, importIdRef,
|
|
676
|
-
relativePath: 'widgets/components.ts',
|
|
677
|
-
prefix: 'COMPONENT_OVERRIDES',
|
|
678
|
-
standaloneImports: componentOverrideImports,
|
|
679
|
-
standaloneConfigs: componentOverrideConfigs,
|
|
680
|
-
configExpr: (n, id) => `{ moduleId: '${id}', componentOverrides: ((${n} as any).componentOverrides ?? (${n} as any).default ?? []) }`,
|
|
681
|
-
})
|
|
682
|
-
|
|
683
655
|
// Translatable fields: translations.ts (also referenced in module declarations)
|
|
684
656
|
let transFieldsImportName: string | null = null
|
|
685
657
|
transFieldsImportName = processStandaloneConfig({
|
|
@@ -1283,35 +1255,6 @@ export function getRegisteredActionTypes(): string[] {
|
|
|
1283
1255
|
`
|
|
1284
1256
|
writeGeneratedFile({ outFile: inboxActionsOutFile, checksumFile: inboxActionsChecksumFile, content: inboxActionsOutput, structureChecksum, result, quiet })
|
|
1285
1257
|
|
|
1286
|
-
const interceptorEntriesLiteral = interceptorConfigs.join(',\n ')
|
|
1287
|
-
const interceptorImportSection = interceptorImports.join('\n')
|
|
1288
|
-
const interceptorsOutput = `// AUTO-GENERATED by mercato generate registry
|
|
1289
|
-
import type { ApiInterceptor } from '@open-mercato/shared/lib/crud/api-interceptor'
|
|
1290
|
-
${interceptorImportSection ? `\n${interceptorImportSection}\n` : '\n'}type InterceptorEntry = { moduleId: string; interceptors: ApiInterceptor[] }
|
|
1291
|
-
|
|
1292
|
-
export const interceptorEntries: InterceptorEntry[] = [
|
|
1293
|
-
${interceptorEntriesLiteral ? ` ${interceptorEntriesLiteral}\n` : ''}]
|
|
1294
|
-
`
|
|
1295
|
-
writeGeneratedFile({ outFile: interceptorsOutFile, checksumFile: interceptorsChecksumFile, content: interceptorsOutput, structureChecksum, result, quiet })
|
|
1296
|
-
|
|
1297
|
-
const componentOverrideEntriesLiteral = componentOverrideConfigs.join(',\n ')
|
|
1298
|
-
const componentOverrideImportSection = componentOverrideImports.join('\n')
|
|
1299
|
-
const componentOverridesOutput = `// AUTO-GENERATED by mercato generate registry
|
|
1300
|
-
import type { ComponentOverride } from '@open-mercato/shared/modules/widgets/component-registry'
|
|
1301
|
-
${componentOverrideImportSection ? `\n${componentOverrideImportSection}\n` : '\n'}type ComponentOverrideEntry = { moduleId: string; componentOverrides: ComponentOverride[] }
|
|
1302
|
-
|
|
1303
|
-
export const componentOverrideEntries: ComponentOverrideEntry[] = [
|
|
1304
|
-
${componentOverrideEntriesLiteral ? ` ${componentOverrideEntriesLiteral}\n` : ''}]
|
|
1305
|
-
`
|
|
1306
|
-
writeGeneratedFile({
|
|
1307
|
-
outFile: componentOverridesOutFile,
|
|
1308
|
-
checksumFile: componentOverridesChecksumFile,
|
|
1309
|
-
content: componentOverridesOutput,
|
|
1310
|
-
structureChecksum,
|
|
1311
|
-
result,
|
|
1312
|
-
quiet,
|
|
1313
|
-
})
|
|
1314
|
-
|
|
1315
1258
|
return result
|
|
1316
1259
|
}
|
|
1317
1260
|
|
|
@@ -160,7 +160,7 @@ const PLAYWRIGHT_ENV_UNAVAILABLE_PATTERNS: RegExp[] = [
|
|
|
160
160
|
const PLAYWRIGHT_QUICK_FAILURE_THRESHOLD = 6
|
|
161
161
|
const PLAYWRIGHT_QUICK_FAILURE_MAX_DURATION_MS = 1_500
|
|
162
162
|
const PLAYWRIGHT_HEALTH_PROBE_INTERVAL_MS = 3_000
|
|
163
|
-
const ANSI_ESCAPE_REGEX = /\
|
|
163
|
+
const ANSI_ESCAPE_REGEX = /\u001b\[[0-?]*[ -/]*[@-~]/g
|
|
164
164
|
const NEXT_STATIC_ASSET_PATTERN = /\/_next\/static\/[^"'`\s)]+?\.(?:js|css)/g
|
|
165
165
|
const resolver = createResolver()
|
|
166
166
|
const projectRootDirectory = resolver.getRootDir()
|
|
@@ -755,7 +755,7 @@ async function buildSourceFingerprint(options: BuildCacheOptions = {}): Promise<
|
|
|
755
755
|
}
|
|
756
756
|
|
|
757
757
|
const fingerprintParts: string[] = []
|
|
758
|
-
for (const filePath of absoluteFiles.sort(
|
|
758
|
+
for (const filePath of absoluteFiles.sort()) {
|
|
759
759
|
const fileStat = await stat(filePath)
|
|
760
760
|
if (!fileStat.isFile()) {
|
|
761
761
|
continue
|
package/src/lib/utils.ts
CHANGED
|
@@ -67,7 +67,7 @@ function collectStructureEntries(target: string, base: string, acc: string[]): v
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
export function calculateStructureChecksum(paths: string[]): string {
|
|
70
|
-
const normalized = Array.from(new Set(paths.map((p) => path.resolve(p)))).sort(
|
|
70
|
+
const normalized = Array.from(new Set(paths.map((p) => path.resolve(p)))).sort()
|
|
71
71
|
const entries: string[] = []
|
|
72
72
|
for (const target of normalized) {
|
|
73
73
|
if (!fs.existsSync(target)) {
|
|
@@ -173,7 +173,7 @@ export function toSnake(s: string): string {
|
|
|
173
173
|
.replace(/([a-z0-9])([A-Z])/g, '$1_$2')
|
|
174
174
|
.replace(/\W+/g, '_')
|
|
175
175
|
.replace(/_{2,}/g, '_')
|
|
176
|
-
.replace(
|
|
176
|
+
.replace(/^_+|_+$/g, '')
|
|
177
177
|
.toLowerCase()
|
|
178
178
|
}
|
|
179
179
|
|