@warlock.js/core 5.36.0 → 5.37.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/esm/cli/commands/migrate.command.mjs +10 -0
  3. package/esm/cli/commands/migrate.command.mjs.map +1 -1
  4. package/esm/cli/commands/release/release-command.action.mjs +245 -0
  5. package/esm/cli/commands/release/release-command.action.mjs.map +1 -0
  6. package/esm/cli/commands/release.command.mjs +66 -0
  7. package/esm/cli/commands/release.command.mjs.map +1 -0
  8. package/esm/cli/framework-cli-commands.mjs +2 -0
  9. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  10. package/esm/database/migrate-action.mjs +24 -2
  11. package/esm/database/migrate-action.mjs.map +1 -1
  12. package/esm/dev-server/loader/load-hook.d.mts.map +1 -1
  13. package/esm/dev-server/loader/load-hook.mjs +6 -0
  14. package/esm/dev-server/loader/load-hook.mjs.map +1 -1
  15. package/esm/index.d.mts +3 -2
  16. package/esm/index.mjs +2 -2
  17. package/esm/production/route-registration-snapshot.mjs +10 -3
  18. package/esm/production/route-registration-snapshot.mjs.map +1 -1
  19. package/esm/release/activate.mjs +261 -0
  20. package/esm/release/activate.mjs.map +1 -0
  21. package/esm/release/candidate.mjs +107 -0
  22. package/esm/release/candidate.mjs.map +1 -0
  23. package/esm/release/cascade-migration-provider.mjs +32 -0
  24. package/esm/release/cascade-migration-provider.mjs.map +1 -0
  25. package/esm/release/config.mjs +60 -0
  26. package/esm/release/config.mjs.map +1 -0
  27. package/esm/release/gate.mjs +67 -0
  28. package/esm/release/gate.mjs.map +1 -0
  29. package/esm/release/migrations-proof.mjs +100 -0
  30. package/esm/release/migrations-proof.mjs.map +1 -0
  31. package/esm/release/prune.mjs +42 -0
  32. package/esm/release/prune.mjs.map +1 -0
  33. package/esm/release/report.mjs +25 -0
  34. package/esm/release/report.mjs.map +1 -0
  35. package/esm/release/runner.mjs +55 -0
  36. package/esm/release/runner.mjs.map +1 -0
  37. package/esm/release/semver.mjs +53 -0
  38. package/esm/release/semver.mjs.map +1 -0
  39. package/esm/release/stage.mjs +122 -0
  40. package/esm/release/stage.mjs.map +1 -0
  41. package/esm/release/store.mjs +131 -0
  42. package/esm/release/store.mjs.map +1 -0
  43. package/esm/release/types.d.mts +102 -0
  44. package/esm/release/types.d.mts.map +1 -0
  45. package/esm/release/verify.mjs +94 -0
  46. package/esm/release/verify.mjs.map +1 -0
  47. package/esm/router/index.d.mts +2 -2
  48. package/esm/router/index.mjs +2 -2
  49. package/esm/router/router.d.mts +4 -2
  50. package/esm/router/router.d.mts.map +1 -1
  51. package/esm/router/router.mjs +13 -5
  52. package/esm/router/router.mjs.map +1 -1
  53. package/esm/router/types.d.mts +26 -0
  54. package/esm/router/types.d.mts.map +1 -1
  55. package/esm/router/unguarded-route-diagnostics.d.mts +6 -0
  56. package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -1
  57. package/esm/router/unguarded-route-diagnostics.mjs +10 -2
  58. package/esm/router/unguarded-route-diagnostics.mjs.map +1 -1
  59. package/esm/tooling/check/security-conventions.mjs +19 -1
  60. package/esm/tooling/check/security-conventions.mjs.map +1 -1
  61. package/esm/tooling/inspect/collect-routes.mjs +3 -2
  62. package/esm/tooling/inspect/collect-routes.mjs.map +1 -1
  63. package/esm/validation/init.mjs +11 -4
  64. package/esm/validation/init.mjs.map +1 -1
  65. package/esm/validation/translate-rule.mjs +63 -0
  66. package/esm/validation/translate-rule.mjs.map +1 -0
  67. package/esm/warlock-config/index.d.mts +2 -1
  68. package/esm/warlock-config/types.d.mts +8 -0
  69. package/esm/warlock-config/types.d.mts.map +1 -1
  70. package/llms-full.txt +94 -2
  71. package/llms.txt +1 -0
  72. package/package.json +13 -13
  73. package/skills/deploy-release/SKILL.md +76 -0
  74. package/skills/index.md +1 -1
  75. package/skills/register-route/SKILL.md +12 -0
  76. package/skills/warlock-conventions/SKILL.md +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"load-hook.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/loader/load-hook.ts"],"sourcesContent":["import { transformSync } from \"esbuild\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { sourceSlug } from \"./source-slug.js\";\nimport { cacheKey, TranspileCache } from \"./transpile-cache.js\";\n\ntype LoadContext = {\n format?: string;\n importAttributes?: Record<string, string>;\n};\n\ntype LoadResult = {\n format: string;\n source: string | Buffer;\n shortCircuit?: boolean;\n};\n\ntype NextLoad = (url: string, context?: LoadContext) => Promise<LoadResult>;\n\n/**\n * Everything the transpile path needs, computed once on the main thread and\n * shipped into the hook worker via `initialize()`. Always present — esbuild\n * transpile is unconditional now (tsx is no longer in the TS path).\n */\nexport type TranspileInit = {\n /** Absolute `.warlock/transpile` directory. */\n cacheDir: string;\n /** Source-content key salt: esbuild version + epoch + tsconfig blob. */\n fingerprint: string;\n /** esbuild `target` (e.g. `\"node22\"` — must match the prod builder). */\n target: string;\n /** JSON string of `{ compilerOptions }` handed to esbuild as tsconfigRaw. */\n tsconfigRaw: string;\n /**\n * Debug-only: name cache files `<slug>.<hash>.js` and append a trailing\n * `// @source <path>` marker so entries are eyeball-identifiable. Off by\n * default (opaque `<hash>.js`). Cosmetic — never affects keys or lookup.\n */\n debugNames: boolean;\n};\n\nconst VERSION_QUERY = /\\?v=\\d+$/;\nconst TS_FILE = /\\.(ts|tsx|mts|cts)$/;\n\nlet transpile: TranspileInit;\nlet cache: TranspileCache;\n\n/**\n * Called once from the hook worker's `initialize()`. Wires the persisted\n * transpile cache and runs one opportunistic GC pass at boot — cheap, off\n * the hot path, single directory scan.\n */\nexport function configureTranspile(init: TranspileInit): void {\n transpile = init;\n cache = new TranspileCache(init.cacheDir);\n\n // Boot-time eviction so the cache can't grow unbounded across weeks of\n // dev. Bounds are generous; correctness never depends on GC (content\n // hashing already guarantees that) — this is purely disk hygiene.\n cache.gc({\n maxBytes: 256 * 1024 * 1024,\n maxAgeMs: 14 * 24 * 60 * 60 * 1000,\n });\n}\n\n/**\n * ESM loader `load()` hook.\n *\n * Owns the transpile for **every** TypeScript file — project `src/`,\n * `@warlock.js/*` framework source, and `warlock.config.ts` alike. There\n * is no tsx in the TypeScript path any more: we read the source, key it by\n * a content hash + options fingerprint, serve the cached JS on a hit, and\n * otherwise transform it with esbuild directly and persist. Non-TypeScript\n * URLs (npm `.js`/`.cjs`/`.mjs`, `node:` builtins, JSON) are not ours —\n * they fall through to the next loader (Node's default).\n *\n * The `?v=<N>` query drives Node's module identity (HMR) for `src/` files\n * and is **never** part of the cache key — the cache is keyed purely by\n * source content, so the two mechanisms are fully orthogonal. Framework\n * and config `.ts` carry no `?v` (no HMR) but are transpiled and cached\n * exactly the same way.\n *\n * The source map esbuild emits is inline base64 with `sourcefile` set to\n * the clean absolute `.ts` path, so V8 (run with source maps enabled)\n * reports stack frames at the original TypeScript location.\n *\n * @example\n * // load(\"file:///src/user.model.ts?v=3\") → esbuild transpile + cache\n * // load(\"file:///@warlock.js/core/src/x.ts\") → esbuild transpile + cache\n * // load(\"file:///node_modules/ms/index.js\") → nextLoad (Node default)\n */\nexport async function load(\n url: string,\n context: LoadContext,\n nextLoad: NextLoad,\n): Promise<LoadResult> {\n const cleanUrl = url.replace(VERSION_QUERY, \"\");\n\n // Not TypeScript → not ours. npm packages, node: builtins, JSON, etc.\n if (!TS_FILE.test(cleanUrl)) {\n return nextLoad(url, context);\n }\n\n const absolutePath = fileURLToPath(cleanUrl);\n const source = readFileSync(absolutePath, \"utf8\");\n const key = cacheKey(source, transpile.fingerprint);\n\n // Cosmetic filename label; undefined keeps opaque <hash>.js names.\n const label = transpile.debugNames ? sourceSlug(absolutePath) : undefined;\n\n const hit = cache.get(key, label);\n if (hit) {\n return { format: \"module\", source: hit.code, shortCircuit: true };\n }\n\n const loader = absolutePath.endsWith(\".tsx\") ? \"tsx\" : \"ts\";\n\n const result = transformSync(source, {\n loader,\n format: \"esm\",\n target: transpile.target,\n sourcefile: absolutePath,\n // Inline base64 map, self-contained (sourcesContent on by default), so\n // it survives the ?v=N URL with no extra resolution step.\n sourcemap: \"inline\",\n tsconfigRaw: transpile.tsconfigRaw,\n });\n\n // result.code already carries the inline //# sourceMappingURL. The\n // marker goes AFTER that line: a trailing comment can't shift earlier\n // generated lines, so the inline map (and therefore stack-frame line\n // numbers) stays exact. A leading marker would desync it by one line.\n const code = label ? `${result.code}\\n// @source ${absolutePath}\\n` : result.code;\n\n cache.put(key, { code, map: \"\" }, label);\n\n return { format: \"module\", source: code, shortCircuit: true };\n}\n"],"mappings":";;;;;;;AAyCA,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAEhB,IAAI;AACJ,IAAI;;;;;;AAOJ,SAAgB,mBAAmB,MAA2B;CAC5D,YAAY;CACZ,QAAQ,IAAI,eAAe,KAAK,QAAQ;CAKxC,MAAM,GAAG;EACP,UAAU;EACV,UAAU;CACZ,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,KACpB,KACA,SACA,UACqB;CACrB,MAAM,WAAW,IAAI,QAAQ,eAAe,EAAE;CAG9C,IAAI,CAAC,QAAQ,KAAK,QAAQ,GACxB,OAAO,SAAS,KAAK,OAAO;CAG9B,MAAM,eAAe,cAAc,QAAQ;CAC3C,MAAM,SAAS,aAAa,cAAc,MAAM;CAChD,MAAM,MAAM,SAAS,QAAQ,UAAU,WAAW;CAGlD,MAAM,QAAQ,UAAU,aAAa,WAAW,YAAY,IAAI;CAEhE,MAAM,MAAM,MAAM,IAAI,KAAK,KAAK;CAChC,IAAI,KACF,OAAO;EAAE,QAAQ;EAAU,QAAQ,IAAI;EAAM,cAAc;CAAK;CAGlE,MAAM,SAAS,aAAa,SAAS,MAAM,IAAI,QAAQ;CAEvD,MAAM,SAAS,cAAc,QAAQ;EACnC;EACA,QAAQ;EACR,QAAQ,UAAU;EAClB,YAAY;EAGZ,WAAW;EACX,aAAa,UAAU;CACzB,CAAC;CAMD,MAAM,OAAO,QAAQ,GAAG,OAAO,KAAK,eAAe,aAAa,MAAM,OAAO;CAE7E,MAAM,IAAI,KAAK;EAAE;EAAM,KAAK;CAAG,GAAG,KAAK;CAEvC,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAM,cAAc;CAAK;AAC9D"}
