@rebasepro/server 0.14.0 → 0.14.1

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 (58) hide show
  1. package/dist/api/rest/query-parser.d.ts +37 -1
  2. package/dist/api/rest/write-validation.d.ts +26 -0
  3. package/dist/auth/index.d.ts +3 -1
  4. package/dist/auth/interfaces.d.ts +14 -1
  5. package/dist/auth/jwks-routes.d.ts +17 -0
  6. package/dist/auth/jwt-keys.d.ts +108 -0
  7. package/dist/auth/jwt.d.ts +62 -2
  8. package/dist/{auth-CYoPVf-E.js → auth-BobZVd0j.js} +142 -167
  9. package/dist/auth-BobZVd0j.js.map +1 -0
  10. package/dist/boot/boot.d.ts +36 -50
  11. package/dist/boot/ddl-bootstrap.d.ts +15 -0
  12. package/dist/boot/env.d.ts +20 -0
  13. package/dist/boot/provision.d.ts +182 -0
  14. package/dist/boot/role.d.ts +88 -0
  15. package/dist/{cron-store-Dvr4Y1sZ.js → cron-store-CB1x-Ken.js} +3 -3
  16. package/dist/{cron-store-Dvr4Y1sZ.js.map → cron-store-CB1x-Ken.js.map} +1 -1
  17. package/dist/{ddl-bootstrap-BhXbTnBl.js → ddl-bootstrap-Cywoj8Ta.js} +40 -2
  18. package/dist/ddl-bootstrap-Cywoj8Ta.js.map +1 -0
  19. package/dist/env.d.ts +2 -0
  20. package/dist/functions/proxy.d.ts +41 -0
  21. package/dist/functions/selection.d.ts +45 -0
  22. package/dist/index.d.ts +8 -3
  23. package/dist/index.es.js +1113 -661
  24. package/dist/index.es.js.map +1 -1
  25. package/dist/init/shutdown.d.ts +4 -0
  26. package/dist/init/surfaces.d.ts +79 -0
  27. package/dist/init.d.ts +121 -1
  28. package/dist/jobs/index.d.ts +5 -0
  29. package/dist/jobs/job-queue.d.ts +14 -0
  30. package/dist/jobs/job-store.d.ts +22 -0
  31. package/dist/jobs/types.d.ts +125 -0
  32. package/dist/jobs-DR4SjGrD.js +326 -0
  33. package/dist/jobs-DR4SjGrD.js.map +1 -0
  34. package/dist/{jwt-_IFqfTOg.js → jwt-VJyXTdQQ.js} +447 -11
  35. package/dist/jwt-VJyXTdQQ.js.map +1 -0
  36. package/dist/{openapi-generator-DPKtUC9X.js → openapi-generator-DQeQ_q2f.js} +68 -3
  37. package/dist/openapi-generator-DQeQ_q2f.js.map +1 -0
  38. package/dist/proxy-Bj5DVllb.js +139 -0
  39. package/dist/proxy-Bj5DVllb.js.map +1 -0
  40. package/dist/{request-timeout-RivJsME0.js → request-timeout-BuFoEKwT.js} +6 -3
  41. package/dist/request-timeout-BuFoEKwT.js.map +1 -0
  42. package/dist/selection-_z6TM1DB.js +64 -0
  43. package/dist/selection-_z6TM1DB.js.map +1 -0
  44. package/dist/services/webhook-service.d.ts +43 -5
  45. package/dist/{src-C7rkDGxA.js → src-8XDWyDfR.js} +84 -13
  46. package/dist/src-8XDWyDfR.js.map +1 -0
  47. package/dist/src-Cz9nMgUR.js.map +1 -1
  48. package/dist/storage/keys.d.ts +17 -0
  49. package/dist/storage/routes.d.ts +1 -1
  50. package/dist/storage/storage-registry.d.ts +46 -4
  51. package/dist/storage/tus-handler.d.ts +1 -1
  52. package/package.json +5 -5
  53. package/dist/auth-CYoPVf-E.js.map +0 -1
  54. package/dist/ddl-bootstrap-BhXbTnBl.js.map +0 -1
  55. package/dist/jwt-_IFqfTOg.js.map +0 -1
  56. package/dist/openapi-generator-DPKtUC9X.js.map +0 -1
  57. package/dist/request-timeout-RivJsME0.js.map +0 -1
  58. package/dist/src-C7rkDGxA.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth-CYoPVf-E.js","names":["_a","F","initializer","util.jsonStringifyReplacer","core.$ZodAsyncError","util.finalizeIssue","core.config","errors.$ZodError","safeParse","errors.$ZodRealError","safeParseAsync","duration","_emoji","date","time","datetime","string","util.floatSafeRemainder","util.NUMBER_FORMAT_RANGES","regexes.integer","util.nullish","util.getLengthableOrigin","regexes.lowercase","regexes.uppercase","util.escapeRegex","content","util.aborted","util.explicitlyAborted","core.$ZodAsyncError","safeParse","safeParseAsync","regexes.string","regexes.guid","regexes.uuid","regexes.email","regexes.emoji","regexes.nanoid","regexes.cuid","regexes.cuid2","regexes.ulid","regexes.xid","regexes.ksuid","regexes.datetime","regexes.date","regexes.time","regexes.duration","regexes.ipv4","regexes.ipv6","regexes.cidrv4","regexes.cidrv6","regexes.base64","regexes.base64url","regexes.e164","regexes.number","util.prefixIssues","util.optionalKeys","util.cached","isObject","util.isObject","util.esc","allowsEval","util.allowsEval","util.finalizeIssue","core.config","util.cleanRegex","util.isPlainObject","util.getEnumValues","util.escapeRegex","core.$ZodEncodeError","util.issue","util.normalizeParams","checks.$ZodCheckLessThan","checks.$ZodCheckGreaterThan","checks.$ZodCheckMultipleOf","checks.$ZodCheckMaxLength","checks.$ZodCheckMinLength","checks.$ZodCheckLengthEquals","checks.$ZodCheckRegex","checks.$ZodCheckLowerCase","checks.$ZodCheckUpperCase","checks.$ZodCheckIncludes","checks.$ZodCheckStartsWith","checks.$ZodCheckEndsWith","checks.$ZodCheckOverwrite","util.slugify","issue","util.issue","checks.$ZodCheck","process","process","core._isoDateTime","core._isoDate","core._isoTime","core._isoDuration","core.formatError","core.flattenError","util.jsonStringifyReplacer","parse.parse","parse.safeParse","parse.parseAsync","parse.safeParseAsync","parse.encode","parse.decode","parse.encodeAsync","parse.decodeAsync","parse.safeEncode","parse.safeDecode","parse.safeEncodeAsync","parse.safeDecodeAsync","util.mergeDefs","core.clone","checks.overwrite","processors.stringProcessor","checks.regex","checks.includes","checks.startsWith","checks.endsWith","checks.minLength","checks.maxLength","checks.length","checks.lowercase","checks.uppercase","checks.trim","checks.normalize","checks.toLowerCase","checks.toUpperCase","checks.slugify","core._email","core._url","core._jwt","core._emoji","core._guid","core._uuid","core._uuidv4","core._uuidv6","core._uuidv7","core._nanoid","core._cuid","core._cuid2","core._ulid","core._base64","core._base64url","core._xid","core._ksuid","core._ipv4","core._ipv6","core._cidrv4","core._cidrv6","core._e164","iso.datetime","iso.date","iso.time","iso.duration","core._string","processors.numberProcessor","checks.gt","checks.gte","checks.lt","checks.lte","checks.multipleOf","core._int","processors.unknownProcessor","core._unknown","processors.neverProcessor","core._never","processors.arrayProcessor","core._array","processors.objectProcessor","util.extend","util.safeExtend","util.merge","util.pick","util.omit","util.partial","util.required","util.normalizeParams","processors.unionProcessor","processors.intersectionProcessor","processors.enumProcessor","processors.transformProcessor","core.$ZodEncodeError","issue","util.issue","processors.optionalProcessor","processors.nullableProcessor","processors.defaultProcessor","util.shallowClone","processors.prefaultProcessor","processors.nonoptionalProcessor","processors.catchProcessor","processors.pipeProcessor","processors.readonlyProcessor","processors.customProcessor","core._refine","core._superRefine"],"sources":["../../types/src/controllers/storage.ts","../../common/src/util/email.ts","../src/api/rest/query-parser.ts","../src/auth/api-keys/api-key-permission-guard.ts","../src/auth/token-revocation.ts","../src/auth/admin-roles.ts","../src/auth/rls-scope.ts","../src/auth/crypto-utils.ts","../src/auth/bearer-token.ts","../src/auth/api-keys/api-key-middleware.ts","../src/storage/keys.ts","../src/auth/middleware.ts","../src/auth/adapter-middleware.ts","../src/email/html.ts","../src/email/templates.ts","../src/auth/admin-user-ops.ts","../src/auth/password.ts","../src/auth/auth-hooks.ts","../src/email/link-base.ts","../src/email/smtp-email-service.ts","../src/auth/rate-limit-store.ts","../src/auth/rate-limiter.ts","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/core.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/util.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/errors.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/parse.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/regexes.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/checks.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/doc.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/versions.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/schemas.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/registries.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/api.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/to-json-schema.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/core/json-schema-processors.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/iso.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/errors.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/parse.js","../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js","../src/auth/mfa.ts","../src/auth/mfa-crypto.ts","../src/auth/cookie-utils.ts","../src/auth/mfa-routes.ts","../src/auth/mfa-gate.ts","../src/auth/registration-policy.ts","../src/auth/session-routes.ts","../src/auth/magic-link-routes.ts","../src/auth/oauth-signin-policy.ts","../src/auth/routes.ts","../src/auth/reset-password-admin.ts","../src/auth/admin-roles-route.ts","../src/auth/admin-users-route.ts","../src/auth/builtin-auth-adapter.ts","../src/auth/oauth-code-flow.ts","../src/auth/google-oauth.ts","../src/auth/linkedin-oauth.ts","../src/auth/github-oauth.ts","../src/auth/oidc-id-token.ts","../src/auth/microsoft-oauth.ts","../src/auth/apple-oauth.ts","../src/auth/facebook-oauth.ts","../src/auth/twitter-oauth.ts","../src/auth/discord-oauth.ts","../src/auth/gitlab-oauth.ts","../src/auth/bitbucket-oauth.ts","../src/auth/slack-oauth.ts","../src/auth/spotify-oauth.ts","../src/auth/api-keys/api-key-store.ts","../src/auth/api-keys/api-key-routes.ts","../src/auth/custom-auth-adapter.ts","../src/auth/index.ts"],"sourcesContent":["/**\n * Path prefix that marks an object as **public**. Files stored under this\n * prefix are served without any auth token via a stable, permanent,\n * CDN-cacheable URL (see {@link StorageSource.getSignedUrl}). Shared by the\n * client SDK and the backend so both agree on which objects are public.\n *\n * @group Models\n */\nexport const PUBLIC_STORAGE_PREFIX = \"public/\";\n\n/**\n * True when a storage key/path points at a public object (lives under\n * {@link PUBLIC_STORAGE_PREFIX}). The check is applied to the key *within the\n * bucket* — strip any `bucket/` and `scheme://` prefixes first.\n *\n * @group Models\n */\nexport function isPublicStoragePath(path: string | null | undefined): boolean {\n if (!path) return false;\n let p = path;\n const scheme = p.indexOf(\"://\");\n if (scheme !== -1) p = p.substring(scheme + 3);\n p = p.replace(/^\\/+/, \"\");\n\n // Defense-in-depth: a path containing traversal segments is never public,\n // so an attacker can't reach a private object via `public/../secret`.\n if (p.split(\"/\").some((seg) => seg === \"..\")) return false;\n\n // Public iff the object **key** starts with the public prefix. A single\n // leading `default/` bucket segment is tolerated (the default bucket).\n // A substring match is deliberately NOT used — a private object under a\n // folder literally named `public` (e.g. `reports/public/q3.pdf`) must stay\n // private. Named buckets: pass the key (not `bucket/key`) so the prefix is\n // anchored; otherwise it falls back to a private, token-scoped URL (safe).\n return p.startsWith(PUBLIC_STORAGE_PREFIX) || p.startsWith(`default/${PUBLIC_STORAGE_PREFIX}`);\n}\n\n/**\n * @group Models\n */\nexport interface UploadFileProps {\n file: File,\n key: string,\n metadata?: Record<string, unknown>,\n bucket?: string,\n /**\n * Store this object as **public**: it is placed under\n * {@link PUBLIC_STORAGE_PREFIX} and served via a stable, token-less,\n * permanent URL (safe to persist in a database and cache on a CDN).\n * Defaults to `false` (private, short-lived signed URLs).\n */\n public?: boolean\n}\n\n/**\n * @group Models\n */\nexport interface UploadFileResult {\n /**\n * Storage key including the file name where the file was uploaded.\n */\n key: string;\n /**\n * Bucket where the file was uploaded\n */\n bucket: string;\n\n /**\n * Fully qualified storage URL for the uploaded file.\n *\n * For example: `s3://my-bucket/path/to/file.png`.\n *\n * This is optional for backwards compatibility.\n */\n storageUrl?: string;\n}\n\n/**\n * @group Models\n */\nexport interface DownloadConfig {\n /**\n * Temporal url that can be used to download the file\n */\n url: string | null;\n\n metadata?: DownloadMetadata;\n\n fileNotFound?: boolean;\n}\n\n/**\n * The full set of object metadata, including read-only properties.\n * @public\n */\nexport declare interface DownloadMetadata {\n /**\n * The bucket this object is contained in.\n */\n bucket: string;\n /**\n * The full path of this object.\n */\n fullPath: string;\n /**\n * The short name of this object, which is the last component of the full path.\n * For example, if path is 'full/path/image.png', name is 'image.png'.\n */\n name: string;\n /**\n * The size of this object, in bytes.\n */\n size: number;\n /**\n * Type of the uploaded file\n * e.g. \"image/jpeg\"\n */\n contentType: string;\n\n customMetadata: Record<string, unknown>;\n /**\n * Optional short-lived download token (for local/server-mediated storage).\n * Absent for public objects, which need no token.\n */\n token?: string;\n /**\n * Optional remaining lifetime of the token, in seconds.\n */\n tokenExpiresIn?: number;\n /**\n * True when this object is public: it is served without a token via a\n * stable, permanent, CDN-cacheable URL. When set, the client builds a\n * token-less URL and caches it indefinitely.\n */\n public?: boolean;\n}\n\n/**\n * @group Models\n */\nexport interface StorageSource {\n /**\n * Upload an object, specifying a key\n * @param file\n * @param key\n * @param metadata\n * @param bucket\n */\n putObject: ({\n file,\n key,\n metadata,\n bucket\n }: UploadFileProps) => Promise<UploadFileResult>;\n\n /**\n * Convert a storage key or URL into a download configuration (signed URL equivalent)\n * @param keyOrUrl\n * @param bucket\n */\n getSignedUrl: (keyOrUrl: string, bucket?: string) => Promise<DownloadConfig>;\n\n /**\n * Get an object from a storage key.\n * It returns null if the object does not exist.\n * @param key\n * @param bucket\n */\n getObject: (key: string, bucket?: string) => Promise<File | null>;\n\n /**\n * Delete an object.\n * @param key\n * @param bucket\n */\n deleteObject: (key: string, bucket?: string) => Promise<void>;\n\n /**\n * List the contents of a prefix.\n * @param prefix\n * @param options\n */\n listObjects: (prefix: string, options?: {\n bucket?: string,\n maxResults?: number,\n pageToken?: string\n }) => Promise<StorageListResult>;\n\n}\n\n/**\n * Result returned by list().\n * @public\n */\nexport declare interface StorageListResult {\n /**\n * References to prefixes (sub-folders). You can call list() on them to\n * get its contents.\n *\n * Folders are implicit based on '/' in the object paths.\n * For example, if a bucket has two objects '/a/b/1' and '/a/b/2', list('/a')\n * will return '/a/b' as a prefix.\n */\n prefixes: StorageReference[];\n /**\n * Objects in this directory.\n * You can call getMetadata() and getDownloadUrl() on them.\n */\n items: StorageReference[];\n /**\n * If set, there might be more results for this list. Use this token to resume the list.\n */\n nextPageToken?: string;\n}\n\n/**\n * Represents a reference to an S3-compatible storage object. Developers can\n * upload, download, and delete objects, as well as get/set object metadata.\n * @public\n */\nexport declare interface StorageReference {\n /**\n * Returns a s3:// URL for this object in the form\n * `s3://<bucket>/<path>/<to>/<object>`\n * @returns The s3:// URL.\n */\n toString(): string;\n\n /**\n * A reference to the root of this object's bucket.\n */\n root: StorageReference;\n /**\n * The name of the bucket containing this reference's object.\n */\n bucket: string;\n /**\n * The full path of this object.\n */\n fullPath: string;\n /**\n * The short name of this object, which is the last component of the full path.\n * For example, if path is 'full/path/image.png', name is 'image.png'.\n */\n name: string;\n\n /**\n * A reference pointing to the parent location of this reference, or null if\n * this reference is the root.\n */\n parent: StorageReference | null;\n}\n","/**\n * Email normalization — one implementation, because the database enforces it.\n *\n * `ensureAuthTablesExist` puts a `UNIQUE INDEX ON users (lower(email))` on the\n * auth table. That index decides what \"the same address\" means, and it does not\n * trim: to Postgres, `' foo@bar.com'` and `'foo@bar.com'` are two addresses and\n * both may exist. So every write that reaches the column has to agree with\n * every read, exactly, or the two disagree in the one direction that matters —\n * a row that exists and cannot be found.\n *\n * That is not hypothetical. The lookup path trimmed and the admin create paths\n * did not, so a user created through `POST /api/data/users` or\n * `POST /api/auth/admin/users` with a stray space was stored untrimmed,\n * survived the unique index alongside the real address, and was unreachable by\n * login forever after. The HTTP auth routes were unaffected only because Zod's\n * `.email()` happens to reject surrounding whitespace — a guard on a different\n * layer, for a different reason, that the admin paths do not sit behind.\n *\n * It lives in `common` because `server`, `server-postgres` and `server-mongo`\n * all write this column and must agree exactly, and `common` is the only\n * package all three already depend on.\n */\n\n/**\n * Canonical form of an email address: trimmed, lower-cased.\n *\n * Non-strings pass through untouched, so this is safe to apply to a value out\n * of a partial update payload whose type is not known yet.\n */\nexport function normalizeEmail<T>(email: T): T | string {\n return typeof email === \"string\" ? email.trim().toLowerCase() : email;\n}\n","import type { FilterValues, ListLimitBounds, LogicalCondition, VectorSearchParams } from \"@rebasepro/types\";\nimport { toCanonicalOp, resolveClientListLimit, ListLimitError, DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT } from \"@rebasepro/types\";\nimport { deserializeFilter, deserializeLogicalCondition, UnknownFilterOperatorError } from \"@rebasepro/common\";\nimport { QueryOptions } from \"../types\";\nimport { ApiError } from \"../errors\";\n\nexport const mapOperator = (op: string) => toCanonicalOp(op) ?? null;\n\n/**\n * A malformed query parameter, refused with a 400.\n *\n * Every rejection in this file is one of these, and every one of them is\n * `expected` — the flag `errorHandler` reads to log a routine outcome at debug\n * instead of warn. A client that mistypes an operator, a sort direction or a\n * limit is not an incident: nothing on the server is wrong, the request never\n * reached the database, and the caller has already been told what to fix in the\n * response body. Left at warn, a single frontend holding a stale field name\n * writes a `⚠️` line per request forever, and the warn level stops meaning\n * anything — which is why \"routine 4xx logs at WARN\" is a standing finding\n * against this API.\n *\n * Not a factory on `ApiError`: the class's members are part of the tracked\n * runtime surface (`api-surface/server.api.txt`), and this needs no addition to\n * it. `ApiError.unauthenticated` is the same idea one status code up.\n */\nfunction invalidParam(message: string, code: string, details?: unknown): ApiError {\n return new ApiError(400, code, message, details, true);\n}\n\n/**\n * Decode a filter, turning the shared codec's operator rejection into a 400.\n *\n * `deserializeFilter` lives in `@rebasepro/common`, which cannot throw an\n * `ApiError` — it does not depend on this package, and the browser SDK decodes\n * through the same function and has nothing to render one with. So it throws\n * `UnknownFilterOperatorError`, and the HTTP boundary is where that becomes a\n * status code. Same seam `parseLogicalGroup` uses for the nesting bound.\n *\n * Without this the operator string became a *value*: `?where={\"title\":\n * [\"!!\",\"Hello\"]}` compiled to `title IN ('!!','Hello')` and answered 200 with\n * the row the caller was filtering out, and `{\"id\":[\">>\",0]}` reached Postgres\n * and came back a 500 quoting `invalid input syntax for type integer`. Both are\n * malformed requests and now say so.\n */\nfunction decodeFilter(query: Record<string, unknown>): FilterValues<string> {\n try {\n return deserializeFilter(query);\n } catch (e) {\n if (e instanceof UnknownFilterOperatorError) {\n throw invalidParam(e.message, e.code, e.details);\n }\n throw e;\n }\n}\n\nfunction getLastValue(val: unknown): unknown {\n if (Array.isArray(val)) {\n return val[val.length - 1];\n }\n return val;\n}\n\n/**\n * Parse an `or(...)` / `and(...)` logical group from its wire form.\n *\n * The wire carries the inner conditions wrapped in parens (e.g.\n * `(status.eq.active,age.gte.18)`); we re-attach the `or`/`and` prefix and\n * delegate to the canonical filter dialect (`@rebasepro/common`). Values are\n * preserved as strings — type coercion is the schema-aware driver's job, so\n * this path stays byte-for-byte consistent with the SDK/admin path (which\n * also parses via the shared dialect).\n */\nfunction parseLogicalGroup(type: \"or\" | \"and\", raw: unknown): LogicalCondition | undefined {\n let inner = String(raw).trim();\n if (inner.startsWith(\"(\") && inner.endsWith(\")\")) {\n inner = inner.slice(1, -1);\n }\n inner = inner.trim();\n if (!inner) return undefined;\n let parsed;\n try {\n parsed = deserializeLogicalCondition(`${type}(${inner})`);\n } catch (e) {\n // The parser refuses a nesting depth no real filter reaches. That is a\n // request problem, and without this it surfaced as a 500 — the\n // unbounded version reached `RangeError: Maximum call stack size\n // exceeded`, which tells the caller nothing about their filter.\n throw invalidParam(\n `Invalid \\`${type}\\` parameter: ${e instanceof Error ? e.message : String(e)}`,\n \"INVALID_LOGICAL_GROUP\"\n );\n }\n return \"type\" in parsed ? parsed : undefined;\n}\n\n/**\n * Parse the `?where=` JSON filter object.\n *\n * This is the dialect the OpenAPI document publishes on every\n * `GET /api/data/{slug}` — `{\"status\":[\"==\",\"active\"]}`: field → canonical\n * `[WhereFilterOp, value]` tuple. It is normalized through the same\n * `deserializeFilter` as the `?field=op.value` params below, so a value that\n * arrives as a PostgREST dot-string (`{\"status\":\"eq.active\"}`) or as a bare\n * scalar (`{\"status\":\"active\"}`) compiles to the same condition. Unlike the\n * querystring dialect, JSON carries types — a number stays a number.\n *\n * A malformed value is a 400 rather than a silent drop: dropping the filter\n * would run the read unfiltered and return everything RLS happens to allow.\n */\nfunction parseWhereParam(raw: unknown): FilterValues<string> | undefined {\n const str = String(raw).trim();\n if (!str) return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(str);\n } catch {\n throw invalidParam(\n \"Invalid `where` parameter: expected a JSON object, e.g. {\\\"status\\\":[\\\"==\\\",\\\"active\\\"]}\",\n \"INVALID_WHERE\"\n );\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw invalidParam(\n \"Invalid `where` parameter: expected a JSON object mapping fields to conditions, \"\n + \"e.g. {\\\"status\\\":[\\\"==\\\",\\\"active\\\"]}\",\n \"INVALID_WHERE\"\n );\n }\n\n const filter = decodeFilter(parsed as Record<string, unknown>);\n return Object.keys(filter).length > 0 ? filter : undefined;\n}\n\ntype OrderByEntry = { field: string; direction: \"asc\" | \"desc\" };\n\nfunction invalidOrderBy(detail: string): never {\n throw invalidParam(\n `Invalid \\`orderBy\\` parameter: ${detail}. Expected \\`field\\`, \\`field:desc\\`, `\n + \"or a JSON array like [{\\\"field\\\":\\\"created_at\\\",\\\"direction\\\":\\\"desc\\\"}]\",\n \"INVALID_ORDER_BY\"\n );\n}\n\n/** `asc`/`desc`, in any case. Anything else is a request to sort in a way that does not exist. */\nfunction toDirection(raw: unknown, context: string): \"asc\" | \"desc\" {\n if (raw === undefined || raw === null) return \"asc\";\n if (typeof raw !== \"string\") invalidOrderBy(`${context} has a non-string \\`direction\\``);\n const lowered = raw.toLowerCase();\n if (lowered !== \"asc\" && lowered !== \"desc\") {\n invalidOrderBy(`${context} has direction '${raw}'`);\n }\n return lowered;\n}\n\n/** One entry: the canonical `{field, direction}`, or the `field:direction` shorthand as a string. */\nfunction toOrderByEntry(raw: unknown, index: number): OrderByEntry {\n const context = `entry ${index}`;\n if (typeof raw === \"string\") {\n // Split here rather than through `deserializeOrderBy`, which is the\n // *client* end of the codec and normalises anything that is not\n // literally \"desc\" to \"asc\". Routed through it, `?orderBy=x:DESC`\n // reached `toDirection` already collapsed to \"asc\" and answered 200\n // with the rows in the opposite order — a newest-first list showing\n // the oldest rows — and `x:sideways` did the same. The direction token\n // has to arrive here raw for `toDirection` to have anything to refuse.\n const idx = raw.indexOf(\":\");\n const field = (idx === -1 ? raw : raw.slice(0, idx)).trim();\n if (!field) invalidOrderBy(`${context} is an empty field name`);\n return { field, direction: idx === -1 ? \"asc\" : toDirection(raw.slice(idx + 1), context) };\n }\n if (typeof raw !== \"object\" || raw === null || Array.isArray(raw)) {\n invalidOrderBy(`${context} is not a field name or a {field, direction} object`);\n }\n const entry = raw as Record<string, unknown>;\n if (typeof entry.field !== \"string\" || entry.field.trim() === \"\") {\n invalidOrderBy(`${context} has no \\`field\\``);\n }\n return { field: entry.field, direction: toDirection(entry.direction, context) };\n}\n\n/**\n * Parse the `orderBy` query parameter.\n *\n * The field *name* has been validated against the schema for a while — an\n * `?orderBy=titel` is a 400 rather than 200 with unsorted rows, on the grounds\n * that silently dropping the sort leaves the caller believing in an order that\n * is not there. The parameter's *shape* was never checked the same way, and it\n * failed in exactly the same silent manner one layer earlier: whatever\n * `JSON.parse` returned was assigned to an option declared as an array of\n * `{field, direction}`, and the REST layer reads only `orderBy[0].field`. So\n * `?orderBy={\"field\":\"name\"}` — an object rather than an array, and the most\n * natural thing for a client to try — read `undefined`, dropped the ORDER BY,\n * and answered 200. So did a number, a boolean, `null`, and `[\"name\"]`.\n *\n * This refuses those, the way `parseWhereParam` above already refuses a\n * malformed filter and for the same reason. What it keeps working is every\n * shape that worked before: the `field` and `field:desc` shorthands, and the\n * canonical JSON array.\n */\nfunction parseOrderByParam(raw: unknown): OrderByEntry[] | undefined {\n if (Array.isArray(raw)) {\n // A repeated query parameter arrives pre-split; treat it as the list.\n return raw.length === 0 ? undefined : raw.map(toOrderByEntry);\n }\n\n const str = String(raw).trim();\n if (!str) return undefined;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(str);\n } catch {\n // Not JSON at all, so it is the `field:direction` shorthand.\n return [toOrderByEntry(str, 0)];\n }\n\n // `JSON.parse` succeeding says nothing about the shape being usable.\n if (Array.isArray(parsed)) {\n if (parsed.length === 0) return undefined;\n return parsed.map(toOrderByEntry);\n }\n if (typeof parsed === \"string\") return [toOrderByEntry(parsed, 0)];\n if (typeof parsed === \"object\" && parsed !== null) {\n // A bare `{field, direction}` is a near miss rather than nonsense, but\n // accepting it would leave two spellings of one parameter. Name it.\n invalidOrderBy(\"a single object was given where a JSON array was expected\");\n }\n invalidOrderBy(`${typeof parsed} is not a field name or a list of them`);\n}\n\n// Re-exported for callers/tests that reference the REST list bounds. The\n// numbers and the rule live in `@rebasepro/types` so the REST parser and the\n// WebSocket ingress enforce ONE shared guarantee. See `resolveClientListLimit`.\nexport { DEFAULT_LIST_LIMIT, DEFAULT_VECTOR_LIST_LIMIT, MAX_LIST_LIMIT } from \"@rebasepro/types\";\n\n/**\n * Overridable list-pagination bounds for {@link parseQueryOptions}. Without\n * these, `GET /<collection>` with no `?limit` would buffer the ENTIRE table\n * into a JS array + JSON response (a trivial OOM/DoS), and `?limit=100000000`\n * would be honoured verbatim.\n */\nexport interface ListLimitOptions {\n /**\n * Page size used when the client sends no `?limit`. Applied to plain and\n * text-search reads — a vector search falls back to its own default (10).\n */\n defaultLimit?: number;\n /** Largest `?limit` a client may ask for. A larger one is a 400, not a clamp. */\n maxLimit?: number;\n}\n\n/**\n * {@link resolveClientListLimit} for an HTTP route: the same bounds, answered\n * with a 400 rather than a 500.\n *\n * The shared resolver throws a `ListLimitError`, which carries `status` — but\n * the Hono error handler discriminates on `statusCode`, so an unconverted one\n * reaches the client as `INTERNAL_ERROR` with its message stripped, telling the\n * caller nothing about the parameter it got wrong. Every REST list ingress\n * routes its `limit` through here so all of them name the ceiling the same way.\n */\nexport function resolveListLimitParam(\n rawLimit: number | string | null | undefined,\n opts: ListLimitBounds & { vectorSearch?: boolean } = {}\n): number {\n try {\n return resolveClientListLimit(rawLimit, opts);\n } catch (e) {\n if (e instanceof ListLimitError) {\n throw invalidParam(e.message, \"INVALID_LIMIT\");\n }\n throw e;\n }\n}\n\n/**\n * Parse query parameters into QueryOptions\n */\nexport function parseQueryOptions(\n query: Record<string, unknown>,\n limits: ListLimitOptions = {}\n): QueryOptions {\n const options: QueryOptions = {};\n const rawLimit = getLastValue(query.limit) as number | string | null | undefined;\n\n const offsetVal = getLastValue(query.offset);\n if (offsetVal) options.offset = parseInt(String(offsetVal));\n\n const pageVal = getLastValue(query.page);\n if (pageVal) {\n const page = parseInt(String(pageVal));\n // Page stride uses the same bounded page size the read will use, so\n // pages neither overlap nor gap. (Vector search never paginates by\n // page, so the plain/text default is correct here.)\n const limit = resolveListLimitParam(rawLimit, {\n defaultLimit: limits.defaultLimit,\n maxLimit: limits.maxLimit\n });\n options.offset = (page - 1) * limit;\n }\n\n // ── Logical conditions (or / and) ──────────────────────────────────\n const orVal = getLastValue(query.or);\n const andVal = getLastValue(query.and);\n if (orVal) {\n const logical = parseLogicalGroup(\"or\", orVal);\n if (logical) options.logical = logical;\n } else if (andVal) {\n const logical = parseLogicalGroup(\"and\", andVal);\n if (logical) options.logical = logical;\n }\n\n // ── PostgREST-style field filters: ?field=op.value ─────────────────\n // Delegate to the canonical filter dialect (the single source of truth\n // for the wire grammar: operator codes, list/escape handling, implicit\n // eq). Values stay strings; the schema-aware driver coerces them to\n // column types. This keeps the REST path byte-for-byte consistent with\n // the SDK/admin path, which parses through the same `deserializeFilter`.\n //\n // `where` is reserved: it is the JSON filter dialect (see\n // `parseWhereParam`), not a column named \"where\". Leaving it out of this\n // list made the documented `?where={...}` compile as a filter on a\n // nonexistent field — which used to be dropped, widening the read to the\n // whole table, and is now a 400 `UNKNOWN_FILTER_FIELD`.\n const reservedQueryKeys = [\"limit\", \"offset\", \"page\", \"orderBy\", \"include\", \"fields\", \"searchString\", \"searchExplain\", \"vector_search\", \"vector\", \"vector_distance\", \"vector_threshold\", \"or\", \"and\", \"where\"];\n const filterDict: Record<string, unknown> = {};\n for (const [key, rawValue] of Object.entries(query)) {\n if (reservedQueryKeys.includes(key)) continue;\n filterDict[key] = rawValue;\n }\n // Both dialects may be sent together; an explicit `?field=op.value` wins\n // over the same field inside `where`, being the more specific request.\n const whereVal = getLastValue(query.where);\n const where = {\n ...(whereVal !== undefined && whereVal !== null ? parseWhereParam(whereVal) : undefined),\n ...decodeFilter(filterDict)\n };\n if (Object.keys(where).length > 0) {\n options.where = where;\n }\n\n // Sorting\n const orderByVal = getLastValue(query.orderBy);\n if (orderByVal) {\n options.orderBy = parseOrderByParam(orderByVal);\n }\n\n // Relation includes\n const includeVal = getLastValue(query.include);\n if (includeVal) {\n const includeStr = String(includeVal).trim();\n if (includeStr === \"*\") {\n options.include = [\"*\"];\n } else {\n options.include = includeStr.split(\",\").map(s => s.trim()).filter(Boolean);\n }\n }\n\n // Field selection\n const fieldsVal = getLastValue(query.fields);\n if (fieldsVal) {\n const fieldsStr = String(fieldsVal).trim();\n options.fields = fieldsStr.split(\",\").map(s => s.trim()).filter(Boolean);\n }\n\n // ── Vector similarity search ───────────────────────────────────────\n // Every rejection here is a malformed *request*, so it must carry a 400.\n // A bare `Error` reaches the handler with no `statusCode` and no known\n // `code`, which makes it a 500 — logged with a full stack as an incident,\n // and answered with \"An unexpected error occurred\", because the handler\n // only forwards a message to the client below 500. The caller was told\n // nothing about what it got wrong.\n const vectorSearchVal = getLastValue(query.vector_search);\n const vectorVal = getLastValue(query.vector);\n if (vectorSearchVal && vectorVal) {\n const vectorStr = String(vectorVal);\n let decoded: unknown;\n try {\n decoded = JSON.parse(vectorStr);\n } catch {\n decoded = undefined;\n }\n // Validated outside the `try` on purpose: inside it, the thrown\n // ApiError would be caught by its own `catch` and re-thrown as\n // something else.\n if (!Array.isArray(decoded) || !decoded.every(v => typeof v === \"number\")) {\n throw invalidParam(\n \"Invalid `vector` format. Expected a JSON array of numbers, e.g. [0.1,0.2,0.3]\",\n \"INVALID_VECTOR\"\n );\n }\n const queryVector = decoded as number[];\n\n const distanceParamVal = getLastValue(query.vector_distance);\n const distanceParam = distanceParamVal ? String(distanceParamVal) : \"cosine\";\n if (distanceParam !== \"cosine\" && distanceParam !== \"l2\" && distanceParam !== \"inner_product\") {\n throw invalidParam(\n `Invalid \\`vector_distance\\`: ${distanceParam}. Expected: cosine, l2, or inner_product`,\n \"INVALID_VECTOR_DISTANCE\"\n );\n }\n\n const vectorSearch: VectorSearchParams = {\n property: String(vectorSearchVal),\n vector: queryVector,\n distance: distanceParam\n };\n\n const thresholdVal = getLastValue(query.vector_threshold);\n if (thresholdVal) {\n const threshold = parseFloat(String(thresholdVal));\n if (isNaN(threshold)) {\n throw invalidParam(\n \"Invalid `vector_threshold`. Expected a number.\",\n \"INVALID_VECTOR_THRESHOLD\"\n );\n }\n vectorSearch.threshold = threshold;\n }\n\n options.vectorSearch = vectorSearch;\n }\n\n // Resolve the limit LAST — once we know whether this is a vector search —\n // so a client-supplied limit above the ceiling is refused with a 400 and an\n // absent one falls back to the correct mode default (plain/text =\n // defaultLimit, vector = 10). Without this a bare `GET /<collection>` would\n // return the whole table. Shared with the WebSocket ingress via\n // `resolveClientListLimit`.\n options.limit = resolveListLimitParam(rawLimit, {\n vectorSearch: !!options.vectorSearch,\n defaultLimit: limits.defaultLimit,\n maxLimit: limits.maxLimit\n });\n\n return options;\n}\n","/**\n * Permission guard for Service API Keys.\n *\n * Checks whether an API key's permission set allows a specific operation\n * on a specific collection. Used by the REST API generator middleware to\n * enforce fine-grained access control.\n *\n * @module\n */\n\nimport type { ApiKeyPermission } from \"./api-key-types\";\n\n/** Operations that map to HTTP methods. */\nexport type ApiKeyOperation = \"read\" | \"write\" | \"delete\";\n\n/**\n * Map an HTTP method string to an `ApiKeyOperation`.\n *\n * - `GET`, `HEAD`, `OPTIONS` → `\"read\"`\n * - `POST`, `PUT`, `PATCH` → `\"write\"`\n * - `DELETE` → `\"delete\"`\n */\nexport function httpMethodToOperation(method: string): ApiKeyOperation {\n const upper = method.toUpperCase();\n switch (upper) {\n case \"GET\":\n case \"HEAD\":\n case \"OPTIONS\":\n return \"read\";\n case \"POST\":\n case \"PUT\":\n case \"PATCH\":\n return \"write\";\n case \"DELETE\":\n return \"delete\";\n default:\n return \"read\";\n }\n}\n\n/**\n * Check whether the given permissions array allows `operation` on `collection`.\n *\n * Supports the `\"*\"` wildcard for the collection field, which matches any\n * collection. Returns `true` if at least one permission entry grants access.\n *\n * @param permissions - The API key's permission entries.\n * @param collection - The target collection slug.\n * @param operation - The requested operation.\n * @returns `true` if the operation is permitted.\n */\nexport function isOperationAllowed(\n permissions: ApiKeyPermission[],\n collection: string,\n operation: ApiKeyOperation\n): boolean {\n for (const perm of permissions) {\n const collectionMatch = perm.collection === \"*\" || perm.collection === collection;\n if (collectionMatch && perm.operations.includes(operation)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check whether the given permissions array allows a storage operation.\n *\n * Storage, like functions, lives outside the collection namespace: an entry\n * with collection `\"storage\"` grants storage access for the listed\n * operations (GET routes → `read`, upload/folder/tus → `write`,\n * DELETE routes → `delete`), and the global `\"*\"` wildcard also matches.\n * A collection-scoped key gets no storage access at all.\n *\n * Matching is exactly {@link isOperationAllowed} with `\"storage\"` as the\n * resource name — delegated so the semantics can never drift.\n */\nexport function isStorageAllowed(\n permissions: ApiKeyPermission[],\n operation: ApiKeyOperation\n): boolean {\n return isOperationAllowed(permissions, \"storage\", operation);\n}\n\n/**\n * Check whether the given permissions array allows invoking a custom function.\n *\n * Functions live outside the collection namespace, so they have their own\n * resource names in the permission list:\n *\n * - `{ collection: \"functions\", ... }` grants every function\n * - `{ collection: \"functions/<name>\", ... }` grants a single function\n * - the global `\"*\"` wildcard (full-access keys) also matches\n *\n * The operation is derived from the HTTP method as usual (GET → read,\n * POST/PUT/PATCH → write, DELETE → delete). The functions index route is\n * checked as `functionName === \"\"`, which only the `\"functions\"` and `\"*\"`\n * entries can grant.\n *\n * A collection-scoped key (e.g. read-only on `events`) therefore can NOT\n * invoke functions — before this guard existed, any valid key could call\n * every function.\n */\nexport function isFunctionAllowed(\n permissions: ApiKeyPermission[],\n functionName: string,\n operation: ApiKeyOperation\n): boolean {\n for (const perm of permissions) {\n const match = perm.collection === \"*\"\n || perm.collection === \"functions\"\n || (functionName !== \"\" && perm.collection === `functions/${functionName}`);\n if (match && perm.operations.includes(operation)) {\n return true;\n }\n }\n return false;\n}\n","import type { AuthRepository } from \"./interfaces\";\nimport type { AccessTokenPayload } from \"./jwt\";\nimport { logger } from \"../utils/logger\";\n\n/**\n * Has this access token been revoked?\n *\n * `logout`, `change-password`, `reset-password` and `DELETE /auth/sessions` all\n * stamp a `tokensValidAfter` watermark on the user. Every one of them also\n * deletes refresh-token rows, which is what made the gap easy to miss: the\n * session really is gone, and the *refresh* path really does check the\n * watermark — so signing out looked like it worked.\n *\n * The access token was untouched. It is a bearer credential that nothing\n * consulted a database about, so it stayed valid for its full lifetime after\n * every one of those actions. \"Sign out everywhere\" left the stolen token\n * working; so did changing your password because you thought it had leaked.\n *\n * The watermark had exactly one read in the repository, on refresh. This adds\n * the other one.\n *\n * ## Cost\n *\n * One indexed lookup per request, on the paths that already make one. The\n * adapter re-reads roles for every authenticated request; the admin routes now\n * do too. Both call this with the row they were already fetching in mind — a\n * repository that wants to serve both from one query is free to cache\n * internally, but nothing here assumes it.\n *\n * ## Failure\n *\n * Fails **open**, deliberately, and this is the one place in the auth stack\n * where that is right. The watermark is an extra revocation signal layered over\n * a token that has already been verified — signature, expiry and purpose all\n * checked. Refusing every request when the database is unreachable would turn a\n * transient outage into a total sign-out of an entire deployment, and the\n * attacker this protects against needs to have already stolen a live token. The\n * failure is logged at warn so it is visible rather than silent.\n */\nexport async function isAccessTokenRevoked(\n authRepo: Pick<AuthRepository, \"getTokensValidAfter\">,\n payload: Pick<AccessTokenPayload, \"uid\" | \"iat\">\n): Promise<boolean> {\n // A repository that does not implement the watermark cannot revoke, and\n // says so by absence. Nothing to check.\n if (typeof authRepo.getTokensValidAfter !== \"function\") return false;\n\n // A token with no `iat` cannot be placed relative to the watermark. Tokens\n // minted before `iat` was carried through verification are in this class,\n // and they expire on their own; treating them as revoked would sign out\n // every live session on deploy.\n if (typeof payload.iat !== \"number\") return false;\n\n let validAfter: Date | null;\n try {\n validAfter = await authRepo.getTokensValidAfter(payload.uid);\n } catch (error) {\n logger.warn(\"[Auth] Could not read the token revocation watermark; allowing the request\", {\n uid: payload.uid,\n error\n });\n return false;\n }\n\n if (!validAfter) return false;\n\n // `iat` is whole seconds; the watermark is a millisecond timestamp. Compare\n // in seconds and floor the watermark, so a token issued in the same second\n // as the revocation is treated as revoked rather than surviving on a\n // rounding artefact.\n const issuedAtSec = payload.iat;\n const revokedFromSec = Math.floor(validAfter.getTime() / 1000);\n return issuedAtSec < revokedFromSec;\n}\n","/**\n * Which role names carry administrative privilege.\n *\n * One definition, because there used to be several and they disagreed.\n * `requireAdmin` accepted `admin` **or** `schema-admin`; the guard that refuses\n * a dangerous `defaultRole` compared against `admin` alone. So\n * `AUTH_DEFAULT_ROLE=schema-admin` passed the guard and made every public\n * registrant an administrator — and, since a `schema-admin` may edit users, one\n * of them could then grant themselves real `admin` and keep it.\n *\n * The guard and the check have to read the same list or the gap comes back, so\n * neither of them owns it.\n *\n * `schema-admin` is here deliberately: it can reach the schema editor and the\n * SQL surfaces, which is administrative by any definition that matters. If a\n * genuinely lesser role is added later, it does not belong in this list — it\n * belongs in a capability check of its own.\n */\nexport const ADMINISTRATIVE_ROLES = [\"admin\", \"schema-admin\"] as const;\n\nexport type AdministrativeRole = (typeof ADMINISTRATIVE_ROLES)[number];\n\n/** Does this single role name carry administrative privilege? */\nexport function isAdministrativeRole(role: string): role is AdministrativeRole {\n return (ADMINISTRATIVE_ROLES as readonly string[]).includes(role);\n}\n\n/** Does any role in this list carry administrative privilege? */\nexport function hasAdministrativeRole(roles: readonly string[] | null | undefined): boolean {\n return !!roles?.some(isAdministrativeRole);\n}\n","/**\n * Shared RLS (Row-Level Security) scoping helper.\n *\n * DataDrivers may implement a `withAuth()` method that returns a scoped\n * clone of the driver with RLS policies applied for the given user.\n * This is database-specific (e.g. Postgres SET LOCAL ROLE) and is not\n * part of the core DataDriver interface.\n *\n * This module provides the shared duck-typing logic used by the\n * adapter-aware middleware.\n *\n * @module\n */\n\nimport type { DataDriver } from \"@rebasepro/types\";\n\n/**\n * The identity the trusted server plane runs as: `rebase.dataAsAdmin`, and any\n * caller presenting the service key.\n *\n * Naming it makes the privilege legible, because it is narrower than it reads.\n * This is **not** an RLS bypass — a driver scoped with it is an\n * `AuthenticatedPostgresBackendDriver`, so every statement runs in a\n * transaction that has done `SET LOCAL ROLE rebase_user` with\n * `app.uid = 'service'`, and policies are evaluated. Two consequences worth\n * knowing before you write a policy:\n *\n * - It passes the default policies through their `rolesOverlap(['admin'])`\n * arm — the same arm an application user holding the `admin` role passes.\n * - `policy.serverContext()` compiles to `auth.uid() IS NULL` and is therefore\n * **false** for it. A collection with `disableDefaultPolicies: true` whose\n * only rule is `serverContext()` denies these writes (42501) and returns\n * zero rows for these reads.\n *\n * The true bypass is `rebase.sql()`, which runs on the owner connection and\n * never goes near `withAuth`.\n */\nexport const SERVICE_IDENTITY: { uid: string; roles: string[] } = { uid: \"service\", roles: [\"admin\"] };\n\n/**\n * A DataDriver that supports RLS scoping via `withAuth()`.\n *\n * This is not part of the public DataDriver interface because not all\n * database implementations support RLS. Drivers that do (e.g. Postgres)\n * extend DataDriver with this method.\n */\ninterface RLSScopedDriver extends DataDriver {\n withAuth(user: { uid: string; roles?: string[] }): Promise<DataDriver>;\n}\n\n/**\n * Returns true if the driver supports RLS scoping via `withAuth()`.\n */\nfunction isRLSScopedDriver(driver: DataDriver): driver is RLSScopedDriver {\n return \"withAuth\" in driver && typeof (driver as Record<string, unknown>).withAuth === \"function\";\n}\n\n/**\n * Scope a DataDriver via `withAuth()` for RLS.\n *\n * SECURITY: If `withAuth()` is available but fails, the error is re-thrown\n * so the request is **denied** rather than proceeding with unscoped access\n * (fail-closed behavior).\n *\n * If the driver does not support RLS, the original driver is returned.\n *\n * @param driver - The DataDriver to scope.\n * @param user - The authenticated user identity for RLS.\n * @returns The RLS-scoped DataDriver (or the original if RLS is unsupported).\n */\nexport async function scopeDataDriver(\n driver: DataDriver,\n user: { uid: string; roles?: string[] }\n): Promise<DataDriver> {\n if (isRLSScopedDriver(driver)) {\n // Fail closed — do NOT catch and swallow errors here.\n // If RLS scoping fails the request must be rejected.\n return await driver.withAuth(user);\n }\n return driver;\n}\n","/**\n * Cryptographic utility functions for auth.\n *\n * @module\n */\n\nimport { timingSafeEqual } from \"crypto\";\n\n/**\n * Constant-time string comparison to prevent timing attacks.\n *\n * Used for comparing service keys, tokens, and other secrets where\n * timing side-channels could leak information about the expected value.\n *\n * @param a - First string to compare.\n * @param b - Second string to compare.\n * @returns `true` if the strings are identical, `false` otherwise.\n */\nexport function safeCompare(a: string, b: string): boolean {\n // Encode first, then size the padding by BYTE length.\n //\n // Allocating by `String.length` and writing into it truncates at the buffer\n // boundary, so any multi-byte character shortens the region actually\n // compared and the trailing bytes are never examined. With a secret\n // containing one non-ASCII character, a guess matching everything but the\n // final character compares equal — the exact failure this function exists to\n // prevent.\n const bytesA = Buffer.from(a, \"utf8\");\n const bytesB = Buffer.from(b, \"utf8\");\n\n const length = Math.max(bytesA.length, bytesB.length);\n const paddedA = Buffer.alloc(length);\n const paddedB = Buffer.alloc(length);\n bytesA.copy(paddedA);\n bytesB.copy(paddedB);\n\n try {\n // The length check is folded in after the constant-time compare so an\n // early return cannot itself leak the length.\n return timingSafeEqual(paddedA, paddedB) && bytesA.length === bytesB.length;\n } catch {\n return false;\n }\n}\n","/**\n * Parsing of the `Authorization: Bearer <token>` header.\n *\n * Its own module rather than a helper inside `middleware.ts`, because the\n * API-key middleware needs it too and `middleware.ts` already imports from\n * there — putting it in either one would close an import cycle.\n *\n * @module\n */\n\n/**\n * Pull the token out of an `Authorization: Bearer <token>` header.\n *\n * RFC 7235 §2.1 makes the auth-scheme name case-insensitive, and plenty of\n * clients send `bearer` — HTTP libraries that lower-case what they emit,\n * hand-written curl, proxies that normalise headers. Matching `\"Bearer \"`\n * exactly turned those into a 401 that, from the caller's side, is\n * indistinguishable from a rejected token; people spend an afternoon\n * regenerating credentials that were fine. Only the scheme is folded — the\n * token itself is returned byte-for-byte.\n *\n * Returns `undefined` when there is no header or it names another scheme.\n * That is deliberately distinct from an empty token (`Bearer ` with nothing\n * after it), which callers still route into verification so it fails as a bad\n * token rather than as a missing header.\n */\nexport function extractBearerToken(authHeader: string | undefined | null): string | undefined {\n if (!authHeader) return undefined;\n const separator = authHeader.indexOf(\" \");\n if (separator < 0) return undefined;\n if (authHeader.slice(0, separator).toLowerCase() !== \"bearer\") return undefined;\n return authHeader.slice(separator + 1);\n}\n","/**\n * Hono middleware for authenticating requests via Service API Keys.\n *\n * This middleware is integrated into `createAuthMiddleware()` and\n * activates only when the bearer token starts with `rk_`. It:\n *\n * 1. Hashes the token with SHA-256\n * 2. Looks up the hash in the `rebase.api_keys` table\n * 3. Validates the key is not revoked and not expired\n * 4. Sets `c.set(\"user\", ...)` and `c.set(\"apiKey\", ...)` for downstream use\n * 5. Scopes the DataDriver via `withAuth()` using the API key's service identity\n *\n * Authorization is double-gated for API keys: the key's own permission list\n * (checked by the REST generator) is one ceiling, and Postgres RLS is another,\n * independent one — `withAuth()` runs API-key requests as the restricted\n * `rebase_user` role like any other caller. An `admin` key passes RLS via the\n * injected `default_admin` policies; a non-admin key (roles `[\"service\"]`,\n * uid `api-key:<id>`) only sees rows that a policy explicitly grants to the\n * `service` role or to the public. Owner-style policies\n * (`owner_id = auth.uid()`) never match an API key's synthetic uid.\n *\n * @module\n */\n\nimport { createHash } from \"crypto\";\nimport type { Context, MiddlewareHandler } from \"hono\";\nimport type { DataDriver } from \"@rebasepro/types\";\nimport type { HonoEnv } from \"../../api/types\";\nimport type { ApiKeyStore } from \"./api-key-store\";\nimport type { ApiKeyMasked } from \"./api-key-types\";\nimport { scopeDataDriver } from \"../rls-scope\";\nimport { extractBearerToken } from \"../bearer-token\";\nimport { httpMethodToOperation, isFunctionAllowed, isStorageAllowed } from \"./api-key-permission-guard\";\nimport { logger } from \"../../utils/logger\";\n\n/**\n * Check whether a token looks like a Rebase API key.\n */\nexport function isApiKeyToken(token: string): boolean {\n return token.startsWith(\"rk_\");\n}\n\n/**\n * Hash a plaintext API key token for database lookup.\n */\nfunction hashToken(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n/**\n * Options for the API key authentication handler.\n */\nexport interface ApiKeyAuthOptions {\n store: ApiKeyStore;\n driver: DataDriver;\n}\n\n/**\n * Validate an API key token and populate the Hono context.\n *\n * Returns `true` if the key is valid and context has been populated,\n * or returns an error Response if the key is invalid.\n *\n * This is NOT a standalone middleware — it's called from within\n * `createAuthMiddleware()` when a `rk_` prefixed token is detected.\n */\nexport async function validateApiKey(\n c: Context<HonoEnv>,\n token: string,\n options: ApiKeyAuthOptions\n): Promise<Response | true> {\n const { store, driver } = options;\n\n const hash = hashToken(token);\n const apiKey = await store.findByKeyHash(hash);\n\n if (!apiKey) {\n return c.json({\n error: { message: \"Invalid API key\",\ncode: \"UNAUTHORIZED\" }\n }, 401);\n }\n\n // Check revocation\n if (apiKey.revoked_at) {\n return c.json({\n error: { message: \"API key has been revoked\",\ncode: \"UNAUTHORIZED\" }\n }, 401);\n }\n\n // Check expiration\n if (apiKey.expires_at && new Date(apiKey.expires_at) < new Date()) {\n return c.json({\n error: { message: \"API key has expired\",\ncode: \"UNAUTHORIZED\" }\n }, 401);\n }\n\n // Set user identity — API keys represent service accounts\n const uid = `api-key:${apiKey.id}`;\n const roles: string[] = apiKey.admin ? [\"admin\", \"service\"] : [\"service\"];\n c.set(\"user\", { uid,\nroles });\n\n // Expose masked key metadata for downstream permission checks\n const masked: ApiKeyMasked = {\n id: apiKey.id,\n name: apiKey.name,\n key_prefix: apiKey.key_prefix,\n permissions: apiKey.permissions,\n admin: apiKey.admin,\n rate_limit: apiKey.rate_limit,\n created_by: apiKey.created_by,\n created_at: apiKey.created_at,\n updated_at: apiKey.updated_at,\n last_used_at: apiKey.last_used_at,\n expires_at: apiKey.expires_at,\n revoked_at: apiKey.revoked_at\n };\n // Store apiKey in the context for permission checking in api-generator\n c.set(\"apiKey\", masked);\n\n // Scope the DataDriver. API keys do NOT bypass RLS: withAuth() downgrades\n // to the restricted rebase_user role like every other caller. Admin keys\n // pass via the default_admin policies; non-admin keys are additionally\n // bound by whatever the collection policies grant the \"service\" role.\n try {\n const scopedDriver = await scopeDataDriver(driver, {\n uid,\n roles\n });\n c.set(\"driver\", scopedDriver);\n } catch (error) {\n logger.error(\"[AUTH] RLS scoping failed for API key\", { error: error });\n return c.json({\n error: { message: \"Internal authentication error\",\ncode: \"INTERNAL_ERROR\" }\n }, 500);\n }\n\n // Touch last_used_at in the background (non-blocking), debounced: every\n // API-key request on every surface routes through here, and per-request\n // UPDATEs would serialize on the single api_keys row for a busy key.\n // Minute-resolution is plenty for a \"last used\" display.\n const lastTouch = lastUsedTouchedAt.get(apiKey.id);\n const now = Date.now();\n if (!lastTouch || now - lastTouch >= LAST_USED_DEBOUNCE_MS) {\n lastUsedTouchedAt.set(apiKey.id, now);\n store.updateLastUsed(apiKey.id).catch(() => {\n // Swallowed intentionally — logged inside the store\n });\n }\n\n return true;\n}\n\n/** Per-process debounce state for last_used_at touches. */\nconst lastUsedTouchedAt = new Map<string, number>();\nconst LAST_USED_DEBOUNCE_MS = 60_000;\n\n/**\n * Shared 403 response for API-key permission denials outside the REST\n * generator (storage and functions guards). One envelope, one code — a\n * change to the error contract happens in one place.\n */\nfunction forbidApiKey(c: Context<HonoEnv>, operation: string, resource: string, grantHint: string): Response {\n return c.json({\n error: {\n message: `API key does not have \"${operation}\" permission for ${resource}. ` +\n `Grant it with a permission entry like { \"collection\": \"${grantHint}\", \"operations\": [\"${operation}\"] }.`,\n code: \"API_KEY_FORBIDDEN\"\n }\n }, 403);\n}\n\n/**\n * Permission guard for API-key requests to the storage router.\n *\n * Storage previously did not accept API keys at all (`rk_` tokens were\n * misparsed as JWTs and 401'd). Now that the pre-auth middleware\n * authenticates them, this guard decides what they may do: the key needs a\n * `\"storage\"` permission entry (or the global `\"*\"` wildcard) covering the\n * operation derived from the HTTP method. Requests not authenticated via an\n * API key pass through to the storage router's own auth gates.\n *\n * TUS resumable-upload routes (`/tus`, `/tus/:id`) are classified as `write`\n * for EVERY method: the protocol's offset check is a GET and its cancel is a\n * DELETE, but both are steps of an upload — a write-scoped key must be able\n * to complete (and abort) its own resumable upload without also holding\n * `read`/`delete` on stored objects.\n */\nexport function createStorageApiKeyGuard(): MiddlewareHandler<HonoEnv> {\n return async (c, next) => {\n const apiKey = c.get(\"apiKey\") as ApiKeyMasked | undefined;\n if (!apiKey) return next();\n\n const isTus = /\\/tus(\\/|$)/.test(c.req.path);\n const operation = isTus ? \"write\" : httpMethodToOperation(c.req.method);\n if (!isStorageAllowed(apiKey.permissions, operation)) {\n return forbidApiKey(c, operation, \"storage\", \"storage\");\n }\n\n return next();\n };\n}\n\n/**\n * Permission guard for API-key requests to the custom-functions router.\n *\n * The collection permission guard lives in the REST generator and never sees\n * function routes, so before this middleware existed ANY valid API key —\n * however narrowly scoped — could invoke every custom function. This guard\n * closes that: API-key requests must hold a `\"functions\"`/`\"functions/<name>\"`\n * permission entry (or the global `\"*\"` wildcard) for the derived operation.\n *\n * Non-API-key requests (JWT, service key, anonymous) pass through untouched —\n * functions decide their own auth for those, as before.\n *\n * @param mountPrefix - The path the functions router is mounted at\n * (e.g. `/api/functions`), used to extract the function\n * name from the request path.\n */\nexport function createFunctionApiKeyGuard(mountPrefix: string): MiddlewareHandler<HonoEnv> {\n return async (c, next) => {\n const apiKey = c.get(\"apiKey\") as ApiKeyMasked | undefined;\n if (!apiKey) return next();\n\n const path = c.req.path;\n const idx = path.indexOf(mountPrefix);\n const rest = idx < 0 ? \"\" : path.slice(idx + mountPrefix.length);\n const rawName = rest.split(\"/\").filter(Boolean)[0] ?? \"\";\n let functionName: string;\n try {\n functionName = decodeURIComponent(rawName);\n } catch {\n // Malformed percent-encoding (e.g. %ZZ) — fall back to the raw\n // segment rather than throwing a 500. It won't match any\n // functions/<name> entry, so only namespace-wide grants pass.\n functionName = rawName;\n }\n\n const operation = httpMethodToOperation(c.req.method);\n if (!isFunctionAllowed(apiKey.permissions, functionName, operation)) {\n const resource = functionName ? `function \"${functionName}\"` : \"the functions index\";\n return forbidApiKey(c, operation, resource, `functions${functionName ? `/${functionName}` : \"\"}`);\n }\n\n return next();\n };\n}\n\n/**\n * Standalone pre-auth middleware for `rk_` bearer tokens.\n *\n * Routers whose auth gate is JWT-based (`requireAuth` / `createRequireAuth` —\n * the admin surfaces: admin users/roles, api-keys management, cron, backups,\n * logs, schema editor) don't know about API keys. Mounting this middleware in\n * front of them authenticates `rk_` tokens and populates the request context;\n * the downstream gates then see the already-resolved user and apply their\n * role checks (`requireAdmin`) as usual — so an `admin: true` key passes and\n * a non-admin key is rejected with 403.\n *\n * Requests without an `rk_` bearer token pass through untouched. An invalid,\n * revoked, or expired `rk_` token is rejected here (401) rather than falling\n * through to be misparsed as a JWT.\n */\nexport function createApiKeyPreAuth(options: ApiKeyAuthOptions): MiddlewareHandler<HonoEnv> {\n return async (c, next) => {\n // Already validated by an earlier instance (e.g. the app-level\n // /admin/* pre-auth composing with a router-level one) — don't hit\n // the store twice.\n if (c.get(\"apiKey\")) return next();\n\n const token = extractBearerToken(c.req.header(\"authorization\")) ?? \"\";\n if (!token || !isApiKeyToken(token)) return next();\n\n const result = await validateApiKey(c, token, options);\n if (result !== true) return result;\n return next();\n };\n}\n","/**\n * Canonical storage keys and bucket names.\n *\n * Storage is not under RLS, so a `storageAuthorize` hook is the whole access\n * control model — and a hook can only be correct if the key it is shown is the\n * key that is written. That is the invariant this module exists to hold: one\n * canonical string, computed once per request, handed to the hook, to the\n * controller, and to the download token alike.\n *\n * ## Why rejecting beats stripping\n *\n * The previous `sanitizeStorageKey` *stripped* `../` in a single pass. Two\n * things were wrong with that, and only one of them was the obvious one.\n *\n * The obvious one: a single pass is not a fixed point. `....//` contains `../`\n * at offset 2, so removing it leaves `../` behind — the sanitizer manufactured\n * the traversal it was there to remove. `users/alice/....//bob/x` came out as\n * `users/alice/../bob/x`, which a prefix hook reads as alice's (it starts with\n * `users/alice/`) and the filesystem reads as bob's. The hook approved one\n * object and the controller wrote another.\n *\n * The subtler one, and the reason this is a rewrite rather than a loop: even a\n * correct strip is a silent rewrite. A caller who asks to store at `a/../b` and\n * gets an object at `a/b` was not protected, they were misled — and every later\n * read, ownership row and audit line now refers to a path nobody chose. So a key\n * that means something other than what it says is refused (400), not repaired.\n *\n * Note what is NOT traversal under this rule: `....` is an ordinary directory\n * name, and `users/alice/....//bob/x` canonicalizes to\n * `users/alice/..../bob/x` — still comfortably inside alice's prefix, which is\n * exactly right. Only a real `..` segment is refused.\n */\n\nimport path from \"node:path\";\n\n/** Longest key accepted, in UTF-16 code units. Matches the previous cap. */\nexport const MAX_STORAGE_KEY_LENGTH = 1024;\n\n/**\n * A key that cannot be canonicalized. Carries no path back to the caller\n * beyond what they sent, so it is safe to surface as a 400 message.\n */\nexport class InvalidStorageKeyError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidStorageKeyError\";\n }\n}\n\n/**\n * Canonicalize a caller-supplied storage key, or throw\n * {@link InvalidStorageKeyError}.\n *\n * Normalizations applied (safe, idempotent, and meaning-preserving):\n * - leading slashes removed — `/a/b` and `a/b` name the same object\n * - `.` segments and repeated slashes collapsed\n *\n * Refusals (the key means something other than what it says):\n * - any `..` segment, on either separator, at any depth\n * - null bytes\n * - keys longer than {@link MAX_STORAGE_KEY_LENGTH}\n *\n * A trailing slash is preserved: it is how the folder route marks a prefix.\n */\nexport function canonicalStorageKey(rawKey: string): string {\n if (rawKey.includes(\"\\0\")) {\n throw new InvalidStorageKeyError(\"Storage key contains a null byte.\");\n }\n if (rawKey.length > MAX_STORAGE_KEY_LENGTH) {\n throw new InvalidStorageKeyError(\n `Storage key exceeds the maximum length of ${MAX_STORAGE_KEY_LENGTH} characters.`\n );\n }\n\n // Split on both separators: `path.join` treats `\\` as a separator on\n // Windows, so `..\\` is traversal there even though POSIX reads it as a\n // filename. Checked against the RAW key, before any normalization — the\n // whole point is that `a/../b` is refused rather than quietly turned into\n // `b`.\n if (rawKey.split(/[\\\\/]/).some((segment) => segment === \"..\")) {\n throw new InvalidStorageKeyError(\n \"Storage key contains a '..' path segment. Keys must name an object directly.\"\n );\n }\n\n const withoutLeadingSlashes = rawKey.replace(/^\\/+/, \"\");\n if (withoutLeadingSlashes === \"\") return \"\";\n\n // Whether the key names a *directory* rather than an object: it ends with a\n // separator, or its last segment is the `.` that means \"this directory\".\n //\n // Recorded before normalizing, because `path.posix.normalize` drops the\n // distinction in one of those two spellings and not the other: `public/.`\n // becomes `public` while `public/./` stays `public/`. That asymmetry breaks\n // the rule this module states — a trailing slash is preserved, because it is\n // how the folder route marks a prefix — and it is not cosmetic on `list`,\n // where a prefix of `public` also matches `publicity/` and hands back keys\n // the caller never asked for.\n const denotesDirectory = /(?:^|\\/)\\.?$/.test(withoutLeadingSlashes);\n\n // Safe now: with no `..` segment in the input, `normalize` can only collapse\n // `.` and duplicate slashes — it cannot climb.\n const normalized = path.posix.normalize(withoutLeadingSlashes);\n\n // `normalize(\".\")`, and `normalize(\"./\")` → `./`; neither names an object.\n if (normalized === \".\" || normalized === \"./\") return \"\";\n\n // `normalize` re-introduces a leading `./` for keys like `.//a`.\n const key = normalized.replace(/^\\.\\//, \"\").replace(/^\\/+/, \"\");\n if (key === \"\") return \"\";\n return denotesDirectory && !key.endsWith(\"/\") ? `${key}/` : key;\n}\n\n/**\n * Canonicalize, or return `null` when the key is not canonicalizable.\n *\n * For callers that must fail closed without an exception — the download-token\n * middleware compares a request path against a granted path, and a key it\n * cannot canonicalize simply matches nothing.\n */\nexport function tryCanonicalStorageKey(rawKey: string): string | null {\n try {\n return canonicalStorageKey(rawKey);\n } catch {\n return null;\n }\n}\n\n/**\n * Longest bucket name accepted. 63 is the S3/GCS limit, and a local bucket is\n * one directory name, so the tighter of the two bounds everything.\n */\nexport const MAX_STORAGE_BUCKET_LENGTH = 63;\n\n/** A bucket name that does not name a bucket. See {@link canonicalStorageBucket}. */\nexport class InvalidStorageBucketError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidStorageBucketError\";\n }\n}\n\n/**\n * One path segment: letters, digits, `.`, `_`, `-`, first character\n * alphanumeric. Deliberately narrow — it is the intersection of what S3, GCS\n * and a filesystem directory all accept, and it makes `..`, `.tus-uploads`,\n * absolute paths and anything containing a separator unrepresentable.\n */\nconst STORAGE_BUCKET_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\n/**\n * Canonicalize a caller-supplied bucket name, or throw\n * {@link InvalidStorageBucketError}.\n *\n * The bucket is the *other* caller-controlled routing value in an upload\n * request, and it was the one nobody validated. `LocalStorageController`\n * builds `join(basePath, bucket)` and then checks containment against that\n * result, so a bucket of `../../etc` moved the boundary rather than crossing\n * it — the guard passed because the guard's reference point was the attacker's.\n * The containment check now resolves against the storage root, and this is the\n * check at the route boundary that stops the value before it gets there.\n *\n * A bucket is configuration, not user data: there is no legitimate caller that\n * needs a separator, a leading dot, or a `..` in one. So this refuses rather\n * than repairs, exactly as {@link canonicalStorageKey} does — a rewritten\n * bucket would silently store the object somewhere the caller did not ask for.\n *\n * Returns `undefined` when the caller named no bucket (absent, or an empty\n * form field), which is how every controller spells \"use my default\". An empty\n * string used to reach `getFullPath` and resolve to the storage *root* rather\n * than the `default` bucket, which is a third place a bare key did not\n * round-trip.\n */\nexport function canonicalStorageBucket(rawBucket: string | undefined | null): string | undefined {\n if (rawBucket === undefined || rawBucket === null || rawBucket === \"\") return undefined;\n if (rawBucket.length > MAX_STORAGE_BUCKET_LENGTH) {\n throw new InvalidStorageBucketError(\n `Storage bucket exceeds the maximum length of ${MAX_STORAGE_BUCKET_LENGTH} characters.`\n );\n }\n if (!STORAGE_BUCKET_PATTERN.test(rawBucket)) {\n throw new InvalidStorageBucketError(\n \"Storage bucket must be a single name of letters, digits, '.', '_' or '-', \" +\n \"starting with a letter or digit.\"\n );\n }\n return rawBucket;\n}\n","import { MiddlewareHandler, Context } from \"hono\";\nimport type { AuthRepository } from \"./interfaces\";\nimport { isAccessTokenRevoked } from \"./token-revocation\";\nimport { hasAdministrativeRole } from \"./admin-roles\";\nimport { ANONYMOUS_USER_ID, DataDriver, isPublicStoragePath } from \"@rebasepro/types\";\nimport { verifyAccessToken, AccessTokenPayload, isJwtConfigured, verifyDownloadToken } from \"./jwt\";\nimport type { HonoEnv } from \"../api/types\";\nimport { scopeDataDriver } from \"./rls-scope\";\nimport { safeCompare } from \"./crypto-utils\";\nimport { isApiKeyToken, validateApiKey } from \"./api-keys/api-key-middleware\";\nimport type { ApiKeyStore } from \"./api-keys/api-key-store\";\nimport { logger } from \"../utils/logger\";\nimport { extractBearerToken } from \"./bearer-token\";\n// A leaf module (node:path only), so this does not close an import cycle with\n// `storage/routes.ts` — which is the point: both sides of the token comparison\n// must derive a key with the same function, not with two copies of one rule.\nimport { tryCanonicalStorageKey } from \"../storage/keys\";\n\n// Re-exported from here because this is where callers look for it; the separate\n// module exists only so `api-key-middleware` can use it without closing an\n// import cycle with this file.\nexport { extractBearerToken };\n\n/**\n * Result from a custom auth validator.\n * - `false`/`null`/`undefined` = not authenticated\n * - `true` = authenticated as default user\n * - object with `uid` (or legacy `userId`) = authenticated with user info\n */\nexport type AuthResult = boolean | null | undefined | { uid?: string; userId?: string; roles?: string[]; [key: string]: unknown };\n\n/**\n * Options for creating an auth middleware via createAuthMiddleware()\n */\nexport interface AuthMiddlewareOptions {\n /** DataDriver to scope via withAuth() for RLS */\n driver: DataDriver;\n /**\n * Optional per-request driver resolver for multi-data-source backends.\n * Given the request context, returns the unscoped delegate to use (e.g.\n * Postgres vs Mongo, picked by the request's collection data source).\n * When omitted, `driver` is used for every request.\n */\n resolveDriver?: (c: Context<HonoEnv>) => DataDriver;\n /**\n * If true, return 401 when no valid token is present.\n *\n * **Defaults to `true` (secure by default).** Set to `false` only for\n * intentionally public endpoints where access control is fully delegated\n * to Postgres Row-Level Security policies.\n */\n requireAuth?: boolean;\n /** Optional custom validator (for non-JWT auth, e.g. external auth providers) */\n validator?: (c: Context<HonoEnv>) => Promise<AuthResult>;\n /**\n * A static secret key for server-to-server / script authentication.\n *\n * When a request sends `Authorization: Bearer <key>` and the key matches\n * this value, the request is granted admin-level access (uid: `service`,\n * roles: `[\"admin\"]`) **without** JWT verification. The driver is scoped\n * via `withAuth()` with the service identity.\n *\n * This is the Rebase equivalent of a Service Account key.\n * Set via `REBASE_SERVICE_KEY` in `.env` and pass through the backend config.\n *\n * **Security:** The comparison uses constant-time equality to prevent\n * timing attacks. The key must be at least 32 characters.\n */\n serviceKey?: string;\n /**\n * API key store for authenticating `rk_` prefixed tokens.\n * When set, tokens starting with `rk_` are validated against the\n * database instead of being treated as JWTs.\n */\n apiKeyStore?: ApiKeyStore;\n}\n\n/**\n * Hono middleware that requires a valid JWT token via Authorization header.\n * Returns 401 if token is missing or invalid.\n *\n * **Security:** Tokens are only accepted via the `Authorization: Bearer`\n * header. Query-string tokens (`?token=`) are intentionally NOT accepted\n * here because URLs leak into access logs, proxies, Referer headers, and\n * browser history. Use {@link queryTokenAuth} on routes that legitimately\n * need query-string tokens (e.g. storage file serving for `<img src>`).\n */\nexport const requireAuth: MiddlewareHandler<HonoEnv> = async (\n c,\n next\n) => {\n // A prior middleware (queryTokenAuth, API-key pre-auth) may have already\n // resolved the user — respect it instead of re-parsing the token as a JWT.\n if (c.get(\"user\")) return next();\n\n const token = extractBearerToken(c.req.header(\"authorization\"));\n\n if (token === undefined) {\n return c.json({\n error: {\n message: \"Authorization header missing or invalid\",\n code: \"UNAUTHORIZED\"\n }\n }, 401);\n }\n\n const payload = verifyAccessToken(token);\n\n if (!payload) {\n return c.json({\n error: {\n message: \"Invalid or expired token\",\n code: \"UNAUTHORIZED\"\n }\n }, 401);\n }\n\n c.set(\"user\", payload);\n return next();\n};\n\n/**\n * Factory that creates a requireAuth middleware with optional service key support.\n *\n * When `serviceKey` is provided, the middleware will check if the Bearer token\n * matches the service key using constant-time comparison. If it matches, the\n * request is authenticated as a service user with admin privileges.\n *\n * This allows admin routes (which use standalone requireAuth + requireAdmin)\n * to be accessed via service keys for scripts and server-to-server calls.\n */\nexport function createRequireAuth(options?: {\n serviceKey?: string;\n /**\n * Read this user's roles from the database, replacing whatever the token\n * claims.\n *\n * Without it, `requireAdmin` downstream trusts the `roles` array inside the\n * access token — so demoting an administrator does nothing until that token\n * expires, and in the meantime the demoted admin can call\n * `PUT /api/admin/users/<self>` and put the role back for good. The data\n * plane already re-reads roles per request (`builtin-auth-adapter`); the\n * admin routes, which are the ones that can grant roles, did not.\n *\n * Optional because two call sites have no repository in scope. A route that\n * can supply one should: the cost is one indexed lookup on requests that\n * are already administrative.\n */\n resolveRoles?: (uid: string) => Promise<string[]>;\n /**\n * Repository used to check the token-revocation watermark.\n *\n * Separate from {@link resolveRoles} only because that one is a narrow\n * function; a caller with a repository should pass it here so a token\n * invalidated by `logout` or a password reset stops working on admin routes\n * too, not just on the data plane.\n */\n revocationRepo?: Pick<AuthRepository, \"getTokensValidAfter\">;\n}): MiddlewareHandler<HonoEnv> {\n if (!options?.serviceKey) return requireAuth;\n\n const key = options.serviceKey;\n const resolveRoles = options.resolveRoles;\n const revocationRepo = options.revocationRepo;\n return async (c, next) => {\n // Respect a user already resolved upstream (e.g. API-key pre-auth).\n if (c.get(\"user\")) return next();\n\n const token = extractBearerToken(c.req.header(\"authorization\"));\n\n if (token === undefined) {\n return c.json({\n error: {\n message: \"Authorization header missing or invalid\",\n code: \"UNAUTHORIZED\"\n }\n }, 401);\n }\n\n // Check service key first (constant-time comparison)\n if (safeCompare(token, key)) {\n c.set(\"user\", { uid: \"service\",\nroles: [\"admin\"] } as AccessTokenPayload);\n return next();\n }\n\n // Fall back to JWT verification\n const payload = verifyAccessToken(token);\n\n if (!payload) {\n return c.json({\n error: {\n message: \"Invalid or expired token\",\n code: \"UNAUTHORIZED\"\n }\n }, 401);\n }\n\n if (resolveRoles) {\n try {\n // Same watermark the data plane checks. An admin route is the\n // last place a revoked token should still work.\n if (revocationRepo && await isAccessTokenRevoked(revocationRepo, payload)) {\n return c.json({\n error: { message: \"Session has been revoked\", code: \"SESSION_REVOKED\" }\n }, 401);\n }\n c.set(\"user\", { ...payload,\nroles: await resolveRoles(payload.uid) });\n return next();\n } catch (error) {\n // Fail closed. The token's own claim is exactly what must not be\n // trusted here, so falling back to it would reinstate the bug\n // the lookup exists to close.\n logger.warn(\"[Auth] Could not resolve roles for an admin-gated request\", {\n uid: payload.uid,\n error\n });\n return c.json({\n error: {\n message: \"Could not verify your permissions. Please try again.\",\n code: \"ROLE_LOOKUP_FAILED\"\n }\n }, 503);\n }\n }\n\n c.set(\"user\", payload);\n return next();\n };\n}\n\n/**\n * Middleware that requires the user to have an admin or schema-admin role.\n * Must be used AFTER requireAuth or on a route where user is guaranteed.\n */\nexport const requireAdmin: MiddlewareHandler<HonoEnv> = async (\n c,\n next\n) => {\n const user = c.get(\"user\");\n if (!user) {\n return c.json({\n error: {\n message: \"User not authenticated. requireAuth middleware is missing?\",\n code: \"UNAUTHORIZED\"\n }\n }, 401);\n }\n\n const roles = (typeof user === \"object\" && user !== null && \"roles\" in user) ? (user.roles || []) : [];\n const isAdmin = hasAdministrativeRole(roles as string[]);\n\n if (!isAdmin) {\n return c.json({\n error: {\n message: \"Admin privileges required for this operation\",\n code: \"FORBIDDEN\"\n }\n }, 403);\n }\n\n return next();\n};\n\n\n/**\n * Middleware that optionally extracts user from JWT via Authorization header.\n * Does not return 401 if token is missing — allows anonymous access.\n *\n * Query-string tokens are NOT accepted here. Use {@link queryTokenAuth}\n * on routes that need them.\n */\nexport const optionalAuth: MiddlewareHandler<HonoEnv> = async (\n c,\n next\n) => {\n // Skip if a prior middleware (e.g. queryTokenAuth) already set the user.\n if (c.get(\"user\")) return next();\n\n const token = extractBearerToken(c.req.header(\"authorization\"));\n\n // A backend that authenticates through an adapter (Firebase, Clerk) never\n // calls `configureJwt`, so verifying here would throw — turning a route\n // that had already accepted anonymous callers into a 500 for every\n // request that happens to carry a bearer token. Anonymous is the answer.\n if (token !== undefined && isJwtConfigured()) {\n const payload = verifyAccessToken(token);\n if (payload) {\n c.set(\"user\", payload);\n }\n }\n\n return next();\n};\n\n/**\n * Extract user from token - for WebSocket authentication\n */\nexport function extractUserFromToken(token: string): AccessTokenPayload | null {\n // Returns \"nobody\" rather than throwing on a backend with no JWT of its\n // own — the socket then closes as unauthenticated, which is the outcome\n // this function already describes.\n if (!isJwtConfigured()) return null;\n return verifyAccessToken(token);\n}\n\n/**\n * Create a configurable auth middleware that handles:\n * 1. Token extraction (via custom validator or JWT Bearer token)\n * 2. RLS-scoped DataDriver via withAuth()\n * 3. Enforcement (401 when requireAuth is true and no user)\n *\n * **Secure by default:** `requireAuth` defaults to `true`. Anonymous\n * access is only allowed when the developer explicitly opts out by\n * setting `requireAuth: false`, indicating that Postgres RLS policies\n * fully control access.\n *\n * **Fail-closed:** The raw unscoped driver is never placed in the\n * request context. Every code path either scopes via `withAuth()` or\n * rejects the request. This prevents silent RLS bypass.\n *\n * This is the single source of truth for HTTP auth in Rebase.\n * Use this instead of manually parsing tokens in route handlers.\n */\n\nexport function createAuthMiddleware(options: AuthMiddlewareOptions): MiddlewareHandler<HonoEnv> {\n const { driver: baseDriver, resolveDriver, requireAuth: enforceAuth = true, validator, serviceKey, apiKeyStore } = options;\n\n return async (c, next) => {\n // Pick the per-request delegate (multi-data-source) before scoping.\n const driver = resolveDriver ? resolveDriver(c) : baseDriver;\n if (validator) {\n // Custom validator path (e.g., API keys, external auth)\n try {\n const authResult = await validator(c);\n if (authResult && typeof authResult === \"object\") {\n // `uid` first: it is the spelling everything else uses. A\n // custom validator written against the older `uid` shape\n // still works — this is a user-supplied extension point, so\n // it stays tolerant of both rather than breaking on rename.\n const id = (\"uid\" in authResult ? authResult.uid : undefined)\n || (\"uid\" in authResult ? authResult.uid : undefined);\n if (id) {\n const roles = authResult.roles || [];\n c.set(\"user\", { uid: id,\nroles });\n const user = { uid: id,\nroles,\n...authResult };\n c.set(\"driver\", await scopeDataDriver(driver, user));\n } else {\n // Validator returned an object but without an ID — scope as anon\n c.set(\"driver\", await scopeDataDriver(driver, { uid: ANONYMOUS_USER_ID,\nroles: [\"anon\"] }));\n }\n } else if (authResult === true) {\n c.set(\"user\", { uid: \"default\",\nroles: [] });\n c.set(\"driver\", await scopeDataDriver(driver, { uid: \"default\",\nroles: [] }));\n } else {\n // Not authenticated — scope as anon so RLS can evaluate.\n // Fail closed: if anon scoping fails, reject instead of\n // falling back to the raw driver.\n c.set(\"driver\", await scopeDataDriver(driver, { uid: ANONYMOUS_USER_ID,\nroles: [\"anon\"] }));\n }\n } catch (error) {\n return c.json({ error: { message: \"Unauthorized\",\ncode: \"UNAUTHORIZED\" } }, 401);\n }\n } else {\n // Default JWT path (with optional service key support)\n const token = extractBearerToken(c.req.header(\"authorization\"));\n\n if (token !== undefined) {\n // ── Service Key check ──────────────────────────────────\n // Check BEFORE JWT verification. Service keys are static\n // secrets (like Service Account keys) that grant admin access\n // for scripts, cron jobs, and server-to-server calls.\n if (serviceKey && safeCompare(token, serviceKey)) {\n const serviceUser: AccessTokenPayload = {\n uid: \"service\",\n roles: [\"admin\"]\n };\n c.set(\"user\", serviceUser);\n try {\n c.set(\"driver\", await scopeDataDriver(driver, {\n uid: \"service\",\n roles: [\"admin\"]\n }));\n } catch (error) {\n logger.error(\"[AUTH] RLS scoping failed for service key\", { error: error });\n return c.json({ error: { message: \"Internal authentication error\",\ncode: \"INTERNAL_ERROR\" } }, 500);\n }\n } else if (apiKeyStore && isApiKeyToken(token)) {\n // ── API Key verification ──────────────────────────────\n // Tokens starting with `rk_` are validated against the\n // api_keys table instead of JWT verification.\n const result = await validateApiKey(c, token, {\n store: apiKeyStore,\n driver\n });\n if (result !== true) {\n return result;\n }\n } else {\n // ── JWT verification ───────────────────────────────────\n const payload = extractUserFromToken(token);\n\n if (payload) {\n c.set(\"user\", payload);\n try {\n const user = { uid: payload.uid,\nroles: payload.roles };\n c.set(\"driver\", await scopeDataDriver(driver, user));\n } catch (error) {\n // withAuth() failed for a valid token — reject (fail closed)\n logger.error(\"[AUTH] RLS scoping failed for authenticated user\", { error: error });\n return c.json({ error: { message: \"Internal authentication error\",\ncode: \"INTERNAL_ERROR\" } }, 500);\n }\n } else {\n // Token present but invalid — always reject.\n // Providing a malformed token should never grant access,\n // regardless of requireAuth setting.\n return c.json({ error: { message: \"Invalid or expired token\",\ncode: \"UNAUTHORIZED\" } }, 401);\n }\n }\n } else {\n // No token provided — scope as anon for RLS evaluation.\n // Fail closed: if anon scoping fails, return 500 rather\n // than silently proceeding with an unscoped driver.\n try {\n c.set(\"driver\", await scopeDataDriver(driver, { uid: ANONYMOUS_USER_ID,\nroles: [\"anon\"] }));\n } catch (error) {\n logger.error(\"[AUTH] Failed to create anon-scoped driver\", { error: error });\n return c.json({ error: { message: \"Server configuration error\",\ncode: \"INTERNAL_ERROR\" } }, 500);\n }\n }\n }\n\n if (enforceAuth && !c.get(\"user\")) {\n return c.json({ error: { message: \"Unauthorized: Authentication required\",\ncode: \"UNAUTHORIZED\" } }, 401);\n }\n\n return next();\n };\n}\n\n/**\n * Middleware that authenticates via a `?token=` query parameter.\n *\n * **Use sparingly.** Tokens in URLs leak into access logs, proxy logs,\n * Referer headers, and browser history. This middleware exists solely for\n * routes where the consumer cannot set HTTP headers — e.g. `<img src>`,\n * `<a href>` for file downloads, or similar browser-native requests.\n *\n * Apply it **before** `requireAuth` or `optionalAuth` on the specific\n * route that needs it. Those middlewares will see the user context this\n * middleware sets and skip their own 401 check.\n *\n * @example\n * ```ts\n * router.get(\"/file/*\", queryTokenAuth, readAuthMiddleware, handler);\n * ```\n */\nexport const queryTokenAuth: MiddlewareHandler<HonoEnv> = async (c, next) => {\n // Only activate when no Authorization header is present and a query token exists.\n if (extractBearerToken(c.req.header(\"authorization\")) !== undefined) {\n // Authorization header takes precedence — let downstream middleware handle it.\n return next();\n }\n\n const queryToken = c.req.query(\"token\");\n if (queryToken && isJwtConfigured()) {\n const payload = verifyAccessToken(queryToken);\n if (payload) {\n c.set(\"user\", payload);\n }\n // If the token is invalid, we don't reject here — let the downstream\n // requireAuth / optionalAuth middleware decide the enforcement policy.\n }\n\n return next();\n};\n\n/**\n * Authorizes anonymous access to **public** storage objects (those under the\n * public prefix), which are served token-less via stable, permanent URLs.\n *\n * Runs on the storage `/file/*` and `/metadata/*` routes, *after* the token\n * middleware and *before* the read-auth gate. If the request is already\n * authenticated (Bearer or scoped token), it does nothing. Otherwise, when the\n * requested object path is public, it sets a minimal \"public\" principal so the\n * downstream `requireAuth` gate lets the read through. Private paths are left\n * untouched, so they still require a valid token.\n */\nexport const publicObjectAuth: MiddlewareHandler<HonoEnv> = async (c, next) => {\n // Already authenticated (Bearer / scoped token) — nothing to authorize.\n if (c.get(\"user\")) return next();\n\n const routePath = c.req.routePath; // e.g. \"/api/storage/file/*\"\n const prefix = routePath.replace(\"/*\", \"\");\n const fullPath = c.req.path;\n const idx = fullPath.indexOf(prefix);\n const rawPath = idx < 0 ? \"\" : fullPath.substring(idx + prefix.length + 1);\n\n if (rawPath && isPublicStoragePath(decodeURIComponent(rawPath))) {\n c.set(\"user\", { uid: \"public\", roles: [\"public\"] });\n }\n\n return next();\n};\n\n/**\n * Helper to match paths for scoped file tokens.\n * Matches exact paths or prefixes (exact folder prefixes or ending with /).\n *\n * The traversal check is defence in depth, not the load-bearing defence.\n *\n * A prefix comparison is a lie for any path containing `..`: `user1/../user2/x`\n * starts with `user1/`, so a token scoped to `user1/` would authorize reading\n * user2's file — and the storage controller would not object, because its own\n * guard stops a path escaping the *bucket*, and that one resolves to `user2/x`,\n * comfortably inside it. The grant is what would be escaped, and this is the\n * only layer that knows what was granted.\n *\n * Nothing arrives here in that shape today: the URL parser resolves `..` (and\n * `%2e%2e`, which the WHATWG spec treats as a dot for normalization) before\n * Hono routes the request, so this comparison already runs on a resolved path.\n * But that is a guarantee of the runtime rather than of this code, and it is\n * one line to not depend on it. The same rule already guards the public-object\n * path — see `isPublicStoragePath`.\n */\nexport function isPathMatch(requested: string, allowed: string): boolean {\n if (requested.split(\"/\").some((seg) => seg === \"..\")) return false;\n if (requested === allowed) return true;\n if (allowed.endsWith(\"/\")) {\n return requested.startsWith(allowed);\n }\n return requested.startsWith(allowed + \"/\");\n}\n\n/**\n * Middleware that authenticates file-serving routes using scoped download tokens.\n * It enforces that only scoped \"file-read\" tokens can access \"/file/*\" and \"?token=\" query params.\n * Full access JWTs are explicitly rejected on \"/file/*\" routes, and in the \"?token=\" query param.\n */\nexport const fileTokenAuth: MiddlewareHandler<HonoEnv> = async (c, next) => {\n const path = c.req.path;\n const isFileRoute = path.includes(\"/storage/file/\");\n const authHeader = c.req.header(\"authorization\");\n const queryToken = c.req.query(\"token\");\n\n // Local copy of helper to avoid circular imports with routes.ts\n const extractWildcard = (ctx: import(\"hono\").Context): string => {\n const routePath = ctx.req.routePath;\n const prefix = routePath.replace(\"/*\", \"\");\n const fullPath = ctx.req.path;\n const idx = fullPath.indexOf(prefix);\n if (idx < 0) return \"\";\n return fullPath.substring(idx + prefix.length + 1);\n };\n\n /**\n * Must agree with `parseBucketAndPath` in `storage/routes.ts`, because the\n * path a token GRANTS is minted there and the path a request ASKS FOR is\n * derived here. `/metadata` canonicalizes before signing, so a raw\n * comparison here would 403 an otherwise-valid request for any key whose\n * URL form is not already canonical (`a//b.txt`, `a/./b.txt`).\n *\n * A key that cannot be canonicalized yields null, which matches no grant —\n * the same fail-closed answer `isPathMatch` gives a `..` segment.\n */\n const parseBucketPath = (filePath: string): { bucket: string; resolvedPath: string | null } => {\n const parts = filePath.split(\"/\");\n if (parts.length > 1 && parts[0].toLowerCase() === \"default\") {\n return {\n bucket: \"default\",\n resolvedPath: tryCanonicalStorageKey(parts.slice(1).join(\"/\"))\n };\n }\n return {\n bucket: \"default\",\n resolvedPath: tryCanonicalStorageKey(filePath)\n };\n };\n\n // 1. Authorization: Bearer <token>\n const bearerToken = extractBearerToken(authHeader);\n if (bearerToken !== undefined) {\n const token = bearerToken;\n const payload = verifyDownloadToken(token);\n\n if (payload) {\n const rawPath = extractWildcard(c);\n if (rawPath) {\n const filePath = decodeURIComponent(rawPath);\n const { bucket, resolvedPath } = parseBucketPath(filePath);\n const requestedFullPath = resolvedPath === null ? null : `${bucket}/${resolvedPath}`;\n\n if (requestedFullPath !== null && isPathMatch(requestedFullPath, payload.path)) {\n c.set(\"user\", { uid: \"download-token\", roles: [\"reader\"] });\n return next();\n } else {\n return c.json({ error: { message: \"Forbidden: Scoped token path mismatch\", code: \"FORBIDDEN\" } }, 403);\n }\n }\n }\n\n // If it's a file serving route, explicitly reject full access JWTs\n if (isFileRoute) {\n return c.json({ error: { message: \"Unauthorized: Access JWT not allowed on file routes\", code: \"UNAUTHORIZED\" } }, 401);\n }\n\n // Otherwise (e.g. /metadata/*) let it pass to downstream requireAuth\n return next();\n }\n\n // 2. Query param: ?token=<token>\n if (queryToken) {\n const payload = verifyDownloadToken(queryToken);\n\n if (payload) {\n const rawPath = extractWildcard(c);\n if (rawPath) {\n const filePath = decodeURIComponent(rawPath);\n const { bucket, resolvedPath } = parseBucketPath(filePath);\n const requestedFullPath = resolvedPath === null ? null : `${bucket}/${resolvedPath}`;\n\n if (requestedFullPath !== null && isPathMatch(requestedFullPath, payload.path)) {\n c.set(\"user\", { uid: \"download-token\", roles: [\"reader\"] });\n return next();\n } else {\n return c.json({ error: { message: \"Forbidden: Scoped token path mismatch\", code: \"FORBIDDEN\" } }, 403);\n }\n }\n }\n\n // Explicitly reject query-token if it is not a valid scoped download token (e.g. if it is a full access JWT)\n return c.json({ error: { message: \"Unauthorized: Invalid or unauthorized token\", code: \"UNAUTHORIZED\" } }, 401);\n }\n\n return next();\n};\n\n","/**\n * Adapter Auth Middleware\n *\n * Creates a Hono middleware that delegates authentication to an `AuthAdapter`\n * instead of hardcoded JWT verification. This is used when the user passes\n * an `AuthAdapter` to `initializeRebaseBackend()`.\n *\n * The middleware:\n * 1. Checks for API key tokens (`rk_` prefix) first — these are Rebase-level\n * 2. Falls back to `adapter.verifyRequest(request)` to resolve the user\n * 3. Scopes the DataDriver via `withAuth()` for RLS\n * 4. Rejects a presented-but-unverifiable token with 401, whatever\n * `requireAuth` says\n * 5. Enforces auth (401) when `requireAuth` is true and no user is found\n *\n * The behavior is identical to `createAuthMiddleware()` — only the\n * token verification strategy is pluggable.\n */\n\nimport type { MiddlewareHandler, Context } from \"hono\";\nimport type { DataDriver, AuthAdapter } from \"@rebasepro/types\";\nimport { ANONYMOUS_USER_ID } from \"@rebasepro/types\";\nimport type { HonoEnv } from \"../api/types\";\nimport type { ApiKeyStore } from \"./api-keys/api-key-store\";\nimport { scopeDataDriver } from \"./rls-scope\";\nimport { validateApiKey } from \"./api-keys/api-key-middleware\";\nimport { extractBearerToken } from \"./bearer-token\";\nimport { logger } from \"../utils/logger\";\n\nexport interface AdapterAuthMiddlewareOptions {\n /** The auth adapter to delegate verification to. */\n adapter: AuthAdapter;\n /** The DataDriver to scope via withAuth() for RLS. */\n driver: DataDriver;\n /**\n * Optional per-request driver resolver for multi-data-source backends.\n * Returns the unscoped delegate to use for this request (e.g. Postgres vs\n * Mongo). When omitted, `driver` is used for every request.\n */\n resolveDriver?: (c: Context<HonoEnv>) => DataDriver;\n /**\n * If true, return 401 when no valid user is resolved.\n * Defaults to `true` (secure by default).\n */\n requireAuth?: boolean;\n /** Optional API key store — when provided, `rk_` bearer tokens are accepted. */\n apiKeyStore?: ApiKeyStore;\n}\n\n/**\n * Create a Hono middleware that uses an `AuthAdapter` for request verification.\n */\nexport function createAdapterAuthMiddleware(options: AdapterAuthMiddlewareOptions): MiddlewareHandler<HonoEnv> {\n const { adapter, driver: baseDriver, resolveDriver, requireAuth: enforceAuth = true, apiKeyStore } = options;\n\n return async (c, next) => {\n // Pick the per-request delegate (multi-data-source) before scoping.\n const driver = resolveDriver ? resolveDriver(c) : baseDriver;\n // Whether the caller presented a bearer token at all. A token that is\n // present and does not verify is a 401 below, exactly as in\n // `createAuthMiddleware` — see the comment there.\n const presentedToken = extractBearerToken(c.req.header(\"authorization\"));\n // ── API Key check (Rebase-level, independent of auth adapter) ────\n if (apiKeyStore) {\n const token = presentedToken ?? \"\";\n if (token.startsWith(\"rk_\")) {\n const result = await validateApiKey(c, token, { store: apiKeyStore,\ndriver });\n if (result === true) return next();\n return result;\n }\n }\n\n let authenticatedUser = null;\n\n try {\n authenticatedUser = await adapter.verifyRequest(c.req.raw);\n } catch (error) {\n // adapter.verifyRequest() threw — reject the request (fail closed)\n return c.json({ error: { message: \"Unauthorized\",\ncode: \"UNAUTHORIZED\" } }, 401);\n }\n\n if (authenticatedUser) {\n // Authenticated — set user context and scope driver\n c.set(\"user\", {\n uid: authenticatedUser.uid,\n email: authenticatedUser.email,\n roles: authenticatedUser.roles\n });\n try {\n c.set(\"driver\", await scopeDataDriver(driver, {\n uid: authenticatedUser.uid,\n roles: authenticatedUser.roles\n }));\n } catch (error) {\n logger.error(\"[AUTH-ADAPTER] RLS scoping failed for authenticated user\", { error: error });\n return c.json({ error: { message: \"Internal authentication error\",\ncode: \"INTERNAL_ERROR\" } }, 500);\n }\n } else {\n // Token present but invalid — always reject, regardless of\n // `requireAuth`. Presenting a malformed or expired token should\n // never grant access, and it must not be *downgraded* to an\n // anonymous request either: the SDK's refresh flow is driven by a\n // 401, so a router mounted with `requireAuth: false` — the custom\n // functions router is the only one — would answer 200 with public\n // content to a user whose access token had merely expired, and the\n // refresh would never fire.\n //\n // This is the rule `createAuthMiddleware` already applies. It lived\n // in only one of the two implementations, and this is the path that\n // runs whenever `config.auth` is a config object.\n //\n // A request with no Authorization header stays anonymous: adapters\n // may authenticate by cookie, and \"no credential\" is not \"a bad\n // credential\".\n if (presentedToken !== undefined) {\n return c.json({ error: { message: \"Invalid or expired token\",\ncode: \"UNAUTHORIZED\" } }, 401);\n }\n\n // Not authenticated — scope as anon for RLS evaluation\n try {\n c.set(\"driver\", await scopeDataDriver(driver, { uid: ANONYMOUS_USER_ID,\nroles: [\"anon\"] }));\n } catch (error) {\n logger.error(\"[AUTH-ADAPTER] Failed to create anon-scoped driver\", { error: error });\n return c.json({ error: { message: \"Server configuration error\",\ncode: \"INTERNAL_ERROR\" } }, 500);\n }\n }\n\n // Enforce auth if required\n if (enforceAuth && !c.get(\"user\")) {\n return c.json({ error: { message: \"Unauthorized: Authentication required\",\ncode: \"UNAUTHORIZED\" } }, 401);\n }\n\n return next();\n };\n}\n","/**\n * HTML escaping for email bodies.\n *\n * Every default template interpolates values the server does not control — a\n * `displayName` chosen at registration, an `appName` from config, a link base a\n * host set — into markup that is then mailed, signed by the sending domain, to\n * an address the same request chose. Unescaped, that turns `POST /auth/register`\n * into a way to deliver arbitrary HTML (a heading, an anchor) from a domain\n * whose SPF and DKIM check out.\n *\n * The fix is deliberately not five escaping calls at five interpolation sites:\n * a sixth template would simply forget. Templates are built with the {@link html}\n * tag, which escapes *every* interpolated value by default, and markup that is\n * meant to pass through verbatim — the static style strings, a nested fragment —\n * must say so with {@link raw}. Forgetting `raw` produces visibly escaped text\n * in a test; forgetting to escape is invisible until someone exploits it.\n */\n\n/**\n * Markup that has already been vetted and must be interpolated verbatim.\n *\n * Only ever construct this from a string literal in this package's own source\n * (or from the {@link html} tag, which produces one). Wrapping user input in\n * `raw()` defeats the entire mechanism.\n */\nexport class RawHtml {\n constructor(readonly value: string) {}\n\n toString(): string {\n return this.value;\n }\n}\n\n/**\n * Mark a static, author-controlled string as safe to interpolate unescaped.\n */\nexport function raw(markup: string): RawHtml {\n return new RawHtml(markup);\n}\n\n/**\n * Escape the five characters that can change the meaning of HTML text or of a\n * quoted attribute value.\n *\n * `&` goes first: escaping it after the others would double-escape the entities\n * they just produced. `'` is included because it is a legal attribute delimiter,\n * and `\"` because it is the one this file uses.\n */\nexport function escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/**\n * Render one interpolated value: pass {@link RawHtml} through, drop nullish,\n * escape everything else.\n */\nfunction interpolate(value: unknown): string {\n if (value instanceof RawHtml) return value.value;\n if (value === null || value === undefined) return \"\";\n return escapeHtml(String(value));\n}\n\n/**\n * Tagged template for email markup. Every `${...}` is escaped unless it is\n * {@link RawHtml}.\n *\n * Returns `RawHtml` so fragments nest without being escaped a second time:\n *\n * ```ts\n * const button = url ? html`<a href=\"${url}\">Open</a>` : raw(\"\");\n * const body = html`<div>${button}</div>`;\n * ```\n */\nexport function html(strings: TemplateStringsArray, ...values: unknown[]): RawHtml {\n let out = strings[0];\n for (let i = 0; i < values.length; i++) {\n out += interpolate(values[i]) + strings[i + 1];\n }\n return new RawHtml(out);\n}\n","/**\n * Default email templates for authentication emails.\n *\n * Every HTML body is built with the `html` tag from `./html`, which escapes each\n * interpolated value unless it is explicitly marked `raw`. `displayName` reaches\n * these templates straight from the registration body, and the resulting mail is\n * sent — signed by the sending domain — to an address the same anonymous request\n * chose, so an unescaped interpolation here is a phishing primitive, not a\n * rendering glitch. Escaping lives in the tag rather than at the call sites so a\n * sixth template inherits it instead of having to remember it.\n */\n\nimport { html, raw } from \"./html\";\n\ninterface TemplateUser {\n email: string;\n displayName?: string | null;\n}\n\n/**\n * Get a greeting name for the user.\n *\n * Returns the raw value — `displayName` is whatever the account was registered\n * with, including markup. Escaping is the `html` tag's job, so that a template\n * that interpolates the greeting into text (the plain-text bodies below) and one\n * that interpolates it into markup can share this.\n */\nfunction getGreeting(user: TemplateUser): string {\n return user.displayName || user.email.split(\"@\")[0];\n}\n\n/**\n * Common email styles.\n *\n * `raw` because these are static, author-written CSS — the one category of\n * interpolation the `html` tag lets through unescaped. (Escaping them would\n * survive an HTML parser but not every mail client's CSS parser: the\n * `'Segoe UI'` quotes would arrive as entities.)\n */\nconst styles = {\n container: raw(`\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n max-width: 600px;\n margin: 0 auto;\n padding: 40px 20px;\n background-color: #f8fafc;\n `),\n card: raw(`\n background-color: #ffffff;\n border-radius: 12px;\n padding: 40px;\n box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);\n `),\n heading: raw(`\n color: #1e293b;\n font-size: 24px;\n font-weight: 600;\n margin: 0 0 20px 0;\n `),\n paragraph: raw(`\n color: #475569;\n font-size: 16px;\n line-height: 1.6;\n margin: 0 0 20px 0;\n `),\n button: raw(`\n display: inline-block;\n background-color: #3b82f6;\n color: #ffffff;\n font-size: 16px;\n font-weight: 600;\n text-decoration: none;\n padding: 14px 28px;\n border-radius: 8px;\n margin: 20px 0;\n `),\n footer: raw(`\n color: #94a3b8;\n font-size: 14px;\n margin-top: 30px;\n padding-top: 20px;\n border-top: 1px solid #e2e8f0;\n `),\n warning: raw(`\n color: #64748b;\n font-size: 14px;\n background-color: #fef3c7;\n padding: 12px 16px;\n border-radius: 6px;\n margin-top: 20px;\n `)\n};\n\n/**\n * Default password reset email template\n */\nexport function getPasswordResetTemplate(\n resetUrl: string,\n user: TemplateUser,\n appName = \"Rebase\"\n): { subject: string; html: string; text: string } {\n const greeting = getGreeting(user);\n\n const subject = `Reset your ${appName} password`;\n\n const body = html`\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${subject}</title>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f8fafc;\">\n <div style=\"${styles.container}\">\n <div style=\"${styles.card}\">\n <h1 style=\"${styles.heading}\">Reset Your Password</h1>\n \n <p style=\"${styles.paragraph}\">\n Hi ${greeting},\n </p>\n \n <p style=\"${styles.paragraph}\">\n We received a request to reset your password for your ${appName} account. \n Click the button below to create a new password:\n </p>\n \n <div style=\"text-align: center;\">\n <a href=\"${resetUrl}\" style=\"${styles.button}\">Reset Password</a>\n </div>\n \n <p style=\"${styles.paragraph}\">\n Or copy and paste this link into your browser:\n </p>\n <p style=\"color: #3b82f6; word-break: break-all; font-size: 14px;\">\n ${resetUrl}\n </p>\n \n <div style=\"${styles.warning}\">\n ⏰ This link will expire in 1 hour for security reasons.\n </div>\n \n <div style=\"${styles.footer}\">\n <p style=\"margin: 0;\">\n If you didn't request a password reset, you can safely ignore this email. \n Your password will remain unchanged.\n </p>\n </div>\n </div>\n </div>\n</body>\n</html>\n `;\n\n const text = `\nReset Your Password\n\nHi ${greeting},\n\nWe received a request to reset your password for your ${appName} account.\n\nClick this link to create a new password:\n${resetUrl}\n\nThis link will expire in 1 hour for security reasons.\n\nIf you didn't request a password reset, you can safely ignore this email.\nYour password will remain unchanged.\n `.trim();\n\n return { subject,\nhtml: body.toString().trim(),\ntext };\n}\n\n/**\n * Default email verification template\n */\nexport function getEmailVerificationTemplate(\n verifyUrl: string,\n user: TemplateUser,\n appName = \"Rebase\"\n): { subject: string; html: string; text: string } {\n const greeting = getGreeting(user);\n\n const subject = `Verify your ${appName} email address`;\n\n const body = html`\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${subject}</title>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f8fafc;\">\n <div style=\"${styles.container}\">\n <div style=\"${styles.card}\">\n <h1 style=\"${styles.heading}\">Verify Your Email</h1>\n \n <p style=\"${styles.paragraph}\">\n Hi ${greeting},\n </p>\n \n <p style=\"${styles.paragraph}\">\n Thanks for signing up for ${appName}! Please verify your email address \n by clicking the button below:\n </p>\n \n <div style=\"text-align: center;\">\n <a href=\"${verifyUrl}\" style=\"${styles.button}\">Verify Email Address</a>\n </div>\n \n <p style=\"${styles.paragraph}\">\n Or copy and paste this link into your browser:\n </p>\n <p style=\"color: #3b82f6; word-break: break-all; font-size: 14px;\">\n ${verifyUrl}\n </p>\n \n <div style=\"${styles.footer}\">\n <p style=\"margin: 0;\">\n If you didn't create an account with ${appName}, you can safely ignore this email.\n </p>\n </div>\n </div>\n </div>\n</body>\n</html>\n `;\n\n const text = `\nVerify Your Email\n\nHi ${greeting},\n\nThanks for signing up for ${appName}! Please verify your email address by clicking this link:\n${verifyUrl}\n\nIf you didn't create an account with ${appName}, you can safely ignore this email.\n `.trim();\n\n return { subject,\nhtml: body.toString().trim(),\ntext };\n}\n\n/**\n * Default user invitation email template\n * Sent when an admin creates a new user account\n */\nexport function getUserInvitationTemplate(\n setPasswordUrl: string,\n user: TemplateUser,\n appName = \"Rebase\"\n): { subject: string; html: string; text: string } {\n const greeting = getGreeting(user);\n\n const subject = `You've been invited to ${appName}`;\n\n const body = html`\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${subject}</title>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f8fafc;\">\n <div style=\"${styles.container}\">\n <div style=\"${styles.card}\">\n <h1 style=\"${styles.heading}\">Welcome to ${appName}!</h1>\n \n <p style=\"${styles.paragraph}\">\n Hi ${greeting},\n </p>\n \n <p style=\"${styles.paragraph}\">\n An account has been created for you on ${appName}. \n Click the button below to set your password and get started:\n </p>\n \n <div style=\"text-align: center;\">\n <a href=\"${setPasswordUrl}\" style=\"${styles.button}\">Set Your Password</a>\n </div>\n \n <p style=\"${styles.paragraph}\">\n Or copy and paste this link into your browser:\n </p>\n <p style=\"color: #3b82f6; word-break: break-all; font-size: 14px;\">\n ${setPasswordUrl}\n </p>\n \n <div style=\"${styles.warning}\">\n ⏰ This link will expire in 1 hour for security reasons.\n </div>\n \n <div style=\"${styles.footer}\">\n <p style=\"margin: 0;\">\n If you weren't expecting this invitation, you can safely ignore this email.\n </p>\n </div>\n </div>\n </div>\n</body>\n</html>\n `;\n\n const text = `\nWelcome to ${appName}!\n\nHi ${greeting},\n\nAn account has been created for you on ${appName}.\n\nClick this link to set your password and get started:\n${setPasswordUrl}\n\nThis link will expire in 1 hour for security reasons.\n\nIf you weren't expecting this invitation, you can safely ignore this email.\n `.trim();\n\n return { subject,\nhtml: body.toString().trim(),\ntext };\n}\n\n/**\n * Default welcome email template\n * Sent automatically when a new user registers\n */\nexport function getWelcomeEmailTemplate(\n user: TemplateUser,\n appName = \"Rebase\",\n loginUrl?: string\n): { subject: string; html: string; text: string } {\n const greeting = getGreeting(user);\n const url = loginUrl || \"\";\n\n const subject = `¡Bienvenido/a a ${appName}!`;\n\n const body = html`\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${subject}</title>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f8fafc;\">\n <div style=\"${styles.container}\">\n <div style=\"${styles.card}\">\n <h1 style=\"${styles.heading}\">¡Bienvenido/a a ${appName}!</h1>\n \n <p style=\"${styles.paragraph}\">\n Hola ${greeting},\n </p>\n \n <p style=\"${styles.paragraph}\">\n Tu cuenta en ${appName} ha sido creada exitosamente. \n Estamos encantados de tenerte con nosotros.\n </p>\n \n <p style=\"${styles.paragraph}\">\n Ya puedes acceder a tu panel y empezar a explorar todas las oportunidades \n que tenemos para ti.\n </p>\n\n ${url ? html`\n <div style=\"text-align: center;\">\n <a href=\"${url}\" style=\"${styles.button}\">Ir a mi Panel</a>\n </div>\n ` : raw(\"\")}\n \n <p style=\"${styles.paragraph}\">\n Si tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.\n </p>\n \n <div style=\"${styles.footer}\">\n <p style=\"margin: 0;\">\n Este correo fue enviado porque se creó una cuenta con esta dirección de email en ${appName}.\n </p>\n </div>\n </div>\n </div>\n</body>\n</html>\n `;\n\n const text = `\n¡Bienvenido/a a ${appName}!\n\nHola ${greeting},\n\nTu cuenta en ${appName} ha sido creada exitosamente. Estamos encantados de tenerte con nosotros.\n\nYa puedes acceder a tu panel y empezar a explorar todas las oportunidades que tenemos para ti.\n\n${url ? `Ir a mi panel: ${url}` : \"\"}\n\nSi tienes alguna pregunta, no dudes en contactarnos respondiendo a este correo.\n `.trim();\n\n return { subject,\nhtml: body.toString().trim(),\ntext };\n}\n\n/**\n * Default magic link email template\n */\nexport function getMagicLinkTemplate(\n magicLinkUrl: string,\n user: TemplateUser,\n appName = \"Rebase\"\n): { subject: string; html: string; text: string } {\n const greeting = getGreeting(user);\n\n const subject = `Sign in to ${appName}`;\n\n const body = html`\n<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${subject}</title>\n</head>\n<body style=\"margin: 0; padding: 0; background-color: #f8fafc;\">\n <div style=\"${styles.container}\">\n <div style=\"${styles.card}\">\n <h1 style=\"${styles.heading}\">Sign In to ${appName}</h1>\n \n <p style=\"${styles.paragraph}\">\n Hi ${greeting},\n </p>\n \n <p style=\"${styles.paragraph}\">\n We received a request to sign in to your ${appName} account. \n Click the button below to log in:\n </p>\n \n <div style=\"text-align: center;\">\n <a href=\"${magicLinkUrl}\" style=\"${styles.button}\">Sign In</a>\n </div>\n \n <p style=\"${styles.paragraph}\">\n Or copy and paste this link into your browser:\n </p>\n <p style=\"color: #3b82f6; word-break: break-all; font-size: 14px;\">\n ${magicLinkUrl}\n </p>\n \n <div style=\"${styles.warning}\">\n ⏰ This link will expire in 15 minutes for security reasons and can only be used once.\n </div>\n \n <div style=\"${styles.footer}\">\n <p style=\"margin: 0;\">\n If you didn't request this sign-in link, you can safely ignore this email. \n No action is needed.\n </p>\n </div>\n </div>\n </div>\n</body>\n</html>\n `;\n\n const text = `\nSign In to ${appName}\n\nHi ${greeting},\n\nWe received a request to sign in to your ${appName} account.\n\nClick this link to log in:\n${magicLinkUrl}\n\nThis link will expire in 15 minutes for security reasons and can only be used once.\n\nIf you didn't request this sign-in link, you can safely ignore this email.\nNo action is needed.\n `.trim();\n\n return { subject,\nhtml: body.toString().trim(),\ntext };\n}\n","/**\n * Admin User Operations\n *\n * Shared utilities and orchestration for admin-initiated user management\n * (user creation via REST API, password reset via admin panel).\n *\n * Hook resolution order:\n * 1. Collection-level hook (`auth.onCreateUser` on the collection) — closest to the data\n * 2. Backend-level hook (`AuthHooks.onAdminCreateUser`) — global override\n * 3. Built-in default — framework fallback\n */\n\nimport { randomBytes, createHash, randomInt } from \"node:crypto\";\nimport { normalizeEmail } from \"@rebasepro/common\";\nimport type { AuthRepository } from \"./interfaces\";\nimport type { EmailService, EmailConfig } from \"../email\";\nimport type { ResolvedAuthHooks } from \"./auth-hooks\";\nimport type { AuthCollectionConfig, AuthCollectionContext } from \"@rebasepro/types\";\nimport { getUserInvitationTemplate } from \"../email/templates\";\nimport { logger } from \"../utils/logger\";\n\n// ─── Shared Crypto Utilities ────────────────────────────────────────────────\n\n/**\n * Generate a cryptographically secure random password that meets strength requirements.\n *\n * 16 characters, guaranteed at least one uppercase, one lowercase, one digit.\n * Ambiguous characters (0, O, 1, l, I) are excluded.\n */\nexport function generateSecurePassword(): string {\n const upper = \"ABCDEFGHJKLMNPQRSTUVWXYZ\";\n const lower = \"abcdefghjkmnpqrstuvwxyz\";\n const digits = \"23456789\";\n const all = upper + lower + digits;\n\n const pick = (chars: string) => chars[randomInt(chars.length)];\n const parts = [pick(upper), pick(lower), pick(digits)];\n\n for (let i = parts.length; i < 16; i++) {\n parts.push(pick(all));\n }\n\n // Shuffle\n for (let i = parts.length - 1; i > 0; i--) {\n const j = randomInt(i + 1);\n [parts[i], parts[j]] = [parts[j], parts[i]];\n }\n return parts.join(\"\");\n}\n\n/**\n * Generate a cryptographically secure random token (80 hex characters).\n */\nexport function generateSecureToken(): string {\n return randomBytes(40).toString(\"hex\");\n}\n\n/**\n * Hash a token for database storage using SHA-256.\n */\nexport function hashToken(token: string): string {\n return createHash(\"sha256\").update(token).digest(\"hex\");\n}\n\n// ─── Admin User Creation ────────────────────────────────────────────────────\n\n/**\n * Context needed by admin user creation / password reset operations.\n */\nexport interface AdminUserContext {\n authRepo: AuthRepository;\n emailService?: EmailService;\n emailConfig?: EmailConfig;\n resolvedHooks: ResolvedAuthHooks;\n /** The parsed auth config from the collection (if `auth` is an object, not just `true`). */\n collectionAuthConfig?: AuthCollectionConfig;\n}\n\n/**\n * Result of preparing user values for admin-initiated creation.\n */\nexport interface AdminUserPrepareResult {\n /** Values ready for `driver.save()`. */\n values: Record<string, unknown>;\n /** The cleartext password (for returning to admin or sending via email). */\n clearPassword?: string;\n /** Whether the hook already handled the invitation email. */\n hookHandledEmail: boolean;\n /** Whether an invitation was sent (only relevant when hookHandledEmail is true). */\n invitationSent: boolean;\n}\n\n/**\n * Build the `AuthCollectionContext` facade from server internals.\n *\n * This is the simplified context exposed to collection-level auth hooks,\n * keeping them decoupled from internal interfaces like `AuthRepository`.\n */\nfunction buildCollectionContext(ctx: AdminUserContext): AuthCollectionContext {\n const isEmailConfigured = !!(ctx.emailService && ctx.emailService.isConfigured());\n\n return {\n hashPassword: (password: string) => ctx.resolvedHooks.hashPassword(password),\n sendEmail: isEmailConfigured\n ? (options) => ctx.emailService!.send(options)\n : undefined,\n emailConfigured: isEmailConfigured,\n appName: ctx.emailConfig?.appName || \"Rebase\",\n resetPasswordUrl: ctx.emailConfig?.resetPasswordUrl || \"\"\n };\n}\n\n/**\n * Prepare user values for an admin-initiated user creation.\n *\n * Resolution order:\n * 1. Collection-level `auth.onCreateUser` — closest to the data\n * 2. Backend-level `AuthHooks.onAdminCreateUser` — global override\n * 3. Built-in default — generate password → hash → normalize email\n *\n * The caller is responsible for persisting (via `driver.save()`).\n */\nexport async function prepareAdminUserValues(\n body: Record<string, unknown>,\n ctx: AdminUserContext\n): Promise<AdminUserPrepareResult> {\n const { resolvedHooks, collectionAuthConfig } = ctx;\n\n // 1. Collection-level hook (closest to the data)\n if (collectionAuthConfig?.onCreateUser) {\n const collectionCtx = buildCollectionContext(ctx);\n const hookResult = await collectionAuthConfig.onCreateUser(body, collectionCtx);\n return {\n values: hookResult.values,\n clearPassword: hookResult.temporaryPassword,\n hookHandledEmail: true,\n invitationSent: hookResult.invitationSent ?? false\n };\n }\n\n // 2. Backend-level hook (global override)\n if (resolvedHooks.onAdminCreateUser) {\n const hookResult = await resolvedHooks.onAdminCreateUser(body, {\n authRepo: ctx.authRepo,\n emailService: ctx.emailService,\n emailConfig: ctx.emailConfig,\n hashPassword: (password: string) => resolvedHooks.hashPassword(password)\n });\n return {\n values: hookResult.values,\n clearPassword: hookResult.temporaryPassword,\n hookHandledEmail: true,\n invitationSent: hookResult.invitationSent ?? false\n };\n }\n\n // 3. Built-in default\n const password = body.password as string | undefined;\n const clearPassword = password || generateSecurePassword();\n const passwordHash = await resolvedHooks.hashPassword(clearPassword);\n\n const values = { ...body };\n values.passwordHash = passwordHash;\n if (values.email) {\n values.email = normalizeEmail(values.email as string);\n }\n values.emailVerified = true;\n delete values.password;\n\n return {\n values,\n clearPassword: password ? undefined : clearPassword,\n hookHandledEmail: false,\n invitationSent: false\n };\n}\n\n/**\n * Handle post-creation work for admin-created users.\n *\n * Sends an invitation email (password-reset link) if email is configured\n * and no explicit password was provided. Falls back to returning the\n * temporary password if email fails or is not configured.\n */\nexport async function finalizeAdminUserCreation(\n entity: { id: string; values: Record<string, unknown> },\n clearPassword: string | undefined,\n ctx: AdminUserContext\n): Promise<{\n temporaryPassword?: string;\n invitationSent: boolean;\n emailDeliveryFailed?: boolean;\n}> {\n // If an explicit password was provided (clearPassword is undefined), nothing to do\n if (!clearPassword) {\n return { invitationSent: false };\n }\n\n const isEmailConfigured = !!(ctx.emailService && ctx.emailService.isConfigured());\n\n if (isEmailConfigured) {\n try {\n const token = generateSecureToken();\n const tokenHash = hashToken(token);\n const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours\n\n await ctx.authRepo.createPasswordResetToken(entity.id, tokenHash, expiresAt);\n\n const baseUrl = ctx.emailConfig?.resetPasswordUrl || \"\";\n const setPasswordUrl = `${baseUrl}/reset-password?token=${token}`;\n\n // The invitation template, not the password-reset one.\n //\n // This is the *creation* path: the recipient has never had an\n // account, let alone a password to reset. It sent\n // \"Reset your <App> password\" anyway, because\n // `templates.userInvitation` — declared in `EmailConfig`, typed as\n // `UserInvitationTemplateFunction`, and backed by a written default\n // that `email/index.ts` exports — was read by nothing at all. The\n // one flow named for it reached past it to its neighbour.\n //\n // `getUserInvitationTemplate` says what actually happened: \"An\n // account has been created for you … set your password and get\n // started\". `reset-password-admin.ts` keeps the reset template,\n // because there the account really does already exist.\n const appName = ctx.emailConfig?.appName || \"Rebase\";\n const templateFn = ctx.emailConfig?.templates?.userInvitation;\n const emailContent = templateFn\n ? templateFn(setPasswordUrl, { email: entity.values.email as string,\ndisplayName: entity.values.displayName as string })\n : getUserInvitationTemplate(setPasswordUrl, { email: entity.values.email as string,\ndisplayName: entity.values.displayName as string }, appName);\n\n await ctx.emailService!.send({\n to: entity.values.email as string,\n subject: emailContent.subject,\n html: emailContent.html,\n text: emailContent.text\n });\n return { invitationSent: true };\n } catch (emailError: unknown) {\n logger.error(\"Failed to send reset email\", { error: emailError instanceof Error ? emailError.message : emailError });\n // Fall back to returning the temporary password\n return { temporaryPassword: clearPassword,\ninvitationSent: false,\nemailDeliveryFailed: true };\n }\n }\n\n // No email service — return the temporary password\n return { temporaryPassword: clearPassword,\ninvitationSent: false };\n}\n","import { scrypt, randomBytes, timingSafeEqual, type ScryptOptions } from \"crypto\";\nimport { promisify } from \"util\";\n\n// `promisify` resolves to the 4-argument overload of `scrypt`, which has no\n// options parameter — so passing one is a type error, and that is exactly why\n// the parameters below sat unused. Named here so the options overload is the\n// one this module calls.\nconst scryptAsync = promisify(scrypt) as (\n password: string,\n salt: Buffer,\n keylen: number,\n options: ScryptOptions\n) => Promise<Buffer>;\n\n// Scrypt parameters (recommended values for 2024+).\n//\n// Passed explicitly. They were declared here and handed to neither call, which\n// happened to be harmless because they are also Node's defaults — so raising\n// any of them would have changed nothing while reading as though it had. That\n// is the failure worth avoiding: the next person to strengthen this needs the\n// edit to take effect.\nconst SALT_LENGTH = 32;\nconst KEY_LENGTH = 64;\nconst SCRYPT_PARAMS = { N: 16384, r: 8, p: 1 };\n\nexport interface PasswordValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Password requirements:\n * - Minimum 8 characters\n * - At least 1 uppercase letter\n * - At least 1 lowercase letter\n * - At least 1 number\n */\nexport function validatePasswordStrength(password: string): PasswordValidationResult {\n const errors: string[] = [];\n\n if (password.length < 8) {\n errors.push(\"Password must be at least 8 characters long\");\n }\n\n if (!/[A-Z]/.test(password)) {\n errors.push(\"Password must contain at least one uppercase letter\");\n }\n\n if (!/[a-z]/.test(password)) {\n errors.push(\"Password must contain at least one lowercase letter\");\n }\n\n if (!/[0-9]/.test(password)) {\n errors.push(\"Password must contain at least one number\");\n }\n\n return {\n valid: errors.length === 0,\n errors\n };\n}\n\n/**\n * Hash a password using Node's built-in scrypt\n * Returns format: salt:hash (both hex encoded)\n */\nexport async function hashPassword(password: string): Promise<string> {\n const salt = randomBytes(SALT_LENGTH);\n const derivedKey = await scryptAsync(password, salt, KEY_LENGTH, SCRYPT_PARAMS);\n return `${salt.toString(\"hex\")}:${derivedKey.toString(\"hex\")}`;\n}\n\n/**\n * Verify a password against a scrypt hash\n * Expects format: salt:hash (both hex encoded)\n */\nexport async function verifyPassword(password: string, storedHash: string): Promise<boolean> {\n const [saltHex, hashHex] = storedHash.split(\":\");\n if (!saltHex || !hashHex) {\n return false;\n }\n\n const salt = Buffer.from(saltHex, \"hex\");\n const storedKey = Buffer.from(hashHex, \"hex\");\n\n const derivedKey = await scryptAsync(password, salt, KEY_LENGTH, SCRYPT_PARAMS);\n\n // Use timing-safe comparison to prevent timing attacks\n return timingSafeEqual(derivedKey, storedKey);\n}\n","/**\n * AuthHooks\n *\n * Customize specific behaviors of the built-in Rebase auth system.\n *\n * Each method replaces one piece of the default implementation.\n * Unset methods fall through to the built-in defaults (scrypt passwords,\n * standard validation rules, etc.).\n *\n * This interface is intentionally open for extension — new hooks\n * can be added as optional methods without breaking existing configurations.\n *\n * @example bcrypt password support\n * ```ts\n * import bcrypt from \"bcrypt\";\n *\n * const hooks: AuthHooks = {\n * hashPassword: (pw) => bcrypt.hash(pw, 12),\n * verifyPassword: (pw, hash) => bcrypt.compare(pw, hash),\n * validatePasswordStrength: (pw) => ({\n * valid: pw.length >= 6,\n * errors: pw.length < 6 ? [\"Password must be at least 6 characters\"] : []\n * })\n * };\n * ```\n *\n * @example Override the entire login credential check\n * ```ts\n * const hooks: AuthHooks = {\n * verifyCredentials: async (email, password, repo) => {\n * const user = await repo.getUserByEmail(email);\n * if (!user || !user.passwordHash) return null;\n * const valid = await myCustomVerify(password, user.passwordHash);\n * return valid ? user : null;\n * }\n * };\n * ```\n */\n\nimport {\n hashPassword as defaultHashPassword,\n verifyPassword as defaultVerifyPassword,\n validatePasswordStrength as defaultValidatePasswordStrength\n} from \"./password\";\nimport type { PasswordValidationResult } from \"./password\";\nimport type { AuthRepository, UserData, CreateUserData } from \"./interfaces\";\nimport type { EmailService, EmailConfig } from \"../email\";\nimport type { AuthResponsePayload, TransformAuthResponseContext } from \"@rebasepro/types\";\n\n/**\n * Authentication method identifier for lifecycle hooks.\n */\nexport type AuthMethod = \"login\" | \"register\" | \"oauth\" | \"refresh\" | \"password-reset\" | \"anonymous\" | \"magic-link\" | \"mfa\";\n\n/**\n * Hook specific parts of the built-in Rebase auth implementation.\n *\n * Every method is optional. The built-in defaults apply for any method\n * that is not provided.\n */\nexport interface AuthHooks {\n // ─── Password Operations ──────────────────────────────────────────────\n\n /**\n * Hash a cleartext password for storage.\n *\n * Default: scrypt (Node.js crypto, 64-byte key, random 32-byte salt).\n *\n * @param password - The cleartext password.\n * @returns The hashed password string (format is implementation-defined).\n */\n hashPassword?(password: string): Promise<string>;\n\n /**\n * Verify a cleartext password against a stored hash.\n *\n * Default: scrypt verification with timing-safe comparison.\n *\n * @param password - The cleartext password to check.\n * @param storedHash - The hash string retrieved from the database.\n * @returns `true` if the password matches the hash.\n */\n verifyPassword?(password: string, storedHash: string): Promise<boolean>;\n\n /**\n * Validate password strength before hashing.\n *\n * Default: minimum 8 characters, at least one uppercase, one lowercase, one digit.\n *\n * @param password - The cleartext password to validate.\n * @returns Validation result with `valid` flag and error messages.\n */\n validatePasswordStrength?(password: string): PasswordValidationResult;\n\n // ─── Credential Resolution ────────────────────────────────────────────\n\n /**\n * Override the complete credential verification during email/password login.\n *\n * When set, this replaces the default flow:\n * 1. Look up user by email\n * 2. Verify password hash\n *\n * The auth repository is provided for database access. Return the user\n * data if credentials are valid, or `null` to reject the login.\n *\n * Default: `getUserByEmail(email)` + `verifyPassword(password, user.passwordHash)`.\n */\n verifyCredentials?(email: string, password: string, repo: AuthRepository): Promise<UserData | null>;\n\n // ─── Lifecycle Hooks ──────────────────────────────────────────────────\n\n /**\n * Called after any successful authentication event (login, register,\n * OAuth, token refresh, password reset).\n *\n * Use for audit logging, syncing external state, updating\n * last-login timestamps, etc.\n *\n * This is fire-and-forget — errors are logged but do not fail the request.\n */\n onAuthenticated?(user: UserData, method: AuthMethod): Promise<void>;\n\n /**\n * Called before a new user is created (registration or admin creation).\n *\n * Return modified data to alter what gets stored, or throw an error\n * to reject the creation entirely.\n *\n * Default: passthrough (returns data unchanged).\n */\n beforeUserCreate?(data: CreateUserData): Promise<CreateUserData>;\n\n /**\n * Called after a new user is created.\n *\n * Use for provisioning external resources, sending notifications\n * to third-party systems, etc.\n *\n * This is fire-and-forget — errors are logged but do not fail the request.\n */\n afterUserCreate?(user: UserData): Promise<void>;\n\n // ─── Extended Lifecycle Hooks ─────────────────────────────────────────\n\n /**\n * Pre-login validation. Called before credential verification.\n *\n * Throw an error to reject the login attempt (e.g. for account lockout,\n * IP-based restrictions, etc.).\n */\n beforeLogin?(email: string, method: AuthMethod): Promise<void>;\n\n /**\n * Post-logout cleanup.\n *\n * Called after a user's session has been invalidated.\n * Use for audit logging, cleanup of temporary resources, etc.\n *\n * This is fire-and-forget — errors are logged but do not fail the request.\n */\n afterLogout?(uid: string): Promise<void>;\n\n /**\n * Called after successful MFA verification.\n *\n * Use for audit logging, notifying external systems, etc.\n *\n * This is fire-and-forget — errors are logged but do not fail the request.\n */\n onMfaVerified?(uid: string, factorId: string): Promise<void>;\n\n /**\n * Customize JWT access token claims before signing.\n *\n * Return the modified claims object. The returned claims are merged\n * into the JWT payload alongside standard claims (uid, roles).\n *\n * @param claims - The default claims that would be included.\n * @param user - The authenticated user data.\n * @returns Modified claims to include in the JWT.\n */\n customizeAccessToken?(claims: Record<string, unknown>, user: UserData): Promise<Record<string, unknown>>;\n\n /**\n * Transform the auth response before sending it to the client.\n *\n * Called after successful login, register, refresh, OAuth, anonymous,\n * magic-link, and MFA flows. The hook receives the fully-formed\n * response and returns a (potentially enriched) response.\n *\n * Use cases:\n * - Inject tokens from external auth systems (custom provider tokens, etc.)\n * - Add project-specific metadata to the response\n * - Enrich the user object with data from external sources\n *\n * The hook runs in the request path — keep it fast.\n * Heavy work should be offloaded to `onAuthenticated` (fire-and-forget).\n */\n transformAuthResponse?(\n response: AuthResponsePayload,\n context: TransformAuthResponseContext\n ): Promise<AuthResponsePayload>;\n\n /**\n * Called after a successful password reset.\n *\n * Use for audit logging, sending confirmation notifications, etc.\n *\n * This is fire-and-forget — errors are logged but do not fail the request.\n */\n onPasswordReset?(uid: string): Promise<void>;\n\n /**\n * Called before a user is deleted.\n *\n * Throw an error to prevent deletion (e.g. for users with active\n * subscriptions, pending transactions, etc.).\n */\n beforeUserDelete?(uid: string): Promise<void>;\n\n /**\n * Called after a user is deleted.\n *\n * Use for cleaning up external resources, audit logging, etc.\n *\n * This is fire-and-forget — errors are logged but do not fail the request.\n */\n afterUserDelete?(uid: string): Promise<void>;\n\n /**\n * Optional hook to customize or override the default user creation flow via the admin panel/REST API.\n * When provided, this replaces the built-in password generation, hashing, and invitation email logic.\n */\n onAdminCreateUser?(\n values: Record<string, unknown>,\n ctx: {\n authRepo: AuthRepository;\n emailService?: EmailService;\n emailConfig?: EmailConfig;\n hashPassword: (password: string) => Promise<string>;\n }\n ): Promise<{\n values: Record<string, unknown>;\n temporaryPassword?: string;\n invitationSent?: boolean;\n }>;\n\n /**\n * Optional hook to customize or override the default password reset flow via the admin panel.\n * When provided, this replaces the built-in password reset token generation, hashing, and email logic.\n */\n onAdminResetPassword?(\n uid: string,\n ctx: {\n authRepo: AuthRepository;\n emailService?: EmailService;\n emailConfig?: EmailConfig;\n }\n ): Promise<{\n temporaryPassword?: string;\n invitationSent?: boolean;\n }>;\n}\n\n/**\n * Resolved auth hooks — password operations are guaranteed to exist,\n * all other hooks are passed through as-is (optional).\n *\n * Created by `resolveAuthHooks()` which merges user hooks\n * with built-in defaults.\n *\n * Consumers should use the resolved object exclusively —\n * never access the raw `AuthHooks` directly.\n */\nexport type ResolvedAuthHooks =\n Required<Pick<AuthHooks, \"hashPassword\" | \"verifyPassword\" | \"validatePasswordStrength\">>\n & Omit<AuthHooks, \"hashPassword\" | \"verifyPassword\" | \"validatePasswordStrength\">;\n\n/**\n * Merge user-provided hooks with the built-in defaults to produce\n * a complete set of resolved hooks.\n *\n * This is the single point where defaults are applied — all consumers\n * call this once and use the resolved hooks throughout.\n */\nexport function resolveAuthHooks(hooks?: AuthHooks): ResolvedAuthHooks {\n return {\n ...hooks,\n\n hashPassword: hooks?.hashPassword\n ?? defaultHashPassword,\n\n verifyPassword: hooks?.verifyPassword\n ?? defaultVerifyPassword,\n\n validatePasswordStrength: hooks?.validatePasswordStrength\n ?? defaultValidatePasswordStrength\n };\n}\n","import type { EmailConfig } from \"./types\";\n\n/**\n * Resolution — and boot-time validation — of the base URL every emailed link is\n * built from.\n *\n * Each link kind used to read one config field and fall back to `\"\"`, which\n * produces `href=\"/verify-email?token=…\"`. A mail client has no base document to\n * resolve that against, so the link is inert: the route still answers\n * `{ success: true }`, the token is still minted and stored, and nothing in the\n * logs says anything is wrong. `verifyEmailUrl` in particular is set by no boot\n * path, so that was the *default* behaviour of email verification.\n *\n * Two changes: the fallback chains live here rather than being re-spelled at\n * each call site (only the magic-link route had one), and\n * {@link assertEmailLinkBases} refuses at boot when no absolute base can be\n * resolved. A configuration error that only ever shows up as \"the link in the\n * email does nothing\" is worth a failed start.\n */\n\n/** Which link a base URL is being resolved for. */\nexport type EmailLinkKind = \"resetPassword\" | \"verifyEmail\" | \"magicLink\";\n\n/**\n * The config fields consulted for each link kind, most specific first.\n *\n * `resetPasswordUrl` is the general fallback because it is the only one any boot\n * path sets, and in every real deployment all three point at the same frontend.\n */\nconst LINK_BASE_FIELDS: Record<EmailLinkKind, (keyof EmailConfig)[]> = {\n resetPassword: [\"resetPasswordUrl\"],\n verifyEmail: [\"verifyEmailUrl\", \"resetPasswordUrl\"],\n magicLink: [\"magicLinkUrl\", \"resetPasswordUrl\"]\n};\n\n/**\n * True when `value` is an absolute `http(s)` URL — the only kind a mail client\n * can follow. A protocol-relative or path-only base is treated as missing.\n */\nfunction isAbsoluteHttpUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n\n/** Drop a trailing slash so callers can append `/verify-email?token=…`. */\nfunction normalizeBase(value: string): string {\n return value.replace(/\\/+$/, \"\");\n}\n\n/**\n * The absolute base URL for a link kind, or `\"\"` when the config has none.\n *\n * Callers append their path to the result. `\"\"` is only reachable on a config\n * that never went through {@link assertEmailLinkBases} — a hand-constructed\n * `SMTPEmailService` in a test, say — and is kept rather than thrown so that a\n * misconfiguration cannot turn a password-reset request into a 500 that\n * distinguishes existing accounts from missing ones.\n */\nexport function resolveEmailLinkBase(\n config: EmailConfig | undefined,\n kind: EmailLinkKind\n): string {\n if (!config) return \"\";\n for (const field of LINK_BASE_FIELDS[kind]) {\n const value = config[field];\n if (typeof value === \"string\" && isAbsoluteHttpUrl(value)) {\n return normalizeBase(value);\n }\n }\n return \"\";\n}\n\n/**\n * Throw when an email configuration cannot produce a followable link.\n *\n * Called from `createEmailService`, i.e. from every boot path that wires email\n * up (the managed runtime, both driver bootstrappers, and any app that passes\n * `auth.email`). A base that is set but relative is reported separately from one\n * that is missing, because the two have different fixes.\n */\nexport function assertEmailLinkBases(config: EmailConfig): void {\n const relative = ([\"resetPasswordUrl\", \"verifyEmailUrl\", \"magicLinkUrl\"] as const)\n .filter(field => typeof config[field] === \"string\" && config[field] !== \"\" && !isAbsoluteHttpUrl(config[field]!));\n\n if (relative.length > 0) {\n throw new Error(\n `Email is configured with a relative link base: ${relative.map(f => `email.${f}`).join(\", \")}. ` +\n \"Emailed links must be absolute (e.g. \\\"https://app.example.com\\\") — a mail client has no \" +\n \"base document to resolve a relative href against, so the link is dead.\"\n );\n }\n\n if (!resolveEmailLinkBase(config, \"resetPassword\") && !resolveEmailLinkBase(config, \"verifyEmail\")) {\n throw new Error(\n \"Email is configured but no base URL for emailed links is set. Password-reset, verification \" +\n \"and magic-link emails would carry relative hrefs, which are dead links in every mail client. \" +\n \"Set FRONTEND_URL (or `auth.email.resetPasswordUrl`) to an absolute URL such as \" +\n \"\\\"https://app.example.com\\\".\"\n );\n }\n}\n","import type { Transporter } from \"nodemailer\";\nimport { EmailConfig, EmailSendOptions, EmailService } from \"./types\";\nimport { assertEmailLinkBases } from \"./link-base\";\nimport { logger } from \"../utils/logger\";\n\nlet _nodemailer: typeof import(\"nodemailer\") | undefined;\n\nasync function loadNodemailer() {\n if (!_nodemailer) {\n try {\n _nodemailer = await import(\"nodemailer\");\n } catch {\n throw new Error(\n \"nodemailer is required for SMTP email. \" +\n \"Install it: pnpm add nodemailer\"\n );\n }\n }\n return _nodemailer;\n}\n\n/**\n * Safely parse a hostname from a URL string\n */\nfunction getHostname(urlStr: string): string | undefined {\n try {\n const url = new URL(urlStr.includes(\"://\") ? urlStr : `https://${urlStr}`);\n return url.hostname;\n } catch {\n return undefined;\n }\n}\n\n/**\n * SMTP Email Service implementation using Nodemailer\n */\nexport class SMTPEmailService implements EmailService {\n private transporter: Transporter | null = null;\n private config: EmailConfig;\n private _initialized = false;\n\n constructor(config: EmailConfig) {\n this.config = config;\n }\n\n /**\n * Lazily initialize the SMTP transporter on first use\n */\n private async ensureTransporter(): Promise<void> {\n if (this._initialized) return;\n this._initialized = true;\n\n if (this.config.smtp) {\n const nodemailer = await loadNodemailer();\n\n let smtpName = this.config.smtp.name;\n if (!smtpName) {\n const urlsToTry = [\n process.env.FRONTEND_URL,\n this.config.resetPasswordUrl,\n this.config.verifyEmailUrl\n ];\n for (const urlStr of urlsToTry) {\n if (urlStr) {\n const hostname = getHostname(urlStr);\n if (hostname) {\n smtpName = hostname;\n break;\n }\n }\n }\n }\n\n this.transporter = nodemailer.createTransport({\n name: smtpName,\n host: this.config.smtp.host,\n port: this.config.smtp.port,\n secure: this.config.smtp.secure ?? (this.config.smtp.port === 465),\n auth: this.config.smtp.auth ? {\n user: this.config.smtp.auth.user,\n pass: this.config.smtp.auth.pass\n } : undefined\n });\n }\n }\n\n /**\n * Check if the email service is properly configured\n */\n isConfigured(): boolean {\n return !!(this.config.smtp || this.config.sendEmail);\n }\n\n /**\n * Send an email using SMTP or custom send function\n */\n async send(options: EmailSendOptions): Promise<void> {\n // Use custom send function if provided\n if (this.config.sendEmail) {\n await this.config.sendEmail(options);\n return;\n }\n\n // Use SMTP transporter\n await this.ensureTransporter();\n\n if (!this.transporter) {\n throw new Error(\"Email service not configured. Provide SMTP config or sendEmail function.\");\n }\n\n const to = Array.isArray(options.to) ? options.to.join(\", \") : options.to;\n\n try {\n await this.transporter.sendMail({\n from: this.config.from,\n to,\n subject: options.subject,\n html: options.html,\n text: options.text,\n replyTo: options.replyTo\n });\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(\"Failed to send email\", { detail: message });\n throw new Error(`Failed to send email: ${message}`);\n }\n }\n\n /**\n * Verify SMTP connection (useful for startup checks)\n */\n async verifyConnection(): Promise<boolean> {\n await this.ensureTransporter();\n\n if (!this.transporter) {\n return !!this.config.sendEmail;\n }\n\n try {\n await this.transporter.verify();\n return true;\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n logger.error(\"SMTP connection verification failed\", { detail: message });\n return false;\n }\n }\n}\n\n/**\n * Create an email service from configuration.\n *\n * This is the choke point every boot path goes through — the managed runtime,\n * both driver bootstrappers, and any app that passes `auth.email` — so it is\n * where the link bases are checked. A config that can send mail but cannot build\n * an absolute link fails the start rather than delivering dead `href=\"/…\"` links\n * and reporting success; see `assertEmailLinkBases`.\n */\nexport function createEmailService(config: EmailConfig): EmailService {\n assertEmailLinkBases(config);\n return new SMTPEmailService(config);\n}\n","/**\n * Where a rate limiter keeps its counts.\n *\n * Split out from the limiter itself because the two have different lifetimes:\n * the policy (how many, how often, keyed by what) is a property of the route,\n * and the storage is a property of the deployment. One process behind one\n * proxy is happy with a Map; several replicas behind a load balancer are not,\n * because a limit of 200 enforced independently by four of them is a limit of\n * 800.\n */\nexport interface RateLimitDecision {\n allowed: boolean;\n /** Requests left in the current window. Zero when `allowed` is false. */\n remaining: number;\n /** How long until the oldest hit falls out of the window. */\n retryAfterMs: number;\n}\n\nexport interface RateLimitStore {\n /**\n * Record a hit against `key` and say whether it is allowed.\n *\n * Called once per request, so it must not be chatty. Implementations are\n * expected to be atomic per key: two concurrent hits must not both read a\n * count of `limit - 1` and both be allowed.\n */\n hit(key: string, windowMs: number, limit: number): Promise<RateLimitDecision>;\n\n /** Release timers/connections. Tests need this; servers rarely do. */\n dispose?(): void;\n}\n\n/**\n * The default store: a sliding window in this process's memory.\n *\n * Sliding rather than fixed: a fixed window lets a caller spend its whole\n * allowance in the last second of one window and again in the first second of\n * the next, which is twice the limit over an instant. Timestamps outside the\n * window are dropped on read, and swept periodically so an idle key does not\n * pin its array forever.\n *\n * Per-process, so N replicas enforce N times the limit between them. That is\n * the honest reason {@link RateLimitStore} exists.\n */\nexport class MemoryRateLimitStore implements RateLimitStore {\n private store = new Map<string, number[]>();\n private cleanupInterval?: ReturnType<typeof setInterval>;\n private now: () => number;\n\n /**\n * `now` exists so the window can be driven directly instead of by sleeping:\n * a test that waits half a real window is a test that fails on a loaded\n * machine, where the sleep overruns and the hits it expects to still be in\n * the window have left it.\n */\n constructor(sweepMs = 15 * 60 * 1000, now: () => number = Date.now) {\n this.now = now;\n this.cleanupInterval = setInterval(() => this.sweep(sweepMs), sweepMs);\n // Never hold the process open for a cache sweep.\n this.cleanupInterval.unref?.();\n }\n\n async hit(key: string, windowMs: number, limit: number): Promise<RateLimitDecision> {\n const now = this.now();\n const timestamps = (this.store.get(key) ?? []).filter(t => now - t < windowMs);\n\n if (timestamps.length >= limit) {\n this.store.set(key, timestamps);\n return {\n allowed: false,\n remaining: 0,\n retryAfterMs: Math.max(0, timestamps[0] + windowMs - now)\n };\n }\n\n timestamps.push(now);\n this.store.set(key, timestamps);\n return {\n allowed: true,\n remaining: limit - timestamps.length,\n retryAfterMs: 0\n };\n }\n\n private sweep(windowMs: number): void {\n const now = this.now();\n for (const [key, timestamps] of this.store.entries()) {\n const live = timestamps.filter(t => now - t < windowMs);\n if (live.length === 0) this.store.delete(key);\n else this.store.set(key, live);\n }\n }\n\n dispose(): void {\n if (this.cleanupInterval) clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n this.store.clear();\n }\n}\n","import { MiddlewareHandler } from \"hono\";\nimport { getConnInfo } from \"@hono/node-server/conninfo\";\nimport { isAnonymousUid } from \"@rebasepro/types\";\nimport { HonoEnv } from \"../api/types\";\nimport { MemoryRateLimitStore, RateLimitStore } from \"./rate-limit-store\";\nimport { logger } from \"../utils/logger\";\n\n/**\n * Sliding-window rate limiting for Hono.\n *\n * The counting lives in a {@link RateLimitStore} — in this process's memory by\n * default, which is a per-replica limit and says so. See `rate-limit-store.ts`.\n */\n\ninterface RateLimiterOptions {\n /** Time window in milliseconds (default: 15 minutes) */\n windowMs?: number;\n /** Maximum requests per window (default: 100) */\n limit?: number;\n /** Key generator function. Defaults to IP-based keying. */\n keyGenerator?: (c: Parameters<MiddlewareHandler<HonoEnv>>[0]) => string;\n /** Custom message for rate limit responses */\n message?: string;\n /**\n * Where to keep the counts. Defaults to a private in-memory store — pass a\n * shared one to have several limiters (or several processes) agree.\n */\n store?: RateLimitStore;\n /**\n * Per-request limit override, for buckets whose allowance is data rather\n * than config (an API key's own `rate_limit`). Returning `undefined` uses\n * `limit`; returning `null` skips the limiter for this request.\n */\n resolveLimit?: (c: Parameters<MiddlewareHandler<HonoEnv>>[0]) => number | null | undefined;\n /**\n * Number of trusted reverse-proxy hops in front of this server. Each hop\n * appends the address it saw to `X-Forwarded-For`, so the real client IP is\n * the Nth entry from the right. Anything further left is client-supplied and\n * ignored — which is what stops a caller spoofing `X-Forwarded-For` to\n * rotate rate-limit keys.\n *\n * **Defaults to `0`: no proxy is trusted, and `X-Forwarded-For` and\n * `X-Real-IP` are both ignored in favour of the socket address.** A server\n * cannot tell from a request whether a proxy put that header there or the\n * caller did, so the number of hops is a deployment fact that has to be\n * declared. It previously defaulted to `1`, and nothing in the repo ever\n * set it — so on any directly-exposed server (`rebase dev`, a self-hosted\n * `rebase-server`, a passthrough load balancer) one header gave every\n * IP-keyed limiter an effective limit of one request per attacker-chosen\n * value.\n *\n * Set it — via this option or `TRUSTED_PROXY_HOPS` — to the number of\n * proxies you actually run. Behind one ingress or load balancer that is\n * `1`. Leaving it unset behind a proxy makes every client share the\n * proxy's address as one bucket, which the boot-time warning below tells\n * you about the first time it happens.\n */\n trustedProxyHops?: number;\n}\n\n/**\n * Resolve the number of trusted proxy hops from an explicit option, the\n * `TRUSTED_PROXY_HOPS` env var, or the fail-safe default of 0.\n *\n * Zero, not one: trusting a hop that is not there hands the rate-limit key to\n * the caller, and a server has no way to detect the difference from a request.\n */\nfunction resolveTrustedProxyHops(optionValue?: number): number {\n if (typeof optionValue === \"number\" && Number.isFinite(optionValue) && optionValue >= 0) {\n return Math.floor(optionValue);\n }\n const fromEnv = Number(process.env.TRUSTED_PROXY_HOPS);\n if (Number.isFinite(fromEnv) && fromEnv >= 0) {\n return Math.floor(fromEnv);\n }\n return 0;\n}\n\n/**\n * Warn once when the deployment looks proxied but has not said so.\n *\n * The safe default is the wrong answer for the other common topology: behind an\n * ingress, every request arrives from the proxy, so ignoring `X-Forwarded-For`\n * collapses every client into one bucket and the limiter starts locking real\n * users out of each other's quota. That is a loud failure in production and a\n * silent one in staging, so it gets a warning rather than a guess — guessing is\n * what made the header trustworthy in the first place.\n */\nlet warnedAboutUntrustedForwardedFor = false;\n\nfunction warnIfProxiedButUntrusted(hasForwardedFor: boolean): void {\n if (!hasForwardedFor || warnedAboutUntrustedForwardedFor) return;\n warnedAboutUntrustedForwardedFor = true;\n logger.warn(\n \"[RateLimit] Requests carry X-Forwarded-For but TRUSTED_PROXY_HOPS is 0, so it is \" +\n \"being ignored and every client behind the proxy shares one rate-limit bucket. \" +\n \"If this server really is behind a reverse proxy, set TRUSTED_PROXY_HOPS to the \" +\n \"number of proxies in front of it (1 for a single ingress or load balancer). \" +\n \"If it is exposed directly, this warning means someone is sending the header \" +\n \"themselves and 0 is the correct setting.\"\n );\n}\n\n/**\n * Create a rate-limiting middleware.\n *\n * Uses a sliding window: only hits within the last `windowMs` are counted.\n */\nexport function createRateLimiter(options: RateLimiterOptions = {}): MiddlewareHandler<HonoEnv> {\n const trustedProxyHops = resolveTrustedProxyHops(options.trustedProxyHops);\n const {\n windowMs = 15 * 60 * 1000,\n limit = 100,\n keyGenerator = (c: Parameters<MiddlewareHandler<HonoEnv>>[0]) => defaultKeyGenerator(c, trustedProxyHops),\n message = \"Too many requests, please try again later.\",\n store = new MemoryRateLimitStore(windowMs),\n resolveLimit\n } = options;\n\n return async (c, next) => {\n const effectiveLimit = resolveLimit ? resolveLimit(c) : limit;\n // `null` means \"not my bucket\" — e.g. an API-key limiter looking at a\n // request that carries no API key.\n if (effectiveLimit === null) return next();\n const activeLimit = effectiveLimit ?? limit;\n\n const decision = await store.hit(keyGenerator(c), windowMs, activeLimit);\n\n c.header(\"X-RateLimit-Limit\", String(activeLimit));\n c.header(\"X-RateLimit-Remaining\", String(decision.remaining));\n\n if (!decision.allowed) {\n const retryAfterSec = Math.ceil(decision.retryAfterMs / 1000);\n c.header(\"Retry-After\", String(retryAfterSec));\n c.header(\"X-RateLimit-Reset\", String(Math.ceil((Date.now() + decision.retryAfterMs) / 1000)));\n\n return c.json({\n error: {\n message,\n code: \"RATE_LIMITED\"\n }\n }, 429);\n }\n\n return next();\n };\n}\n\n/**\n * The address the socket is actually connected to, or `undefined` on a runtime\n * that cannot say. Unforgeable, unlike every header below.\n *\n * `getConnInfo` is Node-specific and throws elsewhere, so the failure is\n * swallowed: a runtime without connection info falls back to the shared bucket,\n * which is a availability trade the caller cannot exploit.\n */\nfunction socketAddress(c: Parameters<MiddlewareHandler<HonoEnv>>[0]): string | undefined {\n try {\n return getConnInfo(c).remote.address;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Default key generator: the client's address, from the most trustworthy source\n * this deployment has.\n *\n * `X-Forwarded-For` is a client-writable header; only the entries appended by\n * trusted reverse proxies can be believed. With `trustedProxyHops` proxies in\n * front, each appends the address it saw, so the real client IP is the\n * `trustedProxyHops`-th entry from the right — everything further left is\n * client-supplied and must be ignored. This is what prevents a caller from\n * spoofing `X-Forwarded-For` to spread its requests across many rate-limit keys.\n *\n * `X-Real-IP` is the *same* kind of header and needs the same rule, which it\n * did not have: it was read unconditionally, including under\n * `trustedProxyHops === 0` — the mode whose entire meaning is \"no proxy is in\n * front of me\". With no proxy there, nothing writes `X-Real-IP` except the\n * caller, so the key was theirs to choose: one header per request bought an\n * unlimited number of buckets, and the limiters on login, registration and\n * password reset counted to one. The reasoning had been done carefully for one\n * spelling of a proxy header and not carried to its twin.\n *\n * So `X-Real-IP` is now believed only where a proxy is declared to exist. With\n * none, the connection's own address is used — unforgeable, and available\n * because the server runs on `@hono/node-server`. `\"unknown\"` is the last\n * resort only, and it is a single shared bucket by design: better that\n * anonymous callers throttle each other than that any of them throttles nobody.\n */\nfunction defaultKeyGenerator(\n c: Parameters<MiddlewareHandler<HonoEnv>>[0],\n trustedProxyHops: number = resolveTrustedProxyHops()\n): string {\n if (trustedProxyHops === 0) {\n // Neither header is evidence of anything: both are trivially set by the\n // caller, and no proxy has been declared that would overwrite them.\n warnIfProxiedButUntrusted(!!c.req.header(\"x-forwarded-for\"));\n return socketAddress(c) ?? \"unknown\";\n }\n\n {\n const forwardedFor = c.req.header(\"x-forwarded-for\");\n if (forwardedFor) {\n const ips = forwardedFor.split(\",\").map(s => s.trim()).filter(Boolean);\n if (ips.length > 0) {\n const idx = Math.max(0, ips.length - trustedProxyHops);\n return ips[idx];\n }\n }\n // A trusted proxy is declared to be in front, so this header is its to\n // set — and a proxy that sets only `X-Real-IP` (the stock nginx recipe)\n // is a normal deployment.\n const realIp = c.req.header(\"x-real-ip\");\n if (realIp) return realIp;\n }\n return socketAddress(c) ?? \"unknown\";\n}\n\n/**\n * Pre-configured rate limiter for general auth endpoints (login, register).\n * 200 requests per 15 minutes per IP.\n */\nexport const defaultAuthLimiter = createRateLimiter({\n windowMs: 15 * 60 * 1000,\n limit: 200,\n message: \"Too many authentication attempts, please try again later.\"\n});\n\n/**\n * Pre-configured strict rate limiter for sensitive endpoints (password reset, verification).\n * 50 requests per 15 minutes per IP.\n */\nexport const strictAuthLimiter = createRateLimiter({\n windowMs: 15 * 60 * 1000,\n limit: 50,\n message: \"Too many requests to this sensitive endpoint, please try again later.\"\n});\n\n/**\n * Limiter for `POST /auth/send-verification`, keyed by the authenticated user.\n *\n * That route had no limiter at all while every one of its email-sending\n * siblings had one, and being authenticated is not the protection it looks\n * like: registration does not verify the address it is given, so an attacker\n * registers a victim's address, signs in to the account they just made, and\n * loops the route. Each call mints a token and mails the victim.\n *\n * An IP limiter cannot express what is wanted here — the recipient is the\n * quantity being protected, not the caller — so this one keys on the uid, which\n * on this route is one-to-one with the recipient address (emails are unique per\n * account). `strictAuthLimiter` still runs in front of it to bound the caller by\n * IP; this bounds what any single address can be sent.\n *\n * Five per 15 minutes is generous for \"I didn't get the email, resend it\" and\n * useless as a mail bomb. Unauthenticated requests fall back to the IP bucket so\n * the limiter is never a no-op if it is ever mounted before the auth middleware.\n */\nexport const verificationEmailLimiter = createRateLimiter({\n windowMs: 15 * 60 * 1000,\n limit: 5,\n keyGenerator: (c) => {\n const user = c.get(\"user\") as { uid?: string } | undefined;\n return user?.uid\n ? `verification-email:user:${user.uid}`\n : `verification-email:ip:${defaultKeyGenerator(c)}`;\n },\n message: \"Too many verification emails requested, please try again later.\"\n});\n\n/**\n * Key generator for API-key-based rate limiting.\n *\n * Uses the API key ID (from `c.get(\"apiKey\")`) as the rate limit key.\n * Falls back to IP-based keying when the request is not authenticated\n * via an API key.\n */\nexport function apiKeyKeyGenerator(c: Parameters<MiddlewareHandler<HonoEnv>>[0]): string {\n const apiKey = c.get(\"apiKey\") as { id: string } | undefined;\n if (apiKey) {\n return `api-key:${apiKey.id}`;\n }\n return defaultKeyGenerator(c);\n}\n\n/** How the data API's limits are apportioned. All fields optional. */\nexport interface DataRateLimitConfig {\n /** Turn the whole thing off — for a deployment whose proxy already does it. */\n enabled?: boolean;\n /**\n * Trusted reverse-proxy hops, for the IP bucket. Same meaning and same\n * fail-safe default of 0 as {@link RateLimiterOptions.trustedProxyHops} —\n * threaded explicitly because this limiter builds its own key generator,\n * and before this existed the option was accepted by the surrounding\n * limiter and then ignored for the one bucket that keys on an address.\n */\n trustedProxyHops?: number;\n windowMs?: number;\n /** Fallback for an API key with no `rate_limit` of its own. Default 1000. */\n apiKey?: number;\n /** Per signed-in user. Default 1000. */\n user?: number;\n /**\n * Per IP, for requests with no principal at all. Default 300.\n * `null` disables the anonymous bucket entirely.\n */\n anonymous?: number | null;\n /**\n * Per IP, for anonymous requests to `/api/functions/*`. Default 3000 —\n * deliberately far looser than {@link anonymous}, because the functions\n * router is public by default for webhook receivers (Stripe, GitHub) whose\n * bursts arrive from a handful of provider IPs and would trip the data\n * API's ceiling.\n *\n * The looseness bounds the *value*, not the existence of the limit: this\n * router is the one that invites anonymous callers, so it is the last one\n * that should have no ceiling at all. `null` disables it — an explicit\n * choice, which is what the hardcoded `anonymous: null` here used to be\n * without any way to say otherwise.\n */\n anonymousFunctions?: number | null;\n /** Share counts across replicas. Defaults to this process's memory. */\n store?: RateLimitStore;\n}\n\n/** @see DataRateLimitConfig.anonymousFunctions */\nexport const DEFAULT_FUNCTIONS_ANONYMOUS_LIMIT = 3000;\n\n/**\n * Rate limiting for the data API.\n *\n * Every request is in exactly one bucket, resolved most-specific first: an API\n * key by its id, a signed-in user by their uid, anyone else by IP. Previously\n * only the first of those was limited at all — the middleware returned early\n * for any request without an API key — so JWT and anonymous traffic to\n * `/api/data/*` was unbounded, which is most of the traffic a BaaS gets.\n *\n * Per bucket, not per route: the point is to bound what one caller costs, and\n * they can spend it wherever they like.\n *\n * The defaults are deliberately loose. This is a floor against a runaway client\n * or a naive scraper, not a quota — a deployment that wants real quotas should\n * set them, and one that already has a proxy doing this should pass\n * `enabled: false` rather than pay for it twice.\n */\nexport function createDataRateLimiter(config: DataRateLimitConfig = {}): MiddlewareHandler<HonoEnv> {\n const {\n windowMs = 15 * 60 * 1000,\n apiKey: apiKeyLimit = 1000,\n user: userLimit = 1000,\n anonymous: anonLimit = 300,\n // One store for every bucket: the keys are already namespaced, and a\n // shared store is what makes a shared limit possible.\n store = new MemoryRateLimitStore(windowMs)\n } = config;\n const trustedProxyHops = resolveTrustedProxyHops(config.trustedProxyHops);\n\n return createRateLimiter({\n windowMs,\n store,\n message: \"Too many requests, please try again later.\",\n keyGenerator: (c) => {\n const key = c.get(\"apiKey\") as { id: string } | undefined;\n if (key) return `api-key:${key.id}`;\n const user = c.get(\"user\") as { uid?: string } | undefined;\n if (user?.uid && !isAnonymousUid(user.uid)) return `user:${user.uid}`;\n return `ip:${defaultKeyGenerator(c, trustedProxyHops)}`;\n },\n resolveLimit: (c) => {\n const key = c.get(\"apiKey\") as { id: string; rate_limit?: number | null } | undefined;\n if (key) return key.rate_limit ?? apiKeyLimit;\n const user = c.get(\"user\") as { uid?: string } | undefined;\n if (user?.uid && !isAnonymousUid(user.uid)) return userLimit;\n return anonLimit;\n }\n });\n}\n\n","var _a;\n/** A special constant with type `never` */\nexport const NEVER = /*@__PURE__*/ Object.freeze({\n status: \"aborted\",\n});\nexport /*@__NO_SIDE_EFFECTS__*/ function $constructor(name, initializer, params) {\n function init(inst, def) {\n if (!inst._zod) {\n Object.defineProperty(inst, \"_zod\", {\n value: {\n def,\n constr: _,\n traits: new Set(),\n },\n enumerable: false,\n });\n }\n if (inst._zod.traits.has(name)) {\n return;\n }\n inst._zod.traits.add(name);\n initializer(inst, def);\n // support prototype modifications\n const proto = _.prototype;\n const keys = Object.keys(proto);\n for (let i = 0; i < keys.length; i++) {\n const k = keys[i];\n if (!(k in inst)) {\n inst[k] = proto[k].bind(inst);\n }\n }\n }\n // doesn't work if Parent has a constructor with arguments\n const Parent = params?.Parent ?? Object;\n class Definition extends Parent {\n }\n Object.defineProperty(Definition, \"name\", { value: name });\n function _(def) {\n var _a;\n const inst = params?.Parent ? new Definition() : this;\n init(inst, def);\n (_a = inst._zod).deferred ?? (_a.deferred = []);\n for (const fn of inst._zod.deferred) {\n fn();\n }\n return inst;\n }\n Object.defineProperty(_, \"init\", { value: init });\n Object.defineProperty(_, Symbol.hasInstance, {\n value: (inst) => {\n if (params?.Parent && inst instanceof params.Parent)\n return true;\n return inst?._zod?.traits?.has(name);\n },\n });\n Object.defineProperty(_, \"name\", { value: name });\n return _;\n}\n////////////////////////////// UTILITIES ///////////////////////////////////////\nexport const $brand = Symbol(\"zod_brand\");\nexport class $ZodAsyncError extends Error {\n constructor() {\n super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);\n }\n}\nexport class $ZodEncodeError extends Error {\n constructor(name) {\n super(`Encountered unidirectional transform during encode: ${name}`);\n this.name = \"ZodEncodeError\";\n }\n}\n(_a = globalThis).__zod_globalConfig ?? (_a.__zod_globalConfig = {});\nexport const globalConfig = globalThis.__zod_globalConfig;\nexport function config(newConfig) {\n if (newConfig)\n Object.assign(globalConfig, newConfig);\n return globalConfig;\n}\n","import { globalConfig } from \"./core.js\";\n// functions\nexport function assertEqual(val) {\n return val;\n}\nexport function assertNotEqual(val) {\n return val;\n}\nexport function assertIs(_arg) { }\nexport function assertNever(_x) {\n throw new Error(\"Unexpected value in exhaustive check\");\n}\nexport function assert(_) { }\nexport function getEnumValues(entries) {\n const numericValues = Object.values(entries).filter((v) => typeof v === \"number\");\n const values = Object.entries(entries)\n .filter(([k, _]) => numericValues.indexOf(+k) === -1)\n .map(([_, v]) => v);\n return values;\n}\nexport function joinValues(array, separator = \"|\") {\n return array.map((val) => stringifyPrimitive(val)).join(separator);\n}\nexport function jsonStringifyReplacer(_, value) {\n if (typeof value === \"bigint\")\n return value.toString();\n return value;\n}\nexport function cached(getter) {\n const set = false;\n return {\n get value() {\n if (!set) {\n const value = getter();\n Object.defineProperty(this, \"value\", { value });\n return value;\n }\n throw new Error(\"cached value already set\");\n },\n };\n}\nexport function nullish(input) {\n return input === null || input === undefined;\n}\nexport function cleanRegex(source) {\n const start = source.startsWith(\"^\") ? 1 : 0;\n const end = source.endsWith(\"$\") ? source.length - 1 : source.length;\n return source.slice(start, end);\n}\nexport function floatSafeRemainder(val, step) {\n const ratio = val / step;\n const roundedRatio = Math.round(ratio);\n // Use a relative epsilon scaled to the magnitude of the result\n const tolerance = Number.EPSILON * Math.max(Math.abs(ratio), 1);\n if (Math.abs(ratio - roundedRatio) < tolerance)\n return 0;\n return ratio - roundedRatio;\n}\nconst EVALUATING = /* @__PURE__*/ Symbol(\"evaluating\");\nexport function defineLazy(object, key, getter) {\n let value = undefined;\n Object.defineProperty(object, key, {\n get() {\n if (value === EVALUATING) {\n // Circular reference detected, return undefined to break the cycle\n return undefined;\n }\n if (value === undefined) {\n value = EVALUATING;\n value = getter();\n }\n return value;\n },\n set(v) {\n Object.defineProperty(object, key, {\n value: v,\n // configurable: true,\n });\n // object[key] = v;\n },\n configurable: true,\n });\n}\nexport function objectClone(obj) {\n return Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj));\n}\nexport function assignProp(target, prop, value) {\n Object.defineProperty(target, prop, {\n value,\n writable: true,\n enumerable: true,\n configurable: true,\n });\n}\nexport function mergeDefs(...defs) {\n const mergedDescriptors = {};\n for (const def of defs) {\n const descriptors = Object.getOwnPropertyDescriptors(def);\n Object.assign(mergedDescriptors, descriptors);\n }\n return Object.defineProperties({}, mergedDescriptors);\n}\nexport function cloneDef(schema) {\n return mergeDefs(schema._zod.def);\n}\nexport function getElementAtPath(obj, path) {\n if (!path)\n return obj;\n return path.reduce((acc, key) => acc?.[key], obj);\n}\nexport function promiseAllObject(promisesObj) {\n const keys = Object.keys(promisesObj);\n const promises = keys.map((key) => promisesObj[key]);\n return Promise.all(promises).then((results) => {\n const resolvedObj = {};\n for (let i = 0; i < keys.length; i++) {\n resolvedObj[keys[i]] = results[i];\n }\n return resolvedObj;\n });\n}\nexport function randomString(length = 10) {\n const chars = \"abcdefghijklmnopqrstuvwxyz\";\n let str = \"\";\n for (let i = 0; i < length; i++) {\n str += chars[Math.floor(Math.random() * chars.length)];\n }\n return str;\n}\nexport function esc(str) {\n return JSON.stringify(str);\n}\nexport function slugify(input) {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, \"\")\n .replace(/[\\s_-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n}\nexport const captureStackTrace = (\"captureStackTrace\" in Error ? Error.captureStackTrace : (..._args) => { });\nexport function isObject(data) {\n return typeof data === \"object\" && data !== null && !Array.isArray(data);\n}\nexport const allowsEval = /* @__PURE__*/ cached(() => {\n // Skip the probe under `jitless`: strict CSPs report the caught `new Function`\n // as a `securitypolicyviolation` even though the throw is swallowed.\n if (globalConfig.jitless) {\n return false;\n }\n // @ts-ignore\n if (typeof navigator !== \"undefined\" && navigator?.userAgent?.includes(\"Cloudflare\")) {\n return false;\n }\n try {\n const F = Function;\n new F(\"\");\n return true;\n }\n catch (_) {\n return false;\n }\n});\nexport function isPlainObject(o) {\n if (isObject(o) === false)\n return false;\n // modified constructor\n const ctor = o.constructor;\n if (ctor === undefined)\n return true;\n if (typeof ctor !== \"function\")\n return true;\n // modified prototype\n const prot = ctor.prototype;\n if (isObject(prot) === false)\n return false;\n // ctor doesn't have static `isPrototypeOf`\n if (Object.prototype.hasOwnProperty.call(prot, \"isPrototypeOf\") === false) {\n return false;\n }\n return true;\n}\nexport function shallowClone(o) {\n if (isPlainObject(o))\n return { ...o };\n if (Array.isArray(o))\n return [...o];\n if (o instanceof Map)\n return new Map(o);\n if (o instanceof Set)\n return new Set(o);\n return o;\n}\nexport function numKeys(data) {\n let keyCount = 0;\n for (const key in data) {\n if (Object.prototype.hasOwnProperty.call(data, key)) {\n keyCount++;\n }\n }\n return keyCount;\n}\nexport const getParsedType = (data) => {\n const t = typeof data;\n switch (t) {\n case \"undefined\":\n return \"undefined\";\n case \"string\":\n return \"string\";\n case \"number\":\n return Number.isNaN(data) ? \"nan\" : \"number\";\n case \"boolean\":\n return \"boolean\";\n case \"function\":\n return \"function\";\n case \"bigint\":\n return \"bigint\";\n case \"symbol\":\n return \"symbol\";\n case \"object\":\n if (Array.isArray(data)) {\n return \"array\";\n }\n if (data === null) {\n return \"null\";\n }\n if (data.then && typeof data.then === \"function\" && data.catch && typeof data.catch === \"function\") {\n return \"promise\";\n }\n if (typeof Map !== \"undefined\" && data instanceof Map) {\n return \"map\";\n }\n if (typeof Set !== \"undefined\" && data instanceof Set) {\n return \"set\";\n }\n if (typeof Date !== \"undefined\" && data instanceof Date) {\n return \"date\";\n }\n // @ts-ignore\n if (typeof File !== \"undefined\" && data instanceof File) {\n return \"file\";\n }\n return \"object\";\n default:\n throw new Error(`Unknown data type: ${t}`);\n }\n};\nexport const propertyKeyTypes = /* @__PURE__*/ new Set([\"string\", \"number\", \"symbol\"]);\nexport const primitiveTypes = /* @__PURE__*/ new Set([\n \"string\",\n \"number\",\n \"bigint\",\n \"boolean\",\n \"symbol\",\n \"undefined\",\n]);\nexport function escapeRegex(str) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n// zod-specific utils\nexport function clone(inst, def, params) {\n const cl = new inst._zod.constr(def ?? inst._zod.def);\n if (!def || params?.parent)\n cl._zod.parent = inst;\n return cl;\n}\nexport function normalizeParams(_params) {\n const params = _params;\n if (!params)\n return {};\n if (typeof params === \"string\")\n return { error: () => params };\n if (params?.message !== undefined) {\n if (params?.error !== undefined)\n throw new Error(\"Cannot specify both `message` and `error` params\");\n params.error = params.message;\n }\n delete params.message;\n if (typeof params.error === \"string\")\n return { ...params, error: () => params.error };\n return params;\n}\nexport function createTransparentProxy(getter) {\n let target;\n return new Proxy({}, {\n get(_, prop, receiver) {\n target ?? (target = getter());\n return Reflect.get(target, prop, receiver);\n },\n set(_, prop, value, receiver) {\n target ?? (target = getter());\n return Reflect.set(target, prop, value, receiver);\n },\n has(_, prop) {\n target ?? (target = getter());\n return Reflect.has(target, prop);\n },\n deleteProperty(_, prop) {\n target ?? (target = getter());\n return Reflect.deleteProperty(target, prop);\n },\n ownKeys(_) {\n target ?? (target = getter());\n return Reflect.ownKeys(target);\n },\n getOwnPropertyDescriptor(_, prop) {\n target ?? (target = getter());\n return Reflect.getOwnPropertyDescriptor(target, prop);\n },\n defineProperty(_, prop, descriptor) {\n target ?? (target = getter());\n return Reflect.defineProperty(target, prop, descriptor);\n },\n });\n}\nexport function stringifyPrimitive(value) {\n if (typeof value === \"bigint\")\n return value.toString() + \"n\";\n if (typeof value === \"string\")\n return `\"${value}\"`;\n return `${value}`;\n}\nexport function optionalKeys(shape) {\n return Object.keys(shape).filter((k) => {\n return shape[k]._zod.optin === \"optional\" && shape[k]._zod.optout === \"optional\";\n });\n}\nexport const NUMBER_FORMAT_RANGES = {\n safeint: [Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER],\n int32: [-2147483648, 2147483647],\n uint32: [0, 4294967295],\n float32: [-3.4028234663852886e38, 3.4028234663852886e38],\n float64: [-Number.MAX_VALUE, Number.MAX_VALUE],\n};\nexport const BIGINT_FORMAT_RANGES = {\n int64: [/* @__PURE__*/ BigInt(\"-9223372036854775808\"), /* @__PURE__*/ BigInt(\"9223372036854775807\")],\n uint64: [/* @__PURE__*/ BigInt(0), /* @__PURE__*/ BigInt(\"18446744073709551615\")],\n};\nexport function pick(schema, mask) {\n const currDef = schema._zod.def;\n const checks = currDef.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n throw new Error(\".pick() cannot be used on object schemas containing refinements\");\n }\n const def = mergeDefs(schema._zod.def, {\n get shape() {\n const newShape = {};\n for (const key in mask) {\n if (!(key in currDef.shape)) {\n throw new Error(`Unrecognized key: \"${key}\"`);\n }\n if (!mask[key])\n continue;\n newShape[key] = currDef.shape[key];\n }\n assignProp(this, \"shape\", newShape); // self-caching\n return newShape;\n },\n checks: [],\n });\n return clone(schema, def);\n}\nexport function omit(schema, mask) {\n const currDef = schema._zod.def;\n const checks = currDef.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n throw new Error(\".omit() cannot be used on object schemas containing refinements\");\n }\n const def = mergeDefs(schema._zod.def, {\n get shape() {\n const newShape = { ...schema._zod.def.shape };\n for (const key in mask) {\n if (!(key in currDef.shape)) {\n throw new Error(`Unrecognized key: \"${key}\"`);\n }\n if (!mask[key])\n continue;\n delete newShape[key];\n }\n assignProp(this, \"shape\", newShape); // self-caching\n return newShape;\n },\n checks: [],\n });\n return clone(schema, def);\n}\nexport function extend(schema, shape) {\n if (!isPlainObject(shape)) {\n throw new Error(\"Invalid input to extend: expected a plain object\");\n }\n const checks = schema._zod.def.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n // Only throw if new shape overlaps with existing shape\n // Use getOwnPropertyDescriptor to check key existence without accessing values\n const existingShape = schema._zod.def.shape;\n for (const key in shape) {\n if (Object.getOwnPropertyDescriptor(existingShape, key) !== undefined) {\n throw new Error(\"Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.\");\n }\n }\n }\n const def = mergeDefs(schema._zod.def, {\n get shape() {\n const _shape = { ...schema._zod.def.shape, ...shape };\n assignProp(this, \"shape\", _shape); // self-caching\n return _shape;\n },\n });\n return clone(schema, def);\n}\nexport function safeExtend(schema, shape) {\n if (!isPlainObject(shape)) {\n throw new Error(\"Invalid input to safeExtend: expected a plain object\");\n }\n const def = mergeDefs(schema._zod.def, {\n get shape() {\n const _shape = { ...schema._zod.def.shape, ...shape };\n assignProp(this, \"shape\", _shape); // self-caching\n return _shape;\n },\n });\n return clone(schema, def);\n}\nexport function merge(a, b) {\n if (a._zod.def.checks?.length) {\n throw new Error(\".merge() cannot be used on object schemas containing refinements. Use .safeExtend() instead.\");\n }\n const def = mergeDefs(a._zod.def, {\n get shape() {\n const _shape = { ...a._zod.def.shape, ...b._zod.def.shape };\n assignProp(this, \"shape\", _shape); // self-caching\n return _shape;\n },\n get catchall() {\n return b._zod.def.catchall;\n },\n checks: b._zod.def.checks ?? [],\n });\n return clone(a, def);\n}\nexport function partial(Class, schema, mask) {\n const currDef = schema._zod.def;\n const checks = currDef.checks;\n const hasChecks = checks && checks.length > 0;\n if (hasChecks) {\n throw new Error(\".partial() cannot be used on object schemas containing refinements\");\n }\n const def = mergeDefs(schema._zod.def, {\n get shape() {\n const oldShape = schema._zod.def.shape;\n const shape = { ...oldShape };\n if (mask) {\n for (const key in mask) {\n if (!(key in oldShape)) {\n throw new Error(`Unrecognized key: \"${key}\"`);\n }\n if (!mask[key])\n continue;\n // if (oldShape[key]!._zod.optin === \"optional\") continue;\n shape[key] = Class\n ? new Class({\n type: \"optional\",\n innerType: oldShape[key],\n })\n : oldShape[key];\n }\n }\n else {\n for (const key in oldShape) {\n // if (oldShape[key]!._zod.optin === \"optional\") continue;\n shape[key] = Class\n ? new Class({\n type: \"optional\",\n innerType: oldShape[key],\n })\n : oldShape[key];\n }\n }\n assignProp(this, \"shape\", shape); // self-caching\n return shape;\n },\n checks: [],\n });\n return clone(schema, def);\n}\nexport function required(Class, schema, mask) {\n const def = mergeDefs(schema._zod.def, {\n get shape() {\n const oldShape = schema._zod.def.shape;\n const shape = { ...oldShape };\n if (mask) {\n for (const key in mask) {\n if (!(key in shape)) {\n throw new Error(`Unrecognized key: \"${key}\"`);\n }\n if (!mask[key])\n continue;\n // overwrite with non-optional\n shape[key] = new Class({\n type: \"nonoptional\",\n innerType: oldShape[key],\n });\n }\n }\n else {\n for (const key in oldShape) {\n // overwrite with non-optional\n shape[key] = new Class({\n type: \"nonoptional\",\n innerType: oldShape[key],\n });\n }\n }\n assignProp(this, \"shape\", shape); // self-caching\n return shape;\n },\n });\n return clone(schema, def);\n}\n// invalid_type | too_big | too_small | invalid_format | not_multiple_of | unrecognized_keys | invalid_union | invalid_key | invalid_element | invalid_value | custom\nexport function aborted(x, startIndex = 0) {\n if (x.aborted === true)\n return true;\n for (let i = startIndex; i < x.issues.length; i++) {\n if (x.issues[i]?.continue !== true) {\n return true;\n }\n }\n return false;\n}\n// Checks for explicit abort (continue === false), as opposed to implicit abort (continue === undefined).\n// Used to respect `abort: true` in .refine() even for checks that have a `when` function.\nexport function explicitlyAborted(x, startIndex = 0) {\n if (x.aborted === true)\n return true;\n for (let i = startIndex; i < x.issues.length; i++) {\n if (x.issues[i]?.continue === false) {\n return true;\n }\n }\n return false;\n}\nexport function prefixIssues(path, issues) {\n return issues.map((iss) => {\n var _a;\n (_a = iss).path ?? (_a.path = []);\n iss.path.unshift(path);\n return iss;\n });\n}\nexport function unwrapMessage(message) {\n return typeof message === \"string\" ? message : message?.message;\n}\nexport function finalizeIssue(iss, ctx, config) {\n const message = iss.message\n ? iss.message\n : (unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ??\n unwrapMessage(ctx?.error?.(iss)) ??\n unwrapMessage(config.customError?.(iss)) ??\n unwrapMessage(config.localeError?.(iss)) ??\n \"Invalid input\");\n const { inst: _inst, continue: _continue, input: _input, ...rest } = iss;\n rest.path ?? (rest.path = []);\n rest.message = message;\n if (ctx?.reportInput) {\n rest.input = _input;\n }\n return rest;\n}\nexport function getSizableOrigin(input) {\n if (input instanceof Set)\n return \"set\";\n if (input instanceof Map)\n return \"map\";\n // @ts-ignore\n if (input instanceof File)\n return \"file\";\n return \"unknown\";\n}\nexport function getLengthableOrigin(input) {\n if (Array.isArray(input))\n return \"array\";\n if (typeof input === \"string\")\n return \"string\";\n return \"unknown\";\n}\nexport function parsedType(data) {\n const t = typeof data;\n switch (t) {\n case \"number\": {\n return Number.isNaN(data) ? \"nan\" : \"number\";\n }\n case \"object\": {\n if (data === null) {\n return \"null\";\n }\n if (Array.isArray(data)) {\n return \"array\";\n }\n const obj = data;\n if (obj && Object.getPrototypeOf(obj) !== Object.prototype && \"constructor\" in obj && obj.constructor) {\n return obj.constructor.name;\n }\n }\n }\n return t;\n}\nexport function issue(...args) {\n const [iss, input, inst] = args;\n if (typeof iss === \"string\") {\n return {\n message: iss,\n code: \"custom\",\n input,\n inst,\n };\n }\n return { ...iss };\n}\nexport function cleanEnum(obj) {\n return Object.entries(obj)\n .filter(([k, _]) => {\n // return true if NaN, meaning it's not a number, thus a string key\n return Number.isNaN(Number.parseInt(k, 10));\n })\n .map((el) => el[1]);\n}\n// Codec utility functions\nexport function base64ToUint8Array(base64) {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n}\nexport function uint8ArrayToBase64(bytes) {\n let binaryString = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binaryString += String.fromCharCode(bytes[i]);\n }\n return btoa(binaryString);\n}\nexport function base64urlToUint8Array(base64url) {\n const base64 = base64url.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const padding = \"=\".repeat((4 - (base64.length % 4)) % 4);\n return base64ToUint8Array(base64 + padding);\n}\nexport function uint8ArrayToBase64url(bytes) {\n return uint8ArrayToBase64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=/g, \"\");\n}\nexport function hexToUint8Array(hex) {\n const cleanHex = hex.replace(/^0x/, \"\");\n if (cleanHex.length % 2 !== 0) {\n throw new Error(\"Invalid hex string length\");\n }\n const bytes = new Uint8Array(cleanHex.length / 2);\n for (let i = 0; i < cleanHex.length; i += 2) {\n bytes[i / 2] = Number.parseInt(cleanHex.slice(i, i + 2), 16);\n }\n return bytes;\n}\nexport function uint8ArrayToHex(bytes) {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n// instanceof\nexport class Class {\n constructor(..._args) { }\n}\n","import { $constructor } from \"./core.js\";\nimport * as util from \"./util.js\";\nconst initializer = (inst, def) => {\n inst.name = \"$ZodError\";\n Object.defineProperty(inst, \"_zod\", {\n value: inst._zod,\n enumerable: false,\n });\n Object.defineProperty(inst, \"issues\", {\n value: def,\n enumerable: false,\n });\n inst.message = JSON.stringify(def, util.jsonStringifyReplacer, 2);\n Object.defineProperty(inst, \"toString\", {\n value: () => inst.message,\n enumerable: false,\n });\n};\nexport const $ZodError = $constructor(\"$ZodError\", initializer);\nexport const $ZodRealError = $constructor(\"$ZodError\", initializer, { Parent: Error });\nexport function flattenError(error, mapper = (issue) => issue.message) {\n const fieldErrors = {};\n const formErrors = [];\n for (const sub of error.issues) {\n if (sub.path.length > 0) {\n fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];\n fieldErrors[sub.path[0]].push(mapper(sub));\n }\n else {\n formErrors.push(mapper(sub));\n }\n }\n return { formErrors, fieldErrors };\n}\nexport function formatError(error, mapper = (issue) => issue.message) {\n const fieldErrors = { _errors: [] };\n const processError = (error, path = []) => {\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\" && issue.errors.length) {\n issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));\n }\n else if (issue.code === \"invalid_key\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else if (issue.code === \"invalid_element\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else {\n const fullpath = [...path, ...issue.path];\n if (fullpath.length === 0) {\n fieldErrors._errors.push(mapper(issue));\n }\n else {\n let curr = fieldErrors;\n let i = 0;\n while (i < fullpath.length) {\n const el = fullpath[i];\n const terminal = i === fullpath.length - 1;\n if (!terminal) {\n curr[el] = curr[el] || { _errors: [] };\n }\n else {\n curr[el] = curr[el] || { _errors: [] };\n curr[el]._errors.push(mapper(issue));\n }\n curr = curr[el];\n i++;\n }\n }\n }\n }\n };\n processError(error);\n return fieldErrors;\n}\nexport function treeifyError(error, mapper = (issue) => issue.message) {\n const result = { errors: [] };\n const processError = (error, path = []) => {\n var _a, _b;\n for (const issue of error.issues) {\n if (issue.code === \"invalid_union\" && issue.errors.length) {\n // regular union error\n issue.errors.map((issues) => processError({ issues }, [...path, ...issue.path]));\n }\n else if (issue.code === \"invalid_key\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else if (issue.code === \"invalid_element\") {\n processError({ issues: issue.issues }, [...path, ...issue.path]);\n }\n else {\n const fullpath = [...path, ...issue.path];\n if (fullpath.length === 0) {\n result.errors.push(mapper(issue));\n continue;\n }\n let curr = result;\n let i = 0;\n while (i < fullpath.length) {\n const el = fullpath[i];\n const terminal = i === fullpath.length - 1;\n if (typeof el === \"string\") {\n curr.properties ?? (curr.properties = {});\n (_a = curr.properties)[el] ?? (_a[el] = { errors: [] });\n curr = curr.properties[el];\n }\n else {\n curr.items ?? (curr.items = []);\n (_b = curr.items)[el] ?? (_b[el] = { errors: [] });\n curr = curr.items[el];\n }\n if (terminal) {\n curr.errors.push(mapper(issue));\n }\n i++;\n }\n }\n }\n };\n processError(error);\n return result;\n}\n/** Format a ZodError as a human-readable string in the following form.\n *\n * From\n *\n * ```ts\n * ZodError {\n * issues: [\n * {\n * expected: 'string',\n * code: 'invalid_type',\n * path: [ 'username' ],\n * message: 'Invalid input: expected string'\n * },\n * {\n * expected: 'number',\n * code: 'invalid_type',\n * path: [ 'favoriteNumbers', 1 ],\n * message: 'Invalid input: expected number'\n * }\n * ];\n * }\n * ```\n *\n * to\n *\n * ```\n * username\n * ✖ Expected number, received string at \"username\n * favoriteNumbers[0]\n * ✖ Invalid input: expected number\n * ```\n */\nexport function toDotPath(_path) {\n const segs = [];\n const path = _path.map((seg) => (typeof seg === \"object\" ? seg.key : seg));\n for (const seg of path) {\n if (typeof seg === \"number\")\n segs.push(`[${seg}]`);\n else if (typeof seg === \"symbol\")\n segs.push(`[${JSON.stringify(String(seg))}]`);\n else if (/[^\\w$]/.test(seg))\n segs.push(`[${JSON.stringify(seg)}]`);\n else {\n if (segs.length)\n segs.push(\".\");\n segs.push(seg);\n }\n }\n return segs.join(\"\");\n}\nexport function prettifyError(error) {\n const lines = [];\n // sort by path length\n const issues = [...error.issues].sort((a, b) => (a.path ?? []).length - (b.path ?? []).length);\n // Process each issue\n for (const issue of issues) {\n lines.push(`✖ ${issue.message}`);\n if (issue.path?.length)\n lines.push(` → at ${toDotPath(issue.path)}`);\n }\n // Convert Map to formatted string\n return lines.join(\"\\n\");\n}\n","import * as core from \"./core.js\";\nimport * as errors from \"./errors.js\";\nimport * as util from \"./util.js\";\nexport const _parse = (_Err) => (schema, value, _ctx, _params) => {\n const ctx = _ctx ? { ..._ctx, async: false } : { async: false };\n const result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n if (result.issues.length) {\n const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));\n util.captureStackTrace(e, _params?.callee);\n throw e;\n }\n return result.value;\n};\nexport const parse = /* @__PURE__*/ _parse(errors.$ZodRealError);\nexport const _parseAsync = (_Err) => async (schema, value, _ctx, params) => {\n const ctx = _ctx ? { ..._ctx, async: true } : { async: true };\n let result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise)\n result = await result;\n if (result.issues.length) {\n const e = new (params?.Err ?? _Err)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())));\n util.captureStackTrace(e, params?.callee);\n throw e;\n }\n return result.value;\n};\nexport const parseAsync = /* @__PURE__*/ _parseAsync(errors.$ZodRealError);\nexport const _safeParse = (_Err) => (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, async: false } : { async: false };\n const result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n return result.issues.length\n ? {\n success: false,\n error: new (_Err ?? errors.$ZodError)(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),\n }\n : { success: true, data: result.value };\n};\nexport const safeParse = /* @__PURE__*/ _safeParse(errors.$ZodRealError);\nexport const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, async: true } : { async: true };\n let result = schema._zod.run({ value, issues: [] }, ctx);\n if (result instanceof Promise)\n result = await result;\n return result.issues.length\n ? {\n success: false,\n error: new _Err(result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),\n }\n : { success: true, data: result.value };\n};\nexport const safeParseAsync = /* @__PURE__*/ _safeParseAsync(errors.$ZodRealError);\nexport const _encode = (_Err) => (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return _parse(_Err)(schema, value, ctx);\n};\nexport const encode = /* @__PURE__*/ _encode(errors.$ZodRealError);\nexport const _decode = (_Err) => (schema, value, _ctx) => {\n return _parse(_Err)(schema, value, _ctx);\n};\nexport const decode = /* @__PURE__*/ _decode(errors.$ZodRealError);\nexport const _encodeAsync = (_Err) => async (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return _parseAsync(_Err)(schema, value, ctx);\n};\nexport const encodeAsync = /* @__PURE__*/ _encodeAsync(errors.$ZodRealError);\nexport const _decodeAsync = (_Err) => async (schema, value, _ctx) => {\n return _parseAsync(_Err)(schema, value, _ctx);\n};\nexport const decodeAsync = /* @__PURE__*/ _decodeAsync(errors.$ZodRealError);\nexport const _safeEncode = (_Err) => (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return _safeParse(_Err)(schema, value, ctx);\n};\nexport const safeEncode = /* @__PURE__*/ _safeEncode(errors.$ZodRealError);\nexport const _safeDecode = (_Err) => (schema, value, _ctx) => {\n return _safeParse(_Err)(schema, value, _ctx);\n};\nexport const safeDecode = /* @__PURE__*/ _safeDecode(errors.$ZodRealError);\nexport const _safeEncodeAsync = (_Err) => async (schema, value, _ctx) => {\n const ctx = _ctx ? { ..._ctx, direction: \"backward\" } : { direction: \"backward\" };\n return _safeParseAsync(_Err)(schema, value, ctx);\n};\nexport const safeEncodeAsync = /* @__PURE__*/ _safeEncodeAsync(errors.$ZodRealError);\nexport const _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {\n return _safeParseAsync(_Err)(schema, value, _ctx);\n};\nexport const safeDecodeAsync = /* @__PURE__*/ _safeDecodeAsync(errors.$ZodRealError);\n","import * as util from \"./util.js\";\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link cuid2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport const cuid = /^[cC][0-9a-z]{6,}$/;\nexport const cuid2 = /^[0-9a-z]+$/;\nexport const ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;\nexport const xid = /^[0-9a-vA-V]{20}$/;\nexport const ksuid = /^[A-Za-z0-9]{27}$/;\nexport const nanoid = /^[a-zA-Z0-9_-]{21}$/;\n/** ISO 8601-1 duration regex. Does not support the 8601-2 extensions like negative durations or fractional/negative components. */\nexport const duration = /^P(?:(\\d+W)|(?!.*W)(?=\\d|T\\d)(\\d+Y)?(\\d+M)?(\\d+D)?(T(?=\\d)(\\d+H)?(\\d+M)?(\\d+([.,]\\d+)?S)?)?)$/;\n/** Implements ISO 8601-2 extensions like explicit +- prefixes, mixing weeks with other units, and fractional/negative components. */\nexport const extendedDuration = /^[-+]?P(?!$)(?:(?:[-+]?\\d+Y)|(?:[-+]?\\d+[.,]\\d+Y$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:(?:[-+]?\\d+W)|(?:[-+]?\\d+[.,]\\d+W$))?(?:(?:[-+]?\\d+D)|(?:[-+]?\\d+[.,]\\d+D$))?(?:T(?=[\\d+-])(?:(?:[-+]?\\d+H)|(?:[-+]?\\d+[.,]\\d+H$))?(?:(?:[-+]?\\d+M)|(?:[-+]?\\d+[.,]\\d+M$))?(?:[-+]?\\d+(?:[.,]\\d+)?S)?)??$/;\n/** A regex for any UUID-like identifier: 8-4-4-4-12 hex pattern */\nexport const guid = /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/;\n/** Returns a regex for validating an RFC 9562/4122 UUID.\n *\n * @param version Optionally specify a version 1-8. If no version is specified, all versions are supported. */\nexport const uuid = (version) => {\n if (!version)\n return /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;\n return new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${version}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`);\n};\nexport const uuid4 = /*@__PURE__*/ uuid(4);\nexport const uuid6 = /*@__PURE__*/ uuid(6);\nexport const uuid7 = /*@__PURE__*/ uuid(7);\n/** Practical email validation */\nexport const email = /^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$/;\n/** Equivalent to the HTML5 input[type=email] validation implemented by browsers. Source: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email */\nexport const html5Email = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n/** The classic emailregex.com regex for RFC 5322-compliant emails */\nexport const rfc5322Email = /^(([^<>()\\[\\]\\\\.,;:\\s@\"]+(\\.[^<>()\\[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n/** A loose regex that allows Unicode characters, enforces length limits, and that's about it. */\nexport const unicodeEmail = /^[^\\s@\"]{1,64}@[^\\s@]{1,255}$/u;\nexport const idnEmail = unicodeEmail;\nexport const browserEmail = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression\nconst _emoji = `^(\\\\p{Extended_Pictographic}|\\\\p{Emoji_Component})+$`;\nexport function emoji() {\n return new RegExp(_emoji, \"u\");\n}\nexport const ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;\nexport const ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;\nexport const mac = (delimiter) => {\n const escapedDelim = util.escapeRegex(delimiter ?? \":\");\n return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);\n};\nexport const cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/([0-9]|[1-2][0-9]|3[0-2])$/;\nexport const cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;\n// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript\nexport const base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;\nexport const base64url = /^[A-Za-z0-9_-]*$/;\n// based on https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address\n// export const hostname: RegExp = /^([a-zA-Z0-9-]+\\.)*[a-zA-Z0-9-]+$/;\nexport const hostname = /^(?=.{1,253}\\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\\.?$/;\nexport const domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,}$/;\nexport const httpProtocol = /^https?$/;\n// https://blog.stevenlevithan.com/archives/validate-phone-number#r4-3 (regex sans spaces)\n// E.164: leading digit must be 1-9; total digits (excluding '+') between 7-15\nexport const e164 = /^\\+[1-9]\\d{6,14}$/;\n// const dateSource = `((\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\\\d|30)|(02)-(0[1-9]|1\\\\d|2[0-8])))`;\nconst dateSource = `(?:(?:\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\\\d|30)|(?:02)-(?:0[1-9]|1\\\\d|2[0-8])))`;\nexport const date = /*@__PURE__*/ new RegExp(`^${dateSource}$`);\nfunction timeSource(args) {\n const hhmm = `(?:[01]\\\\d|2[0-3]):[0-5]\\\\d`;\n const regex = typeof args.precision === \"number\"\n ? args.precision === -1\n ? `${hhmm}`\n : args.precision === 0\n ? `${hhmm}:[0-5]\\\\d`\n : `${hhmm}:[0-5]\\\\d\\\\.\\\\d{${args.precision}}`\n : `${hhmm}(?::[0-5]\\\\d(?:\\\\.\\\\d+)?)?`;\n return regex;\n}\nexport function time(args) {\n return new RegExp(`^${timeSource(args)}$`);\n}\n// Adapted from https://stackoverflow.com/a/3143231\nexport function datetime(args) {\n const time = timeSource({ precision: args.precision });\n const opts = [\"Z\"];\n if (args.local)\n opts.push(\"\");\n // if (args.offset) opts.push(`([+-]\\\\d{2}:\\\\d{2})`);\n if (args.offset)\n opts.push(`([+-](?:[01]\\\\d|2[0-3]):[0-5]\\\\d)`);\n const timeRegex = `${time}(?:${opts.join(\"|\")})`;\n return new RegExp(`^${dateSource}T(?:${timeRegex})$`);\n}\nexport const string = (params) => {\n const regex = params ? `[\\\\s\\\\S]{${params?.minimum ?? 0},${params?.maximum ?? \"\"}}` : `[\\\\s\\\\S]*`;\n return new RegExp(`^${regex}$`);\n};\nexport const bigint = /^-?\\d+n?$/;\nexport const integer = /^-?\\d+$/;\nexport const number = /^-?\\d+(?:\\.\\d+)?$/;\nexport const boolean = /^(?:true|false)$/i;\nconst _null = /^null$/i;\nexport { _null as null };\nconst _undefined = /^undefined$/i;\nexport { _undefined as undefined };\n// regex for string with no uppercase letters\nexport const lowercase = /^[^A-Z]*$/;\n// regex for string with no lowercase letters\nexport const uppercase = /^[^a-z]*$/;\n// regex for hexadecimal strings (any length)\nexport const hex = /^[0-9a-fA-F]*$/;\n// Hash regexes for different algorithms and encodings\n// Helper function to create base64 regex with exact length and padding\nfunction fixedBase64(bodyLength, padding) {\n return new RegExp(`^[A-Za-z0-9+/]{${bodyLength}}${padding}$`);\n}\n// Helper function to create base64url regex with exact length (no padding)\nfunction fixedBase64url(length) {\n return new RegExp(`^[A-Za-z0-9_-]{${length}}$`);\n}\n// MD5 (16 bytes): base64 = 24 chars total (22 + \"==\")\nexport const md5_hex = /^[0-9a-fA-F]{32}$/;\nexport const md5_base64 = /*@__PURE__*/ fixedBase64(22, \"==\");\nexport const md5_base64url = /*@__PURE__*/ fixedBase64url(22);\n// SHA1 (20 bytes): base64 = 28 chars total (27 + \"=\")\nexport const sha1_hex = /^[0-9a-fA-F]{40}$/;\nexport const sha1_base64 = /*@__PURE__*/ fixedBase64(27, \"=\");\nexport const sha1_base64url = /*@__PURE__*/ fixedBase64url(27);\n// SHA256 (32 bytes): base64 = 44 chars total (43 + \"=\")\nexport const sha256_hex = /^[0-9a-fA-F]{64}$/;\nexport const sha256_base64 = /*@__PURE__*/ fixedBase64(43, \"=\");\nexport const sha256_base64url = /*@__PURE__*/ fixedBase64url(43);\n// SHA384 (48 bytes): base64 = 64 chars total (no padding)\nexport const sha384_hex = /^[0-9a-fA-F]{96}$/;\nexport const sha384_base64 = /*@__PURE__*/ fixedBase64(64, \"\");\nexport const sha384_base64url = /*@__PURE__*/ fixedBase64url(64);\n// SHA512 (64 bytes): base64 = 88 chars total (86 + \"==\")\nexport const sha512_hex = /^[0-9a-fA-F]{128}$/;\nexport const sha512_base64 = /*@__PURE__*/ fixedBase64(86, \"==\");\nexport const sha512_base64url = /*@__PURE__*/ fixedBase64url(86);\n","// import { $ZodType } from \"./schemas.js\";\nimport * as core from \"./core.js\";\nimport * as regexes from \"./regexes.js\";\nimport * as util from \"./util.js\";\nexport const $ZodCheck = /*@__PURE__*/ core.$constructor(\"$ZodCheck\", (inst, def) => {\n var _a;\n inst._zod ?? (inst._zod = {});\n inst._zod.def = def;\n (_a = inst._zod).onattach ?? (_a.onattach = []);\n});\nconst numericOriginMap = {\n number: \"number\",\n bigint: \"bigint\",\n object: \"date\",\n};\nexport const $ZodCheckLessThan = /*@__PURE__*/ core.$constructor(\"$ZodCheckLessThan\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const origin = numericOriginMap[typeof def.value];\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n const curr = (def.inclusive ? bag.maximum : bag.exclusiveMaximum) ?? Number.POSITIVE_INFINITY;\n if (def.value < curr) {\n if (def.inclusive)\n bag.maximum = def.value;\n else\n bag.exclusiveMaximum = def.value;\n }\n });\n inst._zod.check = (payload) => {\n if (def.inclusive ? payload.value <= def.value : payload.value < def.value) {\n return;\n }\n payload.issues.push({\n origin,\n code: \"too_big\",\n maximum: typeof def.value === \"object\" ? def.value.getTime() : def.value,\n input: payload.value,\n inclusive: def.inclusive,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckGreaterThan = /*@__PURE__*/ core.$constructor(\"$ZodCheckGreaterThan\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const origin = numericOriginMap[typeof def.value];\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n const curr = (def.inclusive ? bag.minimum : bag.exclusiveMinimum) ?? Number.NEGATIVE_INFINITY;\n if (def.value > curr) {\n if (def.inclusive)\n bag.minimum = def.value;\n else\n bag.exclusiveMinimum = def.value;\n }\n });\n inst._zod.check = (payload) => {\n if (def.inclusive ? payload.value >= def.value : payload.value > def.value) {\n return;\n }\n payload.issues.push({\n origin,\n code: \"too_small\",\n minimum: typeof def.value === \"object\" ? def.value.getTime() : def.value,\n input: payload.value,\n inclusive: def.inclusive,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMultipleOf = \n/*@__PURE__*/ core.$constructor(\"$ZodCheckMultipleOf\", (inst, def) => {\n $ZodCheck.init(inst, def);\n inst._zod.onattach.push((inst) => {\n var _a;\n (_a = inst._zod.bag).multipleOf ?? (_a.multipleOf = def.value);\n });\n inst._zod.check = (payload) => {\n if (typeof payload.value !== typeof def.value)\n throw new Error(\"Cannot mix number and bigint in multiple_of check.\");\n const isMultiple = typeof payload.value === \"bigint\"\n ? payload.value % def.value === BigInt(0)\n : util.floatSafeRemainder(payload.value, def.value) === 0;\n if (isMultiple)\n return;\n payload.issues.push({\n origin: typeof payload.value,\n code: \"not_multiple_of\",\n divisor: def.value,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckNumberFormat = /*@__PURE__*/ core.$constructor(\"$ZodCheckNumberFormat\", (inst, def) => {\n $ZodCheck.init(inst, def); // no format checks\n def.format = def.format || \"float64\";\n const isInt = def.format?.includes(\"int\");\n const origin = isInt ? \"int\" : \"number\";\n const [minimum, maximum] = util.NUMBER_FORMAT_RANGES[def.format];\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.format = def.format;\n bag.minimum = minimum;\n bag.maximum = maximum;\n if (isInt)\n bag.pattern = regexes.integer;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n if (isInt) {\n if (!Number.isInteger(input)) {\n // invalid_format issue\n // payload.issues.push({\n // expected: def.format,\n // format: def.format,\n // code: \"invalid_format\",\n // input,\n // inst,\n // });\n // invalid_type issue\n payload.issues.push({\n expected: origin,\n format: def.format,\n code: \"invalid_type\",\n continue: false,\n input,\n inst,\n });\n return;\n // not_multiple_of issue\n // payload.issues.push({\n // code: \"not_multiple_of\",\n // origin: \"number\",\n // input,\n // inst,\n // divisor: 1,\n // });\n }\n if (!Number.isSafeInteger(input)) {\n if (input > 0) {\n // too_big\n payload.issues.push({\n input,\n code: \"too_big\",\n maximum: Number.MAX_SAFE_INTEGER,\n note: \"Integers must be within the safe integer range.\",\n inst,\n origin,\n inclusive: true,\n continue: !def.abort,\n });\n }\n else {\n // too_small\n payload.issues.push({\n input,\n code: \"too_small\",\n minimum: Number.MIN_SAFE_INTEGER,\n note: \"Integers must be within the safe integer range.\",\n inst,\n origin,\n inclusive: true,\n continue: !def.abort,\n });\n }\n return;\n }\n }\n if (input < minimum) {\n payload.issues.push({\n origin: \"number\",\n input,\n code: \"too_small\",\n minimum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n if (input > maximum) {\n payload.issues.push({\n origin: \"number\",\n input,\n code: \"too_big\",\n maximum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodCheckBigIntFormat = /*@__PURE__*/ core.$constructor(\"$ZodCheckBigIntFormat\", (inst, def) => {\n $ZodCheck.init(inst, def); // no format checks\n const [minimum, maximum] = util.BIGINT_FORMAT_RANGES[def.format];\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.format = def.format;\n bag.minimum = minimum;\n bag.maximum = maximum;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n if (input < minimum) {\n payload.issues.push({\n origin: \"bigint\",\n input,\n code: \"too_small\",\n minimum: minimum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n if (input > maximum) {\n payload.issues.push({\n origin: \"bigint\",\n input,\n code: \"too_big\",\n maximum,\n inclusive: true,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodCheckMaxSize = /*@__PURE__*/ core.$constructor(\"$ZodCheckMaxSize\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.size !== undefined;\n });\n inst._zod.onattach.push((inst) => {\n const curr = (inst._zod.bag.maximum ?? Number.POSITIVE_INFINITY);\n if (def.maximum < curr)\n inst._zod.bag.maximum = def.maximum;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n const size = input.size;\n if (size <= def.maximum)\n return;\n payload.issues.push({\n origin: util.getSizableOrigin(input),\n code: \"too_big\",\n maximum: def.maximum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMinSize = /*@__PURE__*/ core.$constructor(\"$ZodCheckMinSize\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.size !== undefined;\n });\n inst._zod.onattach.push((inst) => {\n const curr = (inst._zod.bag.minimum ?? Number.NEGATIVE_INFINITY);\n if (def.minimum > curr)\n inst._zod.bag.minimum = def.minimum;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n const size = input.size;\n if (size >= def.minimum)\n return;\n payload.issues.push({\n origin: util.getSizableOrigin(input),\n code: \"too_small\",\n minimum: def.minimum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckSizeEquals = /*@__PURE__*/ core.$constructor(\"$ZodCheckSizeEquals\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.size !== undefined;\n });\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.minimum = def.size;\n bag.maximum = def.size;\n bag.size = def.size;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n const size = input.size;\n if (size === def.size)\n return;\n const tooBig = size > def.size;\n payload.issues.push({\n origin: util.getSizableOrigin(input),\n ...(tooBig ? { code: \"too_big\", maximum: def.size } : { code: \"too_small\", minimum: def.size }),\n inclusive: true,\n exact: true,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMaxLength = /*@__PURE__*/ core.$constructor(\"$ZodCheckMaxLength\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.length !== undefined;\n });\n inst._zod.onattach.push((inst) => {\n const curr = (inst._zod.bag.maximum ?? Number.POSITIVE_INFINITY);\n if (def.maximum < curr)\n inst._zod.bag.maximum = def.maximum;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n const length = input.length;\n if (length <= def.maximum)\n return;\n const origin = util.getLengthableOrigin(input);\n payload.issues.push({\n origin,\n code: \"too_big\",\n maximum: def.maximum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckMinLength = /*@__PURE__*/ core.$constructor(\"$ZodCheckMinLength\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.length !== undefined;\n });\n inst._zod.onattach.push((inst) => {\n const curr = (inst._zod.bag.minimum ?? Number.NEGATIVE_INFINITY);\n if (def.minimum > curr)\n inst._zod.bag.minimum = def.minimum;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n const length = input.length;\n if (length >= def.minimum)\n return;\n const origin = util.getLengthableOrigin(input);\n payload.issues.push({\n origin,\n code: \"too_small\",\n minimum: def.minimum,\n inclusive: true,\n input,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckLengthEquals = /*@__PURE__*/ core.$constructor(\"$ZodCheckLengthEquals\", (inst, def) => {\n var _a;\n $ZodCheck.init(inst, def);\n (_a = inst._zod.def).when ?? (_a.when = (payload) => {\n const val = payload.value;\n return !util.nullish(val) && val.length !== undefined;\n });\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.minimum = def.length;\n bag.maximum = def.length;\n bag.length = def.length;\n });\n inst._zod.check = (payload) => {\n const input = payload.value;\n const length = input.length;\n if (length === def.length)\n return;\n const origin = util.getLengthableOrigin(input);\n const tooBig = length > def.length;\n payload.issues.push({\n origin,\n ...(tooBig ? { code: \"too_big\", maximum: def.length } : { code: \"too_small\", minimum: def.length }),\n inclusive: true,\n exact: true,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckStringFormat = /*@__PURE__*/ core.$constructor(\"$ZodCheckStringFormat\", (inst, def) => {\n var _a, _b;\n $ZodCheck.init(inst, def);\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.format = def.format;\n if (def.pattern) {\n bag.patterns ?? (bag.patterns = new Set());\n bag.patterns.add(def.pattern);\n }\n });\n if (def.pattern)\n (_a = inst._zod).check ?? (_a.check = (payload) => {\n def.pattern.lastIndex = 0;\n if (def.pattern.test(payload.value))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: def.format,\n input: payload.value,\n ...(def.pattern ? { pattern: def.pattern.toString() } : {}),\n inst,\n continue: !def.abort,\n });\n });\n else\n (_b = inst._zod).check ?? (_b.check = () => { });\n});\nexport const $ZodCheckRegex = /*@__PURE__*/ core.$constructor(\"$ZodCheckRegex\", (inst, def) => {\n $ZodCheckStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n def.pattern.lastIndex = 0;\n if (def.pattern.test(payload.value))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"regex\",\n input: payload.value,\n pattern: def.pattern.toString(),\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckLowerCase = /*@__PURE__*/ core.$constructor(\"$ZodCheckLowerCase\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.lowercase);\n $ZodCheckStringFormat.init(inst, def);\n});\nexport const $ZodCheckUpperCase = /*@__PURE__*/ core.$constructor(\"$ZodCheckUpperCase\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.uppercase);\n $ZodCheckStringFormat.init(inst, def);\n});\nexport const $ZodCheckIncludes = /*@__PURE__*/ core.$constructor(\"$ZodCheckIncludes\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const escapedRegex = util.escapeRegex(def.includes);\n const pattern = new RegExp(typeof def.position === \"number\" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);\n def.pattern = pattern;\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.patterns ?? (bag.patterns = new Set());\n bag.patterns.add(pattern);\n });\n inst._zod.check = (payload) => {\n if (payload.value.includes(def.includes, def.position))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"includes\",\n includes: def.includes,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckStartsWith = /*@__PURE__*/ core.$constructor(\"$ZodCheckStartsWith\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);\n def.pattern ?? (def.pattern = pattern);\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.patterns ?? (bag.patterns = new Set());\n bag.patterns.add(pattern);\n });\n inst._zod.check = (payload) => {\n if (payload.value.startsWith(def.prefix))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"starts_with\",\n prefix: def.prefix,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckEndsWith = /*@__PURE__*/ core.$constructor(\"$ZodCheckEndsWith\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);\n def.pattern ?? (def.pattern = pattern);\n inst._zod.onattach.push((inst) => {\n const bag = inst._zod.bag;\n bag.patterns ?? (bag.patterns = new Set());\n bag.patterns.add(pattern);\n });\n inst._zod.check = (payload) => {\n if (payload.value.endsWith(def.suffix))\n return;\n payload.issues.push({\n origin: \"string\",\n code: \"invalid_format\",\n format: \"ends_with\",\n suffix: def.suffix,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\n///////////////////////////////////\n///// $ZodCheckProperty /////\n///////////////////////////////////\nfunction handleCheckPropertyResult(result, payload, property) {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(property, result.issues));\n }\n}\nexport const $ZodCheckProperty = /*@__PURE__*/ core.$constructor(\"$ZodCheckProperty\", (inst, def) => {\n $ZodCheck.init(inst, def);\n inst._zod.check = (payload) => {\n const result = def.schema._zod.run({\n value: payload.value[def.property],\n issues: [],\n }, {});\n if (result instanceof Promise) {\n return result.then((result) => handleCheckPropertyResult(result, payload, def.property));\n }\n handleCheckPropertyResult(result, payload, def.property);\n return;\n };\n});\nexport const $ZodCheckMimeType = /*@__PURE__*/ core.$constructor(\"$ZodCheckMimeType\", (inst, def) => {\n $ZodCheck.init(inst, def);\n const mimeSet = new Set(def.mime);\n inst._zod.onattach.push((inst) => {\n inst._zod.bag.mime = def.mime;\n });\n inst._zod.check = (payload) => {\n if (mimeSet.has(payload.value.type))\n return;\n payload.issues.push({\n code: \"invalid_value\",\n values: def.mime,\n input: payload.value.type,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCheckOverwrite = /*@__PURE__*/ core.$constructor(\"$ZodCheckOverwrite\", (inst, def) => {\n $ZodCheck.init(inst, def);\n inst._zod.check = (payload) => {\n payload.value = def.tx(payload.value);\n };\n});\n","export class Doc {\n constructor(args = []) {\n this.content = [];\n this.indent = 0;\n if (this)\n this.args = args;\n }\n indented(fn) {\n this.indent += 1;\n fn(this);\n this.indent -= 1;\n }\n write(arg) {\n if (typeof arg === \"function\") {\n arg(this, { execution: \"sync\" });\n arg(this, { execution: \"async\" });\n return;\n }\n const content = arg;\n const lines = content.split(\"\\n\").filter((x) => x);\n const minIndent = Math.min(...lines.map((x) => x.length - x.trimStart().length));\n const dedented = lines.map((x) => x.slice(minIndent)).map((x) => \" \".repeat(this.indent * 2) + x);\n for (const line of dedented) {\n this.content.push(line);\n }\n }\n compile() {\n const F = Function;\n const args = this?.args;\n const content = this?.content ?? [``];\n const lines = [...content.map((x) => ` ${x}`)];\n // console.log(lines.join(\"\\n\"));\n return new F(...args, lines.join(\"\\n\"));\n }\n}\n","export const version = {\n major: 4,\n minor: 4,\n patch: 3,\n};\n","import * as checks from \"./checks.js\";\nimport * as core from \"./core.js\";\nimport { Doc } from \"./doc.js\";\nimport { parse, parseAsync, safeParse, safeParseAsync } from \"./parse.js\";\nimport * as regexes from \"./regexes.js\";\nimport * as util from \"./util.js\";\nimport { version } from \"./versions.js\";\nexport const $ZodType = /*@__PURE__*/ core.$constructor(\"$ZodType\", (inst, def) => {\n var _a;\n inst ?? (inst = {});\n inst._zod.def = def; // set _def property\n inst._zod.bag = inst._zod.bag || {}; // initialize _bag object\n inst._zod.version = version;\n const checks = [...(inst._zod.def.checks ?? [])];\n // if inst is itself a checks.$ZodCheck, run it as a check\n if (inst._zod.traits.has(\"$ZodCheck\")) {\n checks.unshift(inst);\n }\n for (const ch of checks) {\n for (const fn of ch._zod.onattach) {\n fn(inst);\n }\n }\n if (checks.length === 0) {\n // deferred initializer\n // inst._zod.parse is not yet defined\n (_a = inst._zod).deferred ?? (_a.deferred = []);\n inst._zod.deferred?.push(() => {\n inst._zod.run = inst._zod.parse;\n });\n }\n else {\n const runChecks = (payload, checks, ctx) => {\n let isAborted = util.aborted(payload);\n let asyncResult;\n for (const ch of checks) {\n if (ch._zod.def.when) {\n if (util.explicitlyAborted(payload))\n continue;\n const shouldRun = ch._zod.def.when(payload);\n if (!shouldRun)\n continue;\n }\n else if (isAborted) {\n continue;\n }\n const currLen = payload.issues.length;\n const _ = ch._zod.check(payload);\n if (_ instanceof Promise && ctx?.async === false) {\n throw new core.$ZodAsyncError();\n }\n if (asyncResult || _ instanceof Promise) {\n asyncResult = (asyncResult ?? Promise.resolve()).then(async () => {\n await _;\n const nextLen = payload.issues.length;\n if (nextLen === currLen)\n return;\n if (!isAborted)\n isAborted = util.aborted(payload, currLen);\n });\n }\n else {\n const nextLen = payload.issues.length;\n if (nextLen === currLen)\n continue;\n if (!isAborted)\n isAborted = util.aborted(payload, currLen);\n }\n }\n if (asyncResult) {\n return asyncResult.then(() => {\n return payload;\n });\n }\n return payload;\n };\n const handleCanaryResult = (canary, payload, ctx) => {\n // abort if the canary is aborted\n if (util.aborted(canary)) {\n canary.aborted = true;\n return canary;\n }\n // run checks first, then\n const checkResult = runChecks(payload, checks, ctx);\n if (checkResult instanceof Promise) {\n if (ctx.async === false)\n throw new core.$ZodAsyncError();\n return checkResult.then((checkResult) => inst._zod.parse(checkResult, ctx));\n }\n return inst._zod.parse(checkResult, ctx);\n };\n inst._zod.run = (payload, ctx) => {\n if (ctx.skipChecks) {\n return inst._zod.parse(payload, ctx);\n }\n if (ctx.direction === \"backward\") {\n // run canary\n // initial pass (no checks)\n const canary = inst._zod.parse({ value: payload.value, issues: [] }, { ...ctx, skipChecks: true });\n if (canary instanceof Promise) {\n return canary.then((canary) => {\n return handleCanaryResult(canary, payload, ctx);\n });\n }\n return handleCanaryResult(canary, payload, ctx);\n }\n // forward\n const result = inst._zod.parse(payload, ctx);\n if (result instanceof Promise) {\n if (ctx.async === false)\n throw new core.$ZodAsyncError();\n return result.then((result) => runChecks(result, checks, ctx));\n }\n return runChecks(result, checks, ctx);\n };\n }\n // Lazy initialize ~standard to avoid creating objects for every schema\n util.defineLazy(inst, \"~standard\", () => ({\n validate: (value) => {\n try {\n const r = safeParse(inst, value);\n return r.success ? { value: r.data } : { issues: r.error?.issues };\n }\n catch (_) {\n return safeParseAsync(inst, value).then((r) => (r.success ? { value: r.data } : { issues: r.error?.issues }));\n }\n },\n vendor: \"zod\",\n version: 1,\n }));\n});\nexport { clone } from \"./util.js\";\nexport const $ZodString = /*@__PURE__*/ core.$constructor(\"$ZodString\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = [...(inst?._zod.bag?.patterns ?? [])].pop() ?? regexes.string(inst._zod.bag);\n inst._zod.parse = (payload, _) => {\n if (def.coerce)\n try {\n payload.value = String(payload.value);\n }\n catch (_) { }\n if (typeof payload.value === \"string\")\n return payload;\n payload.issues.push({\n expected: \"string\",\n code: \"invalid_type\",\n input: payload.value,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodStringFormat = /*@__PURE__*/ core.$constructor(\"$ZodStringFormat\", (inst, def) => {\n // check initialization must come first\n checks.$ZodCheckStringFormat.init(inst, def);\n $ZodString.init(inst, def);\n});\nexport const $ZodGUID = /*@__PURE__*/ core.$constructor(\"$ZodGUID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.guid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodUUID = /*@__PURE__*/ core.$constructor(\"$ZodUUID\", (inst, def) => {\n if (def.version) {\n const versionMap = {\n v1: 1,\n v2: 2,\n v3: 3,\n v4: 4,\n v5: 5,\n v6: 6,\n v7: 7,\n v8: 8,\n };\n const v = versionMap[def.version];\n if (v === undefined)\n throw new Error(`Invalid UUID version: \"${def.version}\"`);\n def.pattern ?? (def.pattern = regexes.uuid(v));\n }\n else\n def.pattern ?? (def.pattern = regexes.uuid());\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodEmail = /*@__PURE__*/ core.$constructor(\"$ZodEmail\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.email);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodURL = /*@__PURE__*/ core.$constructor(\"$ZodURL\", (inst, def) => {\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n try {\n // Trim whitespace from input\n const trimmed = payload.value.trim();\n // When normalize is off, require :// for http/https URLs\n // This prevents strings like \"http:example.com\" or \"https:/path\" from being silently accepted\n if (!def.normalize && def.protocol?.source === regexes.httpProtocol.source) {\n if (!/^https?:\\/\\//i.test(trimmed)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n note: \"Invalid URL format\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n return;\n }\n }\n // @ts-ignore\n const url = new URL(trimmed);\n if (def.hostname) {\n def.hostname.lastIndex = 0;\n if (!def.hostname.test(url.hostname)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n note: \"Invalid hostname\",\n pattern: def.hostname.source,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n }\n if (def.protocol) {\n def.protocol.lastIndex = 0;\n if (!def.protocol.test(url.protocol.endsWith(\":\") ? url.protocol.slice(0, -1) : url.protocol)) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n note: \"Invalid protocol\",\n pattern: def.protocol.source,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n }\n // Set the output value based on normalize flag\n if (def.normalize) {\n // Use normalized URL\n payload.value = url.href;\n }\n else {\n // Preserve the original input (trimmed)\n payload.value = trimmed;\n }\n return;\n }\n catch (_) {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"url\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodEmoji = /*@__PURE__*/ core.$constructor(\"$ZodEmoji\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.emoji());\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodNanoID = /*@__PURE__*/ core.$constructor(\"$ZodNanoID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.nanoid);\n $ZodStringFormat.init(inst, def);\n});\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link $ZodCUID2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport const $ZodCUID = /*@__PURE__*/ core.$constructor(\"$ZodCUID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cuid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodCUID2 = /*@__PURE__*/ core.$constructor(\"$ZodCUID2\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cuid2);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodULID = /*@__PURE__*/ core.$constructor(\"$ZodULID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ulid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodXID = /*@__PURE__*/ core.$constructor(\"$ZodXID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.xid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodKSUID = /*@__PURE__*/ core.$constructor(\"$ZodKSUID\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ksuid);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISODateTime = /*@__PURE__*/ core.$constructor(\"$ZodISODateTime\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.datetime(def));\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISODate = /*@__PURE__*/ core.$constructor(\"$ZodISODate\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.date);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISOTime = /*@__PURE__*/ core.$constructor(\"$ZodISOTime\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.time(def));\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodISODuration = /*@__PURE__*/ core.$constructor(\"$ZodISODuration\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.duration);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodIPv4 = /*@__PURE__*/ core.$constructor(\"$ZodIPv4\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ipv4);\n $ZodStringFormat.init(inst, def);\n inst._zod.bag.format = `ipv4`;\n});\nexport const $ZodIPv6 = /*@__PURE__*/ core.$constructor(\"$ZodIPv6\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.ipv6);\n $ZodStringFormat.init(inst, def);\n inst._zod.bag.format = `ipv6`;\n inst._zod.check = (payload) => {\n try {\n // @ts-ignore\n new URL(`http://[${payload.value}]`);\n // return;\n }\n catch {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"ipv6\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\nexport const $ZodMAC = /*@__PURE__*/ core.$constructor(\"$ZodMAC\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.mac(def.delimiter));\n $ZodStringFormat.init(inst, def);\n inst._zod.bag.format = `mac`;\n});\nexport const $ZodCIDRv4 = /*@__PURE__*/ core.$constructor(\"$ZodCIDRv4\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cidrv4);\n $ZodStringFormat.init(inst, def);\n});\nexport const $ZodCIDRv6 = /*@__PURE__*/ core.$constructor(\"$ZodCIDRv6\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.cidrv6); // not used for validation\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n const parts = payload.value.split(\"/\");\n try {\n if (parts.length !== 2)\n throw new Error();\n const [address, prefix] = parts;\n if (!prefix)\n throw new Error();\n const prefixNum = Number(prefix);\n if (`${prefixNum}` !== prefix)\n throw new Error();\n if (prefixNum < 0 || prefixNum > 128)\n throw new Error();\n // @ts-ignore\n new URL(`http://[${address}]`);\n }\n catch {\n payload.issues.push({\n code: \"invalid_format\",\n format: \"cidrv6\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n }\n };\n});\n////////////////////////////// ZodBase64 //////////////////////////////\nexport function isValidBase64(data) {\n if (data === \"\")\n return true;\n // atob ignores whitespace, so reject it up front.\n if (/\\s/.test(data))\n return false;\n if (data.length % 4 !== 0)\n return false;\n try {\n // @ts-ignore\n atob(data);\n return true;\n }\n catch {\n return false;\n }\n}\nexport const $ZodBase64 = /*@__PURE__*/ core.$constructor(\"$ZodBase64\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.base64);\n $ZodStringFormat.init(inst, def);\n inst._zod.bag.contentEncoding = \"base64\";\n inst._zod.check = (payload) => {\n if (isValidBase64(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"base64\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\n////////////////////////////// ZodBase64 //////////////////////////////\nexport function isValidBase64URL(data) {\n if (!regexes.base64url.test(data))\n return false;\n const base64 = data.replace(/[-_]/g, (c) => (c === \"-\" ? \"+\" : \"/\"));\n const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, \"=\");\n return isValidBase64(padded);\n}\nexport const $ZodBase64URL = /*@__PURE__*/ core.$constructor(\"$ZodBase64URL\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.base64url);\n $ZodStringFormat.init(inst, def);\n inst._zod.bag.contentEncoding = \"base64url\";\n inst._zod.check = (payload) => {\n if (isValidBase64URL(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"base64url\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodE164 = /*@__PURE__*/ core.$constructor(\"$ZodE164\", (inst, def) => {\n def.pattern ?? (def.pattern = regexes.e164);\n $ZodStringFormat.init(inst, def);\n});\n////////////////////////////// ZodJWT //////////////////////////////\nexport function isValidJWT(token, algorithm = null) {\n try {\n const tokensParts = token.split(\".\");\n if (tokensParts.length !== 3)\n return false;\n const [header] = tokensParts;\n if (!header)\n return false;\n // @ts-ignore\n const parsedHeader = JSON.parse(atob(header));\n if (\"typ\" in parsedHeader && parsedHeader?.typ !== \"JWT\")\n return false;\n if (!parsedHeader.alg)\n return false;\n if (algorithm && (!(\"alg\" in parsedHeader) || parsedHeader.alg !== algorithm))\n return false;\n return true;\n }\n catch {\n return false;\n }\n}\nexport const $ZodJWT = /*@__PURE__*/ core.$constructor(\"$ZodJWT\", (inst, def) => {\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (isValidJWT(payload.value, def.alg))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: \"jwt\",\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodCustomStringFormat = /*@__PURE__*/ core.$constructor(\"$ZodCustomStringFormat\", (inst, def) => {\n $ZodStringFormat.init(inst, def);\n inst._zod.check = (payload) => {\n if (def.fn(payload.value))\n return;\n payload.issues.push({\n code: \"invalid_format\",\n format: def.format,\n input: payload.value,\n inst,\n continue: !def.abort,\n });\n };\n});\nexport const $ZodNumber = /*@__PURE__*/ core.$constructor(\"$ZodNumber\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = inst._zod.bag.pattern ?? regexes.number;\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce)\n try {\n payload.value = Number(payload.value);\n }\n catch (_) { }\n const input = payload.value;\n if (typeof input === \"number\" && !Number.isNaN(input) && Number.isFinite(input)) {\n return payload;\n }\n const received = typeof input === \"number\"\n ? Number.isNaN(input)\n ? \"NaN\"\n : !Number.isFinite(input)\n ? \"Infinity\"\n : undefined\n : undefined;\n payload.issues.push({\n expected: \"number\",\n code: \"invalid_type\",\n input,\n inst,\n ...(received ? { received } : {}),\n });\n return payload;\n };\n});\nexport const $ZodNumberFormat = /*@__PURE__*/ core.$constructor(\"$ZodNumberFormat\", (inst, def) => {\n checks.$ZodCheckNumberFormat.init(inst, def);\n $ZodNumber.init(inst, def); // no format checks\n});\nexport const $ZodBoolean = /*@__PURE__*/ core.$constructor(\"$ZodBoolean\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.boolean;\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce)\n try {\n payload.value = Boolean(payload.value);\n }\n catch (_) { }\n const input = payload.value;\n if (typeof input === \"boolean\")\n return payload;\n payload.issues.push({\n expected: \"boolean\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodBigInt = /*@__PURE__*/ core.$constructor(\"$ZodBigInt\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.bigint;\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce)\n try {\n payload.value = BigInt(payload.value);\n }\n catch (_) { }\n if (typeof payload.value === \"bigint\")\n return payload;\n payload.issues.push({\n expected: \"bigint\",\n code: \"invalid_type\",\n input: payload.value,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodBigIntFormat = /*@__PURE__*/ core.$constructor(\"$ZodBigIntFormat\", (inst, def) => {\n checks.$ZodCheckBigIntFormat.init(inst, def);\n $ZodBigInt.init(inst, def); // no format checks\n});\nexport const $ZodSymbol = /*@__PURE__*/ core.$constructor(\"$ZodSymbol\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (typeof input === \"symbol\")\n return payload;\n payload.issues.push({\n expected: \"symbol\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodUndefined = /*@__PURE__*/ core.$constructor(\"$ZodUndefined\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.undefined;\n inst._zod.values = new Set([undefined]);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (typeof input === \"undefined\")\n return payload;\n payload.issues.push({\n expected: \"undefined\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodNull = /*@__PURE__*/ core.$constructor(\"$ZodNull\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.pattern = regexes.null;\n inst._zod.values = new Set([null]);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (input === null)\n return payload;\n payload.issues.push({\n expected: \"null\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodAny = /*@__PURE__*/ core.$constructor(\"$ZodAny\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload) => payload;\n});\nexport const $ZodUnknown = /*@__PURE__*/ core.$constructor(\"$ZodUnknown\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload) => payload;\n});\nexport const $ZodNever = /*@__PURE__*/ core.$constructor(\"$ZodNever\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n payload.issues.push({\n expected: \"never\",\n code: \"invalid_type\",\n input: payload.value,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodVoid = /*@__PURE__*/ core.$constructor(\"$ZodVoid\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (typeof input === \"undefined\")\n return payload;\n payload.issues.push({\n expected: \"void\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodDate = /*@__PURE__*/ core.$constructor(\"$ZodDate\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n if (def.coerce) {\n try {\n payload.value = new Date(payload.value);\n }\n catch (_err) { }\n }\n const input = payload.value;\n const isDate = input instanceof Date;\n const isValidDate = isDate && !Number.isNaN(input.getTime());\n if (isValidDate)\n return payload;\n payload.issues.push({\n expected: \"date\",\n code: \"invalid_type\",\n input,\n ...(isDate ? { received: \"Invalid Date\" } : {}),\n inst,\n });\n return payload;\n };\n});\nfunction handleArrayResult(result, final, index) {\n if (result.issues.length) {\n final.issues.push(...util.prefixIssues(index, result.issues));\n }\n final.value[index] = result.value;\n}\nexport const $ZodArray = /*@__PURE__*/ core.$constructor(\"$ZodArray\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!Array.isArray(input)) {\n payload.issues.push({\n expected: \"array\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n payload.value = Array(input.length);\n const proms = [];\n for (let i = 0; i < input.length; i++) {\n const item = input[i];\n const result = def.element._zod.run({\n value: item,\n issues: [],\n }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => handleArrayResult(result, payload, i)));\n }\n else {\n handleArrayResult(result, payload, i);\n }\n }\n if (proms.length) {\n return Promise.all(proms).then(() => payload);\n }\n return payload; //handleArrayResultsAsync(parseResults, final);\n };\n});\nfunction handlePropertyResult(result, final, key, input, isOptionalIn, isOptionalOut) {\n const isPresent = key in input;\n if (result.issues.length) {\n // For optional-in/out schemas, ignore errors on absent keys.\n if (isOptionalIn && isOptionalOut && !isPresent) {\n return;\n }\n final.issues.push(...util.prefixIssues(key, result.issues));\n }\n if (!isPresent && !isOptionalIn) {\n if (!result.issues.length) {\n final.issues.push({\n code: \"invalid_type\",\n expected: \"nonoptional\",\n input: undefined,\n path: [key],\n });\n }\n return;\n }\n if (result.value === undefined) {\n if (isPresent) {\n final.value[key] = undefined;\n }\n }\n else {\n final.value[key] = result.value;\n }\n}\nfunction normalizeDef(def) {\n const keys = Object.keys(def.shape);\n for (const k of keys) {\n if (!def.shape?.[k]?._zod?.traits?.has(\"$ZodType\")) {\n throw new Error(`Invalid element at key \"${k}\": expected a Zod schema`);\n }\n }\n const okeys = util.optionalKeys(def.shape);\n return {\n ...def,\n keys,\n keySet: new Set(keys),\n numKeys: keys.length,\n optionalKeys: new Set(okeys),\n };\n}\nfunction handleCatchall(proms, input, payload, ctx, def, inst) {\n const unrecognized = [];\n const keySet = def.keySet;\n const _catchall = def.catchall._zod;\n const t = _catchall.def.type;\n const isOptionalIn = _catchall.optin === \"optional\";\n const isOptionalOut = _catchall.optout === \"optional\";\n for (const key in input) {\n // skip __proto__ so it can't replace the result prototype via the\n // assignment setter on the plain {} we build into\n if (key === \"__proto__\")\n continue;\n if (keySet.has(key))\n continue;\n if (t === \"never\") {\n unrecognized.push(key);\n continue;\n }\n const r = _catchall.run({ value: input[key], issues: [] }, ctx);\n if (r instanceof Promise) {\n proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut)));\n }\n else {\n handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut);\n }\n }\n if (unrecognized.length) {\n payload.issues.push({\n code: \"unrecognized_keys\",\n keys: unrecognized,\n input,\n inst,\n });\n }\n if (!proms.length)\n return payload;\n return Promise.all(proms).then(() => {\n return payload;\n });\n}\nexport const $ZodObject = /*@__PURE__*/ core.$constructor(\"$ZodObject\", (inst, def) => {\n // requires cast because technically $ZodObject doesn't extend\n $ZodType.init(inst, def);\n // const sh = def.shape;\n const desc = Object.getOwnPropertyDescriptor(def, \"shape\");\n if (!desc?.get) {\n const sh = def.shape;\n Object.defineProperty(def, \"shape\", {\n get: () => {\n const newSh = { ...sh };\n Object.defineProperty(def, \"shape\", {\n value: newSh,\n });\n return newSh;\n },\n });\n }\n const _normalized = util.cached(() => normalizeDef(def));\n util.defineLazy(inst._zod, \"propValues\", () => {\n const shape = def.shape;\n const propValues = {};\n for (const key in shape) {\n const field = shape[key]._zod;\n if (field.values) {\n propValues[key] ?? (propValues[key] = new Set());\n for (const v of field.values)\n propValues[key].add(v);\n }\n }\n return propValues;\n });\n const isObject = util.isObject;\n const catchall = def.catchall;\n let value;\n inst._zod.parse = (payload, ctx) => {\n value ?? (value = _normalized.value);\n const input = payload.value;\n if (!isObject(input)) {\n payload.issues.push({\n expected: \"object\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n payload.value = {};\n const proms = [];\n const shape = value.shape;\n for (const key of value.keys) {\n const el = shape[key];\n const isOptionalIn = el._zod.optin === \"optional\";\n const isOptionalOut = el._zod.optout === \"optional\";\n const r = el._zod.run({ value: input[key], issues: [] }, ctx);\n if (r instanceof Promise) {\n proms.push(r.then((r) => handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut)));\n }\n else {\n handlePropertyResult(r, payload, key, input, isOptionalIn, isOptionalOut);\n }\n }\n if (!catchall) {\n return proms.length ? Promise.all(proms).then(() => payload) : payload;\n }\n return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);\n };\n});\nexport const $ZodObjectJIT = /*@__PURE__*/ core.$constructor(\"$ZodObjectJIT\", (inst, def) => {\n // requires cast because technically $ZodObject doesn't extend\n $ZodObject.init(inst, def);\n const superParse = inst._zod.parse;\n const _normalized = util.cached(() => normalizeDef(def));\n const generateFastpass = (shape) => {\n const doc = new Doc([\"shape\", \"payload\", \"ctx\"]);\n const normalized = _normalized.value;\n const parseStr = (key) => {\n const k = util.esc(key);\n return `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;\n };\n doc.write(`const input = payload.value;`);\n const ids = Object.create(null);\n let counter = 0;\n for (const key of normalized.keys) {\n ids[key] = `key_${counter++}`;\n }\n // A: preserve key order {\n doc.write(`const newResult = {};`);\n for (const key of normalized.keys) {\n const id = ids[key];\n const k = util.esc(key);\n const schema = shape[key];\n const isOptionalIn = schema?._zod?.optin === \"optional\";\n const isOptionalOut = schema?._zod?.optout === \"optional\";\n doc.write(`const ${id} = ${parseStr(key)};`);\n if (isOptionalIn && isOptionalOut) {\n // For optional-in/out schemas, ignore errors on absent keys\n doc.write(`\n if (${id}.issues.length) {\n if (${k} in input) {\n payload.issues = payload.issues.concat(${id}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${k}, ...iss.path] : [${k}]\n })));\n }\n }\n \n if (${id}.value === undefined) {\n if (${k} in input) {\n newResult[${k}] = undefined;\n }\n } else {\n newResult[${k}] = ${id}.value;\n }\n \n `);\n }\n else if (!isOptionalIn) {\n doc.write(`\n const ${id}_present = ${k} in input;\n if (${id}.issues.length) {\n payload.issues = payload.issues.concat(${id}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${k}, ...iss.path] : [${k}]\n })));\n }\n if (!${id}_present && !${id}.issues.length) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"nonoptional\",\n input: undefined,\n path: [${k}]\n });\n }\n\n if (${id}_present) {\n if (${id}.value === undefined) {\n newResult[${k}] = undefined;\n } else {\n newResult[${k}] = ${id}.value;\n }\n }\n\n `);\n }\n else {\n doc.write(`\n if (${id}.issues.length) {\n payload.issues = payload.issues.concat(${id}.issues.map(iss => ({\n ...iss,\n path: iss.path ? [${k}, ...iss.path] : [${k}]\n })));\n }\n \n if (${id}.value === undefined) {\n if (${k} in input) {\n newResult[${k}] = undefined;\n }\n } else {\n newResult[${k}] = ${id}.value;\n }\n \n `);\n }\n }\n doc.write(`payload.value = newResult;`);\n doc.write(`return payload;`);\n const fn = doc.compile();\n return (payload, ctx) => fn(shape, payload, ctx);\n };\n let fastpass;\n const isObject = util.isObject;\n const jit = !core.globalConfig.jitless;\n const allowsEval = util.allowsEval;\n const fastEnabled = jit && allowsEval.value; // && !def.catchall;\n const catchall = def.catchall;\n let value;\n inst._zod.parse = (payload, ctx) => {\n value ?? (value = _normalized.value);\n const input = payload.value;\n if (!isObject(input)) {\n payload.issues.push({\n expected: \"object\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n if (jit && fastEnabled && ctx?.async === false && ctx.jitless !== true) {\n // always synchronous\n if (!fastpass)\n fastpass = generateFastpass(def.shape);\n payload = fastpass(payload, ctx);\n if (!catchall)\n return payload;\n return handleCatchall([], input, payload, ctx, value, inst);\n }\n return superParse(payload, ctx);\n };\n});\nfunction handleUnionResults(results, final, inst, ctx) {\n for (const result of results) {\n if (result.issues.length === 0) {\n final.value = result.value;\n return final;\n }\n }\n const nonaborted = results.filter((r) => !util.aborted(r));\n if (nonaborted.length === 1) {\n final.value = nonaborted[0].value;\n return nonaborted[0];\n }\n final.issues.push({\n code: \"invalid_union\",\n input: final.value,\n inst,\n errors: results.map((result) => result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),\n });\n return final;\n}\nexport const $ZodUnion = /*@__PURE__*/ core.$constructor(\"$ZodUnion\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazy(inst._zod, \"optin\", () => def.options.some((o) => o._zod.optin === \"optional\") ? \"optional\" : undefined);\n util.defineLazy(inst._zod, \"optout\", () => def.options.some((o) => o._zod.optout === \"optional\") ? \"optional\" : undefined);\n util.defineLazy(inst._zod, \"values\", () => {\n if (def.options.every((o) => o._zod.values)) {\n return new Set(def.options.flatMap((option) => Array.from(option._zod.values)));\n }\n return undefined;\n });\n util.defineLazy(inst._zod, \"pattern\", () => {\n if (def.options.every((o) => o._zod.pattern)) {\n const patterns = def.options.map((o) => o._zod.pattern);\n return new RegExp(`^(${patterns.map((p) => util.cleanRegex(p.source)).join(\"|\")})$`);\n }\n return undefined;\n });\n const first = def.options.length === 1 ? def.options[0]._zod.run : null;\n inst._zod.parse = (payload, ctx) => {\n if (first) {\n return first(payload, ctx);\n }\n let async = false;\n const results = [];\n for (const option of def.options) {\n const result = option._zod.run({\n value: payload.value,\n issues: [],\n }, ctx);\n if (result instanceof Promise) {\n results.push(result);\n async = true;\n }\n else {\n if (result.issues.length === 0)\n return result;\n results.push(result);\n }\n }\n if (!async)\n return handleUnionResults(results, payload, inst, ctx);\n return Promise.all(results).then((results) => {\n return handleUnionResults(results, payload, inst, ctx);\n });\n };\n});\nfunction handleExclusiveUnionResults(results, final, inst, ctx) {\n const successes = results.filter((r) => r.issues.length === 0);\n if (successes.length === 1) {\n final.value = successes[0].value;\n return final;\n }\n if (successes.length === 0) {\n // No matches - same as regular union\n final.issues.push({\n code: \"invalid_union\",\n input: final.value,\n inst,\n errors: results.map((result) => result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config()))),\n });\n }\n else {\n // Multiple matches - exclusive union failure\n final.issues.push({\n code: \"invalid_union\",\n input: final.value,\n inst,\n errors: [],\n inclusive: false,\n });\n }\n return final;\n}\nexport const $ZodXor = /*@__PURE__*/ core.$constructor(\"$ZodXor\", (inst, def) => {\n $ZodUnion.init(inst, def);\n def.inclusive = false;\n const first = def.options.length === 1 ? def.options[0]._zod.run : null;\n inst._zod.parse = (payload, ctx) => {\n if (first) {\n return first(payload, ctx);\n }\n let async = false;\n const results = [];\n for (const option of def.options) {\n const result = option._zod.run({\n value: payload.value,\n issues: [],\n }, ctx);\n if (result instanceof Promise) {\n results.push(result);\n async = true;\n }\n else {\n results.push(result);\n }\n }\n if (!async)\n return handleExclusiveUnionResults(results, payload, inst, ctx);\n return Promise.all(results).then((results) => {\n return handleExclusiveUnionResults(results, payload, inst, ctx);\n });\n };\n});\nexport const $ZodDiscriminatedUnion = \n/*@__PURE__*/\ncore.$constructor(\"$ZodDiscriminatedUnion\", (inst, def) => {\n def.inclusive = false;\n $ZodUnion.init(inst, def);\n const _super = inst._zod.parse;\n util.defineLazy(inst._zod, \"propValues\", () => {\n const propValues = {};\n for (const option of def.options) {\n const pv = option._zod.propValues;\n if (!pv || Object.keys(pv).length === 0)\n throw new Error(`Invalid discriminated union option at index \"${def.options.indexOf(option)}\"`);\n for (const [k, v] of Object.entries(pv)) {\n if (!propValues[k])\n propValues[k] = new Set();\n for (const val of v) {\n propValues[k].add(val);\n }\n }\n }\n return propValues;\n });\n const disc = util.cached(() => {\n const opts = def.options;\n const map = new Map();\n for (const o of opts) {\n const values = o._zod.propValues?.[def.discriminator];\n if (!values || values.size === 0)\n throw new Error(`Invalid discriminated union option at index \"${def.options.indexOf(o)}\"`);\n for (const v of values) {\n if (map.has(v)) {\n throw new Error(`Duplicate discriminator value \"${String(v)}\"`);\n }\n map.set(v, o);\n }\n }\n return map;\n });\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!util.isObject(input)) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"object\",\n input,\n inst,\n });\n return payload;\n }\n const opt = disc.value.get(input?.[def.discriminator]);\n if (opt) {\n return opt._zod.run(payload, ctx);\n }\n // Fall back to union matching when the fast discriminator path fails:\n // - explicitly enabled via unionFallback, or\n // - during backward direction (encode), since codec-based discriminators\n // have different values in forward vs backward directions\n if (def.unionFallback || ctx.direction === \"backward\") {\n return _super(payload, ctx);\n }\n // no matching discriminator\n payload.issues.push({\n code: \"invalid_union\",\n errors: [],\n note: \"No matching discriminator\",\n discriminator: def.discriminator,\n options: Array.from(disc.value.keys()),\n input,\n path: [def.discriminator],\n inst,\n });\n return payload;\n };\n});\nexport const $ZodIntersection = /*@__PURE__*/ core.$constructor(\"$ZodIntersection\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n const left = def.left._zod.run({ value: input, issues: [] }, ctx);\n const right = def.right._zod.run({ value: input, issues: [] }, ctx);\n const async = left instanceof Promise || right instanceof Promise;\n if (async) {\n return Promise.all([left, right]).then(([left, right]) => {\n return handleIntersectionResults(payload, left, right);\n });\n }\n return handleIntersectionResults(payload, left, right);\n };\n});\nfunction mergeValues(a, b) {\n // const aType = parse.t(a);\n // const bType = parse.t(b);\n if (a === b) {\n return { valid: true, data: a };\n }\n if (a instanceof Date && b instanceof Date && +a === +b) {\n return { valid: true, data: a };\n }\n if (util.isPlainObject(a) && util.isPlainObject(b)) {\n const bKeys = Object.keys(b);\n const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);\n const newObj = { ...a, ...b };\n for (const key of sharedKeys) {\n const sharedValue = mergeValues(a[key], b[key]);\n if (!sharedValue.valid) {\n return {\n valid: false,\n mergeErrorPath: [key, ...sharedValue.mergeErrorPath],\n };\n }\n newObj[key] = sharedValue.data;\n }\n return { valid: true, data: newObj };\n }\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return { valid: false, mergeErrorPath: [] };\n }\n const newArray = [];\n for (let index = 0; index < a.length; index++) {\n const itemA = a[index];\n const itemB = b[index];\n const sharedValue = mergeValues(itemA, itemB);\n if (!sharedValue.valid) {\n return {\n valid: false,\n mergeErrorPath: [index, ...sharedValue.mergeErrorPath],\n };\n }\n newArray.push(sharedValue.data);\n }\n return { valid: true, data: newArray };\n }\n return { valid: false, mergeErrorPath: [] };\n}\nfunction handleIntersectionResults(result, left, right) {\n // Track which side(s) report each key as unrecognized\n const unrecKeys = new Map();\n let unrecIssue;\n for (const iss of left.issues) {\n if (iss.code === \"unrecognized_keys\") {\n unrecIssue ?? (unrecIssue = iss);\n for (const k of iss.keys) {\n if (!unrecKeys.has(k))\n unrecKeys.set(k, {});\n unrecKeys.get(k).l = true;\n }\n }\n else {\n result.issues.push(iss);\n }\n }\n for (const iss of right.issues) {\n if (iss.code === \"unrecognized_keys\") {\n for (const k of iss.keys) {\n if (!unrecKeys.has(k))\n unrecKeys.set(k, {});\n unrecKeys.get(k).r = true;\n }\n }\n else {\n result.issues.push(iss);\n }\n }\n // Report only keys unrecognized by BOTH sides\n const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);\n if (bothKeys.length && unrecIssue) {\n result.issues.push({ ...unrecIssue, keys: bothKeys });\n }\n if (util.aborted(result))\n return result;\n const merged = mergeValues(left.value, right.value);\n if (!merged.valid) {\n throw new Error(`Unmergable intersection. Error path: ` + `${JSON.stringify(merged.mergeErrorPath)}`);\n }\n result.value = merged.data;\n return result;\n}\nexport const $ZodTuple = /*@__PURE__*/ core.$constructor(\"$ZodTuple\", (inst, def) => {\n $ZodType.init(inst, def);\n const items = def.items;\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!Array.isArray(input)) {\n payload.issues.push({\n input,\n inst,\n expected: \"tuple\",\n code: \"invalid_type\",\n });\n return payload;\n }\n payload.value = [];\n const proms = [];\n const optinStart = getTupleOptStart(items, \"optin\");\n const optoutStart = getTupleOptStart(items, \"optout\");\n if (!def.rest) {\n if (input.length < optinStart) {\n payload.issues.push({\n code: \"too_small\",\n minimum: optinStart,\n inclusive: true,\n input,\n inst,\n origin: \"array\",\n });\n return payload;\n }\n if (input.length > items.length) {\n payload.issues.push({\n code: \"too_big\",\n maximum: items.length,\n inclusive: true,\n input,\n inst,\n origin: \"array\",\n });\n }\n }\n // Run every item in parallel, collecting results into an indexed\n // array. The post-processing in `handleTupleResults` walks them in\n // order so it can decide whether an absent optional-output error can\n // truncate the tail or must be reported to preserve required output.\n const itemResults = new Array(items.length);\n for (let i = 0; i < items.length; i++) {\n const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);\n if (r instanceof Promise) {\n proms.push(r.then((rr) => {\n itemResults[i] = rr;\n }));\n }\n else {\n itemResults[i] = r;\n }\n }\n if (def.rest) {\n let i = items.length - 1;\n const rest = input.slice(items.length);\n for (const el of rest) {\n i++;\n const result = def.rest._zod.run({ value: el, issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((r) => handleTupleResult(r, payload, i)));\n }\n else {\n handleTupleResult(result, payload, i);\n }\n }\n }\n if (proms.length) {\n return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));\n }\n return handleTupleResults(itemResults, payload, items, input, optoutStart);\n };\n});\nfunction getTupleOptStart(items, key) {\n for (let i = items.length - 1; i >= 0; i--) {\n if (items[i]._zod[key] !== \"optional\")\n return i + 1;\n }\n return 0;\n}\nfunction handleTupleResult(result, final, index) {\n if (result.issues.length) {\n final.issues.push(...util.prefixIssues(index, result.issues));\n }\n final.value[index] = result.value;\n}\nfunction handleTupleResults(itemResults, final, items, input, optoutStart) {\n // Walk results in order. Mirror $ZodObject's swallow-on-absent-optional\n // rule, but only after `optoutStart`: the first index where the output\n // tuple tail can be absent.\n for (let i = 0; i < items.length; i++) {\n const r = itemResults[i];\n const isPresent = i < input.length;\n if (r.issues.length) {\n if (!isPresent && i >= optoutStart) {\n final.value.length = i;\n break;\n }\n final.issues.push(...util.prefixIssues(i, r.issues));\n }\n final.value[i] = r.value;\n }\n // Drop trailing slots that produced `undefined` for absent input\n // (the array analog of an absent optional key on an object). The\n // `i >= input.length` floor is critical: an explicit `undefined`\n // *inside* the input must be preserved even when the schema is\n // optional-out (e.g. `z.string().or(z.undefined())` accepting an\n // explicit undefined value).\n for (let i = final.value.length - 1; i >= input.length; i--) {\n if (items[i]._zod.optout === \"optional\" && final.value[i] === undefined) {\n final.value.length = i;\n }\n else {\n break;\n }\n }\n return final;\n}\nexport const $ZodRecord = /*@__PURE__*/ core.$constructor(\"$ZodRecord\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!util.isPlainObject(input)) {\n payload.issues.push({\n expected: \"record\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n const proms = [];\n const values = def.keyType._zod.values;\n if (values) {\n payload.value = {};\n const recordKeys = new Set();\n for (const key of values) {\n if (typeof key === \"string\" || typeof key === \"number\" || typeof key === \"symbol\") {\n recordKeys.add(typeof key === \"number\" ? key.toString() : key);\n const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);\n if (keyResult instanceof Promise) {\n throw new Error(\"Async schemas not supported in object keys currently\");\n }\n if (keyResult.issues.length) {\n payload.issues.push({\n code: \"invalid_key\",\n origin: \"record\",\n issues: keyResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n input: key,\n path: [key],\n inst,\n });\n continue;\n }\n const outKey = keyResult.value;\n const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[outKey] = result.value;\n }));\n }\n else {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[outKey] = result.value;\n }\n }\n }\n let unrecognized;\n for (const key in input) {\n if (!recordKeys.has(key)) {\n unrecognized = unrecognized ?? [];\n unrecognized.push(key);\n }\n }\n if (unrecognized && unrecognized.length > 0) {\n payload.issues.push({\n code: \"unrecognized_keys\",\n input,\n inst,\n keys: unrecognized,\n });\n }\n }\n else {\n payload.value = {};\n // Reflect.ownKeys for Symbol-key support; filter non-enumerable to match z.object()\n for (const key of Reflect.ownKeys(input)) {\n if (key === \"__proto__\")\n continue;\n if (!Object.prototype.propertyIsEnumerable.call(input, key))\n continue;\n let keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);\n if (keyResult instanceof Promise) {\n throw new Error(\"Async schemas not supported in object keys currently\");\n }\n // Numeric string fallback: if key is a numeric string and failed, retry with Number(key)\n // This handles z.number(), z.literal([1, 2, 3]), and unions containing numeric literals\n const checkNumericKey = typeof key === \"string\" && regexes.number.test(key) && keyResult.issues.length;\n if (checkNumericKey) {\n const retryResult = def.keyType._zod.run({ value: Number(key), issues: [] }, ctx);\n if (retryResult instanceof Promise) {\n throw new Error(\"Async schemas not supported in object keys currently\");\n }\n if (retryResult.issues.length === 0) {\n keyResult = retryResult;\n }\n }\n if (keyResult.issues.length) {\n if (def.mode === \"loose\") {\n // Pass through unchanged\n payload.value[key] = input[key];\n }\n else {\n // Default \"strict\" behavior: error on invalid key\n payload.issues.push({\n code: \"invalid_key\",\n origin: \"record\",\n issues: keyResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n input: key,\n path: [key],\n inst,\n });\n }\n continue;\n }\n const result = def.valueType._zod.run({ value: input[key], issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[keyResult.value] = result.value;\n }));\n }\n else {\n if (result.issues.length) {\n payload.issues.push(...util.prefixIssues(key, result.issues));\n }\n payload.value[keyResult.value] = result.value;\n }\n }\n }\n if (proms.length) {\n return Promise.all(proms).then(() => payload);\n }\n return payload;\n };\n});\nexport const $ZodMap = /*@__PURE__*/ core.$constructor(\"$ZodMap\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!(input instanceof Map)) {\n payload.issues.push({\n expected: \"map\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n }\n const proms = [];\n payload.value = new Map();\n for (const [key, value] of input) {\n const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);\n const valueResult = def.valueType._zod.run({ value: value, issues: [] }, ctx);\n if (keyResult instanceof Promise || valueResult instanceof Promise) {\n proms.push(Promise.all([keyResult, valueResult]).then(([keyResult, valueResult]) => {\n handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);\n }));\n }\n else {\n handleMapResult(keyResult, valueResult, payload, key, input, inst, ctx);\n }\n }\n if (proms.length)\n return Promise.all(proms).then(() => payload);\n return payload;\n };\n});\nfunction handleMapResult(keyResult, valueResult, final, key, input, inst, ctx) {\n if (keyResult.issues.length) {\n if (util.propertyKeyTypes.has(typeof key)) {\n final.issues.push(...util.prefixIssues(key, keyResult.issues));\n }\n else {\n final.issues.push({\n code: \"invalid_key\",\n origin: \"map\",\n input,\n inst,\n issues: keyResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n });\n }\n }\n if (valueResult.issues.length) {\n if (util.propertyKeyTypes.has(typeof key)) {\n final.issues.push(...util.prefixIssues(key, valueResult.issues));\n }\n else {\n final.issues.push({\n origin: \"map\",\n code: \"invalid_element\",\n input,\n inst,\n key: key,\n issues: valueResult.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n });\n }\n }\n final.value.set(keyResult.value, valueResult.value);\n}\nexport const $ZodSet = /*@__PURE__*/ core.$constructor(\"$ZodSet\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n const input = payload.value;\n if (!(input instanceof Set)) {\n payload.issues.push({\n input,\n inst,\n expected: \"set\",\n code: \"invalid_type\",\n });\n return payload;\n }\n const proms = [];\n payload.value = new Set();\n for (const item of input) {\n const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);\n if (result instanceof Promise) {\n proms.push(result.then((result) => handleSetResult(result, payload)));\n }\n else\n handleSetResult(result, payload);\n }\n if (proms.length)\n return Promise.all(proms).then(() => payload);\n return payload;\n };\n});\nfunction handleSetResult(result, final) {\n if (result.issues.length) {\n final.issues.push(...result.issues);\n }\n final.value.add(result.value);\n}\nexport const $ZodEnum = /*@__PURE__*/ core.$constructor(\"$ZodEnum\", (inst, def) => {\n $ZodType.init(inst, def);\n const values = util.getEnumValues(def.entries);\n const valuesSet = new Set(values);\n inst._zod.values = valuesSet;\n inst._zod.pattern = new RegExp(`^(${values\n .filter((k) => util.propertyKeyTypes.has(typeof k))\n .map((o) => (typeof o === \"string\" ? util.escapeRegex(o) : o.toString()))\n .join(\"|\")})$`);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (valuesSet.has(input)) {\n return payload;\n }\n payload.issues.push({\n code: \"invalid_value\",\n values,\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodLiteral = /*@__PURE__*/ core.$constructor(\"$ZodLiteral\", (inst, def) => {\n $ZodType.init(inst, def);\n if (def.values.length === 0) {\n throw new Error(\"Cannot create literal schema with no valid values\");\n }\n const values = new Set(def.values);\n inst._zod.values = values;\n inst._zod.pattern = new RegExp(`^(${def.values\n .map((o) => (typeof o === \"string\" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o)))\n .join(\"|\")})$`);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n if (values.has(input)) {\n return payload;\n }\n payload.issues.push({\n code: \"invalid_value\",\n values: def.values,\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodFile = /*@__PURE__*/ core.$constructor(\"$ZodFile\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n const input = payload.value;\n // @ts-ignore\n if (input instanceof File)\n return payload;\n payload.issues.push({\n expected: \"file\",\n code: \"invalid_type\",\n input,\n inst,\n });\n return payload;\n };\n});\nexport const $ZodTransform = /*@__PURE__*/ core.$constructor(\"$ZodTransform\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.optin = \"optional\";\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n throw new core.$ZodEncodeError(inst.constructor.name);\n }\n const _out = def.transform(payload.value, payload);\n if (ctx.async) {\n const output = _out instanceof Promise ? _out : Promise.resolve(_out);\n return output.then((output) => {\n payload.value = output;\n payload.fallback = true;\n return payload;\n });\n }\n if (_out instanceof Promise) {\n throw new core.$ZodAsyncError();\n }\n payload.value = _out;\n payload.fallback = true;\n return payload;\n };\n});\nfunction handleOptionalResult(result, input) {\n if (input === undefined && (result.issues.length || result.fallback)) {\n return { issues: [], value: undefined };\n }\n return result;\n}\nexport const $ZodOptional = /*@__PURE__*/ core.$constructor(\"$ZodOptional\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.optin = \"optional\";\n inst._zod.optout = \"optional\";\n util.defineLazy(inst._zod, \"values\", () => {\n return def.innerType._zod.values ? new Set([...def.innerType._zod.values, undefined]) : undefined;\n });\n util.defineLazy(inst._zod, \"pattern\", () => {\n const pattern = def.innerType._zod.pattern;\n return pattern ? new RegExp(`^(${util.cleanRegex(pattern.source)})?$`) : undefined;\n });\n inst._zod.parse = (payload, ctx) => {\n if (def.innerType._zod.optin === \"optional\") {\n const input = payload.value;\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise)\n return result.then((r) => handleOptionalResult(r, input));\n return handleOptionalResult(result, input);\n }\n if (payload.value === undefined) {\n return payload;\n }\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodExactOptional = /*@__PURE__*/ core.$constructor(\"$ZodExactOptional\", (inst, def) => {\n // Call parent init - inherits optin/optout = \"optional\"\n $ZodOptional.init(inst, def);\n // Override values/pattern to NOT add undefined\n util.defineLazy(inst._zod, \"values\", () => def.innerType._zod.values);\n util.defineLazy(inst._zod, \"pattern\", () => def.innerType._zod.pattern);\n // Override parse to just delegate (no undefined handling)\n inst._zod.parse = (payload, ctx) => {\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodNullable = /*@__PURE__*/ core.$constructor(\"$ZodNullable\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazy(inst._zod, \"optin\", () => def.innerType._zod.optin);\n util.defineLazy(inst._zod, \"optout\", () => def.innerType._zod.optout);\n util.defineLazy(inst._zod, \"pattern\", () => {\n const pattern = def.innerType._zod.pattern;\n return pattern ? new RegExp(`^(${util.cleanRegex(pattern.source)}|null)$`) : undefined;\n });\n util.defineLazy(inst._zod, \"values\", () => {\n return def.innerType._zod.values ? new Set([...def.innerType._zod.values, null]) : undefined;\n });\n inst._zod.parse = (payload, ctx) => {\n // Forward direction (decode): allow null to pass through\n if (payload.value === null)\n return payload;\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodDefault = /*@__PURE__*/ core.$constructor(\"$ZodDefault\", (inst, def) => {\n $ZodType.init(inst, def);\n // inst._zod.qin = \"true\";\n inst._zod.optin = \"optional\";\n util.defineLazy(inst._zod, \"values\", () => def.innerType._zod.values);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n // Forward direction (decode): apply defaults for undefined input\n if (payload.value === undefined) {\n payload.value = def.defaultValue;\n /**\n * $ZodDefault returns the default value immediately in forward direction.\n * It doesn't pass the default value into the validator (\"prefault\"). There's no reason to pass the default value through validation. The validity of the default is enforced by TypeScript statically. Otherwise, it's the responsibility of the user to ensure the default is valid. In the case of pipes with divergent in/out types, you can specify the default on the `in` schema of your ZodPipe to set a \"prefault\" for the pipe. */\n return payload;\n }\n // Forward direction: continue with default handling\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => handleDefaultResult(result, def));\n }\n return handleDefaultResult(result, def);\n };\n});\nfunction handleDefaultResult(payload, def) {\n if (payload.value === undefined) {\n payload.value = def.defaultValue;\n }\n return payload;\n}\nexport const $ZodPrefault = /*@__PURE__*/ core.$constructor(\"$ZodPrefault\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.optin = \"optional\";\n util.defineLazy(inst._zod, \"values\", () => def.innerType._zod.values);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n // Forward direction (decode): apply prefault for undefined input\n if (payload.value === undefined) {\n payload.value = def.defaultValue;\n }\n return def.innerType._zod.run(payload, ctx);\n };\n});\nexport const $ZodNonOptional = /*@__PURE__*/ core.$constructor(\"$ZodNonOptional\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazy(inst._zod, \"values\", () => {\n const v = def.innerType._zod.values;\n return v ? new Set([...v].filter((x) => x !== undefined)) : undefined;\n });\n inst._zod.parse = (payload, ctx) => {\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => handleNonOptionalResult(result, inst));\n }\n return handleNonOptionalResult(result, inst);\n };\n});\nfunction handleNonOptionalResult(payload, inst) {\n if (!payload.issues.length && payload.value === undefined) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"nonoptional\",\n input: payload.value,\n inst,\n });\n }\n return payload;\n}\nexport const $ZodSuccess = /*@__PURE__*/ core.$constructor(\"$ZodSuccess\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n throw new core.$ZodEncodeError(\"ZodSuccess\");\n }\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => {\n payload.value = result.issues.length === 0;\n return payload;\n });\n }\n payload.value = result.issues.length === 0;\n return payload;\n };\n});\nexport const $ZodCatch = /*@__PURE__*/ core.$constructor(\"$ZodCatch\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.optin = \"optional\";\n util.defineLazy(inst._zod, \"optout\", () => def.innerType._zod.optout);\n util.defineLazy(inst._zod, \"values\", () => def.innerType._zod.values);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n // Forward direction (decode): apply catch logic\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then((result) => {\n payload.value = result.value;\n if (result.issues.length) {\n payload.value = def.catchValue({\n ...payload,\n error: {\n issues: result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n },\n input: payload.value,\n });\n payload.issues = [];\n payload.fallback = true;\n }\n return payload;\n });\n }\n payload.value = result.value;\n if (result.issues.length) {\n payload.value = def.catchValue({\n ...payload,\n error: {\n issues: result.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())),\n },\n input: payload.value,\n });\n payload.issues = [];\n payload.fallback = true;\n }\n return payload;\n };\n});\nexport const $ZodNaN = /*@__PURE__*/ core.$constructor(\"$ZodNaN\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _ctx) => {\n if (typeof payload.value !== \"number\" || !Number.isNaN(payload.value)) {\n payload.issues.push({\n input: payload.value,\n inst,\n expected: \"nan\",\n code: \"invalid_type\",\n });\n return payload;\n }\n return payload;\n };\n});\nexport const $ZodPipe = /*@__PURE__*/ core.$constructor(\"$ZodPipe\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazy(inst._zod, \"values\", () => def.in._zod.values);\n util.defineLazy(inst._zod, \"optin\", () => def.in._zod.optin);\n util.defineLazy(inst._zod, \"optout\", () => def.out._zod.optout);\n util.defineLazy(inst._zod, \"propValues\", () => def.in._zod.propValues);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n const right = def.out._zod.run(payload, ctx);\n if (right instanceof Promise) {\n return right.then((right) => handlePipeResult(right, def.in, ctx));\n }\n return handlePipeResult(right, def.in, ctx);\n }\n const left = def.in._zod.run(payload, ctx);\n if (left instanceof Promise) {\n return left.then((left) => handlePipeResult(left, def.out, ctx));\n }\n return handlePipeResult(left, def.out, ctx);\n };\n});\nfunction handlePipeResult(left, next, ctx) {\n if (left.issues.length) {\n // prevent further checks\n left.aborted = true;\n return left;\n }\n return next._zod.run({ value: left.value, issues: left.issues, fallback: left.fallback }, ctx);\n}\nexport const $ZodCodec = /*@__PURE__*/ core.$constructor(\"$ZodCodec\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazy(inst._zod, \"values\", () => def.in._zod.values);\n util.defineLazy(inst._zod, \"optin\", () => def.in._zod.optin);\n util.defineLazy(inst._zod, \"optout\", () => def.out._zod.optout);\n util.defineLazy(inst._zod, \"propValues\", () => def.in._zod.propValues);\n inst._zod.parse = (payload, ctx) => {\n const direction = ctx.direction || \"forward\";\n if (direction === \"forward\") {\n const left = def.in._zod.run(payload, ctx);\n if (left instanceof Promise) {\n return left.then((left) => handleCodecAResult(left, def, ctx));\n }\n return handleCodecAResult(left, def, ctx);\n }\n else {\n const right = def.out._zod.run(payload, ctx);\n if (right instanceof Promise) {\n return right.then((right) => handleCodecAResult(right, def, ctx));\n }\n return handleCodecAResult(right, def, ctx);\n }\n };\n});\nfunction handleCodecAResult(result, def, ctx) {\n if (result.issues.length) {\n // prevent further checks\n result.aborted = true;\n return result;\n }\n const direction = ctx.direction || \"forward\";\n if (direction === \"forward\") {\n const transformed = def.transform(result.value, result);\n if (transformed instanceof Promise) {\n return transformed.then((value) => handleCodecTxResult(result, value, def.out, ctx));\n }\n return handleCodecTxResult(result, transformed, def.out, ctx);\n }\n else {\n const transformed = def.reverseTransform(result.value, result);\n if (transformed instanceof Promise) {\n return transformed.then((value) => handleCodecTxResult(result, value, def.in, ctx));\n }\n return handleCodecTxResult(result, transformed, def.in, ctx);\n }\n}\nfunction handleCodecTxResult(left, value, nextSchema, ctx) {\n // Check if transform added any issues\n if (left.issues.length) {\n left.aborted = true;\n return left;\n }\n return nextSchema._zod.run({ value, issues: left.issues }, ctx);\n}\nexport const $ZodPreprocess = /*@__PURE__*/ core.$constructor(\"$ZodPreprocess\", (inst, def) => {\n $ZodPipe.init(inst, def);\n});\nexport const $ZodReadonly = /*@__PURE__*/ core.$constructor(\"$ZodReadonly\", (inst, def) => {\n $ZodType.init(inst, def);\n util.defineLazy(inst._zod, \"propValues\", () => def.innerType._zod.propValues);\n util.defineLazy(inst._zod, \"values\", () => def.innerType._zod.values);\n util.defineLazy(inst._zod, \"optin\", () => def.innerType?._zod?.optin);\n util.defineLazy(inst._zod, \"optout\", () => def.innerType?._zod?.optout);\n inst._zod.parse = (payload, ctx) => {\n if (ctx.direction === \"backward\") {\n return def.innerType._zod.run(payload, ctx);\n }\n const result = def.innerType._zod.run(payload, ctx);\n if (result instanceof Promise) {\n return result.then(handleReadonlyResult);\n }\n return handleReadonlyResult(result);\n };\n});\nfunction handleReadonlyResult(payload) {\n payload.value = Object.freeze(payload.value);\n return payload;\n}\nexport const $ZodTemplateLiteral = /*@__PURE__*/ core.$constructor(\"$ZodTemplateLiteral\", (inst, def) => {\n $ZodType.init(inst, def);\n const regexParts = [];\n for (const part of def.parts) {\n if (typeof part === \"object\" && part !== null) {\n // is Zod schema\n if (!part._zod.pattern) {\n // if (!source)\n throw new Error(`Invalid template literal part, no pattern found: ${[...part._zod.traits].shift()}`);\n }\n const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern;\n if (!source)\n throw new Error(`Invalid template literal part: ${part._zod.traits}`);\n const start = source.startsWith(\"^\") ? 1 : 0;\n const end = source.endsWith(\"$\") ? source.length - 1 : source.length;\n regexParts.push(source.slice(start, end));\n }\n else if (part === null || util.primitiveTypes.has(typeof part)) {\n regexParts.push(util.escapeRegex(`${part}`));\n }\n else {\n throw new Error(`Invalid template literal part: ${part}`);\n }\n }\n inst._zod.pattern = new RegExp(`^${regexParts.join(\"\")}$`);\n inst._zod.parse = (payload, _ctx) => {\n if (typeof payload.value !== \"string\") {\n payload.issues.push({\n input: payload.value,\n inst,\n expected: \"string\",\n code: \"invalid_type\",\n });\n return payload;\n }\n inst._zod.pattern.lastIndex = 0;\n if (!inst._zod.pattern.test(payload.value)) {\n payload.issues.push({\n input: payload.value,\n inst,\n code: \"invalid_format\",\n format: def.format ?? \"template_literal\",\n pattern: inst._zod.pattern.source,\n });\n return payload;\n }\n return payload;\n };\n});\nexport const $ZodFunction = /*@__PURE__*/ core.$constructor(\"$ZodFunction\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._def = def;\n inst._zod.def = def;\n inst.implement = (func) => {\n if (typeof func !== \"function\") {\n throw new Error(\"implement() must be called with a function\");\n }\n return function (...args) {\n const parsedArgs = inst._def.input ? parse(inst._def.input, args) : args;\n const result = Reflect.apply(func, this, parsedArgs);\n if (inst._def.output) {\n return parse(inst._def.output, result);\n }\n return result;\n };\n };\n inst.implementAsync = (func) => {\n if (typeof func !== \"function\") {\n throw new Error(\"implementAsync() must be called with a function\");\n }\n return async function (...args) {\n const parsedArgs = inst._def.input ? await parseAsync(inst._def.input, args) : args;\n const result = await Reflect.apply(func, this, parsedArgs);\n if (inst._def.output) {\n return await parseAsync(inst._def.output, result);\n }\n return result;\n };\n };\n inst._zod.parse = (payload, _ctx) => {\n if (typeof payload.value !== \"function\") {\n payload.issues.push({\n code: \"invalid_type\",\n expected: \"function\",\n input: payload.value,\n inst,\n });\n return payload;\n }\n // Check if output is a promise type to determine if we should use async implementation\n const hasPromiseOutput = inst._def.output && inst._def.output._zod.def.type === \"promise\";\n if (hasPromiseOutput) {\n payload.value = inst.implementAsync(payload.value);\n }\n else {\n payload.value = inst.implement(payload.value);\n }\n return payload;\n };\n inst.input = (...args) => {\n const F = inst.constructor;\n if (Array.isArray(args[0])) {\n return new F({\n type: \"function\",\n input: new $ZodTuple({\n type: \"tuple\",\n items: args[0],\n rest: args[1],\n }),\n output: inst._def.output,\n });\n }\n return new F({\n type: \"function\",\n input: args[0],\n output: inst._def.output,\n });\n };\n inst.output = (output) => {\n const F = inst.constructor;\n return new F({\n type: \"function\",\n input: inst._def.input,\n output,\n });\n };\n return inst;\n});\nexport const $ZodPromise = /*@__PURE__*/ core.$constructor(\"$ZodPromise\", (inst, def) => {\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, ctx) => {\n return Promise.resolve(payload.value).then((inner) => def.innerType._zod.run({ value: inner, issues: [] }, ctx));\n };\n});\nexport const $ZodLazy = /*@__PURE__*/ core.$constructor(\"$ZodLazy\", (inst, def) => {\n $ZodType.init(inst, def);\n // Cache the resolved inner type on the shared `def` so all clones of this\n // lazy (e.g. via `.describe()`/`.meta()`) share the same inner instance,\n // preserving identity for cycle detection on recursive schemas.\n util.defineLazy(inst._zod, \"innerType\", () => {\n const d = def;\n if (!d._cachedInner)\n d._cachedInner = def.getter();\n return d._cachedInner;\n });\n util.defineLazy(inst._zod, \"pattern\", () => inst._zod.innerType?._zod?.pattern);\n util.defineLazy(inst._zod, \"propValues\", () => inst._zod.innerType?._zod?.propValues);\n util.defineLazy(inst._zod, \"optin\", () => inst._zod.innerType?._zod?.optin ?? undefined);\n util.defineLazy(inst._zod, \"optout\", () => inst._zod.innerType?._zod?.optout ?? undefined);\n inst._zod.parse = (payload, ctx) => {\n const inner = inst._zod.innerType;\n return inner._zod.run(payload, ctx);\n };\n});\nexport const $ZodCustom = /*@__PURE__*/ core.$constructor(\"$ZodCustom\", (inst, def) => {\n checks.$ZodCheck.init(inst, def);\n $ZodType.init(inst, def);\n inst._zod.parse = (payload, _) => {\n return payload;\n };\n inst._zod.check = (payload) => {\n const input = payload.value;\n const r = def.fn(input);\n if (r instanceof Promise) {\n return r.then((r) => handleRefineResult(r, payload, input, inst));\n }\n handleRefineResult(r, payload, input, inst);\n return;\n };\n});\nfunction handleRefineResult(result, payload, input, inst) {\n if (!result) {\n const _iss = {\n code: \"custom\",\n input,\n inst, // incorporates params.error into issue reporting\n path: [...(inst._zod.def.path ?? [])], // incorporates params.error into issue reporting\n continue: !inst._zod.def.abort,\n // params: inst._zod.def.params,\n };\n if (inst._zod.def.params)\n _iss.params = inst._zod.def.params;\n payload.issues.push(util.issue(_iss));\n }\n}\n","var _a;\nexport const $output = Symbol(\"ZodOutput\");\nexport const $input = Symbol(\"ZodInput\");\nexport class $ZodRegistry {\n constructor() {\n this._map = new WeakMap();\n this._idmap = new Map();\n }\n add(schema, ..._meta) {\n const meta = _meta[0];\n this._map.set(schema, meta);\n if (meta && typeof meta === \"object\" && \"id\" in meta) {\n this._idmap.set(meta.id, schema);\n }\n return this;\n }\n clear() {\n this._map = new WeakMap();\n this._idmap = new Map();\n return this;\n }\n remove(schema) {\n const meta = this._map.get(schema);\n if (meta && typeof meta === \"object\" && \"id\" in meta) {\n this._idmap.delete(meta.id);\n }\n this._map.delete(schema);\n return this;\n }\n get(schema) {\n // return this._map.get(schema) as any;\n // inherit metadata\n const p = schema._zod.parent;\n if (p) {\n const pm = { ...(this.get(p) ?? {}) };\n delete pm.id; // do not inherit id\n const f = { ...pm, ...this._map.get(schema) };\n return Object.keys(f).length ? f : undefined;\n }\n return this._map.get(schema);\n }\n has(schema) {\n return this._map.has(schema);\n }\n}\n// registries\nexport function registry() {\n return new $ZodRegistry();\n}\n(_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());\nexport const globalRegistry = globalThis.__zod_globalRegistry;\n","import * as checks from \"./checks.js\";\nimport * as registries from \"./registries.js\";\nimport * as schemas from \"./schemas.js\";\nimport * as util from \"./util.js\";\n// @__NO_SIDE_EFFECTS__\nexport function _string(Class, params) {\n return new Class({\n type: \"string\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedString(Class, params) {\n return new Class({\n type: \"string\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _email(Class, params) {\n return new Class({\n type: \"string\",\n format: \"email\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _guid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"guid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuidv4(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n version: \"v4\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuidv6(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n version: \"v6\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uuidv7(Class, params) {\n return new Class({\n type: \"string\",\n format: \"uuid\",\n check: \"string_format\",\n abort: false,\n version: \"v7\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _url(Class, params) {\n return new Class({\n type: \"string\",\n format: \"url\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _emoji(Class, params) {\n return new Class({\n type: \"string\",\n format: \"emoji\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nanoid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"nanoid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link _cuid2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\n// @__NO_SIDE_EFFECTS__\nexport function _cuid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cuid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _cuid2(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cuid2\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ulid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ulid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _xid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"xid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ksuid(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ksuid\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ipv4(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ipv4\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _ipv6(Class, params) {\n return new Class({\n type: \"string\",\n format: \"ipv6\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _mac(Class, params) {\n return new Class({\n type: \"string\",\n format: \"mac\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _cidrv4(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cidrv4\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _cidrv6(Class, params) {\n return new Class({\n type: \"string\",\n format: \"cidrv6\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _base64(Class, params) {\n return new Class({\n type: \"string\",\n format: \"base64\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _base64url(Class, params) {\n return new Class({\n type: \"string\",\n format: \"base64url\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _e164(Class, params) {\n return new Class({\n type: \"string\",\n format: \"e164\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _jwt(Class, params) {\n return new Class({\n type: \"string\",\n format: \"jwt\",\n check: \"string_format\",\n abort: false,\n ...util.normalizeParams(params),\n });\n}\nexport const TimePrecision = {\n Any: null,\n Minute: -1,\n Second: 0,\n Millisecond: 3,\n Microsecond: 6,\n};\n// @__NO_SIDE_EFFECTS__\nexport function _isoDateTime(Class, params) {\n return new Class({\n type: \"string\",\n format: \"datetime\",\n check: \"string_format\",\n offset: false,\n local: false,\n precision: null,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _isoDate(Class, params) {\n return new Class({\n type: \"string\",\n format: \"date\",\n check: \"string_format\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _isoTime(Class, params) {\n return new Class({\n type: \"string\",\n format: \"time\",\n check: \"string_format\",\n precision: null,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _isoDuration(Class, params) {\n return new Class({\n type: \"string\",\n format: \"duration\",\n check: \"string_format\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _number(Class, params) {\n return new Class({\n type: \"number\",\n checks: [],\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedNumber(Class, params) {\n return new Class({\n type: \"number\",\n coerce: true,\n checks: [],\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _int(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"safeint\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _float32(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"float32\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _float64(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"float64\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _int32(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"int32\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uint32(Class, params) {\n return new Class({\n type: \"number\",\n check: \"number_format\",\n abort: false,\n format: \"uint32\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _boolean(Class, params) {\n return new Class({\n type: \"boolean\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedBoolean(Class, params) {\n return new Class({\n type: \"boolean\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _bigint(Class, params) {\n return new Class({\n type: \"bigint\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedBigint(Class, params) {\n return new Class({\n type: \"bigint\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _int64(Class, params) {\n return new Class({\n type: \"bigint\",\n check: \"bigint_format\",\n abort: false,\n format: \"int64\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uint64(Class, params) {\n return new Class({\n type: \"bigint\",\n check: \"bigint_format\",\n abort: false,\n format: \"uint64\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _symbol(Class, params) {\n return new Class({\n type: \"symbol\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _undefined(Class, params) {\n return new Class({\n type: \"undefined\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _null(Class, params) {\n return new Class({\n type: \"null\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _any(Class) {\n return new Class({\n type: \"any\",\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _unknown(Class) {\n return new Class({\n type: \"unknown\",\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _never(Class, params) {\n return new Class({\n type: \"never\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _void(Class, params) {\n return new Class({\n type: \"void\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _date(Class, params) {\n return new Class({\n type: \"date\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _coercedDate(Class, params) {\n return new Class({\n type: \"date\",\n coerce: true,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nan(Class, params) {\n return new Class({\n type: \"nan\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lt(value, params) {\n return new checks.$ZodCheckLessThan({\n check: \"less_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: false,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lte(value, params) {\n return new checks.$ZodCheckLessThan({\n check: \"less_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: true,\n });\n}\nexport { \n/** @deprecated Use `z.lte()` instead. */\n_lte as _max, };\n// @__NO_SIDE_EFFECTS__\nexport function _gt(value, params) {\n return new checks.$ZodCheckGreaterThan({\n check: \"greater_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: false,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _gte(value, params) {\n return new checks.$ZodCheckGreaterThan({\n check: \"greater_than\",\n ...util.normalizeParams(params),\n value,\n inclusive: true,\n });\n}\nexport { \n/** @deprecated Use `z.gte()` instead. */\n_gte as _min, };\n// @__NO_SIDE_EFFECTS__\nexport function _positive(params) {\n return _gt(0, params);\n}\n// negative\n// @__NO_SIDE_EFFECTS__\nexport function _negative(params) {\n return _lt(0, params);\n}\n// nonpositive\n// @__NO_SIDE_EFFECTS__\nexport function _nonpositive(params) {\n return _lte(0, params);\n}\n// nonnegative\n// @__NO_SIDE_EFFECTS__\nexport function _nonnegative(params) {\n return _gte(0, params);\n}\n// @__NO_SIDE_EFFECTS__\nexport function _multipleOf(value, params) {\n return new checks.$ZodCheckMultipleOf({\n check: \"multiple_of\",\n ...util.normalizeParams(params),\n value,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _maxSize(maximum, params) {\n return new checks.$ZodCheckMaxSize({\n check: \"max_size\",\n ...util.normalizeParams(params),\n maximum,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _minSize(minimum, params) {\n return new checks.$ZodCheckMinSize({\n check: \"min_size\",\n ...util.normalizeParams(params),\n minimum,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _size(size, params) {\n return new checks.$ZodCheckSizeEquals({\n check: \"size_equals\",\n ...util.normalizeParams(params),\n size,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _maxLength(maximum, params) {\n const ch = new checks.$ZodCheckMaxLength({\n check: \"max_length\",\n ...util.normalizeParams(params),\n maximum,\n });\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _minLength(minimum, params) {\n return new checks.$ZodCheckMinLength({\n check: \"min_length\",\n ...util.normalizeParams(params),\n minimum,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _length(length, params) {\n return new checks.$ZodCheckLengthEquals({\n check: \"length_equals\",\n ...util.normalizeParams(params),\n length,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _regex(pattern, params) {\n return new checks.$ZodCheckRegex({\n check: \"string_format\",\n format: \"regex\",\n ...util.normalizeParams(params),\n pattern,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lowercase(params) {\n return new checks.$ZodCheckLowerCase({\n check: \"string_format\",\n format: \"lowercase\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _uppercase(params) {\n return new checks.$ZodCheckUpperCase({\n check: \"string_format\",\n format: \"uppercase\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _includes(includes, params) {\n return new checks.$ZodCheckIncludes({\n check: \"string_format\",\n format: \"includes\",\n ...util.normalizeParams(params),\n includes,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _startsWith(prefix, params) {\n return new checks.$ZodCheckStartsWith({\n check: \"string_format\",\n format: \"starts_with\",\n ...util.normalizeParams(params),\n prefix,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _endsWith(suffix, params) {\n return new checks.$ZodCheckEndsWith({\n check: \"string_format\",\n format: \"ends_with\",\n ...util.normalizeParams(params),\n suffix,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _property(property, schema, params) {\n return new checks.$ZodCheckProperty({\n check: \"property\",\n property,\n schema,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _mime(types, params) {\n return new checks.$ZodCheckMimeType({\n check: \"mime_type\",\n mime: types,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _overwrite(tx) {\n return new checks.$ZodCheckOverwrite({\n check: \"overwrite\",\n tx,\n });\n}\n// normalize\n// @__NO_SIDE_EFFECTS__\nexport function _normalize(form) {\n return _overwrite((input) => input.normalize(form));\n}\n// trim\n// @__NO_SIDE_EFFECTS__\nexport function _trim() {\n return _overwrite((input) => input.trim());\n}\n// toLowerCase\n// @__NO_SIDE_EFFECTS__\nexport function _toLowerCase() {\n return _overwrite((input) => input.toLowerCase());\n}\n// toUpperCase\n// @__NO_SIDE_EFFECTS__\nexport function _toUpperCase() {\n return _overwrite((input) => input.toUpperCase());\n}\n// slugify\n// @__NO_SIDE_EFFECTS__\nexport function _slugify() {\n return _overwrite((input) => util.slugify(input));\n}\n// @__NO_SIDE_EFFECTS__\nexport function _array(Class, element, params) {\n return new Class({\n type: \"array\",\n element,\n // get element() {\n // return element;\n // },\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _union(Class, options, params) {\n return new Class({\n type: \"union\",\n options,\n ...util.normalizeParams(params),\n });\n}\nexport function _xor(Class, options, params) {\n return new Class({\n type: \"union\",\n options,\n inclusive: false,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _discriminatedUnion(Class, discriminator, options, params) {\n return new Class({\n type: \"union\",\n options,\n discriminator,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _intersection(Class, left, right) {\n return new Class({\n type: \"intersection\",\n left,\n right,\n });\n}\n// export function _tuple(\n// Class: util.SchemaClass<schemas.$ZodTuple>,\n// items: [],\n// params?: string | $ZodTupleParams\n// ): schemas.$ZodTuple<[], null>;\n// @__NO_SIDE_EFFECTS__\nexport function _tuple(Class, items, _paramsOrRest, _params) {\n const hasRest = _paramsOrRest instanceof schemas.$ZodType;\n const params = hasRest ? _params : _paramsOrRest;\n const rest = hasRest ? _paramsOrRest : null;\n return new Class({\n type: \"tuple\",\n items,\n rest,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _record(Class, keyType, valueType, params) {\n return new Class({\n type: \"record\",\n keyType,\n valueType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _map(Class, keyType, valueType, params) {\n return new Class({\n type: \"map\",\n keyType,\n valueType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _set(Class, valueType, params) {\n return new Class({\n type: \"set\",\n valueType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _enum(Class, values, params) {\n const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values;\n // if (Array.isArray(values)) {\n // for (const value of values) {\n // entries[value] = value;\n // }\n // } else {\n // Object.assign(entries, values);\n // }\n // const entries: util.EnumLike = {};\n // for (const val of values) {\n // entries[val] = val;\n // }\n return new Class({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\n/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.\n *\n * ```ts\n * enum Colors { red, green, blue }\n * z.enum(Colors);\n * ```\n */\nexport function _nativeEnum(Class, entries, params) {\n return new Class({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _literal(Class, value, params) {\n return new Class({\n type: \"literal\",\n values: Array.isArray(value) ? value : [value],\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _file(Class, params) {\n return new Class({\n type: \"file\",\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _transform(Class, fn) {\n return new Class({\n type: \"transform\",\n transform: fn,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _optional(Class, innerType) {\n return new Class({\n type: \"optional\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nullable(Class, innerType) {\n return new Class({\n type: \"nullable\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _default(Class, innerType, defaultValue) {\n return new Class({\n type: \"default\",\n innerType,\n get defaultValue() {\n return typeof defaultValue === \"function\" ? defaultValue() : util.shallowClone(defaultValue);\n },\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _nonoptional(Class, innerType, params) {\n return new Class({\n type: \"nonoptional\",\n innerType,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _success(Class, innerType) {\n return new Class({\n type: \"success\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _catch(Class, innerType, catchValue) {\n return new Class({\n type: \"catch\",\n innerType,\n catchValue: (typeof catchValue === \"function\" ? catchValue : () => catchValue),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _pipe(Class, in_, out) {\n return new Class({\n type: \"pipe\",\n in: in_,\n out,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _readonly(Class, innerType) {\n return new Class({\n type: \"readonly\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _templateLiteral(Class, parts, params) {\n return new Class({\n type: \"template_literal\",\n parts,\n ...util.normalizeParams(params),\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _lazy(Class, getter) {\n return new Class({\n type: \"lazy\",\n getter,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _promise(Class, innerType) {\n return new Class({\n type: \"promise\",\n innerType,\n });\n}\n// @__NO_SIDE_EFFECTS__\nexport function _custom(Class, fn, _params) {\n const norm = util.normalizeParams(_params);\n norm.abort ?? (norm.abort = true); // default to abort:false\n const schema = new Class({\n type: \"custom\",\n check: \"custom\",\n fn: fn,\n ...norm,\n });\n return schema;\n}\n// same as _custom but defaults to abort:false\n// @__NO_SIDE_EFFECTS__\nexport function _refine(Class, fn, _params) {\n const schema = new Class({\n type: \"custom\",\n check: \"custom\",\n fn: fn,\n ...util.normalizeParams(_params),\n });\n return schema;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _superRefine(fn, params) {\n const ch = _check((payload) => {\n payload.addIssue = (issue) => {\n if (typeof issue === \"string\") {\n payload.issues.push(util.issue(issue, payload.value, ch._zod.def));\n }\n else {\n // for Zod 3 backwards compatibility\n const _issue = issue;\n if (_issue.fatal)\n _issue.continue = false;\n _issue.code ?? (_issue.code = \"custom\");\n _issue.input ?? (_issue.input = payload.value);\n _issue.inst ?? (_issue.inst = ch);\n _issue.continue ?? (_issue.continue = !ch._zod.def.abort); // abort is always undefined, so this is always true...\n payload.issues.push(util.issue(_issue));\n }\n };\n return fn(payload.value, payload);\n }, params);\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _check(fn, params) {\n const ch = new checks.$ZodCheck({\n check: \"custom\",\n ...util.normalizeParams(params),\n });\n ch._zod.check = fn;\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function describe(description) {\n const ch = new checks.$ZodCheck({ check: \"describe\" });\n ch._zod.onattach = [\n (inst) => {\n const existing = registries.globalRegistry.get(inst) ?? {};\n registries.globalRegistry.add(inst, { ...existing, description });\n },\n ];\n ch._zod.check = () => { }; // no-op check\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function meta(metadata) {\n const ch = new checks.$ZodCheck({ check: \"meta\" });\n ch._zod.onattach = [\n (inst) => {\n const existing = registries.globalRegistry.get(inst) ?? {};\n registries.globalRegistry.add(inst, { ...existing, ...metadata });\n },\n ];\n ch._zod.check = () => { }; // no-op check\n return ch;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _stringbool(Classes, _params) {\n const params = util.normalizeParams(_params);\n let truthyArray = params.truthy ?? [\"true\", \"1\", \"yes\", \"on\", \"y\", \"enabled\"];\n let falsyArray = params.falsy ?? [\"false\", \"0\", \"no\", \"off\", \"n\", \"disabled\"];\n if (params.case !== \"sensitive\") {\n truthyArray = truthyArray.map((v) => (typeof v === \"string\" ? v.toLowerCase() : v));\n falsyArray = falsyArray.map((v) => (typeof v === \"string\" ? v.toLowerCase() : v));\n }\n const truthySet = new Set(truthyArray);\n const falsySet = new Set(falsyArray);\n const _Codec = Classes.Codec ?? schemas.$ZodCodec;\n const _Boolean = Classes.Boolean ?? schemas.$ZodBoolean;\n const _String = Classes.String ?? schemas.$ZodString;\n const stringSchema = new _String({ type: \"string\", error: params.error });\n const booleanSchema = new _Boolean({ type: \"boolean\", error: params.error });\n const codec = new _Codec({\n type: \"pipe\",\n in: stringSchema,\n out: booleanSchema,\n transform: ((input, payload) => {\n let data = input;\n if (params.case !== \"sensitive\")\n data = data.toLowerCase();\n if (truthySet.has(data)) {\n return true;\n }\n else if (falsySet.has(data)) {\n return false;\n }\n else {\n payload.issues.push({\n code: \"invalid_value\",\n expected: \"stringbool\",\n values: [...truthySet, ...falsySet],\n input: payload.value,\n inst: codec,\n continue: false,\n });\n return {};\n }\n }),\n reverseTransform: ((input, _payload) => {\n if (input === true) {\n return truthyArray[0] || \"true\";\n }\n else {\n return falsyArray[0] || \"false\";\n }\n }),\n error: params.error,\n });\n return codec;\n}\n// @__NO_SIDE_EFFECTS__\nexport function _stringFormat(Class, format, fnOrRegex, _params = {}) {\n const params = util.normalizeParams(_params);\n const def = {\n ...util.normalizeParams(_params),\n check: \"string_format\",\n type: \"string\",\n format,\n fn: typeof fnOrRegex === \"function\" ? fnOrRegex : (val) => fnOrRegex.test(val),\n ...params,\n };\n if (fnOrRegex instanceof RegExp) {\n def.pattern = fnOrRegex;\n }\n const inst = new Class(def);\n return inst;\n}\n","import { globalRegistry } from \"./registries.js\";\n// function initializeContext<T extends schemas.$ZodType>(inputs: JSONSchemaGeneratorParams<T>): ToJSONSchemaContext<T> {\n// return {\n// processor: inputs.processor,\n// metadataRegistry: inputs.metadata ?? globalRegistry,\n// target: inputs.target ?? \"draft-2020-12\",\n// unrepresentable: inputs.unrepresentable ?? \"throw\",\n// };\n// }\nexport function initializeContext(params) {\n // Normalize target: convert old non-hyphenated versions to hyphenated versions\n let target = params?.target ?? \"draft-2020-12\";\n if (target === \"draft-4\")\n target = \"draft-04\";\n if (target === \"draft-7\")\n target = \"draft-07\";\n return {\n processors: params.processors ?? {},\n metadataRegistry: params?.metadata ?? globalRegistry,\n target,\n unrepresentable: params?.unrepresentable ?? \"throw\",\n override: params?.override ?? (() => { }),\n io: params?.io ?? \"output\",\n counter: 0,\n seen: new Map(),\n cycles: params?.cycles ?? \"ref\",\n reused: params?.reused ?? \"inline\",\n external: params?.external ?? undefined,\n };\n}\nexport function process(schema, ctx, _params = { path: [], schemaPath: [] }) {\n var _a;\n const def = schema._zod.def;\n // check for schema in seens\n const seen = ctx.seen.get(schema);\n if (seen) {\n seen.count++;\n // check if cycle\n const isCycle = _params.schemaPath.includes(schema);\n if (isCycle) {\n seen.cycle = _params.path;\n }\n return seen.schema;\n }\n // initialize\n const result = { schema: {}, count: 1, cycle: undefined, path: _params.path };\n ctx.seen.set(schema, result);\n // custom method overrides default behavior\n const overrideSchema = schema._zod.toJSONSchema?.();\n if (overrideSchema) {\n result.schema = overrideSchema;\n }\n else {\n const params = {\n ..._params,\n schemaPath: [..._params.schemaPath, schema],\n path: _params.path,\n };\n if (schema._zod.processJSONSchema) {\n schema._zod.processJSONSchema(ctx, result.schema, params);\n }\n else {\n const _json = result.schema;\n const processor = ctx.processors[def.type];\n if (!processor) {\n throw new Error(`[toJSONSchema]: Non-representable type encountered: ${def.type}`);\n }\n processor(schema, ctx, _json, params);\n }\n const parent = schema._zod.parent;\n if (parent) {\n // Also set ref if processor didn't (for inheritance)\n if (!result.ref)\n result.ref = parent;\n process(parent, ctx, params);\n ctx.seen.get(parent).isParent = true;\n }\n }\n // metadata\n const meta = ctx.metadataRegistry.get(schema);\n if (meta)\n Object.assign(result.schema, meta);\n if (ctx.io === \"input\" && isTransforming(schema)) {\n // examples/defaults only apply to output type of pipe\n delete result.schema.examples;\n delete result.schema.default;\n }\n // set prefault as default\n if (ctx.io === \"input\" && \"_prefault\" in result.schema)\n (_a = result.schema).default ?? (_a.default = result.schema._prefault);\n delete result.schema._prefault;\n // pulling fresh from ctx.seen in case it was overwritten\n const _result = ctx.seen.get(schema);\n return _result.schema;\n}\nexport function extractDefs(ctx, schema\n// params: EmitParams\n) {\n // iterate over seen map;\n const root = ctx.seen.get(schema);\n if (!root)\n throw new Error(\"Unprocessed schema. This is a bug in Zod.\");\n // Track ids to detect duplicates across different schemas\n const idToSchema = new Map();\n for (const entry of ctx.seen.entries()) {\n const id = ctx.metadataRegistry.get(entry[0])?.id;\n if (id) {\n const existing = idToSchema.get(id);\n if (existing && existing !== entry[0]) {\n throw new Error(`Duplicate schema id \"${id}\" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);\n }\n idToSchema.set(id, entry[0]);\n }\n }\n // returns a ref to the schema\n // defId will be empty if the ref points to an external schema (or #)\n const makeURI = (entry) => {\n // comparing the seen objects because sometimes\n // multiple schemas map to the same seen object.\n // e.g. lazy\n // external is configured\n const defsSegment = ctx.target === \"draft-2020-12\" ? \"$defs\" : \"definitions\";\n if (ctx.external) {\n const externalId = ctx.external.registry.get(entry[0])?.id; // ?? \"__shared\";// `__schema${ctx.counter++}`;\n // check if schema is in the external registry\n const uriGenerator = ctx.external.uri ?? ((id) => id);\n if (externalId) {\n return { ref: uriGenerator(externalId) };\n }\n // otherwise, add to __shared\n const id = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;\n entry[1].defId = id; // set defId so it will be reused if needed\n return { defId: id, ref: `${uriGenerator(\"__shared\")}#/${defsSegment}/${id}` };\n }\n if (entry[1] === root) {\n return { ref: \"#\" };\n }\n // self-contained schema\n const uriPrefix = `#`;\n const defUriPrefix = `${uriPrefix}/${defsSegment}/`;\n const defId = entry[1].schema.id ?? `__schema${ctx.counter++}`;\n return { defId, ref: defUriPrefix + defId };\n };\n // stored cached version in `def` property\n // remove all properties, set $ref\n const extractToDef = (entry) => {\n // if the schema is already a reference, do not extract it\n if (entry[1].schema.$ref) {\n return;\n }\n const seen = entry[1];\n const { ref, defId } = makeURI(entry);\n seen.def = { ...seen.schema };\n // defId won't be set if the schema is a reference to an external schema\n // or if the schema is the root schema\n if (defId)\n seen.defId = defId;\n // wipe away all properties except $ref\n const schema = seen.schema;\n for (const key in schema) {\n delete schema[key];\n }\n schema.$ref = ref;\n };\n // throw on cycles\n // break cycles\n if (ctx.cycles === \"throw\") {\n for (const entry of ctx.seen.entries()) {\n const seen = entry[1];\n if (seen.cycle) {\n throw new Error(\"Cycle detected: \" +\n `#/${seen.cycle?.join(\"/\")}/<root>` +\n '\\n\\nSet the `cycles` parameter to `\"ref\"` to resolve cyclical schemas with defs.');\n }\n }\n }\n // extract schemas into $defs\n for (const entry of ctx.seen.entries()) {\n const seen = entry[1];\n // convert root schema to # $ref\n if (schema === entry[0]) {\n extractToDef(entry); // this has special handling for the root schema\n continue;\n }\n // extract schemas that are in the external registry\n if (ctx.external) {\n const ext = ctx.external.registry.get(entry[0])?.id;\n if (schema !== entry[0] && ext) {\n extractToDef(entry);\n continue;\n }\n }\n // extract schemas with `id` meta\n const id = ctx.metadataRegistry.get(entry[0])?.id;\n if (id) {\n extractToDef(entry);\n continue;\n }\n // break cycles\n if (seen.cycle) {\n // any\n extractToDef(entry);\n continue;\n }\n // extract reused schemas\n if (seen.count > 1) {\n if (ctx.reused === \"ref\") {\n extractToDef(entry);\n // biome-ignore lint:\n continue;\n }\n }\n }\n}\nexport function finalize(ctx, schema) {\n const root = ctx.seen.get(schema);\n if (!root)\n throw new Error(\"Unprocessed schema. This is a bug in Zod.\");\n // flatten refs - inherit properties from parent schemas\n const flattenRef = (zodSchema) => {\n const seen = ctx.seen.get(zodSchema);\n // already processed\n if (seen.ref === null)\n return;\n const schema = seen.def ?? seen.schema;\n const _cached = { ...schema };\n const ref = seen.ref;\n seen.ref = null; // prevent infinite recursion\n if (ref) {\n flattenRef(ref);\n const refSeen = ctx.seen.get(ref);\n const refSchema = refSeen.schema;\n // merge referenced schema into current\n if (refSchema.$ref && (ctx.target === \"draft-07\" || ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\")) {\n // older drafts can't combine $ref with other properties\n schema.allOf = schema.allOf ?? [];\n schema.allOf.push(refSchema);\n }\n else {\n Object.assign(schema, refSchema);\n }\n // restore child's own properties (child wins)\n Object.assign(schema, _cached);\n const isParentRef = zodSchema._zod.parent === ref;\n // For parent chain, child is a refinement - remove parent-only properties\n if (isParentRef) {\n for (const key in schema) {\n if (key === \"$ref\" || key === \"allOf\")\n continue;\n if (!(key in _cached)) {\n delete schema[key];\n }\n }\n }\n // When ref was extracted to $defs, remove properties that match the definition\n if (refSchema.$ref && refSeen.def) {\n for (const key in schema) {\n if (key === \"$ref\" || key === \"allOf\")\n continue;\n if (key in refSeen.def && JSON.stringify(schema[key]) === JSON.stringify(refSeen.def[key])) {\n delete schema[key];\n }\n }\n }\n }\n // If parent was extracted (has $ref), propagate $ref to this schema\n // This handles cases like: readonly().meta({id}).describe()\n // where processor sets ref to innerType but parent should be referenced\n const parent = zodSchema._zod.parent;\n if (parent && parent !== ref) {\n // Ensure parent is processed first so its def has inherited properties\n flattenRef(parent);\n const parentSeen = ctx.seen.get(parent);\n if (parentSeen?.schema.$ref) {\n schema.$ref = parentSeen.schema.$ref;\n // De-duplicate with parent's definition\n if (parentSeen.def) {\n for (const key in schema) {\n if (key === \"$ref\" || key === \"allOf\")\n continue;\n if (key in parentSeen.def && JSON.stringify(schema[key]) === JSON.stringify(parentSeen.def[key])) {\n delete schema[key];\n }\n }\n }\n }\n }\n // execute overrides\n ctx.override({\n zodSchema: zodSchema,\n jsonSchema: schema,\n path: seen.path ?? [],\n });\n };\n for (const entry of [...ctx.seen.entries()].reverse()) {\n flattenRef(entry[0]);\n }\n const result = {};\n if (ctx.target === \"draft-2020-12\") {\n result.$schema = \"https://json-schema.org/draft/2020-12/schema\";\n }\n else if (ctx.target === \"draft-07\") {\n result.$schema = \"http://json-schema.org/draft-07/schema#\";\n }\n else if (ctx.target === \"draft-04\") {\n result.$schema = \"http://json-schema.org/draft-04/schema#\";\n }\n else if (ctx.target === \"openapi-3.0\") {\n // OpenAPI 3.0 schema objects should not include a $schema property\n }\n else {\n // Arbitrary string values are allowed but won't have a $schema property set\n }\n if (ctx.external?.uri) {\n const id = ctx.external.registry.get(schema)?.id;\n if (!id)\n throw new Error(\"Schema is missing an `id` property\");\n result.$id = ctx.external.uri(id);\n }\n Object.assign(result, root.def ?? root.schema);\n // The `id` in `.meta()` is a Zod-specific registration tag used to extract\n // schemas into $defs — it is not user-facing JSON Schema metadata. Strip it\n // from the output body where it would otherwise leak. The id is preserved\n // implicitly via the $defs key (and via $ref paths).\n const rootMetaId = ctx.metadataRegistry.get(schema)?.id;\n if (rootMetaId !== undefined && result.id === rootMetaId)\n delete result.id;\n // build defs object\n const defs = ctx.external?.defs ?? {};\n for (const entry of ctx.seen.entries()) {\n const seen = entry[1];\n if (seen.def && seen.defId) {\n if (seen.def.id === seen.defId)\n delete seen.def.id;\n defs[seen.defId] = seen.def;\n }\n }\n // set definitions in result\n if (ctx.external) {\n }\n else {\n if (Object.keys(defs).length > 0) {\n if (ctx.target === \"draft-2020-12\") {\n result.$defs = defs;\n }\n else {\n result.definitions = defs;\n }\n }\n }\n try {\n // this \"finalizes\" this schema and ensures all cycles are removed\n // each call to finalize() is functionally independent\n // though the seen map is shared\n const finalized = JSON.parse(JSON.stringify(result));\n Object.defineProperty(finalized, \"~standard\", {\n value: {\n ...schema[\"~standard\"],\n jsonSchema: {\n input: createStandardJSONSchemaMethod(schema, \"input\", ctx.processors),\n output: createStandardJSONSchemaMethod(schema, \"output\", ctx.processors),\n },\n },\n enumerable: false,\n writable: false,\n });\n return finalized;\n }\n catch (_err) {\n throw new Error(\"Error converting schema to JSON.\");\n }\n}\nfunction isTransforming(_schema, _ctx) {\n const ctx = _ctx ?? { seen: new Set() };\n if (ctx.seen.has(_schema))\n return false;\n ctx.seen.add(_schema);\n const def = _schema._zod.def;\n if (def.type === \"transform\")\n return true;\n if (def.type === \"array\")\n return isTransforming(def.element, ctx);\n if (def.type === \"set\")\n return isTransforming(def.valueType, ctx);\n if (def.type === \"lazy\")\n return isTransforming(def.getter(), ctx);\n if (def.type === \"promise\" ||\n def.type === \"optional\" ||\n def.type === \"nonoptional\" ||\n def.type === \"nullable\" ||\n def.type === \"readonly\" ||\n def.type === \"default\" ||\n def.type === \"prefault\") {\n return isTransforming(def.innerType, ctx);\n }\n if (def.type === \"intersection\") {\n return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);\n }\n if (def.type === \"record\" || def.type === \"map\") {\n return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);\n }\n if (def.type === \"pipe\") {\n if (_schema._zod.traits.has(\"$ZodCodec\"))\n return true;\n return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);\n }\n if (def.type === \"object\") {\n for (const key in def.shape) {\n if (isTransforming(def.shape[key], ctx))\n return true;\n }\n return false;\n }\n if (def.type === \"union\") {\n for (const option of def.options) {\n if (isTransforming(option, ctx))\n return true;\n }\n return false;\n }\n if (def.type === \"tuple\") {\n for (const item of def.items) {\n if (isTransforming(item, ctx))\n return true;\n }\n if (def.rest && isTransforming(def.rest, ctx))\n return true;\n return false;\n }\n return false;\n}\n/**\n * Creates a toJSONSchema method for a schema instance.\n * This encapsulates the logic of initializing context, processing, extracting defs, and finalizing.\n */\nexport const createToJSONSchemaMethod = (schema, processors = {}) => (params) => {\n const ctx = initializeContext({ ...params, processors });\n process(schema, ctx);\n extractDefs(ctx, schema);\n return finalize(ctx, schema);\n};\nexport const createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) => {\n const { libraryOptions, target } = params ?? {};\n const ctx = initializeContext({ ...(libraryOptions ?? {}), target, io, processors });\n process(schema, ctx);\n extractDefs(ctx, schema);\n return finalize(ctx, schema);\n};\n","import { extractDefs, finalize, initializeContext, process, } from \"./to-json-schema.js\";\nimport { getEnumValues } from \"./util.js\";\nconst formatMap = {\n guid: \"uuid\",\n url: \"uri\",\n datetime: \"date-time\",\n json_string: \"json-string\",\n regex: \"\", // do not set\n};\n// ==================== SIMPLE TYPE PROCESSORS ====================\nexport const stringProcessor = (schema, ctx, _json, _params) => {\n const json = _json;\n json.type = \"string\";\n const { minimum, maximum, format, patterns, contentEncoding } = schema._zod\n .bag;\n if (typeof minimum === \"number\")\n json.minLength = minimum;\n if (typeof maximum === \"number\")\n json.maxLength = maximum;\n // custom pattern overrides format\n if (format) {\n json.format = formatMap[format] ?? format;\n if (json.format === \"\")\n delete json.format; // empty format is not valid\n // JSON Schema format: \"time\" requires a full time with offset or Z\n // z.iso.time() does not include timezone information, so format: \"time\" should never be used\n if (format === \"time\") {\n delete json.format;\n }\n }\n if (contentEncoding)\n json.contentEncoding = contentEncoding;\n if (patterns && patterns.size > 0) {\n const regexes = [...patterns];\n if (regexes.length === 1)\n json.pattern = regexes[0].source;\n else if (regexes.length > 1) {\n json.allOf = [\n ...regexes.map((regex) => ({\n ...(ctx.target === \"draft-07\" || ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\"\n ? { type: \"string\" }\n : {}),\n pattern: regex.source,\n })),\n ];\n }\n }\n};\nexport const numberProcessor = (schema, ctx, _json, _params) => {\n const json = _json;\n const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = schema._zod.bag;\n if (typeof format === \"string\" && format.includes(\"int\"))\n json.type = \"integer\";\n else\n json.type = \"number\";\n // when both minimum and exclusiveMinimum exist, pick the more restrictive one\n const exMin = typeof exclusiveMinimum === \"number\" && exclusiveMinimum >= (minimum ?? Number.NEGATIVE_INFINITY);\n const exMax = typeof exclusiveMaximum === \"number\" && exclusiveMaximum <= (maximum ?? Number.POSITIVE_INFINITY);\n const legacy = ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\";\n if (exMin) {\n if (legacy) {\n json.minimum = exclusiveMinimum;\n json.exclusiveMinimum = true;\n }\n else {\n json.exclusiveMinimum = exclusiveMinimum;\n }\n }\n else if (typeof minimum === \"number\") {\n json.minimum = minimum;\n }\n if (exMax) {\n if (legacy) {\n json.maximum = exclusiveMaximum;\n json.exclusiveMaximum = true;\n }\n else {\n json.exclusiveMaximum = exclusiveMaximum;\n }\n }\n else if (typeof maximum === \"number\") {\n json.maximum = maximum;\n }\n if (typeof multipleOf === \"number\")\n json.multipleOf = multipleOf;\n};\nexport const booleanProcessor = (_schema, _ctx, json, _params) => {\n json.type = \"boolean\";\n};\nexport const bigintProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"BigInt cannot be represented in JSON Schema\");\n }\n};\nexport const symbolProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Symbols cannot be represented in JSON Schema\");\n }\n};\nexport const nullProcessor = (_schema, ctx, json, _params) => {\n if (ctx.target === \"openapi-3.0\") {\n json.type = \"string\";\n json.nullable = true;\n json.enum = [null];\n }\n else {\n json.type = \"null\";\n }\n};\nexport const undefinedProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Undefined cannot be represented in JSON Schema\");\n }\n};\nexport const voidProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Void cannot be represented in JSON Schema\");\n }\n};\nexport const neverProcessor = (_schema, _ctx, json, _params) => {\n json.not = {};\n};\nexport const anyProcessor = (_schema, _ctx, _json, _params) => {\n // empty schema accepts anything\n};\nexport const unknownProcessor = (_schema, _ctx, _json, _params) => {\n // empty schema accepts anything\n};\nexport const dateProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Date cannot be represented in JSON Schema\");\n }\n};\nexport const enumProcessor = (schema, _ctx, json, _params) => {\n const def = schema._zod.def;\n const values = getEnumValues(def.entries);\n // Number enums can have both string and number values\n if (values.every((v) => typeof v === \"number\"))\n json.type = \"number\";\n if (values.every((v) => typeof v === \"string\"))\n json.type = \"string\";\n json.enum = values;\n};\nexport const literalProcessor = (schema, ctx, json, _params) => {\n const def = schema._zod.def;\n const vals = [];\n for (const val of def.values) {\n if (val === undefined) {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Literal `undefined` cannot be represented in JSON Schema\");\n }\n else {\n // do not add to vals\n }\n }\n else if (typeof val === \"bigint\") {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"BigInt literals cannot be represented in JSON Schema\");\n }\n else {\n vals.push(Number(val));\n }\n }\n else {\n vals.push(val);\n }\n }\n if (vals.length === 0) {\n // do nothing (an undefined literal was stripped)\n }\n else if (vals.length === 1) {\n const val = vals[0];\n json.type = val === null ? \"null\" : typeof val;\n if (ctx.target === \"draft-04\" || ctx.target === \"openapi-3.0\") {\n json.enum = [val];\n }\n else {\n json.const = val;\n }\n }\n else {\n if (vals.every((v) => typeof v === \"number\"))\n json.type = \"number\";\n if (vals.every((v) => typeof v === \"string\"))\n json.type = \"string\";\n if (vals.every((v) => typeof v === \"boolean\"))\n json.type = \"boolean\";\n if (vals.every((v) => v === null))\n json.type = \"null\";\n json.enum = vals;\n }\n};\nexport const nanProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"NaN cannot be represented in JSON Schema\");\n }\n};\nexport const templateLiteralProcessor = (schema, _ctx, json, _params) => {\n const _json = json;\n const pattern = schema._zod.pattern;\n if (!pattern)\n throw new Error(\"Pattern not found in template literal\");\n _json.type = \"string\";\n _json.pattern = pattern.source;\n};\nexport const fileProcessor = (schema, _ctx, json, _params) => {\n const _json = json;\n const file = {\n type: \"string\",\n format: \"binary\",\n contentEncoding: \"binary\",\n };\n const { minimum, maximum, mime } = schema._zod.bag;\n if (minimum !== undefined)\n file.minLength = minimum;\n if (maximum !== undefined)\n file.maxLength = maximum;\n if (mime) {\n if (mime.length === 1) {\n file.contentMediaType = mime[0];\n Object.assign(_json, file);\n }\n else {\n Object.assign(_json, file); // shared props at root\n _json.anyOf = mime.map((m) => ({ contentMediaType: m })); // only contentMediaType differs\n }\n }\n else {\n Object.assign(_json, file);\n }\n};\nexport const successProcessor = (_schema, _ctx, json, _params) => {\n json.type = \"boolean\";\n};\nexport const customProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Custom types cannot be represented in JSON Schema\");\n }\n};\nexport const functionProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Function types cannot be represented in JSON Schema\");\n }\n};\nexport const transformProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Transforms cannot be represented in JSON Schema\");\n }\n};\nexport const mapProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Map cannot be represented in JSON Schema\");\n }\n};\nexport const setProcessor = (_schema, ctx, _json, _params) => {\n if (ctx.unrepresentable === \"throw\") {\n throw new Error(\"Set cannot be represented in JSON Schema\");\n }\n};\n// ==================== COMPOSITE TYPE PROCESSORS ====================\nexport const arrayProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n const { minimum, maximum } = schema._zod.bag;\n if (typeof minimum === \"number\")\n json.minItems = minimum;\n if (typeof maximum === \"number\")\n json.maxItems = maximum;\n json.type = \"array\";\n json.items = process(def.element, ctx, {\n ...params,\n path: [...params.path, \"items\"],\n });\n};\nexport const objectProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n json.type = \"object\";\n json.properties = {};\n const shape = def.shape;\n for (const key in shape) {\n json.properties[key] = process(shape[key], ctx, {\n ...params,\n path: [...params.path, \"properties\", key],\n });\n }\n // required keys\n const allKeys = new Set(Object.keys(shape));\n const requiredKeys = new Set([...allKeys].filter((key) => {\n const v = def.shape[key]._zod;\n if (ctx.io === \"input\") {\n return v.optin === undefined;\n }\n else {\n return v.optout === undefined;\n }\n }));\n if (requiredKeys.size > 0) {\n json.required = Array.from(requiredKeys);\n }\n // catchall\n if (def.catchall?._zod.def.type === \"never\") {\n // strict\n json.additionalProperties = false;\n }\n else if (!def.catchall) {\n // regular\n if (ctx.io === \"output\")\n json.additionalProperties = false;\n }\n else if (def.catchall) {\n json.additionalProperties = process(def.catchall, ctx, {\n ...params,\n path: [...params.path, \"additionalProperties\"],\n });\n }\n};\nexport const unionProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n // Exclusive unions (inclusive === false) use oneOf (exactly one match) instead of anyOf (one or more matches)\n // This includes both z.xor() and discriminated unions\n const isExclusive = def.inclusive === false;\n const options = def.options.map((x, i) => process(x, ctx, {\n ...params,\n path: [...params.path, isExclusive ? \"oneOf\" : \"anyOf\", i],\n }));\n if (isExclusive) {\n json.oneOf = options;\n }\n else {\n json.anyOf = options;\n }\n};\nexport const intersectionProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n const a = process(def.left, ctx, {\n ...params,\n path: [...params.path, \"allOf\", 0],\n });\n const b = process(def.right, ctx, {\n ...params,\n path: [...params.path, \"allOf\", 1],\n });\n const isSimpleIntersection = (val) => \"allOf\" in val && Object.keys(val).length === 1;\n const allOf = [\n ...(isSimpleIntersection(a) ? a.allOf : [a]),\n ...(isSimpleIntersection(b) ? b.allOf : [b]),\n ];\n json.allOf = allOf;\n};\nexport const tupleProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n json.type = \"array\";\n const prefixPath = ctx.target === \"draft-2020-12\" ? \"prefixItems\" : \"items\";\n const restPath = ctx.target === \"draft-2020-12\" ? \"items\" : ctx.target === \"openapi-3.0\" ? \"items\" : \"additionalItems\";\n const prefixItems = def.items.map((x, i) => process(x, ctx, {\n ...params,\n path: [...params.path, prefixPath, i],\n }));\n const rest = def.rest\n ? process(def.rest, ctx, {\n ...params,\n path: [...params.path, restPath, ...(ctx.target === \"openapi-3.0\" ? [def.items.length] : [])],\n })\n : null;\n if (ctx.target === \"draft-2020-12\") {\n json.prefixItems = prefixItems;\n if (rest) {\n json.items = rest;\n }\n }\n else if (ctx.target === \"openapi-3.0\") {\n json.items = {\n anyOf: prefixItems,\n };\n if (rest) {\n json.items.anyOf.push(rest);\n }\n json.minItems = prefixItems.length;\n if (!rest) {\n json.maxItems = prefixItems.length;\n }\n }\n else {\n json.items = prefixItems;\n if (rest) {\n json.additionalItems = rest;\n }\n }\n // length\n const { minimum, maximum } = schema._zod.bag;\n if (typeof minimum === \"number\")\n json.minItems = minimum;\n if (typeof maximum === \"number\")\n json.maxItems = maximum;\n};\nexport const recordProcessor = (schema, ctx, _json, params) => {\n const json = _json;\n const def = schema._zod.def;\n json.type = \"object\";\n // For looseRecord with regex patterns, use patternProperties\n // This correctly represents \"only validate keys matching the pattern\" semantics\n // and composes well with allOf (intersections)\n const keyType = def.keyType;\n const keyBag = keyType._zod.bag;\n const patterns = keyBag?.patterns;\n if (def.mode === \"loose\" && patterns && patterns.size > 0) {\n // Use patternProperties for looseRecord with regex patterns\n const valueSchema = process(def.valueType, ctx, {\n ...params,\n path: [...params.path, \"patternProperties\", \"*\"],\n });\n json.patternProperties = {};\n for (const pattern of patterns) {\n json.patternProperties[pattern.source] = valueSchema;\n }\n }\n else {\n // Default behavior: use propertyNames + additionalProperties\n if (ctx.target === \"draft-07\" || ctx.target === \"draft-2020-12\") {\n json.propertyNames = process(def.keyType, ctx, {\n ...params,\n path: [...params.path, \"propertyNames\"],\n });\n }\n json.additionalProperties = process(def.valueType, ctx, {\n ...params,\n path: [...params.path, \"additionalProperties\"],\n });\n }\n // Add required for keys with discrete values (enum, literal, etc.)\n const keyValues = keyType._zod.values;\n if (keyValues) {\n const validKeyValues = [...keyValues].filter((v) => typeof v === \"string\" || typeof v === \"number\");\n if (validKeyValues.length > 0) {\n json.required = validKeyValues;\n }\n }\n};\nexport const nullableProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n const inner = process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n if (ctx.target === \"openapi-3.0\") {\n seen.ref = def.innerType;\n json.nullable = true;\n }\n else {\n json.anyOf = [inner, { type: \"null\" }];\n }\n};\nexport const nonoptionalProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n};\nexport const defaultProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n json.default = JSON.parse(JSON.stringify(def.defaultValue));\n};\nexport const prefaultProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n if (ctx.io === \"input\")\n json._prefault = JSON.parse(JSON.stringify(def.defaultValue));\n};\nexport const catchProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n let catchValue;\n try {\n catchValue = def.catchValue(undefined);\n }\n catch {\n throw new Error(\"Dynamic catch values are not supported in JSON Schema\");\n }\n json.default = catchValue;\n};\nexport const pipeProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n const inIsTransform = def.in._zod.traits.has(\"$ZodTransform\");\n const innerType = ctx.io === \"input\" ? (inIsTransform ? def.out : def.in) : def.out;\n process(innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = innerType;\n};\nexport const readonlyProcessor = (schema, ctx, json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n json.readOnly = true;\n};\nexport const promiseProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n};\nexport const optionalProcessor = (schema, ctx, _json, params) => {\n const def = schema._zod.def;\n process(def.innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = def.innerType;\n};\nexport const lazyProcessor = (schema, ctx, _json, params) => {\n const innerType = schema._zod.innerType;\n process(innerType, ctx, params);\n const seen = ctx.seen.get(schema);\n seen.ref = innerType;\n};\n// ==================== ALL PROCESSORS ====================\nexport const allProcessors = {\n string: stringProcessor,\n number: numberProcessor,\n boolean: booleanProcessor,\n bigint: bigintProcessor,\n symbol: symbolProcessor,\n null: nullProcessor,\n undefined: undefinedProcessor,\n void: voidProcessor,\n never: neverProcessor,\n any: anyProcessor,\n unknown: unknownProcessor,\n date: dateProcessor,\n enum: enumProcessor,\n literal: literalProcessor,\n nan: nanProcessor,\n template_literal: templateLiteralProcessor,\n file: fileProcessor,\n success: successProcessor,\n custom: customProcessor,\n function: functionProcessor,\n transform: transformProcessor,\n map: mapProcessor,\n set: setProcessor,\n array: arrayProcessor,\n object: objectProcessor,\n union: unionProcessor,\n intersection: intersectionProcessor,\n tuple: tupleProcessor,\n record: recordProcessor,\n nullable: nullableProcessor,\n nonoptional: nonoptionalProcessor,\n default: defaultProcessor,\n prefault: prefaultProcessor,\n catch: catchProcessor,\n pipe: pipeProcessor,\n readonly: readonlyProcessor,\n promise: promiseProcessor,\n optional: optionalProcessor,\n lazy: lazyProcessor,\n};\nexport function toJSONSchema(input, params) {\n if (\"_idmap\" in input) {\n // Registry case\n const registry = input;\n const ctx = initializeContext({ ...params, processors: allProcessors });\n const defs = {};\n // First pass: process all schemas to build the seen map\n for (const entry of registry._idmap.entries()) {\n const [_, schema] = entry;\n process(schema, ctx);\n }\n const schemas = {};\n const external = {\n registry,\n uri: params?.uri,\n defs,\n };\n // Update the context with external configuration\n ctx.external = external;\n // Second pass: emit each schema\n for (const entry of registry._idmap.entries()) {\n const [key, schema] = entry;\n extractDefs(ctx, schema);\n schemas[key] = finalize(ctx, schema);\n }\n if (Object.keys(defs).length > 0) {\n const defsSegment = ctx.target === \"draft-2020-12\" ? \"$defs\" : \"definitions\";\n schemas.__shared = {\n [defsSegment]: defs,\n };\n }\n return { schemas };\n }\n // Single schema case\n const ctx = initializeContext({ ...params, processors: allProcessors });\n process(input, ctx);\n extractDefs(ctx, input);\n return finalize(ctx, input);\n}\n","import * as core from \"../core/index.js\";\nimport * as schemas from \"./schemas.js\";\nexport const ZodISODateTime = /*@__PURE__*/ core.$constructor(\"ZodISODateTime\", (inst, def) => {\n core.$ZodISODateTime.init(inst, def);\n schemas.ZodStringFormat.init(inst, def);\n});\nexport function datetime(params) {\n return core._isoDateTime(ZodISODateTime, params);\n}\nexport const ZodISODate = /*@__PURE__*/ core.$constructor(\"ZodISODate\", (inst, def) => {\n core.$ZodISODate.init(inst, def);\n schemas.ZodStringFormat.init(inst, def);\n});\nexport function date(params) {\n return core._isoDate(ZodISODate, params);\n}\nexport const ZodISOTime = /*@__PURE__*/ core.$constructor(\"ZodISOTime\", (inst, def) => {\n core.$ZodISOTime.init(inst, def);\n schemas.ZodStringFormat.init(inst, def);\n});\nexport function time(params) {\n return core._isoTime(ZodISOTime, params);\n}\nexport const ZodISODuration = /*@__PURE__*/ core.$constructor(\"ZodISODuration\", (inst, def) => {\n core.$ZodISODuration.init(inst, def);\n schemas.ZodStringFormat.init(inst, def);\n});\nexport function duration(params) {\n return core._isoDuration(ZodISODuration, params);\n}\n","import * as core from \"../core/index.js\";\nimport { $ZodError } from \"../core/index.js\";\nimport * as util from \"../core/util.js\";\nconst initializer = (inst, issues) => {\n $ZodError.init(inst, issues);\n inst.name = \"ZodError\";\n Object.defineProperties(inst, {\n format: {\n value: (mapper) => core.formatError(inst, mapper),\n // enumerable: false,\n },\n flatten: {\n value: (mapper) => core.flattenError(inst, mapper),\n // enumerable: false,\n },\n addIssue: {\n value: (issue) => {\n inst.issues.push(issue);\n inst.message = JSON.stringify(inst.issues, util.jsonStringifyReplacer, 2);\n },\n // enumerable: false,\n },\n addIssues: {\n value: (issues) => {\n inst.issues.push(...issues);\n inst.message = JSON.stringify(inst.issues, util.jsonStringifyReplacer, 2);\n },\n // enumerable: false,\n },\n isEmpty: {\n get() {\n return inst.issues.length === 0;\n },\n // enumerable: false,\n },\n });\n // Object.defineProperty(inst, \"isEmpty\", {\n // get() {\n // return inst.issues.length === 0;\n // },\n // });\n};\nexport const ZodError = /*@__PURE__*/ core.$constructor(\"ZodError\", initializer);\nexport const ZodRealError = /*@__PURE__*/ core.$constructor(\"ZodError\", initializer, {\n Parent: Error,\n});\n// /** @deprecated Use `z.core.$ZodErrorMapCtx` instead. */\n// export type ErrorMapCtx = core.$ZodErrorMapCtx;\n","import * as core from \"../core/index.js\";\nimport { ZodRealError } from \"./errors.js\";\nexport const parse = /* @__PURE__ */ core._parse(ZodRealError);\nexport const parseAsync = /* @__PURE__ */ core._parseAsync(ZodRealError);\nexport const safeParse = /* @__PURE__ */ core._safeParse(ZodRealError);\nexport const safeParseAsync = /* @__PURE__ */ core._safeParseAsync(ZodRealError);\n// Codec functions\nexport const encode = /* @__PURE__ */ core._encode(ZodRealError);\nexport const decode = /* @__PURE__ */ core._decode(ZodRealError);\nexport const encodeAsync = /* @__PURE__ */ core._encodeAsync(ZodRealError);\nexport const decodeAsync = /* @__PURE__ */ core._decodeAsync(ZodRealError);\nexport const safeEncode = /* @__PURE__ */ core._safeEncode(ZodRealError);\nexport const safeDecode = /* @__PURE__ */ core._safeDecode(ZodRealError);\nexport const safeEncodeAsync = /* @__PURE__ */ core._safeEncodeAsync(ZodRealError);\nexport const safeDecodeAsync = /* @__PURE__ */ core._safeDecodeAsync(ZodRealError);\n","import * as core from \"../core/index.js\";\nimport { util } from \"../core/index.js\";\nimport * as processors from \"../core/json-schema-processors.js\";\nimport { createStandardJSONSchemaMethod, createToJSONSchemaMethod } from \"../core/to-json-schema.js\";\nimport * as checks from \"./checks.js\";\nimport * as iso from \"./iso.js\";\nimport * as parse from \"./parse.js\";\n// Lazy-bind builder methods.\n//\n// Builder methods (`.optional`, `.array`, `.refine`, ...) live as\n// non-enumerable getters on each concrete schema constructor's\n// prototype. On first access from an instance the getter allocates\n// `fn.bind(this)` and caches it as an own property on that instance,\n// so detached usage (`const m = schema.optional; m()`) still works\n// and the per-instance allocation only happens for methods actually\n// touched.\n//\n// One install per (prototype, group), memoized by `_installedGroups`.\nconst _installedGroups = /* @__PURE__ */ new WeakMap();\nfunction _installLazyMethods(inst, group, methods) {\n const proto = Object.getPrototypeOf(inst);\n let installed = _installedGroups.get(proto);\n if (!installed) {\n installed = new Set();\n _installedGroups.set(proto, installed);\n }\n if (installed.has(group))\n return;\n installed.add(group);\n for (const key in methods) {\n const fn = methods[key];\n Object.defineProperty(proto, key, {\n configurable: true,\n enumerable: false,\n get() {\n const bound = fn.bind(this);\n Object.defineProperty(this, key, {\n configurable: true,\n writable: true,\n enumerable: true,\n value: bound,\n });\n return bound;\n },\n set(v) {\n Object.defineProperty(this, key, {\n configurable: true,\n writable: true,\n enumerable: true,\n value: v,\n });\n },\n });\n }\n}\nexport const ZodType = /*@__PURE__*/ core.$constructor(\"ZodType\", (inst, def) => {\n core.$ZodType.init(inst, def);\n Object.assign(inst[\"~standard\"], {\n jsonSchema: {\n input: createStandardJSONSchemaMethod(inst, \"input\"),\n output: createStandardJSONSchemaMethod(inst, \"output\"),\n },\n });\n inst.toJSONSchema = createToJSONSchemaMethod(inst, {});\n inst.def = def;\n inst.type = def.type;\n Object.defineProperty(inst, \"_def\", { value: def });\n // Parse-family is intentionally kept as per-instance closures: these are\n // the hot path AND the most-detached methods (`arr.map(schema.parse)`,\n // `const { parse } = schema`, etc.). Eager closures here mean callers pay\n // ~12 closure allocations per schema but get monomorphic call sites and\n // detached usage that \"just works\".\n inst.parse = (data, params) => parse.parse(inst, data, params, { callee: inst.parse });\n inst.safeParse = (data, params) => parse.safeParse(inst, data, params);\n inst.parseAsync = async (data, params) => parse.parseAsync(inst, data, params, { callee: inst.parseAsync });\n inst.safeParseAsync = async (data, params) => parse.safeParseAsync(inst, data, params);\n inst.spa = inst.safeParseAsync;\n inst.encode = (data, params) => parse.encode(inst, data, params);\n inst.decode = (data, params) => parse.decode(inst, data, params);\n inst.encodeAsync = async (data, params) => parse.encodeAsync(inst, data, params);\n inst.decodeAsync = async (data, params) => parse.decodeAsync(inst, data, params);\n inst.safeEncode = (data, params) => parse.safeEncode(inst, data, params);\n inst.safeDecode = (data, params) => parse.safeDecode(inst, data, params);\n inst.safeEncodeAsync = async (data, params) => parse.safeEncodeAsync(inst, data, params);\n inst.safeDecodeAsync = async (data, params) => parse.safeDecodeAsync(inst, data, params);\n // All builder methods are placed on the internal prototype as lazy-bind\n // getters. On first access per-instance, a bound thunk is allocated and\n // cached as an own property; subsequent accesses skip the getter. This\n // means: no per-instance allocation for unused methods, full\n // detachability preserved (`const m = schema.optional; m()` works), and\n // shared underlying function references across all instances.\n _installLazyMethods(inst, \"ZodType\", {\n check(...chks) {\n const def = this.def;\n return this.clone(util.mergeDefs(def, {\n checks: [\n ...(def.checks ?? []),\n ...chks.map((ch) => typeof ch === \"function\" ? { _zod: { check: ch, def: { check: \"custom\" }, onattach: [] } } : ch),\n ],\n }), { parent: true });\n },\n with(...chks) {\n return this.check(...chks);\n },\n clone(def, params) {\n return core.clone(this, def, params);\n },\n brand() {\n return this;\n },\n register(reg, meta) {\n reg.add(this, meta);\n return this;\n },\n refine(check, params) {\n return this.check(refine(check, params));\n },\n superRefine(refinement, params) {\n return this.check(superRefine(refinement, params));\n },\n overwrite(fn) {\n return this.check(checks.overwrite(fn));\n },\n optional() {\n return optional(this);\n },\n exactOptional() {\n return exactOptional(this);\n },\n nullable() {\n return nullable(this);\n },\n nullish() {\n return optional(nullable(this));\n },\n nonoptional(params) {\n return nonoptional(this, params);\n },\n array() {\n return array(this);\n },\n or(arg) {\n return union([this, arg]);\n },\n and(arg) {\n return intersection(this, arg);\n },\n transform(tx) {\n return pipe(this, transform(tx));\n },\n default(d) {\n return _default(this, d);\n },\n prefault(d) {\n return prefault(this, d);\n },\n catch(params) {\n return _catch(this, params);\n },\n pipe(target) {\n return pipe(this, target);\n },\n readonly() {\n return readonly(this);\n },\n describe(description) {\n const cl = this.clone();\n core.globalRegistry.add(cl, { description });\n return cl;\n },\n meta(...args) {\n // overloaded: meta() returns the registered metadata, meta(data)\n // returns a clone with `data` registered. The mapped type picks\n // up the second overload, so we accept variadic any-args and\n // return `any` to satisfy both at runtime.\n if (args.length === 0)\n return core.globalRegistry.get(this);\n const cl = this.clone();\n core.globalRegistry.add(cl, args[0]);\n return cl;\n },\n isOptional() {\n return this.safeParse(undefined).success;\n },\n isNullable() {\n return this.safeParse(null).success;\n },\n apply(fn) {\n return fn(this);\n },\n });\n Object.defineProperty(inst, \"description\", {\n get() {\n return core.globalRegistry.get(inst)?.description;\n },\n configurable: true,\n });\n return inst;\n});\n/** @internal */\nexport const _ZodString = /*@__PURE__*/ core.$constructor(\"_ZodString\", (inst, def) => {\n core.$ZodString.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.stringProcessor(inst, ctx, json, params);\n const bag = inst._zod.bag;\n inst.format = bag.format ?? null;\n inst.minLength = bag.minimum ?? null;\n inst.maxLength = bag.maximum ?? null;\n _installLazyMethods(inst, \"_ZodString\", {\n regex(...args) {\n return this.check(checks.regex(...args));\n },\n includes(...args) {\n return this.check(checks.includes(...args));\n },\n startsWith(...args) {\n return this.check(checks.startsWith(...args));\n },\n endsWith(...args) {\n return this.check(checks.endsWith(...args));\n },\n min(...args) {\n return this.check(checks.minLength(...args));\n },\n max(...args) {\n return this.check(checks.maxLength(...args));\n },\n length(...args) {\n return this.check(checks.length(...args));\n },\n nonempty(...args) {\n return this.check(checks.minLength(1, ...args));\n },\n lowercase(params) {\n return this.check(checks.lowercase(params));\n },\n uppercase(params) {\n return this.check(checks.uppercase(params));\n },\n trim() {\n return this.check(checks.trim());\n },\n normalize(...args) {\n return this.check(checks.normalize(...args));\n },\n toLowerCase() {\n return this.check(checks.toLowerCase());\n },\n toUpperCase() {\n return this.check(checks.toUpperCase());\n },\n slugify() {\n return this.check(checks.slugify());\n },\n });\n});\nexport const ZodString = /*@__PURE__*/ core.$constructor(\"ZodString\", (inst, def) => {\n core.$ZodString.init(inst, def);\n _ZodString.init(inst, def);\n inst.email = (params) => inst.check(core._email(ZodEmail, params));\n inst.url = (params) => inst.check(core._url(ZodURL, params));\n inst.jwt = (params) => inst.check(core._jwt(ZodJWT, params));\n inst.emoji = (params) => inst.check(core._emoji(ZodEmoji, params));\n inst.guid = (params) => inst.check(core._guid(ZodGUID, params));\n inst.uuid = (params) => inst.check(core._uuid(ZodUUID, params));\n inst.uuidv4 = (params) => inst.check(core._uuidv4(ZodUUID, params));\n inst.uuidv6 = (params) => inst.check(core._uuidv6(ZodUUID, params));\n inst.uuidv7 = (params) => inst.check(core._uuidv7(ZodUUID, params));\n inst.nanoid = (params) => inst.check(core._nanoid(ZodNanoID, params));\n inst.guid = (params) => inst.check(core._guid(ZodGUID, params));\n inst.cuid = (params) => inst.check(core._cuid(ZodCUID, params));\n inst.cuid2 = (params) => inst.check(core._cuid2(ZodCUID2, params));\n inst.ulid = (params) => inst.check(core._ulid(ZodULID, params));\n inst.base64 = (params) => inst.check(core._base64(ZodBase64, params));\n inst.base64url = (params) => inst.check(core._base64url(ZodBase64URL, params));\n inst.xid = (params) => inst.check(core._xid(ZodXID, params));\n inst.ksuid = (params) => inst.check(core._ksuid(ZodKSUID, params));\n inst.ipv4 = (params) => inst.check(core._ipv4(ZodIPv4, params));\n inst.ipv6 = (params) => inst.check(core._ipv6(ZodIPv6, params));\n inst.cidrv4 = (params) => inst.check(core._cidrv4(ZodCIDRv4, params));\n inst.cidrv6 = (params) => inst.check(core._cidrv6(ZodCIDRv6, params));\n inst.e164 = (params) => inst.check(core._e164(ZodE164, params));\n // iso\n inst.datetime = (params) => inst.check(iso.datetime(params));\n inst.date = (params) => inst.check(iso.date(params));\n inst.time = (params) => inst.check(iso.time(params));\n inst.duration = (params) => inst.check(iso.duration(params));\n});\nexport function string(params) {\n return core._string(ZodString, params);\n}\nexport const ZodStringFormat = /*@__PURE__*/ core.$constructor(\"ZodStringFormat\", (inst, def) => {\n core.$ZodStringFormat.init(inst, def);\n _ZodString.init(inst, def);\n});\nexport const ZodEmail = /*@__PURE__*/ core.$constructor(\"ZodEmail\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodEmail.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function email(params) {\n return core._email(ZodEmail, params);\n}\nexport const ZodGUID = /*@__PURE__*/ core.$constructor(\"ZodGUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodGUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function guid(params) {\n return core._guid(ZodGUID, params);\n}\nexport const ZodUUID = /*@__PURE__*/ core.$constructor(\"ZodUUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodUUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function uuid(params) {\n return core._uuid(ZodUUID, params);\n}\nexport function uuidv4(params) {\n return core._uuidv4(ZodUUID, params);\n}\n// ZodUUIDv6\nexport function uuidv6(params) {\n return core._uuidv6(ZodUUID, params);\n}\n// ZodUUIDv7\nexport function uuidv7(params) {\n return core._uuidv7(ZodUUID, params);\n}\nexport const ZodURL = /*@__PURE__*/ core.$constructor(\"ZodURL\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodURL.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function url(params) {\n return core._url(ZodURL, params);\n}\nexport function httpUrl(params) {\n return core._url(ZodURL, {\n protocol: core.regexes.httpProtocol,\n hostname: core.regexes.domain,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodEmoji = /*@__PURE__*/ core.$constructor(\"ZodEmoji\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodEmoji.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function emoji(params) {\n return core._emoji(ZodEmoji, params);\n}\nexport const ZodNanoID = /*@__PURE__*/ core.$constructor(\"ZodNanoID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodNanoID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function nanoid(params) {\n return core._nanoid(ZodNanoID, params);\n}\n/**\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link ZodCUID2} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport const ZodCUID = /*@__PURE__*/ core.$constructor(\"ZodCUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodCUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\n/**\n * Validates a CUID v1 string.\n *\n * @deprecated CUID v1 is deprecated by its authors due to information leakage\n * (timestamps embedded in the id). Use {@link cuid2 | `z.cuid2()`} instead.\n * See https://github.com/paralleldrive/cuid.\n */\nexport function cuid(params) {\n return core._cuid(ZodCUID, params);\n}\nexport const ZodCUID2 = /*@__PURE__*/ core.$constructor(\"ZodCUID2\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodCUID2.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function cuid2(params) {\n return core._cuid2(ZodCUID2, params);\n}\nexport const ZodULID = /*@__PURE__*/ core.$constructor(\"ZodULID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodULID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ulid(params) {\n return core._ulid(ZodULID, params);\n}\nexport const ZodXID = /*@__PURE__*/ core.$constructor(\"ZodXID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodXID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function xid(params) {\n return core._xid(ZodXID, params);\n}\nexport const ZodKSUID = /*@__PURE__*/ core.$constructor(\"ZodKSUID\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodKSUID.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ksuid(params) {\n return core._ksuid(ZodKSUID, params);\n}\nexport const ZodIPv4 = /*@__PURE__*/ core.$constructor(\"ZodIPv4\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodIPv4.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ipv4(params) {\n return core._ipv4(ZodIPv4, params);\n}\nexport const ZodMAC = /*@__PURE__*/ core.$constructor(\"ZodMAC\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodMAC.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function mac(params) {\n return core._mac(ZodMAC, params);\n}\nexport const ZodIPv6 = /*@__PURE__*/ core.$constructor(\"ZodIPv6\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodIPv6.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function ipv6(params) {\n return core._ipv6(ZodIPv6, params);\n}\nexport const ZodCIDRv4 = /*@__PURE__*/ core.$constructor(\"ZodCIDRv4\", (inst, def) => {\n core.$ZodCIDRv4.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function cidrv4(params) {\n return core._cidrv4(ZodCIDRv4, params);\n}\nexport const ZodCIDRv6 = /*@__PURE__*/ core.$constructor(\"ZodCIDRv6\", (inst, def) => {\n core.$ZodCIDRv6.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function cidrv6(params) {\n return core._cidrv6(ZodCIDRv6, params);\n}\nexport const ZodBase64 = /*@__PURE__*/ core.$constructor(\"ZodBase64\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodBase64.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function base64(params) {\n return core._base64(ZodBase64, params);\n}\nexport const ZodBase64URL = /*@__PURE__*/ core.$constructor(\"ZodBase64URL\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodBase64URL.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function base64url(params) {\n return core._base64url(ZodBase64URL, params);\n}\nexport const ZodE164 = /*@__PURE__*/ core.$constructor(\"ZodE164\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodE164.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function e164(params) {\n return core._e164(ZodE164, params);\n}\nexport const ZodJWT = /*@__PURE__*/ core.$constructor(\"ZodJWT\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodJWT.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function jwt(params) {\n return core._jwt(ZodJWT, params);\n}\nexport const ZodCustomStringFormat = /*@__PURE__*/ core.$constructor(\"ZodCustomStringFormat\", (inst, def) => {\n // ZodStringFormat.init(inst, def);\n core.$ZodCustomStringFormat.init(inst, def);\n ZodStringFormat.init(inst, def);\n});\nexport function stringFormat(format, fnOrRegex, _params = {}) {\n return core._stringFormat(ZodCustomStringFormat, format, fnOrRegex, _params);\n}\nexport function hostname(_params) {\n return core._stringFormat(ZodCustomStringFormat, \"hostname\", core.regexes.hostname, _params);\n}\nexport function hex(_params) {\n return core._stringFormat(ZodCustomStringFormat, \"hex\", core.regexes.hex, _params);\n}\nexport function hash(alg, params) {\n const enc = params?.enc ?? \"hex\";\n const format = `${alg}_${enc}`;\n const regex = core.regexes[format];\n if (!regex)\n throw new Error(`Unrecognized hash format: ${format}`);\n return core._stringFormat(ZodCustomStringFormat, format, regex, params);\n}\nexport const ZodNumber = /*@__PURE__*/ core.$constructor(\"ZodNumber\", (inst, def) => {\n core.$ZodNumber.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.numberProcessor(inst, ctx, json, params);\n _installLazyMethods(inst, \"ZodNumber\", {\n gt(value, params) {\n return this.check(checks.gt(value, params));\n },\n gte(value, params) {\n return this.check(checks.gte(value, params));\n },\n min(value, params) {\n return this.check(checks.gte(value, params));\n },\n lt(value, params) {\n return this.check(checks.lt(value, params));\n },\n lte(value, params) {\n return this.check(checks.lte(value, params));\n },\n max(value, params) {\n return this.check(checks.lte(value, params));\n },\n int(params) {\n return this.check(int(params));\n },\n safe(params) {\n return this.check(int(params));\n },\n positive(params) {\n return this.check(checks.gt(0, params));\n },\n nonnegative(params) {\n return this.check(checks.gte(0, params));\n },\n negative(params) {\n return this.check(checks.lt(0, params));\n },\n nonpositive(params) {\n return this.check(checks.lte(0, params));\n },\n multipleOf(value, params) {\n return this.check(checks.multipleOf(value, params));\n },\n step(value, params) {\n return this.check(checks.multipleOf(value, params));\n },\n finite() {\n return this;\n },\n });\n const bag = inst._zod.bag;\n inst.minValue =\n Math.max(bag.minimum ?? Number.NEGATIVE_INFINITY, bag.exclusiveMinimum ?? Number.NEGATIVE_INFINITY) ?? null;\n inst.maxValue =\n Math.min(bag.maximum ?? Number.POSITIVE_INFINITY, bag.exclusiveMaximum ?? Number.POSITIVE_INFINITY) ?? null;\n inst.isInt = (bag.format ?? \"\").includes(\"int\") || Number.isSafeInteger(bag.multipleOf ?? 0.5);\n inst.isFinite = true;\n inst.format = bag.format ?? null;\n});\nexport function number(params) {\n return core._number(ZodNumber, params);\n}\nexport const ZodNumberFormat = /*@__PURE__*/ core.$constructor(\"ZodNumberFormat\", (inst, def) => {\n core.$ZodNumberFormat.init(inst, def);\n ZodNumber.init(inst, def);\n});\nexport function int(params) {\n return core._int(ZodNumberFormat, params);\n}\nexport function float32(params) {\n return core._float32(ZodNumberFormat, params);\n}\nexport function float64(params) {\n return core._float64(ZodNumberFormat, params);\n}\nexport function int32(params) {\n return core._int32(ZodNumberFormat, params);\n}\nexport function uint32(params) {\n return core._uint32(ZodNumberFormat, params);\n}\nexport const ZodBoolean = /*@__PURE__*/ core.$constructor(\"ZodBoolean\", (inst, def) => {\n core.$ZodBoolean.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.booleanProcessor(inst, ctx, json, params);\n});\nexport function boolean(params) {\n return core._boolean(ZodBoolean, params);\n}\nexport const ZodBigInt = /*@__PURE__*/ core.$constructor(\"ZodBigInt\", (inst, def) => {\n core.$ZodBigInt.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.bigintProcessor(inst, ctx, json, params);\n inst.gte = (value, params) => inst.check(checks.gte(value, params));\n inst.min = (value, params) => inst.check(checks.gte(value, params));\n inst.gt = (value, params) => inst.check(checks.gt(value, params));\n inst.gte = (value, params) => inst.check(checks.gte(value, params));\n inst.min = (value, params) => inst.check(checks.gte(value, params));\n inst.lt = (value, params) => inst.check(checks.lt(value, params));\n inst.lte = (value, params) => inst.check(checks.lte(value, params));\n inst.max = (value, params) => inst.check(checks.lte(value, params));\n inst.positive = (params) => inst.check(checks.gt(BigInt(0), params));\n inst.negative = (params) => inst.check(checks.lt(BigInt(0), params));\n inst.nonpositive = (params) => inst.check(checks.lte(BigInt(0), params));\n inst.nonnegative = (params) => inst.check(checks.gte(BigInt(0), params));\n inst.multipleOf = (value, params) => inst.check(checks.multipleOf(value, params));\n const bag = inst._zod.bag;\n inst.minValue = bag.minimum ?? null;\n inst.maxValue = bag.maximum ?? null;\n inst.format = bag.format ?? null;\n});\nexport function bigint(params) {\n return core._bigint(ZodBigInt, params);\n}\nexport const ZodBigIntFormat = /*@__PURE__*/ core.$constructor(\"ZodBigIntFormat\", (inst, def) => {\n core.$ZodBigIntFormat.init(inst, def);\n ZodBigInt.init(inst, def);\n});\n// int64\nexport function int64(params) {\n return core._int64(ZodBigIntFormat, params);\n}\n// uint64\nexport function uint64(params) {\n return core._uint64(ZodBigIntFormat, params);\n}\nexport const ZodSymbol = /*@__PURE__*/ core.$constructor(\"ZodSymbol\", (inst, def) => {\n core.$ZodSymbol.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.symbolProcessor(inst, ctx, json, params);\n});\nexport function symbol(params) {\n return core._symbol(ZodSymbol, params);\n}\nexport const ZodUndefined = /*@__PURE__*/ core.$constructor(\"ZodUndefined\", (inst, def) => {\n core.$ZodUndefined.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.undefinedProcessor(inst, ctx, json, params);\n});\nfunction _undefined(params) {\n return core._undefined(ZodUndefined, params);\n}\nexport { _undefined as undefined };\nexport const ZodNull = /*@__PURE__*/ core.$constructor(\"ZodNull\", (inst, def) => {\n core.$ZodNull.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nullProcessor(inst, ctx, json, params);\n});\nfunction _null(params) {\n return core._null(ZodNull, params);\n}\nexport { _null as null };\nexport const ZodAny = /*@__PURE__*/ core.$constructor(\"ZodAny\", (inst, def) => {\n core.$ZodAny.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.anyProcessor(inst, ctx, json, params);\n});\nexport function any() {\n return core._any(ZodAny);\n}\nexport const ZodUnknown = /*@__PURE__*/ core.$constructor(\"ZodUnknown\", (inst, def) => {\n core.$ZodUnknown.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.unknownProcessor(inst, ctx, json, params);\n});\nexport function unknown() {\n return core._unknown(ZodUnknown);\n}\nexport const ZodNever = /*@__PURE__*/ core.$constructor(\"ZodNever\", (inst, def) => {\n core.$ZodNever.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.neverProcessor(inst, ctx, json, params);\n});\nexport function never(params) {\n return core._never(ZodNever, params);\n}\nexport const ZodVoid = /*@__PURE__*/ core.$constructor(\"ZodVoid\", (inst, def) => {\n core.$ZodVoid.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.voidProcessor(inst, ctx, json, params);\n});\nfunction _void(params) {\n return core._void(ZodVoid, params);\n}\nexport { _void as void };\nexport const ZodDate = /*@__PURE__*/ core.$constructor(\"ZodDate\", (inst, def) => {\n core.$ZodDate.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.dateProcessor(inst, ctx, json, params);\n inst.min = (value, params) => inst.check(checks.gte(value, params));\n inst.max = (value, params) => inst.check(checks.lte(value, params));\n const c = inst._zod.bag;\n inst.minDate = c.minimum ? new Date(c.minimum) : null;\n inst.maxDate = c.maximum ? new Date(c.maximum) : null;\n});\nexport function date(params) {\n return core._date(ZodDate, params);\n}\nexport const ZodArray = /*@__PURE__*/ core.$constructor(\"ZodArray\", (inst, def) => {\n core.$ZodArray.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.arrayProcessor(inst, ctx, json, params);\n inst.element = def.element;\n _installLazyMethods(inst, \"ZodArray\", {\n min(n, params) {\n return this.check(checks.minLength(n, params));\n },\n nonempty(params) {\n return this.check(checks.minLength(1, params));\n },\n max(n, params) {\n return this.check(checks.maxLength(n, params));\n },\n length(n, params) {\n return this.check(checks.length(n, params));\n },\n unwrap() {\n return this.element;\n },\n });\n});\nexport function array(element, params) {\n return core._array(ZodArray, element, params);\n}\n// .keyof\nexport function keyof(schema) {\n const shape = schema._zod.def.shape;\n return _enum(Object.keys(shape));\n}\nexport const ZodObject = /*@__PURE__*/ core.$constructor(\"ZodObject\", (inst, def) => {\n core.$ZodObjectJIT.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.objectProcessor(inst, ctx, json, params);\n util.defineLazy(inst, \"shape\", () => {\n return def.shape;\n });\n _installLazyMethods(inst, \"ZodObject\", {\n keyof() {\n return _enum(Object.keys(this._zod.def.shape));\n },\n catchall(catchall) {\n return this.clone({ ...this._zod.def, catchall: catchall });\n },\n passthrough() {\n return this.clone({ ...this._zod.def, catchall: unknown() });\n },\n loose() {\n return this.clone({ ...this._zod.def, catchall: unknown() });\n },\n strict() {\n return this.clone({ ...this._zod.def, catchall: never() });\n },\n strip() {\n return this.clone({ ...this._zod.def, catchall: undefined });\n },\n extend(incoming) {\n return util.extend(this, incoming);\n },\n safeExtend(incoming) {\n return util.safeExtend(this, incoming);\n },\n merge(other) {\n return util.merge(this, other);\n },\n pick(mask) {\n return util.pick(this, mask);\n },\n omit(mask) {\n return util.omit(this, mask);\n },\n partial(...args) {\n return util.partial(ZodOptional, this, args[0]);\n },\n required(...args) {\n return util.required(ZodNonOptional, this, args[0]);\n },\n });\n});\nexport function object(shape, params) {\n const def = {\n type: \"object\",\n shape: shape ?? {},\n ...util.normalizeParams(params),\n };\n return new ZodObject(def);\n}\n// strictObject\nexport function strictObject(shape, params) {\n return new ZodObject({\n type: \"object\",\n shape,\n catchall: never(),\n ...util.normalizeParams(params),\n });\n}\n// looseObject\nexport function looseObject(shape, params) {\n return new ZodObject({\n type: \"object\",\n shape,\n catchall: unknown(),\n ...util.normalizeParams(params),\n });\n}\nexport const ZodUnion = /*@__PURE__*/ core.$constructor(\"ZodUnion\", (inst, def) => {\n core.$ZodUnion.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.unionProcessor(inst, ctx, json, params);\n inst.options = def.options;\n});\nexport function union(options, params) {\n return new ZodUnion({\n type: \"union\",\n options: options,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodXor = /*@__PURE__*/ core.$constructor(\"ZodXor\", (inst, def) => {\n ZodUnion.init(inst, def);\n core.$ZodXor.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.unionProcessor(inst, ctx, json, params);\n inst.options = def.options;\n});\n/** Creates an exclusive union (XOR) where exactly one option must match.\n * Unlike regular unions that succeed when any option matches, xor fails if\n * zero or more than one option matches the input. */\nexport function xor(options, params) {\n return new ZodXor({\n type: \"union\",\n options: options,\n inclusive: false,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodDiscriminatedUnion = /*@__PURE__*/ core.$constructor(\"ZodDiscriminatedUnion\", (inst, def) => {\n ZodUnion.init(inst, def);\n core.$ZodDiscriminatedUnion.init(inst, def);\n});\nexport function discriminatedUnion(discriminator, options, params) {\n // const [options, params] = args;\n return new ZodDiscriminatedUnion({\n type: \"union\",\n options,\n discriminator,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodIntersection = /*@__PURE__*/ core.$constructor(\"ZodIntersection\", (inst, def) => {\n core.$ZodIntersection.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.intersectionProcessor(inst, ctx, json, params);\n});\nexport function intersection(left, right) {\n return new ZodIntersection({\n type: \"intersection\",\n left: left,\n right: right,\n });\n}\nexport const ZodTuple = /*@__PURE__*/ core.$constructor(\"ZodTuple\", (inst, def) => {\n core.$ZodTuple.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.tupleProcessor(inst, ctx, json, params);\n inst.rest = (rest) => inst.clone({\n ...inst._zod.def,\n rest: rest,\n });\n});\nexport function tuple(items, _paramsOrRest, _params) {\n const hasRest = _paramsOrRest instanceof core.$ZodType;\n const params = hasRest ? _params : _paramsOrRest;\n const rest = hasRest ? _paramsOrRest : null;\n return new ZodTuple({\n type: \"tuple\",\n items: items,\n rest,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodRecord = /*@__PURE__*/ core.$constructor(\"ZodRecord\", (inst, def) => {\n core.$ZodRecord.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.recordProcessor(inst, ctx, json, params);\n inst.keyType = def.keyType;\n inst.valueType = def.valueType;\n});\nexport function record(keyType, valueType, params) {\n // v3-compat: z.record(valueType, params?) — defaults keyType to z.string()\n if (!valueType || !valueType._zod) {\n return new ZodRecord({\n type: \"record\",\n keyType: string(),\n valueType: keyType,\n ...util.normalizeParams(valueType),\n });\n }\n return new ZodRecord({\n type: \"record\",\n keyType,\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\n// type alksjf = core.output<core.$ZodRecordKey>;\nexport function partialRecord(keyType, valueType, params) {\n const k = core.clone(keyType);\n k._zod.values = undefined;\n return new ZodRecord({\n type: \"record\",\n keyType: k,\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\nexport function looseRecord(keyType, valueType, params) {\n return new ZodRecord({\n type: \"record\",\n keyType,\n valueType: valueType,\n mode: \"loose\",\n ...util.normalizeParams(params),\n });\n}\nexport const ZodMap = /*@__PURE__*/ core.$constructor(\"ZodMap\", (inst, def) => {\n core.$ZodMap.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.mapProcessor(inst, ctx, json, params);\n inst.keyType = def.keyType;\n inst.valueType = def.valueType;\n inst.min = (...args) => inst.check(core._minSize(...args));\n inst.nonempty = (params) => inst.check(core._minSize(1, params));\n inst.max = (...args) => inst.check(core._maxSize(...args));\n inst.size = (...args) => inst.check(core._size(...args));\n});\nexport function map(keyType, valueType, params) {\n return new ZodMap({\n type: \"map\",\n keyType: keyType,\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodSet = /*@__PURE__*/ core.$constructor(\"ZodSet\", (inst, def) => {\n core.$ZodSet.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.setProcessor(inst, ctx, json, params);\n inst.min = (...args) => inst.check(core._minSize(...args));\n inst.nonempty = (params) => inst.check(core._minSize(1, params));\n inst.max = (...args) => inst.check(core._maxSize(...args));\n inst.size = (...args) => inst.check(core._size(...args));\n});\nexport function set(valueType, params) {\n return new ZodSet({\n type: \"set\",\n valueType: valueType,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodEnum = /*@__PURE__*/ core.$constructor(\"ZodEnum\", (inst, def) => {\n core.$ZodEnum.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.enumProcessor(inst, ctx, json, params);\n inst.enum = def.entries;\n inst.options = Object.values(def.entries);\n const keys = new Set(Object.keys(def.entries));\n inst.extract = (values, params) => {\n const newEntries = {};\n for (const value of values) {\n if (keys.has(value)) {\n newEntries[value] = def.entries[value];\n }\n else\n throw new Error(`Key ${value} not found in enum`);\n }\n return new ZodEnum({\n ...def,\n checks: [],\n ...util.normalizeParams(params),\n entries: newEntries,\n });\n };\n inst.exclude = (values, params) => {\n const newEntries = { ...def.entries };\n for (const value of values) {\n if (keys.has(value)) {\n delete newEntries[value];\n }\n else\n throw new Error(`Key ${value} not found in enum`);\n }\n return new ZodEnum({\n ...def,\n checks: [],\n ...util.normalizeParams(params),\n entries: newEntries,\n });\n };\n});\nfunction _enum(values, params) {\n const entries = Array.isArray(values) ? Object.fromEntries(values.map((v) => [v, v])) : values;\n return new ZodEnum({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\nexport { _enum as enum };\n/** @deprecated This API has been merged into `z.enum()`. Use `z.enum()` instead.\n *\n * ```ts\n * enum Colors { red, green, blue }\n * z.enum(Colors);\n * ```\n */\nexport function nativeEnum(entries, params) {\n return new ZodEnum({\n type: \"enum\",\n entries,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodLiteral = /*@__PURE__*/ core.$constructor(\"ZodLiteral\", (inst, def) => {\n core.$ZodLiteral.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.literalProcessor(inst, ctx, json, params);\n inst.values = new Set(def.values);\n Object.defineProperty(inst, \"value\", {\n get() {\n if (def.values.length > 1) {\n throw new Error(\"This schema contains multiple valid literal values. Use `.values` instead.\");\n }\n return def.values[0];\n },\n });\n});\nexport function literal(value, params) {\n return new ZodLiteral({\n type: \"literal\",\n values: Array.isArray(value) ? value : [value],\n ...util.normalizeParams(params),\n });\n}\nexport const ZodFile = /*@__PURE__*/ core.$constructor(\"ZodFile\", (inst, def) => {\n core.$ZodFile.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.fileProcessor(inst, ctx, json, params);\n inst.min = (size, params) => inst.check(core._minSize(size, params));\n inst.max = (size, params) => inst.check(core._maxSize(size, params));\n inst.mime = (types, params) => inst.check(core._mime(Array.isArray(types) ? types : [types], params));\n});\nexport function file(params) {\n return core._file(ZodFile, params);\n}\nexport const ZodTransform = /*@__PURE__*/ core.$constructor(\"ZodTransform\", (inst, def) => {\n core.$ZodTransform.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.transformProcessor(inst, ctx, json, params);\n inst._zod.parse = (payload, _ctx) => {\n if (_ctx.direction === \"backward\") {\n throw new core.$ZodEncodeError(inst.constructor.name);\n }\n payload.addIssue = (issue) => {\n if (typeof issue === \"string\") {\n payload.issues.push(util.issue(issue, payload.value, def));\n }\n else {\n // for Zod 3 backwards compatibility\n const _issue = issue;\n if (_issue.fatal)\n _issue.continue = false;\n _issue.code ?? (_issue.code = \"custom\");\n _issue.input ?? (_issue.input = payload.value);\n _issue.inst ?? (_issue.inst = inst);\n // _issue.continue ??= true;\n payload.issues.push(util.issue(_issue));\n }\n };\n const output = def.transform(payload.value, payload);\n if (output instanceof Promise) {\n return output.then((output) => {\n payload.value = output;\n payload.fallback = true;\n return payload;\n });\n }\n payload.value = output;\n payload.fallback = true;\n return payload;\n };\n});\nexport function transform(fn) {\n return new ZodTransform({\n type: \"transform\",\n transform: fn,\n });\n}\nexport const ZodOptional = /*@__PURE__*/ core.$constructor(\"ZodOptional\", (inst, def) => {\n core.$ZodOptional.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.optionalProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function optional(innerType) {\n return new ZodOptional({\n type: \"optional\",\n innerType: innerType,\n });\n}\nexport const ZodExactOptional = /*@__PURE__*/ core.$constructor(\"ZodExactOptional\", (inst, def) => {\n core.$ZodExactOptional.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.optionalProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function exactOptional(innerType) {\n return new ZodExactOptional({\n type: \"optional\",\n innerType: innerType,\n });\n}\nexport const ZodNullable = /*@__PURE__*/ core.$constructor(\"ZodNullable\", (inst, def) => {\n core.$ZodNullable.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nullableProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function nullable(innerType) {\n return new ZodNullable({\n type: \"nullable\",\n innerType: innerType,\n });\n}\n// nullish\nexport function nullish(innerType) {\n return optional(nullable(innerType));\n}\nexport const ZodDefault = /*@__PURE__*/ core.$constructor(\"ZodDefault\", (inst, def) => {\n core.$ZodDefault.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.defaultProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n inst.removeDefault = inst.unwrap;\n});\nexport function _default(innerType, defaultValue) {\n return new ZodDefault({\n type: \"default\",\n innerType: innerType,\n get defaultValue() {\n return typeof defaultValue === \"function\" ? defaultValue() : util.shallowClone(defaultValue);\n },\n });\n}\nexport const ZodPrefault = /*@__PURE__*/ core.$constructor(\"ZodPrefault\", (inst, def) => {\n core.$ZodPrefault.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.prefaultProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function prefault(innerType, defaultValue) {\n return new ZodPrefault({\n type: \"prefault\",\n innerType: innerType,\n get defaultValue() {\n return typeof defaultValue === \"function\" ? defaultValue() : util.shallowClone(defaultValue);\n },\n });\n}\nexport const ZodNonOptional = /*@__PURE__*/ core.$constructor(\"ZodNonOptional\", (inst, def) => {\n core.$ZodNonOptional.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nonoptionalProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function nonoptional(innerType, params) {\n return new ZodNonOptional({\n type: \"nonoptional\",\n innerType: innerType,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodSuccess = /*@__PURE__*/ core.$constructor(\"ZodSuccess\", (inst, def) => {\n core.$ZodSuccess.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.successProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function success(innerType) {\n return new ZodSuccess({\n type: \"success\",\n innerType: innerType,\n });\n}\nexport const ZodCatch = /*@__PURE__*/ core.$constructor(\"ZodCatch\", (inst, def) => {\n core.$ZodCatch.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.catchProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n inst.removeCatch = inst.unwrap;\n});\nfunction _catch(innerType, catchValue) {\n return new ZodCatch({\n type: \"catch\",\n innerType: innerType,\n catchValue: (typeof catchValue === \"function\" ? catchValue : () => catchValue),\n });\n}\nexport { _catch as catch };\nexport const ZodNaN = /*@__PURE__*/ core.$constructor(\"ZodNaN\", (inst, def) => {\n core.$ZodNaN.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.nanProcessor(inst, ctx, json, params);\n});\nexport function nan(params) {\n return core._nan(ZodNaN, params);\n}\nexport const ZodPipe = /*@__PURE__*/ core.$constructor(\"ZodPipe\", (inst, def) => {\n core.$ZodPipe.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.pipeProcessor(inst, ctx, json, params);\n inst.in = def.in;\n inst.out = def.out;\n});\nexport function pipe(in_, out) {\n return new ZodPipe({\n type: \"pipe\",\n in: in_,\n out: out,\n // ...util.normalizeParams(params),\n });\n}\nexport const ZodCodec = /*@__PURE__*/ core.$constructor(\"ZodCodec\", (inst, def) => {\n ZodPipe.init(inst, def);\n core.$ZodCodec.init(inst, def);\n});\nexport function codec(in_, out, params) {\n return new ZodCodec({\n type: \"pipe\",\n in: in_,\n out: out,\n transform: params.decode,\n reverseTransform: params.encode,\n });\n}\nexport function invertCodec(codec) {\n const def = codec._zod.def;\n return new ZodCodec({\n type: \"pipe\",\n in: def.out,\n out: def.in,\n transform: def.reverseTransform,\n reverseTransform: def.transform,\n });\n}\nexport const ZodPreprocess = /*@__PURE__*/ core.$constructor(\"ZodPreprocess\", (inst, def) => {\n ZodPipe.init(inst, def);\n core.$ZodPreprocess.init(inst, def);\n});\nexport const ZodReadonly = /*@__PURE__*/ core.$constructor(\"ZodReadonly\", (inst, def) => {\n core.$ZodReadonly.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.readonlyProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function readonly(innerType) {\n return new ZodReadonly({\n type: \"readonly\",\n innerType: innerType,\n });\n}\nexport const ZodTemplateLiteral = /*@__PURE__*/ core.$constructor(\"ZodTemplateLiteral\", (inst, def) => {\n core.$ZodTemplateLiteral.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.templateLiteralProcessor(inst, ctx, json, params);\n});\nexport function templateLiteral(parts, params) {\n return new ZodTemplateLiteral({\n type: \"template_literal\",\n parts,\n ...util.normalizeParams(params),\n });\n}\nexport const ZodLazy = /*@__PURE__*/ core.$constructor(\"ZodLazy\", (inst, def) => {\n core.$ZodLazy.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.lazyProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.getter();\n});\nexport function lazy(getter) {\n return new ZodLazy({\n type: \"lazy\",\n getter: getter,\n });\n}\nexport const ZodPromise = /*@__PURE__*/ core.$constructor(\"ZodPromise\", (inst, def) => {\n core.$ZodPromise.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.promiseProcessor(inst, ctx, json, params);\n inst.unwrap = () => inst._zod.def.innerType;\n});\nexport function promise(innerType) {\n return new ZodPromise({\n type: \"promise\",\n innerType: innerType,\n });\n}\nexport const ZodFunction = /*@__PURE__*/ core.$constructor(\"ZodFunction\", (inst, def) => {\n core.$ZodFunction.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.functionProcessor(inst, ctx, json, params);\n});\nexport function _function(params) {\n return new ZodFunction({\n type: \"function\",\n input: Array.isArray(params?.input) ? tuple(params?.input) : (params?.input ?? array(unknown())),\n output: params?.output ?? unknown(),\n });\n}\nexport { _function as function };\nexport const ZodCustom = /*@__PURE__*/ core.$constructor(\"ZodCustom\", (inst, def) => {\n core.$ZodCustom.init(inst, def);\n ZodType.init(inst, def);\n inst._zod.processJSONSchema = (ctx, json, params) => processors.customProcessor(inst, ctx, json, params);\n});\n// custom checks\nexport function check(fn) {\n const ch = new core.$ZodCheck({\n check: \"custom\",\n // ...util.normalizeParams(params),\n });\n ch._zod.check = fn;\n return ch;\n}\nexport function custom(fn, _params) {\n return core._custom(ZodCustom, fn ?? (() => true), _params);\n}\nexport function refine(fn, _params = {}) {\n return core._refine(ZodCustom, fn, _params);\n}\n// superRefine\nexport function superRefine(fn, params) {\n return core._superRefine(fn, params);\n}\n// Re-export describe and meta from core\nexport const describe = core.describe;\nexport const meta = core.meta;\nfunction _instanceof(cls, params = {}) {\n const inst = new ZodCustom({\n type: \"custom\",\n check: \"custom\",\n fn: (data) => data instanceof cls,\n abort: true,\n ...util.normalizeParams(params),\n });\n inst._zod.bag.Class = cls;\n // Override check to emit invalid_type instead of custom\n inst._zod.check = (payload) => {\n if (!(payload.value instanceof cls)) {\n payload.issues.push({\n code: \"invalid_type\",\n expected: cls.name,\n input: payload.value,\n inst,\n path: [...(inst._zod.def.path ?? [])],\n });\n }\n };\n return inst;\n}\nexport { _instanceof as instanceof };\n// stringbool\nexport const stringbool = (...args) => core._stringbool({\n Codec: ZodCodec,\n Boolean: ZodBoolean,\n String: ZodString,\n}, ...args);\nexport function json(params) {\n const jsonSchema = lazy(() => {\n return union([string(params), number(), boolean(), _null(), array(jsonSchema), record(string(), jsonSchema)]);\n });\n return jsonSchema;\n}\n// preprocess\nexport function preprocess(fn, schema) {\n return new ZodPreprocess({\n type: \"pipe\",\n in: transform(fn),\n out: schema,\n });\n}\n","/**\n * TOTP (Time-based One-Time Password) implementation.\n *\n * Pure Node.js crypto implementation — no external dependencies required.\n * Implements RFC 6238 (TOTP) and RFC 4226 (HOTP).\n */\n\nimport { createHmac, randomBytes, createHash } from \"crypto\";\n\n// ─── Base32 Encoding/Decoding ────────────────────────────────────────────────\n\nconst BASE32_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";\n\n/**\n * Encode a Buffer to Base32 string (RFC 4648)\n */\nexport function base32Encode(buffer: Buffer): string {\n let bits = 0;\n let value = 0;\n let output = \"\";\n\n for (let i = 0; i < buffer.length; i++) {\n value = (value << 8) | buffer[i];\n bits += 8;\n\n while (bits >= 5) {\n output += BASE32_ALPHABET[(value >>> (bits - 5)) & 31];\n bits -= 5;\n }\n }\n\n if (bits > 0) {\n output += BASE32_ALPHABET[(value << (5 - bits)) & 31];\n }\n\n return output;\n}\n\n/**\n * Decode a Base32 string to Buffer\n */\nexport function base32Decode(encoded: string): Buffer {\n const cleanInput = encoded.replace(/=+$/, \"\").toUpperCase();\n const bytes: number[] = [];\n let bits = 0;\n let value = 0;\n\n for (let i = 0; i < cleanInput.length; i++) {\n const index = BASE32_ALPHABET.indexOf(cleanInput[i]);\n if (index === -1) continue;\n\n value = (value << 5) | index;\n bits += 5;\n\n if (bits >= 8) {\n bytes.push((value >>> (bits - 8)) & 255);\n bits -= 8;\n }\n }\n\n return Buffer.from(bytes);\n}\n\n// ─── HOTP/TOTP ───────────────────────────────────────────────────────────────\n\n/**\n * Generate an HOTP value per RFC 4226\n */\nfunction generateHotp(secret: Buffer, counter: bigint): string {\n const hmac = createHmac(\"sha1\", secret);\n const counterBuffer = Buffer.alloc(8);\n counterBuffer.writeBigInt64BE(counter);\n hmac.update(counterBuffer);\n const hash = hmac.digest();\n\n const offset = hash[hash.length - 1] & 0x0f;\n const code =\n (((hash[offset] & 0x7f) << 24) |\n (hash[offset + 1] << 16) |\n (hash[offset + 2] << 8) |\n hash[offset + 3]) %\n 1000000;\n\n return code.toString().padStart(6, \"0\");\n}\n\n/**\n * Generate a TOTP value for the current time step\n */\nexport function generateTotp(secret: Buffer, timeStep = 30): string {\n const counter = BigInt(Math.floor(Date.now() / 1000 / timeStep));\n return generateHotp(secret, counter);\n}\n\n/**\n * Verify a TOTP token with a configurable time window\n *\n * @param secret - The shared secret as a Buffer\n * @param token - The 6-digit TOTP code to verify\n * @param window - Number of time steps to check on each side (default: 1)\n * @returns true if the token is valid within the window\n */\nexport function verifyTotp(secret: Buffer, token: string, window = 1): boolean {\n return verifyTotpCounter(secret, token, window) !== null;\n}\n\n/**\n * Verify a TOTP token and report *which* time step matched.\n *\n * RFC 6238 §5.2 requires that an accepted OTP not be accepted a second time,\n * and a boolean cannot express what was accepted: with `window = 1` the same\n * six digits stay valid for up to 90 seconds, so a code observed once — by a\n * phishing relay, over a shoulder, in a pasted support message — can be\n * presented again for the rest of that window. The caller records the returned\n * counter against the factor and refuses anything at or below it.\n *\n * @param secret - The shared secret as a Buffer\n * @param token - The 6-digit TOTP code to verify\n * @param window - Number of time steps to check on each side (default: 1)\n * @returns The matched time step, or `null` when no step in the window matches\n */\nexport function verifyTotpCounter(secret: Buffer, token: string, window = 1): number | null {\n const timeStep = 30;\n const counter = BigInt(Math.floor(Date.now() / 1000 / timeStep));\n for (let i = -window; i <= window; i++) {\n const step = counter + BigInt(i);\n if (generateHotp(secret, step) === token) {\n return Number(step);\n }\n }\n return null;\n}\n\n// ─── Secret Generation ───────────────────────────────────────────────────────\n\n/**\n * Generate a new TOTP secret and return the setup information\n *\n * @param issuer - The issuer name (app name) for the QR code\n * @param accountName - The account identifier (usually email)\n * @returns Object with base32 secret and otpauth URI\n */\nexport function generateTotpSecret(issuer: string, accountName: string): {\n secret: string;\n uri: string;\n} {\n // Generate a 20-byte random secret (160 bits, recommended by RFC 4226)\n const secretBuffer = randomBytes(20);\n const secret = base32Encode(secretBuffer);\n\n // Build otpauth:// URI for QR code generation\n const encodedIssuer = encodeURIComponent(issuer);\n const encodedAccount = encodeURIComponent(accountName);\n const uri = `otpauth://totp/${encodedIssuer}:${encodedAccount}?secret=${secret}&issuer=${encodedIssuer}&algorithm=SHA1&digits=6&period=30`;\n\n return { secret,\nuri };\n}\n\n// ─── Recovery Codes ──────────────────────────────────────────────────────────\n\n/**\n * Generate a set of one-time recovery codes\n *\n * @param count - Number of recovery codes to generate (default: 10)\n * @returns Array of formatted recovery code strings (e.g. \"A1B2C-D3E4F\")\n */\nexport function generateRecoveryCodes(count = 10): string[] {\n return Array.from({ length: count }, () => {\n const raw = randomBytes(5).toString(\"hex\").toUpperCase();\n const parts = raw.match(/.{1,5}/g);\n return parts ? parts.join(\"-\") : raw;\n });\n}\n\n/**\n * Hash a recovery code for storage\n */\nexport function hashRecoveryCode(code: string): string {\n return createHash(\"sha256\").update(code.replace(/-/g, \"\").toUpperCase()).digest(\"hex\");\n}\n","/**\n * Envelope encryption for TOTP secrets using AES-256-GCM.\n *\n * - Derives a 32-byte key via SHA-256 from `MFA_ENCRYPTION_KEY` or `JWT_SECRET`.\n * - Generates a random 12-byte IV per encryption call.\n * - Stamps the key that made the ciphertext, so the key can be changed without\n * locking every enrolled user out — see \"Rotating the key\" below.\n *\n * ## Rotating the key\n *\n * A ciphertext used to be `iv:authTag:ciphertext` and recorded nothing about\n * which key produced it, while the key was re-derived from the environment on\n * every call. Setting `MFA_ENCRYPTION_KEY` on a deployment that had been\n * falling back to `JWT_SECRET` therefore made every stored factor undecryptable\n * — AES-GCM authenticates, so it did not return a wrong secret, it threw, and\n * every MFA sign-in failed until the variable was removed again.\n *\n * Now a ciphertext carries `v1.<keyId>`, where `keyId` is derived from the key\n * itself (no key names to keep in sync), and decryption runs against a list of\n * candidates: `MFA_ENCRYPTION_KEY`, then each comma-separated entry in\n * `MFA_ENCRYPTION_KEY_PREVIOUS`, then `JWT_SECRET`. To rotate:\n *\n * 1. **Deploy this code first.** It reads both formats. Doing it the other way\n * round — setting the key before the readers understand the old ciphertexts\n * — is the outage this exists to prevent.\n * 2. Move the old value into `MFA_ENCRYPTION_KEY_PREVIOUS` and set the new one\n * as `MFA_ENCRYPTION_KEY`.\n * 3. Each factor is re-wrapped with the current key the next time its owner\n * authenticates (`openTotpSecret` reports it via `rewrapped`).\n * 4. Once every enrolled user has signed in, drop `MFA_ENCRYPTION_KEY_PREVIOUS`.\n * Any factor still on the old key then fails loudly, naming the key id,\n * rather than being silently unreadable.\n *\n * Trial decryption across candidates is safe here: GCM's auth tag is a 128-bit\n * MAC, so a wrong key throws instead of yielding a plausible-looking secret.\n *\n * @module\n */\n\nimport { createCipheriv, createDecipheriv, createHash, randomBytes } from \"crypto\";\nimport { logger } from \"../utils/logger\";\n\nconst ALGORITHM = \"aes-256-gcm\";\nconst IV_BYTES = 12;\nconst AUTH_TAG_LENGTH = 16;\n\n/** Ciphertext prefix marking the key-stamped format. */\nconst VERSION = \"v1\";\n\n/** A key the process could decrypt with, and the id a ciphertext names it by. */\ninterface KeyCandidate {\n /** First 8 hex of `sha256(raw)` — derived, so no key registry to maintain. */\n id: string;\n key: Buffer;\n /** Where it came from, for error messages. */\n source: string;\n}\n\n/** Warn once, not once per sign-in. */\nlet warnedAboutFallback = false;\n\nfunction toCandidate(raw: string, source: string): KeyCandidate {\n const digest = createHash(\"sha256\").update(raw).digest();\n return { id: digest.toString(\"hex\").slice(0, 8),\nkey: digest,\nsource };\n}\n\n/**\n * Every key this process can decrypt with, most-preferred first.\n *\n * The head of the list is the key new ciphertexts are written with; the rest\n * exist so that ciphertexts written before a rotation still open.\n */\nfunction keyCandidates(): KeyCandidate[] {\n const candidates: KeyCandidate[] = [];\n const seen = new Set<string>();\n\n const add = (raw: string | undefined, source: string) => {\n const trimmed = raw?.trim();\n if (!trimmed || seen.has(trimmed)) return;\n seen.add(trimmed);\n candidates.push(toCandidate(trimmed, source));\n };\n\n add(process.env.MFA_ENCRYPTION_KEY, \"MFA_ENCRYPTION_KEY\");\n for (const previous of (process.env.MFA_ENCRYPTION_KEY_PREVIOUS ?? \"\").split(\",\")) {\n add(previous, \"MFA_ENCRYPTION_KEY_PREVIOUS\");\n }\n add(process.env.JWT_SECRET, \"JWT_SECRET\");\n\n if (candidates.length === 0) {\n throw new Error(\n \"Cannot encrypt or decrypt TOTP secrets: none of MFA_ENCRYPTION_KEY, \" +\n \"MFA_ENCRYPTION_KEY_PREVIOUS or JWT_SECRET is configured.\"\n );\n }\n\n if (!process.env.MFA_ENCRYPTION_KEY && !warnedAboutFallback) {\n warnedAboutFallback = true;\n logger.warn(\n \"[MFA-Crypto] MFA_ENCRYPTION_KEY is not set — falling back to JWT_SECRET. \" +\n \"Set a dedicated MFA_ENCRYPTION_KEY for production; see the rotation \" +\n \"steps in mfa-crypto.ts before you do it on a live deployment.\"\n );\n }\n\n return candidates;\n}\n\n/** The key new ciphertexts are written with. */\nfunction currentKey(): KeyCandidate {\n return keyCandidates()[0];\n}\n\n/**\n * Encrypt a plaintext TOTP secret.\n *\n * @param plaintext - The Base32 TOTP secret to encrypt.\n * @returns A string in the format `v1.<keyId>:iv_hex:authTag_hex:ciphertext_hex`.\n */\nexport function encryptTotpSecret(plaintext: string): string {\n const { id, key } = currentKey();\n const iv = randomBytes(IV_BYTES);\n\n const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });\n const encrypted = Buffer.concat([cipher.update(plaintext, \"utf8\"), cipher.final()]);\n const authTag = cipher.getAuthTag();\n\n return `${VERSION}.${id}:${iv.toString(\"hex\")}:${authTag.toString(\"hex\")}:${encrypted.toString(\"hex\")}`;\n}\n\nfunction openWith(candidate: KeyCandidate, ivHex: string, authTagHex: string, encryptedHex: string): string {\n const decipher = createDecipheriv(ALGORITHM, candidate.key, Buffer.from(ivHex, \"hex\"), {\n authTagLength: AUTH_TAG_LENGTH\n });\n decipher.setAuthTag(Buffer.from(authTagHex, \"hex\"));\n return Buffer.concat([decipher.update(Buffer.from(encryptedHex, \"hex\")), decipher.final()]).toString(\"utf8\");\n}\n\n/** What a factor's stored secret opened to, and whether it should be re-stored. */\nexport interface OpenedTotpSecret {\n /** The Base32 TOTP secret. */\n secret: string;\n /**\n * Set when the secret opened with something other than the current key —\n * the same secret, re-encrypted under it. Persist this and the factor\n * stops depending on the old key. `null` when it is already current.\n */\n rewrapped: string | null;\n}\n\n/**\n * Decrypt a stored TOTP secret, reporting whether it wants re-wrapping.\n *\n * Accepts both the key-stamped format and the original unstamped\n * `iv:authTag:ciphertext`, which is tried against each candidate in turn.\n */\nexport function openTotpSecret(ciphertext: string): OpenedTotpSecret {\n const parts = ciphertext.split(\":\");\n const candidates = keyCandidates();\n const current = candidates[0];\n\n if (parts.length === 4) {\n const [stamp, ivHex, authTagHex, encryptedHex] = parts;\n const [version, keyId] = stamp.split(\".\");\n if (version !== VERSION || !keyId) {\n throw new Error(`Unsupported encrypted TOTP secret version \"${stamp}\"`);\n }\n\n const named = candidates.find(c => c.id === keyId);\n if (!named) {\n // Loud on purpose. An unknown key id means a key this deployment\n // once used is no longer configured — recoverable by restoring it\n // to MFA_ENCRYPTION_KEY_PREVIOUS, but only if someone is told.\n throw new Error(\n `No configured key matches this TOTP secret (key id \"${keyId}\"). ` +\n \"Restore the key that encrypted it via MFA_ENCRYPTION_KEY_PREVIOUS. \" +\n `Configured key ids: ${candidates.map(c => `${c.id} (${c.source})`).join(\", \")}.`\n );\n }\n\n const secret = openWith(named, ivHex, authTagHex, encryptedHex);\n return { secret,\nrewrapped: named.id === current.id ? null : encryptTotpSecret(secret) };\n }\n\n if (parts.length !== 3) {\n throw new Error(\n \"Invalid encrypted TOTP secret format — expected v1.<keyId>:iv:authTag:ciphertext \" +\n \"or the legacy iv:authTag:ciphertext\"\n );\n }\n\n // Unstamped, from before key ids existed: it was written with whatever the\n // environment resolved to at the time, which we can only discover by trying.\n const [ivHex, authTagHex, encryptedHex] = parts;\n for (const candidate of candidates) {\n try {\n const secret = openWith(candidate, ivHex, authTagHex, encryptedHex);\n // Always re-wrapped: even when the key is unchanged, stamping it\n // is what lets the next rotation identify this ciphertext.\n return { secret,\nrewrapped: encryptTotpSecret(secret) };\n } catch {\n // Wrong key — GCM refused to authenticate. Try the next one.\n }\n }\n\n throw new Error(\n \"Could not decrypt TOTP secret with any configured key. Tried: \" +\n `${candidates.map(c => c.source).join(\", \")}.`\n );\n}\n\n/**\n * Decrypt a previously encrypted TOTP secret.\n *\n * Prefer {@link openTotpSecret} on any path that can persist the result —\n * this wrapper discards the re-wrapped form, so a factor read through it stays\n * on whichever key it was written with.\n *\n * @param ciphertext - A stored TOTP secret, in either format.\n * @returns The original Base32 TOTP secret.\n */\nexport function decryptTotpSecret(ciphertext: string): string {\n return openTotpSecret(ciphertext).secret;\n}\n","import type { Context } from \"hono\";\nimport type { AuthResponsePayload } from \"@rebasepro/types\";\nimport type { HonoEnv } from \"../api/types\";\nimport type { CookieAuthConfig } from \"./routes\";\nimport { getRefreshTokenTtlMs, MAX_COOKIE_AGE_MS } from \"./jwt\";\n\n/**\n * Cookie auth helpers for httpOnly refresh tokens.\n */\nexport function getCookieSettings(config: CookieAuthConfig | undefined) {\n const COOKIE_NAME = config?.cookieName || \"__rb_refresh\";\n const COOKIE_PATH = config?.path || \"/\";\n const COOKIE_SAMESITE = config?.sameSite || \"Lax\";\n const COOKIE_DOMAIN = config?.domain;\n const COOKIE_SECURE = config?.secure;\n\n return {\n name: COOKIE_NAME,\n path: COOKIE_PATH,\n sameSite: COOKIE_SAMESITE,\n domain: COOKIE_DOMAIN,\n secure: COOKIE_SECURE\n };\n}\n\n/**\n * Set the refresh token as an httpOnly cookie on the response.\n */\nexport function setRefreshCookie(c: Context<HonoEnv>, refreshToken: string, config: CookieAuthConfig | undefined): void {\n if (!config) return;\n\n const settings = getCookieSettings(config);\n // Secure unless the deployment explicitly says otherwise.\n //\n // This used to be inferred from `c.req.url`, which `@hono/node-server`\n // derives from `socket.encrypted` — so behind any TLS-terminating proxy,\n // which is the normal production topology, the server saw `http` and\n // omitted the flag. The refresh token is a credential with a lifetime\n // measured in months, and it was travelling in cleartext on every request\n // to a plain-http URL on the same host.\n //\n // Inverted rather than patched: no request header can downgrade this, since\n // `X-Forwarded-Proto` is written by whoever is talking to us. Only\n // `cookieAuth.secure: false` turns it off, which is a deployment saying so\n // deliberately. Local development does not need that escape hatch —\n // browsers treat `http://localhost` as a trustworthy origin and accept\n // Secure cookies there.\n const isSecure = settings.secure ?? true;\n\n let cookie = `${settings.name}=${encodeURIComponent(refreshToken)}; Path=${settings.path}; HttpOnly; SameSite=${settings.sameSite}`;\n if (isSecure) cookie += \"; Secure\";\n if (settings.domain) cookie += `; Domain=${settings.domain}`;\n // Match the server's refresh token expiry rather than assuming it. This\n // was hardcoded to 30 days, which quietly capped every deployment's\n // sessions at 30 days no matter what JWT_REFRESH_EXPIRES_IN said: the row\n // in the database stayed valid for as long as it was configured to, and\n // the browser threw away the cookie that pointed at it. Re-set on every\n // rotation, so an active session's cookie slides forward with it.\n const maxAgeSeconds = Math.floor(Math.min(getRefreshTokenTtlMs(), MAX_COOKIE_AGE_MS) / 1000);\n cookie += `; Max-Age=${maxAgeSeconds}`;\n c.header(\"Set-Cookie\", cookie, { append: true });\n}\n\n/**\n * Clear the refresh token cookie.\n */\nexport function clearRefreshCookie(c: Context<HonoEnv>, config: CookieAuthConfig | undefined): void {\n if (!config) return;\n\n const settings = getCookieSettings(config);\n let cookie = `${settings.name}=; Path=${settings.path}; HttpOnly; SameSite=${settings.sameSite}; Max-Age=0`;\n // Mirror the attributes the cookie was set with, so the clear matches it.\n if (settings.secure ?? true) cookie += \"; Secure\";\n if (settings.domain) cookie += `; Domain=${settings.domain}`;\n c.header(\"Set-Cookie\", cookie, { append: true });\n}\n\n/**\n * Read the refresh token from the request — cookie first, then body fallback.\n */\nexport function readRefreshToken(c: Context<HonoEnv>, body: { refreshToken?: string }, config: CookieAuthConfig | undefined): string | undefined {\n if (config) {\n const settings = getCookieSettings(config);\n const cookieHeader = c.req.header(\"cookie\") || \"\";\n const prefix = `${settings.name}=`;\n const cookies = cookieHeader.split(\";\");\n for (const part of cookies) {\n const trimmed = part.trim();\n if (trimmed.startsWith(prefix)) {\n return decodeURIComponent(trimmed.slice(prefix.length));\n }\n }\n }\n return body.refreshToken;\n}\n\n/**\n * Redact the refresh token from the response body when cookie mode is active.\n */\nexport function redactRefreshToken(\n response: AuthResponsePayload,\n c: Context<HonoEnv>,\n refreshToken: string,\n config: CookieAuthConfig | undefined\n): AuthResponsePayload {\n if (!config) return response;\n\n setRefreshCookie(c, refreshToken, config);\n return {\n ...response,\n tokens: {\n ...response.tokens,\n refreshToken: \"\" // Omit from JSON body — the cookie carries it\n }\n };\n}\n","import { Hono, type Context, type MiddlewareHandler } from \"hono\";\nimport { z } from \"zod\";\nimport { ApiError } from \"../api/errors\";\nimport { HonoEnv } from \"../api/types\";\nimport { requireAuth, extractBearerToken } from \"./middleware\";\nimport { logger } from \"../utils/logger\";\nimport { createRateLimiter, strictAuthLimiter } from \"./rate-limiter\";\nimport {\n generateTotpSecret,\n verifyTotpCounter,\n base32Decode,\n generateRecoveryCodes,\n hashRecoveryCode\n} from \"./mfa\";\nimport { encryptTotpSecret, openTotpSecret } from \"./mfa-crypto\";\nimport {\n getAccessTokenExpiry,\n verifyAccessToken,\n verifyMfaPendingToken,\n type AccessTokenPayload\n} from \"./jwt\";\nimport type { AuthModuleConfig } from \"./routes\";\nimport type { AuthRepository } from \"./interfaces\";\nimport { redactRefreshToken } from \"./cookie-utils\";\nimport { resolveAuthHooks } from \"./auth-hooks\";\nimport type { AuthResponsePayload, TransformAuthResponseContext } from \"@rebasepro/types\";\n\n/**\n * How many failed verifications one challenge tolerates before it is spent.\n *\n * A 6-digit code with a ±1 step window accepts 3 of 1,000,000 values, so the\n * only thing standing between an attacker and the second factor is how many\n * guesses a challenge will take. Five, and then they must open another one —\n * which the per-user limiter below is counting.\n */\nconst MAX_CHALLENGE_ATTEMPTS = 5;\n\n/** Verification attempts one *account* may make per window, across all IPs. */\nconst MFA_VERIFICATION_ATTEMPTS_PER_WINDOW = 10;\n\ninterface MfaRoutesConfig {\n router: Hono<HonoEnv>;\n config: AuthModuleConfig;\n ops: ReturnType<typeof resolveAuthHooks>;\n parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T;\n buildAuthResponse: (\n user: { id: string; email: string; displayName?: string | null; photoUrl?: string | null; emailVerified?: boolean; isAnonymous?: boolean; metadata?: Record<string, unknown> | null },\n roleIds: string[],\n accessToken: string,\n refreshToken: string,\n providerId: string\n ) => unknown;\n createSessionAndTokens: (\n uid: string,\n userAgent: string,\n ipAddress: string,\n options?: { skipMfaGate?: boolean; aal?: \"aal1\" | \"aal2\" }\n ) => Promise<{ roleIds: string[]; accessToken: string; refreshToken: string }>;\n applyTransformHook?: (\n response: AuthResponsePayload,\n method: TransformAuthResponseContext[\"method\"],\n request: Request,\n uid: string\n ) => Promise<AuthResponsePayload>;\n}\n\n/**\n * Who is asking, on the two routes that may be reached *before* a session\n * exists.\n *\n * `pending` marks the caller as one factor short of a session: they hold the\n * short-lived, purpose-scoped token issued alongside `MFA_REQUIRED`, which is\n * refused as a credential everywhere else in the server.\n */\ninterface StepUpPrincipal {\n uid: string;\n aal: \"aal1\" | \"aal2\";\n pending: boolean;\n}\n\n/**\n * Resolve the caller of a challenge route from either a full session or a\n * pre-auth token.\n *\n * Both are parsed here rather than by `requireAuth` because the whole point of\n * the challenge pair is that it runs before the session exists — a login by an\n * MFA-enrolled user never receives an access token until it is finished.\n */\n/**\n * Open a factor's stored secret, re-storing it under the current key if it\n * opened with an older one.\n *\n * This is what makes an `MFA_ENCRYPTION_KEY` rotation complete on its own: each\n * factor moves to the new key the next time its owner authenticates, so the\n * previous key can eventually be dropped. See `mfa-crypto.ts` for the sequence.\n *\n * A failed re-wrap must never fail the verification — the code the user typed\n * was already checked against the right secret, and the only cost of not\n * persisting is that this factor is re-wrapped again next time.\n */\nasync function openAndRewrap(\n authRepo: AuthRepository,\n factorId: string,\n secretEncrypted: string\n): Promise<string> {\n const { secret, rewrapped } = openTotpSecret(secretEncrypted);\n if (!rewrapped) return secret;\n\n // Optional on the interface: a repository that cannot re-store a secret\n // keeps working, it just leaves the factor on its original key.\n if (typeof authRepo.updateMfaFactorSecret !== \"function\") return secret;\n\n try {\n await authRepo.updateMfaFactorSecret(factorId, rewrapped);\n logger.info(\"[MFA-Crypto] Re-wrapped a TOTP secret under the current key\", { factorId });\n } catch (error) {\n logger.warn(\"[MFA-Crypto] Could not re-wrap a TOTP secret; leaving it on its original key\", {\n factorId,\n error\n });\n }\n return secret;\n}\n\nfunction resolveStepUpPrincipal(c: Context<HonoEnv>): StepUpPrincipal | null {\n // Respect a principal an upstream middleware already resolved, exactly as\n // `requireAuth` does.\n const existing = c.get(\"user\") as AccessTokenPayload | undefined;\n if (existing?.uid) {\n return { uid: existing.uid,\naal: existing.aal === \"aal2\" ? \"aal2\" : \"aal1\",\npending: false };\n }\n\n const token = extractBearerToken(c.req.header(\"authorization\"));\n if (token === undefined) return null;\n\n const session = verifyAccessToken(token);\n if (session) {\n return { uid: session.uid,\naal: session.aal === \"aal2\" ? \"aal2\" : \"aal1\",\npending: false };\n }\n\n const pending = verifyMfaPendingToken(token);\n if (pending) {\n return { uid: pending.uid,\naal: \"aal1\",\npending: true };\n }\n\n return null;\n}\n\n/**\n * Per-account throttle on code verification.\n *\n * Keyed on the uid rather than the IP because an IP is the attacker's to\n * rotate and the account under attack is not: a distributed run against one\n * account passes an IP-keyed limiter untouched. The IP limiter still runs in\n * front of this one — they bound different things.\n */\nconst mfaVerificationLimiter: MiddlewareHandler<HonoEnv> = createRateLimiter({\n windowMs: 15 * 60 * 1000,\n limit: MFA_VERIFICATION_ATTEMPTS_PER_WINDOW,\n keyGenerator: (c) => `mfa-verify:${resolveStepUpPrincipal(c as Context<HonoEnv>)?.uid ?? \"unidentified\"}`,\n message: \"Too many verification attempts for this account, please try again later.\"\n});\n\nexport function mountMfaRoutes(opts: MfaRoutesConfig): void {\n const { router, config, ops, parseBody, buildAuthResponse, createSessionAndTokens, applyTransformHook } = opts;\n const authRepo = config.authRepo;\n const emailConfig = config.emailConfig;\n\n /**\n * Changing which factors an account trusts is itself a privileged act.\n *\n * An account that already has a verified factor may only gain or confirm\n * another one from a session that presented the existing one. Without this\n * the `aal2` gate on unenroll was self-service: an `aal1` session enrolled\n * a factor of its own, verified it with a code it computed from the secret\n * the enrol response had just handed it, stepped up on that, and deleted\n * the victim's real factor — arriving at `aal2` without ever holding the\n * second factor the account was protected by.\n *\n * The first enrolment on an account with no verified factor is deliberately\n * allowed at `aal1`: there is no second factor to demand yet.\n */\n async function requireStepUpForFactorChange(userCtx: AccessTokenPayload): Promise<void> {\n if (userCtx.aal === \"aal2\") return;\n if (!(await authRepo.hasVerifiedMfaFactors(userCtx.uid))) return;\n throw ApiError.forbidden(\n \"This account already has a verified second factor. Re-authenticate with it before changing enrolled factors.\",\n \"AAL2_REQUIRED\"\n );\n }\n\n /**\n * Spend a TOTP time step, or refuse it as already spent.\n *\n * RFC 6238 §5.2: an accepted OTP must not be accepted again. The window\n * that exists for clock drift is also a 90-second replay window, and a\n * replay here is not momentary — `challenge/verify` mints a refresh token,\n * so one observed code buys a durable session.\n */\n async function claimTotpStep(factorId: string, counter: number): Promise<boolean> {\n if (typeof authRepo.claimMfaFactorCounter !== \"function\") {\n logger.warn(\"[MFA] Auth repository cannot record spent TOTP steps; an accepted code stays replayable for its window\", {\n factorId\n });\n return true;\n }\n return authRepo.claimMfaFactorCounter(factorId, counter);\n }\n\n /**\n * POST /auth/mfa/enroll\n * Start MFA enrollment: generate TOTP secret and recovery codes\n */\n router.post(\"/mfa/enroll\", strictAuthLimiter, requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as AccessTokenPayload | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n await requireStepUpForFactorChange(userCtx);\n\n const body = (await c.req.json().catch(() => ({}))) as Record<string, unknown>;\n const friendlyName = typeof body.friendlyName === \"string\" ? body.friendlyName : undefined;\n const issuer = typeof body.issuer === \"string\" ? body.issuer : emailConfig?.appName || \"Rebase\";\n\n // Get user for account name\n const user = await authRepo.getUserById(userCtx.uid);\n if (!user) {\n throw ApiError.notFound(\"User not found\");\n }\n\n // Generate TOTP secret\n const { secret, uri } = generateTotpSecret(issuer, user.email);\n\n // Encrypt the TOTP secret before storage (AES-256-GCM envelope encryption)\n const encryptedSecret = encryptTotpSecret(secret);\n const factor = await authRepo.createMfaFactor(\n user.id,\n \"totp\",\n encryptedSecret,\n friendlyName\n );\n\n // Generate recovery codes\n const codes = generateRecoveryCodes(10);\n const codeHashes = codes.map(hashRecoveryCode);\n await authRepo.createRecoveryCodes(user.id, codeHashes);\n\n return c.json(\n {\n factor: {\n id: factor.id,\n factorType: factor.factorType,\n friendlyName: factor.friendlyName\n },\n totp: {\n secret,\n uri,\n qrUri: uri\n },\n recoveryCodes: codes\n },\n 201\n );\n });\n\n /**\n * POST /auth/mfa/verify\n * Verify TOTP code to complete MFA enrollment\n */\n router.post(\"/mfa/verify\", strictAuthLimiter, requireAuth, mfaVerificationLimiter, async (c) => {\n const userCtx = c.get(\"user\") as AccessTokenPayload | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n await requireStepUpForFactorChange(userCtx);\n\n const verifySchema = z.object({\n factorId: z.string().min(1, \"Factor ID is required\"),\n code: z.string().length(6, \"Code must be 6 digits\")\n });\n const { factorId, code } = parseBody(verifySchema, await c.req.json());\n\n // Get the factor\n const factor = await authRepo.getMfaFactorById(factorId);\n if (!factor || factor.uid !== userCtx.uid) {\n throw ApiError.notFound(\"MFA factor not found\");\n }\n\n if (factor.verified) {\n throw ApiError.badRequest(\"Factor is already verified\", \"ALREADY_VERIFIED\");\n }\n\n // Decrypt and verify the TOTP code\n const decryptedSecret = await openAndRewrap(authRepo, factor.id, factor.secretEncrypted);\n const secretBuffer = base32Decode(decryptedSecret);\n const matchedCounter = verifyTotpCounter(secretBuffer, code);\n\n if (matchedCounter === null || !(await claimTotpStep(factor.id, matchedCounter))) {\n throw ApiError.unauthorized(\"Invalid TOTP code\", \"INVALID_CODE\");\n }\n\n // Mark factor as verified\n await authRepo.verifyMfaFactor(factorId);\n\n return c.json({\n success: true,\n message: \"MFA factor verified and enrolled\"\n });\n });\n\n /**\n * POST /auth/mfa/challenge\n * Open a challenge — either to finish a sign-in that answered\n * `MFA_REQUIRED`, or to step an existing session up to `aal2`.\n */\n router.post(\"/mfa/challenge\", strictAuthLimiter, async (c) => {\n const principal = resolveStepUpPrincipal(c);\n if (!principal) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const challengeSchema = z.object({\n factorId: z.string().min(1, \"Factor ID is required\")\n });\n const { factorId } = parseBody(challengeSchema, await c.req.json());\n\n // Verify the factor belongs to this user and is verified\n const factor = await authRepo.getMfaFactorById(factorId);\n if (!factor || factor.uid !== principal.uid) {\n throw ApiError.notFound(\"MFA factor not found\");\n }\n\n if (!factor.verified) {\n throw ApiError.badRequest(\"MFA factor is not yet verified\", \"FACTOR_NOT_VERIFIED\");\n }\n\n const ipAddress = c.req.header(\"x-forwarded-for\") || \"unknown\";\n const challenge = await authRepo.createMfaChallenge(factorId, ipAddress);\n\n return c.json({\n challengeId: challenge.id,\n factorId: challenge.factorId,\n expiresAt: new Date(Date.now() + 5 * 60 * 1000).toISOString()\n });\n });\n\n /**\n * POST /auth/mfa/challenge/verify\n * Answer a challenge: this is where an MFA-enrolled account's session is\n * minted, at `aal2`.\n */\n router.post(\"/mfa/challenge/verify\", strictAuthLimiter, mfaVerificationLimiter, async (c) => {\n const principal = resolveStepUpPrincipal(c);\n if (!principal) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const challengeVerifySchema = z.object({\n challengeId: z.string().min(1, \"Challenge ID is required\"),\n code: z.string().min(1, \"Code is required\")\n });\n const { challengeId, code } = parseBody(challengeVerifySchema, await c.req.json());\n\n // Find the challenge\n const challenge = await authRepo.getMfaChallengeById(challengeId);\n if (!challenge) {\n throw ApiError.badRequest(\"Invalid or expired challenge\", \"INVALID_CHALLENGE\");\n }\n\n // Get the factor and verify ownership\n const factor = await authRepo.getMfaFactorById(challenge.factorId);\n if (!factor || factor.uid !== principal.uid) {\n throw ApiError.notFound(\"MFA factor not found\");\n }\n\n // A challenge that has already been guessed at its limit is spent, and\n // stays spent for its remaining lifetime — otherwise one open challenge\n // is an unlimited number of guesses at six digits.\n if ((challenge.attempts ?? 0) >= MAX_CHALLENGE_ATTEMPTS) {\n logger.warn(\"[Security Audit] MFA challenge attempt limit reached\", {\n eventType: \"auth.mfa.challenge.exhausted\",\n uid: principal.uid,\n challengeId\n });\n throw ApiError.unauthorized(\"Too many failed attempts for this challenge\", \"CHALLENGE_EXHAUSTED\");\n }\n\n // Try TOTP verification first (standard 6-digit codes)\n const decryptedSecret = await openAndRewrap(authRepo, factor.id, factor.secretEncrypted);\n const secretBuffer = base32Decode(decryptedSecret);\n const matchedCounter = verifyTotpCounter(secretBuffer, code);\n let isValid = matchedCounter !== null && await claimTotpStep(factor.id, matchedCounter);\n\n // Fall back to recovery code verification if TOTP didn't match\n if (!isValid && matchedCounter === null) {\n const codeHash = hashRecoveryCode(code);\n isValid = await authRepo.useRecoveryCode(principal.uid, codeHash);\n }\n\n if (!isValid) {\n const attempts = typeof authRepo.recordMfaChallengeAttempt === \"function\"\n ? await authRepo.recordMfaChallengeAttempt(challengeId)\n : undefined;\n logger.warn(\"[Security Audit] MFA verification failed\", {\n eventType: \"auth.mfa.verify.failure\",\n uid: principal.uid,\n challengeId,\n attempts\n });\n throw ApiError.unauthorized(\"Invalid verification code\", \"INVALID_CODE\");\n }\n\n // Mark challenge as verified\n await authRepo.verifyMfaChallenge(challengeId);\n\n // A fresh authentication opens a fresh session, dated now — which is\n // what lets a later revocation void it. The gate is skipped because\n // this route IS the gate: the second factor was just presented.\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n principal.uid,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\",\n { skipMfaGate: true,\naal: \"aal2\" }\n );\n\n // Fire onMfaVerified hook\n if (ops.onMfaVerified) {\n ops.onMfaVerified(principal.uid, factor.id).catch((err) => {\n logger.error(\"[AuthHooks] onMfaVerified error\", {\n error: err instanceof Error ? err.message : err\n });\n });\n }\n\n logger.info(\"[Security Audit] MFA verification success\", {\n eventType: \"auth.mfa.verify.success\",\n uid: principal.uid,\n factorId: factor.id,\n completedSignIn: principal.pending\n });\n\n // The caller who arrived with a pre-auth token is completing a sign-in\n // and has no user object yet, so return the same payload a login would\n // have returned. Best-effort: a session was minted either way, and\n // failing the response over the enrichment would strand the caller.\n const user = await authRepo.getUserById(principal.uid).catch(() => null);\n let mfaResponse: AuthResponsePayload = user\n ? buildAuthResponse(user, roleIds, accessToken, refreshToken, \"mfa\") as AuthResponsePayload\n : {\n tokens: {\n accessToken,\n refreshToken,\n accessTokenExpiresAt: getAccessTokenExpiry()\n }\n };\n if (applyTransformHook) {\n mfaResponse = await applyTransformHook(mfaResponse, \"mfa\", c.req.raw, principal.uid);\n }\n return c.json(redactRefreshToken(mfaResponse, c, refreshToken, config.cookieAuth));\n });\n\n /**\n * GET /auth/mfa/factors\n * List enrolled MFA factors for the current user\n */\n router.get(\"/mfa/factors\", strictAuthLimiter, requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const factors = await authRepo.getMfaFactors(userCtx.uid);\n return c.json({\n factors: factors.map((f) => ({\n id: f.id,\n factorType: f.factorType,\n friendlyName: f.friendlyName,\n verified: f.verified,\n createdAt: f.createdAt\n }))\n });\n });\n\n /**\n * DELETE /auth/mfa/unenroll\n * Remove an MFA factor\n */\n router.delete(\"/mfa/unenroll\", strictAuthLimiter, requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as AccessTokenPayload | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n // Require aal2 (MFA-verified session) to unenroll MFA factors\n if (userCtx.aal !== \"aal2\") {\n throw ApiError.forbidden(\n \"MFA verification required to unenroll. Please re-authenticate with your second factor.\",\n \"AAL2_REQUIRED\"\n );\n }\n\n const unenrollSchema = z.object({\n factorId: z.string().min(1, \"Factor ID is required\")\n });\n const { factorId } = parseBody(unenrollSchema, await c.req.json());\n\n // Verify ownership\n const factor = await authRepo.getMfaFactorById(factorId);\n if (!factor || factor.uid !== userCtx.uid) {\n throw ApiError.notFound(\"MFA factor not found\");\n }\n\n await authRepo.deleteMfaFactor(factorId, userCtx.uid);\n\n // If no more verified factors, clean up recovery codes\n const hasFactors = await authRepo.hasVerifiedMfaFactors(userCtx.uid);\n if (!hasFactors) {\n await authRepo.deleteAllRecoveryCodes(userCtx.uid);\n }\n\n return c.json({\n success: true,\n message: \"MFA factor removed\"\n });\n });\n}\n","/**\n * The gate between \"first factor accepted\" and \"session issued\".\n *\n * MFA used to be modelled as an optional step-up that no resource required: a\n * user could enrol TOTP, print recovery codes, and change nothing about what a\n * stolen password bought, because every session-minting route issued a full\n * `aal1` token without ever asking whether the account had a second factor.\n * This module is the ask. It lives apart from the routes so that there is one\n * decision, made once, that `createSessionAndTokens` cannot be extended past —\n * a new sign-in route inherits the gate by construction rather than by the\n * author remembering it.\n *\n * @module\n */\n\nimport { ApiError } from \"../api/errors\";\nimport { logger } from \"../utils/logger\";\nimport { generateMfaPendingToken } from \"./jwt\";\nimport type { AuthRepository } from \"./interfaces\";\n\n/** Error code a client watches for to switch a sign-in into its second step. */\nexport const MFA_REQUIRED_CODE = \"MFA_REQUIRED\";\n\n/** Shape carried in `error.details` of an {@link MFA_REQUIRED_CODE} response. */\nexport interface MfaRequiredDetails {\n /**\n * Short-lived, purpose-scoped credential proving the first factor was\n * accepted. It is refused as a session everywhere (`verifyAccessToken`\n * rejects purpose-scoped tokens); `POST /auth/mfa/challenge` and\n * `POST /auth/mfa/challenge/verify` are the only routes that accept it.\n */\n mfaToken: string;\n /** The verified factors the caller may answer the challenge with. */\n factors: Array<{ id: string; factorType: string; friendlyName?: string }>;\n}\n\n/**\n * Refuse to mint a session for an account whose second factor has not been\n * presented, handing back what the client needs to present it.\n *\n * A 401 rather than a 200 with a different body: a client that has not been\n * taught about MFA must fail, not proceed. The credential in `details` is\n * useless for anything except the challenge routes.\n */\nexport async function assertMfaSatisfied(authRepo: AuthRepository, uid: string): Promise<void> {\n if (typeof authRepo.hasVerifiedMfaFactors !== \"function\") {\n // A custom repository from before MFA existed. It cannot hold a factor\n // either, so there is nothing to enforce — but say so once, because a\n // repository that *does* have factors and no way to report them would\n // be a silent bypass.\n logger.warn(\"[MFA] Auth repository cannot report enrolled factors; the login step-up gate is inert on this backend\");\n return;\n }\n\n if (!(await authRepo.hasVerifiedMfaFactors(uid))) return;\n\n const factors = (await authRepo.getMfaFactors(uid)).filter(f => f.verified);\n const details: MfaRequiredDetails = {\n mfaToken: generateMfaPendingToken(uid),\n factors: factors.map(f => ({ id: f.id,\nfactorType: f.factorType,\nfriendlyName: f.friendlyName }))\n };\n\n logger.info(\"[Security Audit] MFA step-up required\", {\n eventType: \"auth.mfa.required\",\n uid\n });\n\n throw new ApiError(\n 401,\n MFA_REQUIRED_CODE,\n \"Multi-factor authentication is required to complete sign-in.\",\n details,\n // Routine: every sign-in by an enrolled user takes this path.\n true\n );\n}\n","/**\n * Whether a registration may proceed — computed in exactly one place.\n *\n * This predicate had drifted across three independent implementations, which is\n * the shape the bug always takes: one endpoint *advertises* that registration is\n * open, another *enforces* that it is closed, and the user lands on a form that\n * can only ever 403.\n *\n * 1. `POST /auth/register` (routes.ts) — enforces.\n * 2. `GET /auth/config` (session-routes.ts) — advertises.\n * 3. `getCapabilities()` (builtin-auth-adapter.ts) — also advertises, and is\n * the one that actually answers `GET /auth/config` on a real backend:\n * `init.ts` registers that path directly *before* mounting the auth router,\n * so Hono resolves it first and the session-routes copy never runs for it.\n *\n * Two of the three had already been fixed for the empty-database case when the\n * third was still returning `allowRegistration || needsSetup` — missing the kill\n * switch entirely. The fix is not to correct the third copy but to delete all\n * three: every caller now goes through this function, so the next term added\n * here reaches every surface at once.\n *\n * The rule itself:\n *\n * - `disableSelfRegistration` is absolute. It blocks even the first user, for\n * operators who provision accounts out of band and never want a public\n * first-come-first-admin window.\n * - Otherwise an **empty** user table always admits the first registration,\n * which auto-promotes to admin. Without this a backend deployed with\n * `allowRegistration: false` is a dead end: `POST /admin/bootstrap` needs an\n * authenticated caller, and an empty database cannot produce one.\n * - Otherwise `allowRegistration` decides, as it always did.\n */\nexport interface RegistrationPolicy {\n /** The hard kill switch. Blocks registration including first-user bootstrap. */\n disableSelfRegistration?: boolean;\n /** Steady-state self-registration, once at least one user exists. */\n allowRegistration?: boolean;\n /**\n * True when the user table is empty — the bootstrap window.\n *\n * Callers that already know this (the config endpoints compute it to report\n * `needsSetup`) pass it directly. `POST /auth/register` must not: it serves\n * anonymous callers, so it checks {@link isSteadyStateRegistrationOpen}\n * first and only pays for the count when that says no.\n */\n needsSetup: boolean;\n}\n\n/** The full predicate, for callers that already know whether setup is needed. */\nexport function isRegistrationOpen(policy: RegistrationPolicy): boolean {\n if (policy.disableSelfRegistration) return false;\n return policy.needsSetup || !!policy.allowRegistration;\n}\n\n/**\n * The same predicate with the bootstrap window assumed closed.\n *\n * Exists so `POST /auth/register` can reject the common case without counting\n * rows. A `false` here does **not** mean \"refuse\" — it means \"the answer depends\n * on whether the table is empty, so now go and look\".\n */\nexport function isSteadyStateRegistrationOpen(\n policy: Omit<RegistrationPolicy, \"needsSetup\">\n): boolean {\n return isRegistrationOpen({ ...policy, needsSetup: false });\n}\n\n/**\n * Whether `POST /auth/anonymous` may mint a user.\n *\n * Anonymous sign-in *is* registration: it inserts a `users` row and assigns\n * `defaultRole` exactly as `POST /auth/register` does. It simply never asked.\n * Both anonymous routes were mounted unconditionally and consulted none of the\n * gates above, so a backend with `allowRegistration: false` **and**\n * `disableSelfRegistration: true` — the documented hard kill switch — still\n * handed a permanent account to any caller in two unauthenticated requests:\n * `POST /auth/anonymous` for the row and the session, then\n * `POST /auth/anonymous/link` to put an email and password on it.\n *\n * Two terms, because the two questions are genuinely different:\n *\n * - `allowAnonymous` is the feature switch, and it is **opt-in**. There was no\n * key at all before, so a deployment could not turn anonymous auth off even\n * after finding it on; defaulting it to `true` here would keep that hole\n * open for everyone who never learns the key exists.\n * - `disableSelfRegistration` still wins over it. Its docstring calls it a\n * hard kill switch that blocks \"self-registration outright\", and an account\n * created without credentials is still an account created by the public.\n * An operator who sets both gets the kill switch they asked for.\n *\n * `allowRegistration` deliberately does **not** gate this. A public read-mostly\n * app that wants anonymous sessions but no sign-up forms is a real deployment,\n * and `allowAnonymous: true` says so precisely.\n */\nexport function isAnonymousAuthOpen(policy: {\n allowAnonymous?: boolean;\n disableSelfRegistration?: boolean;\n}): boolean {\n if (policy.disableSelfRegistration) return false;\n return !!policy.allowAnonymous;\n}\n","import { Hono } from \"hono\";\nimport { normalizeEmail } from \"@rebasepro/common\";\nimport { z } from \"zod\";\nimport { randomBytes } from \"crypto\";\nimport { ApiError } from \"../api/errors\";\nimport { HonoEnv } from \"../api/types\";\nimport { requireAuth } from \"./middleware\";\nimport { extractBearerToken } from \"./bearer-token\";\nimport { logger } from \"../utils/logger\";\nimport { strictAuthLimiter, defaultAuthLimiter } from \"./rate-limiter\";\nimport { hashRefreshToken } from \"./jwt\";\nimport type { AuthModuleConfig } from \"./routes\";\nimport type { AuthResponsePayload, TransformAuthResponseContext } from \"@rebasepro/types\";\nimport { readRefreshToken, clearRefreshCookie } from \"./cookie-utils\";\nimport { isAnonymousAuthOpen, isRegistrationOpen } from \"./registration-policy\";\nimport type { resolveAuthHooks } from \"./auth-hooks\";\nimport type { CreateUserData } from \"./interfaces\";\n\ninterface SessionRoutesConfig {\n router: Hono<HonoEnv>;\n config: AuthModuleConfig;\n ops: ReturnType<typeof resolveAuthHooks>;\n parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T;\n buildAuthResponse: (\n user: { id: string; email: string; displayName?: string | null; photoUrl?: string | null; emailVerified?: boolean; isAnonymous?: boolean; metadata?: Record<string, unknown> | null },\n roleIds: string[],\n accessToken: string,\n refreshToken: string,\n providerId: string\n ) => unknown;\n createSessionAndTokens: (uid: string, userAgent: string, ipAddress: string) => Promise<{\n roleIds: string[];\n accessToken: string;\n refreshToken: string;\n }>;\n applyTransformHook: (\n response: AuthResponsePayload,\n method: TransformAuthResponseContext[\"method\"],\n request: Request,\n uid: string\n ) => Promise<AuthResponsePayload>;\n}\n\nexport function mountSessionRoutes(opts: SessionRoutesConfig): void {\n const { router, config, ops, parseBody, buildAuthResponse, createSessionAndTokens, applyTransformHook } = opts;\n const authRepo = config.authRepo;\n\n /**\n * Refuse the anonymous routes unless the deployment opted in.\n *\n * 403 rather than 404: the route exists, and a client that was told\n * `anonymousLogin: true` by `GET /auth/config` and then sees a 404 has no\n * way to tell a disabled feature from a version skew. The error names the\n * key, because the failure this closes was an operator believing they had\n * already switched registration off.\n */\n function assertAnonymousAuthOpen(): void {\n if (isAnonymousAuthOpen({\n allowAnonymous: config.allowAnonymous,\n disableSelfRegistration: config.disableSelfRegistration\n })) return;\n throw ApiError.forbidden(\n config.disableSelfRegistration\n ? \"Anonymous sign-in is disabled: disableSelfRegistration blocks it.\"\n : \"Anonymous sign-in is disabled. Set `auth.allowAnonymous: true` to enable it.\",\n \"ANONYMOUS_AUTH_DISABLED\"\n );\n }\n\n const logoutSchema = z.object({\n refreshToken: z.string().optional()\n });\n\n const linkSchema = z.object({\n email: z.string().email(\"Invalid email address\").max(255),\n password: z.string().min(1, \"Password is required\").max(128)\n });\n\n const updateProfileSchema = z.object({\n displayName: z.string().max(255).optional(),\n photoURL: z.string().url().max(2048).optional()\n });\n\n const findUserSchema = z.object({\n email: z.string().email(\"Invalid email address\").max(255)\n });\n\n const isEmailConfigured = () => !!(config.emailService && config.emailService.isConfigured());\n\n /**\n * POST /auth/logout\n */\n router.post(\"/logout\", async (c) => {\n const body = await c.req.json().catch(() => ({}));\n const parsed = parseBody(logoutSchema, body);\n const refreshToken = readRefreshToken(c, parsed, config.cookieAuth);\n\n if (refreshToken) {\n const tokenHash = hashRefreshToken(refreshToken);\n // Kill the whole sign-in, not just the token that happened to be\n // presented. Rotation can leave siblings alive (a second tab, a\n // replay inside the reuse window), and deleting one row would\n // leave the others perfectly usable — a logout that does not log\n // you out is worse than no logout at all.\n const stored = await authRepo.findRefreshTokenByHash(tokenHash).catch(() => null);\n const sessionId = stored?.sessionId;\n if (sessionId && authRepo.revokeRefreshTokenSession) {\n await authRepo.revokeRefreshTokenSession(sessionId);\n } else {\n await authRepo.deleteRefreshToken(tokenHash);\n }\n }\n\n // Always clear the cookie if in cookie mode\n clearRefreshCookie(c, config.cookieAuth);\n\n // Call afterLogout hook (fire-and-forget)\n // Extract uid from the access token if present\n const accessToken = extractBearerToken(c.req.header(\"authorization\"));\n if (ops.afterLogout && accessToken !== undefined) {\n const { verifyAccessToken } = await import(\"./jwt\");\n const payload = verifyAccessToken(accessToken);\n if (payload) {\n ops.afterLogout(payload.uid).catch((err: unknown) => {\n logger.error(\"[AuthHooks] afterLogout error\", {\n error: err instanceof Error ? err.message : err\n });\n });\n }\n }\n\n return c.json({ success: true });\n });\n\n /**\n * GET /auth/sessions\n * Get active refresh tokens (sessions) for the current user\n */\n router.get(\"/sessions\", requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const currentRefreshToken = c.req.header(\"x-refresh-token\") as string;\n const currentTokenHash = currentRefreshToken ? hashRefreshToken(currentRefreshToken) : null;\n\n const tokens = await authRepo.listRefreshTokensForUser(userCtx.uid);\n\n // One entry per SIGN-IN, not per token row. Rotation leaves several\n // rows behind for one session (the live token, its superseded parent\n // inside the reuse window, a sibling minted for a second tab), and a\n // user reading \"your devices\" must not be shown three copies of the\n // laptop they are sitting at. Revoked rows are tombstones and never\n // appear at all.\n const bySession = new Map<string, typeof tokens[number]>();\n for (const token of tokens) {\n if (token.revoked) continue;\n const key = token.sessionId ?? token.id;\n const existing = bySession.get(key);\n // Keep the newest row of the session as its representative, so the\n // id offered for revocation belongs to a token that still exists.\n if (!existing || existing.createdAt < token.createdAt) bySession.set(key, token);\n }\n\n const mappedSessions = [...bySession.values()].map((s) => ({\n id: s.id,\n userAgent: s.userAgent,\n ipAddress: s.ipAddress,\n // The sign-in, not the last rotation — otherwise every session\n // looks like it started an hour ago, whatever its real age.\n createdAt: s.sessionStartedAt ?? s.createdAt,\n isCurrentSession: currentTokenHash\n ? tokens.some(t => t.tokenHash === currentTokenHash && (t.sessionId ?? t.id) === (s.sessionId ?? s.id))\n : false\n }));\n\n return c.json({ sessions: mappedSessions });\n });\n\n /**\n * DELETE /auth/sessions\n * Delete all refresh tokens for the current user (remote logout every device)\n */\n router.delete(\"/sessions\", requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n await authRepo.deleteAllRefreshTokensForUser(userCtx.uid);\n // Belt and braces: a refresh already in flight can insert a rotated\n // token a moment after the delete has run and walk away with a live\n // session. The watermark voids it on its next use.\n await authRepo.setTokensValidAfter?.(userCtx.uid, new Date()).catch(() => undefined);\n return c.json({\n success: true,\n message: \"All sessions revoked successfully\"\n });\n });\n\n /**\n * DELETE /auth/sessions/:id\n * Delete a specific refresh token (remote logout)\n */\n router.delete(\"/sessions/:id\", requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const id = c.req.param(\"id\");\n if (!id) {\n throw ApiError.badRequest(\"Session ID is required\", \"INVALID_INPUT\");\n }\n\n // The id names one token row, but the user is revoking a device — so\n // resolve it to its session and take the whole family down. Deleting\n // the single row would leave that device holding a live sibling.\n const owned = await authRepo.listRefreshTokensForUser(userCtx.uid).catch(() => []);\n const target = owned.find(t => t.id === id);\n if (target?.sessionId && authRepo.revokeRefreshTokenSession) {\n await authRepo.revokeRefreshTokenSession(target.sessionId);\n } else {\n await authRepo.deleteRefreshTokenById(id, userCtx.uid);\n }\n return c.json({\n success: true,\n message: \"Session revoked successfully\"\n });\n });\n\n /**\n * GET /auth/me\n * Get current authenticated user\n */\n router.get(\"/me\", requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const result = await authRepo.getUserWithRoles(userCtx.uid);\n if (!result) {\n throw ApiError.notFound(\"User not found\");\n }\n\n return c.json({\n user: {\n uid: result.user.id,\n email: result.user.email,\n displayName: result.user.displayName,\n photoURL: result.user.photoUrl,\n providerId: \"password\",\n isAnonymous: result.user.isAnonymous ?? false,\n emailVerified: result.user.emailVerified,\n roles: result.roles.map((r) => r.id),\n metadata: result.user.metadata ?? {}\n }\n });\n });\n\n /**\n * POST /auth/find-user\n * Resolve an email to a MINIMAL public profile (uid, displayName, photoURL).\n * Opt-in (`auth.allowUserLookup`) and authenticated-only — powers\n * invite-by-email flows without exposing the users table or a custom admin\n * server function. Never returns the email, roles, metadata, or any other\n * field of the looked-up user.\n */\n if (config.allowUserLookup) {\n router.post(\"/find-user\", defaultAuthLimiter, requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n const { email } = parseBody(findUserSchema, await c.req.json());\n const user = await authRepo.getUserByEmail(normalizeEmail(email));\n return c.json({\n user: user\n ? { uid: user.id, displayName: user.displayName ?? null, photoURL: user.photoUrl ?? null }\n : null\n });\n });\n }\n\n /**\n * PATCH /auth/me\n * Update current authenticated user profile\n */\n router.patch(\"/me\", requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const { displayName, photoURL } = parseBody(updateProfileSchema, await c.req.json());\n\n const updatedUser = await authRepo.updateUser(userCtx.uid, {\n displayName: displayName !== undefined ? displayName : undefined,\n photoUrl: photoURL !== undefined ? photoURL : undefined\n });\n\n if (!updatedUser) {\n throw ApiError.notFound(\"User not found\");\n }\n\n const result = await authRepo.getUserWithRoles(userCtx.uid);\n if (!result) {\n throw ApiError.notFound(\"User not found\");\n }\n\n return c.json({\n user: {\n uid: result.user.id,\n email: result.user.email,\n displayName: result.user.displayName,\n photoURL: result.user.photoUrl,\n providerId: \"password\",\n isAnonymous: result.user.isAnonymous ?? false,\n emailVerified: result.user.emailVerified,\n roles: result.roles.map((r) => r.id),\n metadata: result.user.metadata ?? {}\n }\n });\n });\n\n /**\n * GET /auth/config\n * Get public auth configuration.\n *\n * ⚠️ SHADOWED on a backend booted through `initializeRebaseBackend`.\n * `init.ts` registers `${basePath}/auth/config` directly and only mounts\n * this router afterwards, so Hono resolves that registration first and this\n * handler never runs. The live implementation is `getCapabilities()` in\n * `builtin-auth-adapter.ts`.\n *\n * Both return `needsSetup` and `registrationEnabled`, so the response shape\n * cannot tell them apart — which is how a fix for the empty-database dead\n * end was once applied here, to no effect, while the live copy kept\n * advertising the wrong answer. `bootstrap-e2e.test.ts` pins which handler\n * actually answers.\n *\n * It is kept because this router is also mounted standalone (tests, and any\n * embedder that wires `createAuthRoutes` without init.ts). If you change the\n * registration rule, change it in `registration-policy.ts` — both callers\n * read it from there, so neither can drift again.\n */\n router.get(\"/config\", defaultAuthLimiter, async (c) => {\n let needsSetup: boolean;\n if (config.isBootstrapCompleted) {\n needsSetup = !(await config.isBootstrapCompleted());\n } else {\n const allUsers = await authRepo.listUsers();\n needsSetup = allUsers.length === 0;\n }\n\n // Shared with the POST /auth/register gate and with getCapabilities(),\n // so what is advertised here and what is enforced there cannot drift.\n // Advertising anything else sends the UI to a form that can only 403.\n const registrationAllowed = isRegistrationOpen({\n disableSelfRegistration: config.disableSelfRegistration,\n allowRegistration: config.allowRegistration,\n needsSetup\n });\n const enabledProviders = (config.oauthProviders || []).map((p) => p.id);\n\n return c.json({\n needsSetup,\n registrationEnabled: registrationAllowed,\n emailServiceEnabled: isEmailConfigured(),\n magicLinkEnabled: !!config.enableMagicLink && isEmailConfigured(),\n // A capability that exists and is not in the capability surface is\n // how a client ends up calling a route it cannot discover is off.\n anonymousLoginEnabled: isAnonymousAuthOpen({\n allowAnonymous: config.allowAnonymous,\n disableSelfRegistration: config.disableSelfRegistration\n }),\n enabledProviders\n });\n });\n\n /**\n * POST /auth/anonymous\n * Create an anonymous user with temporary credentials\n */\n router.post(\"/anonymous\", strictAuthLimiter, async (c) => {\n assertAnonymousAuthOpen();\n\n // `email` is NOT NULL, so an anonymous user needs a synthetic address —\n // and it lands under a unique index, which makes the width of this\n // string a correctness property rather than cosmetics. It used to keep 8\n // of the 32 hex characters generated here: a 2^32 space, where a\n // collision is ~1% likely by 9,000 anonymous users and ~50% by 77,000,\n // surfacing as an unexplained 500 on sign-in for one unlucky visitor.\n // The entropy was already generated; there was no reason to discard it.\n const anonEmail = `anon_${randomBytes(16).toString(\"hex\")}@anonymous.local`;\n\n let createData: CreateUserData = {\n email: anonEmail,\n emailVerified: false,\n isAnonymous: true\n };\n\n if (ops.beforeUserCreate) {\n createData = await ops.beforeUserCreate(createData);\n }\n\n const user = await authRepo.createUser(createData);\n\n // Assign default role (follow register route pattern, but never auto-admin)\n if (config.defaultRole) {\n await authRepo.assignDefaultRole(user.id, config.defaultRole);\n }\n\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n user.id,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\"\n );\n\n // Fire afterUserCreate hook\n if (ops.afterUserCreate) {\n ops.afterUserCreate(user).catch((err: unknown) => {\n logger.error(\"[AuthHooks] afterUserCreate error\", {\n error: err instanceof Error ? err.message : err\n });\n });\n }\n\n // Fire onAuthenticated hook\n if (ops.onAuthenticated) {\n ops.onAuthenticated(user, \"anonymous\").catch((err: unknown) => {\n logger.error(\"[AuthHooks] onAuthenticated error\", {\n error: err instanceof Error ? err.message : err\n });\n });\n }\n\n const authResponse = buildAuthResponse(user, roleIds, accessToken, refreshToken, \"anonymous\") as AuthResponsePayload;\n const finalResponse = await applyTransformHook(authResponse, \"anonymous\", c.req.raw, user.id);\n return c.json(finalResponse, 201);\n });\n\n /**\n * POST /auth/anonymous/link\n * Upgrade an anonymous user to a permanent account with email/password\n */\n router.post(\"/anonymous/link\", strictAuthLimiter, requireAuth, async (c) => {\n // Gated on the same predicate as `/anonymous`, not on registration: this\n // route cannot create an account, only put credentials on one that\n // `/anonymous` already made. If anonymous auth is off, any session\n // reaching here predates the switch, and letting it finish would be a\n // second way to reach the state the switch exists to prevent.\n assertAnonymousAuthOpen();\n\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const user = await authRepo.getUserById(userCtx.uid);\n if (!user?.isAnonymous) {\n throw ApiError.badRequest(\"User is not anonymous\", \"NOT_ANONYMOUS\");\n }\n\n const { email, password } = parseBody(linkSchema, await c.req.json());\n\n // Validate password strength\n const passwordValidation = ops.validatePasswordStrength(password);\n if (!passwordValidation.valid) {\n throw ApiError.badRequest(passwordValidation.errors.join(\". \"), \"WEAK_PASSWORD\");\n }\n\n // Check if email is already taken\n const existingUser = await authRepo.getUserByEmail(normalizeEmail(email));\n if (existingUser) {\n throw ApiError.conflict(\"Email already registered\", \"EMAIL_EXISTS\");\n }\n\n // Hash password\n const passwordHash = await ops.hashPassword(password);\n\n // Update user: set email, password, remove anonymous flag\n const updatedUser = await authRepo.updateUser(user.id, {\n email: normalizeEmail(email),\n passwordHash,\n isAnonymous: false\n });\n\n if (!updatedUser) {\n throw ApiError.notFound(\"User not found\");\n }\n\n // Generate new tokens with updated identity\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n user.id,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\"\n );\n\n const authResponse = buildAuthResponse(updatedUser, roleIds, accessToken, refreshToken, \"password\") as AuthResponsePayload;\n const finalResponse = await applyTransformHook(authResponse, \"anonymous\", c.req.raw, user.id);\n return c.json(finalResponse);\n });\n}\n","import { Hono } from \"hono\";\nimport type { AuthModuleConfig } from \"./routes\";\nimport type { ResolvedAuthHooks } from \"./auth-hooks\";\nimport type { HonoEnv } from \"../api/types\";\nimport { ApiError } from \"../api/errors\";\nimport { generateSecureToken, hashToken } from \"./admin-user-ops\";\nimport { getMagicLinkTemplate } from \"../email/templates\";\nimport { resolveEmailLinkBase } from \"../email/link-base\";\nimport { strictAuthLimiter } from \"./rate-limiter\";\nimport { z } from \"zod\";\nimport { logger } from \"../utils/logger\";\nimport type { AuthResponsePayload, TransformAuthResponseContext } from \"@rebasepro/types\";\n\n/**\n * Magic link token expiry (15 minutes from now)\n */\nfunction getMagicLinkExpiry(): Date {\n return new Date(Date.now() + 15 * 60 * 1000);\n}\n\n/**\n * Mount magic link routes onto the auth router.\n *\n * Follows the same delegation pattern as `mountMfaRoutes()` and `mountSessionRoutes()`.\n */\nexport function mountMagicLinkRoutes(deps: {\n router: Hono<HonoEnv>;\n config: AuthModuleConfig;\n ops: ResolvedAuthHooks;\n parseBody: <T>(schema: z.ZodSchema<T>, body: unknown) => T;\n buildAuthResponse: (\n user: { id: string; email: string; displayName?: string | null; photoUrl?: string | null; emailVerified?: boolean; isAnonymous?: boolean; metadata?: Record<string, unknown> | null },\n roleIds: string[],\n accessToken: string,\n refreshToken: string,\n providerId: string\n ) => unknown;\n createSessionAndTokens: (uid: string, userAgent: string, ipAddress: string) => Promise<{ roleIds: string[]; accessToken: string; refreshToken: string }>;\n applyTransformHook: (\n response: AuthResponsePayload,\n method: TransformAuthResponseContext[\"method\"],\n request: Request,\n uid: string\n ) => Promise<AuthResponsePayload>;\n}) {\n const { router, config, ops, parseBody, buildAuthResponse, createSessionAndTokens, applyTransformHook } = deps;\n const { authRepo, emailService, emailConfig } = config;\n\n const magicLinkSchema = z.object({\n email: z.string().email(\"Invalid email address\").max(255)\n });\n\n const verifyMagicLinkSchema = z.object({\n token: z.string().min(1, \"Token is required\")\n });\n\n function isEmailConfigured(): boolean {\n return !!(emailService && emailService.isConfigured());\n }\n\n /**\n * POST /auth/magic-link\n * Request a magic link email\n */\n router.post(\"/magic-link\", strictAuthLimiter, async (c) => {\n const { email } = parseBody(magicLinkSchema, await c.req.json());\n\n // Require email service\n if (!isEmailConfigured()) {\n throw ApiError.serviceUnavailable(\"Email service not configured. Magic link login is not available.\", \"EMAIL_NOT_CONFIGURED\");\n }\n\n // Always return success (security: don't reveal if email exists)\n const user = await authRepo.getUserByEmail(email);\n\n if (user) {\n // Call beforeLogin hook if provided (throw to reject)\n if (ops.beforeLogin) {\n await ops.beforeLogin(email, \"magic-link\");\n }\n\n // Generate magic link token\n const token = generateSecureToken();\n const tokenHash = hashToken(token);\n const expiresAt = getMagicLinkExpiry();\n\n await authRepo.createMagicLinkToken(user.id, tokenHash, expiresAt);\n\n // Build magic link URL\n const baseUrl = resolveEmailLinkBase(emailConfig, \"magicLink\");\n const magicLinkUrl = `${baseUrl}/auth/magic-link?token=${token}`;\n\n // Get email template\n const appName = emailConfig?.appName || \"Rebase\";\n const templateFn = emailConfig?.templates?.magicLink;\n const emailContent = templateFn\n ? templateFn(magicLinkUrl, { email: user.email, displayName: user.displayName })\n : getMagicLinkTemplate(magicLinkUrl, { email: user.email, displayName: user.displayName }, appName);\n\n // Send email\n try {\n await emailService!.send({\n to: user.email,\n subject: emailContent.subject,\n html: emailContent.html,\n text: emailContent.text\n });\n } catch (emailError: unknown) {\n logger.error(\"Failed to send magic link email\", { error: emailError instanceof Error ? emailError.message : emailError });\n // Don't reveal email sending failure to client\n }\n }\n\n // Always return success\n return c.json({\n success: true,\n message: \"If an account with that email exists, a magic link has been sent.\"\n });\n });\n\n /**\n * POST /auth/magic-link/verify\n * Verify magic link token and create session\n */\n router.post(\"/magic-link/verify\", strictAuthLimiter, async (c) => {\n const { token } = parseBody(verifyMagicLinkSchema, await c.req.json());\n\n // Find valid token\n const tokenHash = hashToken(token);\n const storedToken = await authRepo.findValidMagicLinkToken(tokenHash);\n\n if (!storedToken) {\n throw ApiError.badRequest(\"Invalid or expired magic link\", \"INVALID_TOKEN\");\n }\n\n // Mark token as used (one-time use)\n await authRepo.markMagicLinkTokenUsed(tokenHash);\n\n // Get user\n const user = await authRepo.getUserById(storedToken.uid);\n if (!user) {\n throw ApiError.badRequest(\"Invalid or expired magic link\", \"INVALID_TOKEN\");\n }\n\n // Clicking a magic link proves email ownership — auto-verify\n if (!user.emailVerified) {\n await authRepo.setEmailVerified(user.id, true);\n user.emailVerified = true;\n }\n\n // Create session\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n user.id,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\"\n );\n\n // Fire onAuthenticated hook (fire-and-forget)\n if (ops.onAuthenticated) {\n ops.onAuthenticated(user, \"magic-link\").catch(err => {\n logger.error(\"[AuthHooks] onAuthenticated error\", { error: err instanceof Error ? err.message : err });\n });\n }\n\n const authResponse = buildAuthResponse(user, roleIds, accessToken, refreshToken, \"magic-link\") as AuthResponsePayload;\n const finalResponse = await applyTransformHook(authResponse, \"magic-link\", c.req.raw, user.id);\n return c.json(finalResponse);\n });\n}\n","/**\n * The two decisions the OAuth sign-in route makes before it will hand a caller\n * an existing account, extracted so they are stated once for all twelve\n * providers and can be tested without a provider, a network or a database.\n */\n\n/** Why an incoming OAuth identity may not be auto-attached to an existing account. */\nexport type AutoLinkRefusal =\n /** The provider did not report that it verified the address. */\n | \"provider-email-unverified\"\n /**\n * The local account holds a password nobody ever proved they own: it was\n * created through `POST /auth/register`, which does not verify the\n * address. Attaching a provider identity to it would hand the session to\n * whoever registered the address first — the classic pre-hijack.\n */\n | \"local-account-unverified\";\n\nexport type AutoLinkDecision =\n | { allowed: true }\n | { allowed: false; reason: AutoLinkRefusal };\n\n/** The part of an existing user row the decision depends on. */\nexport interface AutoLinkExistingUser {\n emailVerified: boolean;\n passwordHash?: string | null;\n}\n\n/**\n * May an OAuth identity be attached to a pre-existing account found *by email*?\n *\n * Both sides have to be trustworthy, and only one of them used to be checked:\n *\n * - the **provider** must have verified the address, or the caller has not\n * shown they control it;\n * - the **local account** must itself be trustworthy — either its address was\n * verified, or it has no password at all (it was created by an OAuth\n * sign-in or an invitation, so there is no credential an attacker could\n * have planted in advance).\n *\n * A refusal is not a dead end: `POST /auth/link/<provider>` attaches the\n * identity once the caller proves ownership by holding a session.\n */\nexport function decideOAuthAutoLink(args: {\n providerEmailVerified: boolean | undefined;\n existingUser: AutoLinkExistingUser;\n}): AutoLinkDecision {\n if (args.providerEmailVerified !== true) {\n return { allowed: false, reason: \"provider-email-unverified\" };\n }\n const hasPassword = Boolean(args.existingUser.passwordHash);\n if (hasPassword && !args.existingUser.emailVerified) {\n return { allowed: false, reason: \"local-account-unverified\" };\n }\n return { allowed: true };\n}\n\n/**\n * Is `redirectUri` one the operator authorised?\n *\n * The provider's own registered-URI match is a real control but a coarse one:\n * it authorises *every* URI registered on that OAuth client, so a `localhost`\n * entry kept for development, or a second product sharing the client id, can\n * mint codes this backend accepts. An empty or absent allowlist keeps the old\n * behaviour (the provider's check is the only one) so existing deployments are\n * unaffected; setting one narrows it to the origins this backend serves.\n *\n * Comparison is on origin plus path, with the origin lowercased and a trailing\n * slash ignored — query strings and fragments are not part of the identity of a\n * redirect URI, and neither is the case of the host.\n */\nexport function isRedirectUriAllowed(redirectUri: string, allowlist?: string[]): boolean {\n if (!allowlist || allowlist.length === 0) return true;\n const candidate = canonicalRedirectUri(redirectUri);\n if (!candidate) return false;\n return allowlist.some((allowed) => canonicalRedirectUri(allowed) === candidate);\n}\n\nfunction canonicalRedirectUri(uri: string): string | null {\n let parsed: URL;\n try {\n parsed = new URL(uri);\n } catch {\n return null;\n }\n const path = parsed.pathname.replace(/\\/+$/, \"\");\n return `${parsed.protocol.toLowerCase()}//${parsed.host.toLowerCase()}${path}`;\n}\n","import { Hono } from \"hono\";\nimport { ADMINISTRATIVE_ROLES, isAdministrativeRole } from \"./admin-roles\";\nimport { normalizeEmail } from \"@rebasepro/common\";\nimport { ApiError, errorHandler } from \"../api/errors\";\nimport { randomBytes, randomUUID } from \"crypto\";\nimport { generateSecureToken, hashToken } from \"./admin-user-ops\";\nimport type { AuthRepository, OAuthProvider, CreateUserData } from \"./interfaces\";\nimport { generateAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry } from \"./jwt\";\nimport type { AuthHooks } from \"./auth-hooks\";\nimport { resolveAuthHooks } from \"./auth-hooks\";\nimport { requireAuth } from \"./middleware\";\nimport { EmailService, EmailConfig, resolveEmailLinkBase } from \"../email\";\nimport { getPasswordResetTemplate, getEmailVerificationTemplate, getWelcomeEmailTemplate } from \"../email/templates\";\nimport { HonoEnv } from \"../api/types\";\nimport { defaultAuthLimiter, strictAuthLimiter, verificationEmailLimiter } from \"./rate-limiter\";\nimport { z } from \"zod\";\nimport { logger } from \"../utils/logger\";\nimport { mountMfaRoutes } from \"./mfa-routes\";\nimport { assertMfaSatisfied } from \"./mfa-gate\";\nimport { mountSessionRoutes } from \"./session-routes\";\nimport { mountMagicLinkRoutes } from \"./magic-link-routes\";\nimport { isSteadyStateRegistrationOpen } from \"./registration-policy\";\nimport { decideOAuthAutoLink, isRedirectUriAllowed } from \"./oauth-signin-policy\";\nimport type { AuthResponsePayload, TransformAuthResponseContext } from \"@rebasepro/types\";\nimport type { Context } from \"hono\";\nimport { readRefreshToken, redactRefreshToken, clearRefreshCookie } from \"./cookie-utils\";\n\n/**\n * Shared configuration for auth and admin route factories.\n */\nexport interface AuthModuleConfig {\n authRepo: AuthRepository;\n emailService?: EmailService;\n emailConfig?: EmailConfig;\n /** Allow new user registration (default: false). */\n allowRegistration?: boolean;\n /** Expose the authenticated email→minimal-profile lookup route (default: false). */\n allowUserLookup?: boolean;\n /** Default role ID to assign to new users (default: none). Must NOT be \"admin\". */\n defaultRole?: string;\n /** Optional array of OAuth providers */\n oauthProviders?: OAuthProvider<unknown>[];\n /**\n * Redirect URIs the OAuth routes will accept, for every provider.\n *\n * Left unset, the only check is the provider's own registered-URI match,\n * which authorises every URI registered on that OAuth client. Compared on\n * origin plus path; query and fragment are ignored, as is a trailing slash.\n */\n allowedRedirectUris?: string[];\n /** When true, blocks all self-registration regardless of `allowRegistration`. */\n disableSelfRegistration?: boolean;\n /**\n * Opt-in: allow `POST /auth/anonymous` to mint a user without credentials.\n *\n * Off by default. See {@link isAnonymousAuthOpen} for why this is opt-in\n * rather than opt-out, and why `disableSelfRegistration` overrides it.\n */\n allowAnonymous?: boolean;\n /**\n * Auth hooks for customizing password hashing, credential\n * verification, lifecycle hooks, etc.\n */\n authHooks?: AuthHooks;\n /**\n * Callback that checks if bootstrap has already been completed.\n * Used by GET /auth/config to report `needsSetup` status.\n * When not provided, falls back to checking if any users exist.\n */\n isBootstrapCompleted?: () => Promise<boolean>;\n /** Enable magic link (passwordless email) login. Requires email service. */\n enableMagicLink?: boolean;\n /**\n * Opt-in httpOnly cookie mode for refresh tokens.\n *\n * When set, the refresh token is delivered as an `httpOnly`, `Secure`,\n * `SameSite` cookie instead of in the JSON response body. This\n * prevents XSS from stealing the long-lived refresh token.\n *\n * The access token remains in the JSON body so the client can use it\n * in `Authorization: Bearer` headers for API calls.\n *\n * **Requires** `credentials: \"include\"` on client-side fetch calls to\n * auth endpoints, and CORS must allow credentials (no `origin: \"*\"`).\n */\n cookieAuth?: CookieAuthConfig;\n /**\n * How long a refresh token stays usable after it has been rotated away,\n * in seconds. Default 10, matching GoTrue's `refresh_token_reuse_interval`.\n *\n * Rotation is only safe if the client is guaranteed to receive the\n * replacement, and no network guarantees that. A pod rolls mid-response, a\n * laptop suspends, a second tab boots at the same instant — and the client\n * is left holding a token the database has moved past. Within this window\n * that client is handed a fresh token of the same session instead of a\n * 401, which is the difference between a hiccup and being silently signed\n * out of an app you were using.\n *\n * Widen it if your clients are flaky or your deploys are long; the cost is\n * how long a captured token stays useful to someone who copied it.\n */\n refreshTokenReuseIntervalSeconds?: number;\n}\n\n/**\n * Configuration for httpOnly refresh-token cookies.\n */\nexport interface CookieAuthConfig {\n /** Cookie name (default: \"__rb_refresh\"). */\n cookieName?: string;\n /** Cookie domain. Omit to use the current domain. */\n domain?: string;\n /** Cookie path (default: \"/\"). */\n path?: string;\n /** SameSite attribute (default: \"Lax\"). */\n sameSite?: \"Strict\" | \"Lax\" | \"None\";\n /** Force the Secure flag. Defaults to `true` when SameSite is \"None\", otherwise auto-detected from the request protocol. */\n secure?: boolean;\n}\n\n/**\n * Helper to build standard auth response output\n */\nfunction buildAuthResponse(\n user: { id: string; email: string; displayName?: string | null; photoUrl?: string | null; emailVerified?: boolean; isAnonymous?: boolean; metadata?: Record<string, unknown> | null },\n roleIds: string[],\n accessToken: string,\n refreshToken: string,\n providerId: string\n): AuthResponsePayload {\n return {\n user: {\n uid: user.id,\n email: user.email,\n displayName: user.displayName ?? null,\n photoURL: user.photoUrl ?? null,\n providerId,\n isAnonymous: user.isAnonymous ?? false,\n emailVerified: user.emailVerified ?? false,\n roles: roleIds,\n metadata: user.metadata ?? {}\n },\n tokens: {\n accessToken,\n refreshToken,\n accessTokenExpiresAt: getAccessTokenExpiry()\n }\n };\n}\n\n\n/**\n * Get password reset token expiry (1 hour from now)\n */\nfunction getPasswordResetExpiry(): Date {\n return new Date(Date.now() + 60 * 60 * 1000); // 1 hour\n}\n\nexport function createAuthRoutes(config: AuthModuleConfig): Hono<HonoEnv> {\n // Every administrative role, not just the one named \"admin\". This compared\n // against `\"admin\"` alone while `requireAdmin` accepted `schema-admin` too,\n // so `AUTH_DEFAULT_ROLE=schema-admin` walked past it and handed every public\n // registrant the schema editor and the SQL surfaces — from which real\n // `admin` is one user edit away.\n if (config.defaultRole && isAdministrativeRole(config.defaultRole)) {\n throw new Error(\n `CRITICAL SECURITY ERROR: defaultRole cannot be '${config.defaultRole}'. ` +\n `Administrative privilege escalation via registration is strictly forbidden ` +\n `(administrative roles: ${ADMINISTRATIVE_ROLES.join(\", \")}). ` +\n \"Use the POST /admin/bootstrap endpoint to promote the initial administrator.\"\n );\n }\n\n const router = new Hono<HonoEnv>();\n\n // Attach Rebase error handler to ensure ApiError exceptions are correctly\n // formatted instead of caught by Hono's default error handler.\n // Hono's onError does NOT propagate from parent to child routers.\n router.onError(errorHandler);\n\n const authRepo = config.authRepo;\n const { emailService, emailConfig, allowRegistration = false } = config;\n const ops = resolveAuthHooks(config.authHooks);\n\n /**\n * Apply the `transformAuthResponse` hook if provided.\n *\n * Errors are caught and logged — the untransformed response is returned\n * as a graceful fallback so auth never breaks due to a hook failure.\n */\n async function applyTransformHook(\n response: AuthResponsePayload,\n method: TransformAuthResponseContext[\"method\"],\n request: Request,\n uid: string\n ): Promise<AuthResponsePayload> {\n if (!ops.transformAuthResponse) return response;\n try {\n return await ops.transformAuthResponse(response, { uid, method, request });\n } catch (err) {\n logger.error(\"[AuthHooks] transformAuthResponse error\", {\n error: err instanceof Error ? err.message : err\n });\n return response;\n }\n }\n\n // ── Zod input schemas ──────────────────────────────────────────────\n const registerSchema = z.object({\n email: z.string().email(\"Invalid email address\").max(255),\n password: z.string().min(1, \"Password is required\").max(128),\n displayName: z.string().max(255).optional()\n });\n const loginSchema = z.object({\n email: z.string().email(\"Invalid email address\").max(255),\n password: z.string().min(1, \"Password is required\").max(128)\n });\n const forgotPasswordSchema = z.object({\n email: z.string().email(\"Invalid email address\").max(255)\n });\n const resetPasswordSchema = z.object({\n token: z.string().min(1, \"Token is required\"),\n password: z.string().min(1, \"Password is required\").max(128)\n });\n const changePasswordSchema = z.object({\n oldPassword: z.string().min(1, \"Old password is required\").max(128),\n newPassword: z.string().min(1, \"New password is required\").max(128)\n });\n const refreshSchema = z.object({\n // Always optional. The token may arrive in the body or, under cookieAuth,\n // in an httpOnly cookie, so \"is a token present\" cannot be decided at the\n // schema — `readRefreshToken` decides it, and the handler answers a\n // missing one with 401 NO_SESSION. Making the body field required in\n // non-cookie mode meant an anonymous visitor (who sends no body) got a\n // 400 INVALID_INPUT logged at warn on every page load, when the honest\n // answer is simply \"not signed in\".\n refreshToken: z.string().min(1).optional()\n });\n // `logoutSchema` and `updateProfileSchema` were declared here and used by\n // nothing: `/auth/logout` and `PATCH /auth/me` live in `session-routes.ts`,\n // which declares its own and applies them. Two copies of a validation rule,\n // one of them unreachable, is a rule that will be tightened in the wrong\n // file some day.\n\n /** Parse a Zod schema against the request body, throwing ApiError on failure */\n function parseBody<T>(schema: z.ZodSchema<T>, body: unknown): T {\n const result = schema.safeParse(body);\n if (!result.success) {\n const messages = result.error.issues.map(e => `${e.path.join(\".\")}: ${e.message}`).join(\". \");\n throw ApiError.badRequest(messages, \"INVALID_INPUT\");\n }\n return result.data;\n }\n\n /**\n * Check if email service is configured\n */\n function isEmailConfigured(): boolean {\n return !!(emailService && emailService.isConfigured());\n }\n\n /**\n * Whether registration is open without consulting the user table.\n *\n * The rule lives in `registration-policy.ts` and is shared with both config\n * endpoints, so what this route enforces and what they advertise cannot\n * drift apart — which is exactly how the empty-database dead end happened.\n *\n * `false` here does not mean \"refuse\": it means the answer depends on\n * whether the table is empty, which `POST /auth/register` checks only at\n * that point, because it serves anonymous callers and a count per rejected\n * attempt is a free hit on the database.\n */\n function isRegistrationAllowed(): boolean {\n return isSteadyStateRegistrationOpen({\n disableSelfRegistration: config.disableSelfRegistration,\n allowRegistration\n });\n }\n\n /**\n * Send welcome email to a newly registered user (fire-and-forget).\n */\n function sendWelcomeEmail(user: { email: string; displayName?: string | null }) {\n if (!isEmailConfigured()) return;\n const appName = emailConfig?.appName || \"Rebase\";\n const loginUrl = resolveEmailLinkBase(emailConfig, \"resetPassword\"); // reuse base URL → the login / app page\n const templateFn = emailConfig?.templates?.welcomeEmail;\n const emailContent = templateFn\n ? templateFn(user, appName)\n : getWelcomeEmailTemplate(user, appName, loginUrl ? `${loginUrl}/app` : undefined);\n\n emailService!.send({\n to: user.email,\n subject: emailContent.subject,\n html: emailContent.html,\n text: emailContent.text\n }).catch(err => {\n logger.error(\"Failed to send welcome email\", { error: err instanceof Error ? err.message : err });\n });\n }\n\n /**\n * Helper to generate and store session tokens.\n *\n * Every route that signs somebody in comes through here — password login,\n * register, each OAuth provider, magic link, anonymous and anonymous-link —\n * which is why the second-factor gate is *inside* it rather than repeated at\n * each call site. An account with a verified factor gets no session from\n * this function at all: it throws `MFA_REQUIRED`, and the only thing that\n * mints a session for that user is `POST /auth/mfa/challenge/verify`.\n *\n * `skipMfaGate` exists for exactly one caller: the challenge-verify route\n * itself, which has just seen the second factor and mints at `aal2`.\n */\n async function createSessionAndTokens(\n uid: string,\n userAgent: string,\n ipAddress: string,\n options?: { skipMfaGate?: boolean; aal?: \"aal1\" | \"aal2\" }\n ) {\n if (!options?.skipMfaGate) {\n await assertMfaSatisfied(authRepo, uid);\n }\n const aal = options?.aal ?? \"aal1\";\n const roles = await authRepo.getUserRoles(uid);\n const roleIds = roles.map(r => r.id);\n\n // Allow customization of access token claims via hook\n let customClaims: Record<string, unknown> | undefined;\n if (ops.customizeAccessToken) {\n const user = await authRepo.getUserById(uid);\n if (user) {\n const defaultClaims: Record<string, unknown> = { uid,\nroles: roleIds,\naal };\n customClaims = await ops.customizeAccessToken(defaultClaims, user);\n }\n }\n\n const accessToken = generateAccessToken(uid, roleIds, aal, customClaims);\n const refreshToken = generateRefreshToken();\n\n // A sign-in opens a session; every token later rotated out of it\n // inherits this id and start time. `startedAt` is what\n // `tokens_valid_after` is judged against, so it must NOT advance on\n // rotation — otherwise a session could stay one step ahead of a\n // revocation forever simply by refreshing.\n await authRepo.createRefreshToken(\n uid,\n hashRefreshToken(refreshToken),\n getRefreshTokenExpiry(),\n userAgent,\n ipAddress,\n { id: randomUUID(), startedAt: new Date(), aal }\n );\n\n return { roleIds,\naccessToken,\nrefreshToken };\n }\n\n /**\n * POST /auth/register\n * Create a new account with email/password\n */\n router.post(\"/register\", defaultAuthLimiter, async (c) => {\n const { email, password, displayName } = parseBody(registerSchema, await c.req.json());\n\n // Hard kill switch — blocks registration regardless of allowRegistration,\n // including the empty-database bootstrap exception below.\n if (config.disableSelfRegistration) {\n throw ApiError.forbidden(\"Registration is disabled\", \"REGISTRATION_DISABLED\");\n }\n\n // Bootstrap exception: an empty user table always admits the first\n // registration, even with `allowRegistration: false` — see\n // isRegistrationAllowed() for why refusing here is a dead end. The\n // moment one user exists the flag is enforced again.\n let bootstrapRegistration = false;\n if (!isRegistrationAllowed()) {\n // Paginated on purpose: this runs for anonymous callers, and the\n // unbounded listUsers() would hand them a full-table fetch per\n // rejected attempt.\n const { total } = await authRepo.listUsersPaginated({ limit: 1 });\n bootstrapRegistration = total === 0;\n if (!bootstrapRegistration) {\n throw ApiError.forbidden(\"Registration is disabled\", \"REGISTRATION_DISABLED\");\n }\n }\n\n // Validate password strength\n const passwordValidation = ops.validatePasswordStrength(password);\n if (!passwordValidation.valid) {\n throw ApiError.badRequest(passwordValidation.errors.join(\". \"), \"WEAK_PASSWORD\");\n }\n\n // Check if email already exists\n const existingUser = await authRepo.getUserByEmail(email);\n if (existingUser) {\n throw ApiError.conflict(\"Email already registered\", \"EMAIL_EXISTS\");\n }\n\n // Create user\n const passwordHash = await ops.hashPassword(password);\n let createData: import(\"./interfaces\").CreateUserData = {\n email: normalizeEmail(email),\n passwordHash,\n displayName: displayName || undefined\n };\n if (ops.beforeUserCreate) {\n createData = await ops.beforeUserCreate(createData);\n }\n const user = await authRepo.createUser(createData);\n\n // Auto-bootstrap: if this is the very first user in the system, promote to admin.\n // This avoids the chicken-and-egg problem where the first user has no permissions\n // and no way to access the bootstrap endpoint from the UI.\n const existingUsers = await authRepo.listUsers();\n const isFirstUser = existingUsers.length === 1 && existingUsers[0].id === user.id;\n\n if (bootstrapRegistration && !isFirstUser) {\n // Two registrations raced through the empty-table check. Only the\n // genuine first user may ride the bootstrap exception — the loser\n // would otherwise become a regular account created while\n // registration is disabled. Undo it and report the gate.\n await authRepo.deleteUser(user.id);\n throw ApiError.forbidden(\"Registration is disabled\", \"REGISTRATION_DISABLED\");\n }\n\n if (isFirstUser) {\n await authRepo.setUserRoles(user.id, [\"admin\"]);\n } else if (config.defaultRole) {\n // Assign configured default role (never auto-assign admin via registration)\n await authRepo.assignDefaultRole(user.id, config.defaultRole);\n }\n\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n user.id,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\"\n );\n\n // Send welcome email (fire-and-forget, don't block registration)\n sendWelcomeEmail({ email: user.email,\ndisplayName: user.displayName });\n\n // Fire afterUserCreate hook\n if (ops.afterUserCreate) {\n try {\n await ops.afterUserCreate(user);\n } catch (err) {\n logger.error(\"[AuthHooks] afterUserCreate error\", { error: err instanceof Error ? err.message : err });\n }\n }\n\n // Fire onAuthenticated hook (fire-and-forget)\n if (ops.onAuthenticated) {\n ops.onAuthenticated(user, \"register\").catch(err => {\n logger.error(\"[AuthHooks] onAuthenticated error\", { error: err instanceof Error ? err.message : err });\n });\n }\n\n const authResponse = buildAuthResponse(user, roleIds, accessToken, refreshToken, \"password\");\n const transformedResponse = await applyTransformHook(authResponse, \"register\", c.req.raw, user.id);\n const finalResponse = redactRefreshToken(transformedResponse, c, refreshToken, config.cookieAuth);\n return c.json(finalResponse, 201);\n });\n\n /**\n * POST /auth/login\n * Login with email/password\n */\n router.post(\"/login\", defaultAuthLimiter, async (c) => {\n const { email, password } = parseBody(loginSchema, await c.req.json());\n\n // Call beforeLogin hook if provided (throw to reject)\n if (ops.beforeLogin) {\n await ops.beforeLogin(email, \"login\");\n }\n\n let user;\n\n if (ops.verifyCredentials) {\n // Full credential verification override\n user = await ops.verifyCredentials(email, password, authRepo);\n if (!user) {\n throw ApiError.unauthorized(\"Invalid email or password\", \"INVALID_CREDENTIALS\");\n }\n } else {\n // Default: email lookup + password hash verification\n user = await authRepo.getUserByEmail(email);\n if (!user) {\n throw ApiError.unauthorized(\"Invalid email or password\", \"INVALID_CREDENTIALS\");\n }\n\n if (!user.passwordHash) {\n throw ApiError.unauthorized(\"Invalid email or password\", \"INVALID_CREDENTIALS\");\n }\n\n const isValidPassword = await ops.verifyPassword(password, user.passwordHash);\n if (!isValidPassword) {\n logger.warn(\"[Security Audit] Auth login failure\", {\n eventType: \"auth.login.failure\",\n email,\n uid: user.id\n });\n throw ApiError.unauthorized(\"Invalid email or password\", \"INVALID_CREDENTIALS\");\n }\n }\n\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n user.id,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\"\n );\n\n // Fire onAuthenticated hook (fire-and-forget)\n if (ops.onAuthenticated) {\n ops.onAuthenticated(user, \"login\").catch(err => {\n logger.error(\"[AuthHooks] onAuthenticated error\", { error: err instanceof Error ? err.message : err });\n });\n }\n\n logger.info(\"[Security Audit] Auth login success\", {\n eventType: \"auth.login.success\",\n uid: user.id,\n email\n });\n\n const authResponse = buildAuthResponse(user, roleIds, accessToken, refreshToken, \"password\");\n const transformedResponse = await applyTransformHook(authResponse, \"login\", c.req.raw, user.id);\n const finalResponse = redactRefreshToken(transformedResponse, c, refreshToken, config.cookieAuth);\n return c.json(finalResponse);\n });\n\n /**\n * Dynamically mount OAuth provider routes\n */\n if (config.oauthProviders && config.oauthProviders.length > 0) {\n for (const provider of config.oauthProviders) {\n router.post(`/${provider.id}`, defaultAuthLimiter, async (c) => {\n const payload = parseBody(provider.schema, await c.req.json());\n\n // Allowlist the redirect URI before the code is spent. The\n // provider's own registered-URI match authorises *every* URI\n // on that OAuth client — a leftover localhost entry, a staging\n // host, a second product sharing the client id — and any of\n // them can mint a code this backend would otherwise accept.\n const requestedRedirectUri = (payload as { redirectUri?: unknown }).redirectUri;\n if (typeof requestedRedirectUri === \"string\"\n && !isRedirectUriAllowed(requestedRedirectUri, config.allowedRedirectUris)) {\n throw ApiError.badRequest(\n \"redirectUri is not allowed for this backend\",\n \"REDIRECT_URI_NOT_ALLOWED\"\n );\n }\n\n let externalUser;\n try {\n externalUser = await provider.verify(payload);\n } catch (err: unknown) {\n // The message is logged, never returned: a provider's\n // token-endpoint error body routinely echoes the client_id,\n // the redirect URI and diagnostics about the credential\n // state, and this response goes to an anonymous caller.\n logger.error(`[OAuth] ${provider.id} verification threw`, {\n error: err instanceof Error ? err.message : String(err)\n });\n throw ApiError.unauthorized(`Invalid ${provider.id} credentials`, \"OAUTH_ERROR\");\n }\n if (!externalUser) {\n throw ApiError.unauthorized(`Invalid ${provider.id} credentials`, \"INVALID_TOKEN\");\n }\n\n // Find or create user\n let user = await authRepo.getUserByIdentity(provider.id, externalUser.providerId);\n\n if (!user) {\n // Check if email exists (link accounts)\n user = await authRepo.getUserByEmail(externalUser.email);\n\n if (user) {\n const decision = decideOAuthAutoLink({\n providerEmailVerified: externalUser.emailVerified,\n existingUser: user\n });\n if (!decision.allowed) {\n const why = decision.reason === \"provider-email-unverified\"\n ? `${provider.id} has not verified this email address, so it cannot be linked automatically.`\n : \"That account's email address was never verified, so it cannot be linked automatically.\";\n throw ApiError.forbidden(\n `An account with this email already exists with a different sign-in method. ${why} Sign in with your existing method, then POST to /auth/link/${provider.id} to link ${provider.id} to your account.`,\n \"EMAIL_NOT_VERIFIED\"\n );\n }\n // Link Provider to existing account\n await authRepo.linkUserIdentity(user.id, provider.id, externalUser.providerId, { email: externalUser.email });\n\n // Optional: Update profile info from external provider if empty\n await authRepo.updateUser(user.id, {\n displayName: user.displayName || externalUser.displayName || undefined,\n photoUrl: user.photoUrl || externalUser.photoUrl || undefined\n });\n } else {\n // Creating an account through an OAuth button is still\n // registration, and used to be the one account-creating\n // path that consulted no policy at all — kill switch\n // included, first-user-becomes-admin included.\n if (config.disableSelfRegistration) {\n throw ApiError.forbidden(\"Registration is disabled\", \"REGISTRATION_DISABLED\");\n }\n let bootstrapRegistration = false;\n if (!isRegistrationAllowed()) {\n const { total } = await authRepo.listUsersPaginated({ limit: 1 });\n bootstrapRegistration = total === 0;\n if (!bootstrapRegistration) {\n throw ApiError.forbidden(\"Registration is disabled\", \"REGISTRATION_DISABLED\");\n }\n }\n\n // Create new user. `emailVerified` was computed for the\n // link decision above and used to be discarded here, so\n // every OAuth account sat unverified forever — and was\n // then exactly the unverified local account the link\n // decision refuses to trust.\n user = await authRepo.createUser({\n email: normalizeEmail(externalUser.email),\n displayName: externalUser.displayName || undefined,\n photoUrl: externalUser.photoUrl || undefined,\n emailVerified: externalUser.emailVerified === true\n });\n\n await authRepo.linkUserIdentity(user.id, provider.id, externalUser.providerId, { email: externalUser.email });\n\n // Fire afterUserCreate hook\n if (ops.afterUserCreate) {\n try {\n await ops.afterUserCreate(user);\n } catch (err) {\n logger.error(\"[AuthHooks] afterUserCreate error\", { error: err instanceof Error ? err.message : err });\n }\n }\n\n // Auto-bootstrap: first user in the system gets admin\n const allUsers = await authRepo.listUsers();\n const isFirstUser = allUsers.length === 1 && allUsers[0].id === user.id;\n\n if (bootstrapRegistration && !isFirstUser) {\n // Two sign-ups raced through the empty-table check;\n // same undo as POST /auth/register.\n await authRepo.deleteUser(user.id);\n throw ApiError.forbidden(\"Registration is disabled\", \"REGISTRATION_DISABLED\");\n }\n\n if (isFirstUser) {\n await authRepo.setUserRoles(user.id, [\"admin\"]);\n } else if (config.defaultRole) {\n // Assign configured default role (never auto-assign admin via registration)\n await authRepo.assignDefaultRole(user.id, config.defaultRole);\n }\n\n // Send welcome email for new OAuth users (fire-and-forget)\n sendWelcomeEmail({ email: user.email,\ndisplayName: user.displayName });\n }\n } else {\n // Update profile info from external provider\n await authRepo.updateUser(user.id, {\n displayName: externalUser.displayName || user.displayName || undefined,\n photoUrl: externalUser.photoUrl || user.photoUrl || undefined\n });\n }\n\n const { roleIds, accessToken, refreshToken } = await createSessionAndTokens(\n user.id,\n c.req.header(\"user-agent\") || \"unknown\",\n c.req.header(\"x-forwarded-for\") || \"unknown\"\n );\n\n const authResponse = buildAuthResponse(user, roleIds, accessToken, refreshToken, provider.id);\n const transformedResponse = await applyTransformHook(authResponse, \"oauth\", c.req.raw, user.id);\n const finalResponse = redactRefreshToken(transformedResponse, c, refreshToken, config.cookieAuth);\n return c.json(finalResponse);\n });\n\n /**\n * POST /auth/link/:provider\n * Attach an OAuth identity to the *already authenticated* account.\n *\n * This is the escape hatch from the `EMAIL_NOT_VERIFIED` rejection\n * on the sign-in route above, and the way to attach a provider\n * whose email differs from the account's.\n *\n * Note the deliberate asymmetry with sign-in: linking here does\n * NOT require the provider to have verified the email, and does\n * not require the emails to match at all. On the sign-in route the\n * provider's email is the *only* evidence tying the incoming\n * identity to an existing account, so an unverified address would\n * let an attacker claim someone else's account. Here the caller\n * has already proven ownership by holding a valid session, and the\n * OAuth credential proves control of the provider identity — the\n * email plays no part in the decision, so its verification status\n * is irrelevant.\n */\n router.post(`/link/${provider.id}`, defaultAuthLimiter, requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const payload = parseBody(provider.schema, await c.req.json());\n\n let externalUser;\n try {\n externalUser = await provider.verify(payload);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw ApiError.unauthorized(`${provider.id} link failed: ${msg}`, \"OAUTH_ERROR\");\n }\n if (!externalUser) {\n throw ApiError.unauthorized(`Invalid ${provider.id} credentials`, \"INVALID_TOKEN\");\n }\n\n // Refuse to attach an identity that already belongs to someone\n // else — one provider identity must resolve to exactly one\n // user, or the sign-in lookup above becomes ambiguous.\n const identityOwner = await authRepo.getUserByIdentity(provider.id, externalUser.providerId);\n if (identityOwner && identityOwner.id !== userCtx.uid) {\n throw ApiError.conflict(\n `That ${provider.id} account is already linked to a different user.`,\n \"IDENTITY_ALREADY_LINKED\"\n );\n }\n if (identityOwner) {\n // Already linked to this same user — idempotent success.\n return c.json({ success: true, provider: provider.id, alreadyLinked: true });\n }\n\n await authRepo.linkUserIdentity(\n userCtx.uid,\n provider.id,\n externalUser.providerId,\n { email: externalUser.email }\n );\n\n return c.json({ success: true, provider: provider.id, alreadyLinked: false });\n });\n }\n }\n\n /**\n * POST /auth/forgot-password\n * Request password reset email\n */\n router.post(\"/forgot-password\", strictAuthLimiter, async (c) => {\n const { email } = parseBody(forgotPasswordSchema, await c.req.json());\n\n // Check if email service is configured\n if (!isEmailConfigured()) {\n throw ApiError.serviceUnavailable(\"Email service not configured. Password reset is not available.\", \"EMAIL_NOT_CONFIGURED\");\n }\n\n // Always return success (security: don't reveal if email exists)\n // But only send email if user exists\n const user = await authRepo.getUserByEmail(email);\n\n if (user) {\n // Generate reset token\n const token = generateSecureToken();\n const tokenHash = hashToken(token);\n const expiresAt = getPasswordResetExpiry();\n\n await authRepo.createPasswordResetToken(user.id, tokenHash, expiresAt);\n\n // Build reset URL\n const baseUrl = resolveEmailLinkBase(emailConfig, \"resetPassword\");\n const resetUrl = `${baseUrl}/reset-password?token=${token}`;\n\n // Get email template\n const appName = emailConfig?.appName || \"Rebase\";\n const templateFn = emailConfig?.templates?.passwordReset;\n const emailContent = templateFn\n ? templateFn(resetUrl, { email: user.email,\ndisplayName: user.displayName })\n : getPasswordResetTemplate(resetUrl, { email: user.email,\ndisplayName: user.displayName }, appName);\n\n // Send email\n try {\n await emailService!.send({\n to: user.email,\n subject: emailContent.subject,\n html: emailContent.html,\n text: emailContent.text\n });\n } catch (emailError: unknown) {\n logger.error(\"Failed to send password reset email\", { error: emailError instanceof Error ? emailError.message : emailError });\n // Don't reveal email sending failure to client\n }\n }\n\n // Always return success\n return c.json({\n success: true,\n message: \"If an account with that email exists, a password reset link has been sent.\"\n });\n });\n\n /**\n * POST /auth/reset-password\n * Reset password using token\n */\n router.post(\"/reset-password\", strictAuthLimiter, async (c) => {\n const { token, password } = parseBody(resetPasswordSchema, await c.req.json());\n\n // Validate password strength\n const passwordValidation = ops.validatePasswordStrength(password);\n if (!passwordValidation.valid) {\n throw ApiError.badRequest(passwordValidation.errors.join(\". \"), \"WEAK_PASSWORD\");\n }\n\n // Find valid token\n const tokenHash = hashToken(token);\n const storedToken = await authRepo.findValidPasswordResetToken(tokenHash);\n\n if (!storedToken) {\n throw ApiError.badRequest(\"Invalid or expired reset token\", \"INVALID_TOKEN\");\n }\n\n // Update password\n const passwordHash = await ops.hashPassword(password);\n await authRepo.updatePassword(storedToken.uid, passwordHash);\n\n // Mark token as used\n await authRepo.markPasswordResetTokenUsed(tokenHash);\n\n // Invalidate all refresh tokens (security: log out all sessions).\n // The watermark is what makes this airtight: deleting rows only\n // catches the sessions that exist at this instant, and the whole\n // point of a reset is that someone else may be holding a token and\n // actively refreshing it.\n await authRepo.deleteAllRefreshTokensForUser(storedToken.uid);\n await authRepo.setTokensValidAfter?.(storedToken.uid, new Date()).catch(() => undefined);\n\n // Fire onPasswordReset hook (fire-and-forget)\n if (ops.onPasswordReset) {\n ops.onPasswordReset(storedToken.uid).catch(err => {\n logger.error(\"[AuthHooks] onPasswordReset error\", { error: err instanceof Error ? err.message : err });\n });\n }\n\n return c.json({ success: true,\nmessage: \"Password has been reset successfully\" });\n });\n\n /**\n * POST /auth/change-password\n * Change password for authenticated user\n */\n router.post(\"/change-password\", requireAuth, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n const { oldPassword, newPassword } = parseBody(changePasswordSchema, await c.req.json());\n\n // Get user\n const user = await authRepo.getUserById(userCtx.uid);\n if (!user || !user.passwordHash) {\n throw ApiError.badRequest(\"Cannot change password for this account\", \"INVALID_ACCOUNT\");\n }\n\n // Verify old password\n const isValidOldPassword = await ops.verifyPassword(oldPassword, user.passwordHash);\n if (!isValidOldPassword) {\n throw ApiError.unauthorized(\"Current password is incorrect\", \"INVALID_CREDENTIALS\");\n }\n\n // Validate new password strength\n const passwordValidation = ops.validatePasswordStrength(newPassword);\n if (!passwordValidation.valid) {\n throw ApiError.badRequest(passwordValidation.errors.join(\". \"), \"WEAK_PASSWORD\");\n }\n\n // Update password\n const passwordHash = await ops.hashPassword(newPassword);\n await authRepo.updatePassword(user.id, passwordHash);\n\n // Invalidate all refresh tokens (security: log out all sessions)\n await authRepo.deleteAllRefreshTokensForUser(user.id);\n await authRepo.setTokensValidAfter?.(user.id, new Date()).catch(() => undefined);\n\n return c.json({ success: true,\nmessage: \"Password has been changed successfully\" });\n });\n\n /**\n * POST /auth/send-verification\n * Send email verification link (authenticated)\n *\n * Two limiters, because they bound different things: `strictAuthLimiter`\n * bounds the caller by IP as it does on every other email-sending route, and\n * `verificationEmailLimiter` bounds how much mail one account — i.e. one\n * recipient address — can be made to receive. Authentication is not a bound\n * here: the address is unverified by construction, so an attacker can hold a\n * session for a mailbox that is not theirs.\n */\n router.post(\"/send-verification\", strictAuthLimiter, requireAuth, verificationEmailLimiter, async (c) => {\n const userCtx = c.get(\"user\") as { uid: string; roles?: string[] } | undefined;\n if (!userCtx) {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n // Check if email service is configured\n if (!isEmailConfigured()) {\n throw ApiError.serviceUnavailable(\"Email service not configured. Email verification is not available.\", \"EMAIL_NOT_CONFIGURED\");\n }\n\n const user = await authRepo.getUserById(userCtx.uid);\n if (!user) {\n throw ApiError.notFound(\"User not found\");\n }\n\n if (user.emailVerified) {\n throw ApiError.badRequest(\"Email is already verified\", \"ALREADY_VERIFIED\");\n }\n\n // Generate verification token\n const token = generateSecureToken();\n\n // Store hashed token in user record (raw token goes in the email URL)\n await authRepo.setVerificationToken(user.id, hashToken(token));\n\n // Build verification URL. `verifyEmailUrl` is set by no boot path, so\n // this used to be `\"\"` — a relative href, dead in every mail client,\n // reported as `{ success: true }`. The resolver falls back to the reset\n // base, and `createEmailService` refuses to boot when neither is absolute.\n const baseUrl = resolveEmailLinkBase(emailConfig, \"verifyEmail\");\n const verifyUrl = `${baseUrl}/verify-email?token=${token}`;\n\n // Get email template\n const appName = emailConfig?.appName || \"Rebase\";\n const templateFn = emailConfig?.templates?.emailVerification;\n const emailContent = templateFn\n ? templateFn(verifyUrl, { email: user.email,\ndisplayName: user.displayName })\n : getEmailVerificationTemplate(verifyUrl, { email: user.email,\ndisplayName: user.displayName }, appName);\n\n // Send email\n await emailService!.send({\n to: user.email,\n subject: emailContent.subject,\n html: emailContent.html,\n text: emailContent.text\n });\n\n return c.json({ success: true,\nmessage: \"Verification email sent\" });\n });\n\n /**\n * GET /auth/verify-email\n * Verify email address using token\n */\n router.get(\"/verify-email\", async (c) => {\n const token = c.req.query(\"token\");\n\n if (!token) {\n throw ApiError.badRequest(\"Verification token is required\", \"INVALID_INPUT\");\n }\n\n // Find user by hashed verification token\n const user = await authRepo.getUserByVerificationToken(hashToken(token));\n if (!user) {\n throw ApiError.badRequest(\"Invalid or expired verification token\", \"INVALID_TOKEN\");\n }\n\n // Mark email as verified\n await authRepo.setEmailVerified(user.id, true);\n\n return c.json({ success: true,\nmessage: \"Email verified successfully\" });\n });\n\n /**\n * POST /auth/refresh\n * Refresh access token using refresh token\n */\n router.post(\"/refresh\", async (c) => {\n // Cookie mode sends NO body: the refresh token lives in the httpOnly\n // cookie, which is the entire point of it. Hono's `json()` throws\n // \"Unexpected end of JSON input\" on an empty body, so parsing it\n // unguarded turned every cookie-mode refresh into a 500 — and clients\n // refresh on page load, so sessions never restored and users were\n // signed out on every reload.\n //\n // `refreshToken` is already optional under cookieAuth and\n // `readRefreshToken` already falls back to the cookie; this is only\n // what makes that reachable.\n const body = await c.req.json().catch(() => ({}));\n const parsed = parseBody(refreshSchema, body);\n const refreshToken = readRefreshToken(c, parsed, config.cookieAuth);\n\n if (!refreshToken) {\n // Presenting no token at all is not a malformed request — it is an\n // unauthenticated one, and the overwhelmingly common case is a\n // first-time visitor, because clients refresh on page load before\n // they know whether a session exists. Answering 400 INVALID_INPUT\n // told them their request was wrong and logged a warning for every\n // anonymous page view. The invalid- and expired-token branches below\n // already answer 401; having no token is the same class of thing.\n throw ApiError.unauthenticated(\"No refresh token presented\", \"NO_SESSION\");\n }\n\n const tokenHash = hashRefreshToken(refreshToken);\n const storedToken = await authRepo.findRefreshTokenByHash(tokenHash);\n\n if (!storedToken) {\n // Deliberately NOT clearing the cookie. A token we do not recognise\n // means we cannot authenticate THIS request; it does not mean the\n // credential in the browser should be destroyed. Clearing here made\n // any single stale request — a duplicate from a second tab, a retry\n // after a rolled pod — permanently sign out a user whose session was\n // otherwise perfectly alive, because the good cookie went with it.\n throw ApiError.unauthorized(\"Invalid refresh token\", \"INVALID_TOKEN\");\n }\n\n if (storedToken.revoked) {\n // A hard kill: logout, a remotely revoked device, an admin action.\n // Unlike the case above this session really is over, so clearing is\n // correct — there is nothing left for the cookie to authenticate.\n clearRefreshCookie(c, config.cookieAuth);\n throw ApiError.unauthorized(\"Session has been revoked\", \"SESSION_REVOKED\");\n }\n\n if (new Date() > storedToken.expiresAt) {\n await authRepo.deleteRefreshToken(tokenHash);\n clearRefreshCookie(c, config.cookieAuth);\n throw ApiError.unauthorized(\"Refresh token expired\", \"TOKEN_EXPIRED\");\n }\n\n // A session that began before the user's revocation mark is void, even\n // if its row survived. This closes the race in which a refresh already\n // in flight inserts a rotated token microseconds after a password reset\n // has deleted every row it could see.\n const sessionStartedAt = storedToken.sessionStartedAt ?? storedToken.createdAt;\n const tokensValidAfter = await authRepo.getTokensValidAfter?.(storedToken.uid).catch(() => null);\n if (tokensValidAfter && sessionStartedAt < tokensValidAfter) {\n await authRepo.deleteRefreshToken(tokenHash);\n clearRefreshCookie(c, config.cookieAuth);\n throw ApiError.unauthorized(\"Session has been revoked\", \"SESSION_REVOKED\");\n }\n\n // A token that was already rotated away is the normal signature of a\n // client that never received the answer — a response lost to a deploy,\n // a suspended laptop, two tabs booting together. Inside the reuse window\n // it earns a fresh token of the same session rather than a 401.\n const reuseWindowMs = Math.max(0, config.refreshTokenReuseIntervalSeconds ?? 10) * 1000;\n const supersededAt = storedToken.rotatedAt ? new Date(storedToken.rotatedAt) : null;\n if (supersededAt && Date.now() - supersededAt.getTime() > reuseWindowMs) {\n // Outside the window we decline the request but leave the session\n // standing: the live token this one was rotated into is still good,\n // and punishing its holder for a late straggler is how a legitimate\n // user gets signed out. Logged because a genuine replay of an old\n // token — long after it was superseded — is also what a stolen\n // token looks like, and that signal should not vanish silently.\n logger.warn(\"[Auth] Refresh token replayed after the reuse window\", {\n uid: storedToken.uid,\n sessionId: storedToken.sessionId,\n supersededSecondsAgo: Math.round((Date.now() - supersededAt.getTime()) / 1000),\n userAgent: c.req.header(\"user-agent\") || \"unknown\"\n });\n throw ApiError.unauthorized(\"Refresh token already used\", \"TOKEN_ALREADY_USED\");\n }\n\n // Generate new tokens\n const roles = await authRepo.getUserRoles(storedToken.uid);\n const roleIds = roles.map(r => r.id);\n\n // Best-effort: load the user so we can return it in the response, which\n // lets the client restore a session from an httpOnly cookie alone (cold\n // start in cookie mode). This enrichment must NEVER break refresh — on\n // any failure we fall back to a tokens-only response (the pre-existing\n // behavior), and the client restores the user via GET /me.\n const user = await authRepo.getUserById(storedToken.uid).catch((err: unknown) => {\n logger.warn(\"[Auth] Could not load user during token refresh; returning tokens only\", {\n uid: storedToken.uid,\n error: err instanceof Error ? err.message : String(err)\n });\n return null;\n });\n\n // The assurance level is a property of the sign-in, and rotation is not\n // a new sign-in — so it is read off the presented token's row and\n // carried forward. Hardcoding `aal1` here meant an MFA-verified session\n // silently dropped back to password-grade within one access-token\n // lifetime, which both defeats the step-up and locks the user out of\n // the operations that require it. A row with no stored value (written\n // before the column existed, or by a repository that does not keep it)\n // reads as `aal1`, the restrictive value.\n const sessionAal: \"aal1\" | \"aal2\" = storedToken.aal === \"aal2\" ? \"aal2\" : \"aal1\";\n\n // Allow customization of access token claims via hook\n let customClaims: Record<string, unknown> | undefined;\n if (ops.customizeAccessToken && user) {\n const defaultClaims: Record<string, unknown> = { uid: storedToken.uid,\nroles: roleIds,\naal: sessionAal };\n customClaims = await ops.customizeAccessToken(defaultClaims, user);\n }\n\n const newAccessToken = generateAccessToken(storedToken.uid, roleIds, sessionAal, customClaims);\n const newRefreshToken = generateRefreshToken();\n\n // Rotate: mark the presented token superseded and mint its successor\n // into the same session. Note the ORDER and the absence of a delete —\n // the old row has to survive, because it is the only thing that can\n // tell a client replaying it apart from a stranger.\n //\n // If the presented token was ALREADY superseded (a replay inside the\n // reuse window, allowed above), leave the existing rotation stamp alone\n // and simply add a sibling: two tabs then hold two live tokens of one\n // session, which is exactly what we want them to have.\n const userAgent = c.req.header(\"user-agent\") || \"unknown\";\n const ipAddress = c.req.header(\"x-forwarded-for\") || \"unknown\";\n const session = {\n id: storedToken.sessionId ?? storedToken.id,\n startedAt: sessionStartedAt,\n aal: sessionAal\n };\n\n if (!supersededAt) {\n if (authRepo.markRefreshTokenRotated) {\n await authRepo.markRefreshTokenRotated(tokenHash);\n } else {\n // Repository from an older release: no way to record the\n // supersession, so fall back to the lossy delete.\n await authRepo.deleteRefreshToken(tokenHash);\n }\n }\n\n await authRepo.createRefreshToken(\n storedToken.uid,\n hashRefreshToken(newRefreshToken),\n getRefreshTokenExpiry(),\n userAgent,\n ipAddress,\n session\n );\n\n // Housekeeping, deliberately after the new token exists and never\n // allowed to fail the request: rotation adds a row per refresh, and\n // nothing else would ever remove them.\n authRepo.pruneRefreshTokens?.(\n storedToken.uid,\n session.id,\n new Date(Date.now() - reuseWindowMs)\n ).catch((err: unknown) => {\n logger.warn(\"[Auth] Refresh token prune failed\", {\n error: err instanceof Error ? err.message : String(err)\n });\n });\n\n const tokensOnlyResponse: AuthResponsePayload = {\n tokens: {\n accessToken: newAccessToken,\n refreshToken: newRefreshToken,\n accessTokenExpiresAt: getAccessTokenExpiry()\n }\n };\n let refreshResponse: AuthResponsePayload = tokensOnlyResponse;\n if (user) {\n try {\n refreshResponse = buildAuthResponse(user, roleIds, newAccessToken, newRefreshToken, \"password\");\n } catch (err: unknown) {\n logger.warn(\"[Auth] Could not build enriched refresh response; returning tokens only\", {\n error: err instanceof Error ? err.message : String(err)\n });\n refreshResponse = tokensOnlyResponse;\n }\n }\n const transformedResponse = await applyTransformHook(refreshResponse, \"refresh\", c.req.raw, storedToken.uid);\n const finalResponse = redactRefreshToken(transformedResponse, c, newRefreshToken, config.cookieAuth);\n return c.json(finalResponse);\n });\n\n mountSessionRoutes({\n router,\n config,\n ops,\n parseBody,\n buildAuthResponse,\n createSessionAndTokens,\n applyTransformHook\n });\n\n // ═══════════════════════════════════════════════════════════════════════\n // MFA / TOTP\n // ═══════════════════════════════════════════════════════════════════════\n mountMfaRoutes({\n router,\n config,\n ops,\n parseBody,\n buildAuthResponse,\n createSessionAndTokens,\n applyTransformHook\n });\n\n // ═══════════════════════════════════════════════════════════════════════\n // Magic Link (passwordless email login)\n // ═══════════════════════════════════════════════════════════════════════\n if (config.enableMagicLink) {\n mountMagicLinkRoutes({\n router,\n config,\n ops,\n parseBody,\n buildAuthResponse,\n createSessionAndTokens,\n applyTransformHook\n });\n }\n\n return router;\n}\n","/**\n * Standalone admin endpoint for resetting a user's password.\n *\n * Hook resolution order:\n * 1. Collection-level hook (`auth.onResetPassword` on the collection)\n * 2. Backend-level hook (`AuthHooks.onAdminResetPassword`)\n * 3. Built-in default (send reset email, or generate temp password)\n */\n\nimport { Hono } from \"hono\";\nimport { ApiError, errorHandler } from \"../api/errors\";\nimport type { AuthRepository } from \"./interfaces\";\nimport { createRequireAuth, requireAdmin } from \"./middleware\";\nimport type { AuthHooks } from \"./auth-hooks\";\nimport { resolveAuthHooks } from \"./auth-hooks\";\nimport { generateSecurePassword, generateSecureToken, hashToken } from \"./admin-user-ops\";\nimport { getPasswordResetTemplate } from \"../email/templates\";\nimport type { EmailService, EmailConfig } from \"../email\";\nimport type { HonoEnv } from \"../api/types\";\nimport type { AuthCollectionConfig } from \"@rebasepro/types\";\nimport { logger } from \"../utils/logger\";\n\nexport interface ResetPasswordRouteConfig {\n authRepo: AuthRepository;\n emailService?: EmailService;\n emailConfig?: EmailConfig;\n serviceKey?: string;\n authHooks?: AuthHooks;\n /** The parsed auth config from the collection, if available. */\n collectionAuthConfig?: AuthCollectionConfig;\n}\n\n/**\n * Create a standalone admin route for resetting user passwords.\n *\n * Mounts: POST /users/:uid/reset-password\n */\nexport function createResetPasswordRoute(config: ResetPasswordRouteConfig): Hono<HonoEnv> {\n const router = new Hono<HonoEnv>();\n const authRepo = config.authRepo;\n const { emailService, emailConfig, collectionAuthConfig } = config;\n const ops = resolveAuthHooks(config.authHooks);\n\n router.onError(errorHandler);\n router.use(\"/*\", createRequireAuth({\n serviceKey: config.serviceKey,\n // A demoted admin must not still be able to reset anyone's password.\n resolveRoles: uid => authRepo.getUserRoleIds(uid),\n revocationRepo: authRepo\n }));\n\n router.post(\"/users/:uid/reset-password\", requireAdmin, async (c) => {\n const uid = c.req.param(\"uid\");\n const existing = await authRepo.getUserById(uid);\n if (!existing) {\n throw ApiError.notFound(\"User not found\");\n }\n\n let invitationSent = false;\n let temporaryPassword: string | undefined;\n // Distinguishes \"email was never configured\" from \"email is configured but\n // the send failed\" — both fall back to a temporary password.\n let emailDeliveryFailed = false;\n\n // Parse optional body — if a password is provided, set it directly\n const body = await c.req.json().catch(() => ({}));\n\n if (body.password) {\n const password = body.password as string;\n const validation = ops.validatePasswordStrength(password);\n if (!validation.valid) {\n throw ApiError.badRequest(\n `Password too weak: ${validation.errors.join(\", \")}`\n );\n }\n const passwordHash = await ops.hashPassword(password);\n await authRepo.updatePassword(existing.id, passwordHash);\n temporaryPassword = undefined;\n invitationSent = false;\n }\n // 1. Collection-level hook (closest to the data)\n else if (collectionAuthConfig?.onResetPassword) {\n const isEmailConfigured = !!(emailService && emailService.isConfigured());\n const hookResult = await collectionAuthConfig.onResetPassword(existing.id, {\n hashPassword: (password: string) => ops.hashPassword(password),\n sendEmail: isEmailConfigured\n ? (options) => emailService!.send(options)\n : undefined,\n emailConfigured: isEmailConfigured,\n appName: emailConfig?.appName || \"Rebase\",\n resetPasswordUrl: emailConfig?.resetPasswordUrl || \"\"\n });\n temporaryPassword = hookResult.temporaryPassword;\n invitationSent = hookResult.invitationSent ?? false;\n }\n // 2. Backend-level hook (global override)\n else if (ops.onAdminResetPassword) {\n const hookResult = await ops.onAdminResetPassword(existing.id, {\n authRepo,\n emailService,\n emailConfig\n });\n temporaryPassword = hookResult.temporaryPassword;\n invitationSent = hookResult.invitationSent ?? false;\n }\n // 3. Built-in default\n else {\n const isEmailConfigured = !!(emailService && emailService.isConfigured());\n\n if (isEmailConfigured) {\n try {\n const token = generateSecureToken();\n const tokenHash = hashToken(token);\n const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour\n\n await authRepo.createPasswordResetToken(existing.id, tokenHash, expiresAt);\n\n const baseUrl = emailConfig?.resetPasswordUrl || \"\";\n const setPasswordUrl = `${baseUrl}/reset-password?token=${token}`;\n\n const appName = emailConfig?.appName || \"Rebase\";\n const templateFn = emailConfig?.templates?.passwordReset;\n const emailContent = templateFn\n ? templateFn(setPasswordUrl, { email: existing.email,\ndisplayName: existing.displayName })\n : getPasswordResetTemplate(setPasswordUrl, { email: existing.email,\ndisplayName: existing.displayName }, appName);\n\n await emailService!.send({\n to: existing.email,\n subject: emailContent.subject,\n html: emailContent.html,\n text: emailContent.text\n });\n invitationSent = true;\n } catch (emailError: unknown) {\n logger.error(\"Failed to send reset email\", { error: emailError instanceof Error ? emailError.message : emailError });\n // Fall back to returning the temporary password\n const clearPassword = generateSecurePassword();\n const passwordHash = await ops.hashPassword(clearPassword);\n await authRepo.updatePassword(existing.id, passwordHash);\n temporaryPassword = clearPassword;\n emailDeliveryFailed = true;\n }\n } else {\n // No email service — generate password, set it, and return one-time\n const clearPassword = generateSecurePassword();\n const passwordHash = await ops.hashPassword(clearPassword);\n await authRepo.updatePassword(existing.id, passwordHash);\n temporaryPassword = clearPassword;\n }\n }\n\n const userRoles = await authRepo.getUserRoleIds(existing.id);\n\n return c.json({\n user: {\n uid: existing.id,\n email: existing.email,\n displayName: existing.displayName,\n roles: userRoles\n },\n invitationSent,\n ...(temporaryPassword ? { temporaryPassword } : {}),\n ...(emailDeliveryFailed ? { emailDeliveryFailed } : {})\n }, 200);\n });\n\n return router;\n}\n","/**\n * Admin endpoint for listing all roles.\n *\n * Mounts: GET /roles\n */\n\nimport { Hono } from \"hono\";\nimport { errorHandler } from \"../api/errors\";\nimport type { AuthRepository } from \"./interfaces\";\nimport { createRequireAuth, requireAdmin } from \"./middleware\";\nimport type { HonoEnv } from \"../api/types\";\n\nexport interface AdminRolesRouteConfig {\n authRepo: AuthRepository;\n serviceKey?: string;\n}\n\n/**\n * Create a standalone admin route for listing roles.\n *\n * Mounts: GET /roles\n */\nexport function createAdminRolesRoute(config: AdminRolesRouteConfig): Hono<HonoEnv> {\n const router = new Hono<HonoEnv>();\n const authRepo = config.authRepo;\n\n router.onError(errorHandler);\n router.use(\"/*\", createRequireAuth({\n serviceKey: config.serviceKey,\n // These routes can grant roles, so they must not trust a role claim.\n resolveRoles: uid => authRepo.getUserRoleIds(uid),\n revocationRepo: authRepo\n }));\n\n router.get(\"/roles\", requireAdmin, async (c) => {\n const roles = await authRepo.listRoles();\n return c.json({ roles });\n });\n\n return router;\n}\n","/**\n * Standalone admin endpoint for user management.\n *\n * Mounts:\n * GET /users\n * GET /users/:uid\n * POST /users\n * PUT /users/:uid\n * DELETE /users/:uid\n * POST /bootstrap\n */\n\nimport { Hono } from \"hono\";\nimport { isAnonymousUid } from \"@rebasepro/types\";\nimport { normalizeEmail } from \"@rebasepro/common\";\nimport { ApiError, errorHandler } from \"../api/errors\";\nimport type { AuthRepository } from \"./interfaces\";\nimport { createRequireAuth, requireAdmin } from \"./middleware\";\nimport type { AuthHooks } from \"./auth-hooks\";\nimport { resolveAuthHooks } from \"./auth-hooks\";\nimport { prepareAdminUserValues, finalizeAdminUserCreation } from \"./admin-user-ops\";\nimport type { EmailService, EmailConfig } from \"../email\";\nimport type { HonoEnv } from \"../api/types\";\nimport type { AdminUser, AuthCollectionConfig } from \"@rebasepro/types\";\nimport { resolveListLimitParam } from \"../api/rest/query-parser\";\nimport { logger } from \"../utils/logger\";\n\nexport interface AdminUsersRouteConfig {\n authRepo: AuthRepository;\n emailService?: EmailService;\n emailConfig?: EmailConfig;\n serviceKey?: string;\n authHooks?: AuthHooks;\n collectionAuthConfig?: AuthCollectionConfig;\n isBootstrapCompleted?: () => Promise<boolean>;\n setBootstrapCompleted?: () => Promise<void>;\n}\n\n/** Upper bound for `GET /users?ids=…`, so one request can't fan out unbounded. */\nconst MAX_USER_IDS_PER_LOOKUP = 100;\n\nexport function createAdminUsersRoute(config: AdminUsersRouteConfig): Hono<HonoEnv> {\n const router = new Hono<HonoEnv>();\n const authRepo = config.authRepo;\n const { emailService, emailConfig, collectionAuthConfig } = config;\n const ops = resolveAuthHooks(config.authHooks);\n\n function toAdminUser(\n u: {\n id: string;\n email: string;\n displayName?: string | null;\n photoUrl?: string | null;\n createdAt?: Date | string;\n updatedAt?: Date | string;\n },\n roles: string[]\n ): AdminUser {\n return {\n uid: u.id,\n email: u.email,\n displayName: u.displayName ?? null,\n photoURL: u.photoUrl ?? null,\n providerId: \"custom\",\n roles,\n createdAt: u.createdAt instanceof Date ? u.createdAt.toISOString() : (u.createdAt ?? new Date().toISOString()),\n updatedAt: u.updatedAt instanceof Date ? u.updatedAt.toISOString() : (u.updatedAt ?? new Date().toISOString())\n };\n }\n\n router.onError(errorHandler);\n router.use(\"/*\", createRequireAuth({\n serviceKey: config.serviceKey,\n // These routes can grant roles, so they must not trust a role claim.\n resolveRoles: uid => authRepo.getUserRoleIds(uid),\n revocationRepo: authRepo\n }));\n\n router.post(\"/bootstrap\", async (c) => {\n const user = c.get(\"user\");\n if (!user || typeof user !== \"object\") {\n throw ApiError.unauthorized(\"Not authenticated\");\n }\n\n if (config.isBootstrapCompleted) {\n const alreadyDone = await config.isBootstrapCompleted();\n if (alreadyDone) {\n throw ApiError.forbidden(\"Bootstrap has already been completed.\", \"BOOTSTRAP_COMPLETED\");\n }\n }\n\n const users = await authRepo.listUsers();\n let hasAdmin = false;\n\n for (const u of users) {\n const roles = await authRepo.getUserRoleIds(u.id);\n if (roles.includes(\"admin\")) {\n hasAdmin = true;\n break;\n }\n }\n\n if (hasAdmin) {\n throw ApiError.forbidden(\"Admin users already exist. Bootstrap not allowed.\", \"BOOTSTRAP_COMPLETED\");\n }\n\n const uid = \"uid\" in user ? (user as { uid: string }).uid : undefined;\n if (!uid) {\n throw ApiError.unauthorized(\"User ID not found in auth context\");\n }\n\n // An anonymous session may not claim the initial admin role.\n //\n // `POST /auth/anonymous` mints a real session for anyone who asks, and\n // an anonymous principal is a row in the users table like any other —\n // so on an empty backend it was also the *earliest* one, which is the\n // only thing the land-grab gate below checks. Two unauthenticated\n // requests therefore took a fresh deployment: anonymous session, then\n // bootstrap. It worked with `disableSelfRegistration: true` as well,\n // the flag whose docblock promises \"an empty backend has no\n // self-service path in at all\".\n if (isAnonymousUid(uid)) {\n logger.warn(\"[Security Audit] Bootstrap denied: anonymous caller\", {\n eventType: \"auth.bootstrap.denied.anonymous\",\n callerId: uid\n });\n throw ApiError.forbidden(\n \"An anonymous session cannot claim the initial admin role. Register a real \" +\n \"account and bootstrap from it, or assign the admin role using the service key.\",\n \"BOOTSTRAP_ANONYMOUS\"\n );\n }\n const caller = await authRepo.getUserById(uid);\n if (!caller) {\n throw ApiError.notFound(\"Authenticated user does not exist in the database.\", \"USER_NOT_FOUND\");\n }\n\n // Even while no admin exists, only the earliest-registered user may claim\n // the initial admin role. The common paths already auto-promote the first\n // user, so this endpoint only matters once a system has reached a \"users\n // exist but no admin\" state — e.g. concurrent first-registrations, or the\n // first user being deleted. Without this gate, any authenticated user\n // could then seize admin: a land-grab. The genuine first user is\n // deterministic; tie-break by id so identical timestamps still resolve to\n // a single winner.\n // Anonymous principals are excluded from \"earliest registered\" for the\n // same reason they cannot bootstrap: they are sessions, not\n // registrations. Leaving them in would also let an anonymous row that\n // happens to predate the real first user block that user forever.\n const registeredUsers = users.filter(u => !isAnonymousUid(u.id));\n if (registeredUsers.length > 0) {\n const earliest = registeredUsers.reduce((a, b) => {\n const at = new Date(a.createdAt).getTime();\n const bt = new Date(b.createdAt).getTime();\n if (at !== bt) return at < bt ? a : b;\n return a.id < b.id ? a : b;\n });\n if (earliest.id !== uid) {\n logger.warn(\"[Security Audit] Bootstrap denied: caller is not the earliest-registered user\", {\n eventType: \"auth.bootstrap.denied\",\n callerId: uid,\n earliestUserId: earliest.id\n });\n throw ApiError.forbidden(\n \"Only the first registered user may claim the initial admin role. \" +\n \"Ask that user to bootstrap, or assign the admin role using the service key.\",\n \"BOOTSTRAP_NOT_FIRST_USER\"\n );\n }\n }\n\n await authRepo.setUserRoles(uid, [\"admin\"]);\n logger.info(\"[Security Audit] Initial admin bootstrapped\", {\n eventType: \"auth.bootstrap.success\",\n uid\n });\n\n if (config.setBootstrapCompleted) {\n await config.setBootstrapCompleted();\n }\n\n return c.json({\n success: true,\n message: \"You are now an admin\",\n user: {\n uid: uid,\n roles: [\"admin\"]\n }\n });\n });\n\n router.get(\"/users\", requireAdmin, async (c) => {\n // `?ids=a,b,c` resolves a known set of users in one round trip. The admin\n // UI needs it to turn the ids stored in `userSelect` columns into names\n // without firing one request per row.\n const idsParam = c.req.query(\"ids\");\n if (idsParam !== undefined) {\n const ids = [...new Set(idsParam.split(\",\").map(id => id.trim()).filter(Boolean))]\n .slice(0, MAX_USER_IDS_PER_LOOKUP);\n const resolved = await Promise.all(ids.map(async (id) => {\n const result = await authRepo.getUserWithRoles(id);\n return result ? toAdminUser(result.user, result.roles.map((r) => r.id)) : undefined;\n }));\n const users = resolved.filter((u): u is AdminUser => u !== undefined);\n return c.json({ users,\ntotal: users.length,\nlimit: ids.length,\noffset: 0 });\n }\n\n const limitParam = c.req.query(\"limit\");\n const offsetParam = c.req.query(\"offset\");\n const search = c.req.query(\"search\");\n const orderBy = c.req.query(\"orderBy\");\n const orderDir = c.req.query(\"orderDir\") as \"asc\" | \"desc\" | undefined;\n\n // Same bounded guarantee as every other list ingress: an absent limit\n // gets this endpoint's own 25 default, and one above the ceiling is a\n // 400 naming it rather than a shorter page that reads like the end of\n // the user list.\n const limit = resolveListLimitParam(limitParam, { defaultLimit: 25 });\n const offset = offsetParam ? Math.max(0, parseInt(offsetParam, 10) || 0) : 0;\n\n const result = await authRepo.listUsersPaginated({\n limit,\n offset,\n search: search || undefined,\n orderBy: orderBy || undefined,\n orderDir: orderDir || undefined,\n roleId: c.req.query(\"role\") || undefined\n });\n\n const usersWithRoles = await Promise.all(\n result.users.map(async (u) => {\n const roles = await authRepo.getUserRoleIds(u.id);\n return toAdminUser(u, roles);\n })\n );\n\n return c.json({\n users: usersWithRoles,\n total: result.total,\n limit: result.limit,\n offset: result.offset\n });\n });\n\n router.get(\"/users/:uid\", requireAdmin, async (c) => {\n const uid = c.req.param(\"uid\");\n const result = await authRepo.getUserWithRoles(uid);\n\n if (!result) {\n throw ApiError.notFound(\"User not found\");\n }\n\n const adminUser = toAdminUser(result.user, result.roles.map((r) => r.id));\n return c.json({ user: adminUser });\n });\n\n router.post(\"/users\", requireAdmin, async (c) => {\n const body = await c.req.json();\n const { email, roles } = body;\n if (!email) {\n throw ApiError.badRequest(\"Email is required\");\n }\n\n const existing = await authRepo.getUserByEmail(normalizeEmail(email));\n if (existing) {\n throw ApiError.conflict(\"A user with this email already exists\");\n }\n\n const prepResult = await prepareAdminUserValues(body, {\n authRepo,\n emailService,\n emailConfig,\n resolvedHooks: ops,\n collectionAuthConfig\n });\n\n // `beforeUserCreate` runs here too.\n //\n // It fired on self-service registration and nowhere else, while the\n // boot warning and `authentication.md` name admin user management as\n // one of the paths that bypasses collection callbacks and tell\n // developers to use this hook instead. A hook that skips the path its\n // own documentation sends people to is worse than no hook: they wrote\n // the validation, and it silently does not run here.\n let createData = {\n email: prepResult.values.email as string,\n passwordHash: prepResult.values.passwordHash as string | undefined,\n displayName: prepResult.values.displayName as string | undefined,\n photoUrl: prepResult.values.photoUrl as string | undefined,\n metadata: prepResult.values.metadata as Record<string, unknown> | undefined\n };\n\n if (ops.beforeUserCreate) {\n createData = await ops.beforeUserCreate(createData) as typeof createData;\n }\n\n const user = await authRepo.createUser(createData);\n\n if (roles && Array.isArray(roles)) {\n await authRepo.setUserRoles(user.id, roles);\n }\n\n const finalizeResult = await finalizeAdminUserCreation(\n { id: user.id,\nvalues: prepResult.values },\n prepResult.clearPassword,\n {\n authRepo,\n emailService,\n emailConfig,\n resolvedHooks: ops,\n collectionAuthConfig\n }\n );\n\n const userRoles = await authRepo.getUserRoleIds(user.id);\n const adminUser = toAdminUser(user, userRoles);\n\n return c.json(\n {\n user: adminUser,\n invitationSent: finalizeResult.invitationSent,\n ...(finalizeResult.temporaryPassword ? { temporaryPassword: finalizeResult.temporaryPassword } : {}),\n ...(finalizeResult.emailDeliveryFailed ? { emailDeliveryFailed: true } : {})\n },\n 201\n );\n });\n\n router.put(\"/users/:uid\", requireAdmin, async (c) => {\n const uid = c.req.param(\"uid\");\n const body = await c.req.json();\n const { password, email, displayName, roles } = body;\n\n const existing = await authRepo.getUserById(uid);\n if (!existing) {\n throw ApiError.notFound(\"User not found\");\n }\n\n const updates: Record<string, unknown> = {};\n if (email !== undefined) updates.email = normalizeEmail(email);\n if (displayName !== undefined) updates.displayName = displayName;\n\n if (password) {\n const validation = ops.validatePasswordStrength(password);\n if (!validation.valid) {\n throw ApiError.badRequest(`Password too weak: ${validation.errors.join(\". \")}`);\n }\n updates.passwordHash = await ops.hashPassword(password);\n }\n\n if (Object.keys(updates).length > 0) {\n await authRepo.updateUser(uid, updates);\n }\n\n if (roles !== undefined && Array.isArray(roles)) {\n const currentRoles = await authRepo.getUserRoleIds(uid);\n const wasAdmin = currentRoles.includes(\"admin\");\n const willBeAdmin = roles.includes(\"admin\");\n\n if (wasAdmin && !willBeAdmin) {\n const adminUsers = await authRepo.listUsersPaginated({\n roleId: \"admin\",\n limit: 1\n });\n if (adminUsers.total <= 1) {\n throw ApiError.forbidden(\"Cannot demote the last administrator\", \"LAST_ADMIN\");\n }\n }\n await authRepo.setUserRoles(uid, roles);\n }\n\n const result = await authRepo.getUserWithRoles(uid);\n const adminUser = toAdminUser(result!.user, result!.roles.map((r) => r.id));\n\n return c.json({ user: adminUser });\n });\n\n router.delete(\"/users/:uid\", requireAdmin, async (c) => {\n const uid = c.req.param(\"uid\");\n const authUser = c.get(\"user\") as { uid?: string } | undefined;\n\n if (authUser?.uid === uid) {\n throw ApiError.badRequest(\"Cannot delete your own account\", \"SELF_DELETE\");\n }\n\n const existing = await authRepo.getUserById(uid);\n if (!existing) {\n throw ApiError.notFound(\"User not found\");\n }\n\n const roles = await authRepo.getUserRoleIds(uid);\n if (roles.includes(\"admin\")) {\n const adminUsers = await authRepo.listUsersPaginated({\n roleId: \"admin\",\n limit: 1\n });\n if (adminUsers.total <= 1) {\n throw ApiError.forbidden(\"Cannot delete the last administrator\", \"LAST_ADMIN\");\n }\n }\n\n // The delete hooks fire here, because this is where users are deleted.\n //\n // They had a single call site — `UserManagementAdapter.deleteUser` — and\n // no route invokes it, so `beforeUserDelete` and `afterUserDelete` fired\n // on no reachable path at all. Both the boot warning and\n // `authentication.md` tell developers to use exactly these hooks for the\n // side effects their collection callbacks will not see on this path, so\n // anyone who followed that advice had a veto that vetoed nothing and a\n // cleanup that never ran.\n //\n // `beforeUserDelete` throws to prevent the deletion, so it is awaited\n // before the write; `afterUserDelete` is fire-and-forget, so a failing\n // listener cannot fail a deletion that already happened.\n if (ops.beforeUserDelete) {\n await ops.beforeUserDelete(uid);\n }\n\n await authRepo.deleteUser(uid);\n\n if (ops.afterUserDelete) {\n ops.afterUserDelete(uid).catch(err => {\n logger.error(\"[AuthHooks] afterUserDelete error\", {\n error: err instanceof Error ? err.message : err\n });\n });\n }\n\n return c.json({ success: true });\n });\n\n return router;\n}\n","/**\n * RebaseBuiltinAuthAdapter\n *\n * Wraps Rebase's existing built-in JWT auth system (routes, middleware, user/role\n * management) into the `AuthAdapter` interface. This is the default adapter used\n * when the user passes a plain `RebaseAuthConfig` object.\n *\n * This is NOT a rewrite — it delegates to the existing `createAuthRoutes()`,\n * `createResetPasswordRoute()`, and `verifyAccessToken()` functions. The goal is to\n * present the same functionality through the pluggable `AuthAdapter` contract.\n */\n\nimport type {\n AuthAdapter,\n AuthenticatedUser,\n AuthAdapterCapabilities,\n UserManagementAdapter,\n AuthUserListOptions,\n AuthUserListResult,\n AuthUserData,\n AuthCreateUserData,\n BootstrappedAuth\n} from \"@rebasepro/types\";\n\nimport { Hono } from \"hono\";\nimport { isAccessTokenRevoked } from \"./token-revocation\";\nimport { hasAdministrativeRole } from \"./admin-roles\";\nimport { verifyAccessToken } from \"./jwt\";\nimport type { AccessTokenPayload } from \"./jwt\";\nimport { createAuthRoutes } from \"./routes\";\nimport { isAnonymousAuthOpen, isRegistrationOpen } from \"./registration-policy\";\nimport { createResetPasswordRoute } from \"./reset-password-admin\";\nimport { createAdminRolesRoute } from \"./admin-roles-route\";\nimport { createAdminUsersRoute } from \"./admin-users-route\";\nimport { prepareAdminUserValues, finalizeAdminUserCreation } from \"./admin-user-ops\";\nimport type { AuthRepository, OAuthProvider } from \"./interfaces\";\nimport type { AuthHooks, ResolvedAuthHooks } from \"./auth-hooks\";\nimport { resolveAuthHooks } from \"./auth-hooks\";\nimport type { EmailService, EmailConfig } from \"../email\";\nimport type { HonoEnv } from \"../api/types\";\nimport { safeCompare } from \"./crypto-utils\";\nimport { extractBearerToken } from \"./bearer-token\";\nimport { logger } from \"../utils/logger\";\n\n/**\n * Configuration for the built-in Rebase auth adapter.\n *\n * This mirrors the existing `RebaseAuthConfig` — users pass this and\n * server auto-wraps it in a `RebaseBuiltinAuthAdapter`.\n */\nexport interface BuiltinAuthAdapterConfig {\n /** The bootstrapper-provided auth repository (users, roles, tokens). */\n authRepository: AuthRepository;\n /** Email service for password resets, verification, etc. */\n emailService?: EmailService;\n /** Email configuration. */\n emailConfig?: EmailConfig;\n /** Whether to allow new user registration. */\n allowRegistration?: boolean;\n /**\n * Hard kill switch: block self-registration outright, including the\n * first-user bootstrap window that an empty database would otherwise open.\n *\n * Was declared on the route module and read by both config endpoints, but\n * never plumbed through here — so nothing a user of the framework could\n * write ever reached it, and the tests that covered it passed only because\n * they built `createAuthRoutes` directly, bypassing this adapter (the sole\n * wiring path a real backend uses).\n */\n disableSelfRegistration?: boolean;\n /**\n * Opt-in: allow `POST /auth/anonymous` to mint a user without credentials.\n *\n * Off by default, and overridden by `disableSelfRegistration`. Anonymous\n * sign-in inserts a `users` row and assigns `defaultRole` exactly as\n * registration does, so before this key existed a closed backend still\n * handed out permanent accounts via `/auth/anonymous` + `/auth/anonymous/link`.\n */\n allowAnonymous?: boolean;\n /** Whether to expose the authenticated email→minimal-profile lookup route. */\n allowUserLookup?: boolean;\n /** Default role to assign to new users. */\n defaultRole?: string;\n /** OAuth providers to register. */\n oauthProviders?: OAuthProvider<unknown>[];\n /** Redirect URIs the OAuth routes accept, for every provider. */\n allowedRedirectUris?: string[];\n /** Static service key for server-to-server auth. */\n serviceKey?: string;\n /** Auth hooks for customizing password, credentials, lifecycle, etc. */\n authHooks?: AuthHooks;\n /** The parsed auth config from the collection (if `auth` is an object, not just `true`). */\n collectionAuthConfig?: import(\"@rebasepro/types\").AuthCollectionConfig;\n /** Enable magic link (passwordless email) login. Requires email service. */\n enableMagicLink?: boolean;\n /** Opt-in httpOnly cookie mode for refresh tokens. */\n cookieAuth?: import(\"./routes\").CookieAuthConfig;\n}\n\n/**\n * Create the built-in Rebase auth adapter.\n *\n * This wraps the existing auth infrastructure (JWT, OAuth, user/role management)\n * into the `AuthAdapter` interface. It's used internally by `initializeRebaseBackend()`\n * when the user passes a plain `RebaseAuthConfig` object.\n */\nexport function createBuiltinAuthAdapter(config: BuiltinAuthAdapterConfig): AuthAdapter {\n const {\n authRepository,\n emailService,\n emailConfig,\n allowRegistration = false,\n disableSelfRegistration = false,\n allowAnonymous = false,\n allowUserLookup = false,\n defaultRole,\n oauthProviders = [],\n allowedRedirectUris,\n serviceKey,\n authHooks,\n collectionAuthConfig,\n enableMagicLink = false,\n cookieAuth\n } = config;\n\n const resolvedOps = resolveAuthHooks(authHooks);\n\n const adapter: AuthAdapter = {\n id: \"rebase-builtin\",\n\n serviceKey,\n\n async verifyRequest(request: Request): Promise<AuthenticatedUser | null> {\n // Tokens are accepted ONLY via the Authorization header. A `?token=`\n // query param must NOT authenticate here: URLs leak into access\n // logs, proxies, Referer headers, and browser history, and the\n // non-adapter middleware already refuses query tokens for exactly\n // that reason. Routes that legitimately need query-string tokens\n // (storage file serving for `<img src>`) use scoped download\n // tokens via `fileTokenAuth`, which never reach this adapter.\n const token = extractBearerToken(request.headers.get(\"authorization\"));\n\n if (token === undefined) {\n return null;\n }\n\n // Check service key first (constant-time)\n if (serviceKey && safeCompare(token, serviceKey)) {\n return {\n uid: \"service\",\n email: \"service@rebase.internal\",\n roles: [\"admin\"],\n isAdmin: true,\n rawToken: token\n };\n }\n\n // JWT verification\n const payload = verifyAccessToken(token);\n if (!payload) {\n return null;\n }\n\n // A token issued before the user's revocation watermark is void,\n // however well it verifies. This is the read that makes `logout`,\n // `change-password`, `reset-password` and `DELETE /auth/sessions`\n // reach the access token instead of only the refresh row.\n if (await isAccessTokenRevoked(authRepository, payload)) {\n logger.warn(\"[Security Audit] Refused a revoked access token\", {\n eventType: \"auth.token.revoked\",\n uid: payload.uid\n });\n return null;\n }\n\n // Resolve roles from the repository\n let roles: string[] = payload.roles || [];\n try {\n roles = await authRepository.getUserRoleIds(payload.uid);\n } catch (err: unknown) {\n logger.warn(\"Role lookup from repository failed, using token roles as fallback\", { uid: payload.uid, error: err });\n }\n\n const isAdmin = hasAdministrativeRole(roles);\n\n return {\n uid: payload.uid,\n email: payload.email ?? \"\",\n displayName: payload.displayName ?? null,\n roles,\n isAdmin,\n rawToken: token\n };\n },\n\n async verifyToken(token: string): Promise<AuthenticatedUser | null> {\n // Service key check (constant-time)\n if (serviceKey && safeCompare(token, serviceKey)) {\n return {\n uid: \"service\",\n email: \"service@rebase.internal\",\n roles: [\"admin\"],\n isAdmin: true,\n rawToken: token\n };\n }\n\n // JWT verification\n const payload = verifyAccessToken(token);\n if (!payload) {\n return null;\n }\n\n let roles: string[] = payload.roles || [];\n try {\n roles = await authRepository.getUserRoleIds(payload.uid);\n } catch (err: unknown) {\n logger.warn(\"Role lookup from repository failed, using token roles as fallback\", { uid: payload.uid, error: err });\n }\n\n const isAdmin = hasAdministrativeRole(roles);\n\n return {\n uid: payload.uid,\n email: payload.email ?? \"\",\n displayName: payload.displayName ?? null,\n roles,\n isAdmin,\n rawToken: token\n };\n },\n\n userManagement: createUserManagementFromRepo(authRepository, resolvedOps),\n\n\n createAuthRoutes(): Hono<HonoEnv> | undefined {\n return createAuthRoutes({\n authRepo: authRepository,\n emailService,\n emailConfig,\n allowRegistration,\n disableSelfRegistration,\n allowAnonymous,\n allowUserLookup,\n defaultRole,\n oauthProviders,\n allowedRedirectUris,\n authHooks,\n enableMagicLink,\n cookieAuth\n });\n },\n\n createAdminRoutes(): Hono<HonoEnv> | undefined {\n const router = new Hono<HonoEnv>();\n const resetPasswordRoute = createResetPasswordRoute({\n authRepo: authRepository,\n emailService,\n emailConfig,\n serviceKey,\n authHooks,\n collectionAuthConfig\n });\n const rolesRoute = createAdminRolesRoute({\n authRepo: authRepository,\n serviceKey\n });\n const adminUsersRoute = createAdminUsersRoute({\n authRepo: authRepository,\n emailService,\n emailConfig,\n serviceKey,\n authHooks,\n collectionAuthConfig\n });\n router.route(\"/\", resetPasswordRoute);\n router.route(\"/\", rolesRoute);\n router.route(\"/\", adminUsersRoute);\n return router;\n },\n\n async prepareUserCreation(values, collectionAuth) {\n const parsedCollectionAuth = collectionAuth as import(\"@rebasepro/types\").AuthCollectionConfig | undefined;\n return prepareAdminUserValues(values, {\n authRepo: authRepository,\n emailService,\n emailConfig,\n resolvedHooks: resolvedOps,\n collectionAuthConfig: parsedCollectionAuth ?? collectionAuthConfig\n });\n },\n\n describeUserCreationContract(collectionAuth) {\n const parsedCollectionAuth = collectionAuth as import(\"@rebasepro/types\").AuthCollectionConfig | undefined;\n const authConfig = parsedCollectionAuth ?? collectionAuthConfig;\n\n // A custom hook owns the body's shape — `prepareAdminUserValues`\n // hands it the raw body and returns whatever the hook built, so the\n // fields it accepts are the hook's business and unknowable here.\n // Checking against the collection would reject bodies the hook is\n // designed to take.\n if (authConfig?.onCreateUser || resolvedOps.onAdminCreateUser) {\n return { validate: false, extraFields: [] };\n }\n\n // The built-in path consumes exactly one field the users table does\n // not declare: `password`, which it hashes into `passwordHash` and\n // deletes. Everything else it spreads through untouched, so\n // everything else has to be a real column.\n return { validate: true, extraFields: [\"password\"] };\n },\n\n async finalizeUserCreation(entity, clearPassword) {\n return finalizeAdminUserCreation(entity, clearPassword, {\n authRepo: authRepository,\n emailService,\n emailConfig,\n resolvedHooks: resolvedOps,\n collectionAuthConfig\n });\n },\n\n async getCapabilities(): Promise<AuthAdapterCapabilities> {\n // Detect bootstrap mode: are there any users?\n let needsSetup = false;\n try {\n const result = await authRepository.listUsersPaginated({ limit: 1 });\n needsSetup = result.total === 0;\n } catch {\n // If the check fails, assume not in setup mode\n }\n\n const enabledProviders = oauthProviders.map((p) => p.id);\n\n // This is what `GET /auth/config` actually returns: init.ts\n // registers that path directly, before mounting the auth router, so\n // Hono resolves it here and never reaches the session-routes copy.\n // Both go through the shared predicate now, precisely because the\n // copy that was easy to overlook is the one that was live.\n const registrationAllowed = isRegistrationOpen({\n disableSelfRegistration,\n allowRegistration,\n needsSetup\n });\n const anonymousAllowed = isAnonymousAuthOpen({\n allowAnonymous,\n disableSelfRegistration\n });\n\n return {\n hasBuiltInAuthRoutes: true,\n emailPasswordLogin: true,\n registration: registrationAllowed,\n registrationEnabled: registrationAllowed,\n passwordReset: !!emailService?.isConfigured(),\n // Always available: createAdminRoutes() unconditionally mounts the\n // reset-password route, which falls back to returning a one-time\n // temporary password when no email service is configured.\n adminPasswordReset: true,\n sessionManagement: true,\n profileUpdate: true,\n emailVerification: !!emailService?.isConfigured(),\n magicLink: enableMagicLink && !!emailService?.isConfigured(),\n // Anonymous auth was reachable and undiscoverable: no key turned\n // it off and no capability announced it was on.\n anonymousLogin: anonymousAllowed,\n enabledProviders,\n needsSetup\n };\n }\n };\n\n return adapter;\n}\n\n// ─── Internal Helpers ────────────────────────────────────────────────────────\n\nfunction createUserManagementFromRepo(repo: AuthRepository, resolvedOps: ResolvedAuthHooks): UserManagementAdapter {\n return {\n async listUsers(options?: AuthUserListOptions): Promise<AuthUserListResult> {\n const result = await repo.listUsersPaginated({\n limit: options?.limit,\n offset: options?.offset,\n search: options?.search,\n orderBy: options?.orderBy,\n orderDir: options?.orderDir,\n roleId: options?.roleId\n });\n return {\n users: result.users.map(toAuthUserData),\n total: result.total,\n limit: result.limit,\n offset: result.offset\n };\n },\n\n async getUserById(id: string): Promise<AuthUserData | null> {\n const user = await repo.getUserById(id);\n return user ? toAuthUserData(user) : null;\n },\n\n async createUser(data: AuthCreateUserData): Promise<AuthUserData> {\n const passwordHash = data.password ? await resolvedOps.hashPassword(data.password) : undefined;\n let createData: import(\"./interfaces\").CreateUserData = {\n email: data.email,\n passwordHash,\n displayName: data.displayName,\n photoUrl: data.photoUrl,\n metadata: data.metadata\n };\n if (resolvedOps.beforeUserCreate) {\n createData = await resolvedOps.beforeUserCreate(createData);\n }\n const user = await repo.createUser(createData);\n if (resolvedOps.afterUserCreate) {\n try {\n await resolvedOps.afterUserCreate(user);\n } catch (err) {\n logger.error(\"[AuthHooks] afterUserCreate error\", { error: err instanceof Error ? err.message : err });\n }\n }\n return toAuthUserData(user);\n },\n\n async updateUser(id: string, data: Partial<AuthCreateUserData>): Promise<AuthUserData | null> {\n const updateData: Record<string, unknown> = {};\n if (data.email !== undefined) updateData.email = data.email;\n if (data.displayName !== undefined) updateData.displayName = data.displayName;\n if (data.photoUrl !== undefined) updateData.photoUrl = data.photoUrl;\n if (data.metadata !== undefined) updateData.metadata = data.metadata;\n if (data.password) {\n updateData.passwordHash = await resolvedOps.hashPassword(data.password);\n }\n const user = await repo.updateUser(id, updateData);\n return user ? toAuthUserData(user) : null;\n },\n\n async deleteUser(id: string): Promise<void> {\n // Call beforeUserDelete hook (throw to prevent deletion)\n if (resolvedOps.beforeUserDelete) {\n await resolvedOps.beforeUserDelete(id);\n }\n\n await repo.deleteUser(id);\n\n // Fire afterUserDelete hook (fire-and-forget)\n if (resolvedOps.afterUserDelete) {\n resolvedOps.afterUserDelete(id).catch(err => {\n logger.error(\"[AuthHooks] afterUserDelete error\", { error: err instanceof Error ? err.message : err });\n });\n }\n },\n\n async getUserRoles(uid: string): Promise<string[]> {\n return repo.getUserRoleIds(uid);\n },\n\n async setUserRoles(uid: string, roleIds: string[]): Promise<void> {\n await repo.setUserRoles(uid, roleIds);\n }\n };\n}\n\nfunction toAuthUserData(user: { id: string; email: string; displayName?: string | null; photoUrl?: string | null; emailVerified?: boolean; metadata?: Record<string, unknown>; createdAt?: Date; updatedAt?: Date }): AuthUserData {\n return {\n id: user.id,\n email: user.email,\n displayName: user.displayName,\n photoUrl: user.photoUrl,\n emailVerified: user.emailVerified,\n metadata: user.metadata,\n createdAt: user.createdAt,\n updatedAt: user.updatedAt\n };\n}\n","import { z } from \"zod\";\n\n/**\n * The authorization-code request shape every OAuth provider accepts, and the\n * two derivations of it that were previously copy-pasted twelve times.\n *\n * Twelve providers declared their own `z.object({ code, redirectUri })` and\n * each decided independently whether to accept a PKCE verifier (one did) and\n * how to read a verification signal off the provider's profile response (five\n * skipped the question and hardcoded `true`). One predicate, twelve\n * implementations — so the controls below live here and every provider calls\n * them, which is what makes it impossible for a thirteenth provider to ship\n * without them.\n */\n\n/** The request body every authorization-code provider consumes. */\nexport interface OAuthCodeFlowPayload {\n /** Authorization code returned to the client by the provider. */\n code: string;\n /**\n * Redirect URI the code was issued against. Echoed to the token endpoint,\n * which is what binds the code to the client that started the flow — and\n * why the route allowlists it before `verify` ever runs\n * (see `isRedirectUriAllowed`).\n */\n redirectUri: string;\n /**\n * PKCE verifier, when the client started the flow with a\n * `code_challenge`. Forwarded to the token endpoint verbatim.\n */\n codeVerifier?: string;\n}\n\n/**\n * Build the request schema for an authorization-code provider.\n *\n * `pkce` defaults to `\"optional\"`: the client decides whether it sent a\n * `code_challenge`, and providers that do not implement PKCE simply never see\n * a verifier because their clients never generate one. `\"required\"` is for\n * providers that mandate PKCE (Twitter/X).\n */\nexport function oauthCodeFlowSchema(opts: { pkce?: \"required\" | \"optional\" } = {}) {\n const verifier = opts.pkce === \"required\"\n ? z.string().min(1, \"PKCE code verifier is required\")\n : z.string().min(1).optional();\n\n return z.object({\n code: z.string().min(1, \"Auth code is required\"),\n redirectUri: z.string().url(\"Valid redirect URI is required\"),\n codeVerifier: verifier\n });\n}\n\n/**\n * The `code_verifier` token-endpoint parameter, or nothing.\n *\n * Returned as a spreadable object so a provider adds PKCE with one `...` in\n * its existing body literal, rather than branching.\n */\nexport function pkceTokenParams(codeVerifier?: string): Record<string, string> {\n return codeVerifier ? { code_verifier: codeVerifier } : {};\n}\n\n/**\n * Normalise a provider's email-verification signal into the boolean that\n * `OAuthProviderProfile.emailVerified` promises.\n *\n * The whole point is the default: anything that is not an affirmative\n * verification signal — `undefined`, `null`, a missing field, an empty string,\n * `false` — becomes `false`. A provider that reports nothing therefore cannot\n * accidentally assert that it verified the address, which is exactly the\n * mistake five providers had made.\n *\n * Accepts the string forms because OIDC issuers are inconsistent about whether\n * `email_verified` is a JSON boolean or a string.\n */\nexport function providerVerifiedEmail(signal: unknown): boolean {\n if (signal === true) return true;\n if (typeof signal === \"string\") {\n const normalized = signal.trim().toLowerCase();\n return normalized === \"true\" || normalized === \"1\";\n }\n return false;\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { z } from \"zod\";\nimport { logger } from \"../utils/logger\";\nimport { pkceTokenParams, providerVerifiedEmail } from \"./oauth-code-flow\";\n\nlet _googleAuth: typeof import(\"google-auth-library/build/src/index.js\") | undefined;\n\nasync function loadGoogleAuth() {\n if (!_googleAuth) {\n try {\n _googleAuth = await import(\"google-auth-library/build/src/index.js\");\n } catch {\n throw new Error(\n \"google-auth-library is required for Google OAuth. \" +\n \"Install it: pnpm add google-auth-library\"\n );\n }\n }\n return _googleAuth;\n}\n\n/**\n * Verify a Google **access token** and resolve it to a profile.\n *\n * SECURITY: an access token must be checked against Google's `tokeninfo`\n * endpoint so we can confirm its `aud` (the OAuth client the token was issued\n * to) matches *our* `clientId`. The `userinfo` endpoint does **not** verify\n * audience — it returns a profile for any valid Google access token — so\n * trusting it alone lets an attacker present a token they obtained for a\n * *different* client (e.g. their own app, via a phished consent) and log in as\n * whatever account that token belongs to. The `aud` check is what binds the\n * token to this application.\n *\n * Identity (`sub` / `email` / `email_verified`) is taken from the\n * audience-checked `tokeninfo` response. `userinfo` is used only, best-effort,\n * to enrich display fields (name, picture).\n */\nasync function verifyGoogleAccessToken(\n accessToken: string,\n expectedClientId: string\n): Promise<OAuthProviderProfile> {\n const tokenInfoRes = await fetch(\n `https://oauth2.googleapis.com/tokeninfo?access_token=${encodeURIComponent(accessToken)}`\n );\n if (!tokenInfoRes.ok) {\n throw new Error(`Google tokeninfo request failed with status ${tokenInfoRes.status}`);\n }\n const tokenInfo = await tokenInfoRes.json() as {\n aud?: string;\n sub?: string;\n email?: string;\n // The legacy tokeninfo endpoint returns this as the string \"true\"/\"false\".\n email_verified?: string | boolean;\n };\n\n if (tokenInfo.aud !== expectedClientId) {\n throw new Error(\n \"Google access token audience mismatch: the token was not issued for this application\"\n );\n }\n if (!tokenInfo.sub || !tokenInfo.email) {\n throw new Error(\"Google access token missing sub or email (the email scope is required)\");\n }\n\n const emailVerified = providerVerifiedEmail(tokenInfo.email_verified);\n\n let displayName: string | null = null;\n let photoUrl: string | null = null;\n try {\n const res = await fetch(\n \"https://www.googleapis.com/oauth2/v3/userinfo\",\n { headers: { Authorization: `Bearer ${accessToken}` } }\n );\n if (res.ok) {\n const info = await res.json() as { name?: string; picture?: string };\n displayName = info.name || null;\n photoUrl = info.picture || null;\n }\n } catch {\n // Non-fatal: identity is already established from tokeninfo.\n }\n\n return {\n providerId: tokenInfo.sub,\n email: tokenInfo.email,\n displayName,\n photoUrl,\n emailVerified\n };\n}\n\nexport interface GoogleUserInfo {\n googleId: string;\n email: string;\n displayName: string | null;\n photoUrl: string | null;\n emailVerified: boolean;\n}\n\nexport interface GoogleProviderConfig {\n clientId: string;\n /**\n * The OAuth 2.0 client secret from Google Cloud Console.\n *\n * Required for the **authorization code flow** (Path 3), where the\n * frontend sends an authorization `code` and the backend exchanges it\n * server-side for tokens. This is the most secure flow because tokens\n * never touch the browser.\n *\n * When omitted, only ID-token and access-token verification are available\n * (Paths 1 & 2), which rely on the frontend obtaining tokens directly.\n */\n clientSecret?: string;\n}\n\n/**\n * Creates a Google OAuth Provider integration.\n *\n * Supports three verification paths:\n *\n * **Path 1 – ID Token** (One Tap / Sign In With Google button):\n * Frontend sends `idToken`. Backend verifies cryptographically using\n * Google's public keys. No secret required.\n *\n * **Path 2 – Access Token** (popup via `initTokenClient`):\n * Frontend sends `accessToken`. Backend validates by calling Google's\n * userinfo endpoint. No secret required.\n *\n * **Path 3 – Authorization Code** (most secure, requires `clientSecret`):\n * Frontend sends `code` + `redirectUri`. Backend exchanges the code\n * server-side for an ID token using `clientId` + `clientSecret`, then\n * verifies the ID token. Tokens never touch the browser.\n */\nexport function createGoogleProvider(config: GoogleProviderConfig | string): OAuthProvider<{\n idToken?: string;\n accessToken?: string;\n code?: string;\n redirectUri?: string;\n codeVerifier?: string;\n}> {\n const clientId = typeof config === \"string\" ? config : config.clientId;\n const clientSecret = typeof config === \"string\" ? undefined : config.clientSecret;\n\n // The admin panel's login button uses the authorization-code flow, which\n // needs the secret. Without it the provider still advertises itself, the\n // button still renders, and the failure only surfaces when someone clicks\n // it — so say it at boot instead.\n if (!clientSecret) {\n console.warn(\n \"[Rebase] Google provider configured without a client secret. ID-token and access-token \"\n + \"sign-in still work, but the authorization-code flow used by the admin login button will \"\n + \"fail. Set GOOGLE_CLIENT_SECRET to enable it.\"\n );\n }\n let googleClient: InstanceType<typeof import(\"google-auth-library/build/src/index.js\").OAuth2Client> | undefined;\n\n async function getClient() {\n if (!googleClient) {\n const { OAuth2Client } = await loadGoogleAuth();\n googleClient = new OAuth2Client(clientId, clientSecret);\n }\n return googleClient;\n }\n\n return {\n id: \"google\",\n schema: z.object({\n idToken: z.string().min(1).optional(),\n accessToken: z.string().min(1).optional(),\n code: z.string().min(1).optional(),\n redirectUri: z.string().min(1).optional(),\n codeVerifier: z.string().min(1).optional()\n }).refine(\n (data) => data.idToken || data.accessToken || (data.code && data.redirectUri),\n { message: \"One of idToken, accessToken, or code+redirectUri is required\" }\n ),\n verify: async (payload: {\n idToken?: string;\n accessToken?: string;\n code?: string;\n redirectUri?: string;\n codeVerifier?: string;\n }): Promise<OAuthProviderProfile | null> => {\n try {\n // Path 1: verify an ID token (One Tap / renderButton)\n if (payload.idToken) {\n const client = await getClient();\n const ticket = await client.verifyIdToken({\n idToken: payload.idToken,\n audience: clientId\n });\n\n const content = ticket.getPayload();\n if (!content) {\n throw new Error(\"Google ID token payload was empty\");\n }\n\n return {\n providerId: content.sub,\n email: content.email || \"\",\n displayName: content.name || null,\n photoUrl: content.picture || null,\n emailVerified: providerVerifiedEmail(content.email_verified)\n };\n }\n\n // Path 2: verify a client-supplied access token. This validates\n // the token's audience against our clientId — see\n // verifyGoogleAccessToken — before trusting the identity.\n if (payload.accessToken) {\n return await verifyGoogleAccessToken(payload.accessToken, clientId);\n }\n\n // Path 3: authorization code exchange (most secure)\n // The frontend obtained a one-time authorization code via the\n // Google OAuth consent screen. We exchange it server-side for\n // tokens, so the access/id tokens never touch the browser.\n if (payload.code && payload.redirectUri) {\n if (!clientSecret) {\n throw new Error(\n \"Google authorization code flow requires clientSecret. \" +\n \"Configure GOOGLE_CLIENT_SECRET in your environment.\"\n );\n }\n\n // Exchange the authorization code for tokens\n const tokenResponse = await fetch(\"https://oauth2.googleapis.com/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n code: payload.code,\n client_id: clientId,\n client_secret: clientSecret,\n redirect_uri: payload.redirectUri,\n grant_type: \"authorization_code\",\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n const errorBody = await tokenResponse.text();\n throw new Error(`Google token exchange failed (${tokenResponse.status}): ${errorBody}`);\n }\n\n const tokenData = await tokenResponse.json() as {\n id_token?: string;\n access_token?: string;\n error?: string;\n error_description?: string;\n };\n\n if (tokenData.error) {\n throw new Error(`Google token exchange error: ${tokenData.error} – ${tokenData.error_description || \"no details\"}`);\n }\n\n // Prefer verifying the ID token (cryptographic verification)\n if (tokenData.id_token) {\n const client = await getClient();\n const ticket = await client.verifyIdToken({\n idToken: tokenData.id_token,\n audience: clientId\n });\n\n const content = ticket.getPayload();\n if (!content) {\n throw new Error(\"Google ID token payload was empty after code exchange\");\n }\n\n return {\n providerId: content.sub,\n email: content.email || \"\",\n displayName: content.name || null,\n photoUrl: content.picture || null,\n emailVerified: providerVerifiedEmail(content.email_verified)\n };\n }\n\n // Fallback: use the access token from our own confidential\n // exchange. Its audience is necessarily our clientId, so the\n // check in verifyGoogleAccessToken passes — we route through\n // it anyway for a single trusted identity path.\n if (tokenData.access_token) {\n return await verifyGoogleAccessToken(tokenData.access_token, clientId);\n }\n\n throw new Error(\"Google token exchange returned neither id_token nor access_token\");\n }\n\n throw new Error(\"No valid Google credential provided (expected idToken, accessToken, or code+redirectUri)\");\n } catch (error) {\n logger.error(\"Google OAuth verification failed\", { error: error });\n throw error;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\nexport interface LinkedinUserInfo {\n linkedinId: string;\n email: string;\n displayName: string | null;\n photoUrl: string | null;\n emailVerified: boolean;\n}\n\n/**\n * Creates a LinkedIn OAuth Provider integration\n */\nexport function createLinkedinProvider(config: { clientId: string, clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"linkedin\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n // Exchange code for access token\n const tokenResponse = await fetch(\"https://www.linkedin.com/oauth/v2/accessToken\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n code: payload.code,\n redirect_uri: payload.redirectUri,\n client_id: config.clientId,\n client_secret: config.clientSecret,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n const errBody = await tokenResponse.text();\n logger.error(\"Failed to get LinkedIn access token\", { detail: errBody });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string; id_token?: string };\n const accessToken = tokenData.access_token;\n\n // Fetch User Info using OIDC userinfo endpoint\n const profileResponse = await fetch(\"https://api.linkedin.com/v2/userinfo\", {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`\n }\n });\n\n if (!profileResponse.ok) {\n const errBody = await profileResponse.text();\n logger.error(\"Failed to get LinkedIn user info\", { detail: errBody });\n return null;\n }\n\n const profileData = await profileResponse.json() as {\n sub: string;\n email?: string;\n name?: string;\n picture?: string;\n email_verified?: boolean;\n };\n\n if (!profileData.email) {\n logger.error(\"LinkedIn user has no email (the 'email' scope may not have been granted)\");\n return null;\n }\n\n return {\n providerId: profileData.sub,\n email: profileData.email,\n displayName: profileData.name || null,\n photoUrl: profileData.picture || null,\n emailVerified: providerVerifiedEmail(profileData.email_verified)\n };\n } catch (error) {\n logger.error(\"LinkedIn OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a GitHub OAuth Provider integration.\n *\n * Flow: Frontend receives an authorization `code` via the GitHub OAuth redirect.\n * This provider exchanges the code for an access token, then fetches the user's\n * profile and primary email from the GitHub API.\n */\nexport function createGitHubProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"github\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n // Exchange code for access token\n const tokenResponse = await fetch(\"https://github.com/login/oauth/access_token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Accept\": \"application/json\"\n },\n body: JSON.stringify({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n code: payload.code,\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get GitHub access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token?: string; error?: string };\n if (tokenData.error || !tokenData.access_token) {\n logger.error(\"GitHub token exchange error\", { detail: tokenData.error });\n return null;\n }\n\n const accessToken = tokenData.access_token;\n\n // Fetch user profile\n const profileResponse = await fetch(\"https://api.github.com/user\", {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"Accept\": \"application/vnd.github+json\",\n \"User-Agent\": \"Rebase-Auth\"\n }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get GitHub user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const profileData = await profileResponse.json() as {\n id: number;\n login: string;\n name?: string | null;\n avatar_url?: string | null;\n email?: string | null;\n };\n\n // `/user`'s `email` is the *public profile* address — GitHub\n // applies no verification to it, and it is often absent\n // anyway. `/user/emails` is the only endpoint that reports a\n // `verified` flag, so ask it unconditionally rather than\n // treating the profile field as a fast path that skips the\n // check: that fast path is precisely what used to reach the\n // hardcoded `emailVerified: true` below.\n let email = profileData.email;\n let emailVerified = false;\n\n const emailsResponse = await fetch(\"https://api.github.com/user/emails\", {\n headers: {\n \"Authorization\": `Bearer ${accessToken}`,\n \"Accept\": \"application/vnd.github+json\",\n \"User-Agent\": \"Rebase-Auth\"\n }\n });\n\n if (emailsResponse.ok) {\n const emails = await emailsResponse.json() as Array<{\n email: string;\n primary: boolean;\n verified: boolean;\n }>;\n const chosen = emails.find(e => e.primary && e.verified)\n || emails.find(e => e.verified)\n || (email ? emails.find(e => e.email.toLowerCase() === email!.toLowerCase()) : undefined);\n if (chosen) {\n email = chosen.email;\n emailVerified = providerVerifiedEmail(chosen.verified);\n }\n }\n\n if (!email) {\n logger.error(\"GitHub user has no email\");\n return null;\n }\n\n return {\n providerId: String(profileData.id),\n email,\n displayName: profileData.name || profileData.login || null,\n photoUrl: profileData.avatar_url || null,\n emailVerified\n };\n } catch (error) {\n logger.error(\"GitHub OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import jwt from \"jsonwebtoken\";\nimport { createPublicKey, type KeyObject } from \"crypto\";\nimport { logger } from \"../utils/logger\";\n\n/**\n * Minimal JWKS-backed id_token verification, shared by the OIDC providers.\n *\n * Apple's id_token used to be `split(\".\")` + `JSON.parse`, justified by the\n * comment \"we only need the payload\". That skips `aud` — nothing confirmed the\n * token was minted for *this* Services ID rather than another one under the\n * same Apple team — along with `iss`, `exp` and the signature. Microsoft did\n * not request an id_token at all and inferred verification from a directory\n * attribute instead.\n *\n * Deliberately hand-rolled rather than pulling in a JWKS client: the only\n * cryptography here is `jsonwebtoken`'s (already a dependency) and Node's own\n * JWK→KeyObject import. What this file adds is key discovery and a cache.\n */\n\nexport interface OidcIdTokenClaims {\n sub: string;\n iss: string;\n aud: string | string[];\n exp: number;\n email?: string;\n email_verified?: boolean | string;\n nonce?: string;\n [claim: string]: unknown;\n}\n\nexport interface VerifyOidcIdTokenOptions {\n /** The compact JWS to verify. */\n idToken: string;\n /** JWKS endpoint of the issuer. */\n jwksUri: string;\n /**\n * Expected `iss`. A `RegExp` is for multi-tenant issuers whose tenant id is\n * part of the issuer URL (Entra ID with `tenantId: \"common\"`); everything\n * else passes the exact string.\n */\n issuer: string | RegExp;\n /** Expected `aud` — the client/services id this backend is configured with. */\n audience: string;\n /** Permitted signing algorithms. Defaults to RS256, which is what Apple and Entra use. */\n algorithms?: jwt.Algorithm[];\n /** Seconds of clock skew tolerated on `exp`/`iat`. Defaults to 60. */\n clockToleranceSec?: number;\n /** Expected `nonce`, when the client bound one to the authorization request. */\n nonce?: string;\n /** Injection point for tests; defaults to global `fetch`. */\n fetchImpl?: typeof fetch;\n}\n\ninterface Jwk {\n kid?: string;\n kty?: string;\n alg?: string;\n use?: string;\n [param: string]: unknown;\n}\n\ninterface CachedJwks {\n keys: Jwk[];\n fetchedAt: number;\n}\n\nconst JWKS_TTL_MS = 10 * 60 * 1000;\nconst jwksCache = new Map<string, CachedJwks>();\n\n/** Drops the JWKS cache. Exported for tests; nothing in the runtime calls it. */\nexport function resetJwksCache(): void {\n jwksCache.clear();\n}\n\nasync function loadJwks(jwksUri: string, fetchImpl: typeof fetch, forceRefresh: boolean): Promise<Jwk[]> {\n const cached = jwksCache.get(jwksUri);\n if (!forceRefresh && cached && Date.now() - cached.fetchedAt < JWKS_TTL_MS) {\n return cached.keys;\n }\n const response = await fetchImpl(jwksUri);\n if (!response.ok) {\n throw new Error(`JWKS fetch failed (${response.status})`);\n }\n const body = await response.json() as { keys?: Jwk[] };\n const keys = Array.isArray(body.keys) ? body.keys : [];\n jwksCache.set(jwksUri, { keys, fetchedAt: Date.now() });\n return keys;\n}\n\nfunction toKeyObject(jwk: Jwk): KeyObject {\n // `format: \"jwk\"` is Node's own importer — no third-party JWK parsing.\n return createPublicKey({ key: jwk as Record<string, unknown>, format: \"jwk\" } as Parameters<typeof createPublicKey>[0]);\n}\n\nfunction decodeKid(idToken: string): string | undefined {\n const decoded = jwt.decode(idToken, { complete: true });\n return decoded?.header?.kid;\n}\n\n/**\n * Verify an id_token's signature, `aud`, `iss` and `exp`, and return its claims.\n *\n * Throws on any failure — callers treat a throw as \"reject this sign-in\",\n * never as \"continue without the claims\".\n */\nexport async function verifyOidcIdToken(options: VerifyOidcIdTokenOptions): Promise<OidcIdTokenClaims> {\n const {\n idToken,\n jwksUri,\n issuer,\n audience,\n algorithms = [\"RS256\"],\n clockToleranceSec = 60,\n nonce,\n fetchImpl = fetch\n } = options;\n\n if (!idToken || typeof idToken !== \"string\") {\n throw new Error(\"id_token missing\");\n }\n\n const kid = decodeKid(idToken);\n\n // An unknown `kid` is the normal signal that the issuer rotated its keys,\n // so miss the cache once before giving up.\n let keys = await loadJwks(jwksUri, fetchImpl, false);\n let jwk = keys.find((k) => !kid || k.kid === kid);\n if (!jwk) {\n keys = await loadJwks(jwksUri, fetchImpl, true);\n jwk = keys.find((k) => !kid || k.kid === kid);\n }\n if (!jwk) {\n throw new Error(`No JWKS key matches kid \"${kid ?? \"<none>\"}\"`);\n }\n\n const claims = jwt.verify(idToken, toKeyObject(jwk), {\n algorithms,\n audience,\n clockTolerance: clockToleranceSec\n }) as OidcIdTokenClaims;\n\n // `jsonwebtoken` only compares `iss` against a string or a list, so the\n // multi-tenant case is checked here rather than passed through.\n const issuerOk = typeof issuer === \"string\" ? claims.iss === issuer : issuer.test(String(claims.iss ?? \"\"));\n if (!issuerOk) {\n throw new Error(`Unexpected id_token issuer \"${claims.iss}\"`);\n }\n\n if (nonce !== undefined && claims.nonce !== nonce) {\n throw new Error(\"id_token nonce mismatch\");\n }\n\n return claims;\n}\n\n/**\n * `verifyOidcIdToken` that reports failure as `null` and logs it, for the one\n * call site that has to decide between \"reject\" and \"degrade\".\n */\nexport async function tryVerifyOidcIdToken(\n providerId: string,\n options: VerifyOidcIdTokenOptions\n): Promise<OidcIdTokenClaims | null> {\n try {\n return await verifyOidcIdToken(options);\n } catch (error) {\n logger.error(`[${providerId}] id_token verification failed`, {\n error: error instanceof Error ? error.message : error\n });\n return null;\n }\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\nimport { tryVerifyOidcIdToken } from \"./oidc-id-token\";\n\n/** Endpoints that federate to more than one directory. */\nconst MULTI_TENANT_ENDPOINTS = new Set([\"common\", \"organizations\", \"consumers\"]);\n\n/**\n * Creates a Microsoft / Entra ID (Azure AD) OAuth Provider integration.\n *\n * Supports both personal Microsoft accounts and work/school (Azure AD) accounts\n * via the \"common\" tenant endpoint. Uses the authorization code flow.\n *\n * ## On `emailVerified`\n *\n * Microsoft Graph exposes no email-verification field, and `mail` is *not* a\n * substitute: it is a directory attribute a tenant administrator sets to any\n * string they like, through Graph or AAD Connect sync. With the default\n * `tenantId: \"common\"` every Entra tenant in the world is an accepted issuer,\n * so \"there is a `mail` value\" would mean \"anybody who can create a free\n * tenant can nominate any address\" — including one that already has an account\n * here.\n *\n * The only signal Microsoft offers is the `xms_edov` (\"email domain owner\n * verified\") optional claim on the id_token, so that is what this provider\n * reads, off a signature-verified token. If the app registration does not emit\n * `xms_edov`, sign-in still works and the address comes back unverified —\n * which routes the user to `POST /auth/link/microsoft` rather than silently\n * handing them somebody else's account.\n */\nexport function createMicrosoftProvider(config: {\n clientId: string;\n clientSecret: string;\n /** Tenant ID. Defaults to \"common\" which allows both personal and organizational accounts. */\n tenantId?: string;\n}): OAuthProvider<OAuthCodeFlowPayload> {\n const tenantId = config.tenantId || \"common\";\n const multiTenant = MULTI_TENANT_ENDPOINTS.has(tenantId.toLowerCase());\n\n const jwksUri = `https://login.microsoftonline.com/${tenantId}/discovery/v2.0/keys`;\n // Single-tenant apps pin the issuer exactly. Multi-tenant ones cannot —\n // the tenant id is part of the issuer URL — so accept any well-formed\n // tenant GUID and lean on `xms_edov` for the verification decision.\n const issuer: string | RegExp = multiTenant\n ? /^https:\\/\\/login\\.microsoftonline\\.com\\/[0-9a-fA-F-]{36}\\/v2\\.0$/\n : `https://login.microsoftonline.com/${tenantId}/v2.0`;\n\n if (multiTenant) {\n logger.warn(\n `[Rebase] Microsoft provider configured with tenantId \"${tenantId}\", which accepts sign-ins from `\n + \"every Entra tenant. Email addresses are reported as unverified unless the app registration emits \"\n + \"the xms_edov optional claim. Set an explicit tenantId, or enable xms_edov, to allow automatic \"\n + \"linking onto existing accounts.\"\n );\n }\n\n return {\n id: \"microsoft\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n // Exchange code for access token\n const tokenResponse = await fetch(\n `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n code: payload.code,\n redirect_uri: payload.redirectUri,\n grant_type: \"authorization_code\",\n scope: \"openid profile email User.Read\",\n ...pkceTokenParams(payload.codeVerifier)\n })\n }\n );\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Microsoft access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string; id_token?: string };\n const accessToken = tokenData.access_token;\n\n // The `openid` scope above means Entra returns an id_token. If\n // one is present it must verify — a token that fails signature,\n // audience or issuer checks is not something to shrug off and\n // continue past.\n let idTokenClaims: Record<string, unknown> | null = null;\n if (tokenData.id_token) {\n idTokenClaims = await tryVerifyOidcIdToken(\"microsoft\", {\n idToken: tokenData.id_token,\n jwksUri,\n issuer,\n audience: config.clientId\n });\n if (!idTokenClaims) return null;\n }\n\n // Fetch user profile from Microsoft Graph\n const profileResponse = await fetch(\"https://graph.microsoft.com/v1.0/me\", {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Microsoft user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const profileData = await profileResponse.json() as {\n id: string;\n displayName?: string | null;\n mail?: string | null;\n userPrincipalName?: string | null;\n };\n\n const email = profileData.mail || profileData.userPrincipalName;\n if (!email) {\n logger.error(\"Microsoft user has no email\");\n return null;\n }\n\n // `xms_edov` is asserted about the id_token's own email claim,\n // so it only carries over to the Graph address when the two\n // agree.\n const claimedEmail = (idTokenClaims?.email ?? idTokenClaims?.preferred_username) as string | undefined;\n const emailVerified = providerVerifiedEmail(idTokenClaims?.xms_edov)\n && typeof claimedEmail === \"string\"\n && claimedEmail.toLowerCase() === email.toLowerCase();\n\n // Attempt to fetch profile photo URL (Graph returns binary, not a URL).\n // We skip this and let the frontend use the Microsoft Graph photo endpoint.\n return {\n // Keyed on the Graph object id, unchanged: it is what every\n // already-linked identity row holds.\n providerId: profileData.id,\n email,\n displayName: profileData.displayName || null,\n photoUrl: null,\n emailVerified\n };\n } catch (error) {\n logger.error(\"Microsoft OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { z } from \"zod\";\nimport jwt from \"jsonwebtoken\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\nimport { tryVerifyOidcIdToken } from \"./oidc-id-token\";\n\nconst APPLE_ISSUER = \"https://appleid.apple.com\";\nconst APPLE_JWKS_URI = \"https://appleid.apple.com/auth/keys\";\n\n/** Extra field Apple's client sends that no other provider has. */\nexport interface AppleCodeFlowPayload extends OAuthCodeFlowPayload {\n /**\n * Apple sends the user's *name* only on the first authorization, so the\n * frontend has to forward it. It is display data and nothing else — the\n * identity email comes from the id_token, never from the request body.\n */\n user?: { name?: { firstName?: string; lastName?: string } };\n}\n\n/**\n * Creates an Apple Sign In OAuth Provider integration.\n *\n * Apple requires a client secret that is a signed JWT, regenerated on each\n * token exchange (valid up to 6 months). This provider handles that automatically.\n *\n * Required Apple Developer configuration:\n * - Services ID (clientId)\n * - Key ID from the private key registered with Apple\n * - Team ID from Apple Developer account\n * - Private key (.p8 file contents) downloaded from Apple Developer portal\n */\nexport function createAppleProvider(config: {\n clientId: string;\n teamId: string;\n keyId: string;\n /** The raw PEM contents of the .p8 private key file */\n privateKey: string;\n}): OAuthProvider<AppleCodeFlowPayload> {\n /**\n * Generate a client_secret JWT signed with the Apple private key.\n * Apple requires this instead of a static client_secret.\n */\n async function generateClientSecret(): Promise<string> {\n return jwt.sign({}, config.privateKey, {\n algorithm: \"ES256\",\n keyid: config.keyId,\n issuer: config.teamId,\n expiresIn: \"180d\",\n audience: \"https://appleid.apple.com\",\n subject: config.clientId\n });\n }\n\n return {\n id: \"apple\",\n schema: oauthCodeFlowSchema().extend({\n /**\n * Apple sends user info only on first authorization; the frontend\n * must forward it. Only the *name* is accepted — an `email` here\n * used to be promoted to the account's identity whenever the\n * id_token had no `email` claim, and an attacker chooses whether\n * that claim is absent simply by omitting the `email` scope from\n * their own authorization request.\n */\n user: z.object({\n name: z.object({\n firstName: z.string().optional(),\n lastName: z.string().optional()\n }).optional()\n }).optional()\n }),\n verify: async (payload: AppleCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n const clientSecret = await generateClientSecret();\n\n // Exchange code for tokens\n const tokenResponse = await fetch(\"https://appleid.apple.com/auth/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: clientSecret,\n code: payload.code,\n grant_type: \"authorization_code\",\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Apple access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { id_token?: string };\n\n // Verify the id_token against Apple's JWKS rather than\n // base64-decoding it. The signature is the least of it: `aud`\n // is what confirms the token was minted for *this* Services ID\n // and not another one under the same Apple team, and `exp`\n // stops a captured token being replayed.\n const decoded = tokenData.id_token\n ? await tryVerifyOidcIdToken(\"apple\", {\n idToken: tokenData.id_token,\n jwksUri: APPLE_JWKS_URI,\n issuer: APPLE_ISSUER,\n audience: config.clientId\n })\n : null;\n\n if (!decoded) {\n logger.error(\"Apple token exchange returned no verifiable id_token\");\n return null;\n }\n\n // The id_token is the only acceptable source of the address.\n const email = decoded.email;\n if (!email) {\n logger.error(\"Apple id_token carries no email claim\");\n return null;\n }\n\n let displayName: string | null = null;\n if (payload.user?.name) {\n const parts = [payload.user.name.firstName, payload.user.name.lastName].filter(Boolean);\n displayName = parts.length > 0 ? parts.join(\" \") : null;\n }\n\n return {\n providerId: decoded.sub,\n email,\n displayName,\n photoUrl: null, // Apple does not provide a profile photo\n emailVerified: providerVerifiedEmail(decoded.email_verified)\n };\n } catch (error) {\n logger.error(\"Apple OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a Facebook / Meta OAuth Provider integration.\n *\n * Uses the authorization code flow to exchange a code for an access token,\n * then fetches user profile from the Facebook Graph API.\n */\nexport function createFacebookProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"facebook\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n // Exchange code for access token.\n //\n // POSTed as a form body, not a query string: the URL is the\n // part of a request that outbound proxies, APM spans and\n // `fetch` error objects log by default, and a long-lived app\n // secret sitting in a log aggregator is a compromise nobody\n // notices. Graph accepts both.\n const tokenResponse = await fetch(\"https://graph.facebook.com/v19.0/oauth/access_token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: payload.redirectUri,\n code: payload.code,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Facebook access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string };\n const accessToken = tokenData.access_token;\n\n // Fetch user profile with email and profile picture\n const profileUrl = new URL(\"https://graph.facebook.com/v19.0/me\");\n profileUrl.searchParams.set(\"fields\", \"id,name,email,picture.type(large)\");\n\n const profileResponse = await fetch(profileUrl.toString(), {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Facebook user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const profileData = await profileResponse.json() as {\n id: string;\n name?: string;\n email?: string;\n picture?: { data?: { url?: string } };\n };\n\n if (!profileData.email) {\n logger.error(\"Facebook user has no email (email permission may not have been granted)\");\n return null;\n }\n\n return {\n providerId: profileData.id,\n email: profileData.email,\n displayName: profileData.name || null,\n photoUrl: profileData.picture?.data?.url || null,\n // Graph exposes no email-verification field on `/me`, so\n // nothing in the response supports a `true` here.\n // `emailVerified` is the sole gate on attaching this\n // identity to a pre-existing account; users who already\n // have one link through `POST /auth/link/facebook`.\n emailVerified: false\n };\n } catch (error) {\n logger.error(\"Facebook OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a Twitter/X OAuth 2.0 Provider integration.\n *\n * Uses OAuth 2.0 with PKCE (authorization code flow). The frontend must include\n * the PKCE `code_verifier` when sending the authorization code.\n *\n * Twitter API v2 requires the \"tweet.read\" and \"users.read\" scopes at minimum,\n * plus \"offline.access\" if refresh tokens are needed on Twitter's side.\n */\nexport function createTwitterProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"twitter\",\n // The one provider where PKCE is not optional: Twitter's token\n // endpoint rejects an exchange without a verifier.\n schema: oauthCodeFlowSchema({ pkce: \"required\" }),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n // Twitter OAuth 2.0 uses Basic auth for the token endpoint\n const basicAuth = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString(\"base64\");\n\n // Exchange code for access token\n const tokenResponse = await fetch(\"https://api.twitter.com/2/oauth2/token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"Authorization\": `Basic ${basicAuth}`\n },\n body: new URLSearchParams({\n code: payload.code,\n grant_type: \"authorization_code\",\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Twitter access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string };\n const accessToken = tokenData.access_token;\n\n // Fetch user profile from Twitter API v2\n const profileResponse = await fetch(\n \"https://api.twitter.com/2/users/me?user.fields=id,name,username,profile_image_url\",\n {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n }\n );\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Twitter user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const profileResult = await profileResponse.json() as {\n data: {\n id: string;\n name: string;\n username: string;\n profile_image_url?: string;\n };\n };\n\n const profileData = profileResult.data;\n\n // Twitter does NOT expose email via API v2 by default.\n // It requires elevated access. If we can't get an email, we\n // generate a placeholder email — the user can update it later.\n // For apps with elevated access, fetch from v1.1 endpoint.\n let email: string | null = null;\n let emailVerified = false;\n try {\n const emailResponse = await fetch(\n \"https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true\",\n {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n }\n );\n if (emailResponse.ok) {\n const emailData = await emailResponse.json() as { email?: string };\n email = emailData.email || null;\n if (email) {\n emailVerified = true;\n }\n }\n } catch {\n // Elevated access not available — fall through\n }\n\n if (!email) {\n // Construct a deterministic placeholder email from the Twitter user ID.\n // This allows the account to be created and linked; the user should\n // update their email through the profile settings.\n email = `${profileData.id}@twitter.placeholder.rebase`;\n // Placeholder emails are NOT verified — prevents auto-linking to existing accounts\n emailVerified = false;\n }\n\n return {\n providerId: profileData.id,\n email,\n displayName: profileData.name || profileData.username || null,\n photoUrl: profileData.profile_image_url?.replace(\"_normal\", \"_400x400\") || null,\n emailVerified\n };\n } catch (error) {\n logger.error(\"Twitter OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a Discord OAuth2 Provider integration.\n *\n * Uses the authorization code flow (with PKCE when the client supplies a\n * verifier). Requires the \"identify\" and \"email\" scopes to retrieve the\n * user's email and profile information.\n */\nexport function createDiscordProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"discord\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n // Exchange code for access token\n const tokenResponse = await fetch(\"https://discord.com/api/v10/oauth2/token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n grant_type: \"authorization_code\",\n code: payload.code,\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Discord access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string };\n const accessToken = tokenData.access_token;\n\n // Fetch user profile\n const profileResponse = await fetch(\"https://discord.com/api/v10/users/@me\", {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Discord user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const profileData = await profileResponse.json() as {\n id: string;\n username: string;\n global_name?: string | null;\n avatar?: string | null;\n email?: string | null;\n verified?: boolean;\n };\n\n if (!profileData.email) {\n logger.error(\"Discord user has no email (email scope may not have been granted)\");\n return null;\n }\n\n // Build avatar URL\n let photoUrl: string | null = null;\n if (profileData.avatar) {\n const ext = profileData.avatar.startsWith(\"a_\") ? \"gif\" : \"png\";\n photoUrl = `https://cdn.discordapp.com/avatars/${profileData.id}/${profileData.avatar}.${ext}?size=256`;\n }\n\n return {\n providerId: profileData.id,\n email: profileData.email,\n displayName: profileData.global_name || profileData.username || null,\n photoUrl,\n emailVerified: providerVerifiedEmail(profileData.verified)\n };\n } catch (error) {\n logger.error(\"Discord OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a GitLab OAuth Provider integration.\n * Works with both GitLab.com and self-hosted instances.\n *\n * `baseUrl` is configuration only and must stay that way: a caller-supplied\n * instance URL would make this provider an SSRF primitive and an\n * arbitrary-identity oracle in one step.\n */\nexport function createGitLabProvider(config: {\n clientId: string;\n clientSecret: string;\n baseUrl?: string;\n}): OAuthProvider<OAuthCodeFlowPayload> {\n const gitlabUrl = (config.baseUrl || \"https://gitlab.com\").replace(/\\/$/, \"\");\n\n return {\n id: \"gitlab\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n const tokenResponse = await fetch(`${gitlabUrl}/oauth/token`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n code: payload.code,\n grant_type: \"authorization_code\",\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get GitLab access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string };\n\n const profileResponse = await fetch(`${gitlabUrl}/api/v4/user`, {\n headers: { \"Authorization\": `Bearer ${tokenData.access_token}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get GitLab user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const p = await profileResponse.json() as {\n id: number; username: string; name?: string;\n email?: string; avatar_url?: string | null;\n confirmed_at?: string | null;\n };\n\n if (!p.email) { logger.error(\"GitLab user has no email\"); return null; }\n\n return {\n providerId: String(p.id),\n email: p.email,\n displayName: p.name || p.username || null,\n photoUrl: p.avatar_url || null,\n // `/api/v4/user` timestamps the address confirmation for\n // the authenticated user. That timestamp is the only\n // verification signal GitLab gives us, so it is the only\n // thing allowed to produce a `true` — a self-hosted\n // instance with confirmation disabled reports nothing here\n // and correctly comes back unverified.\n emailVerified: Boolean(p.confirmed_at)\n };\n } catch (error) {\n logger.error(\"GitLab OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a Bitbucket OAuth Provider integration (OAuth 2.0 consumer).\n */\nexport function createBitbucketProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"bitbucket\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n const basicAuth = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString(\"base64\");\n\n const tokenResponse = await fetch(\"https://bitbucket.org/site/oauth2/access_token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"Authorization\": `Basic ${basicAuth}`\n },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n code: payload.code,\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Bitbucket access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string };\n const accessToken = tokenData.access_token;\n\n const profileResponse = await fetch(\"https://api.bitbucket.org/2.0/user\", {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Bitbucket user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const p = await profileResponse.json() as {\n uuid: string; display_name?: string; username?: string;\n links?: { avatar?: { href?: string } };\n };\n\n // Bitbucket doesn't return email in user profile — fetch from /emails endpoint\n const emailsResponse = await fetch(\"https://api.bitbucket.org/2.0/user/emails\", {\n headers: { \"Authorization\": `Bearer ${accessToken}` }\n });\n\n let selected: { email: string; is_confirmed: boolean } | undefined;\n if (emailsResponse.ok) {\n const emailData = await emailsResponse.json() as {\n values: Array<{ email: string; is_primary: boolean; is_confirmed: boolean }>;\n };\n selected = emailData.values.find(e => e.is_primary && e.is_confirmed)\n || emailData.values.find(e => e.is_confirmed);\n }\n\n if (!selected?.email) { logger.error(\"Bitbucket user has no verified email\"); return null; }\n\n return {\n providerId: p.uuid,\n email: selected.email,\n displayName: p.display_name || p.username || null,\n photoUrl: p.links?.avatar?.href || null,\n // Read off the address we actually chose rather than\n // restating the filter above as a literal `true` — the two\n // cannot drift apart this way.\n emailVerified: providerVerifiedEmail(selected.is_confirmed)\n };\n } catch (error) {\n logger.error(\"Bitbucket OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a Slack OAuth Provider integration (OAuth 2.0 / \"Sign in with Slack\").\n * Uses the OpenID Connect flow with the \"openid,email,profile\" scopes.\n */\nexport function createSlackProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"slack\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n const tokenResponse = await fetch(\"https://slack.com/api/openid.connect.token\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n code: payload.code,\n redirect_uri: payload.redirectUri,\n grant_type: \"authorization_code\",\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Slack access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { ok: boolean; access_token?: string; error?: string };\n if (!tokenData.ok || !tokenData.access_token) {\n logger.error(\"Slack token exchange failed\", { detail: tokenData.error });\n return null;\n }\n\n const profileResponse = await fetch(\"https://slack.com/api/openid.connect.userInfo\", {\n headers: { \"Authorization\": `Bearer ${tokenData.access_token}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Slack user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const p = await profileResponse.json() as {\n ok: boolean; sub: string; name?: string;\n email?: string; picture?: string; email_verified?: boolean;\n };\n\n if (!p.ok || !p.email) {\n logger.error(\"Slack user has no email\");\n return null;\n }\n\n return {\n providerId: p.sub,\n email: p.email,\n displayName: p.name || null,\n photoUrl: p.picture || null,\n emailVerified: providerVerifiedEmail(p.email_verified)\n };\n } catch (error) {\n logger.error(\"Slack OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","import type { OAuthProvider, OAuthProviderProfile } from \"./interfaces\";\nimport { logger } from \"../utils/logger\";\nimport { oauthCodeFlowSchema, pkceTokenParams, type OAuthCodeFlowPayload } from \"./oauth-code-flow\";\n\n/**\n * Creates a Spotify OAuth Provider integration.\n * Uses the authorization code flow with the \"user-read-email\" scope.\n */\nexport function createSpotifyProvider(config: { clientId: string; clientSecret: string }): OAuthProvider<OAuthCodeFlowPayload> {\n return {\n id: \"spotify\",\n schema: oauthCodeFlowSchema(),\n verify: async (payload: OAuthCodeFlowPayload): Promise<OAuthProviderProfile | null> => {\n try {\n const basicAuth = Buffer.from(`${config.clientId}:${config.clientSecret}`).toString(\"base64\");\n\n const tokenResponse = await fetch(\"https://accounts.spotify.com/api/token\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n \"Authorization\": `Basic ${basicAuth}`\n },\n body: new URLSearchParams({\n grant_type: \"authorization_code\",\n code: payload.code,\n redirect_uri: payload.redirectUri,\n ...pkceTokenParams(payload.codeVerifier)\n })\n });\n\n if (!tokenResponse.ok) {\n logger.error(\"Failed to get Spotify access token\", { detail: await tokenResponse.text() });\n return null;\n }\n\n const tokenData = await tokenResponse.json() as { access_token: string };\n\n const profileResponse = await fetch(\"https://api.spotify.com/v1/me\", {\n headers: { \"Authorization\": `Bearer ${tokenData.access_token}` }\n });\n\n if (!profileResponse.ok) {\n logger.error(\"Failed to get Spotify user info\", { detail: await profileResponse.text() });\n return null;\n }\n\n const p = await profileResponse.json() as {\n id: string; display_name?: string | null;\n email?: string; images?: Array<{ url: string }>;\n };\n\n if (!p.email) { logger.error(\"Spotify user has no email\"); return null; }\n\n return {\n providerId: p.id,\n email: p.email,\n displayName: p.display_name || null,\n photoUrl: p.images?.[0]?.url || null,\n // `/v1/me` carries no verification field, so there is\n // nothing here to read — and `emailVerified` is the sole\n // gate on attaching this identity to a pre-existing\n // account. Reporting \"not verified\" is the honest answer;\n // users with an existing account link through\n // `POST /auth/link/spotify`, which proves ownership with a\n // live session instead.\n emailVerified: false\n };\n } catch (error) {\n logger.error(\"Spotify OAuth error\", { error: error });\n return null;\n }\n }\n };\n}\n","/**\n * Database operations for Service API Keys.\n *\n * Uses the DataDriver's `admin.executeSql` capability (same pattern as\n * the cron-store and ensure-tables modules). All data lives in the\n * `rebase.api_keys` table.\n *\n * @module\n */\n\nimport { randomBytes, createHash } from \"crypto\";\nimport type { DataDriver } from \"@rebasepro/types\";\nimport { isSQLAdmin } from \"@rebasepro/types\";\nimport { revokeInternalTableSql } from \"@rebasepro/common\";\nimport { logger } from \"../../utils/logger\";\nimport { createDdlBootstrapper } from \"../../boot/ddl-bootstrap\";\nimport type {\n ApiKey,\n ApiKeyMasked,\n ApiKeyPermission,\n ApiKeyWithSecret,\n CreateApiKeyRequest,\n UpdateApiKeyRequest\n} from \"./api-key-types\";\n\nconst TABLE = \"rebase.api_keys\";\n\n/** Characters used to generate the random portion of an API key. */\nconst HEX_CHARS = \"abcdef0123456789\";\n\n/**\n * Generate a plaintext API key with the `rk_live_` prefix.\n *\n * Format: `rk_live_` + 32 random hex characters.\n */\nfunction generateApiKey(): string {\n const random = randomBytes(16).toString(\"hex\"); // 32 hex chars\n return `rk_live_${random}`;\n}\n\n/**\n * SHA-256 hash a plaintext API key for database storage.\n */\nfunction hashKey(plaintext: string): string {\n return createHash(\"sha256\").update(plaintext).digest(\"hex\");\n}\n\n/**\n * Extract the display prefix from a plaintext key (first 12 chars).\n */\nfunction keyPrefix(plaintext: string): string {\n return plaintext.substring(0, 12);\n}\n\n/**\n * Strip the `key_hash` field and return a safe-to-expose masked key.\n */\nfunction toMasked(row: ApiKey): ApiKeyMasked {\n return {\n id: row.id,\n name: row.name,\n key_prefix: row.key_prefix,\n permissions: row.permissions,\n admin: row.admin,\n rate_limit: row.rate_limit,\n created_by: row.created_by,\n created_at: row.created_at,\n updated_at: row.updated_at,\n last_used_at: row.last_used_at,\n expires_at: row.expires_at,\n revoked_at: row.revoked_at\n };\n}\n\n/**\n * Parse a raw DB row into the typed `ApiKey` shape.\n */\nfunction rowToApiKey(row: Record<string, unknown>): ApiKey {\n let permissions = (row.permissions ?? []) as ApiKeyPermission[];\n if (typeof row.permissions === \"string\") {\n try {\n permissions = JSON.parse(row.permissions) as ApiKeyPermission[];\n } catch {\n permissions = [];\n }\n }\n\n return {\n id: row.id as string,\n name: row.name as string,\n key_prefix: row.key_prefix as string,\n key_hash: row.key_hash as string,\n permissions,\n admin: Boolean(row.admin),\n rate_limit: row.rate_limit !== null && row.rate_limit !== undefined\n ? Number(row.rate_limit)\n : null,\n created_by: row.created_by as string,\n created_at: new Date(row.created_at as string).toISOString(),\n updated_at: new Date(row.updated_at as string).toISOString(),\n last_used_at: row.last_used_at ? new Date(row.last_used_at as string).toISOString() : null,\n expires_at: row.expires_at ? new Date(row.expires_at as string).toISOString() : null,\n revoked_at: row.revoked_at ? new Date(row.revoked_at as string).toISOString() : null\n };\n}\n\n// ─── Public API ──────────────────────────────────────────────────────\n\nexport interface ApiKeyStore {\n /** Ensure the `rebase.api_keys` table exists. Called once on startup. */\n ensureTable(): Promise<void>;\n\n /** Create a new API key. Returns the full plaintext key exactly once. */\n createApiKey(request: CreateApiKeyRequest, createdBy: string): Promise<ApiKeyWithSecret>;\n\n /** Look up an API key by its SHA-256 hash. Returns `null` if not found. */\n findByKeyHash(hash: string): Promise<ApiKey | null>;\n\n /** List all API keys (masked, never includes hash). */\n listApiKeys(): Promise<ApiKeyMasked[]>;\n\n /** Get a single API key by ID (masked). */\n getApiKeyById(id: string): Promise<ApiKeyMasked | null>;\n\n /** Update name, permissions, rate_limit, or expires_at. */\n updateApiKey(id: string, updates: UpdateApiKeyRequest): Promise<ApiKeyMasked | null>;\n\n /** Soft-delete: set `revoked_at` to now. */\n revokeApiKey(id: string): Promise<boolean>;\n\n /** Touch `last_used_at` to the current timestamp. */\n updateLastUsed(id: string): Promise<void>;\n}\n\n/**\n * Create an `ApiKeyStore` backed by the driver's SQL admin capability.\n *\n * Returns `undefined` if the driver does not support `executeSql`.\n */\nexport function createApiKeyStore(driver: DataDriver): ApiKeyStore | undefined {\n const admin = driver.admin;\n if (!isSQLAdmin(admin)) {\n logger.warn(\"⚠️ [api-key-store] DataDriver does not support SQL admin — API keys will not be available.\");\n return undefined;\n }\n\n const exec = (sqlText: string, options?: { params?: unknown[] }) =>\n admin.executeSql(sqlText, options?.params ? { params: options.params } : undefined);\n\n const ddl = createDdlBootstrapper(exec, \"api-key-store\");\n\n return {\n // ── Schema bootstrap ────────────────────────────────────────\n async ensureTable(): Promise<void> {\n // Every statement here is idempotent, so losing the race to a peer\n // that booted at the same moment is survivable — but only if the\n // loser retries instead of abandoning everything below it. One\n // contained step each, so that a hard failure on any one of them\n // does not take the others with it. See `boot/ddl-bootstrap.ts`.\n await ddl.ensureObject(\"Creating schema rebase\", \"CREATE SCHEMA IF NOT EXISTS rebase\");\n\n await ddl.ensureObject(`Creating ${TABLE}`, `\n CREATE TABLE IF NOT EXISTS ${TABLE} (\n id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,\n name TEXT NOT NULL,\n key_prefix TEXT NOT NULL,\n key_hash TEXT NOT NULL UNIQUE,\n permissions JSONB NOT NULL DEFAULT '[]'::jsonb,\n admin BOOLEAN NOT NULL DEFAULT FALSE,\n rate_limit INTEGER,\n created_by TEXT NOT NULL,\n created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),\n last_used_at TIMESTAMPTZ,\n expires_at TIMESTAMPTZ,\n revoked_at TIMESTAMPTZ\n )\n `);\n\n await ddl.ensureObject(\"Creating idx_api_keys_hash\", `\n CREATE INDEX IF NOT EXISTS idx_api_keys_hash\n ON ${TABLE}(key_hash)\n `);\n\n await ddl.ensureObject(\"Creating idx_api_keys_prefix\", `\n CREATE INDEX IF NOT EXISTS idx_api_keys_prefix\n ON ${TABLE}(key_prefix)\n `);\n\n // Migration: add admin column to existing tables. Idempotent in the\n // same way and raced in the same way — two instances running it\n // together can deadlock on the table's catalog lock.\n await ddl.ensureObject(`Adding ${TABLE}.admin`, `\n ALTER TABLE ${TABLE}\n ADD COLUMN IF NOT EXISTS admin BOOLEAN NOT NULL DEFAULT FALSE\n `);\n\n // Keyed on what exists, not on who created it. The revoke below used\n // to sit at the end of one long try block, so an instance that lost\n // any race above skipped it and reported only that API keys were\n // unavailable — while the table it had just helped create stayed\n // reachable by the end-user role.\n if (!await ddl.isReadable(TABLE)) {\n logger.error(\n `❌ [api-key-store] ${TABLE} is unavailable — every API-key authenticated ` +\n \"request will be rejected on this instance, and the table could not be \" +\n \"taken back off the end-user role.\"\n );\n return;\n }\n\n // This table holds key hashes and an `admin` flag, and it has no\n // RLS — it is not a collection. The Postgres driver grants the\n // authenticated role DML on everything in `rebase`, including\n // tables (like this one) created after that grant ran, so the\n // privilege has to come back off. Without it a user-context\n // query that reached this table could mint itself an admin key.\n // A security control, so it is re-applied by every instance on\n // every boot, whatever else went wrong above.\n await ddl.step(\"Revoking end-user access to api_keys\", () =>\n exec(revokeInternalTableSql(\"rebase\", \"api_keys\")));\n\n logger.debug(\"✅ API keys table ready\");\n },\n\n // ── Create ──────────────────────────────────────────────────\n async createApiKey(request: CreateApiKeyRequest, createdBy: string): Promise<ApiKeyWithSecret> {\n const plaintext = generateApiKey();\n const hash = hashKey(plaintext);\n const prefix = keyPrefix(plaintext);\n const permissionsJson = JSON.stringify(request.permissions);\n\n const rows = await exec(\n `INSERT INTO ${TABLE} (name, key_prefix, key_hash, permissions, admin, rate_limit, created_by, expires_at)\n VALUES ($1, $2, $3, $4::jsonb, $5, $6, $7, $8)\n RETURNING *`,\n { params: [\n request.name,\n prefix,\n hash,\n permissionsJson,\n request.admin ?? false,\n request.rate_limit ?? null,\n createdBy,\n request.expires_at ?? null\n ] }\n );\n\n const apiKey = rowToApiKey(rows[0]);\n return {\n ...toMasked(apiKey),\n key: plaintext\n };\n },\n\n // ── Lookup by hash ──────────────────────────────────────────\n async findByKeyHash(hash: string): Promise<ApiKey | null> {\n const rows = await exec(\n `SELECT * FROM ${TABLE}\n WHERE key_hash = $1\n LIMIT 1`,\n { params: [hash] }\n );\n if (rows.length === 0) return null;\n return rowToApiKey(rows[0]);\n },\n\n // ── List all (masked) ───────────────────────────────────────\n async listApiKeys(): Promise<ApiKeyMasked[]> {\n const rows = await exec(`\n SELECT * FROM ${TABLE}\n ORDER BY created_at DESC\n `);\n return rows.map(r => toMasked(rowToApiKey(r)));\n },\n\n // ── Get by ID (masked) ──────────────────────────────────────\n async getApiKeyById(id: string): Promise<ApiKeyMasked | null> {\n const rows = await exec(\n `SELECT * FROM ${TABLE}\n WHERE id = $1\n LIMIT 1`,\n { params: [id] }\n );\n if (rows.length === 0) return null;\n return toMasked(rowToApiKey(rows[0]));\n },\n\n // ── Update ──────────────────────────────────────────────────\n async updateApiKey(id: string, updates: UpdateApiKeyRequest): Promise<ApiKeyMasked | null> {\n const setClauses: string[] = [];\n const params: unknown[] = [];\n let paramIdx = 1;\n\n if (updates.name !== undefined) {\n setClauses.push(`name = $${paramIdx++}`);\n params.push(updates.name);\n }\n if (updates.permissions !== undefined) {\n setClauses.push(`permissions = $${paramIdx++}::jsonb`);\n params.push(JSON.stringify(updates.permissions));\n }\n if (updates.admin !== undefined) {\n setClauses.push(`admin = $${paramIdx++}`);\n params.push(updates.admin);\n }\n if (updates.rate_limit !== undefined) {\n if (updates.rate_limit !== null) {\n setClauses.push(`rate_limit = $${paramIdx++}`);\n params.push(updates.rate_limit);\n } else {\n setClauses.push(\"rate_limit = NULL\");\n }\n }\n if (updates.expires_at !== undefined) {\n if (updates.expires_at !== null) {\n setClauses.push(`expires_at = $${paramIdx++}`);\n params.push(updates.expires_at);\n } else {\n setClauses.push(\"expires_at = NULL\");\n }\n }\n\n if (setClauses.length === 0) {\n return this.getApiKeyById(id);\n }\n\n setClauses.push(\"updated_at = NOW()\");\n\n // The WHERE id = $N uses the next available param index\n params.push(id);\n\n const rows = await exec(\n `UPDATE ${TABLE}\n SET ${setClauses.join(\", \")}\n WHERE id = $${paramIdx}\n RETURNING *`,\n { params }\n );\n\n if (rows.length === 0) return null;\n return toMasked(rowToApiKey(rows[0]));\n },\n\n // ── Revoke (soft-delete) ────────────────────────────────────\n async revokeApiKey(id: string): Promise<boolean> {\n const rows = await exec(\n `UPDATE ${TABLE}\n SET revoked_at = NOW(), updated_at = NOW()\n WHERE id = $1 AND revoked_at IS NULL\n RETURNING id`,\n { params: [id] }\n );\n return rows.length > 0;\n },\n\n // ── Touch last_used_at ──────────────────────────────────────\n async updateLastUsed(id: string): Promise<void> {\n try {\n await exec(\n `UPDATE ${TABLE}\n SET last_used_at = NOW()\n WHERE id = $1`,\n { params: [id] }\n );\n } catch (err) {\n // Non-blocking — don't fail requests because of a usage timestamp update\n logger.error(\"[api-key-store] Failed to update last_used_at\", { error: err });\n }\n }\n };\n}\n","/**\n * Admin routes for managing Service API Keys.\n *\n * Mounted under `/api/admin/api-keys` with `requireAuth` + `requireAdmin`.\n * All routes return masked keys (never the hash). The full plaintext key\n * is returned exactly once in the POST response.\n *\n * @module\n */\n\nimport { Hono, type MiddlewareHandler } from \"hono\";\nimport { ApiError, errorHandler } from \"../../api/errors\";\nimport { createRequireAuth, requireAdmin } from \"../middleware\";\nimport type { HonoEnv } from \"../../api/types\";\nimport type { ApiKeyStore } from \"./api-key-store\";\nimport type { CreateApiKeyRequest, UpdateApiKeyRequest, ApiKeyPermission } from \"./api-key-types\";\n\nexport interface ApiKeyRouteOptions {\n store: ApiKeyStore;\n serviceKey?: string;\n}\n\n/**\n * Validate that a permissions array is well-formed.\n */\nfunction validatePermissions(permissions: unknown): permissions is ApiKeyPermission[] {\n if (!Array.isArray(permissions)) return false;\n for (const perm of permissions) {\n if (typeof perm !== \"object\" || perm === null) return false;\n if (typeof perm.collection !== \"string\" || perm.collection.length === 0) return false;\n if (!Array.isArray(perm.operations) || perm.operations.length === 0) return false;\n const validOps = new Set([\"read\", \"write\", \"delete\"]);\n for (const op of perm.operations) {\n if (!validOps.has(op)) return false;\n }\n }\n return true;\n}\n\n/**\n * Refuse API-key-authenticated requests to the key-management routes.\n *\n * `createApiKeyPreAuth` runs in front of every `/admin/*` router so that keys\n * created with `admin: true` genuinely reach the admin surfaces — their\n * documented behaviour, and the right behaviour everywhere except here.\n * Applied to *this* router it means an admin key can mint a second admin key,\n * widen its own grants through `PUT /:id`, or revoke the keys other\n * integrations run on. Revoking the original key undoes none of that, because\n * the keys it minted are ordinary rows with no link back to it.\n *\n * So key management is reserved for callers that are not themselves an API\n * key: a human admin's session, or the service key.\n *\n * Reads are refused alongside writes. The list response enumerates every key's\n * name, prefix, permission set and admin flag — reconnaissance for exactly the\n * escalation above — and \"an API key never touches API keys\" is a rule with no\n * edges left to get wrong.\n */\nconst rejectApiKeyAuth: MiddlewareHandler<HonoEnv> = async (c, next) => {\n if (c.get(\"apiKey\")) {\n throw ApiError.forbidden(\n \"API keys cannot manage API keys. Authenticate as an admin user, or use the service key.\",\n \"API_KEY_SELF_MANAGEMENT_FORBIDDEN\"\n );\n }\n return next();\n};\n\n/**\n * Create admin routes for API key management.\n */\nexport function createApiKeyRoutes(options: ApiKeyRouteOptions): Hono<HonoEnv> {\n const { store, serviceKey } = options;\n const router = new Hono<HonoEnv>();\n\n router.onError(errorHandler);\n\n // Apply auth middleware (service-key-aware)\n router.use(\"/*\", createRequireAuth({ serviceKey }));\n // Before requireAdmin, so a non-admin key gets the reason it was refused\n // rather than a generic \"needs admin\" that implies a wider key would work.\n router.use(\"/*\", rejectApiKeyAuth);\n router.use(\"/*\", requireAdmin);\n\n // GET / — List all API keys (masked)\n router.get(\"/\", async (c) => {\n const keys = await store.listApiKeys();\n return c.json({ keys });\n });\n\n // POST / — Create a new API key\n router.post(\"/\", async (c) => {\n const body = await c.req.json() as Record<string, unknown>;\n const { name, permissions, admin, rate_limit, expires_at } = body;\n\n if (!name || typeof name !== \"string\" || name.trim().length === 0) {\n throw ApiError.badRequest(\"Name is required\", \"INVALID_INPUT\");\n }\n\n if (!validatePermissions(permissions)) {\n throw ApiError.badRequest(\n \"Permissions must be an array of { collection: string, operations: ('read' | 'write' | 'delete')[] }\",\n \"INVALID_INPUT\"\n );\n }\n\n if (admin !== undefined && typeof admin !== \"boolean\") {\n throw ApiError.badRequest(\"admin must be a boolean\", \"INVALID_INPUT\");\n }\n\n if (rate_limit !== undefined && rate_limit !== null) {\n if (typeof rate_limit !== \"number\" || rate_limit < 1 || !Number.isInteger(rate_limit)) {\n throw ApiError.badRequest(\"rate_limit must be a positive integer or null\", \"INVALID_INPUT\");\n }\n }\n\n if (expires_at !== undefined && expires_at !== null) {\n const parsed = new Date(expires_at as string);\n if (isNaN(parsed.getTime())) {\n throw ApiError.badRequest(\"expires_at must be a valid ISO-8601 date\", \"INVALID_INPUT\");\n }\n if (parsed <= new Date()) {\n throw ApiError.badRequest(\"expires_at must be in the future\", \"INVALID_INPUT\");\n }\n }\n\n const user = c.get(\"user\");\n const createdBy = (user && typeof user === \"object\" && \"uid\" in user)\n ? (user.uid as string)\n : \"unknown\";\n\n const request: CreateApiKeyRequest = {\n name: name.trim(),\n permissions: permissions as ApiKeyPermission[],\n admin: (admin as boolean) ?? false,\n rate_limit: (rate_limit as number | null) ?? null,\n expires_at: (expires_at as string | null) ?? null\n };\n\n const keyWithSecret = await store.createApiKey(request, createdBy);\n\n return c.json({ key: keyWithSecret }, 201);\n });\n\n // GET /:id — Get API key details (masked)\n router.get(\"/:id\", async (c) => {\n const id = c.req.param(\"id\");\n const key = await store.getApiKeyById(id);\n\n if (!key) {\n throw ApiError.notFound(\"API key not found\");\n }\n\n return c.json({ key });\n });\n\n // PUT /:id — Update API key\n router.put(\"/:id\", async (c) => {\n const id = c.req.param(\"id\");\n const body = await c.req.json() as Record<string, unknown>;\n const { name, permissions, admin, rate_limit, expires_at } = body;\n\n // Validate fields if provided\n if (name !== undefined) {\n if (typeof name !== \"string\" || name.trim().length === 0) {\n throw ApiError.badRequest(\"Name must be a non-empty string\", \"INVALID_INPUT\");\n }\n }\n\n if (permissions !== undefined) {\n if (!validatePermissions(permissions)) {\n throw ApiError.badRequest(\n \"Permissions must be an array of { collection: string, operations: ('read' | 'write' | 'delete')[] }\",\n \"INVALID_INPUT\"\n );\n }\n }\n\n if (admin !== undefined && typeof admin !== \"boolean\") {\n throw ApiError.badRequest(\"admin must be a boolean\", \"INVALID_INPUT\");\n }\n\n if (rate_limit !== undefined && rate_limit !== null) {\n if (typeof rate_limit !== \"number\" || rate_limit < 1 || !Number.isInteger(rate_limit)) {\n throw ApiError.badRequest(\"rate_limit must be a positive integer or null\", \"INVALID_INPUT\");\n }\n }\n\n if (expires_at !== undefined && expires_at !== null) {\n const parsed = new Date(expires_at as string);\n if (isNaN(parsed.getTime())) {\n throw ApiError.badRequest(\"expires_at must be a valid ISO-8601 date\", \"INVALID_INPUT\");\n }\n }\n\n const updates: UpdateApiKeyRequest = {};\n if (name !== undefined) updates.name = (name as string).trim();\n if (permissions !== undefined) updates.permissions = permissions as ApiKeyPermission[];\n if (admin !== undefined) updates.admin = admin as boolean;\n if (rate_limit !== undefined) updates.rate_limit = rate_limit as number | null;\n if (expires_at !== undefined) updates.expires_at = expires_at as string | null;\n\n const key = await store.updateApiKey(id, updates);\n\n if (!key) {\n throw ApiError.notFound(\"API key not found\");\n }\n\n return c.json({ key });\n });\n\n // DELETE /:id — Revoke (soft-delete)\n router.delete(\"/:id\", async (c) => {\n const id = c.req.param(\"id\");\n const revoked = await store.revokeApiKey(id);\n\n if (!revoked) {\n throw ApiError.notFound(\"API key not found or already revoked\");\n }\n\n return c.json({ success: true });\n });\n\n return router;\n}\n","/**\n * Custom Auth Adapter Factory\n *\n * Provides a minimal-config way for users with existing auth systems\n * to plug into Rebase. Only `verifyRequest` is required — everything\n * else is optional.\n *\n * @example\n * ```ts\n * import { createCustomAuthAdapter } from \"@rebasepro/server\";\n *\n * const auth = createCustomAuthAdapter({\n * verifyRequest: async (request) => {\n * const token = request.headers.get(\"Authorization\")?.replace(\"Bearer \", \"\");\n * if (!token) return null;\n * const decoded = jwt.verify(token, MY_SECRET);\n * return {\n * uid: decoded.sub,\n * email: decoded.email,\n * displayName: decoded.name,\n * roles: decoded.roles || [],\n * isAdmin: decoded.roles?.includes(\"admin\") ?? false,\n * };\n * },\n * });\n * ```\n */\n\nimport type {\n AuthAdapter,\n AuthAdapterCapabilities,\n CustomAuthAdapterOptions\n} from \"@rebasepro/types\";\n\n/**\n * Create a custom auth adapter from minimal options.\n *\n * This is the recommended entry point for users who already have their own\n * auth system and just need to tell Rebase how to extract the user from\n * incoming requests.\n *\n * @param options - Configuration options. Only `verifyRequest` is required.\n * @returns A fully-formed `AuthAdapter` ready for `initializeRebaseBackend()`.\n */\nexport function createCustomAuthAdapter(options: CustomAuthAdapterOptions): AuthAdapter {\n const defaultCapabilities: AuthAdapterCapabilities = {\n hasBuiltInAuthRoutes: false,\n emailPasswordLogin: false,\n registration: false,\n passwordReset: false,\n // Off unless the adapter's own createAdminRoutes() mounts a\n // reset-password route and opts in via `capabilities`.\n adminPasswordReset: false,\n sessionManagement: false,\n profileUpdate: false,\n emailVerification: false,\n magicLink: false,\n enabledProviders: [],\n ...options.capabilities\n };\n\n const resolvedVerifyToken = options.verifyToken\n ?? (async (token: string) => {\n // Synthesize a minimal Request so adapters that only implement\n // verifyRequest still work for WebSocket token verification.\n const syntheticRequest = new Request(\"http://localhost/_ws_auth\", {\n headers: { Authorization: `Bearer ${token}` }\n });\n return options.verifyRequest(syntheticRequest);\n });\n\n return {\n id: \"custom\",\n\n serviceKey: options.serviceKey,\n\n verifyRequest: options.verifyRequest,\n\n verifyToken: resolvedVerifyToken,\n\n userManagement: options.userManagement,\n\n transformAuthResponse: options.transformAuthResponse,\n\n getCapabilities() {\n return defaultCapabilities;\n }\n };\n}\n","// Auth module exports\nexport * from \"./interfaces\";\n\nexport { configureJwt, isJwtConfigured, generateAccessToken, verifyAccessToken, generateRefreshToken, hashRefreshToken, getRefreshTokenExpiry, getAccessTokenExpiry, generateDownloadToken, verifyDownloadToken } from \"./jwt\";\nexport type { JwtConfig, AccessTokenPayload, DownloadTokenPayload } from \"./jwt\";\n\nexport { hashPassword, verifyPassword, validatePasswordStrength } from \"./password\";\n// Constant-time compare for static secrets (service keys), so token checks\n// outside this package cannot accidentally use ===.\nexport { safeCompare } from \"./crypto-utils\";\nexport type { PasswordValidationResult } from \"./password\";\n\nexport type { AuthHooks, AuthMethod, ResolvedAuthHooks } from \"./auth-hooks\";\nexport { resolveAuthHooks } from \"./auth-hooks\";\n\nexport { generateSecurePassword, generateSecureToken, hashToken, prepareAdminUserValues, finalizeAdminUserCreation } from \"./admin-user-ops\";\nexport type { AdminUserContext, AdminUserPrepareResult } from \"./admin-user-ops\";\n\n// OAuth Providers\nexport { createGoogleProvider } from \"./google-oauth\";\nexport type { GoogleProviderConfig } from \"./google-oauth\";\nexport { createLinkedinProvider } from \"./linkedin-oauth\";\nexport { createGitHubProvider } from \"./github-oauth\";\nexport { createMicrosoftProvider } from \"./microsoft-oauth\";\nexport { createAppleProvider } from \"./apple-oauth\";\nexport { createFacebookProvider } from \"./facebook-oauth\";\nexport { createTwitterProvider } from \"./twitter-oauth\";\nexport { createDiscordProvider } from \"./discord-oauth\";\nexport { createGitLabProvider } from \"./gitlab-oauth\";\nexport { createBitbucketProvider } from \"./bitbucket-oauth\";\nexport { createSlackProvider } from \"./slack-oauth\";\nexport { createSpotifyProvider } from \"./spotify-oauth\";\nexport type { AppleCodeFlowPayload } from \"./apple-oauth\";\n\n// Shared OAuth machinery — the controls every provider, including a custom one\n// passed through `auth.providers`, is expected to go through.\nexport { oauthCodeFlowSchema, pkceTokenParams, providerVerifiedEmail } from \"./oauth-code-flow\";\nexport type { OAuthCodeFlowPayload } from \"./oauth-code-flow\";\nexport { verifyOidcIdToken, tryVerifyOidcIdToken } from \"./oidc-id-token\";\nexport type { OidcIdTokenClaims, VerifyOidcIdTokenOptions } from \"./oidc-id-token\";\nexport { decideOAuthAutoLink, isRedirectUriAllowed } from \"./oauth-signin-policy\";\nexport type { AutoLinkDecision, AutoLinkRefusal } from \"./oauth-signin-policy\";\n\nexport { requireAuth, requireAdmin, optionalAuth, extractUserFromToken, createAuthMiddleware, queryTokenAuth, fileTokenAuth } from \"./middleware\";\nexport type { AuthMiddlewareOptions, AuthResult } from \"./middleware\";\n\n\nexport { createAuthRoutes } from \"./routes\";\nexport type { AuthModuleConfig, CookieAuthConfig } from \"./routes\";\n\nexport { mountMagicLinkRoutes } from \"./magic-link-routes\";\n\nexport { createResetPasswordRoute } from \"./reset-password-admin\";\nexport type { ResetPasswordRouteConfig } from \"./reset-password-admin\";\n\n\nexport { createRateLimiter, defaultAuthLimiter, strictAuthLimiter, createDataRateLimiter, apiKeyKeyGenerator } from \"./rate-limiter\";\nexport type { DataRateLimitConfig } from \"./rate-limiter\";\nexport { MemoryRateLimitStore } from \"./rate-limit-store\";\nexport type { RateLimitStore, RateLimitDecision } from \"./rate-limit-store\";\n\n// API Keys\nexport { createApiKeyStore, createApiKeyRoutes, isApiKeyToken, validateApiKey, httpMethodToOperation, isOperationAllowed } from \"./api-keys\";\nexport type { ApiKey, ApiKeyMasked, ApiKeyPermission, ApiKeyWithSecret, CreateApiKeyRequest, UpdateApiKeyRequest, ApiKeyStore, ApiKeyOperation } from \"./api-keys\";\n\n// Auth Adapters\nexport { createBuiltinAuthAdapter } from \"./builtin-auth-adapter\";\nexport type { BuiltinAuthAdapterConfig } from \"./builtin-auth-adapter\";\nexport { createCustomAuthAdapter } from \"./custom-auth-adapter\";\nexport { createAdapterAuthMiddleware } from \"./adapter-middleware\";\nexport type { AdapterAuthMiddlewareOptions } from \"./adapter-middleware\";\n"],"x_google_ignoreList":[22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"mappings":"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"}