tempest-express-sdk 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/context.ts","../src/core/logging.ts","../src/core/enums.ts","../src/exceptions/base.ts","../src/exceptions/http.ts","../src/exceptions/i18n.ts","../src/schemas/base.ts","../src/schemas/fields.ts","../src/schemas/pagination.ts","../src/schemas/sync.ts","../src/schemas/linkHeaders.ts","../src/schemas/logs.ts","../src/settings/base.ts","../src/settings/mixins.ts","../src/db/model.ts","../src/db/userModel.ts","../src/db/audit.ts","../src/db/tenant.ts","../src/db/outbox.ts","../src/db/slowQuery.ts","../src/db/backup.ts","../src/services/base.ts","../src/controllers/base.ts","../src/utils/br.ts","../src/utils/data/brLocations.json","../src/utils/locations.ts","../src/utils/datetime.ts","../src/utils/dict.ts","../src/utils/opaqueToken.ts","../src/utils/password.ts","../src/utils/jwt.ts","../src/utils/throttle.ts","../src/utils/clientIp.ts","../src/storage/local.ts","../src/utils/download.ts","../src/utils/log.ts","../src/utils/totp.ts","../src/utils/httpClient.ts","../src/utils/metrics.ts","../src/utils/email.ts","../src/cache/manager.ts","../src/cache/cached.ts","../src/sessions/store.ts","../src/sessions/service.ts","../src/sessions/middleware.ts","../src/sessions/redisStore.ts","../src/sse/eventStream.ts","../src/sse/broker.ts","../src/sse/redisBroker.ts","../src/websockets/schemas.ts","../src/websockets/hub.ts","../src/websockets/attach.ts","../src/queue/broker.ts","../src/tasks/manager.ts","../src/flags/backends.ts","../src/flags/service.ts","../src/storage/s3.ts","../src/webpush/schemas.ts","../src/webpush/dispatcher.ts","../src/integrations/provider.ts","../src/integrations/whatsapp.ts","../src/integrations/webhook.ts","../src/integrations/telegram.ts","../src/integrations/sms.ts","../src/integrations/email.ts","../src/integrations/broadcast.ts","../src/admin/site.ts","../src/admin/router.ts","../src/auth/schemas.ts","../src/auth/service.ts","../src/auth/mfa.ts","../src/auth/activation.ts","../src/auth/passwordReset.ts","../src/auth/middleware.ts","../src/auth/router.ts","../src/auth/htmlPages.ts","../src/api/handlers.ts","../src/api/openapi.ts","../src/api/docs.ts","../src/api/health.ts","../src/api/metrics.ts","../src/api/server.ts","../src/api/middlewares/bodySize.ts","../src/api/middlewares/csrf.ts","../src/api/middlewares/graceful.ts","../src/api/middlewares/idempotency.ts","../src/api/middlewares/prometheus.ts","../src/api/middlewares/rateLimit.ts","../src/api/middlewares/tracing.ts","../src/api/oauth.ts","../src/api/webhooks.ts","../src/api/toolSpec.ts","../src/api/logs.ts","../src/testing/database.ts","../src/version.ts"],"names":["AsyncLocalStorage","extendZodWithOpenApi","z","page","Model","column","sql","BaseRepository","RecordNotFound","logger","detectDialect","copyFile","spawn","createHash","randomBytes","timingSafeEqual","cached","join","mkdir","dirname","writeFile","readFile","rm","normalize","relative","isAbsolute","stat","createReadStream","mkdirSync","createWriteStream","createHmac","promisify","execFile","cpus","loadavg","totalmem","freemem","snapshot","randomUUID","createRouter","update","PAGINATION_KEYS","ZodError","OpenAPIRegistry","OpenApiGeneratorV31","OpenApiGeneratorV3","express","getAbsoluteFSPath","safeEqual","esc","bearerToken","Router","NodeSqliteDriver","reflectTable","renderOperation","AsyncEngine"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Request-scoped context propagation via `AsyncLocalStorage`.\n *\n * Mirrors `tempest_fastapi_sdk.core.context`: a per-request id that any layer\n * (logger, exception handler, service) can read without threading it through\n * every call. The store is populated by the request-id middleware and survives\n * across `await` boundaries within the same request.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n/** The shape of the per-request store. */\nexport interface RequestContext {\n /** Stable id correlating every log line of a single request. */\n requestId: string;\n}\n\nconst storage = new AsyncLocalStorage<RequestContext>();\n\n/**\n * Run `fn` with `context` bound as the active request context.\n *\n * @param context - The context to bind for the duration of `fn`.\n * @param fn - The function to run within the bound context.\n * @returns Whatever `fn` returns.\n */\nexport function runWithRequestContext<T>(context: RequestContext, fn: () => T): T {\n return storage.run(context, fn);\n}\n\n/**\n * Read the current request id, or `null` when called outside a request.\n *\n * @returns The active request id, or `null`.\n */\nexport function getRequestId(): string | null {\n return storage.getStore()?.requestId ?? null;\n}\n\n/**\n * Overwrite the request id on the active context (no-op outside a request).\n *\n * @param requestId - The id to set.\n */\nexport function setRequestId(requestId: string): void {\n const store = storage.getStore();\n if (store) store.requestId = requestId;\n}\n","/**\n * Structured JSON logging, mirroring `tempest_fastapi_sdk.core.logging`.\n *\n * Emits one JSON object per line to stdout (or stderr for `error`), enriched\n * with the active request id. Server errors (`500`) carry the\n * {@link HTTP_500_MARKER} flag so an external log router can split them into a\n * dedicated `500.log` sink.\n */\n\nimport { getRequestId } from \"@/core/context\";\n\n/** Flag key marking a record as a captured HTTP 500 for sink routing. */\nexport const HTTP_500_MARKER = \"http_500\";\n\n/** Severity levels, ordered from least to most severe. */\nexport type LogLevel = \"debug\" | \"info\" | \"warning\" | \"error\";\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warning: 30,\n error: 40,\n};\n\n/** Free-form structured context merged into the emitted record. */\nexport type LogExtra = Record<string, unknown>;\n\n/** A sink receiving every emitted record (for file routing, shipping, …). */\nexport type LogSink = (level: LogLevel, record: Record<string, unknown>) => void;\n\nconst sinks: LogSink[] = [];\n\n/**\n * Register a sink invoked for every record every {@link JSONLogger} emits (in\n * addition to the stdout/stderr line). Used by `configureFileLogging` to route\n * records into per-level + `500.log` files.\n *\n * @param sink - The sink callback. Errors thrown by it are swallowed.\n * @returns A function that removes the sink.\n */\nexport function addLogSink(sink: LogSink): () => void {\n sinks.push(sink);\n return () => {\n const index = sinks.indexOf(sink);\n if (index !== -1) sinks.splice(index, 1);\n };\n}\n\n/** A minimal structured logger writing one JSON line per record. */\nexport class JSONLogger {\n /**\n * @param name - Logger name embedded in every record.\n * @param level - Minimum level to emit; quieter records are dropped.\n */\n constructor(\n private readonly name: string,\n private readonly level: LogLevel = \"info\",\n ) {}\n\n /** Log a debug-level message. */\n debug(message: string, extra?: LogExtra): void {\n this.log(\"debug\", message, extra);\n }\n\n /** Log an info-level message. */\n info(message: string, extra?: LogExtra): void {\n this.log(\"info\", message, extra);\n }\n\n /** Log a warning-level message. */\n warning(message: string, extra?: LogExtra): void {\n this.log(\"warning\", message, extra);\n }\n\n /** Log an error-level message. */\n error(message: string, extra?: LogExtra): void {\n this.log(\"error\", message, extra);\n }\n\n /**\n * Emit a record at `level` when it clears the configured threshold.\n *\n * @param level - The record severity.\n * @param message - The human-readable message.\n * @param extra - Structured context merged into the record.\n */\n log(level: LogLevel, message: string, extra?: LogExtra): void {\n if (LEVEL_ORDER[level] < LEVEL_ORDER[this.level]) return;\n const record: Record<string, unknown> = {\n level,\n logger: this.name,\n message,\n requestId: getRequestId(),\n ...extra,\n };\n const line = JSON.stringify(record);\n if (level === \"error\") process.stderr.write(`${line}\\n`);\n else process.stdout.write(`${line}\\n`);\n for (const sink of sinks) {\n try {\n sink(level, record);\n } catch {\n // A sink must never break logging.\n }\n }\n }\n}\n\n/**\n * Build a {@link JSONLogger}.\n *\n * @param name - Logger name.\n * @param level - Minimum level to emit (defaults to `info`).\n * @returns A configured logger.\n */\nexport function configureLogging(name: string, level: LogLevel = \"info\"): JSONLogger {\n return new JSONLogger(name, level);\n}\n","/**\n * Enum helpers mirroring `BaseStrEnum` / `BaseIntEnum`.\n *\n * TypeScript has no Python-style `Enum`, so this module offers a factory that\n * turns a plain literal map into a frozen object carrying the same\n * introspection helpers (`values`/`keys`/`choices`/`has`/`from`) the FastAPI\n * SDK exposes. The inferred type is the literal union of the member values, so\n * it stays as strongly typed as a hand-written `as const` map.\n */\n\n/** A member-name → member-value map (string- or number-valued). */\nexport type EnumSpec = Record<string, string | number>;\n\n/** Introspection helpers attached to every built enum. */\nexport interface EnumHelpers<S extends EnumSpec> {\n /** Every member value, in declaration order. */\n values(): Array<S[keyof S]>;\n /** Every member name, in declaration order. */\n keys(): Array<keyof S & string>;\n /** `[value, name]` pairs, e.g. for building `<select>` options. */\n choices(): Array<[S[keyof S], keyof S & string]>;\n /** Whether `value` is the value of some member. */\n hasValue(value: unknown): value is S[keyof S];\n /** Whether `key` is the name of some member. */\n hasKey(key: string): key is keyof S & string;\n /** Resolve a member value from a raw value or member name, else `fallback`. */\n from(value: unknown, fallback?: S[keyof S]): S[keyof S] | undefined;\n}\n\n/** A built enum: the literal member map plus {@link EnumHelpers}. */\nexport type Enum<S extends EnumSpec> = Readonly<S> & EnumHelpers<S>;\n\n/**\n * Build a frozen enum object with introspection helpers from a literal spec.\n *\n * @param spec - The member-name → value map. Pass it inline so TypeScript\n * infers the precise literal union (e.g. `defineEnum({ RED: \"red\" })`).\n * @returns The frozen members merged with {@link EnumHelpers}.\n */\nexport function defineEnum<const S extends EnumSpec>(spec: S): Enum<S> {\n const names = Object.keys(spec) as Array<keyof S & string>;\n const valueSet = new Set<unknown>(names.map((name) => spec[name]));\n\n const helpers: EnumHelpers<S> = {\n values: () => names.map((name) => spec[name]) as Array<S[keyof S]>,\n keys: () => [...names],\n choices: () =>\n names.map((name) => [spec[name], name]) as Array<[S[keyof S], keyof S & string]>,\n hasValue: (value: unknown): value is S[keyof S] => valueSet.has(value),\n hasKey: (key: string): key is keyof S & string => key in spec,\n from: (value: unknown, fallback?: S[keyof S]): S[keyof S] | undefined => {\n if (valueSet.has(value)) return value as S[keyof S];\n if (typeof value === \"string\" && value in spec) return spec[value] as S[keyof S];\n return fallback;\n },\n };\n\n return Object.freeze({ ...spec, ...helpers }) as Enum<S>;\n}\n","/**\n * Base application exception.\n *\n * Mirrors `tempest_fastapi_sdk.exceptions.base.AppException`: a single base any\n * layer can throw, carrying an HTTP status, a stable machine-readable `code`,\n * free-form `details`, optional response `headers`, and localization hooks\n * (`messageKey` / `messageParams`). The exception handler\n * ({@link registerExceptionHandlers}) serializes it to the canonical envelope:\n *\n * ```json\n * { \"detail\": \"<message>\", \"code\": \"<code>\", \"details\": { } }\n * ```\n *\n * Concrete projects either throw a domain subclass (for `instanceof` matching)\n * or the base directly, overriding fields via the constructor options.\n */\n\n/** Free-form structured context attached to the response payload. */\nexport type ExceptionDetails = Record<string, unknown>;\n\n/** Constructor options for {@link AppException} and subclasses. */\nexport interface AppExceptionOptions {\n /** Override the default message; used verbatim as `detail` absent a catalog. */\n message?: string;\n /** Override the default machine-readable code on this instance only. */\n code?: string;\n /** Override the default HTTP status code on this instance only. */\n statusCode?: number;\n /** Structured context merged into the JSON response `details`. */\n details?: ExceptionDetails;\n /** Extra HTTP response headers. */\n headers?: Record<string, string>;\n /** Catalog key used to localize `detail`; falls back to `code`. */\n messageKey?: string;\n /** Values interpolated into the localized message template. */\n messageParams?: Record<string, unknown>;\n}\n\nexport class AppException extends Error {\n /** Default HTTP status code for the class. */\n static statusCode = 500;\n /** Default human-readable message for the class. */\n static message = \"Internal server error\";\n /** Default machine-readable code for the class. */\n static code = \"INTERNAL_SERVER_ERROR\";\n /** Default catalog key for the class (falls back to `code`). */\n static messageKey: string | null = null;\n\n readonly statusCode: number;\n readonly code: string;\n readonly details: ExceptionDetails;\n readonly headers: Record<string, string>;\n readonly messageKey: string | null;\n readonly messageParams: Record<string, unknown>;\n\n /**\n * @param options - Per-instance overrides; omitted fields fall back to the\n * static class defaults.\n */\n constructor(options: AppExceptionOptions = {}) {\n const cls = new.target as typeof AppException;\n super(options.message ?? cls.message);\n this.name = cls.name;\n this.statusCode = options.statusCode ?? cls.statusCode;\n this.code = options.code ?? cls.code;\n this.details = options.details ?? {};\n this.headers = options.headers ?? {};\n this.messageKey = options.messageKey ?? cls.messageKey;\n this.messageParams = options.messageParams ?? {};\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Concrete HTTP exception subclasses, mirroring the FastAPI SDK hierarchy.\n *\n * Each exists primarily for `instanceof` matching and to carry a sane default\n * status/code/message. Throw them directly or subclass further for domain\n * errors (e.g. `class UserNotFound extends NotFoundException {}`).\n */\n\nimport {\n AppException,\n type AppExceptionOptions,\n type ExceptionDetails,\n} from \"@/exceptions/base\";\n\n/** 409 — a write would violate a uniqueness/integrity rule. */\nexport class ConflictException extends AppException {\n static override statusCode = 409;\n static override message = \"Resource conflict\";\n static override code = \"CONFLICT\";\n}\n\n/** 404 — a single resource could not be located. Never for collections. */\nexport class NotFoundException extends AppException {\n static override statusCode = 404;\n static override message = \"Resource not found\";\n static override code = \"NOT_FOUND\";\n}\n\n/** 401 — the caller is not authenticated. */\nexport class UnauthorizedException extends AppException {\n static override statusCode = 401;\n static override message = \"Unauthorized\";\n static override code = \"UNAUTHORIZED\";\n}\n\n/** 403 — the caller is authenticated but lacks permission. */\nexport class ForbiddenException extends AppException {\n static override statusCode = 403;\n static override message = \"Forbidden\";\n static override code = \"FORBIDDEN\";\n}\n\n/** 422 — input failed a business rule beyond schema validation. */\nexport class ValidationException extends AppException {\n static override statusCode = 422;\n static override message = \"Validation error\";\n static override code = \"VALIDATION_ERROR\";\n}\n\n/** 401 — a JWT failed signature or claim validation. */\nexport class InvalidTokenException extends UnauthorizedException {\n static override message = \"Invalid token\";\n static override code = \"INVALID_TOKEN\";\n}\n\n/** 401 — a JWT's `exp` claim is in the past. */\nexport class ExpiredTokenException extends UnauthorizedException {\n static override message = \"Token expired\";\n static override code = \"TOKEN_EXPIRED\";\n}\n\n/** Options for {@link TooManyRequestsException}, adding a cooldown. */\nexport interface TooManyRequestsOptions extends AppExceptionOptions {\n /** Cooldown in seconds; sets `Retry-After` and `details.retryAfterSeconds`. */\n retryAfterSeconds?: number;\n}\n\n/** 429 — the client exceeded a rate limit or attempt budget. */\nexport class TooManyRequestsException extends AppException {\n static override statusCode = 429;\n static override message = \"Too many requests\";\n static override code = \"TOO_MANY_REQUESTS\";\n\n /**\n * @param options - Standard options plus an optional `retryAfterSeconds`\n * that populates both the `Retry-After` header and `details`.\n */\n constructor(options: TooManyRequestsOptions = {}) {\n const { retryAfterSeconds, details, headers, ...rest } = options;\n const mergedDetails: ExceptionDetails = { ...details };\n const mergedHeaders: Record<string, string> = { ...headers };\n if (retryAfterSeconds !== undefined) {\n mergedDetails.retryAfterSeconds ??= retryAfterSeconds;\n mergedHeaders[\"Retry-After\"] ??= String(retryAfterSeconds);\n }\n super({ ...rest, details: mergedDetails, headers: mergedHeaders });\n }\n}\n","/**\n * Lightweight message localization, mirroring `exceptions.i18n`.\n *\n * A {@link MessageCatalog} maps `code` → `{ locale: template }`. The exception\n * handler negotiates a locale from the request `Accept-Language` header and\n * resolves the exception's `messageKey` (or `code`) into a localized `detail`,\n * interpolating `messageParams` via `{name}` placeholders. A missing\n * translation falls back to the literal message, so partial catalogs are safe.\n */\n\n/** Default locale used when negotiation finds no match. */\nexport const DEFAULT_LOCALE = \"en\";\n\n/** A `code` → (`locale` → template) translation table. */\nexport type CatalogData = Record<string, Record<string, string>>;\n\n/**\n * Parse an `Accept-Language` header into locales ordered by descending `q`.\n *\n * @param header - The raw header value, or `null`/`undefined`.\n * @returns Lower-cased language tags, highest quality first.\n */\nexport function parseAcceptLanguage(header: string | null | undefined): string[] {\n if (!header) return [];\n return header\n .split(\",\")\n .map((part) => {\n const [tag, ...params] = part.trim().split(\";\");\n const q = params\n .map((p) => p.trim())\n .find((p) => p.startsWith(\"q=\"))\n ?.slice(2);\n return { tag: (tag ?? \"\").trim().toLowerCase(), q: q ? Number(q) : 1 };\n })\n .filter((entry) => entry.tag.length > 0 && !Number.isNaN(entry.q))\n .sort((a, b) => b.q - a.q)\n .map((entry) => entry.tag);\n}\n\n/** Interpolate `{name}` placeholders in `template` with `params`. */\nfunction interpolate(template: string, params: Record<string, unknown>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n key in params ? String(params[key]) : match,\n );\n}\n\n/** A localized message catalog keyed by error `code`. */\nexport class MessageCatalog {\n /**\n * @param data - The translation table.\n * @param defaultLocale - Locale used when negotiation matches nothing.\n */\n constructor(\n private readonly data: CatalogData = {},\n private readonly defaultLocale: string = DEFAULT_LOCALE,\n ) {}\n\n /**\n * Pick the best locale for an `Accept-Language` header.\n *\n * Matches exact tags first, then the primary subtag (`pt-br` → `pt`),\n * falling back to `defaultLocale`.\n *\n * @param header - The raw `Accept-Language` value.\n * @param defaultLocale - Override the catalog's default for this call.\n * @returns The negotiated locale tag.\n */\n negotiate(header: string | null | undefined, defaultLocale?: string): string {\n const fallback = defaultLocale ?? this.defaultLocale;\n const available = new Set<string>();\n for (const byLocale of Object.values(this.data)) {\n for (const locale of Object.keys(byLocale)) available.add(locale.toLowerCase());\n }\n for (const tag of parseAcceptLanguage(header)) {\n if (available.has(tag)) return tag;\n const primary = tag.split(\"-\")[0];\n if (primary && available.has(primary)) return primary;\n }\n return fallback;\n }\n\n /**\n * Resolve a localized message for `code` in `locale`.\n *\n * @param code - The catalog key (an exception's `messageKey` or `code`).\n * @param locale - The negotiated locale.\n * @param params - Values interpolated into the template.\n * @returns The localized string, or `null` when no template exists.\n */\n resolve(\n code: string,\n locale: string,\n params: Record<string, unknown> = {},\n ): string | null {\n const byLocale = this.data[code];\n if (!byLocale) return null;\n const template = byLocale[locale] ?? byLocale[this.defaultLocale];\n return template ? interpolate(template, params) : null;\n }\n}\n\n/** Build an empty default catalog. */\nexport function defaultMessageCatalog(): MessageCatalog {\n return new MessageCatalog();\n}\n","/**\n * Zod foundation shared by every DTO, mirroring `schemas.base.BaseSchema`.\n *\n * Pydantic uses class inheritance for shared config; Zod composes instead. This\n * module re-exports a `z` already augmented with `.openapi()` (so every schema\n * can carry OpenAPI metadata) and a {@link toDict} helper matching\n * `BaseSchema.to_dict` (drop nullish, exclude keys, merge extras).\n */\n\nimport { extendZodWithOpenApi } from \"@asteasolutions/zod-to-openapi\";\nimport { z } from \"zod\";\n\n// Augment the shared `z` instance with `.openapi(...)`. Idempotent — calling it\n// more than once across modules is safe.\nextendZodWithOpenApi(z);\n\nexport { z };\n\n/** Options for {@link toDict}. */\nexport interface ToDictOptions {\n /** Field names to drop from the output. */\n exclude?: string[];\n /** Extra entries merged on top (override existing keys). */\n include?: Record<string, unknown>;\n}\n\n/**\n * Serialize a validated object to a plain record, dropping `null`/`undefined`,\n * removing `exclude`d keys and merging `include` on top.\n *\n * @param data - The source object (typically a parsed schema).\n * @param options - Keys to exclude and entries to merge in.\n * @returns The cleaned record.\n */\nexport function toDict(\n data: Record<string, unknown>,\n options: ToDictOptions = {},\n): Record<string, unknown> {\n const exclude = new Set(options.exclude ?? []);\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (exclude.has(key)) continue;\n if (value === null || value === undefined) continue;\n out[key] = value;\n }\n return { ...out, ...(options.include ?? {}) };\n}\n\n/**\n * Response schema fields every ORM record carries (`id`, `isActive`,\n * `createdAt`, `updatedAt`). Mirrors `BaseResponseSchema`. Extend it with\n * `baseResponseSchema.extend({ ... })` to build concrete `*ResponseSchema`s.\n */\nexport const baseResponseSchema = z.object({\n id: z.uuid().openapi({ description: \"The unique identifier of the record.\" }),\n isActive: z\n .boolean()\n .openapi({ description: \"Whether the record is active (soft-delete flag).\" }),\n createdAt: z.coerce\n .date()\n .openapi({ description: \"The creation timestamp of the record (UTC).\" }),\n updatedAt: z.coerce\n .date()\n .openapi({ description: \"The last update timestamp of the record (UTC).\" }),\n});\n\n/** The inferred TS type of a {@link baseResponseSchema} payload. */\nexport type BaseResponse = z.infer<typeof baseResponseSchema>;\n","/**\n * Ready-made, validated Zod field types, mirroring `utils.fields`.\n *\n * Reusable building blocks for DTOs so you don't re-derive the same constraint\n * everywhere: money in cents, a price string, a percentage, a latitude, a slug,\n * a hex color. Compose them into schemas with `z.object({ price: priceField })`.\n */\n\nimport { z } from \"@/schemas/base\";\n\n// --- Integers ---------------------------------------------------------------\n\n/** A strictly positive integer (`> 0`). */\nexport const positiveIntField = z.number().int().positive();\n/** A non-negative integer (`>= 0`). */\nexport const nonNegativeIntField = z.number().int().min(0);\n/** A monetary amount in the smallest unit (cents), `>= 0`. Avoids float drift. */\nexport const centsField = z.number().int().min(0);\n/** A TCP port (`1..65535`). */\nexport const portField = z.number().int().min(1).max(65535);\n/** A 0–5 star rating. */\nexport const ratingField = z.number().int().min(0).max(5);\n\n// --- Floats -----------------------------------------------------------------\n\n/** A strictly positive float (`> 0`). */\nexport const positiveFloatField = z.number().positive();\n/** A non-negative float (`>= 0`). */\nexport const nonNegativeFloatField = z.number().min(0);\n/** A percentage (`0..100`). */\nexport const percentField = z.number().min(0).max(100);\n/** A ratio (`0..1`). */\nexport const ratioField = z.number().min(0).max(1);\n/** A WGS-84 latitude (`-90..90`). */\nexport const latitudeField = z.number().min(-90).max(90);\n/** A WGS-84 longitude (`-180..180`). */\nexport const longitudeField = z.number().min(-180).max(180);\n\n// --- Strings ----------------------------------------------------------------\n\n/** A non-empty string; whitespace is trimmed before the length check. */\nexport const nonEmptyStrField = z\n .string()\n .transform((value) => value.trim())\n .pipe(z.string().min(1));\n\n/** A URL slug: lowercase alphanumerics separated by single hyphens. */\nexport const slugField = z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {\n message: \"Must be a lowercase hyphen-separated slug.\",\n});\n\n/** A hex color: `#rgb` or `#rrggbb`. */\nexport const hexColorField = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, {\n message: \"Must be a #rgb or #rrggbb hex color.\",\n});\n\n/**\n * A money amount as an exact decimal **string** with up to two decimal places\n * (e.g. `\"19.90\"`). Mirrors `PriceField` — `tempest-db-js` `numeric` columns map\n * to strings, so money stays exact instead of drifting through a float.\n */\nexport const priceField = z\n .string()\n .regex(/^\\d+(?:\\.\\d{1,2})?$/, {\n message: 'Must be a decimal money string, e.g. \"19.90\".',\n });\n\n// --- Booleans ---------------------------------------------------------------\n\n/** Message shown when a value is neither a boolean nor a boolean-ish token. */\nconst LOOSE_BOOLEAN_ERROR =\n 'Must be a boolean value such as \"true\", \"false\", \"1\", \"0\", \"yes\" or \"no\".';\n\n/**\n * A boolean read from a **textual** source — a query string or an environment\n * variable, where every value arrives as a string.\n *\n * `z.coerce.boolean()` is the wrong tool for those: it is `Boolean(input)`, so\n * every non-empty string is `true` — `\"false\"` and `\"0\"` included — and there is\n * no way to ask for `false` over the wire. This reads the usual textual tokens\n * in both directions (`true`/`1`/`yes`/`on`/`y`/`enabled` and\n * `false`/`0`/`no`/`off`/`n`/`disabled`, case-insensitive, surrounding\n * whitespace trimmed) and **rejects** anything else, so a typo surfaces as a\n * validation error instead of silently becoming `false`.\n *\n * An absent value — and an empty or whitespace-only string, which is how an\n * unset `.env` entry (`DEBUG=`) reaches the schema — falls back to\n * `defaultValue`. Real booleans pass through untouched, so a schema built for\n * `process.env` still parses a synthetic object in tests.\n *\n * The OpenAPI metadata is pinned to `type: boolean` (with the default) so the\n * document describes the field the client actually sends, not the union used to\n * parse it.\n *\n * @param defaultValue - The value used when the field is absent or empty.\n * @returns A zod schema producing a `boolean`.\n */\nexport function looseBoolean(defaultValue: boolean) {\n return z\n .preprocess(\n (value) => (typeof value === \"string\" ? value.trim() || undefined : value),\n z\n .union([z.boolean(), z.stringbool()], { error: LOOSE_BOOLEAN_ERROR })\n .default(defaultValue),\n )\n .openapi({ type: \"boolean\", default: defaultValue });\n}\n","/**\n * Pagination request/response primitives, mirroring `schemas.pagination`.\n *\n * Offset pagination ({@link paginationFilterSchema} / {@link paginationSchema})\n * and cursor pagination ({@link cursorPaginationFilterSchema} /\n * {@link cursorPaginationSchema}). Field names match the `tempest-db-js`\n * `BaseRepository.paginate` arguments so a parsed filter forwards through with\n * no renaming.\n */\n\nimport { type ToDictOptions, toDict, z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/**\n * Filter schema for offset-paginated list endpoints. Subclass via `.extend`\n * to add domain filters; {@link getConditions} strips the pagination keys.\n */\nexport const paginationFilterSchema = z.object({\n page: z.coerce\n .number()\n .int()\n .min(1)\n .default(1)\n .openapi({ description: \"The page number to retrieve (1-indexed).\" }),\n pageSize: z.coerce\n .number()\n .int()\n .min(1)\n .default(20)\n .openapi({ description: \"The number of items per page.\" }),\n orderBy: z\n .string()\n .optional()\n .openapi({ description: \"Column to order by; defaults to repository default.\" }),\n ascending: looseBoolean(true).openapi({\n description: \"Whether to order results ascending.\",\n }),\n});\n\n/** The parsed shape of {@link paginationFilterSchema}. */\nexport type PaginationFilter = z.infer<typeof paginationFilterSchema>;\n\nconst PAGINATION_KEYS = [\"page\", \"pageSize\", \"orderBy\", \"ascending\"];\n\n/**\n * Strip pagination/sort keys from a parsed filter, leaving only domain filters.\n *\n * @param filter - The parsed filter object (may carry extra domain fields).\n * @param options - Extra exclude/include passed through to {@link toDict}.\n * @returns The domain-level filter conditions.\n */\nexport function getConditions(\n filter: Record<string, unknown>,\n options: ToDictOptions = {},\n): Record<string, unknown> {\n return toDict(filter, {\n ...options,\n exclude: [...PAGINATION_KEYS, ...(options.exclude ?? [])],\n });\n}\n\n/**\n * The pagination/sort keyword arguments to forward to `BaseRepository.paginate`.\n *\n * @param filter - The parsed pagination filter.\n * @returns `{ page, pageSize, orderBy, ascending }`.\n */\nexport function getPaginationConditions(filter: PaginationFilter): {\n page: number;\n pageSize: number;\n orderBy?: string;\n ascending: boolean;\n} {\n return {\n page: filter.page,\n pageSize: filter.pageSize,\n ...(filter.orderBy !== undefined ? { orderBy: filter.orderBy } : {}),\n ascending: filter.ascending,\n };\n}\n\n/**\n * Build the offset-pagination response envelope for a given item schema.\n *\n * @param item - The zod schema for a single item.\n * @returns A zod object schema `{ items, total, page, pageSize, pages }`.\n */\nexport function paginationSchema<T extends z.ZodType>(item: T) {\n return z.object({\n items: z.array(item).openapi({ description: \"The items on the current page.\" }),\n total: z\n .number()\n .int()\n .min(0)\n .openapi({ description: \"Total items across all pages.\" }),\n page: z.number().int().min(1).openapi({ description: \"Current page (1-indexed).\" }),\n pageSize: z.number().int().min(1).openapi({ description: \"Items per page.\" }),\n pages: z.number().int().min(0).openapi({ description: \"Total number of pages.\" }),\n });\n}\n\n/** Filter schema for cursor-paginated endpoints. */\nexport const cursorPaginationFilterSchema = z.object({\n cursor: z\n .string()\n .optional()\n .openapi({ description: \"Opaque cursor; omit for the first page.\" }),\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(500)\n .default(20)\n .openapi({ description: \"Maximum number of items to return.\" }),\n orderBy: z.string().default(\"createdAt\").openapi({ description: \"Column to sort by.\" }),\n ascending: looseBoolean(false).openapi({\n description: \"Whether to sort ascending (default newest first).\",\n }),\n});\n\n/** The parsed shape of {@link cursorPaginationFilterSchema}. */\nexport type CursorPaginationFilter = z.infer<typeof cursorPaginationFilterSchema>;\n\n/**\n * Build the cursor-pagination response envelope for a given item schema.\n *\n * @param item - The zod schema for a single item.\n * @returns A zod object schema `{ items, nextCursor, hasMore, limit }`.\n */\nexport function cursorPaginationSchema<T extends z.ZodType>(item: T) {\n return z.object({\n items: z.array(item).openapi({ description: \"The items on the current page.\" }),\n nextCursor: z\n .string()\n .nullable()\n .openapi({ description: \"Cursor for the next page, or null when exhausted.\" }),\n hasMore: z.boolean().openapi({ description: \"Whether another page is available.\" }),\n limit: z.number().int().min(1).openapi({ description: \"The page size used.\" }),\n });\n}\n\n/**\n * Serialize a cursor payload to an opaque URL-safe base64 string (no padding).\n *\n * @param payload - The cursor state, e.g. `{ id, value }`.\n * @returns The encoded cursor.\n */\nexport function encodeCursor(payload: Record<string, unknown>): string {\n const json = JSON.stringify(payload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\n/**\n * Decode a cursor produced by {@link encodeCursor}.\n *\n * @param cursor - The opaque cursor string.\n * @returns The decoded payload.\n * @throws {Error} When the cursor is not valid base64 or not a JSON object.\n */\nexport function decodeCursor(cursor: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf8\"));\n } catch (cause) {\n throw new Error(\"Invalid cursor\", { cause });\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"Invalid cursor payload\");\n }\n return parsed as Record<string, unknown>;\n}\n","/**\n * Delta-sync pagination schemas, mirroring `schemas.pagination` (Sync* half).\n *\n * For offline-first clients that pull \"everything changed since my last sync\".\n * The client sends the `serverTime` from the previous page back as `since`;\n * using the **server** clock as the watermark avoids clock-skew gaps.\n */\n\nimport { z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/**\n * Filter schema for a delta-sync pull. Extend with `.extend` to add domain\n * filters; the sync keys stay reserved.\n */\nexport const syncFilterSchema = z.object({\n since: z.coerce\n .date()\n .optional()\n .openapi({\n description: \"High-water mark; only rows changed after this are returned.\",\n }),\n cursor: z\n .string()\n .optional()\n .openapi({\n description: \"Opaque cursor from the previous page; omit for the first.\",\n }),\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(1000)\n .default(100)\n .openapi({ description: \"Maximum number of items to return.\" }),\n includeDeleted: looseBoolean(false).openapi({\n description: \"Whether soft-deleted rows are included in the delta.\",\n }),\n});\n\n/** The parsed shape of {@link syncFilterSchema}. */\nexport type SyncFilter = z.infer<typeof syncFilterSchema>;\n\n/**\n * Build the delta-sync response envelope for a given item schema. Persist\n * `serverTime` on the client and send it back as the next `since`.\n *\n * @param item - The zod schema for a single item.\n * @returns A zod object `{ items, nextCursor, hasMore, limit, serverTime }`.\n */\nexport function syncPaginationSchema<T extends z.ZodType>(item: T) {\n return z.object({\n items: z.array(item).openapi({ description: \"Changed rows in this page.\" }),\n nextCursor: z\n .string()\n .nullable()\n .openapi({ description: \"Cursor for the next page, or null when exhausted.\" }),\n hasMore: z.boolean().openapi({ description: \"Whether another page is available.\" }),\n limit: z.number().int().min(1).openapi({ description: \"The page size used.\" }),\n serverTime: z.coerce\n .date()\n .openapi({\n description: \"Server instant to persist as the next `since` watermark.\",\n }),\n });\n}\n","/**\n * RFC-5988 pagination `Link` header builder, mirroring `schemas.link_headers`.\n *\n * Emits the `first` / `prev` / `next` / `last` rels GitHub-style clients expect.\n * `prev`/`next` are omitted at the ends. Assign the result to\n * `res.setHeader(\"Link\", value)`.\n */\n\n/** Options for {@link buildPaginationLinkHeader}. */\nexport interface PaginationLinkOptions {\n /** Absolute or relative collection URL; existing query params are preserved. */\n baseUrl: string;\n /** Current page (1-based). */\n page: number;\n /** Page size. */\n pageSize: number;\n /** Total number of pages. */\n pages: number;\n /** Extra query params to preserve on every link (filters, sort). */\n extraParams?: Record<string, string>;\n /** Query param name for the page index. Default `\"page\"`. */\n pageParam?: string;\n /** Query param name for the page size. Default `\"pageSize\"`. */\n sizeParam?: string;\n}\n\n/**\n * Build a `Link` header value for an offset-paginated collection.\n *\n * @param options - Base URL, current page, page size, total pages and param names.\n * @returns The `Link` header value, or `\"\"` when there's nothing to link (single page).\n */\nexport function buildPaginationLinkHeader(options: PaginationLinkOptions): string {\n const { baseUrl, page, pageSize, pages } = options;\n if (pages <= 0) return \"\";\n\n const pageParam = options.pageParam ?? \"page\";\n const sizeParam = options.sizeParam ?? \"pageSize\";\n\n // Split any existing query off the base so we can rebuild it deterministically.\n const [path, existingQuery = \"\"] = baseUrl.split(\"?\", 2);\n const params = new URLSearchParams(existingQuery);\n for (const [key, value] of Object.entries(options.extraParams ?? {})) {\n if (!params.has(key)) params.set(key, value);\n }\n\n const urlFor = (target: number): string => {\n const q = new URLSearchParams(params);\n q.set(pageParam, String(target));\n q.set(sizeParam, String(pageSize));\n return `${path}?${q.toString()}`;\n };\n\n const parts: string[] = [\n `<${urlFor(1)}>; rel=\"first\"`,\n `<${urlFor(pages)}>; rel=\"last\"`,\n ];\n if (page > 1) parts.push(`<${urlFor(page - 1)}>; rel=\"prev\"`);\n if (page < pages) parts.push(`<${urlFor(page + 1)}>; rel=\"next\"`);\n return parts.join(\", \");\n}\n","/**\n * `logEntrySchema` — the shape of one structured log record, mirroring\n * `schemas.logs.LogEntrySchema`.\n *\n * Matches the JSON `JSONLogger` emits. It is intentionally open (`.loose()`)\n * so arbitrary `extra` keys (`path`, `requestId`, `http_500`, …) survive instead\n * of being dropped — useful when a logs endpoint parses and returns records.\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** One structured log record; extra keys pass through unchanged. */\nexport const logEntrySchema = z\n .object({\n timestamp: z\n .string()\n .openapi({ description: \"ISO-8601 UTC timestamp of the record.\" }),\n level: z.string().openapi({ description: \"Log level name (INFO, ERROR, …).\" }),\n logger: z.string().openapi({ description: \"Name of the emitting logger.\" }),\n message: z.string().openapi({ description: \"The formatted log message.\" }),\n requestId: z\n .string()\n .nullable()\n .optional()\n .openapi({ description: \"Correlation id, when present.\" }),\n stack: z\n .string()\n .nullable()\n .optional()\n .openapi({\n description: \"Formatted stack trace, when the record carries an error.\",\n }),\n })\n .loose();\n\n/** The parsed shape of {@link logEntrySchema} (plus any extra keys). */\nexport type LogEntry = z.infer<typeof logEntrySchema>;\n","/**\n * Environment-driven settings, mirroring `settings.base.BaseAppSettings`.\n *\n * Pydantic-settings reads env vars into a frozen, validated model. Here a zod\n * schema plays the same role: {@link loadSettings} parses `process.env` (env\n * names are matched case-sensitively, like the FastAPI SDK) and returns a\n * frozen, fully-typed object. Composable fragments ({@link serverSettingsShape}\n * etc.) cover the common server/database/CORS knobs.\n */\n\nimport { z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/** Server bind/runtime settings. Defaults bind to localhost. */\nexport const serverSettingsShape = {\n HOST: z.string().default(\"127.0.0.1\"),\n PORT: z.coerce.number().int().min(0).max(65535).default(8000),\n DEBUG: looseBoolean(false),\n} as const;\n\n/** Database connection settings. */\nexport const databaseSettingsShape = {\n DATABASE_URL: z.string().default(\"sqlite://./app.db\"),\n} as const;\n\n/** CORS settings. `CORS_ORIGINS` is a comma-separated list. */\nexport const corsSettingsShape = {\n CORS_ORIGINS: z\n .string()\n .default(\"*\")\n .transform((value) =>\n value\n .split(\",\")\n .map((origin) => origin.trim())\n .filter((origin) => origin.length > 0),\n ),\n} as const;\n\n/** The combined base settings shape (server + database + CORS). */\nexport const baseAppSettingsShape = {\n ...serverSettingsShape,\n ...databaseSettingsShape,\n ...corsSettingsShape,\n} as const;\n\n/** A zod object built from {@link baseAppSettingsShape}. */\nexport const baseAppSettingsSchema = z.object(baseAppSettingsShape);\n\n/** The parsed shape of {@link baseAppSettingsSchema}. */\nexport type BaseAppSettings = z.infer<typeof baseAppSettingsSchema>;\n\n/**\n * Parse and freeze settings from an environment source.\n *\n * Extend the base shape with project fields:\n *\n * ```ts\n * const settings = loadSettings(\n * z.object({ ...baseAppSettingsShape, JWT_SECRET: z.string() }),\n * );\n * ```\n *\n * @param schema - The settings zod schema.\n * @param env - The environment source (defaults to `process.env`).\n * @returns The validated, frozen settings object.\n * @throws {z.ZodError} When required env vars are missing or malformed.\n */\nexport function loadSettings<S extends z.ZodType>(\n schema: S,\n env: NodeJS.ProcessEnv = process.env,\n): Readonly<z.infer<S>> {\n return Object.freeze(schema.parse(env));\n}\n","/**\n * Composable settings fragments covering common service dependencies,\n * mirroring `settings.mixins`.\n *\n * Each fragment is a plain object of zod fields keyed by the **environment\n * variable name** (matched case-sensitively, no prefix), with the same defaults\n * as the FastAPI SDK. Compose the ones a service needs onto\n * {@link baseAppSettingsShape} and parse with {@link loadSettings}:\n *\n * ```ts\n * import { baseAppSettingsShape, jwtSettingsShape, loadSettings, z } from \"tempest-express-sdk\";\n *\n * const settings = loadSettings(\n * z.object({ ...baseAppSettingsShape, ...jwtSettingsShape }),\n * );\n * settings.JWT_SECRET; // typed\n * ```\n *\n * Nothing here reads `process.env` on its own — `loadSettings` does, so the\n * fragments stay pure and testable.\n */\n\nimport { z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/**\n * Parse an environment string into a boolean — the settings-facing name for\n * {@link looseBoolean}, which is the single implementation shared with the\n * query-string filters. Keeping one implementation is the point: two token\n * lists drift, and a boolean that parses one way in a filter and another way in\n * a settings field is the kind of divergence nothing catches.\n */\nexport { looseBoolean as envBoolean };\n\n/**\n * Parse a comma-separated environment string into a trimmed, non-empty list.\n *\n * @param defaultValue - The default CSV string when the variable is absent.\n * @returns A zod schema producing `string[]`.\n */\nexport function envList(defaultValue = \"\") {\n return z\n .string()\n .default(defaultValue)\n .transform((value) =>\n value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0),\n );\n}\n\n/** Structured logging configuration. */\nexport const logSettingsShape = {\n LOG_LEVEL: z.enum([\"DEBUG\", \"INFO\", \"WARNING\", \"ERROR\"]).default(\"INFO\"),\n LOG_JSON: looseBoolean(true),\n LOG_DIR: z.string().default(\"logs\"),\n} as const;\n\n/** Redis connection settings (cache / sessions / SSE broker). */\nexport const redisSettingsShape = {\n REDIS_URL: z.string().default(\"redis://localhost:6379/0\"),\n} as const;\n\n/** RabbitMQ connection settings (queue broker). */\nexport const rabbitmqSettingsShape = {\n RABBITMQ_URL: z.string().default(\"amqp://guest:guest@localhost:5672/\"),\n RABBITMQ_PREFETCH_COUNT: z.coerce.number().int().min(1).default(10),\n} as const;\n\n/** JWT signing/verification settings. */\nexport const jwtSettingsShape = {\n JWT_SECRET: z.string().default(\"change-me-change-me-change-me-32\"),\n JWT_ALGORITHM: z.string().default(\"HS256\"),\n JWT_ACCESS_TTL_SECONDS: z.coerce.number().int().min(1).default(3600),\n JWT_REFRESH_TTL_SECONDS: z.coerce\n .number()\n .int()\n .min(1)\n .default(86400 * 7),\n JWT_ISSUER: z.string().optional(),\n} as const;\n\n/** Opaque shared-secret token settings (`X-Token` guards). */\nexport const tokenSettingsShape = {\n TOKEN_SECRET: z.string().default(\"\"),\n} as const;\n\n/** SMTP email transport settings. */\nexport const emailSettingsShape = {\n SMTP_HOST: z.string().default(\"localhost\"),\n SMTP_PORT: z.coerce.number().int().min(1).max(65535).default(587),\n SMTP_USERNAME: z.string().optional(),\n SMTP_PASSWORD: z.string().optional(),\n SMTP_FROM_ADDR: z.string().default(\"noreply@example.com\"),\n SMTP_USE_TLS: looseBoolean(true),\n SMTP_USE_SSL: looseBoolean(false),\n SMTP_TIMEOUT_SECONDS: z.coerce.number().min(0).default(30),\n} as const;\n\n/** Local upload storage settings. */\nexport const uploadSettingsShape = {\n UPLOAD_DIR: z.string().default(\"./var/uploads\"),\n UPLOAD_MAX_SIZE_BYTES: z.coerce\n .number()\n .int()\n .min(0)\n .default(10 * 1024 * 1024),\n UPLOAD_ALLOWED_EXTENSIONS: envList(),\n UPLOAD_ALLOWED_MIMETYPES: envList(),\n} as const;\n\n/** MinIO / S3 object-storage settings. */\nexport const minioSettingsShape = {\n MINIO_ENDPOINT: z.string().default(\"localhost:9000\"),\n MINIO_ACCESS_KEY: z.string().default(\"minioadmin\"),\n MINIO_SECRET_KEY: z.string().default(\"minioadmin\"),\n MINIO_SECURE: looseBoolean(false),\n MINIO_REGION: z.string().default(\"us-east-1\"),\n MINIO_DEFAULT_BUCKET: z.string().default(\"uploads\"),\n MINIO_PUBLIC_ENDPOINT: z.string().optional(),\n MINIO_PUBLIC_SECURE: z\n .union([z.boolean(), z.string()])\n .optional()\n .transform((value) =>\n value === undefined\n ? undefined\n : typeof value === \"boolean\"\n ? value\n : [\"true\", \"1\", \"yes\", \"on\"].includes(value.trim().toLowerCase()),\n ),\n} as const;\n\n/** Web Push (VAPID) settings. */\nexport const webPushSettingsShape = {\n VAPID_PUBLIC_KEY: z.string().default(\"\"),\n VAPID_PRIVATE_KEY: z.string().default(\"\"),\n VAPID_SUBJECT: z.string().default(\"mailto:admin@example.com\"),\n WEBPUSH_DEFAULT_TTL_SECONDS: z.coerce.number().int().min(0).default(86400),\n} as const;\n\n/** Server-side session settings (cookie + TTL). */\nexport const sessionSettingsShape = {\n SESSION_TTL_SECONDS: z.coerce.number().int().min(1).default(86400),\n SESSION_SLIDING: looseBoolean(true),\n SESSION_COOKIE_NAME: z.string().default(\"tempest_session\"),\n SESSION_COOKIE_DOMAIN: z.string().optional(),\n SESSION_COOKIE_PATH: z.string().default(\"/\"),\n SESSION_COOKIE_SECURE: looseBoolean(true),\n SESSION_COOKIE_HTTPONLY: looseBoolean(true),\n SESSION_COOKIE_SAMESITE: z.enum([\"lax\", \"strict\", \"none\"]).default(\"lax\"),\n SESSION_ROTATE_ON_LOGIN: looseBoolean(true),\n} as const;\n\n/** WebSocket hub tuning. */\nexport const webSocketSettingsShape = {\n WS_HEARTBEAT_SECONDS: z.coerce.number().int().min(1).default(30),\n WS_HEARTBEAT_TIMEOUT_SECONDS: z.coerce.number().int().min(1).default(60),\n WS_MAX_CONNECTIONS_PER_USER: z.coerce.number().int().min(1).default(5),\n WS_MAX_MESSAGE_BYTES: z.coerce\n .number()\n .int()\n .min(1)\n .default(64 * 1024),\n} as const;\n\n/**\n * Authentication flow settings (signup/activation/reset/MFA + token delivery).\n * The FastAPI SDK's HTML-template fields (SSR activation/reset pages) are\n * omitted — this SDK ships the JSON auth API and defers rendering to a\n * decoupled frontend.\n */\nexport const authSettingsShape = {\n AUTH_AUTO_ACTIVATE: looseBoolean(false),\n AUTH_RETURN_TOKEN_IN_RESPONSE: looseBoolean(false),\n AUTH_ACTIVATION_TTL_SECONDS: z.coerce\n .number()\n .int()\n .min(1)\n .default(86400 * 7),\n AUTH_PASSWORD_RESET_TTL_SECONDS: z.coerce.number().int().min(1).default(3600),\n AUTH_ACTIVATION_URL_TEMPLATE: z\n .string()\n .default(\"http://localhost:3000/activate?token={token}\"),\n AUTH_PASSWORD_RESET_URL_TEMPLATE: z\n .string()\n .default(\"http://localhost:3000/reset-password?token={token}\"),\n AUTH_PASSWORD_MIN_LENGTH: z.coerce.number().int().min(1).default(12),\n AUTH_PASSWORD_REQUIRE_COMPLEXITY: looseBoolean(false),\n AUTH_DEFAULT_LOCALE: z.string().default(\"pt-BR\"),\n AUTH_MFA_ENABLED: looseBoolean(false),\n AUTH_MFA_ISSUER: z.string().default(\"Tempest\"),\n AUTH_MFA_RECOVERY_CODES_COUNT: z.coerce.number().int().min(0).default(10),\n AUTH_MFA_TOKEN_TTL_SECONDS: z.coerce.number().int().min(1).default(300),\n AUTH_MFA_VERIFY_WINDOW: z.coerce.number().int().min(0).default(1),\n AUTH_TOKEN_DELIVERY: z.enum([\"bearer\", \"cookie\", \"both\"]).default(\"bearer\"),\n AUTH_COOKIE_SECURE: looseBoolean(true),\n AUTH_COOKIE_SAMESITE: z.enum([\"lax\", \"strict\", \"none\"]).default(\"lax\"),\n AUTH_COOKIE_DOMAIN: z.string().optional(),\n AUTH_ACCESS_COOKIE_NAME: z.string().default(\"access_token\"),\n AUTH_REFRESH_COOKIE_NAME: z.string().default(\"refresh_token\"),\n} as const;\n","/**\n * Canonical base ORM model + opt-in column mixins, mirroring `db.model` /\n * `db.mixins`.\n *\n * `tempest-db-js` models are declarative classes whose fields are runtime\n * column builders. {@link BaseModel} gives every model the four columns the SDK\n * conventions require — `id` (UUID primary key), `isActive` (soft-delete flag),\n * `createdAt` and `updatedAt` (DB-managed timestamps) — so a concrete model\n * only declares its own domain columns plus a `tablename`.\n *\n * TypeScript has no multiple inheritance, so the \"mixins\" ship as reusable\n * column-builder factories ({@link deletedAtColumn} etc.) you assign as fields,\n * rather than as base classes.\n */\n\nimport { Model, column, sql } from \"tempest-db-js\";\n\n/** Convert `CamelCase` to `snake_case` (e.g. `OrderItem` → `order_item`). */\nfunction toSnakeCase(name: string): string {\n return name.replace(/(?<!^)(?=[A-Z])/g, \"_\").toLowerCase();\n}\n\n/**\n * Derive a conventional table name from a model class name: the trailing\n * `Model` suffix is stripped and the rest snake-cased (`UserModel` → `user`).\n *\n * @param className - The model class name.\n * @returns The derived table name.\n */\nexport function tableNameFor(className: string): string {\n return toSnakeCase(className.replace(/Model$/, \"\"));\n}\n\n/**\n * Abstract base for every model. Concrete models extend it, set a static\n * `tablename`, and declare their own columns:\n *\n * ```ts\n * class UserModel extends BaseModel {\n * static tablename = tableNameFor(\"UserModel\"); // \"user\"\n * email = column.varchar(320).notNull();\n * name = column.text().notNull();\n * }\n * ```\n */\nexport abstract class BaseModel extends Model {\n /** Primary key — a UUID v4 generated on insert. */\n id = column.uuid().primaryKey().default(sql.uuidv4());\n /** Soft-delete flag; `true` means the record is active. */\n isActive = column.boolean().notNull().default(true);\n /** Creation timestamp, set by the database on insert. */\n createdAt = column.datetime().notNull().default(sql.now());\n /** Last-update timestamp, refreshed by the database on every update. */\n updatedAt = column.datetime().notNull().default(sql.now()).onUpdate(sql.now());\n}\n\n/**\n * Soft-delete timestamp column (`deleted_at`). `null` while the row is alive;\n * set when soft-deleted. Pairs with {@link BaseModel.isActive}.\n *\n * @returns A nullable datetime column builder, defaulting to `null`.\n */\nexport function deletedAtColumn() {\n return column.datetime();\n}\n\n/**\n * `created_by` audit column: UUID of the user that created the row.\n *\n * @returns A nullable UUID column builder.\n */\nexport function createdByColumn() {\n return column.uuid();\n}\n\n/**\n * `updated_by` audit column: UUID of the user that last updated the row.\n *\n * @returns A nullable UUID column builder.\n */\nexport function updatedByColumn() {\n return column.uuid();\n}\n","/**\n * Optional base user + token models, mirroring `db.user_model` /\n * `db.user_token_model` / `db.user_refresh_token_model`.\n *\n * These are **opt-in** starting points: subclass one, set a `static tablename`,\n * and add the columns your domain needs. They extend {@link BaseModel}, so they\n * already carry `id` / `isActive` / `createdAt` / `updatedAt`.\n */\n\nimport { BaseModel } from \"@/db/model\";\nimport { column, sql } from \"tempest-db-js\";\n\n/**\n * Base for an authenticated user. Subclass it, set `tablename`, and add domain\n * columns (name, avatar, …):\n *\n * ```ts\n * class UserModel extends BaseUserModel {\n * static tablename = tableNameFor(\"UserModel\"); // \"user\"\n * name = column.text().notNull();\n * }\n * ```\n */\nexport abstract class BaseUserModel extends BaseModel {\n /** Login identifier; enforce uniqueness with a unique index in a migration. */\n email = column.varchar(320).notNull();\n /** The password hash (never the plaintext) — see `PasswordUtils`. */\n hashedPassword = column.text().notNull();\n /** Whether the user has administrative privileges. */\n isAdmin = column.boolean().notNull().default(false);\n /** Timestamp of the last successful login, or `null` if never. */\n lastLoginAt = column.datetime();\n}\n\n/** Purpose of a single-use user token. */\nexport const UserTokenPurpose = {\n ACTIVATION: \"activation\",\n PASSWORD_RESET: \"password_reset\",\n EMAIL_VERIFICATION: \"email_verification\",\n EMAIL_CHANGE: \"email_change\",\n} as const;\n\n/** A `UserTokenPurpose` value. */\nexport type UserTokenPurpose = (typeof UserTokenPurpose)[keyof typeof UserTokenPurpose];\n\n/**\n * Base for a single-use, hashed user token (activation, password reset, email\n * verification/change). Store only the **hash** of the token; compare hashes on\n * redemption.\n */\nexport abstract class BaseUserTokenModel extends BaseModel {\n /** Owning user id. */\n userId = column.uuid().notNull();\n /** Hash of the opaque token value. */\n tokenHash = column.text().notNull();\n /** Purpose discriminator (a {@link UserTokenPurpose} value). */\n purpose = column.varchar(32).notNull();\n /** When the token stops being valid. */\n expiresAt = column.datetime().notNull();\n /** When the token was consumed, or `null` while still usable. */\n usedAt = column.datetime();\n /** Optional JSON payload carried with the token (e.g. the pending email). */\n payload = column.json<Record<string, unknown>>();\n}\n\n/**\n * Base for a rotating refresh token. Rotation revokes the used token and issues\n * a new one in the same `familyId`; reuse of a revoked token in a family is the\n * signal to revoke the whole family (theft detection).\n */\nexport abstract class BaseUserRefreshTokenModel extends BaseModel {\n /** Owning user id. */\n userId = column.uuid().notNull();\n /** Hash of the opaque refresh token. */\n tokenHash = column.text().notNull();\n /** Rotation family — all tokens descended from one login share it. */\n familyId = column.uuid().notNull().default(sql.uuidv4());\n /** When the token expires. */\n expiresAt = column.datetime().notNull();\n /** When the token was rotated/consumed, or `null`. */\n usedAt = column.datetime();\n /** When the token was revoked, or `null` while active. */\n revokedAt = column.datetime();\n}\n","/**\n * Audit log model + snapshot/diff helpers, mirroring `db.audit`.\n *\n * `BaseAuditLogModel` records who changed what: the entity, its id, the action,\n * an actor and a before/after `changes` diff. {@link snapshot} freezes a row to\n * a plain record and {@link diffSnapshots} computes the changed-field diff — the\n * two together are what a service writes into an audit row on every mutation.\n */\n\nimport { BaseModel } from \"@/db/model\";\nimport { column } from \"tempest-db-js\";\n\n/** The kind of mutation an audit entry records. */\nexport const AuditAction = {\n CREATE: \"create\",\n UPDATE: \"update\",\n DELETE: \"delete\",\n} as const;\n\n/** An `AuditAction` value. */\nexport type AuditAction = (typeof AuditAction)[keyof typeof AuditAction];\n\n/** A per-field before/after change. */\nexport interface FieldChange {\n before: unknown;\n after: unknown;\n}\n\n/**\n * Freeze a row (ORM instance or plain object) into a plain, comparable record,\n * dropping keys whose value is a function.\n *\n * @param row - The row to snapshot.\n * @param exclude - Field names to omit (e.g. `[\"hashedPassword\"]`).\n * @returns A plain record of the row's own enumerable data fields.\n */\nexport function snapshot(\n row: Record<string, unknown>,\n exclude: readonly string[] = [],\n): Record<string, unknown> {\n const skip = new Set(exclude);\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n if (skip.has(key) || typeof value === \"function\") continue;\n out[key] = value;\n }\n return out;\n}\n\n/**\n * Compute the changed-field diff between two snapshots.\n *\n * @param before - The snapshot before the change.\n * @param after - The snapshot after the change.\n * @returns A map of changed field → `{ before, after }`; empty when nothing\n * changed. Keys present in only one side count as a change.\n */\nexport function diffSnapshots(\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n): Record<string, FieldChange> {\n const changed: Record<string, FieldChange> = {};\n const keys = new Set([...Object.keys(before), ...Object.keys(after)]);\n for (const key of keys) {\n const oldValue = before[key];\n const newValue = after[key];\n if (\n !Object.is(oldValue, newValue) &&\n JSON.stringify(oldValue) !== JSON.stringify(newValue)\n ) {\n changed[key] = { before: oldValue, after: newValue };\n }\n }\n return changed;\n}\n\n/**\n * Base for an append-only audit log. Subclass it, set `tablename`, add indexes\n * on `entity` / `entityId` / `actor` in a migration.\n */\nexport abstract class BaseAuditLogModel extends BaseModel {\n /** Changed model name (e.g. `\"UserModel\"`). */\n entity = column.varchar(128).notNull();\n /** Changed row id, stored as text. */\n entityId = column.varchar(64).notNull();\n /** Mutation kind (an {@link AuditAction} value). */\n action = column.varchar(16).notNull();\n /** Who performed the change, or `null` for system/anonymous. */\n actor = column.varchar(128);\n /** Before/after diff, serialized as JSON. */\n changes = column.json<Record<string, FieldChange>>().notNull();\n /** Optional extra metadata (request id, ip, reason, …). */\n context = column.json<Record<string, unknown>>();\n}\n","/**\n * `TenantScopedRepository` — a `BaseRepository` that can't leak across tenants,\n * mirroring `db.tenant`.\n *\n * In a shared-schema multi-tenant database every tenant's rows live in the same\n * table, told apart by a `tenantId` column. Forget one `WHERE tenant_id = ?` and\n * tenant A reads (or deletes) tenant B's data. This repository binds a tenant id\n * at construction and injects it into every read filter and every write — the\n * scoping is invisible at the call site.\n */\n\nimport {\n BaseRepository,\n type InferInsert,\n type InferModel,\n type ModelClass,\n type PaginationFilter,\n type PaginationResult,\n RecordNotFound,\n type WhereInput,\n} from \"tempest-db-js\";\n\n/**\n * A repository whose every operation is scoped to a single tenant. Use it\n * exactly like {@link BaseRepository}.\n *\n * ```ts\n * const repo = new TenantScopedRepository(OrderModel, session, tenantId);\n * await repo.list(); // WHERE tenant_id = tenantId\n * await repo.create({ total: \"10\" }); // tenant_id stamped automatically\n * ```\n *\n * @typeParam C - the model class (must declare the tenant column).\n */\nexport class TenantScopedRepository<\n C extends ModelClass,\n TF extends string = \"tenantId\",\n> extends BaseRepository<C> {\n private readonly tenantId: unknown;\n private readonly tenantField: string;\n private readonly modelClass: C;\n\n /**\n * @param model - The model class (must have the `tenantField` column).\n * @param session - The async session.\n * @param tenantId - The tenant every operation is scoped to.\n * @param tenantField - Name of the tenant column. Default `\"tenantId\"`.\n */\n constructor(\n model: C,\n session: ConstructorParameters<typeof BaseRepository<C>>[1],\n tenantId: unknown,\n tenantField: TF = \"tenantId\" as TF,\n ) {\n super(model, session);\n this.modelClass = model;\n this.tenantId = tenantId;\n this.tenantField = tenantField;\n }\n\n /** Merge the tenant predicate into a filter object. */\n private scoped(filters?: WhereInput<InferModel<C>>): WhereInput<InferModel<C>> {\n return { ...(filters ?? {}), [this.tenantField]: this.tenantId } as WhereInput<\n InferModel<C>\n >;\n }\n\n /** Stamp the tenant id onto an insert payload. */\n private stamped<T extends Record<string, unknown>>(data: T): T {\n return { ...data, [this.tenantField]: this.tenantId };\n }\n\n override list(filters?: WhereInput<InferModel<C>>): Promise<InferModel<C>[]> {\n return super.list(this.scoped(filters));\n }\n\n override first(filters?: WhereInput<InferModel<C>>): Promise<InferModel<C> | null> {\n return super.first(this.scoped(filters));\n }\n\n override exists(filters: WhereInput<InferModel<C>>): Promise<boolean> {\n return super.exists(this.scoped(filters));\n }\n\n override count(filters?: WhereInput<InferModel<C>>): Promise<number> {\n return super.count(this.scoped(filters));\n }\n\n /** Fetch by id **within the tenant**; throws `RecordNotFound` across tenants. */\n override async getById(id: unknown): Promise<InferModel<C>> {\n const row = await super.first(this.scoped({ id } as WhereInput<InferModel<C>>));\n if (row === null) {\n throw new RecordNotFound(\n (this.modelClass as { tablename?: string }).tablename ?? \"row\",\n id,\n );\n }\n return row;\n }\n\n override getByIdOrNull(id: unknown): Promise<InferModel<C> | null> {\n return super.first(this.scoped({ id } as WhereInput<InferModel<C>>));\n }\n\n /** Insert one row; the tenant id is stamped for you (don't pass it). */\n override create(data: Omit<InferInsert<C>, TF>): Promise<InferModel<C>> {\n return super.create(this.stamped(data as Record<string, unknown>) as InferInsert<C>);\n }\n\n /** Insert many rows; the tenant id is stamped onto each. */\n override createMany(\n data: readonly Omit<InferInsert<C>, TF>[],\n ): Promise<InferModel<C>[]> {\n return super.createMany(\n data.map((d) => this.stamped(d as Record<string, unknown>) as InferInsert<C>),\n );\n }\n\n override update(\n filters: WhereInput<InferModel<C>>,\n set: Partial<InferModel<C>>,\n ): Promise<number> {\n // Never let a caller move a row to another tenant.\n const { [this.tenantField]: _drop, ...safeSet } = set as Record<string, unknown>;\n return super.update(this.scoped(filters), safeSet as Partial<InferModel<C>>);\n }\n\n override delete(filters: WhereInput<InferModel<C>>): Promise<number> {\n return super.delete(this.scoped(filters));\n }\n\n override paginate(\n filter: PaginationFilter<InferModel<C>> = {},\n ): Promise<PaginationResult<InferModel<C>>> {\n return super.paginate({ ...filter, filters: this.scoped(filter.filters) });\n }\n}\n","/**\n * Transactional outbox model + relay, mirroring `db.outbox`.\n *\n * Write a domain change and its \"event to publish\" **in the same transaction**\n * (into `BaseOutboxModel`), so the event can never be lost even if the broker is\n * down at write time. {@link OutboxRelay} then polls pending rows and publishes\n * them with at-least-once delivery, retrying failures with a backoff.\n */\n\nimport { JSONLogger } from \"@/core\";\nimport { BaseModel } from \"@/db/model\";\nimport type { BaseRepository, InferModel, ModelClass } from \"tempest-db-js\";\nimport { column, sql } from \"tempest-db-js\";\n\n/** Delivery state of an outbox event. */\nexport const OutboxStatus = {\n PENDING: \"pending\",\n SENT: \"sent\",\n FAILED: \"failed\",\n} as const;\n\n/** An `OutboxStatus` value. */\nexport type OutboxStatus = (typeof OutboxStatus)[keyof typeof OutboxStatus];\n\n/**\n * Base for a transactional outbox row. Subclass it and set `tablename`. Insert a\n * row in the same transaction as the write it describes.\n */\nexport abstract class BaseOutboxModel extends BaseModel {\n /** Destination topic / routing key. */\n topic = column.varchar(255).notNull();\n /** The event body, serialized as JSON. */\n payload = column.json<Record<string, unknown>>().notNull();\n /** Delivery state (an {@link OutboxStatus} value). */\n status = column.varchar(16).notNull().default(OutboxStatus.PENDING);\n /** How many delivery attempts have been made. */\n attempts = column.integer().notNull().default(0);\n /** Give up (mark `failed`) after this many attempts. */\n maxAttempts = column.integer().notNull().default(5);\n /** Earliest time the row may be delivered (drives retry backoff). */\n availableAt = column.datetime().notNull().default(sql.now());\n /** When the row was successfully delivered, or `null`. */\n sentAt = column.datetime();\n /** The last delivery error message, or `null`. */\n lastError = column.text();\n}\n\n/** Publishes one event to the broker; throws to signal a delivery failure. */\nexport type OutboxPublisher = (\n topic: string,\n payload: Record<string, unknown>,\n) => Promise<void>;\n\n/** Options for {@link OutboxRelay}. */\nexport interface OutboxRelayOptions {\n /** Max rows to drain per pass. Default `100`. */\n batchSize?: number;\n /** Base backoff (seconds) between retries; scaled by attempt count. Default `30`. */\n retryBackoffSeconds?: number;\n}\n\n/**\n * Polls a `BaseOutboxModel` table and publishes pending events with retries.\n *\n * @typeParam C - the concrete outbox model class.\n */\nexport class OutboxRelay<C extends ModelClass> {\n private readonly logger = new JSONLogger(\"tempest_express_sdk.db.outbox\");\n private readonly batchSize: number;\n private readonly retryBackoffSeconds: number;\n private running = false;\n\n /**\n * @param repository - Repository over the outbox model.\n * @param publish - Callback that delivers one event to the broker.\n * @param options - Batch size and retry backoff.\n */\n constructor(\n private readonly repository: BaseRepository<C>,\n private readonly publish: OutboxPublisher,\n options: OutboxRelayOptions = {},\n ) {\n this.batchSize = options.batchSize ?? 100;\n this.retryBackoffSeconds = options.retryBackoffSeconds ?? 30;\n }\n\n /**\n * Deliver one batch of due pending events.\n *\n * @param now - The current time (injectable for tests). Defaults to `new Date()`.\n * @returns The number of events successfully delivered.\n */\n async drainOnce(now: Date = new Date()): Promise<number> {\n // `list` has no LIMIT; fetch the due pending rows and process a batch.\n const due = (await this.repository.list({\n status: OutboxStatus.PENDING,\n availableAt: { lte: now },\n } as never)) as Array<InferModel<C> & Record<string, unknown>>;\n\n let delivered = 0;\n for (const event of due.slice(0, this.batchSize)) {\n try {\n await this.publish(\n event.topic as string,\n event.payload as Record<string, unknown>,\n );\n await this.repository.update(\n { id: event.id } as never,\n {\n status: OutboxStatus.SENT,\n sentAt: now,\n lastError: null,\n } as never,\n );\n delivered += 1;\n } catch (error) {\n await this.markFailure(event, error, now);\n }\n }\n return delivered;\n }\n\n private async markFailure(\n event: InferModel<C> & Record<string, unknown>,\n error: unknown,\n now: Date,\n ): Promise<void> {\n const attempts = (event.attempts as number) + 1;\n const maxAttempts = event.maxAttempts as number;\n const message = error instanceof Error ? error.message : String(error);\n const exhausted = attempts >= maxAttempts;\n const nextAvailable = new Date(\n now.getTime() + attempts * this.retryBackoffSeconds * 1000,\n );\n await this.repository.update(\n { id: event.id } as never,\n {\n attempts,\n status: exhausted ? OutboxStatus.FAILED : OutboxStatus.PENDING,\n availableAt: exhausted ? (event.availableAt as Date) : nextAvailable,\n lastError: message,\n } as never,\n );\n this.logger.warning(\"outbox delivery failed\", {\n id: String(event.id),\n topic: String(event.topic),\n attempts,\n exhausted,\n });\n }\n\n /**\n * Run `drainOnce` on an interval until {@link stop} is called.\n *\n * @param intervalMs - Delay between passes in milliseconds. Default `1000`.\n */\n async run(intervalMs = 1000): Promise<void> {\n this.running = true;\n while (this.running) {\n try {\n await this.drainOnce();\n } catch (error) {\n this.logger.error(\"outbox relay pass failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n\n /** Stop the {@link run} loop after the current pass. */\n stop(): void {\n this.running = false;\n }\n}\n","/**\n * Slow-query logging, mirroring `db.slow_query`.\n *\n * `tempest-db-js` exposes an `onQuery` hook with the SQL + params but **no\n * duration**, so timing has to happen at the driver boundary. This wraps an\n * `AsyncDriver` so every statement is timed and any that meets or exceeds a\n * threshold is logged — including statements run inside a reserved transaction.\n *\n * ```ts\n * import { AsyncEngine, NodeSqliteDriver } from \"tempest-express-sdk\";\n * import { wrapWithSlowQueryLog } from \"tempest-express-sdk\";\n *\n * const sync = NodeSqliteDriver.open(\"app.db\");\n * const timed = wrapWithSlowQueryLog(\n * { execute: (s, p) => Promise.resolve(sync.execute(s, p)), close: async () => sync.close() },\n * { thresholdMs: 200 },\n * );\n * const engine = new AsyncEngine(timed, \"sqlite\");\n * ```\n */\n\nimport { JSONLogger, type LogLevel } from \"@/core\";\nimport type { AsyncDriver } from \"tempest-db-js\";\n\n/** Options for {@link wrapWithSlowQueryLog}. */\nexport interface SlowQueryOptions {\n /** Statements at or above this many ms are logged. Default `500`. */\n thresholdMs?: number;\n /** Level for the slow-query lines. Default `\"warning\"`. */\n level?: LogLevel;\n /** Include the bound params in the log line. **Dev only** — may carry PII. */\n logParameters?: boolean;\n /** Logger name. Default `tempest_express_sdk.db.slow_query`. */\n loggerName?: string;\n}\n\n/**\n * Wrap an `AsyncDriver` so slow statements are logged. The returned driver is a\n * drop-in for {@link AsyncEngine}; `iterate` and `reserve` (transactions) are\n * preserved and their statements timed too.\n *\n * @param driver - The driver to wrap.\n * @param options - Threshold, level and whether to log params.\n * @returns A timing driver delegating to `driver`.\n */\nexport function wrapWithSlowQueryLog(\n driver: AsyncDriver,\n options: SlowQueryOptions = {},\n): AsyncDriver {\n const thresholdMs = options.thresholdMs ?? 500;\n const level = options.level ?? \"warning\";\n const logParameters = options.logParameters ?? false;\n const logger = new JSONLogger(\n options.loggerName ?? \"tempest_express_sdk.db.slow_query\",\n );\n\n // Wrap a given `execute` with timing so both the pooled driver and any\n // reserved (transaction-pinned) connection log slow statements correctly.\n const timed = (exec: AsyncDriver[\"execute\"]): AsyncDriver[\"execute\"] => {\n return async (sql, params) => {\n const start = process.hrtime.bigint();\n try {\n return await exec(sql, params);\n } finally {\n const durationMs = Number(process.hrtime.bigint() - start) / 1e6;\n if (durationMs >= thresholdMs) {\n logger.log(level, \"slow query\", {\n sql,\n durationMs: Math.round(durationMs * 1000) / 1000,\n ...(logParameters ? { params } : {}),\n });\n }\n }\n };\n };\n\n const wrapped: AsyncDriver = {\n execute: timed(driver.execute.bind(driver)),\n close: () => driver.close(),\n };\n if (driver.iterate) {\n wrapped.iterate = (sql, params) => driver.iterate?.(sql, params) as never;\n }\n if (driver.reserve) {\n wrapped.reserve = async () => {\n const reserved = await driver.reserve?.();\n if (!reserved) throw new Error(\"driver.reserve() returned nothing\");\n return {\n execute: timed(reserved.execute.bind(reserved)),\n close: () => reserved.close(),\n release: () => reserved.release(),\n ...(reserved.iterate\n ? { iterate: (sql, params) => reserved.iterate?.(sql, params) as never }\n : {}),\n };\n };\n }\n return wrapped;\n}\n","/**\n * Database backup helper, mirroring `db.backup`.\n *\n * `backupDatabase` detects the dialect from the URL and produces a backup file:\n * a `pg_dump` for PostgreSQL, a file copy for SQLite. It shells out to `pg_dump`\n * for Postgres (must be on `PATH`), so the heavy lifting stays with the battle-\n * tested tool rather than a hand-rolled dump.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { copyFile } from \"node:fs/promises\";\nimport { detectDialect } from \"tempest-db-js\";\n\n/** Options for {@link backupDatabase}. */\nexport interface BackupOptions {\n /** Path to the `pg_dump` binary. Default `\"pg_dump\"` (resolved on `PATH`). */\n pgDumpPath?: string;\n /** Extra `pg_dump` arguments (e.g. `[\"--no-owner\", \"-Fc\"]`). */\n pgDumpArgs?: string[];\n}\n\n/** Resolve the on-disk file path from a `sqlite://` URL. */\nfunction sqlitePath(url: string): string {\n // sqlite://./app.db, sqlite:///abs/app.db, sqlite://:memory:\n const withoutScheme = url.replace(/^sqlite:\\/\\//, \"\");\n if (withoutScheme === \":memory:\" || withoutScheme === \"\") {\n throw new Error(\"Cannot back up an in-memory SQLite database\");\n }\n // sqlite:///abs → \"/abs\"; sqlite://./rel → \"./rel\"\n return withoutScheme.startsWith(\"/\")\n ? withoutScheme\n : withoutScheme.replace(/^\\.?\\//, \"./\");\n}\n\n/**\n * Back up a database to `destPath`.\n *\n * @param databaseUrl - The connection URL (SQLite or PostgreSQL).\n * @param destPath - Where to write the backup.\n * @param options - `pg_dump` binary path and extra args (Postgres only).\n * @returns The `destPath` on success.\n * @throws {Error} For in-memory SQLite, an unsupported dialect, or a non-zero\n * `pg_dump` exit.\n */\nexport async function backupDatabase(\n databaseUrl: string,\n destPath: string,\n options: BackupOptions = {},\n): Promise<string> {\n const dialect = detectDialect(databaseUrl);\n\n if (dialect === \"sqlite\") {\n await copyFile(sqlitePath(databaseUrl), destPath);\n return destPath;\n }\n\n if (dialect === \"postgresql\") {\n const bin = options.pgDumpPath ?? \"pg_dump\";\n const args = [...(options.pgDumpArgs ?? []), \"-f\", destPath, databaseUrl];\n await runPgDump(bin, args);\n return destPath;\n }\n\n throw new Error(`backupDatabase does not support the '${dialect}' dialect`);\n}\n\nfunction runPgDump(bin: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(bin, args, { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`pg_dump exited with code ${code}: ${stderr.trim()}`));\n });\n });\n}\n","/**\n * Generic async service over a `tempest-db-js` repository.\n *\n * Mirrors `services.base.BaseService`: a thin business-logic layer wrapping a\n * `BaseRepository`. Unlike a pure pass-through, every read method maps the raw\n * ORM row through {@link ResponseMapper} into the response shape routers and\n * controllers consume — that mapping is the layer's reason to exist. Override\n * methods that need orchestration (multi-repository writes, side effects,\n * domain rules); leave the rest.\n */\n\nimport type {\n BaseRepository,\n InferInsert,\n InferModel,\n ModelClass,\n PaginationResult,\n RepositoryPaginationFilter,\n WhereInput,\n} from \"@/db\";\n\n/** Maps a raw ORM row to the response shape (sync or async). */\nexport type ResponseMapper<C extends ModelClass, Resp> = (\n row: InferModel<C>,\n) => Resp | Promise<Resp>;\n\nexport class BaseService<C extends ModelClass, Resp> {\n /**\n * @param repository - The repository to delegate persistence to.\n * @param mapToResponse - Maps a raw row to the response shape.\n */\n constructor(\n protected readonly repository: BaseRepository<C>,\n protected readonly mapToResponse: ResponseMapper<C, Resp>,\n ) {}\n\n /** Map a batch of rows to responses, preserving order. */\n protected mapMany(rows: InferModel<C>[]): Promise<Resp[]> {\n return Promise.all(rows.map((row) => this.mapToResponse(row)));\n }\n\n /**\n * Fetch a single record by primary key and map it.\n *\n * @param id - The primary-key value.\n * @returns The mapped response.\n * @throws {RecordNotFound} When no row matches (404 convention).\n */\n async getById(id: unknown): Promise<Resp> {\n return this.mapToResponse(await this.repository.getById(id));\n }\n\n /**\n * List records matching `filters` (or all), mapped to responses.\n *\n * @param filters - Optional filter conditions.\n * @returns The mapped responses; `[]` when nothing matches.\n */\n async list(filters?: WhereInput<InferModel<C>>): Promise<Resp[]> {\n return this.mapMany(await this.repository.list(filters));\n }\n\n /**\n * Count records matching `filters` (or the whole table).\n *\n * @param filters - Optional filter conditions.\n * @returns The matching row count.\n */\n async count(filters?: WhereInput<InferModel<C>>): Promise<number> {\n return this.repository.count(filters);\n }\n\n /**\n * Insert one record and map the created row.\n *\n * @param data - The insert payload.\n * @returns The mapped, created response.\n */\n async create(data: InferInsert<C>): Promise<Resp> {\n return this.mapToResponse(await this.repository.create(data));\n }\n\n /**\n * Update records matching `filters`.\n *\n * @param filters - Which rows to update.\n * @param set - The partial column values to write.\n * @returns The number of rows affected.\n */\n async update(\n filters: WhereInput<InferModel<C>>,\n set: Partial<InferModel<C>>,\n ): Promise<number> {\n return this.repository.update(filters, set);\n }\n\n /**\n * Delete records matching `filters`.\n *\n * @param filters - Which rows to delete.\n * @returns The number of rows affected.\n */\n async delete(filters: WhereInput<InferModel<C>>): Promise<number> {\n return this.repository.delete(filters);\n }\n\n /**\n * Fetch a page of records with the items mapped to responses.\n *\n * @param filter - Page, size, ordering and filters.\n * @returns The page envelope with mapped items.\n */\n async paginate(\n filter: RepositoryPaginationFilter<InferModel<C>> = {},\n ): Promise<PaginationResult<Resp>> {\n const page = await this.repository.paginate(filter);\n return { ...page, items: await this.mapMany(page.items) };\n }\n}\n","/**\n * Generic controller bridging routers and services.\n *\n * Mirrors `controllers.base.BaseController`. Per the SDK layering\n * (router → controller → service → repository), controllers are an intentional\n * abstraction boundary kept present even when no orchestration is required, so\n * the import graph stays uniform across services. Override a method when one\n * endpoint must call several services or apply cross-cutting policy; otherwise\n * the thin delegations stand in for the boundary.\n */\n\nimport type {\n InferInsert,\n InferModel,\n ModelClass,\n PaginationResult,\n RepositoryPaginationFilter,\n WhereInput,\n} from \"@/db\";\nimport type { BaseService } from \"@/services/base\";\n\nexport class BaseController<C extends ModelClass, Resp> {\n /**\n * @param service - The service the controller delegates to.\n */\n constructor(protected readonly service: BaseService<C, Resp>) {}\n\n /**\n * Fetch one record by primary key.\n *\n * @param id - The primary-key value.\n * @returns The mapped response.\n */\n getById(id: unknown): Promise<Resp> {\n return this.service.getById(id);\n }\n\n /**\n * List records matching `filters`.\n *\n * @param filters - Optional filter conditions.\n * @returns The mapped responses.\n */\n list(filters?: WhereInput<InferModel<C>>): Promise<Resp[]> {\n return this.service.list(filters);\n }\n\n /**\n * Count records matching `filters`.\n *\n * @param filters - Optional filter conditions.\n * @returns The matching row count.\n */\n count(filters?: WhereInput<InferModel<C>>): Promise<number> {\n return this.service.count(filters);\n }\n\n /**\n * Create a record.\n *\n * @param data - The insert payload.\n * @returns The mapped, created response.\n */\n create(data: InferInsert<C>): Promise<Resp> {\n return this.service.create(data);\n }\n\n /**\n * Update records matching `filters`.\n *\n * @param filters - Which rows to update.\n * @param set - The partial column values to write.\n * @returns The number of rows affected.\n */\n update(\n filters: WhereInput<InferModel<C>>,\n set: Partial<InferModel<C>>,\n ): Promise<number> {\n return this.service.update(filters, set);\n }\n\n /**\n * Delete records matching `filters`.\n *\n * @param filters - Which rows to delete.\n * @returns The number of rows affected.\n */\n delete(filters: WhereInput<InferModel<C>>): Promise<number> {\n return this.service.delete(filters);\n }\n\n /**\n * Fetch a page of records.\n *\n * @param filter - Page, size, ordering and filters.\n * @returns The page envelope with mapped items.\n */\n paginate(\n filter: RepositoryPaginationFilter<InferModel<C>> = {},\n ): Promise<PaginationResult<Resp>> {\n return this.service.paginate(filter);\n }\n}\n","/**\n * Brazilian identity/contact helpers, mirroring `utils.regex`.\n *\n * Patterns, validators (format + check digits), normalizers, and ready-to-use\n * Zod field schemas for the fields that show up in almost every BR API: CPF,\n * CNPJ, CEP and phone. Validators accept masked or unmasked input; normalizers\n * strip masks to a canonical digits-only form (and throw on invalid input).\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** Match a CPF in masked (`000.000.000-00`) or raw form. */\nexport const CPF_PATTERN = /^\\d{3}\\.?\\d{3}\\.?\\d{3}-?\\d{2}$/;\n/** Match a CNPJ in masked (`00.000.000/0000-00`) or raw form. */\nexport const CNPJ_PATTERN = /^\\d{2}\\.?\\d{3}\\.?\\d{3}\\/?\\d{4}-?\\d{2}$/;\n/** Match a BR phone with optional `+55`, DDD, mask or 9th digit. */\nexport const PHONE_BR_PATTERN = /^(?:\\+?55\\s?)?(?:\\(?\\d{2}\\)?\\s?)?9?\\d{4}[-\\s]?\\d{4}$/;\n/** Match a CEP in masked (`00000-000`) or raw form. */\nexport const CEP_PATTERN = /^\\d{5}-?\\d{3}$/;\n\n/**\n * Strip every non-digit character from `value`.\n *\n * @param value - The raw input (masked CPF, phone, etc.).\n * @returns A string of only the digits in `value`.\n */\nexport function onlyDigits(value: string): string {\n return value.replace(/\\D/g, \"\");\n}\n\n/** Validate the two CPF check digits over an 11-digit string. */\nfunction cpfCheckDigits(digits: string): boolean {\n if (digits.length !== 11 || new Set(digits).size === 1) return false;\n for (const size of [9, 10]) {\n let total = 0;\n for (let i = 0; i < size; i++) total += Number(digits[i]) * (size + 1 - i);\n let check = (total * 10) % 11;\n if (check === 10) check = 0;\n if (check !== Number(digits[size])) return false;\n }\n return true;\n}\n\n/** Validate the two CNPJ check digits over a 14-digit string. */\nfunction cnpjCheckDigits(digits: string): boolean {\n if (digits.length !== 14 || new Set(digits).size === 1) return false;\n const first = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n const second = [6, ...first];\n for (const [size, weights] of [\n [12, first],\n [13, second],\n ] as const) {\n let total = 0;\n for (let i = 0; i < size; i++) total += Number(digits[i]) * (weights[i] ?? 0);\n const rest = total % 11;\n const check = rest < 2 ? 0 : 11 - rest;\n if (check !== Number(digits[size])) return false;\n }\n return true;\n}\n\n/** Whether `value` is a syntactically valid CPF (format + check digits). */\nexport function isValidCpf(value: string): boolean {\n return CPF_PATTERN.test(value) && cpfCheckDigits(onlyDigits(value));\n}\n\n/** Whether `value` is a syntactically valid CNPJ (format + check digits). */\nexport function isValidCnpj(value: string): boolean {\n return CNPJ_PATTERN.test(value) && cnpjCheckDigits(onlyDigits(value));\n}\n\n/** Whether `value` is a valid CPF or CNPJ. */\nexport function isValidCpfCnpj(value: string): boolean {\n const digits = onlyDigits(value);\n if (digits.length === 11) return isValidCpf(value);\n if (digits.length === 14) return isValidCnpj(value);\n return false;\n}\n\n/** Whether `value` looks like a CEP (eight-digit shape; no check digits). */\nexport function isValidCep(value: string): boolean {\n return CEP_PATTERN.test(value);\n}\n\n/** Whether `value` looks like a BR phone (10 or 11 digits, optional `+55`). */\nexport function isValidPhoneBr(value: string): boolean {\n if (!PHONE_BR_PATTERN.test(value)) return false;\n let digits = onlyDigits(value);\n if (digits.startsWith(\"55\") && (digits.length === 12 || digits.length === 13)) {\n digits = digits.slice(2);\n }\n return digits.length === 10 || digits.length === 11;\n}\n\n/** Normalize a CPF to 11 digits, throwing when invalid. */\nexport function normalizeCpf(value: string): string {\n if (!isValidCpf(value)) throw new Error(\"invalid CPF\");\n return onlyDigits(value);\n}\n\n/** Normalize a CNPJ to 14 digits, throwing when invalid. */\nexport function normalizeCnpj(value: string): string {\n if (!isValidCnpj(value)) throw new Error(\"invalid CNPJ\");\n return onlyDigits(value);\n}\n\n/** Normalize a CPF/CNPJ to digits only, throwing when invalid. */\nexport function normalizeCpfCnpj(value: string): string {\n if (!isValidCpfCnpj(value)) throw new Error(\"invalid CPF/CNPJ\");\n return onlyDigits(value);\n}\n\n/** Normalize a CEP to 8 digits, throwing when invalid. */\nexport function normalizeCep(value: string): string {\n if (!isValidCep(value)) throw new Error(\"invalid CEP\");\n return onlyDigits(value);\n}\n\n/** Normalize a BR phone to digits only, throwing when invalid. */\nexport function normalizePhoneBr(value: string): string {\n if (!isValidPhoneBr(value)) throw new Error(\"invalid BR phone\");\n return onlyDigits(value);\n}\n\n/** Zod field: validates a CPF and normalizes it to 11 digits. */\nexport const cpfField = z\n .string()\n .refine(isValidCpf, { message: \"invalid CPF\" })\n .transform(onlyDigits);\n/** Zod field: validates a CNPJ and normalizes it to 14 digits. */\nexport const cnpjField = z\n .string()\n .refine(isValidCnpj, { message: \"invalid CNPJ\" })\n .transform(onlyDigits);\n/** Zod field: accepts either a CPF or a CNPJ, normalized to digits. */\nexport const cpfOrCnpjField = z\n .string()\n .refine(isValidCpfCnpj, { message: \"invalid CPF/CNPJ\" })\n .transform(onlyDigits);\n/** Zod field: validates a CEP and normalizes it to 8 digits. */\nexport const cepField = z\n .string()\n .refine(isValidCep, { message: \"invalid CEP\" })\n .transform(onlyDigits);\n/** Zod field: validates a BR phone and normalizes it to digits. */\nexport const phoneBrField = z\n .string()\n .refine(isValidPhoneBr, { message: \"invalid BR phone\" })\n .transform(onlyDigits);\n","[\n {\n \"uf\": \"AC\",\n \"name\": \"Acre\",\n \"cities\": [\n \"Acrelândia\",\n \"Assis Brasil\",\n \"Brasiléia\",\n \"Bujari\",\n \"Capixaba\",\n \"Cruzeiro do Sul\",\n \"Epitaciolândia\",\n \"Feijó\",\n \"Jordão\",\n \"Mâncio Lima\",\n \"Manoel Urbano\",\n \"Marechal Thaumaturgo\",\n \"Plácido de Castro\",\n \"Porto Acre\",\n \"Porto Walter\",\n \"Rio Branco\",\n \"Rodrigues Alves\",\n \"Santa Rosa do Purus\",\n \"Sena Madureira\",\n \"Senador Guiomard\",\n \"Tarauacá\",\n \"Xapuri\"\n ]\n },\n {\n \"uf\": \"AL\",\n \"name\": \"Alagoas\",\n \"cities\": [\n \"Água Branca\",\n \"Anadia\",\n \"Arapiraca\",\n \"Atalaia\",\n \"Barra de Santo Antônio\",\n \"Barra de São Miguel\",\n \"Batalha\",\n \"Belém\",\n \"Belo Monte\",\n \"Boca da Mata\",\n \"Branquinha\",\n \"Cacimbinhas\",\n \"Cajueiro\",\n \"Campestre\",\n \"Campo Alegre\",\n \"Campo Grande\",\n \"Canapi\",\n \"Capela\",\n \"Carneiros\",\n \"Chã Preta\",\n \"Coité do Nóia\",\n \"Colônia Leopoldina\",\n \"Coqueiro Seco\",\n \"Coruripe\",\n \"Craíbas\",\n \"Delmiro Gouveia\",\n \"Dois Riachos\",\n \"Estrela de Alagoas\",\n \"Feira Grande\",\n \"Feliz Deserto\",\n \"Flexeiras\",\n \"Girau do Ponciano\",\n \"Ibateguara\",\n \"Igaci\",\n \"Igreja Nova\",\n \"Inhapi\",\n \"Jacaré dos Homens\",\n \"Jacuípe\",\n \"Japaratinga\",\n \"Jaramataia\",\n \"Jequiá da Praia\",\n \"Joaquim Gomes\",\n \"Jundiá\",\n \"Junqueiro\",\n \"Lagoa da Canoa\",\n \"Limoeiro de Anadia\",\n \"Maceió\",\n \"Major Isidoro\",\n \"Mar Vermelho\",\n \"Maragogi\",\n \"Maravilha\",\n \"Marechal Deodoro\",\n \"Maribondo\",\n \"Mata Grande\",\n \"Matriz de Camaragibe\",\n \"Messias\",\n \"Minador do Negrão\",\n \"Monteirópolis\",\n \"Murici\",\n \"Novo Lino\",\n \"Olho d'Água das Flores\",\n \"Olho d'Água do Casado\",\n \"Olho d'Água Grande\",\n \"Olivença\",\n \"Ouro Branco\",\n \"Palestina\",\n \"Palmeira dos Índios\",\n \"Pão de Açúcar\",\n \"Pariconha\",\n \"Paripueira\",\n \"Passo de Camaragibe\",\n \"Paulo Jacinto\",\n \"Penedo\",\n \"Piaçabuçu\",\n \"Pilar\",\n \"Pindoba\",\n \"Piranhas\",\n \"Poço das Trincheiras\",\n \"Porto Calvo\",\n \"Porto de Pedras\",\n \"Porto Real do Colégio\",\n \"Quebrangulo\",\n \"Rio Largo\",\n \"Roteiro\",\n \"Santa Luzia do Norte\",\n \"Santana do Ipanema\",\n \"Santana do Mundaú\",\n \"São Brás\",\n \"São José da Laje\",\n \"São José da Tapera\",\n \"São Luís do Quitunde\",\n \"São Miguel dos Campos\",\n \"São Miguel dos Milagres\",\n \"São Sebastião\",\n \"Satuba\",\n \"Senador Rui Palmeira\",\n \"Tanque d'Arca\",\n \"Taquarana\",\n \"Teotônio Vilela\",\n \"Traipu\",\n \"União dos Palmares\",\n \"Viçosa\"\n ]\n },\n {\n \"uf\": \"AM\",\n \"name\": \"Amazonas\",\n \"cities\": [\n \"Alvarães\",\n \"Amaturá\",\n \"Anamã\",\n \"Anori\",\n \"Apuí\",\n \"Atalaia do Norte\",\n \"Autazes\",\n \"Barcelos\",\n \"Barreirinha\",\n \"Benjamin Constant\",\n \"Beruri\",\n \"Boa Vista do Ramos\",\n \"Boca do Acre\",\n \"Borba\",\n \"Caapiranga\",\n \"Canutama\",\n \"Carauari\",\n \"Careiro\",\n \"Careiro da Várzea\",\n \"Coari\",\n \"Codajás\",\n \"Eirunepé\",\n \"Envira\",\n \"Fonte Boa\",\n \"Guajará\",\n \"Humaitá\",\n \"Ipixuna\",\n \"Iranduba\",\n \"Itacoatiara\",\n \"Itamarati\",\n \"Itapiranga\",\n \"Japurá\",\n \"Juruá\",\n \"Jutaí\",\n \"Lábrea\",\n \"Manacapuru\",\n \"Manaquiri\",\n \"Manaus\",\n \"Manicoré\",\n \"Maraã\",\n \"Maués\",\n \"Nhamundá\",\n \"Nova Olinda do Norte\",\n \"Novo Airão\",\n \"Novo Aripuanã\",\n \"Parintins\",\n \"Pauini\",\n \"Presidente Figueiredo\",\n \"Rio Preto da Eva\",\n \"Santa Isabel do Rio Negro\",\n \"Santo Antônio do Içá\",\n \"São Gabriel da Cachoeira\",\n \"São Paulo de Olivença\",\n \"São Sebastião do Uatumã\",\n \"Silves\",\n \"Tabatinga\",\n \"Tapauá\",\n \"Tefé\",\n \"Tonantins\",\n \"Uarini\",\n \"Urucará\",\n \"Urucurituba\"\n ]\n },\n {\n \"uf\": \"AP\",\n \"name\": \"Amapá\",\n \"cities\": [\n \"Amapá\",\n \"Calçoene\",\n \"Cutias\",\n \"Ferreira Gomes\",\n \"Itaubal\",\n \"Laranjal do Jari\",\n \"Macapá\",\n \"Mazagão\",\n \"Oiapoque\",\n \"Pedra Branca do Amapari\",\n \"Porto Grande\",\n \"Pracuúba\",\n \"Santana\",\n \"Serra do Navio\",\n \"Tartarugalzinho\",\n \"Vitória do Jari\"\n ]\n },\n {\n \"uf\": \"BA\",\n \"name\": \"Bahia\",\n \"cities\": [\n \"Abaíra\",\n \"Abaré\",\n \"Acajutiba\",\n \"Adustina\",\n \"Água Fria\",\n \"Aiquara\",\n \"Alagoinhas\",\n \"Alcobaça\",\n \"Almadina\",\n \"Amargosa\",\n \"Amélia Rodrigues\",\n \"América Dourada\",\n \"Anagé\",\n \"Andaraí\",\n \"Andorinha\",\n \"Angical\",\n \"Anguera\",\n \"Antas\",\n \"Antônio Cardoso\",\n \"Antônio Gonçalves\",\n \"Aporá\",\n \"Apuarema\",\n \"Araçás\",\n \"Aracatu\",\n \"Araci\",\n \"Aramari\",\n \"Arataca\",\n \"Aratuípe\",\n \"Aurelino Leal\",\n \"Baianópolis\",\n \"Baixa Grande\",\n \"Banzaê\",\n \"Barra\",\n \"Barra da Estiva\",\n \"Barra do Choça\",\n \"Barra do Mendes\",\n \"Barra do Rocha\",\n \"Barreiras\",\n \"Barro Alto\",\n \"Barro Preto\",\n \"Barrocas\",\n \"Belmonte\",\n \"Belo Campo\",\n \"Biritinga\",\n \"Boa Nova\",\n \"Boa Vista do Tupim\",\n \"Bom Jesus da Lapa\",\n \"Bom Jesus da Serra\",\n \"Boninal\",\n \"Bonito\",\n \"Boquira\",\n \"Botuporã\",\n \"Brejões\",\n \"Brejolândia\",\n \"Brotas de Macaúbas\",\n \"Brumado\",\n \"Buerarema\",\n \"Buritirama\",\n \"Caatiba\",\n \"Cabaceiras do Paraguaçu\",\n \"Cachoeira\",\n \"Caculé\",\n \"Caém\",\n \"Caetanos\",\n \"Caetité\",\n \"Cafarnaum\",\n \"Cairu\",\n \"Caldeirão Grande\",\n \"Camacan\",\n \"Camaçari\",\n \"Camamu\",\n \"Campo Alegre de Lourdes\",\n \"Campo Formoso\",\n \"Canápolis\",\n \"Canarana\",\n \"Canavieiras\",\n \"Candeal\",\n \"Candeias\",\n \"Candiba\",\n \"Cândido Sales\",\n \"Cansanção\",\n \"Canudos\",\n \"Capela do Alto Alegre\",\n \"Capim Grosso\",\n \"Caraíbas\",\n \"Caravelas\",\n \"Cardeal da Silva\",\n \"Carinhanha\",\n \"Casa Nova\",\n \"Castro Alves\",\n \"Catolândia\",\n \"Catu\",\n \"Caturama\",\n \"Central\",\n \"Chorrochó\",\n \"Cícero Dantas\",\n \"Cipó\",\n \"Coaraci\",\n \"Cocos\",\n \"Conceição da Feira\",\n \"Conceição do Almeida\",\n \"Conceição do Coité\",\n \"Conceição do Jacuípe\",\n \"Conde\",\n \"Condeúba\",\n \"Contendas do Sincorá\",\n \"Coração de Maria\",\n \"Cordeiros\",\n \"Coribe\",\n \"Coronel João Sá\",\n \"Correntina\",\n \"Cotegipe\",\n \"Cravolândia\",\n \"Crisópolis\",\n \"Cristópolis\",\n \"Cruz das Almas\",\n \"Curaçá\",\n \"Dário Meira\",\n \"Dias d'Ávila\",\n \"Dom Basílio\",\n \"Dom Macedo Costa\",\n \"Elísio Medrado\",\n \"Encruzilhada\",\n \"Entre Rios\",\n \"Érico Cardoso\",\n \"Esplanada\",\n \"Euclides da Cunha\",\n \"Eunápolis\",\n \"Fátima\",\n \"Feira da Mata\",\n \"Feira de Santana\",\n \"Filadélfia\",\n \"Firmino Alves\",\n \"Floresta Azul\",\n \"Formosa do Rio Preto\",\n \"Gandu\",\n \"Gavião\",\n \"Gentio do Ouro\",\n \"Glória\",\n \"Gongogi\",\n \"Governador Mangabeira\",\n \"Guajeru\",\n \"Guanambi\",\n \"Guaratinga\",\n \"Heliópolis\",\n \"Iaçu\",\n \"Ibiassucê\",\n \"Ibicaraí\",\n \"Ibicoara\",\n \"Ibicuí\",\n \"Ibipeba\",\n \"Ibipitanga\",\n \"Ibiquera\",\n \"Ibirapitanga\",\n \"Ibirapuã\",\n \"Ibirataia\",\n \"Ibitiara\",\n \"Ibititá\",\n \"Ibotirama\",\n \"Ichu\",\n \"Igaporã\",\n \"Igrapiúna\",\n \"Iguaí\",\n \"Ilhéus\",\n \"Inhambupe\",\n \"Ipecaetá\",\n \"Ipiaú\",\n \"Ipirá\",\n \"Ipupiara\",\n \"Irajuba\",\n \"Iramaia\",\n \"Iraquara\",\n \"Irará\",\n \"Irecê\",\n \"Itabela\",\n \"Itaberaba\",\n \"Itabuna\",\n \"Itacaré\",\n \"Itaeté\",\n \"Itagi\",\n \"Itagibá\",\n \"Itagimirim\",\n \"Itaguaçu da Bahia\",\n \"Itaju do Colônia\",\n \"Itajuípe\",\n \"Itamaraju\",\n \"Itamari\",\n \"Itambé\",\n \"Itanagra\",\n \"Itanhém\",\n \"Itaparica\",\n \"Itapé\",\n \"Itapebi\",\n \"Itapetinga\",\n \"Itapicuru\",\n \"Itapitanga\",\n \"Itaquara\",\n \"Itarantim\",\n \"Itatim\",\n \"Itiruçu\",\n \"Itiúba\",\n \"Itororó\",\n \"Ituaçu\",\n \"Ituberá\",\n \"Iuiu\",\n \"Jaborandi\",\n \"Jacaraci\",\n \"Jacobina\",\n \"Jaguaquara\",\n \"Jaguarari\",\n \"Jaguaripe\",\n \"Jandaíra\",\n \"Jequié\",\n \"Jeremoabo\",\n \"Jiquiriçá\",\n \"Jitaúna\",\n \"João Dourado\",\n \"Juazeiro\",\n \"Jucuruçu\",\n \"Jussara\",\n \"Jussari\",\n \"Jussiape\",\n \"Lafaiete Coutinho\",\n \"Lagoa Real\",\n \"Laje\",\n \"Lajedão\",\n \"Lajedinho\",\n \"Lajedo do Tabocal\",\n \"Lamarão\",\n \"Lapão\",\n \"Lauro de Freitas\",\n \"Lençóis\",\n \"Licínio de Almeida\",\n \"Livramento de Nossa Senhora\",\n \"Luís Eduardo Magalhães\",\n \"Macajuba\",\n \"Macarani\",\n \"Macaúbas\",\n \"Macururé\",\n \"Madre de Deus\",\n \"Maetinga\",\n \"Maiquinique\",\n \"Mairi\",\n \"Malhada\",\n \"Malhada de Pedras\",\n \"Manoel Vitorino\",\n \"Mansidão\",\n \"Maracás\",\n \"Maragogipe\",\n \"Maraú\",\n \"Marcionílio Souza\",\n \"Mascote\",\n \"Mata de São João\",\n \"Matina\",\n \"Medeiros Neto\",\n \"Miguel Calmon\",\n \"Milagres\",\n \"Mirangaba\",\n \"Mirante\",\n \"Monte Santo\",\n \"Morpará\",\n \"Morro do Chapéu\",\n \"Mortugaba\",\n \"Mucugê\",\n \"Mucuri\",\n \"Mulungu do Morro\",\n \"Mundo Novo\",\n \"Muniz Ferreira\",\n \"Muquém do São Francisco\",\n \"Muritiba\",\n \"Mutuípe\",\n \"Nazaré\",\n \"Nilo Peçanha\",\n \"Nordestina\",\n \"Nova Canaã\",\n \"Nova Fátima\",\n \"Nova Ibiá\",\n \"Nova Itarana\",\n \"Nova Redenção\",\n \"Nova Soure\",\n \"Nova Viçosa\",\n \"Novo Horizonte\",\n \"Novo Triunfo\",\n \"Olindina\",\n \"Oliveira dos Brejinhos\",\n \"Ouriçangas\",\n \"Ourolândia\",\n \"Palmas de Monte Alto\",\n \"Palmeiras\",\n \"Paramirim\",\n \"Paratinga\",\n \"Paripiranga\",\n \"Pau Brasil\",\n \"Paulo Afonso\",\n \"Pé de Serra\",\n \"Pedrão\",\n \"Pedro Alexandre\",\n \"Piatã\",\n \"Pilão Arcado\",\n \"Pindaí\",\n \"Pindobaçu\",\n \"Pintadas\",\n \"Piraí do Norte\",\n \"Piripá\",\n \"Piritiba\",\n \"Planaltino\",\n \"Planalto\",\n \"Poções\",\n \"Pojuca\",\n \"Ponto Novo\",\n \"Porto Seguro\",\n \"Potiraguá\",\n \"Prado\",\n \"Presidente Dutra\",\n \"Presidente Jânio Quadros\",\n \"Presidente Tancredo Neves\",\n \"Queimadas\",\n \"Quijingue\",\n \"Quixabeira\",\n \"Rafael Jambeiro\",\n \"Remanso\",\n \"Retirolândia\",\n \"Riachão das Neves\",\n \"Riachão do Jacuípe\",\n \"Riacho de Santana\",\n \"Ribeira do Amparo\",\n \"Ribeira do Pombal\",\n \"Ribeirão do Largo\",\n \"Rio de Contas\",\n \"Rio do Antônio\",\n \"Rio do Pires\",\n \"Rio Real\",\n \"Rodelas\",\n \"Ruy Barbosa\",\n \"Salinas da Margarida\",\n \"Salvador\",\n \"Santa Bárbara\",\n \"Santa Brígida\",\n \"Santa Cruz Cabrália\",\n \"Santa Cruz da Vitória\",\n \"Santa Inês\",\n \"Santa Luzia\",\n \"Santa Maria da Vitória\",\n \"Santa Rita de Cássia\",\n \"Santa Terezinha\",\n \"Santaluz\",\n \"Santana\",\n \"Santanópolis\",\n \"Santo Amaro\",\n \"Santo Antônio de Jesus\",\n \"Santo Estêvão\",\n \"São Desidério\",\n \"São Domingos\",\n \"São Felipe\",\n \"São Félix\",\n \"São Félix do Coribe\",\n \"São Francisco do Conde\",\n \"São Gabriel\",\n \"São Gonçalo dos Campos\",\n \"São José da Vitória\",\n \"São José do Jacuípe\",\n \"São Miguel das Matas\",\n \"São Sebastião do Passé\",\n \"Sapeaçu\",\n \"Sátiro Dias\",\n \"Saubara\",\n \"Saúde\",\n \"Seabra\",\n \"Sebastião Laranjeiras\",\n \"Senhor do Bonfim\",\n \"Sento Sé\",\n \"Serra do Ramalho\",\n \"Serra Dourada\",\n \"Serra Preta\",\n \"Serrinha\",\n \"Serrolândia\",\n \"Simões Filho\",\n \"Sítio do Mato\",\n \"Sítio do Quinto\",\n \"Sobradinho\",\n \"Souto Soares\",\n \"Tabocas do Brejo Velho\",\n \"Tanhaçu\",\n \"Tanque Novo\",\n \"Tanquinho\",\n \"Taperoá\",\n \"Tapiramutá\",\n \"Teixeira de Freitas\",\n \"Teodoro Sampaio\",\n \"Teofilândia\",\n \"Teolândia\",\n \"Terra Nova\",\n \"Tremedal\",\n \"Tucano\",\n \"Uauá\",\n \"Ubaíra\",\n \"Ubaitaba\",\n \"Ubatã\",\n \"Uibaí\",\n \"Umburanas\",\n \"Una\",\n \"Urandi\",\n \"Uruçuca\",\n \"Utinga\",\n \"Valença\",\n \"Valente\",\n \"Várzea da Roça\",\n \"Várzea do Poço\",\n \"Várzea Nova\",\n \"Varzedo\",\n \"Vera Cruz\",\n \"Vereda\",\n \"Vitória da Conquista\",\n \"Wagner\",\n \"Wanderley\",\n \"Wenceslau Guimarães\",\n \"Xique-Xique\"\n ]\n },\n {\n \"uf\": \"CE\",\n \"name\": \"Ceará\",\n \"cities\": [\n \"Abaiara\",\n \"Acarape\",\n \"Acaraú\",\n \"Acopiara\",\n \"Aiuaba\",\n \"Alcântaras\",\n \"Altaneira\",\n \"Alto Santo\",\n \"Amontada\",\n \"Antonina do Norte\",\n \"Apuiarés\",\n \"Aquiraz\",\n \"Aracati\",\n \"Aracoiaba\",\n \"Ararendá\",\n \"Araripe\",\n \"Aratuba\",\n \"Arneiroz\",\n \"Assaré\",\n \"Aurora\",\n \"Baixio\",\n \"Banabuiú\",\n \"Barbalha\",\n \"Barreira\",\n \"Barro\",\n \"Barroquinha\",\n \"Baturité\",\n \"Beberibe\",\n \"Bela Cruz\",\n \"Boa Viagem\",\n \"Brejo Santo\",\n \"Camocim\",\n \"Campos Sales\",\n \"Canindé\",\n \"Capistrano\",\n \"Caridade\",\n \"Cariré\",\n \"Caririaçu\",\n \"Cariús\",\n \"Carnaubal\",\n \"Cascavel\",\n \"Catarina\",\n \"Catunda\",\n \"Caucaia\",\n \"Cedro\",\n \"Chaval\",\n \"Choró\",\n \"Chorozinho\",\n \"Coreaú\",\n \"Crateús\",\n \"Crato\",\n \"Croatá\",\n \"Cruz\",\n \"Deputado Irapuan Pinheiro\",\n \"Ereré\",\n \"Eusébio\",\n \"Farias Brito\",\n \"Forquilha\",\n \"Fortaleza\",\n \"Fortim\",\n \"Frecheirinha\",\n \"General Sampaio\",\n \"Graça\",\n \"Granja\",\n \"Granjeiro\",\n \"Groaíras\",\n \"Guaiúba\",\n \"Guaraciaba do Norte\",\n \"Guaramiranga\",\n \"Hidrolândia\",\n \"Horizonte\",\n \"Ibaretama\",\n \"Ibiapina\",\n \"Ibicuitinga\",\n \"Icapuí\",\n \"Icó\",\n \"Iguatu\",\n \"Independência\",\n \"Ipaporanga\",\n \"Ipaumirim\",\n \"Ipu\",\n \"Ipueiras\",\n \"Iracema\",\n \"Irauçuba\",\n \"Itaiçaba\",\n \"Itaitinga\",\n \"Itapajé\",\n \"Itapipoca\",\n \"Itapiúna\",\n \"Itarema\",\n \"Itatira\",\n \"Jaguaretama\",\n \"Jaguaribara\",\n \"Jaguaribe\",\n \"Jaguaruana\",\n \"Jardim\",\n \"Jati\",\n \"Jijoca de Jericoacoara\",\n \"Juazeiro do Norte\",\n \"Jucás\",\n \"Lavras da Mangabeira\",\n \"Limoeiro do Norte\",\n \"Madalena\",\n \"Maracanaú\",\n \"Maranguape\",\n \"Marco\",\n \"Martinópole\",\n \"Massapê\",\n \"Mauriti\",\n \"Meruoca\",\n \"Milagres\",\n \"Milhã\",\n \"Miraíma\",\n \"Missão Velha\",\n \"Mombaça\",\n \"Monsenhor Tabosa\",\n \"Morada Nova\",\n \"Moraújo\",\n \"Morrinhos\",\n \"Mucambo\",\n \"Mulungu\",\n \"Nova Olinda\",\n \"Nova Russas\",\n \"Novo Oriente\",\n \"Ocara\",\n \"Orós\",\n \"Pacajus\",\n \"Pacatuba\",\n \"Pacoti\",\n \"Pacujá\",\n \"Palhano\",\n \"Palmácia\",\n \"Paracuru\",\n \"Paraipaba\",\n \"Parambu\",\n \"Paramoti\",\n \"Pedra Branca\",\n \"Penaforte\",\n \"Pentecoste\",\n \"Pereiro\",\n \"Pindoretama\",\n \"Piquet Carneiro\",\n \"Pires Ferreira\",\n \"Poranga\",\n \"Porteiras\",\n \"Potengi\",\n \"Potiretama\",\n \"Quiterianópolis\",\n \"Quixadá\",\n \"Quixelô\",\n \"Quixeramobim\",\n \"Quixeré\",\n \"Redenção\",\n \"Reriutaba\",\n \"Russas\",\n \"Saboeiro\",\n \"Salitre\",\n \"Santa Quitéria\",\n \"Santana do Acaraú\",\n \"Santana do Cariri\",\n \"São Benedito\",\n \"São Gonçalo do Amarante\",\n \"São João do Jaguaribe\",\n \"São Luís do Curu\",\n \"Senador Pompeu\",\n \"Senador Sá\",\n \"Sobral\",\n \"Solonópole\",\n \"Tabuleiro do Norte\",\n \"Tamboril\",\n \"Tarrafas\",\n \"Tauá\",\n \"Tejuçuoca\",\n \"Tianguá\",\n \"Trairi\",\n \"Tururu\",\n \"Ubajara\",\n \"Umari\",\n \"Umirim\",\n \"Uruburetama\",\n \"Uruoca\",\n \"Varjota\",\n \"Várzea Alegre\",\n \"Viçosa do Ceará\"\n ]\n },\n {\n \"uf\": \"DF\",\n \"name\": \"Distrito Federal\",\n \"cities\": [\n \"Águas Claras\",\n \"Arniqueira\",\n \"Brasília\",\n \"Brazlândia\",\n \"Candangolândia\",\n \"Ceilândia\",\n \"Cruzeiro\",\n \"Estrutural\",\n \"Fercal\",\n \"Gama\",\n \"Guará\",\n \"Itapoã\",\n \"Jardim Botânico\",\n \"Lago Norte\",\n \"Lago Sul\",\n \"Núcleo Bandeirante\",\n \"Octogonal\",\n \"Paranoá\",\n \"Park Way\",\n \"Planaltina\",\n \"Plano Piloto\",\n \"Pôr do Sol\",\n \"Recanto das Emas\",\n \"Riacho Fundo\",\n \"Riacho Fundo II\",\n \"Samambaia\",\n \"Santa Maria\",\n \"São Sebastião\",\n \"SIA\",\n \"Sobradinho\",\n \"Sobradinho II\",\n \"Sol Nascente\",\n \"Sudoeste\",\n \"Taguatinga\",\n \"Varjão\",\n \"Vicente Pires\"\n ]\n },\n {\n \"uf\": \"ES\",\n \"name\": \"Espírito Santo\",\n \"cities\": [\n \"Afonso Cláudio\",\n \"Água Doce do Norte\",\n \"Águia Branca\",\n \"Alegre\",\n \"Alfredo Chaves\",\n \"Alto Rio Novo\",\n \"Anchieta\",\n \"Apiacá\",\n \"Aracruz\",\n \"Atílio Vivácqua\",\n \"Baixo Guandu\",\n \"Barra de São Francisco\",\n \"Boa Esperança\",\n \"Bom Jesus do Norte\",\n \"Brejetuba\",\n \"Cachoeiro de Itapemirim\",\n \"Cariacica\",\n \"Castelo\",\n \"Colatina\",\n \"Conceição da Barra\",\n \"Conceição do Castelo\",\n \"Divino de São Lourenço\",\n \"Domingos Martins\",\n \"Dores do Rio Preto\",\n \"Ecoporanga\",\n \"Fundão\",\n \"Governador Lindenberg\",\n \"Guaçuí\",\n \"Guarapari\",\n \"Ibatiba\",\n \"Ibiraçu\",\n \"Ibitirama\",\n \"Iconha\",\n \"Irupi\",\n \"Itaguaçu\",\n \"Itapemirim\",\n \"Itarana\",\n \"Iúna\",\n \"Jaguaré\",\n \"Jerônimo Monteiro\",\n \"João Neiva\",\n \"Laranja da Terra\",\n \"Linhares\",\n \"Mantenópolis\",\n \"Marataízes\",\n \"Marechal Floriano\",\n \"Marilândia\",\n \"Mimoso do Sul\",\n \"Montanha\",\n \"Mucurici\",\n \"Muniz Freire\",\n \"Muqui\",\n \"Nova Venécia\",\n \"Pancas\",\n \"Pedro Canário\",\n \"Pinheiros\",\n \"Piúma\",\n \"Ponto Belo\",\n \"Presidente Kennedy\",\n \"Rio Bananal\",\n \"Rio Novo do Sul\",\n \"Santa Leopoldina\",\n \"Santa Maria de Jetibá\",\n \"Santa Teresa\",\n \"São Domingos do Norte\",\n \"São Gabriel da Palha\",\n \"São José do Calçado\",\n \"São Mateus\",\n \"São Roque do Canaã\",\n \"Serra\",\n \"Sooretama\",\n \"Vargem Alta\",\n \"Venda Nova do Imigrante\",\n \"Viana\",\n \"Vila Pavão\",\n \"Vila Valério\",\n \"Vila Velha\",\n \"Vitória\"\n ]\n },\n {\n \"uf\": \"GO\",\n \"name\": \"Goiás\",\n \"cities\": [\n \"Abadia de Goiás\",\n \"Abadiânia\",\n \"Acreúna\",\n \"Adelândia\",\n \"Água Fria de Goiás\",\n \"Água Limpa\",\n \"Águas Lindas de Goiás\",\n \"Alexânia\",\n \"Aloândia\",\n \"Alto Horizonte\",\n \"Alto Paraíso de Goiás\",\n \"Alvorada do Norte\",\n \"Amaralina\",\n \"Americano do Brasil\",\n \"Amorinópolis\",\n \"Anápolis\",\n \"Anhanguera\",\n \"Anicuns\",\n \"Aparecida de Goiânia\",\n \"Aparecida do Rio Doce\",\n \"Aporé\",\n \"Araçu\",\n \"Aragarças\",\n \"Aragoiânia\",\n \"Araguapaz\",\n \"Arenópolis\",\n \"Aruanã\",\n \"Aurilândia\",\n \"Avelinópolis\",\n \"Baliza\",\n \"Barro Alto\",\n \"Bela Vista de Goiás\",\n \"Bom Jardim de Goiás\",\n \"Bom Jesus de Goiás\",\n \"Bonfinópolis\",\n \"Bonópolis\",\n \"Brazabrantes\",\n \"Britânia\",\n \"Buriti Alegre\",\n \"Buriti de Goiás\",\n \"Buritinópolis\",\n \"Cabeceiras\",\n \"Cachoeira Alta\",\n \"Cachoeira de Goiás\",\n \"Cachoeira Dourada\",\n \"Caçu\",\n \"Caiapônia\",\n \"Caldas Novas\",\n \"Caldazinha\",\n \"Campestre de Goiás\",\n \"Campinaçu\",\n \"Campinorte\",\n \"Campo Alegre de Goiás\",\n \"Campo Limpo de Goiás\",\n \"Campos Belos\",\n \"Campos Verdes\",\n \"Carmo do Rio Verde\",\n \"Castelândia\",\n \"Catalão\",\n \"Caturaí\",\n \"Cavalcante\",\n \"Ceres\",\n \"Cezarina\",\n \"Chapadão do Céu\",\n \"Cidade Ocidental\",\n \"Cocalzinho de Goiás\",\n \"Colinas do Sul\",\n \"Córrego do Ouro\",\n \"Corumbá de Goiás\",\n \"Corumbaíba\",\n \"Cristalina\",\n \"Cristianópolis\",\n \"Crixás\",\n \"Cromínia\",\n \"Cumari\",\n \"Damianópolis\",\n \"Damolândia\",\n \"Davinópolis\",\n \"Diorama\",\n \"Divinópolis de Goiás\",\n \"Doverlândia\",\n \"Edealina\",\n \"Edéia\",\n \"Estrela do Norte\",\n \"Faina\",\n \"Fazenda Nova\",\n \"Firminópolis\",\n \"Flores de Goiás\",\n \"Formosa\",\n \"Formoso\",\n \"Gameleira de Goiás\",\n \"Goianápolis\",\n \"Goiandira\",\n \"Goianésia\",\n \"Goiânia\",\n \"Goianira\",\n \"Goiás\",\n \"Goiatuba\",\n \"Gouvelândia\",\n \"Guapó\",\n \"Guaraíta\",\n \"Guarani de Goiás\",\n \"Guarinos\",\n \"Heitoraí\",\n \"Hidrolândia\",\n \"Hidrolina\",\n \"Iaciara\",\n \"Inaciolândia\",\n \"Indiara\",\n \"Inhumas\",\n \"Ipameri\",\n \"Ipiranga de Goiás\",\n \"Iporá\",\n \"Israelândia\",\n \"Itaberaí\",\n \"Itaguari\",\n \"Itaguaru\",\n \"Itajá\",\n \"Itapaci\",\n \"Itapirapuã\",\n \"Itapuranga\",\n \"Itarumã\",\n \"Itauçu\",\n \"Itumbiara\",\n \"Ivolândia\",\n \"Jandaia\",\n \"Jaraguá\",\n \"Jataí\",\n \"Jaupaci\",\n \"Jesúpolis\",\n \"Joviânia\",\n \"Jussara\",\n \"Lagoa Santa\",\n \"Leopoldo de Bulhões\",\n \"Luziânia\",\n \"Mairipotaba\",\n \"Mambaí\",\n \"Mara Rosa\",\n \"Marzagão\",\n \"Matrinchã\",\n \"Maurilândia\",\n \"Mimoso de Goiás\",\n \"Minaçu\",\n \"Mineiros\",\n \"Moiporá\",\n \"Monte Alegre de Goiás\",\n \"Montes Claros de Goiás\",\n \"Montividiu\",\n \"Montividiu do Norte\",\n \"Morrinhos\",\n \"Morro Agudo de Goiás\",\n \"Mossâmedes\",\n \"Mozarlândia\",\n \"Mundo Novo\",\n \"Mutunópolis\",\n \"Nazário\",\n \"Nerópolis\",\n \"Niquelândia\",\n \"Nova América\",\n \"Nova Aurora\",\n \"Nova Crixás\",\n \"Nova Glória\",\n \"Nova Iguaçu de Goiás\",\n \"Nova Roma\",\n \"Nova Veneza\",\n \"Novo Brasil\",\n \"Novo Gama\",\n \"Novo Planalto\",\n \"Orizona\",\n \"Ouro Verde de Goiás\",\n \"Ouvidor\",\n \"Padre Bernardo\",\n \"Palestina de Goiás\",\n \"Palmeiras de Goiás\",\n \"Palmelo\",\n \"Palminópolis\",\n \"Panamá\",\n \"Paranaiguara\",\n \"Paraúna\",\n \"Perolândia\",\n \"Petrolina de Goiás\",\n \"Pilar de Goiás\",\n \"Piracanjuba\",\n \"Piranhas\",\n \"Pirenópolis\",\n \"Pires do Rio\",\n \"Planaltina\",\n \"Pontalina\",\n \"Porangatu\",\n \"Porteirão\",\n \"Portelândia\",\n \"Posse\",\n \"Professor Jamil\",\n \"Quirinópolis\",\n \"Rialma\",\n \"Rianápolis\",\n \"Rio Quente\",\n \"Rio Verde\",\n \"Rubiataba\",\n \"Sanclerlândia\",\n \"Santa Bárbara de Goiás\",\n \"Santa Cruz de Goiás\",\n \"Santa Fé de Goiás\",\n \"Santa Helena de Goiás\",\n \"Santa Isabel\",\n \"Santa Rita do Araguaia\",\n \"Santa Rita do Novo Destino\",\n \"Santa Rosa de Goiás\",\n \"Santa Tereza de Goiás\",\n \"Santa Terezinha de Goiás\",\n \"Santo Antônio da Barra\",\n \"Santo Antônio de Goiás\",\n \"Santo Antônio do Descoberto\",\n \"São Domingos\",\n \"São Francisco de Goiás\",\n \"São João d'Aliança\",\n \"São João da Paraúna\",\n \"São Luís de Montes Belos\",\n \"São Luiz do Norte\",\n \"São Miguel do Araguaia\",\n \"São Miguel do Passa Quatro\",\n \"São Patrício\",\n \"São Simão\",\n \"Senador Canedo\",\n \"Serranópolis\",\n \"Silvânia\",\n \"Simolândia\",\n \"Sítio d'Abadia\",\n \"Taquaral de Goiás\",\n \"Teresina de Goiás\",\n \"Terezópolis de Goiás\",\n \"Três Ranchos\",\n \"Trindade\",\n \"Trombas\",\n \"Turvânia\",\n \"Turvelândia\",\n \"Uirapuru\",\n \"Uruaçu\",\n \"Uruana\",\n \"Urutaí\",\n \"Valparaíso de Goiás\",\n \"Varjão\",\n \"Vianópolis\",\n \"Vicentinópolis\",\n \"Vila Boa\",\n \"Vila Propício\"\n ]\n },\n {\n \"uf\": \"MA\",\n \"name\": \"Maranhão\",\n \"cities\": [\n \"Açailândia\",\n \"Afonso Cunha\",\n \"Água Doce do Maranhão\",\n \"Alcântara\",\n \"Aldeias Altas\",\n \"Altamira do Maranhão\",\n \"Alto Alegre do Maranhão\",\n \"Alto Alegre do Pindaré\",\n \"Alto Parnaíba\",\n \"Amapá do Maranhão\",\n \"Amarante do Maranhão\",\n \"Anajatuba\",\n \"Anapurus\",\n \"Apicum-Açu\",\n \"Araguanã\",\n \"Araioses\",\n \"Arame\",\n \"Arari\",\n \"Axixá\",\n \"Bacabal\",\n \"Bacabeira\",\n \"Bacuri\",\n \"Bacurituba\",\n \"Balsas\",\n \"Barão de Grajaú\",\n \"Barra do Corda\",\n \"Barreirinhas\",\n \"Bela Vista do Maranhão\",\n \"Belágua\",\n \"Benedito Leite\",\n \"Bequimão\",\n \"Bernardo do Mearim\",\n \"Boa Vista do Gurupi\",\n \"Bom Jardim\",\n \"Bom Jesus das Selvas\",\n \"Bom Lugar\",\n \"Brejo\",\n \"Brejo de Areia\",\n \"Buriti\",\n \"Buriti Bravo\",\n \"Buriticupu\",\n \"Buritirana\",\n \"Cachoeira Grande\",\n \"Cajapió\",\n \"Cajari\",\n \"Campestre do Maranhão\",\n \"Cândido Mendes\",\n \"Cantanhede\",\n \"Capinzal do Norte\",\n \"Carolina\",\n \"Carutapera\",\n \"Caxias\",\n \"Cedral\",\n \"Central do Maranhão\",\n \"Centro do Guilherme\",\n \"Centro Novo do Maranhão\",\n \"Chapadinha\",\n \"Cidelândia\",\n \"Codó\",\n \"Coelho Neto\",\n \"Colinas\",\n \"Conceição do Lago-Açu\",\n \"Coroatá\",\n \"Cururupu\",\n \"Davinópolis\",\n \"Dom Pedro\",\n \"Duque Bacelar\",\n \"Esperantinópolis\",\n \"Estreito\",\n \"Feira Nova do Maranhão\",\n \"Fernando Falcão\",\n \"Formosa da Serra Negra\",\n \"Fortaleza dos Nogueiras\",\n \"Fortuna\",\n \"Godofredo Viana\",\n \"Gonçalves Dias\",\n \"Governador Archer\",\n \"Governador Edison Lobão\",\n \"Governador Eugênio Barros\",\n \"Governador Luiz Rocha\",\n \"Governador Newton Bello\",\n \"Governador Nunes Freire\",\n \"Graça Aranha\",\n \"Grajaú\",\n \"Guimarães\",\n \"Humberto de Campos\",\n \"Icatu\",\n \"Igarapé do Meio\",\n \"Igarapé Grande\",\n \"Imperatriz\",\n \"Itaipava do Grajaú\",\n \"Itapecuru Mirim\",\n \"Itinga do Maranhão\",\n \"Jatobá\",\n \"Jenipapo dos Vieiras\",\n \"João Lisboa\",\n \"Joselândia\",\n \"Junco do Maranhão\",\n \"Lago da Pedra\",\n \"Lago do Junco\",\n \"Lago dos Rodrigues\",\n \"Lago Verde\",\n \"Lagoa do Mato\",\n \"Lagoa Grande do Maranhão\",\n \"Lajeado Novo\",\n \"Lima Campos\",\n \"Loreto\",\n \"Luís Domingues\",\n \"Magalhães de Almeida\",\n \"Maracaçumé\",\n \"Marajá do Sena\",\n \"Maranhãozinho\",\n \"Mata Roma\",\n \"Matinha\",\n \"Matões\",\n \"Matões do Norte\",\n \"Milagres do Maranhão\",\n \"Mirador\",\n \"Miranda do Norte\",\n \"Mirinzal\",\n \"Monção\",\n \"Montes Altos\",\n \"Morros\",\n \"Nina Rodrigues\",\n \"Nova Colinas\",\n \"Nova Iorque\",\n \"Nova Olinda do Maranhão\",\n \"Olho d'Água das Cunhãs\",\n \"Olinda Nova do Maranhão\",\n \"Paço do Lumiar\",\n \"Palmeirândia\",\n \"Paraibano\",\n \"Parnarama\",\n \"Passagem Franca\",\n \"Pastos Bons\",\n \"Paulino Neves\",\n \"Paulo Ramos\",\n \"Pedreiras\",\n \"Pedro do Rosário\",\n \"Penalva\",\n \"Peri Mirim\",\n \"Peritoró\",\n \"Pindaré-Mirim\",\n \"Pinheiro\",\n \"Pio XII\",\n \"Pirapemas\",\n \"Poção de Pedras\",\n \"Porto Franco\",\n \"Porto Rico do Maranhão\",\n \"Presidente Dutra\",\n \"Presidente Juscelino\",\n \"Presidente Médici\",\n \"Presidente Sarney\",\n \"Presidente Vargas\",\n \"Primeira Cruz\",\n \"Raposa\",\n \"Riachão\",\n \"Ribamar Fiquene\",\n \"Rosário\",\n \"Sambaíba\",\n \"Santa Filomena do Maranhão\",\n \"Santa Helena\",\n \"Santa Inês\",\n \"Santa Luzia\",\n \"Santa Luzia do Paruá\",\n \"Santa Quitéria do Maranhão\",\n \"Santa Rita\",\n \"Santana do Maranhão\",\n \"Santo Amaro do Maranhão\",\n \"Santo Antônio dos Lopes\",\n \"São Benedito do Rio Preto\",\n \"São Bento\",\n \"São Bernardo\",\n \"São Domingos do Azeitão\",\n \"São Domingos do Maranhão\",\n \"São Félix de Balsas\",\n \"São Francisco do Brejão\",\n \"São Francisco do Maranhão\",\n \"São João Batista\",\n \"São João do Carú\",\n \"São João do Paraíso\",\n \"São João do Soter\",\n \"São João dos Patos\",\n \"São José de Ribamar\",\n \"São José dos Basílios\",\n \"São Luís\",\n \"São Luís Gonzaga do Maranhão\",\n \"São Mateus do Maranhão\",\n \"São Pedro da Água Branca\",\n \"São Pedro dos Crentes\",\n \"São Raimundo das Mangabeiras\",\n \"São Raimundo do Doca Bezerra\",\n \"São Roberto\",\n \"São Vicente Ferrer\",\n \"Satubinha\",\n \"Senador Alexandre Costa\",\n \"Senador La Rocque\",\n \"Serrano do Maranhão\",\n \"Sítio Novo\",\n \"Sucupira do Norte\",\n \"Sucupira do Riachão\",\n \"Tasso Fragoso\",\n \"Timbiras\",\n \"Timon\",\n \"Trizidela do Vale\",\n \"Tufilândia\",\n \"Tuntum\",\n \"Turiaçu\",\n \"Turilândia\",\n \"Tutóia\",\n \"Urbano Santos\",\n \"Vargem Grande\",\n \"Viana\",\n \"Vila Nova dos Martírios\",\n \"Vitória do Mearim\",\n \"Vitorino Freire\",\n \"Zé Doca\"\n ]\n },\n {\n \"uf\": \"MG\",\n \"name\": \"Minas Gerais\",\n \"cities\": [\n \"Abadia dos Dourados\",\n \"Abaeté\",\n \"Abre Campo\",\n \"Acaiaca\",\n \"Açucena\",\n \"Água Boa\",\n \"Água Comprida\",\n \"Aguanil\",\n \"Águas Formosas\",\n \"Águas Vermelhas\",\n \"Aimorés\",\n \"Aiuruoca\",\n \"Alagoa\",\n \"Albertina\",\n \"Além Paraíba\",\n \"Alfenas\",\n \"Alfredo Vasconcelos\",\n \"Almenara\",\n \"Alpercata\",\n \"Alpinópolis\",\n \"Alterosa\",\n \"Alto Caparaó\",\n \"Alto Jequitibá\",\n \"Alto Rio Doce\",\n \"Alvarenga\",\n \"Alvinópolis\",\n \"Alvorada de Minas\",\n \"Amparo do Serra\",\n \"Andradas\",\n \"Andrelândia\",\n \"Angelândia\",\n \"Antônio Carlos\",\n \"Antônio Dias\",\n \"Antônio Prado de Minas\",\n \"Araçaí\",\n \"Aracitaba\",\n \"Araçuaí\",\n \"Araguari\",\n \"Arantina\",\n \"Araponga\",\n \"Araporã\",\n \"Arapuá\",\n \"Araújos\",\n \"Araxá\",\n \"Arceburgo\",\n \"Arcos\",\n \"Areado\",\n \"Argirita\",\n \"Aricanduva\",\n \"Arinos\",\n \"Astolfo Dutra\",\n \"Ataléia\",\n \"Augusto de Lima\",\n \"Baependi\",\n \"Baldim\",\n \"Bambuí\",\n \"Bandeira\",\n \"Bandeira do Sul\",\n \"Barão de Cocais\",\n \"Barão do Monte Alto\",\n \"Barbacena\",\n \"Barra Longa\",\n \"Barroso\",\n \"Bela Vista de Minas\",\n \"Belmiro Braga\",\n \"Belo Horizonte\",\n \"Belo Oriente\",\n \"Belo Vale\",\n \"Berilo\",\n \"Berizal\",\n \"Bertópolis\",\n \"Betim\",\n \"Bias Fortes\",\n \"Bicas\",\n \"Biquinhas\",\n \"Boa Esperança\",\n \"Bocaina de Minas\",\n \"Bocaiúva\",\n \"Bom Despacho\",\n \"Bom Jardim de Minas\",\n \"Bom Jesus da Penha\",\n \"Bom Jesus do Amparo\",\n \"Bom Jesus do Galho\",\n \"Bom Repouso\",\n \"Bom Sucesso\",\n \"Bonfim\",\n \"Bonfinópolis de Minas\",\n \"Bonito de Minas\",\n \"Borda da Mata\",\n \"Botelhos\",\n \"Botumirim\",\n \"Brás Pires\",\n \"Brasilândia de Minas\",\n \"Brasília de Minas\",\n \"Braúnas\",\n \"Brazópolis\",\n \"Brumadinho\",\n \"Bueno Brandão\",\n \"Buenópolis\",\n \"Bugre\",\n \"Buritis\",\n \"Buritizeiro\",\n \"Cabeceira Grande\",\n \"Cabo Verde\",\n \"Cachoeira da Prata\",\n \"Cachoeira de Minas\",\n \"Cachoeira de Pajeú\",\n \"Cachoeira Dourada\",\n \"Caetanópolis\",\n \"Caeté\",\n \"Caiana\",\n \"Cajuri\",\n \"Caldas\",\n \"Camacho\",\n \"Camanducaia\",\n \"Cambuí\",\n \"Cambuquira\",\n \"Campanário\",\n \"Campanha\",\n \"Campestre\",\n \"Campina Verde\",\n \"Campo Azul\",\n \"Campo Belo\",\n \"Campo do Meio\",\n \"Campo Florido\",\n \"Campos Altos\",\n \"Campos Gerais\",\n \"Cana Verde\",\n \"Canaã\",\n \"Canápolis\",\n \"Candeias\",\n \"Cantagalo\",\n \"Caparaó\",\n \"Capela Nova\",\n \"Capelinha\",\n \"Capetinga\",\n \"Capim Branco\",\n \"Capinópolis\",\n \"Capitão Andrade\",\n \"Capitão Enéas\",\n \"Capitólio\",\n \"Caputira\",\n \"Caraí\",\n \"Caranaíba\",\n \"Carandaí\",\n \"Carangola\",\n \"Caratinga\",\n \"Carbonita\",\n \"Careaçu\",\n \"Carlos Chagas\",\n \"Carmésia\",\n \"Carmo da Cachoeira\",\n \"Carmo da Mata\",\n \"Carmo de Minas\",\n \"Carmo do Cajuru\",\n \"Carmo do Paranaíba\",\n \"Carmo do Rio Claro\",\n \"Carmópolis de Minas\",\n \"Carneirinho\",\n \"Carrancas\",\n \"Carvalhópolis\",\n \"Carvalhos\",\n \"Casa Grande\",\n \"Cascalho Rico\",\n \"Cássia\",\n \"Cataguases\",\n \"Catas Altas\",\n \"Catas Altas da Noruega\",\n \"Catuji\",\n \"Catuti\",\n \"Caxambu\",\n \"Cedro do Abaeté\",\n \"Central de Minas\",\n \"Centralina\",\n \"Chácara\",\n \"Chalé\",\n \"Chapada do Norte\",\n \"Chapada Gaúcha\",\n \"Chiador\",\n \"Cipotânea\",\n \"Claraval\",\n \"Claro dos Poções\",\n \"Cláudio\",\n \"Coimbra\",\n \"Coluna\",\n \"Comendador Gomes\",\n \"Comercinho\",\n \"Conceição da Aparecida\",\n \"Conceição da Barra de Minas\",\n \"Conceição das Alagoas\",\n \"Conceição das Pedras\",\n \"Conceição de Ipanema\",\n \"Conceição do Mato Dentro\",\n \"Conceição do Pará\",\n \"Conceição do Rio Verde\",\n \"Conceição dos Ouros\",\n \"Cônego Marinho\",\n \"Confins\",\n \"Congonhal\",\n \"Congonhas\",\n \"Congonhas do Norte\",\n \"Conquista\",\n \"Conselheiro Lafaiete\",\n \"Conselheiro Pena\",\n \"Consolação\",\n \"Contagem\",\n \"Coqueiral\",\n \"Coração de Jesus\",\n \"Cordisburgo\",\n \"Cordislândia\",\n \"Corinto\",\n \"Coroaci\",\n \"Coromandel\",\n \"Coronel Fabriciano\",\n \"Coronel Murta\",\n \"Coronel Pacheco\",\n \"Coronel Xavier Chaves\",\n \"Córrego Danta\",\n \"Córrego do Bom Jesus\",\n \"Córrego Fundo\",\n \"Córrego Novo\",\n \"Couto de Magalhães de Minas\",\n \"Crisólita\",\n \"Cristais\",\n \"Cristália\",\n \"Cristiano Otoni\",\n \"Cristina\",\n \"Crucilândia\",\n \"Cruzeiro da Fortaleza\",\n \"Cruzília\",\n \"Cuparaque\",\n \"Curral de Dentro\",\n \"Curvelo\",\n \"Datas\",\n \"Delfim Moreira\",\n \"Delfinópolis\",\n \"Delta\",\n \"Descoberto\",\n \"Desterro de Entre Rios\",\n \"Desterro do Melo\",\n \"Diamantina\",\n \"Diogo de Vasconcelos\",\n \"Dionísio\",\n \"Divinésia\",\n \"Divino\",\n \"Divino das Laranjeiras\",\n \"Divinolândia de Minas\",\n \"Divinópolis\",\n \"Divisa Alegre\",\n \"Divisa Nova\",\n \"Divisópolis\",\n \"Dom Bosco\",\n \"Dom Cavati\",\n \"Dom Joaquim\",\n \"Dom Silvério\",\n \"Dom Viçoso\",\n \"Dona Euzébia\",\n \"Dores de Campos\",\n \"Dores de Guanhães\",\n \"Dores do Indaiá\",\n \"Dores do Turvo\",\n \"Doresópolis\",\n \"Douradoquara\",\n \"Durandé\",\n \"Elói Mendes\",\n \"Engenheiro Caldas\",\n \"Engenheiro Navarro\",\n \"Entre Folhas\",\n \"Entre Rios de Minas\",\n \"Ervália\",\n \"Esmeraldas\",\n \"Espera Feliz\",\n \"Espinosa\",\n \"Espírito Santo do Dourado\",\n \"Estiva\",\n \"Estrela Dalva\",\n \"Estrela do Indaiá\",\n \"Estrela do Sul\",\n \"Eugenópolis\",\n \"Ewbank da Câmara\",\n \"Extrema\",\n \"Fama\",\n \"Faria Lemos\",\n \"Felício dos Santos\",\n \"Felisburgo\",\n \"Felixlândia\",\n \"Fernandes Tourinho\",\n \"Ferros\",\n \"Fervedouro\",\n \"Florestal\",\n \"Formiga\",\n \"Formoso\",\n \"Fortaleza de Minas\",\n \"Fortuna de Minas\",\n \"Francisco Badaró\",\n \"Francisco Dumont\",\n \"Francisco Sá\",\n \"Franciscópolis\",\n \"Frei Gaspar\",\n \"Frei Inocêncio\",\n \"Frei Lagonegro\",\n \"Fronteira\",\n \"Fronteira dos Vales\",\n \"Fruta de Leite\",\n \"Frutal\",\n \"Funilândia\",\n \"Galiléia\",\n \"Gameleiras\",\n \"Glaucilândia\",\n \"Goiabeira\",\n \"Goianá\",\n \"Gonçalves\",\n \"Gonzaga\",\n \"Gouveia\",\n \"Governador Valadares\",\n \"Grão Mogol\",\n \"Grupiara\",\n \"Guanhães\",\n \"Guapé\",\n \"Guaraciaba\",\n \"Guaraciama\",\n \"Guaranésia\",\n \"Guarani\",\n \"Guarará\",\n \"Guarda-Mor\",\n \"Guaxupé\",\n \"Guidoval\",\n \"Guimarânia\",\n \"Guiricema\",\n \"Gurinhatã\",\n \"Heliodora\",\n \"Iapu\",\n \"Ibertioga\",\n \"Ibiá\",\n \"Ibiaí\",\n \"Ibiracatu\",\n \"Ibiraci\",\n \"Ibirité\",\n \"Ibitiúra de Minas\",\n \"Ibituruna\",\n \"Icaraí de Minas\",\n \"Igarapé\",\n \"Igaratinga\",\n \"Iguatama\",\n \"Ijaci\",\n \"Ilicínea\",\n \"Imbé de Minas\",\n \"Inconfidentes\",\n \"Indaiabira\",\n \"Indianópolis\",\n \"Ingaí\",\n \"Inhapim\",\n \"Inhaúma\",\n \"Inimutaba\",\n \"Ipaba\",\n \"Ipanema\",\n \"Ipatinga\",\n \"Ipiaçu\",\n \"Ipuiúna\",\n \"Iraí de Minas\",\n \"Itabira\",\n \"Itabirinha\",\n \"Itabirito\",\n \"Itacambira\",\n \"Itacarambi\",\n \"Itaguara\",\n \"Itaipé\",\n \"Itajubá\",\n \"Itamarandiba\",\n \"Itamarati de Minas\",\n \"Itambacuri\",\n \"Itambé do Mato Dentro\",\n \"Itamogi\",\n \"Itamonte\",\n \"Itanhandu\",\n \"Itanhomi\",\n \"Itaobim\",\n \"Itapagipe\",\n \"Itapecerica\",\n \"Itapeva\",\n \"Itatiaiuçu\",\n \"Itaú de Minas\",\n \"Itaúna\",\n \"Itaverava\",\n \"Itinga\",\n \"Itueta\",\n \"Ituiutaba\",\n \"Itumirim\",\n \"Iturama\",\n \"Itutinga\",\n \"Jaboticatubas\",\n \"Jacinto\",\n \"Jacuí\",\n \"Jacutinga\",\n \"Jaguaraçu\",\n \"Jaíba\",\n \"Jampruca\",\n \"Janaúba\",\n \"Januária\",\n \"Japaraíba\",\n \"Japonvar\",\n \"Jeceaba\",\n \"Jenipapo de Minas\",\n \"Jequeri\",\n \"Jequitaí\",\n \"Jequitibá\",\n \"Jequitinhonha\",\n \"Jesuânia\",\n \"Joaíma\",\n \"Joanésia\",\n \"João Monlevade\",\n \"João Pinheiro\",\n \"Joaquim Felício\",\n \"Jordânia\",\n \"José Gonçalves de Minas\",\n \"José Raydan\",\n \"Josenópolis\",\n \"Juatuba\",\n \"Juiz de Fora\",\n \"Juramento\",\n \"Juruaia\",\n \"Juvenília\",\n \"Ladainha\",\n \"Lagamar\",\n \"Lagoa da Prata\",\n \"Lagoa dos Patos\",\n \"Lagoa Dourada\",\n \"Lagoa Formosa\",\n \"Lagoa Grande\",\n \"Lagoa Santa\",\n \"Lajinha\",\n \"Lambari\",\n \"Lamim\",\n \"Laranjal\",\n \"Lassance\",\n \"Lavras\",\n \"Leandro Ferreira\",\n \"Leme do Prado\",\n \"Leopoldina\",\n \"Liberdade\",\n \"Lima Duarte\",\n \"Limeira do Oeste\",\n \"Lontra\",\n \"Luisburgo\",\n \"Luislândia\",\n \"Luminárias\",\n \"Luz\",\n \"Machacalis\",\n \"Machado\",\n \"Madre de Deus de Minas\",\n \"Malacacheta\",\n \"Mamonas\",\n \"Manga\",\n \"Manhuaçu\",\n \"Manhumirim\",\n \"Mantena\",\n \"Mar de Espanha\",\n \"Maravilhas\",\n \"Maria da Fé\",\n \"Mariana\",\n \"Marilac\",\n \"Mário Campos\",\n \"Maripá de Minas\",\n \"Marliéria\",\n \"Marmelópolis\",\n \"Martinho Campos\",\n \"Martins Soares\",\n \"Mata Verde\",\n \"Materlândia\",\n \"Mateus Leme\",\n \"Mathias Lobato\",\n \"Matias Barbosa\",\n \"Matias Cardoso\",\n \"Matipó\",\n \"Mato Verde\",\n \"Matozinhos\",\n \"Matutina\",\n \"Medeiros\",\n \"Medina\",\n \"Mendes Pimentel\",\n \"Mercês\",\n \"Mesquita\",\n \"Minas Novas\",\n \"Minduri\",\n \"Mirabela\",\n \"Miradouro\",\n \"Miraí\",\n \"Miravânia\",\n \"Moeda\",\n \"Moema\",\n \"Monjolos\",\n \"Monsenhor Paulo\",\n \"Montalvânia\",\n \"Monte Alegre de Minas\",\n \"Monte Azul\",\n \"Monte Belo\",\n \"Monte Carmelo\",\n \"Monte Formoso\",\n \"Monte Santo de Minas\",\n \"Monte Sião\",\n \"Montes Claros\",\n \"Montezuma\",\n \"Morada Nova de Minas\",\n \"Morro da Garça\",\n \"Morro do Pilar\",\n \"Munhoz\",\n \"Muriaé\",\n \"Mutum\",\n \"Muzambinho\",\n \"Nacip Raydan\",\n \"Nanuque\",\n \"Naque\",\n \"Natalândia\",\n \"Natércia\",\n \"Nazareno\",\n \"Nepomuceno\",\n \"Ninheira\",\n \"Nova Belém\",\n \"Nova Era\",\n \"Nova Lima\",\n \"Nova Módica\",\n \"Nova Ponte\",\n \"Nova Porteirinha\",\n \"Nova Resende\",\n \"Nova Serrana\",\n \"Nova União\",\n \"Novo Cruzeiro\",\n \"Novo Oriente de Minas\",\n \"Novorizonte\",\n \"Olaria\",\n \"Olhos-d'Água\",\n \"Olímpio Noronha\",\n \"Oliveira\",\n \"Oliveira Fortes\",\n \"Onça de Pitangui\",\n \"Oratórios\",\n \"Orizânia\",\n \"Ouro Branco\",\n \"Ouro Fino\",\n \"Ouro Preto\",\n \"Ouro Verde de Minas\",\n \"Padre Carvalho\",\n \"Padre Paraíso\",\n \"Pai Pedro\",\n \"Paineiras\",\n \"Pains\",\n \"Paiva\",\n \"Palma\",\n \"Palmópolis\",\n \"Papagaios\",\n \"Pará de Minas\",\n \"Paracatu\",\n \"Paraguaçu\",\n \"Paraisópolis\",\n \"Paraopeba\",\n \"Passa Quatro\",\n \"Passa Tempo\",\n \"Passa Vinte\",\n \"Passabém\",\n \"Passos\",\n \"Patis\",\n \"Patos de Minas\",\n \"Patrocínio\",\n \"Patrocínio do Muriaé\",\n \"Paula Cândido\",\n \"Paulistas\",\n \"Pavão\",\n \"Peçanha\",\n \"Pedra Azul\",\n \"Pedra Bonita\",\n \"Pedra do Anta\",\n \"Pedra do Indaiá\",\n \"Pedra Dourada\",\n \"Pedralva\",\n \"Pedras de Maria da Cruz\",\n \"Pedrinópolis\",\n \"Pedro Leopoldo\",\n \"Pedro Teixeira\",\n \"Pequeri\",\n \"Pequi\",\n \"Perdigão\",\n \"Perdizes\",\n \"Perdões\",\n \"Periquito\",\n \"Pescador\",\n \"Piau\",\n \"Piedade de Caratinga\",\n \"Piedade de Ponte Nova\",\n \"Piedade do Rio Grande\",\n \"Piedade dos Gerais\",\n \"Pimenta\",\n \"Pingo-d'Água\",\n \"Pintópolis\",\n \"Piracema\",\n \"Pirajuba\",\n \"Piranga\",\n \"Piranguçu\",\n \"Piranguinho\",\n \"Pirapetinga\",\n \"Pirapora\",\n \"Piraúba\",\n \"Pitangui\",\n \"Piumhi\",\n \"Planura\",\n \"Poço Fundo\",\n \"Poços de Caldas\",\n \"Pocrane\",\n \"Pompéu\",\n \"Ponte Nova\",\n \"Ponto Chique\",\n \"Ponto dos Volantes\",\n \"Porteirinha\",\n \"Porto Firme\",\n \"Poté\",\n \"Pouso Alegre\",\n \"Pouso Alto\",\n \"Prados\",\n \"Prata\",\n \"Pratápolis\",\n \"Pratinha\",\n \"Presidente Bernardes\",\n \"Presidente Juscelino\",\n \"Presidente Kubitschek\",\n \"Presidente Olegário\",\n \"Prudente de Morais\",\n \"Quartel Geral\",\n \"Queluzito\",\n \"Raposos\",\n \"Raul Soares\",\n \"Recreio\",\n \"Reduto\",\n \"Resende Costa\",\n \"Resplendor\",\n \"Ressaquinha\",\n \"Riachinho\",\n \"Riacho dos Machados\",\n \"Ribeirão das Neves\",\n \"Ribeirão Vermelho\",\n \"Rio Acima\",\n \"Rio Casca\",\n \"Rio do Prado\",\n \"Rio Doce\",\n \"Rio Espera\",\n \"Rio Manso\",\n \"Rio Novo\",\n \"Rio Paranaíba\",\n \"Rio Pardo de Minas\",\n \"Rio Piracicaba\",\n \"Rio Pomba\",\n \"Rio Preto\",\n \"Rio Vermelho\",\n \"Ritápolis\",\n \"Rochedo de Minas\",\n \"Rodeiro\",\n \"Romaria\",\n \"Rosário da Limeira\",\n \"Rubelita\",\n \"Rubim\",\n \"Sabará\",\n \"Sabinópolis\",\n \"Sacramento\",\n \"Salinas\",\n \"Salto da Divisa\",\n \"Santa Bárbara\",\n \"Santa Bárbara do Leste\",\n \"Santa Bárbara do Monte Verde\",\n \"Santa Bárbara do Tugúrio\",\n \"Santa Cruz de Minas\",\n \"Santa Cruz de Salinas\",\n \"Santa Cruz do Escalvado\",\n \"Santa Efigênia de Minas\",\n \"Santa Fé de Minas\",\n \"Santa Helena de Minas\",\n \"Santa Juliana\",\n \"Santa Luzia\",\n \"Santa Margarida\",\n \"Santa Maria de Itabira\",\n \"Santa Maria do Salto\",\n \"Santa Maria do Suaçuí\",\n \"Santa Rita de Caldas\",\n \"Santa Rita de Ibitipoca\",\n \"Santa Rita de Jacutinga\",\n \"Santa Rita de Minas\",\n \"Santa Rita do Itueto\",\n \"Santa Rita do Sapucaí\",\n \"Santa Rosa da Serra\",\n \"Santa Vitória\",\n \"Santana da Vargem\",\n \"Santana de Cataguases\",\n \"Santana de Pirapama\",\n \"Santana do Deserto\",\n \"Santana do Garambéu\",\n \"Santana do Jacaré\",\n \"Santana do Manhuaçu\",\n \"Santana do Paraíso\",\n \"Santana do Riacho\",\n \"Santana dos Montes\",\n \"Santo Antônio do Amparo\",\n \"Santo Antônio do Aventureiro\",\n \"Santo Antônio do Grama\",\n \"Santo Antônio do Itambé\",\n \"Santo Antônio do Jacinto\",\n \"Santo Antônio do Monte\",\n \"Santo Antônio do Retiro\",\n \"Santo Antônio do Rio Abaixo\",\n \"Santo Hipólito\",\n \"Santos Dumont\",\n \"São Bento Abade\",\n \"São Brás do Suaçuí\",\n \"São Domingos das Dores\",\n \"São Domingos do Prata\",\n \"São Félix de Minas\",\n \"São Francisco\",\n \"São Francisco de Paula\",\n \"São Francisco de Sales\",\n \"São Francisco do Glória\",\n \"São Geraldo\",\n \"São Geraldo da Piedade\",\n \"São Geraldo do Baixio\",\n \"São Gonçalo do Abaeté\",\n \"São Gonçalo do Pará\",\n \"São Gonçalo do Rio Abaixo\",\n \"São Gonçalo do Rio Preto\",\n \"São Gonçalo do Sapucaí\",\n \"São Gotardo\",\n \"São João Batista do Glória\",\n \"São João da Lagoa\",\n \"São João da Mata\",\n \"São João da Ponte\",\n \"São João das Missões\",\n \"São João del Rei\",\n \"São João do Manhuaçu\",\n \"São João do Manteninha\",\n \"São João do Oriente\",\n \"São João do Pacuí\",\n \"São João do Paraíso\",\n \"São João Evangelista\",\n \"São João Nepomuceno\",\n \"São Joaquim de Bicas\",\n \"São José da Barra\",\n \"São José da Lapa\",\n \"São José da Safira\",\n \"São José da Varginha\",\n \"São José do Alegre\",\n \"São José do Divino\",\n \"São José do Goiabal\",\n \"São José do Jacuri\",\n \"São José do Mantimento\",\n \"São Lourenço\",\n \"São Miguel do Anta\",\n \"São Pedro da União\",\n \"São Pedro do Suaçuí\",\n \"São Pedro dos Ferros\",\n \"São Romão\",\n \"São Roque de Minas\",\n \"São Sebastião da Bela Vista\",\n \"São Sebastião da Vargem Alegre\",\n \"São Sebastião do Anta\",\n \"São Sebastião do Maranhão\",\n \"São Sebastião do Oeste\",\n \"São Sebastião do Paraíso\",\n \"São Sebastião do Rio Preto\",\n \"São Sebastião do Rio Verde\",\n \"São Tiago\",\n \"São Tomás de Aquino\",\n \"São Tomé das Letras\",\n \"São Vicente de Minas\",\n \"Sapucaí-Mirim\",\n \"Sardoá\",\n \"Sarzedo\",\n \"Sem-Peixe\",\n \"Senador Amaral\",\n \"Senador Cortes\",\n \"Senador Firmino\",\n \"Senador José Bento\",\n \"Senador Modestino Gonçalves\",\n \"Senhora de Oliveira\",\n \"Senhora do Porto\",\n \"Senhora dos Remédios\",\n \"Sericita\",\n \"Seritinga\",\n \"Serra Azul de Minas\",\n \"Serra da Saudade\",\n \"Serra do Salitre\",\n \"Serra dos Aimorés\",\n \"Serrania\",\n \"Serranópolis de Minas\",\n \"Serranos\",\n \"Serro\",\n \"Sete Lagoas\",\n \"Setubinha\",\n \"Silveirânia\",\n \"Silvianópolis\",\n \"Simão Pereira\",\n \"Simonésia\",\n \"Sobrália\",\n \"Soledade de Minas\",\n \"Tabuleiro\",\n \"Taiobeiras\",\n \"Taparuba\",\n \"Tapira\",\n \"Tapiraí\",\n \"Taquaraçu de Minas\",\n \"Tarumirim\",\n \"Teixeiras\",\n \"Teófilo Otoni\",\n \"Timóteo\",\n \"Tiradentes\",\n \"Tiros\",\n \"Tocantins\",\n \"Tocos do Moji\",\n \"Toledo\",\n \"Tombos\",\n \"Três Corações\",\n \"Três Marias\",\n \"Três Pontas\",\n \"Tumiritinga\",\n \"Tupaciguara\",\n \"Turmalina\",\n \"Turvolândia\",\n \"Ubá\",\n \"Ubaí\",\n \"Ubaporanga\",\n \"Uberaba\",\n \"Uberlândia\",\n \"Umburatiba\",\n \"Unaí\",\n \"União de Minas\",\n \"Uruana de Minas\",\n \"Urucânia\",\n \"Urucuia\",\n \"Vargem Alegre\",\n \"Vargem Bonita\",\n \"Vargem Grande do Rio Pardo\",\n \"Varginha\",\n \"Varjão de Minas\",\n \"Várzea da Palma\",\n \"Varzelândia\",\n \"Vazante\",\n \"Verdelândia\",\n \"Veredinha\",\n \"Veríssimo\",\n \"Vermelho Novo\",\n \"Vespasiano\",\n \"Viçosa\",\n \"Vieiras\",\n \"Virgem da Lapa\",\n \"Virgínia\",\n \"Virginópolis\",\n \"Virgolândia\",\n \"Visconde do Rio Branco\",\n \"Volta Grande\",\n \"Wenceslau Braz\"\n ]\n },\n {\n \"uf\": \"MS\",\n \"name\": \"Mato Grosso do Sul\",\n \"cities\": [\n \"Água Clara\",\n \"Alcinópolis\",\n \"Amambai\",\n \"Anastácio\",\n \"Anaurilândia\",\n \"Angélica\",\n \"Antônio João\",\n \"Aparecida do Taboado\",\n \"Aquidauana\",\n \"Aral Moreira\",\n \"Bandeirantes\",\n \"Bataguassu\",\n \"Batayporã\",\n \"Bela Vista\",\n \"Bodoquena\",\n \"Bonito\",\n \"Brasilândia\",\n \"Caarapó\",\n \"Camapuã\",\n \"Campo Grande\",\n \"Caracol\",\n \"Cassilândia\",\n \"Chapadão do Sul\",\n \"Corguinho\",\n \"Coronel Sapucaia\",\n \"Corumbá\",\n \"Costa Rica\",\n \"Coxim\",\n \"Deodápolis\",\n \"Dois Irmãos do Buriti\",\n \"Douradina\",\n \"Dourados\",\n \"Eldorado\",\n \"Fátima do Sul\",\n \"Figueirão\",\n \"Glória de Dourados\",\n \"Guia Lopes da Laguna\",\n \"Iguatemi\",\n \"Inocência\",\n \"Itaporã\",\n \"Itaquiraí\",\n \"Ivinhema\",\n \"Japorã\",\n \"Jaraguari\",\n \"Jardim\",\n \"Jateí\",\n \"Juti\",\n \"Ladário\",\n \"Laguna Carapã\",\n \"Maracaju\",\n \"Miranda\",\n \"Mundo Novo\",\n \"Naviraí\",\n \"Nioaque\",\n \"Nova Alvorada do Sul\",\n \"Nova Andradina\",\n \"Novo Horizonte do Sul\",\n \"Paraíso das Águas\",\n \"Paranaíba\",\n \"Paranhos\",\n \"Pedro Gomes\",\n \"Ponta Porã\",\n \"Porto Murtinho\",\n \"Ribas do Rio Pardo\",\n \"Rio Brilhante\",\n \"Rio Negro\",\n \"Rio Verde de Mato Grosso\",\n \"Rochedo\",\n \"Santa Rita do Pardo\",\n \"São Gabriel do Oeste\",\n \"Selvíria\",\n \"Sete Quedas\",\n \"Sidrolândia\",\n \"Sonora\",\n \"Tacuru\",\n \"Taquarussu\",\n \"Terenos\",\n \"Três Lagoas\",\n \"Vicentina\"\n ]\n },\n {\n \"uf\": \"MT\",\n \"name\": \"Mato Grosso\",\n \"cities\": [\n \"Acorizal\",\n \"Água Boa\",\n \"Alta Floresta\",\n \"Alto Araguaia\",\n \"Alto Boa Vista\",\n \"Alto Garças\",\n \"Alto Paraguai\",\n \"Alto Taquari\",\n \"Apiacás\",\n \"Araguaiana\",\n \"Araguainha\",\n \"Araputanga\",\n \"Arenápolis\",\n \"Aripuanã\",\n \"Barão de Melgaço\",\n \"Barra do Bugres\",\n \"Barra do Garças\",\n \"Boa Esperança do Norte\",\n \"Bom Jesus do Araguaia\",\n \"Brasnorte\",\n \"Cáceres\",\n \"Campinápolis\",\n \"Campo Novo do Parecis\",\n \"Campo Verde\",\n \"Campos de Júlio\",\n \"Canabrava do Norte\",\n \"Canarana\",\n \"Carlinda\",\n \"Castanheira\",\n \"Chapada dos Guimarães\",\n \"Cláudia\",\n \"Cocalinho\",\n \"Colíder\",\n \"Colniza\",\n \"Comodoro\",\n \"Confresa\",\n \"Conquista D'Oeste\",\n \"Cotriguaçu\",\n \"Cuiabá\",\n \"Curvelândia\",\n \"Denise\",\n \"Diamantino\",\n \"Dom Aquino\",\n \"Feliz Natal\",\n \"Figueirópolis D'Oeste\",\n \"Gaúcha do Norte\",\n \"General Carneiro\",\n \"Glória D'Oeste\",\n \"Guarantã do Norte\",\n \"Guiratinga\",\n \"Indiavaí\",\n \"Ipiranga do Norte\",\n \"Itanhangá\",\n \"Itaúba\",\n \"Itiquira\",\n \"Jaciara\",\n \"Jangada\",\n \"Jauru\",\n \"Juara\",\n \"Juína\",\n \"Juruena\",\n \"Juscimeira\",\n \"Lambari D'Oeste\",\n \"Lucas do Rio Verde\",\n \"Luciara\",\n \"Marcelândia\",\n \"Matupá\",\n \"Mirassol d'Oeste\",\n \"Nobres\",\n \"Nortelândia\",\n \"Nossa Senhora do Livramento\",\n \"Nova Bandeirantes\",\n \"Nova Brasilândia\",\n \"Nova Canaã do Norte\",\n \"Nova Guarita\",\n \"Nova Lacerda\",\n \"Nova Marilândia\",\n \"Nova Maringá\",\n \"Nova Monte Verde\",\n \"Nova Mutum\",\n \"Nova Nazaré\",\n \"Nova Olímpia\",\n \"Nova Santa Helena\",\n \"Nova Ubiratã\",\n \"Nova Xavantina\",\n \"Novo Horizonte do Norte\",\n \"Novo Mundo\",\n \"Novo Santo Antônio\",\n \"Novo São Joaquim\",\n \"Paranaíta\",\n \"Paranatinga\",\n \"Pedra Preta\",\n \"Peixoto de Azevedo\",\n \"Planalto da Serra\",\n \"Poconé\",\n \"Pontal do Araguaia\",\n \"Ponte Branca\",\n \"Pontes e Lacerda\",\n \"Porto Alegre do Norte\",\n \"Porto dos Gaúchos\",\n \"Porto Esperidião\",\n \"Porto Estrela\",\n \"Poxoréu\",\n \"Primavera do Leste\",\n \"Querência\",\n \"Reserva do Cabaçal\",\n \"Ribeirão Cascalheira\",\n \"Ribeirãozinho\",\n \"Rio Branco\",\n \"Rondolândia\",\n \"Rondonópolis\",\n \"Rosário Oeste\",\n \"Salto do Céu\",\n \"Santa Carmem\",\n \"Santa Cruz do Xingu\",\n \"Santa Rita do Trivelato\",\n \"Santa Terezinha\",\n \"Santo Afonso\",\n \"Santo Antônio de Leverger\",\n \"Santo Antônio do Leste\",\n \"São Félix do Araguaia\",\n \"São José do Povo\",\n \"São José do Rio Claro\",\n \"São José do Xingu\",\n \"São José dos Quatro Marcos\",\n \"São Pedro da Cipa\",\n \"Sapezal\",\n \"Serra Nova Dourada\",\n \"Sinop\",\n \"Sorriso\",\n \"Tabaporã\",\n \"Tangará da Serra\",\n \"Tapurah\",\n \"Terra Nova do Norte\",\n \"Tesouro\",\n \"Torixoréu\",\n \"União do Sul\",\n \"Vale de São Domingos\",\n \"Várzea Grande\",\n \"Vera\",\n \"Vila Bela da Santíssima Trindade\",\n \"Vila Rica\"\n ]\n },\n {\n \"uf\": \"PA\",\n \"name\": \"Pará\",\n \"cities\": [\n \"Abaetetuba\",\n \"Abel Figueiredo\",\n \"Acará\",\n \"Afuá\",\n \"Água Azul do Norte\",\n \"Alenquer\",\n \"Almeirim\",\n \"Altamira\",\n \"Anajás\",\n \"Ananindeua\",\n \"Anapu\",\n \"Augusto Corrêa\",\n \"Aurora do Pará\",\n \"Aveiro\",\n \"Bagre\",\n \"Baião\",\n \"Bannach\",\n \"Barcarena\",\n \"Belém\",\n \"Belterra\",\n \"Benevides\",\n \"Bom Jesus do Tocantins\",\n \"Bonito\",\n \"Bragança\",\n \"Brasil Novo\",\n \"Brejo Grande do Araguaia\",\n \"Breu Branco\",\n \"Breves\",\n \"Bujaru\",\n \"Cachoeira do Arari\",\n \"Cachoeira do Piriá\",\n \"Cametá\",\n \"Canaã dos Carajás\",\n \"Capanema\",\n \"Capitão Poço\",\n \"Castanhal\",\n \"Chaves\",\n \"Colares\",\n \"Conceição do Araguaia\",\n \"Concórdia do Pará\",\n \"Cumaru do Norte\",\n \"Curionópolis\",\n \"Curralinho\",\n \"Curuá\",\n \"Curuçá\",\n \"Dom Eliseu\",\n \"Eldorado do Carajás\",\n \"Faro\",\n \"Floresta do Araguaia\",\n \"Garrafão do Norte\",\n \"Goianésia do Pará\",\n \"Gurupá\",\n \"Igarapé-Açu\",\n \"Igarapé-Miri\",\n \"Inhangapi\",\n \"Ipixuna do Pará\",\n \"Irituia\",\n \"Itaituba\",\n \"Itupiranga\",\n \"Jacareacanga\",\n \"Jacundá\",\n \"Juruti\",\n \"Limoeiro do Ajuru\",\n \"Mãe do Rio\",\n \"Magalhães Barata\",\n \"Marabá\",\n \"Maracanã\",\n \"Marapanim\",\n \"Marituba\",\n \"Medicilândia\",\n \"Melgaço\",\n \"Mocajuba\",\n \"Moju\",\n \"Mojuí dos Campos\",\n \"Monte Alegre\",\n \"Muaná\",\n \"Nova Esperança do Piriá\",\n \"Nova Ipixuna\",\n \"Nova Timboteua\",\n \"Novo Progresso\",\n \"Novo Repartimento\",\n \"Óbidos\",\n \"Oeiras do Pará\",\n \"Oriximiná\",\n \"Ourém\",\n \"Ourilândia do Norte\",\n \"Pacajá\",\n \"Palestina do Pará\",\n \"Paragominas\",\n \"Parauapebas\",\n \"Pau D'Arco\",\n \"Peixe-Boi\",\n \"Piçarra\",\n \"Placas\",\n \"Ponta de Pedras\",\n \"Portel\",\n \"Porto de Moz\",\n \"Prainha\",\n \"Primavera\",\n \"Quatipuru\",\n \"Redenção\",\n \"Rio Maria\",\n \"Rondon do Pará\",\n \"Rurópolis\",\n \"Salinópolis\",\n \"Salvaterra\",\n \"Santa Bárbara do Pará\",\n \"Santa Cruz do Arari\",\n \"Santa Izabel do Pará\",\n \"Santa Luzia do Pará\",\n \"Santa Maria das Barreiras\",\n \"Santa Maria do Pará\",\n \"Santana do Araguaia\",\n \"Santarém\",\n \"Santarém Novo\",\n \"Santo Antônio do Tauá\",\n \"São Caetano de Odivelas\",\n \"São Domingos do Araguaia\",\n \"São Domingos do Capim\",\n \"São Félix do Xingu\",\n \"São Francisco do Pará\",\n \"São Geraldo do Araguaia\",\n \"São João da Ponta\",\n \"São João de Pirabas\",\n \"São João do Araguaia\",\n \"São Miguel do Guamá\",\n \"São Sebastião da Boa Vista\",\n \"Sapucaia\",\n \"Senador José Porfírio\",\n \"Soure\",\n \"Tailândia\",\n \"Terra Alta\",\n \"Terra Santa\",\n \"Tomé-Açu\",\n \"Tracuateua\",\n \"Trairão\",\n \"Tucumã\",\n \"Tucuruí\",\n \"Ulianópolis\",\n \"Uruará\",\n \"Vigia\",\n \"Viseu\",\n \"Vitória do Xingu\",\n \"Xinguara\"\n ]\n },\n {\n \"uf\": \"PB\",\n \"name\": \"Paraíba\",\n \"cities\": [\n \"Água Branca\",\n \"Aguiar\",\n \"Alagoa Grande\",\n \"Alagoa Nova\",\n \"Alagoinha\",\n \"Alcantil\",\n \"Algodão de Jandaíra\",\n \"Alhandra\",\n \"Amparo\",\n \"Aparecida\",\n \"Araçagi\",\n \"Arara\",\n \"Araruna\",\n \"Areia\",\n \"Areia de Baraúnas\",\n \"Areial\",\n \"Aroeiras\",\n \"Assunção\",\n \"Baía da Traição\",\n \"Bananeiras\",\n \"Baraúna\",\n \"Barra de Santa Rosa\",\n \"Barra de Santana\",\n \"Barra de São Miguel\",\n \"Bayeux\",\n \"Belém\",\n \"Belém do Brejo do Cruz\",\n \"Bernardino Batista\",\n \"Boa Ventura\",\n \"Boa Vista\",\n \"Bom Jesus\",\n \"Bom Sucesso\",\n \"Bonito de Santa Fé\",\n \"Boqueirão\",\n \"Borborema\",\n \"Brejo do Cruz\",\n \"Brejo dos Santos\",\n \"Caaporã\",\n \"Cabaceiras\",\n \"Cabedelo\",\n \"Cachoeira dos Índios\",\n \"Cacimba de Areia\",\n \"Cacimba de Dentro\",\n \"Cacimbas\",\n \"Caiçara\",\n \"Cajazeiras\",\n \"Cajazeirinhas\",\n \"Caldas Brandão\",\n \"Camalaú\",\n \"Campina Grande\",\n \"Capim\",\n \"Caraúbas\",\n \"Carrapateira\",\n \"Casserengue\",\n \"Catingueira\",\n \"Catolé do Rocha\",\n \"Caturité\",\n \"Conceição\",\n \"Condado\",\n \"Conde\",\n \"Congo\",\n \"Coremas\",\n \"Coxixola\",\n \"Cruz do Espírito Santo\",\n \"Cubati\",\n \"Cuité\",\n \"Cuité de Mamanguape\",\n \"Cuitegi\",\n \"Curral de Cima\",\n \"Curral Velho\",\n \"Damião\",\n \"Desterro\",\n \"Diamante\",\n \"Dona Inês\",\n \"Duas Estradas\",\n \"Emas\",\n \"Esperança\",\n \"Fagundes\",\n \"Frei Martinho\",\n \"Gado Bravo\",\n \"Guarabira\",\n \"Gurinhém\",\n \"Gurjão\",\n \"Ibiara\",\n \"Igaracy\",\n \"Imaculada\",\n \"Ingá\",\n \"Itabaiana\",\n \"Itaporanga\",\n \"Itapororoca\",\n \"Itatuba\",\n \"Jacaraú\",\n \"Jericó\",\n \"João Pessoa\",\n \"Joca Claudino\",\n \"Juarez Távora\",\n \"Juazeirinho\",\n \"Junco do Seridó\",\n \"Juripiranga\",\n \"Juru\",\n \"Lagoa\",\n \"Lagoa de Dentro\",\n \"Lagoa Seca\",\n \"Lastro\",\n \"Livramento\",\n \"Logradouro\",\n \"Lucena\",\n \"Mãe d'Água\",\n \"Malta\",\n \"Mamanguape\",\n \"Manaíra\",\n \"Marcação\",\n \"Mari\",\n \"Marizópolis\",\n \"Massaranduba\",\n \"Mataraca\",\n \"Matinhas\",\n \"Mato Grosso\",\n \"Maturéia\",\n \"Mogeiro\",\n \"Montadas\",\n \"Monte Horebe\",\n \"Monteiro\",\n \"Mulungu\",\n \"Natuba\",\n \"Nazarezinho\",\n \"Nova Floresta\",\n \"Nova Olinda\",\n \"Nova Palmeira\",\n \"Olho d'Água\",\n \"Olivedos\",\n \"Ouro Velho\",\n \"Parari\",\n \"Passagem\",\n \"Patos\",\n \"Paulista\",\n \"Pedra Branca\",\n \"Pedra Lavrada\",\n \"Pedras de Fogo\",\n \"Pedro Régis\",\n \"Piancó\",\n \"Picuí\",\n \"Pilar\",\n \"Pilões\",\n \"Pilõezinhos\",\n \"Pirpirituba\",\n \"Pitimbu\",\n \"Pocinhos\",\n \"Poço Dantas\",\n \"Poço de José de Moura\",\n \"Pombal\",\n \"Prata\",\n \"Princesa Isabel\",\n \"Puxinanã\",\n \"Queimadas\",\n \"Quixaba\",\n \"Remígio\",\n \"Riachão\",\n \"Riachão do Bacamarte\",\n \"Riachão do Poço\",\n \"Riacho de Santo Antônio\",\n \"Riacho dos Cavalos\",\n \"Rio Tinto\",\n \"Salgadinho\",\n \"Salgado de São Félix\",\n \"Santa Cecília\",\n \"Santa Cruz\",\n \"Santa Helena\",\n \"Santa Inês\",\n \"Santa Luzia\",\n \"Santa Rita\",\n \"Santa Teresinha\",\n \"Santana de Mangueira\",\n \"Santana dos Garrotes\",\n \"Santo André\",\n \"São Bentinho\",\n \"São Bento\",\n \"São Domingos\",\n \"São Domingos do Cariri\",\n \"São Francisco\",\n \"São João do Cariri\",\n \"São João do Rio do Peixe\",\n \"São João do Tigre\",\n \"São José da Lagoa Tapada\",\n \"São José de Caiana\",\n \"São José de Espinharas\",\n \"São José de Piranhas\",\n \"São José de Princesa\",\n \"São José do Bonfim\",\n \"São José do Brejo do Cruz\",\n \"São José do Sabugi\",\n \"São José dos Cordeiros\",\n \"São José dos Ramos\",\n \"São Mamede\",\n \"São Miguel de Taipu\",\n \"São Sebastião de Lagoa de Roça\",\n \"São Sebastião do Umbuzeiro\",\n \"São Vicente do Seridó\",\n \"Sapé\",\n \"Serra Branca\",\n \"Serra da Raiz\",\n \"Serra Grande\",\n \"Serra Redonda\",\n \"Serraria\",\n \"Sertãozinho\",\n \"Sobrado\",\n \"Solânea\",\n \"Soledade\",\n \"Sossêgo\",\n \"Sousa\",\n \"Sumé\",\n \"Tacima\",\n \"Taperoá\",\n \"Tavares\",\n \"Teixeira\",\n \"Tenório\",\n \"Triunfo\",\n \"Uiraúna\",\n \"Umbuzeiro\",\n \"Várzea\",\n \"Vieirópolis\",\n \"Vista Serrana\",\n \"Zabelê\"\n ]\n },\n {\n \"uf\": \"PE\",\n \"name\": \"Pernambuco\",\n \"cities\": [\n \"Abreu e Lima\",\n \"Afogados da Ingazeira\",\n \"Afrânio\",\n \"Agrestina\",\n \"Água Preta\",\n \"Águas Belas\",\n \"Alagoinha\",\n \"Aliança\",\n \"Altinho\",\n \"Amaraji\",\n \"Angelim\",\n \"Araçoiaba\",\n \"Araripina\",\n \"Arcoverde\",\n \"Barra de Guabiraba\",\n \"Barreiros\",\n \"Belém de Maria\",\n \"Belém do São Francisco\",\n \"Belo Jardim\",\n \"Betânia\",\n \"Bezerros\",\n \"Bodocó\",\n \"Bom Conselho\",\n \"Bom Jardim\",\n \"Bonito\",\n \"Brejão\",\n \"Brejinho\",\n \"Brejo da Madre de Deus\",\n \"Buenos Aires\",\n \"Buíque\",\n \"Cabo de Santo Agostinho\",\n \"Cabrobó\",\n \"Cachoeirinha\",\n \"Caetés\",\n \"Calçado\",\n \"Calumbi\",\n \"Camaragibe\",\n \"Camocim de São Félix\",\n \"Camutanga\",\n \"Canhotinho\",\n \"Capoeiras\",\n \"Carnaíba\",\n \"Carnaubeira da Penha\",\n \"Carpina\",\n \"Caruaru\",\n \"Casinhas\",\n \"Catende\",\n \"Cedro\",\n \"Chã de Alegria\",\n \"Chã Grande\",\n \"Condado\",\n \"Correntes\",\n \"Cortês\",\n \"Cumaru\",\n \"Cupira\",\n \"Custódia\",\n \"Dormentes\",\n \"Escada\",\n \"Exu\",\n \"Feira Nova\",\n \"Fernando de Noronha\",\n \"Ferreiros\",\n \"Flores\",\n \"Floresta\",\n \"Frei Miguelinho\",\n \"Gameleira\",\n \"Garanhuns\",\n \"Glória do Goitá\",\n \"Goiana\",\n \"Granito\",\n \"Gravatá\",\n \"Iati\",\n \"Ibimirim\",\n \"Ibirajuba\",\n \"Igarassu\",\n \"Iguaracy\",\n \"Ilha de Itamaracá\",\n \"Inajá\",\n \"Ingazeira\",\n \"Ipojuca\",\n \"Ipubi\",\n \"Itacuruba\",\n \"Itaíba\",\n \"Itambé\",\n \"Itapetim\",\n \"Itapissuma\",\n \"Itaquitinga\",\n \"Jaboatão dos Guararapes\",\n \"Jaqueira\",\n \"Jataúba\",\n \"Jatobá\",\n \"João Alfredo\",\n \"Joaquim Nabuco\",\n \"Jucati\",\n \"Jupi\",\n \"Jurema\",\n \"Lagoa de Itaenga\",\n \"Lagoa do Carro\",\n \"Lagoa do Ouro\",\n \"Lagoa dos Gatos\",\n \"Lagoa Grande\",\n \"Lajedo\",\n \"Limoeiro\",\n \"Macaparana\",\n \"Machados\",\n \"Manari\",\n \"Maraial\",\n \"Mirandiba\",\n \"Moreilândia\",\n \"Moreno\",\n \"Nazaré da Mata\",\n \"Olinda\",\n \"Orobó\",\n \"Orocó\",\n \"Ouricuri\",\n \"Palmares\",\n \"Palmeirina\",\n \"Panelas\",\n \"Paranatama\",\n \"Parnamirim\",\n \"Passira\",\n \"Paudalho\",\n \"Paulista\",\n \"Pedra\",\n \"Pesqueira\",\n \"Petrolândia\",\n \"Petrolina\",\n \"Poção\",\n \"Pombos\",\n \"Primavera\",\n \"Quipapá\",\n \"Quixaba\",\n \"Recife\",\n \"Riacho das Almas\",\n \"Ribeirão\",\n \"Rio Formoso\",\n \"Sairé\",\n \"Salgadinho\",\n \"Salgueiro\",\n \"Saloá\",\n \"Sanharó\",\n \"Santa Cruz\",\n \"Santa Cruz da Baixa Verde\",\n \"Santa Cruz do Capibaribe\",\n \"Santa Filomena\",\n \"Santa Maria da Boa Vista\",\n \"Santa Maria do Cambucá\",\n \"Santa Terezinha\",\n \"São Benedito do Sul\",\n \"São Bento do Una\",\n \"São Caitano\",\n \"São João\",\n \"São Joaquim do Monte\",\n \"São José da Coroa Grande\",\n \"São José do Belmonte\",\n \"São José do Egito\",\n \"São Lourenço da Mata\",\n \"São Vicente Férrer\",\n \"Serra Talhada\",\n \"Serrita\",\n \"Sertânia\",\n \"Sirinhaém\",\n \"Solidão\",\n \"Surubim\",\n \"Tabira\",\n \"Tacaimbó\",\n \"Tacaratu\",\n \"Tamandaré\",\n \"Taquaritinga do Norte\",\n \"Terezinha\",\n \"Terra Nova\",\n \"Timbaúba\",\n \"Toritama\",\n \"Tracunhaém\",\n \"Trindade\",\n \"Triunfo\",\n \"Tupanatinga\",\n \"Tuparetama\",\n \"Venturosa\",\n \"Verdejante\",\n \"Vertente do Lério\",\n \"Vertentes\",\n \"Vicência\",\n \"Vitória de Santo Antão\",\n \"Xexéu\"\n ]\n },\n {\n \"uf\": \"PI\",\n \"name\": \"Piauí\",\n \"cities\": [\n \"Acauã\",\n \"Agricolândia\",\n \"Água Branca\",\n \"Alagoinha do Piauí\",\n \"Alegrete do Piauí\",\n \"Alto Longá\",\n \"Altos\",\n \"Alvorada do Gurguéia\",\n \"Amarante\",\n \"Angical do Piauí\",\n \"Anísio de Abreu\",\n \"Antônio Almeida\",\n \"Aroazes\",\n \"Aroeiras do Itaim\",\n \"Arraial\",\n \"Assunção do Piauí\",\n \"Avelino Lopes\",\n \"Baixa Grande do Ribeiro\",\n \"Barra D'Alcântara\",\n \"Barras\",\n \"Barreiras do Piauí\",\n \"Barro Duro\",\n \"Batalha\",\n \"Bela Vista do Piauí\",\n \"Belém do Piauí\",\n \"Beneditinos\",\n \"Bertolínia\",\n \"Betânia do Piauí\",\n \"Boa Hora\",\n \"Bocaina\",\n \"Bom Jesus\",\n \"Bom Princípio do Piauí\",\n \"Bonfim do Piauí\",\n \"Boqueirão do Piauí\",\n \"Brasileira\",\n \"Brejo do Piauí\",\n \"Buriti dos Lopes\",\n \"Buriti dos Montes\",\n \"Cabeceiras do Piauí\",\n \"Cajazeiras do Piauí\",\n \"Cajueiro da Praia\",\n \"Caldeirão Grande do Piauí\",\n \"Campinas do Piauí\",\n \"Campo Alegre do Fidalgo\",\n \"Campo Grande do Piauí\",\n \"Campo Largo do Piauí\",\n \"Campo Maior\",\n \"Canavieira\",\n \"Canto do Buriti\",\n \"Capitão de Campos\",\n \"Capitão Gervásio Oliveira\",\n \"Caracol\",\n \"Caraúbas do Piauí\",\n \"Caridade do Piauí\",\n \"Castelo do Piauí\",\n \"Caxingó\",\n \"Cocal\",\n \"Cocal de Telha\",\n \"Cocal dos Alves\",\n \"Coivaras\",\n \"Colônia do Gurguéia\",\n \"Colônia do Piauí\",\n \"Conceição do Canindé\",\n \"Coronel José Dias\",\n \"Corrente\",\n \"Cristalândia do Piauí\",\n \"Cristino Castro\",\n \"Curimatá\",\n \"Currais\",\n \"Curral Novo do Piauí\",\n \"Curralinhos\",\n \"Demerval Lobão\",\n \"Dirceu Arcoverde\",\n \"Dom Expedito Lopes\",\n \"Dom Inocêncio\",\n \"Domingos Mourão\",\n \"Elesbão Veloso\",\n \"Eliseu Martins\",\n \"Esperantina\",\n \"Fartura do Piauí\",\n \"Flores do Piauí\",\n \"Floresta do Piauí\",\n \"Floriano\",\n \"Francinópolis\",\n \"Francisco Ayres\",\n \"Francisco Macedo\",\n \"Francisco Santos\",\n \"Fronteiras\",\n \"Geminiano\",\n \"Gilbués\",\n \"Guadalupe\",\n \"Guaribas\",\n \"Hugo Napoleão\",\n \"Ilha Grande\",\n \"Inhuma\",\n \"Ipiranga do Piauí\",\n \"Isaías Coelho\",\n \"Itainópolis\",\n \"Itaueira\",\n \"Jacobina do Piauí\",\n \"Jaicós\",\n \"Jardim do Mulato\",\n \"Jatobá do Piauí\",\n \"Jerumenha\",\n \"João Costa\",\n \"Joaquim Pires\",\n \"Joca Marques\",\n \"José de Freitas\",\n \"Juazeiro do Piauí\",\n \"Júlio Borges\",\n \"Jurema\",\n \"Lagoa Alegre\",\n \"Lagoa de São Francisco\",\n \"Lagoa do Barro do Piauí\",\n \"Lagoa do Piauí\",\n \"Lagoa do Sítio\",\n \"Lagoinha do Piauí\",\n \"Landri Sales\",\n \"Luís Correia\",\n \"Luzilândia\",\n \"Madeiro\",\n \"Manoel Emídio\",\n \"Marcolândia\",\n \"Marcos Parente\",\n \"Massapê do Piauí\",\n \"Matias Olímpio\",\n \"Miguel Alves\",\n \"Miguel Leão\",\n \"Milton Brandão\",\n \"Monsenhor Gil\",\n \"Monsenhor Hipólito\",\n \"Monte Alegre do Piauí\",\n \"Morro Cabeça no Tempo\",\n \"Morro do Chapéu do Piauí\",\n \"Murici dos Portelas\",\n \"Nazaré do Piauí\",\n \"Nazária\",\n \"Nossa Senhora de Nazaré\",\n \"Nossa Senhora dos Remédios\",\n \"Nova Santa Rita\",\n \"Novo Oriente do Piauí\",\n \"Novo Santo Antônio\",\n \"Oeiras\",\n \"Olho D'Água do Piauí\",\n \"Padre Marcos\",\n \"Paes Landim\",\n \"Pajeú do Piauí\",\n \"Palmeira do Piauí\",\n \"Palmeirais\",\n \"Paquetá\",\n \"Parnaguá\",\n \"Parnaíba\",\n \"Passagem Franca do Piauí\",\n \"Patos do Piauí\",\n \"Pau D'Arco do Piauí\",\n \"Paulistana\",\n \"Pavussu\",\n \"Pedro II\",\n \"Pedro Laurentino\",\n \"Picos\",\n \"Pimenteiras\",\n \"Pio IX\",\n \"Piracuruca\",\n \"Piripiri\",\n \"Porto\",\n \"Porto Alegre do Piauí\",\n \"Prata do Piauí\",\n \"Queimada Nova\",\n \"Redenção do Gurguéia\",\n \"Regeneração\",\n \"Riacho Frio\",\n \"Ribeira do Piauí\",\n \"Ribeiro Gonçalves\",\n \"Rio Grande do Piauí\",\n \"Santa Cruz do Piauí\",\n \"Santa Cruz dos Milagres\",\n \"Santa Filomena\",\n \"Santa Luz\",\n \"Santa Rosa do Piauí\",\n \"Santana do Piauí\",\n \"Santo Antônio de Lisboa\",\n \"Santo Antônio dos Milagres\",\n \"Santo Inácio do Piauí\",\n \"São Braz do Piauí\",\n \"São Félix do Piauí\",\n \"São Francisco de Assis do Piauí\",\n \"São Francisco do Piauí\",\n \"São Gonçalo do Gurguéia\",\n \"São Gonçalo do Piauí\",\n \"São João da Canabrava\",\n \"São João da Fronteira\",\n \"São João da Serra\",\n \"São João da Varjota\",\n \"São João do Arraial\",\n \"São João do Piauí\",\n \"São José do Divino\",\n \"São José do Peixe\",\n \"São José do Piauí\",\n \"São Julião\",\n \"São Lourenço do Piauí\",\n \"São Luis do Piauí\",\n \"São Miguel da Baixa Grande\",\n \"São Miguel do Fidalgo\",\n \"São Miguel do Tapuio\",\n \"São Pedro do Piauí\",\n \"São Raimundo Nonato\",\n \"Sebastião Barros\",\n \"Sebastião Leal\",\n \"Sigefredo Pacheco\",\n \"Simões\",\n \"Simplício Mendes\",\n \"Socorro do Piauí\",\n \"Sussuapara\",\n \"Tamboril do Piauí\",\n \"Tanque do Piauí\",\n \"Teresina\",\n \"União\",\n \"Uruçuí\",\n \"Valença do Piauí\",\n \"Várzea Branca\",\n \"Várzea Grande\",\n \"Vera Mendes\",\n \"Vila Nova do Piauí\",\n \"Wall Ferraz\"\n ]\n },\n {\n \"uf\": \"PR\",\n \"name\": \"Paraná\",\n \"cities\": [\n \"Abatiá\",\n \"Adrianópolis\",\n \"Agudos do Sul\",\n \"Almirante Tamandaré\",\n \"Altamira do Paraná\",\n \"Alto Paraíso\",\n \"Alto Paraná\",\n \"Alto Piquiri\",\n \"Altônia\",\n \"Alvorada do Sul\",\n \"Amaporã\",\n \"Ampére\",\n \"Anahy\",\n \"Andirá\",\n \"Ângulo\",\n \"Antonina\",\n \"Antônio Olinto\",\n \"Apucarana\",\n \"Arapongas\",\n \"Arapoti\",\n \"Arapuã\",\n \"Araruna\",\n \"Araucária\",\n \"Ariranha do Ivaí\",\n \"Assaí\",\n \"Assis Chateaubriand\",\n \"Astorga\",\n \"Atalaia\",\n \"Balsa Nova\",\n \"Bandeirantes\",\n \"Barbosa Ferraz\",\n \"Barra do Jacaré\",\n \"Barracão\",\n \"Bela Vista da Caroba\",\n \"Bela Vista do Paraíso\",\n \"Bituruna\",\n \"Boa Esperança\",\n \"Boa Esperança do Iguaçu\",\n \"Boa Ventura de São Roque\",\n \"Boa Vista da Aparecida\",\n \"Bocaiúva do Sul\",\n \"Bom Jesus do Sul\",\n \"Bom Sucesso\",\n \"Bom Sucesso do Sul\",\n \"Borrazópolis\",\n \"Braganey\",\n \"Brasilândia do Sul\",\n \"Cafeara\",\n \"Cafelândia\",\n \"Cafezal do Sul\",\n \"Califórnia\",\n \"Cambará\",\n \"Cambé\",\n \"Cambira\",\n \"Campina da Lagoa\",\n \"Campina do Simão\",\n \"Campina Grande do Sul\",\n \"Campo Bonito\",\n \"Campo do Tenente\",\n \"Campo Largo\",\n \"Campo Magro\",\n \"Campo Mourão\",\n \"Cândido de Abreu\",\n \"Candói\",\n \"Cantagalo\",\n \"Capanema\",\n \"Capitão Leônidas Marques\",\n \"Carambeí\",\n \"Carlópolis\",\n \"Cascavel\",\n \"Castro\",\n \"Catanduvas\",\n \"Centenário do Sul\",\n \"Cerro Azul\",\n \"Céu Azul\",\n \"Chopinzinho\",\n \"Cianorte\",\n \"Cidade Gaúcha\",\n \"Clevelândia\",\n \"Colombo\",\n \"Colorado\",\n \"Congonhinhas\",\n \"Conselheiro Mairinck\",\n \"Contenda\",\n \"Corbélia\",\n \"Cornélio Procópio\",\n \"Coronel Domingos Soares\",\n \"Coronel Vivida\",\n \"Corumbataí do Sul\",\n \"Cruz Machado\",\n \"Cruzeiro do Iguaçu\",\n \"Cruzeiro do Oeste\",\n \"Cruzeiro do Sul\",\n \"Cruzmaltina\",\n \"Curitiba\",\n \"Curiúva\",\n \"Diamante D'Oeste\",\n \"Diamante do Norte\",\n \"Diamante do Sul\",\n \"Dois Vizinhos\",\n \"Douradina\",\n \"Doutor Camargo\",\n \"Doutor Ulysses\",\n \"Enéas Marques\",\n \"Engenheiro Beltrão\",\n \"Entre Rios do Oeste\",\n \"Esperança Nova\",\n \"Espigão Alto do Iguaçu\",\n \"Farol\",\n \"Faxinal\",\n \"Fazenda Rio Grande\",\n \"Fênix\",\n \"Fernandes Pinheiro\",\n \"Figueira\",\n \"Flor da Serra do Sul\",\n \"Floraí\",\n \"Floresta\",\n \"Florestópolis\",\n \"Flórida\",\n \"Formosa do Oeste\",\n \"Foz do Iguaçu\",\n \"Foz do Jordão\",\n \"Francisco Alves\",\n \"Francisco Beltrão\",\n \"General Carneiro\",\n \"Godoy Moreira\",\n \"Goioerê\",\n \"Goioxim\",\n \"Grandes Rios\",\n \"Guaíra\",\n \"Guairaçá\",\n \"Guamiranga\",\n \"Guapirama\",\n \"Guaporema\",\n \"Guaraci\",\n \"Guaraniaçu\",\n \"Guarapuava\",\n \"Guaraqueçaba\",\n \"Guaratuba\",\n \"Honório Serpa\",\n \"Ibaiti\",\n \"Ibema\",\n \"Ibiporã\",\n \"Icaraíma\",\n \"Iguaraçu\",\n \"Iguatu\",\n \"Imbaú\",\n \"Imbituva\",\n \"Inácio Martins\",\n \"Inajá\",\n \"Indianópolis\",\n \"Ipiranga\",\n \"Iporã\",\n \"Iracema do Oeste\",\n \"Irati\",\n \"Iretama\",\n \"Itaguajé\",\n \"Itaipulândia\",\n \"Itambaracá\",\n \"Itambé\",\n \"Itapejara d'Oeste\",\n \"Itaperuçu\",\n \"Itaúna do Sul\",\n \"Ivaí\",\n \"Ivaiporã\",\n \"Ivaté\",\n \"Ivatuba\",\n \"Jaboti\",\n \"Jacarezinho\",\n \"Jaguapitã\",\n \"Jaguariaíva\",\n \"Jandaia do Sul\",\n \"Janiópolis\",\n \"Japira\",\n \"Japurá\",\n \"Jardim Alegre\",\n \"Jardim Olinda\",\n \"Jataizinho\",\n \"Jesuítas\",\n \"Joaquim Távora\",\n \"Jundiaí do Sul\",\n \"Juranda\",\n \"Jussara\",\n \"Kaloré\",\n \"Lapa\",\n \"Laranjal\",\n \"Laranjeiras do Sul\",\n \"Leópolis\",\n \"Lidianópolis\",\n \"Lindoeste\",\n \"Loanda\",\n \"Lobato\",\n \"Londrina\",\n \"Luiziana\",\n \"Lunardelli\",\n \"Lupionópolis\",\n \"Mallet\",\n \"Mamborê\",\n \"Mandaguaçu\",\n \"Mandaguari\",\n \"Mandirituba\",\n \"Manfrinópolis\",\n \"Mangueirinha\",\n \"Manoel Ribas\",\n \"Marechal Cândido Rondon\",\n \"Maria Helena\",\n \"Marialva\",\n \"Marilândia do Sul\",\n \"Marilena\",\n \"Mariluz\",\n \"Maringá\",\n \"Mariópolis\",\n \"Maripá\",\n \"Marmeleiro\",\n \"Marquinho\",\n \"Marumbi\",\n \"Matelândia\",\n \"Matinhos\",\n \"Mato Rico\",\n \"Mauá da Serra\",\n \"Medianeira\",\n \"Mercedes\",\n \"Mirador\",\n \"Miraselva\",\n \"Missal\",\n \"Moreira Sales\",\n \"Morretes\",\n \"Munhoz de Melo\",\n \"Nossa Senhora das Graças\",\n \"Nova Aliança do Ivaí\",\n \"Nova América da Colina\",\n \"Nova Aurora\",\n \"Nova Cantu\",\n \"Nova Esperança\",\n \"Nova Esperança do Sudoeste\",\n \"Nova Fátima\",\n \"Nova Laranjeiras\",\n \"Nova Londrina\",\n \"Nova Olímpia\",\n \"Nova Prata do Iguaçu\",\n \"Nova Santa Bárbara\",\n \"Nova Santa Rosa\",\n \"Nova Tebas\",\n \"Novo Itacolomi\",\n \"Ortigueira\",\n \"Ourizona\",\n \"Ouro Verde do Oeste\",\n \"Paiçandu\",\n \"Palmas\",\n \"Palmeira\",\n \"Palmital\",\n \"Palotina\",\n \"Paraíso do Norte\",\n \"Paranacity\",\n \"Paranaguá\",\n \"Paranapoema\",\n \"Paranavaí\",\n \"Pato Bragado\",\n \"Pato Branco\",\n \"Paula Freitas\",\n \"Paulo Frontin\",\n \"Peabiru\",\n \"Perobal\",\n \"Pérola\",\n \"Pérola d'Oeste\",\n \"Piên\",\n \"Pinhais\",\n \"Pinhal de São Bento\",\n \"Pinhalão\",\n \"Pinhão\",\n \"Piraí do Sul\",\n \"Piraquara\",\n \"Pitanga\",\n \"Pitangueiras\",\n \"Planaltina do Paraná\",\n \"Planalto\",\n \"Ponta Grossa\",\n \"Pontal do Paraná\",\n \"Porecatu\",\n \"Porto Amazonas\",\n \"Porto Barreiro\",\n \"Porto Rico\",\n \"Porto Vitória\",\n \"Prado Ferreira\",\n \"Pranchita\",\n \"Presidente Castelo Branco\",\n \"Primeiro de Maio\",\n \"Prudentópolis\",\n \"Quarto Centenário\",\n \"Quatiguá\",\n \"Quatro Barras\",\n \"Quatro Pontes\",\n \"Quedas do Iguaçu\",\n \"Querência do Norte\",\n \"Quinta do Sol\",\n \"Quitandinha\",\n \"Ramilândia\",\n \"Rancho Alegre\",\n \"Rancho Alegre D'Oeste\",\n \"Realeza\",\n \"Rebouças\",\n \"Renascença\",\n \"Reserva\",\n \"Reserva do Iguaçu\",\n \"Ribeirão Claro\",\n \"Ribeirão do Pinhal\",\n \"Rio Azul\",\n \"Rio Bom\",\n \"Rio Bonito do Iguaçu\",\n \"Rio Branco do Ivaí\",\n \"Rio Branco do Sul\",\n \"Rio Negro\",\n \"Rolândia\",\n \"Roncador\",\n \"Rondon\",\n \"Rosário do Ivaí\",\n \"Sabáudia\",\n \"Salgado Filho\",\n \"Salto do Itararé\",\n \"Salto do Lontra\",\n \"Santa Amélia\",\n \"Santa Cecília do Pavão\",\n \"Santa Cruz de Monte Castelo\",\n \"Santa Fé\",\n \"Santa Helena\",\n \"Santa Inês\",\n \"Santa Isabel do Ivaí\",\n \"Santa Izabel do Oeste\",\n \"Santa Lúcia\",\n \"Santa Maria do Oeste\",\n \"Santa Mariana\",\n \"Santa Mônica\",\n \"Santa Tereza do Oeste\",\n \"Santa Terezinha de Itaipu\",\n \"Santana do Itararé\",\n \"Santo Antônio da Platina\",\n \"Santo Antônio do Caiuá\",\n \"Santo Antônio do Paraíso\",\n \"Santo Antônio do Sudoeste\",\n \"Santo Inácio\",\n \"São Carlos do Ivaí\",\n \"São Jerônimo da Serra\",\n \"São João\",\n \"São João do Caiuá\",\n \"São João do Ivaí\",\n \"São João do Triunfo\",\n \"São Jorge d'Oeste\",\n \"São Jorge do Ivaí\",\n \"São Jorge do Patrocínio\",\n \"São José da Boa Vista\",\n \"São José das Palmeiras\",\n \"São José dos Pinhais\",\n \"São Manoel do Paraná\",\n \"São Mateus do Sul\",\n \"São Miguel do Iguaçu\",\n \"São Pedro do Iguaçu\",\n \"São Pedro do Ivaí\",\n \"São Pedro do Paraná\",\n \"São Sebastião da Amoreira\",\n \"São Tomé\",\n \"Sapopema\",\n \"Sarandi\",\n \"Saudade do Iguaçu\",\n \"Sengés\",\n \"Serranópolis do Iguaçu\",\n \"Sertaneja\",\n \"Sertanópolis\",\n \"Siqueira Campos\",\n \"Sulina\",\n \"Tamarana\",\n \"Tamboara\",\n \"Tapejara\",\n \"Tapira\",\n \"Teixeira Soares\",\n \"Telêmaco Borba\",\n \"Terra Boa\",\n \"Terra Rica\",\n \"Terra Roxa\",\n \"Tibagi\",\n \"Tijucas do Sul\",\n \"Toledo\",\n \"Tomazina\",\n \"Três Barras do Paraná\",\n \"Tunas do Paraná\",\n \"Tuneiras do Oeste\",\n \"Tupãssi\",\n \"Turvo\",\n \"Ubiratã\",\n \"Umuarama\",\n \"União da Vitória\",\n \"Uniflor\",\n \"Uraí\",\n \"Ventania\",\n \"Vera Cruz do Oeste\",\n \"Verê\",\n \"Virmond\",\n \"Vitorino\",\n \"Wenceslau Braz\",\n \"Xambrê\"\n ]\n },\n {\n \"uf\": \"RJ\",\n \"name\": \"Rio de Janeiro\",\n \"cities\": [\n \"Angra dos Reis\",\n \"Aperibé\",\n \"Araruama\",\n \"Areal\",\n \"Armação dos Búzios\",\n \"Arraial do Cabo\",\n \"Barra do Piraí\",\n \"Barra Mansa\",\n \"Belford Roxo\",\n \"Bom Jardim\",\n \"Bom Jesus do Itabapoana\",\n \"Cabo Frio\",\n \"Cachoeiras de Macacu\",\n \"Cambuci\",\n \"Campos dos Goytacazes\",\n \"Cantagalo\",\n \"Carapebus\",\n \"Cardoso Moreira\",\n \"Carmo\",\n \"Casimiro de Abreu\",\n \"Comendador Levy Gasparian\",\n \"Conceição de Macabu\",\n \"Cordeiro\",\n \"Duas Barras\",\n \"Duque de Caxias\",\n \"Engenheiro Paulo de Frontin\",\n \"Guapimirim\",\n \"Iguaba Grande\",\n \"Itaboraí\",\n \"Itaguaí\",\n \"Italva\",\n \"Itaocara\",\n \"Itaperuna\",\n \"Itatiaia\",\n \"Japeri\",\n \"Laje do Muriaé\",\n \"Macaé\",\n \"Macuco\",\n \"Magé\",\n \"Mangaratiba\",\n \"Maricá\",\n \"Mendes\",\n \"Mesquita\",\n \"Miguel Pereira\",\n \"Miracema\",\n \"Natividade\",\n \"Nilópolis\",\n \"Niterói\",\n \"Nova Friburgo\",\n \"Nova Iguaçu\",\n \"Paracambi\",\n \"Paraíba do Sul\",\n \"Paraty\",\n \"Paty do Alferes\",\n \"Petrópolis\",\n \"Pinheiral\",\n \"Piraí\",\n \"Porciúncula\",\n \"Porto Real\",\n \"Quatis\",\n \"Queimados\",\n \"Quissamã\",\n \"Resende\",\n \"Rio Bonito\",\n \"Rio Claro\",\n \"Rio das Flores\",\n \"Rio das Ostras\",\n \"Rio de Janeiro\",\n \"Santa Maria Madalena\",\n \"Santo Antônio de Pádua\",\n \"São Fidélis\",\n \"São Francisco de Itabapoana\",\n \"São Gonçalo\",\n \"São João da Barra\",\n \"São João de Meriti\",\n \"São José de Ubá\",\n \"São José do Vale do Rio Preto\",\n \"São Pedro da Aldeia\",\n \"São Sebastião do Alto\",\n \"Sapucaia\",\n \"Saquarema\",\n \"Seropédica\",\n \"Silva Jardim\",\n \"Sumidouro\",\n \"Tanguá\",\n \"Teresópolis\",\n \"Trajano de Moraes\",\n \"Três Rios\",\n \"Valença\",\n \"Varre-Sai\",\n \"Vassouras\",\n \"Volta Redonda\"\n ]\n },\n {\n \"uf\": \"RN\",\n \"name\": \"Rio Grande do Norte\",\n \"cities\": [\n \"Acari\",\n \"Afonso Bezerra\",\n \"Água Nova\",\n \"Alexandria\",\n \"Almino Afonso\",\n \"Alto do Rodrigues\",\n \"Angicos\",\n \"Antônio Martins\",\n \"Apodi\",\n \"Areia Branca\",\n \"Arez\",\n \"Assú\",\n \"Baía Formosa\",\n \"Baraúna\",\n \"Barcelona\",\n \"Bento Fernandes\",\n \"Bodó\",\n \"Bom Jesus\",\n \"Brejinho\",\n \"Caiçara do Norte\",\n \"Caiçara do Rio do Vento\",\n \"Caicó\",\n \"Campo Grande\",\n \"Campo Redondo\",\n \"Canguaretama\",\n \"Caraúbas\",\n \"Carnaúba dos Dantas\",\n \"Carnaubais\",\n \"Ceará-Mirim\",\n \"Cerro Corá\",\n \"Coronel Ezequiel\",\n \"Coronel João Pessoa\",\n \"Cruzeta\",\n \"Currais Novos\",\n \"Doutor Severiano\",\n \"Encanto\",\n \"Equador\",\n \"Espírito Santo\",\n \"Extremoz\",\n \"Felipe Guerra\",\n \"Fernando Pedroza\",\n \"Florânia\",\n \"Francisco Dantas\",\n \"Frutuoso Gomes\",\n \"Galinhos\",\n \"Goianinha\",\n \"Governador Dix-Sept Rosado\",\n \"Grossos\",\n \"Guamaré\",\n \"Ielmo Marinho\",\n \"Ipanguaçu\",\n \"Ipueira\",\n \"Itajá\",\n \"Itaú\",\n \"Jaçanã\",\n \"Jandaíra\",\n \"Janduís\",\n \"Januário Cicco\",\n \"Japi\",\n \"Jardim de Angicos\",\n \"Jardim de Piranhas\",\n \"Jardim do Seridó\",\n \"João Câmara\",\n \"João Dias\",\n \"José da Penha\",\n \"Jucurutu\",\n \"Jundiá\",\n \"Lagoa d'Anta\",\n \"Lagoa de Pedras\",\n \"Lagoa de Velhos\",\n \"Lagoa Nova\",\n \"Lagoa Salgada\",\n \"Lajes\",\n \"Lajes Pintadas\",\n \"Lucrécia\",\n \"Luís Gomes\",\n \"Macaíba\",\n \"Macau\",\n \"Major Sales\",\n \"Marcelino Vieira\",\n \"Martins\",\n \"Maxaranguape\",\n \"Messias Targino\",\n \"Montanhas\",\n \"Monte Alegre\",\n \"Monte das Gameleiras\",\n \"Mossoró\",\n \"Natal\",\n \"Nísia Floresta\",\n \"Nova Cruz\",\n \"Olho d'Água do Borges\",\n \"Ouro Branco\",\n \"Paraná\",\n \"Paraú\",\n \"Parazinho\",\n \"Parelhas\",\n \"Parnamirim\",\n \"Passa e Fica\",\n \"Passagem\",\n \"Patu\",\n \"Pau dos Ferros\",\n \"Pedra Grande\",\n \"Pedra Preta\",\n \"Pedro Avelino\",\n \"Pedro Velho\",\n \"Pendências\",\n \"Pilões\",\n \"Poço Branco\",\n \"Portalegre\",\n \"Porto do Mangue\",\n \"Pureza\",\n \"Rafael Fernandes\",\n \"Rafael Godeiro\",\n \"Riacho da Cruz\",\n \"Riacho de Santana\",\n \"Riachuelo\",\n \"Rio do Fogo\",\n \"Rodolfo Fernandes\",\n \"Ruy Barbosa\",\n \"Santa Cruz\",\n \"Santa Maria\",\n \"Santana do Matos\",\n \"Santana do Seridó\",\n \"Santo Antônio\",\n \"São Bento do Norte\",\n \"São Bento do Trairí\",\n \"São Fernando\",\n \"São Francisco do Oeste\",\n \"São Gonçalo do Amarante\",\n \"São João do Sabugi\",\n \"São José de Mipibu\",\n \"São José do Campestre\",\n \"São José do Seridó\",\n \"São Miguel\",\n \"São Miguel do Gostoso\",\n \"São Paulo do Potengi\",\n \"São Pedro\",\n \"São Rafael\",\n \"São Tomé\",\n \"São Vicente\",\n \"Senador Elói de Souza\",\n \"Senador Georgino Avelino\",\n \"Serra Caiada\",\n \"Serra de São Bento\",\n \"Serra do Mel\",\n \"Serra Negra do Norte\",\n \"Serrinha\",\n \"Serrinha dos Pintos\",\n \"Severiano Melo\",\n \"Sítio Novo\",\n \"Taboleiro Grande\",\n \"Taipu\",\n \"Tangará\",\n \"Tenente Ananias\",\n \"Tenente Laurentino Cruz\",\n \"Tibau\",\n \"Tibau do Sul\",\n \"Timbaúba dos Batistas\",\n \"Touros\",\n \"Triunfo Potiguar\",\n \"Umarizal\",\n \"Upanema\",\n \"Várzea\",\n \"Venha-Ver\",\n \"Vera Cruz\",\n \"Viçosa\",\n \"Vila Flor\"\n ]\n },\n {\n \"uf\": \"RO\",\n \"name\": \"Rondônia\",\n \"cities\": [\n \"Alta Floresta D'Oeste\",\n \"Alto Alegre dos Parecis\",\n \"Alto Paraíso\",\n \"Alvorada D'Oeste\",\n \"Ariquemes\",\n \"Buritis\",\n \"Cabixi\",\n \"Cacaulândia\",\n \"Cacoal\",\n \"Campo Novo de Rondônia\",\n \"Candeias do Jamari\",\n \"Castanheiras\",\n \"Cerejeiras\",\n \"Chupinguaia\",\n \"Colorado do Oeste\",\n \"Corumbiara\",\n \"Costa Marques\",\n \"Cujubim\",\n \"Espigão D'Oeste\",\n \"Governador Jorge Teixeira\",\n \"Guajará-Mirim\",\n \"Itapuã do Oeste\",\n \"Jaru\",\n \"Ji-Paraná\",\n \"Machadinho D'Oeste\",\n \"Ministro Andreazza\",\n \"Mirante da Serra\",\n \"Monte Negro\",\n \"Nova Brasilândia D'Oeste\",\n \"Nova Mamoré\",\n \"Nova União\",\n \"Novo Horizonte do Oeste\",\n \"Ouro Preto do Oeste\",\n \"Parecis\",\n \"Pimenta Bueno\",\n \"Pimenteiras do Oeste\",\n \"Porto Velho\",\n \"Presidente Médici\",\n \"Primavera de Rondônia\",\n \"Rio Crespo\",\n \"Rolim de Moura\",\n \"Santa Luzia D'Oeste\",\n \"São Felipe D'Oeste\",\n \"São Francisco do Guaporé\",\n \"São Miguel do Guaporé\",\n \"Seringueiras\",\n \"Teixeirópolis\",\n \"Theobroma\",\n \"Urupá\",\n \"Vale do Anari\",\n \"Vale do Paraíso\",\n \"Vilhena\"\n ]\n },\n {\n \"uf\": \"RR\",\n \"name\": \"Roraima\",\n \"cities\": [\n \"Alto Alegre\",\n \"Amajari\",\n \"Boa Vista\",\n \"Bonfim\",\n \"Cantá\",\n \"Caracaraí\",\n \"Caroebe\",\n \"Iracema\",\n \"Mucajaí\",\n \"Normandia\",\n \"Pacaraima\",\n \"Rorainópolis\",\n \"São João da Baliza\",\n \"São Luiz do Anauá\",\n \"Uiramutã\"\n ]\n },\n {\n \"uf\": \"RS\",\n \"name\": \"Rio Grande do Sul\",\n \"cities\": [\n \"Aceguá\",\n \"Água Santa\",\n \"Agudo\",\n \"Ajuricaba\",\n \"Alecrim\",\n \"Alegrete\",\n \"Alegria\",\n \"Almirante Tamandaré do Sul\",\n \"Alpestre\",\n \"Alto Alegre\",\n \"Alto Feliz\",\n \"Alvorada\",\n \"Amaral Ferrador\",\n \"Ametista do Sul\",\n \"André da Rocha\",\n \"Anta Gorda\",\n \"Antônio Prado\",\n \"Arambaré\",\n \"Araricá\",\n \"Aratiba\",\n \"Arroio do Meio\",\n \"Arroio do Padre\",\n \"Arroio do Sal\",\n \"Arroio do Tigre\",\n \"Arroio dos Ratos\",\n \"Arroio Grande\",\n \"Arvorezinha\",\n \"Augusto Pestana\",\n \"Áurea\",\n \"Bagé\",\n \"Balneário Pinhal\",\n \"Barão\",\n \"Barão de Cotegipe\",\n \"Barão do Triunfo\",\n \"Barra do Guarita\",\n \"Barra do Quaraí\",\n \"Barra do Ribeiro\",\n \"Barra do Rio Azul\",\n \"Barra Funda\",\n \"Barracão\",\n \"Barros Cassal\",\n \"Benjamin Constant do Sul\",\n \"Bento Gonçalves\",\n \"Boa Vista das Missões\",\n \"Boa Vista do Buricá\",\n \"Boa Vista do Cadeado\",\n \"Boa Vista do Incra\",\n \"Boa Vista do Sul\",\n \"Bom Jesus\",\n \"Bom Princípio\",\n \"Bom Progresso\",\n \"Bom Retiro do Sul\",\n \"Boqueirão do Leão\",\n \"Bossoroca\",\n \"Bozano\",\n \"Braga\",\n \"Brochier\",\n \"Butiá\",\n \"Caçapava do Sul\",\n \"Cacequi\",\n \"Cachoeira do Sul\",\n \"Cachoeirinha\",\n \"Cacique Doble\",\n \"Caibaté\",\n \"Caiçara\",\n \"Camaquã\",\n \"Camargo\",\n \"Cambará do Sul\",\n \"Campestre da Serra\",\n \"Campina das Missões\",\n \"Campinas do Sul\",\n \"Campo Bom\",\n \"Campo Novo\",\n \"Campos Borges\",\n \"Candelária\",\n \"Cândido Godói\",\n \"Candiota\",\n \"Canela\",\n \"Canguçu\",\n \"Canoas\",\n \"Canudos do Vale\",\n \"Capão Bonito do Sul\",\n \"Capão da Canoa\",\n \"Capão do Cipó\",\n \"Capão do Leão\",\n \"Capela de Santana\",\n \"Capitão\",\n \"Capivari do Sul\",\n \"Caraá\",\n \"Carazinho\",\n \"Carlos Barbosa\",\n \"Carlos Gomes\",\n \"Casca\",\n \"Caseiros\",\n \"Catuípe\",\n \"Caxias do Sul\",\n \"Centenário\",\n \"Cerrito\",\n \"Cerro Branco\",\n \"Cerro Grande\",\n \"Cerro Grande do Sul\",\n \"Cerro Largo\",\n \"Chapada\",\n \"Charqueadas\",\n \"Charrua\",\n \"Chiapetta\",\n \"Chuí\",\n \"Chuvisca\",\n \"Cidreira\",\n \"Ciríaco\",\n \"Colinas\",\n \"Colorado\",\n \"Condor\",\n \"Constantina\",\n \"Coqueiro Baixo\",\n \"Coqueiros do Sul\",\n \"Coronel Barros\",\n \"Coronel Bicaco\",\n \"Coronel Pilar\",\n \"Cotiporã\",\n \"Coxilha\",\n \"Crissiumal\",\n \"Cristal\",\n \"Cristal do Sul\",\n \"Cruz Alta\",\n \"Cruzaltense\",\n \"Cruzeiro do Sul\",\n \"David Canabarro\",\n \"Derrubadas\",\n \"Dezesseis de Novembro\",\n \"Dilermando de Aguiar\",\n \"Dois Irmãos\",\n \"Dois Irmãos das Missões\",\n \"Dois Lajeados\",\n \"Dom Feliciano\",\n \"Dom Pedrito\",\n \"Dom Pedro de Alcântara\",\n \"Dona Francisca\",\n \"Doutor Maurício Cardoso\",\n \"Doutor Ricardo\",\n \"Eldorado do Sul\",\n \"Encantado\",\n \"Encruzilhada do Sul\",\n \"Engenho Velho\",\n \"Entre Rios do Sul\",\n \"Entre-Ijuís\",\n \"Erebango\",\n \"Erechim\",\n \"Ernestina\",\n \"Erval Grande\",\n \"Erval Seco\",\n \"Esmeralda\",\n \"Esperança do Sul\",\n \"Espumoso\",\n \"Estação\",\n \"Estância Velha\",\n \"Esteio\",\n \"Estrela\",\n \"Estrela Velha\",\n \"Eugênio de Castro\",\n \"Fagundes Varela\",\n \"Farroupilha\",\n \"Faxinal do Soturno\",\n \"Faxinalzinho\",\n \"Fazenda Vilanova\",\n \"Feliz\",\n \"Flores da Cunha\",\n \"Floriano Peixoto\",\n \"Fontoura Xavier\",\n \"Formigueiro\",\n \"Forquetinha\",\n \"Fortaleza dos Valos\",\n \"Frederico Westphalen\",\n \"Garibaldi\",\n \"Garruchos\",\n \"Gaurama\",\n \"General Câmara\",\n \"Gentil\",\n \"Getúlio Vargas\",\n \"Giruá\",\n \"Glorinha\",\n \"Gramado\",\n \"Gramado dos Loureiros\",\n \"Gramado Xavier\",\n \"Gravataí\",\n \"Guabiju\",\n \"Guaíba\",\n \"Guaporé\",\n \"Guarani das Missões\",\n \"Harmonia\",\n \"Herval\",\n \"Herveiras\",\n \"Horizontina\",\n \"Hulha Negra\",\n \"Humaitá\",\n \"Ibarama\",\n \"Ibiaçá\",\n \"Ibiraiaras\",\n \"Ibirapuitã\",\n \"Ibirubá\",\n \"Igrejinha\",\n \"Ijuí\",\n \"Ilópolis\",\n \"Imbé\",\n \"Imigrante\",\n \"Independência\",\n \"Inhacorá\",\n \"Ipê\",\n \"Ipiranga do Sul\",\n \"Iraí\",\n \"Itaara\",\n \"Itacurubi\",\n \"Itapuca\",\n \"Itaqui\",\n \"Itati\",\n \"Itatiba do Sul\",\n \"Ivorá\",\n \"Ivoti\",\n \"Jaboticaba\",\n \"Jacuizinho\",\n \"Jacutinga\",\n \"Jaguarão\",\n \"Jaguari\",\n \"Jaquirana\",\n \"Jari\",\n \"Jóia\",\n \"Júlio de Castilhos\",\n \"Lagoa Bonita do Sul\",\n \"Lagoa dos Três Cantos\",\n \"Lagoa Vermelha\",\n \"Lagoão\",\n \"Lajeado\",\n \"Lajeado do Bugre\",\n \"Lavras do Sul\",\n \"Liberato Salzano\",\n \"Lindolfo Collor\",\n \"Linha Nova\",\n \"Maçambará\",\n \"Machadinho\",\n \"Mampituba\",\n \"Manoel Viana\",\n \"Maquiné\",\n \"Maratá\",\n \"Marau\",\n \"Marcelino Ramos\",\n \"Mariana Pimentel\",\n \"Mariano Moro\",\n \"Marques de Souza\",\n \"Mata\",\n \"Mato Castelhano\",\n \"Mato Leitão\",\n \"Mato Queimado\",\n \"Maximiliano de Almeida\",\n \"Minas do Leão\",\n \"Miraguaí\",\n \"Montauri\",\n \"Monte Alegre dos Campos\",\n \"Monte Belo do Sul\",\n \"Montenegro\",\n \"Mormaço\",\n \"Morrinhos do Sul\",\n \"Morro Redondo\",\n \"Morro Reuter\",\n \"Mostardas\",\n \"Muçum\",\n \"Muitos Capões\",\n \"Muliterno\",\n \"Não-Me-Toque\",\n \"Nicolau Vergueiro\",\n \"Nonoai\",\n \"Nova Alvorada\",\n \"Nova Araçá\",\n \"Nova Bassano\",\n \"Nova Boa Vista\",\n \"Nova Bréscia\",\n \"Nova Candelária\",\n \"Nova Esperança do Sul\",\n \"Nova Hartz\",\n \"Nova Pádua\",\n \"Nova Palma\",\n \"Nova Petrópolis\",\n \"Nova Prata\",\n \"Nova Ramada\",\n \"Nova Roma do Sul\",\n \"Nova Santa Rita\",\n \"Novo Barreiro\",\n \"Novo Cabrais\",\n \"Novo Hamburgo\",\n \"Novo Machado\",\n \"Novo Tiradentes\",\n \"Novo Xingu\",\n \"Osório\",\n \"Paim Filho\",\n \"Palmares do Sul\",\n \"Palmeira das Missões\",\n \"Palmitinho\",\n \"Panambi\",\n \"Pantano Grande\",\n \"Paraí\",\n \"Paraíso do Sul\",\n \"Pareci Novo\",\n \"Parobé\",\n \"Passa Sete\",\n \"Passo do Sobrado\",\n \"Passo Fundo\",\n \"Paulo Bento\",\n \"Paverama\",\n \"Pedras Altas\",\n \"Pedro Osório\",\n \"Pejuçara\",\n \"Pelotas\",\n \"Picada Café\",\n \"Pinhal\",\n \"Pinhal da Serra\",\n \"Pinhal Grande\",\n \"Pinheirinho do Vale\",\n \"Pinheiro Machado\",\n \"Pinto Bandeira\",\n \"Pirapó\",\n \"Piratini\",\n \"Planalto\",\n \"Poço das Antas\",\n \"Pontão\",\n \"Ponte Preta\",\n \"Portão\",\n \"Porto Alegre\",\n \"Porto Lucena\",\n \"Porto Mauá\",\n \"Porto Vera Cruz\",\n \"Porto Xavier\",\n \"Pouso Novo\",\n \"Presidente Lucena\",\n \"Progresso\",\n \"Protásio Alves\",\n \"Putinga\",\n \"Quaraí\",\n \"Quatro Irmãos\",\n \"Quevedos\",\n \"Quinze de Novembro\",\n \"Redentora\",\n \"Relvado\",\n \"Restinga Sêca\",\n \"Rio dos Índios\",\n \"Rio Grande\",\n \"Rio Pardo\",\n \"Riozinho\",\n \"Roca Sales\",\n \"Rodeio Bonito\",\n \"Rolador\",\n \"Rolante\",\n \"Ronda Alta\",\n \"Rondinha\",\n \"Roque Gonzales\",\n \"Rosário do Sul\",\n \"Sagrada Família\",\n \"Saldanha Marinho\",\n \"Salto do Jacuí\",\n \"Salvador das Missões\",\n \"Salvador do Sul\",\n \"Sananduva\",\n \"Sant'Ana do Livramento\",\n \"Santa Bárbara do Sul\",\n \"Santa Cecília do Sul\",\n \"Santa Clara do Sul\",\n \"Santa Cruz do Sul\",\n \"Santa Margarida do Sul\",\n \"Santa Maria\",\n \"Santa Maria do Herval\",\n \"Santa Rosa\",\n \"Santa Tereza\",\n \"Santa Vitória do Palmar\",\n \"Santana da Boa Vista\",\n \"Santiago\",\n \"Santo Ângelo\",\n \"Santo Antônio da Patrulha\",\n \"Santo Antônio das Missões\",\n \"Santo Antônio do Palma\",\n \"Santo Antônio do Planalto\",\n \"Santo Augusto\",\n \"Santo Cristo\",\n \"Santo Expedito do Sul\",\n \"São Borja\",\n \"São Domingos do Sul\",\n \"São Francisco de Assis\",\n \"São Francisco de Paula\",\n \"São Gabriel\",\n \"São Jerônimo\",\n \"São João da Urtiga\",\n \"São João do Polêsine\",\n \"São Jorge\",\n \"São José das Missões\",\n \"São José do Herval\",\n \"São José do Hortêncio\",\n \"São José do Inhacorá\",\n \"São José do Norte\",\n \"São José do Ouro\",\n \"São José do Sul\",\n \"São José dos Ausentes\",\n \"São Leopoldo\",\n \"São Lourenço do Sul\",\n \"São Luiz Gonzaga\",\n \"São Marcos\",\n \"São Martinho\",\n \"São Martinho da Serra\",\n \"São Miguel das Missões\",\n \"São Nicolau\",\n \"São Paulo das Missões\",\n \"São Pedro da Serra\",\n \"São Pedro das Missões\",\n \"São Pedro do Butiá\",\n \"São Pedro do Sul\",\n \"São Sebastião do Caí\",\n \"São Sepé\",\n \"São Valentim\",\n \"São Valentim do Sul\",\n \"São Valério do Sul\",\n \"São Vendelino\",\n \"São Vicente do Sul\",\n \"Sapiranga\",\n \"Sapucaia do Sul\",\n \"Sarandi\",\n \"Seberi\",\n \"Sede Nova\",\n \"Segredo\",\n \"Selbach\",\n \"Senador Salgado Filho\",\n \"Sentinela do Sul\",\n \"Serafina Corrêa\",\n \"Sério\",\n \"Sertão\",\n \"Sertão Santana\",\n \"Sete de Setembro\",\n \"Severiano de Almeida\",\n \"Silveira Martins\",\n \"Sinimbu\",\n \"Sobradinho\",\n \"Soledade\",\n \"Tabaí\",\n \"Tapejara\",\n \"Tapera\",\n \"Tapes\",\n \"Taquara\",\n \"Taquari\",\n \"Taquaruçu do Sul\",\n \"Tavares\",\n \"Tenente Portela\",\n \"Terra de Areia\",\n \"Teutônia\",\n \"Tio Hugo\",\n \"Tiradentes do Sul\",\n \"Toropi\",\n \"Torres\",\n \"Tramandaí\",\n \"Travesseiro\",\n \"Três Arroios\",\n \"Três Cachoeiras\",\n \"Três Coroas\",\n \"Três de Maio\",\n \"Três Forquilhas\",\n \"Três Palmeiras\",\n \"Três Passos\",\n \"Trindade do Sul\",\n \"Triunfo\",\n \"Tucunduva\",\n \"Tunas\",\n \"Tupanci do Sul\",\n \"Tupanciretã\",\n \"Tupandi\",\n \"Tuparendi\",\n \"Turuçu\",\n \"Ubiretama\",\n \"União da Serra\",\n \"Unistalda\",\n \"Uruguaiana\",\n \"Vacaria\",\n \"Vale do Sol\",\n \"Vale Real\",\n \"Vale Verde\",\n \"Vanini\",\n \"Venâncio Aires\",\n \"Vera Cruz\",\n \"Veranópolis\",\n \"Vespasiano Corrêa\",\n \"Viadutos\",\n \"Viamão\",\n \"Vicente Dutra\",\n \"Victor Graeff\",\n \"Vila Flores\",\n \"Vila Lângaro\",\n \"Vila Maria\",\n \"Vila Nova do Sul\",\n \"Vista Alegre\",\n \"Vista Alegre do Prata\",\n \"Vista Gaúcha\",\n \"Vitória das Missões\",\n \"Westfália\",\n \"Xangri-lá\"\n ]\n },\n {\n \"uf\": \"SC\",\n \"name\": \"Santa Catarina\",\n \"cities\": [\n \"Abdon Batista\",\n \"Abelardo Luz\",\n \"Agrolândia\",\n \"Agronômica\",\n \"Água Doce\",\n \"Águas de Chapecó\",\n \"Águas Frias\",\n \"Águas Mornas\",\n \"Alfredo Wagner\",\n \"Alto Bela Vista\",\n \"Anchieta\",\n \"Angelina\",\n \"Anita Garibaldi\",\n \"Anitápolis\",\n \"Antônio Carlos\",\n \"Apiúna\",\n \"Arabutã\",\n \"Araquari\",\n \"Araranguá\",\n \"Armazém\",\n \"Arroio Trinta\",\n \"Arvoredo\",\n \"Ascurra\",\n \"Atalanta\",\n \"Aurora\",\n \"Balneário Arroio do Silva\",\n \"Balneário Barra do Sul\",\n \"Balneário Camboriú\",\n \"Balneário Gaivota\",\n \"Balneário Piçarras\",\n \"Balneário Rincão\",\n \"Bandeirante\",\n \"Barra Bonita\",\n \"Barra Velha\",\n \"Bela Vista do Toldo\",\n \"Belmonte\",\n \"Benedito Novo\",\n \"Biguaçu\",\n \"Blumenau\",\n \"Bocaina do Sul\",\n \"Bom Jardim da Serra\",\n \"Bom Jesus\",\n \"Bom Jesus do Oeste\",\n \"Bom Retiro\",\n \"Bombinhas\",\n \"Botuverá\",\n \"Braço do Norte\",\n \"Braço do Trombudo\",\n \"Brunópolis\",\n \"Brusque\",\n \"Caçador\",\n \"Caibi\",\n \"Calmon\",\n \"Camboriú\",\n \"Campo Alegre\",\n \"Campo Belo do Sul\",\n \"Campo Erê\",\n \"Campos Novos\",\n \"Canelinha\",\n \"Canoinhas\",\n \"Capão Alto\",\n \"Capinzal\",\n \"Capivari de Baixo\",\n \"Catanduvas\",\n \"Caxambu do Sul\",\n \"Celso Ramos\",\n \"Cerro Negro\",\n \"Chapadão do Lageado\",\n \"Chapecó\",\n \"Cocal do Sul\",\n \"Concórdia\",\n \"Cordilheira Alta\",\n \"Coronel Freitas\",\n \"Coronel Martins\",\n \"Correia Pinto\",\n \"Corupá\",\n \"Criciúma\",\n \"Cunha Porã\",\n \"Cunhataí\",\n \"Curitibanos\",\n \"Descanso\",\n \"Dionísio Cerqueira\",\n \"Dona Emma\",\n \"Doutor Pedrinho\",\n \"Entre Rios\",\n \"Ermo\",\n \"Erval Velho\",\n \"Faxinal dos Guedes\",\n \"Flor do Sertão\",\n \"Florianópolis\",\n \"Formosa do Sul\",\n \"Forquilhinha\",\n \"Fraiburgo\",\n \"Frei Rogério\",\n \"Galvão\",\n \"Garopaba\",\n \"Garuva\",\n \"Gaspar\",\n \"Governador Celso Ramos\",\n \"Grão-Pará\",\n \"Gravatal\",\n \"Guabiruba\",\n \"Guaraciaba\",\n \"Guaramirim\",\n \"Guarujá do Sul\",\n \"Guatambú\",\n \"Herval d'Oeste\",\n \"Ibiam\",\n \"Ibicaré\",\n \"Ibirama\",\n \"Içara\",\n \"Ilhota\",\n \"Imaruí\",\n \"Imbituba\",\n \"Imbuia\",\n \"Indaial\",\n \"Iomerê\",\n \"Ipira\",\n \"Iporã do Oeste\",\n \"Ipuaçu\",\n \"Ipumirim\",\n \"Iraceminha\",\n \"Irani\",\n \"Irati\",\n \"Irineópolis\",\n \"Itá\",\n \"Itaiópolis\",\n \"Itajaí\",\n \"Itapema\",\n \"Itapiranga\",\n \"Itapoá\",\n \"Ituporanga\",\n \"Jaborá\",\n \"Jacinto Machado\",\n \"Jaguaruna\",\n \"Jaraguá do Sul\",\n \"Jardinópolis\",\n \"Joaçaba\",\n \"Joinville\",\n \"José Boiteux\",\n \"Jupiá\",\n \"Lacerdópolis\",\n \"Lages\",\n \"Laguna\",\n \"Lajeado Grande\",\n \"Laurentino\",\n \"Lauro Müller\",\n \"Lebon Régis\",\n \"Leoberto Leal\",\n \"Lindóia do Sul\",\n \"Lontras\",\n \"Luiz Alves\",\n \"Luzerna\",\n \"Macieira\",\n \"Mafra\",\n \"Major Gercino\",\n \"Major Vieira\",\n \"Maracajá\",\n \"Maravilha\",\n \"Marema\",\n \"Massaranduba\",\n \"Matos Costa\",\n \"Meleiro\",\n \"Mirim Doce\",\n \"Modelo\",\n \"Mondaí\",\n \"Monte Carlo\",\n \"Monte Castelo\",\n \"Morro da Fumaça\",\n \"Morro Grande\",\n \"Navegantes\",\n \"Nova Erechim\",\n \"Nova Itaberaba\",\n \"Nova Trento\",\n \"Nova Veneza\",\n \"Novo Horizonte\",\n \"Orleans\",\n \"Otacílio Costa\",\n \"Ouro\",\n \"Ouro Verde\",\n \"Paial\",\n \"Painel\",\n \"Palhoça\",\n \"Palma Sola\",\n \"Palmeira\",\n \"Palmitos\",\n \"Papanduva\",\n \"Paraíso\",\n \"Passo de Torres\",\n \"Passos Maia\",\n \"Paulo Lopes\",\n \"Pedras Grandes\",\n \"Penha\",\n \"Peritiba\",\n \"Pescaria Brava\",\n \"Petrolândia\",\n \"Pinhalzinho\",\n \"Pinheiro Preto\",\n \"Piratuba\",\n \"Planalto Alegre\",\n \"Pomerode\",\n \"Ponte Alta\",\n \"Ponte Alta do Norte\",\n \"Ponte Serrada\",\n \"Porto Belo\",\n \"Porto União\",\n \"Pouso Redondo\",\n \"Praia Grande\",\n \"Presidente Castello Branco\",\n \"Presidente Getúlio\",\n \"Presidente Nereu\",\n \"Princesa\",\n \"Quilombo\",\n \"Rancho Queimado\",\n \"Rio das Antas\",\n \"Rio do Campo\",\n \"Rio do Oeste\",\n \"Rio do Sul\",\n \"Rio dos Cedros\",\n \"Rio Fortuna\",\n \"Rio Negrinho\",\n \"Rio Rufino\",\n \"Riqueza\",\n \"Rodeio\",\n \"Romelândia\",\n \"Salete\",\n \"Saltinho\",\n \"Salto Veloso\",\n \"Sangão\",\n \"Santa Cecília\",\n \"Santa Helena\",\n \"Santa Rosa de Lima\",\n \"Santa Rosa do Sul\",\n \"Santa Terezinha\",\n \"Santa Terezinha do Progresso\",\n \"Santiago do Sul\",\n \"Santo Amaro da Imperatriz\",\n \"São Bento do Sul\",\n \"São Bernardino\",\n \"São Bonifácio\",\n \"São Carlos\",\n \"São Cristóvão do Sul\",\n \"São Domingos\",\n \"São Francisco do Sul\",\n \"São João Batista\",\n \"São João do Itaperiú\",\n \"São João do Oeste\",\n \"São João do Sul\",\n \"São Joaquim\",\n \"São José\",\n \"São José do Cedro\",\n \"São José do Cerrito\",\n \"São Lourenço do Oeste\",\n \"São Ludgero\",\n \"São Martinho\",\n \"São Miguel da Boa Vista\",\n \"São Miguel do Oeste\",\n \"São Pedro de Alcântara\",\n \"Saudades\",\n \"Schroeder\",\n \"Seara\",\n \"Serra Alta\",\n \"Siderópolis\",\n \"Sombrio\",\n \"Sul Brasil\",\n \"Taió\",\n \"Tangará\",\n \"Tigrinhos\",\n \"Tijucas\",\n \"Timbé do Sul\",\n \"Timbó\",\n \"Timbó Grande\",\n \"Três Barras\",\n \"Treviso\",\n \"Treze de Maio\",\n \"Treze Tílias\",\n \"Trombudo Central\",\n \"Tubarão\",\n \"Tunápolis\",\n \"Turvo\",\n \"União do Oeste\",\n \"Urubici\",\n \"Urupema\",\n \"Urussanga\",\n \"Vargeão\",\n \"Vargem\",\n \"Vargem Bonita\",\n \"Vidal Ramos\",\n \"Videira\",\n \"Vitor Meireles\",\n \"Witmarsum\",\n \"Xanxerê\",\n \"Xavantina\",\n \"Xaxim\",\n \"Zortéa\"\n ]\n },\n {\n \"uf\": \"SE\",\n \"name\": \"Sergipe\",\n \"cities\": [\n \"Amparo do São Francisco\",\n \"Aquidabã\",\n \"Aracaju\",\n \"Arauá\",\n \"Areia Branca\",\n \"Barra dos Coqueiros\",\n \"Boquim\",\n \"Brejo Grande\",\n \"Campo do Brito\",\n \"Canhoba\",\n \"Canindé de São Francisco\",\n \"Capela\",\n \"Carira\",\n \"Carmópolis\",\n \"Cedro de São João\",\n \"Cristinápolis\",\n \"Cumbe\",\n \"Divina Pastora\",\n \"Estância\",\n \"Feira Nova\",\n \"Frei Paulo\",\n \"Gararu\",\n \"General Maynard\",\n \"Graccho Cardoso\",\n \"Ilha das Flores\",\n \"Indiaroba\",\n \"Itabaiana\",\n \"Itabaianinha\",\n \"Itabi\",\n \"Itaporanga d'Ajuda\",\n \"Japaratuba\",\n \"Japoatã\",\n \"Lagarto\",\n \"Laranjeiras\",\n \"Macambira\",\n \"Malhada dos Bois\",\n \"Malhador\",\n \"Maruim\",\n \"Moita Bonita\",\n \"Monte Alegre de Sergipe\",\n \"Muribeca\",\n \"Neópolis\",\n \"Nossa Senhora Aparecida\",\n \"Nossa Senhora da Glória\",\n \"Nossa Senhora das Dores\",\n \"Nossa Senhora de Lourdes\",\n \"Nossa Senhora do Socorro\",\n \"Pacatuba\",\n \"Pedra Mole\",\n \"Pedrinhas\",\n \"Pinhão\",\n \"Pirambu\",\n \"Poço Redondo\",\n \"Poço Verde\",\n \"Porto da Folha\",\n \"Propriá\",\n \"Riachão do Dantas\",\n \"Riachuelo\",\n \"Ribeirópolis\",\n \"Rosário do Catete\",\n \"Salgado\",\n \"Santa Luzia do Itanhy\",\n \"Santa Rosa de Lima\",\n \"Santana do São Francisco\",\n \"Santo Amaro das Brotas\",\n \"São Cristóvão\",\n \"São Domingos\",\n \"São Francisco\",\n \"São Miguel do Aleixo\",\n \"Simão Dias\",\n \"Siriri\",\n \"Telha\",\n \"Tobias Barreto\",\n \"Tomar do Geru\",\n \"Umbaúba\"\n ]\n },\n {\n \"uf\": \"SP\",\n \"name\": \"São Paulo\",\n \"cities\": [\n \"Adamantina\",\n \"Adolfo\",\n \"Aguaí\",\n \"Águas da Prata\",\n \"Águas de Lindóia\",\n \"Águas de Santa Bárbara\",\n \"Águas de São Pedro\",\n \"Agudos\",\n \"Alambari\",\n \"Alfredo Marcondes\",\n \"Altair\",\n \"Altinópolis\",\n \"Alto Alegre\",\n \"Alumínio\",\n \"Álvares Florence\",\n \"Álvares Machado\",\n \"Álvaro de Carvalho\",\n \"Alvinlândia\",\n \"Americana\",\n \"Américo Brasiliense\",\n \"Américo de Campos\",\n \"Amparo\",\n \"Analândia\",\n \"Andradina\",\n \"Angatuba\",\n \"Anhembi\",\n \"Anhumas\",\n \"Aparecida\",\n \"Aparecida d'Oeste\",\n \"Apiaí\",\n \"Araçariguama\",\n \"Araçatuba\",\n \"Araçoiaba da Serra\",\n \"Aramina\",\n \"Arandu\",\n \"Arapeí\",\n \"Araraquara\",\n \"Araras\",\n \"Arco-Íris\",\n \"Arealva\",\n \"Areias\",\n \"Areiópolis\",\n \"Ariranha\",\n \"Artur Nogueira\",\n \"Arujá\",\n \"Aspásia\",\n \"Assis\",\n \"Atibaia\",\n \"Auriflama\",\n \"Avaí\",\n \"Avanhandava\",\n \"Avaré\",\n \"Bady Bassitt\",\n \"Balbinos\",\n \"Bálsamo\",\n \"Bananal\",\n \"Barão de Antonina\",\n \"Barbosa\",\n \"Bariri\",\n \"Barra Bonita\",\n \"Barra do Chapéu\",\n \"Barra do Turvo\",\n \"Barretos\",\n \"Barrinha\",\n \"Barueri\",\n \"Bastos\",\n \"Batatais\",\n \"Bauru\",\n \"Bebedouro\",\n \"Bento de Abreu\",\n \"Bernardino de Campos\",\n \"Bertioga\",\n \"Bilac\",\n \"Birigui\",\n \"Biritiba Mirim\",\n \"Boa Esperança do Sul\",\n \"Bocaina\",\n \"Bofete\",\n \"Boituva\",\n \"Bom Jesus dos Perdões\",\n \"Bom Sucesso de Itararé\",\n \"Borá\",\n \"Boracéia\",\n \"Borborema\",\n \"Borebi\",\n \"Botucatu\",\n \"Bragança Paulista\",\n \"Braúna\",\n \"Brejo Alegre\",\n \"Brodowski\",\n \"Brotas\",\n \"Buri\",\n \"Buritama\",\n \"Buritizal\",\n \"Cabrália Paulista\",\n \"Cabreúva\",\n \"Caçapava\",\n \"Cachoeira Paulista\",\n \"Caconde\",\n \"Cafelândia\",\n \"Caiabu\",\n \"Caieiras\",\n \"Caiuá\",\n \"Cajamar\",\n \"Cajati\",\n \"Cajobi\",\n \"Cajuru\",\n \"Campina do Monte Alegre\",\n \"Campinas\",\n \"Campo Limpo Paulista\",\n \"Campos do Jordão\",\n \"Campos Novos Paulista\",\n \"Cananéia\",\n \"Canas\",\n \"Cândido Mota\",\n \"Cândido Rodrigues\",\n \"Canitar\",\n \"Capão Bonito\",\n \"Capela do Alto\",\n \"Capivari\",\n \"Caraguatatuba\",\n \"Carapicuíba\",\n \"Cardoso\",\n \"Casa Branca\",\n \"Cássia dos Coqueiros\",\n \"Castilho\",\n \"Catanduva\",\n \"Catiguá\",\n \"Cedral\",\n \"Cerqueira César\",\n \"Cerquilho\",\n \"Cesário Lange\",\n \"Charqueada\",\n \"Chavantes\",\n \"Clementina\",\n \"Colina\",\n \"Colômbia\",\n \"Conchal\",\n \"Conchas\",\n \"Cordeirópolis\",\n \"Coroados\",\n \"Coronel Macedo\",\n \"Corumbataí\",\n \"Cosmópolis\",\n \"Cosmorama\",\n \"Cotia\",\n \"Cravinhos\",\n \"Cristais Paulista\",\n \"Cruzália\",\n \"Cruzeiro\",\n \"Cubatão\",\n \"Cunha\",\n \"Descalvado\",\n \"Diadema\",\n \"Dirce Reis\",\n \"Divinolândia\",\n \"Dobrada\",\n \"Dois Córregos\",\n \"Dolcinópolis\",\n \"Dourado\",\n \"Dracena\",\n \"Duartina\",\n \"Dumont\",\n \"Echaporã\",\n \"Eldorado\",\n \"Elias Fausto\",\n \"Elisiário\",\n \"Embaúba\",\n \"Embu das Artes\",\n \"Embu-Guaçu\",\n \"Emilianópolis\",\n \"Engenheiro Coelho\",\n \"Espírito Santo do Pinhal\",\n \"Espírito Santo do Turvo\",\n \"Estiva Gerbi\",\n \"Estrela d'Oeste\",\n \"Estrela do Norte\",\n \"Euclides da Cunha Paulista\",\n \"Fartura\",\n \"Fernando Prestes\",\n \"Fernandópolis\",\n \"Fernão\",\n \"Ferraz de Vasconcelos\",\n \"Flora Rica\",\n \"Floreal\",\n \"Flórida Paulista\",\n \"Florínea\",\n \"Franca\",\n \"Francisco Morato\",\n \"Franco da Rocha\",\n \"Gabriel Monteiro\",\n \"Gália\",\n \"Garça\",\n \"Gastão Vidigal\",\n \"Gavião Peixoto\",\n \"General Salgado\",\n \"Getulina\",\n \"Glicério\",\n \"Guaiçara\",\n \"Guaimbê\",\n \"Guaíra\",\n \"Guapiaçu\",\n \"Guapiara\",\n \"Guará\",\n \"Guaraçaí\",\n \"Guaraci\",\n \"Guarani d'Oeste\",\n \"Guarantã\",\n \"Guararapes\",\n \"Guararema\",\n \"Guaratinguetá\",\n \"Guareí\",\n \"Guariba\",\n \"Guarujá\",\n \"Guarulhos\",\n \"Guatapará\",\n \"Guzolândia\",\n \"Herculândia\",\n \"Holambra\",\n \"Hortolândia\",\n \"Iacanga\",\n \"Iacri\",\n \"Iaras\",\n \"Ibaté\",\n \"Ibirá\",\n \"Ibirarema\",\n \"Ibitinga\",\n \"Ibiúna\",\n \"Icém\",\n \"Iepê\",\n \"Igaraçu do Tietê\",\n \"Igarapava\",\n \"Igaratá\",\n \"Iguape\",\n \"Ilha Comprida\",\n \"Ilha Solteira\",\n \"Ilhabela\",\n \"Indaiatuba\",\n \"Indiana\",\n \"Indiaporã\",\n \"Inúbia Paulista\",\n \"Ipaussu\",\n \"Iperó\",\n \"Ipeúna\",\n \"Ipiguá\",\n \"Iporanga\",\n \"Ipuã\",\n \"Iracemápolis\",\n \"Irapuã\",\n \"Irapuru\",\n \"Itaberá\",\n \"Itaí\",\n \"Itajobi\",\n \"Itaju\",\n \"Itanhaém\",\n \"Itaoca\",\n \"Itapecerica da Serra\",\n \"Itapetininga\",\n \"Itapeva\",\n \"Itapevi\",\n \"Itapira\",\n \"Itapirapuã Paulista\",\n \"Itápolis\",\n \"Itaporanga\",\n \"Itapuí\",\n \"Itapura\",\n \"Itaquaquecetuba\",\n \"Itararé\",\n \"Itariri\",\n \"Itatiba\",\n \"Itatinga\",\n \"Itirapina\",\n \"Itirapuã\",\n \"Itobi\",\n \"Itu\",\n \"Itupeva\",\n \"Ituverava\",\n \"Jaborandi\",\n \"Jaboticabal\",\n \"Jacareí\",\n \"Jaci\",\n \"Jacupiranga\",\n \"Jaguariúna\",\n \"Jales\",\n \"Jambeiro\",\n \"Jandira\",\n \"Jardinópolis\",\n \"Jarinu\",\n \"Jaú\",\n \"Jeriquara\",\n \"Joanópolis\",\n \"João Ramalho\",\n \"José Bonifácio\",\n \"Júlio Mesquita\",\n \"Jumirim\",\n \"Jundiaí\",\n \"Junqueirópolis\",\n \"Juquiá\",\n \"Juquitiba\",\n \"Lagoinha\",\n \"Laranjal Paulista\",\n \"Lavínia\",\n \"Lavrinhas\",\n \"Leme\",\n \"Lençóis Paulista\",\n \"Limeira\",\n \"Lindóia\",\n \"Lins\",\n \"Lorena\",\n \"Lourdes\",\n \"Louveira\",\n \"Lucélia\",\n \"Lucianópolis\",\n \"Luís Antônio\",\n \"Luiziânia\",\n \"Lupércio\",\n \"Lutécia\",\n \"Macatuba\",\n \"Macaubal\",\n \"Macedônia\",\n \"Magda\",\n \"Mairinque\",\n \"Mairiporã\",\n \"Manduri\",\n \"Marabá Paulista\",\n \"Maracaí\",\n \"Marapoama\",\n \"Mariápolis\",\n \"Marília\",\n \"Marinópolis\",\n \"Martinópolis\",\n \"Matão\",\n \"Mauá\",\n \"Mendonça\",\n \"Meridiano\",\n \"Mesópolis\",\n \"Miguelópolis\",\n \"Mineiros do Tietê\",\n \"Mira Estrela\",\n \"Miracatu\",\n \"Mirandópolis\",\n \"Mirante do Paranapanema\",\n \"Mirassol\",\n \"Mirassolândia\",\n \"Mococa\",\n \"Mogi das Cruzes\",\n \"Mogi Guaçu\",\n \"Mogi Mirim\",\n \"Mombuca\",\n \"Monções\",\n \"Mongaguá\",\n \"Monte Alegre do Sul\",\n \"Monte Alto\",\n \"Monte Aprazível\",\n \"Monte Azul Paulista\",\n \"Monte Castelo\",\n \"Monte Mor\",\n \"Monteiro Lobato\",\n \"Morro Agudo\",\n \"Morungaba\",\n \"Motuca\",\n \"Murutinga do Sul\",\n \"Nantes\",\n \"Narandiba\",\n \"Natividade da Serra\",\n \"Nazaré Paulista\",\n \"Neves Paulista\",\n \"Nhandeara\",\n \"Nipoã\",\n \"Nova Aliança\",\n \"Nova Campina\",\n \"Nova Canaã Paulista\",\n \"Nova Castilho\",\n \"Nova Europa\",\n \"Nova Granada\",\n \"Nova Guataporanga\",\n \"Nova Independência\",\n \"Nova Luzitânia\",\n \"Nova Odessa\",\n \"Novais\",\n \"Novo Horizonte\",\n \"Nuporanga\",\n \"Ocauçu\",\n \"Óleo\",\n \"Olímpia\",\n \"Onda Verde\",\n \"Oriente\",\n \"Orindiúva\",\n \"Orlândia\",\n \"Osasco\",\n \"Oscar Bressane\",\n \"Osvaldo Cruz\",\n \"Ourinhos\",\n \"Ouro Verde\",\n \"Ouroeste\",\n \"Pacaembu\",\n \"Palestina\",\n \"Palmares Paulista\",\n \"Palmeira d'Oeste\",\n \"Palmital\",\n \"Panorama\",\n \"Paraguaçu Paulista\",\n \"Paraibuna\",\n \"Paraíso\",\n \"Paranapanema\",\n \"Paranapuã\",\n \"Parapuã\",\n \"Pardinho\",\n \"Pariquera-Açu\",\n \"Parisi\",\n \"Patrocínio Paulista\",\n \"Paulicéia\",\n \"Paulínia\",\n \"Paulistânia\",\n \"Paulo de Faria\",\n \"Pederneiras\",\n \"Pedra Bela\",\n \"Pedranópolis\",\n \"Pedregulho\",\n \"Pedreira\",\n \"Pedrinhas Paulista\",\n \"Pedro de Toledo\",\n \"Penápolis\",\n \"Pereira Barreto\",\n \"Pereiras\",\n \"Peruíbe\",\n \"Piacatu\",\n \"Piedade\",\n \"Pilar do Sul\",\n \"Pindamonhangaba\",\n \"Pindorama\",\n \"Pinhalzinho\",\n \"Piquerobi\",\n \"Piquete\",\n \"Piracaia\",\n \"Piracicaba\",\n \"Piraju\",\n \"Pirajuí\",\n \"Pirangi\",\n \"Pirapora do Bom Jesus\",\n \"Pirapozinho\",\n \"Pirassununga\",\n \"Piratininga\",\n \"Pitangueiras\",\n \"Planalto\",\n \"Platina\",\n \"Poá\",\n \"Poloni\",\n \"Pompéia\",\n \"Pongaí\",\n \"Pontal\",\n \"Pontalinda\",\n \"Pontes Gestal\",\n \"Populina\",\n \"Porangaba\",\n \"Porto Feliz\",\n \"Porto Ferreira\",\n \"Potim\",\n \"Potirendaba\",\n \"Pracinha\",\n \"Pradópolis\",\n \"Praia Grande\",\n \"Pratânia\",\n \"Presidente Alves\",\n \"Presidente Bernardes\",\n \"Presidente Epitácio\",\n \"Presidente Prudente\",\n \"Presidente Venceslau\",\n \"Promissão\",\n \"Quadra\",\n \"Quatá\",\n \"Queiroz\",\n \"Queluz\",\n \"Quintana\",\n \"Rafard\",\n \"Rancharia\",\n \"Redenção da Serra\",\n \"Regente Feijó\",\n \"Reginópolis\",\n \"Registro\",\n \"Restinga\",\n \"Ribeira\",\n \"Ribeirão Bonito\",\n \"Ribeirão Branco\",\n \"Ribeirão Corrente\",\n \"Ribeirão do Sul\",\n \"Ribeirão dos Índios\",\n \"Ribeirão Grande\",\n \"Ribeirão Pires\",\n \"Ribeirão Preto\",\n \"Rifaina\",\n \"Rincão\",\n \"Rinópolis\",\n \"Rio Claro\",\n \"Rio das Pedras\",\n \"Rio Grande da Serra\",\n \"Riolândia\",\n \"Riversul\",\n \"Rosana\",\n \"Roseira\",\n \"Rubiácea\",\n \"Rubinéia\",\n \"Sabino\",\n \"Sagres\",\n \"Sales\",\n \"Sales Oliveira\",\n \"Salesópolis\",\n \"Salmourão\",\n \"Saltinho\",\n \"Salto\",\n \"Salto de Pirapora\",\n \"Salto Grande\",\n \"Sandovalina\",\n \"Santa Adélia\",\n \"Santa Albertina\",\n \"Santa Bárbara d'Oeste\",\n \"Santa Branca\",\n \"Santa Clara d'Oeste\",\n \"Santa Cruz da Conceição\",\n \"Santa Cruz da Esperança\",\n \"Santa Cruz das Palmeiras\",\n \"Santa Cruz do Rio Pardo\",\n \"Santa Ernestina\",\n \"Santa Fé do Sul\",\n \"Santa Gertrudes\",\n \"Santa Isabel\",\n \"Santa Lúcia\",\n \"Santa Maria da Serra\",\n \"Santa Mercedes\",\n \"Santa Rita d'Oeste\",\n \"Santa Rita do Passa Quatro\",\n \"Santa Rosa de Viterbo\",\n \"Santa Salete\",\n \"Santana da Ponte Pensa\",\n \"Santana de Parnaíba\",\n \"Santo Anastácio\",\n \"Santo André\",\n \"Santo Antônio da Alegria\",\n \"Santo Antônio de Posse\",\n \"Santo Antônio do Aracanguá\",\n \"Santo Antônio do Jardim\",\n \"Santo Antônio do Pinhal\",\n \"Santo Expedito\",\n \"Santópolis do Aguapeí\",\n \"Santos\",\n \"São Bento do Sapucaí\",\n \"São Bernardo do Campo\",\n \"São Caetano do Sul\",\n \"São Carlos\",\n \"São Francisco\",\n \"São João da Boa Vista\",\n \"São João das Duas Pontes\",\n \"São João de Iracema\",\n \"São João do Pau d'Alho\",\n \"São Joaquim da Barra\",\n \"São José da Bela Vista\",\n \"São José do Barreiro\",\n \"São José do Rio Pardo\",\n \"São José do Rio Preto\",\n \"São José dos Campos\",\n \"São Lourenço da Serra\",\n \"São Luiz do Paraitinga\",\n \"São Manuel\",\n \"São Miguel Arcanjo\",\n \"São Paulo\",\n \"São Pedro\",\n \"São Pedro do Turvo\",\n \"São Roque\",\n \"São Sebastião\",\n \"São Sebastião da Grama\",\n \"São Simão\",\n \"São Vicente\",\n \"Sarapuí\",\n \"Sarutaiá\",\n \"Sebastianópolis do Sul\",\n \"Serra Azul\",\n \"Serra Negra\",\n \"Serrana\",\n \"Sertãozinho\",\n \"Sete Barras\",\n \"Severínia\",\n \"Silveiras\",\n \"Socorro\",\n \"Sorocaba\",\n \"Sud Mennucci\",\n \"Sumaré\",\n \"Suzanápolis\",\n \"Suzano\",\n \"Tabapuã\",\n \"Tabatinga\",\n \"Taboão da Serra\",\n \"Taciba\",\n \"Taguaí\",\n \"Taiaçu\",\n \"Taiúva\",\n \"Tambaú\",\n \"Tanabi\",\n \"Tapiraí\",\n \"Tapiratiba\",\n \"Taquaral\",\n \"Taquaritinga\",\n \"Taquarituba\",\n \"Taquarivaí\",\n \"Tarabai\",\n \"Tarumã\",\n \"Tatuí\",\n \"Taubaté\",\n \"Tejupá\",\n \"Teodoro Sampaio\",\n \"Terra Roxa\",\n \"Tietê\",\n \"Timburi\",\n \"Torre de Pedra\",\n \"Torrinha\",\n \"Trabiju\",\n \"Tremembé\",\n \"Três Fronteiras\",\n \"Tuiuti\",\n \"Tupã\",\n \"Tupi Paulista\",\n \"Turiúba\",\n \"Turmalina\",\n \"Ubarana\",\n \"Ubatuba\",\n \"Ubirajara\",\n \"Uchoa\",\n \"União Paulista\",\n \"Urânia\",\n \"Uru\",\n \"Urupês\",\n \"Valentim Gentil\",\n \"Valinhos\",\n \"Valparaíso\",\n \"Vargem\",\n \"Vargem Grande do Sul\",\n \"Vargem Grande Paulista\",\n \"Várzea Paulista\",\n \"Vera Cruz\",\n \"Vinhedo\",\n \"Viradouro\",\n \"Vista Alegre do Alto\",\n \"Vitória Brasil\",\n \"Votorantim\",\n \"Votuporanga\",\n \"Zacarias\"\n ]\n },\n {\n \"uf\": \"TO\",\n \"name\": \"Tocantins\",\n \"cities\": [\n \"Abreulândia\",\n \"Aguiarnópolis\",\n \"Aliança do Tocantins\",\n \"Almas\",\n \"Alvorada\",\n \"Ananás\",\n \"Angico\",\n \"Aparecida do Rio Negro\",\n \"Aragominas\",\n \"Araguacema\",\n \"Araguaçu\",\n \"Araguaína\",\n \"Araguanã\",\n \"Araguatins\",\n \"Arapoema\",\n \"Arraias\",\n \"Augustinópolis\",\n \"Aurora do Tocantins\",\n \"Axixá do Tocantins\",\n \"Babaçulândia\",\n \"Bandeirantes do Tocantins\",\n \"Barra do Ouro\",\n \"Barrolândia\",\n \"Bernardo Sayão\",\n \"Bom Jesus do Tocantins\",\n \"Brasilândia do Tocantins\",\n \"Brejinho de Nazaré\",\n \"Buriti do Tocantins\",\n \"Cachoeirinha\",\n \"Campos Lindos\",\n \"Cariri do Tocantins\",\n \"Carmolândia\",\n \"Carrasco Bonito\",\n \"Caseara\",\n \"Centenário\",\n \"Chapada da Natividade\",\n \"Chapada de Areia\",\n \"Colinas do Tocantins\",\n \"Colméia\",\n \"Combinado\",\n \"Conceição do Tocantins\",\n \"Couto Magalhães\",\n \"Cristalândia\",\n \"Crixás do Tocantins\",\n \"Darcinópolis\",\n \"Dianópolis\",\n \"Divinópolis do Tocantins\",\n \"Dois Irmãos do Tocantins\",\n \"Dueré\",\n \"Esperantina\",\n \"Fátima\",\n \"Figueirópolis\",\n \"Filadélfia\",\n \"Formoso do Araguaia\",\n \"Goianorte\",\n \"Goiatins\",\n \"Guaraí\",\n \"Gurupi\",\n \"Ipueiras\",\n \"Itacajá\",\n \"Itaguatins\",\n \"Itapiratins\",\n \"Itaporã do Tocantins\",\n \"Jaú do Tocantins\",\n \"Juarina\",\n \"Lagoa da Confusão\",\n \"Lagoa do Tocantins\",\n \"Lajeado\",\n \"Lavandeira\",\n \"Lizarda\",\n \"Luzinópolis\",\n \"Marianópolis do Tocantins\",\n \"Mateiros\",\n \"Maurilândia do Tocantins\",\n \"Miracema do Tocantins\",\n \"Miranorte\",\n \"Monte do Carmo\",\n \"Monte Santo do Tocantins\",\n \"Muricilândia\",\n \"Natividade\",\n \"Nazaré\",\n \"Nova Olinda\",\n \"Nova Rosalândia\",\n \"Novo Acordo\",\n \"Novo Alegre\",\n \"Novo Jardim\",\n \"Oliveira de Fátima\",\n \"Palmas\",\n \"Palmeirante\",\n \"Palmeiras do Tocantins\",\n \"Palmeirópolis\",\n \"Paraíso do Tocantins\",\n \"Paranã\",\n \"Pau D'Arco\",\n \"Pedro Afonso\",\n \"Peixe\",\n \"Pequizeiro\",\n \"Pindorama do Tocantins\",\n \"Piraquê\",\n \"Pium\",\n \"Ponte Alta do Bom Jesus\",\n \"Ponte Alta do Tocantins\",\n \"Porto Alegre do Tocantins\",\n \"Porto Nacional\",\n \"Praia Norte\",\n \"Presidente Kennedy\",\n \"Pugmil\",\n \"Recursolândia\",\n \"Riachinho\",\n \"Rio da Conceição\",\n \"Rio dos Bois\",\n \"Rio Sono\",\n \"Sampaio\",\n \"Sandolândia\",\n \"Santa Fé do Araguaia\",\n \"Santa Maria do Tocantins\",\n \"Santa Rita do Tocantins\",\n \"Santa Rosa do Tocantins\",\n \"Santa Tereza do Tocantins\",\n \"Santa Terezinha do Tocantins\",\n \"São Bento do Tocantins\",\n \"São Félix do Tocantins\",\n \"São Miguel do Tocantins\",\n \"São Salvador do Tocantins\",\n \"São Sebastião do Tocantins\",\n \"São Valério\",\n \"Silvanópolis\",\n \"Sítio Novo do Tocantins\",\n \"Sucupira\",\n \"Tabocão\",\n \"Taguatinga\",\n \"Taipas do Tocantins\",\n \"Talismã\",\n \"Tocantínia\",\n \"Tocantinópolis\",\n \"Tupirama\",\n \"Tupiratins\",\n \"Wanderlândia\",\n \"Xambioá\"\n ]\n }\n]\n","/**\n * Brazilian states (UF), regions and municipalities, mirroring\n * `utils.locations`.\n *\n * Ships an offline, dependency-free dataset of every federative unit and its\n * municipalities (bundled at build time), plus query helpers and validators.\n * City lookups are accent- and case-insensitive.\n */\n\nimport { defineEnum } from \"@/core/enums\";\nimport { z } from \"@/schemas/base\";\nimport brLocations from \"@/utils/data/brLocations.json\";\n\n/** The 27 Brazilian federative-unit acronyms. */\nexport const UF = defineEnum({\n AC: \"AC\",\n AL: \"AL\",\n AP: \"AP\",\n AM: \"AM\",\n BA: \"BA\",\n CE: \"CE\",\n DF: \"DF\",\n ES: \"ES\",\n GO: \"GO\",\n MA: \"MA\",\n MT: \"MT\",\n MS: \"MS\",\n MG: \"MG\",\n PA: \"PA\",\n PB: \"PB\",\n PR: \"PR\",\n PE: \"PE\",\n PI: \"PI\",\n RJ: \"RJ\",\n RN: \"RN\",\n RS: \"RS\",\n RO: \"RO\",\n RR: \"RR\",\n SC: \"SC\",\n SP: \"SP\",\n SE: \"SE\",\n TO: \"TO\",\n});\n\n/** A federative-unit acronym. */\nexport type UFValue = ReturnType<typeof UF.values>[number];\n\n/** The five official IBGE macro-regions. */\nexport const Region = defineEnum({\n NORTH: \"Norte\",\n NORTHEAST: \"Nordeste\",\n CENTRAL_WEST: \"Centro-Oeste\",\n SOUTHEAST: \"Sudeste\",\n SOUTH: \"Sul\",\n});\n\n/** A macro-region value. */\nexport type RegionValue = ReturnType<typeof Region.values>[number];\n\n/** Static mapping of every UF to its IBGE macro-region. */\nconst UF_TO_REGION: Record<string, RegionValue> = {\n AC: Region.NORTH,\n AP: Region.NORTH,\n AM: Region.NORTH,\n PA: Region.NORTH,\n RO: Region.NORTH,\n RR: Region.NORTH,\n TO: Region.NORTH,\n AL: Region.NORTHEAST,\n BA: Region.NORTHEAST,\n CE: Region.NORTHEAST,\n MA: Region.NORTHEAST,\n PB: Region.NORTHEAST,\n PE: Region.NORTHEAST,\n PI: Region.NORTHEAST,\n RN: Region.NORTHEAST,\n SE: Region.NORTHEAST,\n DF: Region.CENTRAL_WEST,\n GO: Region.CENTRAL_WEST,\n MS: Region.CENTRAL_WEST,\n MT: Region.CENTRAL_WEST,\n ES: Region.SOUTHEAST,\n MG: Region.SOUTHEAST,\n RJ: Region.SOUTHEAST,\n SP: Region.SOUTHEAST,\n PR: Region.SOUTH,\n RS: Region.SOUTH,\n SC: Region.SOUTH,\n};\n\n/** A Brazilian federative unit and its municipalities. */\nexport interface StateBR {\n /** Federative-unit acronym (e.g. `\"SP\"`). */\n uf: string;\n /** Full state name (e.g. `\"São Paulo\"`). */\n name: string;\n /** The IBGE macro-region the state belongs to. */\n region: RegionValue;\n /** Alphabetically sorted municipality names. */\n cities: string[];\n}\n\nconst RAW = brLocations as Array<{ uf: string; name: string; cities: string[] }>;\n\nconst STATES: StateBR[] = RAW.map((entry) => ({\n uf: entry.uf,\n name: entry.name,\n region: UF_TO_REGION[entry.uf] ?? Region.SOUTHEAST,\n cities: entry.cities,\n}));\n\nconst STATE_BY_UF = new Map(STATES.map((state) => [state.uf, state]));\n\n/** Strip accents and lowercase a string for tolerant comparison. */\nfunction fold(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .trim()\n .toLowerCase();\n}\n\n/** All states, ordered by acronym. */\nexport function listStates(): StateBR[] {\n return STATES.map((state) => ({ ...state, cities: [...state.cities] }));\n}\n\n/** The state for a UF acronym (case-insensitive), or `null`. */\nexport function getState(uf: string): StateBR | null {\n const state = STATE_BY_UF.get(uf.toUpperCase());\n return state ? { ...state, cities: [...state.cities] } : null;\n}\n\n/** The municipalities of a UF, or `[]` for an unknown UF. */\nexport function citiesByUf(uf: string): string[] {\n return getState(uf)?.cities ?? [];\n}\n\n/** All states in a macro-region. */\nexport function statesByRegion(region: RegionValue): StateBR[] {\n return listStates().filter((state) => state.region === region);\n}\n\n/** Whether `value` is a known UF acronym (case-insensitive). */\nexport function isValidUf(value: string): boolean {\n return STATE_BY_UF.has(value.toUpperCase());\n}\n\n/** Normalize a UF to its uppercase acronym, throwing when unknown. */\nexport function normalizeUf(value: string): string {\n const upper = value.toUpperCase();\n if (!STATE_BY_UF.has(upper)) throw new Error(\"invalid UF\");\n return upper;\n}\n\n/** Whether `name` is a municipality of `uf` (accent/case-insensitive). */\nexport function isValidCity(name: string, uf: string): boolean {\n const folded = fold(name);\n return citiesByUf(uf).some((city) => fold(city) === folded);\n}\n\n/** Zod field: validates a UF and normalizes it to its uppercase acronym. */\nexport const ufField = z\n .string()\n .refine(isValidUf, { message: \"invalid UF\" })\n .transform((value) => value.toUpperCase());\n","/** Datetime helpers, mirroring `utils.datetime`. */\n\n/**\n * Return the current instant. JavaScript `Date` is always UTC-based internally;\n * serialize with `.toISOString()` for a UTC wire format.\n *\n * @returns The current `Date`.\n */\nexport function utcnow(): Date {\n return new Date();\n}\n\n/**\n * Coerce a value to a `Date`. Accepts a `Date`, an ISO string or an epoch\n * milliseconds number.\n *\n * @param value - The value to normalize.\n * @returns The corresponding `Date`.\n * @throws {Error} When the value cannot be parsed to a valid date.\n */\nexport function toUtc(value: Date | string | number): Date {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) throw new Error(\"invalid date\");\n return date;\n}\n","/** Dictionary helpers, mirroring `utils.dict`. */\n\n/**\n * Filter and extend a record in a single pass: drop `exclude`d keys and merge\n * `include` on top (merged entries win).\n *\n * @param data - The source record.\n * @param exclude - Keys to drop from the output.\n * @param include - Extra entries to merge in.\n * @returns A new record with the requested mutations.\n */\nexport function modifyDict(\n data: Record<string, unknown>,\n exclude: string[] = [],\n include: Record<string, unknown> = {},\n): Record<string, unknown> {\n const excluded = new Set(exclude);\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!excluded.has(key)) result[key] = value;\n }\n return { ...result, ...include };\n}\n","/**\n * Single-use opaque tokens hashed at rest, mirroring `utils.opaque_token`.\n *\n * For flows where a secret is emailed/SMS'd and later presented back (password\n * reset, email verification, magic links, API keys). The plaintext is shown\n * once; only its SHA-256 digest is stored, so a DB leak exposes no usable\n * tokens. Verification hashes the incoming plaintext and compares in constant\n * time. Pure standard library (`node:crypto`).\n */\n\nimport { createHash, randomBytes, timingSafeEqual } from \"node:crypto\";\n\nconst DEFAULT_NBYTES = 32;\n\n/**\n * Return the SHA-256 hex digest of a token's plaintext.\n *\n * @param plaintext - The token value to hash.\n * @returns A 64-character lowercase hex digest.\n */\nexport function hashOpaqueToken(plaintext: string): string {\n return createHash(\"sha256\").update(plaintext, \"utf8\").digest(\"hex\");\n}\n\n/**\n * Generate a cryptographically random token and its digest.\n *\n * @param nbytes - Entropy in bytes for the URL-safe token (default 32).\n * @returns `{ plaintext, tokenHash }` — show `plaintext` once, store `tokenHash`.\n */\nexport function generateOpaqueToken(nbytes: number = DEFAULT_NBYTES): {\n plaintext: string;\n tokenHash: string;\n} {\n const plaintext = randomBytes(nbytes).toString(\"base64url\");\n return { plaintext, tokenHash: hashOpaqueToken(plaintext) };\n}\n\n/**\n * Constant-time check that `plaintext` hashes to `tokenHash`.\n *\n * @param plaintext - The token submitted by the caller.\n * @param tokenHash - The stored SHA-256 hex digest.\n * @returns `true` when the hashes match.\n */\nexport function verifyOpaqueToken(plaintext: string, tokenHash: string): boolean {\n const computed = Buffer.from(hashOpaqueToken(plaintext), \"hex\");\n const expected = Buffer.from(tokenHash, \"hex\");\n if (computed.length !== expected.length) return false;\n return timingSafeEqual(computed, expected);\n}\n","/**\n * Password hashing backed by bcrypt, mirroring `utils.password.PasswordUtils`.\n *\n * `bcryptjs` is an optional peer dependency, imported lazily so that\n * `import \"tempest-express-sdk\"` keeps working when it is not installed — the\n * clear error is deferred to first use. Methods are async (the idiomatic Node\n * bcrypt surface).\n */\n\ntype BcryptModule = typeof import(\"bcryptjs\");\n\nlet cached: BcryptModule | null = null;\n\n/** Lazily load `bcryptjs`, with a clear install hint when missing. */\nasync function loadBcrypt(): Promise<BcryptModule> {\n if (cached) return cached;\n try {\n const mod = (await import(\"bcryptjs\")) as BcryptModule & { default?: BcryptModule };\n cached = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"PasswordUtils requires the 'bcryptjs' peer dependency. Install with `npm i bcryptjs`.\",\n { cause },\n );\n }\n return cached;\n}\n\n/** Hash and verify passwords using bcrypt. Stateless — construct once, reuse. */\nexport class PasswordUtils {\n /**\n * @param rounds - The bcrypt cost factor. Higher is slower and harder to\n * brute-force. Defaults to 12.\n */\n constructor(private readonly rounds: number = 12) {}\n\n /**\n * Hash a plaintext password.\n *\n * @param plain - The plaintext password.\n * @returns The bcrypt hash, ready to persist.\n */\n async hash(plain: string): Promise<string> {\n const bcrypt = await loadBcrypt();\n const salt = await bcrypt.genSalt(this.rounds);\n return bcrypt.hash(plain, salt);\n }\n\n /**\n * Verify a plaintext password against a stored hash. Returns `false` for\n * malformed hashes rather than throwing.\n *\n * @param plain - The plaintext password to verify.\n * @param hashed - The previously stored bcrypt hash.\n * @returns `true` when the password matches.\n */\n async verify(plain: string, hashed: string): Promise<boolean> {\n try {\n const bcrypt = await loadBcrypt();\n return await bcrypt.compare(plain, hashed);\n } catch {\n return false;\n }\n }\n}\n","/**\n * JWT encode/decode backed by `jsonwebtoken`, mirroring `utils.jwt.JWTUtils`.\n *\n * `jsonwebtoken` is an optional peer dependency, imported lazily so the SDK\n * imports without it; the clear error is deferred to first use. Every token\n * gets `iat`/`exp` automatically; pass `issuer` to add and verify `iss`.\n * Expired/invalid tokens raise the SDK's {@link ExpiredTokenException} /\n * {@link InvalidTokenException}.\n */\n\nimport { ExpiredTokenException, InvalidTokenException } from \"@/exceptions/http\";\n\ntype JwtModule = typeof import(\"jsonwebtoken\");\n\nlet cached: JwtModule | null = null;\n\n/** Lazily load `jsonwebtoken`, with a clear install hint when missing. */\nasync function loadJwt(): Promise<JwtModule> {\n if (cached) return cached;\n try {\n const mod = (await import(\"jsonwebtoken\")) as JwtModule & { default?: JwtModule };\n cached = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"JWTUtils requires the 'jsonwebtoken' peer dependency. Install with `npm i jsonwebtoken`.\",\n { cause },\n );\n }\n return cached;\n}\n\n/** JWT claims — a free-form payload. */\nexport type JwtClaims = Record<string, unknown>;\n\n/** Options for {@link JWTUtils}. */\nexport interface JWTUtilsOptions {\n /** Signing algorithm. Defaults to `HS256`. */\n algorithm?: \"HS256\" | \"HS384\" | \"HS512\" | \"RS256\" | \"ES256\";\n /** Default token lifetime in seconds. Defaults to 3600 (1 hour). */\n defaultTtlSeconds?: number;\n /** Value for the `iss` claim; when set, `decode` verifies it. */\n issuer?: string;\n}\n\n/** Encode and decode JWTs using a shared secret (or asymmetric key). */\nexport class JWTUtils {\n private readonly algorithm: NonNullable<JWTUtilsOptions[\"algorithm\"]>;\n private readonly defaultTtlSeconds: number;\n private readonly issuer: string | undefined;\n\n /**\n * @param secret - The signing key (HMAC secret or private key).\n * @param options - Algorithm, default TTL and optional issuer.\n */\n constructor(\n private readonly secret: string,\n options: JWTUtilsOptions = {},\n ) {\n this.algorithm = options.algorithm ?? \"HS256\";\n this.defaultTtlSeconds = options.defaultTtlSeconds ?? 3600;\n this.issuer = options.issuer;\n }\n\n /**\n * Encode `payload` as a signed JWT.\n *\n * @param payload - Claims to include (typically `{ sub: \"<user-id>\" }`).\n * @param options - Override the default TTL for this call.\n * @returns The compact-serialized JWT.\n */\n async encode(\n payload: JwtClaims,\n options: { ttlSeconds?: number } = {},\n ): Promise<string> {\n const jwt = await loadJwt();\n return jwt.sign(payload, this.secret, {\n algorithm: this.algorithm,\n expiresIn: options.ttlSeconds ?? this.defaultTtlSeconds,\n ...(this.issuer !== undefined ? { issuer: this.issuer } : {}),\n });\n }\n\n /**\n * Decode and verify a JWT.\n *\n * @param token - The token to decode.\n * @returns The decoded claims.\n * @throws {ExpiredTokenException} When `exp` is in the past.\n * @throws {InvalidTokenException} For any other validation failure.\n */\n async decode(token: string): Promise<JwtClaims> {\n const jwt = await loadJwt();\n try {\n const decoded = jwt.verify(token, this.secret, {\n algorithms: [this.algorithm],\n ...(this.issuer !== undefined ? { issuer: this.issuer } : {}),\n });\n return typeof decoded === \"string\" ? { sub: decoded } : (decoded as JwtClaims);\n } catch (error) {\n if (error instanceof jwt.TokenExpiredError) throw new ExpiredTokenException();\n throw new InvalidTokenException();\n }\n }\n\n /**\n * Decode and verify a JWT, returning `null` on failure (soft auth).\n *\n * @param token - The token to decode.\n * @returns The decoded claims, or `null` when invalid/expired.\n */\n async decodeOrNull(token: string): Promise<JwtClaims | null> {\n try {\n return await this.decode(token);\n } catch {\n return null;\n }\n }\n}\n","/**\n * Attempt throttling, mirroring `utils.throttle`.\n *\n * Sliding-window attempt counter for flows that must resist brute force\n * (login, OTP, code verification). The default {@link MemoryThrottleBackend} is\n * process-local; swap in a shared backend (e.g. Redis) for multi-instance\n * deployments by implementing {@link ThrottleBackend}.\n */\n\n/** The outcome of recording or inspecting an attempt. */\nexport interface ThrottleStatus {\n /** Whether the attempt is allowed (budget not yet exhausted). */\n allowed: boolean;\n /** Remaining attempts in the current window (never negative). */\n remaining: number;\n /** Seconds until the window resets (`0` when allowed). */\n retryAfterSeconds: number;\n}\n\n/** Pluggable storage of attempt timestamps per key. */\nexport interface ThrottleBackend {\n /** Record an attempt at `now` (epoch ms) and return timestamps in-window. */\n hit(key: string, windowMs: number, now: number): Promise<number[]>;\n /** Read the in-window attempt timestamps without recording a new one. */\n peek(key: string, windowMs: number, now: number): Promise<number[]>;\n /** Clear all recorded attempts for `key`. */\n reset(key: string): Promise<void>;\n}\n\n/** Process-local {@link ThrottleBackend} backed by a `Map`. */\nexport class MemoryThrottleBackend implements ThrottleBackend {\n private readonly store = new Map<string, number[]>();\n\n private window(key: string, windowMs: number, now: number): number[] {\n const cutoff = now - windowMs;\n const kept = (this.store.get(key) ?? []).filter((ts) => ts > cutoff);\n this.store.set(key, kept);\n return kept;\n }\n\n async hit(key: string, windowMs: number, now: number): Promise<number[]> {\n const kept = this.window(key, windowMs, now);\n kept.push(now);\n this.store.set(key, kept);\n return kept;\n }\n\n async peek(key: string, windowMs: number, now: number): Promise<number[]> {\n return this.window(key, windowMs, now);\n }\n\n async reset(key: string): Promise<void> {\n this.store.delete(key);\n }\n}\n\n/** Options for {@link AttemptThrottle}. */\nexport interface AttemptThrottleOptions {\n /** Maximum attempts allowed within the window. */\n maxAttempts: number;\n /** Sliding-window length in seconds. */\n windowSeconds: number;\n /** Storage backend. Defaults to a {@link MemoryThrottleBackend}. */\n backend?: ThrottleBackend;\n}\n\n/** A sliding-window attempt limiter keyed by an arbitrary string. */\nexport class AttemptThrottle {\n private readonly maxAttempts: number;\n private readonly windowMs: number;\n private readonly backend: ThrottleBackend;\n\n /**\n * @param options - Budget, window and optional backend.\n */\n constructor(options: AttemptThrottleOptions) {\n this.maxAttempts = options.maxAttempts;\n this.windowMs = options.windowSeconds * 1000;\n this.backend = options.backend ?? new MemoryThrottleBackend();\n }\n\n /** Build a status from a set of in-window attempt timestamps. */\n private status(attempts: number[], now: number): ThrottleStatus {\n const allowed = attempts.length <= this.maxAttempts;\n const remaining = Math.max(0, this.maxAttempts - attempts.length);\n let retryAfterSeconds = 0;\n if (!allowed && attempts.length > 0) {\n const oldest = Math.min(...attempts);\n retryAfterSeconds = Math.max(0, Math.ceil((oldest + this.windowMs - now) / 1000));\n }\n return { allowed, remaining, retryAfterSeconds };\n }\n\n /**\n * Inspect the current budget for `key` without recording an attempt.\n *\n * @param key - The throttle key (e.g. `login:<ip>`).\n * @returns The current status.\n */\n async check(key: string): Promise<ThrottleStatus> {\n const now = Date.now();\n return this.status(await this.backend.peek(key, this.windowMs, now), now);\n }\n\n /**\n * Record an attempt for `key` and return the resulting status.\n *\n * @param key - The throttle key.\n * @returns The status after recording the attempt.\n */\n async hit(key: string): Promise<ThrottleStatus> {\n const now = Date.now();\n return this.status(await this.backend.hit(key, this.windowMs, now), now);\n }\n\n /**\n * Clear all recorded attempts for `key` (e.g. after a successful login).\n *\n * @param key - The throttle key.\n */\n async reset(key: string): Promise<void> {\n await this.backend.reset(key);\n }\n}\n","/**\n * Trusted client-IP resolution, mirroring `utils.client_ip`.\n *\n * Reading the leftmost `X-Forwarded-For` entry is a security hole — that header\n * is client-controlled. Resolve from a SINGLE header the edge proxy sets itself\n * (e.g. `X-Real-IP`, `CF-Connecting-IP`), falling back to the socket peer.\n */\n\nimport type { Request } from \"express\";\n\nconst UNKNOWN = \"unknown\";\n\n/** Options for {@link getClientIp}. */\nexport interface ClientIpOptions {\n /**\n * Name of the single edge-set header to trust (case-insensitive, e.g.\n * `\"x-real-ip\"`). Omit to use only the transport peer.\n */\n trustedHeader?: string;\n}\n\n/**\n * Resolve the client IP from an Express request.\n *\n * @param req - The inbound request.\n * @param options - The trusted header to read, if any.\n * @returns The resolved IP, or `\"unknown\"` when unavailable.\n */\nexport function getClientIp(req: Request, options: ClientIpOptions = {}): string {\n if (options.trustedHeader) {\n const value = req.header(options.trustedHeader);\n if (value) return value.trim();\n }\n return req.socket?.remoteAddress ?? req.ip ?? UNKNOWN;\n}\n","/**\n * File storage abstraction, mirroring `utils.storage_backends` / `utils.upload`.\n *\n * A narrow {@link UploadStorage} interface with a filesystem-backed\n * {@link LocalUploadStorage}. For S3/MinIO, implement the same interface over\n * your client (the interface intentionally avoids a hard cloud dependency).\n */\n\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/** The result of persisting an object. */\nexport interface UploadResult {\n /** The storage key (path within the backend). */\n key: string;\n /** A URL the object can be served from. */\n url: string;\n /** The stored byte size. */\n size: number;\n /** The declared content type, when known. */\n contentType?: string;\n}\n\n/** Options for {@link UploadStorage.save}. */\nexport interface SaveOptions {\n /** MIME type recorded on the result. */\n contentType?: string;\n}\n\n/** Narrow object-storage surface backends implement. */\nexport interface UploadStorage {\n /** Persist bytes under `key`, returning metadata. */\n save(key: string, data: Uint8Array, options?: SaveOptions): Promise<UploadResult>;\n /** Read bytes back by key. */\n read(key: string): Promise<Buffer>;\n /** Delete an object. Idempotent. */\n delete(key: string): Promise<void>;\n /** The URL an object is served from. */\n url(key: string): string;\n}\n\n/** Options for {@link LocalUploadStorage}. */\nexport interface LocalUploadStorageOptions {\n /** Filesystem root every key is written under. */\n root: string;\n /** Public base URL prefix for {@link LocalUploadStorage.url}. Default `\"\"`. */\n baseUrl?: string;\n}\n\n/** Filesystem-backed {@link UploadStorage} for local/dev or single-host setups. */\nexport class LocalUploadStorage implements UploadStorage {\n private readonly root: string;\n private readonly baseUrl: string;\n\n /**\n * @param options - Filesystem root and public base URL.\n */\n constructor(options: LocalUploadStorageOptions) {\n this.root = options.root;\n this.baseUrl = options.baseUrl ?? \"\";\n }\n\n async save(\n key: string,\n data: Uint8Array,\n options: SaveOptions = {},\n ): Promise<UploadResult> {\n const target = join(this.root, key);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, data);\n return {\n key,\n url: this.url(key),\n size: data.byteLength,\n ...(options.contentType !== undefined ? { contentType: options.contentType } : {}),\n };\n }\n\n async read(key: string): Promise<Buffer> {\n return readFile(join(this.root, key));\n }\n\n async delete(key: string): Promise<void> {\n await rm(join(this.root, key), { force: true });\n }\n\n url(key: string): string {\n const base = this.baseUrl.replace(/\\/$/, \"\");\n return base ? `${base}/${key}` : `/${key}`;\n }\n}\n\n/**\n * Build a `Content-Disposition` header value.\n *\n * @param filename - The download filename.\n * @param inline - When `true`, use `inline`; otherwise `attachment`.\n * @returns The header value (RFC 5987 `filename*` encoded).\n */\nexport function buildContentDisposition(filename: string, inline = false): string {\n const disposition = inline ? \"inline\" : \"attachment\";\n const encoded = encodeURIComponent(filename);\n return `${disposition}; filename*=UTF-8''${encoded}`;\n}\n","/**\n * File-download helpers, mirroring `utils.download`.\n *\n * Serve a file from disk with HTTP Range support (resumable / seekable\n * downloads → `206 Partial Content`) or send in-memory bytes, both with a\n * correct `Content-Disposition`. Path resolution is traversal-safe.\n */\n\nimport { createReadStream } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport { isAbsolute, join, normalize, relative } from \"node:path\";\nimport { buildContentDisposition } from \"@/storage/local\";\nimport type { Request, Response } from \"express\";\n\n/**\n * Resolve a client-supplied relative path under a root, refusing traversal\n * outside it.\n *\n * @param root - The directory downloads are confined to.\n * @param relativePath - The (untrusted) relative path.\n * @param subdir - Optional sub-directory under `root`.\n * @returns The absolute, validated path.\n * @throws {Error} When the resolved path escapes `root`.\n */\nexport function resolveDownloadPath(\n root: string,\n relativePath: string,\n subdir = \"\",\n): string {\n const base = normalize(join(root, subdir));\n const target = normalize(join(base, relativePath));\n const rel = relative(base, target);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n throw new Error(\"Resolved path escapes the download root\");\n }\n return target;\n}\n\n/** Options for {@link sendFileDownload} / {@link sendBytesDownload}. */\nexport interface DownloadOptions {\n /** Download filename; defaults to the file's basename. */\n filename?: string;\n /** MIME type. Default `application/octet-stream`. */\n contentType?: string;\n /** Serve inline (view in browser) instead of forcing a download. */\n inline?: boolean;\n}\n\n/** Parse a single-range `Range: bytes=start-end` header against a size. */\nfunction parseRange(\n header: string | undefined,\n size: number,\n): { start: number; end: number } | null {\n if (!header) return null;\n const match = /^bytes=(\\d*)-(\\d*)$/.exec(header.trim());\n if (!match) return null;\n const [, rawStart, rawEnd] = match;\n if (rawStart === \"\" && rawEnd === \"\") return null;\n let start: number;\n let end: number;\n if (rawStart === \"\") {\n // Suffix range: last N bytes.\n const suffix = Number(rawEnd);\n start = Math.max(0, size - suffix);\n end = size - 1;\n } else {\n start = Number(rawStart);\n end = rawEnd === \"\" ? size - 1 : Math.min(Number(rawEnd), size - 1);\n }\n if (Number.isNaN(start) || Number.isNaN(end) || start > end || start >= size)\n return null;\n return { start, end };\n}\n\n/**\n * Stream a file from disk as a download, honoring a `Range` request header\n * (responds `206` with `Content-Range` for a partial request, else `200`).\n *\n * @param req - The request (read for the `Range` header).\n * @param res - The response.\n * @param absolutePath - The absolute file path (validate it first — see\n * {@link resolveDownloadPath}).\n * @param options - Filename, content type and inline flag.\n * @returns Resolves once the response stream is wired up.\n */\nexport async function sendFileDownload(\n req: Request,\n res: Response,\n absolutePath: string,\n options: DownloadOptions = {},\n): Promise<void> {\n const info = await stat(absolutePath);\n const filename = options.filename ?? absolutePath.split(/[/\\\\]/).pop() ?? \"download\";\n res.setHeader(\"Content-Type\", options.contentType ?? \"application/octet-stream\");\n res.setHeader(\"Content-Disposition\", buildContentDisposition(filename, options.inline));\n res.setHeader(\"Accept-Ranges\", \"bytes\");\n\n const range = parseRange(req.header(\"range\"), info.size);\n if (range) {\n res.status(206);\n res.setHeader(\"Content-Range\", `bytes ${range.start}-${range.end}/${info.size}`);\n res.setHeader(\"Content-Length\", String(range.end - range.start + 1));\n createReadStream(absolutePath, { start: range.start, end: range.end }).pipe(res);\n return;\n }\n res.status(200);\n res.setHeader(\"Content-Length\", String(info.size));\n createReadStream(absolutePath).pipe(res);\n}\n\n/**\n * Send in-memory bytes as a download.\n *\n * @param res - The response.\n * @param data - The bytes to send.\n * @param options - Filename, content type and inline flag.\n */\nexport function sendBytesDownload(\n res: Response,\n data: Uint8Array,\n options: DownloadOptions = {},\n): void {\n const filename = options.filename ?? \"download\";\n res.setHeader(\"Content-Type\", options.contentType ?? \"application/octet-stream\");\n res.setHeader(\"Content-Disposition\", buildContentDisposition(filename, options.inline));\n res.setHeader(\"Content-Length\", String(data.byteLength));\n res.status(200).end(Buffer.from(data));\n}\n","/**\n * File-based log routing, mirroring `utils.log` / the `core.logging` file sink.\n *\n * `configureFileLogging` installs a {@link LogSink} that appends every record\n * emitted by any {@link JSONLogger} to a per-level file (`info.log`,\n * `error.log`, …) and, additionally, routes records flagged as captured HTTP\n * 500s to a dedicated `500.log` — so uncaught-error triage has its own stream.\n */\n\nimport { type WriteStream, createWriteStream } from \"node:fs\";\nimport { mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { HTTP_500_MARKER, type LogLevel, type LogSink, addLogSink } from \"@/core\";\n\n/** Per-level log file names. */\nexport const LEVEL_LOG_FILES: Record<LogLevel, string> = {\n debug: \"debug.log\",\n info: \"info.log\",\n warning: \"warning.log\",\n error: \"error.log\",\n};\n\n/** The dedicated file for captured HTTP 500 records. */\nexport const HTTP_500_LOG_FILE = \"500.log\";\n\n/** A handle to detach file logging and close the open streams. */\nexport interface FileLoggingHandle {\n /** Remove the sink and close every open file stream. */\n close(): void;\n}\n\n/** Options for {@link configureFileLogging}. */\nexport interface FileLoggingOptions {\n /** Directory the log files are written under (created if missing). */\n dir: string;\n}\n\n/**\n * Route every emitted log record into per-level files + `500.log`.\n *\n * @param options - The log directory.\n * @returns A handle whose `close()` detaches the sink and closes the streams.\n *\n * @example\n * ```ts\n * const logs = configureFileLogging({ dir: \"logs\" });\n * // ... on shutdown:\n * logs.close();\n * ```\n */\nexport function configureFileLogging(options: FileLoggingOptions): FileLoggingHandle {\n const { dir } = options;\n mkdirSync(dir, { recursive: true });\n\n const streams = new Map<string, WriteStream>();\n const streamFor = (filename: string): WriteStream => {\n let stream = streams.get(filename);\n if (!stream) {\n stream = createWriteStream(join(dir, filename), { flags: \"a\" });\n streams.set(filename, stream);\n }\n return stream;\n };\n\n const sink: LogSink = (level, record) => {\n const line = `${JSON.stringify(record)}\\n`;\n streamFor(LEVEL_LOG_FILES[level]).write(line);\n if (record[HTTP_500_MARKER]) streamFor(HTTP_500_LOG_FILE).write(line);\n };\n\n const detach = addLogSink(sink);\n return {\n close() {\n detach();\n for (const stream of streams.values()) stream.end();\n streams.clear();\n },\n };\n}\n","/**\n * TOTP (RFC 6238) helper for MFA, mirroring `utils.totp.TOTPHelper`.\n *\n * Implemented natively over `node:crypto` (HMAC-SHA1) — no external OTP library\n * needed. Generates a base32 secret, builds the `otpauth://` provisioning URI\n * (scanned as a QR code), and verifies a 6-digit code with a clock-drift window.\n */\n\nimport { createHmac, randomBytes } from \"node:crypto\";\n\nconst BASE32_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";\n\n/** Encode bytes to RFC 4648 base32 (no padding). */\nfunction base32Encode(bytes: Uint8Array): string {\n let bits = 0;\n let value = 0;\n let out = \"\";\n for (const byte of bytes) {\n value = (value << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n out += BASE32_ALPHABET[(value >>> (bits - 5)) & 31];\n bits -= 5;\n }\n }\n if (bits > 0) out += BASE32_ALPHABET[(value << (5 - bits)) & 31];\n return out;\n}\n\n/** Decode an RFC 4648 base32 string (ignores padding/case) to bytes. */\nfunction base32Decode(secret: string): Buffer {\n const clean = secret.toUpperCase().replace(/=+$/, \"\").replace(/\\s/g, \"\");\n let bits = 0;\n let value = 0;\n const out: number[] = [];\n for (const char of clean) {\n const index = BASE32_ALPHABET.indexOf(char);\n if (index === -1) continue;\n value = (value << 5) | index;\n bits += 5;\n if (bits >= 8) {\n out.push((value >>> (bits - 8)) & 0xff);\n bits -= 8;\n }\n }\n return Buffer.from(out);\n}\n\n/** Compute the HOTP code for a counter, per RFC 4226. */\nfunction hotp(secret: Buffer, counter: number, digits: number): string {\n const buffer = Buffer.alloc(8);\n // 53-bit safe integer counter written big-endian.\n buffer.writeUInt32BE(Math.floor(counter / 2 ** 32), 0);\n buffer.writeUInt32BE(counter >>> 0, 4);\n const digest = createHmac(\"sha1\", secret).update(buffer).digest();\n const offset = (digest[digest.length - 1] as number) & 0xf;\n const binary =\n (((digest[offset] as number) & 0x7f) << 24) |\n (((digest[offset + 1] as number) & 0xff) << 16) |\n (((digest[offset + 2] as number) & 0xff) << 8) |\n ((digest[offset + 3] as number) & 0xff);\n return (binary % 10 ** digits).toString().padStart(digits, \"0\");\n}\n\n/** Options for {@link TOTPHelper}. */\nexport interface TOTPOptions {\n /** Label shown in the authenticator app (e.g. the product name). */\n issuer: string;\n /** Time step in seconds. Default 30. */\n step?: number;\n /** Number of digits. Default 6. */\n digits?: number;\n}\n\n/** Stateless TOTP issuer + verifier. Construct one per app. */\nexport class TOTPHelper {\n private readonly issuer: string;\n private readonly step: number;\n private readonly digits: number;\n\n /**\n * @param options - Issuer label, time step and digit count.\n */\n constructor(options: TOTPOptions) {\n this.issuer = options.issuer;\n this.step = options.step ?? 30;\n this.digits = options.digits ?? 6;\n }\n\n /**\n * Generate a fresh base32 secret (80 bits).\n *\n * @returns A base32-encoded TOTP secret to persist on the user row.\n */\n generateSecret(): string {\n return base32Encode(randomBytes(10));\n }\n\n /**\n * Build the `otpauth://` provisioning URI (render as a QR code).\n *\n * @param secret - The base32 secret.\n * @param accountName - Identifier shown next to the issuer (e.g. the email).\n * @returns The `otpauth://totp/...` URI.\n */\n provisioningUri(secret: string, accountName: string): string {\n const label = encodeURIComponent(`${this.issuer}:${accountName}`);\n const params = new URLSearchParams({\n secret,\n issuer: this.issuer,\n algorithm: \"SHA1\",\n digits: String(this.digits),\n period: String(this.step),\n });\n return `otpauth://totp/${label}?${params.toString()}`;\n }\n\n /**\n * Verify a code against the secret for the current time window.\n *\n * @param secret - The base32 secret.\n * @param code - The submitted code.\n * @param window - Tolerance in steps (±). Default 1 (previous/current/next).\n * @returns `true` when the code matches within the window.\n */\n verify(secret: string, code: string, window = 1): boolean {\n const cleaned = code.trim().replace(/[\\s-]/g, \"\");\n if (!/^\\d+$/.test(cleaned) || cleaned.length !== this.digits) return false;\n const key = base32Decode(secret);\n const counter = Math.floor(Date.now() / 1000 / this.step);\n for (let offset = -window; offset <= window; offset++) {\n if (hotp(key, counter + offset, this.digits) === cleaned) return true;\n }\n return false;\n }\n}\n","/**\n * Resilient HTTP client, mirroring `utils.http_client`.\n *\n * Wraps the native `fetch` with a retry policy (exponential backoff) and a\n * per-host circuit breaker: after N consecutive failures the breaker opens and\n * requests to that host fail fast with {@link CircuitOpenError} until a cooldown\n * elapses. No external dependency.\n */\n\n/** Raised when the per-host circuit breaker is open. */\nexport class CircuitOpenError extends Error {\n constructor(readonly host: string) {\n super(`Circuit breaker is open for host ${host}`);\n this.name = \"CircuitOpenError\";\n }\n}\n\n/** Retry configuration for {@link HTTPClient}. */\nexport class RetryPolicy {\n /**\n * @param maxRetries - Additional attempts after the first. Default 2.\n * @param baseDelayMs - Base backoff in ms (doubles each attempt). Default 100.\n * @param retryOn - HTTP status codes that trigger a retry. Default 5xx + 429.\n */\n constructor(\n readonly maxRetries = 2,\n readonly baseDelayMs = 100,\n readonly retryOn: number[] = [429, 500, 502, 503, 504],\n ) {}\n\n /** Backoff delay in ms before `attempt` (0-indexed). */\n sleepFor(attempt: number): number {\n return this.baseDelayMs * 2 ** attempt;\n }\n}\n\ninterface BreakerState {\n failures: number;\n openUntil: number;\n}\n\n/** Options for {@link HTTPClient}. */\nexport interface HTTPClientOptions {\n /** Prepended to relative request paths. */\n baseUrl?: string;\n /** Headers merged into every request. */\n defaultHeaders?: Record<string, string>;\n /** Per-request timeout in ms. Default 30000. */\n timeoutMs?: number;\n /** Retry configuration. */\n retryPolicy?: RetryPolicy;\n /** Consecutive failures before the breaker opens. Default 5. */\n breakerThreshold?: number;\n /** Breaker cooldown in ms once open. Default 30000. */\n breakerCooldownMs?: number;\n}\n\n/** A `fetch` wrapper with retries and a per-host circuit breaker. */\nexport class HTTPClient {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeoutMs: number;\n private readonly retryPolicy: RetryPolicy;\n private readonly breakerThreshold: number;\n private readonly breakerCooldownMs: number;\n private readonly breakers = new Map<string, BreakerState>();\n\n /**\n * @param options - Base URL, headers, timeout, retry and breaker settings.\n */\n constructor(options: HTTPClientOptions = {}) {\n this.baseUrl = options.baseUrl ?? \"\";\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.timeoutMs = options.timeoutMs ?? 30000;\n this.retryPolicy = options.retryPolicy ?? new RetryPolicy();\n this.breakerThreshold = options.breakerThreshold ?? 5;\n this.breakerCooldownMs = options.breakerCooldownMs ?? 30000;\n }\n\n private resolve(url: string): string {\n return this.baseUrl && !/^https?:\\/\\//.test(url) ? `${this.baseUrl}${url}` : url;\n }\n\n private hostOf(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return url;\n }\n }\n\n private breakerCheck(host: string): void {\n const state = this.breakers.get(host);\n if (state && state.openUntil > Date.now()) throw new CircuitOpenError(host);\n }\n\n private breakerRecord(host: string, failed: boolean): void {\n const state = this.breakers.get(host) ?? { failures: 0, openUntil: 0 };\n if (failed) {\n state.failures += 1;\n if (state.failures >= this.breakerThreshold) {\n state.openUntil = Date.now() + this.breakerCooldownMs;\n state.failures = 0;\n }\n } else {\n state.failures = 0;\n state.openUntil = 0;\n }\n this.breakers.set(host, state);\n }\n\n /**\n * Perform a request with retries and breaker protection.\n *\n * @param method - HTTP method.\n * @param url - Absolute URL or a path resolved against `baseUrl`.\n * @param init - Extra `fetch` init (headers, body, …).\n * @returns The `Response`.\n * @throws {CircuitOpenError} When the per-host breaker is open.\n */\n async request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const target = this.resolve(url);\n const host = this.hostOf(target);\n this.breakerCheck(host);\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= this.retryPolicy.maxRetries; attempt++) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await fetch(target, {\n ...init,\n method,\n headers: { ...this.defaultHeaders, ...(init.headers ?? {}) },\n signal: controller.signal,\n });\n clearTimeout(timer);\n if (this.retryPolicy.retryOn.includes(response.status)) {\n this.breakerRecord(host, true);\n if (attempt < this.retryPolicy.maxRetries) {\n await this.sleep(this.retryPolicy.sleepFor(attempt));\n continue;\n }\n return response;\n }\n this.breakerRecord(host, false);\n return response;\n } catch (error) {\n clearTimeout(timer);\n lastError = error;\n this.breakerRecord(host, true);\n if (attempt < this.retryPolicy.maxRetries) {\n await this.sleep(this.retryPolicy.sleepFor(attempt));\n continue;\n }\n }\n }\n throw lastError instanceof Error ? lastError : new Error(\"Request failed\");\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /** GET request. */\n get(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"GET\", url, init);\n }\n /** POST request. */\n post(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"POST\", url, init);\n }\n /** PUT request. */\n put(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"PUT\", url, init);\n }\n /** PATCH request. */\n patch(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"PATCH\", url, init);\n }\n /** DELETE request. */\n delete(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"DELETE\", url, init);\n }\n}\n","/**\n * System metrics, mirroring `utils.metrics.MetricsUtils`.\n *\n * Reads CPU, memory and process stats from Node's built-in `node:os` /\n * `process` — no native dependency. Optional GPU metrics shell out to\n * `nvidia-smi` (returns `[]` when unavailable). Includes a Prometheus\n * text-format exporter.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { cpus, freemem, loadavg, totalmem } from \"node:os\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/** CPU load metrics. */\nexport interface CPUMetrics {\n /** Number of logical cores. */\n cores: number;\n /** 1-minute load average (0 on platforms without load average). */\n load1: number;\n /** Load average over 1 minute as a fraction of core count. */\n loadPercent: number;\n}\n\n/** Memory usage metrics (bytes). */\nexport interface MemoryMetrics {\n /** Total system memory. */\n total: number;\n /** Free system memory. */\n free: number;\n /** Used system memory. */\n used: number;\n /** Used memory as a percentage of total. */\n usedPercent: number;\n /** Resident set size of the current process. */\n processRss: number;\n}\n\n/** A single GPU's metrics (from `nvidia-smi`). */\nexport interface GPUMetrics {\n /** GPU index. */\n index: number;\n /** GPU utilization percent. */\n utilizationPercent: number;\n /** Used memory in MiB. */\n memoryUsedMb: number;\n /** Total memory in MiB. */\n memoryTotalMb: number;\n /** Core temperature in °C. */\n temperatureC: number;\n}\n\n/** A snapshot of system + process metrics. */\nexport interface SystemMetrics {\n cpu: CPUMetrics;\n memory: MemoryMetrics;\n /** Process uptime in seconds. */\n uptimeSeconds: number;\n}\n\n/** Read CPU load metrics. */\nfunction readCpu(): CPUMetrics {\n const cores = cpus().length;\n const load1 = loadavg()[0] ?? 0;\n return {\n cores,\n load1,\n loadPercent: cores > 0 ? (load1 / cores) * 100 : 0,\n };\n}\n\n/** Read memory usage metrics. */\nfunction readMemory(): MemoryMetrics {\n const total = totalmem();\n const free = freemem();\n const used = total - free;\n return {\n total,\n free,\n used,\n usedPercent: total > 0 ? (used / total) * 100 : 0,\n processRss: process.memoryUsage().rss,\n };\n}\n\n/** Read a full system snapshot. */\nfunction readSystem(): SystemMetrics {\n return {\n cpu: readCpu(),\n memory: readMemory(),\n uptimeSeconds: process.uptime(),\n };\n}\n\n/**\n * Read GPU metrics via `nvidia-smi`. Returns `[]` when the tool is absent or\n * fails (no GPU, not installed) — never throws.\n *\n * @returns One {@link GPUMetrics} per detected GPU.\n */\nasync function readGpus(): Promise<GPUMetrics[]> {\n try {\n const { stdout } = await execFileAsync(\"nvidia-smi\", [\n \"--query-gpu=index,utilization.gpu,memory.used,memory.total,temperature.gpu\",\n \"--format=csv,noheader,nounits\",\n ]);\n return stdout\n .trim()\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0)\n .map((line) => {\n const [index, util, used, total, temp] = line\n .split(\",\")\n .map((v) => Number(v.trim()));\n return {\n index: index ?? 0,\n utilizationPercent: util ?? 0,\n memoryUsedMb: used ?? 0,\n memoryTotalMb: total ?? 0,\n temperatureC: temp ?? 0,\n };\n });\n } catch {\n return [];\n }\n}\n\n/**\n * Render metrics as Prometheus text-format.\n *\n * @param snapshot - A system snapshot (defaults to a fresh {@link readSystem}).\n * @param gpus - Optional GPU metrics to append (from {@link readGpus}).\n * @returns The Prometheus exposition text.\n */\nfunction toPrometheus(\n snapshot: SystemMetrics = readSystem(),\n gpus: GPUMetrics[] = [],\n): string {\n const lines = [\n \"# HELP process_cpu_load_percent 1-minute load average as percent of cores\",\n \"# TYPE process_cpu_load_percent gauge\",\n `process_cpu_load_percent ${snapshot.cpu.loadPercent}`,\n \"# HELP process_memory_used_percent System memory used percent\",\n \"# TYPE process_memory_used_percent gauge\",\n `process_memory_used_percent ${snapshot.memory.usedPercent}`,\n \"# HELP process_memory_rss_bytes Resident set size of the process\",\n \"# TYPE process_memory_rss_bytes gauge\",\n `process_memory_rss_bytes ${snapshot.memory.processRss}`,\n \"# HELP process_uptime_seconds Process uptime in seconds\",\n \"# TYPE process_uptime_seconds counter\",\n `process_uptime_seconds ${snapshot.uptimeSeconds}`,\n ];\n if (gpus.length > 0) {\n lines.push(\n \"# HELP gpu_utilization_percent GPU utilization percent\",\n \"# TYPE gpu_utilization_percent gauge\",\n );\n for (const gpu of gpus) {\n lines.push(`gpu_utilization_percent{gpu=\"${gpu.index}\"} ${gpu.utilizationPercent}`);\n }\n lines.push(\n \"# HELP gpu_memory_used_mb GPU memory used in MiB\",\n \"# TYPE gpu_memory_used_mb gauge\",\n );\n for (const gpu of gpus) {\n lines.push(`gpu_memory_used_mb{gpu=\"${gpu.index}\"} ${gpu.memoryUsedMb}`);\n }\n lines.push(\n \"# HELP gpu_temperature_celsius GPU core temperature\",\n \"# TYPE gpu_temperature_celsius gauge\",\n );\n for (const gpu of gpus) {\n lines.push(`gpu_temperature_celsius{gpu=\"${gpu.index}\"} ${gpu.temperatureC}`);\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** Stateless system-metrics reader + Prometheus exporter. */\nexport const MetricsUtils = {\n cpu: readCpu,\n memory: readMemory,\n system: readSystem,\n gpus: readGpus,\n toPrometheus,\n} as const;\n","/**\n * Transactional email, mirroring `utils.email.EmailUtils`.\n *\n * Wraps the optional `nodemailer` peer (lazily imported) behind a tiny\n * `send` surface. The transport is created once from SMTP options and reused.\n */\n\n/** SMTP connection + sender options. */\nexport interface EmailOptions {\n /** SMTP host. */\n host: string;\n /** SMTP port. Default 587. */\n port?: number;\n /** Use TLS on connect. Default `false` (STARTTLS on 587). */\n secure?: boolean;\n /** SMTP auth user. */\n user?: string;\n /** SMTP auth password. */\n password?: string;\n /** Default `From` address. */\n from: string;\n}\n\n/** A single email message. */\nexport interface EmailMessage {\n /** Recipient(s). */\n to: string | string[];\n /** Subject line. */\n subject: string;\n /** Plain-text body. */\n text?: string;\n /** HTML body. */\n html?: string;\n /** Override the default `From`. */\n from?: string;\n}\n\ntype NodemailerModule = typeof import(\"nodemailer\");\ntype Transport = ReturnType<NodemailerModule[\"createTransport\"]>;\n\n/** Sends transactional email over SMTP via `nodemailer`. */\nexport class EmailUtils {\n private transport: Transport | null = null;\n\n /**\n * @param options - SMTP connection and default sender.\n */\n constructor(private readonly options: EmailOptions) {}\n\n private async ready(): Promise<Transport> {\n if (this.transport) return this.transport;\n let nodemailer: NodemailerModule;\n try {\n const mod = (await import(\"nodemailer\")) as NodemailerModule & {\n default?: NodemailerModule;\n };\n nodemailer = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"EmailUtils requires the 'nodemailer' peer dependency. Install with `npm i nodemailer`.\",\n { cause },\n );\n }\n this.transport = nodemailer.createTransport({\n host: this.options.host,\n port: this.options.port ?? 587,\n secure: this.options.secure ?? false,\n ...(this.options.user\n ? { auth: { user: this.options.user, pass: this.options.password ?? \"\" } }\n : {}),\n });\n return this.transport;\n }\n\n /**\n * Send an email message.\n *\n * @param message - The message (recipients, subject, body).\n */\n async send(message: EmailMessage): Promise<void> {\n const transport = await this.ready();\n await transport.sendMail({\n from: message.from ?? this.options.from,\n to: message.to,\n subject: message.subject,\n ...(message.text !== undefined ? { text: message.text } : {}),\n ...(message.html !== undefined ? { html: message.html } : {}),\n });\n }\n}\n","/**\n * Cache managers, mirroring `cache.redis_manager`.\n *\n * A narrow async cache interface ({@link CacheManager}) with two backends: an\n * in-process {@link MemoryCacheManager} (dev/tests/single replica) and a\n * {@link RedisCacheManager} backed by the optional `redis` peer (lazily\n * imported, like the auth helpers). Values are JSON-serialized.\n */\n\n/** Narrow async cache surface every backend implements. */\nexport interface CacheManager {\n /** Read a value by key, or `null` when missing/expired. */\n get<T>(key: string): Promise<T | null>;\n /** Write a value with an optional TTL in seconds. */\n set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;\n /** Delete a key. Idempotent. */\n delete(key: string): Promise<void>;\n /** Whether a live (non-expired) value exists for `key`. */\n has(key: string): Promise<boolean>;\n /** Remove every entry. */\n clear(): Promise<void>;\n}\n\ninterface Entry {\n value: string;\n expiresAt: number | null;\n}\n\n/** In-process {@link CacheManager} backed by a `Map`, with lazy TTL expiry. */\nexport class MemoryCacheManager implements CacheManager {\n private readonly store = new Map<string, Entry>();\n\n private live(key: string): Entry | null {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt !== null && entry.expiresAt <= Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const entry = this.live(key);\n return entry ? (JSON.parse(entry.value) as T) : null;\n }\n\n async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {\n this.store.set(key, {\n value: JSON.stringify(value),\n expiresAt: ttlSeconds !== undefined ? Date.now() + ttlSeconds * 1000 : null,\n });\n }\n\n async delete(key: string): Promise<void> {\n this.store.delete(key);\n }\n\n async has(key: string): Promise<boolean> {\n return this.live(key) !== null;\n }\n\n async clear(): Promise<void> {\n this.store.clear();\n }\n}\n\n/** A minimal subset of the `redis` client this manager relies on. */\nexport interface RedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: { EX?: number }): Promise<unknown>;\n del(key: string): Promise<unknown>;\n exists(key: string): Promise<number>;\n flushDb(): Promise<unknown>;\n}\n\n/** Redis-backed {@link CacheManager}. Pass a connected `redis` v4 client. */\nexport class RedisCacheManager implements CacheManager {\n /**\n * @param client - A connected `redis` (node-redis v4) client or compatible.\n * @param prefix - Optional key prefix applied to every operation.\n */\n constructor(\n private readonly client: RedisLike,\n private readonly prefix = \"\",\n ) {}\n\n private key(key: string): string {\n return this.prefix ? `${this.prefix}${key}` : key;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const raw = await this.client.get(this.key(key));\n return raw === null ? null : (JSON.parse(raw) as T);\n }\n\n async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {\n const payload = JSON.stringify(value);\n await this.client.set(\n this.key(key),\n payload,\n ttlSeconds !== undefined ? { EX: ttlSeconds } : undefined,\n );\n }\n\n async delete(key: string): Promise<void> {\n await this.client.del(this.key(key));\n }\n\n async has(key: string): Promise<boolean> {\n return (await this.client.exists(this.key(key))) > 0;\n }\n\n async clear(): Promise<void> {\n await this.client.flushDb();\n }\n}\n","/**\n * Read-through memoization helper, mirroring `cache.decorator.cached`.\n *\n * Wraps an async function so its result is cached under a derived key. On a hit\n * the cached value is returned without calling the function; on a miss the\n * function runs and its result is stored with an optional TTL.\n */\n\nimport type { CacheManager } from \"@/cache/manager\";\n\n/** Options for {@link cached}. */\nexport interface CachedOptions<A extends unknown[]> {\n /** The cache backend to read/write. */\n manager: CacheManager;\n /** Build the cache key from the call arguments. */\n key: (...args: A) => string;\n /** TTL in seconds for stored values. Omit for no expiry. */\n ttlSeconds?: number;\n}\n\n/**\n * Wrap an async function with read-through caching.\n *\n * @param fn - The async function to memoize.\n * @param options - Cache backend, key builder and optional TTL.\n * @returns A function with the same signature, served from cache when possible.\n *\n * @example\n * ```ts\n * const getUser = cached(fetchUser, {\n * manager,\n * key: (id: string) => `user:${id}`,\n * ttlSeconds: 60,\n * });\n * ```\n */\nexport function cached<A extends unknown[], R>(\n fn: (...args: A) => Promise<R>,\n options: CachedOptions<A>,\n): (...args: A) => Promise<R> {\n return async (...args: A): Promise<R> => {\n const key = options.key(...args);\n const hit = await options.manager.get<R>(key);\n if (hit !== null) return hit;\n const result = await fn(...args);\n await options.manager.set(key, result, options.ttlSeconds);\n return result;\n };\n}\n","/**\n * Session model + store, mirroring `sessions.store` / `sessions.schemas`.\n *\n * Sessions are keyed by the SHA-256 hash of the opaque cookie value, so a leak\n * of the store yields no reusable cookies. The {@link SessionStore} interface is\n * narrow; {@link MemorySessionStore} is the in-process implementation for\n * dev/tests/single-replica (a Redis store is a planned follow-up).\n */\n\n/** A persisted session row. */\nexport interface Session {\n /** SHA-256 hash of the opaque cookie value (the store key). */\n idHash: string;\n /** The owning user id. */\n userId: string;\n /** Arbitrary JSON-serializable session payload. */\n data: Record<string, unknown>;\n /** Creation timestamp (epoch ms). */\n createdAt: number;\n /** Expiry timestamp (epoch ms). */\n expiresAt: number;\n}\n\n/** Persistence port every session backend implements. */\nexport interface SessionStore {\n /** Return the live session for `idHash`, or `null` when missing/expired. */\n get(idHash: string): Promise<Session | null>;\n /** Persist or overwrite a session. */\n set(session: Session): Promise<void>;\n /** Remove a single session. Idempotent. */\n delete(idHash: string): Promise<void>;\n /** Remove every session for `userId`; returns the count deleted. */\n deleteByUser(userId: string): Promise<number>;\n /** Return every live session for `userId` (oldest first). */\n listByUser(userId: string): Promise<Session[]>;\n}\n\n/** In-process {@link SessionStore} with a secondary user index. */\nexport class MemorySessionStore implements SessionStore {\n private readonly byHash = new Map<string, Session>();\n\n private live(session: Session | undefined, idHash: string): Session | null {\n if (!session) return null;\n if (session.expiresAt <= Date.now()) {\n this.byHash.delete(idHash);\n return null;\n }\n return session;\n }\n\n async get(idHash: string): Promise<Session | null> {\n return this.live(this.byHash.get(idHash), idHash);\n }\n\n async set(session: Session): Promise<void> {\n this.byHash.set(session.idHash, session);\n }\n\n async delete(idHash: string): Promise<void> {\n this.byHash.delete(idHash);\n }\n\n async deleteByUser(userId: string): Promise<number> {\n let count = 0;\n for (const [hash, session] of this.byHash) {\n if (session.userId === userId) {\n this.byHash.delete(hash);\n count += 1;\n }\n }\n return count;\n }\n\n async listByUser(userId: string): Promise<Session[]> {\n const now = Date.now();\n return [...this.byHash.values()]\n .filter((s) => s.userId === userId && s.expiresAt > now)\n .sort((a, b) => a.createdAt - b.createdAt);\n }\n}\n","/**\n * Session service, mirroring `sessions.service`.\n *\n * Issues opaque session cookies, persists only their SHA-256 hash, and resolves\n * an incoming cookie back to a live {@link Session}. Built on the SDK's opaque\n * token helpers so the store never holds a usable cookie value.\n */\n\nimport type { Session, SessionStore } from \"@/sessions/store\";\nimport { generateOpaqueToken, hashOpaqueToken } from \"@/utils/opaqueToken\";\n\n/** Options for {@link SessionService}. */\nexport interface SessionServiceOptions {\n /** The backing store. */\n store: SessionStore;\n /** Default session lifetime in seconds. Default 604800 (7 days). */\n ttlSeconds?: number;\n}\n\n/** A freshly created session and its one-time plaintext cookie value. */\nexport interface IssuedSession {\n /** The opaque cookie value to set on the client (shown once). */\n token: string;\n /** The persisted session row. */\n session: Session;\n}\n\nexport class SessionService {\n private readonly store: SessionStore;\n private readonly ttlSeconds: number;\n\n /**\n * @param options - Store and default TTL.\n */\n constructor(options: SessionServiceOptions) {\n this.store = options.store;\n this.ttlSeconds = options.ttlSeconds ?? 60 * 60 * 24 * 7;\n }\n\n /**\n * Create a session for `userId` and return its one-time cookie value.\n *\n * @param userId - The owning user id.\n * @param data - Arbitrary session payload.\n * @param ttlSeconds - Override the default lifetime.\n * @returns The plaintext token (set as a cookie) and the stored session.\n */\n async create(\n userId: string,\n data: Record<string, unknown> = {},\n ttlSeconds?: number,\n ): Promise<IssuedSession> {\n const { plaintext, tokenHash } = generateOpaqueToken();\n const now = Date.now();\n const session: Session = {\n idHash: tokenHash,\n userId,\n data,\n createdAt: now,\n expiresAt: now + (ttlSeconds ?? this.ttlSeconds) * 1000,\n };\n await this.store.set(session);\n return { token: plaintext, session };\n }\n\n /**\n * Resolve an opaque cookie value to its live session.\n *\n * @param token - The plaintext cookie value.\n * @returns The session, or `null` when missing/expired.\n */\n async resolve(token: string): Promise<Session | null> {\n return this.store.get(hashOpaqueToken(token));\n }\n\n /**\n * Revoke a single session by its cookie value.\n *\n * @param token - The plaintext cookie value.\n */\n async destroy(token: string): Promise<void> {\n await this.store.delete(hashOpaqueToken(token));\n }\n\n /**\n * Revoke every session a user owns (global logout).\n *\n * @param userId - The user id.\n * @returns The number of sessions removed.\n */\n async destroyByUser(userId: string): Promise<number> {\n return this.store.deleteByUser(userId);\n }\n\n /**\n * List a user's live sessions (e.g. an \"active devices\" view).\n *\n * @param userId - The user id.\n * @returns The user's sessions, oldest first.\n */\n async listByUser(userId: string): Promise<Session[]> {\n return this.store.listByUser(userId);\n }\n}\n","/**\n * Session middleware, mirroring `sessions.middleware`.\n *\n * Reads the session cookie, resolves it to a live {@link Session} via the\n * {@link SessionService}, and attaches it to `req.session` (or `null` when\n * absent/expired). Pairs with {@link makeJwtAuthMiddleware} for JWT auth; use\n * whichever model fits the surface.\n */\n\nimport type { SessionService } from \"@/sessions/service\";\nimport type { Session } from \"@/sessions/store\";\nimport type { Request, RequestHandler } from \"express\";\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n /** The live session for this request, populated by the middleware. */\n interface Request {\n session?: Session | null;\n }\n }\n}\n\n/** Parse the `Cookie` header into a name → value map. */\nexport function parseCookies(header: string | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const index = part.indexOf(\"=\");\n if (index < 0) continue;\n const name = part.slice(0, index).trim();\n const value = part.slice(index + 1).trim();\n if (name) out[name] = decodeURIComponent(value);\n }\n return out;\n}\n\n/** Read the session cookie value from a request, or `null`. */\nexport function sessionCookie(req: Request, cookieName: string): string | null {\n return parseCookies(req.header(\"cookie\") ?? undefined)[cookieName] ?? null;\n}\n\n/** Options for {@link makeSessionMiddleware}. */\nexport interface SessionMiddlewareOptions {\n /** Cookie name carrying the opaque session id. Default `sid`. */\n cookieName?: string;\n}\n\n/**\n * Build middleware that resolves the session cookie into `req.session`.\n *\n * @param service - The session service used to resolve cookies.\n * @param options - Cookie name.\n * @returns An Express middleware.\n */\nexport function makeSessionMiddleware(\n service: SessionService,\n options: SessionMiddlewareOptions = {},\n): RequestHandler {\n const cookieName = options.cookieName ?? \"sid\";\n return (req, _res, next) => {\n const token = sessionCookie(req, cookieName);\n if (!token) {\n req.session = null;\n next();\n return;\n }\n service\n .resolve(token)\n .then((session) => {\n req.session = session;\n next();\n })\n .catch(next);\n };\n}\n","/**\n * Redis-backed {@link SessionStore} for multi-replica deployments.\n *\n * Sessions live under `sess:<idHash>` with a Redis TTL; a per-user set\n * (`sess:user:<userId>`) indexes them so `listByUser`/`deleteByUser` work\n * without scanning. Takes an injected client (node-redis v4 compatible) so the\n * SDK never hard-depends on `redis`. Expired keys drop via TTL; stale index\n * entries are pruned lazily on read.\n */\n\nimport type { Session, SessionStore } from \"@/sessions/store\";\n\n/** The subset of a node-redis v4 client this store needs. */\nexport interface SessionRedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: { EX?: number }): Promise<unknown>;\n del(key: string): Promise<unknown>;\n sAdd(key: string, member: string): Promise<unknown>;\n sRem(key: string, member: string): Promise<unknown>;\n sMembers(key: string): Promise<string[]>;\n}\n\n/** Redis-backed session store. */\nexport class RedisSessionStore implements SessionStore {\n /**\n * @param client - A connected node-redis v4 (or compatible) client.\n * @param prefix - Key prefix. Default `sess:`.\n */\n constructor(\n private readonly client: SessionRedisLike,\n private readonly prefix = \"sess:\",\n ) {}\n\n private key(idHash: string): string {\n return `${this.prefix}${idHash}`;\n }\n\n private userKey(userId: string): string {\n return `${this.prefix}user:${userId}`;\n }\n\n async get(idHash: string): Promise<Session | null> {\n const raw = await this.client.get(this.key(idHash));\n if (raw === null) return null;\n const session = JSON.parse(raw) as Session;\n if (session.expiresAt <= Date.now()) {\n await this.delete(idHash);\n return null;\n }\n return session;\n }\n\n async set(session: Session): Promise<void> {\n const ttlSeconds = Math.max(1, Math.ceil((session.expiresAt - Date.now()) / 1000));\n await this.client.set(this.key(session.idHash), JSON.stringify(session), {\n EX: ttlSeconds,\n });\n await this.client.sAdd(this.userKey(session.userId), session.idHash);\n }\n\n async delete(idHash: string): Promise<void> {\n const raw = await this.client.get(this.key(idHash));\n await this.client.del(this.key(idHash));\n if (raw) {\n const session = JSON.parse(raw) as Session;\n await this.client.sRem(this.userKey(session.userId), idHash);\n }\n }\n\n async deleteByUser(userId: string): Promise<number> {\n const ids = await this.client.sMembers(this.userKey(userId));\n let count = 0;\n for (const idHash of ids) {\n await this.client.del(this.key(idHash));\n await this.client.sRem(this.userKey(userId), idHash);\n count += 1;\n }\n return count;\n }\n\n async listByUser(userId: string): Promise<Session[]> {\n const ids = await this.client.sMembers(this.userKey(userId));\n const sessions: Session[] = [];\n const now = Date.now();\n for (const idHash of ids) {\n const raw = await this.client.get(this.key(idHash));\n if (raw === null) {\n await this.client.sRem(this.userKey(userId), idHash); // prune stale index\n continue;\n }\n const session = JSON.parse(raw) as Session;\n if (session.expiresAt > now) sessions.push(session);\n }\n return sessions.sort((a, b) => a.createdAt - b.createdAt);\n }\n}\n","/**\n * Server-Sent Events primitives, mirroring `sse.event_stream`.\n *\n * {@link ServerSentEvent} encodes the SSE wire format; {@link EventStream} is a\n * per-subscriber push queue exposed as an async iterator with an optional\n * heartbeat; {@link sseResponse} wires a stream to an Express response.\n */\n\nimport type { Request, Response } from \"express\";\n\n/** A single Server-Sent Event. */\nexport interface ServerSentEventInit {\n /** The event payload (serialized to one or more `data:` lines). */\n data: string;\n /** Optional event name (`event:` line). */\n event?: string;\n /** Optional event id (`id:` line). */\n id?: string;\n /** Optional reconnection hint in ms (`retry:` line). */\n retry?: number;\n}\n\n/** An SSE event that can encode itself to the wire format. */\nexport class ServerSentEvent {\n constructor(private readonly init: ServerSentEventInit) {}\n\n /**\n * Encode to the SSE wire format (terminated by a blank line).\n *\n * @returns The encoded event block.\n */\n encode(): string {\n const lines: string[] = [];\n if (this.init.event) lines.push(`event: ${this.init.event}`);\n if (this.init.id) lines.push(`id: ${this.init.id}`);\n if (this.init.retry !== undefined) lines.push(`retry: ${this.init.retry}`);\n for (const line of this.init.data.split(\"\\n\")) lines.push(`data: ${line}`);\n return `${lines.join(\"\\n\")}\\n\\n`;\n }\n}\n\n/** A deferred used to wake the iterator when a new event arrives. */\nfunction deferred<T>(): { promise: Promise<T>; resolve: (value: T) => void } {\n let resolve!: (value: T) => void;\n const promise = new Promise<T>((r) => {\n resolve = r;\n });\n return { promise, resolve };\n}\n\n/** Options for {@link EventStream}. */\nexport interface EventStreamOptions {\n /** Heartbeat interval in seconds (comment ping). `null` disables. Default 15. */\n heartbeatSeconds?: number | null;\n}\n\n/** A single subscriber's event queue, consumable as an async iterator. */\nexport class EventStream {\n private readonly queue: string[] = [];\n private waiter: ReturnType<typeof deferred<void>> | null = null;\n private closed = false;\n private readonly heartbeatSeconds: number | null;\n\n /**\n * @param options - Heartbeat configuration.\n */\n constructor(options: EventStreamOptions = {}) {\n this.heartbeatSeconds = options.heartbeatSeconds ?? 15;\n }\n\n /** Enqueue raw SSE-encoded text and wake the iterator. */\n private push(raw: string): void {\n if (this.closed) return;\n this.queue.push(raw);\n this.waiter?.resolve();\n this.waiter = null;\n }\n\n /**\n * Publish a data payload as an SSE event.\n *\n * @param data - The payload; objects are JSON-encoded.\n * @param event - Optional event name.\n */\n publish(data: unknown, event?: string): void {\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n this.push(\n new ServerSentEvent({ data: payload, ...(event ? { event } : {}) }).encode(),\n );\n }\n\n /** Publish a pre-built {@link ServerSentEvent}. */\n publishEvent(event: ServerSentEvent): void {\n this.push(event.encode());\n }\n\n /** Close the stream; the iterator finishes after draining. */\n close(): void {\n this.closed = true;\n this.waiter?.resolve();\n this.waiter = null;\n }\n\n /**\n * Async iterator yielding encoded SSE chunks, with periodic heartbeats.\n *\n * @returns An async iterator of encoded event strings.\n */\n async *stream(): AsyncIterator<string> & AsyncIterable<string> {\n const heartbeatMs =\n this.heartbeatSeconds !== null ? this.heartbeatSeconds * 1000 : null;\n while (!this.closed || this.queue.length > 0) {\n if (this.queue.length > 0) {\n yield this.queue.shift() as string;\n continue;\n }\n if (this.closed) break;\n this.waiter = deferred<void>();\n if (heartbeatMs === null) {\n await this.waiter.promise;\n } else {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const heartbeat = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, heartbeatMs);\n });\n await Promise.race([this.waiter.promise, heartbeat]);\n if (timer) clearTimeout(timer);\n if (this.queue.length === 0 && !this.closed) yield \": ping\\n\\n\";\n }\n }\n }\n}\n\n/**\n * Stream an {@link EventStream} to an Express response as `text/event-stream`.\n *\n * Sets the SSE headers, writes each encoded chunk, and closes the stream when\n * the client disconnects.\n *\n * @param req - The Express request (used to detect disconnect).\n * @param res - The Express response to stream into.\n * @param stream - The event stream to drain.\n */\nexport async function sseResponse(\n req: Request,\n res: Response,\n stream: EventStream,\n): Promise<void> {\n res.setHeader(\"Content-Type\", \"text/event-stream\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.setHeader(\"Connection\", \"keep-alive\");\n res.flushHeaders?.();\n req.on(\"close\", () => stream.close());\n for await (const chunk of stream.stream()) {\n if (res.writableEnded) break;\n res.write(chunk);\n }\n res.end();\n}\n","/**\n * In-process SSE broker, mirroring `sse.broker.SSEBroker`.\n *\n * Tracks subscribers per channel and fans published events out to every live\n * {@link EventStream} on that channel. Single-process (no cross-replica\n * transport yet — a Redis pub/sub backend is a planned follow-up).\n */\n\nimport { EventStream, type EventStreamOptions } from \"@/sse/eventStream\";\n\n/** Fan-out hub mapping channels to subscriber streams. */\nexport class SSEBroker {\n private readonly channels = new Map<string, Set<EventStream>>();\n\n /**\n * @param streamOptions - Options applied to every {@link EventStream} created\n * by {@link register} (e.g. heartbeat interval).\n */\n constructor(private readonly streamOptions: EventStreamOptions = {}) {}\n\n /**\n * Register a new subscriber stream on `channel`.\n *\n * @param channel - The channel name.\n * @returns A fresh {@link EventStream} to serve to the subscriber.\n */\n register(channel: string): EventStream {\n const stream = new EventStream(this.streamOptions);\n const set = this.channels.get(channel) ?? new Set<EventStream>();\n set.add(stream);\n this.channels.set(channel, set);\n return stream;\n }\n\n /**\n * Remove a subscriber stream from `channel` and close it.\n *\n * @param channel - The channel name.\n * @param stream - The stream to remove.\n */\n unregister(channel: string, stream: EventStream): void {\n const set = this.channels.get(channel);\n if (!set) return;\n set.delete(stream);\n stream.close();\n if (set.size === 0) this.channels.delete(channel);\n }\n\n /**\n * Number of live subscribers on `channel`.\n *\n * @param channel - The channel name.\n * @returns The subscriber count.\n */\n localSubscribers(channel: string): number {\n return this.channels.get(channel)?.size ?? 0;\n }\n\n /**\n * Publish an event to every subscriber on `channel`.\n *\n * @param channel - The channel name.\n * @param data - The payload (objects are JSON-encoded).\n * @param event - Optional event name.\n * @returns The number of subscribers the event was delivered to.\n */\n publish(channel: string, data: unknown, event?: string): number {\n const set = this.channels.get(channel);\n if (!set) return 0;\n for (const stream of set) stream.publish(data, event);\n return set.size;\n }\n}\n","/**\n * Redis pub/sub SSE broker for multi-replica deployments.\n *\n * The in-process {@link SSEBroker} only reaches subscribers on the same node.\n * {@link RedisSSEBroker} publishes to a Redis channel; every replica's\n * subscriber connection receives it and fans out to its local {@link EventStream}s\n * — so a publish on any node reaches SSE clients on all nodes. Takes injected\n * node-redis v4 clients (a dedicated subscriber connection, per Redis pub/sub\n * rules) so the SDK never hard-depends on `redis`.\n */\n\nimport { EventStream, type EventStreamOptions } from \"@/sse/eventStream\";\n\n/** Publisher side (the main client). */\nexport interface RedisPublisherLike {\n publish(channel: string, message: string): Promise<unknown>;\n}\n\n/** Subscriber side (a dedicated connection — `client.duplicate()`). */\nexport interface RedisSubscriberLike {\n subscribe(channel: string, listener: (message: string) => void): Promise<unknown>;\n unsubscribe(channel: string): Promise<unknown>;\n}\n\n/** Options for {@link RedisSSEBroker}. */\nexport interface RedisSSEBrokerOptions extends EventStreamOptions {\n /** Redis channel prefix. Default `sse:`. */\n prefix?: string;\n}\n\n/** Cross-replica SSE fan-out over Redis pub/sub. */\nexport class RedisSSEBroker {\n private readonly local = new Map<string, Set<EventStream>>();\n private readonly prefix: string;\n private readonly streamOptions: EventStreamOptions;\n\n /**\n * @param publisher - The main Redis client (used to `publish`).\n * @param subscriber - A dedicated subscriber connection (`client.duplicate()`).\n * @param options - Channel prefix + per-stream options.\n */\n constructor(\n private readonly publisher: RedisPublisherLike,\n private readonly subscriber: RedisSubscriberLike,\n options: RedisSSEBrokerOptions = {},\n ) {\n this.prefix = options.prefix ?? \"sse:\";\n const { prefix: _p, ...streamOptions } = options;\n this.streamOptions = streamOptions;\n }\n\n private channelKey(channel: string): string {\n return `${this.prefix}${channel}`;\n }\n\n /** Emit a decoded payload to every local stream on a channel. */\n private emitLocal(channel: string, data: unknown, event?: string): void {\n const set = this.local.get(channel);\n if (!set) return;\n for (const stream of set) stream.publish(data, event);\n }\n\n /**\n * Register a subscriber stream, subscribing to the Redis channel on first use.\n *\n * @param channel - The channel name.\n * @returns A fresh {@link EventStream} to serve to the client.\n */\n async register(channel: string): Promise<EventStream> {\n const stream = new EventStream(this.streamOptions);\n let set = this.local.get(channel);\n if (!set) {\n set = new Set<EventStream>();\n this.local.set(channel, set);\n await this.subscriber.subscribe(this.channelKey(channel), (raw) => {\n try {\n const { data, event } = JSON.parse(raw) as { data: unknown; event?: string };\n this.emitLocal(channel, data, event);\n } catch {\n // ignore malformed frames\n }\n });\n }\n set.add(stream);\n return stream;\n }\n\n /**\n * Remove a subscriber stream; unsubscribe from Redis when the last leaves.\n *\n * @param channel - The channel name.\n * @param stream - The stream to remove.\n */\n async unregister(channel: string, stream: EventStream): Promise<void> {\n const set = this.local.get(channel);\n if (!set) return;\n set.delete(stream);\n stream.close();\n if (set.size === 0) {\n this.local.delete(channel);\n await this.subscriber.unsubscribe(this.channelKey(channel));\n }\n }\n\n /** Local subscriber count on `channel` (this replica only). */\n localSubscribers(channel: string): number {\n return this.local.get(channel)?.size ?? 0;\n }\n\n /**\n * Publish to every subscriber across all replicas.\n *\n * @param channel - The channel name.\n * @param data - The payload (JSON-encoded).\n * @param event - Optional event name.\n */\n async publish(channel: string, data: unknown, event?: string): Promise<void> {\n await this.publisher.publish(\n this.channelKey(channel),\n JSON.stringify({ data, ...(event ? { event } : {}) }),\n );\n }\n}\n","/** WebSocket message envelope, mirroring `websockets.schemas`. */\n\nimport { z } from \"@/schemas/base\";\n\n/** The canonical message envelope exchanged over a socket. */\nexport const wsEnvelopeSchema = z\n .object({\n type: z.string().openapi({ description: \"Message type discriminator.\" }),\n data: z.unknown().optional().openapi({ description: \"Arbitrary payload.\" }),\n })\n .openapi(\"WSEnvelope\");\n\n/** A typed message envelope. */\nexport type WSEnvelope = z.infer<typeof wsEnvelopeSchema>;\n","/**\n * In-process connection hub, mirroring `websockets.hub.WebSocketHub`.\n *\n * Transport-agnostic: it tracks {@link WebSocketLike} connections (anything with\n * `send`/`close`) so it works with the `ws` package or any compatible socket.\n * Supports per-user delivery, topic subscriptions, broadcast and a per-user\n * connection cap with oldest-eviction.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport type { WSEnvelope } from \"@/websockets/schemas\";\n\n/** The minimal socket surface the hub needs. */\nexport interface WebSocketLike {\n /** Send a text frame. */\n send(data: string): void;\n /** Close the socket, optionally with a status code. */\n close(code?: number): void;\n}\n\n/** A registered live connection. */\nexport interface WebSocketConnection {\n /** Unique connection id. */\n id: string;\n /** The owning user id. */\n userId: string;\n /** The underlying socket. */\n ws: WebSocketLike;\n /** Topics this connection is subscribed to. */\n topics: Set<string>;\n}\n\n/** Options for {@link WebSocketHub}. */\nexport interface WebSocketHubOptions {\n /** Max simultaneous connections per user (oldest evicted). Default 5. */\n maxPerUser?: number;\n}\n\nexport class WebSocketHub {\n private readonly byId = new Map<string, WebSocketConnection>();\n private readonly byUser = new Map<string, Set<string>>();\n private readonly maxPerUser: number;\n\n /**\n * @param options - Per-user connection cap.\n */\n constructor(options: WebSocketHubOptions = {}) {\n this.maxPerUser = options.maxPerUser ?? 5;\n }\n\n /**\n * Register a new connection for `userId`, evicting the oldest if over cap.\n *\n * @param userId - The owning user id.\n * @param ws - The socket to register.\n * @returns The created connection record.\n */\n register(userId: string, ws: WebSocketLike): WebSocketConnection {\n const connection: WebSocketConnection = {\n id: randomUUID(),\n userId,\n ws,\n topics: new Set(),\n };\n this.byId.set(connection.id, connection);\n const ids = this.byUser.get(userId) ?? new Set<string>();\n ids.add(connection.id);\n this.byUser.set(userId, ids);\n\n if (ids.size > this.maxPerUser) {\n const oldest = ids.values().next().value;\n if (oldest) this.unregister(oldest, 1008);\n }\n return connection;\n }\n\n /**\n * Remove a connection and close its socket.\n *\n * @param connectionId - The connection id.\n * @param code - Optional WebSocket close code.\n */\n unregister(connectionId: string, code?: number): void {\n const connection = this.byId.get(connectionId);\n if (!connection) return;\n this.byId.delete(connectionId);\n const ids = this.byUser.get(connection.userId);\n if (ids) {\n ids.delete(connectionId);\n if (ids.size === 0) this.byUser.delete(connection.userId);\n }\n try {\n connection.ws.close(code);\n } catch {\n // socket already closed — ignore.\n }\n }\n\n /** Subscribe a connection to a topic. */\n subscribe(connectionId: string, topic: string): void {\n this.byId.get(connectionId)?.topics.add(topic);\n }\n\n /** Unsubscribe a connection from a topic. */\n unsubscribe(connectionId: string, topic: string): void {\n this.byId.get(connectionId)?.topics.delete(topic);\n }\n\n /** Serialize and send an envelope to a single connection. */\n private deliver(connection: WebSocketConnection, payload: string): boolean {\n try {\n connection.ws.send(payload);\n return true;\n } catch {\n this.unregister(connection.id);\n return false;\n }\n }\n\n /**\n * Send an envelope to every connection of `userId`.\n *\n * @param userId - The target user.\n * @param envelope - The message envelope.\n * @returns The number of connections delivered to.\n */\n sendTo(userId: string, envelope: WSEnvelope): number {\n const ids = this.byUser.get(userId);\n if (!ids) return 0;\n const payload = JSON.stringify(envelope);\n let count = 0;\n for (const id of [...ids]) {\n const connection = this.byId.get(id);\n if (connection && this.deliver(connection, payload)) count += 1;\n }\n return count;\n }\n\n /**\n * Broadcast an envelope to all connections, or only a topic's subscribers.\n *\n * @param envelope - The message envelope.\n * @param topic - Optional topic to scope the broadcast.\n * @returns The number of connections delivered to.\n */\n broadcast(envelope: WSEnvelope, topic?: string): number {\n const payload = JSON.stringify(envelope);\n let count = 0;\n for (const connection of [...this.byId.values()]) {\n if (topic && !connection.topics.has(topic)) continue;\n if (this.deliver(connection, payload)) count += 1;\n }\n return count;\n }\n\n /** The set of users with at least one live connection. */\n onlineUsers(): Set<string> {\n return new Set(this.byUser.keys());\n }\n\n /** Total live connection count. */\n connectionCount(): number {\n return this.byId.size;\n }\n\n /** Number of connections subscribed to `topic`. */\n topicCount(topic: string): number {\n let count = 0;\n for (const connection of this.byId.values()) {\n if (connection.topics.has(topic)) count += 1;\n }\n return count;\n }\n}\n","/**\n * Attach a {@link WebSocketHub} to an HTTP server, mirroring\n * `websockets.router`.\n *\n * Uses the optional `ws` peer (lazily imported). Authenticates each handshake\n * (e.g. a `?token=` query param), registers the socket into the hub, runs a\n * ping/pong heartbeat to drop half-open peers, and unregisters on close.\n */\n\nimport type { Server } from \"node:http\";\nimport type { WebSocketConnection, WebSocketHub } from \"@/websockets/hub\";\n\n/** Handshake info passed to the authenticator. */\nexport interface HandshakeInfo {\n /** The request URL (includes the query string, e.g. `/ws?token=…`). */\n url: string;\n /** The raw request headers. */\n headers: Record<string, string | string[] | undefined>;\n}\n\n/** Options for {@link attachWebSocketHub}. */\nexport interface AttachWebSocketOptions {\n /** Path the WebSocket server listens on. Default `/ws`. */\n path?: string;\n /**\n * Resolve a user id from the handshake, or `null` to reject (closes 1008).\n * Default accepts every connection as `\"anonymous\"`.\n */\n authenticate?: (info: HandshakeInfo) => Promise<string | null> | string | null;\n /** Heartbeat interval in seconds (`0` disables). Default 30. */\n heartbeatSeconds?: number;\n /** Handler invoked for each inbound text message. */\n onMessage?: (connection: WebSocketConnection, message: string) => void;\n}\n\n/** Read a `token` query param from a handshake URL, or `null`. */\nexport function tokenFromUrl(url: string): string | null {\n const query = url.includes(\"?\") ? url.slice(url.indexOf(\"?\") + 1) : \"\";\n return new URLSearchParams(query).get(\"token\");\n}\n\n/**\n * Attach a hub to an HTTP server over the `ws` package.\n *\n * @param server - The Node HTTP server (e.g. from `runServer`).\n * @param hub - The hub to register connections into.\n * @param options - Path, authenticator, heartbeat and message handler.\n * @returns The created `ws` `WebSocketServer` instance.\n * @throws {Error} When the optional `ws` peer is not installed.\n */\nexport async function attachWebSocketHub(\n server: Server,\n hub: WebSocketHub,\n options: AttachWebSocketOptions = {},\n): Promise<import(\"ws\").WebSocketServer> {\n let ws: typeof import(\"ws\");\n try {\n ws = await import(\"ws\");\n } catch (cause) {\n throw new Error(\n \"attachWebSocketHub requires the 'ws' peer dependency. Install with `npm i ws`.\",\n { cause },\n );\n }\n\n const path = options.path ?? \"/ws\";\n const heartbeatMs = (options.heartbeatSeconds ?? 30) * 1000;\n const authenticate = options.authenticate ?? (() => \"anonymous\");\n const wss = new ws.WebSocketServer({ server, path });\n\n wss.on(\"connection\", (socket: import(\"ws\").WebSocket, req) => {\n void (async () => {\n const userId = await authenticate({\n url: req.url ?? \"\",\n headers: req.headers,\n });\n if (userId === null) {\n socket.close(1008);\n return;\n }\n const connection = hub.register(userId, socket);\n\n let alive = true;\n socket.on(\"pong\", () => {\n alive = true;\n });\n socket.on(\"message\", (data: unknown) => {\n options.onMessage?.(connection, String(data));\n });\n socket.on(\"close\", () => {\n alive = false;\n hub.unregister(connection.id);\n });\n\n if (heartbeatMs > 0) {\n const timer = setInterval(() => {\n if (!alive) {\n clearInterval(timer);\n hub.unregister(connection.id);\n return;\n }\n alive = false;\n socket.ping();\n }, heartbeatMs);\n socket.on(\"close\", () => clearInterval(timer));\n }\n })();\n });\n\n return wss;\n}\n","/**\n * Message broker, mirroring `queue.manager.AsyncBrokerManager`.\n *\n * A narrow async pub/sub surface ({@link BrokerManager}) with two backends: an\n * in-process {@link MemoryBroker} (dev/tests) and a {@link RabbitBroker} over the\n * optional `amqplib` peer (lazily imported). Messages are JSON-serialized.\n */\n\n/** A handler invoked for each delivered message. */\nexport type MessageHandler = (message: unknown) => Promise<void> | void;\n\n/** Narrow async pub/sub surface every backend implements. */\nexport interface BrokerManager {\n /** Publish a message to a named queue. */\n publish(queue: string, message: unknown): Promise<void>;\n /** Subscribe to a queue; resolves to an unsubscribe function. */\n subscribe(queue: string, handler: MessageHandler): Promise<() => Promise<void>>;\n /** Close the broker and release resources. */\n close(): Promise<void>;\n}\n\n/** In-process {@link BrokerManager} backed by handler sets. */\nexport class MemoryBroker implements BrokerManager {\n private readonly handlers = new Map<string, Set<MessageHandler>>();\n\n async publish(queue: string, message: unknown): Promise<void> {\n const set = this.handlers.get(queue);\n if (!set) return;\n // Clone the payload so handlers cannot mutate a shared reference.\n const payload = JSON.parse(JSON.stringify(message)) as unknown;\n for (const handler of [...set]) await handler(payload);\n }\n\n async subscribe(queue: string, handler: MessageHandler): Promise<() => Promise<void>> {\n const set = this.handlers.get(queue) ?? new Set<MessageHandler>();\n set.add(handler);\n this.handlers.set(queue, set);\n return async () => {\n set.delete(handler);\n if (set.size === 0) this.handlers.delete(queue);\n };\n }\n\n async close(): Promise<void> {\n this.handlers.clear();\n }\n}\n\n/** Options for {@link RabbitBroker}. */\nexport interface RabbitBrokerOptions {\n /** AMQP connection URL, e.g. `amqp://localhost`. */\n url: string;\n /** Whether queues are declared durable. Default `true`. */\n durable?: boolean;\n}\n\ntype AmqpModule = typeof import(\"amqplib\");\ntype AmqpConnection = Awaited<ReturnType<AmqpModule[\"connect\"]>>;\ntype AmqpChannel = Awaited<ReturnType<AmqpConnection[\"createChannel\"]>>;\n\n/** RabbitMQ-backed {@link BrokerManager} over the optional `amqplib` peer. */\nexport class RabbitBroker implements BrokerManager {\n private connection: AmqpConnection | null = null;\n private channel: AmqpChannel | null = null;\n private readonly durable: boolean;\n\n /**\n * @param options - Connection URL and queue durability.\n */\n constructor(private readonly options: RabbitBrokerOptions) {\n this.durable = options.durable ?? true;\n }\n\n /** Lazily connect and open a channel. */\n private async ready(): Promise<AmqpChannel> {\n if (this.channel) return this.channel;\n let amqp: AmqpModule;\n try {\n amqp = await import(\"amqplib\");\n } catch (cause) {\n throw new Error(\n \"RabbitBroker requires the 'amqplib' peer dependency. Install with `npm i amqplib`.\",\n { cause },\n );\n }\n this.connection = await amqp.connect(this.options.url);\n this.channel = await this.connection.createChannel();\n return this.channel;\n }\n\n async publish(queue: string, message: unknown): Promise<void> {\n const channel = await this.ready();\n await channel.assertQueue(queue, { durable: this.durable });\n channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)), {\n persistent: this.durable,\n });\n }\n\n async subscribe(queue: string, handler: MessageHandler): Promise<() => Promise<void>> {\n const channel = await this.ready();\n await channel.assertQueue(queue, { durable: this.durable });\n const { consumerTag } = await channel.consume(queue, (msg) => {\n if (!msg) return;\n void Promise.resolve(handler(JSON.parse(msg.content.toString()) as unknown))\n .then(() => channel.ack(msg))\n .catch(() => channel.nack(msg, false, false));\n });\n return async () => {\n await channel.cancel(consumerTag);\n };\n }\n\n async close(): Promise<void> {\n await this.channel?.close();\n await this.connection?.close();\n this.channel = null;\n this.connection = null;\n }\n}\n","/**\n * Background task manager, mirroring `tasks.manager.AsyncTaskBrokerManager`.\n *\n * Rides on a {@link BrokerManager}: enqueue publishes a `{ name, payload }`\n * envelope to a task queue; a worker started with {@link TaskManager.start}\n * consumes it and dispatches to the registered handler. Defaults to an\n * in-process {@link MemoryBroker} so it works with zero infrastructure.\n */\n\nimport { JSONLogger } from \"@/core\";\nimport { type BrokerManager, MemoryBroker } from \"@/queue/broker\";\n\n/** A handler for a registered task. */\nexport type TaskHandler<P = unknown> = (payload: P) => Promise<void> | void;\n\n/** The envelope published for each enqueued task. */\ninterface TaskEnvelope {\n name: string;\n payload: unknown;\n}\n\n/** Options for {@link TaskManager}. */\nexport interface TaskManagerOptions {\n /** The broker to publish/consume on. Defaults to a {@link MemoryBroker}. */\n broker?: BrokerManager;\n /** Queue name used for the task stream. Default `tasks`. */\n queue?: string;\n}\n\nconst logger = new JSONLogger(\"tempest_express_sdk.tasks\");\n\nexport class TaskManager {\n private readonly broker: BrokerManager;\n private readonly queue: string;\n private readonly handlers = new Map<string, TaskHandler>();\n private unsubscribe: (() => Promise<void>) | null = null;\n\n /**\n * @param options - Broker and queue name.\n */\n constructor(options: TaskManagerOptions = {}) {\n this.broker = options.broker ?? new MemoryBroker();\n this.queue = options.queue ?? \"tasks\";\n }\n\n /**\n * Register a handler for a named task.\n *\n * @param name - The task name.\n * @param handler - The handler invoked with the task payload.\n */\n register<P = unknown>(name: string, handler: TaskHandler<P>): void {\n this.handlers.set(name, handler as TaskHandler);\n }\n\n /**\n * Enqueue a task by name.\n *\n * @param name - The registered task name.\n * @param payload - The JSON-serializable payload.\n */\n async enqueue(name: string, payload: unknown = {}): Promise<void> {\n const envelope: TaskEnvelope = { name, payload };\n await this.broker.publish(this.queue, envelope);\n }\n\n /**\n * Start the worker: subscribe to the task queue and dispatch to handlers.\n * A task with no registered handler is logged and skipped.\n */\n async start(): Promise<void> {\n if (this.unsubscribe) return;\n this.unsubscribe = await this.broker.subscribe(this.queue, async (message) => {\n const { name, payload } = message as TaskEnvelope;\n const handler = this.handlers.get(name);\n if (!handler) {\n logger.warning(\"No handler for task\", { task: name });\n return;\n }\n await handler(payload);\n });\n }\n\n /** Stop the worker (stops consuming; does not close the broker). */\n async stop(): Promise<void> {\n await this.unsubscribe?.();\n this.unsubscribe = null;\n }\n}\n","/**\n * Feature-flag backends, mirroring `flags.backends`.\n *\n * A flag resolves to a boolean given a flag name and optional context. Backends\n * are composable — {@link CompositeFeatureFlagBackend} tries each in order and\n * returns the first definitive answer.\n */\n\n/** Arbitrary evaluation context (user id, roles, attributes). */\nexport type FlagContext = Record<string, unknown>;\n\n/** Resolves a flag to enabled/disabled, or `null` when it has no opinion. */\nexport interface FeatureFlagBackend {\n /** Resolve `flag`; `null` defers to the next backend. */\n resolve(flag: string, context?: FlagContext): Promise<boolean | null> | boolean | null;\n}\n\n/** Coerce a loose value (`\"1\"`, `\"true\"`, `\"on\"`, …) to a boolean. */\nexport function coerceFlag(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"number\") return value !== 0;\n if (typeof value === \"string\") {\n return [\"1\", \"true\", \"on\", \"yes\", \"enabled\"].includes(value.trim().toLowerCase());\n }\n return false;\n}\n\n/** In-memory backend backed by a `Map`, ideal for tests and overrides. */\nexport class MemoryFeatureFlagBackend implements FeatureFlagBackend {\n private readonly flags = new Map<string, boolean>();\n\n /**\n * @param initial - Initial flag → enabled map.\n */\n constructor(initial: Record<string, boolean> = {}) {\n for (const [flag, enabled] of Object.entries(initial)) this.flags.set(flag, enabled);\n }\n\n /** Set or override a flag. */\n set(flag: string, enabled: boolean): void {\n this.flags.set(flag, enabled);\n }\n\n resolve(flag: string): boolean | null {\n return this.flags.has(flag) ? (this.flags.get(flag) as boolean) : null;\n }\n}\n\n/** Reads flags from env vars, e.g. flag `new-ui` → `FLAG_NEW_UI`. */\nexport class EnvFeatureFlagBackend implements FeatureFlagBackend {\n /**\n * @param env - Environment source (defaults to `process.env`).\n * @param prefix - Env var prefix. Default `FLAG_`.\n */\n constructor(\n private readonly env: NodeJS.ProcessEnv = process.env,\n private readonly prefix = \"FLAG_\",\n ) {}\n\n private key(flag: string): string {\n return this.prefix + flag.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\");\n }\n\n resolve(flag: string): boolean | null {\n const raw = this.env[this.key(flag)];\n return raw === undefined ? null : coerceFlag(raw);\n }\n}\n\n/** Tries each backend in order; first non-`null` answer wins. */\nexport class CompositeFeatureFlagBackend implements FeatureFlagBackend {\n /**\n * @param backends - Backends in priority order.\n */\n constructor(private readonly backends: FeatureFlagBackend[]) {}\n\n async resolve(flag: string, context?: FlagContext): Promise<boolean | null> {\n for (const backend of this.backends) {\n const answer = await backend.resolve(flag, context);\n if (answer !== null) return answer;\n }\n return null;\n }\n}\n","/**\n * Feature-flag service + Express guard, mirroring `flags.service` /\n * `flags.dependencies`.\n */\n\nimport { NotFoundException } from \"@/exceptions/http\";\nimport type { FeatureFlagBackend, FlagContext } from \"@/flags/backends\";\nimport type { RequestHandler } from \"express\";\n\n/** Evaluates flags against a backend, applying a default when undecided. */\nexport class FeatureFlags {\n /**\n * @param backend - The resolving backend.\n * @param defaultEnabled - Value used when the backend returns `null`.\n */\n constructor(\n private readonly backend: FeatureFlagBackend,\n private readonly defaultEnabled = false,\n ) {}\n\n /**\n * Whether `flag` is enabled for the given context.\n *\n * @param flag - The flag name.\n * @param context - Optional evaluation context.\n * @returns `true` when enabled (or default when the backend is undecided).\n */\n async isEnabled(flag: string, context?: FlagContext): Promise<boolean> {\n const answer = await this.backend.resolve(flag, context);\n return answer ?? this.defaultEnabled;\n }\n}\n\n/**\n * Build middleware that rejects with 404 when `flag` is disabled (hiding the\n * route entirely, the common kill-switch behavior).\n *\n * @param flags - The flag service.\n * @param flag - The flag name to gate on.\n * @returns An Express middleware.\n */\nexport function makeFlagGuard(flags: FeatureFlags, flag: string): RequestHandler {\n return (_req, _res, next) => {\n flags\n .isEnabled(flag)\n .then((enabled) => {\n if (enabled) next();\n else next(new NotFoundException({ message: \"Not found\", details: { flag } }));\n })\n .catch(next);\n };\n}\n","/**\n * S3 / MinIO-backed {@link UploadStorage}, mirroring `utils.storage_backends`.\n *\n * Implements the same narrow `UploadStorage` interface as\n * {@link LocalUploadStorage} over a MinIO/S3 client, so services swap backends\n * without touching call sites. The `minio` client is an **optional** peer\n * dependency, lazy-loaded on first use (or inject your own client for tests /\n * a custom SDK).\n */\n\nimport type { Readable } from \"node:stream\";\nimport type { SaveOptions, UploadResult, UploadStorage } from \"@/storage/local\";\n\n/** Minimal MinIO/S3 client surface used by {@link S3UploadStorage}. */\nexport interface S3ClientLike {\n putObject(\n bucket: string,\n key: string,\n data: Buffer,\n size?: number,\n metaData?: Record<string, string>,\n ): Promise<unknown>;\n getObject(bucket: string, key: string): Promise<Readable>;\n removeObject(bucket: string, key: string): Promise<void>;\n}\n\n/** Options for {@link S3UploadStorage}. */\nexport interface S3UploadStorageOptions {\n /** Target bucket. */\n bucket: string;\n /** Public base URL for {@link S3UploadStorage.url} (e.g. a CDN or the endpoint). */\n publicBaseUrl?: string;\n /** Inject a ready client (e.g. a `minio` `Client`, or a mock). */\n client?: S3ClientLike;\n /** MinIO/S3 endpoint host (used only when `client` is not injected). */\n endPoint?: string;\n /** Endpoint port. */\n port?: number;\n /** Whether to use TLS. */\n useSSL?: boolean;\n /** Access key. */\n accessKey?: string;\n /** Secret key. */\n secretKey?: string;\n /** Region. */\n region?: string;\n}\n\n/** Collect a readable stream into a single {@link Buffer}. */\nasync function streamToBuffer(stream: Readable): Promise<Buffer> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as Uint8Array));\n }\n return Buffer.concat(chunks);\n}\n\n/** {@link UploadStorage} over a MinIO/S3 client. */\nexport class S3UploadStorage implements UploadStorage {\n private readonly bucket: string;\n private readonly publicBaseUrl: string;\n private client: S3ClientLike | undefined;\n private readonly options: S3UploadStorageOptions;\n\n /**\n * @param options - Bucket, public URL and either a client or connection config.\n */\n constructor(options: S3UploadStorageOptions) {\n this.bucket = options.bucket;\n this.publicBaseUrl = options.publicBaseUrl ?? \"\";\n this.client = options.client;\n this.options = options;\n }\n\n /** Resolve the client, lazy-loading `minio` when one wasn't injected. */\n private async getClient(): Promise<S3ClientLike> {\n if (this.client) return this.client;\n // Variable specifier keeps the optional peer out of static resolution.\n const specifier = \"minio\";\n let mod: { Client: new (config: Record<string, unknown>) => S3ClientLike };\n try {\n mod = (await import(specifier)) as typeof mod;\n } catch {\n throw new Error(\n \"S3UploadStorage requires the 'minio' peer dependency. Install with `npm i minio`.\",\n );\n }\n this.client = new mod.Client({\n endPoint: this.options.endPoint,\n port: this.options.port,\n useSSL: this.options.useSSL,\n accessKey: this.options.accessKey,\n secretKey: this.options.secretKey,\n region: this.options.region,\n });\n return this.client;\n }\n\n async save(\n key: string,\n data: Uint8Array,\n options: SaveOptions = {},\n ): Promise<UploadResult> {\n const client = await this.getClient();\n const buffer = Buffer.from(data);\n const metaData = options.contentType\n ? { \"Content-Type\": options.contentType }\n : undefined;\n await client.putObject(this.bucket, key, buffer, buffer.byteLength, metaData);\n return {\n key,\n url: this.url(key),\n size: buffer.byteLength,\n ...(options.contentType !== undefined ? { contentType: options.contentType } : {}),\n };\n }\n\n async read(key: string): Promise<Buffer> {\n const client = await this.getClient();\n return streamToBuffer(await client.getObject(this.bucket, key));\n }\n\n async delete(key: string): Promise<void> {\n const client = await this.getClient();\n await client.removeObject(this.bucket, key);\n }\n\n url(key: string): string {\n const base = this.publicBaseUrl.replace(/\\/$/, \"\");\n return base ? `${base}/${this.bucket}/${key}` : `/${this.bucket}/${key}`;\n }\n}\n","/** Web Push DTOs (Zod), mirroring `webpush.schemas`. */\n\nimport { z } from \"@/schemas/base\";\n\n/** The browser-provided push subscription keys. */\nexport const webPushKeysSchema = z\n .object({\n p256dh: z.string().openapi({ description: \"Client public key (base64url).\" }),\n auth: z.string().openapi({ description: \"Client auth secret (base64url).\" }),\n })\n .openapi(\"WebPushKeys\");\n\n/** A browser push subscription. */\nexport const webPushSubscriptionSchema = z\n .object({\n endpoint: z.url().openapi({ description: \"Push service endpoint URL.\" }),\n keys: webPushKeysSchema,\n })\n .openapi(\"WebPushSubscription\");\n\n/** A push notification payload. */\nexport const webPushPayloadSchema = z\n .object({\n title: z.string().openapi({ description: \"Notification title.\" }),\n body: z.string().optional().openapi({ description: \"Notification body.\" }),\n url: z.string().optional().openapi({ description: \"URL opened on click.\" }),\n data: z\n .record(z.string(), z.unknown())\n .optional()\n .openapi({ description: \"Extra data.\" }),\n })\n .openapi(\"WebPushPayload\");\n\nexport type WebPushKeys = z.infer<typeof webPushKeysSchema>;\nexport type WebPushSubscription = z.infer<typeof webPushSubscriptionSchema>;\nexport type WebPushPayload = z.infer<typeof webPushPayloadSchema>;\n","/**\n * Web Push (VAPID) dispatch, mirroring `webpush.dispatcher`.\n *\n * Wraps the optional `web-push` peer (lazily imported). A `410 Gone` / `404`\n * from the push service means the subscription is dead — surfaced as\n * {@link WebPushGoneError} so the caller can prune it from storage.\n */\n\nimport type { WebPushPayload, WebPushSubscription } from \"@/webpush/schemas\";\n\n/** A Web Push delivery failure. */\nexport class WebPushError extends Error {\n constructor(\n message: string,\n readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"WebPushError\";\n }\n}\n\n/** The subscription is expired/unsubscribed (410/404) — prune it. */\nexport class WebPushGoneError extends WebPushError {\n constructor(statusCode: number) {\n super(\"Push subscription is gone\", statusCode);\n this.name = \"WebPushGoneError\";\n }\n}\n\n/** Options for {@link WebPushDispatcher}. */\nexport interface WebPushDispatcherOptions {\n /** VAPID public key. */\n publicKey: string;\n /** VAPID private key. */\n privateKey: string;\n /** VAPID subject (`mailto:` or site URL). */\n subject: string;\n}\n\ntype WebPushModule = typeof import(\"web-push\");\n\nlet cached: WebPushModule | null = null;\n\nasync function loadWebPush(): Promise<WebPushModule> {\n if (cached) return cached;\n try {\n const mod = (await import(\"web-push\")) as WebPushModule & { default?: WebPushModule };\n cached = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"WebPushDispatcher requires the 'web-push' peer dependency. Install with `npm i web-push`.\",\n { cause },\n );\n }\n return cached;\n}\n\n/** Sends Web Push notifications with configured VAPID details. */\nexport class WebPushDispatcher {\n /**\n * @param options - VAPID keys and subject.\n */\n constructor(private readonly options: WebPushDispatcherOptions) {}\n\n /**\n * Send a payload to a single subscription.\n *\n * @param subscription - The browser push subscription.\n * @param payload - The notification payload.\n * @throws {WebPushGoneError} When the subscription is expired (410/404).\n * @throws {WebPushError} On any other delivery failure.\n */\n async send(subscription: WebPushSubscription, payload: WebPushPayload): Promise<void> {\n const webpush = await loadWebPush();\n webpush.setVapidDetails(\n this.options.subject,\n this.options.publicKey,\n this.options.privateKey,\n );\n try {\n await webpush.sendNotification(subscription, JSON.stringify(payload));\n } catch (error) {\n const status = (error as { statusCode?: number }).statusCode;\n if (status === 404 || status === 410) throw new WebPushGoneError(status);\n throw new WebPushError((error as Error).message, status);\n }\n }\n}\n","/**\n * Messaging integration contracts.\n *\n * A channel-agnostic {@link MessagingProvider} so WhatsApp, SMS and future\n * channels share one shape and are swappable in tests. The first implementation\n * is {@link WhatsAppProvider} (a client for the `zap-api` service).\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** Supported media kinds for {@link MessagingProvider.sendMedia}. */\nexport type MediaKind = \"image\" | \"video\" | \"audio\" | \"document\";\n\n/** A media message to send. */\nexport interface OutboundMedia {\n /** The media kind (selects the underlying route). */\n kind: MediaKind;\n /** A public `http(s)://` URL or a `data:` URI. */\n media: string;\n /** Optional caption (image/video). */\n caption?: string;\n /** File name with extension (required for `document`). */\n fileName?: string;\n}\n\n/** The result of enqueuing an outbound message. */\nexport interface OutboundResult {\n /** Provider message id, when returned. */\n id?: string;\n /** Provider status string (e.g. `\"queued\"`, `\"sent\"`). */\n status: string;\n /** Whether the send was de-duplicated by an idempotency key. */\n deduped?: boolean;\n}\n\n/** Options accepted by send operations. */\nexport interface SendOptions {\n /** Idempotency key to de-duplicate retries on the provider side. */\n idempotencyKey?: string;\n}\n\n/** A normalized inbound (or echoed outbound) message. */\nexport const inboundMessageSchema = z\n .object({\n /** Conversation JID / sender (e.g. `5511999999999@s.whatsapp.net`). */\n from: z.string().openapi({ description: \"Conversation JID / sender.\" }),\n /** Provider message id. */\n messageId: z.string().openapi({ description: \"Provider message id.\" }),\n /** Text body, when present. */\n text: z.string().optional().openapi({ description: \"Text body.\" }),\n /** Media kind, or `null` for plain text. */\n mediaType: z\n .enum([\"image\", \"video\", \"audio\", \"document\", \"sticker\"])\n .nullable()\n .openapi({ description: \"Media kind, or null for text.\" }),\n /** ISO-8601 timestamp. */\n timestamp: z.string().openapi({ description: \"ISO-8601 timestamp.\" }),\n /** Delivery direction. */\n direction: z.enum([\"incoming\", \"outgoing\"]).optional(),\n })\n .openapi(\"InboundMessage\");\n\n/** A normalized inbound message. */\nexport type InboundMessage = z.infer<typeof inboundMessageSchema>;\n\n/** Handler invoked for each inbound message. */\nexport type InboundHandler = (message: InboundMessage) => Promise<void> | void;\n\n/**\n * A channel-agnostic messaging provider. `sendText`/`sendMedia`/`status` are\n * universal; `checkNumber` and `onMessage` are optional because not every\n * channel supports them (e.g. SMS has no persistent subscription — its inbound\n * arrives via a webhook receiver instead).\n */\nexport interface MessagingProvider {\n /** Send a text message. */\n sendText(to: string, text: string, options?: SendOptions): Promise<OutboundResult>;\n /** Send a media message. */\n sendMedia(\n to: string,\n media: OutboundMedia,\n options?: SendOptions,\n ): Promise<OutboundResult>;\n /** The current session/connection status. */\n status(): Promise<string>;\n /** Whether a number/handle exists on the channel (when supported). */\n checkNumber?(number: string): Promise<boolean>;\n /**\n * Subscribe to inbound messages; resolves to an unsubscribe function.\n * Present only on channels with a live subscription (WhatsApp `/ws`,\n * Telegram long-polling).\n *\n * @param handler - Invoked for each inbound message.\n * @param room - Conversation to scope to; `\"*\"` for all. Default `\"*\"`.\n */\n onMessage?(handler: InboundHandler, room?: string): Promise<() => Promise<void>>;\n}\n","/**\n * WhatsApp provider — a typed client for the `zap-api` service.\n *\n * REST for sending (`/message/send-*`, `/message/check-number`) and session\n * control (`/session/*`); the `/ws` pub/sub for receiving inbound messages in\n * real time. HTTP goes through the SDK's resilient {@link HTTPClient}; the\n * WebSocket subscription uses the optional `ws` peer (lazily imported).\n *\n * @see https://github.com/mauriciobenjamin700 (zap-api)\n */\n\nimport type {\n InboundHandler,\n MediaKind,\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n SendOptions,\n} from \"@/integrations/provider\";\nimport { HTTPClient } from \"@/utils/httpClient\";\n\n/** Options for {@link WhatsAppProvider}. */\nexport interface WhatsAppProviderOptions {\n /** Base URL of the `zap-api` instance, e.g. `https://zap.example.com`. */\n baseUrl: string;\n /** Consumer API key (sent as `x-api-key`). */\n apiKey: string;\n /** WebSocket URL. Defaults to `baseUrl` with `http(s)`→`ws(s)` + `/ws`. */\n wsUrl?: string;\n /** Per-request timeout in ms. Default 15000. */\n timeoutMs?: number;\n}\n\n/** Route suffix per media kind. */\nconst MEDIA_ROUTE: Record<MediaKind, string> = {\n image: \"send-image\",\n video: \"send-video\",\n audio: \"send-audio\",\n document: \"send-document\",\n};\n\n/** Derive the default `ws(s)://…/ws` URL from an http(s) base URL. */\nfunction deriveWsUrl(baseUrl: string): string {\n const trimmed = baseUrl.replace(/\\/$/, \"\");\n return `${trimmed.replace(/^http/, \"ws\")}/ws`;\n}\n\n/** A typed client for a running `zap-api` WhatsApp gateway. */\nexport class WhatsAppProvider implements MessagingProvider {\n private readonly http: HTTPClient;\n private readonly apiKey: string;\n private readonly wsUrl: string;\n\n /**\n * @param options - Base URL, API key and optional WebSocket URL.\n */\n constructor(options: WhatsAppProviderOptions) {\n this.apiKey = options.apiKey;\n this.wsUrl = options.wsUrl ?? deriveWsUrl(options.baseUrl);\n this.http = new HTTPClient({\n baseUrl: options.baseUrl.replace(/\\/$/, \"\"),\n defaultHeaders: { \"x-api-key\": options.apiKey, \"content-type\": \"application/json\" },\n timeoutMs: options.timeoutMs ?? 15000,\n });\n }\n\n /** POST JSON and parse the response, throwing on a non-2xx status. */\n private async postJson(\n path: string,\n body: unknown,\n options?: SendOptions,\n ): Promise<Record<string, unknown>> {\n const headers = options?.idempotencyKey\n ? { \"Idempotency-Key\": options.idempotencyKey }\n : undefined;\n const res = await this.http.post(path, {\n body: JSON.stringify(body),\n ...(headers ? { headers } : {}),\n });\n const data = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n throw new Error(\n `zap-api ${path} failed (${res.status}): ${String(data.error ?? res.statusText)}`,\n );\n }\n return data;\n }\n\n async sendText(\n to: string,\n text: string,\n options?: SendOptions,\n ): Promise<OutboundResult> {\n const data = await this.postJson(\"/message/send-text\", { to, text }, options);\n return {\n status: String(data.status ?? \"queued\"),\n ...(typeof data.id === \"string\" ? { id: data.id } : {}),\n ...(typeof data.deduped === \"boolean\" ? { deduped: data.deduped } : {}),\n };\n }\n\n async sendMedia(\n to: string,\n media: OutboundMedia,\n options?: SendOptions,\n ): Promise<OutboundResult> {\n const body: Record<string, unknown> = { to, media: media.media };\n if (media.caption !== undefined) body.caption = media.caption;\n if (media.fileName !== undefined) body.fileName = media.fileName;\n const data = await this.postJson(\n `/message/${MEDIA_ROUTE[media.kind]}`,\n body,\n options,\n );\n return {\n status: String(data.status ?? \"queued\"),\n ...(typeof data.id === \"string\" ? { id: data.id } : {}),\n ...(typeof data.deduped === \"boolean\" ? { deduped: data.deduped } : {}),\n };\n }\n\n async checkNumber(number: string): Promise<boolean> {\n const res = await this.http.get(\n `/message/check-number/${encodeURIComponent(number)}`,\n );\n const data = (await res.json().catch(() => ({}))) as { exists?: boolean };\n return data.exists === true;\n }\n\n async status(): Promise<string> {\n const res = await this.http.get(\"/session/status\");\n const raw = await res.text();\n try {\n const parsed = JSON.parse(raw) as { status?: string };\n return parsed.status ?? raw.trim();\n } catch {\n return raw.trim();\n }\n }\n\n /** Start the WhatsApp session (returns the authenticated QR URL, if any). */\n async startSession(): Promise<Record<string, unknown>> {\n return this.postJson(\"/session/start\", {});\n }\n\n async onMessage(handler: InboundHandler, room = \"*\"): Promise<() => Promise<void>> {\n let ws: typeof import(\"ws\");\n try {\n ws = await import(\"ws\");\n } catch (cause) {\n throw new Error(\n \"WhatsAppProvider.onMessage requires the 'ws' peer dependency. Install with `npm i ws`.\",\n { cause },\n );\n }\n const socket = new ws.WebSocket(this.wsUrl, {\n headers: { \"x-api-key\": this.apiKey },\n });\n\n socket.on(\"open\", () => {\n socket.send(JSON.stringify({ action: \"subscribe\", room }));\n });\n socket.on(\"message\", (raw: unknown) => {\n let frame: { type?: string; payload?: unknown };\n try {\n frame = JSON.parse(String(raw));\n } catch {\n return;\n }\n if (frame.type === \"message\" && frame.payload) {\n const p = frame.payload as Record<string, unknown>;\n void handler({\n from: String(p.remoteJid ?? \"\"),\n messageId: String(p.messageId ?? \"\"),\n ...(typeof p.text === \"string\" ? { text: p.text } : {}),\n mediaType: (p.mediaType as InboundMessageMediaType) ?? null,\n timestamp: String(p.timestamp ?? \"\"),\n ...(p.direction === \"incoming\" || p.direction === \"outgoing\"\n ? { direction: p.direction }\n : {}),\n });\n }\n });\n\n return async () => {\n try {\n socket.send(JSON.stringify({ action: \"unsubscribe\", room }));\n } catch {\n // socket may already be closed.\n }\n socket.close();\n };\n }\n}\n\n/** The media-type union carried on inbound frames. */\ntype InboundMessageMediaType =\n | \"image\"\n | \"video\"\n | \"audio\"\n | \"document\"\n | \"sticker\"\n | null;\n","/**\n * WhatsApp inbound-webhook receiver.\n *\n * `zap-api` POSTs every received message to a configured webhook. This builds\n * an Express router that (optionally) validates the shared `x-api-key`, parses\n * the payload into a typed {@link InboundMessage}, and hands it to your handler.\n */\n\nimport { timingSafeEqual } from \"node:crypto\";\nimport { UnauthorizedException } from \"@/exceptions/http\";\nimport { type InboundHandler, inboundMessageSchema } from \"@/integrations/provider\";\nimport { type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link makeWhatsAppWebhookRouter}. */\nexport interface WhatsAppWebhookOptions {\n /** Handler invoked for each validated inbound message. */\n onMessage: InboundHandler;\n /** Route path. Default `/whatsapp/inbound`. */\n path?: string;\n /** Shared secret expected in `x-api-key`. Omit to skip auth (dev only). */\n apiKey?: string;\n}\n\n/** Constant-time string comparison. */\nfunction safeEqual(a: string, b: string): boolean {\n const bufA = Buffer.from(a);\n const bufB = Buffer.from(b);\n return bufA.length === bufB.length && timingSafeEqual(bufA, bufB);\n}\n\n/**\n * Build the inbound-webhook router.\n *\n * @param options - Handler, path and optional shared secret.\n * @returns An Express router with the webhook endpoint mounted.\n */\nexport function makeWhatsAppWebhookRouter(options: WhatsAppWebhookOptions): Router {\n const path = options.path ?? \"/whatsapp/inbound\";\n const router = createRouter();\n\n router.post(path, async (req, res) => {\n if (options.apiKey) {\n const provided = req.header(\"x-api-key\") ?? \"\";\n if (!safeEqual(provided, options.apiKey)) {\n throw new UnauthorizedException({ message: \"Invalid webhook key\" });\n }\n }\n // zap-api posts `{ from, messageId, text, mediaType, timestamp }`.\n const message = inboundMessageSchema.parse(req.body);\n await options.onMessage(message);\n res.status(200).json({ ok: true });\n });\n\n return router;\n}\n","/**\n * Telegram provider — a client for the Telegram Bot API.\n *\n * Implements {@link MessagingProvider} over the built-in {@link HTTPClient}\n * (no external SDK). Outbound via `sendMessage`/`sendPhoto`/…; inbound via\n * `getUpdates` long-polling exposed through {@link TelegramProvider.onMessage}.\n */\n\nimport type {\n InboundHandler,\n MediaKind,\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n} from \"@/integrations/provider\";\nimport { HTTPClient } from \"@/utils/httpClient\";\n\n/** Options for {@link TelegramProvider}. */\nexport interface TelegramProviderOptions {\n /** Bot token from @BotFather. */\n token: string;\n /** API base. Default `https://api.telegram.org`. */\n apiBase?: string;\n /** Long-poll timeout in seconds for `getUpdates`. Default 30. */\n pollTimeoutSeconds?: number;\n}\n\n/** Bot API method suffix per media kind. */\nconst MEDIA_METHOD: Record<MediaKind, { method: string; field: string }> = {\n image: { method: \"sendPhoto\", field: \"photo\" },\n video: { method: \"sendVideo\", field: \"video\" },\n audio: { method: \"sendAudio\", field: \"audio\" },\n document: { method: \"sendDocument\", field: \"document\" },\n};\n\n/** A typed Telegram Bot API client. */\nexport class TelegramProvider implements MessagingProvider {\n private readonly http: HTTPClient;\n private readonly pollTimeout: number;\n\n /**\n * @param options - Bot token and API options.\n */\n constructor(options: TelegramProviderOptions) {\n const base = `${options.apiBase ?? \"https://api.telegram.org\"}/bot${options.token}`;\n this.pollTimeout = options.pollTimeoutSeconds ?? 30;\n this.http = new HTTPClient({\n baseUrl: base,\n defaultHeaders: { \"content-type\": \"application/json\" },\n // Timeout must exceed the long-poll window.\n timeoutMs: (this.pollTimeout + 10) * 1000,\n });\n }\n\n /** Call a Bot API method, returning the `result`, throwing on `ok: false`. */\n private async call<T>(method: string, body: Record<string, unknown>): Promise<T> {\n const res = await this.http.post(`/${method}`, { body: JSON.stringify(body) });\n const data = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n result?: T;\n description?: string;\n };\n if (!res.ok || !data.ok) {\n throw new Error(`Telegram ${method} failed: ${data.description ?? res.statusText}`);\n }\n return data.result as T;\n }\n\n async sendText(to: string, text: string): Promise<OutboundResult> {\n const result = await this.call<{ message_id: number }>(\"sendMessage\", {\n chat_id: to,\n text,\n });\n return { id: String(result.message_id), status: \"sent\" };\n }\n\n async sendMedia(to: string, media: OutboundMedia): Promise<OutboundResult> {\n const { method, field } = MEDIA_METHOD[media.kind];\n const body: Record<string, unknown> = { chat_id: to, [field]: media.media };\n if (media.caption !== undefined) body.caption = media.caption;\n const result = await this.call<{ message_id: number }>(method, body);\n return { id: String(result.message_id), status: \"sent\" };\n }\n\n async status(): Promise<string> {\n try {\n await this.call<{ id: number }>(\"getMe\", {});\n return \"connected\";\n } catch {\n return \"disconnected\";\n }\n }\n\n /**\n * Subscribe to inbound messages via `getUpdates` long-polling.\n *\n * @param handler - Invoked for each inbound text message.\n * @returns A stop function that ends the polling loop.\n */\n async onMessage(handler: InboundHandler): Promise<() => Promise<void>> {\n let running = true;\n let offset = 0;\n\n const loop = async (): Promise<void> => {\n while (running) {\n let updates: TelegramUpdate[] = [];\n try {\n updates = await this.call<TelegramUpdate[]>(\"getUpdates\", {\n offset,\n timeout: this.pollTimeout,\n });\n } catch {\n if (running) await new Promise((r) => setTimeout(r, 1000));\n continue;\n }\n for (const update of updates) {\n offset = update.update_id + 1;\n const message = update.message;\n if (!message) continue;\n await handler({\n from: String(message.chat.id),\n messageId: String(message.message_id),\n ...(typeof message.text === \"string\" ? { text: message.text } : {}),\n mediaType: null,\n timestamp: new Date(message.date * 1000).toISOString(),\n direction: \"incoming\",\n });\n }\n }\n };\n\n void loop();\n return async () => {\n running = false;\n };\n }\n}\n\n/** Minimal shape of a Telegram update we consume. */\ninterface TelegramUpdate {\n update_id: number;\n message?: {\n message_id: number;\n date: number;\n text?: string;\n chat: { id: number };\n };\n}\n","/**\n * SMS provider — a Twilio client + inbound-webhook receiver.\n *\n * Implements {@link MessagingProvider} over the built-in {@link HTTPClient}\n * (no `twilio` SDK). SMS has no persistent subscription, so `onMessage` is\n * absent — inbound arrives via {@link makeTwilioWebhookRouter}, which validates\n * the `X-Twilio-Signature` HMAC.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { UnauthorizedException } from \"@/exceptions/http\";\nimport type {\n InboundHandler,\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n} from \"@/integrations/provider\";\nimport { HTTPClient } from \"@/utils/httpClient\";\nimport { type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link TwilioSmsProvider}. */\nexport interface TwilioSmsProviderOptions {\n /** Twilio Account SID. */\n accountSid: string;\n /** Twilio Auth Token. */\n authToken: string;\n /** Default `From` number (E.164), e.g. `+15551234567`. */\n from: string;\n /** API base. Default `https://api.twilio.com`. */\n apiBase?: string;\n}\n\n/** A Twilio SMS client. */\nexport class TwilioSmsProvider implements MessagingProvider {\n private readonly http: HTTPClient;\n private readonly from: string;\n private readonly messagesPath: string;\n private readonly accountPath: string;\n\n /**\n * @param options - Account SID, auth token and default sender.\n */\n constructor(options: TwilioSmsProviderOptions) {\n this.from = options.from;\n this.messagesPath = `/2010-04-01/Accounts/${options.accountSid}/Messages.json`;\n this.accountPath = `/2010-04-01/Accounts/${options.accountSid}.json`;\n const basic = Buffer.from(`${options.accountSid}:${options.authToken}`).toString(\n \"base64\",\n );\n this.http = new HTTPClient({\n baseUrl: options.apiBase ?? \"https://api.twilio.com\",\n defaultHeaders: {\n Authorization: `Basic ${basic}`,\n \"content-type\": \"application/x-www-form-urlencoded\",\n },\n });\n }\n\n /** POST a form body to Twilio and parse the JSON, throwing on non-2xx. */\n private async postForm(params: Record<string, string>): Promise<OutboundResult> {\n const res = await this.http.post(this.messagesPath, {\n body: new URLSearchParams(params).toString(),\n });\n const data = (await res.json().catch(() => ({}))) as {\n sid?: string;\n status?: string;\n message?: string;\n };\n if (!res.ok) {\n throw new Error(\n `Twilio send failed (${res.status}): ${data.message ?? res.statusText}`,\n );\n }\n return {\n status: data.status ?? \"queued\",\n ...(data.sid ? { id: data.sid } : {}),\n };\n }\n\n async sendText(to: string, text: string): Promise<OutboundResult> {\n return this.postForm({ To: to, From: this.from, Body: text });\n }\n\n async sendMedia(to: string, media: OutboundMedia): Promise<OutboundResult> {\n return this.postForm({\n To: to,\n From: this.from,\n MediaUrl: media.media,\n ...(media.caption !== undefined ? { Body: media.caption } : {}),\n });\n }\n\n async status(): Promise<string> {\n const res = await this.http.get(this.accountPath);\n const data = (await res.json().catch(() => ({}))) as { status?: string };\n return data.status ?? (res.ok ? \"connected\" : \"disconnected\");\n }\n}\n\n/**\n * Validate a Twilio request signature (`X-Twilio-Signature`).\n *\n * @param authToken - The Twilio auth token.\n * @param url - The full public URL Twilio posted to (scheme + host + path).\n * @param params - The POST form parameters.\n * @param signature - The `X-Twilio-Signature` header value.\n * @returns `true` when the signature matches.\n */\nexport function validateTwilioSignature(\n authToken: string,\n url: string,\n params: Record<string, string>,\n signature: string,\n): boolean {\n const data =\n url +\n Object.keys(params)\n .sort()\n .map((key) => key + params[key])\n .join(\"\");\n const expected = createHmac(\"sha1\", authToken).update(data, \"utf8\").digest(\"base64\");\n const a = Buffer.from(expected);\n const b = Buffer.from(signature);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\n/** Options for {@link makeTwilioWebhookRouter}. */\nexport interface TwilioWebhookOptions {\n /** Handler invoked for each inbound SMS. */\n onMessage: InboundHandler;\n /** Route path. Default `/sms/inbound`. */\n path?: string;\n /** Auth token; when set, `X-Twilio-Signature` is validated. */\n authToken?: string;\n /** Public URL Twilio posts to (needed for signature validation behind a proxy). */\n publicUrl?: string;\n}\n\n/**\n * Build the Twilio inbound-SMS webhook router.\n *\n * Twilio posts `application/x-www-form-urlencoded` (`From`, `Body`,\n * `MessageSid`, …). Mount after `express.urlencoded()` (included by `createApp`).\n *\n * @param options - Handler, path and signature-validation settings.\n * @returns An Express router with the webhook endpoint mounted.\n */\nexport function makeTwilioWebhookRouter(options: TwilioWebhookOptions): Router {\n const path = options.path ?? \"/sms/inbound\";\n const router = createRouter();\n\n router.post(path, async (req, res) => {\n const body = (req.body ?? {}) as Record<string, string>;\n if (options.authToken) {\n const url =\n options.publicUrl ?? `${req.protocol}://${req.get(\"host\")}${req.originalUrl}`;\n const signature = req.header(\"x-twilio-signature\") ?? \"\";\n if (!validateTwilioSignature(options.authToken, url, body, signature)) {\n throw new UnauthorizedException({ message: \"Invalid Twilio signature\" });\n }\n }\n await options.onMessage({\n from: String(body.From ?? \"\"),\n messageId: String(body.MessageSid ?? \"\"),\n ...(body.Body ? { text: body.Body } : {}),\n mediaType: null,\n timestamp: new Date().toISOString(),\n direction: \"incoming\",\n });\n res.type(\"text/xml\").send(\"<Response></Response>\");\n });\n\n return router;\n}\n","/**\n * Email channel — a {@link MessagingProvider} over {@link EmailUtils}.\n *\n * Lets transactional email participate in the same swappable messaging contract\n * as WhatsApp/Telegram/SMS: `sendText` sends a plain email, `sendMedia` sends\n * the media as a link in the body. Inbound (`onMessage`) is absent — email\n * ingestion is out of scope. Requires the optional `nodemailer` peer via\n * {@link EmailUtils}.\n */\n\nimport type {\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n} from \"@/integrations/provider\";\nimport type { EmailUtils } from \"@/utils/email\";\n\n/** Options for {@link EmailProvider}. */\nexport interface EmailProviderOptions {\n /** The configured SMTP sender. */\n email: EmailUtils;\n /** Default subject line for `sendText`/`sendMedia`. Default `\"Notification\"`. */\n subject?: string;\n}\n\n/** An email-backed {@link MessagingProvider}. */\nexport class EmailProvider implements MessagingProvider {\n private readonly email: EmailUtils;\n private readonly subject: string;\n\n /**\n * @param options - The email sender and default subject.\n */\n constructor(options: EmailProviderOptions) {\n this.email = options.email;\n this.subject = options.subject ?? \"Notification\";\n }\n\n /**\n * Send a plain-text email.\n *\n * @param to - Recipient address.\n * @param text - Body text (also used as HTML).\n * @returns A sent result.\n */\n async sendText(to: string, text: string): Promise<OutboundResult> {\n await this.email.send({ to, subject: this.subject, text });\n return { status: \"sent\" };\n }\n\n /**\n * Send an email linking to the media (caption becomes the lead text).\n *\n * @param to - Recipient address.\n * @param media - The media reference (URL) + optional caption.\n * @returns A sent result.\n */\n async sendMedia(to: string, media: OutboundMedia): Promise<OutboundResult> {\n const caption = media.caption ?? \"\";\n await this.email.send({\n to,\n subject: this.subject,\n html: `${caption ? `<p>${caption}</p>` : \"\"}<p><a href=\"${media.media}\">${media.media}</a></p>`,\n });\n return { status: \"sent\" };\n }\n\n /** Always `\"connected\"` — SMTP reachability is verified on first send. */\n async status(): Promise<string> {\n return \"connected\";\n }\n}\n","/**\n * Broadcast + multi-channel helpers over {@link MessagingProvider}.\n *\n * {@link broadcastText} fans one message out to many recipients through a single\n * provider, with bounded concurrency and a per-recipient result (one failure\n * never aborts the rest). {@link MessagingHub} keeps named providers so app code\n * sends by channel name and can broadcast across all of them.\n */\n\nimport type {\n MessagingProvider,\n OutboundResult,\n SendOptions,\n} from \"@/integrations/provider\";\n\n/** The outcome of a single recipient's send within a broadcast. */\nexport interface BroadcastResult {\n /** The recipient address/handle. */\n to: string;\n /** Whether the send succeeded. */\n ok: boolean;\n /** The provider result, when successful. */\n result?: OutboundResult;\n /** The error message, when failed. */\n error?: string;\n}\n\n/** Options for {@link broadcastText}. */\nexport interface BroadcastOptions extends SendOptions {\n /** Maximum concurrent sends. Default 10. */\n concurrency?: number;\n}\n\n/** Run `worker` over `items` with at most `limit` in flight, preserving order. */\nasync function pool<T, R>(\n items: T[],\n limit: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let cursor = 0;\n const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {\n while (cursor < items.length) {\n const index = cursor++;\n results[index] = await worker(items[index] as T, index);\n }\n });\n await Promise.all(runners);\n return results;\n}\n\n/**\n * Send `text` to every recipient through `provider`, bounded by concurrency.\n *\n * A failed recipient is captured in its {@link BroadcastResult} (`ok: false`)\n * rather than aborting the batch.\n *\n * @param provider - The channel to send through.\n * @param recipients - Recipient addresses/handles.\n * @param text - The message body.\n * @param options - Concurrency + send options.\n * @returns One result per recipient, in input order.\n */\nexport function broadcastText(\n provider: MessagingProvider,\n recipients: string[],\n text: string,\n options: BroadcastOptions = {},\n): Promise<BroadcastResult[]> {\n const { concurrency = 10, ...sendOptions } = options;\n return pool(recipients, concurrency, async (to) => {\n try {\n const result = await provider.sendText(to, text, sendOptions);\n return { to, ok: true, result };\n } catch (error) {\n return {\n to,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n });\n}\n\n/** A registry of named messaging channels. */\nexport class MessagingHub {\n private readonly channels = new Map<string, MessagingProvider>();\n\n /**\n * Register a provider under a channel name.\n *\n * @param name - The channel name (e.g. `\"whatsapp\"`, `\"sms\"`).\n * @param provider - The provider implementation.\n * @returns The hub (chainable).\n */\n register(name: string, provider: MessagingProvider): this {\n this.channels.set(name, provider);\n return this;\n }\n\n /**\n * Get a registered provider, throwing when the channel is unknown.\n *\n * @param name - The channel name.\n * @returns The provider.\n * @throws {Error} When no provider is registered under `name`.\n */\n get(name: string): MessagingProvider {\n const provider = this.channels.get(name);\n if (!provider) throw new Error(`Unknown messaging channel: ${name}`);\n return provider;\n }\n\n /** The registered channel names. */\n channelNames(): string[] {\n return [...this.channels.keys()];\n }\n\n /**\n * Send text through a named channel.\n *\n * @param channel - The channel name.\n * @param to - The recipient.\n * @param text - The message body.\n * @param options - Send options.\n * @returns The provider result.\n */\n send(\n channel: string,\n to: string,\n text: string,\n options?: SendOptions,\n ): Promise<OutboundResult> {\n return this.get(channel).sendText(to, text, options);\n }\n\n /**\n * Broadcast text to many recipients on a named channel.\n *\n * @param channel - The channel name.\n * @param recipients - Recipient addresses/handles.\n * @param text - The message body.\n * @param options - Broadcast + send options.\n * @returns One result per recipient.\n */\n broadcast(\n channel: string,\n recipients: string[],\n text: string,\n options?: BroadcastOptions,\n ): Promise<BroadcastResult[]> {\n return broadcastText(this.get(channel), recipients, text, options);\n }\n}\n","/**\n * Admin site + resource registry, mirroring `admin.site` / `admin.config`.\n *\n * The FastAPI SDK ships a server-rendered (jinja) admin UI. Here the admin is a\n * typed **JSON API**: register one {@link AdminResource} per managed entity and\n * {@link makeAdminRouter} exposes auto-derived CRUD + introspection endpoints a\n * frontend (React, etc.) renders. Resources are callback-based, so they wire to\n * a `BaseService` — or any store — in a few lines and stay ORM-agnostic.\n */\n\nimport type { z } from \"@/schemas/base\";\n\n/** A field descriptor a frontend uses to render list columns / form inputs. */\nexport interface AdminField {\n /** Field name (property key). */\n name: string;\n /** Loose type hint for rendering (`string`, `number`, `boolean`, `date`, …). */\n type?: string;\n /** Whether the field is required on create. */\n required?: boolean;\n /** Whether the field is read-only (shown, never submitted). */\n readOnly?: boolean;\n}\n\n/** A paginated list result returned by {@link AdminResource.list}. */\nexport interface AdminListResult<T = unknown> {\n items: T[];\n total: number;\n page: number;\n pageSize: number;\n pages: number;\n}\n\n/** Query parameters passed to {@link AdminResource.list}. */\nexport interface AdminListQuery {\n page: number;\n pageSize: number;\n /** Remaining query-string entries (domain filters). */\n filters: Record<string, string>;\n}\n\n/**\n * A managed resource. Only `name`, `fields` and `list`/`get` are required;\n * omit a write callback to make that operation unavailable (405).\n */\nexport interface AdminResource<T = unknown> {\n /** URL-safe resource slug (e.g. `users`). */\n name: string;\n /** Field descriptors for list/detail/form rendering. */\n fields: AdminField[];\n /** Return a page of records. */\n list(query: AdminListQuery): Promise<AdminListResult<T>>;\n /** Return one record by id, or `null` when absent. */\n get(id: string): Promise<T | null>;\n /** Create a record from validated input. */\n create?(data: unknown): Promise<T>;\n /** Update a record by id from validated input. */\n update?(id: string, data: unknown): Promise<T>;\n /** Delete a record by id. */\n remove?(id: string): Promise<void>;\n /** Zod schema validating the create body. */\n createSchema?: z.ZodType;\n /** Zod schema validating the update body. */\n updateSchema?: z.ZodType;\n}\n\n/** A registry of admin resources. */\nexport class AdminSite {\n private readonly resources = new Map<string, AdminResource>();\n\n /**\n * @param brand - Display name surfaced under `GET {prefix}/`.\n */\n constructor(readonly brand = \"Admin\") {}\n\n /**\n * Register a resource.\n *\n * @param resource - The resource config.\n * @returns The same resource (for chaining).\n */\n register<T>(resource: AdminResource<T>): AdminResource<T> {\n this.resources.set(resource.name, resource as AdminResource);\n return resource;\n }\n\n /** Look up a resource by slug, or `null`. */\n get(name: string): AdminResource | null {\n return this.resources.get(name) ?? null;\n }\n\n /** Every registered resource. */\n list(): AdminResource[] {\n return [...this.resources.values()];\n }\n}\n","/**\n * Admin JSON router, mirroring `admin.router.make_admin_router`.\n *\n * Exposes auto-derived CRUD + introspection over an {@link AdminSite}:\n *\n * ```text\n * GET {prefix}/ site brand + resource list\n * GET {prefix}/:resource/_meta resource field descriptors\n * GET {prefix}/:resource paginated list\n * GET {prefix}/:resource/:id detail (404 when absent)\n * POST {prefix}/:resource create (405 if unsupported)\n * PATCH {prefix}/:resource/:id update (405 if unsupported)\n * DELETE {prefix}/:resource/:id delete (405 if unsupported)\n * ```\n *\n * Pass a `guard` middleware (e.g. JWT + `requireRoles(\"admin\")`) to protect it.\n */\n\nimport type { AdminResource, AdminSite } from \"@/admin/site\";\nimport { AppException } from \"@/exceptions/base\";\nimport { NotFoundException } from \"@/exceptions/http\";\nimport { type RequestHandler, type Router, Router as createRouter } from \"express\";\n\nconst PAGINATION_KEYS = new Set([\"page\", \"pageSize\"]);\n\n/** Options for {@link makeAdminRouter}. */\nexport interface AdminRouterOptions {\n /** Route prefix. Default `/admin`. */\n prefix?: string;\n /** Guard middleware applied to every admin route (auth). */\n guard?: RequestHandler;\n}\n\n/** Raised (405) when a resource does not support a write operation. */\nfunction methodNotAllowed(operation: string): AppException {\n return new AppException({\n message: `Operation not allowed: ${operation}`,\n code: \"METHOD_NOT_ALLOWED\",\n statusCode: 405,\n });\n}\n\n/** Resolve a resource by slug or raise 404. */\nfunction requireResource(site: AdminSite, name: string): AdminResource {\n const resource = site.get(name);\n if (!resource) throw new NotFoundException({ message: `Unknown resource: ${name}` });\n return resource;\n}\n\n/**\n * Build the admin router.\n *\n * @param site - The registered {@link AdminSite}.\n * @param options - Prefix and guard middleware.\n * @returns An Express router with the admin endpoints mounted.\n */\nexport function makeAdminRouter(\n site: AdminSite,\n options: AdminRouterOptions = {},\n): Router {\n const prefix = (options.prefix ?? \"/admin\").replace(/\\/$/, \"\");\n const router = createRouter();\n if (options.guard) router.use(prefix, options.guard);\n\n router.get(prefix, (_req, res) => {\n res.json({\n brand: site.brand,\n resources: site.list().map((r) => ({ name: r.name, fields: r.fields })),\n });\n });\n\n router.get(`${prefix}/:resource/_meta`, (req, res) => {\n const resource = requireResource(site, req.params.resource);\n res.json({\n name: resource.name,\n fields: resource.fields,\n operations: {\n create: Boolean(resource.create),\n update: Boolean(resource.update),\n remove: Boolean(resource.remove),\n },\n });\n });\n\n router.get(`${prefix}/:resource`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n const filters: Record<string, string> = {};\n for (const [key, value] of Object.entries(req.query)) {\n if (!PAGINATION_KEYS.has(key) && typeof value === \"string\") filters[key] = value;\n }\n const page = Math.max(1, Number.parseInt(String(req.query.page ?? \"1\"), 10) || 1);\n const pageSize = Math.max(\n 1,\n Number.parseInt(String(req.query.pageSize ?? \"20\"), 10) || 20,\n );\n res.json(await resource.list({ page, pageSize, filters }));\n });\n\n router.get(`${prefix}/:resource/:id`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n const record = await resource.get(req.params.id);\n if (record === null) throw new NotFoundException({ message: \"Record not found\" });\n res.json(record);\n });\n\n router.post(`${prefix}/:resource`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n if (!resource.create) throw methodNotAllowed(\"create\");\n const data = resource.createSchema ? resource.createSchema.parse(req.body) : req.body;\n res.status(201).json(await resource.create(data));\n });\n\n router.patch(`${prefix}/:resource/:id`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n if (!resource.update) throw methodNotAllowed(\"update\");\n const data = resource.updateSchema ? resource.updateSchema.parse(req.body) : req.body;\n res.json(await resource.update(req.params.id, data));\n });\n\n router.delete(`${prefix}/:resource/:id`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n if (!resource.remove) throw methodNotAllowed(\"remove\");\n await resource.remove(req.params.id);\n res.status(204).end();\n });\n\n return router;\n}\n","/**\n * Auth DTOs (Zod), mirroring `auth.schemas`.\n *\n * Request/response schemas for the bundled signup/login/refresh flows. All are\n * OpenAPI-registered shapes so they render in Swagger/Redoc when the auth\n * router's paths are registered.\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** Request body for `POST /auth/signup`. */\nexport const signupSchema = z\n .object({\n email: z.email().openapi({ description: \"Login identifier (email).\" }),\n password: z\n .string()\n .min(1)\n .openapi({ description: \"Plaintext password (hashed server-side).\" }),\n name: z\n .string()\n .max(120)\n .optional()\n .openapi({ description: \"Optional display name.\" }),\n })\n .openapi(\"Signup\");\n\n/** Request body for `POST /auth/login`. */\nexport const loginSchema = z\n .object({\n email: z.email().openapi({ description: \"Login identifier (email).\" }),\n password: z.string().min(1).openapi({ description: \"Plaintext password.\" }),\n })\n .openapi(\"Login\");\n\n/** Request body for `POST /auth/refresh`. */\nexport const refreshSchema = z\n .object({\n refreshToken: z.string().min(1).openapi({ description: \"A valid refresh token.\" }),\n })\n .openapi(\"Refresh\");\n\n/** A signed access/refresh token pair. */\nexport const tokenPairSchema = z\n .object({\n accessToken: z.string().openapi({ description: \"Short-lived bearer access token.\" }),\n refreshToken: z.string().openapi({ description: \"Long-lived refresh token.\" }),\n tokenType: z.literal(\"bearer\").openapi({ description: \"Always 'bearer'.\" }),\n expiresIn: z\n .number()\n .int()\n .openapi({ description: \"Access-token lifetime in seconds.\" }),\n })\n .openapi(\"TokenPair\");\n\n/** Public user projection returned by `GET /auth/me` and signup/login. */\nexport const userPublicSchema = z\n .object({\n id: z.string().openapi({ description: \"User id.\" }),\n email: z.email().openapi({ description: \"User email.\" }),\n name: z.string().nullable().openapi({ description: \"Display name, or null.\" }),\n isActive: z.boolean().openapi({ description: \"Whether the account is active.\" }),\n roles: z.array(z.string()).openapi({ description: \"Assigned role names.\" }),\n })\n .openapi(\"UserPublic\");\n\n/** Response body for `POST /auth/signup` and `POST /auth/login`. */\nexport const authResponseSchema = z\n .object({\n user: userPublicSchema,\n tokens: tokenPairSchema,\n })\n .openapi(\"AuthResponse\");\n\n/** MFA enrollment response (`POST /auth/mfa/enroll`). */\nexport const mfaEnrollResponseSchema = z\n .object({\n secret: z.string().openapi({ description: \"Base32 TOTP secret (manual entry).\" }),\n otpauthUri: z.string().openapi({ description: \"otpauth:// URI to render as QR.\" }),\n })\n .openapi(\"MfaEnrollResponse\");\n\n/** A 6-digit MFA code body (`POST /auth/mfa/confirm|disable`). */\nexport const mfaCodeSchema = z\n .object({ code: z.string().min(1).openapi({ description: \"Authenticator code.\" }) })\n .openapi(\"MfaCode\");\n\n/** MFA login-challenge body (`POST /auth/mfa/challenge`). */\nexport const mfaChallengeSchema = z\n .object({\n mfaToken: z.string().min(1).openapi({ description: \"Challenge token from login.\" }),\n code: z.string().min(1).openapi({ description: \"Authenticator code.\" }),\n })\n .openapi(\"MfaChallenge\");\n\n/** Activation body (`POST /auth/activate`). */\nexport const activationSchema = z\n .object({ token: z.string().min(1).openapi({ description: \"Activation token.\" }) })\n .openapi(\"Activation\");\n\n/** Password-reset request body (`POST /auth/password-reset/request`). */\nexport const passwordResetRequestSchema = z\n .object({ email: z.email().openapi({ description: \"Account email.\" }) })\n .openapi(\"PasswordResetRequest\");\n\n/** Password-reset confirm body (`POST /auth/password-reset/confirm`). */\nexport const passwordResetConfirmSchema = z\n .object({\n token: z.string().min(1).openapi({ description: \"Reset token.\" }),\n password: z.string().min(1).openapi({ description: \"New plaintext password.\" }),\n })\n .openapi(\"PasswordResetConfirm\");\n\nexport type SignupInput = z.infer<typeof signupSchema>;\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type RefreshInput = z.infer<typeof refreshSchema>;\nexport type TokenPair = z.infer<typeof tokenPairSchema>;\nexport type UserPublic = z.infer<typeof userPublicSchema>;\nexport type AuthResponse = z.infer<typeof authResponseSchema>;\nexport type MfaCodeInput = z.infer<typeof mfaCodeSchema>;\nexport type MfaChallengeInput = z.infer<typeof mfaChallengeSchema>;\nexport type ActivationInput = z.infer<typeof activationSchema>;\nexport type PasswordResetRequestInput = z.infer<typeof passwordResetRequestSchema>;\nexport type PasswordResetConfirmInput = z.infer<typeof passwordResetConfirmSchema>;\n","/**\n * User authentication service, mirroring `auth.service.UserAuthService`.\n *\n * Orchestrates signup / login / refresh over a pluggable {@link UserStore},\n * {@link PasswordUtils} and {@link JWTUtils}. It is ORM-agnostic — back the\n * store with a `tempest-db-js` repository (or anything else). With an\n * {@link MfaService} wired in, `login` returns an MFA challenge for enrolled\n * users (complete it via {@link UserAuthService.verifyMfaChallenge}).\n */\n\nimport type { MfaService } from \"@/auth/mfa\";\nimport type {\n AuthResponse,\n LoginInput,\n SignupInput,\n TokenPair,\n UserPublic,\n} from \"@/auth/schemas\";\nimport {\n ConflictException,\n UnauthorizedException,\n ValidationException,\n} from \"@/exceptions/http\";\nimport type { JWTUtils } from \"@/utils/jwt\";\nimport type { PasswordUtils } from \"@/utils/password\";\n\n/** A persisted user as the auth layer needs to see it. */\nexport interface AuthUser {\n /** Stable user id (string form). */\n id: string;\n /** Login email (lowercased by the service before lookup/create). */\n email: string;\n /** The stored bcrypt password hash. */\n passwordHash: string;\n /** Display name, or `null`. */\n name: string | null;\n /** Whether the account may log in. */\n isActive: boolean;\n /** Assigned role names. */\n roles: string[];\n}\n\n/** Persistence port the service depends on. Implement over any store. */\nexport interface UserStore {\n /** Find a user by (lowercased) email, or `null`. */\n findByEmail(email: string): Promise<AuthUser | null>;\n /** Find a user by id, or `null`. */\n findById(id: string): Promise<AuthUser | null>;\n /** Create a user from validated signup data + a password hash. */\n create(data: {\n email: string;\n passwordHash: string;\n name: string | null;\n }): Promise<AuthUser>;\n}\n\n/** Options for {@link UserAuthService}. */\nexport interface UserAuthServiceOptions {\n /** The user persistence port. */\n store: UserStore;\n /** Password hasher/verifier. */\n password: PasswordUtils;\n /** JWT encoder/decoder used to mint access + refresh tokens. */\n jwt: JWTUtils;\n /** Minimum password length enforced server-side. Default 12. */\n passwordMinLength?: number;\n /** Access-token lifetime in seconds. Default 3600. */\n accessTtlSeconds?: number;\n /** Refresh-token lifetime in seconds. Default 1209600 (14 days). */\n refreshTtlSeconds?: number;\n /**\n * When provided, `login` returns an MFA challenge instead of tokens for users\n * with MFA enabled; complete it with {@link UserAuthService.verifyMfaChallenge}.\n */\n mfa?: MfaService;\n /** MFA challenge-token lifetime in seconds. Default 300 (5 min). */\n mfaChallengeTtlSeconds?: number;\n}\n\n/** Returned by `login` when the user must complete an MFA challenge. */\nexport interface MfaChallenge {\n /** Discriminator: an MFA step is required before tokens are issued. */\n mfaRequired: true;\n /** Short-lived token to submit alongside the code to `verifyMfaChallenge`. */\n mfaToken: string;\n}\n\n/** `login` result: either full auth, or an MFA challenge to complete. */\nexport type LoginResult = AuthResponse | MfaChallenge;\n\n/** Project an {@link AuthUser} to its public shape (no secrets). */\nfunction toPublic(user: AuthUser): UserPublic {\n return {\n id: user.id,\n email: user.email,\n name: user.name,\n isActive: user.isActive,\n roles: user.roles,\n };\n}\n\nexport class UserAuthService {\n private readonly store: UserStore;\n private readonly password: PasswordUtils;\n private readonly jwt: JWTUtils;\n private readonly passwordMinLength: number;\n private readonly accessTtlSeconds: number;\n private readonly refreshTtlSeconds: number;\n private readonly mfa: MfaService | undefined;\n private readonly mfaChallengeTtlSeconds: number;\n\n /**\n * @param options - Store, password/JWT helpers and token policy.\n */\n constructor(options: UserAuthServiceOptions) {\n this.store = options.store;\n this.password = options.password;\n this.jwt = options.jwt;\n this.passwordMinLength = options.passwordMinLength ?? 12;\n this.accessTtlSeconds = options.accessTtlSeconds ?? 3600;\n this.refreshTtlSeconds = options.refreshTtlSeconds ?? 60 * 60 * 24 * 14;\n this.mfa = options.mfa;\n this.mfaChallengeTtlSeconds = options.mfaChallengeTtlSeconds ?? 300;\n }\n\n /** Mint a signed access + refresh token pair for `user`. */\n private async issueTokens(user: AuthUser): Promise<TokenPair> {\n const accessToken = await this.jwt.encode(\n { sub: user.id, roles: user.roles, type: \"access\" },\n { ttlSeconds: this.accessTtlSeconds },\n );\n const refreshToken = await this.jwt.encode(\n { sub: user.id, type: \"refresh\" },\n { ttlSeconds: this.refreshTtlSeconds },\n );\n return {\n accessToken,\n refreshToken,\n tokenType: \"bearer\",\n expiresIn: this.accessTtlSeconds,\n };\n }\n\n /**\n * Register a new user and issue tokens.\n *\n * @param data - Validated signup payload.\n * @returns The public user and a fresh token pair.\n * @throws {ValidationException} When the password is too short.\n * @throws {ConflictException} When the email is already registered.\n */\n async signup(data: SignupInput): Promise<AuthResponse> {\n if (data.password.length < this.passwordMinLength) {\n throw new ValidationException({\n message: `Password must be at least ${this.passwordMinLength} characters`,\n details: { minLength: this.passwordMinLength },\n });\n }\n const email = data.email.toLowerCase();\n if (await this.store.findByEmail(email)) {\n throw new ConflictException({ message: \"Email already registered\" });\n }\n const passwordHash = await this.password.hash(data.password);\n const user = await this.store.create({\n email,\n passwordHash,\n name: data.name ?? null,\n });\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n\n /**\n * Authenticate a user by email + password.\n *\n * @param data - Validated login payload.\n * @returns Full auth, or an {@link MfaChallenge} when MFA is enabled.\n * @throws {UnauthorizedException} On bad credentials or inactive account.\n */\n async login(data: LoginInput): Promise<LoginResult> {\n const user = await this.store.findByEmail(data.email.toLowerCase());\n const ok = user && (await this.password.verify(data.password, user.passwordHash));\n if (!user || !ok) {\n throw new UnauthorizedException({ message: \"Invalid email or password\" });\n }\n if (!user.isActive) {\n throw new UnauthorizedException({ message: \"Account is inactive\" });\n }\n if (this.mfa && (await this.mfa.isEnabled(user.id))) {\n const mfaToken = await this.jwt.encode(\n { sub: user.id, type: \"mfa\" },\n { ttlSeconds: this.mfaChallengeTtlSeconds },\n );\n return { mfaRequired: true, mfaToken };\n }\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n\n /**\n * Complete an MFA login challenge: verify the code and issue tokens.\n *\n * @param mfaToken - The challenge token from {@link login}.\n * @param code - The authenticator code.\n * @returns The public user and a fresh token pair.\n * @throws {UnauthorizedException} When the challenge/code is invalid, MFA is\n * not configured, or the account no longer exists / is inactive.\n */\n async verifyMfaChallenge(mfaToken: string, code: string): Promise<AuthResponse> {\n if (!this.mfa) throw new UnauthorizedException({ message: \"MFA not configured\" });\n const claims = await this.jwt.decodeOrNull(mfaToken);\n if (!claims || claims.type !== \"mfa\" || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Invalid MFA challenge\" });\n }\n if (!(await this.mfa.verify(claims.sub, code))) {\n throw new UnauthorizedException({ message: \"Invalid MFA code\" });\n }\n const user = await this.store.findById(claims.sub);\n if (!user || !user.isActive) {\n throw new UnauthorizedException({ message: \"Account is inactive\" });\n }\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n\n /**\n * Exchange a valid refresh token for a new token pair.\n *\n * @param refreshToken - The refresh token from a prior login.\n * @returns The public user and a fresh token pair.\n * @throws {UnauthorizedException} When the token is invalid or not a refresh\n * token, or the user no longer exists / is inactive.\n */\n async refresh(refreshToken: string): Promise<AuthResponse> {\n const claims = await this.jwt.decodeOrNull(refreshToken);\n if (!claims || claims.type !== \"refresh\" || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Invalid refresh token\" });\n }\n const user = await this.store.findById(claims.sub);\n if (!user || !user.isActive) {\n throw new UnauthorizedException({ message: \"Account is inactive\" });\n }\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n}\n","/**\n * TOTP MFA enrollment/verification, mirroring the FastAPI SDK MFA flow.\n *\n * Orchestrates {@link TOTPHelper} over a pluggable {@link MfaStore}: enroll\n * (generate + persist a secret, return the provisioning URI), confirm (verify a\n * code and flip MFA on), verify (login step) and disable.\n */\n\nimport { ValidationException } from \"@/exceptions/http\";\nimport type { TOTPHelper } from \"@/utils/totp\";\n\n/** Persistence port for MFA secrets/state. */\nexport interface MfaStore {\n /** Persist a user's TOTP secret (pending until confirmed). */\n setSecret(userId: string, secret: string): Promise<void>;\n /** Read a user's TOTP secret, or `null`. */\n getSecret(userId: string): Promise<string | null>;\n /** Flip the MFA-enabled flag. */\n setEnabled(userId: string, enabled: boolean): Promise<void>;\n /** Whether MFA is enabled for the user. */\n isEnabled(userId: string): Promise<boolean>;\n}\n\n/** The result of starting enrollment. */\nexport interface MfaEnrollment {\n /** The base32 secret (persist server-side; also shown once for manual entry). */\n secret: string;\n /** The `otpauth://` URI to render as a QR code. */\n otpauthUri: string;\n}\n\n/** Options for {@link MfaService}. */\nexport interface MfaServiceOptions {\n /** The MFA persistence port. */\n store: MfaStore;\n /** The TOTP helper (issuer preconfigured). */\n totp: TOTPHelper;\n}\n\nexport class MfaService {\n private readonly store: MfaStore;\n private readonly totp: TOTPHelper;\n\n /**\n * @param options - Store and TOTP helper.\n */\n constructor(options: MfaServiceOptions) {\n this.store = options.store;\n this.totp = options.totp;\n }\n\n /**\n * Begin enrollment: generate and persist a secret, return the QR URI.\n *\n * @param userId - The enrolling user.\n * @param accountName - Label shown in the authenticator (usually the email).\n * @returns The secret and provisioning URI.\n */\n async enroll(userId: string, accountName: string): Promise<MfaEnrollment> {\n const secret = this.totp.generateSecret();\n await this.store.setSecret(userId, secret);\n await this.store.setEnabled(userId, false);\n return { secret, otpauthUri: this.totp.provisioningUri(secret, accountName) };\n }\n\n /**\n * Confirm enrollment by verifying a code, enabling MFA on success.\n *\n * @param userId - The user.\n * @param code - The 6-digit code from the authenticator.\n * @throws {ValidationException} When no secret is pending or the code is wrong.\n */\n async confirm(userId: string, code: string): Promise<void> {\n const secret = await this.store.getSecret(userId);\n if (!secret) throw new ValidationException({ message: \"MFA not initialized\" });\n if (!this.totp.verify(secret, code)) {\n throw new ValidationException({ message: \"Invalid MFA code\" });\n }\n await this.store.setEnabled(userId, true);\n }\n\n /**\n * Verify a code (login step). Returns `false` without throwing.\n *\n * @param userId - The user.\n * @param code - The submitted code.\n * @returns `true` when the code is valid.\n */\n async verify(userId: string, code: string): Promise<boolean> {\n const secret = await this.store.getSecret(userId);\n return secret ? this.totp.verify(secret, code) : false;\n }\n\n /**\n * Whether MFA is enabled for a user (used to gate the login challenge).\n *\n * @param userId - The user.\n * @returns `true` when MFA is enabled.\n */\n async isEnabled(userId: string): Promise<boolean> {\n return this.store.isEnabled(userId);\n }\n\n /**\n * Disable MFA after verifying a code.\n *\n * @param userId - The user.\n * @param code - The submitted code.\n * @throws {ValidationException} When the code is invalid.\n */\n async disable(userId: string, code: string): Promise<void> {\n if (!(await this.verify(userId, code))) {\n throw new ValidationException({ message: \"Invalid MFA code\" });\n }\n await this.store.setEnabled(userId, false);\n await this.store.setSecret(userId, \"\");\n }\n}\n","/**\n * Email-activation flow, mirroring the FastAPI SDK activation flow.\n *\n * Issues a single-use opaque token (only its SHA-256 hash is stored), emails\n * the plaintext to the user, and activates the account when the link is opened.\n */\n\nimport { InvalidTokenException } from \"@/exceptions/http\";\nimport { generateOpaqueToken, hashOpaqueToken } from \"@/utils/opaqueToken\";\n\n/** Persistence port for activation tokens. */\nexport interface ActivationStore {\n /** Persist a token hash + expiry (epoch ms) for a user. */\n saveActivationToken(\n userId: string,\n tokenHash: string,\n expiresAt: number,\n ): Promise<void>;\n /** Look up a token hash, returning the owner + expiry, or `null`. */\n findActivationToken(\n tokenHash: string,\n ): Promise<{ userId: string; expiresAt: number } | null>;\n /** Remove a token hash (single-use). */\n clearActivationToken(tokenHash: string): Promise<void>;\n /** Mark a user active. */\n activate(userId: string): Promise<void>;\n}\n\n/** Options for {@link ActivationService}. */\nexport interface ActivationServiceOptions {\n /** The activation persistence port. */\n store: ActivationStore;\n /** Token lifetime in seconds. Default 86400 (24h). */\n ttlSeconds?: number;\n}\n\nexport class ActivationService {\n private readonly store: ActivationStore;\n private readonly ttlSeconds: number;\n\n /**\n * @param options - Store and token TTL.\n */\n constructor(options: ActivationServiceOptions) {\n this.store = options.store;\n this.ttlSeconds = options.ttlSeconds ?? 60 * 60 * 24;\n }\n\n /**\n * Start activation: issue a token and persist its hash.\n *\n * @param userId - The user to activate.\n * @returns The one-time plaintext token (embed in the activation link).\n */\n async start(userId: string): Promise<string> {\n const { plaintext, tokenHash } = generateOpaqueToken();\n await this.store.saveActivationToken(\n userId,\n tokenHash,\n Date.now() + this.ttlSeconds * 1000,\n );\n return plaintext;\n }\n\n /**\n * Activate an account from a token.\n *\n * @param token - The plaintext token from the activation link.\n * @returns The activated user id.\n * @throws {InvalidTokenException} When the token is unknown or expired.\n */\n async activate(token: string): Promise<string> {\n const tokenHash = hashOpaqueToken(token);\n const record = await this.store.findActivationToken(tokenHash);\n if (!record || record.expiresAt <= Date.now()) {\n throw new InvalidTokenException({ message: \"Invalid or expired activation token\" });\n }\n await this.store.activate(record.userId);\n await this.store.clearActivationToken(tokenHash);\n return record.userId;\n }\n}\n","/**\n * Password-reset flow, mirroring the FastAPI SDK reset flow.\n *\n * `request` issues a single-use opaque token (hash stored) for a known email,\n * returning it so the caller can email the reset link — without leaking whether\n * the email exists. `confirm` validates the token + new password and rehashes.\n */\n\nimport { InvalidTokenException, ValidationException } from \"@/exceptions/http\";\nimport { generateOpaqueToken, hashOpaqueToken } from \"@/utils/opaqueToken\";\nimport type { PasswordUtils } from \"@/utils/password\";\n\n/** Persistence port for password resets. */\nexport interface PasswordResetStore {\n /** Resolve a (lowercased) email to a user id, or `null`. */\n findUserIdByEmail(email: string): Promise<string | null>;\n /** Persist a reset token hash + expiry (epoch ms). */\n saveResetToken(userId: string, tokenHash: string, expiresAt: number): Promise<void>;\n /** Look up a reset token hash, returning owner + expiry, or `null`. */\n findResetToken(\n tokenHash: string,\n ): Promise<{ userId: string; expiresAt: number } | null>;\n /** Remove a reset token hash (single-use). */\n clearResetToken(tokenHash: string): Promise<void>;\n /** Overwrite a user's password hash. */\n updatePassword(userId: string, passwordHash: string): Promise<void>;\n}\n\n/** Options for {@link PasswordResetService}. */\nexport interface PasswordResetServiceOptions {\n /** The reset persistence port. */\n store: PasswordResetStore;\n /** Password hasher. */\n password: PasswordUtils;\n /** Token lifetime in seconds. Default 3600 (1h). */\n ttlSeconds?: number;\n /** Minimum new-password length. Default 12. */\n passwordMinLength?: number;\n}\n\nexport class PasswordResetService {\n private readonly store: PasswordResetStore;\n private readonly password: PasswordUtils;\n private readonly ttlSeconds: number;\n private readonly passwordMinLength: number;\n\n /**\n * @param options - Store, password hasher and policy.\n */\n constructor(options: PasswordResetServiceOptions) {\n this.store = options.store;\n this.password = options.password;\n this.ttlSeconds = options.ttlSeconds ?? 3600;\n this.passwordMinLength = options.passwordMinLength ?? 12;\n }\n\n /**\n * Request a reset for `email`.\n *\n * Returns the plaintext token only when the email maps to a user; otherwise\n * `null`. Callers should respond with the same success shape either way to\n * avoid user enumeration — email the token only when present.\n *\n * @param email - The account email.\n * @returns The one-time token, or `null` when no user matches.\n */\n async request(email: string): Promise<string | null> {\n const userId = await this.store.findUserIdByEmail(email.toLowerCase());\n if (!userId) return null;\n const { plaintext, tokenHash } = generateOpaqueToken();\n await this.store.saveResetToken(\n userId,\n tokenHash,\n Date.now() + this.ttlSeconds * 1000,\n );\n return plaintext;\n }\n\n /**\n * Confirm a reset: validate the token + new password and rehash.\n *\n * @param token - The plaintext reset token.\n * @param newPassword - The new plaintext password.\n * @throws {ValidationException} When the new password is too short.\n * @throws {InvalidTokenException} When the token is unknown or expired.\n */\n async confirm(token: string, newPassword: string): Promise<void> {\n if (newPassword.length < this.passwordMinLength) {\n throw new ValidationException({\n message: `Password must be at least ${this.passwordMinLength} characters`,\n details: { minLength: this.passwordMinLength },\n });\n }\n const tokenHash = hashOpaqueToken(token);\n const record = await this.store.findResetToken(tokenHash);\n if (!record || record.expiresAt <= Date.now()) {\n throw new InvalidTokenException({ message: \"Invalid or expired reset token\" });\n }\n await this.store.updatePassword(record.userId, await this.password.hash(newPassword));\n await this.store.clearResetToken(tokenHash);\n }\n}\n","/**\n * JWT auth middleware + role guards, mirroring `api.dependencies.auth`.\n *\n * {@link makeJwtAuthMiddleware} decodes a `Bearer` token and attaches the\n * claims to `req.auth`; {@link requireRoles} gates a route on role membership.\n * Failures raise the SDK's {@link UnauthorizedException} / {@link ForbiddenException}\n * so they render as the canonical error envelope.\n */\n\nimport { ForbiddenException, UnauthorizedException } from \"@/exceptions/http\";\nimport type { JWTUtils, JwtClaims } from \"@/utils/jwt\";\nimport type { Request, RequestHandler } from \"express\";\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n /** Decoded JWT claims, populated by {@link makeJwtAuthMiddleware}. */\n interface Request {\n auth?: JwtClaims;\n }\n }\n}\n\n/** Extract a `Bearer` token from the `Authorization` header, or `null`. */\nexport function bearerToken(req: Request): string | null {\n const header = req.header(\"authorization\");\n if (!header) return null;\n const [scheme, token] = header.split(\" \");\n if (scheme?.toLowerCase() !== \"bearer\" || !token) return null;\n return token;\n}\n\n/** Read the decoded claims attached by the auth middleware, or `null`. */\nexport function getAuth(req: Request): JwtClaims | null {\n return req.auth ?? null;\n}\n\n/** Options for {@link makeJwtAuthMiddleware}. */\nexport interface JwtAuthOptions {\n /** When `true` (default), a missing/invalid token rejects with 401. */\n required?: boolean;\n}\n\n/**\n * Build middleware that decodes the bearer token and sets `req.auth`.\n *\n * @param jwt - The JWT helper used to verify tokens.\n * @param options - Whether authentication is required.\n * @returns An Express middleware.\n */\nexport function makeJwtAuthMiddleware(\n jwt: JWTUtils,\n options: JwtAuthOptions = {},\n): RequestHandler {\n const required = options.required ?? true;\n return (req, _res, next) => {\n const token = bearerToken(req);\n if (!token) {\n if (required) {\n next(new UnauthorizedException({ message: \"Missing bearer token\" }));\n return;\n }\n next();\n return;\n }\n jwt\n .decode(token)\n .then((claims) => {\n req.auth = claims;\n next();\n })\n .catch((error: unknown) => {\n if (required) next(error);\n else next();\n });\n };\n}\n\n/**\n * Build middleware that requires the authenticated user to hold at least one\n * of `roles` (read from the `roles` claim). Must run after the auth middleware.\n *\n * @param roles - Acceptable role names.\n * @returns An Express middleware.\n */\nexport function requireRoles(...roles: string[]): RequestHandler {\n return (req, _res, next) => {\n const claims = req.auth;\n if (!claims) {\n next(new UnauthorizedException({ message: \"Not authenticated\" }));\n return;\n }\n const held = Array.isArray(claims.roles) ? (claims.roles as unknown[]) : [];\n if (roles.some((role) => held.includes(role))) {\n next();\n return;\n }\n next(new ForbiddenException({ message: \"Insufficient role\", details: { roles } }));\n };\n}\n","/**\n * Auth router, mirroring `auth.router.make_auth_router`.\n *\n * Wires `POST /auth/signup`, `POST /auth/login`, `POST /auth/refresh` and a\n * guarded `GET /auth/me` to a {@link UserAuthService}. Pass an\n * {@link OpenAPIRegistry} to register the paths so they appear in Swagger/Redoc.\n */\n\nimport type { OpenAPIRegistry } from \"@/api/openapi\";\nimport type { ActivationService } from \"@/auth/activation\";\nimport type { MfaService } from \"@/auth/mfa\";\nimport { getAuth, makeJwtAuthMiddleware } from \"@/auth/middleware\";\nimport type { PasswordResetService } from \"@/auth/passwordReset\";\nimport {\n activationSchema,\n authResponseSchema,\n loginSchema,\n mfaChallengeSchema,\n mfaCodeSchema,\n passwordResetConfirmSchema,\n passwordResetRequestSchema,\n refreshSchema,\n signupSchema,\n userPublicSchema,\n} from \"@/auth/schemas\";\nimport type { UserAuthService } from \"@/auth/service\";\nimport { UnauthorizedException } from \"@/exceptions/http\";\nimport type { JWTUtils } from \"@/utils/jwt\";\nimport { type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link makeAuthRouter}. */\nexport interface AuthRouterOptions {\n /** The authentication service handling the flows. */\n service: UserAuthService;\n /** The JWT helper used to guard `GET /auth/me`. */\n jwt: JWTUtils;\n /** Route prefix. Default `/auth`. */\n prefix?: string;\n /** When provided, OpenAPI paths are registered for Swagger/Redoc. */\n registry?: OpenAPIRegistry;\n /** Mount `POST /auth/activate` when provided. */\n activation?: ActivationService;\n /** Mount `POST /auth/password-reset/{request,confirm}` when provided. */\n passwordReset?: PasswordResetService;\n /**\n * Mount guarded `POST /auth/mfa/{enroll,confirm,disable}` when provided. The\n * enrolling account label defaults to the `email` claim (falls back to `sub`).\n */\n mfa?: MfaService;\n}\n\n/** Register the auth OpenAPI paths on `registry`. */\nfunction registerPaths(registry: OpenAPIRegistry, prefix: string): void {\n const json = (schema: unknown) => ({\n content: { \"application/json\": { schema: schema as never } },\n });\n registry.registerPath({\n method: \"post\",\n path: `${prefix}/signup`,\n summary: \"Register a new user\",\n request: { body: json(signupSchema) },\n responses: { 201: { description: \"Created\", ...json(authResponseSchema) } },\n });\n registry.registerPath({\n method: \"post\",\n path: `${prefix}/login`,\n summary: \"Authenticate and receive tokens\",\n request: { body: json(loginSchema) },\n responses: { 200: { description: \"OK\", ...json(authResponseSchema) } },\n });\n registry.registerPath({\n method: \"post\",\n path: `${prefix}/refresh`,\n summary: \"Exchange a refresh token for new tokens\",\n request: { body: json(refreshSchema) },\n responses: { 200: { description: \"OK\", ...json(authResponseSchema) } },\n });\n registry.registerPath({\n method: \"get\",\n path: `${prefix}/me`,\n summary: \"Current authenticated user\",\n security: [{ bearerAuth: [] }],\n responses: { 200: { description: \"OK\", ...json(userPublicSchema) } },\n });\n}\n\n/**\n * Build the auth router.\n *\n * @param options - Service, JWT helper, prefix and optional OpenAPI registry.\n * @returns An Express router exposing the auth endpoints.\n */\nexport function makeAuthRouter(options: AuthRouterOptions): Router {\n const { service, jwt, prefix = \"/auth\", registry } = options;\n if (registry) registerPaths(registry, prefix);\n\n const router = createRouter();\n\n router.post(`${prefix}/signup`, async (req, res) => {\n const result = await service.signup(signupSchema.parse(req.body));\n res.status(201).json(result);\n });\n\n router.post(`${prefix}/login`, async (req, res) => {\n res.json(await service.login(loginSchema.parse(req.body)));\n });\n\n router.post(`${prefix}/refresh`, async (req, res) => {\n const { refreshToken } = refreshSchema.parse(req.body);\n res.json(await service.refresh(refreshToken));\n });\n\n router.get(`${prefix}/me`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const claims = getAuth(req);\n if (!claims || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Not authenticated\" });\n }\n res.json(claims);\n });\n\n if (options.activation) {\n const activation = options.activation;\n router.post(`${prefix}/activate`, async (req, res) => {\n const { token } = activationSchema.parse(req.body);\n const userId = await activation.activate(token);\n res.json({ activated: true, userId });\n });\n }\n\n if (options.passwordReset) {\n const reset = options.passwordReset;\n // Always 202 — never reveal whether the email exists. `token` is returned\n // only in dev-style setups where the caller emails it themselves.\n router.post(`${prefix}/password-reset/request`, async (req, res) => {\n const { email } = passwordResetRequestSchema.parse(req.body);\n const token = await reset.request(email);\n res.status(202).json({ requested: true, ...(token ? { token } : {}) });\n });\n router.post(`${prefix}/password-reset/confirm`, async (req, res) => {\n const { token, password } = passwordResetConfirmSchema.parse(req.body);\n await reset.confirm(token, password);\n res.json({ reset: true });\n });\n }\n\n if (options.mfa) {\n const mfa = options.mfa;\n // Unguarded: completes the login challenge using the short-lived mfaToken.\n router.post(`${prefix}/mfa/challenge`, async (req, res) => {\n const { mfaToken, code } = mfaChallengeSchema.parse(req.body);\n res.json(await service.verifyMfaChallenge(mfaToken, code));\n });\n const requireUser = (req: Parameters<typeof getAuth>[0]): string => {\n const claims = getAuth(req);\n if (!claims || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Not authenticated\" });\n }\n return claims.sub;\n };\n router.post(`${prefix}/mfa/enroll`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const claims = getAuth(req);\n const userId = requireUser(req);\n const label = typeof claims?.email === \"string\" ? claims.email : userId;\n res.json(await mfa.enroll(userId, label));\n });\n router.post(`${prefix}/mfa/confirm`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const { code } = mfaCodeSchema.parse(req.body);\n await mfa.confirm(requireUser(req), code);\n res.json({ enabled: true });\n });\n router.post(`${prefix}/mfa/disable`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const { code } = mfaCodeSchema.parse(req.body);\n await mfa.disable(requireUser(req), code);\n res.json({ enabled: false });\n });\n }\n\n return router;\n}\n","/**\n * Optional server-rendered HTML pages for the bundled auth flows, mirroring the\n * FastAPI SDK's activation/reset templates.\n *\n * This SDK favors the JSON auth API + a decoupled frontend, but a link in an\n * email (activation, password reset) sometimes has to land on a *server* page —\n * there's no SPA to route to. These helpers render small, self-contained,\n * theme-aware HTML pages (no template engine, no external assets) for exactly\n * those landings.\n */\n\n/** Escape a string for safe interpolation into HTML text/attributes. */\nfunction esc(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\nconst STYLE = `\n :root { color-scheme: light dark; }\n body { font: 16px/1.5 system-ui, sans-serif; margin: 0; display: grid; min-height: 100vh; place-items: center; background: #f6f7f9; color: #1a1a1a; }\n @media (prefers-color-scheme: dark) { body { background: #16181d; color: #e8e8e8; } .card { background: #1f2229 !important; } input { background: #16181d !important; color: inherit !important; border-color: #3a3f4b !important; } }\n .card { background: #fff; max-width: 26rem; width: calc(100% - 3rem); padding: 2rem; border-radius: 14px; box-shadow: 0 6px 30px rgba(0,0,0,.08); text-align: center; }\n h1 { font-size: 1.4rem; margin: 0 0 .5rem; }\n p { margin: .25rem 0 1rem; opacity: .85; }\n .ico { font-size: 2.5rem; }\n a.btn, button.btn { display: inline-block; margin-top: .5rem; padding: .6rem 1.2rem; border-radius: 9px; border: 0; background: #4f46e5; color: #fff; text-decoration: none; font-weight: 600; cursor: pointer; }\n form { text-align: left; margin-top: 1rem; }\n label { display: block; font-size: .85rem; font-weight: 600; margin-bottom: .3rem; }\n input { width: 100%; box-sizing: border-box; padding: .6rem .7rem; border: 1px solid #d0d3d9; border-radius: 9px; font: inherit; }\n`;\n\nfunction page(title: string, body: string): string {\n return `<!doctype html>\n<html lang=\"pt-BR\">\n<head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>${esc(title)}</title><style>${STYLE}</style></head>\n<body><main class=\"card\">${body}</main></body>\n</html>`;\n}\n\n/** Options for {@link renderAuthResultPage}. */\nexport interface AuthResultPageOptions {\n /** `true` renders a success state, `false` an error state. */\n ok: boolean;\n /** Page + heading title. */\n title: string;\n /** Body message. */\n message: string;\n /** Optional call-to-action link. */\n cta?: { href: string; label: string };\n}\n\n/**\n * Render a success/error result page (e.g. \"account activated\", \"link\n * expired\").\n *\n * @param options - Success flag, title, message and an optional CTA.\n * @returns A complete HTML document.\n */\nexport function renderAuthResultPage(options: AuthResultPageOptions): string {\n const icon = options.ok ? \"✅\" : \"⚠️\";\n const cta = options.cta\n ? `<a class=\"btn\" href=\"${esc(options.cta.href)}\">${esc(options.cta.label)}</a>`\n : \"\";\n return page(\n options.title,\n `<div class=\"ico\">${icon}</div><h1>${esc(options.title)}</h1><p>${esc(options.message)}</p>${cta}`,\n );\n}\n\n/** Options for {@link renderPasswordResetFormPage}. */\nexport interface PasswordResetFormOptions {\n /** Form POST target. */\n action: string;\n /** The reset token, embedded as a hidden field. */\n token: string;\n /** Page + heading title. Default `\"Redefinir senha\"`. */\n title?: string;\n /** Name of the hidden token field. Default `\"token\"`. */\n tokenField?: string;\n /** Name of the password field. Default `\"password\"`. */\n passwordField?: string;\n /** Submit button label. Default `\"Redefinir senha\"`. */\n submitLabel?: string;\n}\n\n/**\n * Render a \"set a new password\" form that POSTs the token + new password to\n * `action`.\n *\n * @param options - Form action, token and field/label overrides.\n * @returns A complete HTML document.\n */\nexport function renderPasswordResetFormPage(options: PasswordResetFormOptions): string {\n const title = options.title ?? \"Redefinir senha\";\n const tokenField = options.tokenField ?? \"token\";\n const passwordField = options.passwordField ?? \"password\";\n const submitLabel = options.submitLabel ?? \"Redefinir senha\";\n return page(\n title,\n `<h1>${esc(title)}</h1>\n <form method=\"post\" action=\"${esc(options.action)}\">\n <input type=\"hidden\" name=\"${esc(tokenField)}\" value=\"${esc(options.token)}\">\n <label for=\"pw\">Nova senha</label>\n <input id=\"pw\" type=\"password\" name=\"${esc(passwordField)}\" required minlength=\"8\" autocomplete=\"new-password\">\n <button class=\"btn\" type=\"submit\" style=\"margin-top:1rem;width:100%\">${esc(submitLabel)}</button>\n </form>`,\n );\n}\n","/**\n * Express error handling, mirroring `api.handlers`.\n *\n * Produces the canonical SDK envelope `{ detail, code, details }` for every\n * failure path: {@link AppException} subclasses, Zod validation errors (→ 422),\n * unmatched routes (→ 404) and uncaught errors (→ 500). A {@link MessageCatalog}\n * localizes `detail` from the request `Accept-Language` header. Server errors\n * are logged with the {@link HTTP_500_MARKER} flag for sink routing.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport {\n HTTP_500_MARKER,\n JSONLogger,\n type LogLevel,\n runWithRequestContext,\n} from \"@/core\";\nimport { AppException, type ExceptionDetails } from \"@/exceptions/base\";\nimport { DEFAULT_LOCALE, type MessageCatalog } from \"@/exceptions/i18n\";\nimport type { ErrorRequestHandler, Express, RequestHandler } from \"express\";\nimport { ZodError } from \"zod\";\n\nconst logger = new JSONLogger(\"tempest_express_sdk.api.handlers\");\n\n/** Header carrying the per-request correlation id. */\nexport const REQUEST_ID_HEADER = \"X-Request-ID\";\n\n/**\n * Whitelist for inbound request IDs: printable ASCII, no whitespace or control\n * characters, so a spoofed header can't inject CRLF into log lines or the\n * echoed response header. Generous enough for UUIDs, ULIDs and trace IDs.\n */\nconst VALID_REQUEST_ID = /^[A-Za-z0-9._\\-:+/=]{1,128}$/;\n\n/**\n * Middleware that establishes a request id and binds the request context.\n *\n * Reuses an inbound `X-Request-ID` when present **and well-formed**, otherwise\n * generates one, sets it on the response, and runs the rest of the chain inside\n * {@link runWithRequestContext} so loggers and handlers can read it.\n *\n * @returns The configured middleware.\n */\nexport function requestIdMiddleware(): RequestHandler {\n return (req, res, next) => {\n const inbound = req.header(REQUEST_ID_HEADER);\n const requestId = inbound && VALID_REQUEST_ID.test(inbound) ? inbound : randomUUID();\n res.setHeader(REQUEST_ID_HEADER, requestId);\n runWithRequestContext({ requestId }, () => next());\n };\n}\n\n/** Options for {@link makeAppExceptionHandler}. */\nexport interface AppExceptionHandlerOptions {\n /** Catalog used to localize `detail`; `null` keeps the literal message. */\n catalog?: MessageCatalog | null;\n /** Locale used when `Accept-Language` is absent or unmatched. */\n defaultLocale?: string;\n /** Level used for 5xx `AppException` records (4xx always logs at `info`). */\n serverErrorLevel?: LogLevel;\n}\n\n/** Serialize an {@link AppException} to the envelope and write the response. */\nfunction writeAppException(\n res: Parameters<ErrorRequestHandler>[2],\n exc: AppException,\n detail: string,\n): void {\n for (const [name, value] of Object.entries(exc.headers)) res.setHeader(name, value);\n res.status(exc.statusCode).json({\n detail,\n code: exc.code,\n details: exc.details,\n });\n}\n\n/**\n * Build the error middleware for {@link AppException} subclasses.\n *\n * Zod errors are coerced into a 422 envelope (`code: \"VALIDATION_ERROR\"`) with\n * the field issues under `details.issues`. Anything else is passed to `next`.\n *\n * @param options - Localization and logging options.\n * @returns An Express error middleware.\n */\nexport function makeAppExceptionHandler(\n options: AppExceptionHandlerOptions = {},\n): ErrorRequestHandler {\n const {\n catalog = null,\n defaultLocale = DEFAULT_LOCALE,\n serverErrorLevel = \"info\",\n } = options;\n\n return (err, req, res, next) => {\n let exc: AppException;\n if (err instanceof AppException) {\n exc = err;\n } else if (err instanceof ZodError) {\n const details: ExceptionDetails = { issues: err.issues };\n exc = new AppException({\n message: \"Validation error\",\n code: \"VALIDATION_ERROR\",\n statusCode: 422,\n details,\n });\n } else {\n next(err);\n return;\n }\n\n const isServerError = exc.statusCode >= 500;\n logger.log(isServerError ? serverErrorLevel : \"info\", \"AppException handled\", {\n path: req.path,\n method: req.method,\n statusCode: exc.statusCode,\n code: exc.code,\n ...(isServerError ? { [HTTP_500_MARKER]: true, stack: exc.stack } : {}),\n });\n\n let detail = exc.message;\n if (catalog) {\n const locale = catalog.negotiate(req.header(\"accept-language\"), defaultLocale);\n const localized = catalog.resolve(\n exc.messageKey ?? exc.code,\n locale,\n exc.messageParams,\n );\n if (localized !== null) detail = localized;\n }\n writeAppException(res, exc, detail);\n };\n}\n\n/** Options for {@link makeUnhandledExceptionHandler}. */\nexport interface UnhandledExceptionHandlerOptions {\n /** Surface the stack under `details.stack` (development only). */\n includeStack?: boolean;\n /** Level used to log the failure. */\n logLevel?: LogLevel;\n}\n\n/**\n * Build the catch-all error middleware for non-{@link AppException} errors.\n *\n * Logs the failure (flagged with {@link HTTP_500_MARKER}) and returns the\n * canonical 500 envelope. With `includeStack` the stack is added to the body —\n * never enable in production.\n *\n * @param options - Stack-exposure and logging options.\n * @returns An Express error middleware.\n */\nexport function makeUnhandledExceptionHandler(\n options: UnhandledExceptionHandlerOptions = {},\n): ErrorRequestHandler {\n const { includeStack = false, logLevel = \"error\" } = options;\n\n return (err, req, res, _next) => {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.log(logLevel, \"Unhandled exception\", {\n path: req.path,\n method: req.method,\n [HTTP_500_MARKER]: true,\n stack: error.stack,\n });\n const details: ExceptionDetails = includeStack ? { stack: error.stack } : {};\n res.status(500).json({\n detail: \"Internal server error\",\n code: \"INTERNAL_SERVER_ERROR\",\n details,\n });\n };\n}\n\n/**\n * Build the fallback 404 handler for unmatched routes.\n *\n * @returns A request handler emitting the canonical 404 envelope.\n */\nexport function notFoundHandler(): RequestHandler {\n return (req, res) => {\n res.status(404).json({\n detail: `No route for ${req.method} ${req.path}`,\n code: \"NOT_FOUND\",\n details: {},\n });\n };\n}\n\n/** Options for {@link registerExceptionHandlers}. */\nexport interface RegisterExceptionHandlersOptions\n extends AppExceptionHandlerOptions,\n UnhandledExceptionHandlerOptions {\n /** Register the {@link notFoundHandler} for unmatched routes. Default `true`. */\n notFound?: boolean;\n}\n\n/**\n * Register the full error-handling stack on an Express app.\n *\n * Call this AFTER all routers are mounted. Order: 404 fallback (optional) →\n * {@link AppException}/Zod handler → catch-all 500 handler.\n *\n * @param app - The Express application.\n * @param options - Localization, logging and 404 options.\n */\nexport function registerExceptionHandlers(\n app: Express,\n options: RegisterExceptionHandlersOptions = {},\n): void {\n const { notFound = true, includeStack, logLevel, ...appOptions } = options;\n if (notFound) app.use(notFoundHandler());\n app.use(makeAppExceptionHandler(appOptions));\n app.use(\n makeUnhandledExceptionHandler({\n ...(includeStack !== undefined ? { includeStack } : {}),\n ...(logLevel !== undefined ? { logLevel } : {}),\n }),\n );\n}\n","/**\n * OpenAPI document generation from Zod schemas.\n *\n * Thin wrapper over `@asteasolutions/zod-to-openapi`. Register schemas and\n * paths on a {@link OpenAPIRegistry}, then call {@link generateOpenApiDocument}\n * to produce a spec that drives both Swagger UI and Redoc. Because every SDK\n * schema is built from the `.openapi()`-augmented `z`, descriptions, examples\n * and component names flow straight into the document.\n */\n\nimport {\n OpenAPIRegistry,\n OpenApiGeneratorV3,\n OpenApiGeneratorV31,\n} from \"@asteasolutions/zod-to-openapi\";\n\nexport { OpenAPIRegistry };\n\n/** The config object accepted by the generator's `generateDocument`. */\ntype OpenApiDocumentConfig = Parameters<OpenApiGeneratorV3[\"generateDocument\"]>[0];\n\n/** Minimal `info` block for the generated document. */\nexport interface OpenApiInfo {\n /** API title shown in the docs header. */\n title: string;\n /** API version string. */\n version: string;\n /** Optional long description (Markdown supported by the renderers). */\n description?: string;\n}\n\n/** Options for {@link generateOpenApiDocument}. */\nexport interface GenerateOpenApiOptions {\n /** The document `info` block. */\n info: OpenApiInfo;\n /** Server entries (`{ url, description }`). */\n servers?: Array<{ url: string; description?: string }>;\n /** Emit OpenAPI 3.1 instead of 3.0. Default `false` (3.0). */\n v31?: boolean;\n}\n\n/**\n * Create a fresh, empty {@link OpenAPIRegistry}.\n *\n * @returns A registry to register schemas and paths on.\n */\nexport function createOpenApiRegistry(): OpenAPIRegistry {\n return new OpenAPIRegistry();\n}\n\n/**\n * Generate an OpenAPI document from a populated registry.\n *\n * @param registry - The registry holding registered schemas and paths.\n * @param options - The `info` block, optional servers and version flag.\n * @returns The generated OpenAPI document (plain object, JSON-serializable).\n */\nexport function generateOpenApiDocument(\n registry: OpenAPIRegistry,\n options: GenerateOpenApiOptions,\n): Record<string, unknown> {\n const config: OpenApiDocumentConfig = {\n openapi: options.v31 ? \"3.1.0\" : \"3.0.0\",\n info: {\n title: options.info.title,\n version: options.info.version,\n ...(options.info.description !== undefined\n ? { description: options.info.description }\n : {}),\n },\n ...(options.servers !== undefined ? { servers: options.servers } : {}),\n };\n const Generator = options.v31 ? OpenApiGeneratorV31 : OpenApiGeneratorV3;\n const document = new Generator(registry.definitions).generateDocument(config);\n return document as unknown as Record<string, unknown>;\n}\n","/**\n * Native Swagger UI and Redoc mounting from a generated OpenAPI document.\n *\n * Swagger UI is served fully self-contained: its static assets ship with the\n * `swagger-ui-dist` dependency and are mounted locally (no CDN), with a small\n * inline initializer pointing at the spec endpoint. Redoc is served as a single\n * HTML page that loads the Redoc standalone bundle from a CDN (the renderer is\n * ~1 MB and intentionally not vendored); override {@link RedocOptions.scriptUrl}\n * to self-host it.\n */\n\nimport express, { type Express, type RequestHandler } from \"express\";\nimport { getAbsoluteFSPath } from \"swagger-ui-dist\";\n\n/** A JSON-serializable OpenAPI document. */\nexport type OpenApiDocument = Record<string, unknown>;\n\n/**\n * Mount the OpenAPI document as JSON at `path`.\n *\n * @param app - The Express application.\n * @param path - Route to serve the document at (e.g. `/openapi.json`).\n * @param document - The generated OpenAPI document.\n */\nexport function mountOpenApiJson(\n app: Express,\n path: string,\n document: OpenApiDocument,\n): void {\n app.get(path, (_req, res) => {\n res.json(document);\n });\n}\n\n/**\n * Build the Swagger UI bootstrap HTML pointing at `specUrl`.\n *\n * Asset URLs are **absolute** (`${assetsBase}/…`), not relative. A relative\n * `./assets/…` resolves against the request path, so visiting `/docs` (no\n * trailing slash) would fetch `/assets/…` — a 404 that leaves the UI unstyled\n * and non-functional. The absolute base resolves correctly at both `/docs` and\n * `/docs/`.\n */\nfunction swaggerHtml(specUrl: string, title: string, assetsBase: string): string {\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${title}</title>\n <link rel=\"stylesheet\" href=\"${assetsBase}/swagger-ui.css\" />\n </head>\n <body>\n <div id=\"swagger-ui\"></div>\n <script src=\"${assetsBase}/swagger-ui-bundle.js\"></script>\n <script src=\"${assetsBase}/swagger-ui-standalone-preset.js\"></script>\n <script>\n window.ui = SwaggerUIBundle({\n url: ${JSON.stringify(specUrl)},\n dom_id: \"#swagger-ui\",\n presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],\n layout: \"StandaloneLayout\",\n });\n </script>\n </body>\n</html>`;\n}\n\n/** Options for {@link mountSwaggerUi}. */\nexport interface SwaggerOptions {\n /** Page title. Default `\"API docs\"`. */\n title?: string;\n}\n\n/**\n * Mount Swagger UI at `path`, reading the spec from `specUrl`.\n *\n * Static assets are served from `${path}/assets` so the page is fully offline.\n *\n * @param app - The Express application.\n * @param path - Mount path for the UI (e.g. `/docs`).\n * @param specUrl - URL the UI fetches the OpenAPI document from.\n * @param options - Page options.\n */\nexport function mountSwaggerUi(\n app: Express,\n path: string,\n specUrl: string,\n options: SwaggerOptions = {},\n): void {\n const title = options.title ?? \"API docs\";\n const assetsPath = `${path.replace(/\\/$/, \"\")}/assets`;\n app.use(assetsPath, express.static(getAbsoluteFSPath()));\n const handler: RequestHandler = (_req, res) => {\n res.type(\"html\").send(swaggerHtml(specUrl, title, assetsPath));\n };\n app.get(path, handler);\n}\n\n/** Options for {@link mountRedoc}. */\nexport interface RedocOptions {\n /** Page title. Default `\"API reference\"`. */\n title?: string;\n /** URL of the Redoc standalone bundle. Defaults to the jsDelivr CDN. */\n scriptUrl?: string;\n}\n\n/** Build the Redoc HTML pointing at `specUrl`. */\nfunction redocHtml(specUrl: string, title: string, scriptUrl: string): string {\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${title}</title>\n <style>body { margin: 0; padding: 0; }</style>\n </head>\n <body>\n <redoc spec-url=${JSON.stringify(specUrl)}></redoc>\n <script src=${JSON.stringify(scriptUrl)}></script>\n </body>\n</html>`;\n}\n\n/**\n * Mount Redoc at `path`, reading the spec from `specUrl`.\n *\n * @param app - The Express application.\n * @param path - Mount path for Redoc (e.g. `/redoc`).\n * @param specUrl - URL Redoc fetches the OpenAPI document from.\n * @param options - Page and bundle options.\n */\nexport function mountRedoc(\n app: Express,\n path: string,\n specUrl: string,\n options: RedocOptions = {},\n): void {\n const title = options.title ?? \"API reference\";\n const scriptUrl =\n options.scriptUrl ??\n \"https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js\";\n app.get(path, (_req, res) => {\n res.type(\"html\").send(redocHtml(specUrl, title, scriptUrl));\n });\n}\n","/**\n * Health-check router, mirroring `api.routers.health`.\n *\n * A meta endpoint mounted at the root prefix (not under `/api`). Returns a\n * small JSON status payload and runs any registered async checks, surfacing\n * their pass/fail under `checks` and degrading the HTTP status to 503 when any\n * check fails.\n */\n\nimport { type Router, Router as createRouter } from \"express\";\n\n/** A named async health probe returning `true` when healthy. */\nexport interface HealthCheck {\n /** Probe name, surfaced under `checks`. */\n name: string;\n /** The probe; resolves `true` when the dependency is healthy. */\n check: () => Promise<boolean> | boolean;\n}\n\n/** Options for {@link makeHealthRouter}. */\nexport interface HealthRouterOptions {\n /** Route path within the router. Default `/health`. */\n path?: string;\n /** Optional dependency probes (e.g. database, cache). */\n checks?: HealthCheck[];\n}\n\n/**\n * Build a health-check router.\n *\n * @param options - Path and dependency probes.\n * @returns An Express router exposing the health endpoint.\n */\nexport function makeHealthRouter(options: HealthRouterOptions = {}): Router {\n const path = options.path ?? \"/health\";\n const checks = options.checks ?? [];\n const router = createRouter();\n\n router.get(path, async (_req, res) => {\n const results: Record<string, boolean> = {};\n let healthy = true;\n for (const probe of checks) {\n let ok = false;\n try {\n ok = await probe.check();\n } catch {\n ok = false;\n }\n results[probe.name] = ok;\n if (!ok) healthy = false;\n }\n res.status(healthy ? 200 : 503).json({\n status: healthy ? \"ok\" : \"degraded\",\n checks: results,\n });\n });\n\n return router;\n}\n","/**\n * Prometheus `/metrics` router, mirroring `api.routers.metrics`.\n *\n * Serves {@link MetricsUtils.toPrometheus} as `text/plain`. Optionally includes\n * GPU metrics (via `nvidia-smi`) and can be guarded so the endpoint stays on the\n * internal network / behind auth.\n */\n\nimport { MetricsUtils } from \"@/utils/metrics\";\nimport { type RequestHandler, type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link makeMetricsRouter}. */\nexport interface MetricsRouterOptions {\n /** Route path. Default `/metrics`. */\n path?: string;\n /** Include GPU metrics via `nvidia-smi` (adds a subprocess call). Default `false`. */\n includeGpu?: boolean;\n /** Optional guard middleware (e.g. internal-network or token check). */\n guard?: RequestHandler;\n}\n\n/**\n * Build the Prometheus metrics router.\n *\n * @param options - Path, GPU toggle and optional guard.\n * @returns An Express router exposing the metrics endpoint.\n */\nexport function makeMetricsRouter(options: MetricsRouterOptions = {}): Router {\n const path = options.path ?? \"/metrics\";\n const router = createRouter();\n if (options.guard) router.use(path, options.guard);\n\n router.get(path, async (_req, res) => {\n const gpus = options.includeGpu ? await MetricsUtils.gpus() : [];\n res.type(\"text/plain\").send(MetricsUtils.toPrometheus(MetricsUtils.system(), gpus));\n });\n\n return router;\n}\n","/**\n * Application factory and server runner, mirroring `api.app` + `api.server`.\n *\n * {@link createApp} wires the conventional middleware stack (JSON body parsing,\n * request-id propagation, optional CORS), mounts the health endpoint, lets the\n * caller register routers and OpenAPI paths via a `configure` hook, mounts\n * native Swagger UI + Redoc, then registers the error-handling stack last.\n * {@link runServer} starts listening and logs the bound address.\n */\n\nimport type { Server } from \"node:http\";\nimport {\n type OpenApiDocument,\n type RedocOptions,\n type SwaggerOptions,\n mountOpenApiJson,\n mountRedoc,\n mountSwaggerUi,\n} from \"@/api/docs\";\nimport {\n type RegisterExceptionHandlersOptions,\n registerExceptionHandlers,\n requestIdMiddleware,\n} from \"@/api/handlers\";\nimport {\n type HealthCheck,\n type HealthRouterOptions,\n makeHealthRouter,\n} from \"@/api/health\";\nimport {\n type GenerateOpenApiOptions,\n type OpenAPIRegistry,\n generateOpenApiDocument,\n} from \"@/api/openapi\";\nimport { JSONLogger } from \"@/core\";\nimport type { MessageCatalog } from \"@/exceptions/i18n\";\nimport express, { type Express, type RequestHandler } from \"express\";\n\nconst logger = new JSONLogger(\"tempest_express_sdk.api.server\");\n\n/** OpenAPI documentation configuration for {@link createApp}. */\nexport interface CreateAppOpenApi extends GenerateOpenApiOptions {\n /** Registry holding the registered schemas and paths. */\n registry: OpenAPIRegistry;\n /** Route serving the spec JSON. Default `/openapi.json`. */\n jsonPath?: string;\n /** Swagger UI mount path, or `false` to disable. Default `/docs`. */\n swaggerPath?: string | false;\n /** Redoc mount path, or `false` to disable. Default `/redoc`. */\n redocPath?: string | false;\n /** Extra Swagger UI options. */\n swagger?: SwaggerOptions;\n /** Extra Redoc options. */\n redoc?: RedocOptions;\n}\n\n/** Options for {@link createApp}. */\nexport interface CreateAppOptions {\n /** Allowed CORS origins. `\"*\"` or a list; omit/`false` to disable CORS. */\n corsOrigins?: string | string[] | false;\n /** Health endpoint options, or `false` to omit it. Default mounts `/health`. */\n health?: HealthRouterOptions | false;\n /** Hook to mount routers and register OpenAPI paths before the error stack. */\n configure?: (app: Express) => void | Promise<void>;\n /** OpenAPI docs configuration; omit to skip Swagger/Redoc. */\n openapi?: CreateAppOpenApi;\n /** Message catalog for localized error responses. */\n catalog?: MessageCatalog;\n /** Error-handling options forwarded to {@link registerExceptionHandlers}. */\n errorHandling?: Omit<RegisterExceptionHandlersOptions, \"catalog\">;\n /** JSON body size limit (e.g. `\"1mb\"`). Default `\"100kb\"`. */\n jsonLimit?: string;\n}\n\n/** Minimal CORS middleware (no external dependency). */\nfunction corsMiddleware(origins: string | string[]): RequestHandler {\n const allowAll = origins === \"*\";\n const allowList = new Set(Array.isArray(origins) ? origins : [origins]);\n return (req, res, next) => {\n const origin = req.header(\"origin\");\n if (allowAll) {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n } else if (origin && allowList.has(origin)) {\n res.setHeader(\"Access-Control-Allow-Origin\", origin);\n res.setHeader(\"Vary\", \"Origin\");\n }\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET,POST,PUT,PATCH,DELETE,OPTIONS\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type,Authorization,X-Request-ID\",\n );\n if (req.method === \"OPTIONS\") {\n res.sendStatus(204);\n return;\n }\n next();\n };\n}\n\n/**\n * Build a fully wired Express application.\n *\n * @param options - Middleware, health, OpenAPI docs and error options.\n * @returns The configured Express app, ready to {@link runServer}.\n */\nexport async function createApp(options: CreateAppOptions = {}): Promise<Express> {\n const app = express();\n app.use(express.json({ limit: options.jsonLimit ?? \"100kb\" }));\n app.use(express.urlencoded({ extended: true }));\n app.use(requestIdMiddleware());\n\n if (options.corsOrigins) {\n app.use(corsMiddleware(options.corsOrigins));\n }\n\n if (options.health !== false) {\n app.use(makeHealthRouter(options.health ?? {}));\n }\n\n if (options.configure) await options.configure(app);\n\n if (options.openapi) {\n const { registry, jsonPath, swaggerPath, redocPath, swagger, redoc, ...genOptions } =\n options.openapi;\n const document = generateOpenApiDocument(registry, genOptions) as OpenApiDocument;\n const specPath = jsonPath ?? \"/openapi.json\";\n mountOpenApiJson(app, specPath, document);\n if (swaggerPath !== false) {\n mountSwaggerUi(app, swaggerPath ?? \"/docs\", specPath, swagger ?? {});\n }\n if (redocPath !== false) {\n mountRedoc(app, redocPath ?? \"/redoc\", specPath, redoc ?? {});\n }\n }\n\n registerExceptionHandlers(app, {\n ...options.errorHandling,\n ...(options.catalog !== undefined ? { catalog: options.catalog } : {}),\n });\n\n return app;\n}\n\n/** Options for {@link runServer}. */\nexport interface RunServerOptions {\n /** Bind host. Default `127.0.0.1`. */\n host?: string;\n /** Bind port. Default `8000`. */\n port?: number;\n}\n\n/**\n * Start listening and log the bound address.\n *\n * @param app - The Express application from {@link createApp}.\n * @param options - Host and port.\n * @returns A promise resolving to the live HTTP server once listening.\n */\nexport function runServer(app: Express, options: RunServerOptions = {}): Promise<Server> {\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 8000;\n return new Promise((resolve) => {\n const server = app.listen(port, host, () => {\n logger.info(\"Server listening\", { host, port });\n resolve(server);\n });\n });\n}\n\n/** Re-export so a `HealthCheck` is reachable from the server module too. */\nexport type { HealthCheck };\n","/**\n * `bodySizeLimitMiddleware` — reject oversize request bodies early, mirroring\n * `api.middlewares.body_size`.\n *\n * Without an upstream limit a client can stream gigabytes before body parsers\n * reject it — wasting bandwidth and RAM. This middleware short-circuits the\n * moment `Content-Length` exceeds the cap, and defensively tracks streamed\n * bytes for chunked/unknown-length uploads.\n */\n\nimport type { RequestHandler } from \"express\";\n\n/** Options for {@link bodySizeLimitMiddleware}. */\nexport interface BodySizeLimitOptions {\n /** Hard cap on the request body in bytes. */\n maxBytes: number;\n /** Path prefixes that bypass the check (e.g. an upload endpoint). */\n excludePaths?: string[];\n}\n\n/**\n * Build a middleware enforcing `maxBytes` per request. A `Content-Length` over\n * the cap is rejected immediately with `413`; chunked bodies are aborted once\n * the streamed size crosses the cap.\n *\n * @param options - The cap and path exclusions.\n * @returns An Express middleware.\n */\nexport function bodySizeLimitMiddleware(options: BodySizeLimitOptions): RequestHandler {\n const { maxBytes } = options;\n const excludePaths = options.excludePaths ?? [];\n\n const reject = (res: Parameters<RequestHandler>[1]): void => {\n res.status(413).json({\n detail: \"Request body too large.\",\n code: \"REQUEST_BODY_TOO_LARGE\",\n details: { maxBytes },\n });\n };\n\n return (req, res, next) => {\n if (maxBytes <= 0 || excludePaths.some((prefix) => req.path.startsWith(prefix))) {\n next();\n return;\n }\n\n // Step 1 — fast path on Content-Length.\n const declared = Number.parseInt(req.header(\"content-length\") ?? \"\", 10);\n if (Number.isFinite(declared) && declared > maxBytes) {\n reject(res);\n return;\n }\n\n // Step 2 — defensive streaming check for chunked/unknown-length bodies.\n // A `data` listener runs alongside any downstream body parser (Node fans\n // each chunk out to every listener), so counting here doesn't steal the\n // body. On overflow we answer 413 and destroy the request to abort.\n let seen = 0;\n let aborted = false;\n const onData = (chunk: Buffer | string): void => {\n if (aborted) return;\n seen += Buffer.byteLength(chunk);\n if (seen > maxBytes) {\n aborted = true;\n req.removeListener(\"data\", onData);\n if (!res.headersSent) reject(res);\n req.destroy();\n }\n };\n req.on(\"data\", onData);\n req.on(\"end\", () => req.removeListener(\"data\", onData));\n next();\n };\n}\n","/**\n * `csrfMiddleware` — double-submit cookie protection for state changes,\n * mirroring `api.middlewares.csrf`.\n *\n * CSRF lets a third-party site trigger authenticated mutating requests through\n * a victim's browser, because cookies ride along automatically. The\n * double-submit defense: issue a random `csrf_token` cookie, have the frontend\n * echo it in an `X-CSRF-Token` header, and reject mutating requests where the\n * header is missing or does not match the cookie. A cross-site page can't read\n * the cookie (same-origin policy), so it can't forge the header.\n *\n * JWT bearer auth (`Authorization: Bearer …`) is **not** subject to CSRF (the\n * browser doesn't auto-attach it), so `/api/` routes are typically excluded.\n */\n\nimport { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport type { Request, RequestHandler } from \"express\";\n\n/** Default cookie holding the CSRF token. */\nexport const CSRF_COOKIE_NAME = \"csrf_token\";\n/** Default header the client echoes the cookie value into. */\nexport const CSRF_HEADER_NAME = \"X-CSRF-Token\";\n\nconst UNSAFE_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\n/**\n * Generate a URL-safe random CSRF token.\n *\n * @param nBytes - Entropy bytes (32 → a 43-char token). Default `32`.\n * @returns A URL-safe base64 token without padding.\n */\nexport function generateCsrfToken(nBytes = 32): string {\n return randomBytes(nBytes).toString(\"base64url\");\n}\n\nfunction readCookie(req: Request, name: string): string | undefined {\n // Prefer a cookie-parser-populated `req.cookies`, else parse the header.\n const parsed = (req as Request & { cookies?: Record<string, string> }).cookies;\n if (parsed && typeof parsed[name] === \"string\") return parsed[name];\n const header = req.header(\"cookie\");\n if (!header) return undefined;\n for (const part of header.split(\";\")) {\n const idx = part.indexOf(\"=\");\n if (idx === -1) continue;\n if (part.slice(0, idx).trim() === name) return part.slice(idx + 1).trim();\n }\n return undefined;\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const bufA = Buffer.from(a);\n const bufB = Buffer.from(b);\n if (bufA.length !== bufB.length) return false;\n return timingSafeEqual(bufA, bufB);\n}\n\n/** Options for {@link csrfMiddleware}. */\nexport interface CsrfOptions {\n /** Name of the CSRF cookie. Default `csrf_token`. */\n cookieName?: string;\n /** Name of the CSRF header. Default `X-CSRF-Token`. */\n headerName?: string;\n /** Path prefixes that bypass the check (e.g. `[\"/api/\", \"/webhooks/\"]`). */\n excludePaths?: string[];\n}\n\n/**\n * Build a double-submit CSRF middleware. Safe methods (GET/HEAD/OPTIONS) pass;\n * unsafe methods must carry a matching cookie + header or get `403`.\n *\n * @param options - Cookie/header names and excluded path prefixes.\n * @returns An Express middleware.\n */\nexport function csrfMiddleware(options: CsrfOptions = {}): RequestHandler {\n const cookieName = options.cookieName ?? CSRF_COOKIE_NAME;\n const headerName = options.headerName ?? CSRF_HEADER_NAME;\n const excludePaths = options.excludePaths ?? [];\n\n const reject = (res: Parameters<RequestHandler>[1], message: string): void => {\n res.status(403).json({ detail: message, code: \"CSRF_FAILED\", details: {} });\n };\n\n return (req, res, next) => {\n if (!UNSAFE_METHODS.has(req.method)) {\n next();\n return;\n }\n if (excludePaths.some((prefix) => req.path.startsWith(prefix))) {\n next();\n return;\n }\n const cookieToken = readCookie(req, cookieName);\n const headerToken = req.header(headerName);\n if (!cookieToken || !headerToken) {\n reject(res, \"CSRF token missing.\");\n return;\n }\n if (!safeEqual(cookieToken, headerToken)) {\n reject(res, \"CSRF token mismatch.\");\n return;\n }\n next();\n };\n}\n","/**\n * `GracefulShutdown` — track in-flight requests and drain on shutdown,\n * mirroring `api.middlewares.graceful`.\n *\n * Wire {@link GracefulShutdown.middleware} into the app, then on `SIGTERM`\n * call {@link GracefulShutdown.beginDrain} (new non-exempt requests get `503`)\n * and `await` {@link GracefulShutdown.waitDrained} before closing the server —\n * so a rolling deploy never cuts an in-flight request mid-response.\n */\n\nimport type { RequestHandler } from \"express\";\n\n/** Options for {@link GracefulShutdown}. */\nexport interface GracefulShutdownOptions {\n /** Max seconds to wait for in-flight requests to finish. Default `30`. */\n drainTimeoutSeconds?: number;\n /** `Retry-After` seconds on the 503 served while draining. Default `5`. */\n retryAfterSeconds?: number;\n /** Exact paths that keep being served while draining. */\n exemptPaths?: string[];\n}\n\n/** In-flight request tracker with a drain gate. */\nexport class GracefulShutdown {\n private readonly drainTimeoutSeconds: number;\n private readonly retryAfterSeconds: number;\n private readonly exempt: Set<string>;\n private inFlightCount = 0;\n private draining = false;\n private idleResolvers: Array<() => void> = [];\n\n constructor(options: GracefulShutdownOptions = {}) {\n this.drainTimeoutSeconds = options.drainTimeoutSeconds ?? 30;\n this.retryAfterSeconds = options.retryAfterSeconds ?? 5;\n this.exempt = new Set(options.exemptPaths ?? []);\n }\n\n /** Number of requests currently being served. */\n get inFlight(): number {\n return this.inFlightCount;\n }\n\n /** Whether draining has begun. */\n get isDraining(): boolean {\n return this.draining;\n }\n\n /** The Express middleware: counts in-flight requests, 503s while draining. */\n middleware(): RequestHandler {\n return (req, res, next) => {\n if (this.draining && !this.exempt.has(req.path)) {\n res.setHeader(\"Retry-After\", String(this.retryAfterSeconds));\n res.setHeader(\"Connection\", \"close\");\n res.status(503).json({\n detail: \"Server is shutting down.\",\n code: \"SERVICE_UNAVAILABLE\",\n details: {},\n });\n return;\n }\n this.inFlightCount += 1;\n // `finish` and `close` can both fire for one response — settle once.\n let settled = false;\n const settle = (): void => {\n if (settled) return;\n settled = true;\n this.release();\n };\n res.on(\"finish\", settle);\n res.on(\"close\", settle);\n next();\n };\n }\n\n private release(): void {\n this.inFlightCount -= 1;\n if (this.inFlightCount === 0) {\n const resolvers = this.idleResolvers;\n this.idleResolvers = [];\n for (const resolve of resolvers) resolve();\n }\n }\n\n /** Flip into draining mode (idempotent). New non-exempt requests get 503. */\n beginDrain(): void {\n this.draining = true;\n }\n\n /**\n * Wait until in-flight requests finish or the drain timeout elapses.\n *\n * @returns `true` if everything drained in time, `false` on timeout.\n */\n waitDrained(): Promise<boolean> {\n if (this.inFlightCount === 0) return Promise.resolve(true);\n return new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => {\n this.idleResolvers = this.idleResolvers.filter((r) => r !== onIdle);\n resolve(false);\n }, this.drainTimeoutSeconds * 1000);\n const onIdle = (): void => {\n clearTimeout(timer);\n resolve(true);\n };\n this.idleResolvers.push(onIdle);\n });\n }\n}\n","/**\n * `idempotencyMiddleware` — cache responses by `Idempotency-Key`, mirroring\n * `api.middlewares.idempotency`.\n *\n * A client retrying a mutating request with the same `Idempotency-Key` gets the\n * original response back instead of a duplicate side effect (a second charge, a\n * second order). Only mutating verbs are eligible; the key is scoped per\n * `(method, path, key)` so the same key on different endpoints never collides.\n */\n\nimport type { RequestHandler, Response } from \"express\";\n\n/** The canonical header (Stripe / AWS / GitHub all use it). */\nexport const IDEMPOTENCY_HEADER = \"Idempotency-Key\";\n\nconst MUTATING_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\n/** A serialized response stored under an idempotency key. */\nexport interface CachedResponse {\n statusCode: number;\n headers: Array<[string, string]>;\n body: string;\n contentType: string | null;\n}\n\n/** Backend every idempotency cache implements. */\nexport interface IdempotencyStore {\n /** Return the cached response for `key`, or `null` when missing/expired. */\n get(key: string): Promise<CachedResponse | null>;\n /** Store `response` under `key` with a TTL. */\n set(key: string, response: CachedResponse, ttlSeconds: number): Promise<void>;\n}\n\n/** In-process {@link IdempotencyStore} with lazy TTL eviction (single-replica). */\nexport class MemoryIdempotencyStore implements IdempotencyStore {\n private readonly store = new Map<\n string,\n { expiresAt: number; response: CachedResponse }\n >();\n\n async get(key: string): Promise<CachedResponse | null> {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt < Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry.response;\n }\n\n async set(key: string, response: CachedResponse, ttlSeconds: number): Promise<void> {\n this.store.set(key, { expiresAt: Date.now() + ttlSeconds * 1000, response });\n }\n}\n\n/** Minimal async Redis surface used by {@link RedisIdempotencyStore}. */\nexport interface IdempotencyRedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options: { EX: number }): Promise<unknown>;\n}\n\n/** {@link IdempotencyStore} backed by an async Redis client (multi-replica). */\nexport class RedisIdempotencyStore implements IdempotencyStore {\n private readonly prefix: string;\n\n constructor(\n private readonly client: IdempotencyRedisLike,\n options: { prefix?: string } = {},\n ) {\n this.prefix = options.prefix ?? \"idem:\";\n }\n\n async get(key: string): Promise<CachedResponse | null> {\n const raw = await this.client.get(this.prefix + key);\n return raw === null ? null : (JSON.parse(raw) as CachedResponse);\n }\n\n async set(key: string, response: CachedResponse, ttlSeconds: number): Promise<void> {\n await this.client.set(this.prefix + key, JSON.stringify(response), {\n EX: ttlSeconds,\n });\n }\n}\n\n/** Options for {@link idempotencyMiddleware}. */\nexport interface IdempotencyOptions {\n /** The cache backend (memory or Redis). */\n store: IdempotencyStore;\n /** Time-to-live for a cached response, in seconds. Default 24h. */\n ttlSeconds?: number;\n /** Header carrying the key. Default `Idempotency-Key`. */\n headerName?: string;\n}\n\n/**\n * Build an idempotency middleware. On a cache hit it replays the stored\n * response; on a miss it captures the response, stores it, and forwards.\n *\n * @param options - Store, TTL and header name.\n * @returns An Express middleware.\n */\nexport function idempotencyMiddleware(options: IdempotencyOptions): RequestHandler {\n const { store } = options;\n const ttlSeconds = options.ttlSeconds ?? 24 * 3600;\n const headerName = options.headerName ?? IDEMPOTENCY_HEADER;\n\n return (req, res, next) => {\n if (!MUTATING_METHODS.has(req.method)) {\n next();\n return;\n }\n const rawKey = req.header(headerName);\n if (!rawKey) {\n next();\n return;\n }\n const scoped = `${req.method}:${req.path}:${rawKey}`;\n\n store\n .get(scoped)\n .then((cached) => {\n if (cached) {\n for (const [name, value] of cached.headers) res.setHeader(name, value);\n res.setHeader(\"Idempotent-Replayed\", \"true\");\n if (cached.contentType) res.type(cached.contentType);\n res.status(cached.statusCode).send(cached.body);\n return;\n }\n captureAndForward(res, scoped, store, ttlSeconds);\n next();\n })\n .catch(next);\n };\n}\n\n/** Wrap `res.send` to capture the first body, then persist on `finish`. */\nfunction captureAndForward(\n res: Response,\n key: string,\n store: IdempotencyStore,\n ttlSeconds: number,\n): void {\n const originalSend = res.send.bind(res);\n let capturedBody = \"\";\n res.send = ((body?: unknown): Response => {\n if (typeof body === \"string\") capturedBody = body;\n else if (body !== undefined) capturedBody = JSON.stringify(body);\n return originalSend(body as never);\n }) as Response[\"send\"];\n\n res.on(\"finish\", () => {\n // Only cache successful, deterministic outcomes (2xx). Errors should be\n // retryable, not frozen.\n if (res.statusCode < 200 || res.statusCode >= 300) return;\n const contentType = res.getHeader(\"content-type\");\n void store\n .set(\n key,\n {\n statusCode: res.statusCode,\n headers: [],\n body: capturedBody,\n contentType: typeof contentType === \"string\" ? contentType : null,\n },\n ttlSeconds,\n )\n .catch(() => {\n // Best-effort cache write; a store outage must not fail the response.\n });\n });\n}\n","/**\n * `HttpMetrics` + `prometheusMiddleware` — per-request Prometheus metrics,\n * mirroring the FastAPI `PrometheusMiddleware`.\n *\n * Complements the system `/metrics` router (`MetricsUtils.toPrometheus`, which\n * reports process/host gauges) with **per-request** instrumentation: a request\n * counter labelled by method/path/status and a latency histogram. Everything is\n * in-process and dependency-free; expose it with {@link HttpMetrics.render}.\n */\n\nimport type { RequestHandler } from \"express\";\n\n/** Default histogram buckets in seconds (Prometheus client defaults). */\nconst DEFAULT_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,\n] as const;\n\ninterface HistogramState {\n bucketCounts: number[];\n sum: number;\n count: number;\n}\n\n/**\n * In-process HTTP request metrics: a labelled request counter and a latency\n * histogram, rendered as Prometheus text.\n */\nexport class HttpMetrics {\n private readonly buckets: number[];\n /** `method|status` → count. */\n private readonly requestTotals = new Map<string, number>();\n /** `method|route` → histogram. */\n private readonly durations = new Map<string, HistogramState>();\n\n constructor(options: { buckets?: number[] } = {}) {\n this.buckets = [...(options.buckets ?? DEFAULT_BUCKETS)].sort((a, b) => a - b);\n }\n\n /**\n * Record one completed request.\n *\n * @param method - HTTP method.\n * @param route - The route pattern (or path) — keep cardinality bounded.\n * @param status - Response status code.\n * @param durationSeconds - Wall-clock request duration in seconds.\n */\n observe(method: string, route: string, status: number, durationSeconds: number): void {\n const totalKey = `${method}|${status}`;\n this.requestTotals.set(totalKey, (this.requestTotals.get(totalKey) ?? 0) + 1);\n\n const durKey = `${method}|${route}`;\n let hist = this.durations.get(durKey);\n if (!hist) {\n hist = { bucketCounts: new Array(this.buckets.length).fill(0), sum: 0, count: 0 };\n this.durations.set(durKey, hist);\n }\n hist.sum += durationSeconds;\n hist.count += 1;\n for (let i = 0; i < this.buckets.length; i += 1) {\n const upper = this.buckets[i];\n if (upper !== undefined && durationSeconds <= upper) {\n hist.bucketCounts[i] = (hist.bucketCounts[i] ?? 0) + 1;\n }\n }\n }\n\n /** Render the collected metrics as Prometheus exposition text. */\n render(): string {\n const lines: string[] = [];\n lines.push(\"# HELP http_requests_total Total HTTP requests.\");\n lines.push(\"# TYPE http_requests_total counter\");\n for (const [key, value] of this.requestTotals) {\n const [method = \"\", status = \"\"] = key.split(\"|\");\n lines.push(\n `http_requests_total{method=\"${esc(method)}\",status=\"${esc(status)}\"} ${value}`,\n );\n }\n\n lines.push(\"# HELP http_request_duration_seconds HTTP request latency.\");\n lines.push(\"# TYPE http_request_duration_seconds histogram\");\n for (const [key, hist] of this.durations) {\n const [method = \"\", route = \"\"] = key.split(\"|\");\n const labels = `method=\"${esc(method)}\",route=\"${esc(route)}\"`;\n // `bucketCounts[i]` is already the cumulative count of observations\n // <= buckets[i], which is exactly the `le` semantics Prometheus wants.\n for (let i = 0; i < this.buckets.length; i += 1) {\n lines.push(\n `http_request_duration_seconds_bucket{${labels},le=\"${this.buckets[i]}\"} ${hist.bucketCounts[i] ?? 0}`,\n );\n }\n lines.push(\n `http_request_duration_seconds_bucket{${labels},le=\"+Inf\"} ${hist.count}`,\n );\n lines.push(`http_request_duration_seconds_sum{${labels}} ${hist.sum}`);\n lines.push(`http_request_duration_seconds_count{${labels}} ${hist.count}`);\n }\n return `${lines.join(\"\\n\")}\\n`;\n }\n\n /**\n * Build the middleware that records each request into this collector.\n *\n * @param options - Optional exempt paths (e.g. the metrics route itself).\n * @returns An Express middleware.\n */\n middleware(options: { exemptPaths?: string[] } = {}): RequestHandler {\n const exempt = new Set(options.exemptPaths ?? []);\n return (req, res, next) => {\n if (exempt.has(req.path)) {\n next();\n return;\n }\n const start = process.hrtime.bigint();\n res.on(\"finish\", () => {\n const durationSeconds = Number(process.hrtime.bigint() - start) / 1e9;\n // `req.route?.path` is the low-cardinality pattern; fall back to path.\n const route = (req.route as { path?: string } | undefined)?.path ?? req.path;\n this.observe(req.method, route, res.statusCode, durationSeconds);\n });\n next();\n };\n }\n}\n\nfunction esc(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n}\n\n/**\n * Convenience factory: a fresh {@link HttpMetrics} plus its middleware.\n *\n * @param options - Histogram buckets and exempt paths.\n * @returns The collector and its middleware.\n */\nexport function prometheusMiddleware(\n options: { buckets?: number[]; exemptPaths?: string[] } = {},\n): { metrics: HttpMetrics; middleware: RequestHandler } {\n const metrics = new HttpMetrics(\n options.buckets !== undefined ? { buckets: options.buckets } : {},\n );\n return {\n metrics,\n middleware: metrics.middleware(\n options.exemptPaths !== undefined ? { exemptPaths: options.exemptPaths } : {},\n ),\n };\n}\n","/**\n * Sliding-window rate-limit middleware with pluggable stores and keys,\n * mirroring `api.middlewares.rate_limit`.\n *\n * Two axes are pluggable:\n *\n * - **Store** — where the counters live. {@link MemoryRateLimitStore} (default,\n * in-process) fits a single worker; {@link RedisRateLimitStore} shares state\n * across replicas via an atomic Lua sliding-window log.\n * - **Key** — *who* a request counts against. {@link keyByIp} (default),\n * {@link keyByHeader} (e.g. an API key), {@link keyByJwtClaim} /\n * {@link keyByJwtSubject} (per authenticated principal), each falling back to\n * the client IP for anonymous traffic.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { type ClientIpOptions, getClientIp } from \"@/utils/clientIp\";\nimport type { Request, RequestHandler } from \"express\";\n\n/** Outcome of a single rate-limit check. */\nexport interface RateLimitResult {\n /** `true` when the request fits under the limit. */\n allowed: boolean;\n /** Requests still allowed in the current window (`0` when rejected). */\n remaining: number;\n /** Seconds to wait before retrying (`0` when allowed, `>= 1` on rejection). */\n retryAfter: number;\n}\n\n/** Backend that counts hits per key inside a sliding window. */\nexport interface RateLimitStore {\n /**\n * Register one hit for `key` and report whether it is allowed.\n *\n * @param key - The rate-limit bucket key.\n * @param maxRequests - Maximum hits allowed in the window.\n * @param windowSeconds - Sliding-window length in seconds.\n * @returns The decision for this hit.\n */\n hit(key: string, maxRequests: number, windowSeconds: number): Promise<RateLimitResult>;\n}\n\n/**\n * In-process sliding-window store backed by per-key timestamp logs.\n *\n * State lives in this worker's memory only — correct for a single process. For\n * multi-replica deployments use {@link RedisRateLimitStore}.\n */\nexport class MemoryRateLimitStore implements RateLimitStore {\n private readonly buckets = new Map<string, number[]>();\n\n async hit(\n key: string,\n maxRequests: number,\n windowSeconds: number,\n ): Promise<RateLimitResult> {\n const now = Date.now();\n const windowMs = windowSeconds * 1000;\n const cutoff = now - windowMs;\n const bucket = this.buckets.get(key) ?? [];\n // Prune timestamps older than the window.\n let start = 0;\n while (start < bucket.length) {\n const ts = bucket[start];\n if (ts === undefined || ts >= cutoff) break;\n start += 1;\n }\n const live = start > 0 ? bucket.slice(start) : bucket;\n\n if (live.length >= maxRequests) {\n this.buckets.set(key, live);\n const oldest = live[0] ?? now;\n const retryAfter = Math.max(1, Math.ceil((oldest + windowMs - now) / 1000));\n return { allowed: false, remaining: 0, retryAfter };\n }\n live.push(now);\n this.buckets.set(key, live);\n return { allowed: true, remaining: maxRequests - live.length, retryAfter: 0 };\n }\n}\n\n/** Minimal async Redis surface used by {@link RedisRateLimitStore}. */\nexport interface RateLimitRedisLike {\n eval(\n script: string,\n options: { keys: string[]; arguments: string[] },\n ): Promise<unknown>;\n}\n\n// Atomic sliding-window log: drop expired members, count, and only add the new\n// member when still under the limit. Returns {allowed, remaining, retry_ms}.\nconst SLIDING_WINDOW_LUA = `\nlocal key = KEYS[1]\nlocal now = tonumber(ARGV[1])\nlocal window = tonumber(ARGV[2])\nlocal limit = tonumber(ARGV[3])\nlocal member = ARGV[4]\nredis.call('ZREMRANGEBYSCORE', key, 0, now - window)\nlocal count = redis.call('ZCARD', key)\nif count < limit then\n redis.call('ZADD', key, now, member)\n redis.call('PEXPIRE', key, window)\n return {1, limit - count - 1, 0}\nend\nlocal oldest = redis.call('ZRANGE', key, 0, 0, 'WITHSCORES')\nlocal retry = window\nif oldest[2] then\n retry = (tonumber(oldest[2]) + window) - now\nend\nif retry < 1 then retry = 1 end\nreturn {0, 0, retry}\n`;\n\n/**\n * Distributed sliding-window store backed by a Redis sorted set. A single Lua\n * script prunes expired members, counts survivors and conditionally adds the\n * new hit, so the check is atomic across replicas. On a backend error the\n * request is allowed when `failOpen` (the default).\n */\nexport class RedisRateLimitStore implements RateLimitStore {\n private readonly namespace: string;\n private readonly failOpen: boolean;\n\n /**\n * @param redis - Async Redis client exposing `eval({ keys, arguments })`.\n * @param options - Key namespace and fail-open behavior.\n */\n constructor(\n private readonly redis: RateLimitRedisLike,\n options: { namespace?: string; failOpen?: boolean } = {},\n ) {\n this.namespace = options.namespace ?? \"ratelimit\";\n this.failOpen = options.failOpen ?? true;\n }\n\n async hit(\n key: string,\n maxRequests: number,\n windowSeconds: number,\n ): Promise<RateLimitResult> {\n const nowMs = Date.now();\n const windowMs = Math.round(windowSeconds * 1000);\n const member = randomUUID();\n try {\n const raw = (await this.redis.eval(SLIDING_WINDOW_LUA, {\n keys: [`${this.namespace}:${key}`],\n arguments: [String(nowMs), String(windowMs), String(maxRequests), member],\n })) as [number, number, number];\n const [allowedFlag, remaining, retryMs] = raw;\n const allowed = Boolean(allowedFlag);\n return {\n allowed,\n remaining: Number(remaining),\n retryAfter: allowed ? 0 : Math.max(1, Math.ceil(Number(retryMs) / 1000)),\n };\n } catch (error) {\n if (this.failOpen) {\n return { allowed: true, remaining: maxRequests - 1, retryAfter: 0 };\n }\n throw error;\n }\n }\n}\n\n/** Builds a rate-limit bucket key from a request (sync or async). */\nexport type RateLimitKeyFunc = (req: Request) => string | Promise<string>;\n\n/** Minimal JWT decoder surface used by the `keyByJwt*` helpers. */\nexport interface JwtDecoderLike {\n decode(token: string): Promise<Record<string, unknown>>;\n}\n\n/** Build `ClientIpOptions`, omitting `trustedHeader` when undefined. */\nfunction ipOpts(trustedHeader: string | undefined): ClientIpOptions {\n return trustedHeader !== undefined ? { trustedHeader } : {};\n}\n\nfunction bearerToken(req: Request): string | null {\n const header = req.header(\"authorization\");\n if (!header) return null;\n const parts = header.split(/\\s+/, 2);\n const [scheme, token] = parts;\n if (scheme?.toLowerCase() === \"bearer\" && token) return token.trim();\n return null;\n}\n\n/** Build a key function that buckets by resolved client IP. */\nexport function keyByIp(options: ClientIpOptions = {}): RateLimitKeyFunc {\n return (req) => `ip:${getClientIp(req, options)}`;\n}\n\n/**\n * Build a key function that buckets by a request header value (e.g. an API\n * key), falling back to the client IP for anonymous callers.\n */\nexport function keyByHeader(\n headerName: string,\n options: { scope?: string; fallbackToIp?: boolean; trustedIpHeader?: string } = {},\n): RateLimitKeyFunc {\n const scope = options.scope ?? \"key\";\n const fallbackToIp = options.fallbackToIp ?? true;\n return (req) => {\n const value = req.header(headerName);\n if (value) return `${scope}:${value.trim()}`;\n if (fallbackToIp) return `ip:${getClientIp(req, ipOpts(options.trustedIpHeader))}`;\n return `${scope}:anonymous`;\n };\n}\n\n/**\n * Build a key function that buckets by a claim in the bearer token, falling\n * back to the client IP for anonymous traffic.\n */\nexport function keyByJwtClaim(\n jwt: JwtDecoderLike,\n claim: string,\n options: { scope?: string; fallbackToIp?: boolean; trustedIpHeader?: string } = {},\n): RateLimitKeyFunc {\n const label = options.scope ?? claim;\n const fallbackToIp = options.fallbackToIp ?? true;\n return async (req) => {\n const token = bearerToken(req);\n if (token) {\n try {\n const claims = await jwt.decode(token);\n const value = claims[claim];\n if (value !== undefined && value !== null) return `${label}:${String(value)}`;\n } catch {\n // Invalid/expired token — treat as anonymous.\n }\n }\n if (fallbackToIp) return `ip:${getClientIp(req, ipOpts(options.trustedIpHeader))}`;\n return `${label}:anonymous`;\n };\n}\n\n/** Build a key function that buckets by the JWT `sub` claim (per-user). */\nexport function keyByJwtSubject(\n jwt: JwtDecoderLike,\n options: { fallbackToIp?: boolean; trustedIpHeader?: string } = {},\n): RateLimitKeyFunc {\n return keyByJwtClaim(jwt, \"sub\", { scope: \"user\", ...options });\n}\n\n/** Options for {@link rateLimitMiddleware}. */\nexport interface RateLimitOptions {\n /** Maximum requests per window. Default `60`. */\n maxRequests?: number;\n /** Window length in seconds. Default `60`. */\n windowSeconds?: number;\n /** Build a rate-limit key from the request. Overrides `trustedIpHeader`. */\n keyFunc?: RateLimitKeyFunc;\n /** Single edge-set header to resolve the client IP from when keying by IP. */\n trustedIpHeader?: string;\n /** Counter backend. Defaults to an in-process {@link MemoryRateLimitStore}. */\n store?: RateLimitStore;\n /** Exact paths to skip entirely (e.g. health probes). */\n exemptPaths?: string[];\n /** Whether to add a `Retry-After` header on 429s. Default `true`. */\n retryAfterHeader?: boolean;\n /** Body message of the 429 response. */\n errorMessage?: string;\n}\n\n/**\n * Build a sliding-window rate-limit middleware.\n *\n * @param options - Limits, key/store strategy and exemptions.\n * @returns An Express middleware rejecting excess traffic with `429`.\n * @throws {RangeError} When `maxRequests` < 1 or `windowSeconds` <= 0.\n */\nexport function rateLimitMiddleware(options: RateLimitOptions = {}): RequestHandler {\n const maxRequests = options.maxRequests ?? 60;\n const windowSeconds = options.windowSeconds ?? 60;\n if (maxRequests < 1) throw new RangeError(\"maxRequests must be >= 1\");\n if (windowSeconds <= 0) throw new RangeError(\"windowSeconds must be > 0\");\n\n const store = options.store ?? new MemoryRateLimitStore();\n const keyFunc: RateLimitKeyFunc =\n options.keyFunc ?? keyByIp(ipOpts(options.trustedIpHeader));\n const exempt = new Set(options.exemptPaths ?? []);\n const retryAfterHeader = options.retryAfterHeader ?? true;\n const errorMessage = options.errorMessage ?? \"Too many requests\";\n\n return (req, res, next) => {\n if (exempt.has(req.path)) {\n next();\n return;\n }\n Promise.resolve(keyFunc(req))\n .then((key) => store.hit(key, maxRequests, windowSeconds))\n .then((result) => {\n res.setHeader(\"X-RateLimit-Limit\", String(maxRequests));\n res.setHeader(\"X-RateLimit-Remaining\", String(Math.max(0, result.remaining)));\n if (!result.allowed) {\n if (retryAfterHeader) res.setHeader(\"Retry-After\", String(result.retryAfter));\n res.status(429).json({\n detail: errorMessage,\n code: \"TOO_MANY_REQUESTS\",\n details: { retryAfterSeconds: result.retryAfter },\n });\n return;\n }\n next();\n })\n .catch(next);\n };\n}\n","/**\n * `requestTracingMiddleware` — structured per-request access logging, mirroring\n * the request-tracing concern of the FastAPI SDK.\n *\n * Logs one JSON line per request with method, path, status, duration and the\n * request id (from the request-id context), so every request is traceable in a\n * log aggregator. It is the lightweight, dependency-free counterpart to full\n * OpenTelemetry tracing — the request id correlates logs across services.\n */\n\nimport { JSONLogger, type LogLevel, getRequestId } from \"@/core\";\nimport type { RequestHandler } from \"express\";\n\n/** Options for {@link requestTracingMiddleware}. */\nexport interface RequestTracingOptions {\n /** Logger name. Default `tempest_express_sdk.api.tracing`. */\n loggerName?: string;\n /** Log level for completed requests. Default `\"info\"`. */\n level?: LogLevel;\n /** Exact paths to skip (e.g. health probes). */\n exemptPaths?: string[];\n}\n\n/**\n * Build an access-logging middleware. Records the request on completion with\n * its duration in milliseconds.\n *\n * @param options - Logger name, level and exempt paths.\n * @returns An Express middleware.\n */\nexport function requestTracingMiddleware(\n options: RequestTracingOptions = {},\n): RequestHandler {\n const logger = new JSONLogger(options.loggerName ?? \"tempest_express_sdk.api.tracing\");\n const level = options.level ?? \"info\";\n const exempt = new Set(options.exemptPaths ?? []);\n\n return (req, res, next) => {\n if (exempt.has(req.path)) {\n next();\n return;\n }\n const start = process.hrtime.bigint();\n res.on(\"finish\", () => {\n const durationMs = Number(process.hrtime.bigint() - start) / 1e6;\n logger.log(level, \"request\", {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n durationMs: Math.round(durationMs * 1000) / 1000,\n requestId: getRequestId(),\n });\n });\n next();\n };\n}\n","/**\n * OAuth2 / OIDC clients, mirroring `api.oauth`.\n *\n * Three clients out of the box: {@link GoogleOAuthClient},\n * {@link GitHubOAuthClient} and the generic {@link OIDCProvider} (Auth0,\n * Keycloak, Okta, Entra, Cognito). They cover only the OAuth2 dance — build an\n * authorize URL, exchange the code for tokens, fetch the user. Storing the user,\n * minting your own session token and setting cookies are the service's calls.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { AppException } from \"@/exceptions/base\";\nimport { HTTPClient } from \"@/utils/httpClient\";\n\n/** Raised when a provider rejects part of the OAuth dance. */\nexport class OAuthError extends AppException {\n static override statusCode = 502;\n static override code = \"OAUTH_ERROR\";\n}\n\n/** The single normalized identity shape the rest of the app sees. */\nexport interface OAuthUser {\n /** Provider label (`\"google\"`, `\"github\"`, `\"oidc:auth0\"`, …). */\n provider: string;\n /** Stable per-provider id; pair with `provider` for a global key. */\n subject: string;\n email: string | null;\n name: string | null;\n picture: string | null;\n /** The raw provider payload. */\n raw: Record<string, unknown>;\n}\n\n/** The token bundle returned by a code exchange. */\nexport interface OAuthTokens {\n accessToken: string;\n tokenType: string;\n refreshToken: string | null;\n /** The OIDC id token (JWT), or `null` on plain OAuth2. */\n idToken: string | null;\n expiresIn: number | null;\n scope: string | null;\n raw: Record<string, unknown>;\n}\n\n/**\n * Generate a URL-safe random `state` value. Store it server-side (or a signed\n * cookie) before redirecting and compare on callback — a mismatch is a forged\n * redirect.\n *\n * @param nBytes - Entropy bytes. Default `32`.\n * @returns A URL-safe token.\n */\nexport function generateOAuthState(nBytes = 32): string {\n return randomBytes(nBytes).toString(\"base64url\");\n}\n\n/** Common constructor options for the OAuth clients. */\nexport interface OAuthClientOptions {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n scopes?: string[];\n httpClient?: HTTPClient;\n}\n\n/** Base class implementing the OAuth2 dance; subclasses fill in the endpoints. */\nexport abstract class BaseOAuthClient {\n abstract readonly providerName: string;\n protected readonly clientId: string;\n protected readonly clientSecret: string;\n protected readonly redirectUri: string;\n protected readonly scopes: string[];\n protected readonly http: HTTPClient;\n\n constructor(options: OAuthClientOptions) {\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.redirectUri = options.redirectUri;\n this.scopes = options.scopes ?? this.defaultScopes();\n this.http = options.httpClient ?? new HTTPClient({ timeoutMs: 10000 });\n }\n\n protected defaultScopes(): string[] {\n return [];\n }\n\n /** The provider's authorization endpoint. */\n protected abstract authorizeUrl(): string;\n /** The provider's token endpoint. */\n protected abstract tokenUrl(): string;\n /** The provider's userinfo endpoint, or `null` when unavailable. */\n protected userinfoUrl(): string | null {\n return null;\n }\n /** Map a raw userinfo payload to {@link OAuthUser}. */\n protected abstract parseUser(payload: Record<string, unknown>): OAuthUser;\n\n /**\n * Build the fully-formed authorize URL to redirect the user to.\n *\n * @param state - A value from {@link generateOAuthState}, saved server-side.\n * @param extra - Extra query params (e.g. `{ access_type: \"offline\" }`).\n * @returns The authorize URL.\n */\n buildAuthorizeUrl(state: string, extra: Record<string, string> = {}): string {\n const params = new URLSearchParams({\n client_id: this.clientId,\n redirect_uri: this.redirectUri,\n response_type: \"code\",\n scope: this.scopes.join(\" \"),\n state,\n ...extra,\n });\n return `${this.authorizeUrl()}?${params.toString()}`;\n }\n\n /**\n * Exchange an authorization code for tokens.\n *\n * @param code - The `code` query param from the callback.\n * @returns The parsed token bundle.\n * @throws {OAuthError} When the provider rejects the exchange.\n */\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: this.redirectUri,\n client_id: this.clientId,\n client_secret: this.clientSecret,\n });\n const response = await this.http.request(\"POST\", this.tokenUrl(), {\n body: body.toString(),\n headers: {\n \"content-type\": \"application/x-www-form-urlencoded\",\n accept: \"application/json\",\n },\n });\n if (response.status >= 400) {\n throw new OAuthError({\n message: `token exchange failed (${response.status})`,\n details: { body: await safeText(response) },\n });\n }\n const payload = (await response.json()) as Record<string, unknown>;\n return {\n accessToken: String(payload.access_token),\n tokenType: (payload.token_type as string) ?? \"Bearer\",\n refreshToken: (payload.refresh_token as string) ?? null,\n idToken: (payload.id_token as string) ?? null,\n expiresIn: (payload.expires_in as number) ?? null,\n scope: (payload.scope as string) ?? null,\n raw: payload,\n };\n }\n\n /**\n * Fetch the normalized user identity for a token bundle.\n *\n * @param tokens - The tokens from {@link exchangeCode}.\n * @returns The normalized user.\n * @throws {OAuthError} When userinfo is unconfigured or the call fails.\n */\n async fetchUser(tokens: OAuthTokens): Promise<OAuthUser> {\n const url = this.userinfoUrl();\n if (url === null) {\n throw new OAuthError({\n message: `${this.providerName}: userinfo endpoint not configured`,\n });\n }\n const response = await this.http.request(\"GET\", url, {\n headers: {\n authorization: `${tokens.tokenType} ${tokens.accessToken}`,\n accept: \"application/json\",\n \"user-agent\": \"tempest-express-sdk\",\n },\n });\n if (response.status >= 400) {\n throw new OAuthError({\n message: `userinfo failed (${response.status})`,\n details: { body: await safeText(response) },\n });\n }\n return this.parseUser((await response.json()) as Record<string, unknown>);\n }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\n/** Google identity (OIDC). Default scopes: `openid email profile`. */\nexport class GoogleOAuthClient extends BaseOAuthClient {\n readonly providerName = \"google\";\n protected override defaultScopes(): string[] {\n return [\"openid\", \"email\", \"profile\"];\n }\n protected authorizeUrl(): string {\n return \"https://accounts.google.com/o/oauth2/v2/auth\";\n }\n protected tokenUrl(): string {\n return \"https://oauth2.googleapis.com/token\";\n }\n protected override userinfoUrl(): string {\n return \"https://openidconnect.googleapis.com/v1/userinfo\";\n }\n protected parseUser(payload: Record<string, unknown>): OAuthUser {\n return {\n provider: this.providerName,\n subject: String(payload.sub),\n email: (payload.email as string) ?? null,\n name: (payload.name as string) ?? null,\n picture: (payload.picture as string) ?? null,\n raw: payload,\n };\n }\n}\n\n/** GitHub OAuth (no id_token; identity from `GET /user`). */\nexport class GitHubOAuthClient extends BaseOAuthClient {\n readonly providerName = \"github\";\n protected override defaultScopes(): string[] {\n return [\"read:user\", \"user:email\"];\n }\n protected authorizeUrl(): string {\n return \"https://github.com/login/oauth/authorize\";\n }\n protected tokenUrl(): string {\n return \"https://github.com/login/oauth/access_token\";\n }\n protected override userinfoUrl(): string {\n return \"https://api.github.com/user\";\n }\n protected parseUser(payload: Record<string, unknown>): OAuthUser {\n return {\n provider: this.providerName,\n subject: String(payload.id),\n email: (payload.email as string) ?? null,\n name: (payload.name as string) ?? (payload.login as string) ?? null,\n picture: (payload.avatar_url as string) ?? null,\n raw: payload,\n };\n }\n}\n\n/** Options for {@link OIDCProvider}. */\nexport interface OIDCProviderOptions extends OAuthClientOptions {\n authorizeUrl: string;\n tokenUrl: string;\n userinfoUrl?: string | null;\n providerName?: string;\n}\n\n/**\n * Generic discovery-driven OIDC client. Pass the authorize / token / userinfo\n * endpoints (fetch them once at boot from `${issuer}/.well-known/openid-configuration`).\n * Default scopes: `openid email profile`.\n */\nexport class OIDCProvider extends BaseOAuthClient {\n readonly providerName: string;\n private readonly _authorizeUrl: string;\n private readonly _tokenUrl: string;\n private readonly _userinfoUrl: string | null;\n\n constructor(options: OIDCProviderOptions) {\n super(options);\n this.providerName = options.providerName ?? \"oidc\";\n this._authorizeUrl = options.authorizeUrl;\n this._tokenUrl = options.tokenUrl;\n this._userinfoUrl = options.userinfoUrl ?? null;\n }\n\n protected override defaultScopes(): string[] {\n return [\"openid\", \"email\", \"profile\"];\n }\n protected authorizeUrl(): string {\n return this._authorizeUrl;\n }\n protected tokenUrl(): string {\n return this._tokenUrl;\n }\n protected override userinfoUrl(): string | null {\n return this._userinfoUrl;\n }\n protected parseUser(payload: Record<string, unknown>): OAuthUser {\n return {\n provider: this.providerName,\n subject: String(payload.sub ?? payload.id),\n email: (payload.email as string) ?? null,\n name: (payload.name as string) ?? null,\n picture: (payload.picture as string) ?? null,\n raw: payload,\n };\n }\n}\n","/**\n * `WebhookSignatureVerifier` — HMAC signature verification for inbound\n * webhooks, mirroring `api.webhooks`.\n *\n * Providers compute `hmac(secret, body)` and ship the digest in a header (hex or\n * base64). This verifies it in constant time and exposes an Express middleware\n * that checks the header against the **raw** request body.\n */\n\nimport { type BinaryLike, createHmac, timingSafeEqual } from \"node:crypto\";\nimport type { Request, RequestHandler } from \"express\";\n\n/** Options for {@link WebhookSignatureVerifier}. */\nexport interface WebhookSignatureOptions {\n /** Digest algorithm (e.g. `\"sha256\"`, `\"sha512\"`). Default `\"sha256\"`. */\n algorithm?: string;\n /** Header carrying the signature. Default `\"X-Signature\"`. */\n headerName?: string;\n /** Digest encoding. Default `\"hex\"`. */\n encoding?: \"hex\" | \"base64\";\n /** Prefix stripped from the header before comparing (e.g. `\"sha256=\"`). */\n prefix?: string;\n}\n\n/** Verifies an HMAC webhook signature over a raw request body. */\nexport class WebhookSignatureVerifier {\n private readonly secret: BinaryLike;\n private readonly algorithm: string;\n private readonly headerName: string;\n private readonly encoding: \"hex\" | \"base64\";\n private readonly prefix: string;\n\n /**\n * @param secret - The shared signing secret.\n * @param options - Algorithm, header name, encoding and optional prefix.\n */\n constructor(secret: string | Buffer, options: WebhookSignatureOptions = {}) {\n this.secret = secret;\n this.algorithm = options.algorithm ?? \"sha256\";\n this.headerName = options.headerName ?? \"X-Signature\";\n this.encoding = options.encoding ?? \"hex\";\n this.prefix = options.prefix ?? \"\";\n }\n\n /** The header name this verifier reads. */\n get header(): string {\n return this.headerName;\n }\n\n /**\n * Compute the expected signature for a raw body.\n *\n * @param body - The raw request body.\n * @returns The signature in the configured encoding.\n */\n expected(body: BinaryLike): string {\n return createHmac(this.algorithm, this.secret).update(body).digest(this.encoding);\n }\n\n /**\n * Verify a signature against a raw body (constant time).\n *\n * @param body - The raw request body.\n * @param signature - The header value (including any configured prefix).\n * @returns `true` when it matches.\n */\n verify(body: BinaryLike, signature: string): boolean {\n let candidate = signature;\n if (this.prefix && candidate.startsWith(this.prefix)) {\n candidate = candidate.slice(this.prefix.length);\n }\n const expected = Buffer.from(this.expected(body));\n const provided = Buffer.from(candidate);\n if (expected.length !== provided.length) return false;\n return timingSafeEqual(expected, provided);\n }\n\n /**\n * Build an Express middleware that rejects requests with a bad signature.\n *\n * The route **must** receive the raw body as a `Buffer` — mount\n * `express.raw({ type: \"...\" })` (matching every content type) before this\n * middleware so `req.body` is the raw bytes. On success the request proceeds\n * (parse `req.body` yourself).\n *\n * @param options - Custom error message.\n * @returns An Express middleware.\n */\n middleware(options: { errorMessage?: string } = {}): RequestHandler {\n const errorMessage = options.errorMessage ?? \"Invalid webhook signature\";\n return (req: Request, res, next) => {\n const signature = req.header(this.headerName) ?? \"\";\n const body: BinaryLike = Buffer.isBuffer(req.body)\n ? req.body\n : Buffer.from(typeof req.body === \"string\" ? req.body : \"\");\n if (!signature || !this.verify(body, signature)) {\n res.status(401).json({ detail: errorMessage, code: \"UNAUTHORIZED\", details: {} });\n return;\n }\n next();\n };\n }\n}\n","/**\n * `makeToolSpecRouter` — a machine-readable capability manifest at the root\n * prefix, mirroring `api.routers.tool_spec`.\n *\n * Services expose a small manifest so callers discover capabilities without\n * parsing the full OpenAPI document. Pass a static object, a sync provider, or\n * an async provider (recomputed per request).\n */\n\nimport { Router } from \"express\";\n\n/** The manifest, or a (possibly async) provider of it. */\nexport type SpecProvider =\n | Record<string, unknown>\n | (() => Record<string, unknown>)\n | (() => Promise<Record<string, unknown>>);\n\n/** Options for {@link makeToolSpecRouter}. */\nexport interface ToolSpecOptions {\n /** Endpoint path. Default `\"/tool-spec\"`. */\n path?: string;\n}\n\n/**\n * Build a router serving the manifest at a root-prefix `GET` route.\n *\n * @param spec - A static object or a sync/async provider.\n * @param options - The endpoint path.\n * @returns An Express router with a single `GET` route.\n */\nexport function makeToolSpecRouter(\n spec: SpecProvider,\n options: ToolSpecOptions = {},\n): Router {\n const router = Router();\n const path = options.path ?? \"/tool-spec\";\n\n router.get(path, (_req, res, next) => {\n Promise.resolve(typeof spec === \"function\" ? spec() : spec)\n .then((result) => res.json(result))\n .catch(next);\n });\n\n return router;\n}\n","/**\n * `makeLogsRouter` — a paginated read endpoint over the file logs, mirroring\n * `api.routers.logs`.\n *\n * Reads the per-level / `500.log` files written by `configureFileLogging`,\n * parses each JSON line, and serves the newest-first, offset-paginated. Guard it\n * (this exposes operational data) with any middleware you pass in `guards`.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { HTTP_500_LOG_FILE, LEVEL_LOG_FILES } from \"@/utils/log\";\nimport { type RequestHandler, Router } from \"express\";\n\n/** Selector for which log file(s) to read. */\nexport type LogSource = \"all\" | \"debug\" | \"info\" | \"warning\" | \"error\" | \"500\";\n\n/** Options for {@link makeLogsRouter}. */\nexport interface LogsRouterOptions {\n /** Directory holding the log files (same one passed to `configureFileLogging`). */\n dir: string;\n /** Endpoint path. Default `\"/logs\"`. */\n path?: string;\n /** Middlewares run before the handler (e.g. a token guard). */\n guards?: RequestHandler[];\n}\n\nfunction filesFor(dir: string, source: LogSource): string[] {\n if (source === \"500\") return [join(dir, HTTP_500_LOG_FILE)];\n if (source === \"all\") return Object.values(LEVEL_LOG_FILES).map((f) => join(dir, f));\n return [join(dir, LEVEL_LOG_FILES[source])];\n}\n\nasync function readEntries(files: string[]): Promise<Record<string, unknown>[]> {\n const entries: Record<string, unknown>[] = [];\n for (const file of files) {\n let content: string;\n try {\n content = await readFile(file, \"utf8\");\n } catch {\n continue; // missing file — skip\n }\n for (const line of content.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line) as Record<string, unknown>);\n } catch {\n // Skip a single corrupt line rather than failing the endpoint.\n }\n }\n }\n return entries;\n}\n\n/**\n * Build a router serving `GET <path>` with query params `source`, `page` and\n * `pageSize`. Returns `{ items, total, page, pageSize, pages }`, newest first.\n *\n * @param options - Log directory, path and optional guards.\n * @returns An Express router.\n */\nexport function makeLogsRouter(options: LogsRouterOptions): Router {\n const router = Router();\n const path = options.path ?? \"/logs\";\n const guards = options.guards ?? [];\n\n const handler: RequestHandler = (req, res, next) => {\n const source = (req.query.source as LogSource) ?? \"all\";\n const validSources: LogSource[] = [\"all\", \"debug\", \"info\", \"warning\", \"error\", \"500\"];\n if (!validSources.includes(source)) {\n res\n .status(422)\n .json({ detail: \"Invalid log source\", code: \"VALIDATION_ERROR\", details: {} });\n return;\n }\n const page = Math.max(1, Number(req.query.page) || 1);\n const pageSize = Math.min(500, Math.max(1, Number(req.query.pageSize) || 50));\n\n readEntries(filesFor(options.dir, source))\n .then((entries) => {\n // Newest first when a timestamp is present; else keep file order reversed.\n entries.reverse();\n const total = entries.length;\n const start = (page - 1) * pageSize;\n res.json({\n items: entries.slice(start, start + pageSize),\n total,\n page,\n pageSize,\n pages: Math.ceil(total / pageSize),\n });\n })\n .catch(next);\n };\n\n router.get(path, ...guards, handler);\n return router;\n}\n","/**\n * In-memory test-database helpers, mirroring `testing.database`.\n *\n * Stand up a fully-wired `tempest-db-js` engine over an in-memory SQLite\n * database whose schema is created directly from your models — no migration\n * files, no temp files, no external service. One shared connection backs both\n * the DDL and every session, so repositories see the tables you declared.\n *\n * The helpers are framework-agnostic (no `vitest`/`jest` import), so wrap them\n * in whatever harness the consuming project uses.\n */\n\nimport {\n type AsyncDriver,\n AsyncEngine,\n type AsyncSession,\n type ModelClass,\n NodeSqliteDriver,\n} from \"tempest-db-js\";\nimport { reflectTable, renderOperation } from \"tempest-db-js/migrations\";\n\n/** A disposable in-memory test database. */\nexport interface TestDatabase {\n /** The wired async engine — hand its sessions to repositories. */\n readonly engine: AsyncEngine;\n /** Open a fresh session on the shared in-memory connection. */\n session(): AsyncSession;\n /** Dispose the engine and drop the in-memory database. */\n close(): Promise<void>;\n}\n\n/**\n * Create an in-memory SQLite test database with tables reflected from `models`.\n *\n * @param models - The model classes whose tables should be created.\n * @returns A {@link TestDatabase} — remember to `await close()` in teardown.\n *\n * @example\n * ```ts\n * const db = createTestDatabase([UserModel]);\n * const repo = new UserRepository(db.session());\n * await repo.create({ name: \"Ana\", email: \"ana@x.com\", passwordHash: \"...\" });\n * await db.close();\n * ```\n */\nexport function createTestDatabase(models: readonly ModelClass[]): TestDatabase {\n const driver = NodeSqliteDriver.open(\":memory:\");\n for (const model of models) {\n const table = reflectTable(model);\n for (const statement of renderOperation({ kind: \"create_table\", table }, \"sqlite\")) {\n driver.execute(statement, []);\n }\n }\n // Wrap the single sync SQLite connection as an async driver so `AsyncEngine`\n // (and therefore `BaseRepository`) runs against the very connection that owns\n // the freshly-created tables.\n const asyncDriver: AsyncDriver = {\n execute: (sql, params) => Promise.resolve(driver.execute(sql, params)),\n close: () => {\n driver.close();\n return Promise.resolve();\n },\n };\n const engine = new AsyncEngine(asyncDriver, \"sqlite\");\n return {\n engine,\n session: () => engine.session(),\n close: () => engine.close(),\n };\n}\n\n/**\n * Run `fn` against a fresh in-memory test database, disposing it afterwards even\n * if `fn` throws.\n *\n * @param models - The model classes whose tables should be created.\n * @param fn - Receives the {@link TestDatabase} and returns a promise.\n * @returns Whatever `fn` resolves to.\n *\n * @example\n * ```ts\n * await withTestDatabase([UserModel], async (db) => {\n * const repo = new UserRepository(db.session());\n * expect(await repo.count()).toBe(0);\n * });\n * ```\n */\nexport async function withTestDatabase<T>(\n models: readonly ModelClass[],\n fn: (db: TestDatabase) => Promise<T>,\n): Promise<T> {\n const db = createTestDatabase(models);\n try {\n return await fn(db);\n } finally {\n await db.close();\n }\n}\n","/** The installed SDK version. Single source of truth for the barrel + CLI. */\nexport const VERSION = \"0.22.0\";\n"]}
1
+ {"version":3,"sources":["../src/core/context.ts","../src/core/logging.ts","../src/core/enums.ts","../src/exceptions/base.ts","../src/exceptions/http.ts","../src/exceptions/i18n.ts","../src/schemas/base.ts","../src/schemas/fields.ts","../src/schemas/pagination.ts","../src/schemas/sync.ts","../src/schemas/linkHeaders.ts","../src/schemas/logs.ts","../src/settings/base.ts","../src/settings/mixins.ts","../src/db/model.ts","../src/db/userModel.ts","../src/db/audit.ts","../src/db/tenant.ts","../src/db/outbox.ts","../src/db/slowQuery.ts","../src/db/backup.ts","../src/services/base.ts","../src/controllers/base.ts","../src/utils/br.ts","../src/utils/data/brLocations.json","../src/utils/locations.ts","../src/utils/datetime.ts","../src/utils/dict.ts","../src/utils/opaqueToken.ts","../src/utils/password.ts","../src/utils/jwt.ts","../src/utils/throttle.ts","../src/utils/clientIp.ts","../src/storage/local.ts","../src/utils/download.ts","../src/utils/log.ts","../src/utils/totp.ts","../src/utils/httpClient.ts","../src/utils/metrics.ts","../src/utils/email.ts","../src/cache/manager.ts","../src/cache/cached.ts","../src/sessions/store.ts","../src/sessions/service.ts","../src/sessions/middleware.ts","../src/sessions/redisStore.ts","../src/sse/eventStream.ts","../src/sse/broker.ts","../src/sse/redisBroker.ts","../src/websockets/schemas.ts","../src/websockets/hub.ts","../src/websockets/attach.ts","../src/queue/broker.ts","../src/tasks/manager.ts","../src/flags/backends.ts","../src/flags/service.ts","../src/storage/s3.ts","../src/webpush/schemas.ts","../src/webpush/dispatcher.ts","../src/integrations/provider.ts","../src/integrations/whatsapp.ts","../src/integrations/webhook.ts","../src/integrations/telegram.ts","../src/integrations/sms.ts","../src/integrations/email.ts","../src/integrations/broadcast.ts","../src/admin/columns.ts","../src/admin/config.ts","../src/admin/forms.ts","../src/admin/auth.ts","../src/admin/session.ts","../src/admin/site.ts","../src/admin/styles.ts","../src/admin/theme.ts","../src/admin/templates.ts","../src/admin/router.ts","../src/admin/json/site.ts","../src/admin/json/router.ts","../src/auth/schemas.ts","../src/auth/service.ts","../src/auth/mfa.ts","../src/auth/activation.ts","../src/auth/passwordReset.ts","../src/auth/middleware.ts","../src/auth/router.ts","../src/auth/htmlPages.ts","../src/api/handlers.ts","../src/api/openapi.ts","../src/api/docs.ts","../src/api/health.ts","../src/api/metrics.ts","../src/api/server.ts","../src/api/middlewares/bodySize.ts","../src/api/middlewares/csrf.ts","../src/api/middlewares/graceful.ts","../src/api/middlewares/idempotency.ts","../src/api/middlewares/prometheus.ts","../src/api/middlewares/rateLimit.ts","../src/api/middlewares/tracing.ts","../src/api/oauth.ts","../src/api/webhooks.ts","../src/api/toolSpec.ts","../src/api/logs.ts","../src/testing/database.ts","../src/version.ts"],"names":["AsyncLocalStorage","extendZodWithOpenApi","z","page","Model","column","sql","BaseRepository","RecordNotFound","logger","detectDialect","copyFile","spawn","createHash","randomBytes","timingSafeEqual","cached","join","mkdir","dirname","writeFile","readFile","rm","normalize","relative","isAbsolute","stat","createReadStream","mkdirSync","createWriteStream","createHmac","promisify","execFile","cpus","loadavg","totalmem","freemem","snapshot","randomUUID","createRouter","update","columnsOf","express","or","and","view","PAGINATION_KEYS","ZodError","OpenAPIRegistry","OpenApiGeneratorV31","OpenApiGeneratorV3","escapeHtml","getAbsoluteFSPath","createRequire","safeEqual","esc","bearerToken","Router","NodeSqliteDriver","reflectTable","renderOperation","AsyncEngine"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA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","file":"index.cjs","sourcesContent":["/**\n * Request-scoped context propagation via `AsyncLocalStorage`.\n *\n * Mirrors `tempest_fastapi_sdk.core.context`: a per-request id that any layer\n * (logger, exception handler, service) can read without threading it through\n * every call. The store is populated by the request-id middleware and survives\n * across `await` boundaries within the same request.\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\n/** The shape of the per-request store. */\nexport interface RequestContext {\n /** Stable id correlating every log line of a single request. */\n requestId: string;\n}\n\nconst storage = new AsyncLocalStorage<RequestContext>();\n\n/**\n * Run `fn` with `context` bound as the active request context.\n *\n * @param context - The context to bind for the duration of `fn`.\n * @param fn - The function to run within the bound context.\n * @returns Whatever `fn` returns.\n */\nexport function runWithRequestContext<T>(context: RequestContext, fn: () => T): T {\n return storage.run(context, fn);\n}\n\n/**\n * Read the current request id, or `null` when called outside a request.\n *\n * @returns The active request id, or `null`.\n */\nexport function getRequestId(): string | null {\n return storage.getStore()?.requestId ?? null;\n}\n\n/**\n * Overwrite the request id on the active context (no-op outside a request).\n *\n * @param requestId - The id to set.\n */\nexport function setRequestId(requestId: string): void {\n const store = storage.getStore();\n if (store) store.requestId = requestId;\n}\n","/**\n * Structured JSON logging, mirroring `tempest_fastapi_sdk.core.logging`.\n *\n * Emits one JSON object per line to stdout (or stderr for `error`), enriched\n * with the active request id. Server errors (`500`) carry the\n * {@link HTTP_500_MARKER} flag so an external log router can split them into a\n * dedicated `500.log` sink.\n */\n\nimport { getRequestId } from \"@/core/context\";\n\n/** Flag key marking a record as a captured HTTP 500 for sink routing. */\nexport const HTTP_500_MARKER = \"http_500\";\n\n/** Severity levels, ordered from least to most severe. */\nexport type LogLevel = \"debug\" | \"info\" | \"warning\" | \"error\";\n\nconst LEVEL_ORDER: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warning: 30,\n error: 40,\n};\n\n/** Free-form structured context merged into the emitted record. */\nexport type LogExtra = Record<string, unknown>;\n\n/** A sink receiving every emitted record (for file routing, shipping, …). */\nexport type LogSink = (level: LogLevel, record: Record<string, unknown>) => void;\n\nconst sinks: LogSink[] = [];\n\n/**\n * Register a sink invoked for every record every {@link JSONLogger} emits (in\n * addition to the stdout/stderr line). Used by `configureFileLogging` to route\n * records into per-level + `500.log` files.\n *\n * @param sink - The sink callback. Errors thrown by it are swallowed.\n * @returns A function that removes the sink.\n */\nexport function addLogSink(sink: LogSink): () => void {\n sinks.push(sink);\n return () => {\n const index = sinks.indexOf(sink);\n if (index !== -1) sinks.splice(index, 1);\n };\n}\n\n/** A minimal structured logger writing one JSON line per record. */\nexport class JSONLogger {\n /**\n * @param name - Logger name embedded in every record.\n * @param level - Minimum level to emit; quieter records are dropped.\n */\n constructor(\n private readonly name: string,\n private readonly level: LogLevel = \"info\",\n ) {}\n\n /** Log a debug-level message. */\n debug(message: string, extra?: LogExtra): void {\n this.log(\"debug\", message, extra);\n }\n\n /** Log an info-level message. */\n info(message: string, extra?: LogExtra): void {\n this.log(\"info\", message, extra);\n }\n\n /** Log a warning-level message. */\n warning(message: string, extra?: LogExtra): void {\n this.log(\"warning\", message, extra);\n }\n\n /** Log an error-level message. */\n error(message: string, extra?: LogExtra): void {\n this.log(\"error\", message, extra);\n }\n\n /**\n * Emit a record at `level` when it clears the configured threshold.\n *\n * @param level - The record severity.\n * @param message - The human-readable message.\n * @param extra - Structured context merged into the record.\n */\n log(level: LogLevel, message: string, extra?: LogExtra): void {\n if (LEVEL_ORDER[level] < LEVEL_ORDER[this.level]) return;\n const record: Record<string, unknown> = {\n level,\n logger: this.name,\n message,\n requestId: getRequestId(),\n ...extra,\n };\n const line = JSON.stringify(record);\n if (level === \"error\") process.stderr.write(`${line}\\n`);\n else process.stdout.write(`${line}\\n`);\n for (const sink of sinks) {\n try {\n sink(level, record);\n } catch {\n // A sink must never break logging.\n }\n }\n }\n}\n\n/**\n * Build a {@link JSONLogger}.\n *\n * @param name - Logger name.\n * @param level - Minimum level to emit (defaults to `info`).\n * @returns A configured logger.\n */\nexport function configureLogging(name: string, level: LogLevel = \"info\"): JSONLogger {\n return new JSONLogger(name, level);\n}\n","/**\n * Enum helpers mirroring `BaseStrEnum` / `BaseIntEnum`.\n *\n * TypeScript has no Python-style `Enum`, so this module offers a factory that\n * turns a plain literal map into a frozen object carrying the same\n * introspection helpers (`values`/`keys`/`choices`/`has`/`from`) the FastAPI\n * SDK exposes. The inferred type is the literal union of the member values, so\n * it stays as strongly typed as a hand-written `as const` map.\n */\n\n/** A member-name → member-value map (string- or number-valued). */\nexport type EnumSpec = Record<string, string | number>;\n\n/** Introspection helpers attached to every built enum. */\nexport interface EnumHelpers<S extends EnumSpec> {\n /** Every member value, in declaration order. */\n values(): Array<S[keyof S]>;\n /** Every member name, in declaration order. */\n keys(): Array<keyof S & string>;\n /** `[value, name]` pairs, e.g. for building `<select>` options. */\n choices(): Array<[S[keyof S], keyof S & string]>;\n /** Whether `value` is the value of some member. */\n hasValue(value: unknown): value is S[keyof S];\n /** Whether `key` is the name of some member. */\n hasKey(key: string): key is keyof S & string;\n /** Resolve a member value from a raw value or member name, else `fallback`. */\n from(value: unknown, fallback?: S[keyof S]): S[keyof S] | undefined;\n}\n\n/** A built enum: the literal member map plus {@link EnumHelpers}. */\nexport type Enum<S extends EnumSpec> = Readonly<S> & EnumHelpers<S>;\n\n/**\n * Build a frozen enum object with introspection helpers from a literal spec.\n *\n * @param spec - The member-name → value map. Pass it inline so TypeScript\n * infers the precise literal union (e.g. `defineEnum({ RED: \"red\" })`).\n * @returns The frozen members merged with {@link EnumHelpers}.\n */\nexport function defineEnum<const S extends EnumSpec>(spec: S): Enum<S> {\n const names = Object.keys(spec) as Array<keyof S & string>;\n const valueSet = new Set<unknown>(names.map((name) => spec[name]));\n\n const helpers: EnumHelpers<S> = {\n values: () => names.map((name) => spec[name]) as Array<S[keyof S]>,\n keys: () => [...names],\n choices: () =>\n names.map((name) => [spec[name], name]) as Array<[S[keyof S], keyof S & string]>,\n hasValue: (value: unknown): value is S[keyof S] => valueSet.has(value),\n hasKey: (key: string): key is keyof S & string => key in spec,\n from: (value: unknown, fallback?: S[keyof S]): S[keyof S] | undefined => {\n if (valueSet.has(value)) return value as S[keyof S];\n if (typeof value === \"string\" && value in spec) return spec[value] as S[keyof S];\n return fallback;\n },\n };\n\n return Object.freeze({ ...spec, ...helpers }) as Enum<S>;\n}\n","/**\n * Base application exception.\n *\n * Mirrors `tempest_fastapi_sdk.exceptions.base.AppException`: a single base any\n * layer can throw, carrying an HTTP status, a stable machine-readable `code`,\n * free-form `details`, optional response `headers`, and localization hooks\n * (`messageKey` / `messageParams`). The exception handler\n * ({@link registerExceptionHandlers}) serializes it to the canonical envelope:\n *\n * ```json\n * { \"detail\": \"<message>\", \"code\": \"<code>\", \"details\": { } }\n * ```\n *\n * Concrete projects either throw a domain subclass (for `instanceof` matching)\n * or the base directly, overriding fields via the constructor options.\n */\n\n/** Free-form structured context attached to the response payload. */\nexport type ExceptionDetails = Record<string, unknown>;\n\n/** Constructor options for {@link AppException} and subclasses. */\nexport interface AppExceptionOptions {\n /** Override the default message; used verbatim as `detail` absent a catalog. */\n message?: string;\n /** Override the default machine-readable code on this instance only. */\n code?: string;\n /** Override the default HTTP status code on this instance only. */\n statusCode?: number;\n /** Structured context merged into the JSON response `details`. */\n details?: ExceptionDetails;\n /** Extra HTTP response headers. */\n headers?: Record<string, string>;\n /** Catalog key used to localize `detail`; falls back to `code`. */\n messageKey?: string;\n /** Values interpolated into the localized message template. */\n messageParams?: Record<string, unknown>;\n}\n\nexport class AppException extends Error {\n /** Default HTTP status code for the class. */\n static statusCode = 500;\n /** Default human-readable message for the class. */\n static message = \"Internal server error\";\n /** Default machine-readable code for the class. */\n static code = \"INTERNAL_SERVER_ERROR\";\n /** Default catalog key for the class (falls back to `code`). */\n static messageKey: string | null = null;\n\n readonly statusCode: number;\n readonly code: string;\n readonly details: ExceptionDetails;\n readonly headers: Record<string, string>;\n readonly messageKey: string | null;\n readonly messageParams: Record<string, unknown>;\n\n /**\n * @param options - Per-instance overrides; omitted fields fall back to the\n * static class defaults.\n */\n constructor(options: AppExceptionOptions = {}) {\n const cls = new.target as typeof AppException;\n super(options.message ?? cls.message);\n this.name = cls.name;\n this.statusCode = options.statusCode ?? cls.statusCode;\n this.code = options.code ?? cls.code;\n this.details = options.details ?? {};\n this.headers = options.headers ?? {};\n this.messageKey = options.messageKey ?? cls.messageKey;\n this.messageParams = options.messageParams ?? {};\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n","/**\n * Concrete HTTP exception subclasses, mirroring the FastAPI SDK hierarchy.\n *\n * Each exists primarily for `instanceof` matching and to carry a sane default\n * status/code/message. Throw them directly or subclass further for domain\n * errors (e.g. `class UserNotFound extends NotFoundException {}`).\n */\n\nimport {\n AppException,\n type AppExceptionOptions,\n type ExceptionDetails,\n} from \"@/exceptions/base\";\n\n/** 409 — a write would violate a uniqueness/integrity rule. */\nexport class ConflictException extends AppException {\n static override statusCode = 409;\n static override message = \"Resource conflict\";\n static override code = \"CONFLICT\";\n}\n\n/** 404 — a single resource could not be located. Never for collections. */\nexport class NotFoundException extends AppException {\n static override statusCode = 404;\n static override message = \"Resource not found\";\n static override code = \"NOT_FOUND\";\n}\n\n/** 401 — the caller is not authenticated. */\nexport class UnauthorizedException extends AppException {\n static override statusCode = 401;\n static override message = \"Unauthorized\";\n static override code = \"UNAUTHORIZED\";\n}\n\n/** 403 — the caller is authenticated but lacks permission. */\nexport class ForbiddenException extends AppException {\n static override statusCode = 403;\n static override message = \"Forbidden\";\n static override code = \"FORBIDDEN\";\n}\n\n/** 422 — input failed a business rule beyond schema validation. */\nexport class ValidationException extends AppException {\n static override statusCode = 422;\n static override message = \"Validation error\";\n static override code = \"VALIDATION_ERROR\";\n}\n\n/** 401 — a JWT failed signature or claim validation. */\nexport class InvalidTokenException extends UnauthorizedException {\n static override message = \"Invalid token\";\n static override code = \"INVALID_TOKEN\";\n}\n\n/** 401 — a JWT's `exp` claim is in the past. */\nexport class ExpiredTokenException extends UnauthorizedException {\n static override message = \"Token expired\";\n static override code = \"TOKEN_EXPIRED\";\n}\n\n/** Options for {@link TooManyRequestsException}, adding a cooldown. */\nexport interface TooManyRequestsOptions extends AppExceptionOptions {\n /** Cooldown in seconds; sets `Retry-After` and `details.retryAfterSeconds`. */\n retryAfterSeconds?: number;\n}\n\n/** 429 — the client exceeded a rate limit or attempt budget. */\nexport class TooManyRequestsException extends AppException {\n static override statusCode = 429;\n static override message = \"Too many requests\";\n static override code = \"TOO_MANY_REQUESTS\";\n\n /**\n * @param options - Standard options plus an optional `retryAfterSeconds`\n * that populates both the `Retry-After` header and `details`.\n */\n constructor(options: TooManyRequestsOptions = {}) {\n const { retryAfterSeconds, details, headers, ...rest } = options;\n const mergedDetails: ExceptionDetails = { ...details };\n const mergedHeaders: Record<string, string> = { ...headers };\n if (retryAfterSeconds !== undefined) {\n mergedDetails.retryAfterSeconds ??= retryAfterSeconds;\n mergedHeaders[\"Retry-After\"] ??= String(retryAfterSeconds);\n }\n super({ ...rest, details: mergedDetails, headers: mergedHeaders });\n }\n}\n","/**\n * Lightweight message localization, mirroring `exceptions.i18n`.\n *\n * A {@link MessageCatalog} maps `code` → `{ locale: template }`. The exception\n * handler negotiates a locale from the request `Accept-Language` header and\n * resolves the exception's `messageKey` (or `code`) into a localized `detail`,\n * interpolating `messageParams` via `{name}` placeholders. A missing\n * translation falls back to the literal message, so partial catalogs are safe.\n */\n\n/** Default locale used when negotiation finds no match. */\nexport const DEFAULT_LOCALE = \"en\";\n\n/** A `code` → (`locale` → template) translation table. */\nexport type CatalogData = Record<string, Record<string, string>>;\n\n/**\n * Parse an `Accept-Language` header into locales ordered by descending `q`.\n *\n * @param header - The raw header value, or `null`/`undefined`.\n * @returns Lower-cased language tags, highest quality first.\n */\nexport function parseAcceptLanguage(header: string | null | undefined): string[] {\n if (!header) return [];\n return header\n .split(\",\")\n .map((part) => {\n const [tag, ...params] = part.trim().split(\";\");\n const q = params\n .map((p) => p.trim())\n .find((p) => p.startsWith(\"q=\"))\n ?.slice(2);\n return { tag: (tag ?? \"\").trim().toLowerCase(), q: q ? Number(q) : 1 };\n })\n .filter((entry) => entry.tag.length > 0 && !Number.isNaN(entry.q))\n .sort((a, b) => b.q - a.q)\n .map((entry) => entry.tag);\n}\n\n/** Interpolate `{name}` placeholders in `template` with `params`. */\nfunction interpolate(template: string, params: Record<string, unknown>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, key: string) =>\n key in params ? String(params[key]) : match,\n );\n}\n\n/** A localized message catalog keyed by error `code`. */\nexport class MessageCatalog {\n /**\n * @param data - The translation table.\n * @param defaultLocale - Locale used when negotiation matches nothing.\n */\n constructor(\n private readonly data: CatalogData = {},\n private readonly defaultLocale: string = DEFAULT_LOCALE,\n ) {}\n\n /**\n * Pick the best locale for an `Accept-Language` header.\n *\n * Matches exact tags first, then the primary subtag (`pt-br` → `pt`),\n * falling back to `defaultLocale`.\n *\n * @param header - The raw `Accept-Language` value.\n * @param defaultLocale - Override the catalog's default for this call.\n * @returns The negotiated locale tag.\n */\n negotiate(header: string | null | undefined, defaultLocale?: string): string {\n const fallback = defaultLocale ?? this.defaultLocale;\n const available = new Set<string>();\n for (const byLocale of Object.values(this.data)) {\n for (const locale of Object.keys(byLocale)) available.add(locale.toLowerCase());\n }\n for (const tag of parseAcceptLanguage(header)) {\n if (available.has(tag)) return tag;\n const primary = tag.split(\"-\")[0];\n if (primary && available.has(primary)) return primary;\n }\n return fallback;\n }\n\n /**\n * Resolve a localized message for `code` in `locale`.\n *\n * @param code - The catalog key (an exception's `messageKey` or `code`).\n * @param locale - The negotiated locale.\n * @param params - Values interpolated into the template.\n * @returns The localized string, or `null` when no template exists.\n */\n resolve(\n code: string,\n locale: string,\n params: Record<string, unknown> = {},\n ): string | null {\n const byLocale = this.data[code];\n if (!byLocale) return null;\n const template = byLocale[locale] ?? byLocale[this.defaultLocale];\n return template ? interpolate(template, params) : null;\n }\n}\n\n/** Build an empty default catalog. */\nexport function defaultMessageCatalog(): MessageCatalog {\n return new MessageCatalog();\n}\n","/**\n * Zod foundation shared by every DTO, mirroring `schemas.base.BaseSchema`.\n *\n * Pydantic uses class inheritance for shared config; Zod composes instead. This\n * module re-exports a `z` already augmented with `.openapi()` (so every schema\n * can carry OpenAPI metadata) and a {@link toDict} helper matching\n * `BaseSchema.to_dict` (drop nullish, exclude keys, merge extras).\n */\n\nimport { extendZodWithOpenApi } from \"@asteasolutions/zod-to-openapi\";\nimport { z } from \"zod\";\n\n// Augment the shared `z` instance with `.openapi(...)`. Idempotent — calling it\n// more than once across modules is safe.\nextendZodWithOpenApi(z);\n\nexport { z };\n\n/** Options for {@link toDict}. */\nexport interface ToDictOptions {\n /** Field names to drop from the output. */\n exclude?: string[];\n /** Extra entries merged on top (override existing keys). */\n include?: Record<string, unknown>;\n}\n\n/**\n * Serialize a validated object to a plain record, dropping `null`/`undefined`,\n * removing `exclude`d keys and merging `include` on top.\n *\n * @param data - The source object (typically a parsed schema).\n * @param options - Keys to exclude and entries to merge in.\n * @returns The cleaned record.\n */\nexport function toDict(\n data: Record<string, unknown>,\n options: ToDictOptions = {},\n): Record<string, unknown> {\n const exclude = new Set(options.exclude ?? []);\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (exclude.has(key)) continue;\n if (value === null || value === undefined) continue;\n out[key] = value;\n }\n return { ...out, ...(options.include ?? {}) };\n}\n\n/**\n * Response schema fields every ORM record carries (`id`, `isActive`,\n * `createdAt`, `updatedAt`). Mirrors `BaseResponseSchema`. Extend it with\n * `baseResponseSchema.extend({ ... })` to build concrete `*ResponseSchema`s.\n */\nexport const baseResponseSchema = z.object({\n id: z.uuid().openapi({ description: \"The unique identifier of the record.\" }),\n isActive: z\n .boolean()\n .openapi({ description: \"Whether the record is active (soft-delete flag).\" }),\n createdAt: z.coerce\n .date()\n .openapi({ description: \"The creation timestamp of the record (UTC).\" }),\n updatedAt: z.coerce\n .date()\n .openapi({ description: \"The last update timestamp of the record (UTC).\" }),\n});\n\n/** The inferred TS type of a {@link baseResponseSchema} payload. */\nexport type BaseResponse = z.infer<typeof baseResponseSchema>;\n","/**\n * Ready-made, validated Zod field types, mirroring `utils.fields`.\n *\n * Reusable building blocks for DTOs so you don't re-derive the same constraint\n * everywhere: money in cents, a price string, a percentage, a latitude, a slug,\n * a hex color. Compose them into schemas with `z.object({ price: priceField })`.\n */\n\nimport { z } from \"@/schemas/base\";\n\n// --- Integers ---------------------------------------------------------------\n\n/** A strictly positive integer (`> 0`). */\nexport const positiveIntField = z.number().int().positive();\n/** A non-negative integer (`>= 0`). */\nexport const nonNegativeIntField = z.number().int().min(0);\n/** A monetary amount in the smallest unit (cents), `>= 0`. Avoids float drift. */\nexport const centsField = z.number().int().min(0);\n/** A TCP port (`1..65535`). */\nexport const portField = z.number().int().min(1).max(65535);\n/** A 0–5 star rating. */\nexport const ratingField = z.number().int().min(0).max(5);\n\n// --- Floats -----------------------------------------------------------------\n\n/** A strictly positive float (`> 0`). */\nexport const positiveFloatField = z.number().positive();\n/** A non-negative float (`>= 0`). */\nexport const nonNegativeFloatField = z.number().min(0);\n/** A percentage (`0..100`). */\nexport const percentField = z.number().min(0).max(100);\n/** A ratio (`0..1`). */\nexport const ratioField = z.number().min(0).max(1);\n/** A WGS-84 latitude (`-90..90`). */\nexport const latitudeField = z.number().min(-90).max(90);\n/** A WGS-84 longitude (`-180..180`). */\nexport const longitudeField = z.number().min(-180).max(180);\n\n// --- Strings ----------------------------------------------------------------\n\n/** A non-empty string; whitespace is trimmed before the length check. */\nexport const nonEmptyStrField = z\n .string()\n .transform((value) => value.trim())\n .pipe(z.string().min(1));\n\n/** A URL slug: lowercase alphanumerics separated by single hyphens. */\nexport const slugField = z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, {\n message: \"Must be a lowercase hyphen-separated slug.\",\n});\n\n/** A hex color: `#rgb` or `#rrggbb`. */\nexport const hexColorField = z.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/, {\n message: \"Must be a #rgb or #rrggbb hex color.\",\n});\n\n/**\n * A money amount as an exact decimal **string** with up to two decimal places\n * (e.g. `\"19.90\"`). Mirrors `PriceField` — `tempest-db-js` `numeric` columns map\n * to strings, so money stays exact instead of drifting through a float.\n */\nexport const priceField = z.string().regex(/^\\d+(?:\\.\\d{1,2})?$/, {\n message: 'Must be a decimal money string, e.g. \"19.90\".',\n});\n\n// --- Booleans ---------------------------------------------------------------\n\n/** Message shown when a value is neither a boolean nor a boolean-ish token. */\nconst LOOSE_BOOLEAN_ERROR =\n 'Must be a boolean value such as \"true\", \"false\", \"1\", \"0\", \"yes\" or \"no\".';\n\n/**\n * A boolean read from a **textual** source — a query string or an environment\n * variable, where every value arrives as a string.\n *\n * `z.coerce.boolean()` is the wrong tool for those: it is `Boolean(input)`, so\n * every non-empty string is `true` — `\"false\"` and `\"0\"` included — and there is\n * no way to ask for `false` over the wire. This reads the usual textual tokens\n * in both directions (`true`/`1`/`yes`/`on`/`y`/`enabled` and\n * `false`/`0`/`no`/`off`/`n`/`disabled`, case-insensitive, surrounding\n * whitespace trimmed) and **rejects** anything else, so a typo surfaces as a\n * validation error instead of silently becoming `false`.\n *\n * An absent value — and an empty or whitespace-only string, which is how an\n * unset `.env` entry (`DEBUG=`) reaches the schema — falls back to\n * `defaultValue`. Real booleans pass through untouched, so a schema built for\n * `process.env` still parses a synthetic object in tests.\n *\n * The OpenAPI metadata is pinned to `type: boolean` (with the default) so the\n * document describes the field the client actually sends, not the union used to\n * parse it.\n *\n * @param defaultValue - The value used when the field is absent or empty.\n * @returns A zod schema producing a `boolean`.\n */\nexport function looseBoolean(defaultValue: boolean) {\n return z\n .preprocess(\n (value) => (typeof value === \"string\" ? value.trim() || undefined : value),\n z\n .union([z.boolean(), z.stringbool()], { error: LOOSE_BOOLEAN_ERROR })\n .default(defaultValue),\n )\n .openapi({ type: \"boolean\", default: defaultValue });\n}\n","/**\n * Pagination request/response primitives, mirroring `schemas.pagination`.\n *\n * Offset pagination ({@link paginationFilterSchema} / {@link paginationSchema})\n * and cursor pagination ({@link cursorPaginationFilterSchema} /\n * {@link cursorPaginationSchema}). Field names match the `tempest-db-js`\n * `BaseRepository.paginate` arguments so a parsed filter forwards through with\n * no renaming.\n */\n\nimport { type ToDictOptions, toDict, z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/**\n * Filter schema for offset-paginated list endpoints. Subclass via `.extend`\n * to add domain filters; {@link getConditions} strips the pagination keys.\n */\nexport const paginationFilterSchema = z.object({\n page: z.coerce\n .number()\n .int()\n .min(1)\n .default(1)\n .openapi({ description: \"The page number to retrieve (1-indexed).\" }),\n pageSize: z.coerce\n .number()\n .int()\n .min(1)\n .default(20)\n .openapi({ description: \"The number of items per page.\" }),\n orderBy: z\n .string()\n .optional()\n .openapi({ description: \"Column to order by; defaults to repository default.\" }),\n ascending: looseBoolean(true).openapi({\n description: \"Whether to order results ascending.\",\n }),\n});\n\n/** The parsed shape of {@link paginationFilterSchema}. */\nexport type PaginationFilter = z.infer<typeof paginationFilterSchema>;\n\nconst PAGINATION_KEYS = [\"page\", \"pageSize\", \"orderBy\", \"ascending\"];\n\n/**\n * Strip pagination/sort keys from a parsed filter, leaving only domain filters.\n *\n * @param filter - The parsed filter object (may carry extra domain fields).\n * @param options - Extra exclude/include passed through to {@link toDict}.\n * @returns The domain-level filter conditions.\n */\nexport function getConditions(\n filter: Record<string, unknown>,\n options: ToDictOptions = {},\n): Record<string, unknown> {\n return toDict(filter, {\n ...options,\n exclude: [...PAGINATION_KEYS, ...(options.exclude ?? [])],\n });\n}\n\n/**\n * The pagination/sort keyword arguments to forward to `BaseRepository.paginate`.\n *\n * @param filter - The parsed pagination filter.\n * @returns `{ page, pageSize, orderBy, ascending }`.\n */\nexport function getPaginationConditions(filter: PaginationFilter): {\n page: number;\n pageSize: number;\n orderBy?: string;\n ascending: boolean;\n} {\n return {\n page: filter.page,\n pageSize: filter.pageSize,\n ...(filter.orderBy !== undefined ? { orderBy: filter.orderBy } : {}),\n ascending: filter.ascending,\n };\n}\n\n/**\n * Build the offset-pagination response envelope for a given item schema.\n *\n * @param item - The zod schema for a single item.\n * @returns A zod object schema `{ items, total, page, pageSize, pages }`.\n */\nexport function paginationSchema<T extends z.ZodType>(item: T) {\n return z.object({\n items: z.array(item).openapi({ description: \"The items on the current page.\" }),\n total: z\n .number()\n .int()\n .min(0)\n .openapi({ description: \"Total items across all pages.\" }),\n page: z.number().int().min(1).openapi({ description: \"Current page (1-indexed).\" }),\n pageSize: z.number().int().min(1).openapi({ description: \"Items per page.\" }),\n pages: z.number().int().min(0).openapi({ description: \"Total number of pages.\" }),\n });\n}\n\n/** Filter schema for cursor-paginated endpoints. */\nexport const cursorPaginationFilterSchema = z.object({\n cursor: z\n .string()\n .optional()\n .openapi({ description: \"Opaque cursor; omit for the first page.\" }),\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(500)\n .default(20)\n .openapi({ description: \"Maximum number of items to return.\" }),\n orderBy: z.string().default(\"createdAt\").openapi({ description: \"Column to sort by.\" }),\n ascending: looseBoolean(false).openapi({\n description: \"Whether to sort ascending (default newest first).\",\n }),\n});\n\n/** The parsed shape of {@link cursorPaginationFilterSchema}. */\nexport type CursorPaginationFilter = z.infer<typeof cursorPaginationFilterSchema>;\n\n/**\n * Build the cursor-pagination response envelope for a given item schema.\n *\n * @param item - The zod schema for a single item.\n * @returns A zod object schema `{ items, nextCursor, hasMore, limit }`.\n */\nexport function cursorPaginationSchema<T extends z.ZodType>(item: T) {\n return z.object({\n items: z.array(item).openapi({ description: \"The items on the current page.\" }),\n nextCursor: z\n .string()\n .nullable()\n .openapi({ description: \"Cursor for the next page, or null when exhausted.\" }),\n hasMore: z.boolean().openapi({ description: \"Whether another page is available.\" }),\n limit: z.number().int().min(1).openapi({ description: \"The page size used.\" }),\n });\n}\n\n/**\n * Serialize a cursor payload to an opaque URL-safe base64 string (no padding).\n *\n * @param payload - The cursor state, e.g. `{ id, value }`.\n * @returns The encoded cursor.\n */\nexport function encodeCursor(payload: Record<string, unknown>): string {\n const json = JSON.stringify(payload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\n/**\n * Decode a cursor produced by {@link encodeCursor}.\n *\n * @param cursor - The opaque cursor string.\n * @returns The decoded payload.\n * @throws {Error} When the cursor is not valid base64 or not a JSON object.\n */\nexport function decodeCursor(cursor: string): Record<string, unknown> {\n let parsed: unknown;\n try {\n parsed = JSON.parse(Buffer.from(cursor, \"base64url\").toString(\"utf8\"));\n } catch (cause) {\n throw new Error(\"Invalid cursor\", { cause });\n }\n if (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n throw new Error(\"Invalid cursor payload\");\n }\n return parsed as Record<string, unknown>;\n}\n","/**\n * Delta-sync pagination schemas, mirroring `schemas.pagination` (Sync* half).\n *\n * For offline-first clients that pull \"everything changed since my last sync\".\n * The client sends the `serverTime` from the previous page back as `since`;\n * using the **server** clock as the watermark avoids clock-skew gaps.\n */\n\nimport { z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/**\n * Filter schema for a delta-sync pull. Extend with `.extend` to add domain\n * filters; the sync keys stay reserved.\n */\nexport const syncFilterSchema = z.object({\n since: z.coerce.date().optional().openapi({\n description: \"High-water mark; only rows changed after this are returned.\",\n }),\n cursor: z.string().optional().openapi({\n description: \"Opaque cursor from the previous page; omit for the first.\",\n }),\n limit: z.coerce\n .number()\n .int()\n .min(1)\n .max(1000)\n .default(100)\n .openapi({ description: \"Maximum number of items to return.\" }),\n includeDeleted: looseBoolean(false).openapi({\n description: \"Whether soft-deleted rows are included in the delta.\",\n }),\n});\n\n/** The parsed shape of {@link syncFilterSchema}. */\nexport type SyncFilter = z.infer<typeof syncFilterSchema>;\n\n/**\n * Build the delta-sync response envelope for a given item schema. Persist\n * `serverTime` on the client and send it back as the next `since`.\n *\n * @param item - The zod schema for a single item.\n * @returns A zod object `{ items, nextCursor, hasMore, limit, serverTime }`.\n */\nexport function syncPaginationSchema<T extends z.ZodType>(item: T) {\n return z.object({\n items: z.array(item).openapi({ description: \"Changed rows in this page.\" }),\n nextCursor: z\n .string()\n .nullable()\n .openapi({ description: \"Cursor for the next page, or null when exhausted.\" }),\n hasMore: z.boolean().openapi({ description: \"Whether another page is available.\" }),\n limit: z.number().int().min(1).openapi({ description: \"The page size used.\" }),\n serverTime: z.coerce.date().openapi({\n description: \"Server instant to persist as the next `since` watermark.\",\n }),\n });\n}\n","/**\n * RFC-5988 pagination `Link` header builder, mirroring `schemas.link_headers`.\n *\n * Emits the `first` / `prev` / `next` / `last` rels GitHub-style clients expect.\n * `prev`/`next` are omitted at the ends. Assign the result to\n * `res.setHeader(\"Link\", value)`.\n */\n\n/** Options for {@link buildPaginationLinkHeader}. */\nexport interface PaginationLinkOptions {\n /** Absolute or relative collection URL; existing query params are preserved. */\n baseUrl: string;\n /** Current page (1-based). */\n page: number;\n /** Page size. */\n pageSize: number;\n /** Total number of pages. */\n pages: number;\n /** Extra query params to preserve on every link (filters, sort). */\n extraParams?: Record<string, string>;\n /** Query param name for the page index. Default `\"page\"`. */\n pageParam?: string;\n /** Query param name for the page size. Default `\"pageSize\"`. */\n sizeParam?: string;\n}\n\n/**\n * Build a `Link` header value for an offset-paginated collection.\n *\n * @param options - Base URL, current page, page size, total pages and param names.\n * @returns The `Link` header value, or `\"\"` when there's nothing to link (single page).\n */\nexport function buildPaginationLinkHeader(options: PaginationLinkOptions): string {\n const { baseUrl, page, pageSize, pages } = options;\n if (pages <= 0) return \"\";\n\n const pageParam = options.pageParam ?? \"page\";\n const sizeParam = options.sizeParam ?? \"pageSize\";\n\n // Split any existing query off the base so we can rebuild it deterministically.\n const [path, existingQuery = \"\"] = baseUrl.split(\"?\", 2);\n const params = new URLSearchParams(existingQuery);\n for (const [key, value] of Object.entries(options.extraParams ?? {})) {\n if (!params.has(key)) params.set(key, value);\n }\n\n const urlFor = (target: number): string => {\n const q = new URLSearchParams(params);\n q.set(pageParam, String(target));\n q.set(sizeParam, String(pageSize));\n return `${path}?${q.toString()}`;\n };\n\n const parts: string[] = [\n `<${urlFor(1)}>; rel=\"first\"`,\n `<${urlFor(pages)}>; rel=\"last\"`,\n ];\n if (page > 1) parts.push(`<${urlFor(page - 1)}>; rel=\"prev\"`);\n if (page < pages) parts.push(`<${urlFor(page + 1)}>; rel=\"next\"`);\n return parts.join(\", \");\n}\n","/**\n * `logEntrySchema` — the shape of one structured log record, mirroring\n * `schemas.logs.LogEntrySchema`.\n *\n * Matches the JSON `JSONLogger` emits. It is intentionally open (`.loose()`)\n * so arbitrary `extra` keys (`path`, `requestId`, `http_500`, …) survive instead\n * of being dropped — useful when a logs endpoint parses and returns records.\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** One structured log record; extra keys pass through unchanged. */\nexport const logEntrySchema = z\n .object({\n timestamp: z\n .string()\n .openapi({ description: \"ISO-8601 UTC timestamp of the record.\" }),\n level: z.string().openapi({ description: \"Log level name (INFO, ERROR, …).\" }),\n logger: z.string().openapi({ description: \"Name of the emitting logger.\" }),\n message: z.string().openapi({ description: \"The formatted log message.\" }),\n requestId: z\n .string()\n .nullable()\n .optional()\n .openapi({ description: \"Correlation id, when present.\" }),\n stack: z.string().nullable().optional().openapi({\n description: \"Formatted stack trace, when the record carries an error.\",\n }),\n })\n .loose();\n\n/** The parsed shape of {@link logEntrySchema} (plus any extra keys). */\nexport type LogEntry = z.infer<typeof logEntrySchema>;\n","/**\n * Environment-driven settings, mirroring `settings.base.BaseAppSettings`.\n *\n * Pydantic-settings reads env vars into a frozen, validated model. Here a zod\n * schema plays the same role: {@link loadSettings} parses `process.env` (env\n * names are matched case-sensitively, like the FastAPI SDK) and returns a\n * frozen, fully-typed object. Composable fragments ({@link serverSettingsShape}\n * etc.) cover the common server/database/CORS knobs.\n */\n\nimport { z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/** Server bind/runtime settings. Defaults bind to localhost. */\nexport const serverSettingsShape = {\n HOST: z.string().default(\"127.0.0.1\"),\n PORT: z.coerce.number().int().min(0).max(65535).default(8000),\n DEBUG: looseBoolean(false),\n} as const;\n\n/** Database connection settings. */\nexport const databaseSettingsShape = {\n DATABASE_URL: z.string().default(\"sqlite://./app.db\"),\n} as const;\n\n/** CORS settings. `CORS_ORIGINS` is a comma-separated list. */\nexport const corsSettingsShape = {\n CORS_ORIGINS: z\n .string()\n .default(\"*\")\n .transform((value) =>\n value\n .split(\",\")\n .map((origin) => origin.trim())\n .filter((origin) => origin.length > 0),\n ),\n} as const;\n\n/** The combined base settings shape (server + database + CORS). */\nexport const baseAppSettingsShape = {\n ...serverSettingsShape,\n ...databaseSettingsShape,\n ...corsSettingsShape,\n} as const;\n\n/** A zod object built from {@link baseAppSettingsShape}. */\nexport const baseAppSettingsSchema = z.object(baseAppSettingsShape);\n\n/** The parsed shape of {@link baseAppSettingsSchema}. */\nexport type BaseAppSettings = z.infer<typeof baseAppSettingsSchema>;\n\n/**\n * Parse and freeze settings from an environment source.\n *\n * Extend the base shape with project fields:\n *\n * ```ts\n * const settings = loadSettings(\n * z.object({ ...baseAppSettingsShape, JWT_SECRET: z.string() }),\n * );\n * ```\n *\n * @param schema - The settings zod schema.\n * @param env - The environment source (defaults to `process.env`).\n * @returns The validated, frozen settings object.\n * @throws {z.ZodError} When required env vars are missing or malformed.\n */\nexport function loadSettings<S extends z.ZodType>(\n schema: S,\n env: NodeJS.ProcessEnv = process.env,\n): Readonly<z.infer<S>> {\n return Object.freeze(schema.parse(env));\n}\n","/**\n * Composable settings fragments covering common service dependencies,\n * mirroring `settings.mixins`.\n *\n * Each fragment is a plain object of zod fields keyed by the **environment\n * variable name** (matched case-sensitively, no prefix), with the same defaults\n * as the FastAPI SDK. Compose the ones a service needs onto\n * {@link baseAppSettingsShape} and parse with {@link loadSettings}:\n *\n * ```ts\n * import { baseAppSettingsShape, jwtSettingsShape, loadSettings, z } from \"tempest-express-sdk\";\n *\n * const settings = loadSettings(\n * z.object({ ...baseAppSettingsShape, ...jwtSettingsShape }),\n * );\n * settings.JWT_SECRET; // typed\n * ```\n *\n * Nothing here reads `process.env` on its own — `loadSettings` does, so the\n * fragments stay pure and testable.\n */\n\nimport { z } from \"@/schemas/base\";\nimport { looseBoolean } from \"@/schemas/fields\";\n\n/**\n * Parse an environment string into a boolean — the settings-facing name for\n * {@link looseBoolean}, which is the single implementation shared with the\n * query-string filters. Keeping one implementation is the point: two token\n * lists drift, and a boolean that parses one way in a filter and another way in\n * a settings field is the kind of divergence nothing catches.\n */\nexport { looseBoolean as envBoolean };\n\n/**\n * Parse a comma-separated environment string into a trimmed, non-empty list.\n *\n * @param defaultValue - The default CSV string when the variable is absent.\n * @returns A zod schema producing `string[]`.\n */\nexport function envList(defaultValue = \"\") {\n return z\n .string()\n .default(defaultValue)\n .transform((value) =>\n value\n .split(\",\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0),\n );\n}\n\n/** Structured logging configuration. */\nexport const logSettingsShape = {\n LOG_LEVEL: z.enum([\"DEBUG\", \"INFO\", \"WARNING\", \"ERROR\"]).default(\"INFO\"),\n LOG_JSON: looseBoolean(true),\n LOG_DIR: z.string().default(\"logs\"),\n} as const;\n\n/** Redis connection settings (cache / sessions / SSE broker). */\nexport const redisSettingsShape = {\n REDIS_URL: z.string().default(\"redis://localhost:6379/0\"),\n} as const;\n\n/** RabbitMQ connection settings (queue broker). */\nexport const rabbitmqSettingsShape = {\n RABBITMQ_URL: z.string().default(\"amqp://guest:guest@localhost:5672/\"),\n RABBITMQ_PREFETCH_COUNT: z.coerce.number().int().min(1).default(10),\n} as const;\n\n/** JWT signing/verification settings. */\nexport const jwtSettingsShape = {\n JWT_SECRET: z.string().default(\"change-me-change-me-change-me-32\"),\n JWT_ALGORITHM: z.string().default(\"HS256\"),\n JWT_ACCESS_TTL_SECONDS: z.coerce.number().int().min(1).default(3600),\n JWT_REFRESH_TTL_SECONDS: z.coerce\n .number()\n .int()\n .min(1)\n .default(86400 * 7),\n JWT_ISSUER: z.string().optional(),\n} as const;\n\n/** Opaque shared-secret token settings (`X-Token` guards). */\nexport const tokenSettingsShape = {\n TOKEN_SECRET: z.string().default(\"\"),\n} as const;\n\n/** SMTP email transport settings. */\nexport const emailSettingsShape = {\n SMTP_HOST: z.string().default(\"localhost\"),\n SMTP_PORT: z.coerce.number().int().min(1).max(65535).default(587),\n SMTP_USERNAME: z.string().optional(),\n SMTP_PASSWORD: z.string().optional(),\n SMTP_FROM_ADDR: z.string().default(\"noreply@example.com\"),\n SMTP_USE_TLS: looseBoolean(true),\n SMTP_USE_SSL: looseBoolean(false),\n SMTP_TIMEOUT_SECONDS: z.coerce.number().min(0).default(30),\n} as const;\n\n/** Local upload storage settings. */\nexport const uploadSettingsShape = {\n UPLOAD_DIR: z.string().default(\"./var/uploads\"),\n UPLOAD_MAX_SIZE_BYTES: z.coerce\n .number()\n .int()\n .min(0)\n .default(10 * 1024 * 1024),\n UPLOAD_ALLOWED_EXTENSIONS: envList(),\n UPLOAD_ALLOWED_MIMETYPES: envList(),\n} as const;\n\n/** MinIO / S3 object-storage settings. */\nexport const minioSettingsShape = {\n MINIO_ENDPOINT: z.string().default(\"localhost:9000\"),\n MINIO_ACCESS_KEY: z.string().default(\"minioadmin\"),\n MINIO_SECRET_KEY: z.string().default(\"minioadmin\"),\n MINIO_SECURE: looseBoolean(false),\n MINIO_REGION: z.string().default(\"us-east-1\"),\n MINIO_DEFAULT_BUCKET: z.string().default(\"uploads\"),\n MINIO_PUBLIC_ENDPOINT: z.string().optional(),\n MINIO_PUBLIC_SECURE: z\n .union([z.boolean(), z.string()])\n .optional()\n .transform((value) =>\n value === undefined\n ? undefined\n : typeof value === \"boolean\"\n ? value\n : [\"true\", \"1\", \"yes\", \"on\"].includes(value.trim().toLowerCase()),\n ),\n} as const;\n\n/** Web Push (VAPID) settings. */\nexport const webPushSettingsShape = {\n VAPID_PUBLIC_KEY: z.string().default(\"\"),\n VAPID_PRIVATE_KEY: z.string().default(\"\"),\n VAPID_SUBJECT: z.string().default(\"mailto:admin@example.com\"),\n WEBPUSH_DEFAULT_TTL_SECONDS: z.coerce.number().int().min(0).default(86400),\n} as const;\n\n/** Server-side session settings (cookie + TTL). */\nexport const sessionSettingsShape = {\n SESSION_TTL_SECONDS: z.coerce.number().int().min(1).default(86400),\n SESSION_SLIDING: looseBoolean(true),\n SESSION_COOKIE_NAME: z.string().default(\"tempest_session\"),\n SESSION_COOKIE_DOMAIN: z.string().optional(),\n SESSION_COOKIE_PATH: z.string().default(\"/\"),\n SESSION_COOKIE_SECURE: looseBoolean(true),\n SESSION_COOKIE_HTTPONLY: looseBoolean(true),\n SESSION_COOKIE_SAMESITE: z.enum([\"lax\", \"strict\", \"none\"]).default(\"lax\"),\n SESSION_ROTATE_ON_LOGIN: looseBoolean(true),\n} as const;\n\n/** WebSocket hub tuning. */\nexport const webSocketSettingsShape = {\n WS_HEARTBEAT_SECONDS: z.coerce.number().int().min(1).default(30),\n WS_HEARTBEAT_TIMEOUT_SECONDS: z.coerce.number().int().min(1).default(60),\n WS_MAX_CONNECTIONS_PER_USER: z.coerce.number().int().min(1).default(5),\n WS_MAX_MESSAGE_BYTES: z.coerce\n .number()\n .int()\n .min(1)\n .default(64 * 1024),\n} as const;\n\n/**\n * Authentication flow settings (signup/activation/reset/MFA + token delivery).\n * The FastAPI SDK's HTML-template fields (SSR activation/reset pages) are\n * omitted — this SDK ships the JSON auth API and defers rendering to a\n * decoupled frontend.\n */\nexport const authSettingsShape = {\n AUTH_AUTO_ACTIVATE: looseBoolean(false),\n AUTH_RETURN_TOKEN_IN_RESPONSE: looseBoolean(false),\n AUTH_ACTIVATION_TTL_SECONDS: z.coerce\n .number()\n .int()\n .min(1)\n .default(86400 * 7),\n AUTH_PASSWORD_RESET_TTL_SECONDS: z.coerce.number().int().min(1).default(3600),\n AUTH_ACTIVATION_URL_TEMPLATE: z\n .string()\n .default(\"http://localhost:3000/activate?token={token}\"),\n AUTH_PASSWORD_RESET_URL_TEMPLATE: z\n .string()\n .default(\"http://localhost:3000/reset-password?token={token}\"),\n AUTH_PASSWORD_MIN_LENGTH: z.coerce.number().int().min(1).default(12),\n AUTH_PASSWORD_REQUIRE_COMPLEXITY: looseBoolean(false),\n AUTH_DEFAULT_LOCALE: z.string().default(\"pt-BR\"),\n AUTH_MFA_ENABLED: looseBoolean(false),\n AUTH_MFA_ISSUER: z.string().default(\"Tempest\"),\n AUTH_MFA_RECOVERY_CODES_COUNT: z.coerce.number().int().min(0).default(10),\n AUTH_MFA_TOKEN_TTL_SECONDS: z.coerce.number().int().min(1).default(300),\n AUTH_MFA_VERIFY_WINDOW: z.coerce.number().int().min(0).default(1),\n AUTH_TOKEN_DELIVERY: z.enum([\"bearer\", \"cookie\", \"both\"]).default(\"bearer\"),\n AUTH_COOKIE_SECURE: looseBoolean(true),\n AUTH_COOKIE_SAMESITE: z.enum([\"lax\", \"strict\", \"none\"]).default(\"lax\"),\n AUTH_COOKIE_DOMAIN: z.string().optional(),\n AUTH_ACCESS_COOKIE_NAME: z.string().default(\"access_token\"),\n AUTH_REFRESH_COOKIE_NAME: z.string().default(\"refresh_token\"),\n} as const;\n","/**\n * Canonical base ORM model + opt-in column mixins, mirroring `db.model` /\n * `db.mixins`.\n *\n * `tempest-db-js` models are declarative classes whose fields are runtime\n * column builders. {@link BaseModel} gives every model the four columns the SDK\n * conventions require — `id` (UUID primary key), `isActive` (soft-delete flag),\n * `createdAt` and `updatedAt` (DB-managed timestamps) — so a concrete model\n * only declares its own domain columns plus a `tablename`.\n *\n * TypeScript has no multiple inheritance, so the \"mixins\" ship as reusable\n * column-builder factories ({@link deletedAtColumn} etc.) you assign as fields,\n * rather than as base classes.\n */\n\nimport { Model, column, sql } from \"tempest-db-js\";\n\n/** Convert `CamelCase` to `snake_case` (e.g. `OrderItem` → `order_item`). */\nfunction toSnakeCase(name: string): string {\n return name.replace(/(?<!^)(?=[A-Z])/g, \"_\").toLowerCase();\n}\n\n/**\n * Derive a conventional table name from a model class name: the trailing\n * `Model` suffix is stripped and the rest snake-cased (`UserModel` → `user`).\n *\n * @param className - The model class name.\n * @returns The derived table name.\n */\nexport function tableNameFor(className: string): string {\n return toSnakeCase(className.replace(/Model$/, \"\"));\n}\n\n/**\n * Abstract base for every model. Concrete models extend it, set a static\n * `tablename`, and declare their own columns:\n *\n * ```ts\n * class UserModel extends BaseModel {\n * static tablename = tableNameFor(\"UserModel\"); // \"user\"\n * email = column.varchar(320).notNull();\n * name = column.text().notNull();\n * }\n * ```\n */\nexport abstract class BaseModel extends Model {\n /** Primary key — a UUID v4 generated on insert. */\n id = column.uuid().primaryKey().default(sql.uuidv4());\n /** Soft-delete flag; `true` means the record is active. */\n isActive = column.boolean().notNull().default(true);\n /** Creation timestamp, set by the database on insert. */\n createdAt = column.datetime().notNull().default(sql.now());\n /** Last-update timestamp, refreshed by the database on every update. */\n updatedAt = column.datetime().notNull().default(sql.now()).onUpdate(sql.now());\n}\n\n/**\n * Soft-delete timestamp column (`deleted_at`). `null` while the row is alive;\n * set when soft-deleted. Pairs with {@link BaseModel.isActive}.\n *\n * @returns A nullable datetime column builder, defaulting to `null`.\n */\nexport function deletedAtColumn() {\n return column.datetime();\n}\n\n/**\n * `created_by` audit column: UUID of the user that created the row.\n *\n * @returns A nullable UUID column builder.\n */\nexport function createdByColumn() {\n return column.uuid();\n}\n\n/**\n * `updated_by` audit column: UUID of the user that last updated the row.\n *\n * @returns A nullable UUID column builder.\n */\nexport function updatedByColumn() {\n return column.uuid();\n}\n","/**\n * Optional base user + token models, mirroring `db.user_model` /\n * `db.user_token_model` / `db.user_refresh_token_model`.\n *\n * These are **opt-in** starting points: subclass one, set a `static tablename`,\n * and add the columns your domain needs. They extend {@link BaseModel}, so they\n * already carry `id` / `isActive` / `createdAt` / `updatedAt`.\n */\n\nimport { BaseModel } from \"@/db/model\";\nimport { column, sql } from \"tempest-db-js\";\n\n/**\n * Base for an authenticated user. Subclass it, set `tablename`, and add domain\n * columns (name, avatar, …):\n *\n * ```ts\n * class UserModel extends BaseUserModel {\n * static tablename = tableNameFor(\"UserModel\"); // \"user\"\n * name = column.text().notNull();\n * }\n * ```\n */\nexport abstract class BaseUserModel extends BaseModel {\n /** Login identifier; enforce uniqueness with a unique index in a migration. */\n email = column.varchar(320).notNull();\n /** The password hash (never the plaintext) — see `PasswordUtils`. */\n hashedPassword = column.text().notNull();\n /** Whether the user has administrative privileges. */\n isAdmin = column.boolean().notNull().default(false);\n /** Timestamp of the last successful login, or `null` if never. */\n lastLoginAt = column.datetime();\n}\n\n/** Purpose of a single-use user token. */\nexport const UserTokenPurpose = {\n ACTIVATION: \"activation\",\n PASSWORD_RESET: \"password_reset\",\n EMAIL_VERIFICATION: \"email_verification\",\n EMAIL_CHANGE: \"email_change\",\n} as const;\n\n/** A `UserTokenPurpose` value. */\nexport type UserTokenPurpose = (typeof UserTokenPurpose)[keyof typeof UserTokenPurpose];\n\n/**\n * Base for a single-use, hashed user token (activation, password reset, email\n * verification/change). Store only the **hash** of the token; compare hashes on\n * redemption.\n */\nexport abstract class BaseUserTokenModel extends BaseModel {\n /** Owning user id. */\n userId = column.uuid().notNull();\n /** Hash of the opaque token value. */\n tokenHash = column.text().notNull();\n /** Purpose discriminator (a {@link UserTokenPurpose} value). */\n purpose = column.varchar(32).notNull();\n /** When the token stops being valid. */\n expiresAt = column.datetime().notNull();\n /** When the token was consumed, or `null` while still usable. */\n usedAt = column.datetime();\n /** Optional JSON payload carried with the token (e.g. the pending email). */\n payload = column.json<Record<string, unknown>>();\n}\n\n/**\n * Base for a rotating refresh token. Rotation revokes the used token and issues\n * a new one in the same `familyId`; reuse of a revoked token in a family is the\n * signal to revoke the whole family (theft detection).\n */\nexport abstract class BaseUserRefreshTokenModel extends BaseModel {\n /** Owning user id. */\n userId = column.uuid().notNull();\n /** Hash of the opaque refresh token. */\n tokenHash = column.text().notNull();\n /** Rotation family — all tokens descended from one login share it. */\n familyId = column.uuid().notNull().default(sql.uuidv4());\n /** When the token expires. */\n expiresAt = column.datetime().notNull();\n /** When the token was rotated/consumed, or `null`. */\n usedAt = column.datetime();\n /** When the token was revoked, or `null` while active. */\n revokedAt = column.datetime();\n}\n","/**\n * Audit log model + snapshot/diff helpers, mirroring `db.audit`.\n *\n * `BaseAuditLogModel` records who changed what: the entity, its id, the action,\n * an actor and a before/after `changes` diff. {@link snapshot} freezes a row to\n * a plain record and {@link diffSnapshots} computes the changed-field diff — the\n * two together are what a service writes into an audit row on every mutation.\n */\n\nimport { BaseModel } from \"@/db/model\";\nimport { column } from \"tempest-db-js\";\n\n/** The kind of mutation an audit entry records. */\nexport const AuditAction = {\n CREATE: \"create\",\n UPDATE: \"update\",\n DELETE: \"delete\",\n} as const;\n\n/** An `AuditAction` value. */\nexport type AuditAction = (typeof AuditAction)[keyof typeof AuditAction];\n\n/** A per-field before/after change. */\nexport interface FieldChange {\n before: unknown;\n after: unknown;\n}\n\n/**\n * Freeze a row (ORM instance or plain object) into a plain, comparable record,\n * dropping keys whose value is a function.\n *\n * @param row - The row to snapshot.\n * @param exclude - Field names to omit (e.g. `[\"hashedPassword\"]`).\n * @returns A plain record of the row's own enumerable data fields.\n */\nexport function snapshot(\n row: Record<string, unknown>,\n exclude: readonly string[] = [],\n): Record<string, unknown> {\n const skip = new Set(exclude);\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(row)) {\n if (skip.has(key) || typeof value === \"function\") continue;\n out[key] = value;\n }\n return out;\n}\n\n/**\n * Compute the changed-field diff between two snapshots.\n *\n * @param before - The snapshot before the change.\n * @param after - The snapshot after the change.\n * @returns A map of changed field → `{ before, after }`; empty when nothing\n * changed. Keys present in only one side count as a change.\n */\nexport function diffSnapshots(\n before: Record<string, unknown>,\n after: Record<string, unknown>,\n): Record<string, FieldChange> {\n const changed: Record<string, FieldChange> = {};\n const keys = new Set([...Object.keys(before), ...Object.keys(after)]);\n for (const key of keys) {\n const oldValue = before[key];\n const newValue = after[key];\n if (\n !Object.is(oldValue, newValue) &&\n JSON.stringify(oldValue) !== JSON.stringify(newValue)\n ) {\n changed[key] = { before: oldValue, after: newValue };\n }\n }\n return changed;\n}\n\n/**\n * Base for an append-only audit log. Subclass it, set `tablename`, add indexes\n * on `entity` / `entityId` / `actor` in a migration.\n */\nexport abstract class BaseAuditLogModel extends BaseModel {\n /** Changed model name (e.g. `\"UserModel\"`). */\n entity = column.varchar(128).notNull();\n /** Changed row id, stored as text. */\n entityId = column.varchar(64).notNull();\n /** Mutation kind (an {@link AuditAction} value). */\n action = column.varchar(16).notNull();\n /** Who performed the change, or `null` for system/anonymous. */\n actor = column.varchar(128);\n /** Before/after diff, serialized as JSON. */\n changes = column.json<Record<string, FieldChange>>().notNull();\n /** Optional extra metadata (request id, ip, reason, …). */\n context = column.json<Record<string, unknown>>();\n}\n","/**\n * `TenantScopedRepository` — a `BaseRepository` that can't leak across tenants,\n * mirroring `db.tenant`.\n *\n * In a shared-schema multi-tenant database every tenant's rows live in the same\n * table, told apart by a `tenantId` column. Forget one `WHERE tenant_id = ?` and\n * tenant A reads (or deletes) tenant B's data. This repository binds a tenant id\n * at construction and injects it into every read filter and every write — the\n * scoping is invisible at the call site.\n */\n\nimport {\n BaseRepository,\n type InferInsert,\n type InferModel,\n type ModelClass,\n type PaginationFilter,\n type PaginationResult,\n RecordNotFound,\n type WhereInput,\n} from \"tempest-db-js\";\n\n/**\n * A repository whose every operation is scoped to a single tenant. Use it\n * exactly like {@link BaseRepository}.\n *\n * ```ts\n * const repo = new TenantScopedRepository(OrderModel, session, tenantId);\n * await repo.list(); // WHERE tenant_id = tenantId\n * await repo.create({ total: \"10\" }); // tenant_id stamped automatically\n * ```\n *\n * @typeParam C - the model class (must declare the tenant column).\n */\nexport class TenantScopedRepository<\n C extends ModelClass,\n TF extends string = \"tenantId\",\n> extends BaseRepository<C> {\n private readonly tenantId: unknown;\n private readonly tenantField: string;\n private readonly modelClass: C;\n\n /**\n * @param model - The model class (must have the `tenantField` column).\n * @param session - The async session.\n * @param tenantId - The tenant every operation is scoped to.\n * @param tenantField - Name of the tenant column. Default `\"tenantId\"`.\n */\n constructor(\n model: C,\n session: ConstructorParameters<typeof BaseRepository<C>>[1],\n tenantId: unknown,\n tenantField: TF = \"tenantId\" as TF,\n ) {\n super(model, session);\n this.modelClass = model;\n this.tenantId = tenantId;\n this.tenantField = tenantField;\n }\n\n /** Merge the tenant predicate into a filter object. */\n private scoped(filters?: WhereInput<InferModel<C>>): WhereInput<InferModel<C>> {\n return { ...(filters ?? {}), [this.tenantField]: this.tenantId } as WhereInput<\n InferModel<C>\n >;\n }\n\n /** Stamp the tenant id onto an insert payload. */\n private stamped<T extends Record<string, unknown>>(data: T): T {\n return { ...data, [this.tenantField]: this.tenantId };\n }\n\n override list(filters?: WhereInput<InferModel<C>>): Promise<InferModel<C>[]> {\n return super.list(this.scoped(filters));\n }\n\n override first(filters?: WhereInput<InferModel<C>>): Promise<InferModel<C> | null> {\n return super.first(this.scoped(filters));\n }\n\n override exists(filters: WhereInput<InferModel<C>>): Promise<boolean> {\n return super.exists(this.scoped(filters));\n }\n\n override count(filters?: WhereInput<InferModel<C>>): Promise<number> {\n return super.count(this.scoped(filters));\n }\n\n /** Fetch by id **within the tenant**; throws `RecordNotFound` across tenants. */\n override async getById(id: unknown): Promise<InferModel<C>> {\n const row = await super.first(this.scoped({ id } as WhereInput<InferModel<C>>));\n if (row === null) {\n throw new RecordNotFound(\n (this.modelClass as { tablename?: string }).tablename ?? \"row\",\n id,\n );\n }\n return row;\n }\n\n override getByIdOrNull(id: unknown): Promise<InferModel<C> | null> {\n return super.first(this.scoped({ id } as WhereInput<InferModel<C>>));\n }\n\n /** Insert one row; the tenant id is stamped for you (don't pass it). */\n override create(data: Omit<InferInsert<C>, TF>): Promise<InferModel<C>> {\n return super.create(this.stamped(data as Record<string, unknown>) as InferInsert<C>);\n }\n\n /** Insert many rows; the tenant id is stamped onto each. */\n override createMany(\n data: readonly Omit<InferInsert<C>, TF>[],\n ): Promise<InferModel<C>[]> {\n return super.createMany(\n data.map((d) => this.stamped(d as Record<string, unknown>) as InferInsert<C>),\n );\n }\n\n override update(\n filters: WhereInput<InferModel<C>>,\n set: Partial<InferModel<C>>,\n ): Promise<number> {\n // Never let a caller move a row to another tenant.\n const { [this.tenantField]: _drop, ...safeSet } = set as Record<string, unknown>;\n return super.update(this.scoped(filters), safeSet as Partial<InferModel<C>>);\n }\n\n override delete(filters: WhereInput<InferModel<C>>): Promise<number> {\n return super.delete(this.scoped(filters));\n }\n\n override paginate(\n filter: PaginationFilter<InferModel<C>> = {},\n ): Promise<PaginationResult<InferModel<C>>> {\n return super.paginate({ ...filter, filters: this.scoped(filter.filters) });\n }\n}\n","/**\n * Transactional outbox model + relay, mirroring `db.outbox`.\n *\n * Write a domain change and its \"event to publish\" **in the same transaction**\n * (into `BaseOutboxModel`), so the event can never be lost even if the broker is\n * down at write time. {@link OutboxRelay} then polls pending rows and publishes\n * them with at-least-once delivery, retrying failures with a backoff.\n */\n\nimport { JSONLogger } from \"@/core\";\nimport { BaseModel } from \"@/db/model\";\nimport type { BaseRepository, InferModel, ModelClass } from \"tempest-db-js\";\nimport { column, sql } from \"tempest-db-js\";\n\n/** Delivery state of an outbox event. */\nexport const OutboxStatus = {\n PENDING: \"pending\",\n SENT: \"sent\",\n FAILED: \"failed\",\n} as const;\n\n/** An `OutboxStatus` value. */\nexport type OutboxStatus = (typeof OutboxStatus)[keyof typeof OutboxStatus];\n\n/**\n * Base for a transactional outbox row. Subclass it and set `tablename`. Insert a\n * row in the same transaction as the write it describes.\n */\nexport abstract class BaseOutboxModel extends BaseModel {\n /** Destination topic / routing key. */\n topic = column.varchar(255).notNull();\n /** The event body, serialized as JSON. */\n payload = column.json<Record<string, unknown>>().notNull();\n /** Delivery state (an {@link OutboxStatus} value). */\n status = column.varchar(16).notNull().default(OutboxStatus.PENDING);\n /** How many delivery attempts have been made. */\n attempts = column.integer().notNull().default(0);\n /** Give up (mark `failed`) after this many attempts. */\n maxAttempts = column.integer().notNull().default(5);\n /** Earliest time the row may be delivered (drives retry backoff). */\n availableAt = column.datetime().notNull().default(sql.now());\n /** When the row was successfully delivered, or `null`. */\n sentAt = column.datetime();\n /** The last delivery error message, or `null`. */\n lastError = column.text();\n}\n\n/** Publishes one event to the broker; throws to signal a delivery failure. */\nexport type OutboxPublisher = (\n topic: string,\n payload: Record<string, unknown>,\n) => Promise<void>;\n\n/** Options for {@link OutboxRelay}. */\nexport interface OutboxRelayOptions {\n /** Max rows to drain per pass. Default `100`. */\n batchSize?: number;\n /** Base backoff (seconds) between retries; scaled by attempt count. Default `30`. */\n retryBackoffSeconds?: number;\n}\n\n/**\n * Polls a `BaseOutboxModel` table and publishes pending events with retries.\n *\n * @typeParam C - the concrete outbox model class.\n */\nexport class OutboxRelay<C extends ModelClass> {\n private readonly logger = new JSONLogger(\"tempest_express_sdk.db.outbox\");\n private readonly batchSize: number;\n private readonly retryBackoffSeconds: number;\n private running = false;\n\n /**\n * @param repository - Repository over the outbox model.\n * @param publish - Callback that delivers one event to the broker.\n * @param options - Batch size and retry backoff.\n */\n constructor(\n private readonly repository: BaseRepository<C>,\n private readonly publish: OutboxPublisher,\n options: OutboxRelayOptions = {},\n ) {\n this.batchSize = options.batchSize ?? 100;\n this.retryBackoffSeconds = options.retryBackoffSeconds ?? 30;\n }\n\n /**\n * Deliver one batch of due pending events.\n *\n * @param now - The current time (injectable for tests). Defaults to `new Date()`.\n * @returns The number of events successfully delivered.\n */\n async drainOnce(now: Date = new Date()): Promise<number> {\n // `list` has no LIMIT; fetch the due pending rows and process a batch.\n const due = (await this.repository.list({\n status: OutboxStatus.PENDING,\n availableAt: { lte: now },\n } as never)) as Array<InferModel<C> & Record<string, unknown>>;\n\n let delivered = 0;\n for (const event of due.slice(0, this.batchSize)) {\n try {\n await this.publish(\n event.topic as string,\n event.payload as Record<string, unknown>,\n );\n await this.repository.update(\n { id: event.id } as never,\n {\n status: OutboxStatus.SENT,\n sentAt: now,\n lastError: null,\n } as never,\n );\n delivered += 1;\n } catch (error) {\n await this.markFailure(event, error, now);\n }\n }\n return delivered;\n }\n\n private async markFailure(\n event: InferModel<C> & Record<string, unknown>,\n error: unknown,\n now: Date,\n ): Promise<void> {\n const attempts = (event.attempts as number) + 1;\n const maxAttempts = event.maxAttempts as number;\n const message = error instanceof Error ? error.message : String(error);\n const exhausted = attempts >= maxAttempts;\n const nextAvailable = new Date(\n now.getTime() + attempts * this.retryBackoffSeconds * 1000,\n );\n await this.repository.update(\n { id: event.id } as never,\n {\n attempts,\n status: exhausted ? OutboxStatus.FAILED : OutboxStatus.PENDING,\n availableAt: exhausted ? (event.availableAt as Date) : nextAvailable,\n lastError: message,\n } as never,\n );\n this.logger.warning(\"outbox delivery failed\", {\n id: String(event.id),\n topic: String(event.topic),\n attempts,\n exhausted,\n });\n }\n\n /**\n * Run `drainOnce` on an interval until {@link stop} is called.\n *\n * @param intervalMs - Delay between passes in milliseconds. Default `1000`.\n */\n async run(intervalMs = 1000): Promise<void> {\n this.running = true;\n while (this.running) {\n try {\n await this.drainOnce();\n } catch (error) {\n this.logger.error(\"outbox relay pass failed\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n\n /** Stop the {@link run} loop after the current pass. */\n stop(): void {\n this.running = false;\n }\n}\n","/**\n * Slow-query logging, mirroring `db.slow_query`.\n *\n * `tempest-db-js` exposes an `onQuery` hook with the SQL + params but **no\n * duration**, so timing has to happen at the driver boundary. This wraps an\n * `AsyncDriver` so every statement is timed and any that meets or exceeds a\n * threshold is logged — including statements run inside a reserved transaction.\n *\n * ```ts\n * import { AsyncEngine, NodeSqliteDriver } from \"tempest-express-sdk\";\n * import { wrapWithSlowQueryLog } from \"tempest-express-sdk\";\n *\n * const sync = NodeSqliteDriver.open(\"app.db\");\n * const timed = wrapWithSlowQueryLog(\n * { execute: (s, p) => Promise.resolve(sync.execute(s, p)), close: async () => sync.close() },\n * { thresholdMs: 200 },\n * );\n * const engine = new AsyncEngine(timed, \"sqlite\");\n * ```\n */\n\nimport { JSONLogger, type LogLevel } from \"@/core\";\nimport type { AsyncDriver } from \"tempest-db-js\";\n\n/** Options for {@link wrapWithSlowQueryLog}. */\nexport interface SlowQueryOptions {\n /** Statements at or above this many ms are logged. Default `500`. */\n thresholdMs?: number;\n /** Level for the slow-query lines. Default `\"warning\"`. */\n level?: LogLevel;\n /** Include the bound params in the log line. **Dev only** — may carry PII. */\n logParameters?: boolean;\n /** Logger name. Default `tempest_express_sdk.db.slow_query`. */\n loggerName?: string;\n}\n\n/**\n * Wrap an `AsyncDriver` so slow statements are logged. The returned driver is a\n * drop-in for {@link AsyncEngine}; `iterate` and `reserve` (transactions) are\n * preserved and their statements timed too.\n *\n * @param driver - The driver to wrap.\n * @param options - Threshold, level and whether to log params.\n * @returns A timing driver delegating to `driver`.\n */\nexport function wrapWithSlowQueryLog(\n driver: AsyncDriver,\n options: SlowQueryOptions = {},\n): AsyncDriver {\n const thresholdMs = options.thresholdMs ?? 500;\n const level = options.level ?? \"warning\";\n const logParameters = options.logParameters ?? false;\n const logger = new JSONLogger(\n options.loggerName ?? \"tempest_express_sdk.db.slow_query\",\n );\n\n // Wrap a given `execute` with timing so both the pooled driver and any\n // reserved (transaction-pinned) connection log slow statements correctly.\n const timed = (exec: AsyncDriver[\"execute\"]): AsyncDriver[\"execute\"] => {\n return async (sql, params) => {\n const start = process.hrtime.bigint();\n try {\n return await exec(sql, params);\n } finally {\n const durationMs = Number(process.hrtime.bigint() - start) / 1e6;\n if (durationMs >= thresholdMs) {\n logger.log(level, \"slow query\", {\n sql,\n durationMs: Math.round(durationMs * 1000) / 1000,\n ...(logParameters ? { params } : {}),\n });\n }\n }\n };\n };\n\n const wrapped: AsyncDriver = {\n execute: timed(driver.execute.bind(driver)),\n close: () => driver.close(),\n };\n if (driver.iterate) {\n wrapped.iterate = (sql, params) => driver.iterate?.(sql, params) as never;\n }\n if (driver.reserve) {\n wrapped.reserve = async () => {\n const reserved = await driver.reserve?.();\n if (!reserved) throw new Error(\"driver.reserve() returned nothing\");\n return {\n execute: timed(reserved.execute.bind(reserved)),\n close: () => reserved.close(),\n release: () => reserved.release(),\n ...(reserved.iterate\n ? { iterate: (sql, params) => reserved.iterate?.(sql, params) as never }\n : {}),\n };\n };\n }\n return wrapped;\n}\n","/**\n * Database backup helper, mirroring `db.backup`.\n *\n * `backupDatabase` detects the dialect from the URL and produces a backup file:\n * a `pg_dump` for PostgreSQL, a file copy for SQLite. It shells out to `pg_dump`\n * for Postgres (must be on `PATH`), so the heavy lifting stays with the battle-\n * tested tool rather than a hand-rolled dump.\n */\n\nimport { spawn } from \"node:child_process\";\nimport { copyFile } from \"node:fs/promises\";\nimport { detectDialect } from \"tempest-db-js\";\n\n/** Options for {@link backupDatabase}. */\nexport interface BackupOptions {\n /** Path to the `pg_dump` binary. Default `\"pg_dump\"` (resolved on `PATH`). */\n pgDumpPath?: string;\n /** Extra `pg_dump` arguments (e.g. `[\"--no-owner\", \"-Fc\"]`). */\n pgDumpArgs?: string[];\n}\n\n/** Resolve the on-disk file path from a `sqlite://` URL. */\nfunction sqlitePath(url: string): string {\n // sqlite://./app.db, sqlite:///abs/app.db, sqlite://:memory:\n const withoutScheme = url.replace(/^sqlite:\\/\\//, \"\");\n if (withoutScheme === \":memory:\" || withoutScheme === \"\") {\n throw new Error(\"Cannot back up an in-memory SQLite database\");\n }\n // sqlite:///abs → \"/abs\"; sqlite://./rel → \"./rel\"\n return withoutScheme.startsWith(\"/\")\n ? withoutScheme\n : withoutScheme.replace(/^\\.?\\//, \"./\");\n}\n\n/**\n * Back up a database to `destPath`.\n *\n * @param databaseUrl - The connection URL (SQLite or PostgreSQL).\n * @param destPath - Where to write the backup.\n * @param options - `pg_dump` binary path and extra args (Postgres only).\n * @returns The `destPath` on success.\n * @throws {Error} For in-memory SQLite, an unsupported dialect, or a non-zero\n * `pg_dump` exit.\n */\nexport async function backupDatabase(\n databaseUrl: string,\n destPath: string,\n options: BackupOptions = {},\n): Promise<string> {\n const dialect = detectDialect(databaseUrl);\n\n if (dialect === \"sqlite\") {\n await copyFile(sqlitePath(databaseUrl), destPath);\n return destPath;\n }\n\n if (dialect === \"postgresql\") {\n const bin = options.pgDumpPath ?? \"pg_dump\";\n const args = [...(options.pgDumpArgs ?? []), \"-f\", destPath, databaseUrl];\n await runPgDump(bin, args);\n return destPath;\n }\n\n throw new Error(`backupDatabase does not support the '${dialect}' dialect`);\n}\n\nfunction runPgDump(bin: string, args: string[]): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(bin, args, { stdio: [\"ignore\", \"ignore\", \"pipe\"] });\n let stderr = \"\";\n child.stderr?.on(\"data\", (chunk) => {\n stderr += String(chunk);\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code === 0) resolve();\n else reject(new Error(`pg_dump exited with code ${code}: ${stderr.trim()}`));\n });\n });\n}\n","/**\n * Generic async service over a `tempest-db-js` repository.\n *\n * Mirrors `services.base.BaseService`: a thin business-logic layer wrapping a\n * `BaseRepository`. Unlike a pure pass-through, every read method maps the raw\n * ORM row through {@link ResponseMapper} into the response shape routers and\n * controllers consume — that mapping is the layer's reason to exist. Override\n * methods that need orchestration (multi-repository writes, side effects,\n * domain rules); leave the rest.\n */\n\nimport type {\n BaseRepository,\n InferInsert,\n InferModel,\n ModelClass,\n PaginationResult,\n RepositoryPaginationFilter,\n WhereInput,\n} from \"@/db\";\n\n/** Maps a raw ORM row to the response shape (sync or async). */\nexport type ResponseMapper<C extends ModelClass, Resp> = (\n row: InferModel<C>,\n) => Resp | Promise<Resp>;\n\nexport class BaseService<C extends ModelClass, Resp> {\n /**\n * @param repository - The repository to delegate persistence to.\n * @param mapToResponse - Maps a raw row to the response shape.\n */\n constructor(\n protected readonly repository: BaseRepository<C>,\n protected readonly mapToResponse: ResponseMapper<C, Resp>,\n ) {}\n\n /** Map a batch of rows to responses, preserving order. */\n protected mapMany(rows: InferModel<C>[]): Promise<Resp[]> {\n return Promise.all(rows.map((row) => this.mapToResponse(row)));\n }\n\n /**\n * Fetch a single record by primary key and map it.\n *\n * @param id - The primary-key value.\n * @returns The mapped response.\n * @throws {RecordNotFound} When no row matches (404 convention).\n */\n async getById(id: unknown): Promise<Resp> {\n return this.mapToResponse(await this.repository.getById(id));\n }\n\n /**\n * List records matching `filters` (or all), mapped to responses.\n *\n * @param filters - Optional filter conditions.\n * @returns The mapped responses; `[]` when nothing matches.\n */\n async list(filters?: WhereInput<InferModel<C>>): Promise<Resp[]> {\n return this.mapMany(await this.repository.list(filters));\n }\n\n /**\n * Count records matching `filters` (or the whole table).\n *\n * @param filters - Optional filter conditions.\n * @returns The matching row count.\n */\n async count(filters?: WhereInput<InferModel<C>>): Promise<number> {\n return this.repository.count(filters);\n }\n\n /**\n * Insert one record and map the created row.\n *\n * @param data - The insert payload.\n * @returns The mapped, created response.\n */\n async create(data: InferInsert<C>): Promise<Resp> {\n return this.mapToResponse(await this.repository.create(data));\n }\n\n /**\n * Update records matching `filters`.\n *\n * @param filters - Which rows to update.\n * @param set - The partial column values to write.\n * @returns The number of rows affected.\n */\n async update(\n filters: WhereInput<InferModel<C>>,\n set: Partial<InferModel<C>>,\n ): Promise<number> {\n return this.repository.update(filters, set);\n }\n\n /**\n * Delete records matching `filters`.\n *\n * @param filters - Which rows to delete.\n * @returns The number of rows affected.\n */\n async delete(filters: WhereInput<InferModel<C>>): Promise<number> {\n return this.repository.delete(filters);\n }\n\n /**\n * Fetch a page of records with the items mapped to responses.\n *\n * @param filter - Page, size, ordering and filters.\n * @returns The page envelope with mapped items.\n */\n async paginate(\n filter: RepositoryPaginationFilter<InferModel<C>> = {},\n ): Promise<PaginationResult<Resp>> {\n const page = await this.repository.paginate(filter);\n return { ...page, items: await this.mapMany(page.items) };\n }\n}\n","/**\n * Generic controller bridging routers and services.\n *\n * Mirrors `controllers.base.BaseController`. Per the SDK layering\n * (router → controller → service → repository), controllers are an intentional\n * abstraction boundary kept present even when no orchestration is required, so\n * the import graph stays uniform across services. Override a method when one\n * endpoint must call several services or apply cross-cutting policy; otherwise\n * the thin delegations stand in for the boundary.\n */\n\nimport type {\n InferInsert,\n InferModel,\n ModelClass,\n PaginationResult,\n RepositoryPaginationFilter,\n WhereInput,\n} from \"@/db\";\nimport type { BaseService } from \"@/services/base\";\n\nexport class BaseController<C extends ModelClass, Resp> {\n /**\n * @param service - The service the controller delegates to.\n */\n constructor(protected readonly service: BaseService<C, Resp>) {}\n\n /**\n * Fetch one record by primary key.\n *\n * @param id - The primary-key value.\n * @returns The mapped response.\n */\n getById(id: unknown): Promise<Resp> {\n return this.service.getById(id);\n }\n\n /**\n * List records matching `filters`.\n *\n * @param filters - Optional filter conditions.\n * @returns The mapped responses.\n */\n list(filters?: WhereInput<InferModel<C>>): Promise<Resp[]> {\n return this.service.list(filters);\n }\n\n /**\n * Count records matching `filters`.\n *\n * @param filters - Optional filter conditions.\n * @returns The matching row count.\n */\n count(filters?: WhereInput<InferModel<C>>): Promise<number> {\n return this.service.count(filters);\n }\n\n /**\n * Create a record.\n *\n * @param data - The insert payload.\n * @returns The mapped, created response.\n */\n create(data: InferInsert<C>): Promise<Resp> {\n return this.service.create(data);\n }\n\n /**\n * Update records matching `filters`.\n *\n * @param filters - Which rows to update.\n * @param set - The partial column values to write.\n * @returns The number of rows affected.\n */\n update(\n filters: WhereInput<InferModel<C>>,\n set: Partial<InferModel<C>>,\n ): Promise<number> {\n return this.service.update(filters, set);\n }\n\n /**\n * Delete records matching `filters`.\n *\n * @param filters - Which rows to delete.\n * @returns The number of rows affected.\n */\n delete(filters: WhereInput<InferModel<C>>): Promise<number> {\n return this.service.delete(filters);\n }\n\n /**\n * Fetch a page of records.\n *\n * @param filter - Page, size, ordering and filters.\n * @returns The page envelope with mapped items.\n */\n paginate(\n filter: RepositoryPaginationFilter<InferModel<C>> = {},\n ): Promise<PaginationResult<Resp>> {\n return this.service.paginate(filter);\n }\n}\n","/**\n * Brazilian identity/contact helpers, mirroring `utils.regex`.\n *\n * Patterns, validators (format + check digits), normalizers, and ready-to-use\n * Zod field schemas for the fields that show up in almost every BR API: CPF,\n * CNPJ, CEP and phone. Validators accept masked or unmasked input; normalizers\n * strip masks to a canonical digits-only form (and throw on invalid input).\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** Match a CPF in masked (`000.000.000-00`) or raw form. */\nexport const CPF_PATTERN = /^\\d{3}\\.?\\d{3}\\.?\\d{3}-?\\d{2}$/;\n/** Match a CNPJ in masked (`00.000.000/0000-00`) or raw form. */\nexport const CNPJ_PATTERN = /^\\d{2}\\.?\\d{3}\\.?\\d{3}\\/?\\d{4}-?\\d{2}$/;\n/** Match a BR phone with optional `+55`, DDD, mask or 9th digit. */\nexport const PHONE_BR_PATTERN = /^(?:\\+?55\\s?)?(?:\\(?\\d{2}\\)?\\s?)?9?\\d{4}[-\\s]?\\d{4}$/;\n/** Match a CEP in masked (`00000-000`) or raw form. */\nexport const CEP_PATTERN = /^\\d{5}-?\\d{3}$/;\n\n/**\n * Strip every non-digit character from `value`.\n *\n * @param value - The raw input (masked CPF, phone, etc.).\n * @returns A string of only the digits in `value`.\n */\nexport function onlyDigits(value: string): string {\n return value.replace(/\\D/g, \"\");\n}\n\n/** Validate the two CPF check digits over an 11-digit string. */\nfunction cpfCheckDigits(digits: string): boolean {\n if (digits.length !== 11 || new Set(digits).size === 1) return false;\n for (const size of [9, 10]) {\n let total = 0;\n for (let i = 0; i < size; i++) total += Number(digits[i]) * (size + 1 - i);\n let check = (total * 10) % 11;\n if (check === 10) check = 0;\n if (check !== Number(digits[size])) return false;\n }\n return true;\n}\n\n/** Validate the two CNPJ check digits over a 14-digit string. */\nfunction cnpjCheckDigits(digits: string): boolean {\n if (digits.length !== 14 || new Set(digits).size === 1) return false;\n const first = [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2];\n const second = [6, ...first];\n for (const [size, weights] of [\n [12, first],\n [13, second],\n ] as const) {\n let total = 0;\n for (let i = 0; i < size; i++) total += Number(digits[i]) * (weights[i] ?? 0);\n const rest = total % 11;\n const check = rest < 2 ? 0 : 11 - rest;\n if (check !== Number(digits[size])) return false;\n }\n return true;\n}\n\n/** Whether `value` is a syntactically valid CPF (format + check digits). */\nexport function isValidCpf(value: string): boolean {\n return CPF_PATTERN.test(value) && cpfCheckDigits(onlyDigits(value));\n}\n\n/** Whether `value` is a syntactically valid CNPJ (format + check digits). */\nexport function isValidCnpj(value: string): boolean {\n return CNPJ_PATTERN.test(value) && cnpjCheckDigits(onlyDigits(value));\n}\n\n/** Whether `value` is a valid CPF or CNPJ. */\nexport function isValidCpfCnpj(value: string): boolean {\n const digits = onlyDigits(value);\n if (digits.length === 11) return isValidCpf(value);\n if (digits.length === 14) return isValidCnpj(value);\n return false;\n}\n\n/** Whether `value` looks like a CEP (eight-digit shape; no check digits). */\nexport function isValidCep(value: string): boolean {\n return CEP_PATTERN.test(value);\n}\n\n/** Whether `value` looks like a BR phone (10 or 11 digits, optional `+55`). */\nexport function isValidPhoneBr(value: string): boolean {\n if (!PHONE_BR_PATTERN.test(value)) return false;\n let digits = onlyDigits(value);\n if (digits.startsWith(\"55\") && (digits.length === 12 || digits.length === 13)) {\n digits = digits.slice(2);\n }\n return digits.length === 10 || digits.length === 11;\n}\n\n/** Normalize a CPF to 11 digits, throwing when invalid. */\nexport function normalizeCpf(value: string): string {\n if (!isValidCpf(value)) throw new Error(\"invalid CPF\");\n return onlyDigits(value);\n}\n\n/** Normalize a CNPJ to 14 digits, throwing when invalid. */\nexport function normalizeCnpj(value: string): string {\n if (!isValidCnpj(value)) throw new Error(\"invalid CNPJ\");\n return onlyDigits(value);\n}\n\n/** Normalize a CPF/CNPJ to digits only, throwing when invalid. */\nexport function normalizeCpfCnpj(value: string): string {\n if (!isValidCpfCnpj(value)) throw new Error(\"invalid CPF/CNPJ\");\n return onlyDigits(value);\n}\n\n/** Normalize a CEP to 8 digits, throwing when invalid. */\nexport function normalizeCep(value: string): string {\n if (!isValidCep(value)) throw new Error(\"invalid CEP\");\n return onlyDigits(value);\n}\n\n/** Normalize a BR phone to digits only, throwing when invalid. */\nexport function normalizePhoneBr(value: string): string {\n if (!isValidPhoneBr(value)) throw new Error(\"invalid BR phone\");\n return onlyDigits(value);\n}\n\n/** Zod field: validates a CPF and normalizes it to 11 digits. */\nexport const cpfField = z\n .string()\n .refine(isValidCpf, { message: \"invalid CPF\" })\n .transform(onlyDigits);\n/** Zod field: validates a CNPJ and normalizes it to 14 digits. */\nexport const cnpjField = z\n .string()\n .refine(isValidCnpj, { message: \"invalid CNPJ\" })\n .transform(onlyDigits);\n/** Zod field: accepts either a CPF or a CNPJ, normalized to digits. */\nexport const cpfOrCnpjField = z\n .string()\n .refine(isValidCpfCnpj, { message: \"invalid CPF/CNPJ\" })\n .transform(onlyDigits);\n/** Zod field: validates a CEP and normalizes it to 8 digits. */\nexport const cepField = z\n .string()\n .refine(isValidCep, { message: \"invalid CEP\" })\n .transform(onlyDigits);\n/** Zod field: validates a BR phone and normalizes it to digits. */\nexport const phoneBrField = z\n .string()\n .refine(isValidPhoneBr, { message: \"invalid BR phone\" })\n .transform(onlyDigits);\n","[\n {\n \"uf\": \"AC\",\n \"name\": \"Acre\",\n \"cities\": [\n \"Acrelândia\",\n \"Assis Brasil\",\n \"Brasiléia\",\n \"Bujari\",\n \"Capixaba\",\n \"Cruzeiro do Sul\",\n \"Epitaciolândia\",\n \"Feijó\",\n \"Jordão\",\n \"Mâncio Lima\",\n \"Manoel Urbano\",\n \"Marechal Thaumaturgo\",\n \"Plácido de Castro\",\n \"Porto Acre\",\n \"Porto Walter\",\n \"Rio Branco\",\n \"Rodrigues Alves\",\n \"Santa Rosa do Purus\",\n \"Sena Madureira\",\n \"Senador Guiomard\",\n \"Tarauacá\",\n \"Xapuri\"\n ]\n },\n {\n \"uf\": \"AL\",\n \"name\": \"Alagoas\",\n \"cities\": [\n \"Água Branca\",\n \"Anadia\",\n \"Arapiraca\",\n \"Atalaia\",\n \"Barra de Santo Antônio\",\n \"Barra de São Miguel\",\n \"Batalha\",\n \"Belém\",\n \"Belo Monte\",\n \"Boca da Mata\",\n \"Branquinha\",\n \"Cacimbinhas\",\n \"Cajueiro\",\n \"Campestre\",\n \"Campo Alegre\",\n \"Campo Grande\",\n \"Canapi\",\n \"Capela\",\n \"Carneiros\",\n \"Chã Preta\",\n \"Coité do Nóia\",\n \"Colônia Leopoldina\",\n \"Coqueiro Seco\",\n \"Coruripe\",\n \"Craíbas\",\n \"Delmiro Gouveia\",\n \"Dois Riachos\",\n \"Estrela de Alagoas\",\n \"Feira Grande\",\n \"Feliz Deserto\",\n \"Flexeiras\",\n \"Girau do Ponciano\",\n \"Ibateguara\",\n \"Igaci\",\n \"Igreja Nova\",\n \"Inhapi\",\n \"Jacaré dos Homens\",\n \"Jacuípe\",\n \"Japaratinga\",\n \"Jaramataia\",\n \"Jequiá da Praia\",\n \"Joaquim Gomes\",\n \"Jundiá\",\n \"Junqueiro\",\n \"Lagoa da Canoa\",\n \"Limoeiro de Anadia\",\n \"Maceió\",\n \"Major Isidoro\",\n \"Mar Vermelho\",\n \"Maragogi\",\n \"Maravilha\",\n \"Marechal Deodoro\",\n \"Maribondo\",\n \"Mata Grande\",\n \"Matriz de Camaragibe\",\n \"Messias\",\n \"Minador do Negrão\",\n \"Monteirópolis\",\n \"Murici\",\n \"Novo Lino\",\n \"Olho d'Água das Flores\",\n \"Olho d'Água do Casado\",\n \"Olho d'Água Grande\",\n \"Olivença\",\n \"Ouro Branco\",\n \"Palestina\",\n \"Palmeira dos Índios\",\n \"Pão de Açúcar\",\n \"Pariconha\",\n \"Paripueira\",\n \"Passo de Camaragibe\",\n \"Paulo Jacinto\",\n \"Penedo\",\n \"Piaçabuçu\",\n \"Pilar\",\n \"Pindoba\",\n \"Piranhas\",\n \"Poço das Trincheiras\",\n \"Porto Calvo\",\n \"Porto de Pedras\",\n \"Porto Real do Colégio\",\n \"Quebrangulo\",\n \"Rio Largo\",\n \"Roteiro\",\n \"Santa Luzia do Norte\",\n \"Santana do Ipanema\",\n \"Santana do Mundaú\",\n \"São Brás\",\n \"São José da Laje\",\n \"São José da Tapera\",\n \"São Luís do Quitunde\",\n \"São Miguel dos Campos\",\n \"São Miguel dos Milagres\",\n \"São Sebastião\",\n \"Satuba\",\n \"Senador Rui Palmeira\",\n \"Tanque d'Arca\",\n \"Taquarana\",\n \"Teotônio Vilela\",\n \"Traipu\",\n \"União dos Palmares\",\n \"Viçosa\"\n ]\n },\n {\n \"uf\": \"AM\",\n \"name\": \"Amazonas\",\n \"cities\": [\n \"Alvarães\",\n \"Amaturá\",\n \"Anamã\",\n \"Anori\",\n \"Apuí\",\n \"Atalaia do Norte\",\n \"Autazes\",\n \"Barcelos\",\n \"Barreirinha\",\n \"Benjamin Constant\",\n \"Beruri\",\n \"Boa Vista do Ramos\",\n \"Boca do Acre\",\n \"Borba\",\n \"Caapiranga\",\n \"Canutama\",\n \"Carauari\",\n \"Careiro\",\n \"Careiro da Várzea\",\n \"Coari\",\n \"Codajás\",\n \"Eirunepé\",\n \"Envira\",\n \"Fonte Boa\",\n \"Guajará\",\n \"Humaitá\",\n \"Ipixuna\",\n \"Iranduba\",\n \"Itacoatiara\",\n \"Itamarati\",\n \"Itapiranga\",\n \"Japurá\",\n \"Juruá\",\n \"Jutaí\",\n \"Lábrea\",\n \"Manacapuru\",\n \"Manaquiri\",\n \"Manaus\",\n \"Manicoré\",\n \"Maraã\",\n \"Maués\",\n \"Nhamundá\",\n \"Nova Olinda do Norte\",\n \"Novo Airão\",\n \"Novo Aripuanã\",\n \"Parintins\",\n \"Pauini\",\n \"Presidente Figueiredo\",\n \"Rio Preto da Eva\",\n \"Santa Isabel do Rio Negro\",\n \"Santo Antônio do Içá\",\n \"São Gabriel da Cachoeira\",\n \"São Paulo de Olivença\",\n \"São Sebastião do Uatumã\",\n \"Silves\",\n \"Tabatinga\",\n \"Tapauá\",\n \"Tefé\",\n \"Tonantins\",\n \"Uarini\",\n \"Urucará\",\n \"Urucurituba\"\n ]\n },\n {\n \"uf\": \"AP\",\n \"name\": \"Amapá\",\n \"cities\": [\n \"Amapá\",\n \"Calçoene\",\n \"Cutias\",\n \"Ferreira Gomes\",\n \"Itaubal\",\n \"Laranjal do Jari\",\n \"Macapá\",\n \"Mazagão\",\n \"Oiapoque\",\n \"Pedra Branca do Amapari\",\n \"Porto Grande\",\n \"Pracuúba\",\n \"Santana\",\n \"Serra do Navio\",\n \"Tartarugalzinho\",\n \"Vitória do Jari\"\n ]\n },\n {\n \"uf\": \"BA\",\n \"name\": \"Bahia\",\n \"cities\": [\n \"Abaíra\",\n \"Abaré\",\n \"Acajutiba\",\n \"Adustina\",\n \"Água Fria\",\n \"Aiquara\",\n \"Alagoinhas\",\n \"Alcobaça\",\n \"Almadina\",\n \"Amargosa\",\n \"Amélia Rodrigues\",\n \"América Dourada\",\n \"Anagé\",\n \"Andaraí\",\n \"Andorinha\",\n \"Angical\",\n \"Anguera\",\n \"Antas\",\n \"Antônio Cardoso\",\n \"Antônio Gonçalves\",\n \"Aporá\",\n \"Apuarema\",\n \"Araçás\",\n \"Aracatu\",\n \"Araci\",\n \"Aramari\",\n \"Arataca\",\n \"Aratuípe\",\n \"Aurelino Leal\",\n \"Baianópolis\",\n \"Baixa Grande\",\n \"Banzaê\",\n \"Barra\",\n \"Barra da Estiva\",\n \"Barra do Choça\",\n \"Barra do Mendes\",\n \"Barra do Rocha\",\n \"Barreiras\",\n \"Barro Alto\",\n \"Barro Preto\",\n \"Barrocas\",\n \"Belmonte\",\n \"Belo Campo\",\n \"Biritinga\",\n \"Boa Nova\",\n \"Boa Vista do Tupim\",\n \"Bom Jesus da Lapa\",\n \"Bom Jesus da Serra\",\n \"Boninal\",\n \"Bonito\",\n \"Boquira\",\n \"Botuporã\",\n \"Brejões\",\n \"Brejolândia\",\n \"Brotas de Macaúbas\",\n \"Brumado\",\n \"Buerarema\",\n \"Buritirama\",\n \"Caatiba\",\n \"Cabaceiras do Paraguaçu\",\n \"Cachoeira\",\n \"Caculé\",\n \"Caém\",\n \"Caetanos\",\n \"Caetité\",\n \"Cafarnaum\",\n \"Cairu\",\n \"Caldeirão Grande\",\n \"Camacan\",\n \"Camaçari\",\n \"Camamu\",\n \"Campo Alegre de Lourdes\",\n \"Campo Formoso\",\n \"Canápolis\",\n \"Canarana\",\n \"Canavieiras\",\n \"Candeal\",\n \"Candeias\",\n \"Candiba\",\n \"Cândido Sales\",\n \"Cansanção\",\n \"Canudos\",\n \"Capela do Alto Alegre\",\n \"Capim Grosso\",\n \"Caraíbas\",\n \"Caravelas\",\n \"Cardeal da Silva\",\n \"Carinhanha\",\n \"Casa Nova\",\n \"Castro Alves\",\n \"Catolândia\",\n \"Catu\",\n \"Caturama\",\n \"Central\",\n \"Chorrochó\",\n \"Cícero Dantas\",\n \"Cipó\",\n \"Coaraci\",\n \"Cocos\",\n \"Conceição da Feira\",\n \"Conceição do Almeida\",\n \"Conceição do Coité\",\n \"Conceição do Jacuípe\",\n \"Conde\",\n \"Condeúba\",\n \"Contendas do Sincorá\",\n \"Coração de Maria\",\n \"Cordeiros\",\n \"Coribe\",\n \"Coronel João Sá\",\n \"Correntina\",\n \"Cotegipe\",\n \"Cravolândia\",\n \"Crisópolis\",\n \"Cristópolis\",\n \"Cruz das Almas\",\n \"Curaçá\",\n \"Dário Meira\",\n \"Dias d'Ávila\",\n \"Dom Basílio\",\n \"Dom Macedo Costa\",\n \"Elísio Medrado\",\n \"Encruzilhada\",\n \"Entre Rios\",\n \"Érico Cardoso\",\n \"Esplanada\",\n \"Euclides da Cunha\",\n \"Eunápolis\",\n \"Fátima\",\n \"Feira da Mata\",\n \"Feira de Santana\",\n \"Filadélfia\",\n \"Firmino Alves\",\n \"Floresta Azul\",\n \"Formosa do Rio Preto\",\n \"Gandu\",\n \"Gavião\",\n \"Gentio do Ouro\",\n \"Glória\",\n \"Gongogi\",\n \"Governador Mangabeira\",\n \"Guajeru\",\n \"Guanambi\",\n \"Guaratinga\",\n \"Heliópolis\",\n \"Iaçu\",\n \"Ibiassucê\",\n \"Ibicaraí\",\n \"Ibicoara\",\n \"Ibicuí\",\n \"Ibipeba\",\n \"Ibipitanga\",\n \"Ibiquera\",\n \"Ibirapitanga\",\n \"Ibirapuã\",\n \"Ibirataia\",\n \"Ibitiara\",\n \"Ibititá\",\n \"Ibotirama\",\n \"Ichu\",\n \"Igaporã\",\n \"Igrapiúna\",\n \"Iguaí\",\n \"Ilhéus\",\n \"Inhambupe\",\n \"Ipecaetá\",\n \"Ipiaú\",\n \"Ipirá\",\n \"Ipupiara\",\n \"Irajuba\",\n \"Iramaia\",\n \"Iraquara\",\n \"Irará\",\n \"Irecê\",\n \"Itabela\",\n \"Itaberaba\",\n \"Itabuna\",\n \"Itacaré\",\n \"Itaeté\",\n \"Itagi\",\n \"Itagibá\",\n \"Itagimirim\",\n \"Itaguaçu da Bahia\",\n \"Itaju do Colônia\",\n \"Itajuípe\",\n \"Itamaraju\",\n \"Itamari\",\n \"Itambé\",\n \"Itanagra\",\n \"Itanhém\",\n \"Itaparica\",\n \"Itapé\",\n \"Itapebi\",\n \"Itapetinga\",\n \"Itapicuru\",\n \"Itapitanga\",\n \"Itaquara\",\n \"Itarantim\",\n \"Itatim\",\n \"Itiruçu\",\n \"Itiúba\",\n \"Itororó\",\n \"Ituaçu\",\n \"Ituberá\",\n \"Iuiu\",\n \"Jaborandi\",\n \"Jacaraci\",\n \"Jacobina\",\n \"Jaguaquara\",\n \"Jaguarari\",\n \"Jaguaripe\",\n \"Jandaíra\",\n \"Jequié\",\n \"Jeremoabo\",\n \"Jiquiriçá\",\n \"Jitaúna\",\n \"João Dourado\",\n \"Juazeiro\",\n \"Jucuruçu\",\n \"Jussara\",\n \"Jussari\",\n \"Jussiape\",\n \"Lafaiete Coutinho\",\n \"Lagoa Real\",\n \"Laje\",\n \"Lajedão\",\n \"Lajedinho\",\n \"Lajedo do Tabocal\",\n \"Lamarão\",\n \"Lapão\",\n \"Lauro de Freitas\",\n \"Lençóis\",\n \"Licínio de Almeida\",\n \"Livramento de Nossa Senhora\",\n \"Luís Eduardo Magalhães\",\n \"Macajuba\",\n \"Macarani\",\n \"Macaúbas\",\n \"Macururé\",\n \"Madre de Deus\",\n \"Maetinga\",\n \"Maiquinique\",\n \"Mairi\",\n \"Malhada\",\n \"Malhada de Pedras\",\n \"Manoel Vitorino\",\n \"Mansidão\",\n \"Maracás\",\n \"Maragogipe\",\n \"Maraú\",\n \"Marcionílio Souza\",\n \"Mascote\",\n \"Mata de São João\",\n \"Matina\",\n \"Medeiros Neto\",\n \"Miguel Calmon\",\n \"Milagres\",\n \"Mirangaba\",\n \"Mirante\",\n \"Monte Santo\",\n \"Morpará\",\n \"Morro do Chapéu\",\n \"Mortugaba\",\n \"Mucugê\",\n \"Mucuri\",\n \"Mulungu do Morro\",\n \"Mundo Novo\",\n \"Muniz Ferreira\",\n \"Muquém do São Francisco\",\n \"Muritiba\",\n \"Mutuípe\",\n \"Nazaré\",\n \"Nilo Peçanha\",\n \"Nordestina\",\n \"Nova Canaã\",\n \"Nova Fátima\",\n \"Nova Ibiá\",\n \"Nova Itarana\",\n \"Nova Redenção\",\n \"Nova Soure\",\n \"Nova Viçosa\",\n \"Novo Horizonte\",\n \"Novo Triunfo\",\n \"Olindina\",\n \"Oliveira dos Brejinhos\",\n \"Ouriçangas\",\n \"Ourolândia\",\n \"Palmas de Monte Alto\",\n \"Palmeiras\",\n \"Paramirim\",\n \"Paratinga\",\n \"Paripiranga\",\n \"Pau Brasil\",\n \"Paulo Afonso\",\n \"Pé de Serra\",\n \"Pedrão\",\n \"Pedro Alexandre\",\n \"Piatã\",\n \"Pilão Arcado\",\n \"Pindaí\",\n \"Pindobaçu\",\n \"Pintadas\",\n \"Piraí do Norte\",\n \"Piripá\",\n \"Piritiba\",\n \"Planaltino\",\n \"Planalto\",\n \"Poções\",\n \"Pojuca\",\n \"Ponto Novo\",\n \"Porto Seguro\",\n \"Potiraguá\",\n \"Prado\",\n \"Presidente Dutra\",\n \"Presidente Jânio Quadros\",\n \"Presidente Tancredo Neves\",\n \"Queimadas\",\n \"Quijingue\",\n \"Quixabeira\",\n \"Rafael Jambeiro\",\n \"Remanso\",\n \"Retirolândia\",\n \"Riachão das Neves\",\n \"Riachão do Jacuípe\",\n \"Riacho de Santana\",\n \"Ribeira do Amparo\",\n \"Ribeira do Pombal\",\n \"Ribeirão do Largo\",\n \"Rio de Contas\",\n \"Rio do Antônio\",\n \"Rio do Pires\",\n \"Rio Real\",\n \"Rodelas\",\n \"Ruy Barbosa\",\n \"Salinas da Margarida\",\n \"Salvador\",\n \"Santa Bárbara\",\n \"Santa Brígida\",\n \"Santa Cruz Cabrália\",\n \"Santa Cruz da Vitória\",\n \"Santa Inês\",\n \"Santa Luzia\",\n \"Santa Maria da Vitória\",\n \"Santa Rita de Cássia\",\n \"Santa Terezinha\",\n \"Santaluz\",\n \"Santana\",\n \"Santanópolis\",\n \"Santo Amaro\",\n \"Santo Antônio de Jesus\",\n \"Santo Estêvão\",\n \"São Desidério\",\n \"São Domingos\",\n \"São Felipe\",\n \"São Félix\",\n \"São Félix do Coribe\",\n \"São Francisco do Conde\",\n \"São Gabriel\",\n \"São Gonçalo dos Campos\",\n \"São José da Vitória\",\n \"São José do Jacuípe\",\n \"São Miguel das Matas\",\n \"São Sebastião do Passé\",\n \"Sapeaçu\",\n \"Sátiro Dias\",\n \"Saubara\",\n \"Saúde\",\n \"Seabra\",\n \"Sebastião Laranjeiras\",\n \"Senhor do Bonfim\",\n \"Sento Sé\",\n \"Serra do Ramalho\",\n \"Serra Dourada\",\n \"Serra Preta\",\n \"Serrinha\",\n \"Serrolândia\",\n \"Simões Filho\",\n \"Sítio do Mato\",\n \"Sítio do Quinto\",\n \"Sobradinho\",\n \"Souto Soares\",\n \"Tabocas do Brejo Velho\",\n \"Tanhaçu\",\n \"Tanque Novo\",\n \"Tanquinho\",\n \"Taperoá\",\n \"Tapiramutá\",\n \"Teixeira de Freitas\",\n \"Teodoro Sampaio\",\n \"Teofilândia\",\n \"Teolândia\",\n \"Terra Nova\",\n \"Tremedal\",\n \"Tucano\",\n \"Uauá\",\n \"Ubaíra\",\n \"Ubaitaba\",\n \"Ubatã\",\n \"Uibaí\",\n \"Umburanas\",\n \"Una\",\n \"Urandi\",\n \"Uruçuca\",\n \"Utinga\",\n \"Valença\",\n \"Valente\",\n \"Várzea da Roça\",\n \"Várzea do Poço\",\n \"Várzea Nova\",\n \"Varzedo\",\n \"Vera Cruz\",\n \"Vereda\",\n \"Vitória da Conquista\",\n \"Wagner\",\n \"Wanderley\",\n \"Wenceslau Guimarães\",\n \"Xique-Xique\"\n ]\n },\n {\n \"uf\": \"CE\",\n \"name\": \"Ceará\",\n \"cities\": [\n \"Abaiara\",\n \"Acarape\",\n \"Acaraú\",\n \"Acopiara\",\n \"Aiuaba\",\n \"Alcântaras\",\n \"Altaneira\",\n \"Alto Santo\",\n \"Amontada\",\n \"Antonina do Norte\",\n \"Apuiarés\",\n \"Aquiraz\",\n \"Aracati\",\n \"Aracoiaba\",\n \"Ararendá\",\n \"Araripe\",\n \"Aratuba\",\n \"Arneiroz\",\n \"Assaré\",\n \"Aurora\",\n \"Baixio\",\n \"Banabuiú\",\n \"Barbalha\",\n \"Barreira\",\n \"Barro\",\n \"Barroquinha\",\n \"Baturité\",\n \"Beberibe\",\n \"Bela Cruz\",\n \"Boa Viagem\",\n \"Brejo Santo\",\n \"Camocim\",\n \"Campos Sales\",\n \"Canindé\",\n \"Capistrano\",\n \"Caridade\",\n \"Cariré\",\n \"Caririaçu\",\n \"Cariús\",\n \"Carnaubal\",\n \"Cascavel\",\n \"Catarina\",\n \"Catunda\",\n \"Caucaia\",\n \"Cedro\",\n \"Chaval\",\n \"Choró\",\n \"Chorozinho\",\n \"Coreaú\",\n \"Crateús\",\n \"Crato\",\n \"Croatá\",\n \"Cruz\",\n \"Deputado Irapuan Pinheiro\",\n \"Ereré\",\n \"Eusébio\",\n \"Farias Brito\",\n \"Forquilha\",\n \"Fortaleza\",\n \"Fortim\",\n \"Frecheirinha\",\n \"General Sampaio\",\n \"Graça\",\n \"Granja\",\n \"Granjeiro\",\n \"Groaíras\",\n \"Guaiúba\",\n \"Guaraciaba do Norte\",\n \"Guaramiranga\",\n \"Hidrolândia\",\n \"Horizonte\",\n \"Ibaretama\",\n \"Ibiapina\",\n \"Ibicuitinga\",\n \"Icapuí\",\n \"Icó\",\n \"Iguatu\",\n \"Independência\",\n \"Ipaporanga\",\n \"Ipaumirim\",\n \"Ipu\",\n \"Ipueiras\",\n \"Iracema\",\n \"Irauçuba\",\n \"Itaiçaba\",\n \"Itaitinga\",\n \"Itapajé\",\n \"Itapipoca\",\n \"Itapiúna\",\n \"Itarema\",\n \"Itatira\",\n \"Jaguaretama\",\n \"Jaguaribara\",\n \"Jaguaribe\",\n \"Jaguaruana\",\n \"Jardim\",\n \"Jati\",\n \"Jijoca de Jericoacoara\",\n \"Juazeiro do Norte\",\n \"Jucás\",\n \"Lavras da Mangabeira\",\n \"Limoeiro do Norte\",\n \"Madalena\",\n \"Maracanaú\",\n \"Maranguape\",\n \"Marco\",\n \"Martinópole\",\n \"Massapê\",\n \"Mauriti\",\n \"Meruoca\",\n \"Milagres\",\n \"Milhã\",\n \"Miraíma\",\n \"Missão Velha\",\n \"Mombaça\",\n \"Monsenhor Tabosa\",\n \"Morada Nova\",\n \"Moraújo\",\n \"Morrinhos\",\n \"Mucambo\",\n \"Mulungu\",\n \"Nova Olinda\",\n \"Nova Russas\",\n \"Novo Oriente\",\n \"Ocara\",\n \"Orós\",\n \"Pacajus\",\n \"Pacatuba\",\n \"Pacoti\",\n \"Pacujá\",\n \"Palhano\",\n \"Palmácia\",\n \"Paracuru\",\n \"Paraipaba\",\n \"Parambu\",\n \"Paramoti\",\n \"Pedra Branca\",\n \"Penaforte\",\n \"Pentecoste\",\n \"Pereiro\",\n \"Pindoretama\",\n \"Piquet Carneiro\",\n \"Pires Ferreira\",\n \"Poranga\",\n \"Porteiras\",\n \"Potengi\",\n \"Potiretama\",\n \"Quiterianópolis\",\n \"Quixadá\",\n \"Quixelô\",\n \"Quixeramobim\",\n \"Quixeré\",\n \"Redenção\",\n \"Reriutaba\",\n \"Russas\",\n \"Saboeiro\",\n \"Salitre\",\n \"Santa Quitéria\",\n \"Santana do Acaraú\",\n \"Santana do Cariri\",\n \"São Benedito\",\n \"São Gonçalo do Amarante\",\n \"São João do Jaguaribe\",\n \"São Luís do Curu\",\n \"Senador Pompeu\",\n \"Senador Sá\",\n \"Sobral\",\n \"Solonópole\",\n \"Tabuleiro do Norte\",\n \"Tamboril\",\n \"Tarrafas\",\n \"Tauá\",\n \"Tejuçuoca\",\n \"Tianguá\",\n \"Trairi\",\n \"Tururu\",\n \"Ubajara\",\n \"Umari\",\n \"Umirim\",\n \"Uruburetama\",\n \"Uruoca\",\n \"Varjota\",\n \"Várzea Alegre\",\n \"Viçosa do Ceará\"\n ]\n },\n {\n \"uf\": \"DF\",\n \"name\": \"Distrito Federal\",\n \"cities\": [\n \"Águas Claras\",\n \"Arniqueira\",\n \"Brasília\",\n \"Brazlândia\",\n \"Candangolândia\",\n \"Ceilândia\",\n \"Cruzeiro\",\n \"Estrutural\",\n \"Fercal\",\n \"Gama\",\n \"Guará\",\n \"Itapoã\",\n \"Jardim Botânico\",\n \"Lago Norte\",\n \"Lago Sul\",\n \"Núcleo Bandeirante\",\n \"Octogonal\",\n \"Paranoá\",\n \"Park Way\",\n \"Planaltina\",\n \"Plano Piloto\",\n \"Pôr do Sol\",\n \"Recanto das Emas\",\n \"Riacho Fundo\",\n \"Riacho Fundo II\",\n \"Samambaia\",\n \"Santa Maria\",\n \"São Sebastião\",\n \"SIA\",\n \"Sobradinho\",\n \"Sobradinho II\",\n \"Sol Nascente\",\n \"Sudoeste\",\n \"Taguatinga\",\n \"Varjão\",\n \"Vicente Pires\"\n ]\n },\n {\n \"uf\": \"ES\",\n \"name\": \"Espírito Santo\",\n \"cities\": [\n \"Afonso Cláudio\",\n \"Água Doce do Norte\",\n \"Águia Branca\",\n \"Alegre\",\n \"Alfredo Chaves\",\n \"Alto Rio Novo\",\n \"Anchieta\",\n \"Apiacá\",\n \"Aracruz\",\n \"Atílio Vivácqua\",\n \"Baixo Guandu\",\n \"Barra de São Francisco\",\n \"Boa Esperança\",\n \"Bom Jesus do Norte\",\n \"Brejetuba\",\n \"Cachoeiro de Itapemirim\",\n \"Cariacica\",\n \"Castelo\",\n \"Colatina\",\n \"Conceição da Barra\",\n \"Conceição do Castelo\",\n \"Divino de São Lourenço\",\n \"Domingos Martins\",\n \"Dores do Rio Preto\",\n \"Ecoporanga\",\n \"Fundão\",\n \"Governador Lindenberg\",\n \"Guaçuí\",\n \"Guarapari\",\n \"Ibatiba\",\n \"Ibiraçu\",\n \"Ibitirama\",\n \"Iconha\",\n \"Irupi\",\n \"Itaguaçu\",\n \"Itapemirim\",\n \"Itarana\",\n \"Iúna\",\n \"Jaguaré\",\n \"Jerônimo Monteiro\",\n \"João Neiva\",\n \"Laranja da Terra\",\n \"Linhares\",\n \"Mantenópolis\",\n \"Marataízes\",\n \"Marechal Floriano\",\n \"Marilândia\",\n \"Mimoso do Sul\",\n \"Montanha\",\n \"Mucurici\",\n \"Muniz Freire\",\n \"Muqui\",\n \"Nova Venécia\",\n \"Pancas\",\n \"Pedro Canário\",\n \"Pinheiros\",\n \"Piúma\",\n \"Ponto Belo\",\n \"Presidente Kennedy\",\n \"Rio Bananal\",\n \"Rio Novo do Sul\",\n \"Santa Leopoldina\",\n \"Santa Maria de Jetibá\",\n \"Santa Teresa\",\n \"São Domingos do Norte\",\n \"São Gabriel da Palha\",\n \"São José do Calçado\",\n \"São Mateus\",\n \"São Roque do Canaã\",\n \"Serra\",\n \"Sooretama\",\n \"Vargem Alta\",\n \"Venda Nova do Imigrante\",\n \"Viana\",\n \"Vila Pavão\",\n \"Vila Valério\",\n \"Vila Velha\",\n \"Vitória\"\n ]\n },\n {\n \"uf\": \"GO\",\n \"name\": \"Goiás\",\n \"cities\": [\n \"Abadia de Goiás\",\n \"Abadiânia\",\n \"Acreúna\",\n \"Adelândia\",\n \"Água Fria de Goiás\",\n \"Água Limpa\",\n \"Águas Lindas de Goiás\",\n \"Alexânia\",\n \"Aloândia\",\n \"Alto Horizonte\",\n \"Alto Paraíso de Goiás\",\n \"Alvorada do Norte\",\n \"Amaralina\",\n \"Americano do Brasil\",\n \"Amorinópolis\",\n \"Anápolis\",\n \"Anhanguera\",\n \"Anicuns\",\n \"Aparecida de Goiânia\",\n \"Aparecida do Rio Doce\",\n \"Aporé\",\n \"Araçu\",\n \"Aragarças\",\n \"Aragoiânia\",\n \"Araguapaz\",\n \"Arenópolis\",\n \"Aruanã\",\n \"Aurilândia\",\n \"Avelinópolis\",\n \"Baliza\",\n \"Barro Alto\",\n \"Bela Vista de Goiás\",\n \"Bom Jardim de Goiás\",\n \"Bom Jesus de Goiás\",\n \"Bonfinópolis\",\n \"Bonópolis\",\n \"Brazabrantes\",\n \"Britânia\",\n \"Buriti Alegre\",\n \"Buriti de Goiás\",\n \"Buritinópolis\",\n \"Cabeceiras\",\n \"Cachoeira Alta\",\n \"Cachoeira de Goiás\",\n \"Cachoeira Dourada\",\n \"Caçu\",\n \"Caiapônia\",\n \"Caldas Novas\",\n \"Caldazinha\",\n \"Campestre de Goiás\",\n \"Campinaçu\",\n \"Campinorte\",\n \"Campo Alegre de Goiás\",\n \"Campo Limpo de Goiás\",\n \"Campos Belos\",\n \"Campos Verdes\",\n \"Carmo do Rio Verde\",\n \"Castelândia\",\n \"Catalão\",\n \"Caturaí\",\n \"Cavalcante\",\n \"Ceres\",\n \"Cezarina\",\n \"Chapadão do Céu\",\n \"Cidade Ocidental\",\n \"Cocalzinho de Goiás\",\n \"Colinas do Sul\",\n \"Córrego do Ouro\",\n \"Corumbá de Goiás\",\n \"Corumbaíba\",\n \"Cristalina\",\n \"Cristianópolis\",\n \"Crixás\",\n \"Cromínia\",\n \"Cumari\",\n \"Damianópolis\",\n \"Damolândia\",\n \"Davinópolis\",\n \"Diorama\",\n \"Divinópolis de Goiás\",\n \"Doverlândia\",\n \"Edealina\",\n \"Edéia\",\n \"Estrela do Norte\",\n \"Faina\",\n \"Fazenda Nova\",\n \"Firminópolis\",\n \"Flores de Goiás\",\n \"Formosa\",\n \"Formoso\",\n \"Gameleira de Goiás\",\n \"Goianápolis\",\n \"Goiandira\",\n \"Goianésia\",\n \"Goiânia\",\n \"Goianira\",\n \"Goiás\",\n \"Goiatuba\",\n \"Gouvelândia\",\n \"Guapó\",\n \"Guaraíta\",\n \"Guarani de Goiás\",\n \"Guarinos\",\n \"Heitoraí\",\n \"Hidrolândia\",\n \"Hidrolina\",\n \"Iaciara\",\n \"Inaciolândia\",\n \"Indiara\",\n \"Inhumas\",\n \"Ipameri\",\n \"Ipiranga de Goiás\",\n \"Iporá\",\n \"Israelândia\",\n \"Itaberaí\",\n \"Itaguari\",\n \"Itaguaru\",\n \"Itajá\",\n \"Itapaci\",\n \"Itapirapuã\",\n \"Itapuranga\",\n \"Itarumã\",\n \"Itauçu\",\n \"Itumbiara\",\n \"Ivolândia\",\n \"Jandaia\",\n \"Jaraguá\",\n \"Jataí\",\n \"Jaupaci\",\n \"Jesúpolis\",\n \"Joviânia\",\n \"Jussara\",\n \"Lagoa Santa\",\n \"Leopoldo de Bulhões\",\n \"Luziânia\",\n \"Mairipotaba\",\n \"Mambaí\",\n \"Mara Rosa\",\n \"Marzagão\",\n \"Matrinchã\",\n \"Maurilândia\",\n \"Mimoso de Goiás\",\n \"Minaçu\",\n \"Mineiros\",\n \"Moiporá\",\n \"Monte Alegre de Goiás\",\n \"Montes Claros de Goiás\",\n \"Montividiu\",\n \"Montividiu do Norte\",\n \"Morrinhos\",\n \"Morro Agudo de Goiás\",\n \"Mossâmedes\",\n \"Mozarlândia\",\n \"Mundo Novo\",\n \"Mutunópolis\",\n \"Nazário\",\n \"Nerópolis\",\n \"Niquelândia\",\n \"Nova América\",\n \"Nova Aurora\",\n \"Nova Crixás\",\n \"Nova Glória\",\n \"Nova Iguaçu de Goiás\",\n \"Nova Roma\",\n \"Nova Veneza\",\n \"Novo Brasil\",\n \"Novo Gama\",\n \"Novo Planalto\",\n \"Orizona\",\n \"Ouro Verde de Goiás\",\n \"Ouvidor\",\n \"Padre Bernardo\",\n \"Palestina de Goiás\",\n \"Palmeiras de Goiás\",\n \"Palmelo\",\n \"Palminópolis\",\n \"Panamá\",\n \"Paranaiguara\",\n \"Paraúna\",\n \"Perolândia\",\n \"Petrolina de Goiás\",\n \"Pilar de Goiás\",\n \"Piracanjuba\",\n \"Piranhas\",\n \"Pirenópolis\",\n \"Pires do Rio\",\n \"Planaltina\",\n \"Pontalina\",\n \"Porangatu\",\n \"Porteirão\",\n \"Portelândia\",\n \"Posse\",\n \"Professor Jamil\",\n \"Quirinópolis\",\n \"Rialma\",\n \"Rianápolis\",\n \"Rio Quente\",\n \"Rio Verde\",\n \"Rubiataba\",\n \"Sanclerlândia\",\n \"Santa Bárbara de Goiás\",\n \"Santa Cruz de Goiás\",\n \"Santa Fé de Goiás\",\n \"Santa Helena de Goiás\",\n \"Santa Isabel\",\n \"Santa Rita do Araguaia\",\n \"Santa Rita do Novo Destino\",\n \"Santa Rosa de Goiás\",\n \"Santa Tereza de Goiás\",\n \"Santa Terezinha de Goiás\",\n \"Santo Antônio da Barra\",\n \"Santo Antônio de Goiás\",\n \"Santo Antônio do Descoberto\",\n \"São Domingos\",\n \"São Francisco de Goiás\",\n \"São João d'Aliança\",\n \"São João da Paraúna\",\n \"São Luís de Montes Belos\",\n \"São Luiz do Norte\",\n \"São Miguel do Araguaia\",\n \"São Miguel do Passa Quatro\",\n \"São Patrício\",\n \"São Simão\",\n \"Senador Canedo\",\n \"Serranópolis\",\n \"Silvânia\",\n \"Simolândia\",\n \"Sítio d'Abadia\",\n \"Taquaral de Goiás\",\n \"Teresina de Goiás\",\n \"Terezópolis de Goiás\",\n \"Três Ranchos\",\n \"Trindade\",\n \"Trombas\",\n \"Turvânia\",\n \"Turvelândia\",\n \"Uirapuru\",\n \"Uruaçu\",\n \"Uruana\",\n \"Urutaí\",\n \"Valparaíso de Goiás\",\n \"Varjão\",\n \"Vianópolis\",\n \"Vicentinópolis\",\n \"Vila Boa\",\n \"Vila Propício\"\n ]\n },\n {\n \"uf\": \"MA\",\n \"name\": \"Maranhão\",\n \"cities\": [\n \"Açailândia\",\n \"Afonso Cunha\",\n \"Água Doce do Maranhão\",\n \"Alcântara\",\n \"Aldeias Altas\",\n \"Altamira do Maranhão\",\n \"Alto Alegre do Maranhão\",\n \"Alto Alegre do Pindaré\",\n \"Alto Parnaíba\",\n \"Amapá do Maranhão\",\n \"Amarante do Maranhão\",\n \"Anajatuba\",\n \"Anapurus\",\n \"Apicum-Açu\",\n \"Araguanã\",\n \"Araioses\",\n \"Arame\",\n \"Arari\",\n \"Axixá\",\n \"Bacabal\",\n \"Bacabeira\",\n \"Bacuri\",\n \"Bacurituba\",\n \"Balsas\",\n \"Barão de Grajaú\",\n \"Barra do Corda\",\n \"Barreirinhas\",\n \"Bela Vista do Maranhão\",\n \"Belágua\",\n \"Benedito Leite\",\n \"Bequimão\",\n \"Bernardo do Mearim\",\n \"Boa Vista do Gurupi\",\n \"Bom Jardim\",\n \"Bom Jesus das Selvas\",\n \"Bom Lugar\",\n \"Brejo\",\n \"Brejo de Areia\",\n \"Buriti\",\n \"Buriti Bravo\",\n \"Buriticupu\",\n \"Buritirana\",\n \"Cachoeira Grande\",\n \"Cajapió\",\n \"Cajari\",\n \"Campestre do Maranhão\",\n \"Cândido Mendes\",\n \"Cantanhede\",\n \"Capinzal do Norte\",\n \"Carolina\",\n \"Carutapera\",\n \"Caxias\",\n \"Cedral\",\n \"Central do Maranhão\",\n \"Centro do Guilherme\",\n \"Centro Novo do Maranhão\",\n \"Chapadinha\",\n \"Cidelândia\",\n \"Codó\",\n \"Coelho Neto\",\n \"Colinas\",\n \"Conceição do Lago-Açu\",\n \"Coroatá\",\n \"Cururupu\",\n \"Davinópolis\",\n \"Dom Pedro\",\n \"Duque Bacelar\",\n \"Esperantinópolis\",\n \"Estreito\",\n \"Feira Nova do Maranhão\",\n \"Fernando Falcão\",\n \"Formosa da Serra Negra\",\n \"Fortaleza dos Nogueiras\",\n \"Fortuna\",\n \"Godofredo Viana\",\n \"Gonçalves Dias\",\n \"Governador Archer\",\n \"Governador Edison Lobão\",\n \"Governador Eugênio Barros\",\n \"Governador Luiz Rocha\",\n \"Governador Newton Bello\",\n \"Governador Nunes Freire\",\n \"Graça Aranha\",\n \"Grajaú\",\n \"Guimarães\",\n \"Humberto de Campos\",\n \"Icatu\",\n \"Igarapé do Meio\",\n \"Igarapé Grande\",\n \"Imperatriz\",\n \"Itaipava do Grajaú\",\n \"Itapecuru Mirim\",\n \"Itinga do Maranhão\",\n \"Jatobá\",\n \"Jenipapo dos Vieiras\",\n \"João Lisboa\",\n \"Joselândia\",\n \"Junco do Maranhão\",\n \"Lago da Pedra\",\n \"Lago do Junco\",\n \"Lago dos Rodrigues\",\n \"Lago Verde\",\n \"Lagoa do Mato\",\n \"Lagoa Grande do Maranhão\",\n \"Lajeado Novo\",\n \"Lima Campos\",\n \"Loreto\",\n \"Luís Domingues\",\n \"Magalhães de Almeida\",\n \"Maracaçumé\",\n \"Marajá do Sena\",\n \"Maranhãozinho\",\n \"Mata Roma\",\n \"Matinha\",\n \"Matões\",\n \"Matões do Norte\",\n \"Milagres do Maranhão\",\n \"Mirador\",\n \"Miranda do Norte\",\n \"Mirinzal\",\n \"Monção\",\n \"Montes Altos\",\n \"Morros\",\n \"Nina Rodrigues\",\n \"Nova Colinas\",\n \"Nova Iorque\",\n \"Nova Olinda do Maranhão\",\n \"Olho d'Água das Cunhãs\",\n \"Olinda Nova do Maranhão\",\n \"Paço do Lumiar\",\n \"Palmeirândia\",\n \"Paraibano\",\n \"Parnarama\",\n \"Passagem Franca\",\n \"Pastos Bons\",\n \"Paulino Neves\",\n \"Paulo Ramos\",\n \"Pedreiras\",\n \"Pedro do Rosário\",\n \"Penalva\",\n \"Peri Mirim\",\n \"Peritoró\",\n \"Pindaré-Mirim\",\n \"Pinheiro\",\n \"Pio XII\",\n \"Pirapemas\",\n \"Poção de Pedras\",\n \"Porto Franco\",\n \"Porto Rico do Maranhão\",\n \"Presidente Dutra\",\n \"Presidente Juscelino\",\n \"Presidente Médici\",\n \"Presidente Sarney\",\n \"Presidente Vargas\",\n \"Primeira Cruz\",\n \"Raposa\",\n \"Riachão\",\n \"Ribamar Fiquene\",\n \"Rosário\",\n \"Sambaíba\",\n \"Santa Filomena do Maranhão\",\n \"Santa Helena\",\n \"Santa Inês\",\n \"Santa Luzia\",\n \"Santa Luzia do Paruá\",\n \"Santa Quitéria do Maranhão\",\n \"Santa Rita\",\n \"Santana do Maranhão\",\n \"Santo Amaro do Maranhão\",\n \"Santo Antônio dos Lopes\",\n \"São Benedito do Rio Preto\",\n \"São Bento\",\n \"São Bernardo\",\n \"São Domingos do Azeitão\",\n \"São Domingos do Maranhão\",\n \"São Félix de Balsas\",\n \"São Francisco do Brejão\",\n \"São Francisco do Maranhão\",\n \"São João Batista\",\n \"São João do Carú\",\n \"São João do Paraíso\",\n \"São João do Soter\",\n \"São João dos Patos\",\n \"São José de Ribamar\",\n \"São José dos Basílios\",\n \"São Luís\",\n \"São Luís Gonzaga do Maranhão\",\n \"São Mateus do Maranhão\",\n \"São Pedro da Água Branca\",\n \"São Pedro dos Crentes\",\n \"São Raimundo das Mangabeiras\",\n \"São Raimundo do Doca Bezerra\",\n \"São Roberto\",\n \"São Vicente Ferrer\",\n \"Satubinha\",\n \"Senador Alexandre Costa\",\n \"Senador La Rocque\",\n \"Serrano do Maranhão\",\n \"Sítio Novo\",\n \"Sucupira do Norte\",\n \"Sucupira do Riachão\",\n \"Tasso Fragoso\",\n \"Timbiras\",\n \"Timon\",\n \"Trizidela do Vale\",\n \"Tufilândia\",\n \"Tuntum\",\n \"Turiaçu\",\n \"Turilândia\",\n \"Tutóia\",\n \"Urbano Santos\",\n \"Vargem Grande\",\n \"Viana\",\n \"Vila Nova dos Martírios\",\n \"Vitória do Mearim\",\n \"Vitorino Freire\",\n \"Zé Doca\"\n ]\n },\n {\n \"uf\": \"MG\",\n \"name\": \"Minas Gerais\",\n \"cities\": [\n \"Abadia dos Dourados\",\n \"Abaeté\",\n \"Abre Campo\",\n \"Acaiaca\",\n \"Açucena\",\n \"Água Boa\",\n \"Água Comprida\",\n \"Aguanil\",\n \"Águas Formosas\",\n \"Águas Vermelhas\",\n \"Aimorés\",\n \"Aiuruoca\",\n \"Alagoa\",\n \"Albertina\",\n \"Além Paraíba\",\n \"Alfenas\",\n \"Alfredo Vasconcelos\",\n \"Almenara\",\n \"Alpercata\",\n \"Alpinópolis\",\n \"Alterosa\",\n \"Alto Caparaó\",\n \"Alto Jequitibá\",\n \"Alto Rio Doce\",\n \"Alvarenga\",\n \"Alvinópolis\",\n \"Alvorada de Minas\",\n \"Amparo do Serra\",\n \"Andradas\",\n \"Andrelândia\",\n \"Angelândia\",\n \"Antônio Carlos\",\n \"Antônio Dias\",\n \"Antônio Prado de Minas\",\n \"Araçaí\",\n \"Aracitaba\",\n \"Araçuaí\",\n \"Araguari\",\n \"Arantina\",\n \"Araponga\",\n \"Araporã\",\n \"Arapuá\",\n \"Araújos\",\n \"Araxá\",\n \"Arceburgo\",\n \"Arcos\",\n \"Areado\",\n \"Argirita\",\n \"Aricanduva\",\n \"Arinos\",\n \"Astolfo Dutra\",\n \"Ataléia\",\n \"Augusto de Lima\",\n \"Baependi\",\n \"Baldim\",\n \"Bambuí\",\n \"Bandeira\",\n \"Bandeira do Sul\",\n \"Barão de Cocais\",\n \"Barão do Monte Alto\",\n \"Barbacena\",\n \"Barra Longa\",\n \"Barroso\",\n \"Bela Vista de Minas\",\n \"Belmiro Braga\",\n \"Belo Horizonte\",\n \"Belo Oriente\",\n \"Belo Vale\",\n \"Berilo\",\n \"Berizal\",\n \"Bertópolis\",\n \"Betim\",\n \"Bias Fortes\",\n \"Bicas\",\n \"Biquinhas\",\n \"Boa Esperança\",\n \"Bocaina de Minas\",\n \"Bocaiúva\",\n \"Bom Despacho\",\n \"Bom Jardim de Minas\",\n \"Bom Jesus da Penha\",\n \"Bom Jesus do Amparo\",\n \"Bom Jesus do Galho\",\n \"Bom Repouso\",\n \"Bom Sucesso\",\n \"Bonfim\",\n \"Bonfinópolis de Minas\",\n \"Bonito de Minas\",\n \"Borda da Mata\",\n \"Botelhos\",\n \"Botumirim\",\n \"Brás Pires\",\n \"Brasilândia de Minas\",\n \"Brasília de Minas\",\n \"Braúnas\",\n \"Brazópolis\",\n \"Brumadinho\",\n \"Bueno Brandão\",\n \"Buenópolis\",\n \"Bugre\",\n \"Buritis\",\n \"Buritizeiro\",\n \"Cabeceira Grande\",\n \"Cabo Verde\",\n \"Cachoeira da Prata\",\n \"Cachoeira de Minas\",\n \"Cachoeira de Pajeú\",\n \"Cachoeira Dourada\",\n \"Caetanópolis\",\n \"Caeté\",\n \"Caiana\",\n \"Cajuri\",\n \"Caldas\",\n \"Camacho\",\n \"Camanducaia\",\n \"Cambuí\",\n \"Cambuquira\",\n \"Campanário\",\n \"Campanha\",\n \"Campestre\",\n \"Campina Verde\",\n \"Campo Azul\",\n \"Campo Belo\",\n \"Campo do Meio\",\n \"Campo Florido\",\n \"Campos Altos\",\n \"Campos Gerais\",\n \"Cana Verde\",\n \"Canaã\",\n \"Canápolis\",\n \"Candeias\",\n \"Cantagalo\",\n \"Caparaó\",\n \"Capela Nova\",\n \"Capelinha\",\n \"Capetinga\",\n \"Capim Branco\",\n \"Capinópolis\",\n \"Capitão Andrade\",\n \"Capitão Enéas\",\n \"Capitólio\",\n \"Caputira\",\n \"Caraí\",\n \"Caranaíba\",\n \"Carandaí\",\n \"Carangola\",\n \"Caratinga\",\n \"Carbonita\",\n \"Careaçu\",\n \"Carlos Chagas\",\n \"Carmésia\",\n \"Carmo da Cachoeira\",\n \"Carmo da Mata\",\n \"Carmo de Minas\",\n \"Carmo do Cajuru\",\n \"Carmo do Paranaíba\",\n \"Carmo do Rio Claro\",\n \"Carmópolis de Minas\",\n \"Carneirinho\",\n \"Carrancas\",\n \"Carvalhópolis\",\n \"Carvalhos\",\n \"Casa Grande\",\n \"Cascalho Rico\",\n \"Cássia\",\n \"Cataguases\",\n \"Catas Altas\",\n \"Catas Altas da Noruega\",\n \"Catuji\",\n \"Catuti\",\n \"Caxambu\",\n \"Cedro do Abaeté\",\n \"Central de Minas\",\n \"Centralina\",\n \"Chácara\",\n \"Chalé\",\n \"Chapada do Norte\",\n \"Chapada Gaúcha\",\n \"Chiador\",\n \"Cipotânea\",\n \"Claraval\",\n \"Claro dos Poções\",\n \"Cláudio\",\n \"Coimbra\",\n \"Coluna\",\n \"Comendador Gomes\",\n \"Comercinho\",\n \"Conceição da Aparecida\",\n \"Conceição da Barra de Minas\",\n \"Conceição das Alagoas\",\n \"Conceição das Pedras\",\n \"Conceição de Ipanema\",\n \"Conceição do Mato Dentro\",\n \"Conceição do Pará\",\n \"Conceição do Rio Verde\",\n \"Conceição dos Ouros\",\n \"Cônego Marinho\",\n \"Confins\",\n \"Congonhal\",\n \"Congonhas\",\n \"Congonhas do Norte\",\n \"Conquista\",\n \"Conselheiro Lafaiete\",\n \"Conselheiro Pena\",\n \"Consolação\",\n \"Contagem\",\n \"Coqueiral\",\n \"Coração de Jesus\",\n \"Cordisburgo\",\n \"Cordislândia\",\n \"Corinto\",\n \"Coroaci\",\n \"Coromandel\",\n \"Coronel Fabriciano\",\n \"Coronel Murta\",\n \"Coronel Pacheco\",\n \"Coronel Xavier Chaves\",\n \"Córrego Danta\",\n \"Córrego do Bom Jesus\",\n \"Córrego Fundo\",\n \"Córrego Novo\",\n \"Couto de Magalhães de Minas\",\n \"Crisólita\",\n \"Cristais\",\n \"Cristália\",\n \"Cristiano Otoni\",\n \"Cristina\",\n \"Crucilândia\",\n \"Cruzeiro da Fortaleza\",\n \"Cruzília\",\n \"Cuparaque\",\n \"Curral de Dentro\",\n \"Curvelo\",\n \"Datas\",\n \"Delfim Moreira\",\n \"Delfinópolis\",\n \"Delta\",\n \"Descoberto\",\n \"Desterro de Entre Rios\",\n \"Desterro do Melo\",\n \"Diamantina\",\n \"Diogo de Vasconcelos\",\n \"Dionísio\",\n \"Divinésia\",\n \"Divino\",\n \"Divino das Laranjeiras\",\n \"Divinolândia de Minas\",\n \"Divinópolis\",\n \"Divisa Alegre\",\n \"Divisa Nova\",\n \"Divisópolis\",\n \"Dom Bosco\",\n \"Dom Cavati\",\n \"Dom Joaquim\",\n \"Dom Silvério\",\n \"Dom Viçoso\",\n \"Dona Euzébia\",\n \"Dores de Campos\",\n \"Dores de Guanhães\",\n \"Dores do Indaiá\",\n \"Dores do Turvo\",\n \"Doresópolis\",\n \"Douradoquara\",\n \"Durandé\",\n \"Elói Mendes\",\n \"Engenheiro Caldas\",\n \"Engenheiro Navarro\",\n \"Entre Folhas\",\n \"Entre Rios de Minas\",\n \"Ervália\",\n \"Esmeraldas\",\n \"Espera Feliz\",\n \"Espinosa\",\n \"Espírito Santo do Dourado\",\n \"Estiva\",\n \"Estrela Dalva\",\n \"Estrela do Indaiá\",\n \"Estrela do Sul\",\n \"Eugenópolis\",\n \"Ewbank da Câmara\",\n \"Extrema\",\n \"Fama\",\n \"Faria Lemos\",\n \"Felício dos Santos\",\n \"Felisburgo\",\n \"Felixlândia\",\n \"Fernandes Tourinho\",\n \"Ferros\",\n \"Fervedouro\",\n \"Florestal\",\n \"Formiga\",\n \"Formoso\",\n \"Fortaleza de Minas\",\n \"Fortuna de Minas\",\n \"Francisco Badaró\",\n \"Francisco Dumont\",\n \"Francisco Sá\",\n \"Franciscópolis\",\n \"Frei Gaspar\",\n \"Frei Inocêncio\",\n \"Frei Lagonegro\",\n \"Fronteira\",\n \"Fronteira dos Vales\",\n \"Fruta de Leite\",\n \"Frutal\",\n \"Funilândia\",\n \"Galiléia\",\n \"Gameleiras\",\n \"Glaucilândia\",\n \"Goiabeira\",\n \"Goianá\",\n \"Gonçalves\",\n \"Gonzaga\",\n \"Gouveia\",\n \"Governador Valadares\",\n \"Grão Mogol\",\n \"Grupiara\",\n \"Guanhães\",\n \"Guapé\",\n \"Guaraciaba\",\n \"Guaraciama\",\n \"Guaranésia\",\n \"Guarani\",\n \"Guarará\",\n \"Guarda-Mor\",\n \"Guaxupé\",\n \"Guidoval\",\n \"Guimarânia\",\n \"Guiricema\",\n \"Gurinhatã\",\n \"Heliodora\",\n \"Iapu\",\n \"Ibertioga\",\n \"Ibiá\",\n \"Ibiaí\",\n \"Ibiracatu\",\n \"Ibiraci\",\n \"Ibirité\",\n \"Ibitiúra de Minas\",\n \"Ibituruna\",\n \"Icaraí de Minas\",\n \"Igarapé\",\n \"Igaratinga\",\n \"Iguatama\",\n \"Ijaci\",\n \"Ilicínea\",\n \"Imbé de Minas\",\n \"Inconfidentes\",\n \"Indaiabira\",\n \"Indianópolis\",\n \"Ingaí\",\n \"Inhapim\",\n \"Inhaúma\",\n \"Inimutaba\",\n \"Ipaba\",\n \"Ipanema\",\n \"Ipatinga\",\n \"Ipiaçu\",\n \"Ipuiúna\",\n \"Iraí de Minas\",\n \"Itabira\",\n \"Itabirinha\",\n \"Itabirito\",\n \"Itacambira\",\n \"Itacarambi\",\n \"Itaguara\",\n \"Itaipé\",\n \"Itajubá\",\n \"Itamarandiba\",\n \"Itamarati de Minas\",\n \"Itambacuri\",\n \"Itambé do Mato Dentro\",\n \"Itamogi\",\n \"Itamonte\",\n \"Itanhandu\",\n \"Itanhomi\",\n \"Itaobim\",\n \"Itapagipe\",\n \"Itapecerica\",\n \"Itapeva\",\n \"Itatiaiuçu\",\n \"Itaú de Minas\",\n \"Itaúna\",\n \"Itaverava\",\n \"Itinga\",\n \"Itueta\",\n \"Ituiutaba\",\n \"Itumirim\",\n \"Iturama\",\n \"Itutinga\",\n \"Jaboticatubas\",\n \"Jacinto\",\n \"Jacuí\",\n \"Jacutinga\",\n \"Jaguaraçu\",\n \"Jaíba\",\n \"Jampruca\",\n \"Janaúba\",\n \"Januária\",\n \"Japaraíba\",\n \"Japonvar\",\n \"Jeceaba\",\n \"Jenipapo de Minas\",\n \"Jequeri\",\n \"Jequitaí\",\n \"Jequitibá\",\n \"Jequitinhonha\",\n \"Jesuânia\",\n \"Joaíma\",\n \"Joanésia\",\n \"João Monlevade\",\n \"João Pinheiro\",\n \"Joaquim Felício\",\n \"Jordânia\",\n \"José Gonçalves de Minas\",\n \"José Raydan\",\n \"Josenópolis\",\n \"Juatuba\",\n \"Juiz de Fora\",\n \"Juramento\",\n \"Juruaia\",\n \"Juvenília\",\n \"Ladainha\",\n \"Lagamar\",\n \"Lagoa da Prata\",\n \"Lagoa dos Patos\",\n \"Lagoa Dourada\",\n \"Lagoa Formosa\",\n \"Lagoa Grande\",\n \"Lagoa Santa\",\n \"Lajinha\",\n \"Lambari\",\n \"Lamim\",\n \"Laranjal\",\n \"Lassance\",\n \"Lavras\",\n \"Leandro Ferreira\",\n \"Leme do Prado\",\n \"Leopoldina\",\n \"Liberdade\",\n \"Lima Duarte\",\n \"Limeira do Oeste\",\n \"Lontra\",\n \"Luisburgo\",\n \"Luislândia\",\n \"Luminárias\",\n \"Luz\",\n \"Machacalis\",\n \"Machado\",\n \"Madre de Deus de Minas\",\n \"Malacacheta\",\n \"Mamonas\",\n \"Manga\",\n \"Manhuaçu\",\n \"Manhumirim\",\n \"Mantena\",\n \"Mar de Espanha\",\n \"Maravilhas\",\n \"Maria da Fé\",\n \"Mariana\",\n \"Marilac\",\n \"Mário Campos\",\n \"Maripá de Minas\",\n \"Marliéria\",\n \"Marmelópolis\",\n \"Martinho Campos\",\n \"Martins Soares\",\n \"Mata Verde\",\n \"Materlândia\",\n \"Mateus Leme\",\n \"Mathias Lobato\",\n \"Matias Barbosa\",\n \"Matias Cardoso\",\n \"Matipó\",\n \"Mato Verde\",\n \"Matozinhos\",\n \"Matutina\",\n \"Medeiros\",\n \"Medina\",\n \"Mendes Pimentel\",\n \"Mercês\",\n \"Mesquita\",\n \"Minas Novas\",\n \"Minduri\",\n \"Mirabela\",\n \"Miradouro\",\n \"Miraí\",\n \"Miravânia\",\n \"Moeda\",\n \"Moema\",\n \"Monjolos\",\n \"Monsenhor Paulo\",\n \"Montalvânia\",\n \"Monte Alegre de Minas\",\n \"Monte Azul\",\n \"Monte Belo\",\n \"Monte Carmelo\",\n \"Monte Formoso\",\n \"Monte Santo de Minas\",\n \"Monte Sião\",\n \"Montes Claros\",\n \"Montezuma\",\n \"Morada Nova de Minas\",\n \"Morro da Garça\",\n \"Morro do Pilar\",\n \"Munhoz\",\n \"Muriaé\",\n \"Mutum\",\n \"Muzambinho\",\n \"Nacip Raydan\",\n \"Nanuque\",\n \"Naque\",\n \"Natalândia\",\n \"Natércia\",\n \"Nazareno\",\n \"Nepomuceno\",\n \"Ninheira\",\n \"Nova Belém\",\n \"Nova Era\",\n \"Nova Lima\",\n \"Nova Módica\",\n \"Nova Ponte\",\n \"Nova Porteirinha\",\n \"Nova Resende\",\n \"Nova Serrana\",\n \"Nova União\",\n \"Novo Cruzeiro\",\n \"Novo Oriente de Minas\",\n \"Novorizonte\",\n \"Olaria\",\n \"Olhos-d'Água\",\n \"Olímpio Noronha\",\n \"Oliveira\",\n \"Oliveira Fortes\",\n \"Onça de Pitangui\",\n \"Oratórios\",\n \"Orizânia\",\n \"Ouro Branco\",\n \"Ouro Fino\",\n \"Ouro Preto\",\n \"Ouro Verde de Minas\",\n \"Padre Carvalho\",\n \"Padre Paraíso\",\n \"Pai Pedro\",\n \"Paineiras\",\n \"Pains\",\n \"Paiva\",\n \"Palma\",\n \"Palmópolis\",\n \"Papagaios\",\n \"Pará de Minas\",\n \"Paracatu\",\n \"Paraguaçu\",\n \"Paraisópolis\",\n \"Paraopeba\",\n \"Passa Quatro\",\n \"Passa Tempo\",\n \"Passa Vinte\",\n \"Passabém\",\n \"Passos\",\n \"Patis\",\n \"Patos de Minas\",\n \"Patrocínio\",\n \"Patrocínio do Muriaé\",\n \"Paula Cândido\",\n \"Paulistas\",\n \"Pavão\",\n \"Peçanha\",\n \"Pedra Azul\",\n \"Pedra Bonita\",\n \"Pedra do Anta\",\n \"Pedra do Indaiá\",\n \"Pedra Dourada\",\n \"Pedralva\",\n \"Pedras de Maria da Cruz\",\n \"Pedrinópolis\",\n \"Pedro Leopoldo\",\n \"Pedro Teixeira\",\n \"Pequeri\",\n \"Pequi\",\n \"Perdigão\",\n \"Perdizes\",\n \"Perdões\",\n \"Periquito\",\n \"Pescador\",\n \"Piau\",\n \"Piedade de Caratinga\",\n \"Piedade de Ponte Nova\",\n \"Piedade do Rio Grande\",\n \"Piedade dos Gerais\",\n \"Pimenta\",\n \"Pingo-d'Água\",\n \"Pintópolis\",\n \"Piracema\",\n \"Pirajuba\",\n \"Piranga\",\n \"Piranguçu\",\n \"Piranguinho\",\n \"Pirapetinga\",\n \"Pirapora\",\n \"Piraúba\",\n \"Pitangui\",\n \"Piumhi\",\n \"Planura\",\n \"Poço Fundo\",\n \"Poços de Caldas\",\n \"Pocrane\",\n \"Pompéu\",\n \"Ponte Nova\",\n \"Ponto Chique\",\n \"Ponto dos Volantes\",\n \"Porteirinha\",\n \"Porto Firme\",\n \"Poté\",\n \"Pouso Alegre\",\n \"Pouso Alto\",\n \"Prados\",\n \"Prata\",\n \"Pratápolis\",\n \"Pratinha\",\n \"Presidente Bernardes\",\n \"Presidente Juscelino\",\n \"Presidente Kubitschek\",\n \"Presidente Olegário\",\n \"Prudente de Morais\",\n \"Quartel Geral\",\n \"Queluzito\",\n \"Raposos\",\n \"Raul Soares\",\n \"Recreio\",\n \"Reduto\",\n \"Resende Costa\",\n \"Resplendor\",\n \"Ressaquinha\",\n \"Riachinho\",\n \"Riacho dos Machados\",\n \"Ribeirão das Neves\",\n \"Ribeirão Vermelho\",\n \"Rio Acima\",\n \"Rio Casca\",\n \"Rio do Prado\",\n \"Rio Doce\",\n \"Rio Espera\",\n \"Rio Manso\",\n \"Rio Novo\",\n \"Rio Paranaíba\",\n \"Rio Pardo de Minas\",\n \"Rio Piracicaba\",\n \"Rio Pomba\",\n \"Rio Preto\",\n \"Rio Vermelho\",\n \"Ritápolis\",\n \"Rochedo de Minas\",\n \"Rodeiro\",\n \"Romaria\",\n \"Rosário da Limeira\",\n \"Rubelita\",\n \"Rubim\",\n \"Sabará\",\n \"Sabinópolis\",\n \"Sacramento\",\n \"Salinas\",\n \"Salto da Divisa\",\n \"Santa Bárbara\",\n \"Santa Bárbara do Leste\",\n \"Santa Bárbara do Monte Verde\",\n \"Santa Bárbara do Tugúrio\",\n \"Santa Cruz de Minas\",\n \"Santa Cruz de Salinas\",\n \"Santa Cruz do Escalvado\",\n \"Santa Efigênia de Minas\",\n \"Santa Fé de Minas\",\n \"Santa Helena de Minas\",\n \"Santa Juliana\",\n \"Santa Luzia\",\n \"Santa Margarida\",\n \"Santa Maria de Itabira\",\n \"Santa Maria do Salto\",\n \"Santa Maria do Suaçuí\",\n \"Santa Rita de Caldas\",\n \"Santa Rita de Ibitipoca\",\n \"Santa Rita de Jacutinga\",\n \"Santa Rita de Minas\",\n \"Santa Rita do Itueto\",\n \"Santa Rita do Sapucaí\",\n \"Santa Rosa da Serra\",\n \"Santa Vitória\",\n \"Santana da Vargem\",\n \"Santana de Cataguases\",\n \"Santana de Pirapama\",\n \"Santana do Deserto\",\n \"Santana do Garambéu\",\n \"Santana do Jacaré\",\n \"Santana do Manhuaçu\",\n \"Santana do Paraíso\",\n \"Santana do Riacho\",\n \"Santana dos Montes\",\n \"Santo Antônio do Amparo\",\n \"Santo Antônio do Aventureiro\",\n \"Santo Antônio do Grama\",\n \"Santo Antônio do Itambé\",\n \"Santo Antônio do Jacinto\",\n \"Santo Antônio do Monte\",\n \"Santo Antônio do Retiro\",\n \"Santo Antônio do Rio Abaixo\",\n \"Santo Hipólito\",\n \"Santos Dumont\",\n \"São Bento Abade\",\n \"São Brás do Suaçuí\",\n \"São Domingos das Dores\",\n \"São Domingos do Prata\",\n \"São Félix de Minas\",\n \"São Francisco\",\n \"São Francisco de Paula\",\n \"São Francisco de Sales\",\n \"São Francisco do Glória\",\n \"São Geraldo\",\n \"São Geraldo da Piedade\",\n \"São Geraldo do Baixio\",\n \"São Gonçalo do Abaeté\",\n \"São Gonçalo do Pará\",\n \"São Gonçalo do Rio Abaixo\",\n \"São Gonçalo do Rio Preto\",\n \"São Gonçalo do Sapucaí\",\n \"São Gotardo\",\n \"São João Batista do Glória\",\n \"São João da Lagoa\",\n \"São João da Mata\",\n \"São João da Ponte\",\n \"São João das Missões\",\n \"São João del Rei\",\n \"São João do Manhuaçu\",\n \"São João do Manteninha\",\n \"São João do Oriente\",\n \"São João do Pacuí\",\n \"São João do Paraíso\",\n \"São João Evangelista\",\n \"São João Nepomuceno\",\n \"São Joaquim de Bicas\",\n \"São José da Barra\",\n \"São José da Lapa\",\n \"São José da Safira\",\n \"São José da Varginha\",\n \"São José do Alegre\",\n \"São José do Divino\",\n \"São José do Goiabal\",\n \"São José do Jacuri\",\n \"São José do Mantimento\",\n \"São Lourenço\",\n \"São Miguel do Anta\",\n \"São Pedro da União\",\n \"São Pedro do Suaçuí\",\n \"São Pedro dos Ferros\",\n \"São Romão\",\n \"São Roque de Minas\",\n \"São Sebastião da Bela Vista\",\n \"São Sebastião da Vargem Alegre\",\n \"São Sebastião do Anta\",\n \"São Sebastião do Maranhão\",\n \"São Sebastião do Oeste\",\n \"São Sebastião do Paraíso\",\n \"São Sebastião do Rio Preto\",\n \"São Sebastião do Rio Verde\",\n \"São Tiago\",\n \"São Tomás de Aquino\",\n \"São Tomé das Letras\",\n \"São Vicente de Minas\",\n \"Sapucaí-Mirim\",\n \"Sardoá\",\n \"Sarzedo\",\n \"Sem-Peixe\",\n \"Senador Amaral\",\n \"Senador Cortes\",\n \"Senador Firmino\",\n \"Senador José Bento\",\n \"Senador Modestino Gonçalves\",\n \"Senhora de Oliveira\",\n \"Senhora do Porto\",\n \"Senhora dos Remédios\",\n \"Sericita\",\n \"Seritinga\",\n \"Serra Azul de Minas\",\n \"Serra da Saudade\",\n \"Serra do Salitre\",\n \"Serra dos Aimorés\",\n \"Serrania\",\n \"Serranópolis de Minas\",\n \"Serranos\",\n \"Serro\",\n \"Sete Lagoas\",\n \"Setubinha\",\n \"Silveirânia\",\n \"Silvianópolis\",\n \"Simão Pereira\",\n \"Simonésia\",\n \"Sobrália\",\n \"Soledade de Minas\",\n \"Tabuleiro\",\n \"Taiobeiras\",\n \"Taparuba\",\n \"Tapira\",\n \"Tapiraí\",\n \"Taquaraçu de Minas\",\n \"Tarumirim\",\n \"Teixeiras\",\n \"Teófilo Otoni\",\n \"Timóteo\",\n \"Tiradentes\",\n \"Tiros\",\n \"Tocantins\",\n \"Tocos do Moji\",\n \"Toledo\",\n \"Tombos\",\n \"Três Corações\",\n \"Três Marias\",\n \"Três Pontas\",\n \"Tumiritinga\",\n \"Tupaciguara\",\n \"Turmalina\",\n \"Turvolândia\",\n \"Ubá\",\n \"Ubaí\",\n \"Ubaporanga\",\n \"Uberaba\",\n \"Uberlândia\",\n \"Umburatiba\",\n \"Unaí\",\n \"União de Minas\",\n \"Uruana de Minas\",\n \"Urucânia\",\n \"Urucuia\",\n \"Vargem Alegre\",\n \"Vargem Bonita\",\n \"Vargem Grande do Rio Pardo\",\n \"Varginha\",\n \"Varjão de Minas\",\n \"Várzea da Palma\",\n \"Varzelândia\",\n \"Vazante\",\n \"Verdelândia\",\n \"Veredinha\",\n \"Veríssimo\",\n \"Vermelho Novo\",\n \"Vespasiano\",\n \"Viçosa\",\n \"Vieiras\",\n \"Virgem da Lapa\",\n \"Virgínia\",\n \"Virginópolis\",\n \"Virgolândia\",\n \"Visconde do Rio Branco\",\n \"Volta Grande\",\n \"Wenceslau Braz\"\n ]\n },\n {\n \"uf\": \"MS\",\n \"name\": \"Mato Grosso do Sul\",\n \"cities\": [\n \"Água Clara\",\n \"Alcinópolis\",\n \"Amambai\",\n \"Anastácio\",\n \"Anaurilândia\",\n \"Angélica\",\n \"Antônio João\",\n \"Aparecida do Taboado\",\n \"Aquidauana\",\n \"Aral Moreira\",\n \"Bandeirantes\",\n \"Bataguassu\",\n \"Batayporã\",\n \"Bela Vista\",\n \"Bodoquena\",\n \"Bonito\",\n \"Brasilândia\",\n \"Caarapó\",\n \"Camapuã\",\n \"Campo Grande\",\n \"Caracol\",\n \"Cassilândia\",\n \"Chapadão do Sul\",\n \"Corguinho\",\n \"Coronel Sapucaia\",\n \"Corumbá\",\n \"Costa Rica\",\n \"Coxim\",\n \"Deodápolis\",\n \"Dois Irmãos do Buriti\",\n \"Douradina\",\n \"Dourados\",\n \"Eldorado\",\n \"Fátima do Sul\",\n \"Figueirão\",\n \"Glória de Dourados\",\n \"Guia Lopes da Laguna\",\n \"Iguatemi\",\n \"Inocência\",\n \"Itaporã\",\n \"Itaquiraí\",\n \"Ivinhema\",\n \"Japorã\",\n \"Jaraguari\",\n \"Jardim\",\n \"Jateí\",\n \"Juti\",\n \"Ladário\",\n \"Laguna Carapã\",\n \"Maracaju\",\n \"Miranda\",\n \"Mundo Novo\",\n \"Naviraí\",\n \"Nioaque\",\n \"Nova Alvorada do Sul\",\n \"Nova Andradina\",\n \"Novo Horizonte do Sul\",\n \"Paraíso das Águas\",\n \"Paranaíba\",\n \"Paranhos\",\n \"Pedro Gomes\",\n \"Ponta Porã\",\n \"Porto Murtinho\",\n \"Ribas do Rio Pardo\",\n \"Rio Brilhante\",\n \"Rio Negro\",\n \"Rio Verde de Mato Grosso\",\n \"Rochedo\",\n \"Santa Rita do Pardo\",\n \"São Gabriel do Oeste\",\n \"Selvíria\",\n \"Sete Quedas\",\n \"Sidrolândia\",\n \"Sonora\",\n \"Tacuru\",\n \"Taquarussu\",\n \"Terenos\",\n \"Três Lagoas\",\n \"Vicentina\"\n ]\n },\n {\n \"uf\": \"MT\",\n \"name\": \"Mato Grosso\",\n \"cities\": [\n \"Acorizal\",\n \"Água Boa\",\n \"Alta Floresta\",\n \"Alto Araguaia\",\n \"Alto Boa Vista\",\n \"Alto Garças\",\n \"Alto Paraguai\",\n \"Alto Taquari\",\n \"Apiacás\",\n \"Araguaiana\",\n \"Araguainha\",\n \"Araputanga\",\n \"Arenápolis\",\n \"Aripuanã\",\n \"Barão de Melgaço\",\n \"Barra do Bugres\",\n \"Barra do Garças\",\n \"Boa Esperança do Norte\",\n \"Bom Jesus do Araguaia\",\n \"Brasnorte\",\n \"Cáceres\",\n \"Campinápolis\",\n \"Campo Novo do Parecis\",\n \"Campo Verde\",\n \"Campos de Júlio\",\n \"Canabrava do Norte\",\n \"Canarana\",\n \"Carlinda\",\n \"Castanheira\",\n \"Chapada dos Guimarães\",\n \"Cláudia\",\n \"Cocalinho\",\n \"Colíder\",\n \"Colniza\",\n \"Comodoro\",\n \"Confresa\",\n \"Conquista D'Oeste\",\n \"Cotriguaçu\",\n \"Cuiabá\",\n \"Curvelândia\",\n \"Denise\",\n \"Diamantino\",\n \"Dom Aquino\",\n \"Feliz Natal\",\n \"Figueirópolis D'Oeste\",\n \"Gaúcha do Norte\",\n \"General Carneiro\",\n \"Glória D'Oeste\",\n \"Guarantã do Norte\",\n \"Guiratinga\",\n \"Indiavaí\",\n \"Ipiranga do Norte\",\n \"Itanhangá\",\n \"Itaúba\",\n \"Itiquira\",\n \"Jaciara\",\n \"Jangada\",\n \"Jauru\",\n \"Juara\",\n \"Juína\",\n \"Juruena\",\n \"Juscimeira\",\n \"Lambari D'Oeste\",\n \"Lucas do Rio Verde\",\n \"Luciara\",\n \"Marcelândia\",\n \"Matupá\",\n \"Mirassol d'Oeste\",\n \"Nobres\",\n \"Nortelândia\",\n \"Nossa Senhora do Livramento\",\n \"Nova Bandeirantes\",\n \"Nova Brasilândia\",\n \"Nova Canaã do Norte\",\n \"Nova Guarita\",\n \"Nova Lacerda\",\n \"Nova Marilândia\",\n \"Nova Maringá\",\n \"Nova Monte Verde\",\n \"Nova Mutum\",\n \"Nova Nazaré\",\n \"Nova Olímpia\",\n \"Nova Santa Helena\",\n \"Nova Ubiratã\",\n \"Nova Xavantina\",\n \"Novo Horizonte do Norte\",\n \"Novo Mundo\",\n \"Novo Santo Antônio\",\n \"Novo São Joaquim\",\n \"Paranaíta\",\n \"Paranatinga\",\n \"Pedra Preta\",\n \"Peixoto de Azevedo\",\n \"Planalto da Serra\",\n \"Poconé\",\n \"Pontal do Araguaia\",\n \"Ponte Branca\",\n \"Pontes e Lacerda\",\n \"Porto Alegre do Norte\",\n \"Porto dos Gaúchos\",\n \"Porto Esperidião\",\n \"Porto Estrela\",\n \"Poxoréu\",\n \"Primavera do Leste\",\n \"Querência\",\n \"Reserva do Cabaçal\",\n \"Ribeirão Cascalheira\",\n \"Ribeirãozinho\",\n \"Rio Branco\",\n \"Rondolândia\",\n \"Rondonópolis\",\n \"Rosário Oeste\",\n \"Salto do Céu\",\n \"Santa Carmem\",\n \"Santa Cruz do Xingu\",\n \"Santa Rita do Trivelato\",\n \"Santa Terezinha\",\n \"Santo Afonso\",\n \"Santo Antônio de Leverger\",\n \"Santo Antônio do Leste\",\n \"São Félix do Araguaia\",\n \"São José do Povo\",\n \"São José do Rio Claro\",\n \"São José do Xingu\",\n \"São José dos Quatro Marcos\",\n \"São Pedro da Cipa\",\n \"Sapezal\",\n \"Serra Nova Dourada\",\n \"Sinop\",\n \"Sorriso\",\n \"Tabaporã\",\n \"Tangará da Serra\",\n \"Tapurah\",\n \"Terra Nova do Norte\",\n \"Tesouro\",\n \"Torixoréu\",\n \"União do Sul\",\n \"Vale de São Domingos\",\n \"Várzea Grande\",\n \"Vera\",\n \"Vila Bela da Santíssima Trindade\",\n \"Vila Rica\"\n ]\n },\n {\n \"uf\": \"PA\",\n \"name\": \"Pará\",\n \"cities\": [\n \"Abaetetuba\",\n \"Abel Figueiredo\",\n \"Acará\",\n \"Afuá\",\n \"Água Azul do Norte\",\n \"Alenquer\",\n \"Almeirim\",\n \"Altamira\",\n \"Anajás\",\n \"Ananindeua\",\n \"Anapu\",\n \"Augusto Corrêa\",\n \"Aurora do Pará\",\n \"Aveiro\",\n \"Bagre\",\n \"Baião\",\n \"Bannach\",\n \"Barcarena\",\n \"Belém\",\n \"Belterra\",\n \"Benevides\",\n \"Bom Jesus do Tocantins\",\n \"Bonito\",\n \"Bragança\",\n \"Brasil Novo\",\n \"Brejo Grande do Araguaia\",\n \"Breu Branco\",\n \"Breves\",\n \"Bujaru\",\n \"Cachoeira do Arari\",\n \"Cachoeira do Piriá\",\n \"Cametá\",\n \"Canaã dos Carajás\",\n \"Capanema\",\n \"Capitão Poço\",\n \"Castanhal\",\n \"Chaves\",\n \"Colares\",\n \"Conceição do Araguaia\",\n \"Concórdia do Pará\",\n \"Cumaru do Norte\",\n \"Curionópolis\",\n \"Curralinho\",\n \"Curuá\",\n \"Curuçá\",\n \"Dom Eliseu\",\n \"Eldorado do Carajás\",\n \"Faro\",\n \"Floresta do Araguaia\",\n \"Garrafão do Norte\",\n \"Goianésia do Pará\",\n \"Gurupá\",\n \"Igarapé-Açu\",\n \"Igarapé-Miri\",\n \"Inhangapi\",\n \"Ipixuna do Pará\",\n \"Irituia\",\n \"Itaituba\",\n \"Itupiranga\",\n \"Jacareacanga\",\n \"Jacundá\",\n \"Juruti\",\n \"Limoeiro do Ajuru\",\n \"Mãe do Rio\",\n \"Magalhães Barata\",\n \"Marabá\",\n \"Maracanã\",\n \"Marapanim\",\n \"Marituba\",\n \"Medicilândia\",\n \"Melgaço\",\n \"Mocajuba\",\n \"Moju\",\n \"Mojuí dos Campos\",\n \"Monte Alegre\",\n \"Muaná\",\n \"Nova Esperança do Piriá\",\n \"Nova Ipixuna\",\n \"Nova Timboteua\",\n \"Novo Progresso\",\n \"Novo Repartimento\",\n \"Óbidos\",\n \"Oeiras do Pará\",\n \"Oriximiná\",\n \"Ourém\",\n \"Ourilândia do Norte\",\n \"Pacajá\",\n \"Palestina do Pará\",\n \"Paragominas\",\n \"Parauapebas\",\n \"Pau D'Arco\",\n \"Peixe-Boi\",\n \"Piçarra\",\n \"Placas\",\n \"Ponta de Pedras\",\n \"Portel\",\n \"Porto de Moz\",\n \"Prainha\",\n \"Primavera\",\n \"Quatipuru\",\n \"Redenção\",\n \"Rio Maria\",\n \"Rondon do Pará\",\n \"Rurópolis\",\n \"Salinópolis\",\n \"Salvaterra\",\n \"Santa Bárbara do Pará\",\n \"Santa Cruz do Arari\",\n \"Santa Izabel do Pará\",\n \"Santa Luzia do Pará\",\n \"Santa Maria das Barreiras\",\n \"Santa Maria do Pará\",\n \"Santana do Araguaia\",\n \"Santarém\",\n \"Santarém Novo\",\n \"Santo Antônio do Tauá\",\n \"São Caetano de Odivelas\",\n \"São Domingos do Araguaia\",\n \"São Domingos do Capim\",\n \"São Félix do Xingu\",\n \"São Francisco do Pará\",\n \"São Geraldo do Araguaia\",\n \"São João da Ponta\",\n \"São João de Pirabas\",\n \"São João do Araguaia\",\n \"São Miguel do Guamá\",\n \"São Sebastião da Boa Vista\",\n \"Sapucaia\",\n \"Senador José Porfírio\",\n \"Soure\",\n \"Tailândia\",\n \"Terra Alta\",\n \"Terra Santa\",\n \"Tomé-Açu\",\n \"Tracuateua\",\n \"Trairão\",\n \"Tucumã\",\n \"Tucuruí\",\n \"Ulianópolis\",\n \"Uruará\",\n \"Vigia\",\n \"Viseu\",\n \"Vitória do Xingu\",\n \"Xinguara\"\n ]\n },\n {\n \"uf\": \"PB\",\n \"name\": \"Paraíba\",\n \"cities\": [\n \"Água Branca\",\n \"Aguiar\",\n \"Alagoa Grande\",\n \"Alagoa Nova\",\n \"Alagoinha\",\n \"Alcantil\",\n \"Algodão de Jandaíra\",\n \"Alhandra\",\n \"Amparo\",\n \"Aparecida\",\n \"Araçagi\",\n \"Arara\",\n \"Araruna\",\n \"Areia\",\n \"Areia de Baraúnas\",\n \"Areial\",\n \"Aroeiras\",\n \"Assunção\",\n \"Baía da Traição\",\n \"Bananeiras\",\n \"Baraúna\",\n \"Barra de Santa Rosa\",\n \"Barra de Santana\",\n \"Barra de São Miguel\",\n \"Bayeux\",\n \"Belém\",\n \"Belém do Brejo do Cruz\",\n \"Bernardino Batista\",\n \"Boa Ventura\",\n \"Boa Vista\",\n \"Bom Jesus\",\n \"Bom Sucesso\",\n \"Bonito de Santa Fé\",\n \"Boqueirão\",\n \"Borborema\",\n \"Brejo do Cruz\",\n \"Brejo dos Santos\",\n \"Caaporã\",\n \"Cabaceiras\",\n \"Cabedelo\",\n \"Cachoeira dos Índios\",\n \"Cacimba de Areia\",\n \"Cacimba de Dentro\",\n \"Cacimbas\",\n \"Caiçara\",\n \"Cajazeiras\",\n \"Cajazeirinhas\",\n \"Caldas Brandão\",\n \"Camalaú\",\n \"Campina Grande\",\n \"Capim\",\n \"Caraúbas\",\n \"Carrapateira\",\n \"Casserengue\",\n \"Catingueira\",\n \"Catolé do Rocha\",\n \"Caturité\",\n \"Conceição\",\n \"Condado\",\n \"Conde\",\n \"Congo\",\n \"Coremas\",\n \"Coxixola\",\n \"Cruz do Espírito Santo\",\n \"Cubati\",\n \"Cuité\",\n \"Cuité de Mamanguape\",\n \"Cuitegi\",\n \"Curral de Cima\",\n \"Curral Velho\",\n \"Damião\",\n \"Desterro\",\n \"Diamante\",\n \"Dona Inês\",\n \"Duas Estradas\",\n \"Emas\",\n \"Esperança\",\n \"Fagundes\",\n \"Frei Martinho\",\n \"Gado Bravo\",\n \"Guarabira\",\n \"Gurinhém\",\n \"Gurjão\",\n \"Ibiara\",\n \"Igaracy\",\n \"Imaculada\",\n \"Ingá\",\n \"Itabaiana\",\n \"Itaporanga\",\n \"Itapororoca\",\n \"Itatuba\",\n \"Jacaraú\",\n \"Jericó\",\n \"João Pessoa\",\n \"Joca Claudino\",\n \"Juarez Távora\",\n \"Juazeirinho\",\n \"Junco do Seridó\",\n \"Juripiranga\",\n \"Juru\",\n \"Lagoa\",\n \"Lagoa de Dentro\",\n \"Lagoa Seca\",\n \"Lastro\",\n \"Livramento\",\n \"Logradouro\",\n \"Lucena\",\n \"Mãe d'Água\",\n \"Malta\",\n \"Mamanguape\",\n \"Manaíra\",\n \"Marcação\",\n \"Mari\",\n \"Marizópolis\",\n \"Massaranduba\",\n \"Mataraca\",\n \"Matinhas\",\n \"Mato Grosso\",\n \"Maturéia\",\n \"Mogeiro\",\n \"Montadas\",\n \"Monte Horebe\",\n \"Monteiro\",\n \"Mulungu\",\n \"Natuba\",\n \"Nazarezinho\",\n \"Nova Floresta\",\n \"Nova Olinda\",\n \"Nova Palmeira\",\n \"Olho d'Água\",\n \"Olivedos\",\n \"Ouro Velho\",\n \"Parari\",\n \"Passagem\",\n \"Patos\",\n \"Paulista\",\n \"Pedra Branca\",\n \"Pedra Lavrada\",\n \"Pedras de Fogo\",\n \"Pedro Régis\",\n \"Piancó\",\n \"Picuí\",\n \"Pilar\",\n \"Pilões\",\n \"Pilõezinhos\",\n \"Pirpirituba\",\n \"Pitimbu\",\n \"Pocinhos\",\n \"Poço Dantas\",\n \"Poço de José de Moura\",\n \"Pombal\",\n \"Prata\",\n \"Princesa Isabel\",\n \"Puxinanã\",\n \"Queimadas\",\n \"Quixaba\",\n \"Remígio\",\n \"Riachão\",\n \"Riachão do Bacamarte\",\n \"Riachão do Poço\",\n \"Riacho de Santo Antônio\",\n \"Riacho dos Cavalos\",\n \"Rio Tinto\",\n \"Salgadinho\",\n \"Salgado de São Félix\",\n \"Santa Cecília\",\n \"Santa Cruz\",\n \"Santa Helena\",\n \"Santa Inês\",\n \"Santa Luzia\",\n \"Santa Rita\",\n \"Santa Teresinha\",\n \"Santana de Mangueira\",\n \"Santana dos Garrotes\",\n \"Santo André\",\n \"São Bentinho\",\n \"São Bento\",\n \"São Domingos\",\n \"São Domingos do Cariri\",\n \"São Francisco\",\n \"São João do Cariri\",\n \"São João do Rio do Peixe\",\n \"São João do Tigre\",\n \"São José da Lagoa Tapada\",\n \"São José de Caiana\",\n \"São José de Espinharas\",\n \"São José de Piranhas\",\n \"São José de Princesa\",\n \"São José do Bonfim\",\n \"São José do Brejo do Cruz\",\n \"São José do Sabugi\",\n \"São José dos Cordeiros\",\n \"São José dos Ramos\",\n \"São Mamede\",\n \"São Miguel de Taipu\",\n \"São Sebastião de Lagoa de Roça\",\n \"São Sebastião do Umbuzeiro\",\n \"São Vicente do Seridó\",\n \"Sapé\",\n \"Serra Branca\",\n \"Serra da Raiz\",\n \"Serra Grande\",\n \"Serra Redonda\",\n \"Serraria\",\n \"Sertãozinho\",\n \"Sobrado\",\n \"Solânea\",\n \"Soledade\",\n \"Sossêgo\",\n \"Sousa\",\n \"Sumé\",\n \"Tacima\",\n \"Taperoá\",\n \"Tavares\",\n \"Teixeira\",\n \"Tenório\",\n \"Triunfo\",\n \"Uiraúna\",\n \"Umbuzeiro\",\n \"Várzea\",\n \"Vieirópolis\",\n \"Vista Serrana\",\n \"Zabelê\"\n ]\n },\n {\n \"uf\": \"PE\",\n \"name\": \"Pernambuco\",\n \"cities\": [\n \"Abreu e Lima\",\n \"Afogados da Ingazeira\",\n \"Afrânio\",\n \"Agrestina\",\n \"Água Preta\",\n \"Águas Belas\",\n \"Alagoinha\",\n \"Aliança\",\n \"Altinho\",\n \"Amaraji\",\n \"Angelim\",\n \"Araçoiaba\",\n \"Araripina\",\n \"Arcoverde\",\n \"Barra de Guabiraba\",\n \"Barreiros\",\n \"Belém de Maria\",\n \"Belém do São Francisco\",\n \"Belo Jardim\",\n \"Betânia\",\n \"Bezerros\",\n \"Bodocó\",\n \"Bom Conselho\",\n \"Bom Jardim\",\n \"Bonito\",\n \"Brejão\",\n \"Brejinho\",\n \"Brejo da Madre de Deus\",\n \"Buenos Aires\",\n \"Buíque\",\n \"Cabo de Santo Agostinho\",\n \"Cabrobó\",\n \"Cachoeirinha\",\n \"Caetés\",\n \"Calçado\",\n \"Calumbi\",\n \"Camaragibe\",\n \"Camocim de São Félix\",\n \"Camutanga\",\n \"Canhotinho\",\n \"Capoeiras\",\n \"Carnaíba\",\n \"Carnaubeira da Penha\",\n \"Carpina\",\n \"Caruaru\",\n \"Casinhas\",\n \"Catende\",\n \"Cedro\",\n \"Chã de Alegria\",\n \"Chã Grande\",\n \"Condado\",\n \"Correntes\",\n \"Cortês\",\n \"Cumaru\",\n \"Cupira\",\n \"Custódia\",\n \"Dormentes\",\n \"Escada\",\n \"Exu\",\n \"Feira Nova\",\n \"Fernando de Noronha\",\n \"Ferreiros\",\n \"Flores\",\n \"Floresta\",\n \"Frei Miguelinho\",\n \"Gameleira\",\n \"Garanhuns\",\n \"Glória do Goitá\",\n \"Goiana\",\n \"Granito\",\n \"Gravatá\",\n \"Iati\",\n \"Ibimirim\",\n \"Ibirajuba\",\n \"Igarassu\",\n \"Iguaracy\",\n \"Ilha de Itamaracá\",\n \"Inajá\",\n \"Ingazeira\",\n \"Ipojuca\",\n \"Ipubi\",\n \"Itacuruba\",\n \"Itaíba\",\n \"Itambé\",\n \"Itapetim\",\n \"Itapissuma\",\n \"Itaquitinga\",\n \"Jaboatão dos Guararapes\",\n \"Jaqueira\",\n \"Jataúba\",\n \"Jatobá\",\n \"João Alfredo\",\n \"Joaquim Nabuco\",\n \"Jucati\",\n \"Jupi\",\n \"Jurema\",\n \"Lagoa de Itaenga\",\n \"Lagoa do Carro\",\n \"Lagoa do Ouro\",\n \"Lagoa dos Gatos\",\n \"Lagoa Grande\",\n \"Lajedo\",\n \"Limoeiro\",\n \"Macaparana\",\n \"Machados\",\n \"Manari\",\n \"Maraial\",\n \"Mirandiba\",\n \"Moreilândia\",\n \"Moreno\",\n \"Nazaré da Mata\",\n \"Olinda\",\n \"Orobó\",\n \"Orocó\",\n \"Ouricuri\",\n \"Palmares\",\n \"Palmeirina\",\n \"Panelas\",\n \"Paranatama\",\n \"Parnamirim\",\n \"Passira\",\n \"Paudalho\",\n \"Paulista\",\n \"Pedra\",\n \"Pesqueira\",\n \"Petrolândia\",\n \"Petrolina\",\n \"Poção\",\n \"Pombos\",\n \"Primavera\",\n \"Quipapá\",\n \"Quixaba\",\n \"Recife\",\n \"Riacho das Almas\",\n \"Ribeirão\",\n \"Rio Formoso\",\n \"Sairé\",\n \"Salgadinho\",\n \"Salgueiro\",\n \"Saloá\",\n \"Sanharó\",\n \"Santa Cruz\",\n \"Santa Cruz da Baixa Verde\",\n \"Santa Cruz do Capibaribe\",\n \"Santa Filomena\",\n \"Santa Maria da Boa Vista\",\n \"Santa Maria do Cambucá\",\n \"Santa Terezinha\",\n \"São Benedito do Sul\",\n \"São Bento do Una\",\n \"São Caitano\",\n \"São João\",\n \"São Joaquim do Monte\",\n \"São José da Coroa Grande\",\n \"São José do Belmonte\",\n \"São José do Egito\",\n \"São Lourenço da Mata\",\n \"São Vicente Férrer\",\n \"Serra Talhada\",\n \"Serrita\",\n \"Sertânia\",\n \"Sirinhaém\",\n \"Solidão\",\n \"Surubim\",\n \"Tabira\",\n \"Tacaimbó\",\n \"Tacaratu\",\n \"Tamandaré\",\n \"Taquaritinga do Norte\",\n \"Terezinha\",\n \"Terra Nova\",\n \"Timbaúba\",\n \"Toritama\",\n \"Tracunhaém\",\n \"Trindade\",\n \"Triunfo\",\n \"Tupanatinga\",\n \"Tuparetama\",\n \"Venturosa\",\n \"Verdejante\",\n \"Vertente do Lério\",\n \"Vertentes\",\n \"Vicência\",\n \"Vitória de Santo Antão\",\n \"Xexéu\"\n ]\n },\n {\n \"uf\": \"PI\",\n \"name\": \"Piauí\",\n \"cities\": [\n \"Acauã\",\n \"Agricolândia\",\n \"Água Branca\",\n \"Alagoinha do Piauí\",\n \"Alegrete do Piauí\",\n \"Alto Longá\",\n \"Altos\",\n \"Alvorada do Gurguéia\",\n \"Amarante\",\n \"Angical do Piauí\",\n \"Anísio de Abreu\",\n \"Antônio Almeida\",\n \"Aroazes\",\n \"Aroeiras do Itaim\",\n \"Arraial\",\n \"Assunção do Piauí\",\n \"Avelino Lopes\",\n \"Baixa Grande do Ribeiro\",\n \"Barra D'Alcântara\",\n \"Barras\",\n \"Barreiras do Piauí\",\n \"Barro Duro\",\n \"Batalha\",\n \"Bela Vista do Piauí\",\n \"Belém do Piauí\",\n \"Beneditinos\",\n \"Bertolínia\",\n \"Betânia do Piauí\",\n \"Boa Hora\",\n \"Bocaina\",\n \"Bom Jesus\",\n \"Bom Princípio do Piauí\",\n \"Bonfim do Piauí\",\n \"Boqueirão do Piauí\",\n \"Brasileira\",\n \"Brejo do Piauí\",\n \"Buriti dos Lopes\",\n \"Buriti dos Montes\",\n \"Cabeceiras do Piauí\",\n \"Cajazeiras do Piauí\",\n \"Cajueiro da Praia\",\n \"Caldeirão Grande do Piauí\",\n \"Campinas do Piauí\",\n \"Campo Alegre do Fidalgo\",\n \"Campo Grande do Piauí\",\n \"Campo Largo do Piauí\",\n \"Campo Maior\",\n \"Canavieira\",\n \"Canto do Buriti\",\n \"Capitão de Campos\",\n \"Capitão Gervásio Oliveira\",\n \"Caracol\",\n \"Caraúbas do Piauí\",\n \"Caridade do Piauí\",\n \"Castelo do Piauí\",\n \"Caxingó\",\n \"Cocal\",\n \"Cocal de Telha\",\n \"Cocal dos Alves\",\n \"Coivaras\",\n \"Colônia do Gurguéia\",\n \"Colônia do Piauí\",\n \"Conceição do Canindé\",\n \"Coronel José Dias\",\n \"Corrente\",\n \"Cristalândia do Piauí\",\n \"Cristino Castro\",\n \"Curimatá\",\n \"Currais\",\n \"Curral Novo do Piauí\",\n \"Curralinhos\",\n \"Demerval Lobão\",\n \"Dirceu Arcoverde\",\n \"Dom Expedito Lopes\",\n \"Dom Inocêncio\",\n \"Domingos Mourão\",\n \"Elesbão Veloso\",\n \"Eliseu Martins\",\n \"Esperantina\",\n \"Fartura do Piauí\",\n \"Flores do Piauí\",\n \"Floresta do Piauí\",\n \"Floriano\",\n \"Francinópolis\",\n \"Francisco Ayres\",\n \"Francisco Macedo\",\n \"Francisco Santos\",\n \"Fronteiras\",\n \"Geminiano\",\n \"Gilbués\",\n \"Guadalupe\",\n \"Guaribas\",\n \"Hugo Napoleão\",\n \"Ilha Grande\",\n \"Inhuma\",\n \"Ipiranga do Piauí\",\n \"Isaías Coelho\",\n \"Itainópolis\",\n \"Itaueira\",\n \"Jacobina do Piauí\",\n \"Jaicós\",\n \"Jardim do Mulato\",\n \"Jatobá do Piauí\",\n \"Jerumenha\",\n \"João Costa\",\n \"Joaquim Pires\",\n \"Joca Marques\",\n \"José de Freitas\",\n \"Juazeiro do Piauí\",\n \"Júlio Borges\",\n \"Jurema\",\n \"Lagoa Alegre\",\n \"Lagoa de São Francisco\",\n \"Lagoa do Barro do Piauí\",\n \"Lagoa do Piauí\",\n \"Lagoa do Sítio\",\n \"Lagoinha do Piauí\",\n \"Landri Sales\",\n \"Luís Correia\",\n \"Luzilândia\",\n \"Madeiro\",\n \"Manoel Emídio\",\n \"Marcolândia\",\n \"Marcos Parente\",\n \"Massapê do Piauí\",\n \"Matias Olímpio\",\n \"Miguel Alves\",\n \"Miguel Leão\",\n \"Milton Brandão\",\n \"Monsenhor Gil\",\n \"Monsenhor Hipólito\",\n \"Monte Alegre do Piauí\",\n \"Morro Cabeça no Tempo\",\n \"Morro do Chapéu do Piauí\",\n \"Murici dos Portelas\",\n \"Nazaré do Piauí\",\n \"Nazária\",\n \"Nossa Senhora de Nazaré\",\n \"Nossa Senhora dos Remédios\",\n \"Nova Santa Rita\",\n \"Novo Oriente do Piauí\",\n \"Novo Santo Antônio\",\n \"Oeiras\",\n \"Olho D'Água do Piauí\",\n \"Padre Marcos\",\n \"Paes Landim\",\n \"Pajeú do Piauí\",\n \"Palmeira do Piauí\",\n \"Palmeirais\",\n \"Paquetá\",\n \"Parnaguá\",\n \"Parnaíba\",\n \"Passagem Franca do Piauí\",\n \"Patos do Piauí\",\n \"Pau D'Arco do Piauí\",\n \"Paulistana\",\n \"Pavussu\",\n \"Pedro II\",\n \"Pedro Laurentino\",\n \"Picos\",\n \"Pimenteiras\",\n \"Pio IX\",\n \"Piracuruca\",\n \"Piripiri\",\n \"Porto\",\n \"Porto Alegre do Piauí\",\n \"Prata do Piauí\",\n \"Queimada Nova\",\n \"Redenção do Gurguéia\",\n \"Regeneração\",\n \"Riacho Frio\",\n \"Ribeira do Piauí\",\n \"Ribeiro Gonçalves\",\n \"Rio Grande do Piauí\",\n \"Santa Cruz do Piauí\",\n \"Santa Cruz dos Milagres\",\n \"Santa Filomena\",\n \"Santa Luz\",\n \"Santa Rosa do Piauí\",\n \"Santana do Piauí\",\n \"Santo Antônio de Lisboa\",\n \"Santo Antônio dos Milagres\",\n \"Santo Inácio do Piauí\",\n \"São Braz do Piauí\",\n \"São Félix do Piauí\",\n \"São Francisco de Assis do Piauí\",\n \"São Francisco do Piauí\",\n \"São Gonçalo do Gurguéia\",\n \"São Gonçalo do Piauí\",\n \"São João da Canabrava\",\n \"São João da Fronteira\",\n \"São João da Serra\",\n \"São João da Varjota\",\n \"São João do Arraial\",\n \"São João do Piauí\",\n \"São José do Divino\",\n \"São José do Peixe\",\n \"São José do Piauí\",\n \"São Julião\",\n \"São Lourenço do Piauí\",\n \"São Luis do Piauí\",\n \"São Miguel da Baixa Grande\",\n \"São Miguel do Fidalgo\",\n \"São Miguel do Tapuio\",\n \"São Pedro do Piauí\",\n \"São Raimundo Nonato\",\n \"Sebastião Barros\",\n \"Sebastião Leal\",\n \"Sigefredo Pacheco\",\n \"Simões\",\n \"Simplício Mendes\",\n \"Socorro do Piauí\",\n \"Sussuapara\",\n \"Tamboril do Piauí\",\n \"Tanque do Piauí\",\n \"Teresina\",\n \"União\",\n \"Uruçuí\",\n \"Valença do Piauí\",\n \"Várzea Branca\",\n \"Várzea Grande\",\n \"Vera Mendes\",\n \"Vila Nova do Piauí\",\n \"Wall Ferraz\"\n ]\n },\n {\n \"uf\": \"PR\",\n \"name\": \"Paraná\",\n \"cities\": [\n \"Abatiá\",\n \"Adrianópolis\",\n \"Agudos do Sul\",\n \"Almirante Tamandaré\",\n \"Altamira do Paraná\",\n \"Alto Paraíso\",\n \"Alto Paraná\",\n \"Alto Piquiri\",\n \"Altônia\",\n \"Alvorada do Sul\",\n \"Amaporã\",\n \"Ampére\",\n \"Anahy\",\n \"Andirá\",\n \"Ângulo\",\n \"Antonina\",\n \"Antônio Olinto\",\n \"Apucarana\",\n \"Arapongas\",\n \"Arapoti\",\n \"Arapuã\",\n \"Araruna\",\n \"Araucária\",\n \"Ariranha do Ivaí\",\n \"Assaí\",\n \"Assis Chateaubriand\",\n \"Astorga\",\n \"Atalaia\",\n \"Balsa Nova\",\n \"Bandeirantes\",\n \"Barbosa Ferraz\",\n \"Barra do Jacaré\",\n \"Barracão\",\n \"Bela Vista da Caroba\",\n \"Bela Vista do Paraíso\",\n \"Bituruna\",\n \"Boa Esperança\",\n \"Boa Esperança do Iguaçu\",\n \"Boa Ventura de São Roque\",\n \"Boa Vista da Aparecida\",\n \"Bocaiúva do Sul\",\n \"Bom Jesus do Sul\",\n \"Bom Sucesso\",\n \"Bom Sucesso do Sul\",\n \"Borrazópolis\",\n \"Braganey\",\n \"Brasilândia do Sul\",\n \"Cafeara\",\n \"Cafelândia\",\n \"Cafezal do Sul\",\n \"Califórnia\",\n \"Cambará\",\n \"Cambé\",\n \"Cambira\",\n \"Campina da Lagoa\",\n \"Campina do Simão\",\n \"Campina Grande do Sul\",\n \"Campo Bonito\",\n \"Campo do Tenente\",\n \"Campo Largo\",\n \"Campo Magro\",\n \"Campo Mourão\",\n \"Cândido de Abreu\",\n \"Candói\",\n \"Cantagalo\",\n \"Capanema\",\n \"Capitão Leônidas Marques\",\n \"Carambeí\",\n \"Carlópolis\",\n \"Cascavel\",\n \"Castro\",\n \"Catanduvas\",\n \"Centenário do Sul\",\n \"Cerro Azul\",\n \"Céu Azul\",\n \"Chopinzinho\",\n \"Cianorte\",\n \"Cidade Gaúcha\",\n \"Clevelândia\",\n \"Colombo\",\n \"Colorado\",\n \"Congonhinhas\",\n \"Conselheiro Mairinck\",\n \"Contenda\",\n \"Corbélia\",\n \"Cornélio Procópio\",\n \"Coronel Domingos Soares\",\n \"Coronel Vivida\",\n \"Corumbataí do Sul\",\n \"Cruz Machado\",\n \"Cruzeiro do Iguaçu\",\n \"Cruzeiro do Oeste\",\n \"Cruzeiro do Sul\",\n \"Cruzmaltina\",\n \"Curitiba\",\n \"Curiúva\",\n \"Diamante D'Oeste\",\n \"Diamante do Norte\",\n \"Diamante do Sul\",\n \"Dois Vizinhos\",\n \"Douradina\",\n \"Doutor Camargo\",\n \"Doutor Ulysses\",\n \"Enéas Marques\",\n \"Engenheiro Beltrão\",\n \"Entre Rios do Oeste\",\n \"Esperança Nova\",\n \"Espigão Alto do Iguaçu\",\n \"Farol\",\n \"Faxinal\",\n \"Fazenda Rio Grande\",\n \"Fênix\",\n \"Fernandes Pinheiro\",\n \"Figueira\",\n \"Flor da Serra do Sul\",\n \"Floraí\",\n \"Floresta\",\n \"Florestópolis\",\n \"Flórida\",\n \"Formosa do Oeste\",\n \"Foz do Iguaçu\",\n \"Foz do Jordão\",\n \"Francisco Alves\",\n \"Francisco Beltrão\",\n \"General Carneiro\",\n \"Godoy Moreira\",\n \"Goioerê\",\n \"Goioxim\",\n \"Grandes Rios\",\n \"Guaíra\",\n \"Guairaçá\",\n \"Guamiranga\",\n \"Guapirama\",\n \"Guaporema\",\n \"Guaraci\",\n \"Guaraniaçu\",\n \"Guarapuava\",\n \"Guaraqueçaba\",\n \"Guaratuba\",\n \"Honório Serpa\",\n \"Ibaiti\",\n \"Ibema\",\n \"Ibiporã\",\n \"Icaraíma\",\n \"Iguaraçu\",\n \"Iguatu\",\n \"Imbaú\",\n \"Imbituva\",\n \"Inácio Martins\",\n \"Inajá\",\n \"Indianópolis\",\n \"Ipiranga\",\n \"Iporã\",\n \"Iracema do Oeste\",\n \"Irati\",\n \"Iretama\",\n \"Itaguajé\",\n \"Itaipulândia\",\n \"Itambaracá\",\n \"Itambé\",\n \"Itapejara d'Oeste\",\n \"Itaperuçu\",\n \"Itaúna do Sul\",\n \"Ivaí\",\n \"Ivaiporã\",\n \"Ivaté\",\n \"Ivatuba\",\n \"Jaboti\",\n \"Jacarezinho\",\n \"Jaguapitã\",\n \"Jaguariaíva\",\n \"Jandaia do Sul\",\n \"Janiópolis\",\n \"Japira\",\n \"Japurá\",\n \"Jardim Alegre\",\n \"Jardim Olinda\",\n \"Jataizinho\",\n \"Jesuítas\",\n \"Joaquim Távora\",\n \"Jundiaí do Sul\",\n \"Juranda\",\n \"Jussara\",\n \"Kaloré\",\n \"Lapa\",\n \"Laranjal\",\n \"Laranjeiras do Sul\",\n \"Leópolis\",\n \"Lidianópolis\",\n \"Lindoeste\",\n \"Loanda\",\n \"Lobato\",\n \"Londrina\",\n \"Luiziana\",\n \"Lunardelli\",\n \"Lupionópolis\",\n \"Mallet\",\n \"Mamborê\",\n \"Mandaguaçu\",\n \"Mandaguari\",\n \"Mandirituba\",\n \"Manfrinópolis\",\n \"Mangueirinha\",\n \"Manoel Ribas\",\n \"Marechal Cândido Rondon\",\n \"Maria Helena\",\n \"Marialva\",\n \"Marilândia do Sul\",\n \"Marilena\",\n \"Mariluz\",\n \"Maringá\",\n \"Mariópolis\",\n \"Maripá\",\n \"Marmeleiro\",\n \"Marquinho\",\n \"Marumbi\",\n \"Matelândia\",\n \"Matinhos\",\n \"Mato Rico\",\n \"Mauá da Serra\",\n \"Medianeira\",\n \"Mercedes\",\n \"Mirador\",\n \"Miraselva\",\n \"Missal\",\n \"Moreira Sales\",\n \"Morretes\",\n \"Munhoz de Melo\",\n \"Nossa Senhora das Graças\",\n \"Nova Aliança do Ivaí\",\n \"Nova América da Colina\",\n \"Nova Aurora\",\n \"Nova Cantu\",\n \"Nova Esperança\",\n \"Nova Esperança do Sudoeste\",\n \"Nova Fátima\",\n \"Nova Laranjeiras\",\n \"Nova Londrina\",\n \"Nova Olímpia\",\n \"Nova Prata do Iguaçu\",\n \"Nova Santa Bárbara\",\n \"Nova Santa Rosa\",\n \"Nova Tebas\",\n \"Novo Itacolomi\",\n \"Ortigueira\",\n \"Ourizona\",\n \"Ouro Verde do Oeste\",\n \"Paiçandu\",\n \"Palmas\",\n \"Palmeira\",\n \"Palmital\",\n \"Palotina\",\n \"Paraíso do Norte\",\n \"Paranacity\",\n \"Paranaguá\",\n \"Paranapoema\",\n \"Paranavaí\",\n \"Pato Bragado\",\n \"Pato Branco\",\n \"Paula Freitas\",\n \"Paulo Frontin\",\n \"Peabiru\",\n \"Perobal\",\n \"Pérola\",\n \"Pérola d'Oeste\",\n \"Piên\",\n \"Pinhais\",\n \"Pinhal de São Bento\",\n \"Pinhalão\",\n \"Pinhão\",\n \"Piraí do Sul\",\n \"Piraquara\",\n \"Pitanga\",\n \"Pitangueiras\",\n \"Planaltina do Paraná\",\n \"Planalto\",\n \"Ponta Grossa\",\n \"Pontal do Paraná\",\n \"Porecatu\",\n \"Porto Amazonas\",\n \"Porto Barreiro\",\n \"Porto Rico\",\n \"Porto Vitória\",\n \"Prado Ferreira\",\n \"Pranchita\",\n \"Presidente Castelo Branco\",\n \"Primeiro de Maio\",\n \"Prudentópolis\",\n \"Quarto Centenário\",\n \"Quatiguá\",\n \"Quatro Barras\",\n \"Quatro Pontes\",\n \"Quedas do Iguaçu\",\n \"Querência do Norte\",\n \"Quinta do Sol\",\n \"Quitandinha\",\n \"Ramilândia\",\n \"Rancho Alegre\",\n \"Rancho Alegre D'Oeste\",\n \"Realeza\",\n \"Rebouças\",\n \"Renascença\",\n \"Reserva\",\n \"Reserva do Iguaçu\",\n \"Ribeirão Claro\",\n \"Ribeirão do Pinhal\",\n \"Rio Azul\",\n \"Rio Bom\",\n \"Rio Bonito do Iguaçu\",\n \"Rio Branco do Ivaí\",\n \"Rio Branco do Sul\",\n \"Rio Negro\",\n \"Rolândia\",\n \"Roncador\",\n \"Rondon\",\n \"Rosário do Ivaí\",\n \"Sabáudia\",\n \"Salgado Filho\",\n \"Salto do Itararé\",\n \"Salto do Lontra\",\n \"Santa Amélia\",\n \"Santa Cecília do Pavão\",\n \"Santa Cruz de Monte Castelo\",\n \"Santa Fé\",\n \"Santa Helena\",\n \"Santa Inês\",\n \"Santa Isabel do Ivaí\",\n \"Santa Izabel do Oeste\",\n \"Santa Lúcia\",\n \"Santa Maria do Oeste\",\n \"Santa Mariana\",\n \"Santa Mônica\",\n \"Santa Tereza do Oeste\",\n \"Santa Terezinha de Itaipu\",\n \"Santana do Itararé\",\n \"Santo Antônio da Platina\",\n \"Santo Antônio do Caiuá\",\n \"Santo Antônio do Paraíso\",\n \"Santo Antônio do Sudoeste\",\n \"Santo Inácio\",\n \"São Carlos do Ivaí\",\n \"São Jerônimo da Serra\",\n \"São João\",\n \"São João do Caiuá\",\n \"São João do Ivaí\",\n \"São João do Triunfo\",\n \"São Jorge d'Oeste\",\n \"São Jorge do Ivaí\",\n \"São Jorge do Patrocínio\",\n \"São José da Boa Vista\",\n \"São José das Palmeiras\",\n \"São José dos Pinhais\",\n \"São Manoel do Paraná\",\n \"São Mateus do Sul\",\n \"São Miguel do Iguaçu\",\n \"São Pedro do Iguaçu\",\n \"São Pedro do Ivaí\",\n \"São Pedro do Paraná\",\n \"São Sebastião da Amoreira\",\n \"São Tomé\",\n \"Sapopema\",\n \"Sarandi\",\n \"Saudade do Iguaçu\",\n \"Sengés\",\n \"Serranópolis do Iguaçu\",\n \"Sertaneja\",\n \"Sertanópolis\",\n \"Siqueira Campos\",\n \"Sulina\",\n \"Tamarana\",\n \"Tamboara\",\n \"Tapejara\",\n \"Tapira\",\n \"Teixeira Soares\",\n \"Telêmaco Borba\",\n \"Terra Boa\",\n \"Terra Rica\",\n \"Terra Roxa\",\n \"Tibagi\",\n \"Tijucas do Sul\",\n \"Toledo\",\n \"Tomazina\",\n \"Três Barras do Paraná\",\n \"Tunas do Paraná\",\n \"Tuneiras do Oeste\",\n \"Tupãssi\",\n \"Turvo\",\n \"Ubiratã\",\n \"Umuarama\",\n \"União da Vitória\",\n \"Uniflor\",\n \"Uraí\",\n \"Ventania\",\n \"Vera Cruz do Oeste\",\n \"Verê\",\n \"Virmond\",\n \"Vitorino\",\n \"Wenceslau Braz\",\n \"Xambrê\"\n ]\n },\n {\n \"uf\": \"RJ\",\n \"name\": \"Rio de Janeiro\",\n \"cities\": [\n \"Angra dos Reis\",\n \"Aperibé\",\n \"Araruama\",\n \"Areal\",\n \"Armação dos Búzios\",\n \"Arraial do Cabo\",\n \"Barra do Piraí\",\n \"Barra Mansa\",\n \"Belford Roxo\",\n \"Bom Jardim\",\n \"Bom Jesus do Itabapoana\",\n \"Cabo Frio\",\n \"Cachoeiras de Macacu\",\n \"Cambuci\",\n \"Campos dos Goytacazes\",\n \"Cantagalo\",\n \"Carapebus\",\n \"Cardoso Moreira\",\n \"Carmo\",\n \"Casimiro de Abreu\",\n \"Comendador Levy Gasparian\",\n \"Conceição de Macabu\",\n \"Cordeiro\",\n \"Duas Barras\",\n \"Duque de Caxias\",\n \"Engenheiro Paulo de Frontin\",\n \"Guapimirim\",\n \"Iguaba Grande\",\n \"Itaboraí\",\n \"Itaguaí\",\n \"Italva\",\n \"Itaocara\",\n \"Itaperuna\",\n \"Itatiaia\",\n \"Japeri\",\n \"Laje do Muriaé\",\n \"Macaé\",\n \"Macuco\",\n \"Magé\",\n \"Mangaratiba\",\n \"Maricá\",\n \"Mendes\",\n \"Mesquita\",\n \"Miguel Pereira\",\n \"Miracema\",\n \"Natividade\",\n \"Nilópolis\",\n \"Niterói\",\n \"Nova Friburgo\",\n \"Nova Iguaçu\",\n \"Paracambi\",\n \"Paraíba do Sul\",\n \"Paraty\",\n \"Paty do Alferes\",\n \"Petrópolis\",\n \"Pinheiral\",\n \"Piraí\",\n \"Porciúncula\",\n \"Porto Real\",\n \"Quatis\",\n \"Queimados\",\n \"Quissamã\",\n \"Resende\",\n \"Rio Bonito\",\n \"Rio Claro\",\n \"Rio das Flores\",\n \"Rio das Ostras\",\n \"Rio de Janeiro\",\n \"Santa Maria Madalena\",\n \"Santo Antônio de Pádua\",\n \"São Fidélis\",\n \"São Francisco de Itabapoana\",\n \"São Gonçalo\",\n \"São João da Barra\",\n \"São João de Meriti\",\n \"São José de Ubá\",\n \"São José do Vale do Rio Preto\",\n \"São Pedro da Aldeia\",\n \"São Sebastião do Alto\",\n \"Sapucaia\",\n \"Saquarema\",\n \"Seropédica\",\n \"Silva Jardim\",\n \"Sumidouro\",\n \"Tanguá\",\n \"Teresópolis\",\n \"Trajano de Moraes\",\n \"Três Rios\",\n \"Valença\",\n \"Varre-Sai\",\n \"Vassouras\",\n \"Volta Redonda\"\n ]\n },\n {\n \"uf\": \"RN\",\n \"name\": \"Rio Grande do Norte\",\n \"cities\": [\n \"Acari\",\n \"Afonso Bezerra\",\n \"Água Nova\",\n \"Alexandria\",\n \"Almino Afonso\",\n \"Alto do Rodrigues\",\n \"Angicos\",\n \"Antônio Martins\",\n \"Apodi\",\n \"Areia Branca\",\n \"Arez\",\n \"Assú\",\n \"Baía Formosa\",\n \"Baraúna\",\n \"Barcelona\",\n \"Bento Fernandes\",\n \"Bodó\",\n \"Bom Jesus\",\n \"Brejinho\",\n \"Caiçara do Norte\",\n \"Caiçara do Rio do Vento\",\n \"Caicó\",\n \"Campo Grande\",\n \"Campo Redondo\",\n \"Canguaretama\",\n \"Caraúbas\",\n \"Carnaúba dos Dantas\",\n \"Carnaubais\",\n \"Ceará-Mirim\",\n \"Cerro Corá\",\n \"Coronel Ezequiel\",\n \"Coronel João Pessoa\",\n \"Cruzeta\",\n \"Currais Novos\",\n \"Doutor Severiano\",\n \"Encanto\",\n \"Equador\",\n \"Espírito Santo\",\n \"Extremoz\",\n \"Felipe Guerra\",\n \"Fernando Pedroza\",\n \"Florânia\",\n \"Francisco Dantas\",\n \"Frutuoso Gomes\",\n \"Galinhos\",\n \"Goianinha\",\n \"Governador Dix-Sept Rosado\",\n \"Grossos\",\n \"Guamaré\",\n \"Ielmo Marinho\",\n \"Ipanguaçu\",\n \"Ipueira\",\n \"Itajá\",\n \"Itaú\",\n \"Jaçanã\",\n \"Jandaíra\",\n \"Janduís\",\n \"Januário Cicco\",\n \"Japi\",\n \"Jardim de Angicos\",\n \"Jardim de Piranhas\",\n \"Jardim do Seridó\",\n \"João Câmara\",\n \"João Dias\",\n \"José da Penha\",\n \"Jucurutu\",\n \"Jundiá\",\n \"Lagoa d'Anta\",\n \"Lagoa de Pedras\",\n \"Lagoa de Velhos\",\n \"Lagoa Nova\",\n \"Lagoa Salgada\",\n \"Lajes\",\n \"Lajes Pintadas\",\n \"Lucrécia\",\n \"Luís Gomes\",\n \"Macaíba\",\n \"Macau\",\n \"Major Sales\",\n \"Marcelino Vieira\",\n \"Martins\",\n \"Maxaranguape\",\n \"Messias Targino\",\n \"Montanhas\",\n \"Monte Alegre\",\n \"Monte das Gameleiras\",\n \"Mossoró\",\n \"Natal\",\n \"Nísia Floresta\",\n \"Nova Cruz\",\n \"Olho d'Água do Borges\",\n \"Ouro Branco\",\n \"Paraná\",\n \"Paraú\",\n \"Parazinho\",\n \"Parelhas\",\n \"Parnamirim\",\n \"Passa e Fica\",\n \"Passagem\",\n \"Patu\",\n \"Pau dos Ferros\",\n \"Pedra Grande\",\n \"Pedra Preta\",\n \"Pedro Avelino\",\n \"Pedro Velho\",\n \"Pendências\",\n \"Pilões\",\n \"Poço Branco\",\n \"Portalegre\",\n \"Porto do Mangue\",\n \"Pureza\",\n \"Rafael Fernandes\",\n \"Rafael Godeiro\",\n \"Riacho da Cruz\",\n \"Riacho de Santana\",\n \"Riachuelo\",\n \"Rio do Fogo\",\n \"Rodolfo Fernandes\",\n \"Ruy Barbosa\",\n \"Santa Cruz\",\n \"Santa Maria\",\n \"Santana do Matos\",\n \"Santana do Seridó\",\n \"Santo Antônio\",\n \"São Bento do Norte\",\n \"São Bento do Trairí\",\n \"São Fernando\",\n \"São Francisco do Oeste\",\n \"São Gonçalo do Amarante\",\n \"São João do Sabugi\",\n \"São José de Mipibu\",\n \"São José do Campestre\",\n \"São José do Seridó\",\n \"São Miguel\",\n \"São Miguel do Gostoso\",\n \"São Paulo do Potengi\",\n \"São Pedro\",\n \"São Rafael\",\n \"São Tomé\",\n \"São Vicente\",\n \"Senador Elói de Souza\",\n \"Senador Georgino Avelino\",\n \"Serra Caiada\",\n \"Serra de São Bento\",\n \"Serra do Mel\",\n \"Serra Negra do Norte\",\n \"Serrinha\",\n \"Serrinha dos Pintos\",\n \"Severiano Melo\",\n \"Sítio Novo\",\n \"Taboleiro Grande\",\n \"Taipu\",\n \"Tangará\",\n \"Tenente Ananias\",\n \"Tenente Laurentino Cruz\",\n \"Tibau\",\n \"Tibau do Sul\",\n \"Timbaúba dos Batistas\",\n \"Touros\",\n \"Triunfo Potiguar\",\n \"Umarizal\",\n \"Upanema\",\n \"Várzea\",\n \"Venha-Ver\",\n \"Vera Cruz\",\n \"Viçosa\",\n \"Vila Flor\"\n ]\n },\n {\n \"uf\": \"RO\",\n \"name\": \"Rondônia\",\n \"cities\": [\n \"Alta Floresta D'Oeste\",\n \"Alto Alegre dos Parecis\",\n \"Alto Paraíso\",\n \"Alvorada D'Oeste\",\n \"Ariquemes\",\n \"Buritis\",\n \"Cabixi\",\n \"Cacaulândia\",\n \"Cacoal\",\n \"Campo Novo de Rondônia\",\n \"Candeias do Jamari\",\n \"Castanheiras\",\n \"Cerejeiras\",\n \"Chupinguaia\",\n \"Colorado do Oeste\",\n \"Corumbiara\",\n \"Costa Marques\",\n \"Cujubim\",\n \"Espigão D'Oeste\",\n \"Governador Jorge Teixeira\",\n \"Guajará-Mirim\",\n \"Itapuã do Oeste\",\n \"Jaru\",\n \"Ji-Paraná\",\n \"Machadinho D'Oeste\",\n \"Ministro Andreazza\",\n \"Mirante da Serra\",\n \"Monte Negro\",\n \"Nova Brasilândia D'Oeste\",\n \"Nova Mamoré\",\n \"Nova União\",\n \"Novo Horizonte do Oeste\",\n \"Ouro Preto do Oeste\",\n \"Parecis\",\n \"Pimenta Bueno\",\n \"Pimenteiras do Oeste\",\n \"Porto Velho\",\n \"Presidente Médici\",\n \"Primavera de Rondônia\",\n \"Rio Crespo\",\n \"Rolim de Moura\",\n \"Santa Luzia D'Oeste\",\n \"São Felipe D'Oeste\",\n \"São Francisco do Guaporé\",\n \"São Miguel do Guaporé\",\n \"Seringueiras\",\n \"Teixeirópolis\",\n \"Theobroma\",\n \"Urupá\",\n \"Vale do Anari\",\n \"Vale do Paraíso\",\n \"Vilhena\"\n ]\n },\n {\n \"uf\": \"RR\",\n \"name\": \"Roraima\",\n \"cities\": [\n \"Alto Alegre\",\n \"Amajari\",\n \"Boa Vista\",\n \"Bonfim\",\n \"Cantá\",\n \"Caracaraí\",\n \"Caroebe\",\n \"Iracema\",\n \"Mucajaí\",\n \"Normandia\",\n \"Pacaraima\",\n \"Rorainópolis\",\n \"São João da Baliza\",\n \"São Luiz do Anauá\",\n \"Uiramutã\"\n ]\n },\n {\n \"uf\": \"RS\",\n \"name\": \"Rio Grande do Sul\",\n \"cities\": [\n \"Aceguá\",\n \"Água Santa\",\n \"Agudo\",\n \"Ajuricaba\",\n \"Alecrim\",\n \"Alegrete\",\n \"Alegria\",\n \"Almirante Tamandaré do Sul\",\n \"Alpestre\",\n \"Alto Alegre\",\n \"Alto Feliz\",\n \"Alvorada\",\n \"Amaral Ferrador\",\n \"Ametista do Sul\",\n \"André da Rocha\",\n \"Anta Gorda\",\n \"Antônio Prado\",\n \"Arambaré\",\n \"Araricá\",\n \"Aratiba\",\n \"Arroio do Meio\",\n \"Arroio do Padre\",\n \"Arroio do Sal\",\n \"Arroio do Tigre\",\n \"Arroio dos Ratos\",\n \"Arroio Grande\",\n \"Arvorezinha\",\n \"Augusto Pestana\",\n \"Áurea\",\n \"Bagé\",\n \"Balneário Pinhal\",\n \"Barão\",\n \"Barão de Cotegipe\",\n \"Barão do Triunfo\",\n \"Barra do Guarita\",\n \"Barra do Quaraí\",\n \"Barra do Ribeiro\",\n \"Barra do Rio Azul\",\n \"Barra Funda\",\n \"Barracão\",\n \"Barros Cassal\",\n \"Benjamin Constant do Sul\",\n \"Bento Gonçalves\",\n \"Boa Vista das Missões\",\n \"Boa Vista do Buricá\",\n \"Boa Vista do Cadeado\",\n \"Boa Vista do Incra\",\n \"Boa Vista do Sul\",\n \"Bom Jesus\",\n \"Bom Princípio\",\n \"Bom Progresso\",\n \"Bom Retiro do Sul\",\n \"Boqueirão do Leão\",\n \"Bossoroca\",\n \"Bozano\",\n \"Braga\",\n \"Brochier\",\n \"Butiá\",\n \"Caçapava do Sul\",\n \"Cacequi\",\n \"Cachoeira do Sul\",\n \"Cachoeirinha\",\n \"Cacique Doble\",\n \"Caibaté\",\n \"Caiçara\",\n \"Camaquã\",\n \"Camargo\",\n \"Cambará do Sul\",\n \"Campestre da Serra\",\n \"Campina das Missões\",\n \"Campinas do Sul\",\n \"Campo Bom\",\n \"Campo Novo\",\n \"Campos Borges\",\n \"Candelária\",\n \"Cândido Godói\",\n \"Candiota\",\n \"Canela\",\n \"Canguçu\",\n \"Canoas\",\n \"Canudos do Vale\",\n \"Capão Bonito do Sul\",\n \"Capão da Canoa\",\n \"Capão do Cipó\",\n \"Capão do Leão\",\n \"Capela de Santana\",\n \"Capitão\",\n \"Capivari do Sul\",\n \"Caraá\",\n \"Carazinho\",\n \"Carlos Barbosa\",\n \"Carlos Gomes\",\n \"Casca\",\n \"Caseiros\",\n \"Catuípe\",\n \"Caxias do Sul\",\n \"Centenário\",\n \"Cerrito\",\n \"Cerro Branco\",\n \"Cerro Grande\",\n \"Cerro Grande do Sul\",\n \"Cerro Largo\",\n \"Chapada\",\n \"Charqueadas\",\n \"Charrua\",\n \"Chiapetta\",\n \"Chuí\",\n \"Chuvisca\",\n \"Cidreira\",\n \"Ciríaco\",\n \"Colinas\",\n \"Colorado\",\n \"Condor\",\n \"Constantina\",\n \"Coqueiro Baixo\",\n \"Coqueiros do Sul\",\n \"Coronel Barros\",\n \"Coronel Bicaco\",\n \"Coronel Pilar\",\n \"Cotiporã\",\n \"Coxilha\",\n \"Crissiumal\",\n \"Cristal\",\n \"Cristal do Sul\",\n \"Cruz Alta\",\n \"Cruzaltense\",\n \"Cruzeiro do Sul\",\n \"David Canabarro\",\n \"Derrubadas\",\n \"Dezesseis de Novembro\",\n \"Dilermando de Aguiar\",\n \"Dois Irmãos\",\n \"Dois Irmãos das Missões\",\n \"Dois Lajeados\",\n \"Dom Feliciano\",\n \"Dom Pedrito\",\n \"Dom Pedro de Alcântara\",\n \"Dona Francisca\",\n \"Doutor Maurício Cardoso\",\n \"Doutor Ricardo\",\n \"Eldorado do Sul\",\n \"Encantado\",\n \"Encruzilhada do Sul\",\n \"Engenho Velho\",\n \"Entre Rios do Sul\",\n \"Entre-Ijuís\",\n \"Erebango\",\n \"Erechim\",\n \"Ernestina\",\n \"Erval Grande\",\n \"Erval Seco\",\n \"Esmeralda\",\n \"Esperança do Sul\",\n \"Espumoso\",\n \"Estação\",\n \"Estância Velha\",\n \"Esteio\",\n \"Estrela\",\n \"Estrela Velha\",\n \"Eugênio de Castro\",\n \"Fagundes Varela\",\n \"Farroupilha\",\n \"Faxinal do Soturno\",\n \"Faxinalzinho\",\n \"Fazenda Vilanova\",\n \"Feliz\",\n \"Flores da Cunha\",\n \"Floriano Peixoto\",\n \"Fontoura Xavier\",\n \"Formigueiro\",\n \"Forquetinha\",\n \"Fortaleza dos Valos\",\n \"Frederico Westphalen\",\n \"Garibaldi\",\n \"Garruchos\",\n \"Gaurama\",\n \"General Câmara\",\n \"Gentil\",\n \"Getúlio Vargas\",\n \"Giruá\",\n \"Glorinha\",\n \"Gramado\",\n \"Gramado dos Loureiros\",\n \"Gramado Xavier\",\n \"Gravataí\",\n \"Guabiju\",\n \"Guaíba\",\n \"Guaporé\",\n \"Guarani das Missões\",\n \"Harmonia\",\n \"Herval\",\n \"Herveiras\",\n \"Horizontina\",\n \"Hulha Negra\",\n \"Humaitá\",\n \"Ibarama\",\n \"Ibiaçá\",\n \"Ibiraiaras\",\n \"Ibirapuitã\",\n \"Ibirubá\",\n \"Igrejinha\",\n \"Ijuí\",\n \"Ilópolis\",\n \"Imbé\",\n \"Imigrante\",\n \"Independência\",\n \"Inhacorá\",\n \"Ipê\",\n \"Ipiranga do Sul\",\n \"Iraí\",\n \"Itaara\",\n \"Itacurubi\",\n \"Itapuca\",\n \"Itaqui\",\n \"Itati\",\n \"Itatiba do Sul\",\n \"Ivorá\",\n \"Ivoti\",\n \"Jaboticaba\",\n \"Jacuizinho\",\n \"Jacutinga\",\n \"Jaguarão\",\n \"Jaguari\",\n \"Jaquirana\",\n \"Jari\",\n \"Jóia\",\n \"Júlio de Castilhos\",\n \"Lagoa Bonita do Sul\",\n \"Lagoa dos Três Cantos\",\n \"Lagoa Vermelha\",\n \"Lagoão\",\n \"Lajeado\",\n \"Lajeado do Bugre\",\n \"Lavras do Sul\",\n \"Liberato Salzano\",\n \"Lindolfo Collor\",\n \"Linha Nova\",\n \"Maçambará\",\n \"Machadinho\",\n \"Mampituba\",\n \"Manoel Viana\",\n \"Maquiné\",\n \"Maratá\",\n \"Marau\",\n \"Marcelino Ramos\",\n \"Mariana Pimentel\",\n \"Mariano Moro\",\n \"Marques de Souza\",\n \"Mata\",\n \"Mato Castelhano\",\n \"Mato Leitão\",\n \"Mato Queimado\",\n \"Maximiliano de Almeida\",\n \"Minas do Leão\",\n \"Miraguaí\",\n \"Montauri\",\n \"Monte Alegre dos Campos\",\n \"Monte Belo do Sul\",\n \"Montenegro\",\n \"Mormaço\",\n \"Morrinhos do Sul\",\n \"Morro Redondo\",\n \"Morro Reuter\",\n \"Mostardas\",\n \"Muçum\",\n \"Muitos Capões\",\n \"Muliterno\",\n \"Não-Me-Toque\",\n \"Nicolau Vergueiro\",\n \"Nonoai\",\n \"Nova Alvorada\",\n \"Nova Araçá\",\n \"Nova Bassano\",\n \"Nova Boa Vista\",\n \"Nova Bréscia\",\n \"Nova Candelária\",\n \"Nova Esperança do Sul\",\n \"Nova Hartz\",\n \"Nova Pádua\",\n \"Nova Palma\",\n \"Nova Petrópolis\",\n \"Nova Prata\",\n \"Nova Ramada\",\n \"Nova Roma do Sul\",\n \"Nova Santa Rita\",\n \"Novo Barreiro\",\n \"Novo Cabrais\",\n \"Novo Hamburgo\",\n \"Novo Machado\",\n \"Novo Tiradentes\",\n \"Novo Xingu\",\n \"Osório\",\n \"Paim Filho\",\n \"Palmares do Sul\",\n \"Palmeira das Missões\",\n \"Palmitinho\",\n \"Panambi\",\n \"Pantano Grande\",\n \"Paraí\",\n \"Paraíso do Sul\",\n \"Pareci Novo\",\n \"Parobé\",\n \"Passa Sete\",\n \"Passo do Sobrado\",\n \"Passo Fundo\",\n \"Paulo Bento\",\n \"Paverama\",\n \"Pedras Altas\",\n \"Pedro Osório\",\n \"Pejuçara\",\n \"Pelotas\",\n \"Picada Café\",\n \"Pinhal\",\n \"Pinhal da Serra\",\n \"Pinhal Grande\",\n \"Pinheirinho do Vale\",\n \"Pinheiro Machado\",\n \"Pinto Bandeira\",\n \"Pirapó\",\n \"Piratini\",\n \"Planalto\",\n \"Poço das Antas\",\n \"Pontão\",\n \"Ponte Preta\",\n \"Portão\",\n \"Porto Alegre\",\n \"Porto Lucena\",\n \"Porto Mauá\",\n \"Porto Vera Cruz\",\n \"Porto Xavier\",\n \"Pouso Novo\",\n \"Presidente Lucena\",\n \"Progresso\",\n \"Protásio Alves\",\n \"Putinga\",\n \"Quaraí\",\n \"Quatro Irmãos\",\n \"Quevedos\",\n \"Quinze de Novembro\",\n \"Redentora\",\n \"Relvado\",\n \"Restinga Sêca\",\n \"Rio dos Índios\",\n \"Rio Grande\",\n \"Rio Pardo\",\n \"Riozinho\",\n \"Roca Sales\",\n \"Rodeio Bonito\",\n \"Rolador\",\n \"Rolante\",\n \"Ronda Alta\",\n \"Rondinha\",\n \"Roque Gonzales\",\n \"Rosário do Sul\",\n \"Sagrada Família\",\n \"Saldanha Marinho\",\n \"Salto do Jacuí\",\n \"Salvador das Missões\",\n \"Salvador do Sul\",\n \"Sananduva\",\n \"Sant'Ana do Livramento\",\n \"Santa Bárbara do Sul\",\n \"Santa Cecília do Sul\",\n \"Santa Clara do Sul\",\n \"Santa Cruz do Sul\",\n \"Santa Margarida do Sul\",\n \"Santa Maria\",\n \"Santa Maria do Herval\",\n \"Santa Rosa\",\n \"Santa Tereza\",\n \"Santa Vitória do Palmar\",\n \"Santana da Boa Vista\",\n \"Santiago\",\n \"Santo Ângelo\",\n \"Santo Antônio da Patrulha\",\n \"Santo Antônio das Missões\",\n \"Santo Antônio do Palma\",\n \"Santo Antônio do Planalto\",\n \"Santo Augusto\",\n \"Santo Cristo\",\n \"Santo Expedito do Sul\",\n \"São Borja\",\n \"São Domingos do Sul\",\n \"São Francisco de Assis\",\n \"São Francisco de Paula\",\n \"São Gabriel\",\n \"São Jerônimo\",\n \"São João da Urtiga\",\n \"São João do Polêsine\",\n \"São Jorge\",\n \"São José das Missões\",\n \"São José do Herval\",\n \"São José do Hortêncio\",\n \"São José do Inhacorá\",\n \"São José do Norte\",\n \"São José do Ouro\",\n \"São José do Sul\",\n \"São José dos Ausentes\",\n \"São Leopoldo\",\n \"São Lourenço do Sul\",\n \"São Luiz Gonzaga\",\n \"São Marcos\",\n \"São Martinho\",\n \"São Martinho da Serra\",\n \"São Miguel das Missões\",\n \"São Nicolau\",\n \"São Paulo das Missões\",\n \"São Pedro da Serra\",\n \"São Pedro das Missões\",\n \"São Pedro do Butiá\",\n \"São Pedro do Sul\",\n \"São Sebastião do Caí\",\n \"São Sepé\",\n \"São Valentim\",\n \"São Valentim do Sul\",\n \"São Valério do Sul\",\n \"São Vendelino\",\n \"São Vicente do Sul\",\n \"Sapiranga\",\n \"Sapucaia do Sul\",\n \"Sarandi\",\n \"Seberi\",\n \"Sede Nova\",\n \"Segredo\",\n \"Selbach\",\n \"Senador Salgado Filho\",\n \"Sentinela do Sul\",\n \"Serafina Corrêa\",\n \"Sério\",\n \"Sertão\",\n \"Sertão Santana\",\n \"Sete de Setembro\",\n \"Severiano de Almeida\",\n \"Silveira Martins\",\n \"Sinimbu\",\n \"Sobradinho\",\n \"Soledade\",\n \"Tabaí\",\n \"Tapejara\",\n \"Tapera\",\n \"Tapes\",\n \"Taquara\",\n \"Taquari\",\n \"Taquaruçu do Sul\",\n \"Tavares\",\n \"Tenente Portela\",\n \"Terra de Areia\",\n \"Teutônia\",\n \"Tio Hugo\",\n \"Tiradentes do Sul\",\n \"Toropi\",\n \"Torres\",\n \"Tramandaí\",\n \"Travesseiro\",\n \"Três Arroios\",\n \"Três Cachoeiras\",\n \"Três Coroas\",\n \"Três de Maio\",\n \"Três Forquilhas\",\n \"Três Palmeiras\",\n \"Três Passos\",\n \"Trindade do Sul\",\n \"Triunfo\",\n \"Tucunduva\",\n \"Tunas\",\n \"Tupanci do Sul\",\n \"Tupanciretã\",\n \"Tupandi\",\n \"Tuparendi\",\n \"Turuçu\",\n \"Ubiretama\",\n \"União da Serra\",\n \"Unistalda\",\n \"Uruguaiana\",\n \"Vacaria\",\n \"Vale do Sol\",\n \"Vale Real\",\n \"Vale Verde\",\n \"Vanini\",\n \"Venâncio Aires\",\n \"Vera Cruz\",\n \"Veranópolis\",\n \"Vespasiano Corrêa\",\n \"Viadutos\",\n \"Viamão\",\n \"Vicente Dutra\",\n \"Victor Graeff\",\n \"Vila Flores\",\n \"Vila Lângaro\",\n \"Vila Maria\",\n \"Vila Nova do Sul\",\n \"Vista Alegre\",\n \"Vista Alegre do Prata\",\n \"Vista Gaúcha\",\n \"Vitória das Missões\",\n \"Westfália\",\n \"Xangri-lá\"\n ]\n },\n {\n \"uf\": \"SC\",\n \"name\": \"Santa Catarina\",\n \"cities\": [\n \"Abdon Batista\",\n \"Abelardo Luz\",\n \"Agrolândia\",\n \"Agronômica\",\n \"Água Doce\",\n \"Águas de Chapecó\",\n \"Águas Frias\",\n \"Águas Mornas\",\n \"Alfredo Wagner\",\n \"Alto Bela Vista\",\n \"Anchieta\",\n \"Angelina\",\n \"Anita Garibaldi\",\n \"Anitápolis\",\n \"Antônio Carlos\",\n \"Apiúna\",\n \"Arabutã\",\n \"Araquari\",\n \"Araranguá\",\n \"Armazém\",\n \"Arroio Trinta\",\n \"Arvoredo\",\n \"Ascurra\",\n \"Atalanta\",\n \"Aurora\",\n \"Balneário Arroio do Silva\",\n \"Balneário Barra do Sul\",\n \"Balneário Camboriú\",\n \"Balneário Gaivota\",\n \"Balneário Piçarras\",\n \"Balneário Rincão\",\n \"Bandeirante\",\n \"Barra Bonita\",\n \"Barra Velha\",\n \"Bela Vista do Toldo\",\n \"Belmonte\",\n \"Benedito Novo\",\n \"Biguaçu\",\n \"Blumenau\",\n \"Bocaina do Sul\",\n \"Bom Jardim da Serra\",\n \"Bom Jesus\",\n \"Bom Jesus do Oeste\",\n \"Bom Retiro\",\n \"Bombinhas\",\n \"Botuverá\",\n \"Braço do Norte\",\n \"Braço do Trombudo\",\n \"Brunópolis\",\n \"Brusque\",\n \"Caçador\",\n \"Caibi\",\n \"Calmon\",\n \"Camboriú\",\n \"Campo Alegre\",\n \"Campo Belo do Sul\",\n \"Campo Erê\",\n \"Campos Novos\",\n \"Canelinha\",\n \"Canoinhas\",\n \"Capão Alto\",\n \"Capinzal\",\n \"Capivari de Baixo\",\n \"Catanduvas\",\n \"Caxambu do Sul\",\n \"Celso Ramos\",\n \"Cerro Negro\",\n \"Chapadão do Lageado\",\n \"Chapecó\",\n \"Cocal do Sul\",\n \"Concórdia\",\n \"Cordilheira Alta\",\n \"Coronel Freitas\",\n \"Coronel Martins\",\n \"Correia Pinto\",\n \"Corupá\",\n \"Criciúma\",\n \"Cunha Porã\",\n \"Cunhataí\",\n \"Curitibanos\",\n \"Descanso\",\n \"Dionísio Cerqueira\",\n \"Dona Emma\",\n \"Doutor Pedrinho\",\n \"Entre Rios\",\n \"Ermo\",\n \"Erval Velho\",\n \"Faxinal dos Guedes\",\n \"Flor do Sertão\",\n \"Florianópolis\",\n \"Formosa do Sul\",\n \"Forquilhinha\",\n \"Fraiburgo\",\n \"Frei Rogério\",\n \"Galvão\",\n \"Garopaba\",\n \"Garuva\",\n \"Gaspar\",\n \"Governador Celso Ramos\",\n \"Grão-Pará\",\n \"Gravatal\",\n \"Guabiruba\",\n \"Guaraciaba\",\n \"Guaramirim\",\n \"Guarujá do Sul\",\n \"Guatambú\",\n \"Herval d'Oeste\",\n \"Ibiam\",\n \"Ibicaré\",\n \"Ibirama\",\n \"Içara\",\n \"Ilhota\",\n \"Imaruí\",\n \"Imbituba\",\n \"Imbuia\",\n \"Indaial\",\n \"Iomerê\",\n \"Ipira\",\n \"Iporã do Oeste\",\n \"Ipuaçu\",\n \"Ipumirim\",\n \"Iraceminha\",\n \"Irani\",\n \"Irati\",\n \"Irineópolis\",\n \"Itá\",\n \"Itaiópolis\",\n \"Itajaí\",\n \"Itapema\",\n \"Itapiranga\",\n \"Itapoá\",\n \"Ituporanga\",\n \"Jaborá\",\n \"Jacinto Machado\",\n \"Jaguaruna\",\n \"Jaraguá do Sul\",\n \"Jardinópolis\",\n \"Joaçaba\",\n \"Joinville\",\n \"José Boiteux\",\n \"Jupiá\",\n \"Lacerdópolis\",\n \"Lages\",\n \"Laguna\",\n \"Lajeado Grande\",\n \"Laurentino\",\n \"Lauro Müller\",\n \"Lebon Régis\",\n \"Leoberto Leal\",\n \"Lindóia do Sul\",\n \"Lontras\",\n \"Luiz Alves\",\n \"Luzerna\",\n \"Macieira\",\n \"Mafra\",\n \"Major Gercino\",\n \"Major Vieira\",\n \"Maracajá\",\n \"Maravilha\",\n \"Marema\",\n \"Massaranduba\",\n \"Matos Costa\",\n \"Meleiro\",\n \"Mirim Doce\",\n \"Modelo\",\n \"Mondaí\",\n \"Monte Carlo\",\n \"Monte Castelo\",\n \"Morro da Fumaça\",\n \"Morro Grande\",\n \"Navegantes\",\n \"Nova Erechim\",\n \"Nova Itaberaba\",\n \"Nova Trento\",\n \"Nova Veneza\",\n \"Novo Horizonte\",\n \"Orleans\",\n \"Otacílio Costa\",\n \"Ouro\",\n \"Ouro Verde\",\n \"Paial\",\n \"Painel\",\n \"Palhoça\",\n \"Palma Sola\",\n \"Palmeira\",\n \"Palmitos\",\n \"Papanduva\",\n \"Paraíso\",\n \"Passo de Torres\",\n \"Passos Maia\",\n \"Paulo Lopes\",\n \"Pedras Grandes\",\n \"Penha\",\n \"Peritiba\",\n \"Pescaria Brava\",\n \"Petrolândia\",\n \"Pinhalzinho\",\n \"Pinheiro Preto\",\n \"Piratuba\",\n \"Planalto Alegre\",\n \"Pomerode\",\n \"Ponte Alta\",\n \"Ponte Alta do Norte\",\n \"Ponte Serrada\",\n \"Porto Belo\",\n \"Porto União\",\n \"Pouso Redondo\",\n \"Praia Grande\",\n \"Presidente Castello Branco\",\n \"Presidente Getúlio\",\n \"Presidente Nereu\",\n \"Princesa\",\n \"Quilombo\",\n \"Rancho Queimado\",\n \"Rio das Antas\",\n \"Rio do Campo\",\n \"Rio do Oeste\",\n \"Rio do Sul\",\n \"Rio dos Cedros\",\n \"Rio Fortuna\",\n \"Rio Negrinho\",\n \"Rio Rufino\",\n \"Riqueza\",\n \"Rodeio\",\n \"Romelândia\",\n \"Salete\",\n \"Saltinho\",\n \"Salto Veloso\",\n \"Sangão\",\n \"Santa Cecília\",\n \"Santa Helena\",\n \"Santa Rosa de Lima\",\n \"Santa Rosa do Sul\",\n \"Santa Terezinha\",\n \"Santa Terezinha do Progresso\",\n \"Santiago do Sul\",\n \"Santo Amaro da Imperatriz\",\n \"São Bento do Sul\",\n \"São Bernardino\",\n \"São Bonifácio\",\n \"São Carlos\",\n \"São Cristóvão do Sul\",\n \"São Domingos\",\n \"São Francisco do Sul\",\n \"São João Batista\",\n \"São João do Itaperiú\",\n \"São João do Oeste\",\n \"São João do Sul\",\n \"São Joaquim\",\n \"São José\",\n \"São José do Cedro\",\n \"São José do Cerrito\",\n \"São Lourenço do Oeste\",\n \"São Ludgero\",\n \"São Martinho\",\n \"São Miguel da Boa Vista\",\n \"São Miguel do Oeste\",\n \"São Pedro de Alcântara\",\n \"Saudades\",\n \"Schroeder\",\n \"Seara\",\n \"Serra Alta\",\n \"Siderópolis\",\n \"Sombrio\",\n \"Sul Brasil\",\n \"Taió\",\n \"Tangará\",\n \"Tigrinhos\",\n \"Tijucas\",\n \"Timbé do Sul\",\n \"Timbó\",\n \"Timbó Grande\",\n \"Três Barras\",\n \"Treviso\",\n \"Treze de Maio\",\n \"Treze Tílias\",\n \"Trombudo Central\",\n \"Tubarão\",\n \"Tunápolis\",\n \"Turvo\",\n \"União do Oeste\",\n \"Urubici\",\n \"Urupema\",\n \"Urussanga\",\n \"Vargeão\",\n \"Vargem\",\n \"Vargem Bonita\",\n \"Vidal Ramos\",\n \"Videira\",\n \"Vitor Meireles\",\n \"Witmarsum\",\n \"Xanxerê\",\n \"Xavantina\",\n \"Xaxim\",\n \"Zortéa\"\n ]\n },\n {\n \"uf\": \"SE\",\n \"name\": \"Sergipe\",\n \"cities\": [\n \"Amparo do São Francisco\",\n \"Aquidabã\",\n \"Aracaju\",\n \"Arauá\",\n \"Areia Branca\",\n \"Barra dos Coqueiros\",\n \"Boquim\",\n \"Brejo Grande\",\n \"Campo do Brito\",\n \"Canhoba\",\n \"Canindé de São Francisco\",\n \"Capela\",\n \"Carira\",\n \"Carmópolis\",\n \"Cedro de São João\",\n \"Cristinápolis\",\n \"Cumbe\",\n \"Divina Pastora\",\n \"Estância\",\n \"Feira Nova\",\n \"Frei Paulo\",\n \"Gararu\",\n \"General Maynard\",\n \"Graccho Cardoso\",\n \"Ilha das Flores\",\n \"Indiaroba\",\n \"Itabaiana\",\n \"Itabaianinha\",\n \"Itabi\",\n \"Itaporanga d'Ajuda\",\n \"Japaratuba\",\n \"Japoatã\",\n \"Lagarto\",\n \"Laranjeiras\",\n \"Macambira\",\n \"Malhada dos Bois\",\n \"Malhador\",\n \"Maruim\",\n \"Moita Bonita\",\n \"Monte Alegre de Sergipe\",\n \"Muribeca\",\n \"Neópolis\",\n \"Nossa Senhora Aparecida\",\n \"Nossa Senhora da Glória\",\n \"Nossa Senhora das Dores\",\n \"Nossa Senhora de Lourdes\",\n \"Nossa Senhora do Socorro\",\n \"Pacatuba\",\n \"Pedra Mole\",\n \"Pedrinhas\",\n \"Pinhão\",\n \"Pirambu\",\n \"Poço Redondo\",\n \"Poço Verde\",\n \"Porto da Folha\",\n \"Propriá\",\n \"Riachão do Dantas\",\n \"Riachuelo\",\n \"Ribeirópolis\",\n \"Rosário do Catete\",\n \"Salgado\",\n \"Santa Luzia do Itanhy\",\n \"Santa Rosa de Lima\",\n \"Santana do São Francisco\",\n \"Santo Amaro das Brotas\",\n \"São Cristóvão\",\n \"São Domingos\",\n \"São Francisco\",\n \"São Miguel do Aleixo\",\n \"Simão Dias\",\n \"Siriri\",\n \"Telha\",\n \"Tobias Barreto\",\n \"Tomar do Geru\",\n \"Umbaúba\"\n ]\n },\n {\n \"uf\": \"SP\",\n \"name\": \"São Paulo\",\n \"cities\": [\n \"Adamantina\",\n \"Adolfo\",\n \"Aguaí\",\n \"Águas da Prata\",\n \"Águas de Lindóia\",\n \"Águas de Santa Bárbara\",\n \"Águas de São Pedro\",\n \"Agudos\",\n \"Alambari\",\n \"Alfredo Marcondes\",\n \"Altair\",\n \"Altinópolis\",\n \"Alto Alegre\",\n \"Alumínio\",\n \"Álvares Florence\",\n \"Álvares Machado\",\n \"Álvaro de Carvalho\",\n \"Alvinlândia\",\n \"Americana\",\n \"Américo Brasiliense\",\n \"Américo de Campos\",\n \"Amparo\",\n \"Analândia\",\n \"Andradina\",\n \"Angatuba\",\n \"Anhembi\",\n \"Anhumas\",\n \"Aparecida\",\n \"Aparecida d'Oeste\",\n \"Apiaí\",\n \"Araçariguama\",\n \"Araçatuba\",\n \"Araçoiaba da Serra\",\n \"Aramina\",\n \"Arandu\",\n \"Arapeí\",\n \"Araraquara\",\n \"Araras\",\n \"Arco-Íris\",\n \"Arealva\",\n \"Areias\",\n \"Areiópolis\",\n \"Ariranha\",\n \"Artur Nogueira\",\n \"Arujá\",\n \"Aspásia\",\n \"Assis\",\n \"Atibaia\",\n \"Auriflama\",\n \"Avaí\",\n \"Avanhandava\",\n \"Avaré\",\n \"Bady Bassitt\",\n \"Balbinos\",\n \"Bálsamo\",\n \"Bananal\",\n \"Barão de Antonina\",\n \"Barbosa\",\n \"Bariri\",\n \"Barra Bonita\",\n \"Barra do Chapéu\",\n \"Barra do Turvo\",\n \"Barretos\",\n \"Barrinha\",\n \"Barueri\",\n \"Bastos\",\n \"Batatais\",\n \"Bauru\",\n \"Bebedouro\",\n \"Bento de Abreu\",\n \"Bernardino de Campos\",\n \"Bertioga\",\n \"Bilac\",\n \"Birigui\",\n \"Biritiba Mirim\",\n \"Boa Esperança do Sul\",\n \"Bocaina\",\n \"Bofete\",\n \"Boituva\",\n \"Bom Jesus dos Perdões\",\n \"Bom Sucesso de Itararé\",\n \"Borá\",\n \"Boracéia\",\n \"Borborema\",\n \"Borebi\",\n \"Botucatu\",\n \"Bragança Paulista\",\n \"Braúna\",\n \"Brejo Alegre\",\n \"Brodowski\",\n \"Brotas\",\n \"Buri\",\n \"Buritama\",\n \"Buritizal\",\n \"Cabrália Paulista\",\n \"Cabreúva\",\n \"Caçapava\",\n \"Cachoeira Paulista\",\n \"Caconde\",\n \"Cafelândia\",\n \"Caiabu\",\n \"Caieiras\",\n \"Caiuá\",\n \"Cajamar\",\n \"Cajati\",\n \"Cajobi\",\n \"Cajuru\",\n \"Campina do Monte Alegre\",\n \"Campinas\",\n \"Campo Limpo Paulista\",\n \"Campos do Jordão\",\n \"Campos Novos Paulista\",\n \"Cananéia\",\n \"Canas\",\n \"Cândido Mota\",\n \"Cândido Rodrigues\",\n \"Canitar\",\n \"Capão Bonito\",\n \"Capela do Alto\",\n \"Capivari\",\n \"Caraguatatuba\",\n \"Carapicuíba\",\n \"Cardoso\",\n \"Casa Branca\",\n \"Cássia dos Coqueiros\",\n \"Castilho\",\n \"Catanduva\",\n \"Catiguá\",\n \"Cedral\",\n \"Cerqueira César\",\n \"Cerquilho\",\n \"Cesário Lange\",\n \"Charqueada\",\n \"Chavantes\",\n \"Clementina\",\n \"Colina\",\n \"Colômbia\",\n \"Conchal\",\n \"Conchas\",\n \"Cordeirópolis\",\n \"Coroados\",\n \"Coronel Macedo\",\n \"Corumbataí\",\n \"Cosmópolis\",\n \"Cosmorama\",\n \"Cotia\",\n \"Cravinhos\",\n \"Cristais Paulista\",\n \"Cruzália\",\n \"Cruzeiro\",\n \"Cubatão\",\n \"Cunha\",\n \"Descalvado\",\n \"Diadema\",\n \"Dirce Reis\",\n \"Divinolândia\",\n \"Dobrada\",\n \"Dois Córregos\",\n \"Dolcinópolis\",\n \"Dourado\",\n \"Dracena\",\n \"Duartina\",\n \"Dumont\",\n \"Echaporã\",\n \"Eldorado\",\n \"Elias Fausto\",\n \"Elisiário\",\n \"Embaúba\",\n \"Embu das Artes\",\n \"Embu-Guaçu\",\n \"Emilianópolis\",\n \"Engenheiro Coelho\",\n \"Espírito Santo do Pinhal\",\n \"Espírito Santo do Turvo\",\n \"Estiva Gerbi\",\n \"Estrela d'Oeste\",\n \"Estrela do Norte\",\n \"Euclides da Cunha Paulista\",\n \"Fartura\",\n \"Fernando Prestes\",\n \"Fernandópolis\",\n \"Fernão\",\n \"Ferraz de Vasconcelos\",\n \"Flora Rica\",\n \"Floreal\",\n \"Flórida Paulista\",\n \"Florínea\",\n \"Franca\",\n \"Francisco Morato\",\n \"Franco da Rocha\",\n \"Gabriel Monteiro\",\n \"Gália\",\n \"Garça\",\n \"Gastão Vidigal\",\n \"Gavião Peixoto\",\n \"General Salgado\",\n \"Getulina\",\n \"Glicério\",\n \"Guaiçara\",\n \"Guaimbê\",\n \"Guaíra\",\n \"Guapiaçu\",\n \"Guapiara\",\n \"Guará\",\n \"Guaraçaí\",\n \"Guaraci\",\n \"Guarani d'Oeste\",\n \"Guarantã\",\n \"Guararapes\",\n \"Guararema\",\n \"Guaratinguetá\",\n \"Guareí\",\n \"Guariba\",\n \"Guarujá\",\n \"Guarulhos\",\n \"Guatapará\",\n \"Guzolândia\",\n \"Herculândia\",\n \"Holambra\",\n \"Hortolândia\",\n \"Iacanga\",\n \"Iacri\",\n \"Iaras\",\n \"Ibaté\",\n \"Ibirá\",\n \"Ibirarema\",\n \"Ibitinga\",\n \"Ibiúna\",\n \"Icém\",\n \"Iepê\",\n \"Igaraçu do Tietê\",\n \"Igarapava\",\n \"Igaratá\",\n \"Iguape\",\n \"Ilha Comprida\",\n \"Ilha Solteira\",\n \"Ilhabela\",\n \"Indaiatuba\",\n \"Indiana\",\n \"Indiaporã\",\n \"Inúbia Paulista\",\n \"Ipaussu\",\n \"Iperó\",\n \"Ipeúna\",\n \"Ipiguá\",\n \"Iporanga\",\n \"Ipuã\",\n \"Iracemápolis\",\n \"Irapuã\",\n \"Irapuru\",\n \"Itaberá\",\n \"Itaí\",\n \"Itajobi\",\n \"Itaju\",\n \"Itanhaém\",\n \"Itaoca\",\n \"Itapecerica da Serra\",\n \"Itapetininga\",\n \"Itapeva\",\n \"Itapevi\",\n \"Itapira\",\n \"Itapirapuã Paulista\",\n \"Itápolis\",\n \"Itaporanga\",\n \"Itapuí\",\n \"Itapura\",\n \"Itaquaquecetuba\",\n \"Itararé\",\n \"Itariri\",\n \"Itatiba\",\n \"Itatinga\",\n \"Itirapina\",\n \"Itirapuã\",\n \"Itobi\",\n \"Itu\",\n \"Itupeva\",\n \"Ituverava\",\n \"Jaborandi\",\n \"Jaboticabal\",\n \"Jacareí\",\n \"Jaci\",\n \"Jacupiranga\",\n \"Jaguariúna\",\n \"Jales\",\n \"Jambeiro\",\n \"Jandira\",\n \"Jardinópolis\",\n \"Jarinu\",\n \"Jaú\",\n \"Jeriquara\",\n \"Joanópolis\",\n \"João Ramalho\",\n \"José Bonifácio\",\n \"Júlio Mesquita\",\n \"Jumirim\",\n \"Jundiaí\",\n \"Junqueirópolis\",\n \"Juquiá\",\n \"Juquitiba\",\n \"Lagoinha\",\n \"Laranjal Paulista\",\n \"Lavínia\",\n \"Lavrinhas\",\n \"Leme\",\n \"Lençóis Paulista\",\n \"Limeira\",\n \"Lindóia\",\n \"Lins\",\n \"Lorena\",\n \"Lourdes\",\n \"Louveira\",\n \"Lucélia\",\n \"Lucianópolis\",\n \"Luís Antônio\",\n \"Luiziânia\",\n \"Lupércio\",\n \"Lutécia\",\n \"Macatuba\",\n \"Macaubal\",\n \"Macedônia\",\n \"Magda\",\n \"Mairinque\",\n \"Mairiporã\",\n \"Manduri\",\n \"Marabá Paulista\",\n \"Maracaí\",\n \"Marapoama\",\n \"Mariápolis\",\n \"Marília\",\n \"Marinópolis\",\n \"Martinópolis\",\n \"Matão\",\n \"Mauá\",\n \"Mendonça\",\n \"Meridiano\",\n \"Mesópolis\",\n \"Miguelópolis\",\n \"Mineiros do Tietê\",\n \"Mira Estrela\",\n \"Miracatu\",\n \"Mirandópolis\",\n \"Mirante do Paranapanema\",\n \"Mirassol\",\n \"Mirassolândia\",\n \"Mococa\",\n \"Mogi das Cruzes\",\n \"Mogi Guaçu\",\n \"Mogi Mirim\",\n \"Mombuca\",\n \"Monções\",\n \"Mongaguá\",\n \"Monte Alegre do Sul\",\n \"Monte Alto\",\n \"Monte Aprazível\",\n \"Monte Azul Paulista\",\n \"Monte Castelo\",\n \"Monte Mor\",\n \"Monteiro Lobato\",\n \"Morro Agudo\",\n \"Morungaba\",\n \"Motuca\",\n \"Murutinga do Sul\",\n \"Nantes\",\n \"Narandiba\",\n \"Natividade da Serra\",\n \"Nazaré Paulista\",\n \"Neves Paulista\",\n \"Nhandeara\",\n \"Nipoã\",\n \"Nova Aliança\",\n \"Nova Campina\",\n \"Nova Canaã Paulista\",\n \"Nova Castilho\",\n \"Nova Europa\",\n \"Nova Granada\",\n \"Nova Guataporanga\",\n \"Nova Independência\",\n \"Nova Luzitânia\",\n \"Nova Odessa\",\n \"Novais\",\n \"Novo Horizonte\",\n \"Nuporanga\",\n \"Ocauçu\",\n \"Óleo\",\n \"Olímpia\",\n \"Onda Verde\",\n \"Oriente\",\n \"Orindiúva\",\n \"Orlândia\",\n \"Osasco\",\n \"Oscar Bressane\",\n \"Osvaldo Cruz\",\n \"Ourinhos\",\n \"Ouro Verde\",\n \"Ouroeste\",\n \"Pacaembu\",\n \"Palestina\",\n \"Palmares Paulista\",\n \"Palmeira d'Oeste\",\n \"Palmital\",\n \"Panorama\",\n \"Paraguaçu Paulista\",\n \"Paraibuna\",\n \"Paraíso\",\n \"Paranapanema\",\n \"Paranapuã\",\n \"Parapuã\",\n \"Pardinho\",\n \"Pariquera-Açu\",\n \"Parisi\",\n \"Patrocínio Paulista\",\n \"Paulicéia\",\n \"Paulínia\",\n \"Paulistânia\",\n \"Paulo de Faria\",\n \"Pederneiras\",\n \"Pedra Bela\",\n \"Pedranópolis\",\n \"Pedregulho\",\n \"Pedreira\",\n \"Pedrinhas Paulista\",\n \"Pedro de Toledo\",\n \"Penápolis\",\n \"Pereira Barreto\",\n \"Pereiras\",\n \"Peruíbe\",\n \"Piacatu\",\n \"Piedade\",\n \"Pilar do Sul\",\n \"Pindamonhangaba\",\n \"Pindorama\",\n \"Pinhalzinho\",\n \"Piquerobi\",\n \"Piquete\",\n \"Piracaia\",\n \"Piracicaba\",\n \"Piraju\",\n \"Pirajuí\",\n \"Pirangi\",\n \"Pirapora do Bom Jesus\",\n \"Pirapozinho\",\n \"Pirassununga\",\n \"Piratininga\",\n \"Pitangueiras\",\n \"Planalto\",\n \"Platina\",\n \"Poá\",\n \"Poloni\",\n \"Pompéia\",\n \"Pongaí\",\n \"Pontal\",\n \"Pontalinda\",\n \"Pontes Gestal\",\n \"Populina\",\n \"Porangaba\",\n \"Porto Feliz\",\n \"Porto Ferreira\",\n \"Potim\",\n \"Potirendaba\",\n \"Pracinha\",\n \"Pradópolis\",\n \"Praia Grande\",\n \"Pratânia\",\n \"Presidente Alves\",\n \"Presidente Bernardes\",\n \"Presidente Epitácio\",\n \"Presidente Prudente\",\n \"Presidente Venceslau\",\n \"Promissão\",\n \"Quadra\",\n \"Quatá\",\n \"Queiroz\",\n \"Queluz\",\n \"Quintana\",\n \"Rafard\",\n \"Rancharia\",\n \"Redenção da Serra\",\n \"Regente Feijó\",\n \"Reginópolis\",\n \"Registro\",\n \"Restinga\",\n \"Ribeira\",\n \"Ribeirão Bonito\",\n \"Ribeirão Branco\",\n \"Ribeirão Corrente\",\n \"Ribeirão do Sul\",\n \"Ribeirão dos Índios\",\n \"Ribeirão Grande\",\n \"Ribeirão Pires\",\n \"Ribeirão Preto\",\n \"Rifaina\",\n \"Rincão\",\n \"Rinópolis\",\n \"Rio Claro\",\n \"Rio das Pedras\",\n \"Rio Grande da Serra\",\n \"Riolândia\",\n \"Riversul\",\n \"Rosana\",\n \"Roseira\",\n \"Rubiácea\",\n \"Rubinéia\",\n \"Sabino\",\n \"Sagres\",\n \"Sales\",\n \"Sales Oliveira\",\n \"Salesópolis\",\n \"Salmourão\",\n \"Saltinho\",\n \"Salto\",\n \"Salto de Pirapora\",\n \"Salto Grande\",\n \"Sandovalina\",\n \"Santa Adélia\",\n \"Santa Albertina\",\n \"Santa Bárbara d'Oeste\",\n \"Santa Branca\",\n \"Santa Clara d'Oeste\",\n \"Santa Cruz da Conceição\",\n \"Santa Cruz da Esperança\",\n \"Santa Cruz das Palmeiras\",\n \"Santa Cruz do Rio Pardo\",\n \"Santa Ernestina\",\n \"Santa Fé do Sul\",\n \"Santa Gertrudes\",\n \"Santa Isabel\",\n \"Santa Lúcia\",\n \"Santa Maria da Serra\",\n \"Santa Mercedes\",\n \"Santa Rita d'Oeste\",\n \"Santa Rita do Passa Quatro\",\n \"Santa Rosa de Viterbo\",\n \"Santa Salete\",\n \"Santana da Ponte Pensa\",\n \"Santana de Parnaíba\",\n \"Santo Anastácio\",\n \"Santo André\",\n \"Santo Antônio da Alegria\",\n \"Santo Antônio de Posse\",\n \"Santo Antônio do Aracanguá\",\n \"Santo Antônio do Jardim\",\n \"Santo Antônio do Pinhal\",\n \"Santo Expedito\",\n \"Santópolis do Aguapeí\",\n \"Santos\",\n \"São Bento do Sapucaí\",\n \"São Bernardo do Campo\",\n \"São Caetano do Sul\",\n \"São Carlos\",\n \"São Francisco\",\n \"São João da Boa Vista\",\n \"São João das Duas Pontes\",\n \"São João de Iracema\",\n \"São João do Pau d'Alho\",\n \"São Joaquim da Barra\",\n \"São José da Bela Vista\",\n \"São José do Barreiro\",\n \"São José do Rio Pardo\",\n \"São José do Rio Preto\",\n \"São José dos Campos\",\n \"São Lourenço da Serra\",\n \"São Luiz do Paraitinga\",\n \"São Manuel\",\n \"São Miguel Arcanjo\",\n \"São Paulo\",\n \"São Pedro\",\n \"São Pedro do Turvo\",\n \"São Roque\",\n \"São Sebastião\",\n \"São Sebastião da Grama\",\n \"São Simão\",\n \"São Vicente\",\n \"Sarapuí\",\n \"Sarutaiá\",\n \"Sebastianópolis do Sul\",\n \"Serra Azul\",\n \"Serra Negra\",\n \"Serrana\",\n \"Sertãozinho\",\n \"Sete Barras\",\n \"Severínia\",\n \"Silveiras\",\n \"Socorro\",\n \"Sorocaba\",\n \"Sud Mennucci\",\n \"Sumaré\",\n \"Suzanápolis\",\n \"Suzano\",\n \"Tabapuã\",\n \"Tabatinga\",\n \"Taboão da Serra\",\n \"Taciba\",\n \"Taguaí\",\n \"Taiaçu\",\n \"Taiúva\",\n \"Tambaú\",\n \"Tanabi\",\n \"Tapiraí\",\n \"Tapiratiba\",\n \"Taquaral\",\n \"Taquaritinga\",\n \"Taquarituba\",\n \"Taquarivaí\",\n \"Tarabai\",\n \"Tarumã\",\n \"Tatuí\",\n \"Taubaté\",\n \"Tejupá\",\n \"Teodoro Sampaio\",\n \"Terra Roxa\",\n \"Tietê\",\n \"Timburi\",\n \"Torre de Pedra\",\n \"Torrinha\",\n \"Trabiju\",\n \"Tremembé\",\n \"Três Fronteiras\",\n \"Tuiuti\",\n \"Tupã\",\n \"Tupi Paulista\",\n \"Turiúba\",\n \"Turmalina\",\n \"Ubarana\",\n \"Ubatuba\",\n \"Ubirajara\",\n \"Uchoa\",\n \"União Paulista\",\n \"Urânia\",\n \"Uru\",\n \"Urupês\",\n \"Valentim Gentil\",\n \"Valinhos\",\n \"Valparaíso\",\n \"Vargem\",\n \"Vargem Grande do Sul\",\n \"Vargem Grande Paulista\",\n \"Várzea Paulista\",\n \"Vera Cruz\",\n \"Vinhedo\",\n \"Viradouro\",\n \"Vista Alegre do Alto\",\n \"Vitória Brasil\",\n \"Votorantim\",\n \"Votuporanga\",\n \"Zacarias\"\n ]\n },\n {\n \"uf\": \"TO\",\n \"name\": \"Tocantins\",\n \"cities\": [\n \"Abreulândia\",\n \"Aguiarnópolis\",\n \"Aliança do Tocantins\",\n \"Almas\",\n \"Alvorada\",\n \"Ananás\",\n \"Angico\",\n \"Aparecida do Rio Negro\",\n \"Aragominas\",\n \"Araguacema\",\n \"Araguaçu\",\n \"Araguaína\",\n \"Araguanã\",\n \"Araguatins\",\n \"Arapoema\",\n \"Arraias\",\n \"Augustinópolis\",\n \"Aurora do Tocantins\",\n \"Axixá do Tocantins\",\n \"Babaçulândia\",\n \"Bandeirantes do Tocantins\",\n \"Barra do Ouro\",\n \"Barrolândia\",\n \"Bernardo Sayão\",\n \"Bom Jesus do Tocantins\",\n \"Brasilândia do Tocantins\",\n \"Brejinho de Nazaré\",\n \"Buriti do Tocantins\",\n \"Cachoeirinha\",\n \"Campos Lindos\",\n \"Cariri do Tocantins\",\n \"Carmolândia\",\n \"Carrasco Bonito\",\n \"Caseara\",\n \"Centenário\",\n \"Chapada da Natividade\",\n \"Chapada de Areia\",\n \"Colinas do Tocantins\",\n \"Colméia\",\n \"Combinado\",\n \"Conceição do Tocantins\",\n \"Couto Magalhães\",\n \"Cristalândia\",\n \"Crixás do Tocantins\",\n \"Darcinópolis\",\n \"Dianópolis\",\n \"Divinópolis do Tocantins\",\n \"Dois Irmãos do Tocantins\",\n \"Dueré\",\n \"Esperantina\",\n \"Fátima\",\n \"Figueirópolis\",\n \"Filadélfia\",\n \"Formoso do Araguaia\",\n \"Goianorte\",\n \"Goiatins\",\n \"Guaraí\",\n \"Gurupi\",\n \"Ipueiras\",\n \"Itacajá\",\n \"Itaguatins\",\n \"Itapiratins\",\n \"Itaporã do Tocantins\",\n \"Jaú do Tocantins\",\n \"Juarina\",\n \"Lagoa da Confusão\",\n \"Lagoa do Tocantins\",\n \"Lajeado\",\n \"Lavandeira\",\n \"Lizarda\",\n \"Luzinópolis\",\n \"Marianópolis do Tocantins\",\n \"Mateiros\",\n \"Maurilândia do Tocantins\",\n \"Miracema do Tocantins\",\n \"Miranorte\",\n \"Monte do Carmo\",\n \"Monte Santo do Tocantins\",\n \"Muricilândia\",\n \"Natividade\",\n \"Nazaré\",\n \"Nova Olinda\",\n \"Nova Rosalândia\",\n \"Novo Acordo\",\n \"Novo Alegre\",\n \"Novo Jardim\",\n \"Oliveira de Fátima\",\n \"Palmas\",\n \"Palmeirante\",\n \"Palmeiras do Tocantins\",\n \"Palmeirópolis\",\n \"Paraíso do Tocantins\",\n \"Paranã\",\n \"Pau D'Arco\",\n \"Pedro Afonso\",\n \"Peixe\",\n \"Pequizeiro\",\n \"Pindorama do Tocantins\",\n \"Piraquê\",\n \"Pium\",\n \"Ponte Alta do Bom Jesus\",\n \"Ponte Alta do Tocantins\",\n \"Porto Alegre do Tocantins\",\n \"Porto Nacional\",\n \"Praia Norte\",\n \"Presidente Kennedy\",\n \"Pugmil\",\n \"Recursolândia\",\n \"Riachinho\",\n \"Rio da Conceição\",\n \"Rio dos Bois\",\n \"Rio Sono\",\n \"Sampaio\",\n \"Sandolândia\",\n \"Santa Fé do Araguaia\",\n \"Santa Maria do Tocantins\",\n \"Santa Rita do Tocantins\",\n \"Santa Rosa do Tocantins\",\n \"Santa Tereza do Tocantins\",\n \"Santa Terezinha do Tocantins\",\n \"São Bento do Tocantins\",\n \"São Félix do Tocantins\",\n \"São Miguel do Tocantins\",\n \"São Salvador do Tocantins\",\n \"São Sebastião do Tocantins\",\n \"São Valério\",\n \"Silvanópolis\",\n \"Sítio Novo do Tocantins\",\n \"Sucupira\",\n \"Tabocão\",\n \"Taguatinga\",\n \"Taipas do Tocantins\",\n \"Talismã\",\n \"Tocantínia\",\n \"Tocantinópolis\",\n \"Tupirama\",\n \"Tupiratins\",\n \"Wanderlândia\",\n \"Xambioá\"\n ]\n }\n]\n","/**\n * Brazilian states (UF), regions and municipalities, mirroring\n * `utils.locations`.\n *\n * Ships an offline, dependency-free dataset of every federative unit and its\n * municipalities (bundled at build time), plus query helpers and validators.\n * City lookups are accent- and case-insensitive.\n */\n\nimport { defineEnum } from \"@/core/enums\";\nimport { z } from \"@/schemas/base\";\nimport brLocations from \"@/utils/data/brLocations.json\";\n\n/** The 27 Brazilian federative-unit acronyms. */\nexport const UF = defineEnum({\n AC: \"AC\",\n AL: \"AL\",\n AP: \"AP\",\n AM: \"AM\",\n BA: \"BA\",\n CE: \"CE\",\n DF: \"DF\",\n ES: \"ES\",\n GO: \"GO\",\n MA: \"MA\",\n MT: \"MT\",\n MS: \"MS\",\n MG: \"MG\",\n PA: \"PA\",\n PB: \"PB\",\n PR: \"PR\",\n PE: \"PE\",\n PI: \"PI\",\n RJ: \"RJ\",\n RN: \"RN\",\n RS: \"RS\",\n RO: \"RO\",\n RR: \"RR\",\n SC: \"SC\",\n SP: \"SP\",\n SE: \"SE\",\n TO: \"TO\",\n});\n\n/** A federative-unit acronym. */\nexport type UFValue = ReturnType<typeof UF.values>[number];\n\n/** The five official IBGE macro-regions. */\nexport const Region = defineEnum({\n NORTH: \"Norte\",\n NORTHEAST: \"Nordeste\",\n CENTRAL_WEST: \"Centro-Oeste\",\n SOUTHEAST: \"Sudeste\",\n SOUTH: \"Sul\",\n});\n\n/** A macro-region value. */\nexport type RegionValue = ReturnType<typeof Region.values>[number];\n\n/** Static mapping of every UF to its IBGE macro-region. */\nconst UF_TO_REGION: Record<string, RegionValue> = {\n AC: Region.NORTH,\n AP: Region.NORTH,\n AM: Region.NORTH,\n PA: Region.NORTH,\n RO: Region.NORTH,\n RR: Region.NORTH,\n TO: Region.NORTH,\n AL: Region.NORTHEAST,\n BA: Region.NORTHEAST,\n CE: Region.NORTHEAST,\n MA: Region.NORTHEAST,\n PB: Region.NORTHEAST,\n PE: Region.NORTHEAST,\n PI: Region.NORTHEAST,\n RN: Region.NORTHEAST,\n SE: Region.NORTHEAST,\n DF: Region.CENTRAL_WEST,\n GO: Region.CENTRAL_WEST,\n MS: Region.CENTRAL_WEST,\n MT: Region.CENTRAL_WEST,\n ES: Region.SOUTHEAST,\n MG: Region.SOUTHEAST,\n RJ: Region.SOUTHEAST,\n SP: Region.SOUTHEAST,\n PR: Region.SOUTH,\n RS: Region.SOUTH,\n SC: Region.SOUTH,\n};\n\n/** A Brazilian federative unit and its municipalities. */\nexport interface StateBR {\n /** Federative-unit acronym (e.g. `\"SP\"`). */\n uf: string;\n /** Full state name (e.g. `\"São Paulo\"`). */\n name: string;\n /** The IBGE macro-region the state belongs to. */\n region: RegionValue;\n /** Alphabetically sorted municipality names. */\n cities: string[];\n}\n\nconst RAW = brLocations as Array<{ uf: string; name: string; cities: string[] }>;\n\nconst STATES: StateBR[] = RAW.map((entry) => ({\n uf: entry.uf,\n name: entry.name,\n region: UF_TO_REGION[entry.uf] ?? Region.SOUTHEAST,\n cities: entry.cities,\n}));\n\nconst STATE_BY_UF = new Map(STATES.map((state) => [state.uf, state]));\n\n/** Strip accents and lowercase a string for tolerant comparison. */\nfunction fold(value: string): string {\n return value\n .normalize(\"NFD\")\n .replace(/\\p{Diacritic}/gu, \"\")\n .trim()\n .toLowerCase();\n}\n\n/** All states, ordered by acronym. */\nexport function listStates(): StateBR[] {\n return STATES.map((state) => ({ ...state, cities: [...state.cities] }));\n}\n\n/** The state for a UF acronym (case-insensitive), or `null`. */\nexport function getState(uf: string): StateBR | null {\n const state = STATE_BY_UF.get(uf.toUpperCase());\n return state ? { ...state, cities: [...state.cities] } : null;\n}\n\n/** The municipalities of a UF, or `[]` for an unknown UF. */\nexport function citiesByUf(uf: string): string[] {\n return getState(uf)?.cities ?? [];\n}\n\n/** All states in a macro-region. */\nexport function statesByRegion(region: RegionValue): StateBR[] {\n return listStates().filter((state) => state.region === region);\n}\n\n/** Whether `value` is a known UF acronym (case-insensitive). */\nexport function isValidUf(value: string): boolean {\n return STATE_BY_UF.has(value.toUpperCase());\n}\n\n/** Normalize a UF to its uppercase acronym, throwing when unknown. */\nexport function normalizeUf(value: string): string {\n const upper = value.toUpperCase();\n if (!STATE_BY_UF.has(upper)) throw new Error(\"invalid UF\");\n return upper;\n}\n\n/** Whether `name` is a municipality of `uf` (accent/case-insensitive). */\nexport function isValidCity(name: string, uf: string): boolean {\n const folded = fold(name);\n return citiesByUf(uf).some((city) => fold(city) === folded);\n}\n\n/** Zod field: validates a UF and normalizes it to its uppercase acronym. */\nexport const ufField = z\n .string()\n .refine(isValidUf, { message: \"invalid UF\" })\n .transform((value) => value.toUpperCase());\n","/** Datetime helpers, mirroring `utils.datetime`. */\n\n/**\n * Return the current instant. JavaScript `Date` is always UTC-based internally;\n * serialize with `.toISOString()` for a UTC wire format.\n *\n * @returns The current `Date`.\n */\nexport function utcnow(): Date {\n return new Date();\n}\n\n/**\n * Coerce a value to a `Date`. Accepts a `Date`, an ISO string or an epoch\n * milliseconds number.\n *\n * @param value - The value to normalize.\n * @returns The corresponding `Date`.\n * @throws {Error} When the value cannot be parsed to a valid date.\n */\nexport function toUtc(value: Date | string | number): Date {\n const date = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(date.getTime())) throw new Error(\"invalid date\");\n return date;\n}\n","/** Dictionary helpers, mirroring `utils.dict`. */\n\n/**\n * Filter and extend a record in a single pass: drop `exclude`d keys and merge\n * `include` on top (merged entries win).\n *\n * @param data - The source record.\n * @param exclude - Keys to drop from the output.\n * @param include - Extra entries to merge in.\n * @returns A new record with the requested mutations.\n */\nexport function modifyDict(\n data: Record<string, unknown>,\n exclude: string[] = [],\n include: Record<string, unknown> = {},\n): Record<string, unknown> {\n const excluded = new Set(exclude);\n const result: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n if (!excluded.has(key)) result[key] = value;\n }\n return { ...result, ...include };\n}\n","/**\n * Single-use opaque tokens hashed at rest, mirroring `utils.opaque_token`.\n *\n * For flows where a secret is emailed/SMS'd and later presented back (password\n * reset, email verification, magic links, API keys). The plaintext is shown\n * once; only its SHA-256 digest is stored, so a DB leak exposes no usable\n * tokens. Verification hashes the incoming plaintext and compares in constant\n * time. Pure standard library (`node:crypto`).\n */\n\nimport { createHash, randomBytes, timingSafeEqual } from \"node:crypto\";\n\nconst DEFAULT_NBYTES = 32;\n\n/**\n * Return the SHA-256 hex digest of a token's plaintext.\n *\n * @param plaintext - The token value to hash.\n * @returns A 64-character lowercase hex digest.\n */\nexport function hashOpaqueToken(plaintext: string): string {\n return createHash(\"sha256\").update(plaintext, \"utf8\").digest(\"hex\");\n}\n\n/**\n * Generate a cryptographically random token and its digest.\n *\n * @param nbytes - Entropy in bytes for the URL-safe token (default 32).\n * @returns `{ plaintext, tokenHash }` — show `plaintext` once, store `tokenHash`.\n */\nexport function generateOpaqueToken(nbytes: number = DEFAULT_NBYTES): {\n plaintext: string;\n tokenHash: string;\n} {\n const plaintext = randomBytes(nbytes).toString(\"base64url\");\n return { plaintext, tokenHash: hashOpaqueToken(plaintext) };\n}\n\n/**\n * Constant-time check that `plaintext` hashes to `tokenHash`.\n *\n * @param plaintext - The token submitted by the caller.\n * @param tokenHash - The stored SHA-256 hex digest.\n * @returns `true` when the hashes match.\n */\nexport function verifyOpaqueToken(plaintext: string, tokenHash: string): boolean {\n const computed = Buffer.from(hashOpaqueToken(plaintext), \"hex\");\n const expected = Buffer.from(tokenHash, \"hex\");\n if (computed.length !== expected.length) return false;\n return timingSafeEqual(computed, expected);\n}\n","/**\n * Password hashing backed by bcrypt, mirroring `utils.password.PasswordUtils`.\n *\n * `bcryptjs` is an optional peer dependency, imported lazily so that\n * `import \"tempest-express-sdk\"` keeps working when it is not installed — the\n * clear error is deferred to first use. Methods are async (the idiomatic Node\n * bcrypt surface).\n */\n\ntype BcryptModule = typeof import(\"bcryptjs\");\n\nlet cached: BcryptModule | null = null;\n\n/** Lazily load `bcryptjs`, with a clear install hint when missing. */\nasync function loadBcrypt(): Promise<BcryptModule> {\n if (cached) return cached;\n try {\n const mod = (await import(\"bcryptjs\")) as BcryptModule & { default?: BcryptModule };\n cached = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"PasswordUtils requires the 'bcryptjs' peer dependency. Install with `npm i bcryptjs`.\",\n { cause },\n );\n }\n return cached;\n}\n\n/** Hash and verify passwords using bcrypt. Stateless — construct once, reuse. */\nexport class PasswordUtils {\n /**\n * @param rounds - The bcrypt cost factor. Higher is slower and harder to\n * brute-force. Defaults to 12.\n */\n constructor(private readonly rounds: number = 12) {}\n\n /**\n * Hash a plaintext password.\n *\n * @param plain - The plaintext password.\n * @returns The bcrypt hash, ready to persist.\n */\n async hash(plain: string): Promise<string> {\n const bcrypt = await loadBcrypt();\n const salt = await bcrypt.genSalt(this.rounds);\n return bcrypt.hash(plain, salt);\n }\n\n /**\n * Verify a plaintext password against a stored hash. Returns `false` for\n * malformed hashes rather than throwing.\n *\n * @param plain - The plaintext password to verify.\n * @param hashed - The previously stored bcrypt hash.\n * @returns `true` when the password matches.\n */\n async verify(plain: string, hashed: string): Promise<boolean> {\n try {\n const bcrypt = await loadBcrypt();\n return await bcrypt.compare(plain, hashed);\n } catch {\n return false;\n }\n }\n}\n","/**\n * JWT encode/decode backed by `jsonwebtoken`, mirroring `utils.jwt.JWTUtils`.\n *\n * `jsonwebtoken` is an optional peer dependency, imported lazily so the SDK\n * imports without it; the clear error is deferred to first use. Every token\n * gets `iat`/`exp` automatically; pass `issuer` to add and verify `iss`.\n * Expired/invalid tokens raise the SDK's {@link ExpiredTokenException} /\n * {@link InvalidTokenException}.\n */\n\nimport { ExpiredTokenException, InvalidTokenException } from \"@/exceptions/http\";\n\ntype JwtModule = typeof import(\"jsonwebtoken\");\n\nlet cached: JwtModule | null = null;\n\n/** Lazily load `jsonwebtoken`, with a clear install hint when missing. */\nasync function loadJwt(): Promise<JwtModule> {\n if (cached) return cached;\n try {\n const mod = (await import(\"jsonwebtoken\")) as JwtModule & { default?: JwtModule };\n cached = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"JWTUtils requires the 'jsonwebtoken' peer dependency. Install with `npm i jsonwebtoken`.\",\n { cause },\n );\n }\n return cached;\n}\n\n/** JWT claims — a free-form payload. */\nexport type JwtClaims = Record<string, unknown>;\n\n/** Options for {@link JWTUtils}. */\nexport interface JWTUtilsOptions {\n /** Signing algorithm. Defaults to `HS256`. */\n algorithm?: \"HS256\" | \"HS384\" | \"HS512\" | \"RS256\" | \"ES256\";\n /** Default token lifetime in seconds. Defaults to 3600 (1 hour). */\n defaultTtlSeconds?: number;\n /** Value for the `iss` claim; when set, `decode` verifies it. */\n issuer?: string;\n}\n\n/** Encode and decode JWTs using a shared secret (or asymmetric key). */\nexport class JWTUtils {\n private readonly algorithm: NonNullable<JWTUtilsOptions[\"algorithm\"]>;\n private readonly defaultTtlSeconds: number;\n private readonly issuer: string | undefined;\n\n /**\n * @param secret - The signing key (HMAC secret or private key).\n * @param options - Algorithm, default TTL and optional issuer.\n */\n constructor(\n private readonly secret: string,\n options: JWTUtilsOptions = {},\n ) {\n this.algorithm = options.algorithm ?? \"HS256\";\n this.defaultTtlSeconds = options.defaultTtlSeconds ?? 3600;\n this.issuer = options.issuer;\n }\n\n /**\n * Encode `payload` as a signed JWT.\n *\n * @param payload - Claims to include (typically `{ sub: \"<user-id>\" }`).\n * @param options - Override the default TTL for this call.\n * @returns The compact-serialized JWT.\n */\n async encode(\n payload: JwtClaims,\n options: { ttlSeconds?: number } = {},\n ): Promise<string> {\n const jwt = await loadJwt();\n return jwt.sign(payload, this.secret, {\n algorithm: this.algorithm,\n expiresIn: options.ttlSeconds ?? this.defaultTtlSeconds,\n ...(this.issuer !== undefined ? { issuer: this.issuer } : {}),\n });\n }\n\n /**\n * Decode and verify a JWT.\n *\n * @param token - The token to decode.\n * @returns The decoded claims.\n * @throws {ExpiredTokenException} When `exp` is in the past.\n * @throws {InvalidTokenException} For any other validation failure.\n */\n async decode(token: string): Promise<JwtClaims> {\n const jwt = await loadJwt();\n try {\n const decoded = jwt.verify(token, this.secret, {\n algorithms: [this.algorithm],\n ...(this.issuer !== undefined ? { issuer: this.issuer } : {}),\n });\n return typeof decoded === \"string\" ? { sub: decoded } : (decoded as JwtClaims);\n } catch (error) {\n if (error instanceof jwt.TokenExpiredError) throw new ExpiredTokenException();\n throw new InvalidTokenException();\n }\n }\n\n /**\n * Decode and verify a JWT, returning `null` on failure (soft auth).\n *\n * @param token - The token to decode.\n * @returns The decoded claims, or `null` when invalid/expired.\n */\n async decodeOrNull(token: string): Promise<JwtClaims | null> {\n try {\n return await this.decode(token);\n } catch {\n return null;\n }\n }\n}\n","/**\n * Attempt throttling, mirroring `utils.throttle`.\n *\n * Sliding-window attempt counter for flows that must resist brute force\n * (login, OTP, code verification). The default {@link MemoryThrottleBackend} is\n * process-local; swap in a shared backend (e.g. Redis) for multi-instance\n * deployments by implementing {@link ThrottleBackend}.\n */\n\n/** The outcome of recording or inspecting an attempt. */\nexport interface ThrottleStatus {\n /** Whether the attempt is allowed (budget not yet exhausted). */\n allowed: boolean;\n /** Remaining attempts in the current window (never negative). */\n remaining: number;\n /** Seconds until the window resets (`0` when allowed). */\n retryAfterSeconds: number;\n}\n\n/** Pluggable storage of attempt timestamps per key. */\nexport interface ThrottleBackend {\n /** Record an attempt at `now` (epoch ms) and return timestamps in-window. */\n hit(key: string, windowMs: number, now: number): Promise<number[]>;\n /** Read the in-window attempt timestamps without recording a new one. */\n peek(key: string, windowMs: number, now: number): Promise<number[]>;\n /** Clear all recorded attempts for `key`. */\n reset(key: string): Promise<void>;\n}\n\n/** Process-local {@link ThrottleBackend} backed by a `Map`. */\nexport class MemoryThrottleBackend implements ThrottleBackend {\n private readonly store = new Map<string, number[]>();\n\n private window(key: string, windowMs: number, now: number): number[] {\n const cutoff = now - windowMs;\n const kept = (this.store.get(key) ?? []).filter((ts) => ts > cutoff);\n this.store.set(key, kept);\n return kept;\n }\n\n async hit(key: string, windowMs: number, now: number): Promise<number[]> {\n const kept = this.window(key, windowMs, now);\n kept.push(now);\n this.store.set(key, kept);\n return kept;\n }\n\n async peek(key: string, windowMs: number, now: number): Promise<number[]> {\n return this.window(key, windowMs, now);\n }\n\n async reset(key: string): Promise<void> {\n this.store.delete(key);\n }\n}\n\n/** Options for {@link AttemptThrottle}. */\nexport interface AttemptThrottleOptions {\n /** Maximum attempts allowed within the window. */\n maxAttempts: number;\n /** Sliding-window length in seconds. */\n windowSeconds: number;\n /** Storage backend. Defaults to a {@link MemoryThrottleBackend}. */\n backend?: ThrottleBackend;\n}\n\n/** A sliding-window attempt limiter keyed by an arbitrary string. */\nexport class AttemptThrottle {\n private readonly maxAttempts: number;\n private readonly windowMs: number;\n private readonly backend: ThrottleBackend;\n\n /**\n * @param options - Budget, window and optional backend.\n */\n constructor(options: AttemptThrottleOptions) {\n this.maxAttempts = options.maxAttempts;\n this.windowMs = options.windowSeconds * 1000;\n this.backend = options.backend ?? new MemoryThrottleBackend();\n }\n\n /** Build a status from a set of in-window attempt timestamps. */\n private status(attempts: number[], now: number): ThrottleStatus {\n const allowed = attempts.length <= this.maxAttempts;\n const remaining = Math.max(0, this.maxAttempts - attempts.length);\n let retryAfterSeconds = 0;\n if (!allowed && attempts.length > 0) {\n const oldest = Math.min(...attempts);\n retryAfterSeconds = Math.max(0, Math.ceil((oldest + this.windowMs - now) / 1000));\n }\n return { allowed, remaining, retryAfterSeconds };\n }\n\n /**\n * Inspect the current budget for `key` without recording an attempt.\n *\n * @param key - The throttle key (e.g. `login:<ip>`).\n * @returns The current status.\n */\n async check(key: string): Promise<ThrottleStatus> {\n const now = Date.now();\n return this.status(await this.backend.peek(key, this.windowMs, now), now);\n }\n\n /**\n * Record an attempt for `key` and return the resulting status.\n *\n * @param key - The throttle key.\n * @returns The status after recording the attempt.\n */\n async hit(key: string): Promise<ThrottleStatus> {\n const now = Date.now();\n return this.status(await this.backend.hit(key, this.windowMs, now), now);\n }\n\n /**\n * Clear all recorded attempts for `key` (e.g. after a successful login).\n *\n * @param key - The throttle key.\n */\n async reset(key: string): Promise<void> {\n await this.backend.reset(key);\n }\n}\n","/**\n * Trusted client-IP resolution, mirroring `utils.client_ip`.\n *\n * Reading the leftmost `X-Forwarded-For` entry is a security hole — that header\n * is client-controlled. Resolve from a SINGLE header the edge proxy sets itself\n * (e.g. `X-Real-IP`, `CF-Connecting-IP`), falling back to the socket peer.\n */\n\nimport type { Request } from \"express\";\n\nconst UNKNOWN = \"unknown\";\n\n/** Options for {@link getClientIp}. */\nexport interface ClientIpOptions {\n /**\n * Name of the single edge-set header to trust (case-insensitive, e.g.\n * `\"x-real-ip\"`). Omit to use only the transport peer.\n */\n trustedHeader?: string;\n}\n\n/**\n * Resolve the client IP from an Express request.\n *\n * @param req - The inbound request.\n * @param options - The trusted header to read, if any.\n * @returns The resolved IP, or `\"unknown\"` when unavailable.\n */\nexport function getClientIp(req: Request, options: ClientIpOptions = {}): string {\n if (options.trustedHeader) {\n const value = req.header(options.trustedHeader);\n if (value) return value.trim();\n }\n return req.socket?.remoteAddress ?? req.ip ?? UNKNOWN;\n}\n","/**\n * File storage abstraction, mirroring `utils.storage_backends` / `utils.upload`.\n *\n * A narrow {@link UploadStorage} interface with a filesystem-backed\n * {@link LocalUploadStorage}. For S3/MinIO, implement the same interface over\n * your client (the interface intentionally avoids a hard cloud dependency).\n */\n\nimport { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\n\n/** The result of persisting an object. */\nexport interface UploadResult {\n /** The storage key (path within the backend). */\n key: string;\n /** A URL the object can be served from. */\n url: string;\n /** The stored byte size. */\n size: number;\n /** The declared content type, when known. */\n contentType?: string;\n}\n\n/** Options for {@link UploadStorage.save}. */\nexport interface SaveOptions {\n /** MIME type recorded on the result. */\n contentType?: string;\n}\n\n/** Narrow object-storage surface backends implement. */\nexport interface UploadStorage {\n /** Persist bytes under `key`, returning metadata. */\n save(key: string, data: Uint8Array, options?: SaveOptions): Promise<UploadResult>;\n /** Read bytes back by key. */\n read(key: string): Promise<Buffer>;\n /** Delete an object. Idempotent. */\n delete(key: string): Promise<void>;\n /** The URL an object is served from. */\n url(key: string): string;\n}\n\n/** Options for {@link LocalUploadStorage}. */\nexport interface LocalUploadStorageOptions {\n /** Filesystem root every key is written under. */\n root: string;\n /** Public base URL prefix for {@link LocalUploadStorage.url}. Default `\"\"`. */\n baseUrl?: string;\n}\n\n/** Filesystem-backed {@link UploadStorage} for local/dev or single-host setups. */\nexport class LocalUploadStorage implements UploadStorage {\n private readonly root: string;\n private readonly baseUrl: string;\n\n /**\n * @param options - Filesystem root and public base URL.\n */\n constructor(options: LocalUploadStorageOptions) {\n this.root = options.root;\n this.baseUrl = options.baseUrl ?? \"\";\n }\n\n async save(\n key: string,\n data: Uint8Array,\n options: SaveOptions = {},\n ): Promise<UploadResult> {\n const target = join(this.root, key);\n await mkdir(dirname(target), { recursive: true });\n await writeFile(target, data);\n return {\n key,\n url: this.url(key),\n size: data.byteLength,\n ...(options.contentType !== undefined ? { contentType: options.contentType } : {}),\n };\n }\n\n async read(key: string): Promise<Buffer> {\n return readFile(join(this.root, key));\n }\n\n async delete(key: string): Promise<void> {\n await rm(join(this.root, key), { force: true });\n }\n\n url(key: string): string {\n const base = this.baseUrl.replace(/\\/$/, \"\");\n return base ? `${base}/${key}` : `/${key}`;\n }\n}\n\n/**\n * Build a `Content-Disposition` header value.\n *\n * @param filename - The download filename.\n * @param inline - When `true`, use `inline`; otherwise `attachment`.\n * @returns The header value (RFC 5987 `filename*` encoded).\n */\nexport function buildContentDisposition(filename: string, inline = false): string {\n const disposition = inline ? \"inline\" : \"attachment\";\n const encoded = encodeURIComponent(filename);\n return `${disposition}; filename*=UTF-8''${encoded}`;\n}\n","/**\n * File-download helpers, mirroring `utils.download`.\n *\n * Serve a file from disk with HTTP Range support (resumable / seekable\n * downloads → `206 Partial Content`) or send in-memory bytes, both with a\n * correct `Content-Disposition`. Path resolution is traversal-safe.\n */\n\nimport { createReadStream } from \"node:fs\";\nimport { stat } from \"node:fs/promises\";\nimport { isAbsolute, join, normalize, relative } from \"node:path\";\nimport { buildContentDisposition } from \"@/storage/local\";\nimport type { Request, Response } from \"express\";\n\n/**\n * Resolve a client-supplied relative path under a root, refusing traversal\n * outside it.\n *\n * @param root - The directory downloads are confined to.\n * @param relativePath - The (untrusted) relative path.\n * @param subdir - Optional sub-directory under `root`.\n * @returns The absolute, validated path.\n * @throws {Error} When the resolved path escapes `root`.\n */\nexport function resolveDownloadPath(\n root: string,\n relativePath: string,\n subdir = \"\",\n): string {\n const base = normalize(join(root, subdir));\n const target = normalize(join(base, relativePath));\n const rel = relative(base, target);\n if (rel.startsWith(\"..\") || isAbsolute(rel)) {\n throw new Error(\"Resolved path escapes the download root\");\n }\n return target;\n}\n\n/** Options for {@link sendFileDownload} / {@link sendBytesDownload}. */\nexport interface DownloadOptions {\n /** Download filename; defaults to the file's basename. */\n filename?: string;\n /** MIME type. Default `application/octet-stream`. */\n contentType?: string;\n /** Serve inline (view in browser) instead of forcing a download. */\n inline?: boolean;\n}\n\n/** Parse a single-range `Range: bytes=start-end` header against a size. */\nfunction parseRange(\n header: string | undefined,\n size: number,\n): { start: number; end: number } | null {\n if (!header) return null;\n const match = /^bytes=(\\d*)-(\\d*)$/.exec(header.trim());\n if (!match) return null;\n const [, rawStart, rawEnd] = match;\n if (rawStart === \"\" && rawEnd === \"\") return null;\n let start: number;\n let end: number;\n if (rawStart === \"\") {\n // Suffix range: last N bytes.\n const suffix = Number(rawEnd);\n start = Math.max(0, size - suffix);\n end = size - 1;\n } else {\n start = Number(rawStart);\n end = rawEnd === \"\" ? size - 1 : Math.min(Number(rawEnd), size - 1);\n }\n if (Number.isNaN(start) || Number.isNaN(end) || start > end || start >= size)\n return null;\n return { start, end };\n}\n\n/**\n * Stream a file from disk as a download, honoring a `Range` request header\n * (responds `206` with `Content-Range` for a partial request, else `200`).\n *\n * @param req - The request (read for the `Range` header).\n * @param res - The response.\n * @param absolutePath - The absolute file path (validate it first — see\n * {@link resolveDownloadPath}).\n * @param options - Filename, content type and inline flag.\n * @returns Resolves once the response stream is wired up.\n */\nexport async function sendFileDownload(\n req: Request,\n res: Response,\n absolutePath: string,\n options: DownloadOptions = {},\n): Promise<void> {\n const info = await stat(absolutePath);\n const filename = options.filename ?? absolutePath.split(/[/\\\\]/).pop() ?? \"download\";\n res.setHeader(\"Content-Type\", options.contentType ?? \"application/octet-stream\");\n res.setHeader(\"Content-Disposition\", buildContentDisposition(filename, options.inline));\n res.setHeader(\"Accept-Ranges\", \"bytes\");\n\n const range = parseRange(req.header(\"range\"), info.size);\n if (range) {\n res.status(206);\n res.setHeader(\"Content-Range\", `bytes ${range.start}-${range.end}/${info.size}`);\n res.setHeader(\"Content-Length\", String(range.end - range.start + 1));\n createReadStream(absolutePath, { start: range.start, end: range.end }).pipe(res);\n return;\n }\n res.status(200);\n res.setHeader(\"Content-Length\", String(info.size));\n createReadStream(absolutePath).pipe(res);\n}\n\n/**\n * Send in-memory bytes as a download.\n *\n * @param res - The response.\n * @param data - The bytes to send.\n * @param options - Filename, content type and inline flag.\n */\nexport function sendBytesDownload(\n res: Response,\n data: Uint8Array,\n options: DownloadOptions = {},\n): void {\n const filename = options.filename ?? \"download\";\n res.setHeader(\"Content-Type\", options.contentType ?? \"application/octet-stream\");\n res.setHeader(\"Content-Disposition\", buildContentDisposition(filename, options.inline));\n res.setHeader(\"Content-Length\", String(data.byteLength));\n res.status(200).end(Buffer.from(data));\n}\n","/**\n * File-based log routing, mirroring `utils.log` / the `core.logging` file sink.\n *\n * `configureFileLogging` installs a {@link LogSink} that appends every record\n * emitted by any {@link JSONLogger} to a per-level file (`info.log`,\n * `error.log`, …) and, additionally, routes records flagged as captured HTTP\n * 500s to a dedicated `500.log` — so uncaught-error triage has its own stream.\n */\n\nimport { type WriteStream, createWriteStream } from \"node:fs\";\nimport { mkdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { HTTP_500_MARKER, type LogLevel, type LogSink, addLogSink } from \"@/core\";\n\n/** Per-level log file names. */\nexport const LEVEL_LOG_FILES: Record<LogLevel, string> = {\n debug: \"debug.log\",\n info: \"info.log\",\n warning: \"warning.log\",\n error: \"error.log\",\n};\n\n/** The dedicated file for captured HTTP 500 records. */\nexport const HTTP_500_LOG_FILE = \"500.log\";\n\n/** A handle to detach file logging and close the open streams. */\nexport interface FileLoggingHandle {\n /** Remove the sink and close every open file stream. */\n close(): void;\n}\n\n/** Options for {@link configureFileLogging}. */\nexport interface FileLoggingOptions {\n /** Directory the log files are written under (created if missing). */\n dir: string;\n}\n\n/**\n * Route every emitted log record into per-level files + `500.log`.\n *\n * @param options - The log directory.\n * @returns A handle whose `close()` detaches the sink and closes the streams.\n *\n * @example\n * ```ts\n * const logs = configureFileLogging({ dir: \"logs\" });\n * // ... on shutdown:\n * logs.close();\n * ```\n */\nexport function configureFileLogging(options: FileLoggingOptions): FileLoggingHandle {\n const { dir } = options;\n mkdirSync(dir, { recursive: true });\n\n const streams = new Map<string, WriteStream>();\n const streamFor = (filename: string): WriteStream => {\n let stream = streams.get(filename);\n if (!stream) {\n stream = createWriteStream(join(dir, filename), { flags: \"a\" });\n streams.set(filename, stream);\n }\n return stream;\n };\n\n const sink: LogSink = (level, record) => {\n const line = `${JSON.stringify(record)}\\n`;\n streamFor(LEVEL_LOG_FILES[level]).write(line);\n if (record[HTTP_500_MARKER]) streamFor(HTTP_500_LOG_FILE).write(line);\n };\n\n const detach = addLogSink(sink);\n return {\n close() {\n detach();\n for (const stream of streams.values()) stream.end();\n streams.clear();\n },\n };\n}\n","/**\n * TOTP (RFC 6238) helper for MFA, mirroring `utils.totp.TOTPHelper`.\n *\n * Implemented natively over `node:crypto` (HMAC-SHA1) — no external OTP library\n * needed. Generates a base32 secret, builds the `otpauth://` provisioning URI\n * (scanned as a QR code), and verifies a 6-digit code with a clock-drift window.\n */\n\nimport { createHmac, randomBytes } from \"node:crypto\";\n\nconst BASE32_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567\";\n\n/** Encode bytes to RFC 4648 base32 (no padding). */\nfunction base32Encode(bytes: Uint8Array): string {\n let bits = 0;\n let value = 0;\n let out = \"\";\n for (const byte of bytes) {\n value = (value << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n out += BASE32_ALPHABET[(value >>> (bits - 5)) & 31];\n bits -= 5;\n }\n }\n if (bits > 0) out += BASE32_ALPHABET[(value << (5 - bits)) & 31];\n return out;\n}\n\n/** Decode an RFC 4648 base32 string (ignores padding/case) to bytes. */\nfunction base32Decode(secret: string): Buffer {\n const clean = secret.toUpperCase().replace(/=+$/, \"\").replace(/\\s/g, \"\");\n let bits = 0;\n let value = 0;\n const out: number[] = [];\n for (const char of clean) {\n const index = BASE32_ALPHABET.indexOf(char);\n if (index === -1) continue;\n value = (value << 5) | index;\n bits += 5;\n if (bits >= 8) {\n out.push((value >>> (bits - 8)) & 0xff);\n bits -= 8;\n }\n }\n return Buffer.from(out);\n}\n\n/** Compute the HOTP code for a counter, per RFC 4226. */\nfunction hotp(secret: Buffer, counter: number, digits: number): string {\n const buffer = Buffer.alloc(8);\n // 53-bit safe integer counter written big-endian.\n buffer.writeUInt32BE(Math.floor(counter / 2 ** 32), 0);\n buffer.writeUInt32BE(counter >>> 0, 4);\n const digest = createHmac(\"sha1\", secret).update(buffer).digest();\n const offset = (digest[digest.length - 1] as number) & 0xf;\n const binary =\n (((digest[offset] as number) & 0x7f) << 24) |\n (((digest[offset + 1] as number) & 0xff) << 16) |\n (((digest[offset + 2] as number) & 0xff) << 8) |\n ((digest[offset + 3] as number) & 0xff);\n return (binary % 10 ** digits).toString().padStart(digits, \"0\");\n}\n\n/** Options for {@link TOTPHelper}. */\nexport interface TOTPOptions {\n /** Label shown in the authenticator app (e.g. the product name). */\n issuer: string;\n /** Time step in seconds. Default 30. */\n step?: number;\n /** Number of digits. Default 6. */\n digits?: number;\n}\n\n/** Stateless TOTP issuer + verifier. Construct one per app. */\nexport class TOTPHelper {\n private readonly issuer: string;\n private readonly step: number;\n private readonly digits: number;\n\n /**\n * @param options - Issuer label, time step and digit count.\n */\n constructor(options: TOTPOptions) {\n this.issuer = options.issuer;\n this.step = options.step ?? 30;\n this.digits = options.digits ?? 6;\n }\n\n /**\n * Generate a fresh base32 secret (80 bits).\n *\n * @returns A base32-encoded TOTP secret to persist on the user row.\n */\n generateSecret(): string {\n return base32Encode(randomBytes(10));\n }\n\n /**\n * Build the `otpauth://` provisioning URI (render as a QR code).\n *\n * @param secret - The base32 secret.\n * @param accountName - Identifier shown next to the issuer (e.g. the email).\n * @returns The `otpauth://totp/...` URI.\n */\n provisioningUri(secret: string, accountName: string): string {\n const label = encodeURIComponent(`${this.issuer}:${accountName}`);\n const params = new URLSearchParams({\n secret,\n issuer: this.issuer,\n algorithm: \"SHA1\",\n digits: String(this.digits),\n period: String(this.step),\n });\n return `otpauth://totp/${label}?${params.toString()}`;\n }\n\n /**\n * Verify a code against the secret for the current time window.\n *\n * @param secret - The base32 secret.\n * @param code - The submitted code.\n * @param window - Tolerance in steps (±). Default 1 (previous/current/next).\n * @returns `true` when the code matches within the window.\n */\n verify(secret: string, code: string, window = 1): boolean {\n const cleaned = code.trim().replace(/[\\s-]/g, \"\");\n if (!/^\\d+$/.test(cleaned) || cleaned.length !== this.digits) return false;\n const key = base32Decode(secret);\n const counter = Math.floor(Date.now() / 1000 / this.step);\n for (let offset = -window; offset <= window; offset++) {\n if (hotp(key, counter + offset, this.digits) === cleaned) return true;\n }\n return false;\n }\n}\n","/**\n * Resilient HTTP client, mirroring `utils.http_client`.\n *\n * Wraps the native `fetch` with a retry policy (exponential backoff) and a\n * per-host circuit breaker: after N consecutive failures the breaker opens and\n * requests to that host fail fast with {@link CircuitOpenError} until a cooldown\n * elapses. No external dependency.\n */\n\n/** Raised when the per-host circuit breaker is open. */\nexport class CircuitOpenError extends Error {\n constructor(readonly host: string) {\n super(`Circuit breaker is open for host ${host}`);\n this.name = \"CircuitOpenError\";\n }\n}\n\n/** Retry configuration for {@link HTTPClient}. */\nexport class RetryPolicy {\n /**\n * @param maxRetries - Additional attempts after the first. Default 2.\n * @param baseDelayMs - Base backoff in ms (doubles each attempt). Default 100.\n * @param retryOn - HTTP status codes that trigger a retry. Default 5xx + 429.\n */\n constructor(\n readonly maxRetries = 2,\n readonly baseDelayMs = 100,\n readonly retryOn: number[] = [429, 500, 502, 503, 504],\n ) {}\n\n /** Backoff delay in ms before `attempt` (0-indexed). */\n sleepFor(attempt: number): number {\n return this.baseDelayMs * 2 ** attempt;\n }\n}\n\ninterface BreakerState {\n failures: number;\n openUntil: number;\n}\n\n/** Options for {@link HTTPClient}. */\nexport interface HTTPClientOptions {\n /** Prepended to relative request paths. */\n baseUrl?: string;\n /** Headers merged into every request. */\n defaultHeaders?: Record<string, string>;\n /** Per-request timeout in ms. Default 30000. */\n timeoutMs?: number;\n /** Retry configuration. */\n retryPolicy?: RetryPolicy;\n /** Consecutive failures before the breaker opens. Default 5. */\n breakerThreshold?: number;\n /** Breaker cooldown in ms once open. Default 30000. */\n breakerCooldownMs?: number;\n}\n\n/** A `fetch` wrapper with retries and a per-host circuit breaker. */\nexport class HTTPClient {\n private readonly baseUrl: string;\n private readonly defaultHeaders: Record<string, string>;\n private readonly timeoutMs: number;\n private readonly retryPolicy: RetryPolicy;\n private readonly breakerThreshold: number;\n private readonly breakerCooldownMs: number;\n private readonly breakers = new Map<string, BreakerState>();\n\n /**\n * @param options - Base URL, headers, timeout, retry and breaker settings.\n */\n constructor(options: HTTPClientOptions = {}) {\n this.baseUrl = options.baseUrl ?? \"\";\n this.defaultHeaders = options.defaultHeaders ?? {};\n this.timeoutMs = options.timeoutMs ?? 30000;\n this.retryPolicy = options.retryPolicy ?? new RetryPolicy();\n this.breakerThreshold = options.breakerThreshold ?? 5;\n this.breakerCooldownMs = options.breakerCooldownMs ?? 30000;\n }\n\n private resolve(url: string): string {\n return this.baseUrl && !/^https?:\\/\\//.test(url) ? `${this.baseUrl}${url}` : url;\n }\n\n private hostOf(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return url;\n }\n }\n\n private breakerCheck(host: string): void {\n const state = this.breakers.get(host);\n if (state && state.openUntil > Date.now()) throw new CircuitOpenError(host);\n }\n\n private breakerRecord(host: string, failed: boolean): void {\n const state = this.breakers.get(host) ?? { failures: 0, openUntil: 0 };\n if (failed) {\n state.failures += 1;\n if (state.failures >= this.breakerThreshold) {\n state.openUntil = Date.now() + this.breakerCooldownMs;\n state.failures = 0;\n }\n } else {\n state.failures = 0;\n state.openUntil = 0;\n }\n this.breakers.set(host, state);\n }\n\n /**\n * Perform a request with retries and breaker protection.\n *\n * @param method - HTTP method.\n * @param url - Absolute URL or a path resolved against `baseUrl`.\n * @param init - Extra `fetch` init (headers, body, …).\n * @returns The `Response`.\n * @throws {CircuitOpenError} When the per-host breaker is open.\n */\n async request(method: string, url: string, init: RequestInit = {}): Promise<Response> {\n const target = this.resolve(url);\n const host = this.hostOf(target);\n this.breakerCheck(host);\n\n let lastError: unknown;\n for (let attempt = 0; attempt <= this.retryPolicy.maxRetries; attempt++) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.timeoutMs);\n try {\n const response = await fetch(target, {\n ...init,\n method,\n headers: { ...this.defaultHeaders, ...(init.headers ?? {}) },\n signal: controller.signal,\n });\n clearTimeout(timer);\n if (this.retryPolicy.retryOn.includes(response.status)) {\n this.breakerRecord(host, true);\n if (attempt < this.retryPolicy.maxRetries) {\n await this.sleep(this.retryPolicy.sleepFor(attempt));\n continue;\n }\n return response;\n }\n this.breakerRecord(host, false);\n return response;\n } catch (error) {\n clearTimeout(timer);\n lastError = error;\n this.breakerRecord(host, true);\n if (attempt < this.retryPolicy.maxRetries) {\n await this.sleep(this.retryPolicy.sleepFor(attempt));\n }\n }\n }\n throw lastError instanceof Error ? lastError : new Error(\"Request failed\");\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /** GET request. */\n get(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"GET\", url, init);\n }\n /** POST request. */\n post(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"POST\", url, init);\n }\n /** PUT request. */\n put(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"PUT\", url, init);\n }\n /** PATCH request. */\n patch(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"PATCH\", url, init);\n }\n /** DELETE request. */\n delete(url: string, init?: RequestInit): Promise<Response> {\n return this.request(\"DELETE\", url, init);\n }\n}\n","/**\n * System metrics, mirroring `utils.metrics.MetricsUtils`.\n *\n * Reads CPU, memory and process stats from Node's built-in `node:os` /\n * `process` — no native dependency. Optional GPU metrics shell out to\n * `nvidia-smi` (returns `[]` when unavailable). Includes a Prometheus\n * text-format exporter.\n */\n\nimport { execFile } from \"node:child_process\";\nimport { cpus, freemem, loadavg, totalmem } from \"node:os\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\n/** CPU load metrics. */\nexport interface CPUMetrics {\n /** Number of logical cores. */\n cores: number;\n /** 1-minute load average (0 on platforms without load average). */\n load1: number;\n /** Load average over 1 minute as a fraction of core count. */\n loadPercent: number;\n}\n\n/** Memory usage metrics (bytes). */\nexport interface MemoryMetrics {\n /** Total system memory. */\n total: number;\n /** Free system memory. */\n free: number;\n /** Used system memory. */\n used: number;\n /** Used memory as a percentage of total. */\n usedPercent: number;\n /** Resident set size of the current process. */\n processRss: number;\n}\n\n/** A single GPU's metrics (from `nvidia-smi`). */\nexport interface GPUMetrics {\n /** GPU index. */\n index: number;\n /** GPU utilization percent. */\n utilizationPercent: number;\n /** Used memory in MiB. */\n memoryUsedMb: number;\n /** Total memory in MiB. */\n memoryTotalMb: number;\n /** Core temperature in °C. */\n temperatureC: number;\n}\n\n/** A snapshot of system + process metrics. */\nexport interface SystemMetrics {\n cpu: CPUMetrics;\n memory: MemoryMetrics;\n /** Process uptime in seconds. */\n uptimeSeconds: number;\n}\n\n/** Read CPU load metrics. */\nfunction readCpu(): CPUMetrics {\n const cores = cpus().length;\n const load1 = loadavg()[0] ?? 0;\n return {\n cores,\n load1,\n loadPercent: cores > 0 ? (load1 / cores) * 100 : 0,\n };\n}\n\n/** Read memory usage metrics. */\nfunction readMemory(): MemoryMetrics {\n const total = totalmem();\n const free = freemem();\n const used = total - free;\n return {\n total,\n free,\n used,\n usedPercent: total > 0 ? (used / total) * 100 : 0,\n processRss: process.memoryUsage().rss,\n };\n}\n\n/** Read a full system snapshot. */\nfunction readSystem(): SystemMetrics {\n return {\n cpu: readCpu(),\n memory: readMemory(),\n uptimeSeconds: process.uptime(),\n };\n}\n\n/**\n * Read GPU metrics via `nvidia-smi`. Returns `[]` when the tool is absent or\n * fails (no GPU, not installed) — never throws.\n *\n * @returns One {@link GPUMetrics} per detected GPU.\n */\nasync function readGpus(): Promise<GPUMetrics[]> {\n try {\n const { stdout } = await execFileAsync(\"nvidia-smi\", [\n \"--query-gpu=index,utilization.gpu,memory.used,memory.total,temperature.gpu\",\n \"--format=csv,noheader,nounits\",\n ]);\n return stdout\n .trim()\n .split(\"\\n\")\n .filter((line) => line.trim().length > 0)\n .map((line) => {\n const [index, util, used, total, temp] = line\n .split(\",\")\n .map((v) => Number(v.trim()));\n return {\n index: index ?? 0,\n utilizationPercent: util ?? 0,\n memoryUsedMb: used ?? 0,\n memoryTotalMb: total ?? 0,\n temperatureC: temp ?? 0,\n };\n });\n } catch {\n return [];\n }\n}\n\n/**\n * Render metrics as Prometheus text-format.\n *\n * @param snapshot - A system snapshot (defaults to a fresh {@link readSystem}).\n * @param gpus - Optional GPU metrics to append (from {@link readGpus}).\n * @returns The Prometheus exposition text.\n */\nfunction toPrometheus(\n snapshot: SystemMetrics = readSystem(),\n gpus: GPUMetrics[] = [],\n): string {\n const lines = [\n \"# HELP process_cpu_load_percent 1-minute load average as percent of cores\",\n \"# TYPE process_cpu_load_percent gauge\",\n `process_cpu_load_percent ${snapshot.cpu.loadPercent}`,\n \"# HELP process_memory_used_percent System memory used percent\",\n \"# TYPE process_memory_used_percent gauge\",\n `process_memory_used_percent ${snapshot.memory.usedPercent}`,\n \"# HELP process_memory_rss_bytes Resident set size of the process\",\n \"# TYPE process_memory_rss_bytes gauge\",\n `process_memory_rss_bytes ${snapshot.memory.processRss}`,\n \"# HELP process_uptime_seconds Process uptime in seconds\",\n \"# TYPE process_uptime_seconds counter\",\n `process_uptime_seconds ${snapshot.uptimeSeconds}`,\n ];\n if (gpus.length > 0) {\n lines.push(\n \"# HELP gpu_utilization_percent GPU utilization percent\",\n \"# TYPE gpu_utilization_percent gauge\",\n );\n for (const gpu of gpus) {\n lines.push(`gpu_utilization_percent{gpu=\"${gpu.index}\"} ${gpu.utilizationPercent}`);\n }\n lines.push(\n \"# HELP gpu_memory_used_mb GPU memory used in MiB\",\n \"# TYPE gpu_memory_used_mb gauge\",\n );\n for (const gpu of gpus) {\n lines.push(`gpu_memory_used_mb{gpu=\"${gpu.index}\"} ${gpu.memoryUsedMb}`);\n }\n lines.push(\n \"# HELP gpu_temperature_celsius GPU core temperature\",\n \"# TYPE gpu_temperature_celsius gauge\",\n );\n for (const gpu of gpus) {\n lines.push(`gpu_temperature_celsius{gpu=\"${gpu.index}\"} ${gpu.temperatureC}`);\n }\n }\n return `${lines.join(\"\\n\")}\\n`;\n}\n\n/** Stateless system-metrics reader + Prometheus exporter. */\nexport const MetricsUtils = {\n cpu: readCpu,\n memory: readMemory,\n system: readSystem,\n gpus: readGpus,\n toPrometheus,\n} as const;\n","/**\n * Transactional email, mirroring `utils.email.EmailUtils`.\n *\n * Wraps the optional `nodemailer` peer (lazily imported) behind a tiny\n * `send` surface. The transport is created once from SMTP options and reused.\n */\n\n/** SMTP connection + sender options. */\nexport interface EmailOptions {\n /** SMTP host. */\n host: string;\n /** SMTP port. Default 587. */\n port?: number;\n /** Use TLS on connect. Default `false` (STARTTLS on 587). */\n secure?: boolean;\n /** SMTP auth user. */\n user?: string;\n /** SMTP auth password. */\n password?: string;\n /** Default `From` address. */\n from: string;\n}\n\n/** A single email message. */\nexport interface EmailMessage {\n /** Recipient(s). */\n to: string | string[];\n /** Subject line. */\n subject: string;\n /** Plain-text body. */\n text?: string;\n /** HTML body. */\n html?: string;\n /** Override the default `From`. */\n from?: string;\n}\n\ntype NodemailerModule = typeof import(\"nodemailer\");\ntype Transport = ReturnType<NodemailerModule[\"createTransport\"]>;\n\n/** Sends transactional email over SMTP via `nodemailer`. */\nexport class EmailUtils {\n private transport: Transport | null = null;\n\n /**\n * @param options - SMTP connection and default sender.\n */\n constructor(private readonly options: EmailOptions) {}\n\n private async ready(): Promise<Transport> {\n if (this.transport) return this.transport;\n let nodemailer: NodemailerModule;\n try {\n const mod = (await import(\"nodemailer\")) as NodemailerModule & {\n default?: NodemailerModule;\n };\n nodemailer = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"EmailUtils requires the 'nodemailer' peer dependency. Install with `npm i nodemailer`.\",\n { cause },\n );\n }\n this.transport = nodemailer.createTransport({\n host: this.options.host,\n port: this.options.port ?? 587,\n secure: this.options.secure ?? false,\n ...(this.options.user\n ? { auth: { user: this.options.user, pass: this.options.password ?? \"\" } }\n : {}),\n });\n return this.transport;\n }\n\n /**\n * Send an email message.\n *\n * @param message - The message (recipients, subject, body).\n */\n async send(message: EmailMessage): Promise<void> {\n const transport = await this.ready();\n await transport.sendMail({\n from: message.from ?? this.options.from,\n to: message.to,\n subject: message.subject,\n ...(message.text !== undefined ? { text: message.text } : {}),\n ...(message.html !== undefined ? { html: message.html } : {}),\n });\n }\n}\n","/**\n * Cache managers, mirroring `cache.redis_manager`.\n *\n * A narrow async cache interface ({@link CacheManager}) with two backends: an\n * in-process {@link MemoryCacheManager} (dev/tests/single replica) and a\n * {@link RedisCacheManager} backed by the optional `redis` peer (lazily\n * imported, like the auth helpers). Values are JSON-serialized.\n */\n\n/** Narrow async cache surface every backend implements. */\nexport interface CacheManager {\n /** Read a value by key, or `null` when missing/expired. */\n get<T>(key: string): Promise<T | null>;\n /** Write a value with an optional TTL in seconds. */\n set<T>(key: string, value: T, ttlSeconds?: number): Promise<void>;\n /** Delete a key. Idempotent. */\n delete(key: string): Promise<void>;\n /** Whether a live (non-expired) value exists for `key`. */\n has(key: string): Promise<boolean>;\n /** Remove every entry. */\n clear(): Promise<void>;\n}\n\ninterface Entry {\n value: string;\n expiresAt: number | null;\n}\n\n/** In-process {@link CacheManager} backed by a `Map`, with lazy TTL expiry. */\nexport class MemoryCacheManager implements CacheManager {\n private readonly store = new Map<string, Entry>();\n\n private live(key: string): Entry | null {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt !== null && entry.expiresAt <= Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const entry = this.live(key);\n return entry ? (JSON.parse(entry.value) as T) : null;\n }\n\n async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {\n this.store.set(key, {\n value: JSON.stringify(value),\n expiresAt: ttlSeconds !== undefined ? Date.now() + ttlSeconds * 1000 : null,\n });\n }\n\n async delete(key: string): Promise<void> {\n this.store.delete(key);\n }\n\n async has(key: string): Promise<boolean> {\n return this.live(key) !== null;\n }\n\n async clear(): Promise<void> {\n this.store.clear();\n }\n}\n\n/** A minimal subset of the `redis` client this manager relies on. */\nexport interface RedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: { EX?: number }): Promise<unknown>;\n del(key: string): Promise<unknown>;\n exists(key: string): Promise<number>;\n flushDb(): Promise<unknown>;\n}\n\n/** Redis-backed {@link CacheManager}. Pass a connected `redis` v4 client. */\nexport class RedisCacheManager implements CacheManager {\n /**\n * @param client - A connected `redis` (node-redis v4) client or compatible.\n * @param prefix - Optional key prefix applied to every operation.\n */\n constructor(\n private readonly client: RedisLike,\n private readonly prefix = \"\",\n ) {}\n\n private key(key: string): string {\n return this.prefix ? `${this.prefix}${key}` : key;\n }\n\n async get<T>(key: string): Promise<T | null> {\n const raw = await this.client.get(this.key(key));\n return raw === null ? null : (JSON.parse(raw) as T);\n }\n\n async set<T>(key: string, value: T, ttlSeconds?: number): Promise<void> {\n const payload = JSON.stringify(value);\n await this.client.set(\n this.key(key),\n payload,\n ttlSeconds !== undefined ? { EX: ttlSeconds } : undefined,\n );\n }\n\n async delete(key: string): Promise<void> {\n await this.client.del(this.key(key));\n }\n\n async has(key: string): Promise<boolean> {\n return (await this.client.exists(this.key(key))) > 0;\n }\n\n async clear(): Promise<void> {\n await this.client.flushDb();\n }\n}\n","/**\n * Read-through memoization helper, mirroring `cache.decorator.cached`.\n *\n * Wraps an async function so its result is cached under a derived key. On a hit\n * the cached value is returned without calling the function; on a miss the\n * function runs and its result is stored with an optional TTL.\n */\n\nimport type { CacheManager } from \"@/cache/manager\";\n\n/** Options for {@link cached}. */\nexport interface CachedOptions<A extends unknown[]> {\n /** The cache backend to read/write. */\n manager: CacheManager;\n /** Build the cache key from the call arguments. */\n key: (...args: A) => string;\n /** TTL in seconds for stored values. Omit for no expiry. */\n ttlSeconds?: number;\n}\n\n/**\n * Wrap an async function with read-through caching.\n *\n * @param fn - The async function to memoize.\n * @param options - Cache backend, key builder and optional TTL.\n * @returns A function with the same signature, served from cache when possible.\n *\n * @example\n * ```ts\n * const getUser = cached(fetchUser, {\n * manager,\n * key: (id: string) => `user:${id}`,\n * ttlSeconds: 60,\n * });\n * ```\n */\nexport function cached<A extends unknown[], R>(\n fn: (...args: A) => Promise<R>,\n options: CachedOptions<A>,\n): (...args: A) => Promise<R> {\n return async (...args: A): Promise<R> => {\n const key = options.key(...args);\n const hit = await options.manager.get<R>(key);\n if (hit !== null) return hit;\n const result = await fn(...args);\n await options.manager.set(key, result, options.ttlSeconds);\n return result;\n };\n}\n","/**\n * Session model + store, mirroring `sessions.store` / `sessions.schemas`.\n *\n * Sessions are keyed by the SHA-256 hash of the opaque cookie value, so a leak\n * of the store yields no reusable cookies. The {@link SessionStore} interface is\n * narrow; {@link MemorySessionStore} is the in-process implementation for\n * dev/tests/single-replica (a Redis store is a planned follow-up).\n */\n\n/** A persisted session row. */\nexport interface Session {\n /** SHA-256 hash of the opaque cookie value (the store key). */\n idHash: string;\n /** The owning user id. */\n userId: string;\n /** Arbitrary JSON-serializable session payload. */\n data: Record<string, unknown>;\n /** Creation timestamp (epoch ms). */\n createdAt: number;\n /** Expiry timestamp (epoch ms). */\n expiresAt: number;\n}\n\n/** Persistence port every session backend implements. */\nexport interface SessionStore {\n /** Return the live session for `idHash`, or `null` when missing/expired. */\n get(idHash: string): Promise<Session | null>;\n /** Persist or overwrite a session. */\n set(session: Session): Promise<void>;\n /** Remove a single session. Idempotent. */\n delete(idHash: string): Promise<void>;\n /** Remove every session for `userId`; returns the count deleted. */\n deleteByUser(userId: string): Promise<number>;\n /** Return every live session for `userId` (oldest first). */\n listByUser(userId: string): Promise<Session[]>;\n}\n\n/** In-process {@link SessionStore} with a secondary user index. */\nexport class MemorySessionStore implements SessionStore {\n private readonly byHash = new Map<string, Session>();\n\n private live(session: Session | undefined, idHash: string): Session | null {\n if (!session) return null;\n if (session.expiresAt <= Date.now()) {\n this.byHash.delete(idHash);\n return null;\n }\n return session;\n }\n\n async get(idHash: string): Promise<Session | null> {\n return this.live(this.byHash.get(idHash), idHash);\n }\n\n async set(session: Session): Promise<void> {\n this.byHash.set(session.idHash, session);\n }\n\n async delete(idHash: string): Promise<void> {\n this.byHash.delete(idHash);\n }\n\n async deleteByUser(userId: string): Promise<number> {\n let count = 0;\n for (const [hash, session] of this.byHash) {\n if (session.userId === userId) {\n this.byHash.delete(hash);\n count += 1;\n }\n }\n return count;\n }\n\n async listByUser(userId: string): Promise<Session[]> {\n const now = Date.now();\n return [...this.byHash.values()]\n .filter((s) => s.userId === userId && s.expiresAt > now)\n .sort((a, b) => a.createdAt - b.createdAt);\n }\n}\n","/**\n * Session service, mirroring `sessions.service`.\n *\n * Issues opaque session cookies, persists only their SHA-256 hash, and resolves\n * an incoming cookie back to a live {@link Session}. Built on the SDK's opaque\n * token helpers so the store never holds a usable cookie value.\n */\n\nimport type { Session, SessionStore } from \"@/sessions/store\";\nimport { generateOpaqueToken, hashOpaqueToken } from \"@/utils/opaqueToken\";\n\n/** Options for {@link SessionService}. */\nexport interface SessionServiceOptions {\n /** The backing store. */\n store: SessionStore;\n /** Default session lifetime in seconds. Default 604800 (7 days). */\n ttlSeconds?: number;\n}\n\n/** A freshly created session and its one-time plaintext cookie value. */\nexport interface IssuedSession {\n /** The opaque cookie value to set on the client (shown once). */\n token: string;\n /** The persisted session row. */\n session: Session;\n}\n\nexport class SessionService {\n private readonly store: SessionStore;\n private readonly ttlSeconds: number;\n\n /**\n * @param options - Store and default TTL.\n */\n constructor(options: SessionServiceOptions) {\n this.store = options.store;\n this.ttlSeconds = options.ttlSeconds ?? 60 * 60 * 24 * 7;\n }\n\n /**\n * Create a session for `userId` and return its one-time cookie value.\n *\n * @param userId - The owning user id.\n * @param data - Arbitrary session payload.\n * @param ttlSeconds - Override the default lifetime.\n * @returns The plaintext token (set as a cookie) and the stored session.\n */\n async create(\n userId: string,\n data: Record<string, unknown> = {},\n ttlSeconds?: number,\n ): Promise<IssuedSession> {\n const { plaintext, tokenHash } = generateOpaqueToken();\n const now = Date.now();\n const session: Session = {\n idHash: tokenHash,\n userId,\n data,\n createdAt: now,\n expiresAt: now + (ttlSeconds ?? this.ttlSeconds) * 1000,\n };\n await this.store.set(session);\n return { token: plaintext, session };\n }\n\n /**\n * Resolve an opaque cookie value to its live session.\n *\n * @param token - The plaintext cookie value.\n * @returns The session, or `null` when missing/expired.\n */\n async resolve(token: string): Promise<Session | null> {\n return this.store.get(hashOpaqueToken(token));\n }\n\n /**\n * Revoke a single session by its cookie value.\n *\n * @param token - The plaintext cookie value.\n */\n async destroy(token: string): Promise<void> {\n await this.store.delete(hashOpaqueToken(token));\n }\n\n /**\n * Revoke every session a user owns (global logout).\n *\n * @param userId - The user id.\n * @returns The number of sessions removed.\n */\n async destroyByUser(userId: string): Promise<number> {\n return this.store.deleteByUser(userId);\n }\n\n /**\n * List a user's live sessions (e.g. an \"active devices\" view).\n *\n * @param userId - The user id.\n * @returns The user's sessions, oldest first.\n */\n async listByUser(userId: string): Promise<Session[]> {\n return this.store.listByUser(userId);\n }\n}\n","/**\n * Session middleware, mirroring `sessions.middleware`.\n *\n * Reads the session cookie, resolves it to a live {@link Session} via the\n * {@link SessionService}, and attaches it to `req.session` (or `null` when\n * absent/expired). Pairs with {@link makeJwtAuthMiddleware} for JWT auth; use\n * whichever model fits the surface.\n */\n\nimport type { SessionService } from \"@/sessions/service\";\nimport type { Session } from \"@/sessions/store\";\nimport type { Request, RequestHandler } from \"express\";\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n /** The live session for this request, populated by the middleware. */\n interface Request {\n session?: Session | null;\n }\n }\n}\n\n/** Parse the `Cookie` header into a name → value map. */\nexport function parseCookies(header: string | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (!header) return out;\n for (const part of header.split(\";\")) {\n const index = part.indexOf(\"=\");\n if (index < 0) continue;\n const name = part.slice(0, index).trim();\n const value = part.slice(index + 1).trim();\n if (name) out[name] = decodeURIComponent(value);\n }\n return out;\n}\n\n/** Read the session cookie value from a request, or `null`. */\nexport function sessionCookie(req: Request, cookieName: string): string | null {\n return parseCookies(req.header(\"cookie\") ?? undefined)[cookieName] ?? null;\n}\n\n/** Options for {@link makeSessionMiddleware}. */\nexport interface SessionMiddlewareOptions {\n /** Cookie name carrying the opaque session id. Default `sid`. */\n cookieName?: string;\n}\n\n/**\n * Build middleware that resolves the session cookie into `req.session`.\n *\n * @param service - The session service used to resolve cookies.\n * @param options - Cookie name.\n * @returns An Express middleware.\n */\nexport function makeSessionMiddleware(\n service: SessionService,\n options: SessionMiddlewareOptions = {},\n): RequestHandler {\n const cookieName = options.cookieName ?? \"sid\";\n return (req, _res, next) => {\n const token = sessionCookie(req, cookieName);\n if (!token) {\n req.session = null;\n next();\n return;\n }\n service\n .resolve(token)\n .then((session) => {\n req.session = session;\n next();\n })\n .catch(next);\n };\n}\n","/**\n * Redis-backed {@link SessionStore} for multi-replica deployments.\n *\n * Sessions live under `sess:<idHash>` with a Redis TTL; a per-user set\n * (`sess:user:<userId>`) indexes them so `listByUser`/`deleteByUser` work\n * without scanning. Takes an injected client (node-redis v4 compatible) so the\n * SDK never hard-depends on `redis`. Expired keys drop via TTL; stale index\n * entries are pruned lazily on read.\n */\n\nimport type { Session, SessionStore } from \"@/sessions/store\";\n\n/** The subset of a node-redis v4 client this store needs. */\nexport interface SessionRedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: { EX?: number }): Promise<unknown>;\n del(key: string): Promise<unknown>;\n sAdd(key: string, member: string): Promise<unknown>;\n sRem(key: string, member: string): Promise<unknown>;\n sMembers(key: string): Promise<string[]>;\n}\n\n/** Redis-backed session store. */\nexport class RedisSessionStore implements SessionStore {\n /**\n * @param client - A connected node-redis v4 (or compatible) client.\n * @param prefix - Key prefix. Default `sess:`.\n */\n constructor(\n private readonly client: SessionRedisLike,\n private readonly prefix = \"sess:\",\n ) {}\n\n private key(idHash: string): string {\n return `${this.prefix}${idHash}`;\n }\n\n private userKey(userId: string): string {\n return `${this.prefix}user:${userId}`;\n }\n\n async get(idHash: string): Promise<Session | null> {\n const raw = await this.client.get(this.key(idHash));\n if (raw === null) return null;\n const session = JSON.parse(raw) as Session;\n if (session.expiresAt <= Date.now()) {\n await this.delete(idHash);\n return null;\n }\n return session;\n }\n\n async set(session: Session): Promise<void> {\n const ttlSeconds = Math.max(1, Math.ceil((session.expiresAt - Date.now()) / 1000));\n await this.client.set(this.key(session.idHash), JSON.stringify(session), {\n EX: ttlSeconds,\n });\n await this.client.sAdd(this.userKey(session.userId), session.idHash);\n }\n\n async delete(idHash: string): Promise<void> {\n const raw = await this.client.get(this.key(idHash));\n await this.client.del(this.key(idHash));\n if (raw) {\n const session = JSON.parse(raw) as Session;\n await this.client.sRem(this.userKey(session.userId), idHash);\n }\n }\n\n async deleteByUser(userId: string): Promise<number> {\n const ids = await this.client.sMembers(this.userKey(userId));\n let count = 0;\n for (const idHash of ids) {\n await this.client.del(this.key(idHash));\n await this.client.sRem(this.userKey(userId), idHash);\n count += 1;\n }\n return count;\n }\n\n async listByUser(userId: string): Promise<Session[]> {\n const ids = await this.client.sMembers(this.userKey(userId));\n const sessions: Session[] = [];\n const now = Date.now();\n for (const idHash of ids) {\n const raw = await this.client.get(this.key(idHash));\n if (raw === null) {\n await this.client.sRem(this.userKey(userId), idHash); // prune stale index\n continue;\n }\n const session = JSON.parse(raw) as Session;\n if (session.expiresAt > now) sessions.push(session);\n }\n return sessions.sort((a, b) => a.createdAt - b.createdAt);\n }\n}\n","/**\n * Server-Sent Events primitives, mirroring `sse.event_stream`.\n *\n * {@link ServerSentEvent} encodes the SSE wire format; {@link EventStream} is a\n * per-subscriber push queue exposed as an async iterator with an optional\n * heartbeat; {@link sseResponse} wires a stream to an Express response.\n */\n\nimport type { Request, Response } from \"express\";\n\n/** A single Server-Sent Event. */\nexport interface ServerSentEventInit {\n /** The event payload (serialized to one or more `data:` lines). */\n data: string;\n /** Optional event name (`event:` line). */\n event?: string;\n /** Optional event id (`id:` line). */\n id?: string;\n /** Optional reconnection hint in ms (`retry:` line). */\n retry?: number;\n}\n\n/** An SSE event that can encode itself to the wire format. */\nexport class ServerSentEvent {\n constructor(private readonly init: ServerSentEventInit) {}\n\n /**\n * Encode to the SSE wire format (terminated by a blank line).\n *\n * @returns The encoded event block.\n */\n encode(): string {\n const lines: string[] = [];\n if (this.init.event) lines.push(`event: ${this.init.event}`);\n if (this.init.id) lines.push(`id: ${this.init.id}`);\n if (this.init.retry !== undefined) lines.push(`retry: ${this.init.retry}`);\n for (const line of this.init.data.split(\"\\n\")) lines.push(`data: ${line}`);\n return `${lines.join(\"\\n\")}\\n\\n`;\n }\n}\n\n/** A deferred used to wake the iterator when a new event arrives. */\nfunction deferred<T>(): { promise: Promise<T>; resolve: (value: T) => void } {\n let resolve!: (value: T) => void;\n const promise = new Promise<T>((r) => {\n resolve = r;\n });\n return { promise, resolve };\n}\n\n/** Options for {@link EventStream}. */\nexport interface EventStreamOptions {\n /** Heartbeat interval in seconds (comment ping). `null` disables. Default 15. */\n heartbeatSeconds?: number | null;\n}\n\n/** A single subscriber's event queue, consumable as an async iterator. */\nexport class EventStream {\n private readonly queue: string[] = [];\n private waiter: ReturnType<typeof deferred<void>> | null = null;\n private closed = false;\n private readonly heartbeatSeconds: number | null;\n\n /**\n * @param options - Heartbeat configuration.\n */\n constructor(options: EventStreamOptions = {}) {\n this.heartbeatSeconds = options.heartbeatSeconds ?? 15;\n }\n\n /** Enqueue raw SSE-encoded text and wake the iterator. */\n private push(raw: string): void {\n if (this.closed) return;\n this.queue.push(raw);\n this.waiter?.resolve();\n this.waiter = null;\n }\n\n /**\n * Publish a data payload as an SSE event.\n *\n * @param data - The payload; objects are JSON-encoded.\n * @param event - Optional event name.\n */\n publish(data: unknown, event?: string): void {\n const payload = typeof data === \"string\" ? data : JSON.stringify(data);\n this.push(\n new ServerSentEvent({ data: payload, ...(event ? { event } : {}) }).encode(),\n );\n }\n\n /** Publish a pre-built {@link ServerSentEvent}. */\n publishEvent(event: ServerSentEvent): void {\n this.push(event.encode());\n }\n\n /** Close the stream; the iterator finishes after draining. */\n close(): void {\n this.closed = true;\n this.waiter?.resolve();\n this.waiter = null;\n }\n\n /**\n * Async iterator yielding encoded SSE chunks, with periodic heartbeats.\n *\n * @returns An async iterator of encoded event strings.\n */\n async *stream(): AsyncIterator<string> & AsyncIterable<string> {\n const heartbeatMs =\n this.heartbeatSeconds !== null ? this.heartbeatSeconds * 1000 : null;\n while (!this.closed || this.queue.length > 0) {\n if (this.queue.length > 0) {\n yield this.queue.shift() as string;\n continue;\n }\n if (this.closed) break;\n this.waiter = deferred<void>();\n if (heartbeatMs === null) {\n await this.waiter.promise;\n } else {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const heartbeat = new Promise<void>((resolve) => {\n timer = setTimeout(resolve, heartbeatMs);\n });\n await Promise.race([this.waiter.promise, heartbeat]);\n if (timer) clearTimeout(timer);\n if (this.queue.length === 0 && !this.closed) yield \": ping\\n\\n\";\n }\n }\n }\n}\n\n/**\n * Stream an {@link EventStream} to an Express response as `text/event-stream`.\n *\n * Sets the SSE headers, writes each encoded chunk, and closes the stream when\n * the client disconnects.\n *\n * @param req - The Express request (used to detect disconnect).\n * @param res - The Express response to stream into.\n * @param stream - The event stream to drain.\n */\nexport async function sseResponse(\n req: Request,\n res: Response,\n stream: EventStream,\n): Promise<void> {\n res.setHeader(\"Content-Type\", \"text/event-stream\");\n res.setHeader(\"Cache-Control\", \"no-cache\");\n res.setHeader(\"Connection\", \"keep-alive\");\n res.flushHeaders?.();\n req.on(\"close\", () => stream.close());\n for await (const chunk of stream.stream()) {\n if (res.writableEnded) break;\n res.write(chunk);\n }\n res.end();\n}\n","/**\n * In-process SSE broker, mirroring `sse.broker.SSEBroker`.\n *\n * Tracks subscribers per channel and fans published events out to every live\n * {@link EventStream} on that channel. Single-process (no cross-replica\n * transport yet — a Redis pub/sub backend is a planned follow-up).\n */\n\nimport { EventStream, type EventStreamOptions } from \"@/sse/eventStream\";\n\n/** Fan-out hub mapping channels to subscriber streams. */\nexport class SSEBroker {\n private readonly channels = new Map<string, Set<EventStream>>();\n\n /**\n * @param streamOptions - Options applied to every {@link EventStream} created\n * by {@link register} (e.g. heartbeat interval).\n */\n constructor(private readonly streamOptions: EventStreamOptions = {}) {}\n\n /**\n * Register a new subscriber stream on `channel`.\n *\n * @param channel - The channel name.\n * @returns A fresh {@link EventStream} to serve to the subscriber.\n */\n register(channel: string): EventStream {\n const stream = new EventStream(this.streamOptions);\n const set = this.channels.get(channel) ?? new Set<EventStream>();\n set.add(stream);\n this.channels.set(channel, set);\n return stream;\n }\n\n /**\n * Remove a subscriber stream from `channel` and close it.\n *\n * @param channel - The channel name.\n * @param stream - The stream to remove.\n */\n unregister(channel: string, stream: EventStream): void {\n const set = this.channels.get(channel);\n if (!set) return;\n set.delete(stream);\n stream.close();\n if (set.size === 0) this.channels.delete(channel);\n }\n\n /**\n * Number of live subscribers on `channel`.\n *\n * @param channel - The channel name.\n * @returns The subscriber count.\n */\n localSubscribers(channel: string): number {\n return this.channels.get(channel)?.size ?? 0;\n }\n\n /**\n * Publish an event to every subscriber on `channel`.\n *\n * @param channel - The channel name.\n * @param data - The payload (objects are JSON-encoded).\n * @param event - Optional event name.\n * @returns The number of subscribers the event was delivered to.\n */\n publish(channel: string, data: unknown, event?: string): number {\n const set = this.channels.get(channel);\n if (!set) return 0;\n for (const stream of set) stream.publish(data, event);\n return set.size;\n }\n}\n","/**\n * Redis pub/sub SSE broker for multi-replica deployments.\n *\n * The in-process {@link SSEBroker} only reaches subscribers on the same node.\n * {@link RedisSSEBroker} publishes to a Redis channel; every replica's\n * subscriber connection receives it and fans out to its local {@link EventStream}s\n * — so a publish on any node reaches SSE clients on all nodes. Takes injected\n * node-redis v4 clients (a dedicated subscriber connection, per Redis pub/sub\n * rules) so the SDK never hard-depends on `redis`.\n */\n\nimport { EventStream, type EventStreamOptions } from \"@/sse/eventStream\";\n\n/** Publisher side (the main client). */\nexport interface RedisPublisherLike {\n publish(channel: string, message: string): Promise<unknown>;\n}\n\n/** Subscriber side (a dedicated connection — `client.duplicate()`). */\nexport interface RedisSubscriberLike {\n subscribe(channel: string, listener: (message: string) => void): Promise<unknown>;\n unsubscribe(channel: string): Promise<unknown>;\n}\n\n/** Options for {@link RedisSSEBroker}. */\nexport interface RedisSSEBrokerOptions extends EventStreamOptions {\n /** Redis channel prefix. Default `sse:`. */\n prefix?: string;\n}\n\n/** Cross-replica SSE fan-out over Redis pub/sub. */\nexport class RedisSSEBroker {\n private readonly local = new Map<string, Set<EventStream>>();\n private readonly prefix: string;\n private readonly streamOptions: EventStreamOptions;\n\n /**\n * @param publisher - The main Redis client (used to `publish`).\n * @param subscriber - A dedicated subscriber connection (`client.duplicate()`).\n * @param options - Channel prefix + per-stream options.\n */\n constructor(\n private readonly publisher: RedisPublisherLike,\n private readonly subscriber: RedisSubscriberLike,\n options: RedisSSEBrokerOptions = {},\n ) {\n this.prefix = options.prefix ?? \"sse:\";\n const { prefix: _p, ...streamOptions } = options;\n this.streamOptions = streamOptions;\n }\n\n private channelKey(channel: string): string {\n return `${this.prefix}${channel}`;\n }\n\n /** Emit a decoded payload to every local stream on a channel. */\n private emitLocal(channel: string, data: unknown, event?: string): void {\n const set = this.local.get(channel);\n if (!set) return;\n for (const stream of set) stream.publish(data, event);\n }\n\n /**\n * Register a subscriber stream, subscribing to the Redis channel on first use.\n *\n * @param channel - The channel name.\n * @returns A fresh {@link EventStream} to serve to the client.\n */\n async register(channel: string): Promise<EventStream> {\n const stream = new EventStream(this.streamOptions);\n let set = this.local.get(channel);\n if (!set) {\n set = new Set<EventStream>();\n this.local.set(channel, set);\n await this.subscriber.subscribe(this.channelKey(channel), (raw) => {\n try {\n const { data, event } = JSON.parse(raw) as { data: unknown; event?: string };\n this.emitLocal(channel, data, event);\n } catch {\n // ignore malformed frames\n }\n });\n }\n set.add(stream);\n return stream;\n }\n\n /**\n * Remove a subscriber stream; unsubscribe from Redis when the last leaves.\n *\n * @param channel - The channel name.\n * @param stream - The stream to remove.\n */\n async unregister(channel: string, stream: EventStream): Promise<void> {\n const set = this.local.get(channel);\n if (!set) return;\n set.delete(stream);\n stream.close();\n if (set.size === 0) {\n this.local.delete(channel);\n await this.subscriber.unsubscribe(this.channelKey(channel));\n }\n }\n\n /** Local subscriber count on `channel` (this replica only). */\n localSubscribers(channel: string): number {\n return this.local.get(channel)?.size ?? 0;\n }\n\n /**\n * Publish to every subscriber across all replicas.\n *\n * @param channel - The channel name.\n * @param data - The payload (JSON-encoded).\n * @param event - Optional event name.\n */\n async publish(channel: string, data: unknown, event?: string): Promise<void> {\n await this.publisher.publish(\n this.channelKey(channel),\n JSON.stringify({ data, ...(event ? { event } : {}) }),\n );\n }\n}\n","/** WebSocket message envelope, mirroring `websockets.schemas`. */\n\nimport { z } from \"@/schemas/base\";\n\n/** The canonical message envelope exchanged over a socket. */\nexport const wsEnvelopeSchema = z\n .object({\n type: z.string().openapi({ description: \"Message type discriminator.\" }),\n data: z.unknown().optional().openapi({ description: \"Arbitrary payload.\" }),\n })\n .openapi(\"WSEnvelope\");\n\n/** A typed message envelope. */\nexport type WSEnvelope = z.infer<typeof wsEnvelopeSchema>;\n","/**\n * In-process connection hub, mirroring `websockets.hub.WebSocketHub`.\n *\n * Transport-agnostic: it tracks {@link WebSocketLike} connections (anything with\n * `send`/`close`) so it works with the `ws` package or any compatible socket.\n * Supports per-user delivery, topic subscriptions, broadcast and a per-user\n * connection cap with oldest-eviction.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport type { WSEnvelope } from \"@/websockets/schemas\";\n\n/** The minimal socket surface the hub needs. */\nexport interface WebSocketLike {\n /** Send a text frame. */\n send(data: string): void;\n /** Close the socket, optionally with a status code. */\n close(code?: number): void;\n}\n\n/** A registered live connection. */\nexport interface WebSocketConnection {\n /** Unique connection id. */\n id: string;\n /** The owning user id. */\n userId: string;\n /** The underlying socket. */\n ws: WebSocketLike;\n /** Topics this connection is subscribed to. */\n topics: Set<string>;\n}\n\n/** Options for {@link WebSocketHub}. */\nexport interface WebSocketHubOptions {\n /** Max simultaneous connections per user (oldest evicted). Default 5. */\n maxPerUser?: number;\n}\n\nexport class WebSocketHub {\n private readonly byId = new Map<string, WebSocketConnection>();\n private readonly byUser = new Map<string, Set<string>>();\n private readonly maxPerUser: number;\n\n /**\n * @param options - Per-user connection cap.\n */\n constructor(options: WebSocketHubOptions = {}) {\n this.maxPerUser = options.maxPerUser ?? 5;\n }\n\n /**\n * Register a new connection for `userId`, evicting the oldest if over cap.\n *\n * @param userId - The owning user id.\n * @param ws - The socket to register.\n * @returns The created connection record.\n */\n register(userId: string, ws: WebSocketLike): WebSocketConnection {\n const connection: WebSocketConnection = {\n id: randomUUID(),\n userId,\n ws,\n topics: new Set(),\n };\n this.byId.set(connection.id, connection);\n const ids = this.byUser.get(userId) ?? new Set<string>();\n ids.add(connection.id);\n this.byUser.set(userId, ids);\n\n if (ids.size > this.maxPerUser) {\n const oldest = ids.values().next().value;\n if (oldest) this.unregister(oldest, 1008);\n }\n return connection;\n }\n\n /**\n * Remove a connection and close its socket.\n *\n * @param connectionId - The connection id.\n * @param code - Optional WebSocket close code.\n */\n unregister(connectionId: string, code?: number): void {\n const connection = this.byId.get(connectionId);\n if (!connection) return;\n this.byId.delete(connectionId);\n const ids = this.byUser.get(connection.userId);\n if (ids) {\n ids.delete(connectionId);\n if (ids.size === 0) this.byUser.delete(connection.userId);\n }\n try {\n connection.ws.close(code);\n } catch {\n // socket already closed — ignore.\n }\n }\n\n /** Subscribe a connection to a topic. */\n subscribe(connectionId: string, topic: string): void {\n this.byId.get(connectionId)?.topics.add(topic);\n }\n\n /** Unsubscribe a connection from a topic. */\n unsubscribe(connectionId: string, topic: string): void {\n this.byId.get(connectionId)?.topics.delete(topic);\n }\n\n /** Serialize and send an envelope to a single connection. */\n private deliver(connection: WebSocketConnection, payload: string): boolean {\n try {\n connection.ws.send(payload);\n return true;\n } catch {\n this.unregister(connection.id);\n return false;\n }\n }\n\n /**\n * Send an envelope to every connection of `userId`.\n *\n * @param userId - The target user.\n * @param envelope - The message envelope.\n * @returns The number of connections delivered to.\n */\n sendTo(userId: string, envelope: WSEnvelope): number {\n const ids = this.byUser.get(userId);\n if (!ids) return 0;\n const payload = JSON.stringify(envelope);\n let count = 0;\n for (const id of [...ids]) {\n const connection = this.byId.get(id);\n if (connection && this.deliver(connection, payload)) count += 1;\n }\n return count;\n }\n\n /**\n * Broadcast an envelope to all connections, or only a topic's subscribers.\n *\n * @param envelope - The message envelope.\n * @param topic - Optional topic to scope the broadcast.\n * @returns The number of connections delivered to.\n */\n broadcast(envelope: WSEnvelope, topic?: string): number {\n const payload = JSON.stringify(envelope);\n let count = 0;\n for (const connection of [...this.byId.values()]) {\n if (topic && !connection.topics.has(topic)) continue;\n if (this.deliver(connection, payload)) count += 1;\n }\n return count;\n }\n\n /** The set of users with at least one live connection. */\n onlineUsers(): Set<string> {\n return new Set(this.byUser.keys());\n }\n\n /** Total live connection count. */\n connectionCount(): number {\n return this.byId.size;\n }\n\n /** Number of connections subscribed to `topic`. */\n topicCount(topic: string): number {\n let count = 0;\n for (const connection of this.byId.values()) {\n if (connection.topics.has(topic)) count += 1;\n }\n return count;\n }\n}\n","/**\n * Attach a {@link WebSocketHub} to an HTTP server, mirroring\n * `websockets.router`.\n *\n * Uses the optional `ws` peer (lazily imported). Authenticates each handshake\n * (e.g. a `?token=` query param), registers the socket into the hub, runs a\n * ping/pong heartbeat to drop half-open peers, and unregisters on close.\n */\n\nimport type { Server } from \"node:http\";\nimport type { WebSocketConnection, WebSocketHub } from \"@/websockets/hub\";\n\n/** Handshake info passed to the authenticator. */\nexport interface HandshakeInfo {\n /** The request URL (includes the query string, e.g. `/ws?token=…`). */\n url: string;\n /** The raw request headers. */\n headers: Record<string, string | string[] | undefined>;\n}\n\n/** Options for {@link attachWebSocketHub}. */\nexport interface AttachWebSocketOptions {\n /** Path the WebSocket server listens on. Default `/ws`. */\n path?: string;\n /**\n * Resolve a user id from the handshake, or `null` to reject (closes 1008).\n * Default accepts every connection as `\"anonymous\"`.\n */\n authenticate?: (info: HandshakeInfo) => Promise<string | null> | string | null;\n /** Heartbeat interval in seconds (`0` disables). Default 30. */\n heartbeatSeconds?: number;\n /** Handler invoked for each inbound text message. */\n onMessage?: (connection: WebSocketConnection, message: string) => void;\n}\n\n/** Read a `token` query param from a handshake URL, or `null`. */\nexport function tokenFromUrl(url: string): string | null {\n const query = url.includes(\"?\") ? url.slice(url.indexOf(\"?\") + 1) : \"\";\n return new URLSearchParams(query).get(\"token\");\n}\n\n/**\n * Attach a hub to an HTTP server over the `ws` package.\n *\n * @param server - The Node HTTP server (e.g. from `runServer`).\n * @param hub - The hub to register connections into.\n * @param options - Path, authenticator, heartbeat and message handler.\n * @returns The created `ws` `WebSocketServer` instance.\n * @throws {Error} When the optional `ws` peer is not installed.\n */\nexport async function attachWebSocketHub(\n server: Server,\n hub: WebSocketHub,\n options: AttachWebSocketOptions = {},\n): Promise<import(\"ws\").WebSocketServer> {\n let ws: typeof import(\"ws\");\n try {\n ws = await import(\"ws\");\n } catch (cause) {\n throw new Error(\n \"attachWebSocketHub requires the 'ws' peer dependency. Install with `npm i ws`.\",\n { cause },\n );\n }\n\n const path = options.path ?? \"/ws\";\n const heartbeatMs = (options.heartbeatSeconds ?? 30) * 1000;\n const authenticate = options.authenticate ?? (() => \"anonymous\");\n const wss = new ws.WebSocketServer({ server, path });\n\n wss.on(\"connection\", (socket: import(\"ws\").WebSocket, req) => {\n void (async () => {\n const userId = await authenticate({\n url: req.url ?? \"\",\n headers: req.headers,\n });\n if (userId === null) {\n socket.close(1008);\n return;\n }\n const connection = hub.register(userId, socket);\n\n let alive = true;\n socket.on(\"pong\", () => {\n alive = true;\n });\n socket.on(\"message\", (data: unknown) => {\n options.onMessage?.(connection, String(data));\n });\n socket.on(\"close\", () => {\n alive = false;\n hub.unregister(connection.id);\n });\n\n if (heartbeatMs > 0) {\n const timer = setInterval(() => {\n if (!alive) {\n clearInterval(timer);\n hub.unregister(connection.id);\n return;\n }\n alive = false;\n socket.ping();\n }, heartbeatMs);\n socket.on(\"close\", () => clearInterval(timer));\n }\n })();\n });\n\n return wss;\n}\n","/**\n * Message broker, mirroring `queue.manager.AsyncBrokerManager`.\n *\n * A narrow async pub/sub surface ({@link BrokerManager}) with two backends: an\n * in-process {@link MemoryBroker} (dev/tests) and a {@link RabbitBroker} over the\n * optional `amqplib` peer (lazily imported). Messages are JSON-serialized.\n */\n\n/** A handler invoked for each delivered message. */\nexport type MessageHandler = (message: unknown) => Promise<void> | void;\n\n/** Narrow async pub/sub surface every backend implements. */\nexport interface BrokerManager {\n /** Publish a message to a named queue. */\n publish(queue: string, message: unknown): Promise<void>;\n /** Subscribe to a queue; resolves to an unsubscribe function. */\n subscribe(queue: string, handler: MessageHandler): Promise<() => Promise<void>>;\n /** Close the broker and release resources. */\n close(): Promise<void>;\n}\n\n/** In-process {@link BrokerManager} backed by handler sets. */\nexport class MemoryBroker implements BrokerManager {\n private readonly handlers = new Map<string, Set<MessageHandler>>();\n\n async publish(queue: string, message: unknown): Promise<void> {\n const set = this.handlers.get(queue);\n if (!set) return;\n // Clone the payload so handlers cannot mutate a shared reference.\n const payload = JSON.parse(JSON.stringify(message)) as unknown;\n for (const handler of [...set]) await handler(payload);\n }\n\n async subscribe(queue: string, handler: MessageHandler): Promise<() => Promise<void>> {\n const set = this.handlers.get(queue) ?? new Set<MessageHandler>();\n set.add(handler);\n this.handlers.set(queue, set);\n return async () => {\n set.delete(handler);\n if (set.size === 0) this.handlers.delete(queue);\n };\n }\n\n async close(): Promise<void> {\n this.handlers.clear();\n }\n}\n\n/** Options for {@link RabbitBroker}. */\nexport interface RabbitBrokerOptions {\n /** AMQP connection URL, e.g. `amqp://localhost`. */\n url: string;\n /** Whether queues are declared durable. Default `true`. */\n durable?: boolean;\n}\n\ntype AmqpModule = typeof import(\"amqplib\");\ntype AmqpConnection = Awaited<ReturnType<AmqpModule[\"connect\"]>>;\ntype AmqpChannel = Awaited<ReturnType<AmqpConnection[\"createChannel\"]>>;\n\n/** RabbitMQ-backed {@link BrokerManager} over the optional `amqplib` peer. */\nexport class RabbitBroker implements BrokerManager {\n private connection: AmqpConnection | null = null;\n private channel: AmqpChannel | null = null;\n private readonly durable: boolean;\n\n /**\n * @param options - Connection URL and queue durability.\n */\n constructor(private readonly options: RabbitBrokerOptions) {\n this.durable = options.durable ?? true;\n }\n\n /** Lazily connect and open a channel. */\n private async ready(): Promise<AmqpChannel> {\n if (this.channel) return this.channel;\n let amqp: AmqpModule;\n try {\n amqp = await import(\"amqplib\");\n } catch (cause) {\n throw new Error(\n \"RabbitBroker requires the 'amqplib' peer dependency. Install with `npm i amqplib`.\",\n { cause },\n );\n }\n this.connection = await amqp.connect(this.options.url);\n this.channel = await this.connection.createChannel();\n return this.channel;\n }\n\n async publish(queue: string, message: unknown): Promise<void> {\n const channel = await this.ready();\n await channel.assertQueue(queue, { durable: this.durable });\n channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)), {\n persistent: this.durable,\n });\n }\n\n async subscribe(queue: string, handler: MessageHandler): Promise<() => Promise<void>> {\n const channel = await this.ready();\n await channel.assertQueue(queue, { durable: this.durable });\n const { consumerTag } = await channel.consume(queue, (msg) => {\n if (!msg) return;\n void Promise.resolve(handler(JSON.parse(msg.content.toString()) as unknown))\n .then(() => channel.ack(msg))\n .catch(() => channel.nack(msg, false, false));\n });\n return async () => {\n await channel.cancel(consumerTag);\n };\n }\n\n async close(): Promise<void> {\n await this.channel?.close();\n await this.connection?.close();\n this.channel = null;\n this.connection = null;\n }\n}\n","/**\n * Background task manager, mirroring `tasks.manager.AsyncTaskBrokerManager`.\n *\n * Rides on a {@link BrokerManager}: enqueue publishes a `{ name, payload }`\n * envelope to a task queue; a worker started with {@link TaskManager.start}\n * consumes it and dispatches to the registered handler. Defaults to an\n * in-process {@link MemoryBroker} so it works with zero infrastructure.\n */\n\nimport { JSONLogger } from \"@/core\";\nimport { type BrokerManager, MemoryBroker } from \"@/queue/broker\";\n\n/** A handler for a registered task. */\nexport type TaskHandler<P = unknown> = (payload: P) => Promise<void> | void;\n\n/** The envelope published for each enqueued task. */\ninterface TaskEnvelope {\n name: string;\n payload: unknown;\n}\n\n/** Options for {@link TaskManager}. */\nexport interface TaskManagerOptions {\n /** The broker to publish/consume on. Defaults to a {@link MemoryBroker}. */\n broker?: BrokerManager;\n /** Queue name used for the task stream. Default `tasks`. */\n queue?: string;\n}\n\nconst logger = new JSONLogger(\"tempest_express_sdk.tasks\");\n\nexport class TaskManager {\n private readonly broker: BrokerManager;\n private readonly queue: string;\n private readonly handlers = new Map<string, TaskHandler>();\n private unsubscribe: (() => Promise<void>) | null = null;\n\n /**\n * @param options - Broker and queue name.\n */\n constructor(options: TaskManagerOptions = {}) {\n this.broker = options.broker ?? new MemoryBroker();\n this.queue = options.queue ?? \"tasks\";\n }\n\n /**\n * Register a handler for a named task.\n *\n * @param name - The task name.\n * @param handler - The handler invoked with the task payload.\n */\n register<P = unknown>(name: string, handler: TaskHandler<P>): void {\n this.handlers.set(name, handler as TaskHandler);\n }\n\n /**\n * Enqueue a task by name.\n *\n * @param name - The registered task name.\n * @param payload - The JSON-serializable payload.\n */\n async enqueue(name: string, payload: unknown = {}): Promise<void> {\n const envelope: TaskEnvelope = { name, payload };\n await this.broker.publish(this.queue, envelope);\n }\n\n /**\n * Start the worker: subscribe to the task queue and dispatch to handlers.\n * A task with no registered handler is logged and skipped.\n */\n async start(): Promise<void> {\n if (this.unsubscribe) return;\n this.unsubscribe = await this.broker.subscribe(this.queue, async (message) => {\n const { name, payload } = message as TaskEnvelope;\n const handler = this.handlers.get(name);\n if (!handler) {\n logger.warning(\"No handler for task\", { task: name });\n return;\n }\n await handler(payload);\n });\n }\n\n /** Stop the worker (stops consuming; does not close the broker). */\n async stop(): Promise<void> {\n await this.unsubscribe?.();\n this.unsubscribe = null;\n }\n}\n","/**\n * Feature-flag backends, mirroring `flags.backends`.\n *\n * A flag resolves to a boolean given a flag name and optional context. Backends\n * are composable — {@link CompositeFeatureFlagBackend} tries each in order and\n * returns the first definitive answer.\n */\n\n/** Arbitrary evaluation context (user id, roles, attributes). */\nexport type FlagContext = Record<string, unknown>;\n\n/** Resolves a flag to enabled/disabled, or `null` when it has no opinion. */\nexport interface FeatureFlagBackend {\n /** Resolve `flag`; `null` defers to the next backend. */\n resolve(flag: string, context?: FlagContext): Promise<boolean | null> | boolean | null;\n}\n\n/** Coerce a loose value (`\"1\"`, `\"true\"`, `\"on\"`, …) to a boolean. */\nexport function coerceFlag(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"number\") return value !== 0;\n if (typeof value === \"string\") {\n return [\"1\", \"true\", \"on\", \"yes\", \"enabled\"].includes(value.trim().toLowerCase());\n }\n return false;\n}\n\n/** In-memory backend backed by a `Map`, ideal for tests and overrides. */\nexport class MemoryFeatureFlagBackend implements FeatureFlagBackend {\n private readonly flags = new Map<string, boolean>();\n\n /**\n * @param initial - Initial flag → enabled map.\n */\n constructor(initial: Record<string, boolean> = {}) {\n for (const [flag, enabled] of Object.entries(initial)) this.flags.set(flag, enabled);\n }\n\n /** Set or override a flag. */\n set(flag: string, enabled: boolean): void {\n this.flags.set(flag, enabled);\n }\n\n resolve(flag: string): boolean | null {\n return this.flags.has(flag) ? (this.flags.get(flag) as boolean) : null;\n }\n}\n\n/** Reads flags from env vars, e.g. flag `new-ui` → `FLAG_NEW_UI`. */\nexport class EnvFeatureFlagBackend implements FeatureFlagBackend {\n /**\n * @param env - Environment source (defaults to `process.env`).\n * @param prefix - Env var prefix. Default `FLAG_`.\n */\n constructor(\n private readonly env: NodeJS.ProcessEnv = process.env,\n private readonly prefix = \"FLAG_\",\n ) {}\n\n private key(flag: string): string {\n return this.prefix + flag.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\");\n }\n\n resolve(flag: string): boolean | null {\n const raw = this.env[this.key(flag)];\n return raw === undefined ? null : coerceFlag(raw);\n }\n}\n\n/** Tries each backend in order; first non-`null` answer wins. */\nexport class CompositeFeatureFlagBackend implements FeatureFlagBackend {\n /**\n * @param backends - Backends in priority order.\n */\n constructor(private readonly backends: FeatureFlagBackend[]) {}\n\n async resolve(flag: string, context?: FlagContext): Promise<boolean | null> {\n for (const backend of this.backends) {\n const answer = await backend.resolve(flag, context);\n if (answer !== null) return answer;\n }\n return null;\n }\n}\n","/**\n * Feature-flag service + Express guard, mirroring `flags.service` /\n * `flags.dependencies`.\n */\n\nimport { NotFoundException } from \"@/exceptions/http\";\nimport type { FeatureFlagBackend, FlagContext } from \"@/flags/backends\";\nimport type { RequestHandler } from \"express\";\n\n/** Evaluates flags against a backend, applying a default when undecided. */\nexport class FeatureFlags {\n /**\n * @param backend - The resolving backend.\n * @param defaultEnabled - Value used when the backend returns `null`.\n */\n constructor(\n private readonly backend: FeatureFlagBackend,\n private readonly defaultEnabled = false,\n ) {}\n\n /**\n * Whether `flag` is enabled for the given context.\n *\n * @param flag - The flag name.\n * @param context - Optional evaluation context.\n * @returns `true` when enabled (or default when the backend is undecided).\n */\n async isEnabled(flag: string, context?: FlagContext): Promise<boolean> {\n const answer = await this.backend.resolve(flag, context);\n return answer ?? this.defaultEnabled;\n }\n}\n\n/**\n * Build middleware that rejects with 404 when `flag` is disabled (hiding the\n * route entirely, the common kill-switch behavior).\n *\n * @param flags - The flag service.\n * @param flag - The flag name to gate on.\n * @returns An Express middleware.\n */\nexport function makeFlagGuard(flags: FeatureFlags, flag: string): RequestHandler {\n return (_req, _res, next) => {\n flags\n .isEnabled(flag)\n .then((enabled) => {\n if (enabled) next();\n else next(new NotFoundException({ message: \"Not found\", details: { flag } }));\n })\n .catch(next);\n };\n}\n","/**\n * S3 / MinIO-backed {@link UploadStorage}, mirroring `utils.storage_backends`.\n *\n * Implements the same narrow `UploadStorage` interface as\n * {@link LocalUploadStorage} over a MinIO/S3 client, so services swap backends\n * without touching call sites. The `minio` client is an **optional** peer\n * dependency, lazy-loaded on first use (or inject your own client for tests /\n * a custom SDK).\n */\n\nimport type { Readable } from \"node:stream\";\nimport type { SaveOptions, UploadResult, UploadStorage } from \"@/storage/local\";\n\n/** Minimal MinIO/S3 client surface used by {@link S3UploadStorage}. */\nexport interface S3ClientLike {\n putObject(\n bucket: string,\n key: string,\n data: Buffer,\n size?: number,\n metaData?: Record<string, string>,\n ): Promise<unknown>;\n getObject(bucket: string, key: string): Promise<Readable>;\n removeObject(bucket: string, key: string): Promise<void>;\n}\n\n/** Options for {@link S3UploadStorage}. */\nexport interface S3UploadStorageOptions {\n /** Target bucket. */\n bucket: string;\n /** Public base URL for {@link S3UploadStorage.url} (e.g. a CDN or the endpoint). */\n publicBaseUrl?: string;\n /** Inject a ready client (e.g. a `minio` `Client`, or a mock). */\n client?: S3ClientLike;\n /** MinIO/S3 endpoint host (used only when `client` is not injected). */\n endPoint?: string;\n /** Endpoint port. */\n port?: number;\n /** Whether to use TLS. */\n useSSL?: boolean;\n /** Access key. */\n accessKey?: string;\n /** Secret key. */\n secretKey?: string;\n /** Region. */\n region?: string;\n}\n\n/** Collect a readable stream into a single {@link Buffer}. */\nasync function streamToBuffer(stream: Readable): Promise<Buffer> {\n const chunks: Buffer[] = [];\n for await (const chunk of stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as Uint8Array));\n }\n return Buffer.concat(chunks);\n}\n\n/** {@link UploadStorage} over a MinIO/S3 client. */\nexport class S3UploadStorage implements UploadStorage {\n private readonly bucket: string;\n private readonly publicBaseUrl: string;\n private client: S3ClientLike | undefined;\n private readonly options: S3UploadStorageOptions;\n\n /**\n * @param options - Bucket, public URL and either a client or connection config.\n */\n constructor(options: S3UploadStorageOptions) {\n this.bucket = options.bucket;\n this.publicBaseUrl = options.publicBaseUrl ?? \"\";\n this.client = options.client;\n this.options = options;\n }\n\n /** Resolve the client, lazy-loading `minio` when one wasn't injected. */\n private async getClient(): Promise<S3ClientLike> {\n if (this.client) return this.client;\n // Variable specifier keeps the optional peer out of static resolution.\n const specifier = \"minio\";\n let mod: { Client: new (config: Record<string, unknown>) => S3ClientLike };\n try {\n mod = (await import(specifier)) as typeof mod;\n } catch {\n throw new Error(\n \"S3UploadStorage requires the 'minio' peer dependency. Install with `npm i minio`.\",\n );\n }\n this.client = new mod.Client({\n endPoint: this.options.endPoint,\n port: this.options.port,\n useSSL: this.options.useSSL,\n accessKey: this.options.accessKey,\n secretKey: this.options.secretKey,\n region: this.options.region,\n });\n return this.client;\n }\n\n async save(\n key: string,\n data: Uint8Array,\n options: SaveOptions = {},\n ): Promise<UploadResult> {\n const client = await this.getClient();\n const buffer = Buffer.from(data);\n const metaData = options.contentType\n ? { \"Content-Type\": options.contentType }\n : undefined;\n await client.putObject(this.bucket, key, buffer, buffer.byteLength, metaData);\n return {\n key,\n url: this.url(key),\n size: buffer.byteLength,\n ...(options.contentType !== undefined ? { contentType: options.contentType } : {}),\n };\n }\n\n async read(key: string): Promise<Buffer> {\n const client = await this.getClient();\n return streamToBuffer(await client.getObject(this.bucket, key));\n }\n\n async delete(key: string): Promise<void> {\n const client = await this.getClient();\n await client.removeObject(this.bucket, key);\n }\n\n url(key: string): string {\n const base = this.publicBaseUrl.replace(/\\/$/, \"\");\n return base ? `${base}/${this.bucket}/${key}` : `/${this.bucket}/${key}`;\n }\n}\n","/** Web Push DTOs (Zod), mirroring `webpush.schemas`. */\n\nimport { z } from \"@/schemas/base\";\n\n/** The browser-provided push subscription keys. */\nexport const webPushKeysSchema = z\n .object({\n p256dh: z.string().openapi({ description: \"Client public key (base64url).\" }),\n auth: z.string().openapi({ description: \"Client auth secret (base64url).\" }),\n })\n .openapi(\"WebPushKeys\");\n\n/** A browser push subscription. */\nexport const webPushSubscriptionSchema = z\n .object({\n endpoint: z.url().openapi({ description: \"Push service endpoint URL.\" }),\n keys: webPushKeysSchema,\n })\n .openapi(\"WebPushSubscription\");\n\n/** A push notification payload. */\nexport const webPushPayloadSchema = z\n .object({\n title: z.string().openapi({ description: \"Notification title.\" }),\n body: z.string().optional().openapi({ description: \"Notification body.\" }),\n url: z.string().optional().openapi({ description: \"URL opened on click.\" }),\n data: z\n .record(z.string(), z.unknown())\n .optional()\n .openapi({ description: \"Extra data.\" }),\n })\n .openapi(\"WebPushPayload\");\n\nexport type WebPushKeys = z.infer<typeof webPushKeysSchema>;\nexport type WebPushSubscription = z.infer<typeof webPushSubscriptionSchema>;\nexport type WebPushPayload = z.infer<typeof webPushPayloadSchema>;\n","/**\n * Web Push (VAPID) dispatch, mirroring `webpush.dispatcher`.\n *\n * Wraps the optional `web-push` peer (lazily imported). A `410 Gone` / `404`\n * from the push service means the subscription is dead — surfaced as\n * {@link WebPushGoneError} so the caller can prune it from storage.\n */\n\nimport type { WebPushPayload, WebPushSubscription } from \"@/webpush/schemas\";\n\n/** A Web Push delivery failure. */\nexport class WebPushError extends Error {\n constructor(\n message: string,\n readonly statusCode?: number,\n ) {\n super(message);\n this.name = \"WebPushError\";\n }\n}\n\n/** The subscription is expired/unsubscribed (410/404) — prune it. */\nexport class WebPushGoneError extends WebPushError {\n constructor(statusCode: number) {\n super(\"Push subscription is gone\", statusCode);\n this.name = \"WebPushGoneError\";\n }\n}\n\n/** Options for {@link WebPushDispatcher}. */\nexport interface WebPushDispatcherOptions {\n /** VAPID public key. */\n publicKey: string;\n /** VAPID private key. */\n privateKey: string;\n /** VAPID subject (`mailto:` or site URL). */\n subject: string;\n}\n\ntype WebPushModule = typeof import(\"web-push\");\n\nlet cached: WebPushModule | null = null;\n\nasync function loadWebPush(): Promise<WebPushModule> {\n if (cached) return cached;\n try {\n const mod = (await import(\"web-push\")) as WebPushModule & { default?: WebPushModule };\n cached = mod.default ?? mod;\n } catch (cause) {\n throw new Error(\n \"WebPushDispatcher requires the 'web-push' peer dependency. Install with `npm i web-push`.\",\n { cause },\n );\n }\n return cached;\n}\n\n/** Sends Web Push notifications with configured VAPID details. */\nexport class WebPushDispatcher {\n /**\n * @param options - VAPID keys and subject.\n */\n constructor(private readonly options: WebPushDispatcherOptions) {}\n\n /**\n * Send a payload to a single subscription.\n *\n * @param subscription - The browser push subscription.\n * @param payload - The notification payload.\n * @throws {WebPushGoneError} When the subscription is expired (410/404).\n * @throws {WebPushError} On any other delivery failure.\n */\n async send(subscription: WebPushSubscription, payload: WebPushPayload): Promise<void> {\n const webpush = await loadWebPush();\n webpush.setVapidDetails(\n this.options.subject,\n this.options.publicKey,\n this.options.privateKey,\n );\n try {\n await webpush.sendNotification(subscription, JSON.stringify(payload));\n } catch (error) {\n const status = (error as { statusCode?: number }).statusCode;\n if (status === 404 || status === 410) throw new WebPushGoneError(status);\n throw new WebPushError((error as Error).message, status);\n }\n }\n}\n","/**\n * Messaging integration contracts.\n *\n * A channel-agnostic {@link MessagingProvider} so WhatsApp, SMS and future\n * channels share one shape and are swappable in tests. The first implementation\n * is {@link WhatsAppProvider} (a client for the `zap-api` service).\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** Supported media kinds for {@link MessagingProvider.sendMedia}. */\nexport type MediaKind = \"image\" | \"video\" | \"audio\" | \"document\";\n\n/** A media message to send. */\nexport interface OutboundMedia {\n /** The media kind (selects the underlying route). */\n kind: MediaKind;\n /** A public `http(s)://` URL or a `data:` URI. */\n media: string;\n /** Optional caption (image/video). */\n caption?: string;\n /** File name with extension (required for `document`). */\n fileName?: string;\n}\n\n/** The result of enqueuing an outbound message. */\nexport interface OutboundResult {\n /** Provider message id, when returned. */\n id?: string;\n /** Provider status string (e.g. `\"queued\"`, `\"sent\"`). */\n status: string;\n /** Whether the send was de-duplicated by an idempotency key. */\n deduped?: boolean;\n}\n\n/** Options accepted by send operations. */\nexport interface SendOptions {\n /** Idempotency key to de-duplicate retries on the provider side. */\n idempotencyKey?: string;\n}\n\n/** A normalized inbound (or echoed outbound) message. */\nexport const inboundMessageSchema = z\n .object({\n /** Conversation JID / sender (e.g. `5511999999999@s.whatsapp.net`). */\n from: z.string().openapi({ description: \"Conversation JID / sender.\" }),\n /** Provider message id. */\n messageId: z.string().openapi({ description: \"Provider message id.\" }),\n /** Text body, when present. */\n text: z.string().optional().openapi({ description: \"Text body.\" }),\n /** Media kind, or `null` for plain text. */\n mediaType: z\n .enum([\"image\", \"video\", \"audio\", \"document\", \"sticker\"])\n .nullable()\n .openapi({ description: \"Media kind, or null for text.\" }),\n /** ISO-8601 timestamp. */\n timestamp: z.string().openapi({ description: \"ISO-8601 timestamp.\" }),\n /** Delivery direction. */\n direction: z.enum([\"incoming\", \"outgoing\"]).optional(),\n })\n .openapi(\"InboundMessage\");\n\n/** A normalized inbound message. */\nexport type InboundMessage = z.infer<typeof inboundMessageSchema>;\n\n/** Handler invoked for each inbound message. */\nexport type InboundHandler = (message: InboundMessage) => Promise<void> | void;\n\n/**\n * A channel-agnostic messaging provider. `sendText`/`sendMedia`/`status` are\n * universal; `checkNumber` and `onMessage` are optional because not every\n * channel supports them (e.g. SMS has no persistent subscription — its inbound\n * arrives via a webhook receiver instead).\n */\nexport interface MessagingProvider {\n /** Send a text message. */\n sendText(to: string, text: string, options?: SendOptions): Promise<OutboundResult>;\n /** Send a media message. */\n sendMedia(\n to: string,\n media: OutboundMedia,\n options?: SendOptions,\n ): Promise<OutboundResult>;\n /** The current session/connection status. */\n status(): Promise<string>;\n /** Whether a number/handle exists on the channel (when supported). */\n checkNumber?(number: string): Promise<boolean>;\n /**\n * Subscribe to inbound messages; resolves to an unsubscribe function.\n * Present only on channels with a live subscription (WhatsApp `/ws`,\n * Telegram long-polling).\n *\n * @param handler - Invoked for each inbound message.\n * @param room - Conversation to scope to; `\"*\"` for all. Default `\"*\"`.\n */\n onMessage?(handler: InboundHandler, room?: string): Promise<() => Promise<void>>;\n}\n","/**\n * WhatsApp provider — a typed client for the `zap-api` service.\n *\n * REST for sending (`/message/send-*`, `/message/check-number`) and session\n * control (`/session/*`); the `/ws` pub/sub for receiving inbound messages in\n * real time. HTTP goes through the SDK's resilient {@link HTTPClient}; the\n * WebSocket subscription uses the optional `ws` peer (lazily imported).\n *\n * @see https://github.com/mauriciobenjamin700 (zap-api)\n */\n\nimport type {\n InboundHandler,\n MediaKind,\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n SendOptions,\n} from \"@/integrations/provider\";\nimport { HTTPClient } from \"@/utils/httpClient\";\n\n/** Options for {@link WhatsAppProvider}. */\nexport interface WhatsAppProviderOptions {\n /** Base URL of the `zap-api` instance, e.g. `https://zap.example.com`. */\n baseUrl: string;\n /** Consumer API key (sent as `x-api-key`). */\n apiKey: string;\n /** WebSocket URL. Defaults to `baseUrl` with `http(s)`→`ws(s)` + `/ws`. */\n wsUrl?: string;\n /** Per-request timeout in ms. Default 15000. */\n timeoutMs?: number;\n}\n\n/** Route suffix per media kind. */\nconst MEDIA_ROUTE: Record<MediaKind, string> = {\n image: \"send-image\",\n video: \"send-video\",\n audio: \"send-audio\",\n document: \"send-document\",\n};\n\n/** Derive the default `ws(s)://…/ws` URL from an http(s) base URL. */\nfunction deriveWsUrl(baseUrl: string): string {\n const trimmed = baseUrl.replace(/\\/$/, \"\");\n return `${trimmed.replace(/^http/, \"ws\")}/ws`;\n}\n\n/** A typed client for a running `zap-api` WhatsApp gateway. */\nexport class WhatsAppProvider implements MessagingProvider {\n private readonly http: HTTPClient;\n private readonly apiKey: string;\n private readonly wsUrl: string;\n\n /**\n * @param options - Base URL, API key and optional WebSocket URL.\n */\n constructor(options: WhatsAppProviderOptions) {\n this.apiKey = options.apiKey;\n this.wsUrl = options.wsUrl ?? deriveWsUrl(options.baseUrl);\n this.http = new HTTPClient({\n baseUrl: options.baseUrl.replace(/\\/$/, \"\"),\n defaultHeaders: { \"x-api-key\": options.apiKey, \"content-type\": \"application/json\" },\n timeoutMs: options.timeoutMs ?? 15000,\n });\n }\n\n /** POST JSON and parse the response, throwing on a non-2xx status. */\n private async postJson(\n path: string,\n body: unknown,\n options?: SendOptions,\n ): Promise<Record<string, unknown>> {\n const headers = options?.idempotencyKey\n ? { \"Idempotency-Key\": options.idempotencyKey }\n : undefined;\n const res = await this.http.post(path, {\n body: JSON.stringify(body),\n ...(headers ? { headers } : {}),\n });\n const data = (await res.json().catch(() => ({}))) as Record<string, unknown>;\n if (!res.ok) {\n throw new Error(\n `zap-api ${path} failed (${res.status}): ${String(data.error ?? res.statusText)}`,\n );\n }\n return data;\n }\n\n async sendText(\n to: string,\n text: string,\n options?: SendOptions,\n ): Promise<OutboundResult> {\n const data = await this.postJson(\"/message/send-text\", { to, text }, options);\n return {\n status: String(data.status ?? \"queued\"),\n ...(typeof data.id === \"string\" ? { id: data.id } : {}),\n ...(typeof data.deduped === \"boolean\" ? { deduped: data.deduped } : {}),\n };\n }\n\n async sendMedia(\n to: string,\n media: OutboundMedia,\n options?: SendOptions,\n ): Promise<OutboundResult> {\n const body: Record<string, unknown> = { to, media: media.media };\n if (media.caption !== undefined) body.caption = media.caption;\n if (media.fileName !== undefined) body.fileName = media.fileName;\n const data = await this.postJson(\n `/message/${MEDIA_ROUTE[media.kind]}`,\n body,\n options,\n );\n return {\n status: String(data.status ?? \"queued\"),\n ...(typeof data.id === \"string\" ? { id: data.id } : {}),\n ...(typeof data.deduped === \"boolean\" ? { deduped: data.deduped } : {}),\n };\n }\n\n async checkNumber(number: string): Promise<boolean> {\n const res = await this.http.get(\n `/message/check-number/${encodeURIComponent(number)}`,\n );\n const data = (await res.json().catch(() => ({}))) as { exists?: boolean };\n return data.exists === true;\n }\n\n async status(): Promise<string> {\n const res = await this.http.get(\"/session/status\");\n const raw = await res.text();\n try {\n const parsed = JSON.parse(raw) as { status?: string };\n return parsed.status ?? raw.trim();\n } catch {\n return raw.trim();\n }\n }\n\n /** Start the WhatsApp session (returns the authenticated QR URL, if any). */\n async startSession(): Promise<Record<string, unknown>> {\n return this.postJson(\"/session/start\", {});\n }\n\n async onMessage(handler: InboundHandler, room = \"*\"): Promise<() => Promise<void>> {\n let ws: typeof import(\"ws\");\n try {\n ws = await import(\"ws\");\n } catch (cause) {\n throw new Error(\n \"WhatsAppProvider.onMessage requires the 'ws' peer dependency. Install with `npm i ws`.\",\n { cause },\n );\n }\n const socket = new ws.WebSocket(this.wsUrl, {\n headers: { \"x-api-key\": this.apiKey },\n });\n\n socket.on(\"open\", () => {\n socket.send(JSON.stringify({ action: \"subscribe\", room }));\n });\n socket.on(\"message\", (raw: unknown) => {\n let frame: { type?: string; payload?: unknown };\n try {\n frame = JSON.parse(String(raw));\n } catch {\n return;\n }\n if (frame.type === \"message\" && frame.payload) {\n const p = frame.payload as Record<string, unknown>;\n void handler({\n from: String(p.remoteJid ?? \"\"),\n messageId: String(p.messageId ?? \"\"),\n ...(typeof p.text === \"string\" ? { text: p.text } : {}),\n mediaType: (p.mediaType as InboundMessageMediaType) ?? null,\n timestamp: String(p.timestamp ?? \"\"),\n ...(p.direction === \"incoming\" || p.direction === \"outgoing\"\n ? { direction: p.direction }\n : {}),\n });\n }\n });\n\n return async () => {\n try {\n socket.send(JSON.stringify({ action: \"unsubscribe\", room }));\n } catch {\n // socket may already be closed.\n }\n socket.close();\n };\n }\n}\n\n/** The media-type union carried on inbound frames. */\ntype InboundMessageMediaType =\n | \"image\"\n | \"video\"\n | \"audio\"\n | \"document\"\n | \"sticker\"\n | null;\n","/**\n * WhatsApp inbound-webhook receiver.\n *\n * `zap-api` POSTs every received message to a configured webhook. This builds\n * an Express router that (optionally) validates the shared `x-api-key`, parses\n * the payload into a typed {@link InboundMessage}, and hands it to your handler.\n */\n\nimport { timingSafeEqual } from \"node:crypto\";\nimport { UnauthorizedException } from \"@/exceptions/http\";\nimport { type InboundHandler, inboundMessageSchema } from \"@/integrations/provider\";\nimport { type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link makeWhatsAppWebhookRouter}. */\nexport interface WhatsAppWebhookOptions {\n /** Handler invoked for each validated inbound message. */\n onMessage: InboundHandler;\n /** Route path. Default `/whatsapp/inbound`. */\n path?: string;\n /** Shared secret expected in `x-api-key`. Omit to skip auth (dev only). */\n apiKey?: string;\n}\n\n/** Constant-time string comparison. */\nfunction safeEqual(a: string, b: string): boolean {\n const bufA = Buffer.from(a);\n const bufB = Buffer.from(b);\n return bufA.length === bufB.length && timingSafeEqual(bufA, bufB);\n}\n\n/**\n * Build the inbound-webhook router.\n *\n * @param options - Handler, path and optional shared secret.\n * @returns An Express router with the webhook endpoint mounted.\n */\nexport function makeWhatsAppWebhookRouter(options: WhatsAppWebhookOptions): Router {\n const path = options.path ?? \"/whatsapp/inbound\";\n const router = createRouter();\n\n router.post(path, async (req, res) => {\n if (options.apiKey) {\n const provided = req.header(\"x-api-key\") ?? \"\";\n if (!safeEqual(provided, options.apiKey)) {\n throw new UnauthorizedException({ message: \"Invalid webhook key\" });\n }\n }\n // zap-api posts `{ from, messageId, text, mediaType, timestamp }`.\n const message = inboundMessageSchema.parse(req.body);\n await options.onMessage(message);\n res.status(200).json({ ok: true });\n });\n\n return router;\n}\n","/**\n * Telegram provider — a client for the Telegram Bot API.\n *\n * Implements {@link MessagingProvider} over the built-in {@link HTTPClient}\n * (no external SDK). Outbound via `sendMessage`/`sendPhoto`/…; inbound via\n * `getUpdates` long-polling exposed through {@link TelegramProvider.onMessage}.\n */\n\nimport type {\n InboundHandler,\n MediaKind,\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n} from \"@/integrations/provider\";\nimport { HTTPClient } from \"@/utils/httpClient\";\n\n/** Options for {@link TelegramProvider}. */\nexport interface TelegramProviderOptions {\n /** Bot token from @BotFather. */\n token: string;\n /** API base. Default `https://api.telegram.org`. */\n apiBase?: string;\n /** Long-poll timeout in seconds for `getUpdates`. Default 30. */\n pollTimeoutSeconds?: number;\n}\n\n/** Bot API method suffix per media kind. */\nconst MEDIA_METHOD: Record<MediaKind, { method: string; field: string }> = {\n image: { method: \"sendPhoto\", field: \"photo\" },\n video: { method: \"sendVideo\", field: \"video\" },\n audio: { method: \"sendAudio\", field: \"audio\" },\n document: { method: \"sendDocument\", field: \"document\" },\n};\n\n/** A typed Telegram Bot API client. */\nexport class TelegramProvider implements MessagingProvider {\n private readonly http: HTTPClient;\n private readonly pollTimeout: number;\n\n /**\n * @param options - Bot token and API options.\n */\n constructor(options: TelegramProviderOptions) {\n const base = `${options.apiBase ?? \"https://api.telegram.org\"}/bot${options.token}`;\n this.pollTimeout = options.pollTimeoutSeconds ?? 30;\n this.http = new HTTPClient({\n baseUrl: base,\n defaultHeaders: { \"content-type\": \"application/json\" },\n // Timeout must exceed the long-poll window.\n timeoutMs: (this.pollTimeout + 10) * 1000,\n });\n }\n\n /** Call a Bot API method, returning the `result`, throwing on `ok: false`. */\n private async call<T>(method: string, body: Record<string, unknown>): Promise<T> {\n const res = await this.http.post(`/${method}`, { body: JSON.stringify(body) });\n const data = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n result?: T;\n description?: string;\n };\n if (!res.ok || !data.ok) {\n throw new Error(`Telegram ${method} failed: ${data.description ?? res.statusText}`);\n }\n return data.result as T;\n }\n\n async sendText(to: string, text: string): Promise<OutboundResult> {\n const result = await this.call<{ message_id: number }>(\"sendMessage\", {\n chat_id: to,\n text,\n });\n return { id: String(result.message_id), status: \"sent\" };\n }\n\n async sendMedia(to: string, media: OutboundMedia): Promise<OutboundResult> {\n const { method, field } = MEDIA_METHOD[media.kind];\n const body: Record<string, unknown> = { chat_id: to, [field]: media.media };\n if (media.caption !== undefined) body.caption = media.caption;\n const result = await this.call<{ message_id: number }>(method, body);\n return { id: String(result.message_id), status: \"sent\" };\n }\n\n async status(): Promise<string> {\n try {\n await this.call<{ id: number }>(\"getMe\", {});\n return \"connected\";\n } catch {\n return \"disconnected\";\n }\n }\n\n /**\n * Subscribe to inbound messages via `getUpdates` long-polling.\n *\n * @param handler - Invoked for each inbound text message.\n * @returns A stop function that ends the polling loop.\n */\n async onMessage(handler: InboundHandler): Promise<() => Promise<void>> {\n let running = true;\n let offset = 0;\n\n const loop = async (): Promise<void> => {\n while (running) {\n let updates: TelegramUpdate[] = [];\n try {\n updates = await this.call<TelegramUpdate[]>(\"getUpdates\", {\n offset,\n timeout: this.pollTimeout,\n });\n } catch {\n if (running) await new Promise((r) => setTimeout(r, 1000));\n continue;\n }\n for (const update of updates) {\n offset = update.update_id + 1;\n const message = update.message;\n if (!message) continue;\n await handler({\n from: String(message.chat.id),\n messageId: String(message.message_id),\n ...(typeof message.text === \"string\" ? { text: message.text } : {}),\n mediaType: null,\n timestamp: new Date(message.date * 1000).toISOString(),\n direction: \"incoming\",\n });\n }\n }\n };\n\n void loop();\n return async () => {\n running = false;\n };\n }\n}\n\n/** Minimal shape of a Telegram update we consume. */\ninterface TelegramUpdate {\n update_id: number;\n message?: {\n message_id: number;\n date: number;\n text?: string;\n chat: { id: number };\n };\n}\n","/**\n * SMS provider — a Twilio client + inbound-webhook receiver.\n *\n * Implements {@link MessagingProvider} over the built-in {@link HTTPClient}\n * (no `twilio` SDK). SMS has no persistent subscription, so `onMessage` is\n * absent — inbound arrives via {@link makeTwilioWebhookRouter}, which validates\n * the `X-Twilio-Signature` HMAC.\n */\n\nimport { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { UnauthorizedException } from \"@/exceptions/http\";\nimport type {\n InboundHandler,\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n} from \"@/integrations/provider\";\nimport { HTTPClient } from \"@/utils/httpClient\";\nimport { type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link TwilioSmsProvider}. */\nexport interface TwilioSmsProviderOptions {\n /** Twilio Account SID. */\n accountSid: string;\n /** Twilio Auth Token. */\n authToken: string;\n /** Default `From` number (E.164), e.g. `+15551234567`. */\n from: string;\n /** API base. Default `https://api.twilio.com`. */\n apiBase?: string;\n}\n\n/** A Twilio SMS client. */\nexport class TwilioSmsProvider implements MessagingProvider {\n private readonly http: HTTPClient;\n private readonly from: string;\n private readonly messagesPath: string;\n private readonly accountPath: string;\n\n /**\n * @param options - Account SID, auth token and default sender.\n */\n constructor(options: TwilioSmsProviderOptions) {\n this.from = options.from;\n this.messagesPath = `/2010-04-01/Accounts/${options.accountSid}/Messages.json`;\n this.accountPath = `/2010-04-01/Accounts/${options.accountSid}.json`;\n const basic = Buffer.from(`${options.accountSid}:${options.authToken}`).toString(\n \"base64\",\n );\n this.http = new HTTPClient({\n baseUrl: options.apiBase ?? \"https://api.twilio.com\",\n defaultHeaders: {\n Authorization: `Basic ${basic}`,\n \"content-type\": \"application/x-www-form-urlencoded\",\n },\n });\n }\n\n /** POST a form body to Twilio and parse the JSON, throwing on non-2xx. */\n private async postForm(params: Record<string, string>): Promise<OutboundResult> {\n const res = await this.http.post(this.messagesPath, {\n body: new URLSearchParams(params).toString(),\n });\n const data = (await res.json().catch(() => ({}))) as {\n sid?: string;\n status?: string;\n message?: string;\n };\n if (!res.ok) {\n throw new Error(\n `Twilio send failed (${res.status}): ${data.message ?? res.statusText}`,\n );\n }\n return {\n status: data.status ?? \"queued\",\n ...(data.sid ? { id: data.sid } : {}),\n };\n }\n\n async sendText(to: string, text: string): Promise<OutboundResult> {\n return this.postForm({ To: to, From: this.from, Body: text });\n }\n\n async sendMedia(to: string, media: OutboundMedia): Promise<OutboundResult> {\n return this.postForm({\n To: to,\n From: this.from,\n MediaUrl: media.media,\n ...(media.caption !== undefined ? { Body: media.caption } : {}),\n });\n }\n\n async status(): Promise<string> {\n const res = await this.http.get(this.accountPath);\n const data = (await res.json().catch(() => ({}))) as { status?: string };\n return data.status ?? (res.ok ? \"connected\" : \"disconnected\");\n }\n}\n\n/**\n * Validate a Twilio request signature (`X-Twilio-Signature`).\n *\n * @param authToken - The Twilio auth token.\n * @param url - The full public URL Twilio posted to (scheme + host + path).\n * @param params - The POST form parameters.\n * @param signature - The `X-Twilio-Signature` header value.\n * @returns `true` when the signature matches.\n */\nexport function validateTwilioSignature(\n authToken: string,\n url: string,\n params: Record<string, string>,\n signature: string,\n): boolean {\n const data =\n url +\n Object.keys(params)\n .sort()\n .map((key) => key + params[key])\n .join(\"\");\n const expected = createHmac(\"sha1\", authToken).update(data, \"utf8\").digest(\"base64\");\n const a = Buffer.from(expected);\n const b = Buffer.from(signature);\n return a.length === b.length && timingSafeEqual(a, b);\n}\n\n/** Options for {@link makeTwilioWebhookRouter}. */\nexport interface TwilioWebhookOptions {\n /** Handler invoked for each inbound SMS. */\n onMessage: InboundHandler;\n /** Route path. Default `/sms/inbound`. */\n path?: string;\n /** Auth token; when set, `X-Twilio-Signature` is validated. */\n authToken?: string;\n /** Public URL Twilio posts to (needed for signature validation behind a proxy). */\n publicUrl?: string;\n}\n\n/**\n * Build the Twilio inbound-SMS webhook router.\n *\n * Twilio posts `application/x-www-form-urlencoded` (`From`, `Body`,\n * `MessageSid`, …). Mount after `express.urlencoded()` (included by `createApp`).\n *\n * @param options - Handler, path and signature-validation settings.\n * @returns An Express router with the webhook endpoint mounted.\n */\nexport function makeTwilioWebhookRouter(options: TwilioWebhookOptions): Router {\n const path = options.path ?? \"/sms/inbound\";\n const router = createRouter();\n\n router.post(path, async (req, res) => {\n const body = (req.body ?? {}) as Record<string, string>;\n if (options.authToken) {\n const url =\n options.publicUrl ?? `${req.protocol}://${req.get(\"host\")}${req.originalUrl}`;\n const signature = req.header(\"x-twilio-signature\") ?? \"\";\n if (!validateTwilioSignature(options.authToken, url, body, signature)) {\n throw new UnauthorizedException({ message: \"Invalid Twilio signature\" });\n }\n }\n await options.onMessage({\n from: String(body.From ?? \"\"),\n messageId: String(body.MessageSid ?? \"\"),\n ...(body.Body ? { text: body.Body } : {}),\n mediaType: null,\n timestamp: new Date().toISOString(),\n direction: \"incoming\",\n });\n res.type(\"text/xml\").send(\"<Response></Response>\");\n });\n\n return router;\n}\n","/**\n * Email channel — a {@link MessagingProvider} over {@link EmailUtils}.\n *\n * Lets transactional email participate in the same swappable messaging contract\n * as WhatsApp/Telegram/SMS: `sendText` sends a plain email, `sendMedia` sends\n * the media as a link in the body. Inbound (`onMessage`) is absent — email\n * ingestion is out of scope. Requires the optional `nodemailer` peer via\n * {@link EmailUtils}.\n */\n\nimport type {\n MessagingProvider,\n OutboundMedia,\n OutboundResult,\n} from \"@/integrations/provider\";\nimport type { EmailUtils } from \"@/utils/email\";\n\n/** Options for {@link EmailProvider}. */\nexport interface EmailProviderOptions {\n /** The configured SMTP sender. */\n email: EmailUtils;\n /** Default subject line for `sendText`/`sendMedia`. Default `\"Notification\"`. */\n subject?: string;\n}\n\n/** An email-backed {@link MessagingProvider}. */\nexport class EmailProvider implements MessagingProvider {\n private readonly email: EmailUtils;\n private readonly subject: string;\n\n /**\n * @param options - The email sender and default subject.\n */\n constructor(options: EmailProviderOptions) {\n this.email = options.email;\n this.subject = options.subject ?? \"Notification\";\n }\n\n /**\n * Send a plain-text email.\n *\n * @param to - Recipient address.\n * @param text - Body text (also used as HTML).\n * @returns A sent result.\n */\n async sendText(to: string, text: string): Promise<OutboundResult> {\n await this.email.send({ to, subject: this.subject, text });\n return { status: \"sent\" };\n }\n\n /**\n * Send an email linking to the media (caption becomes the lead text).\n *\n * @param to - Recipient address.\n * @param media - The media reference (URL) + optional caption.\n * @returns A sent result.\n */\n async sendMedia(to: string, media: OutboundMedia): Promise<OutboundResult> {\n const caption = media.caption ?? \"\";\n await this.email.send({\n to,\n subject: this.subject,\n html: `${caption ? `<p>${caption}</p>` : \"\"}<p><a href=\"${media.media}\">${media.media}</a></p>`,\n });\n return { status: \"sent\" };\n }\n\n /** Always `\"connected\"` — SMTP reachability is verified on first send. */\n async status(): Promise<string> {\n return \"connected\";\n }\n}\n","/**\n * Broadcast + multi-channel helpers over {@link MessagingProvider}.\n *\n * {@link broadcastText} fans one message out to many recipients through a single\n * provider, with bounded concurrency and a per-recipient result (one failure\n * never aborts the rest). {@link MessagingHub} keeps named providers so app code\n * sends by channel name and can broadcast across all of them.\n */\n\nimport type {\n MessagingProvider,\n OutboundResult,\n SendOptions,\n} from \"@/integrations/provider\";\n\n/** The outcome of a single recipient's send within a broadcast. */\nexport interface BroadcastResult {\n /** The recipient address/handle. */\n to: string;\n /** Whether the send succeeded. */\n ok: boolean;\n /** The provider result, when successful. */\n result?: OutboundResult;\n /** The error message, when failed. */\n error?: string;\n}\n\n/** Options for {@link broadcastText}. */\nexport interface BroadcastOptions extends SendOptions {\n /** Maximum concurrent sends. Default 10. */\n concurrency?: number;\n}\n\n/** Run `worker` over `items` with at most `limit` in flight, preserving order. */\nasync function pool<T, R>(\n items: T[],\n limit: number,\n worker: (item: T, index: number) => Promise<R>,\n): Promise<R[]> {\n const results = new Array<R>(items.length);\n let cursor = 0;\n const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {\n while (cursor < items.length) {\n const index = cursor++;\n results[index] = await worker(items[index] as T, index);\n }\n });\n await Promise.all(runners);\n return results;\n}\n\n/**\n * Send `text` to every recipient through `provider`, bounded by concurrency.\n *\n * A failed recipient is captured in its {@link BroadcastResult} (`ok: false`)\n * rather than aborting the batch.\n *\n * @param provider - The channel to send through.\n * @param recipients - Recipient addresses/handles.\n * @param text - The message body.\n * @param options - Concurrency + send options.\n * @returns One result per recipient, in input order.\n */\nexport function broadcastText(\n provider: MessagingProvider,\n recipients: string[],\n text: string,\n options: BroadcastOptions = {},\n): Promise<BroadcastResult[]> {\n const { concurrency = 10, ...sendOptions } = options;\n return pool(recipients, concurrency, async (to) => {\n try {\n const result = await provider.sendText(to, text, sendOptions);\n return { to, ok: true, result };\n } catch (error) {\n return {\n to,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n });\n}\n\n/** A registry of named messaging channels. */\nexport class MessagingHub {\n private readonly channels = new Map<string, MessagingProvider>();\n\n /**\n * Register a provider under a channel name.\n *\n * @param name - The channel name (e.g. `\"whatsapp\"`, `\"sms\"`).\n * @param provider - The provider implementation.\n * @returns The hub (chainable).\n */\n register(name: string, provider: MessagingProvider): this {\n this.channels.set(name, provider);\n return this;\n }\n\n /**\n * Get a registered provider, throwing when the channel is unknown.\n *\n * @param name - The channel name.\n * @returns The provider.\n * @throws {Error} When no provider is registered under `name`.\n */\n get(name: string): MessagingProvider {\n const provider = this.channels.get(name);\n if (!provider) throw new Error(`Unknown messaging channel: ${name}`);\n return provider;\n }\n\n /** The registered channel names. */\n channelNames(): string[] {\n return [...this.channels.keys()];\n }\n\n /**\n * Send text through a named channel.\n *\n * @param channel - The channel name.\n * @param to - The recipient.\n * @param text - The message body.\n * @param options - Send options.\n * @returns The provider result.\n */\n send(\n channel: string,\n to: string,\n text: string,\n options?: SendOptions,\n ): Promise<OutboundResult> {\n return this.get(channel).sendText(to, text, options);\n }\n\n /**\n * Broadcast text to many recipients on a named channel.\n *\n * @param channel - The channel name.\n * @param recipients - Recipient addresses/handles.\n * @param text - The message body.\n * @param options - Broadcast + send options.\n * @returns One result per recipient.\n */\n broadcast(\n channel: string,\n recipients: string[],\n text: string,\n options?: BroadcastOptions,\n ): Promise<BroadcastResult[]> {\n return broadcastText(this.get(channel), recipients, text, options);\n }\n}\n","/**\n * Column introspection for the admin panel, mirroring `admin.forms`' widget\n * derivation.\n *\n * `tempest-db-js` keeps rich runtime metadata on every column — the canonical\n * type kind, enum members, `varchar` length, the not-null/default/primary-key\n * flags and the foreign-key reference — so the admin derives its form widgets\n * and list filters from the model itself instead of asking the project to\n * restate them. Kept separate from the router so the (fiddly) type handling is\n * unit-testable in isolation.\n */\n\nimport { type Column, type ModelClass, columnsOf } from \"@/db\";\n\n/** The set of form controls the admin knows how to render. */\nexport type AdminWidget =\n | \"text\"\n | \"textarea\"\n | \"number\"\n | \"checkbox\"\n | \"datetime\"\n | \"date\"\n | \"time\"\n | \"select\"\n | \"json\";\n\n/** A `(value, label)` pair for a `select` widget. */\nexport interface AdminSelectOption {\n value: string;\n label: string;\n}\n\n/** The widget a column maps to, plus the attributes that render it. */\nexport interface WidgetSpec {\n /** The control to render. */\n widget: AdminWidget;\n /** `step` attribute for `number` widgets, or `null`. */\n step: string | null;\n /** Options for `select` widgets (empty otherwise). */\n options: AdminSelectOption[];\n}\n\n/** How a column is surfaced in the list view's filter bar. */\nexport type AdminFilterKind = \"select\" | \"daterange\" | \"text\";\n\n/**\n * Humanize a column key into a form label (`lastLoginAt` → `Last Login At`).\n *\n * @param name - The column key.\n * @returns A title-cased label.\n */\nexport function humanizeField(name: string): string {\n return name\n .replace(/[_-]+/g, \" \")\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .trim()\n .split(/\\s+/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(\" \");\n}\n\n/**\n * Return every column of a model, keyed by field name in declaration order.\n *\n * @param model - The model class.\n * @returns The column map (do not mutate).\n */\nexport function adminColumns(model: ModelClass): Record<string, Column<unknown>> {\n return columnsOf(model);\n}\n\n/**\n * Map a column to the widget that edits it.\n *\n * `json` is matched before anything else because a JSON column carries no\n * useful scalar type, and `enum` is matched before the string kinds so its\n * members become a dropdown rather than a free-text input.\n *\n * @param column - The column to inspect.\n * @returns The widget, its `number` step (or `null`) and its `select` options.\n */\nexport function widgetForColumn(column: Column<unknown>): WidgetSpec {\n const { kind, meta } = column.type;\n const plain = (widget: AdminWidget): WidgetSpec => ({\n widget,\n step: null,\n options: [],\n });\n\n switch (kind) {\n case \"json\":\n return plain(\"json\");\n case \"boolean\":\n return plain(\"checkbox\");\n case \"enum\":\n return {\n widget: \"select\",\n step: null,\n options: (meta.values ?? []).map((value) => ({\n value,\n label: humanizeField(value),\n })),\n };\n case \"smallint\":\n case \"integer\":\n case \"bigint\":\n return { widget: \"number\", step: \"1\", options: [] };\n case \"numeric\":\n case \"real\":\n case \"double\":\n return { widget: \"number\", step: \"any\", options: [] };\n case \"datetime\":\n case \"timestamp\":\n return plain(\"datetime\");\n case \"date\":\n return plain(\"date\");\n case \"time\":\n return plain(\"time\");\n case \"text\":\n return plain(\"textarea\");\n case \"varchar\":\n case \"char\":\n return plain(meta.length !== undefined && meta.length > 255 ? \"textarea\" : \"text\");\n default:\n return plain(\"text\");\n }\n}\n\n/**\n * Whether a column may be left blank on submit — it is nullable, carries a\n * default, or is the primary key the database fills in.\n *\n * @param column - The column to inspect.\n * @returns `true` when the field is optional.\n */\nexport function isColumnOptional(column: Column<unknown>): boolean {\n return !column.flags.notNull || column.flags.hasDefault || column.flags.primaryKey;\n}\n\n/**\n * Map a column to the filter control the list view shows for it.\n *\n * Booleans and enums become dropdowns, date-like columns become a from/to pair\n * of date inputs, and anything else falls back to an equality text input.\n *\n * @param column - The column to inspect.\n * @returns The filter kind and, for `select`, its options.\n */\nexport function filterForColumn(column: Column<unknown>): {\n kind: AdminFilterKind;\n options: AdminSelectOption[];\n} {\n const { kind, meta } = column.type;\n if (kind === \"boolean\") {\n return {\n kind: \"select\",\n options: [\n { value: \"true\", label: \"Yes\" },\n { value: \"false\", label: \"No\" },\n ],\n };\n }\n if (kind === \"enum\") {\n return {\n kind: \"select\",\n options: (meta.values ?? []).map((value) => ({\n value,\n label: humanizeField(value),\n })),\n };\n }\n if (kind === \"date\" || kind === \"datetime\" || kind === \"timestamp\") {\n return { kind: \"daterange\", options: [] };\n }\n return { kind: \"text\", options: [] };\n}\n\n/**\n * Whether a column holds free text a `LIKE '%…%'` search can match.\n *\n * @param column - The column to inspect.\n * @returns `true` for `varchar` / `text` / `char` columns.\n */\nexport function isSearchableColumn(column: Column<unknown>): boolean {\n const { kind } = column.type;\n return kind === \"varchar\" || kind === \"text\" || kind === \"char\";\n}\n","/**\n * Declarative admin configuration for one model, mirroring `admin.config`.\n *\n * Instantiate one {@link AdminModel} per managed model and hand it to\n * {@link AdminSite.register}. Unlike Django's class-based `ModelAdmin` this is\n * a plain typed instance — the constructor options are the contract, there is\n * no metaclass magic, and every default is derived from the model's own column\n * metadata so an unconfigured model is already browsable.\n */\n\nimport { adminColumns, humanizeField } from \"@/admin/columns\";\nimport {\n type AsyncSession,\n BaseRepository,\n type InferModel,\n type ModelClass,\n} from \"@/db\";\n\n/** Column keys the generic form never edits, whatever the model declares. */\nconst NEVER_EDITABLE: readonly string[] = [\n \"id\",\n \"createdAt\",\n \"updatedAt\",\n \"hashedPassword\",\n];\n\n/** Column keys hidden from the list view unless `listDisplay` says otherwise. */\nconst NEVER_LISTED: readonly string[] = [\"hashedPassword\"];\n\n/** Configuration accepted by {@link AdminModel}. */\nexport interface AdminModelOptions<C extends ModelClass> {\n /** The model class to manage. */\n model: C;\n /** URL slug. Defaults to the model's `tablename`, so URLs track tables. */\n slug?: string;\n /** Columns shown in the list view. Defaults to every column but the password hash. */\n listDisplay?: readonly string[];\n /** Columns surfaced as filter controls above the list. */\n listFilter?: readonly string[];\n /** Text columns searched with `LIKE '%value%'` by the search box. */\n searchFields?: readonly string[];\n /** Columns shown but never editable in the create/edit form. */\n readonlyFields?: readonly string[];\n /** Default ordering: a column key, or `-column` for descending. */\n ordering?: string;\n /** Rows per page in the list view. Default `25`. */\n pageSize?: number;\n /** Column used to look one row up from the detail URL. Default `\"id\"`. */\n identityField?: string;\n /** Singular display name. Defaults to the humanized class name. */\n verboseName?: string;\n /** Plural display name. Defaults to `verboseName` + `\"s\"`. */\n verboseNamePlural?: string;\n /** Whether the create form + POST endpoint are exposed. Default `true`. */\n canCreate?: boolean;\n /** Whether the edit form + POST endpoint are exposed. Default `true`. */\n canEdit?: boolean;\n /** Whether the delete action is exposed. Default `true`. */\n canDelete?: boolean;\n}\n\n/**\n * The admin configuration for one model.\n *\n * ```ts\n * new AdminModel({\n * model: UserModel,\n * listDisplay: [\"email\", \"isAdmin\", \"isActive\", \"createdAt\"],\n * listFilter: [\"isActive\", \"isAdmin\"],\n * searchFields: [\"email\"],\n * ordering: \"-createdAt\",\n * });\n * ```\n */\nexport class AdminModel<C extends ModelClass = ModelClass> {\n /** The managed model class. */\n readonly model: C;\n /** Columns surfaced as filter controls. */\n readonly listFilter: string[];\n /** Text columns the search box matches against. */\n readonly searchFields: string[];\n /** Columns locked in the create/edit form. */\n readonlyFields: string[];\n /** Default ordering column, or `null` to leave it to the repository. */\n readonly orderKey: string | null;\n /** Whether {@link AdminModel.orderKey} sorts ascending. */\n readonly orderAscending: boolean;\n /** Rows per page in the list view. */\n readonly pageSize: number;\n /** Column used to look a single row up from the detail URL. */\n readonly identityField: string;\n /** Whether the create form is exposed. */\n readonly canCreate: boolean;\n /** Whether the edit form is exposed. */\n readonly canEdit: boolean;\n /** Whether the delete action is exposed. */\n readonly canDelete: boolean;\n\n private readonly slugOverride: string | null;\n private readonly listDisplayOverride: string[] | null;\n private readonly verboseNameOverride: string | null;\n private readonly verboseNamePluralOverride: string | null;\n\n /**\n * Build and validate the configuration.\n *\n * @param options - The declarative configuration. See {@link AdminModelOptions}.\n * @throws Error When a referenced column does not exist on the model.\n */\n constructor(options: AdminModelOptions<C>) {\n this.model = options.model;\n this.slugOverride = options.slug ?? null;\n this.listDisplayOverride =\n options.listDisplay === undefined ? null : [...options.listDisplay];\n this.listFilter = [...(options.listFilter ?? [])];\n this.searchFields = [...(options.searchFields ?? [])];\n this.readonlyFields = [...(options.readonlyFields ?? [])];\n this.pageSize = options.pageSize ?? 25;\n this.identityField = options.identityField ?? \"id\";\n this.verboseNameOverride = options.verboseName ?? null;\n this.verboseNamePluralOverride = options.verboseNamePlural ?? null;\n this.canCreate = options.canCreate ?? true;\n this.canEdit = options.canEdit ?? true;\n this.canDelete = options.canDelete ?? true;\n\n const known = new Set(this.columnNames());\n for (const [option, names] of [\n [\"listDisplay\", this.listDisplayOverride ?? []],\n [\"listFilter\", this.listFilter],\n [\"searchFields\", this.searchFields],\n [\"readonlyFields\", this.readonlyFields],\n [\"identityField\", [this.identityField]],\n ] as const) {\n for (const name of names) {\n if (!known.has(name)) {\n throw new Error(\n `AdminModel(${this.model.tablename}).${option} references unknown column ` +\n `\"${name}\"; available: ${[...known].join(\", \")}`,\n );\n }\n }\n }\n\n const ordering =\n options.ordering ?? (known.has(\"createdAt\") ? \"-createdAt\" : undefined);\n if (ordering === undefined) {\n this.orderKey = null;\n this.orderAscending = true;\n } else {\n const descending = ordering.startsWith(\"-\");\n const key = descending ? ordering.slice(1) : ordering;\n if (!known.has(key)) {\n throw new Error(\n `AdminModel(${this.model.tablename}).ordering references unknown column \"${key}\"`,\n );\n }\n this.orderKey = key;\n this.orderAscending = !descending;\n }\n }\n\n /**\n * Return the URL slug the model is exposed under.\n *\n * @returns The configured slug, or the model's table name.\n */\n slug(): string {\n return this.slugOverride ?? this.model.tablename;\n }\n\n /**\n * Return the singular display name.\n *\n * @returns The configured name, or the humanized class name without its\n * trailing `Model`.\n */\n verboseName(): string {\n if (this.verboseNameOverride !== null) return this.verboseNameOverride;\n const className = (this.model as unknown as { name: string }).name;\n return humanizeField(className.replace(/Model$/, \"\"));\n }\n\n /**\n * Return the plural display name.\n *\n * @returns The configured plural, or the singular with an `s`.\n */\n verboseNamePlural(): string {\n return this.verboseNamePluralOverride ?? `${this.verboseName()}s`;\n }\n\n /**\n * Return every column key on the model, in declaration order.\n *\n * @returns The column keys.\n */\n columnNames(): string[] {\n return Object.keys(adminColumns(this.model));\n }\n\n /**\n * Return the columns the list view renders.\n *\n * @returns The configured `listDisplay`, or every column but the password hash.\n */\n listDisplayNames(): string[] {\n if (this.listDisplayOverride !== null) return [...this.listDisplayOverride];\n return this.columnNames().filter((name) => !NEVER_LISTED.includes(name));\n }\n\n /**\n * Return the columns the detail view renders.\n *\n * Unlike {@link AdminModel.listDisplayNames}, this is not narrowed by\n * `listDisplay`: the list view is a scannable summary, but the detail view is\n * where an operator goes to see the whole record, so trimming it there would\n * hide data with nowhere else to read it.\n *\n * @returns Every column but the password hash, in declaration order.\n */\n detailFieldNames(): string[] {\n return this.columnNames().filter((name) => !NEVER_LISTED.includes(name));\n }\n\n /**\n * Return the columns a create/edit form exposes.\n *\n * Excludes the primary key, the managed timestamps, the password hash and\n * anything listed in `readonlyFields` — none of which a user edits directly\n * through the generic form.\n *\n * @returns The editable column keys, in declaration order.\n */\n editableFieldNames(): string[] {\n const skip = new Set([...this.readonlyFields, ...NEVER_EDITABLE]);\n return this.columnNames().filter((name) => !skip.has(name));\n }\n\n /**\n * Build a repository for this model bound to a session.\n *\n * @param session - The session the repository runs its statements on.\n * @returns A repository over {@link AdminModel.model}.\n */\n repository(session: AsyncSession): BaseRepository<C> {\n return new BaseRepository(this.model, session);\n }\n}\n\n/** The row type a configured {@link AdminModel} reads and writes. */\nexport type AdminRow<A> = A extends AdminModel<infer C> ? InferModel<C> : never;\n","/**\n * Form building and submission parsing for the admin CRUD views, mirroring\n * `admin.forms`.\n *\n * One direction turns a model's columns into typed widget descriptors the\n * templates render; the other reads a posted `application/x-www-form-urlencoded`\n * body back into coerced values ready for the repository. Both live here, away\n * from the router, so the fiddly per-type handling is unit-testable on its own.\n */\n\nimport {\n type AdminSelectOption,\n type AdminWidget,\n adminColumns,\n humanizeField,\n isColumnOptional,\n widgetForColumn,\n} from \"@/admin/columns\";\nimport type { AdminModel } from \"@/admin/config\";\nimport type { Column } from \"@/db\";\n\n/** A single rendered form control. */\nexport interface AdminFormField {\n /** Column key, used as the form field name. */\n name: string;\n /** Human-readable label. */\n label: string;\n /** The control to render. */\n widget: AdminWidget;\n /** Pre-filled value, already stringified for the control. */\n value: string;\n /** Whether the field must be filled in. */\n required: boolean;\n /** Checkbox state (`checkbox` widget only). */\n checked: boolean;\n /** `step` attribute for `number` widgets. */\n step: string | null;\n /** `(value, label)` pairs for `select` widgets. */\n options: AdminSelectOption[];\n /** Per-field validation error, or `null`. */\n error: string | null;\n}\n\n/** The outcome of parsing a submitted create/edit form. */\nexport interface ParsedAdminForm {\n /** Coerced column values, ready to hand to the repository. */\n data: Record<string, unknown>;\n /** Per-field error messages, keyed by column. Empty when the form is valid. */\n errors: Record<string, string>;\n}\n\n/** Options for {@link buildFormFields}. */\nexport interface BuildFormFieldsOptions {\n /** Current values, keyed by column — a row on edit, a re-submission on error. */\n values?: Record<string, unknown>;\n /** Per-field errors to surface, keyed by column. */\n errors?: Record<string, string>;\n}\n\n/**\n * Render a stored value into the string a control pre-fills with.\n *\n * @param widget - The control the value is rendered for.\n * @param value - The stored value.\n * @returns The control's `value` text (empty for `null`/`undefined`).\n */\nexport function formatFieldValue(widget: AdminWidget, value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (widget === \"json\") {\n return typeof value === \"string\" ? value : JSON.stringify(value, null, 2);\n }\n if (value instanceof Date) {\n const iso = value.toISOString();\n if (widget === \"date\") return iso.slice(0, 10);\n if (widget === \"time\") return iso.slice(11, 19);\n return iso.slice(0, 16);\n }\n if (widget === \"datetime\" || widget === \"date\") {\n const parsed = new Date(String(value));\n if (!Number.isNaN(parsed.getTime())) {\n const iso = parsed.toISOString();\n return widget === \"date\" ? iso.slice(0, 10) : iso.slice(0, 16);\n }\n }\n return String(value);\n}\n\n/**\n * Return the literal default a column carries, for pre-filling a blank form.\n *\n * Only literal defaults are usable: an expression default (`now()`,\n * `uuidv4()`) is evaluated by the database, has no client-side value, and\n * belongs to a column the generic form never edits anyway.\n *\n * @param column - The column to inspect.\n * @returns The default value, or `undefined` when there is none to show.\n */\nfunction literalDefault(column: Column<unknown>): unknown {\n const fallback = column.defaultValue;\n if (fallback === null || fallback.kind !== \"literal\") return undefined;\n return fallback.value;\n}\n\n/**\n * Build the controls a create/edit form renders.\n *\n * A field with no current value falls back to its column's literal default, so\n * a blank create form arrives pre-filled the way the database would fill it.\n * Without that, submitting the form untouched would write `false` over a\n * `default(true)` flag — the panel would silently deactivate every row it\n * creates.\n *\n * @param admin - The model configuration.\n * @param options - Current values and per-field errors.\n * @returns One {@link AdminFormField} per editable column, in declaration order.\n */\nexport function buildFormFields(\n admin: AdminModel,\n options: BuildFormFieldsOptions = {},\n): AdminFormField[] {\n const columns = adminColumns(admin.model);\n const values = options.values ?? {};\n const errors = options.errors ?? {};\n\n return admin.editableFieldNames().flatMap((name) => {\n const column = columns[name];\n if (column === undefined) return [];\n const spec = widgetForColumn(column);\n const raw = name in values ? values[name] : literalDefault(column);\n return [\n {\n name,\n label: humanizeField(name),\n widget: spec.widget,\n value: spec.widget === \"checkbox\" ? \"\" : formatFieldValue(spec.widget, raw),\n required: !isColumnOptional(column),\n checked: spec.widget === \"checkbox\" && toBoolean(raw),\n step: spec.step,\n options: spec.options,\n error: errors[name] ?? null,\n },\n ];\n });\n}\n\n/**\n * Interpret a stored or submitted value as a checkbox state.\n *\n * @param value - The value to read.\n * @returns `true` for `true`, `1`, `\"true\"`, `\"on\"`, `\"yes\"` and `\"1\"`.\n */\nfunction toBoolean(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"number\") return value !== 0;\n if (typeof value !== \"string\") return false;\n return [\"true\", \"on\", \"yes\", \"1\"].includes(value.trim().toLowerCase());\n}\n\n/**\n * Coerce one submitted string into the value its column stores.\n *\n * @param column - The target column.\n * @param widget - The control the value came from.\n * @param raw - The submitted text.\n * @returns The coerced value.\n * @throws Error With a user-facing message when the text is not valid for the column.\n */\nfunction coerceValue(column: Column<unknown>, widget: AdminWidget, raw: string): unknown {\n const { kind, meta } = column.type;\n switch (widget) {\n case \"number\": {\n const parsed = Number(raw);\n if (!Number.isFinite(parsed)) throw new Error(\"Enter a valid number.\");\n if (kind === \"bigint\") return BigInt(raw);\n if (kind === \"smallint\" || kind === \"integer\") {\n if (!Number.isInteger(parsed)) throw new Error(\"Enter a whole number.\");\n return parsed;\n }\n if (kind === \"numeric\") return raw;\n return parsed;\n }\n case \"datetime\":\n case \"date\": {\n const parsed = new Date(raw);\n if (Number.isNaN(parsed.getTime())) throw new Error(\"Enter a valid date.\");\n return parsed;\n }\n case \"json\":\n try {\n return JSON.parse(raw);\n } catch {\n throw new Error(\"Enter valid JSON.\");\n }\n case \"select\": {\n const allowed = meta.values ?? [];\n if (allowed.length > 0 && !allowed.includes(raw)) {\n throw new Error(`Choose one of: ${allowed.join(\", \")}.`);\n }\n return raw;\n }\n default:\n return raw;\n }\n}\n\n/**\n * Read a submitted create/edit form back into coerced column values.\n *\n * A checkbox that is absent from the body is `false` (that is how browsers\n * submit an unchecked box), and an empty text field on an optional column\n * becomes `null` rather than an empty string, so a cleared field really clears\n * the column.\n *\n * @param admin - The model configuration.\n * @param body - The parsed request body.\n * @returns The coerced values plus any per-field errors.\n */\nexport function parseFormBody(\n admin: AdminModel,\n body: Record<string, unknown>,\n): ParsedAdminForm {\n const columns = adminColumns(admin.model);\n const data: Record<string, unknown> = {};\n const errors: Record<string, string> = {};\n\n for (const name of admin.editableFieldNames()) {\n const column = columns[name];\n if (column === undefined) continue;\n const { widget } = widgetForColumn(column);\n\n if (widget === \"checkbox\") {\n data[name] = toBoolean(body[name]);\n continue;\n }\n\n const submitted = body[name];\n const raw = typeof submitted === \"string\" ? submitted.trim() : \"\";\n if (raw === \"\") {\n if (!isColumnOptional(column)) {\n errors[name] = \"This field is required.\";\n continue;\n }\n if (column.flags.hasDefault && !(name in body)) continue;\n data[name] = null;\n continue;\n }\n\n try {\n data[name] = coerceValue(column, widget, raw);\n } catch (error) {\n errors[name] = error instanceof Error ? error.message : \"Invalid value.\";\n }\n }\n\n return { data, errors };\n}\n\n/**\n * Render a stored value for a read-only list or detail cell.\n *\n * @param value - The stored value.\n * @returns A display string (empty for `null`/`undefined`).\n */\nexport function formatCellValue(value: unknown): string {\n if (value === null || value === undefined) return \"\";\n if (value instanceof Date) return value.toISOString().replace(\"T\", \" \").slice(0, 19);\n if (typeof value === \"boolean\") return value ? \"Yes\" : \"No\";\n if (typeof value === \"object\") return JSON.stringify(value);\n return String(value);\n}\n","/**\n * Authentication backends for the admin panel, mirroring `admin.auth`.\n *\n * Operators sign in with a row from the project's own database — there is no\n * separate admin password store. {@link UserModelAuthBackend} covers the\n * conventional case (a {@link BaseUserModel} subclass gated on `isActive` and\n * `isAdmin`); anything else — LDAP, an upstream identity provider, a service\n * account table — implements {@link AdminAuthBackend} directly.\n */\n\nimport type { AsyncSession, ModelClass } from \"@/db\";\nimport { BaseRepository } from \"@/db\";\nimport { PasswordUtils } from \"@/utils\";\n\n/** The columns {@link UserModelAuthBackend} reads off a principal row. */\ninterface UserPrincipalRow {\n id: string;\n email: string;\n hashedPassword: string;\n isActive: boolean;\n isAdmin: boolean;\n}\n\n/** Verifies a TOTP code for a principal that enrolled a second factor. */\nexport interface AdminMfaVerifier {\n /** Whether the principal has a confirmed second factor. */\n isEnabled(userId: string): Promise<boolean>;\n /** Whether `code` is a valid current TOTP for the principal. */\n verify(userId: string, code: string): Promise<boolean>;\n}\n\n/**\n * How the panel turns a login form into a principal.\n *\n * The interface is generic in the principal so a custom backend can hand its\n * own row type back to {@link AdminAuthBackend.displayName} and friends.\n */\nexport interface AdminAuthBackend<Principal = unknown> {\n /**\n * Verify credentials.\n *\n * @param session - A DB session for the current request.\n * @param identifier - The submitted login identifier (typically an email).\n * @param password - The submitted plaintext password.\n * @returns The principal, or `null` when the credentials are rejected.\n */\n authenticate(\n session: AsyncSession,\n identifier: string,\n password: string,\n ): Promise<Principal | null>;\n\n /**\n * Re-load the principal a session points at, so a deactivated operator loses\n * access on the next request rather than at cookie expiry.\n *\n * @param session - A DB session for the current request.\n * @param subject - The principal id stored in the session.\n * @returns The principal, or `null` when it no longer qualifies.\n */\n loadPrincipal(session: AsyncSession, subject: string): Promise<Principal | null>;\n\n /**\n * Return the stable id stored in the session cookie.\n *\n * @param principal - The authenticated principal.\n * @returns The principal id.\n */\n principalId(principal: Principal): string;\n\n /**\n * Return the name shown in the panel header.\n *\n * @param principal - The authenticated principal.\n * @returns A human-readable label.\n */\n displayName(principal: Principal): string;\n\n /**\n * Whether this principal must clear a second factor before entering.\n *\n * Omit to declare the backend has no MFA — the panel then treats every\n * successful password check as a complete login.\n *\n * @param principal - The authenticated principal.\n * @returns `true` when a TOTP challenge is required.\n */\n mfaEnabled?(principal: Principal): Promise<boolean>;\n\n /**\n * Verify the submitted TOTP code.\n *\n * @param principal - The authenticated principal.\n * @param code - The submitted code.\n * @returns `true` when the code is valid.\n */\n verifyMfa?(principal: Principal, code: string): Promise<boolean>;\n}\n\n/** Options for {@link UserModelAuthBackend}. */\nexport interface UserModelAuthBackendOptions {\n /** Password hasher. Defaults to a stock {@link PasswordUtils}. */\n passwords?: PasswordUtils;\n /**\n * TOTP verifier. When given, a principal with a confirmed secret is sent\n * through the panel's `/mfa` challenge after the password check, so the\n * admin panel can never be the weaker door into an MFA-protected account.\n */\n mfa?: AdminMfaVerifier;\n /** Column holding the login identifier. Default `\"email\"`. */\n identifierField?: string;\n /**\n * Require `isAdmin === true` on the row. Default `true`. Turn it off only\n * when the model expresses privilege some other way and the panel is already\n * gated elsewhere.\n */\n requireAdmin?: boolean;\n}\n\n/**\n * The conventional backend: authenticate against a {@link BaseUserModel}\n * subclass, admitting only rows that are both active and flagged as admins.\n *\n * ```ts\n * new UserModelAuthBackend(UserModel);\n * ```\n */\nexport class UserModelAuthBackend implements AdminAuthBackend<UserPrincipalRow> {\n private readonly model: ModelClass;\n private readonly passwords: PasswordUtils;\n private readonly mfa: AdminMfaVerifier | null;\n private readonly identifierField: string;\n private readonly requireAdmin: boolean;\n\n /**\n * Build the backend.\n *\n * @param model - The user model class (a `BaseUserModel` subclass).\n * @param options - Hasher, MFA verifier and gating overrides.\n */\n constructor(model: ModelClass, options: UserModelAuthBackendOptions = {}) {\n this.model = model;\n this.passwords = options.passwords ?? new PasswordUtils();\n this.mfa = options.mfa ?? null;\n this.identifierField = options.identifierField ?? \"email\";\n this.requireAdmin = options.requireAdmin ?? true;\n }\n\n /**\n * Whether a row is allowed into the panel at all.\n *\n * @param row - The candidate row.\n * @returns `true` when the row is active and (when required) an admin.\n */\n private admits(row: UserPrincipalRow): boolean {\n if (row.isActive === false) return false;\n return !this.requireAdmin || row.isAdmin === true;\n }\n\n /**\n * Verify an identifier/password pair.\n *\n * The identifier is lowercased and trimmed before lookup, matching the\n * normalization the auth service applies on signup.\n *\n * @param session - A DB session for the current request.\n * @param identifier - The submitted identifier.\n * @param password - The submitted plaintext password.\n * @returns The matching row, or `null` when it does not qualify.\n */\n async authenticate(\n session: AsyncSession,\n identifier: string,\n password: string,\n ): Promise<UserPrincipalRow | null> {\n const repository = new BaseRepository(this.model, session);\n const filters = { [this.identifierField]: identifier.trim().toLowerCase() };\n const row = (await repository.first(\n filters as never,\n )) as unknown as UserPrincipalRow | null;\n if (row === null || !this.admits(row)) return null;\n if (!(await this.passwords.verify(password, row.hashedPassword))) return null;\n return row;\n }\n\n /**\n * Re-load the principal a session points at.\n *\n * @param session - A DB session for the current request.\n * @param subject - The principal id from the session cookie.\n * @returns The row, or `null` when it vanished or lost its privileges.\n */\n async loadPrincipal(\n session: AsyncSession,\n subject: string,\n ): Promise<UserPrincipalRow | null> {\n const repository = new BaseRepository(this.model, session);\n const row = (await repository.getByIdOrNull(\n subject,\n )) as unknown as UserPrincipalRow | null;\n if (row === null || !this.admits(row)) return null;\n return row;\n }\n\n /**\n * Return the row's primary key.\n *\n * @param principal - The authenticated row.\n * @returns The principal id.\n */\n principalId(principal: UserPrincipalRow): string {\n return String(principal.id);\n }\n\n /**\n * Return the label shown in the panel header.\n *\n * @param principal - The authenticated row.\n * @returns The identifier column's value.\n */\n displayName(principal: UserPrincipalRow): string {\n const value = (principal as unknown as Record<string, unknown>)[this.identifierField];\n return typeof value === \"string\" ? value : String(principal.id);\n }\n\n /**\n * Whether the principal enrolled a second factor.\n *\n * @param principal - The authenticated row.\n * @returns `true` when an MFA verifier is configured and reports a secret.\n */\n async mfaEnabled(principal: UserPrincipalRow): Promise<boolean> {\n if (this.mfa === null) return false;\n return await this.mfa.isEnabled(String(principal.id));\n }\n\n /**\n * Verify a submitted TOTP code.\n *\n * @param principal - The authenticated row.\n * @param code - The submitted code.\n * @returns `true` when the code is valid.\n */\n async verifyMfa(principal: UserPrincipalRow, code: string): Promise<boolean> {\n if (this.mfa === null) return false;\n return await this.mfa.verify(String(principal.id), code);\n }\n}\n","/**\n * Signed-cookie sessions for the admin panel, mirroring `admin.session`.\n *\n * The panel's session is **stateless**: the principal id, display name, CSRF\n * token and expiry travel in the cookie itself, signed with HMAC-SHA256 over\n * the caller's secret. Nothing is kept server-side, so the panel survives a\n * restart and works across replicas without a shared store — the property that\n * matters most for an operator tool that is used in bursts and left open.\n *\n * The CSRF token lives inside the session payload, so every write form can\n * carry it and the server compares it against the cookie it already trusts.\n */\n\nimport { createHmac, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { parseCookies } from \"@/sessions\";\nimport type { Request, Response } from \"express\";\n\n/** Minimum secret length; a shorter key makes the HMAC trivially brute-forceable. */\nconst MIN_SECRET_LENGTH = 32;\n\n/** The payload carried by the admin session cookie. */\nexport interface AdminSession {\n /** Stable id of the authenticated principal. */\n subject: string;\n /** Display name shown in the header. */\n displayName: string;\n /** Token every write form echoes back for CSRF validation. */\n csrfToken: string;\n /** Expiry, in epoch seconds. */\n expiresAt: number;\n /**\n * `true` once the second factor was accepted. Sessions issued for a\n * principal without MFA are complete from the start.\n */\n mfaPassed: boolean;\n}\n\n/** Options for {@link AdminSessionStore}. */\nexport interface AdminSessionStoreOptions {\n /** HMAC key signing the cookie. At least 32 characters. */\n secret: string;\n /** Cookie name. Default `tempest_admin_session`. */\n cookieName?: string;\n /** Session lifetime in seconds. Default `28800` (8 hours). */\n maxAgeSeconds?: number;\n /** Send the cookie with `Secure` (HTTPS only). Default `true`. */\n cookieSecure?: boolean;\n /** Cookie `Path`. Default `/`. */\n cookiePath?: string;\n}\n\n/**\n * Encode a value as base64url without padding.\n *\n * @param value - The bytes or string to encode.\n * @returns The base64url text.\n */\nfunction encode(value: string): string {\n return Buffer.from(value, \"utf8\").toString(\"base64url\");\n}\n\n/**\n * Issues, verifies and clears the admin session cookie.\n *\n * The cookie value is `<base64url payload>.<base64url signature>`; a payload\n * whose signature does not verify, or whose expiry has passed, resolves to\n * `null` — an operator with a tampered or stale cookie is simply logged out.\n */\nexport class AdminSessionStore {\n private readonly secret: string;\n private readonly cookieName: string;\n private readonly maxAgeSeconds: number;\n private readonly cookieSecure: boolean;\n private readonly cookiePath: string;\n\n /**\n * Build the store.\n *\n * @param options - Secret, cookie name, lifetime and cookie flags.\n * @throws Error When the secret is shorter than 32 characters.\n */\n constructor(options: AdminSessionStoreOptions) {\n if (options.secret.length < MIN_SECRET_LENGTH) {\n throw new Error(\n `Admin session secret must be at least ${MIN_SECRET_LENGTH} characters; ` +\n `got ${options.secret.length}`,\n );\n }\n this.secret = options.secret;\n this.cookieName = options.cookieName ?? \"tempest_admin_session\";\n this.maxAgeSeconds = options.maxAgeSeconds ?? 8 * 60 * 60;\n this.cookieSecure = options.cookieSecure ?? true;\n this.cookiePath = options.cookiePath ?? \"/\";\n }\n\n /**\n * Sign a payload.\n *\n * @param payload - The base64url payload to sign.\n * @returns The base64url signature.\n */\n private sign(payload: string): string {\n return createHmac(\"sha256\", this.secret).update(payload).digest(\"base64url\");\n }\n\n /**\n * Mint a fresh session for an authenticated principal.\n *\n * @param subject - The principal id.\n * @param displayName - The name shown in the header.\n * @param mfaPassed - Whether the second factor is already satisfied.\n * @returns The new session payload (not yet written to a response).\n */\n issue(subject: string, displayName: string, mfaPassed = true): AdminSession {\n return {\n subject,\n displayName,\n csrfToken: randomUUID(),\n expiresAt: Math.floor(Date.now() / 1000) + this.maxAgeSeconds,\n mfaPassed,\n };\n }\n\n /**\n * Read and verify the session carried by a request.\n *\n * @param req - The inbound request.\n * @returns The session, or `null` when absent, tampered with or expired.\n */\n load(req: Request): AdminSession | null {\n const raw = parseCookies(req.header(\"cookie\") ?? undefined)[this.cookieName];\n if (raw === undefined) return null;\n const separator = raw.lastIndexOf(\".\");\n if (separator <= 0) return null;\n\n const payload = raw.slice(0, separator);\n const signature = Buffer.from(raw.slice(separator + 1), \"base64url\");\n const expected = Buffer.from(this.sign(payload), \"base64url\");\n if (signature.length !== expected.length) return null;\n if (!timingSafeEqual(signature, expected)) return null;\n\n let session: AdminSession;\n try {\n session = JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\"));\n } catch {\n return null;\n }\n if (typeof session.subject !== \"string\" || typeof session.csrfToken !== \"string\") {\n return null;\n }\n if (session.expiresAt <= Math.floor(Date.now() / 1000)) return null;\n return session;\n }\n\n /**\n * Write a session to the response as a signed cookie.\n *\n * @param res - The outbound response.\n * @param session - The session to persist.\n */\n save(res: Response, session: AdminSession): void {\n const payload = encode(JSON.stringify(session));\n const value = `${payload}.${this.sign(payload)}`;\n const maxAge = Math.max(0, session.expiresAt - Math.floor(Date.now() / 1000));\n res.append(\"set-cookie\", this.cookie(value, maxAge));\n }\n\n /**\n * Drop the session cookie.\n *\n * @param res - The outbound response.\n */\n clear(res: Response): void {\n res.append(\"set-cookie\", this.cookie(\"\", 0));\n }\n\n /**\n * Render a `Set-Cookie` value with the configured flags.\n *\n * @param value - The cookie value.\n * @param maxAge - Lifetime in seconds (`0` expires it immediately).\n * @returns The header value.\n */\n private cookie(value: string, maxAge: number): string {\n const parts = [\n `${this.cookieName}=${value}`,\n `Path=${this.cookiePath}`,\n `Max-Age=${maxAge}`,\n \"HttpOnly\",\n \"SameSite=Lax\",\n ];\n if (this.cookieSecure) parts.push(\"Secure\");\n return parts.join(\"; \");\n }\n}\n\n/**\n * Compare a submitted CSRF token against the session's, in constant time.\n *\n * @param session - The active session.\n * @param submitted - The `csrf_token` field from the form body.\n * @returns `true` when the tokens match.\n */\nexport function csrfTokenMatches(session: AdminSession, submitted: unknown): boolean {\n if (typeof submitted !== \"string\") return false;\n const expected = Buffer.from(session.csrfToken, \"utf8\");\n const actual = Buffer.from(submitted, \"utf8\");\n if (expected.length !== actual.length) return false;\n return timingSafeEqual(expected, actual);\n}\n","/**\n * Admin site registry, mirroring `admin.site` — the analog of Django's\n * `AdminSite`.\n *\n * A project instantiates one site, registers its {@link AdminModel}\n * configurations (one at a time with {@link AdminSite.register}, or all at\n * once with {@link AdminSite.automap}), and hands the site to\n * `makeAdminRouter`.\n */\n\nimport { AdminModel, type AdminModelOptions } from \"@/admin/config\";\nimport type { AdminTheme } from \"@/admin/theme\";\nimport { Model, type ModelClass } from \"@/db\";\n\n/** Branding and appearance options for an {@link AdminSite}. */\nexport interface AdminSiteOptions {\n /** Text used in the page `<title>` and the dashboard heading. Default `\"Admin\"`. */\n title?: string;\n /** Centered header brand. Falls back to `title`. */\n brand?: string;\n /** Dashboard subtitle. Default `\"Site administration\"`. */\n indexSubtitle?: string;\n /** Optional outbound \"View site\" link rendered in the header. */\n siteUrl?: string;\n /** Typed appearance overrides. Omitted keeps the stock look. */\n theme?: AdminTheme;\n}\n\n/** Options accepted by {@link AdminSite.automap}. */\nexport interface AdminAutomapOptions\n extends Omit<AdminModelOptions<ModelClass>, \"model\"> {\n /** Models to skip — each entry is the model class or its table name. */\n exclude?: readonly (ModelClass | string)[];\n /**\n * When `true` (default), a model whose slug is already registered is left\n * untouched, so a hand-tuned {@link AdminModel} can be registered first.\n * When `false`, a collision throws, as {@link AdminSite.register} does.\n */\n skipRegistered?: boolean;\n}\n\n/**\n * Whether a value is a usable model class — a constructor extending `Model`\n * that declares a non-empty `tablename`.\n *\n * Abstract bases (`BaseModel`, `BaseUserModel` and friends) declare no table\n * name, so they are filtered out exactly as the Python `automap` skips them.\n *\n * @param value - The candidate value, typically a module namespace entry.\n * @returns `true` when the value can be registered.\n */\nfunction isConcreteModel(value: unknown): value is ModelClass {\n if (typeof value !== \"function\") return false;\n const proto: unknown = (value as { prototype?: unknown }).prototype;\n if (typeof proto !== \"object\" || proto === null) return false;\n if (!(proto instanceof Model)) return false;\n const tablename: unknown = (value as { tablename?: unknown }).tablename;\n return typeof tablename === \"string\" && tablename.length > 0;\n}\n\n/**\n * The registry of {@link AdminModel} configurations a panel exposes.\n *\n * ```ts\n * const site = new AdminSite({ title: \"MyApp Admin\", brand: \"myapp-admin\" });\n * site.register({ model: UserModel, searchFields: [\"email\"] });\n * site.automap(models);\n * ```\n */\nexport class AdminSite {\n /** Text used in the page `<title>` and the dashboard heading. */\n readonly title: string;\n /** Centered header brand, or `null` to fall back to {@link AdminSite.title}. */\n readonly brand: string | null;\n /** Dashboard subtitle. */\n readonly indexSubtitle: string;\n /** Outbound \"View site\" link, or `null`. */\n readonly siteUrl: string | null;\n /** Typed appearance overrides. */\n readonly theme: AdminTheme;\n\n private readonly registry = new Map<string, AdminModel>();\n\n /**\n * Initialize the site.\n *\n * @param options - Branding and appearance. See {@link AdminSiteOptions}.\n */\n constructor(options: AdminSiteOptions = {}) {\n this.title = options.title ?? \"Admin\";\n this.brand = options.brand ?? null;\n this.indexSubtitle = options.indexSubtitle ?? \"Site administration\";\n this.siteUrl = options.siteUrl ?? null;\n this.theme = options.theme ?? {};\n }\n\n /**\n * Return the centered header brand text.\n *\n * @returns {@link AdminSite.brand} when set, otherwise {@link AdminSite.title}.\n */\n brandText(): string {\n return this.brand ?? this.title;\n }\n\n /**\n * Register a model configuration under its slug.\n *\n * @param admin - An {@link AdminModel} instance, or the options to build one.\n * @returns The registered instance, so the call can be chained or assigned.\n * @throws Error When another configuration already holds the same slug.\n */\n register<C extends ModelClass>(\n admin: AdminModel<C> | AdminModelOptions<C>,\n ): AdminModel<C> {\n const config = admin instanceof AdminModel ? admin : new AdminModel(admin);\n const slug = config.slug();\n const existing = this.registry.get(slug);\n if (existing !== undefined) {\n throw new Error(\n `AdminModel for slug \"${slug}\" is already registered ` +\n `(${existing.model.tablename}); refusing to overwrite with ` +\n `${config.model.tablename}`,\n );\n }\n this.registry.set(slug, config as AdminModel);\n return config;\n }\n\n /**\n * Remove a previously registered configuration.\n *\n * @param slug - The slug to drop.\n * @throws Error When no configuration is registered under the slug.\n */\n unregister(slug: string): void {\n if (!this.registry.delete(slug)) {\n throw new Error(`No AdminModel registered for slug \"${slug}\"`);\n }\n }\n\n /**\n * Look a configuration up by slug.\n *\n * @param slug - The admin slug.\n * @returns The configuration, or `null` when nothing matches.\n */\n get(slug: string): AdminModel | null {\n return this.registry.get(slug) ?? null;\n }\n\n /**\n * Return every registered configuration, ordered by display name.\n *\n * @returns The configurations (empty when nothing is registered).\n */\n list(): AdminModel[] {\n return [...this.registry.values()].sort((left, right) =>\n left\n .verboseNamePlural()\n .toLowerCase()\n .localeCompare(right.verboseNamePlural().toLowerCase()),\n );\n }\n\n /**\n * Register every concrete model found in `source` at once.\n *\n * The batch counterpart to {@link AdminSite.register}: instead of one call\n * per table, hand it the models barrel and every model class declaring a\n * `tablename` is wrapped in a default {@link AdminModel}.\n *\n * ```ts\n * import * as models from \"./db/models\";\n *\n * site.automap(models);\n * site.automap([UserModel, OrderModel], { pageSize: 50 });\n * ```\n *\n * @param source - An array of model classes, or a module namespace object\n * whose values are swept (non-model entries are ignored).\n * @param options - `exclude`, `skipRegistered` and any {@link AdminModel}\n * option applied uniformly to every model discovered here.\n * @returns The configurations newly registered by this call.\n * @throws Error When `skipRegistered` is `false` and a slug collides.\n */\n automap(\n source: readonly unknown[] | Record<string, unknown>,\n options: AdminAutomapOptions = {},\n ): AdminModel[] {\n const { exclude = [], skipRegistered = true, ...adminOptions } = options;\n const excluded = new Set(\n exclude.map((entry) => (typeof entry === \"string\" ? entry : entry.tablename)),\n );\n const candidates = Array.isArray(source) ? source : Object.values(source);\n const registered: AdminModel[] = [];\n\n for (const candidate of candidates) {\n if (!isConcreteModel(candidate)) continue;\n if (excluded.has(candidate.tablename)) continue;\n const config = new AdminModel({ ...adminOptions, model: candidate });\n if (skipRegistered && this.registry.get(config.slug()) !== undefined) continue;\n registered.push(this.register(config));\n }\n return registered.sort((left, right) => left.slug().localeCompare(right.slug()));\n }\n}\n","/**\n * The bundled admin stylesheet, served at `{prefix}/static/admin.css`.\n *\n * Ported verbatim from tempest-fastapi-sdk's `admin/static/admin.css` so both\n * SDKs render the same panel. Everything is driven by the `--tempest-*` custom\n * properties an `AdminTheme` overrides, so a project restyles the panel without\n * touching this file — see `@/admin/theme`.\n *\n * It ships as a string rather than an asset because the package publishes only\n * `dist`: a `.css` file on disk would not survive the build.\n */\n\n/** The stylesheet text. */\nexport const ADMIN_CSS: string = `:root {\n --tempest-bg: #0f172a;\n --tempest-bg-soft: #1e293b;\n --tempest-bg-row: #f8fafc;\n --tempest-bg-row-alt: #f1f5f9;\n --tempest-fg: #0f172a;\n --tempest-fg-soft: #475569;\n --tempest-accent: #2563eb;\n --tempest-accent-hover: #1d4ed8;\n --tempest-accent-soft: rgba(37, 99, 235, 0.1);\n --tempest-danger: #b91c1c;\n /* Light surface + hairline used by cards / tables / dropdowns on the\n (light) content area — distinct from the dark sidebar bg vars above.\n Overridable by AdminTheme for dark mode. */\n --tempest-surface: #ffffff;\n --tempest-border: #e2e8f0;\n --tempest-radius: 6px;\n --tempest-shadow: 0 1px 2px rgba(15, 23, 42, 0.08);\n}\n\n* {\n box-sizing: border-box;\n}\n\nbody {\n margin: 0;\n font-family: var(--tempest-font, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif);\n font-size: 14px;\n color: var(--tempest-fg);\n background: var(--tempest-page-bg, #f8fafc);\n /* Sticky-footer column so the layout (and its sidebar) fills the\n viewport even when the page content is short. */\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n}\n\na {\n color: var(--tempest-accent);\n text-decoration: none;\n}\n\na:hover {\n color: var(--tempest-accent-hover);\n text-decoration: underline;\n}\n\nbutton {\n border: 0;\n background: var(--tempest-accent);\n color: #fff;\n padding: 0.5rem 1rem;\n border-radius: var(--tempest-radius);\n cursor: pointer;\n font: inherit;\n}\n\nbutton:hover {\n background: var(--tempest-accent-hover);\n}\n\ninput,\nselect,\ntextarea {\n font: inherit;\n padding: 0.45rem 0.6rem;\n border-radius: var(--tempest-radius);\n border: 1px solid #cbd5e1;\n background: #fff;\n}\n\n.tempest-admin-header {\n position: relative;\n z-index: 20;\n background: var(--tempest-bg);\n color: #f8fafc;\n padding: 0.75rem 1.5rem;\n display: flex;\n align-items: center;\n justify-content: space-between;\n box-shadow: var(--tempest-shadow);\n}\n\n/* Centered brand — pinned to the middle of the header (i.e. the screen)\n regardless of the left (burger) / right (nav) cluster widths. */\n.tempest-admin-header__brand {\n position: absolute;\n left: 50%;\n transform: translateX(-50%);\n text-align: center;\n pointer-events: none;\n}\n\n.tempest-admin-header__brand a {\n color: #fff;\n font-weight: 600;\n font-size: 1.1rem;\n pointer-events: auto;\n display: inline-flex;\n align-items: center;\n}\n\n/* Logo image (shown instead of the brand text when theme.logo_url is\n set). Capped to the header height so any aspect ratio fits cleanly. */\n.tempest-admin-header__logo {\n display: block;\n max-height: 32px;\n width: auto;\n}\n\n.tempest-admin-header__nav {\n display: flex;\n align-items: center;\n gap: 1rem;\n color: #cbd5e1;\n}\n\n.tempest-admin-header__nav a {\n color: #cbd5e1;\n}\n\n.tempest-admin-header__user {\n font-weight: 500;\n color: #f1f5f9;\n}\n\n.tempest-admin-header__logout {\n margin: 0;\n}\n\n.tempest-admin-header__logout button {\n background: transparent;\n color: #f1f5f9;\n padding: 0.25rem 0.5rem;\n border: 1px solid #475569;\n}\n\n.tempest-admin-header__logout button:hover {\n background: rgba(255, 255, 255, 0.08);\n}\n\n.tempest-admin-header__left {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n/* ---- Layout: persistent sidebar + content ---- */\n.tempest-admin-layout {\n display: flex;\n align-items: stretch;\n flex: 1; /* fill the viewport so the sidebar is full-height */\n}\n\n.tempest-admin-sidebar {\n flex: 0 0 220px;\n width: 220px;\n background: var(--tempest-bg-soft);\n color: #e2e8f0;\n padding: 1rem 0.75rem;\n}\n\n.tempest-admin-sidebar__nav {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n position: sticky;\n top: 1rem;\n}\n\n.tempest-admin-sidebar__heading {\n font-size: 0.7rem;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n color: #94a3b8;\n margin: 1rem 0.75rem 0.35rem;\n}\n\n.tempest-admin-sidebar__link {\n display: block;\n padding: 0.5rem 0.75rem;\n border-radius: var(--tempest-radius);\n color: #cbd5e1;\n}\n\n.tempest-admin-sidebar__link:hover {\n background: rgba(255, 255, 255, 0.06);\n color: #fff;\n text-decoration: none;\n}\n\n.tempest-admin-sidebar__link--active,\n.tempest-admin-sidebar__link--active:hover {\n background: var(--tempest-accent);\n color: #fff;\n}\n\n/* Burger toggle (CSS-only, via the hidden checkbox) — mobile only. */\n.tempest-admin-burger {\n display: none;\n flex-direction: column;\n gap: 4px;\n cursor: pointer;\n padding: 0.3rem;\n}\n\n.tempest-admin-burger span {\n display: block;\n width: 22px;\n height: 2px;\n background: #f8fafc;\n border-radius: 2px;\n}\n\n.tempest-admin-scrim {\n display: none;\n}\n\n.tempest-admin-main {\n flex: 1 1 auto;\n min-width: 0;\n max-width: 1080px;\n margin: 2rem auto;\n padding: 0 1.5rem;\n}\n\n.tempest-admin-messages {\n list-style: none;\n padding: 0;\n margin: 0 0 1.5rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.tempest-admin-messages__item {\n padding: 0.75rem 1rem;\n border-radius: var(--tempest-radius);\n border-left: 4px solid var(--tempest-accent);\n background: #eff6ff;\n}\n\n.tempest-admin-messages__item--error {\n border-left-color: var(--tempest-danger);\n background: #fef2f2;\n}\n\n.tempest-admin-login {\n max-width: 360px;\n margin: 4rem auto;\n background: #fff;\n border-radius: var(--tempest-radius);\n padding: 2rem;\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-login h1 {\n margin-top: 0;\n}\n\n.tempest-admin-login__form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.tempest-admin-login__form label {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.tempest-admin-login__error {\n background: #fef2f2;\n color: var(--tempest-danger);\n padding: 0.75rem 1rem;\n border-radius: var(--tempest-radius);\n}\n\n.tempest-admin-dashboard__table,\n.tempest-admin-list__table {\n width: 100%;\n border-collapse: collapse;\n background: #fff;\n border-radius: var(--tempest-radius);\n overflow: hidden;\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-dashboard__table th,\n.tempest-admin-dashboard__table td,\n.tempest-admin-list__table th,\n.tempest-admin-list__table td {\n padding: 0.75rem 1rem;\n text-align: left;\n border-bottom: 1px solid #e2e8f0;\n vertical-align: top;\n}\n\n.tempest-admin-list__table tr:nth-child(even) td {\n background: var(--tempest-bg-row-alt);\n}\n\n.tempest-admin-list__header {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n margin-bottom: 1rem;\n}\n\n.tempest-admin-list__filters {\n display: flex;\n gap: 0.75rem;\n align-items: end;\n margin-bottom: 1rem;\n flex-wrap: wrap;\n}\n\n.tempest-admin-list__filters label {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.tempest-admin-list__pagination {\n display: flex;\n gap: 1rem;\n align-items: center;\n justify-content: center;\n margin-top: 1.5rem;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-detail__fields {\n display: grid;\n grid-template-columns: 200px 1fr;\n gap: 0.5rem 1.5rem;\n background: #fff;\n border-radius: var(--tempest-radius);\n padding: 1.5rem;\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-detail__fields dt {\n font-weight: 600;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-detail__fields dd {\n margin: 0;\n word-break: break-word;\n}\n\n.tempest-admin-detail__audit-title {\n font-size: 1rem;\n margin: 1.5rem 0 0.5rem;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-detail__json {\n margin: 0;\n padding: 0.5rem 0.75rem;\n background: var(--tempest-bg-row);\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.8rem;\n overflow-x: auto;\n}\n\n.tempest-admin-history {\n list-style: none;\n margin: 0;\n padding: 0;\n border-left: 2px solid var(--tempest-border);\n}\n\n.tempest-admin-history__item {\n position: relative;\n padding: 0.5rem 0 1rem 1rem;\n}\n\n.tempest-admin-history__item::before {\n content: \"\";\n position: absolute;\n left: -0.4rem;\n top: 0.9rem;\n width: 0.6rem;\n height: 0.6rem;\n border-radius: 50%;\n background: var(--tempest-fg-soft);\n}\n\n.tempest-admin-history__item--create::before { background: #16a34a; }\n.tempest-admin-history__item--update::before { background: #d97706; }\n.tempest-admin-history__item--delete::before { background: #dc2626; }\n\n.tempest-admin-history__head {\n display: flex;\n gap: 0.75rem;\n align-items: baseline;\n flex-wrap: wrap;\n}\n\n.tempest-admin-history__action {\n font-weight: 600;\n text-transform: uppercase;\n font-size: 0.75rem;\n letter-spacing: 0.04em;\n}\n\n.tempest-admin-history__meta {\n color: var(--tempest-fg-soft);\n font-size: 0.85rem;\n}\n\n.tempest-admin-history__changes {\n width: 100%;\n border-collapse: collapse;\n margin-top: 0.5rem;\n font-size: 0.85rem;\n}\n\n.tempest-admin-history__changes th,\n.tempest-admin-history__changes td {\n text-align: left;\n padding: 0.25rem 0.5rem;\n border-bottom: 1px solid var(--tempest-border);\n vertical-align: top;\n word-break: break-word;\n}\n\n.tempest-admin-history__changes th {\n color: var(--tempest-fg-soft);\n font-weight: 600;\n}\n\n.tempest-admin-history__empty {\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-ac {\n position: relative;\n}\n\n.tempest-admin-ac__search {\n width: 100%;\n}\n\n.tempest-admin-ac__results {\n list-style: none;\n margin: 0.25rem 0 0;\n padding: 0;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius, 6px);\n max-height: 12rem;\n overflow-y: auto;\n background: var(--tempest-surface);\n}\n\n.tempest-admin-ac__results:empty {\n display: none;\n}\n\n.tempest-admin-ac__option {\n display: block;\n width: 100%;\n text-align: left;\n padding: 0.4rem 0.6rem;\n background: none;\n border: 0;\n cursor: pointer;\n color: inherit;\n font: inherit;\n}\n\n.tempest-admin-ac__option:hover,\n.tempest-admin-ac__option:focus {\n background: var(--tempest-accent-soft, rgba(0, 0, 0, 0.06));\n}\n\n.tempest-admin-ac__empty {\n padding: 0.4rem 0.6rem;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-inline {\n margin-top: 2rem;\n}\n\n.tempest-admin-inline__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n margin-bottom: 0.5rem;\n}\n\n.tempest-admin-inline__header h2 {\n font-size: 1rem;\n margin: 0;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-inline__count {\n font-weight: 400;\n}\n\n.tempest-admin-inline__scroll {\n overflow-x: auto;\n}\n\n.tempest-admin-inline__table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.9rem;\n}\n\n.tempest-admin-inline__table th,\n.tempest-admin-inline__table td {\n text-align: left;\n padding: 0.4rem 0.6rem;\n border-bottom: 1px solid var(--tempest-border);\n white-space: nowrap;\n}\n\n.tempest-admin-inline__table th {\n color: var(--tempest-fg-soft);\n font-weight: 600;\n}\n\n.tempest-admin-inline__empty,\n.tempest-admin-inline__more {\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));\n gap: 1rem;\n margin: 1rem 0 2rem;\n}\n\n.tempest-admin-card {\n display: flex;\n flex-direction: column;\n gap: 0.35rem;\n padding: 1rem 1.1rem;\n border: 1px solid var(--tempest-border);\n border-radius: var(--tempest-radius, 8px);\n background: var(--tempest-surface);\n}\n\n.tempest-admin-card__label {\n font-size: 0.8rem;\n color: var(--tempest-fg-soft);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n}\n\n.tempest-admin-card__value {\n font-size: 1.7rem;\n font-weight: 700;\n line-height: 1.1;\n}\n\n.tempest-admin-card__value small {\n font-size: 0.9rem;\n font-weight: 400;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-card__trend {\n font-size: 0.9rem;\n font-weight: 600;\n}\n\n.tempest-admin-card__trend small {\n font-weight: 400;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-card__trend--up { color: #16a34a; }\n.tempest-admin-card__trend--down { color: #dc2626; }\n.tempest-admin-card__trend--flat { color: var(--tempest-fg-soft); }\n\n.tempest-admin-card__parts {\n list-style: none;\n margin: 0.25rem 0 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: 0.3rem;\n}\n\n.tempest-admin-card__parts li {\n display: grid;\n grid-template-columns: 6rem 1fr auto;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.85rem;\n}\n\n.tempest-admin-card__part-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-card__part-bar {\n display: block;\n height: 0.5rem;\n border-radius: 999px;\n background: var(--tempest-border);\n overflow: hidden;\n}\n\n.tempest-admin-card__part-bar span {\n display: block;\n height: 100%;\n background: var(--tempest-accent, #2563eb);\n}\n\n.tempest-admin-card__help {\n font-size: 0.8rem;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-import__result {\n margin: 1rem 0;\n}\n\n.tempest-admin-import__ok {\n color: #16a34a;\n font-weight: 600;\n}\n\n.tempest-admin-import__failed {\n color: #d97706;\n font-weight: 600;\n}\n\n.tempest-admin-import__errors {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.85rem;\n}\n\n.tempest-admin-import__errors th,\n.tempest-admin-import__errors td {\n text-align: left;\n padding: 0.3rem 0.5rem;\n border-bottom: 1px solid var(--tempest-border);\n vertical-align: top;\n}\n\n.tempest-admin-import__form label {\n display: block;\n margin: 1rem 0 0.5rem;\n}\n\n.tempest-admin-lenses {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n margin: 0.5rem 0 1rem;\n border-bottom: 1px solid var(--tempest-border);\n padding-bottom: 0.5rem;\n}\n\n.tempest-admin-lens {\n padding: 0.3rem 0.7rem;\n border-radius: 999px;\n border: 1px solid var(--tempest-border);\n color: var(--tempest-fg-soft);\n text-decoration: none;\n font-size: 0.85rem;\n}\n\n.tempest-admin-lens:hover {\n color: inherit;\n}\n\n.tempest-admin-lens--active {\n background: var(--tempest-accent, #2563eb);\n border-color: var(--tempest-accent, #2563eb);\n color: #fff;\n}\n\n.tempest-admin-footer {\n position: relative;\n z-index: 20;\n text-align: center;\n padding: 2rem 0;\n color: var(--tempest-fg-soft);\n}\n\n/* List toolbar: search/filters on the left, actions (export) on the right. */\n.tempest-admin-list__toolbar {\n display: flex;\n flex-wrap: wrap;\n gap: 0.75rem 1rem;\n align-items: flex-end;\n justify-content: space-between;\n margin-bottom: 1rem;\n}\n\n.tempest-admin-list__actions {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n}\n\n.tempest-admin-list__actions a {\n display: inline-block;\n padding: 0.45rem 0.8rem;\n border: 1px solid var(--tempest-accent);\n border-radius: var(--tempest-radius);\n background: #fff;\n white-space: nowrap;\n}\n\n.tempest-admin-list__actions a:hover {\n background: #eff6ff;\n text-decoration: none;\n}\n\n/* Dashboard: system-metric stat cards + model cards. */\n.tempest-admin-stats {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));\n gap: 1rem;\n margin: 1.5rem 0;\n}\n\n.tempest-admin-stat {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n background: #fff;\n border-radius: var(--tempest-radius);\n padding: 1rem 1.25rem;\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-stat__label {\n font-size: 0.8rem;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-stat__value {\n font-size: 1.6rem;\n font-weight: 700;\n}\n\n.tempest-admin-stat__sub {\n font-size: 0.8rem;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-models {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));\n gap: 1rem;\n margin-top: 1rem;\n}\n\n.tempest-admin-model-card {\n background: #fff;\n border-radius: var(--tempest-radius);\n padding: 1rem 1.25rem;\n box-shadow: var(--tempest-shadow);\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.tempest-admin-model-card__head {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: 0.5rem;\n}\n\n.tempest-admin-model-card__head h2 {\n margin: 0;\n font-size: 1.05rem;\n}\n\n.tempest-admin-model-card__count {\n font-weight: 700;\n color: var(--tempest-accent);\n}\n\n.tempest-admin-model-card__actions {\n display: flex;\n gap: 1rem;\n}\n\n/* Bulk-action bar above the list table. */\n.tempest-admin-bulk {\n margin: 0;\n}\n\n.tempest-admin-bulk__bar {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n margin-bottom: 0.75rem;\n}\n\n.tempest-admin-list__check {\n width: 1%;\n white-space: nowrap;\n text-align: center;\n}\n\n.tempest-admin-list__check input {\n width: auto;\n}\n\n/* Horizontal-scroll wrapper so wide tables never break the layout. */\n.tempest-admin-table-wrap {\n width: 100%;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n border-radius: var(--tempest-radius);\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-table-wrap .tempest-admin-list__table,\n.tempest-admin-table-wrap .tempest-admin-dashboard__table {\n box-shadow: none;\n}\n\n/* Sortable column headers. */\n.tempest-admin-list__table th a.tempest-sort {\n color: inherit;\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n white-space: nowrap;\n}\n\n.tempest-admin-list__table th a.tempest-sort:hover {\n color: var(--tempest-accent);\n text-decoration: none;\n}\n\n.tempest-sort__arrow {\n font-size: 0.75em;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-sort--active .tempest-sort__arrow {\n color: var(--tempest-accent);\n}\n\n/* Detail header actions (back / edit / delete). */\n.tempest-admin-detail__header {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem 1rem;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 1rem;\n}\n\n.tempest-admin-detail__actions {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: center;\n}\n\n.tempest-admin-detail__delete {\n margin: 0;\n}\n\n.tempest-admin-btn {\n display: inline-block;\n padding: 0.45rem 0.8rem;\n border: 1px solid var(--tempest-accent);\n border-radius: var(--tempest-radius);\n background: #fff;\n}\n\n.tempest-admin-btn:hover {\n background: #eff6ff;\n text-decoration: none;\n}\n\n.tempest-admin-btn--danger {\n background: var(--tempest-danger);\n}\n\n.tempest-admin-btn--danger:hover {\n background: #991b1b;\n}\n\n/* Scoped under __actions so it beats \\`.tempest-admin-list__actions a\\`\n (otherwise the white action-link background won + white text = invisible). */\n.tempest-admin-list__actions a.tempest-admin-list__new,\na.tempest-admin-list__new {\n background: var(--tempest-accent);\n color: #fff;\n border-color: var(--tempest-accent);\n}\n\n.tempest-admin-list__actions a.tempest-admin-list__new:hover,\na.tempest-admin-list__new:hover {\n background: var(--tempest-accent-hover);\n color: #fff;\n}\n\n/* Create / edit form. */\n.tempest-admin-form__form {\n display: grid;\n gap: 1rem;\n max-width: 640px;\n background: #fff;\n padding: 1.5rem;\n border-radius: var(--tempest-radius);\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-form__field {\n display: flex;\n flex-direction: column;\n gap: 0.3rem;\n}\n\n.tempest-admin-form__field > label {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.tempest-admin-form__field > label > span {\n font-weight: 600;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-form__field input,\n.tempest-admin-form__field select,\n.tempest-admin-form__field textarea {\n width: 100%;\n}\n\n.tempest-admin-form__json {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.85rem;\n white-space: pre;\n overflow-wrap: normal;\n overflow-x: auto;\n}\n\n.tempest-admin-form__check {\n flex-direction: row !important;\n align-items: center;\n gap: 0.5rem;\n}\n\n.tempest-admin-form__check input {\n width: auto;\n}\n\n.tempest-admin-form__field--error input,\n.tempest-admin-form__field--error select,\n.tempest-admin-form__field--error textarea {\n border-color: var(--tempest-danger);\n}\n\n.tempest-admin-form__field-error {\n color: var(--tempest-danger);\n}\n\n.tempest-admin-form__error {\n background: #fef2f2;\n color: var(--tempest-danger);\n padding: 0.75rem 1rem;\n border-radius: var(--tempest-radius);\n margin-bottom: 1rem;\n}\n\n.tempest-admin-form__actions {\n display: flex;\n gap: 1rem;\n align-items: center;\n}\n\n/* ---- Responsive ---- */\n\n/* Tablet and below. */\n@media (max-width: 1023px) {\n .tempest-admin-main {\n margin: 1.25rem auto;\n padding: 0 1rem;\n }\n}\n\n/* Mobile (<= 430px and small phones). */\n@media (max-width: 600px) {\n .tempest-admin-header {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n }\n\n .tempest-admin-header__nav {\n width: 100%;\n flex-wrap: wrap;\n gap: 0.5rem 0.75rem;\n }\n\n .tempest-admin-main {\n margin: 1rem auto;\n padding: 0 0.75rem;\n }\n\n .tempest-admin-list__header {\n flex-direction: column;\n gap: 0.25rem;\n align-items: flex-start;\n }\n\n .tempest-admin-list__toolbar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .tempest-admin-list__filters {\n flex-direction: column;\n align-items: stretch;\n }\n\n .tempest-admin-list__filters input,\n .tempest-admin-list__filters select,\n .tempest-admin-list__filters button {\n width: 100%;\n }\n\n .tempest-admin-list__actions {\n justify-content: stretch;\n }\n\n .tempest-admin-list__actions a {\n flex: 1;\n text-align: center;\n }\n\n /* Stack the detail grid into single-column rows. */\n .tempest-admin-detail__fields {\n grid-template-columns: 1fr;\n gap: 0.15rem 0;\n padding: 1rem;\n }\n\n /* The logs table becomes stacked cards. Horizontal scroll is fine for a\n list view you skim, but the logs table's fourth column carries the\n message, the request context and the traceback — everything you came to\n read — so at this width it sat off-screen behind a sideways drag, and an\n opened traceback showed up only as a tall blank row. Labels come from\n each cell's data-label, so the header can be dropped without losing\n which value is which. Scoped to this table: the other list views keep\n the scroll treatment. */\n .tempest-admin-logs .tempest-admin-table-wrap {\n overflow-x: visible;\n }\n\n .tempest-admin-logs__table thead {\n display: none;\n }\n\n .tempest-admin-logs__table,\n .tempest-admin-logs__table tbody,\n .tempest-admin-logs__table tr,\n .tempest-admin-logs__table td {\n display: block;\n width: 100%;\n }\n\n .tempest-admin-logs__table tr {\n padding: 0.85rem 0.9rem;\n border-bottom: 1px solid #e2e8f0;\n }\n\n .tempest-admin-logs__table tr:last-child {\n border-bottom: none;\n }\n\n .tempest-admin-logs__table td {\n padding: 0.1rem 0;\n border: none;\n }\n\n .tempest-admin-logs__table td[data-label]::before {\n content: attr(data-label);\n display: block;\n color: var(--tempest-fg-soft);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n font-size: 0.64rem;\n font-weight: 600;\n }\n\n /* The message is the card's body, not another labelled field. */\n .tempest-admin-logs__table td.tempest-admin-logs__msg {\n margin-top: 0.5rem;\n }\n\n .tempest-admin-logs__table td.tempest-admin-logs__msg::before {\n display: none;\n }\n\n .tempest-admin-logs__logger {\n white-space: normal;\n overflow-wrap: anywhere;\n }\n\n .tempest-admin-detail__fields dt {\n margin-top: 0.75rem;\n }\n\n .tempest-admin-detail__fields dd {\n padding-bottom: 0.5rem;\n border-bottom: 1px solid #e2e8f0;\n }\n\n .tempest-admin-login {\n margin: 1.5rem auto;\n padding: 1.5rem;\n }\n\n .tempest-admin-form__form {\n padding: 1rem;\n }\n\n .tempest-admin-form__actions {\n flex-direction: column-reverse;\n align-items: stretch;\n }\n\n .tempest-admin-form__actions button,\n .tempest-admin-form__actions .tempest-admin-form__cancel {\n width: 100%;\n text-align: center;\n }\n\n .tempest-admin-bulk__bar {\n flex-direction: column;\n align-items: stretch;\n }\n\n .tempest-admin-bulk__bar select,\n .tempest-admin-bulk__bar button {\n width: 100%;\n }\n}\n\n/* ---- Application logs page ---- */\n.tempest-log-badge {\n display: inline-block;\n padding: 0.1rem 0.5rem;\n border-radius: 999px;\n font-size: 0.72rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.03em;\n background: #e2e8f0;\n color: #334155;\n}\n\n.tempest-log-badge--debug {\n background: #e2e8f0;\n color: #475569;\n}\n\n.tempest-log-badge--info {\n background: #dbeafe;\n color: #1e40af;\n}\n\n.tempest-log-badge--warning {\n background: #fef3c7;\n color: #92400e;\n}\n\n.tempest-log-badge--error {\n background: #fee2e2;\n color: #991b1b;\n}\n\n.tempest-log-badge--critical {\n background: #7f1d1d;\n color: #fff;\n}\n\n.tempest-admin-logs__ts {\n white-space: nowrap;\n font-variant-numeric: tabular-nums;\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-logs__logger {\n color: var(--tempest-fg-soft);\n white-space: nowrap;\n}\n\n.tempest-admin-logs__msg {\n word-break: break-word;\n}\n\n.tempest-admin-logs__empty {\n color: var(--tempest-fg-soft);\n background: #fff;\n padding: 1.5rem;\n border-radius: var(--tempest-radius);\n box-shadow: var(--tempest-shadow);\n}\n\n.tempest-admin-logs__actions {\n display: flex;\n gap: 0.5rem;\n flex-wrap: wrap;\n}\n\n.tempest-admin-logs__export {\n display: inline-block;\n padding: 0.35rem 0.75rem;\n border-radius: var(--tempest-radius);\n border: 1px solid #cbd5e1;\n background: #fff;\n color: #334155;\n font-size: 0.82rem;\n font-weight: 600;\n text-decoration: none;\n}\n\n.tempest-admin-logs__export:hover {\n background: #f1f5f9;\n}\n\n.tempest-admin-logs__meta {\n list-style: none;\n margin: 0.4rem 0 0;\n padding: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 0.3rem 0.75rem;\n font-size: 0.75rem;\n}\n\n/* The gap is layout only — it does not survive a copy, and an operator copying a\n row to paste into an issue would get \"status_code404\". The template keeps a\n real space between the label and the value for that; this widens the visual\n separation on top of it, since an uppercase micro-label sitting against a\n monospace value reads as one token. */\n.tempest-admin-logs__meta li {\n display: inline-flex;\n align-items: baseline;\n gap: 0.4rem;\n}\n\n.tempest-admin-logs__meta span {\n color: var(--tempest-fg-soft);\n text-transform: uppercase;\n letter-spacing: 0.03em;\n font-size: 0.68rem;\n}\n\n.tempest-admin-logs__meta code {\n word-break: break-all;\n}\n\n/* Collapsed by default so a page full of 500s stays scannable; details/summary\n keeps that working with no JavaScript, which the admin does not ship. */\n.tempest-admin-logs__trace {\n margin-top: 0.5rem;\n}\n\n/* The summary carries the record's own message, so the whole item is the click\n target instead of a separate link. It must therefore read as body text, not\n as a control — the affordance is the marker plus the hint chip. */\n.tempest-admin-logs__trace summary {\n cursor: pointer;\n list-style: none;\n display: block;\n}\n\n.tempest-admin-logs__trace summary::-webkit-details-marker {\n display: none;\n}\n\n.tempest-admin-logs__msg-text::before {\n content: \"▸\";\n display: inline-block;\n width: 0.9rem;\n color: #991b1b;\n font-size: 0.7rem;\n}\n\n.tempest-admin-logs__trace[open] .tempest-admin-logs__msg-text::before {\n content: \"▾\";\n}\n\n.tempest-admin-logs__trace-hint {\n display: inline-block;\n margin-top: 0.3rem;\n font-size: 0.68rem;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n color: #991b1b;\n}\n\n.tempest-admin-logs__trace[open] .tempest-admin-logs__trace-hint {\n opacity: 0.55;\n}\n\n/* Lines wrap instead of extending. A <pre> is sized by its longest line and it\n sits in a table cell, which sizes to content, so \\`overflow-x\\` on the <pre>\n cannot shrink it: the table grew past its scroll container (measured 1364px\n against a 1012px wrap) and the trace could only be read by dragging the table\n sideways. Wrapping keeps the table at its container width. It costs the\n alignment of the caret markers on screen; the markdown export carries the\n exact unwrapped text for real analysis. */\n.tempest-admin-logs__trace pre {\n margin: 0.5rem 0 0;\n padding: 0.75rem;\n max-height: 24rem;\n overflow-y: auto;\n background: #0f172a;\n color: #e2e8f0;\n border-radius: var(--tempest-radius);\n font-size: 0.74rem;\n line-height: 1.45;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n -webkit-user-select: all;\n user-select: all;\n}\n\n.tempest-admin-logs__note {\n color: var(--tempest-fg-soft);\n font-size: 0.8rem;\n margin-top: 0.75rem;\n}\n\n/* ---- Sidebar off-canvas on tablet/mobile, burger reveals it ---- */\n@media (max-width: 768px) {\n .tempest-admin-burger {\n display: flex;\n }\n\n .tempest-admin-sidebar {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n z-index: 50;\n width: 240px;\n flex-basis: 240px;\n transform: translateX(-100%);\n transition: transform 0.2s ease;\n overflow-y: auto;\n box-shadow: 0 0 24px rgba(15, 23, 42, 0.35);\n }\n\n .tempest-admin-navtoggle:checked ~ .tempest-admin-layout .tempest-admin-sidebar {\n transform: translateX(0);\n }\n\n .tempest-admin-navtoggle:checked ~ .tempest-admin-layout .tempest-admin-scrim {\n display: block;\n position: fixed;\n inset: 0;\n z-index: 40;\n background: rgba(15, 23, 42, 0.45);\n }\n}\n\n/* ---- Desktop: sidebar overlays the header + footer ---- */\n@media (min-width: 769px) {\n .tempest-admin-sidebar {\n position: fixed;\n top: 0;\n left: 0;\n bottom: 0;\n z-index: 100; /* above header/footer (z-index: 20) */\n overflow-y: auto;\n /* Clear the header bar so the first nav link sits below it. */\n padding-top: 3.75rem;\n }\n\n /* The fixed sidebar leaves the flex flow, so reserve its gutter on\n the layout row to keep the main content from sliding underneath. */\n .tempest-admin-layout {\n padding-left: 220px;\n }\n}\n\n/* Flash banner shown after a custom bulk action runs. */\n.tempest-admin-flash {\n margin: 0 0 1rem;\n padding: 0.7rem 1rem;\n border-radius: var(--tempest-radius);\n border-left: 4px solid var(--tempest-accent);\n background: var(--tempest-bg);\n color: var(--tempest-fg);\n}\n\n.tempest-admin-flash--error {\n border-left-color: var(--tempest-danger);\n}\n\n.tempest-admin-flash--warning {\n border-left-color: #d97706;\n}\n\n/* Task panel — declared schedule and persisted runs. */\n.tempest-admin-tasks__scope {\n margin: 0 0 1.25rem;\n color: var(--tempest-fg-soft);\n font-size: 0.9rem;\n}\n\n.tempest-admin-tasks__heading {\n margin: 1.75rem 0 0.75rem;\n font-size: 1.05rem;\n}\n\n.tempest-admin-tasks__empty {\n padding: 1rem;\n border: 1px dashed var(--tempest-border);\n border-radius: var(--tempest-radius);\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-tasks__trigger + .tempest-admin-tasks__trigger {\n margin-top: 0.35rem;\n}\n\n.tempest-admin-tasks__offset {\n color: var(--tempest-fg-soft);\n font-size: 0.85rem;\n white-space: nowrap;\n}\n\n.tempest-admin-tasks__status {\n display: inline-block;\n padding: 0.1rem 0.5rem;\n border-radius: 999px;\n font-size: 0.8rem;\n border: 1px solid var(--tempest-border);\n color: var(--tempest-fg-soft);\n}\n\n.tempest-admin-tasks__status--running {\n border-color: var(--tempest-accent);\n color: var(--tempest-accent);\n}\n\n.tempest-admin-tasks__status--done {\n border-color: #15803d;\n color: #15803d;\n}\n\n.tempest-admin-tasks__status--failed {\n border-color: var(--tempest-danger);\n color: var(--tempest-danger);\n}\n\n/* Cancelled is terminal but not a failure, so it stays neutral: an\n operator scanning for red should find only what went wrong. */\n.tempest-admin-tasks__status--cancelled {\n border-color: var(--tempest-border);\n color: var(--tempest-fg-soft);\n}\n\n/* The track uses the border token, not a row background: the list stripes\n rows with --tempest-bg-row-alt, so a track painted in it vanished on\n every other row — an empty progress cell reads as \"no data\", not as 0%. */\n.tempest-admin-tasks__bar {\n display: inline-block;\n width: 90px;\n height: 8px;\n border-radius: 999px;\n background: var(--tempest-border);\n overflow: hidden;\n vertical-align: middle;\n}\n\n.tempest-admin-tasks__bar--wide {\n display: block;\n width: 100%;\n height: 12px;\n margin: 0 0 1.25rem;\n}\n\n.tempest-admin-tasks__bar-fill {\n display: block;\n height: 100%;\n background: var(--tempest-accent);\n}\n\n.tempest-admin-tasks__facts {\n display: grid;\n grid-template-columns: max-content 1fr;\n gap: 0.4rem 1.25rem;\n margin: 0 0 1.5rem;\n}\n\n.tempest-admin-tasks__facts dt {\n color: var(--tempest-fg-soft);\n font-size: 0.85rem;\n}\n\n.tempest-admin-tasks__facts dd {\n margin: 0;\n}\n\n.tempest-admin-tasks__error pre {\n padding: 0.85rem;\n border-radius: var(--tempest-radius);\n border-left: 4px solid var(--tempest-danger);\n background: var(--tempest-bg-row-alt);\n overflow-x: auto;\n white-space: pre-wrap;\n}\n\n.tempest-admin-tasks__cancel {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n flex-wrap: wrap;\n margin: 0 0 1.5rem;\n}\n\n.tempest-admin-tasks__hint {\n color: var(--tempest-fg-soft);\n font-size: 0.85rem;\n}\n\n@media (max-width: 640px) {\n .tempest-admin-tasks__facts {\n grid-template-columns: 1fr;\n gap: 0.15rem;\n }\n\n .tempest-admin-tasks__facts dd {\n margin: 0 0 0.6rem;\n }\n}\n`;\n","/**\n * Typed theming for the server-rendered admin panel, mirroring `admin.theme`.\n *\n * The bundled stylesheet is driven entirely by CSS custom properties declared\n * on `:root`. An {@link AdminTheme} overrides those properties — plus the logo,\n * favicon, font and footer — through typed, documented fields instead of\n * forking the stylesheet. The values are injected as a `<style>` block after\n * the stylesheet (so they win), which means there is no CSS file to maintain on\n * the project side and every knob is discoverable in the editor.\n *\n * For anything the fields do not cover, point `customCssUrl` at your own\n * stylesheet — it is linked last, so it overrides everything, including this.\n */\n\n/**\n * Characters that would let a theme value break out of the injected `<style>`\n * block or an HTML attribute. Theme values are developer-set, not end-user\n * input, but rejecting these keeps a careless value from silently producing\n * broken — or injectable — markup.\n */\nconst FORBIDDEN_CHARS: readonly string[] = [\"<\", \">\", \"{\", \"}\", '\"'];\n\n/**\n * Appearance overrides for the admin panel. Every field is optional and\n * defaults to the stock look, so `{}` is a no-op.\n */\nexport interface AdminTheme {\n /** Primary accent — links, primary buttons, active sidebar item. Default `#2563eb`. */\n accent?: string;\n /** Hover/active shade of {@link AdminTheme.accent}. Default `#1d4ed8`. */\n accentHover?: string;\n /** Color for destructive actions and error messages. Default `#b91c1c`. */\n danger?: string;\n /** Background of the top header band. Default `#0f172a`. */\n headerBg?: string;\n /** Background of the left sidebar. Falls back to `headerBg` so the chrome reads as one surface. */\n sidebarBg?: string;\n /** Main content background. Omitted uses the mode default (light grey, or near-black in dark mode). */\n pageBg?: string;\n /** Border radius for buttons, inputs, cards and tables. Default `6px`. */\n radius?: string;\n /** CSS `font-family` for the whole panel. Omitted keeps the system stack. */\n fontFamily?: string;\n /** URL of an image shown in the header instead of the brand text. */\n logoUrl?: string;\n /** `alt` text for the logo image. Default `Logo`. */\n logoAlt?: string;\n /** URL of the browser-tab favicon. */\n faviconUrl?: string;\n /** Text shown in the page footer. Default `Powered by tempest-express-sdk`. */\n footerText?: string;\n /** Switch the content surfaces to a dark palette (the chrome is already dark). */\n darkMode?: boolean;\n /** URL of an extra stylesheet linked **after** the theme, so it overrides everything. */\n customCssUrl?: string;\n}\n\n/** An {@link AdminTheme} with every default filled in. */\nexport interface ResolvedAdminTheme {\n accent: string;\n accentHover: string;\n danger: string;\n headerBg: string;\n sidebarBg: string;\n pageBg: string | null;\n radius: string;\n fontFamily: string | null;\n logoUrl: string | null;\n logoAlt: string;\n faviconUrl: string | null;\n footerText: string;\n darkMode: boolean;\n customCssUrl: string | null;\n}\n\n/**\n * Reject a theme value that would corrupt the injected markup.\n *\n * @param field - The theme field name, for the error message.\n * @param value - The value to check.\n * @throws Error When the value contains `<`, `>`, `{`, `}` or `\"`.\n */\nfunction assertSafe(field: string, value: string | undefined): void {\n if (value === undefined) return;\n const bad = FORBIDDEN_CHARS.filter((char) => value.includes(char));\n if (bad.length > 0) {\n throw new Error(\n `AdminTheme.${field} contains forbidden character(s) ${bad.join(\" \")}; ` +\n `these would break the injected <style>/HTML. Got: ${value}`,\n );\n }\n}\n\n/**\n * Fill a theme with its defaults, validating every string field.\n *\n * @param theme - The partial theme (or nothing, for the stock look).\n * @returns The theme with every field resolved.\n * @throws Error When a string field contains a character that would break the markup.\n */\nexport function resolveAdminTheme(theme: AdminTheme = {}): ResolvedAdminTheme {\n for (const [field, value] of Object.entries(theme)) {\n if (typeof value === \"string\") assertSafe(field, value);\n }\n const headerBg = theme.headerBg ?? \"#0f172a\";\n return {\n accent: theme.accent ?? \"#2563eb\",\n accentHover: theme.accentHover ?? \"#1d4ed8\",\n danger: theme.danger ?? \"#b91c1c\",\n headerBg,\n sidebarBg: theme.sidebarBg ?? headerBg,\n pageBg: theme.pageBg ?? null,\n radius: theme.radius ?? \"6px\",\n fontFamily: theme.fontFamily ?? null,\n logoUrl: theme.logoUrl ?? null,\n logoAlt: theme.logoAlt ?? \"Logo\",\n faviconUrl: theme.faviconUrl ?? null,\n footerText: theme.footerText ?? \"Powered by tempest-express-sdk\",\n darkMode: theme.darkMode ?? false,\n customCssUrl: theme.customCssUrl ?? null,\n };\n}\n\n/**\n * Render the `<style>` body for a resolved theme.\n *\n * Dark mode only overrides the content-area surfaces — the header and sidebar\n * are already dark via `--tempest-bg` — and is skipped entirely when the\n * project pinned its own `pageBg`, since an explicit value always wins.\n *\n * @param theme - The resolved theme.\n * @returns CSS text, ready to inject verbatim inside a `<style>` element.\n */\nexport function adminThemeCss(theme: ResolvedAdminTheme): string {\n const variables: Record<string, string> = {\n \"--tempest-accent\": theme.accent,\n \"--tempest-accent-hover\": theme.accentHover,\n \"--tempest-danger\": theme.danger,\n \"--tempest-bg\": theme.headerBg,\n \"--tempest-bg-soft\": theme.sidebarBg,\n \"--tempest-radius\": theme.radius,\n };\n if (theme.fontFamily !== null) variables[\"--tempest-font\"] = theme.fontFamily;\n if (theme.pageBg !== null) variables[\"--tempest-page-bg\"] = theme.pageBg;\n\n const rootLines = Object.entries(variables)\n .map(([name, value]) => ` ${name}: ${value};`)\n .join(\"\\n\");\n const blocks: string[] = [`:root {\\n${rootLines}\\n}`];\n\n if (theme.darkMode && theme.pageBg === null) {\n blocks.push(\n [\n \":root {\",\n \" --tempest-page-bg: #0b1120;\",\n \" --tempest-bg-row: #1e293b;\",\n \" --tempest-bg-row-alt: #172033;\",\n \" --tempest-fg: #e2e8f0;\",\n \" --tempest-fg-soft: #94a3b8;\",\n \"}\",\n \"body { color: var(--tempest-fg); }\",\n \"input, select, textarea {\",\n \" background: #1e293b;\",\n \" color: var(--tempest-fg);\",\n \" border-color: #334155;\",\n \"}\",\n ].join(\"\\n\"),\n );\n }\n\n if (theme.fontFamily !== null) {\n blocks.push(\"body { font-family: var(--tempest-font); }\");\n }\n\n return blocks.join(\"\\n\");\n}\n","/**\n * HTML rendering for the admin panel — the analog of the FastAPI SDK's jinja\n * templates, written as plain typed functions.\n *\n * There is no template engine and no external asset: every page is a string\n * built from a view model the router prepares, and the only stylesheet is the\n * one this package serves. That keeps the panel dependency-free (a template\n * engine would be a runtime dependency every consumer inherits) and keeps the\n * markup type-checked against the data that fills it.\n *\n * Every value interpolated into markup goes through {@link escapeHtml}.\n */\n\nimport type { AdminFormField } from \"@/admin/forms\";\nimport type { AdminSession } from \"@/admin/session\";\nimport type { AdminSite } from \"@/admin/site\";\nimport { type ResolvedAdminTheme, adminThemeCss } from \"@/admin/theme\";\n\n/**\n * Escape a value for safe interpolation into HTML text or an attribute.\n *\n * @param value - The value to escape.\n * @returns The escaped text.\n */\nexport function escapeHtml(value: unknown): string {\n return String(value ?? \"\")\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\n}\n\n/** One entry in the sidebar's model list. */\nexport interface AdminNavEntry {\n /** Display label. */\n label: string;\n /** Absolute URL of the model's list view. */\n url: string;\n}\n\n/** A banner shown above the page content. */\nexport interface AdminMessage {\n /** Message text. */\n text: string;\n /** Severity, driving the banner color: `success`, `error` or `warning`. */\n level: \"success\" | \"error\" | \"warning\";\n}\n\n/** Everything the chrome needs, shared by every page. */\nexport interface AdminRenderContext {\n /** The registered site (branding + models). */\n site: AdminSite;\n /** The site's theme, with defaults resolved. */\n theme: ResolvedAdminTheme;\n /** The router's mount prefix, without a trailing slash. */\n prefix: string;\n /** The active session, or `null` on the login and MFA pages. */\n session: AdminSession | null;\n /** The current request path, used to highlight the active sidebar item. */\n currentPath: string;\n /** Sidebar entries, one per registered model. */\n navModels: AdminNavEntry[];\n /** Banners rendered above the content. */\n messages: AdminMessage[];\n}\n\n/**\n * Wrap page content in the panel chrome: header, sidebar, footer and theme.\n *\n * The sidebar is off-canvas below 768px, opened by a checkbox the burger label\n * toggles — pure CSS, so the panel needs no JavaScript to be navigable.\n *\n * @param context - The shared chrome data.\n * @param title - The page `<title>`.\n * @param body - The already-escaped content markup.\n * @returns A complete HTML document.\n */\nexport function renderLayout(\n context: AdminRenderContext,\n title: string,\n body: string,\n): string {\n const { site, theme, prefix, session, currentPath, navModels, messages } = context;\n const authed = session !== null;\n const indexUrl = `${prefix}/`;\n\n const navLink = (url: string, label: string, active: boolean): string =>\n `<a href=\"${escapeHtml(url)}\" class=\"tempest-admin-sidebar__link${\n active ? \" tempest-admin-sidebar__link--active\" : \"\"\n }\">${escapeHtml(label)}</a>`;\n\n const sidebar = authed\n ? `<label for=\"tempest-nav-toggle\" class=\"tempest-admin-scrim\" aria-hidden=\"true\"></label>\n <aside class=\"tempest-admin-sidebar\">\n <nav class=\"tempest-admin-sidebar__nav\" aria-label=\"Admin navigation\">\n ${navLink(indexUrl, \"Dashboard\", currentPath === indexUrl)}\n ${\n navModels.length > 0\n ? `<span class=\"tempest-admin-sidebar__heading\">Models</span>${navModels\n .map((entry) =>\n navLink(entry.url, entry.label, currentPath.startsWith(entry.url)),\n )\n .join(\"\")}`\n : \"\"\n }\n </nav>\n </aside>`\n : \"\";\n\n const brand =\n theme.logoUrl !== null\n ? `<img src=\"${escapeHtml(theme.logoUrl)}\" alt=\"${escapeHtml(theme.logoAlt)}\" class=\"tempest-admin-header__logo\">`\n : escapeHtml(site.brandText());\n\n const headerNav = authed\n ? `<nav class=\"tempest-admin-header__nav\">\n <span class=\"tempest-admin-header__user\">${escapeHtml(session.displayName)}</span>\n ${site.siteUrl !== null ? `<a href=\"${escapeHtml(site.siteUrl)}\">View site</a>` : \"\"}\n <form method=\"post\" action=\"${escapeHtml(`${prefix}/logout`)}\" class=\"tempest-admin-header__logout\">\n <input type=\"hidden\" name=\"csrf_token\" value=\"${escapeHtml(session.csrfToken)}\">\n <button type=\"submit\">Logout</button>\n </form>\n </nav>`\n : \"\";\n\n const banners =\n messages.length > 0\n ? `<ul class=\"tempest-admin-messages\">${messages\n .map(\n (message) =>\n `<li class=\"tempest-admin-messages__item tempest-admin-messages__item--${escapeHtml(\n message.level,\n )}\">${escapeHtml(message.text)}</li>`,\n )\n .join(\"\")}</ul>`\n : \"\";\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>${escapeHtml(title)}</title>\n ${theme.faviconUrl !== null ? `<link rel=\"icon\" href=\"${escapeHtml(theme.faviconUrl)}\">` : \"\"}\n <link rel=\"stylesheet\" href=\"${escapeHtml(`${prefix}/static/admin.css`)}\">\n <style>${adminThemeCss(theme)}</style>\n ${theme.customCssUrl !== null ? `<link rel=\"stylesheet\" href=\"${escapeHtml(theme.customCssUrl)}\">` : \"\"}\n</head>\n<body>\n ${authed ? '<input type=\"checkbox\" id=\"tempest-nav-toggle\" class=\"tempest-admin-navtoggle\" hidden>' : \"\"}\n <header class=\"tempest-admin-header\">\n <div class=\"tempest-admin-header__left\">\n ${\n authed\n ? `<label for=\"tempest-nav-toggle\" class=\"tempest-admin-burger\" aria-label=\"Toggle navigation\"><span></span><span></span><span></span></label>`\n : \"\"\n }\n <div class=\"tempest-admin-header__brand\"><a href=\"${escapeHtml(indexUrl)}\">${brand}</a></div>\n </div>\n ${headerNav}\n </header>\n <div class=\"tempest-admin-layout\">\n ${sidebar}\n <main class=\"tempest-admin-main\">\n ${banners}\n ${body}\n </main>\n </div>\n <footer class=\"tempest-admin-footer\"><small>${escapeHtml(theme.footerText)}</small></footer>\n</body>\n</html>`;\n}\n\n/**\n * Render the sign-in page.\n *\n * @param context - The shared chrome data (with no session).\n * @param error - An error to show above the form, or `null`.\n * @returns The full page.\n */\nexport function renderLoginPage(\n context: AdminRenderContext,\n error: string | null,\n): string {\n const body = `<section class=\"tempest-admin-login\">\n <h1>Sign in</h1>\n <p>${escapeHtml(context.site.indexSubtitle)}</p>\n ${error !== null ? `<p class=\"tempest-admin-login__error\" role=\"alert\">${escapeHtml(error)}</p>` : \"\"}\n <form method=\"post\" action=\"${escapeHtml(`${context.prefix}/login`)}\" class=\"tempest-admin-login__form\">\n <label><span>Email</span><input type=\"email\" name=\"identifier\" autocomplete=\"username\" required autofocus></label>\n <label><span>Password</span><input type=\"password\" name=\"password\" autocomplete=\"current-password\" required></label>\n <button type=\"submit\">Sign in</button>\n </form>\n</section>`;\n return renderLayout(context, `Sign in · ${context.site.title}`, body);\n}\n\n/**\n * Render the TOTP challenge shown between the password check and the panel.\n *\n * @param context - The shared chrome data (with no completed session).\n * @param error - An error to show above the form, or `null`.\n * @returns The full page.\n */\nexport function renderMfaPage(context: AdminRenderContext, error: string | null): string {\n const body = `<section class=\"tempest-admin-login\">\n <h1>Two-factor code</h1>\n <p>Enter the 6-digit code from your authenticator app.</p>\n ${error !== null ? `<p class=\"tempest-admin-login__error\" role=\"alert\">${escapeHtml(error)}</p>` : \"\"}\n <form method=\"post\" action=\"${escapeHtml(`${context.prefix}/mfa`)}\" class=\"tempest-admin-login__form\">\n <label><span>Code</span><input type=\"text\" name=\"code\" inputmode=\"numeric\" autocomplete=\"one-time-code\" required autofocus></label>\n <button type=\"submit\">Verify</button>\n </form>\n</section>`;\n return renderLayout(context, `Two-factor · ${context.site.title}`, body);\n}\n\n/** One model card on the dashboard. */\nexport interface AdminDashboardCard {\n /** Plural display name. */\n label: string;\n /** Row count, or `null` when counting failed. */\n count: number | null;\n /** URL of the list view. */\n url: string;\n /** URL of the create form, or `null` when creation is disabled. */\n newUrl: string | null;\n}\n\n/** The system metrics panel on the dashboard. */\nexport interface AdminDashboardMetrics {\n /** CPU load as a percentage of available cores. */\n cpuPercent: number;\n /** Memory used, as a percentage. */\n memoryPercent: number;\n /** Memory used, in GB. */\n memoryUsedGb: string;\n /** Memory total, in GB. */\n memoryTotalGb: string;\n}\n\n/**\n * Render the dashboard: one card per registered model plus the optional system\n * metrics panel.\n *\n * @param context - The shared chrome data.\n * @param cards - One entry per registered model.\n * @param metrics - The system metrics panel, or `null` when disabled.\n * @returns The full page.\n */\nexport function renderDashboardPage(\n context: AdminRenderContext,\n cards: AdminDashboardCard[],\n metrics: AdminDashboardMetrics | null,\n): string {\n const metricsPanel =\n metrics === null\n ? \"\"\n : `<div class=\"tempest-admin-stats\" aria-label=\"System metrics\">\n <div class=\"tempest-admin-stat\">\n <span class=\"tempest-admin-stat__label\">CPU</span>\n <span class=\"tempest-admin-stat__value\">${escapeHtml(metrics.cpuPercent)}%</span>\n </div>\n <div class=\"tempest-admin-stat\">\n <span class=\"tempest-admin-stat__label\">Memory</span>\n <span class=\"tempest-admin-stat__value\">${escapeHtml(metrics.memoryPercent)}%</span>\n <span class=\"tempest-admin-stat__sub\">${escapeHtml(metrics.memoryUsedGb)} / ${escapeHtml(metrics.memoryTotalGb)} GB</span>\n </div>\n </div>`;\n\n const models =\n cards.length > 0\n ? `<div class=\"tempest-admin-models\">${cards\n .map(\n (card) => `<article class=\"tempest-admin-model-card\">\n <header class=\"tempest-admin-model-card__head\">\n <h2>${escapeHtml(card.label)}</h2>\n ${card.count !== null ? `<span class=\"tempest-admin-model-card__count\">${escapeHtml(card.count)}</span>` : \"\"}\n </header>\n <div class=\"tempest-admin-model-card__actions\">\n <a href=\"${escapeHtml(card.url)}\">Browse</a>\n ${card.newUrl !== null ? `<a href=\"${escapeHtml(card.newUrl)}\">+ New</a>` : \"\"}\n </div>\n </article>`,\n )\n .join(\"\")}</div>`\n : \"<p>No models registered. Register an <code>AdminModel</code> on the <code>AdminSite</code> to populate this dashboard.</p>\";\n\n const body = `<section class=\"tempest-admin-dashboard\">\n <h1>${escapeHtml(context.site.title)}</h1>\n <p>${escapeHtml(context.site.indexSubtitle)}</p>\n ${metricsPanel}\n ${models}\n</section>`;\n return renderLayout(context, context.site.title, body);\n}\n\n/** A filter control rendered above the list view. */\nexport interface AdminFilterView {\n /** Column key the control filters on. */\n field: string;\n /** Human-readable label. */\n label: string;\n /** Which control to render. */\n kind: \"select\" | \"daterange\" | \"text\";\n /** Current value for `select` and `text` controls. */\n value: string;\n /** Lower bound for a `daterange` control. */\n valueFrom: string;\n /** Upper bound for a `daterange` control. */\n valueTo: string;\n /** Options for a `select` control. */\n options: { value: string; label: string; selected: boolean }[];\n}\n\n/** A clickable column header's sort state. */\nexport interface AdminSortView {\n /** URL that applies (or flips) this column's ordering. */\n url: string;\n /** Whether the list is currently ordered by this column. */\n active: boolean;\n /** Whether the current ordering is ascending. */\n ascending: boolean;\n}\n\n/** The view model the list page renders. */\nexport interface AdminListView {\n /** Plural display name shown as the heading. */\n title: string;\n /** Column keys rendered as table columns. */\n columns: string[];\n /** One entry per row: its identity plus the formatted cells. */\n rows: { identity: string; cells: string[]; url: string }[];\n /** Total matching rows, across all pages. */\n total: number;\n /** Current page number, 1-based. */\n page: number;\n /** Total page count. */\n pages: number;\n /** URL of the previous page, or `null` on the first page. */\n prevUrl: string | null;\n /** URL of the next page, or `null` on the last page. */\n nextUrl: string | null;\n /** Whether a search box is rendered. */\n searchable: boolean;\n /** Current search text. */\n searchValue: string;\n /** Filter controls. */\n filters: AdminFilterView[];\n /** Sort state per column key. */\n sort: Record<string, AdminSortView>;\n /** URL of the create form, or `null` when creation is disabled. */\n newUrl: string | null;\n}\n\n/**\n * Render one filter control.\n *\n * @param filter - The filter view model.\n * @returns The control's markup.\n */\nfunction renderFilter(filter: AdminFilterView): string {\n const name = `filter_${filter.field}`;\n if (filter.kind === \"select\") {\n const options = filter.options\n .map(\n (option) =>\n `<option value=\"${escapeHtml(option.value)}\"${option.selected ? \" selected\" : \"\"}>${escapeHtml(option.label)}</option>`,\n )\n .join(\"\");\n return `<label><span>${escapeHtml(filter.label)}</span><select name=\"${escapeHtml(name)}\"><option value=\"\">— any —</option>${options}</select></label>`;\n }\n if (filter.kind === \"daterange\") {\n return `<label><span>${escapeHtml(filter.label)}</span><span class=\"tempest-admin-list__daterange\">\n <input type=\"date\" name=\"${escapeHtml(`${name}_from`)}\" value=\"${escapeHtml(filter.valueFrom)}\" aria-label=\"${escapeHtml(filter.label)} from\">\n <input type=\"date\" name=\"${escapeHtml(`${name}_to`)}\" value=\"${escapeHtml(filter.valueTo)}\" aria-label=\"${escapeHtml(filter.label)} to\">\n </span></label>`;\n }\n return `<label><span>${escapeHtml(filter.label)}</span><input type=\"text\" name=\"${escapeHtml(name)}\" value=\"${escapeHtml(filter.value)}\"></label>`;\n}\n\n/**\n * Render the paginated list view, with its search box, filters and sortable\n * column headers.\n *\n * @param context - The shared chrome data.\n * @param view - The prepared list view model.\n * @returns The full page.\n */\nexport function renderListPage(context: AdminRenderContext, view: AdminListView): string {\n const headers = view.columns\n .map((column) => {\n const state = view.sort[column];\n if (state === undefined) return `<th>${escapeHtml(column)}</th>`;\n const arrow = state.active ? (state.ascending ? \"▲\" : \"▼\") : \"↕\";\n return `<th><a class=\"tempest-sort${state.active ? \" tempest-sort--active\" : \"\"}\" href=\"${escapeHtml(state.url)}\"><span>${escapeHtml(column)}</span><span class=\"tempest-sort__arrow\" aria-hidden=\"true\">${arrow}</span></a></th>`;\n })\n .join(\"\");\n\n const rows =\n view.rows.length > 0\n ? view.rows\n .map(\n (row) =>\n `<tr>${row.cells.map((cell) => `<td>${escapeHtml(cell)}</td>`).join(\"\")}<td><a href=\"${escapeHtml(row.url)}\">View</a></td></tr>`,\n )\n .join(\"\")\n : `<tr><td colspan=\"${view.columns.length + 1}\">No records.</td></tr>`;\n\n const hasControls = view.searchable || view.filters.length > 0;\n const body = `<section class=\"tempest-admin-list\">\n <header class=\"tempest-admin-list__header\">\n <h1>${escapeHtml(view.title)}</h1>\n <p>${escapeHtml(view.total)} record${view.total === 1 ? \"\" : \"s\"}.</p>\n </header>\n <div class=\"tempest-admin-list__toolbar\">\n <form method=\"get\" class=\"tempest-admin-list__filters\">\n ${view.searchable ? `<input type=\"search\" name=\"q\" value=\"${escapeHtml(view.searchValue)}\" placeholder=\"Search…\" aria-label=\"Search\">` : \"\"}\n ${view.filters.map(renderFilter).join(\"\")}\n ${hasControls ? '<button type=\"submit\">Apply</button>' : \"\"}\n </form>\n <div class=\"tempest-admin-list__actions\">\n ${view.newUrl !== null ? `<a class=\"tempest-admin-list__new\" href=\"${escapeHtml(view.newUrl)}\">+ New</a>` : \"\"}\n </div>\n </div>\n <div class=\"tempest-admin-table-wrap\">\n <table class=\"tempest-admin-list__table\">\n <thead><tr>${headers}<th>Actions</th></tr></thead>\n <tbody>${rows}</tbody>\n </table>\n </div>\n ${\n view.pages > 1\n ? `<nav class=\"tempest-admin-list__pagination\" aria-label=\"Pagination\">\n ${view.prevUrl !== null ? `<a href=\"${escapeHtml(view.prevUrl)}\">← Prev</a>` : \"\"}\n <span>Page ${escapeHtml(view.page)} of ${escapeHtml(view.pages)}</span>\n ${view.nextUrl !== null ? `<a href=\"${escapeHtml(view.nextUrl)}\">Next →</a>` : \"\"}\n </nav>`\n : \"\"\n }\n</section>`;\n return renderLayout(context, `${view.title} · ${context.site.title}`, body);\n}\n\n/** The view model the detail page renders. */\nexport interface AdminDetailView {\n /** Singular display name. */\n title: string;\n /** The row's identity, shown next to the title. */\n identity: string;\n /** One `(label, value)` pair per column. */\n fields: { label: string; value: string }[];\n /** URL of the list view. */\n backUrl: string;\n /** URL of the edit form, or `null` when editing is disabled. */\n editUrl: string | null;\n /** URL the delete form posts to, or `null` when deletion is disabled. */\n deleteUrl: string | null;\n}\n\n/**\n * Render the single-record detail view.\n *\n * @param context - The shared chrome data (with an active session).\n * @param view - The prepared detail view model.\n * @returns The full page.\n * @throws Error When called without a session, since the write forms need a CSRF token.\n */\nexport function renderDetailPage(\n context: AdminRenderContext,\n view: AdminDetailView,\n): string {\n if (context.session === null) throw new Error(\"The detail view requires a session\");\n const csrf = escapeHtml(context.session.csrfToken);\n const fields = view.fields\n .map(\n (field) =>\n `<dt>${escapeHtml(field.label)}</dt><dd>${field.value === \"\" ? \"<em>—</em>\" : escapeHtml(field.value)}</dd>`,\n )\n .join(\"\");\n\n const body = `<section class=\"tempest-admin-detail\">\n <header class=\"tempest-admin-detail__header\">\n <h1>${escapeHtml(view.title)} · ${escapeHtml(view.identity)}</h1>\n <div class=\"tempest-admin-detail__actions\">\n <a href=\"${escapeHtml(view.backUrl)}\">← Back to list</a>\n ${view.editUrl !== null ? `<a class=\"tempest-admin-btn\" href=\"${escapeHtml(view.editUrl)}\">Edit</a>` : \"\"}\n ${\n view.deleteUrl !== null\n ? `<form method=\"post\" action=\"${escapeHtml(view.deleteUrl)}\" class=\"tempest-admin-detail__delete\" onsubmit=\"return confirm('Delete this record? This cannot be undone.');\">\n <input type=\"hidden\" name=\"csrf_token\" value=\"${csrf}\">\n <button type=\"submit\" class=\"tempest-admin-btn--danger\">Delete</button>\n </form>`\n : \"\"\n }\n </div>\n </header>\n <dl class=\"tempest-admin-detail__fields\">${fields}</dl>\n</section>`;\n return renderLayout(context, `${view.title} · ${view.identity}`, body);\n}\n\n/** The view model the create/edit form renders. */\nexport interface AdminFormView {\n /** Whether the form creates a new record or edits an existing one. */\n mode: \"create\" | \"edit\";\n /** Singular display name. */\n title: string;\n /** The controls to render. */\n fields: AdminFormField[];\n /** URL the form posts to. */\n actionUrl: string;\n /** URL of the page to return to. */\n backUrl: string;\n /** A form-level error shown above the fields, or `null`. */\n error: string | null;\n}\n\n/**\n * Render one form control.\n *\n * @param field - The field view model.\n * @returns The control's markup, wrapped in its label and error slot.\n */\nfunction renderFormField(field: AdminFormField): string {\n const required = field.required ? \" required\" : \"\";\n const name = escapeHtml(field.name);\n const value = escapeHtml(field.value);\n const label = escapeHtml(field.label);\n\n let control: string;\n switch (field.widget) {\n case \"checkbox\":\n control = `<label class=\"tempest-admin-form__check\"><input type=\"checkbox\" name=\"${name}\" value=\"true\"${field.checked ? \" checked\" : \"\"}><span>${label}</span></label>`;\n break;\n case \"textarea\":\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><textarea name=\"${name}\" rows=\"4\"${required}>${value}</textarea></label>`;\n break;\n case \"json\":\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><textarea name=\"${name}\" rows=\"6\" class=\"tempest-admin-form__json\" spellcheck=\"false\"${required}>${value}</textarea><small class=\"tempest-admin-form__hint\">JSON — must parse (e.g. <code>{}</code>, <code>[]</code>, <code>\"text\"</code>).</small></label>`;\n break;\n case \"select\": {\n const blank = field.required ? \"\" : '<option value=\"\">— none —</option>';\n const options = field.options\n .map(\n (option) =>\n `<option value=\"${escapeHtml(option.value)}\"${option.value === field.value ? \" selected\" : \"\"}>${escapeHtml(option.label)}</option>`,\n )\n .join(\"\");\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><select name=\"${name}\"${required}>${blank}${options}</select></label>`;\n break;\n }\n case \"number\":\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><input type=\"number\" name=\"${name}\" value=\"${value}\"${field.step !== null ? ` step=\"${escapeHtml(field.step)}\"` : \"\"}${required}></label>`;\n break;\n case \"datetime\":\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><input type=\"datetime-local\" name=\"${name}\" value=\"${value}\"${required}></label>`;\n break;\n case \"date\":\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><input type=\"date\" name=\"${name}\" value=\"${value}\"${required}></label>`;\n break;\n case \"time\":\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><input type=\"time\" name=\"${name}\" value=\"${value}\"${required}></label>`;\n break;\n default:\n control = `<label><span>${label}${field.required ? \" *\" : \"\"}</span><input type=\"text\" name=\"${name}\" value=\"${value}\"${required}></label>`;\n }\n\n const error =\n field.error !== null\n ? `<small class=\"tempest-admin-form__field-error\">${escapeHtml(field.error)}</small>`\n : \"\";\n return `<div class=\"tempest-admin-form__field${field.error !== null ? \" tempest-admin-form__field--error\" : \"\"}\">${control}${error}</div>`;\n}\n\n/**\n * Render the create/edit form.\n *\n * @param context - The shared chrome data (with an active session).\n * @param view - The prepared form view model.\n * @returns The full page.\n * @throws Error When called without a session, since the form needs a CSRF token.\n */\nexport function renderFormPage(context: AdminRenderContext, view: AdminFormView): string {\n if (context.session === null) throw new Error(\"The admin form requires a session\");\n const heading = view.mode === \"create\" ? `New ${view.title}` : `Edit ${view.title}`;\n const body = `<section class=\"tempest-admin-form\">\n <header class=\"tempest-admin-detail__header\">\n <h1>${escapeHtml(heading)}</h1>\n <a href=\"${escapeHtml(view.backUrl)}\">← Back</a>\n </header>\n ${view.error !== null ? `<p class=\"tempest-admin-form__error\">${escapeHtml(view.error)}</p>` : \"\"}\n <form method=\"post\" action=\"${escapeHtml(view.actionUrl)}\" class=\"tempest-admin-form__form\">\n <input type=\"hidden\" name=\"csrf_token\" value=\"${escapeHtml(context.session.csrfToken)}\">\n ${view.fields.map(renderFormField).join(\"\")}\n <div class=\"tempest-admin-form__actions\">\n <button type=\"submit\">${view.mode === \"create\" ? \"Create\" : \"Save\"}</button>\n <a href=\"${escapeHtml(view.backUrl)}\" class=\"tempest-admin-form__cancel\">Cancel</a>\n </div>\n </form>\n</section>`;\n return renderLayout(context, `${heading} · ${context.site.title}`, body);\n}\n","/**\n * The server-rendered admin panel router, mirroring `admin.router`.\n *\n * Mounts a Django-style panel over an {@link AdminSite}: operators sign in with\n * a row from the project's own database, then browse, search, filter, sort,\n * create, edit and delete every registered model. Nothing here is JSON — the\n * responses are HTML pages built by `@/admin/templates` and styled by the one\n * stylesheet this package serves.\n *\n * ```text\n * GET {prefix}/static/admin.css the bundled stylesheet\n * GET {prefix}/login sign-in form\n * POST {prefix}/login credential check\n * GET {prefix}/mfa TOTP challenge (backends with MFA)\n * POST {prefix}/mfa TOTP verification\n * POST {prefix}/logout drop the session\n * GET {prefix}/ dashboard: row counts + system metrics\n * GET {prefix}/m/:slug list view: search, filters, sort, pages\n * GET {prefix}/m/:slug/new create form\n * POST {prefix}/m/:slug/new create\n * GET {prefix}/m/:slug/:identity detail view\n * GET {prefix}/m/:slug/:identity/edit edit form\n * POST {prefix}/m/:slug/:identity/edit update\n * POST {prefix}/m/:slug/:identity/delete delete\n * ```\n *\n * Every state-changing POST carries the session's CSRF token and is rejected\n * with `403` when it does not match.\n */\n\nimport type { AdminAuthBackend } from \"@/admin/auth\";\nimport {\n adminColumns,\n filterForColumn,\n humanizeField,\n isSearchableColumn,\n} from \"@/admin/columns\";\nimport type { AdminModel } from \"@/admin/config\";\nimport { buildFormFields, formatCellValue, parseFormBody } from \"@/admin/forms\";\nimport { type AdminSession, AdminSessionStore, csrfTokenMatches } from \"@/admin/session\";\nimport type { AdminSite } from \"@/admin/site\";\nimport { ADMIN_CSS } from \"@/admin/styles\";\nimport {\n type AdminDashboardCard,\n type AdminDashboardMetrics,\n type AdminFilterView,\n type AdminListView,\n type AdminMessage,\n type AdminRenderContext,\n type AdminSortView,\n renderDashboardPage,\n renderDetailPage,\n renderFormPage,\n renderListPage,\n renderLoginPage,\n renderMfaPage,\n} from \"@/admin/templates\";\nimport { resolveAdminTheme } from \"@/admin/theme\";\nimport { JSONLogger } from \"@/core\";\nimport type { AsyncEngine, AsyncSession, Condition, WhereInput } from \"@/db\";\nimport { and, or } from \"@/db\";\nimport { MetricsUtils } from \"@/utils\";\nimport express, { type Request, type Response, type Router } from \"express\";\n\nconst logger = new JSONLogger(\"tempest_express_sdk.admin.router\");\n\n/** Fixed outcome codes carried in the redirect query after a write. */\nconst FLASH_MESSAGES: Record<string, AdminMessage> = {\n created: { text: \"Record created.\", level: \"success\" },\n updated: { text: \"Record updated.\", level: \"success\" },\n deleted: { text: \"Record deleted.\", level: \"success\" },\n};\n\n/** Options for {@link makeAdminRouter}. */\nexport interface AdminRouterOptions {\n /** The engine the panel opens a session on for each request. */\n engine: AsyncEngine;\n /** How the login form turns credentials into a principal. */\n authBackend: AdminAuthBackend;\n /** HMAC key signing the session cookie. At least 32 characters. */\n secretKey: string;\n /** Mount prefix. Default `/admin`. */\n prefix?: string;\n /** Send the session cookie with `Secure`. Default `true` — turn it off only in local HTTP dev. */\n cookieSecure?: boolean;\n /** Session cookie name. Default `tempest_admin_session`. */\n cookieName?: string;\n /** Session lifetime in seconds. Default `28800` (8 hours). */\n sessionMaxAgeSeconds?: number;\n /** Show the CPU/memory panel on the dashboard. Default `true`. */\n showMetrics?: boolean;\n}\n\n/** The per-request state the authenticated handlers share. */\ninterface AdminRequestState {\n session: AdminSession;\n dbSession: AsyncSession;\n}\n\n/**\n * Read the first value of a query parameter as a string.\n *\n * Express hands repeated parameters over as arrays; the panel's controls never\n * repeat, so the first value wins and anything else reads as absent.\n *\n * @param value - The raw query value.\n * @returns The trimmed string, or `\"\"` when absent.\n */\nfunction queryString(value: unknown): string {\n if (typeof value === \"string\") return value.trim();\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0].trim();\n return \"\";\n}\n\n/**\n * Build a query string from defined, non-empty entries.\n *\n * @param entries - Parameter name/value pairs.\n * @returns The encoded query string, without a leading `?`.\n */\nfunction buildQuery(entries: Record<string, string | number | undefined>): string {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(entries)) {\n if (value === undefined || value === \"\") continue;\n params.set(key, String(value));\n }\n return params.toString();\n}\n\n/**\n * Build the admin panel router.\n *\n * @param site - The registered {@link AdminSite}.\n * @param options - Engine, auth backend, signing key and cookie/appearance flags.\n * @returns An Express router serving the whole panel under its prefix.\n * @throws Error When the signing key is shorter than 32 characters.\n */\nexport function makeAdminRouter(site: AdminSite, options: AdminRouterOptions): Router {\n const prefix = (options.prefix ?? \"/admin\").replace(/\\/$/, \"\");\n const theme = resolveAdminTheme(site.theme);\n const showMetrics = options.showMetrics ?? true;\n const sessions = new AdminSessionStore({\n secret: options.secretKey,\n ...(options.cookieName === undefined ? {} : { cookieName: options.cookieName }),\n ...(options.sessionMaxAgeSeconds === undefined\n ? {}\n : { maxAgeSeconds: options.sessionMaxAgeSeconds }),\n ...(options.cookieSecure === undefined ? {} : { cookieSecure: options.cookieSecure }),\n cookiePath: prefix === \"\" ? \"/\" : prefix,\n });\n const backend = options.authBackend;\n const router = express.Router();\n\n router.use(prefix, express.urlencoded({ extended: false }));\n\n /**\n * Build the chrome context every page renders inside.\n *\n * @param req - The inbound request.\n * @param session - The active session, or `null` on the login/MFA pages.\n * @returns The render context.\n */\n const context = (req: Request, session: AdminSession | null): AdminRenderContext => ({\n site,\n theme,\n prefix,\n session,\n currentPath: req.originalUrl.split(\"?\")[0] ?? req.path,\n navModels: site.list().map((admin) => ({\n label: admin.verboseNamePlural(),\n url: `${prefix}/m/${admin.slug()}`,\n })),\n messages: flashFor(req),\n });\n\n /**\n * Resolve the fixed outcome code a redirect carries into a banner.\n *\n * @param req - The inbound request.\n * @returns The banners to render (empty when the request carries none).\n */\n const flashFor = (req: Request): AdminMessage[] => {\n const message = FLASH_MESSAGES[queryString(req.query.ok)];\n return message === undefined ? [] : [message];\n };\n\n /**\n * Send an HTML page.\n *\n * @param res - The outbound response.\n * @param html - The rendered document.\n * @param status - The status code. Default `200`.\n */\n const html = (res: Response, body: string, status = 200): void => {\n res.status(status).type(\"html\").send(body);\n };\n\n /**\n * Wrap an async handler so a thrown error renders an HTML page instead of\n * falling through to the JSON error stack the rest of the app uses.\n *\n * @param handler - The handler to wrap.\n * @returns An Express handler that never rejects.\n */\n const guarded =\n (handler: (req: Request, res: Response) => Promise<void>) =>\n (req: Request, res: Response): void => {\n handler(req, res).catch((error: unknown) => {\n logger.error(\"Admin request failed\", {\n path: req.originalUrl,\n error: error instanceof Error ? error.message : String(error),\n });\n if (res.headersSent) return;\n html(\n res,\n renderLoginPage(context(req, null), \"Something went wrong. Please try again.\"),\n 500,\n );\n });\n };\n\n /**\n * Resolve the session for an authenticated route, redirecting when it is\n * missing, expired, still awaiting MFA, or points at a principal that no\n * longer qualifies.\n *\n * @param req - The inbound request.\n * @param res - The outbound response.\n * @returns The request state, or `null` when a redirect was already sent.\n */\n const authenticate = async (\n req: Request,\n res: Response,\n ): Promise<AdminRequestState | null> => {\n const session = sessions.load(req);\n if (session === null) {\n res.redirect(`${prefix}/login`);\n return null;\n }\n const dbSession = options.engine.session();\n const principal = await backend.loadPrincipal(dbSession, session.subject);\n if (principal === null) {\n sessions.clear(res);\n res.redirect(`${prefix}/login`);\n return null;\n }\n if (!session.mfaPassed) {\n res.redirect(`${prefix}/mfa`);\n return null;\n }\n return { session, dbSession };\n };\n\n /**\n * Resolve the model configuration a URL slug names.\n *\n * @param req - The inbound request.\n * @param res - The outbound response.\n * @param state - The authenticated request state.\n * @returns The configuration, or `null` when a 404 was already sent.\n */\n const resolveAdmin = (\n req: Request,\n res: Response,\n state: AdminRequestState,\n ): AdminModel | null => {\n const admin = site.get(String(req.params.slug));\n if (admin === null) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return null;\n }\n return admin;\n };\n\n /**\n * Render a \"no such page\" body inside the panel chrome.\n *\n * @param ctx - The render context.\n * @returns The full page.\n */\n const renderNotFound = (ctx: AdminRenderContext): string =>\n renderDashboardPage(\n { ...ctx, messages: [{ text: \"Not found.\", level: \"error\" }] },\n [],\n null,\n );\n\n /**\n * Reject a write whose CSRF token does not match the session's.\n *\n * @param req - The inbound request.\n * @param res - The outbound response.\n * @param state - The authenticated request state.\n * @returns `true` when the request may proceed.\n */\n const checkCsrf = (req: Request, res: Response, state: AdminRequestState): boolean => {\n const body = req.body as Record<string, unknown>;\n if (csrfTokenMatches(state.session, body?.csrf_token)) return true;\n html(res, renderNotFound(context(req, state.session)), 403);\n return false;\n };\n\n router.get(`${prefix}/static/admin.css`, (_req, res) => {\n res.type(\"css\").set(\"cache-control\", \"public, max-age=3600\").send(ADMIN_CSS);\n });\n\n router.get(`${prefix}/login`, (req, res) => {\n html(res, renderLoginPage(context(req, null), null));\n });\n\n router.post(\n `${prefix}/login`,\n guarded(async (req, res) => {\n const body = req.body as Record<string, unknown>;\n const identifier = typeof body.identifier === \"string\" ? body.identifier : \"\";\n const password = typeof body.password === \"string\" ? body.password : \"\";\n const dbSession = options.engine.session();\n const principal = await backend.authenticate(dbSession, identifier, password);\n if (principal === null) {\n html(res, renderLoginPage(context(req, null), \"Invalid credentials.\"), 401);\n return;\n }\n const needsMfa = (await backend.mfaEnabled?.(principal)) ?? false;\n const session = sessions.issue(\n backend.principalId(principal),\n backend.displayName(principal),\n !needsMfa,\n );\n sessions.save(res, session);\n res.redirect(needsMfa ? `${prefix}/mfa` : `${prefix}/`);\n }),\n );\n\n router.get(`${prefix}/mfa`, (req, res) => {\n const session = sessions.load(req);\n if (session === null) {\n res.redirect(`${prefix}/login`);\n return;\n }\n if (session.mfaPassed) {\n res.redirect(`${prefix}/`);\n return;\n }\n html(res, renderMfaPage(context(req, null), null));\n });\n\n router.post(\n `${prefix}/mfa`,\n guarded(async (req, res) => {\n const session = sessions.load(req);\n if (session === null) {\n res.redirect(`${prefix}/login`);\n return;\n }\n const body = req.body as Record<string, unknown>;\n const code = typeof body.code === \"string\" ? body.code : \"\";\n const dbSession = options.engine.session();\n const principal = await backend.loadPrincipal(dbSession, session.subject);\n const verified =\n principal !== null && ((await backend.verifyMfa?.(principal, code)) ?? false);\n if (!verified) {\n html(res, renderMfaPage(context(req, null), \"Invalid code.\"), 401);\n return;\n }\n sessions.save(res, { ...session, mfaPassed: true });\n res.redirect(`${prefix}/`);\n }),\n );\n\n router.post(\n `${prefix}/logout`,\n guarded(async (req, res) => {\n const session = sessions.load(req);\n if (\n session !== null &&\n !csrfTokenMatches(session, (req.body as Record<string, unknown>)?.csrf_token)\n ) {\n html(res, renderLoginPage(context(req, null), \"Invalid request.\"), 403);\n return;\n }\n sessions.clear(res);\n res.redirect(`${prefix}/login`);\n }),\n );\n\n router.get(\n `${prefix}/`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n\n const cards: AdminDashboardCard[] = [];\n for (const admin of site.list()) {\n let count: number | null = null;\n try {\n count = await admin.repository(state.dbSession).count();\n } catch (error) {\n logger.warning(\"Admin dashboard count failed\", {\n slug: admin.slug(),\n error: error instanceof Error ? error.message : String(error),\n });\n }\n cards.push({\n label: admin.verboseNamePlural(),\n count,\n url: `${prefix}/m/${admin.slug()}`,\n newUrl: admin.canCreate ? `${prefix}/m/${admin.slug()}/new` : null,\n });\n }\n\n let metrics: AdminDashboardMetrics | null = null;\n if (showMetrics) {\n const snapshot = MetricsUtils.system();\n metrics = {\n cpuPercent: Math.round(snapshot.cpu.loadPercent),\n memoryPercent: Math.round(snapshot.memory.usedPercent),\n memoryUsedGb: (snapshot.memory.used / 1024 ** 3).toFixed(1),\n memoryTotalGb: (snapshot.memory.total / 1024 ** 3).toFixed(1),\n };\n }\n\n html(res, renderDashboardPage(context(req, state.session), cards, metrics));\n }),\n );\n\n router.get(\n `${prefix}/m/:slug`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n html(res, await renderList(req, admin, state));\n }),\n );\n\n router.get(\n `${prefix}/m/:slug/new`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n if (!admin.canCreate) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n html(\n res,\n renderFormPage(context(req, state.session), {\n mode: \"create\",\n title: admin.verboseName(),\n fields: buildFormFields(admin),\n actionUrl: `${prefix}/m/${admin.slug()}/new`,\n backUrl: `${prefix}/m/${admin.slug()}`,\n error: null,\n }),\n );\n }),\n );\n\n router.post(\n `${prefix}/m/:slug/new`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n if (!admin.canCreate) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n if (!checkCsrf(req, res, state)) return;\n\n const body = req.body as Record<string, unknown>;\n const parsed = parseFormBody(admin, body);\n const rerender = (error: string | null, status: number): void => {\n html(\n res,\n renderFormPage(context(req, state.session), {\n mode: \"create\",\n title: admin.verboseName(),\n fields: buildFormFields(admin, { values: body, errors: parsed.errors }),\n actionUrl: `${prefix}/m/${admin.slug()}/new`,\n backUrl: `${prefix}/m/${admin.slug()}`,\n error,\n }),\n status,\n );\n };\n\n if (Object.keys(parsed.errors).length > 0) {\n rerender(\"Please fix the highlighted fields.\", 400);\n return;\n }\n try {\n await admin.repository(state.dbSession).create(parsed.data as never);\n } catch (error) {\n rerender(describeWriteFailure(admin, error), 400);\n return;\n }\n res.redirect(`${prefix}/m/${admin.slug()}?ok=created`);\n }),\n );\n\n router.get(\n `${prefix}/m/:slug/:identity`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n const row = await findRow(admin, state.dbSession, String(req.params.identity));\n if (row === null) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n const identity = String(row[admin.identityField]);\n html(\n res,\n renderDetailPage(context(req, state.session), {\n title: admin.verboseName(),\n identity,\n fields: admin\n .detailFieldNames()\n .map((name) => ({ label: name, value: formatCellValue(row[name]) })),\n backUrl: `${prefix}/m/${admin.slug()}`,\n editUrl: admin.canEdit ? `${prefix}/m/${admin.slug()}/${identity}/edit` : null,\n deleteUrl: admin.canDelete\n ? `${prefix}/m/${admin.slug()}/${identity}/delete`\n : null,\n }),\n );\n }),\n );\n\n router.get(\n `${prefix}/m/:slug/:identity/edit`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n const identity = String(req.params.identity);\n const row = admin.canEdit ? await findRow(admin, state.dbSession, identity) : null;\n if (row === null) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n html(\n res,\n renderFormPage(context(req, state.session), {\n mode: \"edit\",\n title: admin.verboseName(),\n fields: buildFormFields(admin, { values: row }),\n actionUrl: `${prefix}/m/${admin.slug()}/${identity}/edit`,\n backUrl: `${prefix}/m/${admin.slug()}/${identity}`,\n error: null,\n }),\n );\n }),\n );\n\n router.post(\n `${prefix}/m/:slug/:identity/edit`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n const identity = String(req.params.identity);\n if (!admin.canEdit) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n if (!checkCsrf(req, res, state)) return;\n\n const body = req.body as Record<string, unknown>;\n const parsed = parseFormBody(admin, body);\n const rerender = (error: string | null, status: number): void => {\n html(\n res,\n renderFormPage(context(req, state.session), {\n mode: \"edit\",\n title: admin.verboseName(),\n fields: buildFormFields(admin, { values: body, errors: parsed.errors }),\n actionUrl: `${prefix}/m/${admin.slug()}/${identity}/edit`,\n backUrl: `${prefix}/m/${admin.slug()}/${identity}`,\n error,\n }),\n status,\n );\n };\n\n if (Object.keys(parsed.errors).length > 0) {\n rerender(\"Please fix the highlighted fields.\", 400);\n return;\n }\n try {\n const changed = await admin\n .repository(state.dbSession)\n .update({ [admin.identityField]: identity } as never, parsed.data as never);\n if (changed === 0) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n } catch (error) {\n rerender(describeWriteFailure(admin, error), 400);\n return;\n }\n res.redirect(`${prefix}/m/${admin.slug()}/${identity}?ok=updated`);\n }),\n );\n\n router.post(\n `${prefix}/m/:slug/:identity/delete`,\n guarded(async (req, res) => {\n const state = await authenticate(req, res);\n if (state === null) return;\n const admin = resolveAdmin(req, res, state);\n if (admin === null) return;\n if (!admin.canDelete) {\n html(res, renderNotFound(context(req, state.session)), 404);\n return;\n }\n if (!checkCsrf(req, res, state)) return;\n await admin\n .repository(state.dbSession)\n .delete({ [admin.identityField]: String(req.params.identity) } as never);\n res.redirect(`${prefix}/m/${admin.slug()}?ok=deleted`);\n }),\n );\n\n /**\n * Look one row up by the configured identity column.\n *\n * @param admin - The model configuration.\n * @param dbSession - The request's DB session.\n * @param identity - The identity taken from the URL.\n * @returns The row as a plain record, or `null` when nothing matches.\n */\n async function findRow(\n admin: AdminModel,\n dbSession: AsyncSession,\n identity: string,\n ): Promise<Record<string, unknown> | null> {\n const row = await admin\n .repository(dbSession)\n .first({ [admin.identityField]: identity } as never);\n return (row as Record<string, unknown> | null) ?? null;\n }\n\n /**\n * Render the list view for a model, applying the request's search, filters,\n * ordering and page.\n *\n * @param req - The inbound request.\n * @param admin - The model configuration.\n * @param state - The authenticated request state.\n * @returns The full page.\n */\n async function renderList(\n req: Request,\n admin: AdminModel,\n state: AdminRequestState,\n ): Promise<string> {\n const columns = adminColumns(admin.model);\n const search = queryString(req.query.q);\n const page = Math.max(1, Number.parseInt(queryString(req.query.page), 10) || 1);\n const sortField = queryString(req.query.sort);\n const sortColumn = sortField in columns ? sortField : null;\n const ascending =\n sortColumn === null ? admin.orderAscending : queryString(req.query.dir) !== \"desc\";\n\n const conditions: (WhereInput<Record<string, unknown>> | Condition)[] = [];\n const filterViews: AdminFilterView[] = [];\n\n for (const field of admin.listFilter) {\n const column = columns[field];\n if (column === undefined) continue;\n const spec = filterForColumn(column);\n if (spec.kind === \"daterange\") {\n const from = queryString(req.query[`filter_${field}_from`]);\n const to = queryString(req.query[`filter_${field}_to`]);\n const bounds: Record<string, unknown> = {};\n if (from !== \"\") bounds.gte = new Date(from);\n if (to !== \"\") bounds.lte = new Date(`${to}T23:59:59.999Z`);\n if (Object.keys(bounds).length > 0) conditions.push({ [field]: bounds });\n filterViews.push({\n field,\n label: humanizeField(field),\n kind: \"daterange\",\n value: \"\",\n valueFrom: from,\n valueTo: to,\n options: [],\n });\n continue;\n }\n const value = queryString(req.query[`filter_${field}`]);\n if (value !== \"\") {\n conditions.push({\n [field]: column.type.kind === \"boolean\" ? value === \"true\" : value,\n });\n }\n filterViews.push({\n field,\n label: humanizeField(field),\n kind: spec.kind,\n value,\n valueFrom: \"\",\n valueTo: \"\",\n options: spec.options.map((option) => ({\n value: option.value,\n label: option.label,\n selected: option.value === value,\n })),\n });\n }\n\n const searchable = admin.searchFields.filter((field) => {\n const column = columns[field];\n return column !== undefined && isSearchableColumn(column);\n });\n if (search !== \"\" && searchable.length > 0) {\n conditions.push(\n or(...searchable.map((field) => ({ [field]: { ilike: `%${search}%` } }))),\n );\n }\n\n const where = conditions.length === 0 ? undefined : and(...conditions);\n const orderBy = sortColumn ?? admin.orderKey ?? undefined;\n const result = await admin.repository(state.dbSession).paginate({\n page,\n pageSize: admin.pageSize,\n ...(orderBy === undefined ? {} : { orderBy: orderBy as never }),\n ascending,\n ...(where === undefined ? {} : { filters: where as never }),\n });\n\n const displayed = admin.listDisplayNames();\n const baseQuery: Record<string, string> = { q: search };\n for (const view of filterViews) {\n if (view.kind === \"daterange\") {\n baseQuery[`filter_${view.field}_from`] = view.valueFrom;\n baseQuery[`filter_${view.field}_to`] = view.valueTo;\n } else {\n baseQuery[`filter_${view.field}`] = view.value;\n }\n }\n\n const sort: Record<string, AdminSortView> = {};\n for (const column of displayed) {\n if (!(column in columns)) continue;\n const active = (sortColumn ?? admin.orderKey) === column;\n const nextAscending = active ? !ascending : true;\n sort[column] = {\n url: `?${buildQuery({\n ...baseQuery,\n sort: column,\n dir: nextAscending ? \"asc\" : \"desc\",\n })}`,\n active,\n ascending,\n };\n }\n\n const pageUrl = (target: number): string =>\n `?${buildQuery({\n ...baseQuery,\n sort: sortColumn ?? undefined,\n dir: sortColumn === null ? undefined : ascending ? \"asc\" : \"desc\",\n page: target,\n })}`;\n\n const view: AdminListView = {\n title: admin.verboseNamePlural(),\n columns: displayed,\n rows: (result.items as Record<string, unknown>[]).map((row) => {\n const identity = String(row[admin.identityField]);\n return {\n identity,\n cells: displayed.map((column) => formatCellValue(row[column])),\n url: `${prefix}/m/${admin.slug()}/${identity}`,\n };\n }),\n total: result.total,\n page: result.page,\n pages: result.pages,\n prevUrl: result.page > 1 ? pageUrl(result.page - 1) : null,\n nextUrl: result.page < result.pages ? pageUrl(result.page + 1) : null,\n searchable: searchable.length > 0,\n searchValue: search,\n filters: filterViews,\n sort,\n newUrl: admin.canCreate ? `${prefix}/m/${admin.slug()}/new` : null,\n };\n\n return renderListPage(context(req, state.session), view);\n }\n\n return router;\n}\n\n/**\n * Turn a rejected write into a message the operator can act on.\n *\n * A database that refuses a row — a unique index, a foreign key, a `NOT NULL` —\n * is a user error, not a server fault, so it comes back through the form with a\n * `400` instead of escaping as a `500`.\n *\n * @param admin - The model configuration whose write failed.\n * @param error - The thrown value.\n * @returns A human-readable message.\n */\nfunction describeWriteFailure(admin: AdminModel, error: unknown): string {\n const detail = error instanceof Error ? error.message : String(error);\n return `The database refused this ${admin.verboseName().toLowerCase()}: ${detail}`;\n}\n","/**\n * Headless admin: resource registry for the JSON admin API.\n *\n * The counterpart to the server-rendered panel in `@/admin/site`. Register one\n * {@link AdminJsonResource} per managed entity and {@link makeAdminJsonRouter}\n * exposes auto-derived CRUD + introspection endpoints your own frontend\n * (React, etc.) renders. Resources are callback-based, so they wire to a\n * `BaseService` — or any store — in a few lines and stay ORM-agnostic.\n *\n * Reach for this when the UI is yours; reach for {@link AdminSite} +\n * `makeAdminRouter` when you want the batteries-included HTML panel.\n */\n\nimport type { z } from \"@/schemas/base\";\n\n/** A field descriptor a frontend uses to render list columns / form inputs. */\nexport interface AdminJsonField {\n /** Field name (property key). */\n name: string;\n /** Loose type hint for rendering (`string`, `number`, `boolean`, `date`, …). */\n type?: string;\n /** Whether the field is required on create. */\n required?: boolean;\n /** Whether the field is read-only (shown, never submitted). */\n readOnly?: boolean;\n}\n\n/** A paginated list result returned by {@link AdminJsonResource.list}. */\nexport interface AdminJsonListResult<T = unknown> {\n items: T[];\n total: number;\n page: number;\n pageSize: number;\n pages: number;\n}\n\n/** Query parameters passed to {@link AdminJsonResource.list}. */\nexport interface AdminJsonListQuery {\n page: number;\n pageSize: number;\n /** Remaining query-string entries (domain filters). */\n filters: Record<string, string>;\n}\n\n/**\n * A managed resource. Only `name`, `fields` and `list`/`get` are required;\n * omit a write callback to make that operation unavailable (405).\n */\nexport interface AdminJsonResource<T = unknown> {\n /** URL-safe resource slug (e.g. `users`). */\n name: string;\n /** Field descriptors for list/detail/form rendering. */\n fields: AdminJsonField[];\n /** Return a page of records. */\n list(query: AdminJsonListQuery): Promise<AdminJsonListResult<T>>;\n /** Return one record by id, or `null` when absent. */\n get(id: string): Promise<T | null>;\n /** Create a record from validated input. */\n create?(data: unknown): Promise<T>;\n /** Update a record by id from validated input. */\n update?(id: string, data: unknown): Promise<T>;\n /** Delete a record by id. */\n remove?(id: string): Promise<void>;\n /** Zod schema validating the create body. */\n createSchema?: z.ZodType;\n /** Zod schema validating the update body. */\n updateSchema?: z.ZodType;\n}\n\n/** A registry of admin resources. */\nexport class AdminJsonSite {\n private readonly resources = new Map<string, AdminJsonResource>();\n\n /**\n * @param brand - Display name surfaced under `GET {prefix}/`.\n */\n constructor(readonly brand = \"Admin\") {}\n\n /**\n * Register a resource.\n *\n * @param resource - The resource config.\n * @returns The same resource (for chaining).\n */\n register<T>(resource: AdminJsonResource<T>): AdminJsonResource<T> {\n this.resources.set(resource.name, resource as AdminJsonResource);\n return resource;\n }\n\n /** Look up a resource by slug, or `null`. */\n get(name: string): AdminJsonResource | null {\n return this.resources.get(name) ?? null;\n }\n\n /** Every registered resource. */\n list(): AdminJsonResource[] {\n return [...this.resources.values()];\n }\n}\n","/**\n * Admin JSON router, mirroring `admin.router.make_admin_router`.\n *\n * Exposes auto-derived CRUD + introspection over an {@link AdminJsonSite}:\n *\n * ```text\n * GET {prefix}/ site brand + resource list\n * GET {prefix}/:resource/_meta resource field descriptors\n * GET {prefix}/:resource paginated list\n * GET {prefix}/:resource/:id detail (404 when absent)\n * POST {prefix}/:resource create (405 if unsupported)\n * PATCH {prefix}/:resource/:id update (405 if unsupported)\n * DELETE {prefix}/:resource/:id delete (405 if unsupported)\n * ```\n *\n * Pass a `guard` middleware (e.g. JWT + `requireRoles(\"admin\")`) to protect it.\n */\n\nimport type { AdminJsonResource, AdminJsonSite } from \"@/admin/json/site\";\nimport { AppException } from \"@/exceptions/base\";\nimport { NotFoundException } from \"@/exceptions/http\";\nimport { type RequestHandler, type Router, Router as createRouter } from \"express\";\n\nconst PAGINATION_KEYS = new Set([\"page\", \"pageSize\"]);\n\n/** Options for {@link makeAdminJsonRouter}. */\nexport interface AdminJsonRouterOptions {\n /** Route prefix. Default `/admin`. */\n prefix?: string;\n /** Guard middleware applied to every admin route (auth). */\n guard?: RequestHandler;\n}\n\n/** Raised (405) when a resource does not support a write operation. */\nfunction methodNotAllowed(operation: string): AppException {\n return new AppException({\n message: `Operation not allowed: ${operation}`,\n code: \"METHOD_NOT_ALLOWED\",\n statusCode: 405,\n });\n}\n\n/** Resolve a resource by slug or raise 404. */\nfunction requireResource(site: AdminJsonSite, name: string): AdminJsonResource {\n const resource = site.get(name);\n if (!resource) throw new NotFoundException({ message: `Unknown resource: ${name}` });\n return resource;\n}\n\n/**\n * Build the admin router.\n *\n * @param site - The registered {@link AdminJsonSite}.\n * @param options - Prefix and guard middleware.\n * @returns An Express router with the admin endpoints mounted.\n */\nexport function makeAdminJsonRouter(\n site: AdminJsonSite,\n options: AdminJsonRouterOptions = {},\n): Router {\n const prefix = (options.prefix ?? \"/admin\").replace(/\\/$/, \"\");\n const router = createRouter();\n if (options.guard) router.use(prefix, options.guard);\n\n router.get(prefix, (_req, res) => {\n res.json({\n brand: site.brand,\n resources: site.list().map((r) => ({ name: r.name, fields: r.fields })),\n });\n });\n\n router.get(`${prefix}/:resource/_meta`, (req, res) => {\n const resource = requireResource(site, req.params.resource);\n res.json({\n name: resource.name,\n fields: resource.fields,\n operations: {\n create: Boolean(resource.create),\n update: Boolean(resource.update),\n remove: Boolean(resource.remove),\n },\n });\n });\n\n router.get(`${prefix}/:resource`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n const filters: Record<string, string> = {};\n for (const [key, value] of Object.entries(req.query)) {\n if (!PAGINATION_KEYS.has(key) && typeof value === \"string\") filters[key] = value;\n }\n const page = Math.max(1, Number.parseInt(String(req.query.page ?? \"1\"), 10) || 1);\n const pageSize = Math.max(\n 1,\n Number.parseInt(String(req.query.pageSize ?? \"20\"), 10) || 20,\n );\n res.json(await resource.list({ page, pageSize, filters }));\n });\n\n router.get(`${prefix}/:resource/:id`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n const record = await resource.get(req.params.id);\n if (record === null) throw new NotFoundException({ message: \"Record not found\" });\n res.json(record);\n });\n\n router.post(`${prefix}/:resource`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n if (!resource.create) throw methodNotAllowed(\"create\");\n const data = resource.createSchema ? resource.createSchema.parse(req.body) : req.body;\n res.status(201).json(await resource.create(data));\n });\n\n router.patch(`${prefix}/:resource/:id`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n if (!resource.update) throw methodNotAllowed(\"update\");\n const data = resource.updateSchema ? resource.updateSchema.parse(req.body) : req.body;\n res.json(await resource.update(req.params.id, data));\n });\n\n router.delete(`${prefix}/:resource/:id`, async (req, res) => {\n const resource = requireResource(site, req.params.resource);\n if (!resource.remove) throw methodNotAllowed(\"remove\");\n await resource.remove(req.params.id);\n res.status(204).end();\n });\n\n return router;\n}\n","/**\n * Auth DTOs (Zod), mirroring `auth.schemas`.\n *\n * Request/response schemas for the bundled signup/login/refresh flows. All are\n * OpenAPI-registered shapes so they render in Swagger/Redoc when the auth\n * router's paths are registered.\n */\n\nimport { z } from \"@/schemas/base\";\n\n/** Request body for `POST /auth/signup`. */\nexport const signupSchema = z\n .object({\n email: z.email().openapi({ description: \"Login identifier (email).\" }),\n password: z\n .string()\n .min(1)\n .openapi({ description: \"Plaintext password (hashed server-side).\" }),\n name: z\n .string()\n .max(120)\n .optional()\n .openapi({ description: \"Optional display name.\" }),\n })\n .openapi(\"Signup\");\n\n/** Request body for `POST /auth/login`. */\nexport const loginSchema = z\n .object({\n email: z.email().openapi({ description: \"Login identifier (email).\" }),\n password: z.string().min(1).openapi({ description: \"Plaintext password.\" }),\n })\n .openapi(\"Login\");\n\n/** Request body for `POST /auth/refresh`. */\nexport const refreshSchema = z\n .object({\n refreshToken: z.string().min(1).openapi({ description: \"A valid refresh token.\" }),\n })\n .openapi(\"Refresh\");\n\n/** A signed access/refresh token pair. */\nexport const tokenPairSchema = z\n .object({\n accessToken: z.string().openapi({ description: \"Short-lived bearer access token.\" }),\n refreshToken: z.string().openapi({ description: \"Long-lived refresh token.\" }),\n tokenType: z.literal(\"bearer\").openapi({ description: \"Always 'bearer'.\" }),\n expiresIn: z\n .number()\n .int()\n .openapi({ description: \"Access-token lifetime in seconds.\" }),\n })\n .openapi(\"TokenPair\");\n\n/** Public user projection returned by `GET /auth/me` and signup/login. */\nexport const userPublicSchema = z\n .object({\n id: z.string().openapi({ description: \"User id.\" }),\n email: z.email().openapi({ description: \"User email.\" }),\n name: z.string().nullable().openapi({ description: \"Display name, or null.\" }),\n isActive: z.boolean().openapi({ description: \"Whether the account is active.\" }),\n roles: z.array(z.string()).openapi({ description: \"Assigned role names.\" }),\n })\n .openapi(\"UserPublic\");\n\n/** Response body for `POST /auth/signup` and `POST /auth/login`. */\nexport const authResponseSchema = z\n .object({\n user: userPublicSchema,\n tokens: tokenPairSchema,\n })\n .openapi(\"AuthResponse\");\n\n/** MFA enrollment response (`POST /auth/mfa/enroll`). */\nexport const mfaEnrollResponseSchema = z\n .object({\n secret: z.string().openapi({ description: \"Base32 TOTP secret (manual entry).\" }),\n otpauthUri: z.string().openapi({ description: \"otpauth:// URI to render as QR.\" }),\n })\n .openapi(\"MfaEnrollResponse\");\n\n/** A 6-digit MFA code body (`POST /auth/mfa/confirm|disable`). */\nexport const mfaCodeSchema = z\n .object({ code: z.string().min(1).openapi({ description: \"Authenticator code.\" }) })\n .openapi(\"MfaCode\");\n\n/** MFA login-challenge body (`POST /auth/mfa/challenge`). */\nexport const mfaChallengeSchema = z\n .object({\n mfaToken: z.string().min(1).openapi({ description: \"Challenge token from login.\" }),\n code: z.string().min(1).openapi({ description: \"Authenticator code.\" }),\n })\n .openapi(\"MfaChallenge\");\n\n/** Activation body (`POST /auth/activate`). */\nexport const activationSchema = z\n .object({ token: z.string().min(1).openapi({ description: \"Activation token.\" }) })\n .openapi(\"Activation\");\n\n/** Password-reset request body (`POST /auth/password-reset/request`). */\nexport const passwordResetRequestSchema = z\n .object({ email: z.email().openapi({ description: \"Account email.\" }) })\n .openapi(\"PasswordResetRequest\");\n\n/** Password-reset confirm body (`POST /auth/password-reset/confirm`). */\nexport const passwordResetConfirmSchema = z\n .object({\n token: z.string().min(1).openapi({ description: \"Reset token.\" }),\n password: z.string().min(1).openapi({ description: \"New plaintext password.\" }),\n })\n .openapi(\"PasswordResetConfirm\");\n\nexport type SignupInput = z.infer<typeof signupSchema>;\nexport type LoginInput = z.infer<typeof loginSchema>;\nexport type RefreshInput = z.infer<typeof refreshSchema>;\nexport type TokenPair = z.infer<typeof tokenPairSchema>;\nexport type UserPublic = z.infer<typeof userPublicSchema>;\nexport type AuthResponse = z.infer<typeof authResponseSchema>;\nexport type MfaCodeInput = z.infer<typeof mfaCodeSchema>;\nexport type MfaChallengeInput = z.infer<typeof mfaChallengeSchema>;\nexport type ActivationInput = z.infer<typeof activationSchema>;\nexport type PasswordResetRequestInput = z.infer<typeof passwordResetRequestSchema>;\nexport type PasswordResetConfirmInput = z.infer<typeof passwordResetConfirmSchema>;\n","/**\n * User authentication service, mirroring `auth.service.UserAuthService`.\n *\n * Orchestrates signup / login / refresh over a pluggable {@link UserStore},\n * {@link PasswordUtils} and {@link JWTUtils}. It is ORM-agnostic — back the\n * store with a `tempest-db-js` repository (or anything else). With an\n * {@link MfaService} wired in, `login` returns an MFA challenge for enrolled\n * users (complete it via {@link UserAuthService.verifyMfaChallenge}).\n */\n\nimport type { MfaService } from \"@/auth/mfa\";\nimport type {\n AuthResponse,\n LoginInput,\n SignupInput,\n TokenPair,\n UserPublic,\n} from \"@/auth/schemas\";\nimport {\n ConflictException,\n UnauthorizedException,\n ValidationException,\n} from \"@/exceptions/http\";\nimport type { JWTUtils } from \"@/utils/jwt\";\nimport type { PasswordUtils } from \"@/utils/password\";\n\n/** A persisted user as the auth layer needs to see it. */\nexport interface AuthUser {\n /** Stable user id (string form). */\n id: string;\n /** Login email (lowercased by the service before lookup/create). */\n email: string;\n /** The stored bcrypt password hash. */\n passwordHash: string;\n /** Display name, or `null`. */\n name: string | null;\n /** Whether the account may log in. */\n isActive: boolean;\n /** Assigned role names. */\n roles: string[];\n}\n\n/** Persistence port the service depends on. Implement over any store. */\nexport interface UserStore {\n /** Find a user by (lowercased) email, or `null`. */\n findByEmail(email: string): Promise<AuthUser | null>;\n /** Find a user by id, or `null`. */\n findById(id: string): Promise<AuthUser | null>;\n /** Create a user from validated signup data + a password hash. */\n create(data: {\n email: string;\n passwordHash: string;\n name: string | null;\n }): Promise<AuthUser>;\n}\n\n/** Options for {@link UserAuthService}. */\nexport interface UserAuthServiceOptions {\n /** The user persistence port. */\n store: UserStore;\n /** Password hasher/verifier. */\n password: PasswordUtils;\n /** JWT encoder/decoder used to mint access + refresh tokens. */\n jwt: JWTUtils;\n /** Minimum password length enforced server-side. Default 12. */\n passwordMinLength?: number;\n /** Access-token lifetime in seconds. Default 3600. */\n accessTtlSeconds?: number;\n /** Refresh-token lifetime in seconds. Default 1209600 (14 days). */\n refreshTtlSeconds?: number;\n /**\n * When provided, `login` returns an MFA challenge instead of tokens for users\n * with MFA enabled; complete it with {@link UserAuthService.verifyMfaChallenge}.\n */\n mfa?: MfaService;\n /** MFA challenge-token lifetime in seconds. Default 300 (5 min). */\n mfaChallengeTtlSeconds?: number;\n}\n\n/** Returned by `login` when the user must complete an MFA challenge. */\nexport interface MfaChallenge {\n /** Discriminator: an MFA step is required before tokens are issued. */\n mfaRequired: true;\n /** Short-lived token to submit alongside the code to `verifyMfaChallenge`. */\n mfaToken: string;\n}\n\n/** `login` result: either full auth, or an MFA challenge to complete. */\nexport type LoginResult = AuthResponse | MfaChallenge;\n\n/** Project an {@link AuthUser} to its public shape (no secrets). */\nfunction toPublic(user: AuthUser): UserPublic {\n return {\n id: user.id,\n email: user.email,\n name: user.name,\n isActive: user.isActive,\n roles: user.roles,\n };\n}\n\nexport class UserAuthService {\n private readonly store: UserStore;\n private readonly password: PasswordUtils;\n private readonly jwt: JWTUtils;\n private readonly passwordMinLength: number;\n private readonly accessTtlSeconds: number;\n private readonly refreshTtlSeconds: number;\n private readonly mfa: MfaService | undefined;\n private readonly mfaChallengeTtlSeconds: number;\n\n /**\n * @param options - Store, password/JWT helpers and token policy.\n */\n constructor(options: UserAuthServiceOptions) {\n this.store = options.store;\n this.password = options.password;\n this.jwt = options.jwt;\n this.passwordMinLength = options.passwordMinLength ?? 12;\n this.accessTtlSeconds = options.accessTtlSeconds ?? 3600;\n this.refreshTtlSeconds = options.refreshTtlSeconds ?? 60 * 60 * 24 * 14;\n this.mfa = options.mfa;\n this.mfaChallengeTtlSeconds = options.mfaChallengeTtlSeconds ?? 300;\n }\n\n /** Mint a signed access + refresh token pair for `user`. */\n private async issueTokens(user: AuthUser): Promise<TokenPair> {\n const accessToken = await this.jwt.encode(\n { sub: user.id, roles: user.roles, type: \"access\" },\n { ttlSeconds: this.accessTtlSeconds },\n );\n const refreshToken = await this.jwt.encode(\n { sub: user.id, type: \"refresh\" },\n { ttlSeconds: this.refreshTtlSeconds },\n );\n return {\n accessToken,\n refreshToken,\n tokenType: \"bearer\",\n expiresIn: this.accessTtlSeconds,\n };\n }\n\n /**\n * Register a new user and issue tokens.\n *\n * @param data - Validated signup payload.\n * @returns The public user and a fresh token pair.\n * @throws {ValidationException} When the password is too short.\n * @throws {ConflictException} When the email is already registered.\n */\n async signup(data: SignupInput): Promise<AuthResponse> {\n if (data.password.length < this.passwordMinLength) {\n throw new ValidationException({\n message: `Password must be at least ${this.passwordMinLength} characters`,\n details: { minLength: this.passwordMinLength },\n });\n }\n const email = data.email.toLowerCase();\n if (await this.store.findByEmail(email)) {\n throw new ConflictException({ message: \"Email already registered\" });\n }\n const passwordHash = await this.password.hash(data.password);\n const user = await this.store.create({\n email,\n passwordHash,\n name: data.name ?? null,\n });\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n\n /**\n * Authenticate a user by email + password.\n *\n * @param data - Validated login payload.\n * @returns Full auth, or an {@link MfaChallenge} when MFA is enabled.\n * @throws {UnauthorizedException} On bad credentials or inactive account.\n */\n async login(data: LoginInput): Promise<LoginResult> {\n const user = await this.store.findByEmail(data.email.toLowerCase());\n const ok = user && (await this.password.verify(data.password, user.passwordHash));\n if (!user || !ok) {\n throw new UnauthorizedException({ message: \"Invalid email or password\" });\n }\n if (!user.isActive) {\n throw new UnauthorizedException({ message: \"Account is inactive\" });\n }\n if (this.mfa && (await this.mfa.isEnabled(user.id))) {\n const mfaToken = await this.jwt.encode(\n { sub: user.id, type: \"mfa\" },\n { ttlSeconds: this.mfaChallengeTtlSeconds },\n );\n return { mfaRequired: true, mfaToken };\n }\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n\n /**\n * Complete an MFA login challenge: verify the code and issue tokens.\n *\n * @param mfaToken - The challenge token from {@link login}.\n * @param code - The authenticator code.\n * @returns The public user and a fresh token pair.\n * @throws {UnauthorizedException} When the challenge/code is invalid, MFA is\n * not configured, or the account no longer exists / is inactive.\n */\n async verifyMfaChallenge(mfaToken: string, code: string): Promise<AuthResponse> {\n if (!this.mfa) throw new UnauthorizedException({ message: \"MFA not configured\" });\n const claims = await this.jwt.decodeOrNull(mfaToken);\n if (!claims || claims.type !== \"mfa\" || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Invalid MFA challenge\" });\n }\n if (!(await this.mfa.verify(claims.sub, code))) {\n throw new UnauthorizedException({ message: \"Invalid MFA code\" });\n }\n const user = await this.store.findById(claims.sub);\n if (!user || !user.isActive) {\n throw new UnauthorizedException({ message: \"Account is inactive\" });\n }\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n\n /**\n * Exchange a valid refresh token for a new token pair.\n *\n * @param refreshToken - The refresh token from a prior login.\n * @returns The public user and a fresh token pair.\n * @throws {UnauthorizedException} When the token is invalid or not a refresh\n * token, or the user no longer exists / is inactive.\n */\n async refresh(refreshToken: string): Promise<AuthResponse> {\n const claims = await this.jwt.decodeOrNull(refreshToken);\n if (!claims || claims.type !== \"refresh\" || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Invalid refresh token\" });\n }\n const user = await this.store.findById(claims.sub);\n if (!user || !user.isActive) {\n throw new UnauthorizedException({ message: \"Account is inactive\" });\n }\n return { user: toPublic(user), tokens: await this.issueTokens(user) };\n }\n}\n","/**\n * TOTP MFA enrollment/verification, mirroring the FastAPI SDK MFA flow.\n *\n * Orchestrates {@link TOTPHelper} over a pluggable {@link MfaStore}: enroll\n * (generate + persist a secret, return the provisioning URI), confirm (verify a\n * code and flip MFA on), verify (login step) and disable.\n */\n\nimport { ValidationException } from \"@/exceptions/http\";\nimport type { TOTPHelper } from \"@/utils/totp\";\n\n/** Persistence port for MFA secrets/state. */\nexport interface MfaStore {\n /** Persist a user's TOTP secret (pending until confirmed). */\n setSecret(userId: string, secret: string): Promise<void>;\n /** Read a user's TOTP secret, or `null`. */\n getSecret(userId: string): Promise<string | null>;\n /** Flip the MFA-enabled flag. */\n setEnabled(userId: string, enabled: boolean): Promise<void>;\n /** Whether MFA is enabled for the user. */\n isEnabled(userId: string): Promise<boolean>;\n}\n\n/** The result of starting enrollment. */\nexport interface MfaEnrollment {\n /** The base32 secret (persist server-side; also shown once for manual entry). */\n secret: string;\n /** The `otpauth://` URI to render as a QR code. */\n otpauthUri: string;\n}\n\n/** Options for {@link MfaService}. */\nexport interface MfaServiceOptions {\n /** The MFA persistence port. */\n store: MfaStore;\n /** The TOTP helper (issuer preconfigured). */\n totp: TOTPHelper;\n}\n\nexport class MfaService {\n private readonly store: MfaStore;\n private readonly totp: TOTPHelper;\n\n /**\n * @param options - Store and TOTP helper.\n */\n constructor(options: MfaServiceOptions) {\n this.store = options.store;\n this.totp = options.totp;\n }\n\n /**\n * Begin enrollment: generate and persist a secret, return the QR URI.\n *\n * @param userId - The enrolling user.\n * @param accountName - Label shown in the authenticator (usually the email).\n * @returns The secret and provisioning URI.\n */\n async enroll(userId: string, accountName: string): Promise<MfaEnrollment> {\n const secret = this.totp.generateSecret();\n await this.store.setSecret(userId, secret);\n await this.store.setEnabled(userId, false);\n return { secret, otpauthUri: this.totp.provisioningUri(secret, accountName) };\n }\n\n /**\n * Confirm enrollment by verifying a code, enabling MFA on success.\n *\n * @param userId - The user.\n * @param code - The 6-digit code from the authenticator.\n * @throws {ValidationException} When no secret is pending or the code is wrong.\n */\n async confirm(userId: string, code: string): Promise<void> {\n const secret = await this.store.getSecret(userId);\n if (!secret) throw new ValidationException({ message: \"MFA not initialized\" });\n if (!this.totp.verify(secret, code)) {\n throw new ValidationException({ message: \"Invalid MFA code\" });\n }\n await this.store.setEnabled(userId, true);\n }\n\n /**\n * Verify a code (login step). Returns `false` without throwing.\n *\n * @param userId - The user.\n * @param code - The submitted code.\n * @returns `true` when the code is valid.\n */\n async verify(userId: string, code: string): Promise<boolean> {\n const secret = await this.store.getSecret(userId);\n return secret ? this.totp.verify(secret, code) : false;\n }\n\n /**\n * Whether MFA is enabled for a user (used to gate the login challenge).\n *\n * @param userId - The user.\n * @returns `true` when MFA is enabled.\n */\n async isEnabled(userId: string): Promise<boolean> {\n return this.store.isEnabled(userId);\n }\n\n /**\n * Disable MFA after verifying a code.\n *\n * @param userId - The user.\n * @param code - The submitted code.\n * @throws {ValidationException} When the code is invalid.\n */\n async disable(userId: string, code: string): Promise<void> {\n if (!(await this.verify(userId, code))) {\n throw new ValidationException({ message: \"Invalid MFA code\" });\n }\n await this.store.setEnabled(userId, false);\n await this.store.setSecret(userId, \"\");\n }\n}\n","/**\n * Email-activation flow, mirroring the FastAPI SDK activation flow.\n *\n * Issues a single-use opaque token (only its SHA-256 hash is stored), emails\n * the plaintext to the user, and activates the account when the link is opened.\n */\n\nimport { InvalidTokenException } from \"@/exceptions/http\";\nimport { generateOpaqueToken, hashOpaqueToken } from \"@/utils/opaqueToken\";\n\n/** Persistence port for activation tokens. */\nexport interface ActivationStore {\n /** Persist a token hash + expiry (epoch ms) for a user. */\n saveActivationToken(\n userId: string,\n tokenHash: string,\n expiresAt: number,\n ): Promise<void>;\n /** Look up a token hash, returning the owner + expiry, or `null`. */\n findActivationToken(\n tokenHash: string,\n ): Promise<{ userId: string; expiresAt: number } | null>;\n /** Remove a token hash (single-use). */\n clearActivationToken(tokenHash: string): Promise<void>;\n /** Mark a user active. */\n activate(userId: string): Promise<void>;\n}\n\n/** Options for {@link ActivationService}. */\nexport interface ActivationServiceOptions {\n /** The activation persistence port. */\n store: ActivationStore;\n /** Token lifetime in seconds. Default 86400 (24h). */\n ttlSeconds?: number;\n}\n\nexport class ActivationService {\n private readonly store: ActivationStore;\n private readonly ttlSeconds: number;\n\n /**\n * @param options - Store and token TTL.\n */\n constructor(options: ActivationServiceOptions) {\n this.store = options.store;\n this.ttlSeconds = options.ttlSeconds ?? 60 * 60 * 24;\n }\n\n /**\n * Start activation: issue a token and persist its hash.\n *\n * @param userId - The user to activate.\n * @returns The one-time plaintext token (embed in the activation link).\n */\n async start(userId: string): Promise<string> {\n const { plaintext, tokenHash } = generateOpaqueToken();\n await this.store.saveActivationToken(\n userId,\n tokenHash,\n Date.now() + this.ttlSeconds * 1000,\n );\n return plaintext;\n }\n\n /**\n * Activate an account from a token.\n *\n * @param token - The plaintext token from the activation link.\n * @returns The activated user id.\n * @throws {InvalidTokenException} When the token is unknown or expired.\n */\n async activate(token: string): Promise<string> {\n const tokenHash = hashOpaqueToken(token);\n const record = await this.store.findActivationToken(tokenHash);\n if (!record || record.expiresAt <= Date.now()) {\n throw new InvalidTokenException({ message: \"Invalid or expired activation token\" });\n }\n await this.store.activate(record.userId);\n await this.store.clearActivationToken(tokenHash);\n return record.userId;\n }\n}\n","/**\n * Password-reset flow, mirroring the FastAPI SDK reset flow.\n *\n * `request` issues a single-use opaque token (hash stored) for a known email,\n * returning it so the caller can email the reset link — without leaking whether\n * the email exists. `confirm` validates the token + new password and rehashes.\n */\n\nimport { InvalidTokenException, ValidationException } from \"@/exceptions/http\";\nimport { generateOpaqueToken, hashOpaqueToken } from \"@/utils/opaqueToken\";\nimport type { PasswordUtils } from \"@/utils/password\";\n\n/** Persistence port for password resets. */\nexport interface PasswordResetStore {\n /** Resolve a (lowercased) email to a user id, or `null`. */\n findUserIdByEmail(email: string): Promise<string | null>;\n /** Persist a reset token hash + expiry (epoch ms). */\n saveResetToken(userId: string, tokenHash: string, expiresAt: number): Promise<void>;\n /** Look up a reset token hash, returning owner + expiry, or `null`. */\n findResetToken(\n tokenHash: string,\n ): Promise<{ userId: string; expiresAt: number } | null>;\n /** Remove a reset token hash (single-use). */\n clearResetToken(tokenHash: string): Promise<void>;\n /** Overwrite a user's password hash. */\n updatePassword(userId: string, passwordHash: string): Promise<void>;\n}\n\n/** Options for {@link PasswordResetService}. */\nexport interface PasswordResetServiceOptions {\n /** The reset persistence port. */\n store: PasswordResetStore;\n /** Password hasher. */\n password: PasswordUtils;\n /** Token lifetime in seconds. Default 3600 (1h). */\n ttlSeconds?: number;\n /** Minimum new-password length. Default 12. */\n passwordMinLength?: number;\n}\n\nexport class PasswordResetService {\n private readonly store: PasswordResetStore;\n private readonly password: PasswordUtils;\n private readonly ttlSeconds: number;\n private readonly passwordMinLength: number;\n\n /**\n * @param options - Store, password hasher and policy.\n */\n constructor(options: PasswordResetServiceOptions) {\n this.store = options.store;\n this.password = options.password;\n this.ttlSeconds = options.ttlSeconds ?? 3600;\n this.passwordMinLength = options.passwordMinLength ?? 12;\n }\n\n /**\n * Request a reset for `email`.\n *\n * Returns the plaintext token only when the email maps to a user; otherwise\n * `null`. Callers should respond with the same success shape either way to\n * avoid user enumeration — email the token only when present.\n *\n * @param email - The account email.\n * @returns The one-time token, or `null` when no user matches.\n */\n async request(email: string): Promise<string | null> {\n const userId = await this.store.findUserIdByEmail(email.toLowerCase());\n if (!userId) return null;\n const { plaintext, tokenHash } = generateOpaqueToken();\n await this.store.saveResetToken(\n userId,\n tokenHash,\n Date.now() + this.ttlSeconds * 1000,\n );\n return plaintext;\n }\n\n /**\n * Confirm a reset: validate the token + new password and rehash.\n *\n * @param token - The plaintext reset token.\n * @param newPassword - The new plaintext password.\n * @throws {ValidationException} When the new password is too short.\n * @throws {InvalidTokenException} When the token is unknown or expired.\n */\n async confirm(token: string, newPassword: string): Promise<void> {\n if (newPassword.length < this.passwordMinLength) {\n throw new ValidationException({\n message: `Password must be at least ${this.passwordMinLength} characters`,\n details: { minLength: this.passwordMinLength },\n });\n }\n const tokenHash = hashOpaqueToken(token);\n const record = await this.store.findResetToken(tokenHash);\n if (!record || record.expiresAt <= Date.now()) {\n throw new InvalidTokenException({ message: \"Invalid or expired reset token\" });\n }\n await this.store.updatePassword(record.userId, await this.password.hash(newPassword));\n await this.store.clearResetToken(tokenHash);\n }\n}\n","/**\n * JWT auth middleware + role guards, mirroring `api.dependencies.auth`.\n *\n * {@link makeJwtAuthMiddleware} decodes a `Bearer` token and attaches the\n * claims to `req.auth`; {@link requireRoles} gates a route on role membership.\n * Failures raise the SDK's {@link UnauthorizedException} / {@link ForbiddenException}\n * so they render as the canonical error envelope.\n */\n\nimport { ForbiddenException, UnauthorizedException } from \"@/exceptions/http\";\nimport type { JWTUtils, JwtClaims } from \"@/utils/jwt\";\nimport type { Request, RequestHandler } from \"express\";\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/no-namespace\n namespace Express {\n /** Decoded JWT claims, populated by {@link makeJwtAuthMiddleware}. */\n interface Request {\n auth?: JwtClaims;\n }\n }\n}\n\n/** Extract a `Bearer` token from the `Authorization` header, or `null`. */\nexport function bearerToken(req: Request): string | null {\n const header = req.header(\"authorization\");\n if (!header) return null;\n const [scheme, token] = header.split(\" \");\n if (scheme?.toLowerCase() !== \"bearer\" || !token) return null;\n return token;\n}\n\n/** Read the decoded claims attached by the auth middleware, or `null`. */\nexport function getAuth(req: Request): JwtClaims | null {\n return req.auth ?? null;\n}\n\n/** Options for {@link makeJwtAuthMiddleware}. */\nexport interface JwtAuthOptions {\n /** When `true` (default), a missing/invalid token rejects with 401. */\n required?: boolean;\n}\n\n/**\n * Build middleware that decodes the bearer token and sets `req.auth`.\n *\n * @param jwt - The JWT helper used to verify tokens.\n * @param options - Whether authentication is required.\n * @returns An Express middleware.\n */\nexport function makeJwtAuthMiddleware(\n jwt: JWTUtils,\n options: JwtAuthOptions = {},\n): RequestHandler {\n const required = options.required ?? true;\n return (req, _res, next) => {\n const token = bearerToken(req);\n if (!token) {\n if (required) {\n next(new UnauthorizedException({ message: \"Missing bearer token\" }));\n return;\n }\n next();\n return;\n }\n jwt\n .decode(token)\n .then((claims) => {\n req.auth = claims;\n next();\n })\n .catch((error: unknown) => {\n if (required) next(error);\n else next();\n });\n };\n}\n\n/**\n * Build middleware that requires the authenticated user to hold at least one\n * of `roles` (read from the `roles` claim). Must run after the auth middleware.\n *\n * @param roles - Acceptable role names.\n * @returns An Express middleware.\n */\nexport function requireRoles(...roles: string[]): RequestHandler {\n return (req, _res, next) => {\n const claims = req.auth;\n if (!claims) {\n next(new UnauthorizedException({ message: \"Not authenticated\" }));\n return;\n }\n const held = Array.isArray(claims.roles) ? (claims.roles as unknown[]) : [];\n if (roles.some((role) => held.includes(role))) {\n next();\n return;\n }\n next(new ForbiddenException({ message: \"Insufficient role\", details: { roles } }));\n };\n}\n","/**\n * Auth router, mirroring `auth.router.make_auth_router`.\n *\n * Wires `POST /auth/signup`, `POST /auth/login`, `POST /auth/refresh` and a\n * guarded `GET /auth/me` to a {@link UserAuthService}. Pass an\n * {@link OpenAPIRegistry} to register the paths so they appear in Swagger/Redoc.\n */\n\nimport type { OpenAPIRegistry } from \"@/api/openapi\";\nimport type { ActivationService } from \"@/auth/activation\";\nimport type { MfaService } from \"@/auth/mfa\";\nimport { getAuth, makeJwtAuthMiddleware } from \"@/auth/middleware\";\nimport type { PasswordResetService } from \"@/auth/passwordReset\";\nimport {\n activationSchema,\n authResponseSchema,\n loginSchema,\n mfaChallengeSchema,\n mfaCodeSchema,\n passwordResetConfirmSchema,\n passwordResetRequestSchema,\n refreshSchema,\n signupSchema,\n userPublicSchema,\n} from \"@/auth/schemas\";\nimport type { UserAuthService } from \"@/auth/service\";\nimport { UnauthorizedException } from \"@/exceptions/http\";\nimport type { JWTUtils } from \"@/utils/jwt\";\nimport { type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link makeAuthRouter}. */\nexport interface AuthRouterOptions {\n /** The authentication service handling the flows. */\n service: UserAuthService;\n /** The JWT helper used to guard `GET /auth/me`. */\n jwt: JWTUtils;\n /** Route prefix. Default `/auth`. */\n prefix?: string;\n /** When provided, OpenAPI paths are registered for Swagger/Redoc. */\n registry?: OpenAPIRegistry;\n /** Mount `POST /auth/activate` when provided. */\n activation?: ActivationService;\n /** Mount `POST /auth/password-reset/{request,confirm}` when provided. */\n passwordReset?: PasswordResetService;\n /**\n * Mount guarded `POST /auth/mfa/{enroll,confirm,disable}` when provided. The\n * enrolling account label defaults to the `email` claim (falls back to `sub`).\n */\n mfa?: MfaService;\n}\n\n/** Register the auth OpenAPI paths on `registry`. */\nfunction registerPaths(registry: OpenAPIRegistry, prefix: string): void {\n const json = (schema: unknown) => ({\n content: { \"application/json\": { schema: schema as never } },\n });\n registry.registerPath({\n method: \"post\",\n path: `${prefix}/signup`,\n summary: \"Register a new user\",\n request: { body: json(signupSchema) },\n responses: { 201: { description: \"Created\", ...json(authResponseSchema) } },\n });\n registry.registerPath({\n method: \"post\",\n path: `${prefix}/login`,\n summary: \"Authenticate and receive tokens\",\n request: { body: json(loginSchema) },\n responses: { 200: { description: \"OK\", ...json(authResponseSchema) } },\n });\n registry.registerPath({\n method: \"post\",\n path: `${prefix}/refresh`,\n summary: \"Exchange a refresh token for new tokens\",\n request: { body: json(refreshSchema) },\n responses: { 200: { description: \"OK\", ...json(authResponseSchema) } },\n });\n registry.registerPath({\n method: \"get\",\n path: `${prefix}/me`,\n summary: \"Current authenticated user\",\n security: [{ bearerAuth: [] }],\n responses: { 200: { description: \"OK\", ...json(userPublicSchema) } },\n });\n}\n\n/**\n * Build the auth router.\n *\n * @param options - Service, JWT helper, prefix and optional OpenAPI registry.\n * @returns An Express router exposing the auth endpoints.\n */\nexport function makeAuthRouter(options: AuthRouterOptions): Router {\n const { service, jwt, prefix = \"/auth\", registry } = options;\n if (registry) registerPaths(registry, prefix);\n\n const router = createRouter();\n\n router.post(`${prefix}/signup`, async (req, res) => {\n const result = await service.signup(signupSchema.parse(req.body));\n res.status(201).json(result);\n });\n\n router.post(`${prefix}/login`, async (req, res) => {\n res.json(await service.login(loginSchema.parse(req.body)));\n });\n\n router.post(`${prefix}/refresh`, async (req, res) => {\n const { refreshToken } = refreshSchema.parse(req.body);\n res.json(await service.refresh(refreshToken));\n });\n\n router.get(`${prefix}/me`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const claims = getAuth(req);\n if (!claims || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Not authenticated\" });\n }\n res.json(claims);\n });\n\n if (options.activation) {\n const activation = options.activation;\n router.post(`${prefix}/activate`, async (req, res) => {\n const { token } = activationSchema.parse(req.body);\n const userId = await activation.activate(token);\n res.json({ activated: true, userId });\n });\n }\n\n if (options.passwordReset) {\n const reset = options.passwordReset;\n // Always 202 — never reveal whether the email exists. `token` is returned\n // only in dev-style setups where the caller emails it themselves.\n router.post(`${prefix}/password-reset/request`, async (req, res) => {\n const { email } = passwordResetRequestSchema.parse(req.body);\n const token = await reset.request(email);\n res.status(202).json({ requested: true, ...(token ? { token } : {}) });\n });\n router.post(`${prefix}/password-reset/confirm`, async (req, res) => {\n const { token, password } = passwordResetConfirmSchema.parse(req.body);\n await reset.confirm(token, password);\n res.json({ reset: true });\n });\n }\n\n if (options.mfa) {\n const mfa = options.mfa;\n // Unguarded: completes the login challenge using the short-lived mfaToken.\n router.post(`${prefix}/mfa/challenge`, async (req, res) => {\n const { mfaToken, code } = mfaChallengeSchema.parse(req.body);\n res.json(await service.verifyMfaChallenge(mfaToken, code));\n });\n const requireUser = (req: Parameters<typeof getAuth>[0]): string => {\n const claims = getAuth(req);\n if (!claims || typeof claims.sub !== \"string\") {\n throw new UnauthorizedException({ message: \"Not authenticated\" });\n }\n return claims.sub;\n };\n router.post(`${prefix}/mfa/enroll`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const claims = getAuth(req);\n const userId = requireUser(req);\n const label = typeof claims?.email === \"string\" ? claims.email : userId;\n res.json(await mfa.enroll(userId, label));\n });\n router.post(`${prefix}/mfa/confirm`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const { code } = mfaCodeSchema.parse(req.body);\n await mfa.confirm(requireUser(req), code);\n res.json({ enabled: true });\n });\n router.post(`${prefix}/mfa/disable`, makeJwtAuthMiddleware(jwt), async (req, res) => {\n const { code } = mfaCodeSchema.parse(req.body);\n await mfa.disable(requireUser(req), code);\n res.json({ enabled: false });\n });\n }\n\n return router;\n}\n","/**\n * Optional server-rendered HTML pages for the bundled auth flows, mirroring the\n * FastAPI SDK's activation/reset templates.\n *\n * This SDK favors the JSON auth API + a decoupled frontend, but a link in an\n * email (activation, password reset) sometimes has to land on a *server* page —\n * there's no SPA to route to. These helpers render small, self-contained,\n * theme-aware HTML pages (no template engine, no external assets) for exactly\n * those landings.\n */\n\n/** Escape a string for safe interpolation into HTML text/attributes. */\nfunction esc(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\nconst STYLE = `\n :root { color-scheme: light dark; }\n body { font: 16px/1.5 system-ui, sans-serif; margin: 0; display: grid; min-height: 100vh; place-items: center; background: #f6f7f9; color: #1a1a1a; }\n @media (prefers-color-scheme: dark) { body { background: #16181d; color: #e8e8e8; } .card { background: #1f2229 !important; } input { background: #16181d !important; color: inherit !important; border-color: #3a3f4b !important; } }\n .card { background: #fff; max-width: 26rem; width: calc(100% - 3rem); padding: 2rem; border-radius: 14px; box-shadow: 0 6px 30px rgba(0,0,0,.08); text-align: center; }\n h1 { font-size: 1.4rem; margin: 0 0 .5rem; }\n p { margin: .25rem 0 1rem; opacity: .85; }\n .ico { font-size: 2.5rem; }\n a.btn, button.btn { display: inline-block; margin-top: .5rem; padding: .6rem 1.2rem; border-radius: 9px; border: 0; background: #4f46e5; color: #fff; text-decoration: none; font-weight: 600; cursor: pointer; }\n form { text-align: left; margin-top: 1rem; }\n label { display: block; font-size: .85rem; font-weight: 600; margin-bottom: .3rem; }\n input { width: 100%; box-sizing: border-box; padding: .6rem .7rem; border: 1px solid #d0d3d9; border-radius: 9px; font: inherit; }\n`;\n\nfunction page(title: string, body: string): string {\n return `<!doctype html>\n<html lang=\"pt-BR\">\n<head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>${esc(title)}</title><style>${STYLE}</style></head>\n<body><main class=\"card\">${body}</main></body>\n</html>`;\n}\n\n/** Options for {@link renderAuthResultPage}. */\nexport interface AuthResultPageOptions {\n /** `true` renders a success state, `false` an error state. */\n ok: boolean;\n /** Page + heading title. */\n title: string;\n /** Body message. */\n message: string;\n /** Optional call-to-action link. */\n cta?: { href: string; label: string };\n}\n\n/**\n * Render a success/error result page (e.g. \"account activated\", \"link\n * expired\").\n *\n * @param options - Success flag, title, message and an optional CTA.\n * @returns A complete HTML document.\n */\nexport function renderAuthResultPage(options: AuthResultPageOptions): string {\n const icon = options.ok ? \"✅\" : \"⚠️\";\n const cta = options.cta\n ? `<a class=\"btn\" href=\"${esc(options.cta.href)}\">${esc(options.cta.label)}</a>`\n : \"\";\n return page(\n options.title,\n `<div class=\"ico\">${icon}</div><h1>${esc(options.title)}</h1><p>${esc(options.message)}</p>${cta}`,\n );\n}\n\n/** Options for {@link renderPasswordResetFormPage}. */\nexport interface PasswordResetFormOptions {\n /** Form POST target. */\n action: string;\n /** The reset token, embedded as a hidden field. */\n token: string;\n /** Page + heading title. Default `\"Redefinir senha\"`. */\n title?: string;\n /** Name of the hidden token field. Default `\"token\"`. */\n tokenField?: string;\n /** Name of the password field. Default `\"password\"`. */\n passwordField?: string;\n /** Submit button label. Default `\"Redefinir senha\"`. */\n submitLabel?: string;\n}\n\n/**\n * Render a \"set a new password\" form that POSTs the token + new password to\n * `action`.\n *\n * @param options - Form action, token and field/label overrides.\n * @returns A complete HTML document.\n */\nexport function renderPasswordResetFormPage(options: PasswordResetFormOptions): string {\n const title = options.title ?? \"Redefinir senha\";\n const tokenField = options.tokenField ?? \"token\";\n const passwordField = options.passwordField ?? \"password\";\n const submitLabel = options.submitLabel ?? \"Redefinir senha\";\n return page(\n title,\n `<h1>${esc(title)}</h1>\n <form method=\"post\" action=\"${esc(options.action)}\">\n <input type=\"hidden\" name=\"${esc(tokenField)}\" value=\"${esc(options.token)}\">\n <label for=\"pw\">Nova senha</label>\n <input id=\"pw\" type=\"password\" name=\"${esc(passwordField)}\" required minlength=\"8\" autocomplete=\"new-password\">\n <button class=\"btn\" type=\"submit\" style=\"margin-top:1rem;width:100%\">${esc(submitLabel)}</button>\n </form>`,\n );\n}\n","/**\n * Express error handling, mirroring `api.handlers`.\n *\n * Produces the canonical SDK envelope `{ detail, code, details }` for every\n * failure path: {@link AppException} subclasses, Zod validation errors (→ 422),\n * unmatched routes (→ 404) and uncaught errors (→ 500). A {@link MessageCatalog}\n * localizes `detail` from the request `Accept-Language` header. Server errors\n * are logged with the {@link HTTP_500_MARKER} flag for sink routing.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport {\n HTTP_500_MARKER,\n JSONLogger,\n type LogLevel,\n runWithRequestContext,\n} from \"@/core\";\nimport { AppException, type ExceptionDetails } from \"@/exceptions/base\";\nimport { DEFAULT_LOCALE, type MessageCatalog } from \"@/exceptions/i18n\";\nimport type { ErrorRequestHandler, Express, RequestHandler } from \"express\";\nimport { ZodError } from \"zod\";\n\nconst logger = new JSONLogger(\"tempest_express_sdk.api.handlers\");\n\n/** Header carrying the per-request correlation id. */\nexport const REQUEST_ID_HEADER = \"X-Request-ID\";\n\n/**\n * Whitelist for inbound request IDs: printable ASCII, no whitespace or control\n * characters, so a spoofed header can't inject CRLF into log lines or the\n * echoed response header. Generous enough for UUIDs, ULIDs and trace IDs.\n */\nconst VALID_REQUEST_ID = /^[A-Za-z0-9._\\-:+/=]{1,128}$/;\n\n/**\n * Middleware that establishes a request id and binds the request context.\n *\n * Reuses an inbound `X-Request-ID` when present **and well-formed**, otherwise\n * generates one, sets it on the response, and runs the rest of the chain inside\n * {@link runWithRequestContext} so loggers and handlers can read it.\n *\n * @returns The configured middleware.\n */\nexport function requestIdMiddleware(): RequestHandler {\n return (req, res, next) => {\n const inbound = req.header(REQUEST_ID_HEADER);\n const requestId = inbound && VALID_REQUEST_ID.test(inbound) ? inbound : randomUUID();\n res.setHeader(REQUEST_ID_HEADER, requestId);\n runWithRequestContext({ requestId }, () => next());\n };\n}\n\n/** Options for {@link makeAppExceptionHandler}. */\nexport interface AppExceptionHandlerOptions {\n /** Catalog used to localize `detail`; `null` keeps the literal message. */\n catalog?: MessageCatalog | null;\n /** Locale used when `Accept-Language` is absent or unmatched. */\n defaultLocale?: string;\n /** Level used for 5xx `AppException` records (4xx always logs at `info`). */\n serverErrorLevel?: LogLevel;\n}\n\n/** Serialize an {@link AppException} to the envelope and write the response. */\nfunction writeAppException(\n res: Parameters<ErrorRequestHandler>[2],\n exc: AppException,\n detail: string,\n): void {\n for (const [name, value] of Object.entries(exc.headers)) res.setHeader(name, value);\n res.status(exc.statusCode).json({\n detail,\n code: exc.code,\n details: exc.details,\n });\n}\n\n/**\n * Build the error middleware for {@link AppException} subclasses.\n *\n * Zod errors are coerced into a 422 envelope (`code: \"VALIDATION_ERROR\"`) with\n * the field issues under `details.issues`. Anything else is passed to `next`.\n *\n * @param options - Localization and logging options.\n * @returns An Express error middleware.\n */\nexport function makeAppExceptionHandler(\n options: AppExceptionHandlerOptions = {},\n): ErrorRequestHandler {\n const {\n catalog = null,\n defaultLocale = DEFAULT_LOCALE,\n serverErrorLevel = \"info\",\n } = options;\n\n return (err, req, res, next) => {\n let exc: AppException;\n if (err instanceof AppException) {\n exc = err;\n } else if (err instanceof ZodError) {\n const details: ExceptionDetails = { issues: err.issues };\n exc = new AppException({\n message: \"Validation error\",\n code: \"VALIDATION_ERROR\",\n statusCode: 422,\n details,\n });\n } else {\n next(err);\n return;\n }\n\n const isServerError = exc.statusCode >= 500;\n logger.log(isServerError ? serverErrorLevel : \"info\", \"AppException handled\", {\n path: req.path,\n method: req.method,\n statusCode: exc.statusCode,\n code: exc.code,\n ...(isServerError ? { [HTTP_500_MARKER]: true, stack: exc.stack } : {}),\n });\n\n let detail = exc.message;\n if (catalog) {\n const locale = catalog.negotiate(req.header(\"accept-language\"), defaultLocale);\n const localized = catalog.resolve(\n exc.messageKey ?? exc.code,\n locale,\n exc.messageParams,\n );\n if (localized !== null) detail = localized;\n }\n writeAppException(res, exc, detail);\n };\n}\n\n/** Options for {@link makeUnhandledExceptionHandler}. */\nexport interface UnhandledExceptionHandlerOptions {\n /** Surface the stack under `details.stack` (development only). */\n includeStack?: boolean;\n /** Level used to log the failure. */\n logLevel?: LogLevel;\n}\n\n/**\n * Build the catch-all error middleware for non-{@link AppException} errors.\n *\n * Logs the failure (flagged with {@link HTTP_500_MARKER}) and returns the\n * canonical 500 envelope. With `includeStack` the stack is added to the body —\n * never enable in production.\n *\n * @param options - Stack-exposure and logging options.\n * @returns An Express error middleware.\n */\nexport function makeUnhandledExceptionHandler(\n options: UnhandledExceptionHandlerOptions = {},\n): ErrorRequestHandler {\n const { includeStack = false, logLevel = \"error\" } = options;\n\n return (err, req, res, _next) => {\n const error = err instanceof Error ? err : new Error(String(err));\n logger.log(logLevel, \"Unhandled exception\", {\n path: req.path,\n method: req.method,\n [HTTP_500_MARKER]: true,\n stack: error.stack,\n });\n const details: ExceptionDetails = includeStack ? { stack: error.stack } : {};\n res.status(500).json({\n detail: \"Internal server error\",\n code: \"INTERNAL_SERVER_ERROR\",\n details,\n });\n };\n}\n\n/**\n * Build the fallback 404 handler for unmatched routes.\n *\n * @returns A request handler emitting the canonical 404 envelope.\n */\nexport function notFoundHandler(): RequestHandler {\n return (req, res) => {\n res.status(404).json({\n detail: `No route for ${req.method} ${req.path}`,\n code: \"NOT_FOUND\",\n details: {},\n });\n };\n}\n\n/** Options for {@link registerExceptionHandlers}. */\nexport interface RegisterExceptionHandlersOptions\n extends AppExceptionHandlerOptions,\n UnhandledExceptionHandlerOptions {\n /** Register the {@link notFoundHandler} for unmatched routes. Default `true`. */\n notFound?: boolean;\n}\n\n/**\n * Register the full error-handling stack on an Express app.\n *\n * Call this AFTER all routers are mounted. Order: 404 fallback (optional) →\n * {@link AppException}/Zod handler → catch-all 500 handler.\n *\n * @param app - The Express application.\n * @param options - Localization, logging and 404 options.\n */\nexport function registerExceptionHandlers(\n app: Express,\n options: RegisterExceptionHandlersOptions = {},\n): void {\n const { notFound = true, includeStack, logLevel, ...appOptions } = options;\n if (notFound) app.use(notFoundHandler());\n app.use(makeAppExceptionHandler(appOptions));\n app.use(\n makeUnhandledExceptionHandler({\n ...(includeStack !== undefined ? { includeStack } : {}),\n ...(logLevel !== undefined ? { logLevel } : {}),\n }),\n );\n}\n","/**\n * OpenAPI document generation from Zod schemas.\n *\n * Thin wrapper over `@asteasolutions/zod-to-openapi`. Register schemas and\n * paths on a {@link OpenAPIRegistry}, then call {@link generateOpenApiDocument}\n * to produce a spec that drives both Swagger UI and Redoc. Because every SDK\n * schema is built from the `.openapi()`-augmented `z`, descriptions, examples\n * and component names flow straight into the document.\n */\n\nimport {\n OpenAPIRegistry,\n OpenApiGeneratorV3,\n OpenApiGeneratorV31,\n} from \"@asteasolutions/zod-to-openapi\";\n\nexport { OpenAPIRegistry };\n\n/** The config object accepted by the generator's `generateDocument`. */\ntype OpenApiDocumentConfig = Parameters<OpenApiGeneratorV3[\"generateDocument\"]>[0];\n\n/** Minimal `info` block for the generated document. */\nexport interface OpenApiInfo {\n /** API title shown in the docs header. */\n title: string;\n /** API version string. */\n version: string;\n /** Optional long description (Markdown supported by the renderers). */\n description?: string;\n}\n\n/** Options for {@link generateOpenApiDocument}. */\nexport interface GenerateOpenApiOptions {\n /** The document `info` block. */\n info: OpenApiInfo;\n /** Server entries (`{ url, description }`). */\n servers?: Array<{ url: string; description?: string }>;\n /** Emit OpenAPI 3.1 instead of 3.0. Default `false` (3.0). */\n v31?: boolean;\n}\n\n/**\n * Create a fresh, empty {@link OpenAPIRegistry}.\n *\n * @returns A registry to register schemas and paths on.\n */\nexport function createOpenApiRegistry(): OpenAPIRegistry {\n return new OpenAPIRegistry();\n}\n\n/**\n * Generate an OpenAPI document from a populated registry.\n *\n * @param registry - The registry holding registered schemas and paths.\n * @param options - The `info` block, optional servers and version flag.\n * @returns The generated OpenAPI document (plain object, JSON-serializable).\n */\nexport function generateOpenApiDocument(\n registry: OpenAPIRegistry,\n options: GenerateOpenApiOptions,\n): Record<string, unknown> {\n const config: OpenApiDocumentConfig = {\n openapi: options.v31 ? \"3.1.0\" : \"3.0.0\",\n info: {\n title: options.info.title,\n version: options.info.version,\n ...(options.info.description !== undefined\n ? { description: options.info.description }\n : {}),\n },\n ...(options.servers !== undefined ? { servers: options.servers } : {}),\n };\n const Generator = options.v31 ? OpenApiGeneratorV31 : OpenApiGeneratorV3;\n const document = new Generator(registry.definitions).generateDocument(config);\n return document as unknown as Record<string, unknown>;\n}\n","/**\n * Native Swagger UI and Redoc mounting from a generated OpenAPI document.\n *\n * Swagger UI is served fully self-contained: its static assets ship with the\n * `swagger-ui-dist` dependency and are mounted locally (no CDN), with a small\n * inline initializer pointing at the spec endpoint.\n *\n * Redoc's renderer is ~1 MB and is **not** vendored — the `redoc` package pulls\n * 22 dependencies and peers on `react`, `react-dom`, `styled-components`,\n * `mobx` and `core-js`, bounds no backend service should inherit just to render\n * a reference page. It is an **optional peer** instead: install `redoc` and\n * {@link mountRedoc} serves its standalone bundle from disk, so the page works\n * offline; without it the page falls back to the jsDelivr CDN and says so\n * out loud when the network blocks the bundle.\n *\n * Both pages declare an inline `<link rel=\"icon\">`. Without one the browser\n * requests `/favicon.ico` at the origin root, which on an API-only service is a\n * 401, a 404 or an SPA catch-all — a red console error on every page load.\n */\n\nimport { createRequire } from \"node:module\";\nimport { join } from \"node:path\";\nimport express, { type Express, type RequestHandler } from \"express\";\nimport { getAbsoluteFSPath } from \"swagger-ui-dist\";\n\n/** A JSON-serializable OpenAPI document. */\nexport type OpenApiDocument = Record<string, unknown>;\n\n/**\n * The bundled default favicon: a small SVG bolt as a `data:` URI.\n *\n * Inline on purpose — an asset route would be one more thing to mount, and the\n * whole point is to stop the browser from issuing a request the service cannot\n * answer. Pass {@link SwaggerOptions.favicon} to override it, or `false` to emit\n * no tag at all and let the browser fall back to `/favicon.ico`.\n */\nexport const DEFAULT_DOCS_FAVICON =\n \"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PHJlY3Qgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiByeD0iNyIgZmlsbD0iIzRjNmVmNSIvPjxwYXRoIGQ9Ik0xNy45IDQuNSA4LjYgMTguNGg1LjJMMTMgMjcuNWw5LjQtMTMuOWgtNS4zeiIgZmlsbD0iI2ZmZiIvPjwvc3ZnPg==\";\n\n/** The jsDelivr URL used when no local Redoc bundle is available. */\nexport const REDOC_CDN_URL =\n \"https://cdn.jsdelivr.net/npm/redoc@2/bundles/redoc.standalone.js\";\n\n/** Path the `redoc` package publishes its standalone browser bundle at. */\nconst REDOC_BUNDLE_SPECIFIER = \"redoc/bundles/redoc.standalone.js\";\n\n/**\n * Escape a value for interpolation into HTML text or a quoted attribute.\n *\n * Page titles and favicon URLs come from the caller, and a caller reading them\n * from configuration is reading them from outside the program.\n *\n * @param value - The raw value.\n * @returns The escaped value.\n */\nfunction 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 * Serialize a value as a JavaScript literal safe to inline in a `<script>`.\n *\n * `JSON.stringify` alone is not: a `</script>` inside the string closes the\n * element early, so `<` is escaped to its `<` form.\n *\n * @param value - The value to serialize.\n * @returns The escaped JavaScript literal.\n */\nfunction scriptLiteral(value: unknown): string {\n return JSON.stringify(value).replace(/</g, \"\\\\u003c\");\n}\n\n/**\n * Build the `<link rel=\"icon\">` tag for a docs page.\n *\n * @param favicon - The favicon URL, or `false` to emit nothing.\n * @returns The tag, or an empty string.\n */\nfunction faviconTag(favicon: string | false): string {\n if (favicon === false) return \"\";\n return `\\n <link rel=\"icon\" href=\"${escapeHtml(favicon)}\" />`;\n}\n\n/**\n * Mount the OpenAPI document as JSON at `path`.\n *\n * @param app - The Express application.\n * @param path - Route to serve the document at (e.g. `/openapi.json`).\n * @param document - The generated OpenAPI document.\n */\nexport function mountOpenApiJson(\n app: Express,\n path: string,\n document: OpenApiDocument,\n): void {\n app.get(path, (_req, res) => {\n res.json(document);\n });\n}\n\n/**\n * The Swagger UI constructor options this SDK sets before the caller's own.\n *\n * `layout` is `\"BaseLayout\"`, not the `\"StandaloneLayout\"` the Swagger demo\n * uses: standalone renders the **Explore** topbar, an editable URL field that\n * loads any spec from any origin. That is the point of the Swagger editor and\n * the wrong surface for a page documenting one service. `deepLinking` and\n * `persistAuthorization` are the two settings a reader of an authenticated\n * reference notices immediately when they are missing — a linkable operation,\n * and credentials that survive a reload.\n */\nconst SWAGGER_UI_DEFAULTS: Readonly<Record<string, unknown>> = Object.freeze({\n deepLinking: true,\n persistAuthorization: true,\n layout: \"BaseLayout\",\n});\n\n/**\n * Reject Swagger UI options that cannot survive the trip into the page.\n *\n * The options are serialized as JSON into an inline `<script>`, and\n * `JSON.stringify` drops function values **silently** — a `requestInterceptor`\n * passed here would simply never run, with nothing to indicate why.\n *\n * @param options - The caller's Swagger UI options.\n * @param trail - Key path walked so far, for the error message.\n * @throws {Error} When a value is a function.\n */\nfunction assertSerializableUiOptions(options: unknown, trail: string[] = []): void {\n if (typeof options === \"function\") {\n throw new Error(\n [\n `mountSwaggerUi: \\`ui.${trail.join(\".\")}\\` is a function, and the options are`,\n \"serialized as JSON into the page, so it would be dropped silently. Swagger UI\",\n \"options that take a callback have to be wired in the browser.\",\n ].join(\" \"),\n );\n }\n if (Array.isArray(options)) {\n options.forEach((entry, index) =>\n assertSerializableUiOptions(entry, [...trail, String(index)]),\n );\n return;\n }\n if (typeof options === \"object\" && options !== null) {\n for (const [key, value] of Object.entries(options)) {\n assertSerializableUiOptions(value, [...trail, key]);\n }\n }\n}\n\n/**\n * Build the Swagger UI bootstrap HTML pointing at `specUrl`.\n *\n * Asset URLs are **absolute** (`${assetsBase}/…`), not relative. A relative\n * `./assets/…` resolves against the request path, so visiting `/docs` (no\n * trailing slash) would fetch `/assets/…` — a 404 that leaves the UI unstyled\n * and non-functional. The absolute base resolves correctly at both `/docs` and\n * `/docs/`.\n *\n * `presets` is assigned after the merge rather than passed through `ui`: its\n * entries are live objects off `SwaggerUIBundle`, which JSON cannot carry. The\n * standalone preset is loaded — and included — only when the effective layout\n * is `\"StandaloneLayout\"`, so the default page ships neither the extra script\n * nor the Explore topbar it powers.\n */\nfunction swaggerHtml(options: {\n specUrl: string;\n title: string;\n assetsBase: string;\n favicon: string | false;\n ui: Record<string, unknown>;\n}): string {\n const { specUrl, title, assetsBase, favicon, ui } = options;\n const merged: Record<string, unknown> = {\n url: specUrl,\n dom_id: \"#swagger-ui\",\n ...SWAGGER_UI_DEFAULTS,\n ...ui,\n };\n const standalone = merged.layout === \"StandaloneLayout\";\n const presetScript = standalone\n ? `\\n <script src=\"${escapeHtml(assetsBase)}/swagger-ui-standalone-preset.js\"></script>`\n : \"\";\n const presets = standalone\n ? \"[SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset]\"\n : \"[SwaggerUIBundle.presets.apis]\";\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${escapeHtml(title)}</title>${faviconTag(favicon)}\n <link rel=\"stylesheet\" href=\"${escapeHtml(assetsBase)}/swagger-ui.css\" />\n </head>\n <body>\n <div id=\"swagger-ui\"></div>\n <script src=\"${escapeHtml(assetsBase)}/swagger-ui-bundle.js\"></script>${presetScript}\n <script>\n var options = ${scriptLiteral(merged)};\n options.presets = ${presets};\n window.ui = SwaggerUIBundle(options);\n </script>\n </body>\n</html>`;\n}\n\n/** Options for {@link mountSwaggerUi}. */\nexport interface SwaggerOptions {\n /** Page title. Default `\"API docs\"`. */\n title?: string;\n /**\n * Favicon URL or `data:` URI. Default {@link DEFAULT_DOCS_FAVICON}. Pass\n * `false` to emit no tag, letting the browser request `/favicon.ico`.\n */\n favicon?: string | false;\n /**\n * Options merged into the `SwaggerUIBundle` constructor, after\n * {@link SWAGGER_UI_DEFAULTS} and before `presets`. Anything Swagger UI\n * accepts and JSON can carry.\n *\n * Two worth knowing:\n *\n * - `supportedSubmitMethods` — which verbs get a working **Try it out**.\n * Swagger UI enables all of them, so on an API with irreversible side\n * effects (sending, charging, dispatching) the docs page fires the real\n * thing. `[\"get\"]` or `[]` narrows that.\n * - `layout: \"StandaloneLayout\"` — restores the Explore topbar, along with\n * the standalone preset script it needs.\n *\n * Function values throw at mount time rather than being dropped silently by\n * the JSON serialization.\n */\n ui?: Record<string, unknown>;\n}\n\n/**\n * Mount Swagger UI at `path`, reading the spec from `specUrl`.\n *\n * Static assets are served from `${path}/assets` so the page is fully offline.\n *\n * @param app - The Express application.\n * @param path - Mount path for the UI (e.g. `/docs`).\n * @param specUrl - URL the UI fetches the OpenAPI document from.\n * @param options - Page and Swagger UI options.\n * @throws {Error} When `options.ui` carries a function value.\n */\nexport function mountSwaggerUi(\n app: Express,\n path: string,\n specUrl: string,\n options: SwaggerOptions = {},\n): void {\n const title = options.title ?? \"API docs\";\n const favicon = options.favicon ?? DEFAULT_DOCS_FAVICON;\n const ui = options.ui ?? {};\n assertSerializableUiOptions(ui);\n const assetsPath = `${path.replace(/\\/$/, \"\")}/assets`;\n app.use(assetsPath, express.static(getAbsoluteFSPath()));\n const handler: RequestHandler = (_req, res) => {\n res\n .type(\"html\")\n .send(swaggerHtml({ specUrl, title, assetsBase: assetsPath, favicon, ui }));\n };\n app.get(path, handler);\n}\n\n/** Where {@link mountRedoc} takes the standalone renderer bundle from. */\nexport type RedocBundleSource = \"auto\" | \"local\" | \"cdn\";\n\n/** Options for {@link mountRedoc}. */\nexport interface RedocOptions {\n /** Page title. Default `\"API reference\"`. */\n title?: string;\n /**\n * Favicon URL or `data:` URI. Default {@link DEFAULT_DOCS_FAVICON}. Pass\n * `false` to emit no tag, letting the browser request `/favicon.ico`.\n */\n favicon?: string | false;\n /**\n * Where the renderer comes from. Default `\"auto\"`.\n *\n * - `\"auto\"` — serve the `redoc` optional peer's bundle from disk when it is\n * installed, fall back to the CDN when it is not.\n * - `\"local\"` — serve it from disk, and **throw at mount time** when `redoc`\n * is not installed. Use this when an air-gapped deploy must not silently\n * degrade into a CDN request.\n * - `\"cdn\"` — always load from {@link REDOC_CDN_URL}.\n */\n bundle?: RedocBundleSource;\n /**\n * Absolute path to a Redoc standalone bundle to serve, instead of resolving\n * the `redoc` package. For a vendored copy, or a layout the resolver cannot\n * reach (the bundle is resolved from `process.cwd()`).\n */\n bundlePath?: string;\n /**\n * Explicit URL for the bundle. Wins over {@link RedocOptions.bundle} and\n * {@link RedocOptions.bundlePath} — use it to point at a copy you already\n * serve yourself.\n */\n scriptUrl?: string;\n}\n\n/**\n * Resolve the `redoc` package's standalone bundle from the application.\n *\n * Resolution starts at `process.cwd()`, not at this file: `redoc` is an\n * **optional peer**, so the copy that matters is the one the application\n * installed, and Node walks up from there to the project's `node_modules`.\n *\n * @returns The absolute path to the bundle, or `null` when `redoc` is absent.\n */\nexport function resolveRedocBundle(): string | null {\n try {\n const requireFrom = createRequire(join(process.cwd(), \"package.json\"));\n return requireFrom.resolve(REDOC_BUNDLE_SPECIFIER);\n } catch {\n return null;\n }\n}\n\n/**\n * Build the Redoc HTML pointing at `specUrl`.\n *\n * The `onerror` handler matters: when the bundle fails to load — an air-gapped\n * network, a CSP that blocks the CDN — Redoc never initializes and the page\n * renders **blank**, which reads as a broken service rather than a missing\n * script. This replaces the blank page with the reason and the fix.\n */\nfunction redocHtml(\n specUrl: string,\n title: string,\n scriptUrl: string,\n favicon: string | false,\n): string {\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${escapeHtml(title)}</title>${faviconTag(favicon)}\n <style>\n body { margin: 0; padding: 0; }\n #redoc-load-error {\n display: none;\n font: 14px/1.6 system-ui, sans-serif;\n margin: 3rem auto;\n max-width: 40rem;\n padding: 0 1rem;\n }\n #redoc-load-error code {\n background: #f1f3f5;\n border-radius: 3px;\n padding: 0.1rem 0.3rem;\n }\n </style>\n </head>\n <body>\n <div id=\"redoc-load-error\">\n <h1>The API reference could not load</h1>\n <p>\n The Redoc renderer was requested from\n <code id=\"redoc-script-url\"></code> and did not load. The OpenAPI\n document itself is fine — it is served at\n <code id=\"redoc-spec-url\"></code>.\n </p>\n <p>\n On a closed network, install the renderer next to the service\n (<code>npm install redoc</code>) so it is served locally, or point\n <code>scriptUrl</code> at a copy you host.\n </p>\n </div>\n <redoc spec-url=\"${escapeHtml(specUrl)}\"></redoc>\n <script>\n window.__redocLoadFailed = function () {\n document.getElementById(\"redoc-script-url\").textContent = ${scriptLiteral(scriptUrl)};\n document.getElementById(\"redoc-spec-url\").textContent = ${scriptLiteral(specUrl)};\n document.getElementById(\"redoc-load-error\").style.display = \"block\";\n var element = document.querySelector(\"redoc\");\n if (element) element.style.display = \"none\";\n };\n </script>\n <script src=\"${escapeHtml(scriptUrl)}\" onerror=\"window.__redocLoadFailed()\"></script>\n </body>\n</html>`;\n}\n\n/**\n * Mount Redoc at `path`, reading the spec from `specUrl`.\n *\n * By default the renderer is served from the `redoc` optional peer when it is\n * installed, so the page works offline; otherwise it falls back to the CDN.\n *\n * @param app - The Express application.\n * @param path - Mount path for Redoc (e.g. `/redoc`).\n * @param specUrl - URL Redoc fetches the OpenAPI document from.\n * @param options - Page and bundle options.\n * @throws {Error} When `bundle` is `\"local\"` and no bundle can be resolved.\n */\nexport function mountRedoc(\n app: Express,\n path: string,\n specUrl: string,\n options: RedocOptions = {},\n): void {\n const title = options.title ?? \"API reference\";\n const favicon = options.favicon ?? DEFAULT_DOCS_FAVICON;\n const source = options.bundle ?? \"auto\";\n const assetsPath = `${path.replace(/\\/$/, \"\")}/assets`;\n const bundleRoute = `${assetsPath}/redoc.standalone.js`;\n\n let scriptUrl = options.scriptUrl;\n if (scriptUrl === undefined && source !== \"cdn\") {\n const bundlePath = options.bundlePath ?? resolveRedocBundle();\n if (bundlePath !== null && bundlePath !== undefined) {\n app.get(bundleRoute, (_req, res) => {\n res.sendFile(bundlePath);\n });\n scriptUrl = bundleRoute;\n } else if (source === \"local\") {\n throw new Error(\n 'mountRedoc: bundle \"local\" requires the `redoc` package. Install it ' +\n \"(`npm install redoc`) or pass `bundlePath` with an absolute path to \" +\n \"a Redoc standalone bundle.\",\n );\n }\n }\n\n const resolvedScriptUrl = scriptUrl ?? REDOC_CDN_URL;\n app.get(path, (_req, res) => {\n res.type(\"html\").send(redocHtml(specUrl, title, resolvedScriptUrl, favicon));\n });\n}\n","/**\n * Health-check router, mirroring `api.routers.health`.\n *\n * A meta endpoint mounted at the root prefix (not under `/api`). Returns a\n * small JSON status payload and runs any registered async checks, surfacing\n * their pass/fail under `checks` and degrading the HTTP status to 503 when any\n * check fails.\n */\n\nimport { type Router, Router as createRouter } from \"express\";\n\n/** A named async health probe returning `true` when healthy. */\nexport interface HealthCheck {\n /** Probe name, surfaced under `checks`. */\n name: string;\n /** The probe; resolves `true` when the dependency is healthy. */\n check: () => Promise<boolean> | boolean;\n}\n\n/** Options for {@link makeHealthRouter}. */\nexport interface HealthRouterOptions {\n /** Route path within the router. Default `/health`. */\n path?: string;\n /** Optional dependency probes (e.g. database, cache). */\n checks?: HealthCheck[];\n}\n\n/**\n * Build a health-check router.\n *\n * @param options - Path and dependency probes.\n * @returns An Express router exposing the health endpoint.\n */\nexport function makeHealthRouter(options: HealthRouterOptions = {}): Router {\n const path = options.path ?? \"/health\";\n const checks = options.checks ?? [];\n const router = createRouter();\n\n router.get(path, async (_req, res) => {\n const results: Record<string, boolean> = {};\n let healthy = true;\n for (const probe of checks) {\n let ok = false;\n try {\n ok = await probe.check();\n } catch {\n ok = false;\n }\n results[probe.name] = ok;\n if (!ok) healthy = false;\n }\n res.status(healthy ? 200 : 503).json({\n status: healthy ? \"ok\" : \"degraded\",\n checks: results,\n });\n });\n\n return router;\n}\n","/**\n * Prometheus `/metrics` router, mirroring `api.routers.metrics`.\n *\n * Serves {@link MetricsUtils.toPrometheus} as `text/plain`. Optionally includes\n * GPU metrics (via `nvidia-smi`) and can be guarded so the endpoint stays on the\n * internal network / behind auth.\n */\n\nimport { MetricsUtils } from \"@/utils/metrics\";\nimport { type RequestHandler, type Router, Router as createRouter } from \"express\";\n\n/** Options for {@link makeMetricsRouter}. */\nexport interface MetricsRouterOptions {\n /** Route path. Default `/metrics`. */\n path?: string;\n /** Include GPU metrics via `nvidia-smi` (adds a subprocess call). Default `false`. */\n includeGpu?: boolean;\n /** Optional guard middleware (e.g. internal-network or token check). */\n guard?: RequestHandler;\n}\n\n/**\n * Build the Prometheus metrics router.\n *\n * @param options - Path, GPU toggle and optional guard.\n * @returns An Express router exposing the metrics endpoint.\n */\nexport function makeMetricsRouter(options: MetricsRouterOptions = {}): Router {\n const path = options.path ?? \"/metrics\";\n const router = createRouter();\n if (options.guard) router.use(path, options.guard);\n\n router.get(path, async (_req, res) => {\n const gpus = options.includeGpu ? await MetricsUtils.gpus() : [];\n res.type(\"text/plain\").send(MetricsUtils.toPrometheus(MetricsUtils.system(), gpus));\n });\n\n return router;\n}\n","/**\n * Application factory and server runner, mirroring `api.app` + `api.server`.\n *\n * {@link createApp} wires the conventional middleware stack (JSON body parsing,\n * request-id propagation, optional CORS), mounts the health endpoint, lets the\n * caller register routers and OpenAPI paths via a `configure` hook, mounts\n * native Swagger UI + Redoc, then registers the error-handling stack last.\n * {@link runServer} starts listening and logs the bound address.\n */\n\nimport type { Server } from \"node:http\";\nimport {\n type OpenApiDocument,\n type RedocOptions,\n type SwaggerOptions,\n mountOpenApiJson,\n mountRedoc,\n mountSwaggerUi,\n} from \"@/api/docs\";\nimport {\n type RegisterExceptionHandlersOptions,\n registerExceptionHandlers,\n requestIdMiddleware,\n} from \"@/api/handlers\";\nimport {\n type HealthCheck,\n type HealthRouterOptions,\n makeHealthRouter,\n} from \"@/api/health\";\nimport {\n type GenerateOpenApiOptions,\n type OpenAPIRegistry,\n generateOpenApiDocument,\n} from \"@/api/openapi\";\nimport { JSONLogger } from \"@/core\";\nimport type { MessageCatalog } from \"@/exceptions/i18n\";\nimport express, { type Express, type RequestHandler } from \"express\";\n\nconst logger = new JSONLogger(\"tempest_express_sdk.api.server\");\n\n/** OpenAPI documentation configuration for {@link createApp}. */\nexport interface CreateAppOpenApi extends GenerateOpenApiOptions {\n /** Registry holding the registered schemas and paths. */\n registry: OpenAPIRegistry;\n /** Route serving the spec JSON. Default `/openapi.json`. */\n jsonPath?: string;\n /** Swagger UI mount path, or `false` to disable. Default `/docs`. */\n swaggerPath?: string | false;\n /** Redoc mount path, or `false` to disable. Default `/redoc`. */\n redocPath?: string | false;\n /** Extra Swagger UI options. */\n swagger?: SwaggerOptions;\n /** Extra Redoc options. */\n redoc?: RedocOptions;\n}\n\n/** Options for {@link createApp}. */\nexport interface CreateAppOptions {\n /** Allowed CORS origins. `\"*\"` or a list; omit/`false` to disable CORS. */\n corsOrigins?: string | string[] | false;\n /** Health endpoint options, or `false` to omit it. Default mounts `/health`. */\n health?: HealthRouterOptions | false;\n /** Hook to mount routers and register OpenAPI paths before the error stack. */\n configure?: (app: Express) => void | Promise<void>;\n /** OpenAPI docs configuration; omit to skip Swagger/Redoc. */\n openapi?: CreateAppOpenApi;\n /** Message catalog for localized error responses. */\n catalog?: MessageCatalog;\n /** Error-handling options forwarded to {@link registerExceptionHandlers}. */\n errorHandling?: Omit<RegisterExceptionHandlersOptions, \"catalog\">;\n /** JSON body size limit (e.g. `\"1mb\"`). Default `\"100kb\"`. */\n jsonLimit?: string;\n}\n\n/** Minimal CORS middleware (no external dependency). */\nfunction corsMiddleware(origins: string | string[]): RequestHandler {\n const allowAll = origins === \"*\";\n const allowList = new Set(Array.isArray(origins) ? origins : [origins]);\n return (req, res, next) => {\n const origin = req.header(\"origin\");\n if (allowAll) {\n res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n } else if (origin && allowList.has(origin)) {\n res.setHeader(\"Access-Control-Allow-Origin\", origin);\n res.setHeader(\"Vary\", \"Origin\");\n }\n res.setHeader(\"Access-Control-Allow-Methods\", \"GET,POST,PUT,PATCH,DELETE,OPTIONS\");\n res.setHeader(\n \"Access-Control-Allow-Headers\",\n \"Content-Type,Authorization,X-Request-ID\",\n );\n if (req.method === \"OPTIONS\") {\n res.sendStatus(204);\n return;\n }\n next();\n };\n}\n\n/**\n * Build a fully wired Express application.\n *\n * @param options - Middleware, health, OpenAPI docs and error options.\n * @returns The configured Express app, ready to {@link runServer}.\n */\nexport async function createApp(options: CreateAppOptions = {}): Promise<Express> {\n const app = express();\n app.use(express.json({ limit: options.jsonLimit ?? \"100kb\" }));\n app.use(express.urlencoded({ extended: true }));\n app.use(requestIdMiddleware());\n\n if (options.corsOrigins) {\n app.use(corsMiddleware(options.corsOrigins));\n }\n\n if (options.health !== false) {\n app.use(makeHealthRouter(options.health ?? {}));\n }\n\n if (options.configure) await options.configure(app);\n\n if (options.openapi) {\n const { registry, jsonPath, swaggerPath, redocPath, swagger, redoc, ...genOptions } =\n options.openapi;\n const document = generateOpenApiDocument(registry, genOptions) as OpenApiDocument;\n const specPath = jsonPath ?? \"/openapi.json\";\n mountOpenApiJson(app, specPath, document);\n if (swaggerPath !== false) {\n mountSwaggerUi(app, swaggerPath ?? \"/docs\", specPath, swagger ?? {});\n }\n if (redocPath !== false) {\n mountRedoc(app, redocPath ?? \"/redoc\", specPath, redoc ?? {});\n }\n }\n\n registerExceptionHandlers(app, {\n ...options.errorHandling,\n ...(options.catalog !== undefined ? { catalog: options.catalog } : {}),\n });\n\n return app;\n}\n\n/** Options for {@link runServer}. */\nexport interface RunServerOptions {\n /** Bind host. Default `127.0.0.1`. */\n host?: string;\n /** Bind port. Default `8000`. */\n port?: number;\n}\n\n/**\n * Start listening and log the bound address.\n *\n * @param app - The Express application from {@link createApp}.\n * @param options - Host and port.\n * @returns A promise resolving to the live HTTP server once listening.\n */\nexport function runServer(app: Express, options: RunServerOptions = {}): Promise<Server> {\n const host = options.host ?? \"127.0.0.1\";\n const port = options.port ?? 8000;\n return new Promise((resolve) => {\n const server = app.listen(port, host, () => {\n logger.info(\"Server listening\", { host, port });\n resolve(server);\n });\n });\n}\n\n/** Re-export so a `HealthCheck` is reachable from the server module too. */\nexport type { HealthCheck };\n","/**\n * `bodySizeLimitMiddleware` — reject oversize request bodies early, mirroring\n * `api.middlewares.body_size`.\n *\n * Without an upstream limit a client can stream gigabytes before body parsers\n * reject it — wasting bandwidth and RAM. This middleware short-circuits the\n * moment `Content-Length` exceeds the cap, and defensively tracks streamed\n * bytes for chunked/unknown-length uploads.\n */\n\nimport type { RequestHandler } from \"express\";\n\n/** Options for {@link bodySizeLimitMiddleware}. */\nexport interface BodySizeLimitOptions {\n /** Hard cap on the request body in bytes. */\n maxBytes: number;\n /** Path prefixes that bypass the check (e.g. an upload endpoint). */\n excludePaths?: string[];\n}\n\n/**\n * Build a middleware enforcing `maxBytes` per request. A `Content-Length` over\n * the cap is rejected immediately with `413`; chunked bodies are aborted once\n * the streamed size crosses the cap.\n *\n * @param options - The cap and path exclusions.\n * @returns An Express middleware.\n */\nexport function bodySizeLimitMiddleware(options: BodySizeLimitOptions): RequestHandler {\n const { maxBytes } = options;\n const excludePaths = options.excludePaths ?? [];\n\n const reject = (res: Parameters<RequestHandler>[1]): void => {\n res.status(413).json({\n detail: \"Request body too large.\",\n code: \"REQUEST_BODY_TOO_LARGE\",\n details: { maxBytes },\n });\n };\n\n return (req, res, next) => {\n if (maxBytes <= 0 || excludePaths.some((prefix) => req.path.startsWith(prefix))) {\n next();\n return;\n }\n\n // Step 1 — fast path on Content-Length.\n const declared = Number.parseInt(req.header(\"content-length\") ?? \"\", 10);\n if (Number.isFinite(declared) && declared > maxBytes) {\n reject(res);\n return;\n }\n\n // Step 2 — defensive streaming check for chunked/unknown-length bodies.\n // A `data` listener runs alongside any downstream body parser (Node fans\n // each chunk out to every listener), so counting here doesn't steal the\n // body. On overflow we answer 413 and destroy the request to abort.\n let seen = 0;\n let aborted = false;\n const onData = (chunk: Buffer | string): void => {\n if (aborted) return;\n seen += Buffer.byteLength(chunk);\n if (seen > maxBytes) {\n aborted = true;\n req.removeListener(\"data\", onData);\n if (!res.headersSent) reject(res);\n req.destroy();\n }\n };\n req.on(\"data\", onData);\n req.on(\"end\", () => req.removeListener(\"data\", onData));\n next();\n };\n}\n","/**\n * `csrfMiddleware` — double-submit cookie protection for state changes,\n * mirroring `api.middlewares.csrf`.\n *\n * CSRF lets a third-party site trigger authenticated mutating requests through\n * a victim's browser, because cookies ride along automatically. The\n * double-submit defense: issue a random `csrf_token` cookie, have the frontend\n * echo it in an `X-CSRF-Token` header, and reject mutating requests where the\n * header is missing or does not match the cookie. A cross-site page can't read\n * the cookie (same-origin policy), so it can't forge the header.\n *\n * JWT bearer auth (`Authorization: Bearer …`) is **not** subject to CSRF (the\n * browser doesn't auto-attach it), so `/api/` routes are typically excluded.\n */\n\nimport { randomBytes, timingSafeEqual } from \"node:crypto\";\nimport type { Request, RequestHandler } from \"express\";\n\n/** Default cookie holding the CSRF token. */\nexport const CSRF_COOKIE_NAME = \"csrf_token\";\n/** Default header the client echoes the cookie value into. */\nexport const CSRF_HEADER_NAME = \"X-CSRF-Token\";\n\nconst UNSAFE_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\n/**\n * Generate a URL-safe random CSRF token.\n *\n * @param nBytes - Entropy bytes (32 → a 43-char token). Default `32`.\n * @returns A URL-safe base64 token without padding.\n */\nexport function generateCsrfToken(nBytes = 32): string {\n return randomBytes(nBytes).toString(\"base64url\");\n}\n\nfunction readCookie(req: Request, name: string): string | undefined {\n // Prefer a cookie-parser-populated `req.cookies`, else parse the header.\n const parsed = (req as Request & { cookies?: Record<string, string> }).cookies;\n if (parsed && typeof parsed[name] === \"string\") return parsed[name];\n const header = req.header(\"cookie\");\n if (!header) return undefined;\n for (const part of header.split(\";\")) {\n const idx = part.indexOf(\"=\");\n if (idx === -1) continue;\n if (part.slice(0, idx).trim() === name) return part.slice(idx + 1).trim();\n }\n return undefined;\n}\n\nfunction safeEqual(a: string, b: string): boolean {\n const bufA = Buffer.from(a);\n const bufB = Buffer.from(b);\n if (bufA.length !== bufB.length) return false;\n return timingSafeEqual(bufA, bufB);\n}\n\n/** Options for {@link csrfMiddleware}. */\nexport interface CsrfOptions {\n /** Name of the CSRF cookie. Default `csrf_token`. */\n cookieName?: string;\n /** Name of the CSRF header. Default `X-CSRF-Token`. */\n headerName?: string;\n /** Path prefixes that bypass the check (e.g. `[\"/api/\", \"/webhooks/\"]`). */\n excludePaths?: string[];\n}\n\n/**\n * Build a double-submit CSRF middleware. Safe methods (GET/HEAD/OPTIONS) pass;\n * unsafe methods must carry a matching cookie + header or get `403`.\n *\n * @param options - Cookie/header names and excluded path prefixes.\n * @returns An Express middleware.\n */\nexport function csrfMiddleware(options: CsrfOptions = {}): RequestHandler {\n const cookieName = options.cookieName ?? CSRF_COOKIE_NAME;\n const headerName = options.headerName ?? CSRF_HEADER_NAME;\n const excludePaths = options.excludePaths ?? [];\n\n const reject = (res: Parameters<RequestHandler>[1], message: string): void => {\n res.status(403).json({ detail: message, code: \"CSRF_FAILED\", details: {} });\n };\n\n return (req, res, next) => {\n if (!UNSAFE_METHODS.has(req.method)) {\n next();\n return;\n }\n if (excludePaths.some((prefix) => req.path.startsWith(prefix))) {\n next();\n return;\n }\n const cookieToken = readCookie(req, cookieName);\n const headerToken = req.header(headerName);\n if (!cookieToken || !headerToken) {\n reject(res, \"CSRF token missing.\");\n return;\n }\n if (!safeEqual(cookieToken, headerToken)) {\n reject(res, \"CSRF token mismatch.\");\n return;\n }\n next();\n };\n}\n","/**\n * `GracefulShutdown` — track in-flight requests and drain on shutdown,\n * mirroring `api.middlewares.graceful`.\n *\n * Wire {@link GracefulShutdown.middleware} into the app, then on `SIGTERM`\n * call {@link GracefulShutdown.beginDrain} (new non-exempt requests get `503`)\n * and `await` {@link GracefulShutdown.waitDrained} before closing the server —\n * so a rolling deploy never cuts an in-flight request mid-response.\n */\n\nimport type { RequestHandler } from \"express\";\n\n/** Options for {@link GracefulShutdown}. */\nexport interface GracefulShutdownOptions {\n /** Max seconds to wait for in-flight requests to finish. Default `30`. */\n drainTimeoutSeconds?: number;\n /** `Retry-After` seconds on the 503 served while draining. Default `5`. */\n retryAfterSeconds?: number;\n /** Exact paths that keep being served while draining. */\n exemptPaths?: string[];\n}\n\n/** In-flight request tracker with a drain gate. */\nexport class GracefulShutdown {\n private readonly drainTimeoutSeconds: number;\n private readonly retryAfterSeconds: number;\n private readonly exempt: Set<string>;\n private inFlightCount = 0;\n private draining = false;\n private idleResolvers: Array<() => void> = [];\n\n constructor(options: GracefulShutdownOptions = {}) {\n this.drainTimeoutSeconds = options.drainTimeoutSeconds ?? 30;\n this.retryAfterSeconds = options.retryAfterSeconds ?? 5;\n this.exempt = new Set(options.exemptPaths ?? []);\n }\n\n /** Number of requests currently being served. */\n get inFlight(): number {\n return this.inFlightCount;\n }\n\n /** Whether draining has begun. */\n get isDraining(): boolean {\n return this.draining;\n }\n\n /** The Express middleware: counts in-flight requests, 503s while draining. */\n middleware(): RequestHandler {\n return (req, res, next) => {\n if (this.draining && !this.exempt.has(req.path)) {\n res.setHeader(\"Retry-After\", String(this.retryAfterSeconds));\n res.setHeader(\"Connection\", \"close\");\n res.status(503).json({\n detail: \"Server is shutting down.\",\n code: \"SERVICE_UNAVAILABLE\",\n details: {},\n });\n return;\n }\n this.inFlightCount += 1;\n // `finish` and `close` can both fire for one response — settle once.\n let settled = false;\n const settle = (): void => {\n if (settled) return;\n settled = true;\n this.release();\n };\n res.on(\"finish\", settle);\n res.on(\"close\", settle);\n next();\n };\n }\n\n private release(): void {\n this.inFlightCount -= 1;\n if (this.inFlightCount === 0) {\n const resolvers = this.idleResolvers;\n this.idleResolvers = [];\n for (const resolve of resolvers) resolve();\n }\n }\n\n /** Flip into draining mode (idempotent). New non-exempt requests get 503. */\n beginDrain(): void {\n this.draining = true;\n }\n\n /**\n * Wait until in-flight requests finish or the drain timeout elapses.\n *\n * @returns `true` if everything drained in time, `false` on timeout.\n */\n waitDrained(): Promise<boolean> {\n if (this.inFlightCount === 0) return Promise.resolve(true);\n return new Promise<boolean>((resolve) => {\n const timer = setTimeout(() => {\n this.idleResolvers = this.idleResolvers.filter((r) => r !== onIdle);\n resolve(false);\n }, this.drainTimeoutSeconds * 1000);\n const onIdle = (): void => {\n clearTimeout(timer);\n resolve(true);\n };\n this.idleResolvers.push(onIdle);\n });\n }\n}\n","/**\n * `idempotencyMiddleware` — cache responses by `Idempotency-Key`, mirroring\n * `api.middlewares.idempotency`.\n *\n * A client retrying a mutating request with the same `Idempotency-Key` gets the\n * original response back instead of a duplicate side effect (a second charge, a\n * second order). Only mutating verbs are eligible; the key is scoped per\n * `(method, path, key)` so the same key on different endpoints never collides.\n */\n\nimport type { RequestHandler, Response } from \"express\";\n\n/** The canonical header (Stripe / AWS / GitHub all use it). */\nexport const IDEMPOTENCY_HEADER = \"Idempotency-Key\";\n\nconst MUTATING_METHODS = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\n/** A serialized response stored under an idempotency key. */\nexport interface CachedResponse {\n statusCode: number;\n headers: Array<[string, string]>;\n body: string;\n contentType: string | null;\n}\n\n/** Backend every idempotency cache implements. */\nexport interface IdempotencyStore {\n /** Return the cached response for `key`, or `null` when missing/expired. */\n get(key: string): Promise<CachedResponse | null>;\n /** Store `response` under `key` with a TTL. */\n set(key: string, response: CachedResponse, ttlSeconds: number): Promise<void>;\n}\n\n/** In-process {@link IdempotencyStore} with lazy TTL eviction (single-replica). */\nexport class MemoryIdempotencyStore implements IdempotencyStore {\n private readonly store = new Map<\n string,\n { expiresAt: number; response: CachedResponse }\n >();\n\n async get(key: string): Promise<CachedResponse | null> {\n const entry = this.store.get(key);\n if (!entry) return null;\n if (entry.expiresAt < Date.now()) {\n this.store.delete(key);\n return null;\n }\n return entry.response;\n }\n\n async set(key: string, response: CachedResponse, ttlSeconds: number): Promise<void> {\n this.store.set(key, { expiresAt: Date.now() + ttlSeconds * 1000, response });\n }\n}\n\n/** Minimal async Redis surface used by {@link RedisIdempotencyStore}. */\nexport interface IdempotencyRedisLike {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options: { EX: number }): Promise<unknown>;\n}\n\n/** {@link IdempotencyStore} backed by an async Redis client (multi-replica). */\nexport class RedisIdempotencyStore implements IdempotencyStore {\n private readonly prefix: string;\n\n constructor(\n private readonly client: IdempotencyRedisLike,\n options: { prefix?: string } = {},\n ) {\n this.prefix = options.prefix ?? \"idem:\";\n }\n\n async get(key: string): Promise<CachedResponse | null> {\n const raw = await this.client.get(this.prefix + key);\n return raw === null ? null : (JSON.parse(raw) as CachedResponse);\n }\n\n async set(key: string, response: CachedResponse, ttlSeconds: number): Promise<void> {\n await this.client.set(this.prefix + key, JSON.stringify(response), {\n EX: ttlSeconds,\n });\n }\n}\n\n/** Options for {@link idempotencyMiddleware}. */\nexport interface IdempotencyOptions {\n /** The cache backend (memory or Redis). */\n store: IdempotencyStore;\n /** Time-to-live for a cached response, in seconds. Default 24h. */\n ttlSeconds?: number;\n /** Header carrying the key. Default `Idempotency-Key`. */\n headerName?: string;\n}\n\n/**\n * Build an idempotency middleware. On a cache hit it replays the stored\n * response; on a miss it captures the response, stores it, and forwards.\n *\n * @param options - Store, TTL and header name.\n * @returns An Express middleware.\n */\nexport function idempotencyMiddleware(options: IdempotencyOptions): RequestHandler {\n const { store } = options;\n const ttlSeconds = options.ttlSeconds ?? 24 * 3600;\n const headerName = options.headerName ?? IDEMPOTENCY_HEADER;\n\n return (req, res, next) => {\n if (!MUTATING_METHODS.has(req.method)) {\n next();\n return;\n }\n const rawKey = req.header(headerName);\n if (!rawKey) {\n next();\n return;\n }\n const scoped = `${req.method}:${req.path}:${rawKey}`;\n\n store\n .get(scoped)\n .then((cached) => {\n if (cached) {\n for (const [name, value] of cached.headers) res.setHeader(name, value);\n res.setHeader(\"Idempotent-Replayed\", \"true\");\n if (cached.contentType) res.type(cached.contentType);\n res.status(cached.statusCode).send(cached.body);\n return;\n }\n captureAndForward(res, scoped, store, ttlSeconds);\n next();\n })\n .catch(next);\n };\n}\n\n/** Wrap `res.send` to capture the first body, then persist on `finish`. */\nfunction captureAndForward(\n res: Response,\n key: string,\n store: IdempotencyStore,\n ttlSeconds: number,\n): void {\n const originalSend = res.send.bind(res);\n let capturedBody = \"\";\n res.send = ((body?: unknown): Response => {\n if (typeof body === \"string\") capturedBody = body;\n else if (body !== undefined) capturedBody = JSON.stringify(body);\n return originalSend(body as never);\n }) as Response[\"send\"];\n\n res.on(\"finish\", () => {\n // Only cache successful, deterministic outcomes (2xx). Errors should be\n // retryable, not frozen.\n if (res.statusCode < 200 || res.statusCode >= 300) return;\n const contentType = res.getHeader(\"content-type\");\n void store\n .set(\n key,\n {\n statusCode: res.statusCode,\n headers: [],\n body: capturedBody,\n contentType: typeof contentType === \"string\" ? contentType : null,\n },\n ttlSeconds,\n )\n .catch(() => {\n // Best-effort cache write; a store outage must not fail the response.\n });\n });\n}\n","/**\n * `HttpMetrics` + `prometheusMiddleware` — per-request Prometheus metrics,\n * mirroring the FastAPI `PrometheusMiddleware`.\n *\n * Complements the system `/metrics` router (`MetricsUtils.toPrometheus`, which\n * reports process/host gauges) with **per-request** instrumentation: a request\n * counter labelled by method/path/status and a latency histogram. Everything is\n * in-process and dependency-free; expose it with {@link HttpMetrics.render}.\n */\n\nimport type { RequestHandler } from \"express\";\n\n/** Default histogram buckets in seconds (Prometheus client defaults). */\nconst DEFAULT_BUCKETS = [\n 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10,\n] as const;\n\ninterface HistogramState {\n bucketCounts: number[];\n sum: number;\n count: number;\n}\n\n/**\n * In-process HTTP request metrics: a labelled request counter and a latency\n * histogram, rendered as Prometheus text.\n */\nexport class HttpMetrics {\n private readonly buckets: number[];\n /** `method|status` → count. */\n private readonly requestTotals = new Map<string, number>();\n /** `method|route` → histogram. */\n private readonly durations = new Map<string, HistogramState>();\n\n constructor(options: { buckets?: number[] } = {}) {\n this.buckets = [...(options.buckets ?? DEFAULT_BUCKETS)].sort((a, b) => a - b);\n }\n\n /**\n * Record one completed request.\n *\n * @param method - HTTP method.\n * @param route - The route pattern (or path) — keep cardinality bounded.\n * @param status - Response status code.\n * @param durationSeconds - Wall-clock request duration in seconds.\n */\n observe(method: string, route: string, status: number, durationSeconds: number): void {\n const totalKey = `${method}|${status}`;\n this.requestTotals.set(totalKey, (this.requestTotals.get(totalKey) ?? 0) + 1);\n\n const durKey = `${method}|${route}`;\n let hist = this.durations.get(durKey);\n if (!hist) {\n hist = { bucketCounts: new Array(this.buckets.length).fill(0), sum: 0, count: 0 };\n this.durations.set(durKey, hist);\n }\n hist.sum += durationSeconds;\n hist.count += 1;\n for (let i = 0; i < this.buckets.length; i += 1) {\n const upper = this.buckets[i];\n if (upper !== undefined && durationSeconds <= upper) {\n hist.bucketCounts[i] = (hist.bucketCounts[i] ?? 0) + 1;\n }\n }\n }\n\n /** Render the collected metrics as Prometheus exposition text. */\n render(): string {\n const lines: string[] = [];\n lines.push(\"# HELP http_requests_total Total HTTP requests.\");\n lines.push(\"# TYPE http_requests_total counter\");\n for (const [key, value] of this.requestTotals) {\n const [method = \"\", status = \"\"] = key.split(\"|\");\n lines.push(\n `http_requests_total{method=\"${esc(method)}\",status=\"${esc(status)}\"} ${value}`,\n );\n }\n\n lines.push(\"# HELP http_request_duration_seconds HTTP request latency.\");\n lines.push(\"# TYPE http_request_duration_seconds histogram\");\n for (const [key, hist] of this.durations) {\n const [method = \"\", route = \"\"] = key.split(\"|\");\n const labels = `method=\"${esc(method)}\",route=\"${esc(route)}\"`;\n // `bucketCounts[i]` is already the cumulative count of observations\n // <= buckets[i], which is exactly the `le` semantics Prometheus wants.\n for (let i = 0; i < this.buckets.length; i += 1) {\n lines.push(\n `http_request_duration_seconds_bucket{${labels},le=\"${this.buckets[i]}\"} ${hist.bucketCounts[i] ?? 0}`,\n );\n }\n lines.push(\n `http_request_duration_seconds_bucket{${labels},le=\"+Inf\"} ${hist.count}`,\n );\n lines.push(`http_request_duration_seconds_sum{${labels}} ${hist.sum}`);\n lines.push(`http_request_duration_seconds_count{${labels}} ${hist.count}`);\n }\n return `${lines.join(\"\\n\")}\\n`;\n }\n\n /**\n * Build the middleware that records each request into this collector.\n *\n * @param options - Optional exempt paths (e.g. the metrics route itself).\n * @returns An Express middleware.\n */\n middleware(options: { exemptPaths?: string[] } = {}): RequestHandler {\n const exempt = new Set(options.exemptPaths ?? []);\n return (req, res, next) => {\n if (exempt.has(req.path)) {\n next();\n return;\n }\n const start = process.hrtime.bigint();\n res.on(\"finish\", () => {\n const durationSeconds = Number(process.hrtime.bigint() - start) / 1e9;\n // `req.route?.path` is the low-cardinality pattern; fall back to path.\n const route = (req.route as { path?: string } | undefined)?.path ?? req.path;\n this.observe(req.method, route, res.statusCode, durationSeconds);\n });\n next();\n };\n }\n}\n\nfunction esc(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"').replace(/\\n/g, \"\\\\n\");\n}\n\n/**\n * Convenience factory: a fresh {@link HttpMetrics} plus its middleware.\n *\n * @param options - Histogram buckets and exempt paths.\n * @returns The collector and its middleware.\n */\nexport function prometheusMiddleware(\n options: { buckets?: number[]; exemptPaths?: string[] } = {},\n): { metrics: HttpMetrics; middleware: RequestHandler } {\n const metrics = new HttpMetrics(\n options.buckets !== undefined ? { buckets: options.buckets } : {},\n );\n return {\n metrics,\n middleware: metrics.middleware(\n options.exemptPaths !== undefined ? { exemptPaths: options.exemptPaths } : {},\n ),\n };\n}\n","/**\n * Sliding-window rate-limit middleware with pluggable stores and keys,\n * mirroring `api.middlewares.rate_limit`.\n *\n * Two axes are pluggable:\n *\n * - **Store** — where the counters live. {@link MemoryRateLimitStore} (default,\n * in-process) fits a single worker; {@link RedisRateLimitStore} shares state\n * across replicas via an atomic Lua sliding-window log.\n * - **Key** — *who* a request counts against. {@link keyByIp} (default),\n * {@link keyByHeader} (e.g. an API key), {@link keyByJwtClaim} /\n * {@link keyByJwtSubject} (per authenticated principal), each falling back to\n * the client IP for anonymous traffic.\n */\n\nimport { randomUUID } from \"node:crypto\";\nimport { type ClientIpOptions, getClientIp } from \"@/utils/clientIp\";\nimport type { Request, RequestHandler } from \"express\";\n\n/** Outcome of a single rate-limit check. */\nexport interface RateLimitResult {\n /** `true` when the request fits under the limit. */\n allowed: boolean;\n /** Requests still allowed in the current window (`0` when rejected). */\n remaining: number;\n /** Seconds to wait before retrying (`0` when allowed, `>= 1` on rejection). */\n retryAfter: number;\n}\n\n/** Backend that counts hits per key inside a sliding window. */\nexport interface RateLimitStore {\n /**\n * Register one hit for `key` and report whether it is allowed.\n *\n * @param key - The rate-limit bucket key.\n * @param maxRequests - Maximum hits allowed in the window.\n * @param windowSeconds - Sliding-window length in seconds.\n * @returns The decision for this hit.\n */\n hit(key: string, maxRequests: number, windowSeconds: number): Promise<RateLimitResult>;\n}\n\n/**\n * In-process sliding-window store backed by per-key timestamp logs.\n *\n * State lives in this worker's memory only — correct for a single process. For\n * multi-replica deployments use {@link RedisRateLimitStore}.\n */\nexport class MemoryRateLimitStore implements RateLimitStore {\n private readonly buckets = new Map<string, number[]>();\n\n async hit(\n key: string,\n maxRequests: number,\n windowSeconds: number,\n ): Promise<RateLimitResult> {\n const now = Date.now();\n const windowMs = windowSeconds * 1000;\n const cutoff = now - windowMs;\n const bucket = this.buckets.get(key) ?? [];\n // Prune timestamps older than the window.\n let start = 0;\n while (start < bucket.length) {\n const ts = bucket[start];\n if (ts === undefined || ts >= cutoff) break;\n start += 1;\n }\n const live = start > 0 ? bucket.slice(start) : bucket;\n\n if (live.length >= maxRequests) {\n this.buckets.set(key, live);\n const oldest = live[0] ?? now;\n const retryAfter = Math.max(1, Math.ceil((oldest + windowMs - now) / 1000));\n return { allowed: false, remaining: 0, retryAfter };\n }\n live.push(now);\n this.buckets.set(key, live);\n return { allowed: true, remaining: maxRequests - live.length, retryAfter: 0 };\n }\n}\n\n/** Minimal async Redis surface used by {@link RedisRateLimitStore}. */\nexport interface RateLimitRedisLike {\n eval(\n script: string,\n options: { keys: string[]; arguments: string[] },\n ): Promise<unknown>;\n}\n\n// Atomic sliding-window log: drop expired members, count, and only add the new\n// member when still under the limit. Returns {allowed, remaining, retry_ms}.\nconst SLIDING_WINDOW_LUA = `\nlocal key = KEYS[1]\nlocal now = tonumber(ARGV[1])\nlocal window = tonumber(ARGV[2])\nlocal limit = tonumber(ARGV[3])\nlocal member = ARGV[4]\nredis.call('ZREMRANGEBYSCORE', key, 0, now - window)\nlocal count = redis.call('ZCARD', key)\nif count < limit then\n redis.call('ZADD', key, now, member)\n redis.call('PEXPIRE', key, window)\n return {1, limit - count - 1, 0}\nend\nlocal oldest = redis.call('ZRANGE', key, 0, 0, 'WITHSCORES')\nlocal retry = window\nif oldest[2] then\n retry = (tonumber(oldest[2]) + window) - now\nend\nif retry < 1 then retry = 1 end\nreturn {0, 0, retry}\n`;\n\n/**\n * Distributed sliding-window store backed by a Redis sorted set. A single Lua\n * script prunes expired members, counts survivors and conditionally adds the\n * new hit, so the check is atomic across replicas. On a backend error the\n * request is allowed when `failOpen` (the default).\n */\nexport class RedisRateLimitStore implements RateLimitStore {\n private readonly namespace: string;\n private readonly failOpen: boolean;\n\n /**\n * @param redis - Async Redis client exposing `eval({ keys, arguments })`.\n * @param options - Key namespace and fail-open behavior.\n */\n constructor(\n private readonly redis: RateLimitRedisLike,\n options: { namespace?: string; failOpen?: boolean } = {},\n ) {\n this.namespace = options.namespace ?? \"ratelimit\";\n this.failOpen = options.failOpen ?? true;\n }\n\n async hit(\n key: string,\n maxRequests: number,\n windowSeconds: number,\n ): Promise<RateLimitResult> {\n const nowMs = Date.now();\n const windowMs = Math.round(windowSeconds * 1000);\n const member = randomUUID();\n try {\n const raw = (await this.redis.eval(SLIDING_WINDOW_LUA, {\n keys: [`${this.namespace}:${key}`],\n arguments: [String(nowMs), String(windowMs), String(maxRequests), member],\n })) as [number, number, number];\n const [allowedFlag, remaining, retryMs] = raw;\n const allowed = Boolean(allowedFlag);\n return {\n allowed,\n remaining: Number(remaining),\n retryAfter: allowed ? 0 : Math.max(1, Math.ceil(Number(retryMs) / 1000)),\n };\n } catch (error) {\n if (this.failOpen) {\n return { allowed: true, remaining: maxRequests - 1, retryAfter: 0 };\n }\n throw error;\n }\n }\n}\n\n/** Builds a rate-limit bucket key from a request (sync or async). */\nexport type RateLimitKeyFunc = (req: Request) => string | Promise<string>;\n\n/** Minimal JWT decoder surface used by the `keyByJwt*` helpers. */\nexport interface JwtDecoderLike {\n decode(token: string): Promise<Record<string, unknown>>;\n}\n\n/** Build `ClientIpOptions`, omitting `trustedHeader` when undefined. */\nfunction ipOpts(trustedHeader: string | undefined): ClientIpOptions {\n return trustedHeader !== undefined ? { trustedHeader } : {};\n}\n\nfunction bearerToken(req: Request): string | null {\n const header = req.header(\"authorization\");\n if (!header) return null;\n const parts = header.split(/\\s+/, 2);\n const [scheme, token] = parts;\n if (scheme?.toLowerCase() === \"bearer\" && token) return token.trim();\n return null;\n}\n\n/** Build a key function that buckets by resolved client IP. */\nexport function keyByIp(options: ClientIpOptions = {}): RateLimitKeyFunc {\n return (req) => `ip:${getClientIp(req, options)}`;\n}\n\n/**\n * Build a key function that buckets by a request header value (e.g. an API\n * key), falling back to the client IP for anonymous callers.\n */\nexport function keyByHeader(\n headerName: string,\n options: { scope?: string; fallbackToIp?: boolean; trustedIpHeader?: string } = {},\n): RateLimitKeyFunc {\n const scope = options.scope ?? \"key\";\n const fallbackToIp = options.fallbackToIp ?? true;\n return (req) => {\n const value = req.header(headerName);\n if (value) return `${scope}:${value.trim()}`;\n if (fallbackToIp) return `ip:${getClientIp(req, ipOpts(options.trustedIpHeader))}`;\n return `${scope}:anonymous`;\n };\n}\n\n/**\n * Build a key function that buckets by a claim in the bearer token, falling\n * back to the client IP for anonymous traffic.\n */\nexport function keyByJwtClaim(\n jwt: JwtDecoderLike,\n claim: string,\n options: { scope?: string; fallbackToIp?: boolean; trustedIpHeader?: string } = {},\n): RateLimitKeyFunc {\n const label = options.scope ?? claim;\n const fallbackToIp = options.fallbackToIp ?? true;\n return async (req) => {\n const token = bearerToken(req);\n if (token) {\n try {\n const claims = await jwt.decode(token);\n const value = claims[claim];\n if (value !== undefined && value !== null) return `${label}:${String(value)}`;\n } catch {\n // Invalid/expired token — treat as anonymous.\n }\n }\n if (fallbackToIp) return `ip:${getClientIp(req, ipOpts(options.trustedIpHeader))}`;\n return `${label}:anonymous`;\n };\n}\n\n/** Build a key function that buckets by the JWT `sub` claim (per-user). */\nexport function keyByJwtSubject(\n jwt: JwtDecoderLike,\n options: { fallbackToIp?: boolean; trustedIpHeader?: string } = {},\n): RateLimitKeyFunc {\n return keyByJwtClaim(jwt, \"sub\", { scope: \"user\", ...options });\n}\n\n/** Options for {@link rateLimitMiddleware}. */\nexport interface RateLimitOptions {\n /** Maximum requests per window. Default `60`. */\n maxRequests?: number;\n /** Window length in seconds. Default `60`. */\n windowSeconds?: number;\n /** Build a rate-limit key from the request. Overrides `trustedIpHeader`. */\n keyFunc?: RateLimitKeyFunc;\n /** Single edge-set header to resolve the client IP from when keying by IP. */\n trustedIpHeader?: string;\n /** Counter backend. Defaults to an in-process {@link MemoryRateLimitStore}. */\n store?: RateLimitStore;\n /** Exact paths to skip entirely (e.g. health probes). */\n exemptPaths?: string[];\n /** Whether to add a `Retry-After` header on 429s. Default `true`. */\n retryAfterHeader?: boolean;\n /** Body message of the 429 response. */\n errorMessage?: string;\n}\n\n/**\n * Build a sliding-window rate-limit middleware.\n *\n * @param options - Limits, key/store strategy and exemptions.\n * @returns An Express middleware rejecting excess traffic with `429`.\n * @throws {RangeError} When `maxRequests` < 1 or `windowSeconds` <= 0.\n */\nexport function rateLimitMiddleware(options: RateLimitOptions = {}): RequestHandler {\n const maxRequests = options.maxRequests ?? 60;\n const windowSeconds = options.windowSeconds ?? 60;\n if (maxRequests < 1) throw new RangeError(\"maxRequests must be >= 1\");\n if (windowSeconds <= 0) throw new RangeError(\"windowSeconds must be > 0\");\n\n const store = options.store ?? new MemoryRateLimitStore();\n const keyFunc: RateLimitKeyFunc =\n options.keyFunc ?? keyByIp(ipOpts(options.trustedIpHeader));\n const exempt = new Set(options.exemptPaths ?? []);\n const retryAfterHeader = options.retryAfterHeader ?? true;\n const errorMessage = options.errorMessage ?? \"Too many requests\";\n\n return (req, res, next) => {\n if (exempt.has(req.path)) {\n next();\n return;\n }\n Promise.resolve(keyFunc(req))\n .then((key) => store.hit(key, maxRequests, windowSeconds))\n .then((result) => {\n res.setHeader(\"X-RateLimit-Limit\", String(maxRequests));\n res.setHeader(\"X-RateLimit-Remaining\", String(Math.max(0, result.remaining)));\n if (!result.allowed) {\n if (retryAfterHeader) res.setHeader(\"Retry-After\", String(result.retryAfter));\n res.status(429).json({\n detail: errorMessage,\n code: \"TOO_MANY_REQUESTS\",\n details: { retryAfterSeconds: result.retryAfter },\n });\n return;\n }\n next();\n })\n .catch(next);\n };\n}\n","/**\n * `requestTracingMiddleware` — structured per-request access logging, mirroring\n * the request-tracing concern of the FastAPI SDK.\n *\n * Logs one JSON line per request with method, path, status, duration and the\n * request id (from the request-id context), so every request is traceable in a\n * log aggregator. It is the lightweight, dependency-free counterpart to full\n * OpenTelemetry tracing — the request id correlates logs across services.\n */\n\nimport { JSONLogger, type LogLevel, getRequestId } from \"@/core\";\nimport type { RequestHandler } from \"express\";\n\n/** Options for {@link requestTracingMiddleware}. */\nexport interface RequestTracingOptions {\n /** Logger name. Default `tempest_express_sdk.api.tracing`. */\n loggerName?: string;\n /** Log level for completed requests. Default `\"info\"`. */\n level?: LogLevel;\n /** Exact paths to skip (e.g. health probes). */\n exemptPaths?: string[];\n}\n\n/**\n * Build an access-logging middleware. Records the request on completion with\n * its duration in milliseconds.\n *\n * @param options - Logger name, level and exempt paths.\n * @returns An Express middleware.\n */\nexport function requestTracingMiddleware(\n options: RequestTracingOptions = {},\n): RequestHandler {\n const logger = new JSONLogger(options.loggerName ?? \"tempest_express_sdk.api.tracing\");\n const level = options.level ?? \"info\";\n const exempt = new Set(options.exemptPaths ?? []);\n\n return (req, res, next) => {\n if (exempt.has(req.path)) {\n next();\n return;\n }\n const start = process.hrtime.bigint();\n res.on(\"finish\", () => {\n const durationMs = Number(process.hrtime.bigint() - start) / 1e6;\n logger.log(level, \"request\", {\n method: req.method,\n path: req.path,\n statusCode: res.statusCode,\n durationMs: Math.round(durationMs * 1000) / 1000,\n requestId: getRequestId(),\n });\n });\n next();\n };\n}\n","/**\n * OAuth2 / OIDC clients, mirroring `api.oauth`.\n *\n * Three clients out of the box: {@link GoogleOAuthClient},\n * {@link GitHubOAuthClient} and the generic {@link OIDCProvider} (Auth0,\n * Keycloak, Okta, Entra, Cognito). They cover only the OAuth2 dance — build an\n * authorize URL, exchange the code for tokens, fetch the user. Storing the user,\n * minting your own session token and setting cookies are the service's calls.\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { AppException } from \"@/exceptions/base\";\nimport { HTTPClient } from \"@/utils/httpClient\";\n\n/** Raised when a provider rejects part of the OAuth dance. */\nexport class OAuthError extends AppException {\n static override statusCode = 502;\n static override code = \"OAUTH_ERROR\";\n}\n\n/** The single normalized identity shape the rest of the app sees. */\nexport interface OAuthUser {\n /** Provider label (`\"google\"`, `\"github\"`, `\"oidc:auth0\"`, …). */\n provider: string;\n /** Stable per-provider id; pair with `provider` for a global key. */\n subject: string;\n email: string | null;\n name: string | null;\n picture: string | null;\n /** The raw provider payload. */\n raw: Record<string, unknown>;\n}\n\n/** The token bundle returned by a code exchange. */\nexport interface OAuthTokens {\n accessToken: string;\n tokenType: string;\n refreshToken: string | null;\n /** The OIDC id token (JWT), or `null` on plain OAuth2. */\n idToken: string | null;\n expiresIn: number | null;\n scope: string | null;\n raw: Record<string, unknown>;\n}\n\n/**\n * Generate a URL-safe random `state` value. Store it server-side (or a signed\n * cookie) before redirecting and compare on callback — a mismatch is a forged\n * redirect.\n *\n * @param nBytes - Entropy bytes. Default `32`.\n * @returns A URL-safe token.\n */\nexport function generateOAuthState(nBytes = 32): string {\n return randomBytes(nBytes).toString(\"base64url\");\n}\n\n/** Common constructor options for the OAuth clients. */\nexport interface OAuthClientOptions {\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n scopes?: string[];\n httpClient?: HTTPClient;\n}\n\n/** Base class implementing the OAuth2 dance; subclasses fill in the endpoints. */\nexport abstract class BaseOAuthClient {\n abstract readonly providerName: string;\n protected readonly clientId: string;\n protected readonly clientSecret: string;\n protected readonly redirectUri: string;\n protected readonly scopes: string[];\n protected readonly http: HTTPClient;\n\n constructor(options: OAuthClientOptions) {\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.redirectUri = options.redirectUri;\n this.scopes = options.scopes ?? this.defaultScopes();\n this.http = options.httpClient ?? new HTTPClient({ timeoutMs: 10000 });\n }\n\n protected defaultScopes(): string[] {\n return [];\n }\n\n /** The provider's authorization endpoint. */\n protected abstract authorizeUrl(): string;\n /** The provider's token endpoint. */\n protected abstract tokenUrl(): string;\n /** The provider's userinfo endpoint, or `null` when unavailable. */\n protected userinfoUrl(): string | null {\n return null;\n }\n /** Map a raw userinfo payload to {@link OAuthUser}. */\n protected abstract parseUser(payload: Record<string, unknown>): OAuthUser;\n\n /**\n * Build the fully-formed authorize URL to redirect the user to.\n *\n * @param state - A value from {@link generateOAuthState}, saved server-side.\n * @param extra - Extra query params (e.g. `{ access_type: \"offline\" }`).\n * @returns The authorize URL.\n */\n buildAuthorizeUrl(state: string, extra: Record<string, string> = {}): string {\n const params = new URLSearchParams({\n client_id: this.clientId,\n redirect_uri: this.redirectUri,\n response_type: \"code\",\n scope: this.scopes.join(\" \"),\n state,\n ...extra,\n });\n return `${this.authorizeUrl()}?${params.toString()}`;\n }\n\n /**\n * Exchange an authorization code for tokens.\n *\n * @param code - The `code` query param from the callback.\n * @returns The parsed token bundle.\n * @throws {OAuthError} When the provider rejects the exchange.\n */\n async exchangeCode(code: string): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: \"authorization_code\",\n code,\n redirect_uri: this.redirectUri,\n client_id: this.clientId,\n client_secret: this.clientSecret,\n });\n const response = await this.http.request(\"POST\", this.tokenUrl(), {\n body: body.toString(),\n headers: {\n \"content-type\": \"application/x-www-form-urlencoded\",\n accept: \"application/json\",\n },\n });\n if (response.status >= 400) {\n throw new OAuthError({\n message: `token exchange failed (${response.status})`,\n details: { body: await safeText(response) },\n });\n }\n const payload = (await response.json()) as Record<string, unknown>;\n return {\n accessToken: String(payload.access_token),\n tokenType: (payload.token_type as string) ?? \"Bearer\",\n refreshToken: (payload.refresh_token as string) ?? null,\n idToken: (payload.id_token as string) ?? null,\n expiresIn: (payload.expires_in as number) ?? null,\n scope: (payload.scope as string) ?? null,\n raw: payload,\n };\n }\n\n /**\n * Fetch the normalized user identity for a token bundle.\n *\n * @param tokens - The tokens from {@link exchangeCode}.\n * @returns The normalized user.\n * @throws {OAuthError} When userinfo is unconfigured or the call fails.\n */\n async fetchUser(tokens: OAuthTokens): Promise<OAuthUser> {\n const url = this.userinfoUrl();\n if (url === null) {\n throw new OAuthError({\n message: `${this.providerName}: userinfo endpoint not configured`,\n });\n }\n const response = await this.http.request(\"GET\", url, {\n headers: {\n authorization: `${tokens.tokenType} ${tokens.accessToken}`,\n accept: \"application/json\",\n \"user-agent\": \"tempest-express-sdk\",\n },\n });\n if (response.status >= 400) {\n throw new OAuthError({\n message: `userinfo failed (${response.status})`,\n details: { body: await safeText(response) },\n });\n }\n return this.parseUser((await response.json()) as Record<string, unknown>);\n }\n}\n\nasync function safeText(response: Response): Promise<string> {\n try {\n return await response.text();\n } catch {\n return \"\";\n }\n}\n\n/** Google identity (OIDC). Default scopes: `openid email profile`. */\nexport class GoogleOAuthClient extends BaseOAuthClient {\n readonly providerName = \"google\";\n protected override defaultScopes(): string[] {\n return [\"openid\", \"email\", \"profile\"];\n }\n protected authorizeUrl(): string {\n return \"https://accounts.google.com/o/oauth2/v2/auth\";\n }\n protected tokenUrl(): string {\n return \"https://oauth2.googleapis.com/token\";\n }\n protected override userinfoUrl(): string {\n return \"https://openidconnect.googleapis.com/v1/userinfo\";\n }\n protected parseUser(payload: Record<string, unknown>): OAuthUser {\n return {\n provider: this.providerName,\n subject: String(payload.sub),\n email: (payload.email as string) ?? null,\n name: (payload.name as string) ?? null,\n picture: (payload.picture as string) ?? null,\n raw: payload,\n };\n }\n}\n\n/** GitHub OAuth (no id_token; identity from `GET /user`). */\nexport class GitHubOAuthClient extends BaseOAuthClient {\n readonly providerName = \"github\";\n protected override defaultScopes(): string[] {\n return [\"read:user\", \"user:email\"];\n }\n protected authorizeUrl(): string {\n return \"https://github.com/login/oauth/authorize\";\n }\n protected tokenUrl(): string {\n return \"https://github.com/login/oauth/access_token\";\n }\n protected override userinfoUrl(): string {\n return \"https://api.github.com/user\";\n }\n protected parseUser(payload: Record<string, unknown>): OAuthUser {\n return {\n provider: this.providerName,\n subject: String(payload.id),\n email: (payload.email as string) ?? null,\n name: (payload.name as string) ?? (payload.login as string) ?? null,\n picture: (payload.avatar_url as string) ?? null,\n raw: payload,\n };\n }\n}\n\n/** Options for {@link OIDCProvider}. */\nexport interface OIDCProviderOptions extends OAuthClientOptions {\n authorizeUrl: string;\n tokenUrl: string;\n userinfoUrl?: string | null;\n providerName?: string;\n}\n\n/**\n * Generic discovery-driven OIDC client. Pass the authorize / token / userinfo\n * endpoints (fetch them once at boot from `${issuer}/.well-known/openid-configuration`).\n * Default scopes: `openid email profile`.\n */\nexport class OIDCProvider extends BaseOAuthClient {\n readonly providerName: string;\n private readonly _authorizeUrl: string;\n private readonly _tokenUrl: string;\n private readonly _userinfoUrl: string | null;\n\n constructor(options: OIDCProviderOptions) {\n super(options);\n this.providerName = options.providerName ?? \"oidc\";\n this._authorizeUrl = options.authorizeUrl;\n this._tokenUrl = options.tokenUrl;\n this._userinfoUrl = options.userinfoUrl ?? null;\n }\n\n protected override defaultScopes(): string[] {\n return [\"openid\", \"email\", \"profile\"];\n }\n protected authorizeUrl(): string {\n return this._authorizeUrl;\n }\n protected tokenUrl(): string {\n return this._tokenUrl;\n }\n protected override userinfoUrl(): string | null {\n return this._userinfoUrl;\n }\n protected parseUser(payload: Record<string, unknown>): OAuthUser {\n return {\n provider: this.providerName,\n subject: String(payload.sub ?? payload.id),\n email: (payload.email as string) ?? null,\n name: (payload.name as string) ?? null,\n picture: (payload.picture as string) ?? null,\n raw: payload,\n };\n }\n}\n","/**\n * `WebhookSignatureVerifier` — HMAC signature verification for inbound\n * webhooks, mirroring `api.webhooks`.\n *\n * Providers compute `hmac(secret, body)` and ship the digest in a header (hex or\n * base64). This verifies it in constant time and exposes an Express middleware\n * that checks the header against the **raw** request body.\n */\n\nimport { type BinaryLike, createHmac, timingSafeEqual } from \"node:crypto\";\nimport type { Request, RequestHandler } from \"express\";\n\n/** Options for {@link WebhookSignatureVerifier}. */\nexport interface WebhookSignatureOptions {\n /** Digest algorithm (e.g. `\"sha256\"`, `\"sha512\"`). Default `\"sha256\"`. */\n algorithm?: string;\n /** Header carrying the signature. Default `\"X-Signature\"`. */\n headerName?: string;\n /** Digest encoding. Default `\"hex\"`. */\n encoding?: \"hex\" | \"base64\";\n /** Prefix stripped from the header before comparing (e.g. `\"sha256=\"`). */\n prefix?: string;\n}\n\n/** Verifies an HMAC webhook signature over a raw request body. */\nexport class WebhookSignatureVerifier {\n private readonly secret: BinaryLike;\n private readonly algorithm: string;\n private readonly headerName: string;\n private readonly encoding: \"hex\" | \"base64\";\n private readonly prefix: string;\n\n /**\n * @param secret - The shared signing secret.\n * @param options - Algorithm, header name, encoding and optional prefix.\n */\n constructor(secret: string | Buffer, options: WebhookSignatureOptions = {}) {\n this.secret = secret;\n this.algorithm = options.algorithm ?? \"sha256\";\n this.headerName = options.headerName ?? \"X-Signature\";\n this.encoding = options.encoding ?? \"hex\";\n this.prefix = options.prefix ?? \"\";\n }\n\n /** The header name this verifier reads. */\n get header(): string {\n return this.headerName;\n }\n\n /**\n * Compute the expected signature for a raw body.\n *\n * @param body - The raw request body.\n * @returns The signature in the configured encoding.\n */\n expected(body: BinaryLike): string {\n return createHmac(this.algorithm, this.secret).update(body).digest(this.encoding);\n }\n\n /**\n * Verify a signature against a raw body (constant time).\n *\n * @param body - The raw request body.\n * @param signature - The header value (including any configured prefix).\n * @returns `true` when it matches.\n */\n verify(body: BinaryLike, signature: string): boolean {\n let candidate = signature;\n if (this.prefix && candidate.startsWith(this.prefix)) {\n candidate = candidate.slice(this.prefix.length);\n }\n const expected = Buffer.from(this.expected(body));\n const provided = Buffer.from(candidate);\n if (expected.length !== provided.length) return false;\n return timingSafeEqual(expected, provided);\n }\n\n /**\n * Build an Express middleware that rejects requests with a bad signature.\n *\n * The route **must** receive the raw body as a `Buffer` — mount\n * `express.raw({ type: \"...\" })` (matching every content type) before this\n * middleware so `req.body` is the raw bytes. On success the request proceeds\n * (parse `req.body` yourself).\n *\n * @param options - Custom error message.\n * @returns An Express middleware.\n */\n middleware(options: { errorMessage?: string } = {}): RequestHandler {\n const errorMessage = options.errorMessage ?? \"Invalid webhook signature\";\n return (req: Request, res, next) => {\n const signature = req.header(this.headerName) ?? \"\";\n const body: BinaryLike = Buffer.isBuffer(req.body)\n ? req.body\n : Buffer.from(typeof req.body === \"string\" ? req.body : \"\");\n if (!signature || !this.verify(body, signature)) {\n res.status(401).json({ detail: errorMessage, code: \"UNAUTHORIZED\", details: {} });\n return;\n }\n next();\n };\n }\n}\n","/**\n * `makeToolSpecRouter` — a machine-readable capability manifest at the root\n * prefix, mirroring `api.routers.tool_spec`.\n *\n * Services expose a small manifest so callers discover capabilities without\n * parsing the full OpenAPI document. Pass a static object, a sync provider, or\n * an async provider (recomputed per request).\n */\n\nimport { Router } from \"express\";\n\n/** The manifest, or a (possibly async) provider of it. */\nexport type SpecProvider =\n | Record<string, unknown>\n | (() => Record<string, unknown>)\n | (() => Promise<Record<string, unknown>>);\n\n/** Options for {@link makeToolSpecRouter}. */\nexport interface ToolSpecOptions {\n /** Endpoint path. Default `\"/tool-spec\"`. */\n path?: string;\n}\n\n/**\n * Build a router serving the manifest at a root-prefix `GET` route.\n *\n * @param spec - A static object or a sync/async provider.\n * @param options - The endpoint path.\n * @returns An Express router with a single `GET` route.\n */\nexport function makeToolSpecRouter(\n spec: SpecProvider,\n options: ToolSpecOptions = {},\n): Router {\n const router = Router();\n const path = options.path ?? \"/tool-spec\";\n\n router.get(path, (_req, res, next) => {\n Promise.resolve(typeof spec === \"function\" ? spec() : spec)\n .then((result) => res.json(result))\n .catch(next);\n });\n\n return router;\n}\n","/**\n * `makeLogsRouter` — a paginated read endpoint over the file logs, mirroring\n * `api.routers.logs`.\n *\n * Reads the per-level / `500.log` files written by `configureFileLogging`,\n * parses each JSON line, and serves the newest-first, offset-paginated. Guard it\n * (this exposes operational data) with any middleware you pass in `guards`.\n */\n\nimport { readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { HTTP_500_LOG_FILE, LEVEL_LOG_FILES } from \"@/utils/log\";\nimport { type RequestHandler, Router } from \"express\";\n\n/** Selector for which log file(s) to read. */\nexport type LogSource = \"all\" | \"debug\" | \"info\" | \"warning\" | \"error\" | \"500\";\n\n/** Options for {@link makeLogsRouter}. */\nexport interface LogsRouterOptions {\n /** Directory holding the log files (same one passed to `configureFileLogging`). */\n dir: string;\n /** Endpoint path. Default `\"/logs\"`. */\n path?: string;\n /** Middlewares run before the handler (e.g. a token guard). */\n guards?: RequestHandler[];\n}\n\nfunction filesFor(dir: string, source: LogSource): string[] {\n if (source === \"500\") return [join(dir, HTTP_500_LOG_FILE)];\n if (source === \"all\") return Object.values(LEVEL_LOG_FILES).map((f) => join(dir, f));\n return [join(dir, LEVEL_LOG_FILES[source])];\n}\n\nasync function readEntries(files: string[]): Promise<Record<string, unknown>[]> {\n const entries: Record<string, unknown>[] = [];\n for (const file of files) {\n let content: string;\n try {\n content = await readFile(file, \"utf8\");\n } catch {\n continue; // missing file — skip\n }\n for (const line of content.split(\"\\n\")) {\n if (!line.trim()) continue;\n try {\n entries.push(JSON.parse(line) as Record<string, unknown>);\n } catch {\n // Skip a single corrupt line rather than failing the endpoint.\n }\n }\n }\n return entries;\n}\n\n/**\n * Build a router serving `GET <path>` with query params `source`, `page` and\n * `pageSize`. Returns `{ items, total, page, pageSize, pages }`, newest first.\n *\n * @param options - Log directory, path and optional guards.\n * @returns An Express router.\n */\nexport function makeLogsRouter(options: LogsRouterOptions): Router {\n const router = Router();\n const path = options.path ?? \"/logs\";\n const guards = options.guards ?? [];\n\n const handler: RequestHandler = (req, res, next) => {\n const source = (req.query.source as LogSource) ?? \"all\";\n const validSources: LogSource[] = [\"all\", \"debug\", \"info\", \"warning\", \"error\", \"500\"];\n if (!validSources.includes(source)) {\n res\n .status(422)\n .json({ detail: \"Invalid log source\", code: \"VALIDATION_ERROR\", details: {} });\n return;\n }\n const page = Math.max(1, Number(req.query.page) || 1);\n const pageSize = Math.min(500, Math.max(1, Number(req.query.pageSize) || 50));\n\n readEntries(filesFor(options.dir, source))\n .then((entries) => {\n // Newest first when a timestamp is present; else keep file order reversed.\n entries.reverse();\n const total = entries.length;\n const start = (page - 1) * pageSize;\n res.json({\n items: entries.slice(start, start + pageSize),\n total,\n page,\n pageSize,\n pages: Math.ceil(total / pageSize),\n });\n })\n .catch(next);\n };\n\n router.get(path, ...guards, handler);\n return router;\n}\n","/**\n * In-memory test-database helpers, mirroring `testing.database`.\n *\n * Stand up a fully-wired `tempest-db-js` engine over an in-memory SQLite\n * database whose schema is created directly from your models — no migration\n * files, no temp files, no external service. One shared connection backs both\n * the DDL and every session, so repositories see the tables you declared.\n *\n * The helpers are framework-agnostic (no `vitest`/`jest` import), so wrap them\n * in whatever harness the consuming project uses.\n */\n\nimport {\n type AsyncDriver,\n AsyncEngine,\n type AsyncSession,\n type ModelClass,\n NodeSqliteDriver,\n} from \"tempest-db-js\";\nimport { reflectTable, renderOperation } from \"tempest-db-js/migrations\";\n\n/** A disposable in-memory test database. */\nexport interface TestDatabase {\n /** The wired async engine — hand its sessions to repositories. */\n readonly engine: AsyncEngine;\n /** Open a fresh session on the shared in-memory connection. */\n session(): AsyncSession;\n /** Dispose the engine and drop the in-memory database. */\n close(): Promise<void>;\n}\n\n/**\n * Create an in-memory SQLite test database with tables reflected from `models`.\n *\n * @param models - The model classes whose tables should be created.\n * @returns A {@link TestDatabase} — remember to `await close()` in teardown.\n *\n * @example\n * ```ts\n * const db = createTestDatabase([UserModel]);\n * const repo = new UserRepository(db.session());\n * await repo.create({ name: \"Ana\", email: \"ana@x.com\", passwordHash: \"...\" });\n * await db.close();\n * ```\n */\nexport function createTestDatabase(models: readonly ModelClass[]): TestDatabase {\n const driver = NodeSqliteDriver.open(\":memory:\");\n for (const model of models) {\n const table = reflectTable(model);\n for (const statement of renderOperation({ kind: \"create_table\", table }, \"sqlite\")) {\n driver.execute(statement, []);\n }\n }\n // Wrap the single sync SQLite connection as an async driver so `AsyncEngine`\n // (and therefore `BaseRepository`) runs against the very connection that owns\n // the freshly-created tables.\n const asyncDriver: AsyncDriver = {\n execute: (sql, params) => Promise.resolve(driver.execute(sql, params)),\n close: () => {\n driver.close();\n return Promise.resolve();\n },\n };\n const engine = new AsyncEngine(asyncDriver, \"sqlite\");\n return {\n engine,\n session: () => engine.session(),\n close: () => engine.close(),\n };\n}\n\n/**\n * Run `fn` against a fresh in-memory test database, disposing it afterwards even\n * if `fn` throws.\n *\n * @param models - The model classes whose tables should be created.\n * @param fn - Receives the {@link TestDatabase} and returns a promise.\n * @returns Whatever `fn` resolves to.\n *\n * @example\n * ```ts\n * await withTestDatabase([UserModel], async (db) => {\n * const repo = new UserRepository(db.session());\n * expect(await repo.count()).toBe(0);\n * });\n * ```\n */\nexport async function withTestDatabase<T>(\n models: readonly ModelClass[],\n fn: (db: TestDatabase) => Promise<T>,\n): Promise<T> {\n const db = createTestDatabase(models);\n try {\n return await fn(db);\n } finally {\n await db.close();\n }\n}\n","/** The installed SDK version. Single source of truth for the barrel + CLI. */\nexport const VERSION = \"0.24.0\";\n"]}