1
+ {"version":3,"file":"load-hook.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/loader/load-hook.ts"],"sourcesContent":["import { transformSync } from \"esbuild\";\nimport { readFileSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport { sourceSlug } from \"./source-slug.js\";\nimport { cacheKey, TranspileCache } from \"./transpile-cache.js\";\n\ntype LoadContext = {\n format?: string;\n importAttributes?: Record<string, string>;\n};\n\ntype LoadResult = {\n format: string;\n source: string | Buffer;\n shortCircuit?: boolean;\n};\n\ntype NextLoad = (url: string, context?: LoadContext) => Promise<LoadResult>;\n\n/**\n * Everything the transpile path needs, computed once on the main thread and\n * shipped into the hook worker via `initialize()`. Always present — esbuild\n * transpile is unconditional now (tsx is no longer in the TS path).\n */\nexport type TranspileInit = {\n /** Absolute `.warlock/transpile` directory. */\n cacheDir: string;\n /** Source-content key salt: esbuild version + epoch + tsconfig blob. */\n fingerprint: string;\n /** esbuild `target` (e.g. `\"node22\"` — must match the prod builder). */\n target: string;\n /** JSON string of `{ compilerOptions }` handed to esbuild as tsconfigRaw. */\n tsconfigRaw: string;\n /**\n * Debug-only: name cache files `<slug>.<hash>.js` and append a trailing\n * `// @source <path>` marker so entries are eyeball-identifiable. Off by\n * default (opaque `<hash>.js`). Cosmetic — never affects keys or lookup.\n */\n debugNames: boolean;\n};\n\nconst VERSION_QUERY = /\\?v=\\d+$/;\nconst TS_FILE = /\\.(ts|tsx|mts|cts)$/;\nconst STYLESHEET_FILE = /\\.(css|scss|sass|less|styl)$/;\n\nlet transpile: TranspileInit;\nlet cache: TranspileCache;\n\n/**\n * Called once from the hook worker's `initialize()`. Wires the persisted\n * transpile cache and runs one opportunistic GC pass at boot — cheap, off\n * the hot path, single directory scan.\n */\nexport function configureTranspile(init: TranspileInit): void {\n transpile = init;\n cache = new TranspileCache(init.cacheDir);\n\n // Boot-time eviction so the cache can't grow unbounded across weeks of\n // dev. Bounds are generous; correctness never depends on GC (content\n // hashing already guarantees that) — this is purely disk hygiene.\n cache.gc({\n maxBytes: 256 * 1024 * 1024,\n maxAgeMs: 14 * 24 * 60 * 60 * 1000,\n });\n}\n\n/**\n * ESM loader `load()` hook.\n *\n * Owns the transpile for **every** TypeScript file — project `src/`,\n * `@warlock.js/*` framework source, and `warlock.config.ts` alike. There\n * is no tsx in the TypeScript path any more: we read the source, key it by\n * a content hash + options fingerprint, serve the cached JS on a hit, and\n * otherwise transform it with esbuild directly and persist. Non-TypeScript\n * URLs (npm `.js`/`.cjs`/`.mjs`, `node:` builtins, JSON) are not ours —\n * they fall through to the next loader (Node's default).\n *\n * The `?v=<N>` query drives Node's module identity (HMR) for `src/` files\n * and is **never** part of the cache key — the cache is keyed purely by\n * source content, so the two mechanisms are fully orthogonal. Framework\n * and config `.ts` carry no `?v` (no HMR) but are transpiled and cached\n * exactly the same way.\n *\n * The source map esbuild emits is inline base64 with `sourcefile` set to\n * the clean absolute `.ts` path, so V8 (run with source maps enabled)\n * reports stack frames at the original TypeScript location.\n *\n * @example\n * // load(\"file:///src/user.model.ts?v=3\") → esbuild transpile + cache\n * // load(\"file:///@warlock.js/core/src/x.ts\") → esbuild transpile + cache\n * // load(\"file:///node_modules/ms/index.js\") → nextLoad (Node default)\n */\nexport async function load(\n url: string,\n context: LoadContext,\n nextLoad: NextLoad,\n): Promise<LoadResult> {\n const cleanUrl = url.replace(VERSION_QUERY, \"\");\n\n // A stylesheet imported by a component. Node cannot load one, and in Node the\n // styles have no meaning: a module graph imported for its exports (sitemap\n // discovery, page listing) only needs the import to resolve. CSS modules get\n // an empty class map.\n if (STYLESHEET_FILE.test(cleanUrl)) {\n return { format: \"module\", source: \"export default {};\\n\", shortCircuit: true };\n }\n\n // Not TypeScript → not ours. npm packages, node: builtins, JSON, etc.\n if (!TS_FILE.test(cleanUrl)) {\n return nextLoad(url, context);\n }\n\n const absolutePath = fileURLToPath(cleanUrl);\n const source = readFileSync(absolutePath, \"utf8\");\n const key = cacheKey(source, transpile.fingerprint);\n\n // Cosmetic filename label; undefined keeps opaque <hash>.js names.\n const label = transpile.debugNames ? sourceSlug(absolutePath) : undefined;\n\n const hit = cache.get(key, label);\n if (hit) {\n return { format: \"module\", source: hit.code, shortCircuit: true };\n }\n\n const loader = absolutePath.endsWith(\".tsx\") ? \"tsx\" : \"ts\";\n\n const result = transformSync(source, {\n loader,\n format: \"esm\",\n target: transpile.target,\n sourcefile: absolutePath,\n // Inline base64 map, self-contained (sourcesContent on by default), so\n // it survives the ?v=N URL with no extra resolution step.\n sourcemap: \"inline\",\n tsconfigRaw: transpile.tsconfigRaw,\n });\n\n // result.code already carries the inline //# sourceMappingURL. The\n // marker goes AFTER that line: a trailing comment can't shift earlier\n // generated lines, so the inline map (and therefore stack-frame line\n // numbers) stays exact. A leading marker would desync it by one line.\n const code = label ? `${result.code}\\n// @source ${absolutePath}\\n` : result.code;\n\n cache.put(key, { code, map: \"\" }, label);\n\n return { format: \"module\", source: code, shortCircuit: true };\n}\n"],"mappings":";;;;;;;AAyCA,MAAM,gBAAgB;AACtB,MAAM,UAAU;AAChB,MAAM,kBAAkB;AAExB,IAAI;AACJ,IAAI;;;;;;AAOJ,SAAgB,mBAAmB,MAA2B;CAC5D,YAAY;CACZ,QAAQ,IAAI,eAAe,KAAK,QAAQ;CAKxC,MAAM,GAAG;EACP,UAAU;EACV,UAAU;CACZ,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,eAAsB,KACpB,KACA,SACA,UACqB;CACrB,MAAM,WAAW,IAAI,QAAQ,eAAe,EAAE;CAM9C,IAAI,gBAAgB,KAAK,QAAQ,GAC/B,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAwB,cAAc;CAAK;CAIhF,IAAI,CAAC,QAAQ,KAAK,QAAQ,GACxB,OAAO,SAAS,KAAK,OAAO;CAG9B,MAAM,eAAe,cAAc,QAAQ;CAC3C,MAAM,SAAS,aAAa,cAAc,MAAM;CAChD,MAAM,MAAM,SAAS,QAAQ,UAAU,WAAW;CAGlD,MAAM,QAAQ,UAAU,aAAa,WAAW,YAAY,IAAI;CAEhE,MAAM,MAAM,MAAM,IAAI,KAAK,KAAK;CAChC,IAAI,KACF,OAAO;EAAE,QAAQ;EAAU,QAAQ,IAAI;EAAM,cAAc;CAAK;CAGlE,MAAM,SAAS,aAAa,SAAS,MAAM,IAAI,QAAQ;CAEvD,MAAM,SAAS,cAAc,QAAQ;EACnC;EACA,QAAQ;EACR,QAAQ,UAAU;EAClB,YAAY;EAGZ,WAAW;EACX,aAAa,UAAU;CACzB,CAAC;CAMD,MAAM,OAAO,QAAQ,GAAG,OAAO,KAAK,eAAe,aAAa,MAAM,OAAO;CAE7E,MAAM,IAAI,KAAK;EAAE;EAAM,KAAK;CAAG,GAAG,KAAK;CAEvC,OAAO;EAAE,QAAQ;EAAU,QAAQ;EAAM,cAAc;CAAK;AAC9D"}
package/esm/index.d.mts CHANGED
@@ -94,7 +94,7 @@ import { matchesDerivedRouteName, routeNameMethodSuffix } from "./router/route-n
94
94
  import { RouteNameTakenError } from "./router/route-name-taken-error.mjs";
95
95
  import { RouteRegistry } from "./router/route-registry.mjs";
96
96
  import { Router, router } from "./router/router.mjs";
97
- import { AUTH_GUARD_MARKER, isAuthGuardMiddleware, isUnguardedMutatingRoute, markAuthGuard, reportUnguardedMutatingRoutes, resetUnguardedRouteReports } from "./router/unguarded-route-diagnostics.mjs";
97
+ import { AUTH_GUARD_MARKER, isAuthGuardMiddleware, isRequiredGuardRoute, isUnguardedMutatingRoute, markAuthGuard, reportUnguardedMutatingRoutes, resetUnguardedRouteReports } from "./router/unguarded-route-diagnostics.mjs";
98
98
  import "./router/index.mjs";
99
99
  import { app } from "./application/app.mjs";
100
100
  import { Environment, RuntimeStrategy, environment, setEnvironment } from "./utils/environment.mjs";
@@ -122,6 +122,7 @@ import { setConfig } from "./config/config-setter.mjs";
122
122
  import { ConfigSpecialHandlers, configSpecialHandlers } from "./config/config-special-handlers.mjs";
123
123
  import "./config/index.mjs";
124
124
  import { BudgetPage, BudgetViolation, BuildBudgetReport, BuildBudgets, PageBudget, PayloadBudget } from "./production/build-budgets.mjs";
125
+ import { ReleaseCheck, ReleaseConfig } from "./release/types.mjs";
125
126
  import { WarlockConfig } from "./warlock-config/types.mjs";
126
127
  import { Connector, ConnectorBuildContext, ConnectorBuildContribution, ConnectorBuildGenerateResult, ConnectorEsbuildPatch, ConnectorLifecyclePhase, ConnectorName, ConnectorPriority } from "./connectors/types.mjs";
127
128
  import { BaseConnector } from "./connectors/base-connector.mjs";
@@ -237,7 +238,7 @@ import "./warlock-config/index.mjs";
237
238
  import { env } from "@mongez/dotenv";
238
239
  import { colors } from "@mongez/copper";
239
240
  export * from "@mongez/localization";
