@tiangong-lca/cli 0.1.0 → 0.1.2

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 (159) hide show
  1. package/README.md +58 -6
  2. package/dist/src/batch.d.ts +6 -0
  3. package/dist/src/batch.js +6 -0
  4. package/dist/src/batch.js.map +1 -0
  5. package/dist/src/cli.d.ts +161 -0
  6. package/dist/src/cli.js +130 -0
  7. package/dist/src/cli.js.map +1 -1
  8. package/dist/src/command-spec.d.ts +90 -0
  9. package/dist/src/command-spec.js +400 -0
  10. package/dist/src/command-spec.js.map +1 -0
  11. package/dist/src/lib/artifacts.d.ts +9 -0
  12. package/dist/src/lib/auth-identity-receipt.d.ts +160 -0
  13. package/dist/src/lib/auth-identity-receipt.js +634 -0
  14. package/dist/src/lib/auth-identity-receipt.js.map +1 -0
  15. package/dist/src/lib/batch/attempt-recovery.d.ts +12 -0
  16. package/dist/src/lib/batch/attempt-recovery.js +183 -0
  17. package/dist/src/lib/batch/attempt-recovery.js.map +1 -0
  18. package/dist/src/lib/batch/canonical-contracts.d.ts +21 -0
  19. package/dist/src/lib/batch/canonical-contracts.js +180 -0
  20. package/dist/src/lib/batch/canonical-contracts.js.map +1 -0
  21. package/dist/src/lib/batch/engine.d.ts +2 -0
  22. package/dist/src/lib/batch/engine.js +294 -0
  23. package/dist/src/lib/batch/engine.js.map +1 -0
  24. package/dist/src/lib/batch/errors.d.ts +51 -0
  25. package/dist/src/lib/batch/errors.js +81 -0
  26. package/dist/src/lib/batch/errors.js.map +1 -0
  27. package/dist/src/lib/batch/item-projection.d.ts +10 -0
  28. package/dist/src/lib/batch/item-projection.js +118 -0
  29. package/dist/src/lib/batch/item-projection.js.map +1 -0
  30. package/dist/src/lib/batch/run-lock.d.ts +4 -0
  31. package/dist/src/lib/batch/run-lock.js +155 -0
  32. package/dist/src/lib/batch/run-lock.js.map +1 -0
  33. package/dist/src/lib/batch/scheduler-runtime.d.ts +29 -0
  34. package/dist/src/lib/batch/scheduler-runtime.js +114 -0
  35. package/dist/src/lib/batch/scheduler-runtime.js.map +1 -0
  36. package/dist/src/lib/batch/types.d.ts +183 -0
  37. package/dist/src/lib/batch/types.js +2 -0
  38. package/dist/src/lib/batch/types.js.map +1 -0
  39. package/dist/src/lib/dataset-author.d.ts +39 -0
  40. package/dist/src/lib/dataset-bilingual.d.ts +165 -0
  41. package/dist/src/lib/dataset-classification.d.ts +279 -0
  42. package/dist/src/lib/dataset-command.d.ts +53 -0
  43. package/dist/src/lib/dataset-contract.d.ts +82 -0
  44. package/dist/src/lib/dataset-curation-queue.d.ts +219 -0
  45. package/dist/src/lib/dataset-evidence-search.d.ts +134 -0
  46. package/dist/src/lib/dataset-import-lca.d.ts +136 -0
  47. package/dist/src/lib/dataset-local.d.ts +23 -0
  48. package/dist/src/lib/dataset-maintenance-alias-request.d.ts +12 -0
  49. package/dist/src/lib/dataset-maintenance-alias-rewrite.d.ts +111 -0
  50. package/dist/src/lib/dataset-maintenance-apply.d.ts +458 -0
  51. package/dist/src/lib/dataset-maintenance-clear-account.d.ts +161 -0
  52. package/dist/src/lib/dataset-maintenance-contract.d.ts +317 -0
  53. package/dist/src/lib/dataset-maintenance-derivatives.d.ts +48 -0
  54. package/dist/src/lib/dataset-maintenance-flow-identity-approval-claim.d.ts +50 -0
  55. package/dist/src/lib/dataset-maintenance-flow-identity-capture.d.ts +110 -0
  56. package/dist/src/lib/dataset-maintenance-flow-identity-command.d.ts +15 -0
  57. package/dist/src/lib/dataset-maintenance-flow-identity-contract.d.ts +387 -0
  58. package/dist/src/lib/dataset-maintenance-flow-identity-execution-contract.d.ts +456 -0
  59. package/dist/src/lib/dataset-maintenance-flow-identity-freeze.d.ts +99 -0
  60. package/dist/src/lib/dataset-maintenance-flow-identity-plan.d.ts +85 -0
  61. package/dist/src/lib/dataset-maintenance-flow-identity-recovery.d.ts +268 -0
  62. package/dist/src/lib/dataset-maintenance-flow-identity-run.d.ts +123 -0
  63. package/dist/src/lib/dataset-maintenance-flow-identity-seal.d.ts +50 -0
  64. package/dist/src/lib/dataset-maintenance-flow-identity-verify.d.ts +85 -0
  65. package/dist/src/lib/dataset-maintenance-flow-identity-wire.d.ts +32 -0
  66. package/dist/src/lib/dataset-maintenance-pagination.d.ts +58 -0
  67. package/dist/src/lib/dataset-maintenance-plan.d.ts +40 -0
  68. package/dist/src/lib/dataset-maintenance-protected-artifacts.d.ts +16 -0
  69. package/dist/src/lib/dataset-maintenance-protected-before.d.ts +71 -0
  70. package/dist/src/lib/dataset-maintenance-protected-contract.d.ts +385 -0
  71. package/dist/src/lib/dataset-maintenance-protected-freeze.d.ts +148 -0
  72. package/dist/src/lib/dataset-maintenance-protected-preparation.d.ts +76 -0
  73. package/dist/src/lib/dataset-maintenance-protected-run.d.ts +252 -0
  74. package/dist/src/lib/dataset-maintenance-protected-seal.d.ts +93 -0
  75. package/dist/src/lib/dataset-maintenance-protected-toolchain.d.ts +31 -0
  76. package/dist/src/lib/dataset-maintenance-protected-verify.d.ts +99 -0
  77. package/dist/src/lib/dataset-maintenance-remote.d.ts +212 -0
  78. package/dist/src/lib/dataset-maintenance-support-validation.d.ts +18 -0
  79. package/dist/src/lib/dataset-maintenance-verify.d.ts +102 -0
  80. package/dist/src/lib/dataset-patch.d.ts +193 -0
  81. package/dist/src/lib/dataset-references-rewrite.d.ts +77 -0
  82. package/dist/src/lib/dataset-remote-refresh.d.ts +64 -0
  83. package/dist/src/lib/dataset-remote-verify.d.ts +168 -0
  84. package/dist/src/lib/dataset-save-draft-run.d.ts +283 -0
  85. package/dist/src/lib/dataset-save-draft-run.js +54 -21
  86. package/dist/src/lib/dataset-save-draft-run.js.map +1 -1
  87. package/dist/src/lib/dataset-source-upload-attachments.d.ts +109 -0
  88. package/dist/src/lib/dataset-validate.d.ts +62 -0
  89. package/dist/src/lib/dotenv.d.ts +6 -0
  90. package/dist/src/lib/env.d.ts +59 -0
  91. package/dist/src/lib/errors.d.ts +18 -0
  92. package/dist/src/lib/flow-build-alias-map.d.ts +80 -0
  93. package/dist/src/lib/flow-fetch-rows.d.ts +70 -0
  94. package/dist/src/lib/flow-get.d.ts +35 -0
  95. package/dist/src/lib/flow-governance.d.ts +22 -0
  96. package/dist/src/lib/flow-list.d.ts +57 -0
  97. package/dist/src/lib/flow-materialize-decisions.d.ts +67 -0
  98. package/dist/src/lib/flow-payload-validation.d.ts +32 -0
  99. package/dist/src/lib/flow-publish-reviewed-data.d.ts +262 -0
  100. package/dist/src/lib/flow-publish-version.d.ts +193 -0
  101. package/dist/src/lib/flow-qa.d.ts +289 -0
  102. package/dist/src/lib/flow-read.d.ts +70 -0
  103. package/dist/src/lib/flow-regen-product.d.ts +431 -0
  104. package/dist/src/lib/flow-remediate.d.ts +133 -0
  105. package/dist/src/lib/http.d.ts +25 -0
  106. package/dist/src/lib/http.js.map +1 -1
  107. package/dist/src/lib/identity-preflight.d.ts +235 -0
  108. package/dist/src/lib/io.d.ts +2 -0
  109. package/dist/src/lib/kb-search.d.ts +23 -0
  110. package/dist/src/lib/lca-release.d.ts +105 -0
  111. package/dist/src/lib/lifecyclemodel-auto-build.d.ts +223 -0
  112. package/dist/src/lib/lifecyclemodel-bundle-save.d.ts +71 -0
  113. package/dist/src/lib/lifecyclemodel-graph.d.ts +91 -0
  114. package/dist/src/lib/lifecyclemodel-orchestrate.d.ts +349 -0
  115. package/dist/src/lib/lifecyclemodel-publish-build.d.ts +77 -0
  116. package/dist/src/lib/lifecyclemodel-publish-resulting-process.d.ts +27 -0
  117. package/dist/src/lib/lifecyclemodel-qa.d.ts +206 -0
  118. package/dist/src/lib/lifecyclemodel-resulting-process.d.ts +204 -0
  119. package/dist/src/lib/lifecyclemodel-save-draft-run.d.ts +96 -0
  120. package/dist/src/lib/lifecyclemodel-validate-build.d.ts +78 -0
  121. package/dist/src/lib/llm.d.ts +51 -0
  122. package/dist/src/lib/package-version.d.ts +3 -0
  123. package/dist/src/lib/process-auto-build.d.ts +168 -0
  124. package/dist/src/lib/process-batch-build.d.ts +97 -0
  125. package/dist/src/lib/process-dedup-review.d.ts +253 -0
  126. package/dist/src/lib/process-flow-build-plan.d.ts +108 -0
  127. package/dist/src/lib/process-get.d.ts +26 -0
  128. package/dist/src/lib/process-list.d.ts +87 -0
  129. package/dist/src/lib/process-payload-validation.d.ts +27 -0
  130. package/dist/src/lib/process-publish-build.d.ts +148 -0
  131. package/dist/src/lib/process-qa.d.ts +243 -0
  132. package/dist/src/lib/process-refresh-references.d.ts +179 -0
  133. package/dist/src/lib/process-required-fields.d.ts +142 -0
  134. package/dist/src/lib/process-resume-build.d.ts +77 -0
  135. package/dist/src/lib/process-save-draft-run.d.ts +72 -0
  136. package/dist/src/lib/process-save-draft.d.ts +53 -0
  137. package/dist/src/lib/process-scope-statistics.d.ts +210 -0
  138. package/dist/src/lib/process-verify-rows.d.ts +71 -0
  139. package/dist/src/lib/publish.d.ts +219 -0
  140. package/dist/src/lib/remote.d.ts +19 -0
  141. package/dist/src/lib/run.d.ts +60 -0
  142. package/dist/src/lib/runtime-rulesets.d.ts +29 -0
  143. package/dist/src/lib/state-lock.d.ts +25 -0
  144. package/dist/src/lib/state-lock.js +23 -1
  145. package/dist/src/lib/state-lock.js.map +1 -1
  146. package/dist/src/lib/supabase-client.d.ts +47 -0
  147. package/dist/src/lib/supabase-data-api-contract.d.ts +304 -0
  148. package/dist/src/lib/supabase-data-api-replay.d.ts +74 -0
  149. package/dist/src/lib/supabase-json-ordered-write.d.ts +65 -0
  150. package/dist/src/lib/supabase-rest.d.ts +26 -0
  151. package/dist/src/lib/supabase-session.d.ts +115 -0
  152. package/dist/src/lib/tidas-languages.d.ts +3 -0
  153. package/dist/src/lib/tidas-sdk-package-validator.d.ts +111 -0
  154. package/dist/src/lib/tidas-sdk-validation.d.ts +42 -0
  155. package/dist/src/lib/unstructured.d.ts +32 -0
  156. package/dist/src/lib/user-api-key.d.ts +16 -0
  157. package/dist/src/lib/validation.d.ts +82 -0
  158. package/dist/src/main.d.ts +4 -0
  159. package/package.json +17 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-identity-receipt.js","sourceRoot":"","sources":["../../../src/lib/auth-identity-receipt.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\nimport { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n deriveSupabaseProjectBaseUrl,\n requireSupabaseRestRuntime,\n type SupabaseRestRuntime,\n} from './supabase-client.js';\nimport {\n resolveSupabaseUserSession,\n type ResolvedSupabaseUserSession,\n} from './supabase-session.js';\nimport { redactEmail, requireUserApiKeyCredentials } from './user-api-key.js';\n\nexport const AUTH_IDENTITY_RECEIPT_SCHEMA = 'tiangong-lca.auth-identity-receipt.v1' as const;\nexport const AUTH_IDENTITY_MAX_TIMEOUT_MS = 2_147_483_647;\n\nconst CLI_PACKAGE_NAME = '@tiangong-lca/cli' as const;\nconst CURRENT_USER_PATH = '/auth/v1/user' as const;\nconst DEFAULT_TIMEOUT_MS = 10_000;\nconst MAX_RESPONSE_BYTES = 64 * 1024;\nconst SESSION_REFRESH_WINDOW_SECONDS = 300;\nconst SHA256_PATTERN = /^[0-9a-f]{64}$/u;\nconst UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;\nconst EMAIL_PATTERN = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/u;\nconst SESSION_SOURCES = ['memory', 'cache', 'refresh', 'signin'] as const;\nconst CACHE_MODES = ['disabled', 'custom-file', 'platform-default'] as const;\n\ntype SessionSource = (typeof SESSION_SOURCES)[number];\ntype CacheMode = (typeof CACHE_MODES)[number];\ntype JsonObject = Record<string, unknown>;\n\nclass ResponseBodyTooLargeError extends Error {\n constructor() {\n super('Response body exceeded the identity receipt byte limit.');\n this.name = 'ResponseBodyTooLargeError';\n }\n}\n\nexport type AuthIdentityReceiptScope = {\n schema: typeof AUTH_IDENTITY_RECEIPT_SCHEMA;\n status: 'passed';\n operation: 'current-user-read';\n remote_write_mode: 'read-only';\n captured_at_utc: string;\n cli: {\n package_name: typeof CLI_PACKAGE_NAME;\n package_version: string;\n };\n project: {\n project_ref: string;\n project_base_url: string;\n };\n identity: {\n user_id: string;\n display_email: string;\n };\n session: {\n source: SessionSource;\n cache_mode: CacheMode;\n force_reauth: boolean;\n expires_at_utc: string | null;\n };\n bindings: {\n request_sha256: string;\n response_sha256: string;\n };\n assertions: {\n mode: 'observed' | 'partial' | 'intent-bound';\n requested_count: 0 | 1 | 2;\n expected_project_ref: string | null;\n expected_user_id: string | null;\n project_ref_passed: true | null;\n user_id_passed: true | null;\n passed: true;\n };\n};\n\nexport type AuthIdentityReceipt = AuthIdentityReceiptScope & {\n receipt_scope_sha256: string;\n};\n\nexport type ResolveAuthIdentitySession = (options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs?: number;\n now?: Date;\n forceRefresh?: boolean;\n}) => Promise<ResolvedSupabaseUserSession>;\n\nexport type RunAuthIdentityReceiptOptions = {\n env: NodeJS.ProcessEnv;\n fetchImpl: FetchLike;\n cliVersion: string;\n expectedProjectRef?: string | null;\n expectedUserId?: string | null;\n timeoutMs?: number;\n now?: Date;\n resolveSessionImpl?: ResolveAuthIdentitySession;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stableJsonValue(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map(stableJsonValue);\n }\n if (isRecord(value)) {\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [key, stableJsonValue(value[key])]),\n );\n }\n return value;\n}\n\nfunction sha256Json(value: unknown): string {\n return createHash('sha256')\n .update(JSON.stringify(stableJsonValue(value)))\n .digest('hex');\n}\n\nfunction token(value: unknown): string | null {\n if (typeof value !== 'string') {\n return null;\n }\n const normalized = value.trim();\n return normalized || null;\n}\n\nfunction normalizeEmail(value: unknown): string | null {\n const normalized = token(value)?.toLowerCase() ?? null;\n if (!normalized || normalized.length > 254 || !EMAIL_PATTERN.test(normalized)) {\n return null;\n }\n return normalized;\n}\n\nfunction isCanonicalUuid(value: unknown): value is string {\n return typeof value === 'string' && UUID_PATTERN.test(value);\n}\n\nfunction identityError(\n message: string,\n code: string,\n options: { exitCode?: number; details?: unknown } = {},\n): never {\n throw new CliError(message, {\n code,\n exitCode: options.exitCode ?? 1,\n ...(options.details === undefined ? {} : { details: options.details }),\n });\n}\n\nfunction receiptInvalid(message: string): never {\n return identityError(message, 'AUTH_IDENTITY_RECEIPT_INVALID');\n}\n\nfunction normalizeExpectation(value: string | null | undefined, label: string): string | null {\n if (value === null || value === undefined) {\n return null;\n }\n const normalized = token(value);\n if (!normalized) {\n return identityError(\n `${label} must be a non-empty string when provided.`,\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n {\n exitCode: 2,\n details: { option: label },\n },\n );\n }\n return normalized;\n}\n\nfunction normalizeExpectedUserId(value: string | null | undefined): string | null {\n const normalized = normalizeExpectation(value, '--expected-user-id');\n if (normalized !== null && !isCanonicalUuid(normalized)) {\n return identityError(\n '--expected-user-id must be a canonical lowercase UUID.',\n 'AUTH_IDENTITY_EXPECTATION_INVALID',\n { exitCode: 2, details: { option: '--expected-user-id' } },\n );\n }\n return normalized;\n}\n\nfunction normalizeTimeoutMs(value: number | undefined): number {\n const normalized = value ?? DEFAULT_TIMEOUT_MS;\n if (\n !Number.isInteger(normalized) ||\n normalized <= 0 ||\n normalized > AUTH_IDENTITY_MAX_TIMEOUT_MS\n ) {\n return identityError(\n `Auth identity timeout must be an integer between 1 and ${AUTH_IDENTITY_MAX_TIMEOUT_MS}.`,\n 'AUTH_IDENTITY_TIMEOUT_INVALID',\n { exitCode: 2 },\n );\n }\n return normalized;\n}\n\nfunction canonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') {\n return false;\n }\n const timestamp = new Date(value);\n return !Number.isNaN(timestamp.getTime()) && timestamp.toISOString() === value;\n}\n\nfunction canonicalProjectIdentity(\n projectBaseUrl: unknown,\n): { projectBaseUrl: string; projectRef: string } | null {\n const normalized = token(projectBaseUrl);\n if (!normalized || normalized !== projectBaseUrl) {\n return null;\n }\n try {\n const url = new URL(normalized);\n const suffix = '.supabase.co';\n const hostname = url.hostname.toLowerCase();\n const projectRef = hostname.endsWith(suffix) ? hostname.slice(0, -suffix.length) : '';\n if (\n url.protocol !== 'https:' ||\n url.origin !== normalized ||\n url.username ||\n url.password ||\n url.port ||\n !projectRef ||\n projectRef.includes('.') ||\n !/^[a-z0-9-]+$/u.test(projectRef)\n ) {\n return null;\n }\n return { projectBaseUrl: url.origin, projectRef };\n } catch {\n return null;\n }\n}\n\nfunction projectRefFromBaseUrl(projectBaseUrl: string): string {\n const identity = canonicalProjectIdentity(projectBaseUrl);\n if (!identity) {\n return identityError(\n 'The Supabase project URL did not contain a project identity.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n return identity.projectRef;\n}\n\nfunction resolveProjectIdentity(apiBaseUrl: string): {\n projectBaseUrl: string;\n projectRef: string;\n} {\n let projectBaseUrl: string;\n try {\n projectBaseUrl = deriveSupabaseProjectBaseUrl(apiBaseUrl);\n } catch {\n return identityError(\n 'TIANGONG_LCA_API_BASE_URL must identify a canonical Supabase project.',\n 'AUTH_IDENTITY_PROJECT_INVALID',\n { exitCode: 2 },\n );\n }\n const projectRef = projectRefFromBaseUrl(projectBaseUrl);\n return { projectBaseUrl, projectRef };\n}\n\nfunction cacheMode(runtime: SupabaseRestRuntime): CacheMode {\n if (runtime.disableSessionCache) {\n return 'disabled';\n }\n return runtime.sessionFile ? 'custom-file' : 'platform-default';\n}\n\nfunction sessionExpiresAtUtc(expiresAt: number | null): string | null {\n if (expiresAt === null) {\n return null;\n }\n if (!Number.isFinite(expiresAt)) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n const timestamp = new Date(Math.floor(expiresAt) * 1000);\n if (Number.isNaN(timestamp.getTime())) {\n return identityError(\n 'Resolved auth session contained an invalid expiry.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n return timestamp.toISOString();\n}\n\nfunction assertSessionBinding(options: {\n runtime: SupabaseRestRuntime;\n session: ResolvedSupabaseUserSession;\n projectBaseUrl: string;\n apiKeyEmail: string;\n now: Date;\n}): void {\n const { runtime, session } = options;\n const sessionEmail = normalizeEmail(session.userEmail);\n const apiKeyEmail = normalizeEmail(options.apiKeyEmail);\n const accessToken = token(session.accessToken);\n const source = session.source as string;\n const expectedMode = cacheMode(runtime);\n const customSessionPath = runtime.sessionFile ? path.resolve(runtime.sessionFile) : null;\n const sessionPath = session.sessionFile ? path.resolve(session.sessionFile) : null;\n const cachePathMatches =\n expectedMode === 'disabled'\n ? sessionPath === null\n : expectedMode === 'custom-file'\n ? sessionPath === customSessionPath\n : sessionPath !== null;\n const cacheSourceFresh =\n !['memory', 'cache'].includes(source) ||\n (typeof session.expiresAt === 'number' &&\n Number.isFinite(session.expiresAt) &&\n session.expiresAt >\n Math.floor(options.now.getTime() / 1000) + SESSION_REFRESH_WINDOW_SECONDS);\n\n if (\n !accessToken ||\n session.projectBaseUrl !== options.projectBaseUrl ||\n !sessionEmail ||\n !apiKeyEmail ||\n sessionEmail !== apiKeyEmail ||\n !SESSION_SOURCES.includes(session.source) ||\n !cachePathMatches ||\n !cacheSourceFresh ||\n (runtime.forceReauth && ['memory', 'cache'].includes(source))\n ) {\n identityError(\n 'Resolved auth session does not match the requested credential, project, or cache boundary.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n}\n\nasync function resolveBoundSession(options: {\n runtime: SupabaseRestRuntime;\n fetchImpl: FetchLike;\n timeoutMs: number;\n now: Date;\n forceRefresh?: boolean;\n resolveSessionImpl: ResolveAuthIdentitySession;\n}): Promise<ResolvedSupabaseUserSession> {\n try {\n return await options.resolveSessionImpl({\n runtime: options.runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs: options.timeoutMs,\n now: options.now,\n forceRefresh: options.forceRefresh,\n });\n } catch (error) {\n const causeCode =\n error instanceof CliError\n ? error.code\n : isRecord(error) && typeof error.code === 'string'\n ? error.code\n : 'UNEXPECTED_SESSION_FAILURE';\n return identityError(\n 'Failed to resolve the authenticated user session.',\n 'AUTH_IDENTITY_SESSION_FAILED',\n { details: { cause_code: causeCode } },\n );\n }\n}\n\nfunction currentUserFailureStatus(error: unknown): number | null {\n if (\n !(error instanceof CliError) ||\n error.code !== 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED' ||\n !isRecord(error.details) ||\n typeof error.details.status !== 'number' ||\n !Number.isInteger(error.details.status)\n ) {\n return null;\n }\n return error.details.status;\n}\n\nfunction declaredResponseBytes(response: {\n headers: { get(name: string): string | null };\n}): number | null {\n const value = response.headers.get('content-length')?.trim() ?? '';\n if (!/^\\d+$/u.test(value)) {\n return null;\n }\n return Number(value);\n}\n\nasync function readBoundedResponseText(response: {\n body?: ReadableStream<Uint8Array> | null;\n headers: { get(name: string): string | null };\n text(): Promise<string>;\n}): Promise<string> {\n const declaredBytes = declaredResponseBytes(response);\n if (declaredBytes !== null && declaredBytes > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n if (!response.body) {\n const text = await response.text();\n if (Buffer.byteLength(text, 'utf8') > MAX_RESPONSE_BYTES) {\n throw new ResponseBodyTooLargeError();\n }\n return text;\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let observedBytes = 0;\n let text = '';\n try {\n while (true) {\n const chunk = await reader.read();\n if (chunk.done) {\n break;\n }\n observedBytes += chunk.value.byteLength;\n if (observedBytes > MAX_RESPONSE_BYTES) {\n await Promise.allSettled([reader.cancel()]);\n throw new ResponseBodyTooLargeError();\n }\n text += decoder.decode(chunk.value, { stream: true });\n }\n text += decoder.decode();\n return text;\n } finally {\n reader.releaseLock();\n }\n}\n\nasync function fetchCurrentUser(options: {\n projectBaseUrl: string;\n publishableKey: string;\n accessToken: string;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ userId: string; email: string }> {\n const url = `${options.projectBaseUrl}${CURRENT_USER_PATH}`;\n let response;\n try {\n response = await options.fetchImpl(url, {\n method: 'GET',\n headers: buildSupabaseAuthHeaders(options.publishableKey, options.accessToken),\n redirect: 'error',\n signal: AbortSignal.timeout(options.timeoutMs),\n });\n } catch (error) {\n return identityError(\n 'Authenticated current-user lookup failed before a response was received.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n if (!response.ok) {\n return identityError(\n `Authenticated current-user lookup returned HTTP ${response.status}.`,\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const contentType = response.headers.get('content-type')?.toLowerCase() ?? '';\n if (!contentType.includes('application/json')) {\n return identityError(\n 'Authenticated current-user response did not declare JSON content.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n\n let text: string;\n try {\n text = await readBoundedResponseText(response);\n } catch (error) {\n if (error instanceof ResponseBodyTooLargeError) {\n return identityError(\n 'Authenticated current-user response exceeded the bounded receipt limit.',\n 'AUTH_IDENTITY_RESPONSE_TOO_LARGE',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return identityError(\n 'Authenticated current-user response could not be read.',\n 'AUTH_IDENTITY_REMOTE_REQUEST_FAILED',\n {\n details: {\n endpoint: CURRENT_USER_PATH,\n status: response.status,\n cause: error instanceof Error ? error.name : typeof error,\n },\n },\n );\n }\n\n let payload: unknown;\n try {\n payload = JSON.parse(text);\n } catch {\n return identityError(\n 'Authenticated current-user response was not valid JSON.',\n 'AUTH_IDENTITY_REMOTE_INVALID_JSON',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n if (isRecord(payload) && payload.ok === false) {\n return identityError(\n 'Authenticated current-user response explicitly reported ok:false.',\n 'AUTH_IDENTITY_REMOTE_REJECTED',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n const userId = isRecord(payload) && isCanonicalUuid(payload.id) ? payload.id : null;\n const email = isRecord(payload) ? normalizeEmail(payload.email) : null;\n if (!userId || !email) {\n return identityError(\n 'Authenticated current-user response did not contain a valid id and email.',\n 'AUTH_IDENTITY_RESPONSE_INVALID',\n { details: { endpoint: CURRENT_USER_PATH, status: response.status } },\n );\n }\n return { userId, email };\n}\n\nfunction requestFingerprint(projectRef: string): string {\n return sha256Json({\n method: 'GET',\n path: CURRENT_USER_PATH,\n project_ref: projectRef,\n redirect: 'error',\n header_names: ['accept', 'apikey', 'authorization'],\n });\n}\n\nfunction responseFingerprint(options: {\n projectRef: string;\n userId: string;\n displayEmail: string;\n}): string {\n return sha256Json({\n project_ref: options.projectRef,\n user_id: options.userId,\n display_email: options.displayEmail,\n });\n}\n\nfunction hasExactKeys(value: JsonObject, expected: readonly string[]): boolean {\n const actual = Object.keys(value).sort();\n const sortedExpected = [...expected].sort();\n return (\n actual.length === sortedExpected.length &&\n actual.every((key, index) => key === sortedExpected[index])\n );\n}\n\nfunction isOneOf<T extends string>(value: unknown, values: readonly T[]): value is T {\n return typeof value === 'string' && values.includes(value as T);\n}\n\nfunction isCanonicalToken(value: unknown): value is string {\n return typeof value === 'string' && token(value) === value;\n}\n\nfunction isMaskedEmail(value: unknown): value is string {\n return isCanonicalToken(value) && /^(?:[^*@\\s]{2})?\\*{4}@[^@\\s]+\\.[^@\\s]+$/u.test(value);\n}\n\nfunction receiptScope(receipt: AuthIdentityReceipt): AuthIdentityReceiptScope {\n const { receipt_scope_sha256: _receiptScopeSha256, ...scope } = receipt;\n return scope;\n}\n\nexport function parseAuthIdentityReceipt(value: unknown): AuthIdentityReceipt {\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n 'assertions',\n 'bindings',\n 'captured_at_utc',\n 'cli',\n 'identity',\n 'operation',\n 'project',\n 'receipt_scope_sha256',\n 'remote_write_mode',\n 'schema',\n 'session',\n 'status',\n ])\n ) {\n return receiptInvalid('Auth identity receipt must be an exact object.');\n }\n\n const cli = value.cli;\n const project = value.project;\n const identity = value.identity;\n const session = value.session;\n const bindings = value.bindings;\n const assertions = value.assertions;\n const parsedProject =\n isRecord(project) && typeof project.project_base_url === 'string'\n ? canonicalProjectIdentity(project.project_base_url)\n : null;\n if (\n value.schema !== AUTH_IDENTITY_RECEIPT_SCHEMA ||\n value.status !== 'passed' ||\n value.operation !== 'current-user-read' ||\n value.remote_write_mode !== 'read-only' ||\n !canonicalTimestamp(value.captured_at_utc) ||\n !isRecord(cli) ||\n !hasExactKeys(cli, ['package_name', 'package_version']) ||\n cli.package_name !== CLI_PACKAGE_NAME ||\n !isCanonicalToken(cli.package_version) ||\n !isRecord(project) ||\n !hasExactKeys(project, ['project_base_url', 'project_ref']) ||\n !isCanonicalToken(project.project_ref) ||\n !parsedProject ||\n parsedProject.projectRef !== project.project_ref ||\n !isRecord(identity) ||\n !hasExactKeys(identity, ['display_email', 'user_id']) ||\n !isCanonicalUuid(identity.user_id) ||\n !isMaskedEmail(identity.display_email) ||\n !isRecord(session) ||\n !hasExactKeys(session, ['cache_mode', 'expires_at_utc', 'force_reauth', 'source']) ||\n !isOneOf(session.source, SESSION_SOURCES) ||\n !isOneOf(session.cache_mode, CACHE_MODES) ||\n typeof session.force_reauth !== 'boolean' ||\n !(session.expires_at_utc === null || canonicalTimestamp(session.expires_at_utc)) ||\n !isRecord(bindings) ||\n !hasExactKeys(bindings, ['request_sha256', 'response_sha256']) ||\n typeof bindings.request_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.request_sha256) ||\n typeof bindings.response_sha256 !== 'string' ||\n !SHA256_PATTERN.test(bindings.response_sha256) ||\n bindings.request_sha256 !== requestFingerprint(project.project_ref as string) ||\n bindings.response_sha256 !==\n responseFingerprint({\n projectRef: project.project_ref as string,\n userId: identity.user_id as string,\n displayEmail: identity.display_email as string,\n }) ||\n !isRecord(assertions) ||\n !hasExactKeys(assertions, [\n 'expected_project_ref',\n 'expected_user_id',\n 'mode',\n 'passed',\n 'project_ref_passed',\n 'requested_count',\n 'user_id_passed',\n ]) ||\n !isOneOf(assertions.mode, ['observed', 'partial', 'intent-bound'] as const) ||\n ![0, 1, 2].includes(assertions.requested_count as number) ||\n !(\n assertions.expected_project_ref === null || isCanonicalToken(assertions.expected_project_ref)\n ) ||\n !(assertions.expected_user_id === null || isCanonicalUuid(assertions.expected_user_id)) ||\n !(assertions.project_ref_passed === true || assertions.project_ref_passed === null) ||\n !(assertions.user_id_passed === true || assertions.user_id_passed === null) ||\n assertions.passed !== true ||\n (assertions.expected_project_ref === null) !== (assertions.project_ref_passed === null) ||\n (assertions.expected_user_id === null) !== (assertions.user_id_passed === null) ||\n assertions.requested_count !==\n Number(assertions.expected_project_ref !== null) +\n Number(assertions.expected_user_id !== null) ||\n assertions.mode !==\n (assertions.requested_count === 0\n ? 'observed'\n : assertions.requested_count === 2\n ? 'intent-bound'\n : 'partial') ||\n (assertions.expected_project_ref !== null &&\n assertions.expected_project_ref !== project.project_ref) ||\n (assertions.expected_user_id !== null && assertions.expected_user_id !== identity.user_id) ||\n typeof value.receipt_scope_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.receipt_scope_sha256)\n ) {\n return receiptInvalid('Auth identity receipt failed schema validation.');\n }\n\n const receipt = value as AuthIdentityReceipt;\n if (receipt.receipt_scope_sha256 !== sha256Json(receiptScope(receipt))) {\n return receiptInvalid('Auth identity receipt canonical scope hash does not match.');\n }\n return receipt;\n}\n\nexport async function runAuthIdentityReceipt(\n options: RunAuthIdentityReceiptOptions,\n): Promise<AuthIdentityReceipt> {\n const timeoutMs = normalizeTimeoutMs(options.timeoutMs);\n const expectedProjectRef = normalizeExpectation(\n options.expectedProjectRef,\n '--expected-project-ref',\n );\n const expectedUserId = normalizeExpectedUserId(options.expectedUserId);\n const cliVersion = token(options.cliVersion);\n if (!cliVersion) {\n return identityError(\n 'CLI package version is required for an identity receipt.',\n 'AUTH_IDENTITY_VERSION_INVALID',\n { exitCode: 2 },\n );\n }\n const now = options.now ?? new Date();\n if (Number.isNaN(now.getTime())) {\n return identityError(\n 'Identity receipt capture time is invalid.',\n 'AUTH_IDENTITY_CAPTURE_TIME_INVALID',\n { exitCode: 2 },\n );\n }\n\n const runtime = requireSupabaseRestRuntime(options.env);\n const { projectBaseUrl, projectRef } = resolveProjectIdentity(runtime.apiBaseUrl);\n if (expectedProjectRef !== null && expectedProjectRef !== projectRef) {\n return identityError(\n 'Authenticated project does not match --expected-project-ref.',\n 'AUTH_IDENTITY_PROJECT_MISMATCH',\n { details: { expected_project_ref: expectedProjectRef, observed_project_ref: projectRef } },\n );\n }\n const credentials = requireUserApiKeyCredentials(runtime.userApiKey);\n\n let session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n apiKeyEmail: credentials.email,\n now,\n });\n\n let currentUser: Awaited<ReturnType<typeof fetchCurrentUser>>;\n try {\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n } catch (error) {\n const status = currentUserFailureStatus(error);\n if (status === null || ![401, 403].includes(status)) {\n throw error;\n }\n session = await resolveBoundSession({\n runtime,\n fetchImpl: options.fetchImpl,\n timeoutMs,\n now,\n forceRefresh: true,\n resolveSessionImpl: options.resolveSessionImpl ?? resolveSupabaseUserSession,\n });\n assertSessionBinding({\n runtime,\n session,\n projectBaseUrl,\n apiKeyEmail: credentials.email,\n now,\n });\n currentUser = await fetchCurrentUser({\n projectBaseUrl,\n publishableKey: runtime.publishableKey,\n accessToken: session.accessToken,\n timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n }\n const sessionEmail = normalizeEmail(session.userEmail);\n const apiKeyEmail = normalizeEmail(credentials.email);\n if (\n !sessionEmail ||\n !apiKeyEmail ||\n currentUser.email !== sessionEmail ||\n currentUser.email !== apiKeyEmail\n ) {\n return identityError(\n 'Server-verified current user does not match the API-key and session identity.',\n 'AUTH_IDENTITY_SESSION_MISMATCH',\n );\n }\n if (expectedUserId !== null && expectedUserId !== currentUser.userId) {\n return identityError(\n 'Authenticated user does not match --expected-user-id.',\n 'AUTH_IDENTITY_USER_MISMATCH',\n { details: { expected_user_id: expectedUserId, observed_user_id: currentUser.userId } },\n );\n }\n\n const displayEmail = redactEmail(currentUser.email);\n const requestedAssertionCount =\n Number(expectedProjectRef !== null) + Number(expectedUserId !== null);\n const scope: AuthIdentityReceiptScope = {\n schema: AUTH_IDENTITY_RECEIPT_SCHEMA,\n status: 'passed',\n operation: 'current-user-read',\n remote_write_mode: 'read-only',\n captured_at_utc: now.toISOString(),\n cli: {\n package_name: CLI_PACKAGE_NAME,\n package_version: cliVersion,\n },\n project: {\n project_ref: projectRef,\n project_base_url: projectBaseUrl,\n },\n identity: {\n user_id: currentUser.userId,\n display_email: displayEmail,\n },\n session: {\n source: session.source,\n cache_mode: cacheMode(runtime),\n force_reauth: runtime.forceReauth,\n expires_at_utc: sessionExpiresAtUtc(session.expiresAt),\n },\n bindings: {\n request_sha256: requestFingerprint(projectRef),\n response_sha256: responseFingerprint({\n projectRef,\n userId: currentUser.userId,\n displayEmail,\n }),\n },\n assertions: {\n mode:\n requestedAssertionCount === 0\n ? 'observed'\n : requestedAssertionCount === 2\n ? 'intent-bound'\n : 'partial',\n requested_count: requestedAssertionCount as 0 | 1 | 2,\n expected_project_ref: expectedProjectRef,\n expected_user_id: expectedUserId,\n project_ref_passed: expectedProjectRef === null ? null : true,\n user_id_passed: expectedUserId === null ? null : true,\n passed: true,\n },\n };\n return parseAuthIdentityReceipt({\n ...scope,\n receipt_scope_sha256: sha256Json(scope),\n });\n}\n\nexport const __testInternals = {\n MAX_RESPONSE_BYTES,\n assertSessionBinding,\n cacheMode,\n canonicalTimestamp,\n canonicalProjectIdentity,\n currentUserFailureStatus,\n declaredResponseBytes,\n fetchCurrentUser,\n hasExactKeys,\n isCanonicalToken,\n isCanonicalUuid,\n isMaskedEmail,\n isOneOf,\n normalizeEmail,\n normalizeExpectation,\n normalizeExpectedUserId,\n normalizeTimeoutMs,\n projectRefFromBaseUrl,\n readBoundedResponseText,\n requestFingerprint,\n responseFingerprint,\n resolveProjectIdentity,\n sessionExpiresAtUtc,\n sha256Json,\n stableJsonValue,\n token,\n};\n"]}
@@ -0,0 +1,12 @@
1
+ import { type EventEmitter } from './scheduler-runtime.js';
2
+ import type { BatchClock, BatchItemContract, BatchItemResult, BatchJsonValue, BatchResumeItem, BatchSleep, RunBoundedBatchOptions } from './types.js';
3
+ export declare function executeClaim<TInput, TOutput, TIdentity extends BatchJsonValue, TExclusiveKey extends string>(input: {
4
+ options: RunBoundedBatchOptions<TInput, TOutput, TIdentity, TExclusiveKey>;
5
+ index: number;
6
+ itemContract: BatchItemContract;
7
+ exclusiveKey: TExclusiveKey | null;
8
+ resumeItem: BatchResumeItem<TOutput> | undefined;
9
+ clock: BatchClock;
10
+ sleep: BatchSleep;
11
+ emitter: EventEmitter;
12
+ }): Promise<BatchItemResult<TInput, TOutput>>;
@@ -0,0 +1,183 @@
1
+ import { MAX_NODE_TIMER_DELAY_MS } from './canonical-contracts.js';
2
+ import { BatchContractError, BatchMutationReplayError } from './errors.js';
3
+ import { failedResult, freezeResult, readClock } from './scheduler-runtime.js';
4
+ export async function executeClaim(input) {
5
+ const { options, index, itemContract, exclusiveKey, resumeItem, clock, sleep, emitter } = input;
6
+ const itemId = itemContract.item_id;
7
+ const item = options.items[index];
8
+ const resumed = resumeItem?.state === 'attempted';
9
+ const baseAttempts = resumed ? resumeItem.attempts : 0;
10
+ if (resumed && options.mode === 'mutation') {
11
+ const error = new BatchMutationReplayError(itemId);
12
+ if (!options.recoverMutation) {
13
+ return failedResult(item, itemContract, index, baseAttempts, true, true, clock, error, exclusiveKey);
14
+ }
15
+ return recoverMutation({
16
+ options,
17
+ item,
18
+ itemContract,
19
+ exclusiveKey,
20
+ index,
21
+ attempts: baseAttempts,
22
+ error,
23
+ source: 'resume_incomplete',
24
+ resumed: true,
25
+ clock,
26
+ emitter,
27
+ });
28
+ }
29
+ const maxAttempts = options.retry?.maxAttempts ?? 1;
30
+ for (let invocationAttempt = 1;; invocationAttempt += 1) {
31
+ const attempt = baseAttempts + invocationAttempt;
32
+ const context = {
33
+ item,
34
+ item_id: itemId,
35
+ item_contract: itemContract,
36
+ exclusive_key: exclusiveKey,
37
+ input_index: index,
38
+ attempt,
39
+ mode: options.mode,
40
+ };
41
+ await emitter.emit('attempt_started', { item_id: itemId, input_index: index, attempt });
42
+ try {
43
+ const value = await options.execute(context);
44
+ await emitter.emit('attempt_succeeded', { item_id: itemId, input_index: index, attempt });
45
+ return freezeResult({
46
+ item,
47
+ item_id: itemId,
48
+ item_contract: itemContract,
49
+ exclusive_key: exclusiveKey,
50
+ input_index: index,
51
+ attempts: attempt,
52
+ attempt_consumed: true,
53
+ resumed,
54
+ completed_at_ms: readClock(clock),
55
+ status: 'succeeded',
56
+ value,
57
+ });
58
+ }
59
+ catch (error) {
60
+ await emitter.emit('attempt_failed', { item_id: itemId, input_index: index, attempt });
61
+ if (options.mode === 'mutation') {
62
+ if (!options.recoverMutation) {
63
+ return failedResult(item, itemContract, index, attempt, true, resumed, clock, error, exclusiveKey);
64
+ }
65
+ return recoverMutation({
66
+ options,
67
+ item,
68
+ itemContract,
69
+ exclusiveKey,
70
+ index,
71
+ attempts: attempt,
72
+ error,
73
+ source: 'execution_error',
74
+ resumed,
75
+ clock,
76
+ emitter,
77
+ });
78
+ }
79
+ if (!options.retry || invocationAttempt >= maxAttempts) {
80
+ return failedResult(item, itemContract, index, attempt, true, resumed, clock, error, exclusiveKey);
81
+ }
82
+ const retryContext = { ...context, error };
83
+ let retry = false;
84
+ try {
85
+ retry = await options.retry.shouldRetry(retryContext);
86
+ }
87
+ catch (classificationError) {
88
+ return failedResult(item, itemContract, index, attempt, true, resumed, clock, classificationError, exclusiveKey);
89
+ }
90
+ if (!retry) {
91
+ return failedResult(item, itemContract, index, attempt, true, resumed, clock, error, exclusiveKey);
92
+ }
93
+ let requestedDelay;
94
+ try {
95
+ requestedDelay = await options.retry.delayMs(retryContext);
96
+ if (!Number.isSafeInteger(requestedDelay) ||
97
+ requestedDelay < 0 ||
98
+ requestedDelay > MAX_NODE_TIMER_DELAY_MS) {
99
+ throw new BatchContractError(`Batch retry delay must be a non-negative safe integer no greater than the maximum supported timer delay (${MAX_NODE_TIMER_DELAY_MS} ms).`);
100
+ }
101
+ }
102
+ catch (delayError) {
103
+ return failedResult(item, itemContract, index, attempt, true, resumed, clock, delayError, exclusiveKey);
104
+ }
105
+ const delay = Math.min(requestedDelay, options.retry.maxDelayMs);
106
+ await emitter.emit('retry_scheduled', {
107
+ item_id: itemId,
108
+ input_index: index,
109
+ attempt,
110
+ delay_ms: delay,
111
+ });
112
+ try {
113
+ await sleep(delay);
114
+ }
115
+ catch (sleepError) {
116
+ return failedResult(item, itemContract, index, attempt, true, resumed, clock, sleepError, exclusiveKey);
117
+ }
118
+ }
119
+ }
120
+ }
121
+ async function recoverMutation(input) {
122
+ const { options, item, itemContract, exclusiveKey, index, attempts, error, source, resumed, clock, emitter, } = input;
123
+ const itemId = itemContract.item_id;
124
+ await emitter.emit('recovery_started', {
125
+ item_id: itemId,
126
+ input_index: index,
127
+ attempt: attempts,
128
+ source,
129
+ });
130
+ try {
131
+ const recovery = await options.recoverMutation({
132
+ item,
133
+ item_id: itemId,
134
+ item_contract: itemContract,
135
+ exclusive_key: exclusiveKey,
136
+ input_index: index,
137
+ attempts,
138
+ error,
139
+ source,
140
+ });
141
+ if (recovery.status === 'recovered') {
142
+ await emitter.emit('recovery_succeeded', {
143
+ item_id: itemId,
144
+ input_index: index,
145
+ attempt: attempts,
146
+ source,
147
+ });
148
+ return freezeResult({
149
+ item,
150
+ item_id: itemId,
151
+ item_contract: itemContract,
152
+ exclusive_key: exclusiveKey,
153
+ input_index: index,
154
+ attempts,
155
+ attempt_consumed: true,
156
+ resumed,
157
+ completed_at_ms: readClock(clock),
158
+ status: 'recovered',
159
+ value: recovery.value,
160
+ });
161
+ }
162
+ if (recovery.status !== 'unresolved') {
163
+ throw new BatchContractError('Mutation recovery returned an unsupported status.');
164
+ }
165
+ await emitter.emit('recovery_failed', {
166
+ item_id: itemId,
167
+ input_index: index,
168
+ attempt: attempts,
169
+ source,
170
+ });
171
+ return failedResult(item, itemContract, index, attempts, true, resumed, clock, recovery.error ?? error, exclusiveKey);
172
+ }
173
+ catch (recoveryError) {
174
+ await emitter.emit('recovery_failed', {
175
+ item_id: itemId,
176
+ input_index: index,
177
+ attempt: attempts,
178
+ source,
179
+ });
180
+ return failedResult(item, itemContract, index, attempts, true, resumed, clock, recoveryError, exclusiveKey);
181
+ }
182
+ }
183
+ //# sourceMappingURL=attempt-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attempt-recovery.js","sourceRoot":"","sources":["../../../../src/lib/batch/attempt-recovery.ts"],"names":[],"mappings":"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","sourcesContent":["import { MAX_NODE_TIMER_DELAY_MS } from './canonical-contracts.js';\nimport { BatchContractError, BatchMutationReplayError } from './errors.js';\nimport { failedResult, freezeResult, readClock, type EventEmitter } from './scheduler-runtime.js';\nimport type {\n BatchClock,\n BatchExecutionContext,\n BatchItemContract,\n BatchItemResult,\n BatchJsonValue,\n BatchRecoverySource,\n BatchResumeItem,\n BatchRetryContext,\n BatchSleep,\n RunBoundedBatchOptions,\n} from './types.js';\n\nexport async function executeClaim<\n TInput,\n TOutput,\n TIdentity extends BatchJsonValue,\n TExclusiveKey extends string,\n>(input: {\n options: RunBoundedBatchOptions<TInput, TOutput, TIdentity, TExclusiveKey>;\n index: number;\n itemContract: BatchItemContract;\n exclusiveKey: TExclusiveKey | null;\n resumeItem: BatchResumeItem<TOutput> | undefined;\n clock: BatchClock;\n sleep: BatchSleep;\n emitter: EventEmitter;\n}): Promise<BatchItemResult<TInput, TOutput>> {\n const { options, index, itemContract, exclusiveKey, resumeItem, clock, sleep, emitter } = input;\n const itemId = itemContract.item_id;\n const item = options.items[index]!;\n const resumed = resumeItem?.state === 'attempted';\n const baseAttempts = resumed ? resumeItem.attempts : 0;\n if (resumed && options.mode === 'mutation') {\n const error = new BatchMutationReplayError(itemId);\n if (!options.recoverMutation) {\n return failedResult(\n item,\n itemContract,\n index,\n baseAttempts,\n true,\n true,\n clock,\n error,\n exclusiveKey,\n );\n }\n return recoverMutation({\n options,\n item,\n itemContract,\n exclusiveKey,\n index,\n attempts: baseAttempts,\n error,\n source: 'resume_incomplete',\n resumed: true,\n clock,\n emitter,\n });\n }\n\n const maxAttempts = options.retry?.maxAttempts ?? 1;\n for (let invocationAttempt = 1; ; invocationAttempt += 1) {\n const attempt = baseAttempts + invocationAttempt;\n const context: BatchExecutionContext<TInput, TExclusiveKey> = {\n item,\n item_id: itemId,\n item_contract: itemContract,\n exclusive_key: exclusiveKey,\n input_index: index,\n attempt,\n mode: options.mode,\n };\n await emitter.emit('attempt_started', { item_id: itemId, input_index: index, attempt });\n try {\n const value = await options.execute(context);\n await emitter.emit('attempt_succeeded', { item_id: itemId, input_index: index, attempt });\n return freezeResult({\n item,\n item_id: itemId,\n item_contract: itemContract,\n exclusive_key: exclusiveKey,\n input_index: index,\n attempts: attempt,\n attempt_consumed: true,\n resumed,\n completed_at_ms: readClock(clock),\n status: 'succeeded',\n value,\n });\n } catch (error) {\n await emitter.emit('attempt_failed', { item_id: itemId, input_index: index, attempt });\n if (options.mode === 'mutation') {\n if (!options.recoverMutation) {\n return failedResult(\n item,\n itemContract,\n index,\n attempt,\n true,\n resumed,\n clock,\n error,\n exclusiveKey,\n );\n }\n return recoverMutation({\n options,\n item,\n itemContract,\n exclusiveKey,\n index,\n attempts: attempt,\n error,\n source: 'execution_error',\n resumed,\n clock,\n emitter,\n });\n }\n if (!options.retry || invocationAttempt >= maxAttempts) {\n return failedResult(\n item,\n itemContract,\n index,\n attempt,\n true,\n resumed,\n clock,\n error,\n exclusiveKey,\n );\n }\n const retryContext: BatchRetryContext<TInput, TExclusiveKey> = { ...context, error };\n let retry = false;\n try {\n retry = await options.retry.shouldRetry(retryContext);\n } catch (classificationError) {\n return failedResult(\n item,\n itemContract,\n index,\n attempt,\n true,\n resumed,\n clock,\n classificationError,\n exclusiveKey,\n );\n }\n if (!retry) {\n return failedResult(\n item,\n itemContract,\n index,\n attempt,\n true,\n resumed,\n clock,\n error,\n exclusiveKey,\n );\n }\n let requestedDelay: number;\n try {\n requestedDelay = await options.retry.delayMs(retryContext);\n if (\n !Number.isSafeInteger(requestedDelay) ||\n requestedDelay < 0 ||\n requestedDelay > MAX_NODE_TIMER_DELAY_MS\n ) {\n throw new BatchContractError(\n `Batch retry delay must be a non-negative safe integer no greater than the maximum supported timer delay (${MAX_NODE_TIMER_DELAY_MS} ms).`,\n );\n }\n } catch (delayError) {\n return failedResult(\n item,\n itemContract,\n index,\n attempt,\n true,\n resumed,\n clock,\n delayError,\n exclusiveKey,\n );\n }\n const delay = Math.min(requestedDelay, options.retry.maxDelayMs);\n await emitter.emit('retry_scheduled', {\n item_id: itemId,\n input_index: index,\n attempt,\n delay_ms: delay,\n });\n try {\n await sleep(delay);\n } catch (sleepError) {\n return failedResult(\n item,\n itemContract,\n index,\n attempt,\n true,\n resumed,\n clock,\n sleepError,\n exclusiveKey,\n );\n }\n }\n }\n}\n\nasync function recoverMutation<\n TInput,\n TOutput,\n TIdentity extends BatchJsonValue,\n TExclusiveKey extends string,\n>(input: {\n options: RunBoundedBatchOptions<TInput, TOutput, TIdentity, TExclusiveKey>;\n item: TInput;\n itemContract: BatchItemContract;\n exclusiveKey: TExclusiveKey | null;\n index: number;\n attempts: number;\n error: unknown;\n source: BatchRecoverySource;\n resumed: boolean;\n clock: BatchClock;\n emitter: EventEmitter;\n}): Promise<BatchItemResult<TInput, TOutput>> {\n const {\n options,\n item,\n itemContract,\n exclusiveKey,\n index,\n attempts,\n error,\n source,\n resumed,\n clock,\n emitter,\n } = input;\n const itemId = itemContract.item_id;\n await emitter.emit('recovery_started', {\n item_id: itemId,\n input_index: index,\n attempt: attempts,\n source,\n });\n try {\n const recovery = await options.recoverMutation!({\n item,\n item_id: itemId,\n item_contract: itemContract,\n exclusive_key: exclusiveKey,\n input_index: index,\n attempts,\n error,\n source,\n });\n if (recovery.status === 'recovered') {\n await emitter.emit('recovery_succeeded', {\n item_id: itemId,\n input_index: index,\n attempt: attempts,\n source,\n });\n return freezeResult({\n item,\n item_id: itemId,\n item_contract: itemContract,\n exclusive_key: exclusiveKey,\n input_index: index,\n attempts,\n attempt_consumed: true,\n resumed,\n completed_at_ms: readClock(clock),\n status: 'recovered',\n value: recovery.value,\n });\n }\n if (recovery.status !== 'unresolved') {\n throw new BatchContractError('Mutation recovery returned an unsupported status.');\n }\n await emitter.emit('recovery_failed', {\n item_id: itemId,\n input_index: index,\n attempt: attempts,\n source,\n });\n return failedResult(\n item,\n itemContract,\n index,\n attempts,\n true,\n resumed,\n clock,\n recovery.error ?? error,\n exclusiveKey,\n );\n } catch (recoveryError) {\n await emitter.emit('recovery_failed', {\n item_id: itemId,\n input_index: index,\n attempt: attempts,\n source,\n });\n return failedResult(\n item,\n itemContract,\n index,\n attempts,\n true,\n resumed,\n clock,\n recoveryError,\n exclusiveKey,\n );\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { BatchContract, BatchItemContract, BatchJsonValue, CreateBatchContractOptions, CreateBatchItemContractOptions } from './types.js';
2
+ export declare const MAX_NODE_TIMER_DELAY_MS = 2147483647;
3
+ export declare function canonicalBatchJson(value: BatchJsonValue): string;
4
+ export declare function sha256BatchBytes(value: string | Uint8Array): string;
5
+ export declare function sha256BatchJson(value: BatchJsonValue): string;
6
+ export declare function createBatchContract<TIdentity extends BatchJsonValue>(options: CreateBatchContractOptions<TIdentity>): BatchContract<TIdentity>;
7
+ export declare function createBatchItemContract(options: CreateBatchItemContractOptions): BatchItemContract;
8
+ export declare function parseBatchItemContract(value: unknown): BatchItemContract;
9
+ export declare function assertBatchItemContractMatches(expectedValue: unknown, actualValue: unknown): BatchItemContract;
10
+ export declare function parseBatchContract<TIdentity extends BatchJsonValue = BatchJsonValue>(value: unknown): BatchContract<TIdentity>;
11
+ export declare function assertBatchContractMatches<TIdentity extends BatchJsonValue>(expectedValue: unknown, actualValue: unknown): BatchContract<TIdentity>;
12
+ export declare function canonicalizeBatchValue(value: unknown, ancestors: Set<object>): BatchJsonValue;
13
+ export declare function freezeBatchJson<T extends BatchJsonValue>(value: T): T;
14
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
15
+ export declare function parseBatchRunPath(value: unknown): string;
16
+ export declare function parseBatchRunLockToken(value: unknown, label: string): string;
17
+ export declare function assertBatchTimerDelaySupported(value: number | undefined, label: string): void;
18
+ export declare function hasExactKeys(value: Record<string, unknown>, expectedKeys: readonly string[]): boolean;
19
+ export declare function parseItemIdentity(value: unknown, location: number | 'contract'): string;
20
+ export declare function assertUniqueItemIds(itemIds: readonly string[]): void;
21
+ export declare function batchItemContractsMatch(left: BatchItemContract, right: BatchItemContract): boolean;
@@ -0,0 +1,180 @@
1
+ import { createHash } from 'node:crypto';
2
+ import path from 'node:path';
3
+ import { BatchContractError, BatchItemResumeContractError } from './errors.js';
4
+ const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
5
+ export const MAX_NODE_TIMER_DELAY_MS = 2_147_483_647;
6
+ export function canonicalBatchJson(value) {
7
+ return JSON.stringify(canonicalizeBatchValue(value, new Set()));
8
+ }
9
+ export function sha256BatchBytes(value) {
10
+ return createHash('sha256').update(value).digest('hex');
11
+ }
12
+ export function sha256BatchJson(value) {
13
+ return sha256BatchBytes(canonicalBatchJson(value));
14
+ }
15
+ export function createBatchContract(options) {
16
+ const identity = freezeBatchJson(canonicalizeBatchValue(options.identity, new Set()));
17
+ return Object.freeze({
18
+ identity,
19
+ content_sha256: sha256BatchJson(options.content),
20
+ policy_sha256: sha256BatchJson(options.policy),
21
+ });
22
+ }
23
+ export function createBatchItemContract(options) {
24
+ const itemId = parseItemIdentity(options.item_id, 'contract');
25
+ return Object.freeze({
26
+ item_id: itemId,
27
+ content_sha256: sha256BatchJson(options.content),
28
+ policy_sha256: sha256BatchJson(options.policy),
29
+ });
30
+ }
31
+ export function parseBatchItemContract(value) {
32
+ if (!isRecord(value) ||
33
+ typeof value.item_id !== 'string' ||
34
+ typeof value.content_sha256 !== 'string' ||
35
+ !SHA256_PATTERN.test(value.content_sha256) ||
36
+ typeof value.policy_sha256 !== 'string' ||
37
+ !SHA256_PATTERN.test(value.policy_sha256)) {
38
+ throw new BatchContractError('Batch item contract requires item_id plus valid content and policy SHA-256 values.');
39
+ }
40
+ return Object.freeze({
41
+ item_id: parseItemIdentity(value.item_id, 'contract'),
42
+ content_sha256: value.content_sha256,
43
+ policy_sha256: value.policy_sha256,
44
+ });
45
+ }
46
+ export function assertBatchItemContractMatches(expectedValue, actualValue) {
47
+ const expected = parseBatchItemContract(expectedValue);
48
+ const actual = parseBatchItemContract(actualValue);
49
+ if (!batchItemContractsMatch(expected, actual)) {
50
+ throw new BatchItemResumeContractError(expected.item_id);
51
+ }
52
+ return actual;
53
+ }
54
+ export function parseBatchContract(value) {
55
+ if (!isRecord(value) || !hasExactKeys(value, ['content_sha256', 'identity', 'policy_sha256'])) {
56
+ throw new BatchContractError('Batch contract must contain exact identity, content_sha256, and policy_sha256 keys.');
57
+ }
58
+ let identity;
59
+ try {
60
+ identity = freezeBatchJson(canonicalizeBatchValue(value.identity, new Set()));
61
+ }
62
+ catch (error) {
63
+ throw new BatchContractError('Batch contract identity must be canonical JSON data.', {
64
+ cause: error,
65
+ });
66
+ }
67
+ if (typeof value.content_sha256 !== 'string' ||
68
+ !SHA256_PATTERN.test(value.content_sha256) ||
69
+ typeof value.policy_sha256 !== 'string' ||
70
+ !SHA256_PATTERN.test(value.policy_sha256)) {
71
+ throw new BatchContractError('Batch contract content and policy SHA-256 values are malformed.');
72
+ }
73
+ return Object.freeze({
74
+ identity,
75
+ content_sha256: value.content_sha256,
76
+ policy_sha256: value.policy_sha256,
77
+ });
78
+ }
79
+ export function assertBatchContractMatches(expectedValue, actualValue) {
80
+ const expected = parseBatchContract(expectedValue);
81
+ const actual = parseBatchContract(actualValue);
82
+ if (canonicalBatchJson(expected.identity) !== canonicalBatchJson(actual.identity) ||
83
+ expected.content_sha256 !== actual.content_sha256 ||
84
+ expected.policy_sha256 !== actual.policy_sha256) {
85
+ throw new BatchContractError('Batch resume requires an exact identity, content SHA-256, and policy SHA-256 match.');
86
+ }
87
+ return actual;
88
+ }
89
+ export function canonicalizeBatchValue(value, ancestors) {
90
+ if (value === null || typeof value === 'string' || typeof value === 'boolean')
91
+ return value;
92
+ if (typeof value === 'number') {
93
+ if (!Number.isFinite(value)) {
94
+ throw new BatchContractError('Canonical batch JSON rejects non-finite numbers.');
95
+ }
96
+ return value;
97
+ }
98
+ if (typeof value !== 'object') {
99
+ throw new BatchContractError('Canonical batch JSON accepts JSON data only.');
100
+ }
101
+ if (ancestors.has(value)) {
102
+ throw new BatchContractError('Canonical batch JSON rejects cyclic data.');
103
+ }
104
+ ancestors.add(value);
105
+ try {
106
+ if (Array.isArray(value)) {
107
+ return value.map((entry) => canonicalizeBatchValue(entry, ancestors));
108
+ }
109
+ const prototype = Object.getPrototypeOf(value);
110
+ if (prototype !== Object.prototype && prototype !== null) {
111
+ throw new BatchContractError('Canonical batch JSON accepts plain objects only.');
112
+ }
113
+ return Object.fromEntries(Object.keys(value)
114
+ .sort()
115
+ .map((key) => [
116
+ key,
117
+ canonicalizeBatchValue(value[key], ancestors),
118
+ ]));
119
+ }
120
+ finally {
121
+ ancestors.delete(value);
122
+ }
123
+ }
124
+ export function freezeBatchJson(value) {
125
+ if (value !== null && typeof value === 'object') {
126
+ for (const child of Object.values(value))
127
+ freezeBatchJson(child);
128
+ Object.freeze(value);
129
+ }
130
+ return value;
131
+ }
132
+ export function isRecord(value) {
133
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
134
+ }
135
+ export function parseBatchRunPath(value) {
136
+ if (typeof value !== 'string' || value.length === 0 || /[\0\r\n]/u.test(value)) {
137
+ throw new BatchContractError('Batch runPath must be a non-empty single-line path.');
138
+ }
139
+ return path.resolve(value);
140
+ }
141
+ export function parseBatchRunLockToken(value, label) {
142
+ if (typeof value !== 'string' || value.length === 0 || /[\0\r\n]/u.test(value)) {
143
+ throw new BatchContractError(`Batch run-lock ${label} must be a non-empty single-line string.`);
144
+ }
145
+ return value;
146
+ }
147
+ export function assertBatchTimerDelaySupported(value, label) {
148
+ if (value === undefined)
149
+ return;
150
+ if (!Number.isSafeInteger(value) || value < 0) {
151
+ throw new BatchContractError(`Batch ${label} must be a non-negative safe integer.`);
152
+ }
153
+ if (value > MAX_NODE_TIMER_DELAY_MS) {
154
+ throw new BatchContractError(`Batch ${label} exceeds the maximum supported timer delay (${MAX_NODE_TIMER_DELAY_MS} ms).`);
155
+ }
156
+ }
157
+ export function hasExactKeys(value, expectedKeys) {
158
+ const actual = Object.keys(value).sort();
159
+ const expected = [...expectedKeys].sort();
160
+ return actual.length === expected.length && actual.every((key, index) => key === expected[index]);
161
+ }
162
+ export function parseItemIdentity(value, location) {
163
+ if (typeof value !== 'string' || value.length === 0 || /[\0\r\n]/u.test(value)) {
164
+ throw new BatchContractError(location === 'contract'
165
+ ? 'Batch item contract identity must be a non-empty single-line string.'
166
+ : `Batch item identity at input index ${location} must be a non-empty single-line string.`);
167
+ }
168
+ return value;
169
+ }
170
+ export function assertUniqueItemIds(itemIds) {
171
+ if (new Set(itemIds).size !== itemIds.length) {
172
+ throw new BatchContractError('Batch item identities must be unique.');
173
+ }
174
+ }
175
+ export function batchItemContractsMatch(left, right) {
176
+ return (left.item_id === right.item_id &&
177
+ left.content_sha256 === right.content_sha256 &&
178
+ left.policy_sha256 === right.policy_sha256);
179
+ }
180
+ //# sourceMappingURL=canonical-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonical-contracts.js","sourceRoot":"","sources":["../../../../src/lib/batch/canonical-contracts.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto';\nimport path from 'node:path';\n\nimport { BatchContractError, BatchItemResumeContractError } from './errors.js';\nimport type {\n BatchContract,\n BatchItemContract,\n BatchJsonValue,\n CreateBatchContractOptions,\n CreateBatchItemContractOptions,\n} from './types.js';\n\nconst SHA256_PATTERN = /^[a-f0-9]{64}$/u;\nexport const MAX_NODE_TIMER_DELAY_MS = 2_147_483_647;\n\nexport function canonicalBatchJson(value: BatchJsonValue): string {\n return JSON.stringify(canonicalizeBatchValue(value, new Set<object>()));\n}\n\nexport function sha256BatchBytes(value: string | Uint8Array): string {\n return createHash('sha256').update(value).digest('hex');\n}\n\nexport function sha256BatchJson(value: BatchJsonValue): string {\n return sha256BatchBytes(canonicalBatchJson(value));\n}\n\nexport function createBatchContract<TIdentity extends BatchJsonValue>(\n options: CreateBatchContractOptions<TIdentity>,\n): BatchContract<TIdentity> {\n const identity = freezeBatchJson(\n canonicalizeBatchValue(options.identity, new Set<object>()),\n ) as TIdentity;\n return Object.freeze({\n identity,\n content_sha256: sha256BatchJson(options.content),\n policy_sha256: sha256BatchJson(options.policy),\n });\n}\n\nexport function createBatchItemContract(\n options: CreateBatchItemContractOptions,\n): BatchItemContract {\n const itemId = parseItemIdentity(options.item_id, 'contract');\n return Object.freeze({\n item_id: itemId,\n content_sha256: sha256BatchJson(options.content),\n policy_sha256: sha256BatchJson(options.policy),\n });\n}\n\nexport function parseBatchItemContract(value: unknown): BatchItemContract {\n if (\n !isRecord(value) ||\n typeof value.item_id !== 'string' ||\n typeof value.content_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.content_sha256) ||\n typeof value.policy_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.policy_sha256)\n ) {\n throw new BatchContractError(\n 'Batch item contract requires item_id plus valid content and policy SHA-256 values.',\n );\n }\n return Object.freeze({\n item_id: parseItemIdentity(value.item_id, 'contract'),\n content_sha256: value.content_sha256,\n policy_sha256: value.policy_sha256,\n });\n}\n\nexport function assertBatchItemContractMatches(\n expectedValue: unknown,\n actualValue: unknown,\n): BatchItemContract {\n const expected = parseBatchItemContract(expectedValue);\n const actual = parseBatchItemContract(actualValue);\n if (!batchItemContractsMatch(expected, actual)) {\n throw new BatchItemResumeContractError(expected.item_id);\n }\n return actual;\n}\n\nexport function parseBatchContract<TIdentity extends BatchJsonValue = BatchJsonValue>(\n value: unknown,\n): BatchContract<TIdentity> {\n if (!isRecord(value) || !hasExactKeys(value, ['content_sha256', 'identity', 'policy_sha256'])) {\n throw new BatchContractError(\n 'Batch contract must contain exact identity, content_sha256, and policy_sha256 keys.',\n );\n }\n let identity: TIdentity;\n try {\n identity = freezeBatchJson(\n canonicalizeBatchValue(value.identity, new Set<object>()),\n ) as TIdentity;\n } catch (error) {\n throw new BatchContractError('Batch contract identity must be canonical JSON data.', {\n cause: error,\n });\n }\n if (\n typeof value.content_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.content_sha256) ||\n typeof value.policy_sha256 !== 'string' ||\n !SHA256_PATTERN.test(value.policy_sha256)\n ) {\n throw new BatchContractError('Batch contract content and policy SHA-256 values are malformed.');\n }\n return Object.freeze({\n identity,\n content_sha256: value.content_sha256,\n policy_sha256: value.policy_sha256,\n });\n}\n\nexport function assertBatchContractMatches<TIdentity extends BatchJsonValue>(\n expectedValue: unknown,\n actualValue: unknown,\n): BatchContract<TIdentity> {\n const expected = parseBatchContract<TIdentity>(expectedValue);\n const actual = parseBatchContract<TIdentity>(actualValue);\n if (\n canonicalBatchJson(expected.identity) !== canonicalBatchJson(actual.identity) ||\n expected.content_sha256 !== actual.content_sha256 ||\n expected.policy_sha256 !== actual.policy_sha256\n ) {\n throw new BatchContractError(\n 'Batch resume requires an exact identity, content SHA-256, and policy SHA-256 match.',\n );\n }\n return actual;\n}\n\nexport function canonicalizeBatchValue(value: unknown, ancestors: Set<object>): BatchJsonValue {\n if (value === null || typeof value === 'string' || typeof value === 'boolean') return value;\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n throw new BatchContractError('Canonical batch JSON rejects non-finite numbers.');\n }\n return value;\n }\n if (typeof value !== 'object') {\n throw new BatchContractError('Canonical batch JSON accepts JSON data only.');\n }\n if (ancestors.has(value)) {\n throw new BatchContractError('Canonical batch JSON rejects cyclic data.');\n }\n ancestors.add(value);\n try {\n if (Array.isArray(value)) {\n return value.map((entry) => canonicalizeBatchValue(entry, ancestors));\n }\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) {\n throw new BatchContractError('Canonical batch JSON accepts plain objects only.');\n }\n return Object.fromEntries(\n Object.keys(value)\n .sort()\n .map((key) => [\n key,\n canonicalizeBatchValue((value as Record<string, unknown>)[key], ancestors),\n ]),\n );\n } finally {\n ancestors.delete(value);\n }\n}\n\nexport function freezeBatchJson<T extends BatchJsonValue>(value: T): T {\n if (value !== null && typeof value === 'object') {\n for (const child of Object.values(value)) freezeBatchJson(child);\n Object.freeze(value);\n }\n return value;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function parseBatchRunPath(value: unknown): string {\n if (typeof value !== 'string' || value.length === 0 || /[\\0\\r\\n]/u.test(value)) {\n throw new BatchContractError('Batch runPath must be a non-empty single-line path.');\n }\n return path.resolve(value);\n}\n\nexport function parseBatchRunLockToken(value: unknown, label: string): string {\n if (typeof value !== 'string' || value.length === 0 || /[\\0\\r\\n]/u.test(value)) {\n throw new BatchContractError(`Batch run-lock ${label} must be a non-empty single-line string.`);\n }\n return value;\n}\n\nexport function assertBatchTimerDelaySupported(value: number | undefined, label: string): void {\n if (value === undefined) return;\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new BatchContractError(`Batch ${label} must be a non-negative safe integer.`);\n }\n if (value > MAX_NODE_TIMER_DELAY_MS) {\n throw new BatchContractError(\n `Batch ${label} exceeds the maximum supported timer delay (${MAX_NODE_TIMER_DELAY_MS} ms).`,\n );\n }\n}\n\nexport function hasExactKeys(\n value: Record<string, unknown>,\n expectedKeys: readonly string[],\n): boolean {\n const actual = Object.keys(value).sort();\n const expected = [...expectedKeys].sort();\n return actual.length === expected.length && actual.every((key, index) => key === expected[index]);\n}\n\nexport function parseItemIdentity(value: unknown, location: number | 'contract'): string {\n if (typeof value !== 'string' || value.length === 0 || /[\\0\\r\\n]/u.test(value)) {\n throw new BatchContractError(\n location === 'contract'\n ? 'Batch item contract identity must be a non-empty single-line string.'\n : `Batch item identity at input index ${location} must be a non-empty single-line string.`,\n );\n }\n return value;\n}\n\nexport function assertUniqueItemIds(itemIds: readonly string[]): void {\n if (new Set(itemIds).size !== itemIds.length) {\n throw new BatchContractError('Batch item identities must be unique.');\n }\n}\n\nexport function batchItemContractsMatch(\n left: BatchItemContract,\n right: BatchItemContract,\n): boolean {\n return (\n left.item_id === right.item_id &&\n left.content_sha256 === right.content_sha256 &&\n left.policy_sha256 === right.policy_sha256\n );\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import type { BatchJsonValue, BatchRunResult, RunBoundedBatchOptions } from './types.js';
2
+ export declare function runBoundedBatch<TInput, TOutput, TIdentity extends BatchJsonValue, TExclusiveKey extends string = string>(options: RunBoundedBatchOptions<TInput, TOutput, TIdentity, TExclusiveKey>): Promise<BatchRunResult<TInput, TOutput, TIdentity>>;