240
- export { $registerUseCase, $unregisterUseCase, APP_ROLES, AUTH_GUARD_MARKER, AccessConnector, AggregateExpressionInput, AggregateExpressions, AiConnector, AllRepositoryOptions, AppConfigurations, AppError, AppRole, Application, AuthDescriptor, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseCastOutput, BaseConnector, type BenchmarkChannel, type BenchmarkConfigurations, type BenchmarkErrorResult, type BenchmarkOptions, BenchmarkProfiler, type BenchmarkProfilerOptions, type BenchmarkResult, BenchmarkSnapshots, type BenchmarkSnapshotsOptions, type BenchmarkStats, type BenchmarkSuccessResult, BootContext, BootListener, BootSignal, BootSignalType, BootValidator, type BudgetPage, type BudgetViolation, type BuildBudgetReport, type BuildBudgets, CLICommand, type CLICommandAction, type CLICommandOption, type CLICommandOptions, type CLICommandPreload, type CLICommandSource, CacheConnector, type CacheMiddlewareOptions, CachedRepositoryOptions, type CapturedMail, CascadeAdapter, CascadeQueryBuilder, CastOutput, ChunkCallback, ClockSource, ClosableServer, CloudDriver, CloudStorageDriverContract, CloudStorageDriverOptions, CloudStorageFileData, type CommandActionData, type ConcurrencyLimitOptions, ConditionalRequestInput, ConditionalRequestOutcome, ConfigIssue, ConfigKey, ConfigKeyRegistry, ConfigModuleEntry, ConfigName, ConfigOf, ConfigRegistry, ConfigSchema, ConfigSchemaOptions, ConfigSpecialHandlers, ConflictError, Connector, ConnectorBuildContext, ConnectorBuildContribution, ConnectorBuildGenerateResult, ConnectorEsbuildPatch, ConnectorLifecyclePhase, ConnectorName, ConnectorPriority, ConnectorsManager, ConsoleChannel, ContainerTypes, CookieJarUnavailableError, CookieOptions, CspConfig, CsrfOriginCheckReason, CsrfOriginVerdict, CursorPaginationOptions, CursorPaginationResult, DEFAULT_CSP_DIRECTIVES, DEFAULT_POSTMAN_BASE_URL, DOSpacesDriver, DatabaseCacheDriver, type DatabaseCacheOptions, DatabaseConnector, DatabaseLog, DatabaseLogModel, DatabaseLogOptions, DecodedAccessToken, DefineResourceOptions, DeleteManyResult, DetectedImageFormat, type DevelopmentAppModuleEntry, type DevelopmentAppModules, type DevelopmentModelModuleEntry, type DevelopmentModelModuleState, type DevelopmentModelModules, DevelopmentPostmanResult, EMPTY_TRANSLATION_USAGE, ERROR_CODES, ERROR_CODES_DOCS_URL, EncryptionConfigurations, EncryptionPasswordConfigurations, EntityTag, Environment, ErrorCodeArea, ErrorCodeCategory, ErrorCodeDefinition, EventSubscription, ExistsExceptCurrentIdRuleOptions, ExistsExceptCurrentUserRuleOptions, FastifyInstance, FieldOutput, FileNamingStrategy, FileValidationOptions, FileValidator, FileVisibility, FilterFunction, FilterOperator, FilterOptions, FilterRule, FilterRules, ForbiddenError, GenerateImageVariantsOptions, GeneratedImageDescriptor, GeneratedImageVariant, GroupByFields, GroupedRoutesOptions, HealthCheck, HealthStatus, HeraldConnector, HttpConfigurations, HttpConnector, HttpContext, HttpError, HttpErrorCodes, type HttpErrorMapper, type HttpErrorMapping, type HttpErrorResponseContext, type HttpErrorResponseFormatter, HttpLoggingConfig, HttpReadyReport, HttpServerOptions, HttpServerRebuiltListener, HttpTracingConfig, type IdempotencyOptions, IdsSource, Image, ImageFormat, ImageInput, ImageTransformCallback, ImageTransformConfig, ImageTransformOptions, ImageVariantDefinition, ImageVariantFit, ImageVariantOutputFormat, ImageVariantsConfigError, InvalidConfigError, InvalidCspDirectiveError, type IpFilterOptions, JavaScriptRuntime, JavaScriptRuntimeName, ListEndpointBody, ListEndpointOptions, ListEndpointRepositoryOptions, ListOptions, ListQuery, LocalDriver, LocalStorageDriverOptions, LocaleDictionaryEntries, LocaleDictionaryError, LocalizedObject, LogConfigurations, LoggerConnector, MAIL_EVENTS, Mail, type MailAddress, type MailAttachment, type MailConfigurations, MailError, type MailErrorCode, type MailEvents, type MailMode, type MailOptions, type MailPriority, type MailResult, MailerConnector, type MailersConfig, type MaintenanceOptions, MemorySecretBackend, Middleware, MiddlewareResponse, MimeTypes, ModelResourceRegistry, NULLABLE_RESOURCE, NamedApiRoute, NamedApiRoutesOptions, NoopChannel, type NormalizedMail, NotAcceptableError, NotAllowedError, NotificationsConnector, NullableResource, NullableResourceTarget, OPENAPI_JSON_SCHEMA_DIALECT, OpenApiBuildResult, OpenApiComponents, OpenApiContext, OpenApiDocument, OpenApiOperation, OpenApiParameter, OpenApiRequestBody, OpenApiResponse, OpenApiRouteInput, OpenApiSchema, OpenApiSecurityRequirement, OpenApiSecurityScheme, OpenApiValidationResponseConfig, POSTMAN_COLLECTION_SCHEMA, type PageBudget, PaginationMode, PaginationResult, ParsedLocaleDictionary, PartialMiddleware, PartialPick, Path, type PayloadBudget, PipeableReactStream, PipelineOptions, PortInUseError, PositionalHandlerSuspect, PostmanAuth, PostmanAuthEntry, PostmanBody, PostmanCollection, PostmanCollectionOptions, PostmanFolder, PostmanFormParam, PostmanHeader, PostmanItem, PostmanOriginalRequest, PostmanQueryParam, PostmanRequest, PostmanRequestItem, PostmanResponse, PostmanUrl, PostmanVariable, PrefixConfig, PrefixOptions, PresignedOptions, PresignedUploadOptions, PrivateRequestLoggingRule, PurgeImageVariantsOptions, PutDirectoryOptions, PutDirectoryResult, PutFromUrlOptions, PutOptions, QueryBuilderContract, Queue, R2Driver, R2StorageDriverOptions, type RateLimitOptions, RegisterConfiguredConnectorsOptions, RegisterResource, RegisteredUseCase, RepositoryAdapterContract, RepositoryConfigurations, RepositoryEvent, RepositoryManager, RepositoryOptions, RepositoryOptionsWithCursor, RepositoryOptionsWithPages, Request, RequestContextStore, RequestController, RequestControllerContract, RequestEvent, RequestHandler, RequestHandlerType, RequestHandlerValidation, RequestLocals, RequestLog, RequestLogSnapshot, RequestLogSource, RequestLoggingOptions, RequestMethod, RequestTranslator, ResolveImageVariantInput, type ResolvedCLICommandOption, ResolvedImageVariant, ResolvedImageVariantsConfig, Resource, ResourceArraySchema, ResourceCastType, ResourceConstructor, ResourceContract, ResourceFieldBuilder, ResourceFieldBuilderDateOutputOptions, ResourceFieldConfig, ResourceMethod, ResourceNotFoundError, ResourceOutput, ResourceOutputOf, ResourceOutputValueCastType, ResourceSchema, ResourceSelfReference, Response, ResponseBodyOutput, ResponseBodyValue, ResponseEvent, ResponseSSEController, ResponseSSEMessageOptions, ResponseSSEOptions, ResponseSchema, ResponseSchemaOutput, ResponseStatus, ResponseStreamController, ResponseStreamOptions, Restful, RestfulMiddleware, ReturnedResponse, Route, RouteNameTakenError, RouteOptions, RouteRateLimitOptions, RouteRegistry, RouteResource, Router, RouterGroupCallback, RouterStacks, RuntimeStrategy, S3Driver, type SESConfigurations, type SMTPConfigurations, SUPPORTED_RUNTIMES_DOCS_URL, SafeFetchOptions, SafeFetchResult, SafeRedirectOptions, SaveAsOptions, SaveMode, SaveOptions, ScopedStorage, ScopedStorageContract, type SecretBackend, type SecretBackendType, SecretStore, SecretStoreError, SecretStoreErrorCode, type SecretStoreOptions, type SecretsConfigurations, SeedClock, SeedContext, SeedRecordRef, SeedResult, Seeder, SeederDependencyCycleError, SeederMetadata, SendBufferOptions, SendFileOptions, Serialized, SerializedWire, ServerError, ShutdownListener, SocketAdapterFactory, SocketConnector, SocketOptions, StaticMountOptions, Storage, StorageCapabilityError, StorageConfigurations, StorageConnector, StorageCopyEventPayload, StorageDriverConfig, StorageDriverContextStore, StorageDriverContract, StorageDriverName, StorageDriverRegistry, StorageDriverType, StorageError, StorageErrorOptions, StorageEventHandler, StorageEventPayload, StorageEventType, StorageFile, StorageFileData, StorageFileInfo, StorageManagerContract, StorageNotInitializedError, StoragePutEventPayload, StreamReactResponseOptions, TemporaryTokenError, TemporaryTokenPayload, TemporaryTokenValidation, TracingContext, TracingContextSource, TracingHooks, TracingPhaseInfo, TracingRequestEndInfo, Track, TrackableModel, TranslationDynamicSite, TranslationGraphInput, TranslationGraphResult, TranslationSourceScan, TranslationUsage, TypedAllRepositoryOptions, TypedRepositoryOptions, TypedRepositoryOptionsWithCursor, TypedRepositoryOptionsWithPages, UPDATE_MANY_BATCH_SIZE, UPLOADS_DEFAULTS, URL_CREDENTIAL_PARAMS, UnAuthorizedError, UniqueExceptCurrentIdRuleOptions, UniqueExceptCurrentUserRuleOptions, UnknownSeederDependencyError, UploadedFile, UploadedFileControllerOptions, UploadedFileImageOptions, UploadedFileJson, UploadedFileQuery, UploadsConfigurations, UploadsImagesConfigurations, UseCase, UseCaseAfterMiddleware, UseCaseBeforeMiddleware, UseCaseBroadcastChannel, UseCaseBroadcastEvent, UseCaseBroadcastOption, UseCaseConfigurations, UseCaseContext, UseCaseErrorResult, UseCaseEventsCallbacksMap, UseCaseGuard, UseCaseHandler, UseCaseOnExecutingContext, UseCaseResult, UseCaseRuntimeOptions, UseCaseWithSchema, ValidationConfiguration, ValidationFailureContext, ValidationFailureHandler, ValidationFailureResponse, ValidationResponseConfiguration, VariantOutputFormat, VariantSourceFormat, WarlockConfig, WarlockConfigManager, WarlockError, WarlockErrorCode, WarningSink, WatermarkConfig, WhereOperator, XMLable, addUseCaseHistory, analyzePageTranslationUsage, analyzeTranslationGraph, anyMatch, app, appLog, appPath, applyCspHeader, assertConfiguredHttpPortIsFree, assertMailCount, assertMailSent, assertNoReservedConnectorNames, assertNodeOnlyCommand, assertPortIsAvailable, assertSitesRequireWebRole, assertUniqueConnectorNames, assertValidConfigModules, assetsUrl, beginHttpDrain, bootstrap, broadcastSocketEvent, broadcastUseCaseResult, buildCspHeaderValue, buildIdempotencyCacheKey, buildOpenApiDocument, buildRequestLogSnapshot, buildTracingContext, cachePath, captureMail, clearPositionalHandlerSuspects, clearTestMailbox, clock, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, createUploadedFileController, decrypt, defaultHttpConfigurations, defineConfig, defineConfigSchema, defineResource, deriveTraceId, describeJavaScriptRuntime, describePositionalHandlerSuspect, detectJavaScriptRuntime, dispatchPhase, dispatchRequestEnd, dispatchRequestStart, displayEnvironmentMode, encrypt, ensureFatalIsVisible, env, environment, errorCodeDocsUrl, errorCodeOf, escapeHeaderValue, evaluateConditionalRequest, exampleFromSchema, existsExceptCurrentIdRule, existsExceptCurrentUserRule, explainErrorCode, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, findMailsBySubject, findMailsTo, fireLifecycleEvent, forgetPositionalHandlerSuspects, formatConfigIssues, generateImageVariants, generateMailId, getDefaultMailConfig, getDevelopmentOpenApiDocument, getDevelopmentPostmanCollection, getExplicitMailMode, getHttpReadyReport, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getPublicUrl, getRoles, getSites, getSocketServer, getTestMailbox, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hasRole, hashBody, hashPassword, health, hmacHash, httpConfig, ids, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, inspectHandlerSignature, ipMatches, isAllowedCsrfOrigin, isAuthGuardMiddleware, isBootSignal, isConfigSchema, isDevelopmentMode, isNewerVersion, isNullableResource, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isSafeRedirect, isTestMode, isTracingEnabled, isTranslationKeyUsed, isUnguardedMutatingRoute, isUnknownTsExtensionError, isUnresolvedConfigImportError, isUnsupportedTypeStrippingError, isValidIdempotencyKey, isWarlockErrorCode, listEndpoint, listPositionalHandlerSuspects, loadS3, logResponse, logsPath, looksLikePositionalHandler, mailEvents, markAuthGuard, matchesDerivedRouteName, matchesIfMatch, matchesIfNoneMatch, measure, mergeCspDirectives, mergeTranslationUsage, middleware, nodeOnlyCommandError, normalizeOrigin, normalizeRequestPath, normalizeRoutePath, notifyHttpServerRebuilt, nullable, onHttpServerRebuilt, openApiToPostmanCollection, originOf, ownOrigin, parseEntityTag, parseEntityTagList, parseLocaleDictionary, parseRoles, parseSites, parseSize, parseTraceparentTraceId, paths, preflightConfiguredHttpPort, promiseAllObject, publicPath, publicUrl, purgeImageVariants, readSourceFile, readTranslationDeclarations, redactQueryCredentials, redactUrlCredentials, registerAppConfig, registerConfiguredConnectors, registerDevelopmentOpenApiProvider, registerGroupedTranslationKeys, registerHttpPlugins, registerLocaleDictionary, registerTracingHooks, remedyLines, renderReact, renderReactMail, reportPositionalHandlerSuspects, reportUnguardedMutatingRoutes, requestContext, requestMemo, requiresDefaultCsrfGuard, resetHttpReadyReport, resetMailConfig, resetMailMode, resetRolesCacheForTests, resetTracingConfigForTests, resetUnguardedRouteReports, resolveCspConfig, resolveCsrfOriginVerdict, resolveImageVariant, resolveMailConfig, resolvePublicRoot, resolveRequestLoggingOptions, resolveSourceImport, resolveTracingConfig, resolveWithinRoot, rootPath, routeNameMethodSuffix, router, runDefaultCsrfGuard, runPipeline, safeFetchToBuffer, safeRedirect, sanitizePath, scanTranslationSource, secrets, seeder, sendBootSignal, sendMail, serializeCspDirectives, servesHttp, setBaseUrl, setClockSource, setConfig, setEnvironment, setHttpReadyReport, setIdsSource, setLogConfigurations, setMailConfigurations, setMailMode, shouldPreflightHttpPort, sleep, sluggable, srcPath, startHttpServer, stopHttpApplication, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, streamReactResponse, strongEntityTagMatch, t, tempPath, toJson, toSingleLineSseField, trackConnectionsForDrain, translationDeclarationUsage, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, unregisterLocaleDictionary, unverifiedBuildRuntimeNotice, uploadedFileController, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, usageOf, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, validateConfigValue, validateCspConfigAtBoot, validateCspDirectives, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, weakEntityTagMatch, wrapResponseInDataKey };
241
+ export { $registerUseCase, $unregisterUseCase, APP_ROLES, AUTH_GUARD_MARKER, AccessConnector, AggregateExpressionInput, AggregateExpressions, AiConnector, AllRepositoryOptions, AppConfigurations, AppError, AppRole, Application, AuthDescriptor, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseCastOutput, BaseConnector, type BenchmarkChannel, type BenchmarkConfigurations, type BenchmarkErrorResult, type BenchmarkOptions, BenchmarkProfiler, type BenchmarkProfilerOptions, type BenchmarkResult, BenchmarkSnapshots, type BenchmarkSnapshotsOptions, type BenchmarkStats, type BenchmarkSuccessResult, BootContext, BootListener, BootSignal, BootSignalType, BootValidator, type BudgetPage, type BudgetViolation, type BuildBudgetReport, type BuildBudgets, CLICommand, type CLICommandAction, type CLICommandOption, type CLICommandOptions, type CLICommandPreload, type CLICommandSource, CacheConnector, type CacheMiddlewareOptions, CachedRepositoryOptions, type CapturedMail, CascadeAdapter, CascadeQueryBuilder, CastOutput, ChunkCallback, ClockSource, ClosableServer, CloudDriver, CloudStorageDriverContract, CloudStorageDriverOptions, CloudStorageFileData, type CommandActionData, type ConcurrencyLimitOptions, ConditionalRequestInput, ConditionalRequestOutcome, ConfigIssue, ConfigKey, ConfigKeyRegistry, ConfigModuleEntry, ConfigName, ConfigOf, ConfigRegistry, ConfigSchema, ConfigSchemaOptions, ConfigSpecialHandlers, ConflictError, Connector, ConnectorBuildContext, ConnectorBuildContribution, ConnectorBuildGenerateResult, ConnectorEsbuildPatch, ConnectorLifecyclePhase, ConnectorName, ConnectorPriority, ConnectorsManager, ConsoleChannel, ContainerTypes, CookieJarUnavailableError, CookieOptions, CspConfig, CsrfOriginCheckReason, CsrfOriginVerdict, CursorPaginationOptions, CursorPaginationResult, DEFAULT_CSP_DIRECTIVES, DEFAULT_POSTMAN_BASE_URL, DOSpacesDriver, DatabaseCacheDriver, type DatabaseCacheOptions, DatabaseConnector, DatabaseLog, DatabaseLogModel, DatabaseLogOptions, DecodedAccessToken, DefineResourceOptions, DeleteManyResult, DetectedImageFormat, type DevelopmentAppModuleEntry, type DevelopmentAppModules, type DevelopmentModelModuleEntry, type DevelopmentModelModuleState, type DevelopmentModelModules, DevelopmentPostmanResult, EMPTY_TRANSLATION_USAGE, ERROR_CODES, ERROR_CODES_DOCS_URL, EncryptionConfigurations, EncryptionPasswordConfigurations, EntityTag, Environment, ErrorCodeArea, ErrorCodeCategory, ErrorCodeDefinition, EventSubscription, ExistsExceptCurrentIdRuleOptions, ExistsExceptCurrentUserRuleOptions, FastifyInstance, FieldOutput, FileNamingStrategy, FileValidationOptions, FileValidator, FileVisibility, FilterFunction, FilterOperator, FilterOptions, FilterRule, FilterRules, ForbiddenError, GenerateImageVariantsOptions, GeneratedImageDescriptor, GeneratedImageVariant, GroupByFields, GroupedRoutesOptions, HealthCheck, HealthStatus, HeraldConnector, HttpConfigurations, HttpConnector, HttpContext, HttpError, HttpErrorCodes, type HttpErrorMapper, type HttpErrorMapping, type HttpErrorResponseContext, type HttpErrorResponseFormatter, HttpLoggingConfig, HttpReadyReport, HttpServerOptions, HttpServerRebuiltListener, HttpTracingConfig, type IdempotencyOptions, IdsSource, Image, ImageFormat, ImageInput, ImageTransformCallback, ImageTransformConfig, ImageTransformOptions, ImageVariantDefinition, ImageVariantFit, ImageVariantOutputFormat, ImageVariantsConfigError, InvalidConfigError, InvalidCspDirectiveError, type IpFilterOptions, JavaScriptRuntime, JavaScriptRuntimeName, ListEndpointBody, ListEndpointOptions, ListEndpointRepositoryOptions, ListOptions, ListQuery, LocalDriver, LocalStorageDriverOptions, LocaleDictionaryEntries, LocaleDictionaryError, LocalizedObject, LogConfigurations, LoggerConnector, MAIL_EVENTS, Mail, type MailAddress, type MailAttachment, type MailConfigurations, MailError, type MailErrorCode, type MailEvents, type MailMode, type MailOptions, type MailPriority, type MailResult, MailerConnector, type MailersConfig, type MaintenanceOptions, MemorySecretBackend, Middleware, MiddlewareResponse, MimeTypes, ModelResourceRegistry, NULLABLE_RESOURCE, NamedApiRoute, NamedApiRoutesOptions, NoopChannel, type NormalizedMail, NotAcceptableError, NotAllowedError, NotificationsConnector, NullableResource, NullableResourceTarget, OPENAPI_JSON_SCHEMA_DIALECT, OpenApiBuildResult, OpenApiComponents, OpenApiContext, OpenApiDocument, OpenApiOperation, OpenApiParameter, OpenApiRequestBody, OpenApiResponse, OpenApiRouteInput, OpenApiSchema, OpenApiSecurityRequirement, OpenApiSecurityScheme, OpenApiValidationResponseConfig, POSTMAN_COLLECTION_SCHEMA, type PageBudget, PaginationMode, PaginationResult, ParsedLocaleDictionary, PartialMiddleware, PartialPick, Path, type PayloadBudget, PipeableReactStream, PipelineOptions, PortInUseError, PositionalHandlerSuspect, PostmanAuth, PostmanAuthEntry, PostmanBody, PostmanCollection, PostmanCollectionOptions, PostmanFolder, PostmanFormParam, PostmanHeader, PostmanItem, PostmanOriginalRequest, PostmanQueryParam, PostmanRequest, PostmanRequestItem, PostmanResponse, PostmanUrl, PostmanVariable, PrefixConfig, PrefixOptions, PresignedOptions, PresignedUploadOptions, PrivateRequestLoggingRule, PurgeImageVariantsOptions, PutDirectoryOptions, PutDirectoryResult, PutFromUrlOptions, PutOptions, QueryBuilderContract, Queue, R2Driver, R2StorageDriverOptions, type RateLimitOptions, RegisterConfiguredConnectorsOptions, RegisterResource, RegisteredUseCase, type ReleaseCheck, type ReleaseConfig, RepositoryAdapterContract, RepositoryConfigurations, RepositoryEvent, RepositoryManager, RepositoryOptions, RepositoryOptionsWithCursor, RepositoryOptionsWithPages, Request, RequestContextStore, RequestController, RequestControllerContract, RequestEvent, RequestHandler, RequestHandlerType, RequestHandlerValidation, RequestLocals, RequestLog, RequestLogSnapshot, RequestLogSource, RequestLoggingOptions, RequestMethod, RequestTranslator, ResolveImageVariantInput, type ResolvedCLICommandOption, ResolvedImageVariant, ResolvedImageVariantsConfig, Resource, ResourceArraySchema, ResourceCastType, ResourceConstructor, ResourceContract, ResourceFieldBuilder, ResourceFieldBuilderDateOutputOptions, ResourceFieldConfig, ResourceMethod, ResourceNotFoundError, ResourceOutput, ResourceOutputOf, ResourceOutputValueCastType, ResourceSchema, ResourceSelfReference, Response, ResponseBodyOutput, ResponseBodyValue, ResponseEvent, ResponseSSEController, ResponseSSEMessageOptions, ResponseSSEOptions, ResponseSchema, ResponseSchemaOutput, ResponseStatus, ResponseStreamController, ResponseStreamOptions, Restful, RestfulMiddleware, ReturnedResponse, Route, RouteNameTakenError, RouteOptions, RouteRateLimitOptions, RouteRegistry, RouteResource, Router, RouterGroupCallback, RouterStacks, RuntimeStrategy, S3Driver, type SESConfigurations, type SMTPConfigurations, SUPPORTED_RUNTIMES_DOCS_URL, SafeFetchOptions, SafeFetchResult, SafeRedirectOptions, SaveAsOptions, SaveMode, SaveOptions, ScopedStorage, ScopedStorageContract, type SecretBackend, type SecretBackendType, SecretStore, SecretStoreError, SecretStoreErrorCode, type SecretStoreOptions, type SecretsConfigurations, SeedClock, SeedContext, SeedRecordRef, SeedResult, Seeder, SeederDependencyCycleError, SeederMetadata, SendBufferOptions, SendFileOptions, Serialized, SerializedWire, ServerError, ShutdownListener, SocketAdapterFactory, SocketConnector, SocketOptions, StaticMountOptions, Storage, StorageCapabilityError, StorageConfigurations, StorageConnector, StorageCopyEventPayload, StorageDriverConfig, StorageDriverContextStore, StorageDriverContract, StorageDriverName, StorageDriverRegistry, StorageDriverType, StorageError, StorageErrorOptions, StorageEventHandler, StorageEventPayload, StorageEventType, StorageFile, StorageFileData, StorageFileInfo, StorageManagerContract, StorageNotInitializedError, StoragePutEventPayload, StreamReactResponseOptions, TemporaryTokenError, TemporaryTokenPayload, TemporaryTokenValidation, TracingContext, TracingContextSource, TracingHooks, TracingPhaseInfo, TracingRequestEndInfo, Track, TrackableModel, TranslationDynamicSite, TranslationGraphInput, TranslationGraphResult, TranslationSourceScan, TranslationUsage, TypedAllRepositoryOptions, TypedRepositoryOptions, TypedRepositoryOptionsWithCursor, TypedRepositoryOptionsWithPages, UPDATE_MANY_BATCH_SIZE, UPLOADS_DEFAULTS, URL_CREDENTIAL_PARAMS, UnAuthorizedError, UniqueExceptCurrentIdRuleOptions, UniqueExceptCurrentUserRuleOptions, UnknownSeederDependencyError, UploadedFile, UploadedFileControllerOptions, UploadedFileImageOptions, UploadedFileJson, UploadedFileQuery, UploadsConfigurations, UploadsImagesConfigurations, UseCase, UseCaseAfterMiddleware, UseCaseBeforeMiddleware, UseCaseBroadcastChannel, UseCaseBroadcastEvent, UseCaseBroadcastOption, UseCaseConfigurations, UseCaseContext, UseCaseErrorResult, UseCaseEventsCallbacksMap, UseCaseGuard, UseCaseHandler, UseCaseOnExecutingContext, UseCaseResult, UseCaseRuntimeOptions, UseCaseWithSchema, ValidationConfiguration, ValidationFailureContext, ValidationFailureHandler, ValidationFailureResponse, ValidationResponseConfiguration, VariantOutputFormat, VariantSourceFormat, WarlockConfig, WarlockConfigManager, WarlockError, WarlockErrorCode, WarningSink, WatermarkConfig, WhereOperator, XMLable, addUseCaseHistory, analyzePageTranslationUsage, analyzeTranslationGraph, anyMatch, app, appLog, appPath, applyCspHeader, assertConfiguredHttpPortIsFree, assertMailCount, assertMailSent, assertNoReservedConnectorNames, assertNodeOnlyCommand, assertPortIsAvailable, assertSitesRequireWebRole, assertUniqueConnectorNames, assertValidConfigModules, assetsUrl, beginHttpDrain, bootstrap, broadcastSocketEvent, broadcastUseCaseResult, buildCspHeaderValue, buildIdempotencyCacheKey, buildOpenApiDocument, buildRequestLogSnapshot, buildTracingContext, cachePath, captureMail, clearPositionalHandlerSuspects, clearTestMailbox, clock, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, createUploadedFileController, decrypt, defaultHttpConfigurations, defineConfig, defineConfigSchema, defineResource, deriveTraceId, describeJavaScriptRuntime, describePositionalHandlerSuspect, detectJavaScriptRuntime, dispatchPhase, dispatchRequestEnd, dispatchRequestStart, displayEnvironmentMode, encrypt, ensureFatalIsVisible, env, environment, errorCodeDocsUrl, errorCodeOf, escapeHeaderValue, evaluateConditionalRequest, exampleFromSchema, existsExceptCurrentIdRule, existsExceptCurrentUserRule, explainErrorCode, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, findMailsBySubject, findMailsTo, fireLifecycleEvent, forgetPositionalHandlerSuspects, formatConfigIssues, generateImageVariants, generateMailId, getDefaultMailConfig, getDevelopmentOpenApiDocument, getDevelopmentPostmanCollection, getExplicitMailMode, getHttpReadyReport, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getPublicUrl, getRoles, getSites, getSocketServer, getTestMailbox, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hasRole, hashBody, hashPassword, health, hmacHash, httpConfig, ids, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, inspectHandlerSignature, ipMatches, isAllowedCsrfOrigin, isAuthGuardMiddleware, isBootSignal, isConfigSchema, isDevelopmentMode, isNewerVersion, isNullableResource, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isRequiredGuardRoute, isSafeRedirect, isTestMode, isTracingEnabled, isTranslationKeyUsed, isUnguardedMutatingRoute, isUnknownTsExtensionError, isUnresolvedConfigImportError, isUnsupportedTypeStrippingError, isValidIdempotencyKey, isWarlockErrorCode, listEndpoint, listPositionalHandlerSuspects, loadS3, logResponse, logsPath, looksLikePositionalHandler, mailEvents, markAuthGuard, matchesDerivedRouteName, matchesIfMatch, matchesIfNoneMatch, measure, mergeCspDirectives, mergeTranslationUsage, middleware, nodeOnlyCommandError, normalizeOrigin, normalizeRequestPath, normalizeRoutePath, notifyHttpServerRebuilt, nullable, onHttpServerRebuilt, openApiToPostmanCollection, originOf, ownOrigin, parseEntityTag, parseEntityTagList, parseLocaleDictionary, parseRoles, parseSites, parseSize, parseTraceparentTraceId, paths, preflightConfiguredHttpPort, promiseAllObject, publicPath, publicUrl, purgeImageVariants, readSourceFile, readTranslationDeclarations, redactQueryCredentials, redactUrlCredentials, registerAppConfig, registerConfiguredConnectors, registerDevelopmentOpenApiProvider, registerGroupedTranslationKeys, registerHttpPlugins, registerLocaleDictionary, registerTracingHooks, remedyLines, renderReact, renderReactMail, reportPositionalHandlerSuspects, reportUnguardedMutatingRoutes, requestContext, requestMemo, requiresDefaultCsrfGuard, resetHttpReadyReport, resetMailConfig, resetMailMode, resetRolesCacheForTests, resetTracingConfigForTests, resetUnguardedRouteReports, resolveCspConfig, resolveCsrfOriginVerdict, resolveImageVariant, resolveMailConfig, resolvePublicRoot, resolveRequestLoggingOptions, resolveSourceImport, resolveTracingConfig, resolveWithinRoot, rootPath, routeNameMethodSuffix, router, runDefaultCsrfGuard, runPipeline, safeFetchToBuffer, safeRedirect, sanitizePath, scanTranslationSource, secrets, seeder, sendBootSignal, sendMail, serializeCspDirectives, servesHttp, setBaseUrl, setClockSource, setConfig, setEnvironment, setHttpReadyReport, setIdsSource, setLogConfigurations, setMailConfigurations, setMailMode, shouldPreflightHttpPort, sleep, sluggable, srcPath, startHttpServer, stopHttpApplication, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, streamReactResponse, strongEntityTagMatch, t, tempPath, toJson, toSingleLineSseField, trackConnectionsForDrain, translationDeclarationUsage, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, unregisterLocaleDictionary, unverifiedBuildRuntimeNotice, uploadedFileController, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, usageOf, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, validateConfigValue, validateCspConfigAtBoot, validateCspDirectives, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, weakEntityTagMatch, wrapResponseInDataKey };
241
242
  import "./config/types.mjs";
242
243
  import "./http/request.mjs";
243
244
  import "./http/serialized.mjs";
package/esm/index.mjs CHANGED
@@ -73,7 +73,7 @@ import "./image/index.mjs";
73
73
  import { UploadedFile } from "./http/uploaded-file.mjs";
74
74
  import { URL_CREDENTIAL_PARAMS, buildRequestLogSnapshot, redactQueryCredentials, redactUrlCredentials, resolveRequestLoggingOptions } from "./http/request-log-snapshot.mjs";
75
75
  import { Request } from "./http/request.mjs";
76
- import { AUTH_GUARD_MARKER, isAuthGuardMiddleware, isUnguardedMutatingRoute, markAuthGuard, reportUnguardedMutatingRoutes, resetUnguardedRouteReports } from "./router/unguarded-route-diagnostics.mjs";
76
+ import { AUTH_GUARD_MARKER, isAuthGuardMiddleware, isRequiredGuardRoute, isUnguardedMutatingRoute, markAuthGuard, reportUnguardedMutatingRoutes, resetUnguardedRouteReports } from "./router/unguarded-route-diagnostics.mjs";
77
77
  import { Router, router } from "./router/router.mjs";
78
78
  import "./router/index.mjs";
79
79
  import { registerHttpPlugins, resolvePublicRoot } from "./http/plugins.mjs";
@@ -206,4 +206,4 @@ import { colors } from "@mongez/copper";
206
206
 
207
207
  export * from "@mongez/localization"
208
208
 
209
- export { $registerUseCase, $unregisterUseCase, APP_ROLES, AUTH_GUARD_MARKER, AccessConnector, AiConnector, AppError, Application, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseConnector, BenchmarkProfiler, BenchmarkSnapshots, CLICommand, CacheConnector, CascadeAdapter, CascadeQueryBuilder, CloudDriver, ConfigSpecialHandlers, ConflictError, ConnectorLifecyclePhase, ConnectorPriority, ConnectorsManager, ConsoleChannel, CookieJarUnavailableError, DEFAULT_CSP_DIRECTIVES, DEFAULT_POSTMAN_BASE_URL, DOSpacesDriver, DatabaseCacheDriver, DatabaseConnector, DatabaseLog, DatabaseLogModel, EMPTY_TRANSLATION_USAGE, ERROR_CODES, ERROR_CODES_DOCS_URL, FileValidator, ForbiddenError, HeraldConnector, HttpConnector, HttpError, HttpErrorCodes, Image, ImageVariantsConfigError, InvalidConfigError, InvalidCspDirectiveError, LocalDriver, LocaleDictionaryError, LoggerConnector, MAIL_EVENTS, Mail, MailError, MailerConnector, MemorySecretBackend, MimeTypes, NULLABLE_RESOURCE, NoopChannel, NotAcceptableError, NotAllowedError, NotificationsConnector, OPENAPI_JSON_SCHEMA_DIALECT, POSTMAN_COLLECTION_SCHEMA, Path, PortInUseError, Queue, R2Driver, RegisterResource, RepositoryManager, Request, RequestController, RequestLog, Resource, ResourceFieldBuilder, ResourceNotFoundError, Response, ResponseStatus, Restful, RouteNameTakenError, RouteRegistry, Router, S3Driver, SUPPORTED_RUNTIMES_DOCS_URL, ScopedStorage, SecretStore, SecretStoreError, SeederDependencyCycleError, ServerError, SocketConnector, Storage, StorageCapabilityError, StorageConnector, StorageError, StorageFile, StorageNotInitializedError, UPDATE_MANY_BATCH_SIZE, UPLOADS_DEFAULTS, URL_CREDENTIAL_PARAMS, UnAuthorizedError, UnknownSeederDependencyError, UploadedFile, WarlockConfigManager, WarlockError, addUseCaseHistory, analyzePageTranslationUsage, analyzeTranslationGraph, anyMatch, app, appLog, appPath, applyCspHeader, assertConfiguredHttpPortIsFree, assertMailCount, assertMailSent, assertNoReservedConnectorNames, assertNodeOnlyCommand, assertPortIsAvailable, assertSitesRequireWebRole, assertUniqueConnectorNames, assertValidConfigModules, assetsUrl, beginHttpDrain, bootstrap, broadcastSocketEvent, broadcastUseCaseResult, buildCspHeaderValue, buildIdempotencyCacheKey, buildOpenApiDocument, buildRequestLogSnapshot, buildTracingContext, cachePath, captureMail, clearPositionalHandlerSuspects, clearTestMailbox, clock, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, createUploadedFileController, decrypt, defaultHttpConfigurations, defineConfig, defineConfigSchema, defineResource, deriveTraceId, describeJavaScriptRuntime, describePositionalHandlerSuspect, detectJavaScriptRuntime, dispatchPhase, dispatchRequestEnd, dispatchRequestStart, displayEnvironmentMode, encrypt, ensureFatalIsVisible, env, environment, errorCodeDocsUrl, errorCodeOf, escapeHeaderValue, evaluateConditionalRequest, exampleFromSchema, existsExceptCurrentIdRule, existsExceptCurrentUserRule, explainErrorCode, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, findMailsBySubject, findMailsTo, fireLifecycleEvent, forgetPositionalHandlerSuspects, formatConfigIssues, generateImageVariants, generateMailId, getDefaultMailConfig, getDevelopmentOpenApiDocument, getDevelopmentPostmanCollection, getExplicitMailMode, getHttpReadyReport, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getPublicUrl, getRoles, getSites, getSocketServer, getTestMailbox, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hasRole, hashBody, hashPassword, health, hmacHash, httpConfig, ids, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, inspectHandlerSignature, ipMatches, isAllowedCsrfOrigin, isAuthGuardMiddleware, isBootSignal, isConfigSchema, isDevelopmentMode, isNewerVersion, isNullableResource, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isSafeRedirect, isTestMode, isTracingEnabled, isTranslationKeyUsed, isUnguardedMutatingRoute, isUnknownTsExtensionError, isUnresolvedConfigImportError, isUnsupportedTypeStrippingError, isValidIdempotencyKey, isWarlockErrorCode, listEndpoint, listPositionalHandlerSuspects, loadS3, logResponse, logsPath, looksLikePositionalHandler, mailEvents, markAuthGuard, matchesDerivedRouteName, matchesIfMatch, matchesIfNoneMatch, measure, mergeCspDirectives, mergeTranslationUsage, middleware, nodeOnlyCommandError, normalizeOrigin, normalizeRequestPath, normalizeRoutePath, notifyHttpServerRebuilt, nullable, onHttpServerRebuilt, openApiToPostmanCollection, originOf, ownOrigin, parseEntityTag, parseEntityTagList, parseLocaleDictionary, parseRoles, parseSites, parseSize, parseTraceparentTraceId, paths, preflightConfiguredHttpPort, promiseAllObject, publicPath, publicUrl, purgeImageVariants, readSourceFile, readTranslationDeclarations, redactQueryCredentials, redactUrlCredentials, registerAppConfig, registerConfiguredConnectors, registerDevelopmentOpenApiProvider, registerGroupedTranslationKeys, registerHttpPlugins, registerLocaleDictionary, registerTracingHooks, remedyLines, renderReact, renderReactMail, reportPositionalHandlerSuspects, reportUnguardedMutatingRoutes, requestContext, requestMemo, requiresDefaultCsrfGuard, resetHttpReadyReport, resetMailConfig, resetMailMode, resetRolesCacheForTests, resetTracingConfigForTests, resetUnguardedRouteReports, resolveCspConfig, resolveCsrfOriginVerdict, resolveImageVariant, resolveMailConfig, resolvePublicRoot, resolveRequestLoggingOptions, resolveSourceImport, resolveTracingConfig, resolveWithinRoot, rootPath, routeNameMethodSuffix, router, runDefaultCsrfGuard, runPipeline, safeFetchToBuffer, safeRedirect, sanitizePath, scanTranslationSource, secrets, seeder, sendBootSignal, sendMail, serializeCspDirectives, servesHttp, setBaseUrl, setClockSource, setConfig, setEnvironment, setHttpReadyReport, setIdsSource, setLogConfigurations, setMailConfigurations, setMailMode, shouldPreflightHttpPort, sleep, sluggable, srcPath, startHttpServer, stopHttpApplication, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, streamReactResponse, strongEntityTagMatch, t, tempPath, toJson, toSingleLineSseField, trackConnectionsForDrain, translationDeclarationUsage, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, unregisterLocaleDictionary, unverifiedBuildRuntimeNotice, uploadedFileController, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, usageOf, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, validateConfigValue, validateCspConfigAtBoot, validateCspDirectives, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, weakEntityTagMatch, wrapResponseInDataKey };
209
+ export { $registerUseCase, $unregisterUseCase, APP_ROLES, AUTH_GUARD_MARKER, AccessConnector, AiConnector, AppError, Application, BOOT_SIGNAL_ENV_KEY, BOOT_SIGNAL_VERSION, BadRequestError, BadSchemaUseCaseError, BaseConnector, BenchmarkProfiler, BenchmarkSnapshots, CLICommand, CacheConnector, CascadeAdapter, CascadeQueryBuilder, CloudDriver, ConfigSpecialHandlers, ConflictError, ConnectorLifecyclePhase, ConnectorPriority, ConnectorsManager, ConsoleChannel, CookieJarUnavailableError, DEFAULT_CSP_DIRECTIVES, DEFAULT_POSTMAN_BASE_URL, DOSpacesDriver, DatabaseCacheDriver, DatabaseConnector, DatabaseLog, DatabaseLogModel, EMPTY_TRANSLATION_USAGE, ERROR_CODES, ERROR_CODES_DOCS_URL, FileValidator, ForbiddenError, HeraldConnector, HttpConnector, HttpError, HttpErrorCodes, Image, ImageVariantsConfigError, InvalidConfigError, InvalidCspDirectiveError, LocalDriver, LocaleDictionaryError, LoggerConnector, MAIL_EVENTS, Mail, MailError, MailerConnector, MemorySecretBackend, MimeTypes, NULLABLE_RESOURCE, NoopChannel, NotAcceptableError, NotAllowedError, NotificationsConnector, OPENAPI_JSON_SCHEMA_DIALECT, POSTMAN_COLLECTION_SCHEMA, Path, PortInUseError, Queue, R2Driver, RegisterResource, RepositoryManager, Request, RequestController, RequestLog, Resource, ResourceFieldBuilder, ResourceNotFoundError, Response, ResponseStatus, Restful, RouteNameTakenError, RouteRegistry, Router, S3Driver, SUPPORTED_RUNTIMES_DOCS_URL, ScopedStorage, SecretStore, SecretStoreError, SeederDependencyCycleError, ServerError, SocketConnector, Storage, StorageCapabilityError, StorageConnector, StorageError, StorageFile, StorageNotInitializedError, UPDATE_MANY_BATCH_SIZE, UPLOADS_DEFAULTS, URL_CREDENTIAL_PARAMS, UnAuthorizedError, UnknownSeederDependencyError, UploadedFile, WarlockConfigManager, WarlockError, addUseCaseHistory, analyzePageTranslationUsage, analyzeTranslationGraph, anyMatch, app, appLog, appPath, applyCspHeader, assertConfiguredHttpPortIsFree, assertMailCount, assertMailSent, assertNoReservedConnectorNames, assertNodeOnlyCommand, assertPortIsAvailable, assertSitesRequireWebRole, assertUniqueConnectorNames, assertValidConfigModules, assetsUrl, beginHttpDrain, bootstrap, broadcastSocketEvent, broadcastUseCaseResult, buildCspHeaderValue, buildIdempotencyCacheKey, buildOpenApiDocument, buildRequestLogSnapshot, buildTracingContext, cachePath, captureMail, clearPositionalHandlerSuspects, clearTestMailbox, clock, closeAllMailers, closeMailer, closeServerWithTimeout, colors, command, config, configPath, configSpecialHandlers, connectorsManager, container, createHttpApplication, createRequestStore, createUploadedFileController, decrypt, defaultHttpConfigurations, defineConfig, defineConfigSchema, defineResource, deriveTraceId, describeJavaScriptRuntime, describePositionalHandlerSuspect, detectJavaScriptRuntime, dispatchPhase, dispatchRequestEnd, dispatchRequestStart, displayEnvironmentMode, encrypt, ensureFatalIsVisible, env, environment, errorCodeDocsUrl, errorCodeOf, escapeHeaderValue, evaluateConditionalRequest, exampleFromSchema, existsExceptCurrentIdRule, existsExceptCurrentUserRule, explainErrorCode, fetchLatestVersion, fileExtensionRule, fileRule, fileTypeRule, findMailsBySubject, findMailsTo, fireLifecycleEvent, forgetPositionalHandlerSuspects, formatConfigIssues, generateImageVariants, generateMailId, getDefaultMailConfig, getDevelopmentOpenApiDocument, getDevelopmentPostmanCollection, getExplicitMailMode, getHttpReadyReport, getHttpServer, getLastMail, getLocalized, getMailEventName, getMailMode, getMailboxSize, getMailer, getMailerConfig, getMimeType, getPoolStats, getPublicUrl, getRoles, getSites, getSocketServer, getTestMailbox, getUseCase, getUseCaseHistory, getUseCases, globalEventsCallbacksMap, globalUseCasesEvents, hasRole, hashBody, hashPassword, health, hmacHash, httpConfig, ids, imageRule, increaseUseCaseFailedCalls, increaseUseCaseSuccessCalls, inspectHandlerSignature, ipMatches, isAllowedCsrfOrigin, isAuthGuardMiddleware, isBootSignal, isConfigSchema, isDevelopmentMode, isNewerVersion, isNullableResource, isPortAvailable, isPrivateOrReservedIp, isProductionMode, isRequiredGuardRoute, isSafeRedirect, isTestMode, isTracingEnabled, isTranslationKeyUsed, isUnguardedMutatingRoute, isUnknownTsExtensionError, isUnresolvedConfigImportError, isUnsupportedTypeStrippingError, isValidIdempotencyKey, isWarlockErrorCode, listEndpoint, listPositionalHandlerSuspects, loadS3, logResponse, logsPath, looksLikePositionalHandler, mailEvents, markAuthGuard, matchesDerivedRouteName, matchesIfMatch, matchesIfNoneMatch, measure, mergeCspDirectives, mergeTranslationUsage, middleware, nodeOnlyCommandError, normalizeOrigin, normalizeRequestPath, normalizeRoutePath, notifyHttpServerRebuilt, nullable, onHttpServerRebuilt, openApiToPostmanCollection, originOf, ownOrigin, parseEntityTag, parseEntityTagList, parseLocaleDictionary, parseRoles, parseSites, parseSize, parseTraceparentTraceId, paths, preflightConfiguredHttpPort, promiseAllObject, publicPath, publicUrl, purgeImageVariants, readSourceFile, readTranslationDeclarations, redactQueryCredentials, redactUrlCredentials, registerAppConfig, registerConfiguredConnectors, registerDevelopmentOpenApiProvider, registerGroupedTranslationKeys, registerHttpPlugins, registerLocaleDictionary, registerTracingHooks, remedyLines, renderReact, renderReactMail, reportPositionalHandlerSuspects, reportUnguardedMutatingRoutes, requestContext, requestMemo, requiresDefaultCsrfGuard, resetHttpReadyReport, resetMailConfig, resetMailMode, resetRolesCacheForTests, resetTracingConfigForTests, resetUnguardedRouteReports, resolveCspConfig, resolveCsrfOriginVerdict, resolveImageVariant, resolveMailConfig, resolvePublicRoot, resolveRequestLoggingOptions, resolveSourceImport, resolveTracingConfig, resolveWithinRoot, rootPath, routeNameMethodSuffix, router, runDefaultCsrfGuard, runPipeline, safeFetchToBuffer, safeRedirect, sanitizePath, scanTranslationSource, secrets, seeder, sendBootSignal, sendMail, serializeCspDirectives, servesHttp, setBaseUrl, setClockSource, setConfig, setEnvironment, setHttpReadyReport, setIdsSource, setLogConfigurations, setMailConfigurations, setMailMode, shouldPreflightHttpPort, sleep, sluggable, srcPath, startHttpServer, stopHttpApplication, storage, storageConfig, storageConfigurations, storageDriverContext, storagePath, streamReactResponse, strongEntityTagMatch, t, tempPath, toJson, toSingleLineSseField, trackConnectionsForDrain, translationDeclarationUsage, uniqueExceptCurrentIdRule, uniqueExceptCurrentUserRule, unregisterLocaleDictionary, unverifiedBuildRuntimeNotice, uploadedFileController, uploadedFileMetadataSchema, uploadsConfig, uploadsPath, uploadsUrl, url, usageOf, useCase, useComputedModel, useComputedSlug, useCurrentUser, useHashedPassword, useRequest, useRequestStore, validateConfigValue, validateCspConfigAtBoot, validateCspDirectives, verifyMailer, verifyPassword, warlockConfigManager, warlockPath, wasMailSentTo, wasMailSentWithSubject, weakEntityTagMatch, wrapResponseInDataKey };
@@ -33,13 +33,17 @@ function validateSnapshot(value) {
33
33
  if (!isRecord(route) || typeof route.name !== "string" || typeof route.path !== "string" || !isRequestMethod(route.method)) throw new Error("Route registration child sent an invalid route record.");
34
34
  const response = route.response;
35
35
  const clientVisible = route.clientVisible;
36
- const allowedKeys = 3 + (response === void 0 ? 0 : 1) + (clientVisible === void 0 ? 0 : 1);
37
- if (Object.keys(route).length !== allowedKeys || response !== void 0 && !isResponseTypeRecord(response) || clientVisible !== void 0 && clientVisible !== false) throw new Error("Route registration child sent a route record with non-browser-safe fields.");
36
+ const sites = route.sites;
37
+ const guarded = route.guarded;
38
+ const allowedKeys = 3 + (response === void 0 ? 0 : 1) + (clientVisible === void 0 ? 0 : 1) + (sites === void 0 ? 0 : 1) + (guarded === void 0 ? 0 : 1);
39
+ if (Object.keys(route).length !== allowedKeys || response !== void 0 && !isResponseTypeRecord(response) || clientVisible !== void 0 && clientVisible !== false || sites !== void 0 && !isStringList(sites) || guarded !== void 0 && guarded !== true) throw new Error("Route registration child sent a route record with non-browser-safe fields.");
38
40
  const base = {
39
41
  name: route.name,
40
42
  path: route.path,
41
43
  method: normalizeRequestMethod(route.method),
42
- ...clientVisible === false ? { clientVisible: false } : {}
44
+ ...clientVisible === false ? { clientVisible: false } : {},
45
+ ...sites === void 0 ? {} : { sites: Object.freeze([...sites]) },
46
+ ...guarded === true ? { guarded: true } : {}
43
47
  };
44
48
  return Object.freeze(response === void 0 ? base : {
45
49
  ...base,
@@ -51,6 +55,9 @@ function validateSnapshot(value) {
51
55
  routes: Object.freeze(routes)
52
56
  });
53
57
  }
58
+ function isStringList(value) {
59
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string");
60
+ }
54
61
  function isResponseTypeRecord(value) {
55
62
  return isRecord(value) && Object.values(value).every((entry) => typeof entry === "string");
56
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route-registration-snapshot.mjs","names":[],"sources":["../../../../../../../../packages/core/src/production/route-registration-snapshot.ts"],"sourcesContent":["import type { NamedApiRoute, RequestMethod } from \"../router/types\";\nimport type { Environment, RuntimeStrategy } from \"../utils/environment\";\nimport {\n runRegistrationChild,\n type RegistrationChildForker,\n type RegistrationChildProcess,\n} from \"./registration-child-runner\";\n\nconst PROTOCOL_VERSION = 1;\n\nexport type RouteRegistrationSnapshot = Readonly<{\n version: typeof PROTOCOL_VERSION;\n routes: readonly NamedApiRoute[];\n}>;\n\nexport type RouteRegistrationChildRequest = Readonly<{\n version: typeof PROTOCOL_VERSION;\n cwd: string;\n environment?: Environment;\n runtimeStrategy?: RuntimeStrategy;\n}>;\n\nexport type RouteRegistrationChildProcess = RegistrationChildProcess;\n\nexport type RouteRegistrationSnapshotOptions = Readonly<{\n cwd?: string;\n environment?: Environment;\n runtimeStrategy?: RuntimeStrategy;\n timeoutMs?: number;\n childEntry?: string;\n forkProcess?: RegistrationChildForker;\n}>;\n\n/**\n * Collect named application API routes in a fresh process.\n *\n * The child imports application registration modules but deliberately does not\n * register, boot, or start connectors. Application module top-level code can\n * still have arbitrary user-owned side effects; this boundary is framework-only.\n */\nexport function collectRouteRegistrationSnapshot(\n options: RouteRegistrationSnapshotOptions = {},\n): Promise<RouteRegistrationSnapshot> {\n const cwd = options.cwd ?? process.cwd();\n\n return runRegistrationChild<RouteRegistrationSnapshot>({\n cwd,\n timeoutMs: options.timeoutMs,\n childEntry: options.childEntry,\n forkProcess: options.forkProcess,\n request: {\n version: PROTOCOL_VERSION,\n cwd,\n environment: options.environment,\n runtimeStrategy: options.runtimeStrategy,\n } satisfies RouteRegistrationChildRequest,\n resultMessageType: \"route-registration:snapshot\",\n resultNoun: \"snapshot\",\n readResult: (message) => validateSnapshot(message.snapshot),\n });\n}\n\nfunction validateSnapshot(value: unknown): RouteRegistrationSnapshot {\n if (!isRecord(value) || value.version !== PROTOCOL_VERSION || !Array.isArray(value.routes)) {\n throw new Error(\"Route registration child sent an invalid snapshot protocol payload.\");\n }\n\n const routes = value.routes.map((route) => {\n if (\n !isRecord(route) ||\n typeof route.name !== \"string\" ||\n typeof route.path !== \"string\" ||\n !isRequestMethod(route.method)\n ) {\n throw new Error(\"Route registration child sent an invalid route record.\");\n }\n\n const response = route.response;\n const clientVisible = route.clientVisible;\n const allowedKeys =\n 3 + (response === undefined ? 0 : 1) + (clientVisible === undefined ? 0 : 1);\n\n if (\n Object.keys(route).length !== allowedKeys ||\n (response !== undefined && !isResponseTypeRecord(response)) ||\n (clientVisible !== undefined && clientVisible !== false)\n ) {\n throw new Error(\"Route registration child sent a route record with non-browser-safe fields.\");\n }\n\n const base = {\n name: route.name,\n path: route.path,\n method: normalizeRequestMethod(route.method),\n ...(clientVisible === false ? { clientVisible: false as const } : {}),\n };\n\n return Object.freeze(\n response === undefined ? base : { ...base, response: Object.freeze({ ...response }) },\n );\n });\n\n return Object.freeze({ version: PROTOCOL_VERSION, routes: Object.freeze(routes) });\n}\n\nfunction isResponseTypeRecord(value: unknown): value is Record<string, string> {\n return isRecord(value) && Object.values(value).every((entry) => typeof entry === \"string\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isRequestMethod(value: unknown): value is RequestMethod {\n return (\n typeof value === \"string\" &&\n [\"get\", \"post\", \"put\", \"delete\", \"patch\", \"options\", \"head\", \"all\"].includes(\n value.toLowerCase(),\n )\n );\n}\n\nfunction normalizeRequestMethod(value: RequestMethod | string): RequestMethod {\n return value.toLowerCase() === \"all\" ? \"all\" : (value.toUpperCase() as RequestMethod);\n}\n"],"mappings":";;;AAQA,MAAM,mBAAmB;;;;;;;;AAgCzB,SAAgB,iCACd,UAA4C,CAAC,GACT;CACpC,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;CAEvC,OAAO,qBAAgD;EACrD;EACA,WAAW,QAAQ;EACnB,YAAY,QAAQ;EACpB,aAAa,QAAQ;EACrB,SAAS;GACP,SAAS;GACT;GACA,aAAa,QAAQ;GACrB,iBAAiB,QAAQ;EAC3B;EACA,mBAAmB;EACnB,YAAY;EACZ,aAAa,YAAY,iBAAiB,QAAQ,QAAQ;CAC5D,CAAC;AACH;AAEA,SAAS,iBAAiB,OAA2C;CACnE,IAAI,CAAC,SAAS,KAAK,KAAK,MAAM,YAAY,oBAAoB,CAAC,MAAM,QAAQ,MAAM,MAAM,GACvF,MAAM,IAAI,MAAM,qEAAqE;CAGvF,MAAM,SAAS,MAAM,OAAO,KAAK,UAAU;EACzC,IACE,CAAC,SAAS,KAAK,KACf,OAAO,MAAM,SAAS,YACtB,OAAO,MAAM,SAAS,YACtB,CAAC,gBAAgB,MAAM,MAAM,GAE7B,MAAM,IAAI,MAAM,wDAAwD;EAG1E,MAAM,WAAW,MAAM;EACvB,MAAM,gBAAgB,MAAM;EAC5B,MAAM,cACJ,KAAK,aAAa,SAAY,IAAI,MAAM,kBAAkB,SAAY,IAAI;EAE5E,IACE,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,eAC7B,aAAa,UAAa,CAAC,qBAAqB,QAAQ,KACxD,kBAAkB,UAAa,kBAAkB,OAElD,MAAM,IAAI,MAAM,4EAA4E;EAG9F,MAAM,OAAO;GACX,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ,QAAQ,uBAAuB,MAAM,MAAM;GAC3C,GAAI,kBAAkB,QAAQ,EAAE,eAAe,MAAe,IAAI,CAAC;EACrE;EAEA,OAAO,OAAO,OACZ,aAAa,SAAY,OAAO;GAAE,GAAG;GAAM,UAAU,OAAO,OAAO,EAAE,GAAG,SAAS,CAAC;EAAE,CACtF;CACF,CAAC;CAED,OAAO,OAAO,OAAO;EAAE,SAAS;EAAkB,QAAQ,OAAO,OAAO,MAAM;CAAE,CAAC;AACnF;AAEA,SAAS,qBAAqB,OAAiD;CAC7E,OAAO,SAAS,KAAK,KAAK,OAAO,OAAO,KAAK,CAAC,CAAC,OAAO,UAAU,OAAO,UAAU,QAAQ;AAC3F;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,gBAAgB,OAAwC;CAC/D,OACE,OAAO,UAAU,YACjB;EAAC;EAAO;EAAQ;EAAO;EAAU;EAAS;EAAW;EAAQ;CAAK,CAAC,CAAC,SAClE,MAAM,YAAY,CACpB;AAEJ;AAEA,SAAS,uBAAuB,OAA8C;CAC5E,OAAO,MAAM,YAAY,MAAM,QAAQ,QAAS,MAAM,YAAY;AACpE"}
1
+ {"version":3,"file":"route-registration-snapshot.mjs","names":[],"sources":["../../../../../../../../packages/core/src/production/route-registration-snapshot.ts"],"sourcesContent":["import type { NamedApiRoute, RequestMethod } from \"../router/types\";\nimport type { Environment, RuntimeStrategy } from \"../utils/environment\";\nimport {\n runRegistrationChild,\n type RegistrationChildForker,\n type RegistrationChildProcess,\n} from \"./registration-child-runner\";\n\nconst PROTOCOL_VERSION = 1;\n\nexport type RouteRegistrationSnapshot = Readonly<{\n version: typeof PROTOCOL_VERSION;\n routes: readonly NamedApiRoute[];\n}>;\n\nexport type RouteRegistrationChildRequest = Readonly<{\n version: typeof PROTOCOL_VERSION;\n cwd: string;\n environment?: Environment;\n runtimeStrategy?: RuntimeStrategy;\n}>;\n\nexport type RouteRegistrationChildProcess = RegistrationChildProcess;\n\nexport type RouteRegistrationSnapshotOptions = Readonly<{\n cwd?: string;\n environment?: Environment;\n runtimeStrategy?: RuntimeStrategy;\n timeoutMs?: number;\n childEntry?: string;\n forkProcess?: RegistrationChildForker;\n}>;\n\n/**\n * Collect named application API routes in a fresh process.\n *\n * The child imports application registration modules but deliberately does not\n * register, boot, or start connectors. Application module top-level code can\n * still have arbitrary user-owned side effects; this boundary is framework-only.\n */\nexport function collectRouteRegistrationSnapshot(\n options: RouteRegistrationSnapshotOptions = {},\n): Promise<RouteRegistrationSnapshot> {\n const cwd = options.cwd ?? process.cwd();\n\n return runRegistrationChild<RouteRegistrationSnapshot>({\n cwd,\n timeoutMs: options.timeoutMs,\n childEntry: options.childEntry,\n forkProcess: options.forkProcess,\n request: {\n version: PROTOCOL_VERSION,\n cwd,\n environment: options.environment,\n runtimeStrategy: options.runtimeStrategy,\n } satisfies RouteRegistrationChildRequest,\n resultMessageType: \"route-registration:snapshot\",\n resultNoun: \"snapshot\",\n readResult: (message) => validateSnapshot(message.snapshot),\n });\n}\n\nfunction validateSnapshot(value: unknown): RouteRegistrationSnapshot {\n if (!isRecord(value) || value.version !== PROTOCOL_VERSION || !Array.isArray(value.routes)) {\n throw new Error(\"Route registration child sent an invalid snapshot protocol payload.\");\n }\n\n const routes = value.routes.map((route) => {\n if (\n !isRecord(route) ||\n typeof route.name !== \"string\" ||\n typeof route.path !== \"string\" ||\n !isRequestMethod(route.method)\n ) {\n throw new Error(\"Route registration child sent an invalid route record.\");\n }\n\n const response = route.response;\n const clientVisible = route.clientVisible;\n const sites = route.sites;\n const guarded = route.guarded;\n const allowedKeys =\n 3 +\n (response === undefined ? 0 : 1) +\n (clientVisible === undefined ? 0 : 1) +\n (sites === undefined ? 0 : 1) +\n (guarded === undefined ? 0 : 1);\n\n if (\n Object.keys(route).length !== allowedKeys ||\n (response !== undefined && !isResponseTypeRecord(response)) ||\n (clientVisible !== undefined && clientVisible !== false) ||\n (sites !== undefined && !isStringList(sites)) ||\n (guarded !== undefined && guarded !== true)\n ) {\n throw new Error(\"Route registration child sent a route record with non-browser-safe fields.\");\n }\n\n const base = {\n name: route.name,\n path: route.path,\n method: normalizeRequestMethod(route.method),\n ...(clientVisible === false ? { clientVisible: false as const } : {}),\n ...(sites === undefined ? {} : { sites: Object.freeze([...sites]) }),\n ...(guarded === true ? { guarded: true as const } : {}),\n };\n\n return Object.freeze(\n response === undefined ? base : { ...base, response: Object.freeze({ ...response }) },\n );\n });\n\n return Object.freeze({ version: PROTOCOL_VERSION, routes: Object.freeze(routes) });\n}\n\nfunction isStringList(value: unknown): value is readonly string[] {\n return Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n}\n\nfunction isResponseTypeRecord(value: unknown): value is Record<string, string> {\n return isRecord(value) && Object.values(value).every((entry) => typeof entry === \"string\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isRequestMethod(value: unknown): value is RequestMethod {\n return (\n typeof value === \"string\" &&\n [\"get\", \"post\", \"put\", \"delete\", \"patch\", \"options\", \"head\", \"all\"].includes(\n value.toLowerCase(),\n )\n );\n}\n\nfunction normalizeRequestMethod(value: RequestMethod | string): RequestMethod {\n return value.toLowerCase() === \"all\" ? \"all\" : (value.toUpperCase() as RequestMethod);\n}\n"],"mappings":";;;AAQA,MAAM,mBAAmB;;;;;;;;AAgCzB,SAAgB,iCACd,UAA4C,CAAC,GACT;CACpC,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;CAEvC,OAAO,qBAAgD;EACrD;EACA,WAAW,QAAQ;EACnB,YAAY,QAAQ;EACpB,aAAa,QAAQ;EACrB,SAAS;GACP,SAAS;GACT;GACA,aAAa,QAAQ;GACrB,iBAAiB,QAAQ;EAC3B;EACA,mBAAmB;EACnB,YAAY;EACZ,aAAa,YAAY,iBAAiB,QAAQ,QAAQ;CAC5D,CAAC;AACH;AAEA,SAAS,iBAAiB,OAA2C;CACnE,IAAI,CAAC,SAAS,KAAK,KAAK,MAAM,YAAY,oBAAoB,CAAC,MAAM,QAAQ,MAAM,MAAM,GACvF,MAAM,IAAI,MAAM,qEAAqE;CAGvF,MAAM,SAAS,MAAM,OAAO,KAAK,UAAU;EACzC,IACE,CAAC,SAAS,KAAK,KACf,OAAO,MAAM,SAAS,YACtB,OAAO,MAAM,SAAS,YACtB,CAAC,gBAAgB,MAAM,MAAM,GAE7B,MAAM,IAAI,MAAM,wDAAwD;EAG1E,MAAM,WAAW,MAAM;EACvB,MAAM,gBAAgB,MAAM;EAC5B,MAAM,QAAQ,MAAM;EACpB,MAAM,UAAU,MAAM;EACtB,MAAM,cACJ,KACC,aAAa,SAAY,IAAI,MAC7B,kBAAkB,SAAY,IAAI,MAClC,UAAU,SAAY,IAAI,MAC1B,YAAY,SAAY,IAAI;EAE/B,IACE,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,eAC7B,aAAa,UAAa,CAAC,qBAAqB,QAAQ,KACxD,kBAAkB,UAAa,kBAAkB,SACjD,UAAU,UAAa,CAAC,aAAa,KAAK,KAC1C,YAAY,UAAa,YAAY,MAEtC,MAAM,IAAI,MAAM,4EAA4E;EAG9F,MAAM,OAAO;GACX,MAAM,MAAM;GACZ,MAAM,MAAM;GACZ,QAAQ,uBAAuB,MAAM,MAAM;GAC3C,GAAI,kBAAkB,QAAQ,EAAE,eAAe,MAAe,IAAI,CAAC;GACnE,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,OAAO,OAAO,CAAC,GAAG,KAAK,CAAC,EAAE;GAClE,GAAI,YAAY,OAAO,EAAE,SAAS,KAAc,IAAI,CAAC;EACvD;EAEA,OAAO,OAAO,OACZ,aAAa,SAAY,OAAO;GAAE,GAAG;GAAM,UAAU,OAAO,OAAO,EAAE,GAAG,SAAS,CAAC;EAAE,CACtF;CACF,CAAC;CAED,OAAO,OAAO,OAAO;EAAE,SAAS;EAAkB,QAAQ,OAAO,OAAO,MAAM;CAAE,CAAC;AACnF;AAEA,SAAS,aAAa,OAA4C;CAChE,OAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,OAAO,UAAU,OAAO,UAAU,QAAQ;AACjF;AAEA,SAAS,qBAAqB,OAAiD;CAC7E,OAAO,SAAS,KAAK,KAAK,OAAO,OAAO,KAAK,CAAC,CAAC,OAAO,UAAU,OAAO,UAAU,QAAQ;AAC3F;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,gBAAgB,OAAwC;CAC/D,OACE,OAAO,UAAU,YACjB;EAAC;EAAO;EAAQ;EAAO;EAAU;EAAS;EAAW;EAAQ;CAAK,CAAC,CAAC,SAClE,MAAM,YAAY,CACpB;AAEJ;AAEA,SAAS,uBAAuB,OAA8C;CAC5E,OAAO,MAAM,YAAY,MAAM,QAAQ,QAAS,MAAM,YAAY;AACpE"}
@@ -0,0 +1,261 @@
1
+ import { compareVersions } from "./semver.mjs";
2
+ import { appendLog, pointerPath, readManifest, readPointer, releaseDir, switchPointer, writeManifest } from "./store.mjs";
3
+ import { hasStagedArtefacts } from "./stage.mjs";
4
+
5
+ //#region ../../packages/core/src/release/activate.ts
6
+ /**
7
+ * The checks every activation must pass.
8
+ *
9
+ * The version rule is strict on purpose: the candidate has to be greater than
10
+ * the active release. Equal versions need `allowSame` (a rebuild of the same
11
+ * version from another commit); a lower version is never activated this way,
12
+ * `release rollback` is the path back.
13
+ */
14
+ async function runPreflight(context, manifest, options = {}) {
15
+ const checks = [];
16
+ const activeId = await readPointer(context, "current");
17
+ checks.push({
18
+ name: "staged",
19
+ ok: manifest.status === "staged" && await hasStagedArtefacts(context, manifest.id),
20
+ detail: "staged artefacts are present (run `warlock release stage`)"
21
+ });
22
+ checks.push({
23
+ name: "gate",
24
+ ok: manifest.gate?.passed === true,
25
+ detail: "the gate passed"
26
+ });
27
+ if (manifest.migrations) checks.push({
28
+ name: "migrations",
29
+ ok: manifest.migrations.passed,
30
+ detail: "the recorded migration proof passed"
31
+ });
32
+ if (activeId === manifest.id) checks.push({
33
+ name: "not-active",
34
+ ok: false,
35
+ detail: "this release is already active"
36
+ });
37
+ else if (activeId) {
38
+ const active = await readManifest(context, activeId);
39
+ const order = compareVersions(manifest.version, active.version);
40
+ checks.push({
41
+ name: "version",
42
+ ok: order > 0 || order === 0 && options.allowSame === true,
43
+ detail: order > 0 ? `${manifest.version} is greater than the active ${active.version}` : order === 0 ? `${manifest.version} equals the active version (pass --allow-same to accept)` : `${manifest.version} is lower than the active ${active.version} (use \`release rollback\`)`
44
+ });
45
+ } else checks.push({
46
+ name: "version",
47
+ ok: true,
48
+ detail: "no active release yet"
49
+ });
50
+ return {
51
+ checks,
52
+ activeId
53
+ };
54
+ }
55
+ async function restart(context, id) {
56
+ const command = context.config.restart.command;
57
+ if (!command) return {
58
+ ran: false,
59
+ ok: true
60
+ };
61
+ const result = await context.runner(command, {
62
+ cwd: context.root,
63
+ timeoutMs: context.config.restart.timeoutMs,
64
+ env: {
65
+ WARLOCK_RELEASE_ID: id,
66
+ WARLOCK_RELEASE_DIR: releaseDir(context, id),
67
+ WARLOCK_RELEASE_CURRENT: pointerPath(context, "current")
68
+ }
69
+ });
70
+ return {
71
+ ran: true,
72
+ ok: result.code === 0 && !result.timedOut,
73
+ output: result.output
74
+ };
75
+ }
76
+ /**
77
+ * Preflight, then switch `current` to the release and run the restart
78
+ * command.
79
+ *
80
+ * The switch is one atomic symlink rename. The old `current` becomes
81
+ * `previous`. Warlock restarts nothing itself: only the configured
82
+ * `release.restart.command` runs, and when it is unset the pointer switch is
83
+ * the whole activation. If the restart command fails the pointer stays on the
84
+ * new release (the restart may have partly taken effect) and the result says
85
+ * so; `release rollback` is the way back.
86
+ *
87
+ * @example
88
+ * const result = await activateRelease(context, "1.4.0-a1b2c3d", { dryRun: true });
89
+ */
90
+ async function activateRelease(context, id, options = {}) {
91
+ const manifest = await readManifest(context, id);
92
+ const { checks, activeId } = await runPreflight(context, manifest, options);
93
+ const failed = checks.filter((check) => !check.ok);
94
+ const base = {
95
+ id,
96
+ previousId: activeId,
97
+ checks,
98
+ switched: false,
99
+ dryRun: options.dryRun === true,
100
+ restarted: null
101
+ };
102
+ if (failed.length > 0) {
103
+ const message = `Preflight failed: ${failed.map((check) => check.name).join(", ")}.`;
104
+ if (!options.preflightOnly && !options.dryRun) await appendLog(context, {
105
+ event: "activate",
106
+ release: id,
107
+ ok: false,
108
+ detail: message
109
+ });
110
+ return {
111
+ ...base,
112
+ ok: false,
113
+ message
114
+ };
115
+ }
116
+ if (options.preflightOnly) return {
117
+ ...base,
118
+ ok: true,
119
+ message: "Preflight passed."
120
+ };
121
+ if (options.dryRun) return {
122
+ ...base,
123
+ ok: true,
124
+ message: `Dry run: would switch current to ${id}${activeId ? ` (previous becomes ${activeId})` : ""}${context.config.restart.command ? " and run the restart command" : ""}.`
125
+ };
126
+ if (activeId) await switchPointer(context, "previous", activeId);
127
+ await switchPointer(context, "current", id);
128
+ if (activeId) {
129
+ const old = await readManifest(context, activeId);
130
+ await writeManifest(context, {
131
+ ...old,
132
+ status: "superseded"
133
+ });
134
+ }
135
+ const restarted = await restart(context, id);
136
+ await writeManifest(context, {
137
+ ...manifest,
138
+ status: "active",
139
+ activation: {
140
+ at: context.now().toISOString(),
141
+ previousId: activeId,
142
+ restarted: restarted.ran && restarted.ok
143
+ }
144
+ });
145
+ if (!restarted.ok) {
146
+ const message = `Switched current to ${id}, but the restart command failed. Fix it or run \`warlock release rollback\`.`;
147
+ await appendLog(context, {
148
+ event: "activate",
149
+ release: id,
150
+ ok: false,
151
+ detail: message
152
+ });
153
+ return {
154
+ ...base,
155
+ switched: true,
156
+ restarted: false,
157
+ restartOutput: restarted.output,
158
+ ok: false,
159
+ message
160
+ };
161
+ }
162
+ const message = `Activated ${id}${restarted.ran ? " and ran the restart command" : ""}.`;
163
+ await appendLog(context, {
164
+ event: "activate",
165
+ release: id,
166
+ ok: true,
167
+ detail: message
168
+ });
169
+ return {
170
+ ...base,
171
+ switched: true,
172
+ restarted: restarted.ran ? true : null,
173
+ ok: true,
174
+ message
175
+ };
176
+ }
177
+ /**
178
+ * Switch `current` back to `previous`, and `previous` to the release that was
179
+ * just left (so a second rollback returns to it), then run the restart
180
+ * command.
181
+ *
182
+ * Migrations are never rolled back here. A migration may have dropped or
183
+ * rewritten data that no reverse step can restore, and the code that ran
184
+ * before usually tolerates the newer schema; deciding to undo a schema change
185
+ * is a separate, deliberate step (`warlock migrate --rollback`) taken with the
186
+ * data in view.
187
+ */
188
+ async function rollbackRelease(context, options = {}) {
189
+ const current = await readPointer(context, "current");
190
+ const previous = await readPointer(context, "previous");
191
+ const base = {
192
+ from: current,
193
+ to: previous,
194
+ switched: false,
195
+ dryRun: options.dryRun === true,
196
+ restarted: null
197
+ };
198
+ if (!current || !previous) return {
199
+ ...base,
200
+ ok: false,
201
+ message: "There is no previous release to roll back to."
202
+ };
203
+ const target = await readManifest(context, previous);
204
+ const left = await readManifest(context, current);
205
+ if (!await hasStagedArtefacts(context, previous)) return {
206
+ ...base,
207
+ ok: false,
208
+ message: `The staged files of ${previous} are gone; cannot roll back to it.`
209
+ };
210
+ if (options.dryRun) return {
211
+ ...base,
212
+ ok: true,
213
+ message: `Dry run: would switch current back to ${previous}${context.config.restart.command ? " and run the restart command" : ""}.`
214
+ };
215
+ await switchPointer(context, "previous", current);
216
+ await switchPointer(context, "current", previous);
217
+ await writeManifest(context, {
218
+ ...left,
219
+ status: "superseded"
220
+ });
221
+ await writeManifest(context, {
222
+ ...target,
223
+ status: "active"
224
+ });
225
+ const restarted = await restart(context, previous);
226
+ if (!restarted.ok) {
227
+ const message = `Rolled current back to ${previous}, but the restart command failed.`;
228
+ await appendLog(context, {
229
+ event: "rollback",
230
+ release: previous,
231
+ ok: false,
232
+ detail: message
233
+ });
234
+ return {
235
+ ...base,
236
+ switched: true,
237
+ restarted: false,
238
+ restartOutput: restarted.output,
239
+ ok: false,
240
+ message
241
+ };
242
+ }
243
+ const message = `Rolled back from ${current} to ${previous}${restarted.ran ? " and ran the restart command" : ""}.`;
244
+ await appendLog(context, {
245
+ event: "rollback",
246
+ release: previous,
247
+ ok: true,
248
+ detail: message
249
+ });
250
+ return {
251
+ ...base,
252
+ switched: true,
253
+ restarted: restarted.ran ? true : null,
254
+ ok: true,
255
+ message
256
+ };
257
+ }
258
+
259
+ //#endregion
260
+ export { activateRelease, rollbackRelease, runPreflight };
261
+ //# sourceMappingURL=activate.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activate.mjs","names":[],"sources":["../../../../../../../../packages/core/src/release/activate.ts"],"sourcesContent":["import { compareVersions } from \"./semver\";\nimport { hasStagedArtefacts } from \"./stage\";\nimport {\n appendLog,\n pointerPath,\n readManifest,\n readPointer,\n releaseDir,\n switchPointer,\n writeManifest,\n type ReleaseContext,\n} from \"./store\";\nimport type { ReleaseManifest } from \"./types\";\n\nexport type PreflightCheck = { name: string; ok: boolean; detail: string };\n\nexport type ActivateOptions = {\n /** Run the preflight checks and stop. */\n preflightOnly?: boolean;\n /** Report what would change without changing anything. */\n dryRun?: boolean;\n /** Accept a version equal to the active one (a different commit). */\n allowSame?: boolean;\n};\n\nexport type ActivationResult = {\n id: string;\n /** The release that was active before, if any */\n previousId: string | null;\n checks: PreflightCheck[];\n /** Whether the pointer was switched */\n switched: boolean;\n dryRun: boolean;\n /** Whether the restart command ran, and succeeded */\n restarted: boolean | null;\n restartOutput?: string;\n ok: boolean;\n message: string;\n};\n\n/**\n * The checks every activation must pass.\n *\n * The version rule is strict on purpose: the candidate has to be greater than\n * the active release. Equal versions need `allowSame` (a rebuild of the same\n * version from another commit); a lower version is never activated this way,\n * `release rollback` is the path back.\n */\nexport async function runPreflight(\n context: ReleaseContext,\n manifest: ReleaseManifest,\n options: Pick<ActivateOptions, \"allowSame\"> = {},\n): Promise<{ checks: PreflightCheck[]; activeId: string | null }> {\n const checks: PreflightCheck[] = [];\n const activeId = await readPointer(context, \"current\");\n\n checks.push({\n name: \"staged\",\n ok: manifest.status === \"staged\" && (await hasStagedArtefacts(context, manifest.id)),\n detail: \"staged artefacts are present (run `warlock release stage`)\",\n });\n\n checks.push({\n name: \"gate\",\n ok: manifest.gate?.passed === true,\n detail: \"the gate passed\",\n });\n\n if (manifest.migrations) {\n checks.push({\n name: \"migrations\",\n ok: manifest.migrations.passed,\n detail: \"the recorded migration proof passed\",\n });\n }\n\n if (activeId === manifest.id) {\n checks.push({ name: \"not-active\", ok: false, detail: \"this release is already active\" });\n } else if (activeId) {\n const active = await readManifest(context, activeId);\n const order = compareVersions(manifest.version, active.version);\n\n checks.push({\n name: \"version\",\n ok: order > 0 || (order === 0 && options.allowSame === true),\n detail:\n order > 0\n ? `${manifest.version} is greater than the active ${active.version}`\n : order === 0\n ? `${manifest.version} equals the active version (pass --allow-same to accept)`\n : `${manifest.version} is lower than the active ${active.version} (use \\`release rollback\\`)`,\n });\n } else {\n checks.push({ name: \"version\", ok: true, detail: \"no active release yet\" });\n }\n\n return { checks, activeId };\n}\n\nasync function restart(\n context: ReleaseContext,\n id: string,\n): Promise<{ ran: boolean; ok: boolean; output?: string }> {\n const command = context.config.restart.command;\n\n if (!command) return { ran: false, ok: true };\n\n const result = await context.runner(command, {\n cwd: context.root,\n timeoutMs: context.config.restart.timeoutMs,\n env: {\n WARLOCK_RELEASE_ID: id,\n WARLOCK_RELEASE_DIR: releaseDir(context, id),\n WARLOCK_RELEASE_CURRENT: pointerPath(context, \"current\"),\n },\n });\n\n return { ran: true, ok: result.code === 0 && !result.timedOut, output: result.output };\n}\n\n/**\n * Preflight, then switch `current` to the release and run the restart\n * command.\n *\n * The switch is one atomic symlink rename. The old `current` becomes\n * `previous`. Warlock restarts nothing itself: only the configured\n * `release.restart.command` runs, and when it is unset the pointer switch is\n * the whole activation. If the restart command fails the pointer stays on the\n * new release (the restart may have partly taken effect) and the result says\n * so; `release rollback` is the way back.\n *\n * @example\n * const result = await activateRelease(context, \"1.4.0-a1b2c3d\", { dryRun: true });\n */\nexport async function activateRelease(\n context: ReleaseContext,\n id: string,\n options: ActivateOptions = {},\n): Promise<ActivationResult> {\n const manifest = await readManifest(context, id);\n const { checks, activeId } = await runPreflight(context, manifest, options);\n const failed = checks.filter((check) => !check.ok);\n const base = {\n id,\n previousId: activeId,\n checks,\n switched: false,\n dryRun: options.dryRun === true,\n restarted: null,\n };\n\n if (failed.length > 0) {\n const message = `Preflight failed: ${failed.map((check) => check.name).join(\", \")}.`;\n\n if (!options.preflightOnly && !options.dryRun) {\n await appendLog(context, { event: \"activate\", release: id, ok: false, detail: message });\n }\n\n return { ...base, ok: false, message };\n }\n\n if (options.preflightOnly) {\n return { ...base, ok: true, message: \"Preflight passed.\" };\n }\n\n if (options.dryRun) {\n return {\n ...base,\n ok: true,\n message: `Dry run: would switch current to ${id}${activeId ? ` (previous becomes ${activeId})` : \"\"}${\n context.config.restart.command ? \" and run the restart command\" : \"\"\n }.`,\n };\n }\n\n if (activeId) await switchPointer(context, \"previous\", activeId);\n await switchPointer(context, \"current\", id);\n\n if (activeId) {\n const old = await readManifest(context, activeId);\n\n await writeManifest(context, { ...old, status: \"superseded\" });\n }\n\n const restarted = await restart(context, id);\n\n await writeManifest(context, {\n ...manifest,\n status: \"active\",\n activation: {\n at: context.now().toISOString(),\n previousId: activeId,\n restarted: restarted.ran && restarted.ok,\n },\n });\n\n if (!restarted.ok) {\n const message = `Switched current to ${id}, but the restart command failed. Fix it or run \\`warlock release rollback\\`.`;\n\n await appendLog(context, { event: \"activate\", release: id, ok: false, detail: message });\n\n return {\n ...base,\n switched: true,\n restarted: false,\n restartOutput: restarted.output,\n ok: false,\n message,\n };\n }\n\n const message = `Activated ${id}${restarted.ran ? \" and ran the restart command\" : \"\"}.`;\n\n await appendLog(context, { event: \"activate\", release: id, ok: true, detail: message });\n\n return {\n ...base,\n switched: true,\n restarted: restarted.ran ? true : null,\n ok: true,\n message,\n };\n}\n\nexport type RollbackResult = {\n from: string | null;\n to: string | null;\n switched: boolean;\n dryRun: boolean;\n restarted: boolean | null;\n restartOutput?: string;\n ok: boolean;\n message: string;\n};\n\n/**\n * Switch `current` back to `previous`, and `previous` to the release that was\n * just left (so a second rollback returns to it), then run the restart\n * command.\n *\n * Migrations are never rolled back here. A migration may have dropped or\n * rewritten data that no reverse step can restore, and the code that ran\n * before usually tolerates the newer schema; deciding to undo a schema change\n * is a separate, deliberate step (`warlock migrate --rollback`) taken with the\n * data in view.\n */\nexport async function rollbackRelease(\n context: ReleaseContext,\n options: { dryRun?: boolean } = {},\n): Promise<RollbackResult> {\n const current = await readPointer(context, \"current\");\n const previous = await readPointer(context, \"previous\");\n const base = {\n from: current,\n to: previous,\n switched: false,\n dryRun: options.dryRun === true,\n restarted: null,\n };\n\n if (!current || !previous) {\n return { ...base, ok: false, message: \"There is no previous release to roll back to.\" };\n }\n\n // Both manifests must exist before anything moves.\n const target = await readManifest(context, previous);\n const left = await readManifest(context, current);\n\n if (!(await hasStagedArtefacts(context, previous))) {\n return {\n ...base,\n ok: false,\n message: `The staged files of ${previous} are gone; cannot roll back to it.`,\n };\n }\n\n if (options.dryRun) {\n return {\n ...base,\n ok: true,\n message: `Dry run: would switch current back to ${previous}${\n context.config.restart.command ? \" and run the restart command\" : \"\"\n }.`,\n };\n }\n\n await switchPointer(context, \"previous\", current);\n await switchPointer(context, \"current\", previous);\n await writeManifest(context, { ...left, status: \"superseded\" });\n await writeManifest(context, { ...target, status: \"active\" });\n\n const restarted = await restart(context, previous);\n\n if (!restarted.ok) {\n const message = `Rolled current back to ${previous}, but the restart command failed.`;\n\n await appendLog(context, { event: \"rollback\", release: previous, ok: false, detail: message });\n\n return {\n ...base,\n switched: true,\n restarted: false,\n restartOutput: restarted.output,\n ok: false,\n message,\n };\n }\n\n const message = `Rolled back from ${current} to ${previous}${\n restarted.ran ? \" and ran the restart command\" : \"\"\n }.`;\n\n await appendLog(context, { event: \"rollback\", release: previous, ok: true, detail: message });\n\n return {\n ...base,\n switched: true,\n restarted: restarted.ran ? true : null,\n ok: true,\n message,\n };\n}\n"],"mappings":";;;;;;;;;;;;;AAgDA,eAAsB,aACpB,SACA,UACA,UAA8C,CAAC,GACiB;CAChE,MAAM,SAA2B,CAAC;CAClC,MAAM,WAAW,MAAM,YAAY,SAAS,SAAS;CAErD,OAAO,KAAK;EACV,MAAM;EACN,IAAI,SAAS,WAAW,YAAa,MAAM,mBAAmB,SAAS,SAAS,EAAE;EAClF,QAAQ;CACV,CAAC;CAED,OAAO,KAAK;EACV,MAAM;EACN,IAAI,SAAS,MAAM,WAAW;EAC9B,QAAQ;CACV,CAAC;CAED,IAAI,SAAS,YACX,OAAO,KAAK;EACV,MAAM;EACN,IAAI,SAAS,WAAW;EACxB,QAAQ;CACV,CAAC;CAGH,IAAI,aAAa,SAAS,IACxB,OAAO,KAAK;EAAE,MAAM;EAAc,IAAI;EAAO,QAAQ;CAAiC,CAAC;MAClF,IAAI,UAAU;EACnB,MAAM,SAAS,MAAM,aAAa,SAAS,QAAQ;EACnD,MAAM,QAAQ,gBAAgB,SAAS,SAAS,OAAO,OAAO;EAE9D,OAAO,KAAK;GACV,MAAM;GACN,IAAI,QAAQ,KAAM,UAAU,KAAK,QAAQ,cAAc;GACvD,QACE,QAAQ,IACJ,GAAG,SAAS,QAAQ,8BAA8B,OAAO,YACzD,UAAU,IACR,GAAG,SAAS,QAAQ,4DACpB,GAAG,SAAS,QAAQ,4BAA4B,OAAO,QAAQ;EACzE,CAAC;CACH,OACE,OAAO,KAAK;EAAE,MAAM;EAAW,IAAI;EAAM,QAAQ;CAAwB,CAAC;CAG5E,OAAO;EAAE;EAAQ;CAAS;AAC5B;AAEA,eAAe,QACb,SACA,IACyD;CACzD,MAAM,UAAU,QAAQ,OAAO,QAAQ;CAEvC,IAAI,CAAC,SAAS,OAAO;EAAE,KAAK;EAAO,IAAI;CAAK;CAE5C,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;EAC3C,KAAK,QAAQ;EACb,WAAW,QAAQ,OAAO,QAAQ;EAClC,KAAK;GACH,oBAAoB;GACpB,qBAAqB,WAAW,SAAS,EAAE;GAC3C,yBAAyB,YAAY,SAAS,SAAS;EACzD;CACF,CAAC;CAED,OAAO;EAAE,KAAK;EAAM,IAAI,OAAO,SAAS,KAAK,CAAC,OAAO;EAAU,QAAQ,OAAO;CAAO;AACvF;;;;;;;;;;;;;;;AAgBA,eAAsB,gBACpB,SACA,IACA,UAA2B,CAAC,GACD;CAC3B,MAAM,WAAW,MAAM,aAAa,SAAS,EAAE;CAC/C,MAAM,EAAE,QAAQ,aAAa,MAAM,aAAa,SAAS,UAAU,OAAO;CAC1E,MAAM,SAAS,OAAO,QAAQ,UAAU,CAAC,MAAM,EAAE;CACjD,MAAM,OAAO;EACX;EACA,YAAY;EACZ;EACA,UAAU;EACV,QAAQ,QAAQ,WAAW;EAC3B,WAAW;CACb;CAEA,IAAI,OAAO,SAAS,GAAG;EACrB,MAAM,UAAU,qBAAqB,OAAO,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE;EAElF,IAAI,CAAC,QAAQ,iBAAiB,CAAC,QAAQ,QACrC,MAAM,UAAU,SAAS;GAAE,OAAO;GAAY,SAAS;GAAI,IAAI;GAAO,QAAQ;EAAQ,CAAC;EAGzF,OAAO;GAAE,GAAG;GAAM,IAAI;GAAO;EAAQ;CACvC;CAEA,IAAI,QAAQ,eACV,OAAO;EAAE,GAAG;EAAM,IAAI;EAAM,SAAS;CAAoB;CAG3D,IAAI,QAAQ,QACV,OAAO;EACL,GAAG;EACH,IAAI;EACJ,SAAS,oCAAoC,KAAK,WAAW,sBAAsB,SAAS,KAAK,KAC/F,QAAQ,OAAO,QAAQ,UAAU,iCAAiC,GACnE;CACH;CAGF,IAAI,UAAU,MAAM,cAAc,SAAS,YAAY,QAAQ;CAC/D,MAAM,cAAc,SAAS,WAAW,EAAE;CAE1C,IAAI,UAAU;EACZ,MAAM,MAAM,MAAM,aAAa,SAAS,QAAQ;EAEhD,MAAM,cAAc,SAAS;GAAE,GAAG;GAAK,QAAQ;EAAa,CAAC;CAC/D;CAEA,MAAM,YAAY,MAAM,QAAQ,SAAS,EAAE;CAE3C,MAAM,cAAc,SAAS;EAC3B,GAAG;EACH,QAAQ;EACR,YAAY;GACV,IAAI,QAAQ,IAAI,CAAC,CAAC,YAAY;GAC9B,YAAY;GACZ,WAAW,UAAU,OAAO,UAAU;EACxC;CACF,CAAC;CAED,IAAI,CAAC,UAAU,IAAI;EACjB,MAAM,UAAU,uBAAuB,GAAG;EAE1C,MAAM,UAAU,SAAS;GAAE,OAAO;GAAY,SAAS;GAAI,IAAI;GAAO,QAAQ;EAAQ,CAAC;EAEvF,OAAO;GACL,GAAG;GACH,UAAU;GACV,WAAW;GACX,eAAe,UAAU;GACzB,IAAI;GACJ;EACF;CACF;CAEA,MAAM,UAAU,aAAa,KAAK,UAAU,MAAM,iCAAiC,GAAG;CAEtF,MAAM,UAAU,SAAS;EAAE,OAAO;EAAY,SAAS;EAAI,IAAI;EAAM,QAAQ;CAAQ,CAAC;CAEtF,OAAO;EACL,GAAG;EACH,UAAU;EACV,WAAW,UAAU,MAAM,OAAO;EAClC,IAAI;EACJ;CACF;AACF;;;;;;;;;;;;AAwBA,eAAsB,gBACpB,SACA,UAAgC,CAAC,GACR;CACzB,MAAM,UAAU,MAAM,YAAY,SAAS,SAAS;CACpD,MAAM,WAAW,MAAM,YAAY,SAAS,UAAU;CACtD,MAAM,OAAO;EACX,MAAM;EACN,IAAI;EACJ,UAAU;EACV,QAAQ,QAAQ,WAAW;EAC3B,WAAW;CACb;CAEA,IAAI,CAAC,WAAW,CAAC,UACf,OAAO;EAAE,GAAG;EAAM,IAAI;EAAO,SAAS;CAAgD;CAIxF,MAAM,SAAS,MAAM,aAAa,SAAS,QAAQ;CACnD,MAAM,OAAO,MAAM,aAAa,SAAS,OAAO;CAEhD,IAAI,CAAE,MAAM,mBAAmB,SAAS,QAAQ,GAC9C,OAAO;EACL,GAAG;EACH,IAAI;EACJ,SAAS,uBAAuB,SAAS;CAC3C;CAGF,IAAI,QAAQ,QACV,OAAO;EACL,GAAG;EACH,IAAI;EACJ,SAAS,yCAAyC,WAChD,QAAQ,OAAO,QAAQ,UAAU,iCAAiC,GACnE;CACH;CAGF,MAAM,cAAc,SAAS,YAAY,OAAO;CAChD,MAAM,cAAc,SAAS,WAAW,QAAQ;CAChD,MAAM,cAAc,SAAS;EAAE,GAAG;EAAM,QAAQ;CAAa,CAAC;CAC9D,MAAM,cAAc,SAAS;EAAE,GAAG;EAAQ,QAAQ;CAAS,CAAC;CAE5D,MAAM,YAAY,MAAM,QAAQ,SAAS,QAAQ;CAEjD,IAAI,CAAC,UAAU,IAAI;EACjB,MAAM,UAAU,0BAA0B,SAAS;EAEnD,MAAM,UAAU,SAAS;GAAE,OAAO;GAAY,SAAS;GAAU,IAAI;GAAO,QAAQ;EAAQ,CAAC;EAE7F,OAAO;GACL,GAAG;GACH,UAAU;GACV,WAAW;GACX,eAAe,UAAU;GACzB,IAAI;GACJ;EACF;CACF;CAEA,MAAM,UAAU,oBAAoB,QAAQ,MAAM,WAChD,UAAU,MAAM,iCAAiC,GAClD;CAED,MAAM,UAAU,SAAS;EAAE,OAAO;EAAY,SAAS;EAAU,IAAI;EAAM,QAAQ;CAAQ,CAAC;CAE5F,OAAO;EACL,GAAG;EACH,UAAU;EACV,WAAW,UAAU,MAAM,OAAO;EAClC,IAAI;EACJ;CACF;AACF"}
@@ -0,0 +1,107 @@
1
+ import { appendLog, releaseDir, releasesDir, writeManifest } from "./store.mjs";
2
+ import { createHash } from "node:crypto";
3
+ import path from "node:path";
4
+ import { access, mkdir, readFile, rm, symlink } from "node:fs/promises";
5
+
6
+ //#region ../../packages/core/src/release/candidate.ts
7
+ const LOCKFILES = [
8
+ "pnpm-lock.yaml",
9
+ "package-lock.json",
10
+ "yarn.lock",
11
+ "bun.lock",
12
+ "bun.lockb"
13
+ ];
14
+ function shellQuote(value) {
15
+ return `'${value.replace(/'/g, `'\\''`)}'`;
16
+ }
17
+ async function exists(file) {
18
+ try {
19
+ await access(file);
20
+ return true;
21
+ } catch {
22
+ return false;
23
+ }
24
+ }
25
+ async function git(context, command) {
26
+ const result = await context.runner(`git ${command}`, { cwd: context.root });
27
+ if (result.code !== 0) throw new Error(`git ${command} failed: ${result.output.trim() || `exit ${result.code}`}`);
28
+ return result.output.trim();
29
+ }
30
+ /**
31
+ * Freeze a commit into a candidate directory.
32
+ *
33
+ * The commit is exported with `git archive` into `<release>/source`, so every
34
+ * later step (gate, build, stage) works on exactly those bytes and not on a
35
+ * working tree that keeps changing. A dirty tree is refused unless
36
+ * `allowDirty` is set, because the candidate would not describe what is
37
+ * checked out.
38
+ *
39
+ * @example
40
+ * const manifest = await createCandidate(context, {});
41
+ */
42
+ async function createCandidate(context, options = {}) {
43
+ if (!options.allowDirty) {
44
+ const dirty = await git(context, `status --porcelain -- . ${shellQuote(`:(exclude)${context.config.directory}`)}`);
45
+ if (dirty) throw new Error(`The working tree has uncommitted changes:\n${dirty}\nCommit or stash them, or pass --allow-dirty.`);
46
+ }
47
+ const commit = await git(context, `rev-parse --verify ${shellQuote(`${options.commit ?? "HEAD"}^{commit}`)}`);
48
+ const packageText = await git(context, `show ${shellQuote(`${commit}:package.json`)}`);
49
+ const version = JSON.parse(packageText).version;
50
+ if (!version) throw new Error("package.json has no `version`; a release needs one.");
51
+ const id = `${version}-${commit.slice(0, 7)}`;
52
+ const directory = releaseDir(context, id);
53
+ if (await exists(directory)) throw new Error(`Release "${id}" already exists. Releases are never overwritten.`);
54
+ const source = path.join(directory, "source");
55
+ await mkdir(releasesDir(context), { recursive: true });
56
+ await mkdir(source, { recursive: true });
57
+ try {
58
+ const archive = path.join(directory, "source.tar");
59
+ await git(context, `archive --format=tar -o ${shellQuote(archive)} ${shellQuote(commit)}`);
60
+ const extracted = await context.runner(`tar -xf ${shellQuote(archive)} -C ${shellQuote(source)}`, { cwd: context.root });
61
+ await rm(archive, { force: true });
62
+ if (extracted.code !== 0) throw new Error(`Could not extract the commit archive: ${extracted.output.trim()}`);
63
+ if (context.config.linkNodeModules) {
64
+ const modules = path.join(context.root, "node_modules");
65
+ if (await exists(modules)) await symlink(modules, path.join(source, "node_modules"), "dir");
66
+ }
67
+ let lockfile = null;
68
+ for (const file of LOCKFILES) {
69
+ const location = path.join(source, file);
70
+ if (await exists(location)) {
71
+ lockfile = {
72
+ file,
73
+ sha256: createHash("sha256").update(await readFile(location)).digest("hex")
74
+ };
75
+ break;
76
+ }
77
+ }
78
+ const manifest = {
79
+ schema: 1,
80
+ id,
81
+ version,
82
+ commit,
83
+ createdAt: context.now().toISOString(),
84
+ nodeVersion: context.nodeVersion,
85
+ lockfile,
86
+ status: "candidate"
87
+ };
88
+ await writeManifest(context, manifest);
89
+ await appendLog(context, {
90
+ event: "candidate",
91
+ release: id,
92
+ ok: true,
93
+ detail: commit
94
+ });
95
+ return manifest;
96
+ } catch (error) {
97
+ await rm(directory, {
98
+ recursive: true,
99
+ force: true
100
+ });
101
+ throw error;
102
+ }
103
+ }
104
+
105
+ //#endregion
106
+ export { createCandidate, shellQuote };
107
+ //# sourceMappingURL=candidate.mjs.map