@palbase/backend 39.1.7 → 40.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/palbase-backend.cjs.map +1 -1
- package/dist/bin/palbase-backend.js +2 -2
- package/dist/{chunk-C525N4OW.js → chunk-AS2HDWVQ.js} +3 -2
- package/dist/{chunk-C525N4OW.js.map → chunk-AS2HDWVQ.js.map} +1 -1
- package/dist/{chunk-H7EKL6HC.js → chunk-RA7KFELX.js} +88 -2
- package/dist/chunk-RA7KFELX.js.map +1 -0
- package/dist/db/index.d.cts +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/engine/index.cjs +2 -0
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.cts +3 -3
- package/dist/engine/index.d.ts +3 -3
- package/dist/engine/index.js +4 -2
- package/dist/{index-fLaf0PN2.d.ts → index-B8zC9oV0.d.ts} +3 -3
- package/dist/{index-Db5QHdTa.d.cts → index-BAjRbjnq.d.cts} +3 -3
- package/dist/{index-QWN1Ncrv.d.ts → index-Ck2K1TgC.d.ts} +3 -3
- package/dist/{index-CCY1h_J2.d.cts → index-t7Ie44mM.d.cts} +3 -3
- package/dist/index.cjs +84 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -18
- package/dist/index.d.ts +20 -18
- package/dist/index.js +2 -61
- package/dist/index.js.map +1 -1
- package/dist/openapi/index.d.cts +2 -2
- package/dist/openapi/index.d.ts +2 -2
- package/dist/{registry-CH6HRR6T.d.cts → registry-C88au7ti.d.cts} +1 -1
- package/dist/{registry-C7tCRyPm.d.ts → registry-wwVUGunv.d.ts} +1 -1
- package/dist/stack.cjs.map +1 -1
- package/dist/stack.d.cts +21 -6
- package/dist/stack.d.ts +21 -6
- package/dist/test/index.cjs +19 -1
- package/dist/test/index.cjs.map +1 -1
- package/dist/test/index.d.cts +21 -2
- package/dist/test/index.d.ts +21 -2
- package/dist/test/index.js +18 -1
- package/dist/test/index.js.map +1 -1
- package/docs/README.md +6 -6
- package/docs/llms-full.txt +6 -6
- package/package.json +3 -6
- package/template/AGENTS.md +14 -14
- package/template/modules/notes/notes.e2e.test.ts +53 -0
- package/template/package.json +2 -2
- package/dist/chunk-H7EKL6HC.js.map +0 -1
- package/template/scripts/test.sh +0 -33
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/runtime.ts","../src/db/input-guards.ts","../src/db/tx-plan.ts","../src/db/transaction-options.ts","../src/db/schema-json.ts","../src/clients/http.ts","../src/clients/auth.ts","../src/clients/documents.ts","../src/clients/flags.ts","../src/clients/notifications.ts","../src/clients/realtime.ts","../src/clients/storage.ts","../src/clients/index.ts","../src/db/policy.ts","../src/db/foreign-key.ts","../src/db/guard.ts","../src/db/backfill.ts","../src/db/schema.ts","../src/channels.ts","../src/db/extensions.ts","../src/db/columns.ts","../src/db/raw.ts","../src/db/embedding.ts","../src/db/sqlstate.ts","../src/errors.ts","../src/db/typed-db.ts","../src/db/repository.ts","../src/refusals.ts","../src/db/unique.ts","../src/db/env-gen.ts","../src/stack-gen.ts","../src/decorators/registry.ts","../src/decorators/controller.ts","../src/decorators/methods.ts","../src/decorators/surface-name.ts","../src/decorators/webhook.ts","../src/decorators/hook.ts","../src/decorators/upload.ts","../src/decorators/sse.ts","../src/decorators/room.ts","../src/decorators/params.ts","../src/middleware.ts","../src/error-registry.ts","../src/decorators/injectable.ts","../src/decorators/kinds.ts","../src/decorators/module.ts","../src/container.ts","../src/job.ts","../src/decorators/job.ts"],"sourcesContent":["export type {\n PBRequest,\n ClientInfo,\n RateLimitConfig,\n DBClient,\n DBOps,\n FileContext,\n Logger,\n CacheClient,\n SecretsService,\n PalbaseDocsClient,\n PalbaseCollectionRef,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseWhereOperator,\n PalbaseResult,\n Middleware,\n ErrorDef,\n ErrorMap,\n ErrorThrowers,\n} from \"./endpoint.js\";\nexport {\n Database,\n Auth,\n Documents,\n Storage,\n Cache,\n Secrets,\n Log,\n Notifications,\n Flags,\n Realtime,\n __setRuntime,\n __runWithRuntime,\n __requestALS,\n __getRuntime,\n // Where a long-lived resource lives: opened once as the app comes up, closed\n // when it goes away. `__runStartHooks` is the engine's door to them (it\n // CLAIMS the declarations, so a candidate release loaded beside the live one\n // never closes the live one's pool); `__resetLifecycleHooks` is for tests.\n onStart,\n onShutdown,\n __runStartHooks,\n __resetLifecycleHooks,\n} from \"./runtime.js\";\nexport type {\n RuntimeServices,\n RequestStore,\n LifecycleHook,\n ShutdownRunner,\n} from \"./runtime.js\";\n\n// The module clients and their composition root. The PROCESS calls\n// buildModuleClients once at boot and hands the result to createApp — which is\n// the whole reason this package now contains the implementations and not just\n// the interfaces they were being checked against by nobody.\nexport { buildModuleClients } from \"./clients/index.js\";\nexport type { ModuleClientsConfig } from \"./clients/index.js\";\nexport { makeHttpClient, PalbaseModuleError } from \"./clients/http.js\";\n// The one named refusal the role surface raises. Exported because a handler\n// branches on it: a role name that misses is a typo in committed code.\nexport { RoleNotDefined } from \"./clients/auth.js\";\nexport type { ModuleTransport, RequestOptions, TransportConfig } from \"./clients/http.js\";\n\nexport type {\n PalbaseAuthClient,\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseRealtimeClient,\n PalbaseFunctionsClient,\n PalbaseInvokeOptions,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseFlagSource,\n PalbaseSetOverrideResult,\n PalbaseSetOverridesResult,\n PalbaseClearOverrideResult,\n PalbaseClearAllOverridesResult,\n PalbaseBatchOverrideOperation,\n PalbaseBatchSetOverridesResult,\n PalbaseNotificationsClient,\n PalbasePushClient,\n PalbaseEmailClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseInboxClient,\n PalbasePreferencesClient,\n PalbaseAnalyticsClient,\n PalbaseAnalyticsQueryNamespace,\n PalbaseAnalyticsManagementNamespace,\n PalbaseLinksClient,\n // Shared local types\n PalbaseUser,\n PalbaseSession,\n PalbaseDeviceInfo,\n PalbaseAttestAndroidParams,\n PalbaseAttestAndroidResult,\n PalbaseAttestiOSParams,\n PalbaseAttestiOSResult,\n PalbaseBindDeviceParams,\n PalbaseVerifyRequestSignatureParams,\n PalbaseFileObject,\n PalbaseSignedUrlResponse,\n PalbaseUploadOptions,\n PalbaseTransformOptions,\n PalbaseListOptions,\n PalbasePushSendParams,\n PalbasePushSendResponse,\n PalbaseEmailSendParams,\n PalbaseEmailSendResponse,\n PalbaseSmsSendParams,\n PalbaseSmsSendResponse,\n PalbaseWhatsAppTemplate,\n PalbaseWhatsAppSendParams,\n PalbaseWhatsAppSendResponse,\n PalbaseWhatsAppEvent,\n PalbaseInboxSendParams,\n PalbaseInboxSendResponse,\n PalbaseInboxMessage,\n PalbaseInboxListOptions,\n PalbaseInboxListResult,\n PalbasePreferences,\n PalbaseNotificationChannel,\n PalbaseRegisterDeviceParams,\n PalbaseDeviceTokenView,\n PalbaseMultiChannelResponse,\n PalbaseAnalyticsProperties,\n PalbaseIdentifyTraits,\n PalbaseCountQueryInput,\n PalbaseCountResult,\n PalbaseEventsQueryInput,\n PalbaseEventsResult,\n PalbaseUsersQueryInput,\n PalbaseUsersResult,\n PalbaseFunnelQueryInput,\n PalbaseFunnelResult,\n PalbaseRetentionQueryInput,\n PalbaseRetentionResult,\n PalbaseCohortQueryInput,\n PalbaseCohortResult,\n PalbaseOverviewResult,\n PalbaseEventNamesResult,\n PalbaseUserDetailResult,\n PalbaseCreateLinkParams,\n PalbaseUpdateLinkParams,\n PalbaseLink,\n PalbaseLinkDetails,\n PalbaseLinkAnalytics,\n PalbaseQrCodeOptions,\n PalbaseMatchParams,\n PalbaseInitialLink,\n PalbaseListLinksOptions,\n PalbaseListLinksResult,\n} from \"./clients.js\";\nexport { defineSchema, defineTable, TABLE_META, index, IndexBuilder, foreignKey, freeze, guard, backfill } from \"./db/schema.js\";\nexport type { ForeignKeyBuilder, ForeignKeyDef, FkAction, FkMatch, FreezeBuilder, FreezeDef } from \"./db/foreign-key.js\";\nexport type { GuardBuilder, GuardDef, GuardEvent } from \"./db/guard.js\";\nexport type { BackfillDef } from \"./db/backfill.js\";\n// The declaration as DATA — what the deploy reads to build the database. The\n// bundler calls this; a project never has to.\nexport { toSchemaJSON } from \"./db/schema-json.js\";\nexport type { SchemaJSON, TableJSON, ColumnJSON, PolicyJSON, ForeignKeyJSON, FreezeJSON, GuardJSON, BackfillJSON } from \"./db/schema-json.js\";\n// `SchemaInput` is NOT here. It typed the retired dictionary form —\n// `defineSchema({ tables: { todos: { columns } } })` — which `defineSchema`\n// now refuses by name (FR-061), so nothing can be assigned to it and nothing\n// ever imported it. Publishing the type of a shape the code rejects is a\n// second way in that only exists in the editor: its JSDoc taught the old\n// layout to anyone who hovered it.\nexport type { SchemaDef, TableDef, TableInput, ColumnMap, TableHandle, IndexDef } from \"./db/schema.js\";\nexport { policy, can, check, PolicyBuilder, PolicyExprRef, exprCtx } from \"./db/policy.js\";\n// `TableRef` bir tablo bildiriminin ANNOTATION'ı: iki tablo birbirinin\n// kolonuna `existsIn` ile bakınca TypeScript ikisini de birbirinden\n// çıkarmaya çalışır ve döngüyü `any` ile keser. Annotation döngüyü kırar ve\n// kolon adlarını tipli bırakır — bu yüzden TÜKETİCİNİN yazabilmesi gerekir.\nexport type { PolicyDef, PolicyCommand, PolicyMode, PolicyExpr, PolicyBinOp, PolicyExprCtx, PolicyOperand, CheckDef, TableRef } from \"./db/policy.js\";\n// The realtime twin of `policy`: which channels exist and who may join them.\n// Undeclared channels are denied by the server, so this declaration is the\n// whole surface — the runtime reads it back off globalThis at boot.\nexport { defineChannels, ownerOnly, publicChannel } from \"./channels.js\";\nexport type { ChannelsDef, ChannelEntry, ChannelsInput, ChannelGrant, ChannelAuthorizeCtx } from \"./channels.js\";\nexport { PALBASE_EXTENSIONS, EXTENSION_DEPENDENCIES, isPalbaseExtension } from \"./db/extensions.js\";\nexport type { PalbaseExtension } from \"./db/extensions.js\";\nexport {\n uuid, text, integer, bigint, numeric, boolean, timestamp, jsonb, enumType, vector,\n ownedByUser, userRef, installationRef,\n} from \"./db/columns.js\";\nexport type { ColumnBuilder, ColumnDef, ColumnType, OnDeleteAction, AnyColumn } from \"./db/columns.js\";\nexport { raw } from \"./db/raw.js\";\nexport type { RawConstraintDef } from \"./db/raw.js\";\nexport { openai } from \"./db/embedding.js\";\nexport type { EmbeddingModelRef } from \"./db/embedding.js\";\nexport { makeTypedDB, col, sqlFragment, withRetry } from \"./db/typed-db.js\";\nexport type { AtomicDatabase, PageInput } from \"./db/typed-db.js\";\nexport type { Page, PageInfo, PageNavigation, RawPageOptions } from \"./db/page.js\";\nexport type { InsertManyOptions } from \"./db/bulk.js\";\nexport type { CommandOptions } from \"./db/command.js\";\nexport type { AtomicOptions, TransactionIsolation } from \"./db/transaction-options.js\";\nexport type {\n TypedDB,\n TypedTx,\n TypedTable,\n InsertShape,\n RowShape,\n EnvTypedDatabase,\n EnvServiceDatabase,\n EnvTypedTable,\n EnvTables,\n EnvSchemas,\n TxPlan,\n TxTables,\n ColRef,\n SqlFragment,\n SetValue,\n SetShape,\n // FİLTRE TİPLERİ — bir sorguyu parça parça kurup fonksiyonlar arasında\n // geçirebilmek için ADLANDIRILABİLİR olmaları gerekiyor. Yoksa\n // `function siparisFiltresi(): ???` yazılamıyor ve yazar ya `Parameters<...>`\n // gibi bir kaçamağa ya da her şeyi tek çağrıda toplamaya mecbur kalıyor.\n // (`TxWhere` — plan yolunun filtresi — zaten dışa aktarılıyordu; düz yolunki\n // atlanmıştı.)\n WhereFilter,\n WhereOp,\n QueryInput,\n MutateInput,\n AggregateInput,\n AggregateResult,\n InsertValues,\n OrderBySpec,\n FindManyOpts,\n} from \"./db/typed-db.js\";\n// Transaction plans: the `tx.tables.*` operation surface, its handles, and the\n// expressions a plan may write. `Database.$transaction()` is on `Database`.\nexport { increment, decrement, inc, dec, now, TxRefError, TxPlanError } from \"./db/tx-plan.js\";\nexport type {\n Ref,\n TxRow,\n TxRows,\n TxTable,\n TxPlanHandle,\n Materialized,\n TxNow,\n TxColumnExpr,\n TxInsertValue,\n TxSetValue,\n TxInsertShape,\n TxSetShape,\n TxWhere,\n TxSelectOptions,\n TxPlanBody,\n TxPlanResponse,\n TxPlanOpResult,\n TxPlanRejection,\n TxWireOp,\n TxWireRef,\n TxWireExpr,\n TxWireGuard,\n TxWireValue,\n} from \"./db/tx-plan.js\";\n// Kiracıya kapsanmış CRUD'un TEK yazımı. `defineRepository` bir TABAN SINIFI\n// üretir (`class TodoRepository extends defineRepository(Database.public.todos,\n// { tenant: \"household_id\" }) {}`); `RepositoryOf` onun yüzeyi, `RepositoryTable`\n// ise repo'nun tablodan istediği alt küme — kendi tablo sarmalayıcısını yazan\n// bir proje ona göre yazar. Satır anahtarı varsayılan olarak `id`, ama SABİT\n// DEĞİL: `defineTable` bir `id` kolonu şart koşmadığı için `{ key: \"slug\" }`\n// ile adlandırılabiliyor (`DefaultRowKey`/`RowKey` o seçimin tipleri).\nexport { defineRepository } from \"./db/repository.js\";\nexport type {\n DefaultRowKey,\n MissingRowKey,\n RepositoryOf,\n RepositoryTable,\n RowKey,\n} from \"./db/repository.js\";\nexport type { Tables, TableTypes } from \"./db/env.js\";\nexport { makeEnvDts } from \"./db/env-gen.js\";\n// `config/` IS GONE, and so is the purchases family. Both were author-facing\n// surfaces with nothing behind them.\n//\n// The five config declarations nobody applied — storage, flags, notifications,\n// egress, auth — stopped being applied when the server-side declaration applier\n// was retired (v2 S-005, \"settings have one door, and a second one is how the\n// two disagree\"); `contract_lock_test.go` keeps it retired, and its own comment\n// records that the applier produced that silent failure FIVE times. The two that\n// still worked travelled by CLI courier: `config/secrets.ts` gated the push and\n// `config/test-users.ts` was PUT at the stack. Both jobs are now done where the\n// setting lives — `palbase secret set`, `palbase test-user templates set` — and\n// what a controller may SPELL comes back as a type instead of a declaration.\n//\n// `purchases` never had a v2 backend at all: v2 contains no palstore, which\n// `clients/index.ts` recorded on 2026-08-15 while deliberately leaving the tree\n// in place. It is taken now.\n//\n// The rule that replaced all of it: the schema files under `db/` and\n// behaviour-carrying code\n// live in the repo; everything else is CONFIGURATION and is set through the CLI\n// (later MCP) against the stack. Codegen exists so that code can be written\n// against it — a generated type is not a declaration, and it produces no file an\n// author edits.\nexport type { PalbaseSecretName, PalbaseFlagKey, PalbaseBucketName } from \"./stack.js\";\nexport { makeStackDts } from \"./stack-gen.js\";\nexport type { StackNames } from \"./stack-gen.js\";\n// Class-controller decorator model (replaces defineController/defineHandler/route).\n// `getRegisteredControllers` is what makes exporting a controller OPTIONAL:\n// importing the file registers it. `Controller` stays exported for authoring.\nexport { Controller, getRegisteredControllers, __resetRegisteredControllers } from \"./decorators/controller.js\";\n// The APPLICATION-level ring of the auth cascade (route → controller →\n// application → true). Declared once at module scope instead of repeating the\n// same `auth` on every @Controller — the repetition is what gets forgotten.\nexport { defineDefaultAuth, __resetDefaultAuth, assertZeroArgConstructor, resolveEffectiveAuth } from \"./decorators/controller.js\";\nexport type { ControllerOptions } from \"./decorators/controller.js\";\nexport { Get, Post, Put, Patch, Delete, Query } from \"./decorators/methods.js\";\nexport { Deny, getHookConfig, getHookManifest, Hook } from \"./decorators/hook.js\";\nexport type { HookFn, ResolvedHookClass } from \"./decorators/hook.js\";\nexport { Upload } from \"./decorators/upload.js\";\nexport type { UploadConfig } from \"./decorators/upload.js\";\n// `UploadedObject` is exported from upload.js, where BOTH the `@UploadedObject()`\n// decorator value AND the `UploadedObject` type are declared. One module → one\n// export name carries both — authors write `@UploadedObject()` (value) and\n// `: UploadedObject` (type) with a single imported name.\nexport { UploadedObject } from \"./decorators/upload.js\";\n// `@Sse` + its two parameter companions. `SseWriter` is the writer `@SseOut()`\n// injects; `SseConfig` is the route marker's type. The pipeline keys off the\n// config's PRESENCE, not the HTTP verb — see decorators/sse.ts.\nexport { Sse, SseOut, Signal } from \"./decorators/sse.js\";\nexport type { SseConfig, SseWriter } from \"./decorators/sse.js\";\n\n// `@Room` + its six lifecycle hooks. A room is the realtime surface a backend\n// can MANAGE rather than only talk on: it sees who joined, who left, and when\n// nobody is watching any more. Marked by the config's PRESENCE, like every\n// other decorator here — see decorators/room.ts.\nexport {\n Room,\n OnAuthorize,\n OnFirst,\n OnJoin,\n OnLeave,\n OnEmpty,\n OnMessage,\n} from \"./decorators/room.js\";\nexport type { RoomOptions } from \"./decorators/room.js\";\nexport {\n Body,\n QueryParams,\n Headers,\n Param,\n User,\n OptionalUser,\n Client,\n RequestId,\n TraceId,\n Req,\n} from \"./decorators/params.js\";\nexport type { RouteOptions, HttpMethodUpper, ThrowDescriptor, RouteMeta, ParamMeta, ParamKind } from \"./decorators/registry.js\";\n// recordThrows is the stager-injected carrier for inferred throw descriptors\n// (the recordReturn twin) — public so the injected IIFE in a deployed bundle\n// can call it via `require(\"@palbase/backend\").recordThrows(...)`.\nexport { recordThrows } from \"./decorators/registry.js\";\n// getRoutes reads a controller's RouteMeta[] straight from the registry — the\n// isolate runtime enumerates routes with it instead of the worker.js raw-Symbol\n// fallback (the ROUTES symbol stays, both fallbacks keep reading it).\nexport { getRoutes } from \"./decorators/registry.js\";\nexport { defineMiddleware } from \"./middleware.js\";\nexport type { MiddlewareContext, MiddlewareHandler } from \"./middleware.js\";\n// The authenticated-user TYPE is exported as `UserT` (not `User`) because the\n// value name `User` is the @User() parameter decorator (exported above). A\n// controller annotates `@User() user: UserT` — decorator for the value\n// position, `UserT` for the type. (NestJS-style: same name as the decorator\n// would collide in the value+type namespaces.)\nexport type { User as UserT, VerifiedDevice, HttpMethod, AuthConfig } from \"./types.js\";\nexport {\n HttpError,\n PalError,\n BadRequest,\n Unauthorized,\n Forbidden,\n NotFound,\n Conflict,\n TooManyRequests,\n // 23505, typed. The engine throws it; a caller branches on `.constraint`\n // instead of matching the driver's message string.\n UniqueViolation,\n SerializationFailure,\n DeadlockDetected,\n isRetryable,\n} from \"./errors.js\";\n// Typed project errors — defineError returns an HttpError subclass and\n// self-registers {code, status, dataSchema} in the project-global error\n// registry (the OpenAPI spec twins join `RouteMeta.throws` against it).\nexport { defineError, getErrorRegistry } from \"./error-registry.js\";\nexport type { RegisteredError, DefinedError, DefinedErrorWithData } from \"./error-registry.js\";\nexport type { JobMeta } from \"./job.js\";\nexport type { WebhookProvider, WebhookMeta, WebhookRequest } from \"./webhook.js\";\n// Webhooks and jobs are classes: `@Webhook`/`@On` for inbound webhooks,\n// `@Job` for cron. Both take their name from their file — see decorators/*.\nexport { getWebhookConfig, getWebhookManifest, On, Webhook } from \"./decorators/webhook.js\";\n\n// ── dependency injection ───────────────────────────────────────────────────\n//\n// `Injectable` and `Module` are the whole authoring surface: a class says it can\n// be resolved, and ONE module says who owns it, what it exports and what it may\n// reach. There is no `inject()`, no `@Inject`, no token registry — a dependency\n// is named by its constructor parameter's type and by nothing else.\nexport { Injectable } from \"./decorators/injectable.js\";\n// Which of a container's owned classes are entry points of each kind. Discovery\n// used to be a DIRECTORY (jobs/*.ts); now a module lists the class and the\n// decorator says what it is.\nexport { controllersOf, hooksOf, jobsOf, roomsOf, webhooksOf } from \"./decorators/kinds.js\";\nexport { Module } from \"./decorators/module.js\";\nexport type { ModuleDef, Token } from \"./decorators/module.js\";\n// Internal seam, exported for the same reason __runStartHooks is: the engine and\n// the bundle carry SEPARATE copies of this package, and claiming has to be done\n// by the copy that builds the container.\nexport { __claimModules } from \"./decorators/module.js\";\n// The `@Injectable()` half of the same seam. It is what FR-010 counts, and a\n// test fixture that builds two containers in one process has to drain it\n// between them the way it drains modules — a leftover fails the NEXT build with\n// a true refusal about the wrong test.\nexport { __claimInjectables } from \"./decorators/injectable.js\";\nexport { DiError } from \"./container.js\";\n// THE ORPHAN CHECK, and it was a READER WITH NO WRITER.\n//\n// `build-check.js` has always guarded its call with\n// `typeof sdk.assertNoOrphanEntryPoints === 'function'` — and this line was\n// missing, so the guard was false every time and the check never ran on the\n// build path. Measured 2026-09-02 through the real CLI: a `@Controller` that no\n// module lists entered the route table and `palbase build` printed\n// \"build OK — 6 route(s)\", exit 0. The runtime refuses it at boot, which is\n// exactly the failure `palbase build` exists to catch first.\n//\n// `createApp` calls it too; it is exported because the LOCAL build has to reach\n// the same decision with the same code, which is the whole premise of that file.\nexport { assertNoOrphanEntryPoints } from \"./container.js\";\n// `createApp` calls this and hands the result back as `App.container`; a project\n// almost never needs it directly. It is exported because the runtime is the\n// framework's OTHER HALF and builds containers of its own, and because a\n// hand-built one is validated exactly like the engine's — same claim, same\n// refusals, no second way to get an unvalidated graph.\nexport { buildContainer } from \"./container.js\";\nexport type { Container, DiKind, ModulePressure } from \"./container.js\";\nexport type { ResolvedWebhook, SignatureSpec, WebhookEventHandler, WebhookOptions } from \"./decorators/webhook.js\";\nexport { getJobConfig, getJobManifest, Job } from \"./decorators/job.js\";\nexport type { JobOptions, ResolvedJob } from \"./decorators/job.js\";\n// `Resource` is GONE, not deprecated. Its boot registry was never wired: nothing\n// in the runtime ever called `__runResourceBoot` (measured 2026-08-29 —\n// `grep -rn \"ResourceBoot\"` across v2/runtime and palsvc returned nothing), so\n// `init(env)` never ran, the declared secrets never arrived, and a project that\n// wrote one got an object whose fields sat at their initializers with no error\n// anywhere. That is the same silence the `auth`/`storage`/`documents` hook\n// helpers were removed for, one surface down.\n//\n// Nothing replaces it, because the thing it was ceremony around is already the\n// stack's: the VAULT holds what a backend may read, the runtime lists those names\n// off it and mirrors them into `process.env` at boot, and `Secrets.get()` reads a\n// value with the rotation the deploy generation already carries. A field frozen\n// once inside `init(env)` could not have that. `static secrets` was therefore a\n// third list of names, behind the vault and behind `config/secrets.ts` — which is\n// itself down to a hint rather than a constraint (v2/runtime/src/server.ts:517).\n// `config/egress.ts` fences the calls a resource would have made and\n// `openai.embedding(...)` in the schema puts the one vendor client the platform\n// actually runs where the platform runs it. `resources/` stays exactly what the\n// bundler already treats it as — a directory of plain modules a controller\n// imports.\n// Types only. A hook is declared with @Hook/@On in hooks/*.ts.\n//\n// The `auth`/`storage`/`documents` helpers that used to live here are gone, not\n// deprecated: they returned a record nothing in the runtime or the bundler ever\n// read, so a project that called one got a handler that never ran and no error\n// anywhere. api-surface.mjs asks for a deprecation bridge because a major locks\n// every tenant's deploy — a real cost, and the reason this shipped as a bridge\n// in 20.0.0. There are no production tenants to lock yet (owner's call,\n// 2026-08-22), so the bridge is spending a release to soften a break nobody can\n// feel, and the honest surface is the one with no dead names in it.\nexport type {\n HookMeta,\n AuthHookEvent,\n DocumentHookEvent,\n FileUploadedEvent,\n FileDeletedEvent,\n} from \"./hooks.js\";\nexport { z } from \"zod\";\n\nexport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"./refusals.js\";\nexport type { UniqueWhere } from \"./db/unique.js\";\nexport type { DatabaseBudget, DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from \"./db/diagnostics.js\";\n","/**\n * runtime.ts — request-scoped service singletons.\n *\n * The backend SDK no longer threads a `ctx` god-object through every handler.\n * Instead, controller methods import PascalCase service singletons directly:\n *\n * import { Controller, Post, Body, Database } from \"@palbase/backend\";\n *\n * \\@Controller(\"/todos\")\n * export default class TodosController {\n * \\@Post(\"\") create(\\@Body(CreateTodoBody) body: CreateTodoBody): unknown {\n * return Database.public.todos.insert({ title: body.title });\n * }\n * }\n *\n * The singletons are thin Proxies. Every property access forwards to the live\n * client for the CURRENT request scope, resolved through {@link __getRuntime}.\n *\n * # Request-scope resolution (persistent app-server)\n *\n * The runtime is a long-running Node process that serves many concurrent\n * requests on one event loop (NOT a fresh subprocess per request). A single\n * module-global slot would let one in-flight request's services bleed into\n * another's. So the services are carried in an {@link AsyncLocalStorage} store\n * ({@link __requestALS}) that the runtime sets per request with\n * {@link __runWithRuntime}; every async continuation of that request reads its\n * own store. `__getRuntime` reads the ALS store first; the module-global slot\n * (set by {@link __setRuntime}) is only a fallback for callers that run OUTSIDE\n * an ALS scope (dev-server, unit tests, the legacy single-shot path). Because\n * each `br-<ref>` pod is single-tenant, there is no cross-tenant leakage; the\n * ALS store is what prevents cross-REQUEST leakage within the shared process.\n *\n * The seam that makes `import { Database } from \"@palbase/backend\"` resolve to\n * the runtime-injected client: `@palbase/backend` is marked esbuild-EXTERNAL\n * when the tenant bundle is built, and the package is installed globally in the\n * pod (NODE_PATH=/usr/local/lib/node_modules). So worker.js's\n * `require('@palbase/backend')` and the bundle's `import` resolve to ONE shared\n * module instance — the ALS store and `__setRuntime` slot on that instance are\n * visible to the singletons the bundle imported.\n */\n\nimport type { PalbaseFlagKey } from \"./stack.js\";\nimport type { Buckets, BucketTypes, Schemas } from \"./db/env.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type {\n DBClient,\n AtomicClient,\n DBOps,\n CacheClient,\n Logger,\n PalbaseDocsClient,\n SecretsService,\n} from \"./endpoint.js\";\nimport type {\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseNotificationsClient,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseSetOverrideResult,\n PalbaseRealtimeClient,\n} from \"./clients.js\";\nimport type { PalbaseResult } from \"./endpoint.js\";\nimport type {\n EnvTypedDatabase,\n EnvServiceDatabase,\n AtomicDatabase,\n EnvTables,\n TxPlan,\n TxTables,\n} from \"./db/typed-db.js\";\nimport type { Materialized } from \"./db/tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./db/tx-plan.js\";\nimport { assertPlanRetry, type AtomicOptions } from \"./db/transaction-options.js\";\nimport { qualifiedTableKey } from \"./db/schema-json.js\";\nimport type { DollarOps } from \"./db/typed-db.js\";\n\n/** The set of live clients the runtime injects per request scope.\n *\n * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but\n * cannot hold a subscription socket — `subscribe()` lives on the client SDK).\n *\n * EXCLUDED on purpose: Functions, Links, Analytics. They are not exposed as\n * backend handler singletons — out of scope for backend endpoints. `Auth` is\n * here in its ROLE-ASSIGNMENT shape only: signing in is the client SDK's job,\n * but granting a role is an operator verb the tenant's own handler needs\n * (FR-009). */\nexport interface RuntimeServices {\n Database: DBClient;\n Auth: PalbaseAuthAdminClient;\n Secrets: SecretsService;\n Documents: PalbaseDocsClient;\n Storage: PalbaseStorageClient;\n Cache: CacheClient;\n Log: Logger;\n Notifications: PalbaseNotificationsClient;\n Flags: PalbaseFlagsClient;\n Realtime: PalbaseRealtimeClient;\n}\n\n/**\n * The per-request ALS box.\n *\n * `runtime` is the service bundle. `userId` is the request's authenticated user\n * id, written by the runtime immediately after it assembles the request object\n * (worker.js: `requestALS.getStore().userId = pbReq.user?.id || null`) and\n * `null` on an anonymous request. It was already being written there for the\n * Flags client's auto-bind; declaring it here makes the existing contract typed\n * instead of implicit, which is what lets `currentSubjectId()` read a\n * server-owned identity rather than trusting anything the caller sent.\n */\nexport interface RequestStore {\n runtime: RuntimeServices;\n userId?: string | null;\n /** This request's id (`req_…`), written by the runtime. Used as the spend\n * idempotency scope when the caller supplied no `Idempotency-Key`. */\n requestId?: string;\n /** The caller's `Idempotency-Key` header, or `null` when absent. What makes a\n * client's retry replay its first result instead of charging twice. */\n idempotencyKey?: string | null;\n}\n\n/**\n * Per-request store. The persistent runtime runs each request inside\n * {@link __runWithRuntime}, so every async continuation of that request reads\n * its OWN `runtime` (and any other request-scoped fields the runtime adds).\n *\n * Exported with a `__` prefix so the runtime (worker.js) shares the SAME ALS\n * instance across the one module instance — two ALS instances would silently\n * not see each other's stores. NOT part of the public author-facing API.\n */\n/**\n * The per-request store — ON globalThis under a well-known Symbol, for the same\n * reason `lifecycleHooks` and the controller registry are.\n *\n * MEASURED, through the production package gate: `tsup` emits `dist/index.cjs`\n * and `dist/test/index.cjs` as SEPARATE bundles and each inlines this module.\n * With a module-local `AsyncLocalStorage`, `withServices` (which ships from the\n * `/test` subpath) opened a scope in ITS copy while the `Database` singleton\n * (which ships from the root) read the OTHER copy's — and the ambient service a\n * test had just installed was invisible:\n *\n * Error: Palbase services accessed outside a request scope.\n *\n * The unit tests could not see it: inside the package there is only ever one\n * copy. It took calling the built artifact the way a consumer does. Same class\n * as the defect `@Module`'s slot comment describes — two module-local values\n * where the two halves of one contract must agree.\n *\n * SÜRÜMSÜZ, VE BU BİLİNÇLİ. Anahtar `…requestALS@32` gibi sürümlenseydi iki\n * major aynı süreçte ALS'i paylaşmayı BIRAKIRDI — yani yukarıda anlatılan kusur\n * sürüm sınırında geri gelirdi. Bedeli de gerçek ve burada yazılı:\n * `RequestStore.runtime` zorunlu bir `RuntimeServices` ve o küme büyüyor\n * (30.0.0 `Auth` ile 9→10). Eski bir majorün yazdığı kutuyu yeni bir major\n * okursa yeni alan `undefined` gelir.\n *\n * Bu pakette YEDİ well-known Symbol var ve hepsi sürümsüz (`httpError`,\n * `engineRaised`, `channels`, `errorRegistry`, `declarationRefusal`,\n * `lifecycleHooks`, ve bu). Yalnız BİRİNİ sürümlemek tutarsızlıktan başka bir\n * şey üretmez: karar paket geneli olmalı ve `RequestStore`'un şekil\n * sözleşmesiyle birlikte alınmalı (sapma defteri D-05).\n */\nconst REQUEST_ALS: unique symbol = Symbol.for(\"palbase.backend.requestALS\") as never;\n\nexport const __requestALS: AsyncLocalStorage<RequestStore> = ((): AsyncLocalStorage<RequestStore> => {\n const g = globalThis as unknown as Record<symbol, AsyncLocalStorage<RequestStore> | undefined>;\n return (g[REQUEST_ALS] ??= new AsyncLocalStorage<RequestStore>());\n})();\n\n/** Process-global fallback slot. Used only OUTSIDE an ALS scope (dev-server,\n * unit tests, legacy single-shot worker). Inside the persistent server every\n * request runs in {@link __requestALS}, which takes precedence. */\nlet runtime: RuntimeServices | null = null;\n\n/** Install the live clients in the process-global fallback slot.\n *\n * Persistent-server requests should use {@link __runWithRuntime} instead; this\n * remains for dev-server / tests / the legacy single-shot path that run without\n * an ALS scope. NOT part of the public author-facing API. */\nexport function __setRuntime(services: RuntimeServices): void {\n runtime = services;\n}\n\n/** Run `fn` with `services` bound as the request-scoped runtime.\n *\n * The persistent worker calls this once per request so concurrent requests\n * never share a services slot. NOT part of the public author-facing API. */\nexport function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T {\n return __requestALS.run({ runtime: services }, fn);\n}\n\n/** Read the live clients, throwing if accessed outside a request scope.\n *\n * Resolves the ALS store first (persistent server, per-request), then the\n * process-global fallback (dev-server / tests). NOT part of the public\n * author-facing API — used by the runtime and the singleton Proxies. */\n/**\n * Bir kutunun TAŞIMASI GEREKEN servisler.\n *\n * `withServices`'in listesiyle aynı gerçeği söylüyor ama BURADA yaşamak\n * zorunda: `test/` yalnız test yüzeyinde, bu kontrol ise her isteğin yolunda.\n * İkisi de `satisfies` ile `RuntimeServices`'a pinli, yani biri eksik kalırsa\n * derleme durur.\n */\nconst REQUIRED_SERVICES = [\n \"Database\",\n \"Auth\",\n \"Secrets\",\n \"Documents\",\n \"Storage\",\n \"Cache\",\n \"Log\",\n \"Notifications\",\n \"Flags\",\n \"Realtime\",\n] as const satisfies readonly (keyof RuntimeServices)[];\n\n/**\n * ÇAPRAZ-MAJOR KUTUYU ADIYLA REDDET (sapma defteri D-05).\n *\n * `__requestALS` sürümSÜZ bir `Symbol.for` altında ve bu bilinçli: iki bundle\n * (`dist/index.cjs` ve `dist/test/index.cjs`) ambient kapsamı ancak öyle\n * paylaşır. Bedeli de gerçek — tek süreçte iki major varsa ESKİ olanın yazdığı\n * kutuyu YENİ olan okur, ve servis kümesi büyümüşse (30.0.0'da 9→10, `Auth`)\n * yeni alan `undefined` gelir.\n *\n * `undefined` bir servis, erişildiğinde `Reflect.get called on non-object`\n * verir: ne eksik olanın adı, ne sebebi. Bu kontrol o sessizliği bir cümleye\n * çevirir. Maliyeti istek başına on `in` kontrolü.\n */\nfunction refuseIncompleteBox(services: RuntimeServices): RuntimeServices {\n const missing = REQUIRED_SERVICES.filter((k) => services[k] === undefined);\n if (missing.length > 0) {\n throw new Error(\n `the request scope is missing ${missing.join(\", \")} — this box was most likely written by a ` +\n `DIFFERENT @palbase/backend major sharing the same process (the request store is a ` +\n `process-wide well-known Symbol, deliberately, so two bundles of ONE version can share it). ` +\n `Align the versions, or pass every service when building the scope yourself.`,\n );\n }\n return services;\n}\n\nexport function __getRuntime(): RuntimeServices {\n const scoped = __requestALS.getStore();\n if (scoped) return refuseIncompleteBox(scoped.runtime);\n if (runtime === null) {\n throw new Error(\n \"Palbase services accessed outside a request scope. The Database/Documents/… \" +\n \"singletons are only available inside an endpoint handler (or after the \" +\n \"runtime has called __runWithRuntime / __setRuntime).\",\n );\n }\n return runtime;\n}\n\n// ─── lifecycle: where a long-lived resource lives (FR-013) ─────────────────\n//\n// `Resource` was removed in 23.0.0 and nothing replaced the LIFECYCLE half of\n// it. What that left behind is measurable: a connection pool (the driver in\n// `docs/resources.md`'s own example was Neo4j) had no documented place to be\n// opened and NO WAY AT ALL to be closed, so every deploy left the pool it\n// opened behind. These two hooks are that half — and only that half. The\n// secret-distribution half does not come back: a handler reads `Secrets.get`,\n// and a start hook, which runs before any request scope exists, reads the\n// `process.env` the runtime mirrors the vault into at boot.\n\n/** A lifecycle hook. Sync or async; the runtime awaits what it returns. */\nexport type LifecycleHook = () => void | Promise<void>;\n\n/** Runs one release's shutdown hooks. Handed back by {@link __runStartHooks}\n * and called by the engine's `app.shutdown()`. Idempotent. */\nexport type ShutdownRunner = () => Promise<void>;\n\ninterface DeclaredHook {\n name: string;\n run: LifecycleHook;\n}\n\ninterface DeclaredLifecycle {\n start: DeclaredHook[];\n shutdown: DeclaredHook[];\n}\n\n/**\n * What has been DECLARED and not yet claimed by an app.\n *\n * On globalThis under a well-known Symbol for the reason the controller\n * registry is (`decorators/controller.ts`): a deployed bundle inlines its own\n * copy of this package, and the engine that has to RUN these hooks holds the\n * other copy. Two module-local arrays would mean the engine reads the empty one\n * and every declared hook is silently never run — which is exactly how\n * `Resource`'s `init(env)` died.\n */\nconst LIFECYCLE: unique symbol = Symbol.for(\"palbase.backend.lifecycleHooks\") as never;\n\nfunction declaredLifecycle(): DeclaredLifecycle {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n return (g[LIFECYCLE] ??= { start: [], shutdown: [] });\n}\n\n/**\n * Run `hook` ONCE while the application comes up, before it serves anything.\n *\n * Call it at MODULE SCOPE in a file the application imports — the same rule\n * `defineDefaultAuth` and `@Controller` follow, and for the same reason: the\n * declaration is claimed when the app boots, which is after module loading and\n * before the first request. `name` is not decoration: a hook that throws is\n * reported by that name and the boot is REFUSED, so it is what tells an\n * operator which resource did not come up.\n *\n * There is no request scope yet, so the `Database`/`Secrets`/… singletons are\n * NOT available inside a start hook. A secret is read from `process.env` here\n * (the runtime mirrors the vault into it at boot).\n *\n * @example\n * // resources/graph.ts\n * import neo4j from \"neo4j-driver\";\n * import { onStart, onShutdown } from \"@palbase/backend\";\n *\n * export let graph: Driver;\n * onStart(\"graph\", () => {\n * graph = neo4j.driver(process.env.NEO4J_URL!, neo4j.auth.basic(\"neo4j\", process.env.NEO4J_PASSWORD!));\n * });\n * onShutdown(\"graph\", () => graph.close());\n */\nexport function onStart(name: string, hook: LifecycleHook): void {\n declaredLifecycle().start.push({ name, run: hook });\n}\n\n/**\n * Run `hook` while the application shuts down — the place a pool opened in\n * {@link onStart} is closed.\n *\n * Shutdown is BEST-EFFORT by design: a hook that throws is reported by name and\n * the rest still run. A drain that abandoned the remaining hooks on the first\n * failure would leak exactly what this exists to release, and the process is\n * leaving anyway.\n *\n * Hooks run in REVERSE declaration order, so a resource is released before what\n * it was built on.\n */\nexport function onShutdown(name: string, hook: LifecycleHook): void {\n declaredLifecycle().shutdown.push({ name, run: hook });\n}\n\nfunction reason(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Best-effort drain: every hook runs, a failure is reported, none is silent. */\nasync function drain(hooks: DeclaredHook[]): Promise<void> {\n for (const h of [...hooks].reverse()) {\n try {\n await h.run();\n } catch (err) {\n console.error(`[palbase] shutdown hook \"${h.name}\" failed: ${reason(err)}`, err);\n }\n }\n}\n\n/**\n * CLAIM what has been declared, run the start hooks, and hand back the runner\n * for this release's shutdown hooks. Called by the engine's `createApp`; the\n * `App.shutdown()` it builds calls what comes back. NOT part of the public\n * author-facing API.\n *\n * IT CLAIMS RATHER THAN READS, which is what makes it correct in this runtime:\n * a candidate release is loaded BESIDE the live one in one process\n * (`v2/runtime/src/registry-scope.ts`), and both bundles append to the one\n * shared slot above. If each app read the whole list, the live app's shutdown\n * would close the candidate's pool and the candidate's would close the live\n * app's. Taking the declarations leaves each app holding exactly its own.\n *\n * A start hook that throws REFUSES THE BOOT — with the hook's name in the\n * message — after releasing whatever the earlier hooks already opened. Serving\n * from a half-initialised app is the silence this whole surface replaces, and a\n * boot that dies holding an open pool is the leak it replaces.\n */\nexport async function __runStartHooks(): Promise<ShutdownRunner> {\n const slot = declaredLifecycle();\n const start = slot.start.splice(0);\n const shutdown = slot.shutdown.splice(0);\n\n for (const h of start) {\n try {\n await h.run();\n } catch (err) {\n await drain(shutdown);\n throw new Error(`[palbase] start hook \"${h.name}\" failed: ${reason(err)}`, { cause: err });\n }\n }\n\n let drained = false;\n return async () => {\n // SIGTERM racing a redeploy asks twice; a pool is closed once.\n if (drained) return;\n drained = true;\n await drain(shutdown);\n };\n}\n\n/** Drop every declaration. For tests, which declare repeatedly in one process.\n * NOT part of the public author-facing API. */\nexport function __resetLifecycleHooks(): void {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n delete g[LIFECYCLE];\n}\n\n/**\n * Build a Proxy singleton that forwards every property access to the live\n * client named `key` on the current runtime.\n *\n * The single `as RuntimeServices[K]` is the only contained cast in the surface:\n * `Reflect.get` on a typed object returns `unknown` for a `string | symbol`\n * key, but `prop` is constrained to keys of the client interface at the call\n * sites (the exported singletons are typed below), so the forward is sound.\n */\nfunction makeServiceProxy<K extends keyof RuntimeServices>(key: K): RuntimeServices[K] {\n const handler: ProxyHandler<RuntimeServices[K]> = {\n get(_target, prop, receiver) {\n const client = __getRuntime()[key];\n const value = Reflect.get(client as object, prop, receiver) as unknown;\n // Bind methods to their owning client so `this` stays correct when the\n // author destructures or calls `Database.query(...)`.\n return typeof value === \"function\" ? value.bind(client) : value;\n },\n };\n // The Proxy target is irrelevant (all access goes through `get`); the cast\n // names the surface type the singleton presents to authors.\n return new Proxy({} as RuntimeServices[K], handler);\n}\n\n/**\n * Build the `.tables` accessor for the top-level `Database`. Each\n * `tables.<name>` access returns a small object that forwards the five CRUD ops\n * to the underlying client using `name` as the string table identifier. The\n * shapes are typed against the generated `palbase-env.d.ts` (`EnvTables`); at\n * runtime they are plain string-keyed calls, so no schema value is needed here.\n *\n * Returns `EnvTables` — TS cannot infer the mapped type through the Proxy, so\n * a single structural narrowing names the surface (the proxy returns a\n * correctly-shaped accessor for whatever string member is read).\n */\n/** T018 (C-8): similar/recommend'in string-keyed yüzü. DBOps'a (endpoint.ts)\n * BİLEREK eklenmedi — search-param imza üçlüsü (engine/db + typed-db +\n * endpoint) büyümesin: proxy dispatch runtime'da engine ops'una zaten ulaşır,\n * derleme güvenliğini typed yüzey (EnvTypedTable) verir. */\nexport interface RecoOps {\n similar(table: string, id: string, params?: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n recommend(table: string, params: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n}\n\n/**\n * The Proxy behind EVERY `.tables` map — public's and every other schema's.\n *\n * `prefix` is what the wire name is built from: `\"\"` for `public`, so its tables\n * stay BARE, and `\"<schema>.\"` for any other, so `schema(\"billing\").tables\n * .invoices` reaches the broker as `billing.invoices` (D-10 — the same\n * schema-qualified key `toSchemaJSON` and the generated `relations` use).\n *\n * One trap for both surfaces: two copies would be two op lists that can drift,\n * and the one that forgets an op does not complain — it answers `undefined`.\n */\nfunction makeTableProxy(ops: () => DBOps & RecoOps, prefix: string): object {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n const name = `${prefix}${prop}`;\n return {\n insert: (data: Record<string, unknown>) => ops().insert(name, data),\n // DÖRDÜNCÜ FİİL, aynı gerekçeyle: tip söz veriyor, ops katmanı\n // uyguluyor, ve bir handler'ın gerçekten dokunduğu yer BURASI.\n // `runtime-table-verbs` kapısı bunu adıyla saydı.\n aggregate: (q: Parameters<DBOps[\"aggregate\"]>[1]) => ops().aggregate(name, q),\n insertMany: (\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => ops().insertMany(name, rows, opts),\n update: (q: { where: { id: string }; set: Record<string, unknown> }) =>\n ops().update(name, q.where.id, q.set),\n delete: (id: string) => ops().delete(name, id),\n findById: (id: string) => ops().findById(name, id),\n findUnique: (q: { where: Record<string, unknown>; select?: readonly string[]; with?: Record<string, unknown> }) =>\n ops().findUnique(name, q.where, { select: q.select, with: q.with }),\n page: (q?: Record<string, unknown>) => {\n const { where, ...opts } = q ?? {};\n return ops().page(name, where as Record<string, unknown> | undefined, opts as import(\"./db/page.js\").RawPageOptions);\n },\n findMany: (q?: Record<string, unknown>) => {\n // `where` AYIKLANIR; kalan alanlar (orderBy/limit/offset) ham op'un\n // ikinci parametresine gider. Tümünü geçirmek `where`'i tel üstünde\n // ikinci kez gönderirdi — `typed-db.test.ts` bunu yakalıyor.\n const { where, ...opts } = q ?? {};\n return ops().findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<DBOps[\"findMany\"]>[2],\n );\n },\n put: (q: { data: Record<string, unknown>; onConflict: readonly string[] }) =>\n ops().put(name, q.data, { onConflict: q.onConflict }),\n // THREE VERBS THE TYPE PROMISED AND THIS PROXY DID NOT EMIT.\n //\n // `EnvTypedTableBase` declares `updateMany`, `deleteMany` and `count`\n // (typed-db.ts) and the ops layer implements all three — only this\n // proxy, which is what a handler actually touches, left them out. So\n // the type said the verb exists, autocomplete offered it, and the call\n // answered `undefined is not a function`.\n //\n // Older than this run, but the run rewrote this proxy for\n // `Database.schema(name).tables.*` and would have carried the gap onto\n // the new surface too.\n updateMany: (q: { where: Record<string, unknown>; set: Record<string, unknown>; returning?: boolean }) =>\n ops().updateMany(name, q.where, q.set, q.returning === undefined ? undefined : { returning: q.returning }),\n deleteMany: (q: { where: Record<string, unknown> }) => ops().deleteMany(name, q.where),\n count: (q?: { where?: Record<string, unknown> }) => ops().count(name, q?.where),\n search: (params?: Record<string, unknown>) => ops().search(name, params),\n similar: (id: string, params?: Record<string, unknown>) => ops().similar(name, id, params),\n recommend: (params: Record<string, unknown>) => ops().recommend(name, params),\n facets: (params: { facets: string[] } & Record<string, unknown>) => ops().facets(name, params),\n supersede: (id: string, row: Record<string, unknown>) => ops().supersede(name, id, row),\n claim: (unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n ops().claim(name, unique, extra),\n };\n },\n },\n );\n}\n\n\n/** The raw string-keyed `DBClient` for the current request scope. */\nconst rawDatabase: DBClient = makeServiceProxy(\"Database\");\n\n/**\n * Wrap a raw `DBClient` into the typed `{ ...ops, tables, transaction }`\n * surface. The five string ops forward straight through; `tables` is the\n * env-typed accessor; `transaction` yields typed tables. Reused for both the\n * default (RLS-enforced) `Database` and the `asService()` sibling — each is\n * fed its own raw client (the default proxy vs `rawDatabase.asService()`).\n *\n * The `satisfies` pins the op surface so a missing/renamed op is a compile\n * error; the assembled object carries `tables`/`transaction` alongside.\n */\n/**\n * PACKAGE-INTERNAL, and deliberately NOT re-exported from `index.ts`.\n *\n * `test/fake-db.ts` builds the fake's surface with the SAME constructor\n * production uses, so the two cannot drift: the day a `$op` is added here, the\n * fake grows it in the same commit. Exporting it from the public index instead\n * would put a runtime-assembly detail on the author-facing API (FR-006).\n */\nexport function makeTypedSurface(raw: AtomicClient & Partial<Pick<DBClient, \"atomic\">>): EnvServiceDatabase {\n // Proxy dispatch her üyeyi taşır; RecoOps tipi DBClient'a eklenmediğinden\n // (yukarıdaki karar) similar/recommend erişimi bu daraltmadan geçer.\n const reco = raw as Omit<DBClient, \"asService\"> & RecoOps;\n // `$` ÖNEKİ AÇIKÇA YAZILIR, dinamik üretilmez.\n //\n // Bir tur `Object.fromEntries(Object.entries(ops).map(…))` ile üretilmişti ve\n // `database.test.ts`'in sayımı onu göremedi: sayım DEKLARASYONLARI okuyor,\n // string literal'leri değil. Görünmeyen bir yüzey denetlenemez — ve o testin\n // varlık sebebi tam olarak budur (FR-044: yüzeyde bağlantı bilgisi olmadığını\n // kanıtlamak, ama önce yüzeye gerçekten ULAŞTIĞINI kanıtlamak).\n const ops = {\n $query: (sql: string, params?: unknown[]) => raw.query(sql, params),\n $diagnostics: () => raw.diagnostics(),\n $insert: (table: string, data: Record<string, unknown>) => raw.insert(table, data),\n $update: (table: string, id: string, data: Record<string, unknown>) =>\n raw.update(table, id, data),\n $delete: (table: string, id: string) => raw.delete(table, id),\n $findById: (table: string, id: string) => raw.findById(table, id),\n $findUnique: (table: string, where: Record<string, unknown>, opts?: Parameters<DBOps[\"findUnique\"]>[2]) => raw.findUnique(table, where, opts),\n $page: (table: string, query?: Record<string, unknown>, opts?: import(\"./db/page.js\").RawPageOptions) => raw.page(table, query, opts),\n $findMany: (table: string, query?: Record<string, unknown>, opts?: Parameters<DBOps[\"findMany\"]>[2]) =>\n raw.findMany(table, query, opts),\n $put: (table: string, data: Record<string, unknown>, opts: { onConflict: readonly string[] }) =>\n raw.put(table, data, opts),\n // `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,\n // { returning: false })` sessizce SATIRLARI döndürüyordu, sayıyı değil —\n // ve `if (n === 0) throw new Conflict(...)` guard'ı HİÇ çalışmıyordu,\n // çünkü `[] === 0` yanlıştır. Komşu forwarder'lar (`$findMany`, `$put`)\n // kendi opsiyonlarını zaten iletiyordu; bu biri unutulmuştu.\n $updateMany: (\n table: string,\n where: Record<string, unknown>,\n set: Record<string, unknown>,\n opts?: Parameters<DBOps[\"updateMany\"]>[3],\n ) => raw.updateMany(table, where, set, opts),\n $deleteMany: (table: string, where: Record<string, unknown>) => raw.deleteMany(table, where),\n $count: (table: string, where?: Record<string, unknown>) => raw.count(table, where),\n $search: (table: string, params?: Record<string, unknown>) => raw.search(table, params),\n $similar: (table: string, id: string, params?: Record<string, unknown>) =>\n reco.similar(table, id, params),\n $recommend: (table: string, params: Record<string, unknown>) => reco.recommend(table, params),\n $facets: (table: string, params: { facets: string[] } & Record<string, unknown>) => reco.facets(table, params),\n $claim: (table: string, unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n reco.claim(table, unique, extra),\n $lockRows: (table: string, ids: readonly string[]) => reco.lockRows(table, ids),\n $lockRowsWhere: (\n table: string,\n where: Record<string, unknown>,\n opts?: Parameters<DBOps[\"lockRowsWhere\"]>[2],\n ) => reco.lockRowsWhere(table, where, opts),\n $advisoryXactLock: (key: string) => reco.advisoryXactLock(key),\n $aggregate: (table: string, q: Parameters<DBOps[\"aggregate\"]>[1]) => raw.aggregate(table, q),\n $insertMany: ((\n table: string,\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => raw.insertMany(table, rows, opts)) as DBOps[\"insertMany\"],\n $supersede: (table: string, id: string, row: Record<string, unknown>) =>\n raw.supersede(table, id, row),\n } satisfies DollarOps<Omit<DBOps & RecoOps, \"attempt\">>;\n // `ops` DOĞRUDAN verilir, spread edilmez: sayım (`database.test.ts`) nesneyi\n // deklarasyonundan takip ediyor ve bir spread onu kaybettiriyor. Görünmeyen\n // yüzey denetlenemez.\n const base = Object.assign(ops as unknown as Record<string, unknown>, {\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T> {\n if (typeof raw.atomic !== \"function\") {\n throw new Error(\"This Database handle cannot open a root transaction; nested $atomic is not supported\");\n }\n // ALS.run scopes only this callback and its continuations, never another\n // Promise.all branch. Calls made by ordinary services through Database\n // therefore share the callback's physical transaction and identity.\n const parent = __requestALS.getStore();\n let runtime: RuntimeServices | undefined;\n try { runtime = __getRuntime(); } catch { /* Direct typed engine handles need no ambient runtime. */ }\n return raw.atomic(async (tx) => {\n const typed = makeTypedSurface(tx);\n const invoke = () => fn(typed);\n if (!runtime) return invoke();\n const refuse = (): never => { throw new Error(\"Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed\"); };\n const ambient = Object.assign({}, tx, { atomic: refuse, asService: refuse });\n return __requestALS.run({ ...parent, runtime: { ...runtime, Database: ambient } }, invoke);\n }, options);\n },\n // Both surfaces get it: a savepoint on the service transaction is as useful\n // as one on the request's, and each is bound to its own connection.\n $attempt: <T,>(fn: (tx: DBOps) => Promise<T>) => raw.attempt(fn),\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>> {\n // A FRESH builder per call: it holds this transaction's ops and its error\n // slot table, and the runtime serves concurrent requests on one event loop.\n // A shared builder would splice one request's writes into another's plan.\n //\n assertPlanRetry(opts);\n const builder = new TxPlanBuilder();\n return runTxPlan(raw, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./db/command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n });\n // ŞEMA ERİŞİMİ BİR PROXY'DİR, çünkü hangi şemaların bildirildiğini yalnız TİP\n // bilir — runtime'da `Database.billing` diye bir üye yoktur, o ada dokunulduğu\n // anda üretilir. `$`'la başlamayan her ad bir ŞEMA adıdır; ayrım tam olarak\n // budur ve tip tarafındaki DollarOps ile aynı kuralı uygular.\n return new Proxy(base, {\n get(target, prop, receiver) {\n // `tables` DOĞRUDAN YÜZEYDE DE public'in takma adı.\n //\n // Plan tutamağı `tx.tables.todos`'u öğretiyor (göç notu da öyle), ama\n // `Database.public.todos` aynı kelimeyi ADI `tables` OLAN BİR ŞEMA sanıp\n // tele `tables.todos` yazıyordu. Tip onu reddettiği için derlenen kodda\n // erişilemezdi — ama `as any` ya da düz JS ile geçen biri sessizce\n // olmayan bir şemaya gidiyordu, ve iki yüzeyin aynı kelimeye zıt cevap\n // vermesi bu run'ın kapattığı sınıfın kendisi (gözcü M-6).\n if (prop === \"tables\") return makeTableProxy(() => reco, \"\");\n if (typeof prop === \"string\" && !prop.startsWith(\"$\") && !(prop in target)) {\n // Nitelikli tablo anahtarının kuralı BURADA TEKRARLANMAZ (FR-058): tek\n // yazıcı `qualifiedTableKey` ve `table-key-single-source.test.ts` ikinci\n // bir yazıcıyı reddediyor. Prefix ondan türetilir — boş tablo adıyla\n // çağrıldığında geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTableProxy(() => reco, qualifiedTableKey(prop, \"\"));\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as unknown as EnvServiceDatabase;\n}\n\n/**\n * `makeTableProxy`'nin plan ikizi: `tables.<name>` yields the\n * table's PLAN operations, recorded into `builder` instead of sent one by one.\n *\n * Same Proxy shape and same reason for the single narrowing — TS cannot infer a\n * mapped type through a Proxy, so the cast names what the trap returns.\n */\nfunction makeTxTablesAccessor(builder: TxPlanBuilder, prefix = \"\"): TxTables {\n const tablesProxy = new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return builder.table(prefix + prop);\n },\n },\n );\n return tablesProxy as TxTables;\n}\n\n/**\n * Plan tutamağı — `Database` ile AYNI şekil: `tx.public.x`, `tx.<şema>.x`, ve\n * geriye dönük `tx.tables.x`.\n *\n * Şema adı tablo adının ÖNÜNE geçiyor (`billing.invoices`), tıpkı doğrudan\n * yüzeyin `makeTypedSurface` proxy'sinin yaptığı gibi — ve motor artık onu\n * `quoteTable` ile İKİ parça hâlinde tırnaklıyor. Bu ikisi olmadan `billing`\n * şemasındaki iki tabloyu tek atomik planda yazmak imkânsızdı.\n *\n * `tables` ve `public` DIŞINDAKİ HER ad şema kabul edilir ve altındaki tablolar\n * `<ad>.<tablo>` diye adlanır. Yanlış bir şema adı TİPTE yakalanıyor\n * (`keyof Schemas`) — `tx.constructor.x` ve `tx.toString.x` dahil, ölçüldü.\n *\n * TİPTEN KAÇAN bir ad için savunma `quoteTable`'ın KAÇIŞIDIR, başka bir şey\n * değil: `runPlanOp` `op.table`'ı doğrulamadan ona veriyor ve `quoteTable`\n * tırnak ikizleyerek tek bir tanımlayıcı üretiyor. Ölçüldü: `a\"; DROP TABLE t; --`\n * → `\"a\"\"; DROP TABLE t; --\"`, yani enjeksiyon değil, `relation does not exist`.\n * (Bu yorum bir zamanlar `validateSchemaIdentifier`'a atıf yapıyordu — o\n * fonksiyon Go tarafında yaşıyor ve BU yolu hiç görmüyor; gözcü yakaladı.)\n */\nfunction makeTxPlanHandle(builder: TxPlanBuilder): TxPlan {\n const publicTables = makeTxTablesAccessor(builder);\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n if (prop === \"tables\") return publicTables;\n // ÖNEK TEK YAZICIDAN (FR-058): `qualifiedTableKey`. Bu kuralı burada\n // elle yazmıştım — public'i çıplak bırakıp diğerine nokta ekleyen bir\n // if/return çifti — ve FR-058 kapısı onu GÖRMEDİ, çünkü kapı yalnız\n // ternary arıyordu. (Kural burada KELİMEYLE anlatılıyor, kod biçiminde\n // DEĞİL: kapı metni tarıyor ve bir yorumdaki kopya da onu tetikler.)\n // İkinci bir yazıcı, kapının var olma sebebi olan sınıfın kendisi:\n // `env-gen.ts`'in kendi kopyası bir public FK'yi başka bir şemanın\n // tablosuna etiketlemişti ve hiçbir şey bunu söylememişti.\n // Boş tablo adıyla çağrılınca geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTxTablesAccessor(builder, qualifiedTableKey(prop, \"\"));\n },\n },\n ) as TxPlan;\n}\n\n/**\n * The project's own Postgres (pgx, schema `env_<envId>`).\n *\n * Typed by default: `Database.public.<name>.insert({...})` is typed against\n * the project's generated `palbase-env.d.ts` with NO import and NO generic.\n * The raw string ops (`Database.$query`/`$insert`/`$update`/`$delete`/\n * `$findById`/`$findMany`) are also available for read-only SQL and for a table\n * name only known at runtime — which the typed surface cannot express past\n * seven tables (see `db/tx-union-key.test-d.ts`).\n *\n * RLS is enforced by default (the runtime runs each op as `authenticated` with\n * the verified user's claims). To bypass RLS, call `Database.$asService()` —\n * explicit and greppable — which runs as the `service_role` (BYPASSRLS).\n *\n * @example\n * import { Database } from \"@palbase/backend\";\n *\n * const todo = await Database.public.todos.insert({ title: req.input.title });\n * todo.id; // string ✓\n * const rows = await Database.$query(\"SELECT id FROM todos WHERE done = $1\", [false]);\n * const all = await Database.$asService().public.todos.findMany({}); // RLS bypass\n */\nexport const Database: EnvTypedDatabase = Object.assign(makeTypedSurface(rawDatabase), {\n /**\n * Lazily resolve the runtime's service-role sibling on each call. We do NOT\n * cache it: `rawDatabase.asService()` reads the CURRENT request scope through\n * the runtime proxy, and the per-request runtime injects a service client\n * bound to that request's identity headers — caching would leak one request's\n * sibling into another concurrent request.\n */\n $asService(): EnvServiceDatabase {\n return makeTypedSurface(rawDatabase.asService());\n },\n}) as unknown as EnvTypedDatabase;\n\n/** Firestore-like document client (PalDocs). */\nexport const Documents: PalbaseDocsClient = makeServiceProxy(\"Documents\");\n\n/**\n * `buckets.<name>` — the storage twin of `Database.public.<name>`, and the same\n * mechanism: `config/storage.ts` generates a `Buckets` augmentation into\n * `palbase-env.d.ts`, so a bucket name is a property with no import and no\n * generic, and a typo is a compile error.\n *\n * The intermediate `.buckets` is there for the reason `.tables` is: bucket\n * names must not share a namespace with the client's own methods, or the day\n * somebody declares a bucket called `bucket` the surface breaks.\n */\nexport type EnvBuckets = {\n [K in keyof Buckets]: TypedBucketClient<Buckets[K] extends BucketTypes ? Buckets[K] : BucketTypes>;\n};\n\n/** One bucket, with its declared variant names in the type. */\nexport interface TypedBucketClient<B extends BucketTypes> extends Omit<PalbaseBucketClient, \"getPublicUrl\"> {\n /** The public URL for the object, or for one of THIS bucket's declared\n * renditions. A name the bucket does not declare is a compile error. */\n getPublicUrl(path: string, options?: { variant?: B[\"variants\"] }): string;\n}\n\nfunction makeBucketsAccessor(storage: () => PalbaseStorageClient): EnvBuckets {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return storage().bucket(prop);\n },\n },\n ) as EnvBuckets;\n}\n\nconst rawStorage: PalbaseStorageClient = makeServiceProxy(\"Storage\");\n\n/**\n * Object storage: buckets, objects, renditions and signed URLs.\n *\n * `Storage.buckets.posts.upload(...)` is the typed path. `Storage.bucket(name)`\n * remains for a name computed at runtime — rare, and it gives up the typing,\n * which is the honest trade rather than a second blessed way to do it.\n */\nexport const Storage: PalbaseStorageClient & { buckets: EnvBuckets } = Object.assign(\n {\n // FORWARDED explicitly, not assigned onto the service proxy.\n //\n // `Object.assign(rawStorage, {buckets})` writes onto the proxy's TARGET, and\n // the proxy's only trap is `get`, which forwards every read to the module\n // client — so the property landed somewhere nothing reads and\n // `Storage.buckets.docs` was `undefined` in a deployed handler. It\n // typechecked, every test passed, and the live call answered\n // \"TypeError: undefined is not an object\". `Database` never had the bug\n // because it builds a plain surface the same way this now does.\n bucket: (name: string) => rawStorage.bucket(name),\n },\n { buckets: makeBucketsAccessor(() => rawStorage) },\n);\n\n/** JSON-typed cache (get/set/incr/getOrSet). */\nexport const Cache: CacheClient = makeServiceProxy(\"Cache\");\n\n\n/**\n * This tenant's secrets — API keys, provider credentials, signing material the\n * BACKEND owns.\n *\n * `await Secrets.get(\"STRIPE_KEY\")` in a handler. There is no `.env` to read\n * and no file to mount: a secret is written through the vault's authenticated\n * API (or the CLI/MCP that calls it), and this is how the deployed code reads\n * it back. A name this tenant has not set answers null — as does every name\n * the STACK holds, because no route returns a platform secret's value at all.\n */\nexport const Secrets: SecretsService = makeServiceProxy(\"Secrets\");\n\n/**\n * Role assignment, as an operator — `Auth.assignRole(userId, \"agent\")`.\n *\n * The half of auth a SERVER owns. Signing in, MFA and device attestation are a\n * person acting on their own account and live on the client SDK; granting a\n * role is the tenant's product doing something to somebody else, which is\n * exactly what a handler is for. It writes with the service-role credential,\n * because an end user who could write their own assignment would make every\n * permission underneath it meaningless.\n *\n * The write is visible to the very next request: authority is read from the\n * table on each call, never carried on a token.\n */\nexport const Auth: PalbaseAuthAdminClient = makeServiceProxy(\"Auth\");\n\n/** Structured logger. */\nexport const Log: Logger = makeServiceProxy(\"Log\");\n\n/** Push / email / SMS / in-app notifications. */\nexport const Notifications: PalbaseNotificationsClient = makeServiceProxy(\"Notifications\");\n\n\n/**\n * The raw runtime Flags client for the current request scope. Carries the\n * default-surface reads + `setOverride` AND the runtime's `asService()` sibling\n * (the br-pod's `buildFlagsClient` returns both). The default `Flags` singleton\n * below forwards reads + `setOverride` through here; `Flags.$asService()`\n * forwards to this client's own `asService()`.\n */\nconst rawFlags: PalbaseFlagsClient = makeServiceProxy(\"Flags\");\n\n/**\n * Feature flags.\n *\n * Mirrors the `Database` / `Database.$asService()` model. The default surface is\n * RLS-equivalent for flags: reads resolve against the CURRENT request user and\n * `Flags.setOverride(key, value)` writes an override for that same signed-in\n * user (no userId argument, no admin power). Cross-user admin writes\n * (`setOverrideForUser`, …) live behind `Flags.$asService()` — explicit and\n * greppable, just like `Database.$asService()`.\n *\n * @example\n * import { Flags } from \"@palbase/backend\";\n *\n * if (await Flags.isEnabled(\"new_checkout\")) { ... } // current user\n * await Flags.setOverride(\"new_checkout\", true); // current user\n * await Flags.$asService().setOverrideForUser(\"u_9\", \"x\", true); // cross-user\n */\n/**\n * The ambient `Flags` singleton's own surface — NOT the raw client's.\n *\n * MEASURED, as a consumer, against the built tarball: annotating the singleton\n * as `PalbaseFlagsClient` ERASED the `$asService` that `Object.assign` adds, so\n * `Flags.$asService()` did not exist for anyone outside this package —\n *\n * TS2551: Property '$asService' does not exist on type 'PalbaseFlagsClient'.\n * Did you mean 'asService'?\n *\n * — while the only path that DID compile (`asService()`) throws by design. The\n * feature was written and unreachable, which is the defect class this surface\n * exists to remove.\n *\n * `Database` never had the problem because its singleton carries its OWN type\n * (`EnvTypedDatabase`) rather than the raw client's (`DBClient`). This is that,\n * for `Flags`. The raw `PalbaseFlagsClient.asService()` is untouched (FR-023) —\n * it is the seam this forwards to.\n */\nexport type PalbaseFlagsAmbient = Omit<PalbaseFlagsClient, \"asService\"> & {\n /** RLS'i aşan, kullanıcılar arası yazma yüzeyi. */\n $asService(): PalbaseFlagsServiceClient;\n /** 31.0.0 öncesinin adı — SESSİZCE çalışmaz, yerini söyleyerek fırlatır. */\n asService(): never;\n};\n\nexport const Flags: PalbaseFlagsAmbient = Object.assign(\n {\n isEnabled(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<boolean>> {\n return rawFlags.isEnabled(flagName, context);\n },\n getVariant(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagVariant>> {\n return rawFlags.getVariant(flagName, context);\n },\n getAll(context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlag[]>> {\n return rawFlags.getAll(context);\n },\n /**\n * Resolve a flag's value, with an optional fallback.\n *\n * FORWARDED as of 2026-08-15. This surface is written out by hand, method\n * by method, and `get` was missing from it — so the client implemented it,\n * thirty assertions covered it, and `Flags.get(\"x\")` was `undefined` in a\n * deployed handler. Exactly the shape of the `Storage.buckets` defect found\n * the same day: a hand-maintained forwarding list is a list somebody has to\n * remember to update.\n */\n get(\n flagName: PalbaseFlagKey,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n return rawFlags.get(flagName, defaultOrContext, maybeContext);\n },\n setOverride(\n key: PalbaseFlagKey,\n value: PalbaseFlagValue,\n ): Promise<PalbaseResult<PalbaseSetOverrideResult>> {\n return rawFlags.setOverride(key, value);\n },\n },\n {\n /**\n * Lazily resolve the runtime's cross-user sibling on each call. We do NOT\n * cache it: `rawFlags.asService()` reads the CURRENT request scope through\n * the runtime proxy, so caching would leak one request's sibling into\n * another concurrent request. Mirrors `Database.$asService()`.\n */\n $asService(): PalbaseFlagsServiceClient {\n return rawFlags.asService();\n },\n /**\n * The name this member carried before 32.0.0.\n *\n * It does NOT work silently. A retired member that quietly keeps returning\n * is how a rename becomes a mystery: the old call site goes on compiling,\n * the new name never spreads, and the two live side by side until somebody\n * greps for one and misses half the codebase. `Database` made this split\n * first (`$asService`), and this JSDoc promised \"exactly like\n * Database.$asService()\" while the promise went unkept.\n */\n asService(): never {\n throw new Error(\n \"Flags.asService() was renamed to Flags.$asService() in 32.0.0 — system members carry the `$` prefix, like Database.$asService().\",\n );\n },\n },\n);\n\n/**\n * The Realtime broadcast singleton for the current request scope. Backend-side\n * Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —\n * `subscribe()` lives on the client SDK's `pb.realtime`). Fire-and-forget:\n * `broadcast` resolves once accepted (or with an `error`), never blocking the\n * handler on subscribers.\n *\n * @example\n * import { Realtime } from \"@palbase/backend\";\n *\n * await Realtime.broadcast(\"room:42\", \"message\", { text, from: user.id });\n */\nexport const Realtime: PalbaseRealtimeClient = makeServiceProxy(\"Realtime\");\n","/**\n * The refusals a Database call gets BEFORE any SQL exists — written once, so the\n * engine and the test double cannot disagree about them.\n *\n * WHY THIS FILE EXISTS. `fakeDatabase()` is a second implementation of the same\n * surface (`__tests__/helpers/mock-db.ts`), and it never touched `compileWhere`\n * or `asBindParams`. Measured against the published 24.1.0: all four of the\n * calls that release had just started refusing went through the fake SILENTLY —\n * `update{title:undefined}`, `insert{title:undefined}`, `findMany{done:{}}`,\n * `deleteMany{owner,created_at:{}}`.\n *\n * The scaffold tells authors to test the service layer against exactly that\n * fake. So a test went green on a call production would throw on, and the\n * author found out in production instead — the same \"the surface does not match\n * the engine\" shape these refusals exist to end, arriving through the door the\n * SDK hands people for testing.\n *\n * These are pure and SQL-free on purpose: an in-memory store can run them as\n * easily as the driver path can.\n */\n\n/**\n * İşaretçilerin MARKASI — `col()` ve `sqlFragment()` ürünlerini bu süreçte\n * üretilmiş olmakla tanımlar.\n *\n * NEDEN ŞEKİL DEĞİL DE MARKA (gözcü W2-A/C1 ve W2-B/C3, ikisi de ÖLÇTÜ):\n * şekil kontrolü, işaretçiyi güvenilmeyen bir istek gövdesinden UYDURULABİLİR\n * kılıyordu. Ölçülen iki sonuç:\n *\n * findMany(\"docs\", { owner_id: JSON.parse('{\"$col\":\"owner_id\"}') })\n * → WHERE true AND t.\"owner_id\" = t.\"owner_id\" ← kiracılık predikatı totoloji\n * findMany(\"todos\", JSON.parse('{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}'))\n * → WHERE true AND 1=1 -- pwned ← saldırganın metni SQL'e HARFİYEN\n *\n * `{ where: { tenant_id: tid, ...req.body.filter } }` bu SDK'nın öğrettiği\n * desen; T010/T014 öncesinde aynı anahtarlar \"bilinmeyen operatör\" diye\n * REDDEDİLİYORDU. Marka o reddi geri getiriyor.\n *\n * Sembol GLOBAL kayıttan (`Symbol.for`) ve ENUMERABLE DEĞİL. İkisi de kasıtlı:\n * global kayıt paketin iki kopyası arasında da eşleşir; enumerable olmaması ise\n * `JSON.stringify` ve `{...ref, gt: 5}` yayılımının markayı DÜŞÜRMESİNİ sağlar —\n * yani telden geçen ya da elle karıştırılan hiçbir şey işaretçi sayılmaz.\n * Kardeş özellik (`increment`) zaten `Symbol.for(\"palbase.tx.expr\")` kullanıyor;\n * bu onun aynısı.\n */\nconst REF_BRAND = Symbol.for(\"palbase.db.ref\");\n\n/** İşaretçiyi markalar. Yalnız `col()` ve `sqlFragment()` çağırır. */\nexport function brandRef<T extends object>(v: T, kind: \"col\" | \"sql\" | \"ref\"): T {\n Object.defineProperty(v, REF_BRAND, { value: kind, enumerable: false });\n return v;\n}\n\nfunction brandOf(v: unknown): unknown {\n if (typeof v !== \"object\" || v === null) return undefined;\n // KENDİ özelliği olmalı, prototip zincirinden MİRAS ALINMIŞ değil:\n // `Object.create(col(\"x\"))` markayı zincirden okuyup işaretçi sayılıyordu\n // (gözcü ölçtü). Telden erişilemez — JSON `__proto__` üstünden sembol\n // yazamaz — ama daraltmak bedava ve \"işaretçi bu süreçte ÜRETİLDİ\"\n // iddiasının tam karşılığı budur.\n return Object.hasOwn(v, REF_BRAND) ? (v as Record<symbol, unknown>)[REF_BRAND] : undefined;\n}\n\n/**\n * Bir değer, MARKASIZ bir işaretçi taklidi mi? (`{$col:…}` / `{$sql:…}`)\n *\n * Üst düzeyde bunlar zaten \"bilinmeyen operatör\" diye reddediliyor. Ama\n * operatörün SAĞINDA — `{ amount: { gt: {\"$col\":\"other\"} } }` — sessizce\n * PARAMETRE olarak bağlanıyorlardı: sayısal kolonda sürücünün 22P02'si,\n * jsonb/text kolonunda ise HİÇBİR SATIR, hatasız (gözcü ölçtü).\n *\n * `in` listesindeki aynı kusur adıyla reddediliyor; bu onun bir seviye\n * yanındaki hâli ve aynı cevabı hak ediyor.\n */\nexport function looksLikeUnbrandedRef(v: unknown): \"col\" | \"sql\" | \"expr\" | null {\n if (typeof v !== \"object\" || v === null) return null;\n if (brandOf(v) !== undefined) return null; // gerçek işaretçi\n if (isColumnExpr(v)) return null; // gerçek ifade tutamağı (kendi markası var)\n const o = v as { $col?: unknown; $sql?: unknown; $expr?: unknown };\n if (typeof o.$col === \"string\") return \"col\";\n if (o.$sql !== undefined && typeof o.$sql === \"object\" && o.$sql !== null) return \"sql\";\n // `$expr` `now()`/`increment()`'in TEL BİÇİMİ. `now()` filtrede geçerli bir\n // değer olduğu andan itibaren bu şekil de uydurulabilir hâle geldi: ÖLÇÜLDÜ,\n // gövdeden gelen `{\"$expr\":{\"fn\":\"now\"}}` sessizce PARAMETRE olarak bağlanıp\n // sorguyu hatasız biçimde boş sonuca çeviriyordu. `$col`/`$sql`/`$ref` ile\n // aynı kapı, aynı gerekçe.\n if (o.$expr !== undefined && typeof o.$expr === \"object\" && o.$expr !== null) return \"expr\";\n return null;\n}\n\n/**\n * `col()` ürünü mü? (FR-011)\n *\n * Burada, çünkü bu dosya \"iki uygulamanın da okuduğu kurallar\" dosyası: motor,\n * `fakeDatabase` ve guard AYNI cevabı vermek zorunda.\n */\nexport function isColRef(v: unknown): v is { readonly $col: string } {\n return brandOf(v) === \"col\" && typeof (v as { $col?: unknown }).$col === \"string\";\n}\n\n/**\n * `sqlFragment` ürünü mü? (FR-018)\n *\n * `isColRef` ile aynı gerekçeyle burada: motor, guard ve `fakeDatabase` üçü de\n * aynı cevabı vermek zorunda — biri fragment'i \"kolon haritası\" sanarsa filtre\n * sessizce düşer.\n */\n/**\n * Plan REFERANSI mı? (`{ $ref: { op, field } }`)\n *\n * `$ref` bu dilin MARKASIZ KALAN TEK işaretçisiydi — `engine/db.ts` onu\n * `\"$ref\" in v` diye tanıyordu — ve SDK'nın öğrettiği desen\n * `{ where: { tenant_id: tid, ...req.body.filter } }`. Ölçüldü (gözcü):\n * istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}` filtreyi\n * ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyor —\n * DELETE … WHERE t.\"tenant_id\" = $1 AND t.\"id\" = $2 PRM [\"t1\",\"SIZAN_DEGER\"]\n * gövdenin hiç görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir\n * ORACLE: `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek.\n *\n * Marka `Symbol.for` olduğu için SDK'nın İKİ KOPYASI arasında da eşleşiyor —\n * kontrolcü bundle'ı kendi kopyasını inline ediyor, planı çalıştıran ise\n * runtime'ınki. Ve plan gövdesi JSON'lanmıyor: tek üretim `txPlan` uygulaması\n * süreç içi (`engine/db.ts`), doğrulandı.\n */\nexport function isPlanRef(v: unknown): v is { readonly $ref: { op: number; field: string } } {\n if (brandOf(v) !== \"ref\") return false;\n const r = (v as { $ref?: { op?: unknown; field?: unknown } }).$ref;\n return r !== undefined && typeof r.op === \"number\" && typeof r.field === \"string\";\n}\n\n/** Markasız bir `{ $ref: … }` taklidi mi? Adıyla reddedilmesi için. */\nexport function looksLikeUnbrandedPlanRef(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || brandOf(v) !== undefined) return false;\n const r = (v as { $ref?: unknown }).$ref;\n return r !== undefined && typeof r === \"object\" && r !== null;\n}\n\nexport function isSqlFragment(v: unknown): v is { readonly $sql: { text: string[]; values: unknown[] } } {\n if (brandOf(v) !== \"sql\") return false;\n const f = (v as { $sql?: { text?: unknown; values?: unknown } }).$sql;\n return f !== undefined && Array.isArray(f.text) && Array.isArray(f.values);\n}\n\n/**\n * İFADE TUTAMAĞI DEĞER DEĞİLDİR — değer bekleyen yollarda adıyla reddedilir.\n *\n * `increment()` / `decrement()` / `now()` bir Proxy döndürür ve yalnız\n * `updateMany` ile plan yolunun `updateWhere`'i onu SQL'e derler. `insert` /\n * `update` / `put` / `supersede` derlemez; oralarda tutamak bound parametre\n * olarak sürücüye gidiyordu ve reddi SÜRÜCÜ veriyordu (\"Unknown object is not\n * a valid PostgreSQL type\") — yazarın yazdığı hiçbir şeyi adlandırmayan bir\n * mesaj (inceleme I-2/I8, ölçüldü). Plan yolu aynı hatayı kendi diliyle\n * reddediyor; bu, doğrudan yolun karşılığı.\n *\n * Sembol `tx-plan.ts`'in markasıyla AYNI global kayıttan okunuyor; bu dosya\n * kural dosyası olduğu için oraya bağımlılık kurmuyor.\n */\nconst TX_EXPR = Symbol.for(\"palbase.tx.expr\");\n\n/**\n * `now()` — SUNUCU SAATİ, karşılaştırma değeri olarak.\n *\n * `increment()`/`decrement()` bir YAZMA ifadesidir ve filtrede anlamsızdır;\n * `now()` öyle değil: `expires_at > now()` sıradan bir karşılaştırma ve her\n * backend'in en sık yazdığı yüklemlerden biri. Filtrede TÜM ifade tutamaklarını\n * reddetmek, yazarı bunun için `sqlFragment`e düşürüyordu — yani sorgunun\n * içine giren parça, en sıradan koşul için gerekiyordu.\n *\n * Ayrım MARKAYLA: bir istek gövdesinden gelen `{\"$expr\":{\"fn\":\"now\"}}` bu\n * süreçte `now()` ile üretilmediği için marka taşımaz ve reddedilir.\n */\nexport function isNowExpr(v: unknown): boolean {\n if (!isColumnExpr(v)) return false;\n try {\n const e = (v as Record<symbol, unknown>)[TX_EXPR];\n return typeof e === \"object\" && e !== null && (e as { fn?: unknown }).fn === \"now\";\n } catch {\n return false;\n }\n}\n\nexport function isColumnExpr(v: unknown): boolean {\n if (typeof v !== \"object\" && typeof v !== \"function\") return false;\n if (v === null) return false;\n try {\n return (v as Record<symbol, unknown>)[TX_EXPR] !== undefined;\n } catch {\n // Tutamak bir Proxy; bilinmeyen bir prop'ta trap fırlatabilir.\n return false;\n }\n}\n\n/**\n * Değer bekleyen bir yazma yolunda ifade tutamağı ya da `col()` var mı?\n *\n * Motor ve `fakeDatabase` AYNI cevabı vermek zorunda: fake tutamağı satıra\n * YAZIYORDU (`row[k] = proxy`) ve satır artık JSON'a bile çevrilemiyordu, motor\n * ise sürücüde patlıyordu. İki farklı yanlış, tek doğru.\n */\nexport function assertNoExpressionHandles(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n const v = data[c];\n // `now()` ile sayaç ifadeleri AYRI cevaplar hak ediyor: ikisinin de\n // çalışan alternatifi var ama farklı (P6 — hata çalışan bir alternatifi\n // ADIYLA söyler). Tek bir \"ifade tutamağı\" mesajı, `now()` yazan kişiye\n // `increment()` öneriyordu.\n if (isNowExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" now() aldı — bu yolda değer beklenir. ` +\n `Satır EKLENİRKEN sunucu saatini yazmanın yolu kolonu defaultNow() ile ` +\n `bildirmek (varsayılan kolonun yanında durur, her çağrıda tekrarlanmaz); ` +\n `var olan bir satırı damgalamak için updateMany({ where, set: { ${c}: now() } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: now() }).`,\n );\n }\n if (isColumnExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir ifade tutamağı aldı (increment()/decrement()). ` +\n `Bu yolda değer beklenir. Sayaç artışı için updateMany({ where, set: { ${c}: increment(n) } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullanın.`,\n );\n }\n if (isColRef(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir col() aldı. Kolon referansı yalnız FİLTREDE durabilir; ` +\n `bir kolonun değerini başka bir kolona yazmak için $query kullanın.`,\n );\n }\n }\n}\n\n/** The comparison operators a filter value may carry. Kept here because the\n * guard has to tell an operator object from a plain value. */\nconst KNOWN_OPS = new Set([\n \"gt\", \"gte\", \"lt\", \"lte\", \"neq\", \"in\",\n // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bu küme\n // `fakeDatabase()` ile ORTAK kaynaktır: fake bir çağrıyı motorun reddettiği\n // yerde kabul ederse, yazarın testi üretimde patlayan koda karşı yeşil verir.\n \"contains\", \"icontains\", \"startsWith\", \"endsWith\", \"isNull\",\n]);\n\n/**\n * `eq` ADIYLA reddedilir, ve reddi buradadır çünkü guard'ı motor da fake de\n * okuyor.\n *\n * Eşitliğin yazımı ÇIPLAK DEĞERDİR: `{ owner: \"u1\" }`. `eq`'i ikinci bir yazım\n * olarak eklemek, bu run'ın kapatmak için var olduğu şeyi — aynı iş için iki\n * uyumsuz yazım — filtre dilinin İÇİNDE yeniden açardı. Ve eskiden kabul eden\n * ile reddeden ayrışıyordu: guard `eq`'i geçiriyor, derleyici\n * `bilinmeyen operatör \"eq\"` diyordu (gözcü ölçtü).\n */\nconst REFUSED_OPS: Record<string, string> = {\n eq: 'eşitlik ÇIPLAK yazılır: { <kolon>: <değer> } (ya da kolon karşılaştırması için { <kolon>: col(\"…\") })',\n};\n\n/**\n * Refuse a filter that would compile to something other than what it reads like.\n *\n * Three shapes, each measured in production before it was closed:\n *\n * `{ col: undefined }` binds NULL; `= NULL` matches no row, so the query\n * answered \"no records\" and said nothing.\n * `{ col: {} }` produces no term at all — every row on the read\n * path, a dropped condition on the write path.\n * `{ col: { gte: undefined } }` and an `undefined` inside `in`: the same NULL,\n * one level down.\n */\nexport function assertUsableFilter(\n caller: string,\n table: string,\n where: Record<string, unknown> | undefined,\n): void {\n // Bileşim anahtarları (FR-007) bir KOLON adı değildir; kolon doğrulamasından\n // ve operatör kontrolünden muaftır, kendi dalları özyinelemeli olarak aynı\n // kurallardan geçer.\n const COMPOSITES = new Set([\"OR\", \"AND\", \"NOT\"]);\n\n if (!where) return;\n // Fragment bir kolon haritası DEĞİLDİR (FR-018): içeriği SQL'dir, kolon\n // doğrulaması ona uygulanamaz. Değerleri zaten bound gidiyor.\n if (isSqlFragment(where)) return;\n for (const [col, cond] of Object.entries(where)) {\n // Bileşim anahtarları (FR-007) kolon DEĞİLDİR: dalları aynı kurallardan\n // özyinelemeli geçer, ama kendileri operatör kontrolüne girmez.\n if (COMPOSITES.has(col)) {\n const branches = col === \"NOT\" ? [cond] : cond;\n if (!Array.isArray(branches) && col !== \"NOT\") {\n throw new Error(`${caller}(${table}): where.${col} bir dizi olmalı`);\n }\n for (const b of branches as unknown[]) {\n if (b === null || typeof b !== \"object\") {\n throw new Error(`${caller}(${table}): where.${col} dalları filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, b as Record<string, unknown>);\n }\n continue;\n }\n // `has` de kolon DEĞİLDİR: anahtarları İLİŞKİ adları, değerleri BİR TABLO\n // ÖTESİNİN filtresi. İç filtre aynı kurallardan geçiyor — `has` ikinci bir\n // filtre dili değil, aynı dilin bir tablo ötesi.\n //\n // İlişki ADI burada doğrulanMIYOR: grafiği yalnız motor tanıyor (ve tip,\n // derleme anında). Guard'ın onu bilmesi ilişki grafiğinin İKİNCİ bir\n // yorumcusu demekti — `buildRelations`'ın yorumunun adıyla yasakladığı şey.\n if (col === \"has\") {\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) {\n throw new Error(`${caller}(${table}): where.has bir ilişki haritası olmalı ({ <ilişki>: { … } })`);\n }\n for (const [rel, inner] of Object.entries(cond as Record<string, unknown>)) {\n if (inner === null || typeof inner !== \"object\" || Array.isArray(inner)) {\n throw new Error(`${caller}(${table}): where.has.${rel} bir filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, inner as Record<string, unknown>);\n }\n continue;\n }\n if (cond === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col} değeri undefined — bu bir filtre değeri değil. ` +\n `Bağlanınca NULL olur ve '= NULL' hiçbir satıra uymaz, yani sorgu sessizce ` +\n `boş sonuç dönerdi. Değer yoksa anahtarı filtreye hiç koymayın.`,\n );\n }\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) continue;\n // `col()` ürünü bir DEĞER'dir, operatör nesnesi değil (FR-011). Ayırt\n // edilmezse `{ $col: \"x\" }` bir operatör haritası sanılır ve \"bilinmeyen\n // operatör $col\" diye reddedilirdi.\n if (isColRef(cond)) continue;\n // `now()` de bir DEĞER'dir, aynı gerekçeyle — ve tutamak bir Proxy olduğu\n // için `Object.entries` BOŞ döner: ayırt edilmezse \"boş operatör nesnesi\"\n // diye reddedilirdi, yani doğru yazım yanlış bir hatayla karşılanırdı.\n if (isNowExpr(cond)) continue;\n\n const entries = Object.entries(cond as Record<string, unknown>);\n if (entries.length === 0) {\n throw new Error(\n `${caller}(${table}): where.${col} boş bir operatör nesnesi ({}) — hiçbir koşul ` +\n `üretmez, yani bu alan filtreden sessizce DÜŞERDİ. Koşul kurulmayacaksa ` +\n `anahtarı filtreye hiç koymayın (D-21).`,\n );\n }\n for (const [op, v] of entries) {\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n if (v.some((x) => x === undefined)) {\n throw new Error(\n `${caller}(${table}): where.${col}.in listesinde undefined var — sessizce NULL'a ` +\n `bağlanır ve o eleman hiçbir satırla eşleşmez. Listeyi kurarken eleyin.`,\n );\n }\n continue;\n }\n // Sağ tarafta kolon durabilir: `{ total: { gt: col(\"amount_paid\") } }`.\n // Değer kontrolleri (undefined) ona da uygulanır, ama `in` gibi şekil\n // kontrolleri değil — o dal aşağıda zaten ayrı.\n if (REFUSED_OPS[op] !== undefined) {\n // Bilinmeyen değil — BİLİNEREK reddedilen. Hata çalışan yazımı söylüyor.\n throw new Error(`${caller}(${table}): where.${col}.${op} bu filtre dilinde yok — ${REFUSED_OPS[op]}`);\n }\n if (!KNOWN_OPS.has(op)) {\n throw new Error(\n `${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in/contains/icontains/startsWith/endsWith/isNull)`,\n );\n }\n if (v === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col}.${op} değeri undefined — karşılaştırmanın ` +\n `sağ tarafı NULL olur ve sonuç hiçbir satıra uymaz. Koşulu kurmayın.`,\n );\n }\n }\n }\n}\n\n/**\n * Refuse a write whose value never arrived.\n *\n * `{ title: req.body.title }` with no `title` in the body bound NULL and\n * answered 200 — the column was ERASED. `null` is untouched, and the difference\n * is the whole point: null is an author SAYING \"empty this column\"; undefined is\n * nobody saying anything.\n */\nexport function assertUsableWriteValues(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n if (data[c] === undefined) {\n throw new Error(\n `${caller}(${table}): \"${c}\" değeri undefined — bu bir yazma değeri değil. ` +\n `Kolonu boşaltmak istiyorsan null yaz; kolonu değiştirmek istemiyorsan nesneye hiç koyma ` +\n `(bir eksik istek alanı sessizce NULL yazıyordu — FR-016).`,\n );\n }\n }\n}\n","/**\n * tx-plan.ts — `Database.$transaction()` as a PLAN, not a pinned session.\n *\n * A transaction used to be a conversation: BEGIN, then one network round trip\n * per operation, then COMMIT. Each of those round trips cost ~4 ms and, because\n * the pooler runs in transaction mode, an open transaction pinned a Postgres\n * backend for the whole conversation. A 121-operation statement upload pinned\n * one backend for ~490 ms.\n *\n * So the callback no longer TALKS to the database. It DESCRIBES what should\n * happen; the description is serialised and sent once; the broker runs the whole\n * thing inside one transaction and answers once. Committing on return and\n * rolling back on throw is unchanged — that is the only property tenant code\n * actually asked for.\n *\n * The consequences, stated plainly, because they are the whole design:\n *\n * - The callback is SYNCHRONOUS. There is nothing to await: no statement has\n * run yet when it returns. `async` on the callback and `await` inside it are\n * both compile errors (see {@link TxPlan} and {@link NotAwaitable}).\n * - `insert()` does not hand back a row, it hands back {@link TxRows}. Reading\n * a field requires `.expectOne(err)` first, which makes \"what if the row\n * isn't there\" a question you cannot route around: it is the argument.\n * - A field read from a row is a {@link Ref} — a PROMISE OF A VALUE THE SERVER\n * WILL PRODUCE, not the value. It can be written into a later operation and\n * it can be returned from the callback (it is substituted for the real value\n * before `transaction()` resolves). It cannot be branched on. See the\n * \"Truthiness\" note below — this is the sharp edge of the whole design.\n * - Control flow that needs a real value must move OUT of the callback: read\n * before the transaction, or express the condition as a guard\n * (`updateWhere({ id, accepted_at: null }, …).expectOne(new Conflict(…))`)\n * which the server evaluates and which rolls the whole plan back.\n *\n * # Truthiness — the hole this file CANNOT close\n *\n * JavaScript does not let a Proxy trap truthiness. `if (ref)` takes the true\n * branch, always, for every Ref, and no `get` handler ever runs. `tsc` is silent\n * because a Ref is a perfectly good object. So:\n *\n * const pot = tx.tables.pots.select({ id }, { limit: 1 }).expectOne(e);\n * if (!pot.balance) { … } // ← ALWAYS false. Silently wrong data.\n *\n * What this file does close: coercion (`Symbol.toPrimitive`/`valueOf`/\n * `toString`), awaiting (`then` is a callable member with a non-thenable\n * signature, which is a *compile* error), serialisation (`toJSON`), and nesting\n * a Ref inside a literal value where the server would store it as data. What it\n * cannot close is a bare truthiness test. The real defence is the build-time\n * static analysis (`tx_analysis.js`, phase P4); until that ships, this hole is\n * open and this comment is the only warning.\n *\n * # Wire contract\n *\n * The JSON this file emits is consumed by\n * the plan executor in `engine/db.ts`. That executor rejects\n * unknown fields at every level, so an op carries EXACTLY the fields its kind\n * takes. Everything here that looks like a needless restriction is one of the\n * server's rules made visible early:\n *\n * - `$ref` only points BACKWARDS, and only at an op statically known to yield\n * at most one row (insert, or a `one`/`atMost 1` guard, or `select limit 1`).\n * `.expectOne()` is what this file uses to satisfy that, always.\n * - `$expr` is a closed set: `inc`/`dec` (update only — they read the column's\n * current value) and `now()`.\n * - `update`/`delete` require a `where`; `insert` refuses one.\n * - `insertMany` rows must all set the same columns.\n * - ≤1000 ops, ≤5000 rows per insertMany, ≤8 MiB of JSON.\n *\n * Column keys are emitted SORTED, so the same callback always produces byte-\n * identical JSON. That is what lets the Go decoder be locked to golden files\n * this SDK emits (`testdata/tx_plan_golden/`).\n */\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * A plan handle was used as if it were a value: awaited, coerced to a string or\n * number, serialised, or nested inside another value.\n *\n * Thrown while the callback is still BUILDING the plan, so nothing has been sent\n * and nothing has been written.\n */\n// TİP-ONLY, ve döngü kasıtlı: `typed-db.ts` bu dosyadan tip alıyor, bu dosya\n// ondan `WhereOp` alıyor. Çalışma zamanında hiçbir şey ithal edilmiyor (import\n// type), yani modül döngüsü yok — paylaşılan olan şey TEK FİLTRE DİLİ, ve onu\n// iki yerde ayrı ayrı tanımlamak bu run'ın kapattığı \"iki yazım\"ın tipteki\n// hâli olurdu.\nimport type { WhereOpWith, ColRefOf, HasOnly, SqlFragment } from \"./typed-db.js\";\nimport { isColRef, isSqlFragment, brandRef, isNowExpr } from \"./input-guards.js\";\n\nexport class TxRefError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxRefError\";\n }\n}\n\n/**\n * The plan the callback described cannot be sent: it breaks a rule the server\n * would reject, and rejecting it here names the line that wrote it instead of\n * returning a 400 about an op index.\n */\nexport class TxPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxPlanError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire types — mirror the plan executor in `engine/db.ts` exactly.\n// ---------------------------------------------------------------------------\n\n/** A backwards reference to an earlier op's single-row result. */\nexport interface TxWireRef {\n $ref: { op: number; field: string };\n}\n\n/** A call from the server's closed function set. */\nexport interface TxWireExpr {\n $expr: { fn: \"inc\" | \"dec\"; by: number | string } | { fn: \"now\" };\n}\n\n/** One value in a `values`/`set`/`where` map: a literal, a `$ref` or a `$expr`. */\nexport type TxWireValue = TxWireRef | TxWireExpr | unknown;\n\n/** The tenant's declared expectation about an op's row count. `slot` indexes the\n * client-side error table — the error OBJECT never travels. */\nexport interface TxWireGuard {\n kind: \"one\" | \"none\" | \"atLeast\" | \"atMost\";\n n: number;\n slot: number;\n}\n\n/** One operation in the wire plan. Fields are omitted, never null: the decoder\n * rejects a field that does not belong to the op's kind. */\nexport interface TxWireOp {\n /** upsert and insertMany: the columns Postgres matches on. */\n onConflict?: readonly string[];\n /** insertMany only: what a collision does. Absent means no ON CONFLICT clause\n * at all, which is what every insertMany did before this option existed. */\n action?: \"ignore\" | \"update\";\n op: \"insert\" | \"insertMany\" | \"upsert\" | \"update\" | \"delete\" | \"select\";\n table: string;\n values?: Record<string, TxWireValue>;\n rows?: Record<string, TxWireValue>[];\n set?: Record<string, TxWireValue>;\n where?: Record<string, TxWireValue>;\n limit?: number;\n lock?: \"update\";\n guard?: TxWireGuard;\n}\n\n/** The plan the engine executes on the request's own transaction. */\nexport interface TxPlanBody {\n ops: TxWireOp[];\n}\n\n/** One op's outcome, positionally matched to the plan's ops. */\nexport interface TxPlanOpResult {\n rows: Record<string, unknown>[];\n rows_affected: number;\n}\n\n/** One result per op, in plan order. */\nexport interface TxPlanResponse {\n results: TxPlanOpResult[];\n}\n\n/**\n * The fields the runtime must copy from the broker's error envelope onto the\n * rejection it throws out of {@link DBClient.txPlan}.\n *\n * `slot` is the whole point: on a guard failure the server answers with the\n * INDEX of the expectation that did not hold, never with an error message of its\n * own, and this SDK maps that index back to the `Error` the callback handed to\n * `.expectOne(…)`. Without `slot` a guard failure degrades to a generic 409.\n */\nexport interface TxPlanRejection {\n status?: number;\n /** `tx_plan_invalid` | `tx_guard_failed` | `tx_ref_unresolved` | a pg class. */\n error_code?: string;\n /** Present only for `tx_guard_failed`: the client-side error table index. */\n slot?: number;\n /** Present on a database error: which op failed. */\n op?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Handle types\n// ---------------------------------------------------------------------------\n\ndeclare const refBrand: unique symbol;\ndeclare const rowBrand: unique symbol;\ndeclare const rowsBrand: unique symbol;\n\n/**\n * Makes a handle a compile error to `await`.\n *\n * `then` is declared as a CALLABLE member whose signature is not `PromiseLike`,\n * which is precisely the shape TypeScript rejects: `await handle` is TS1320 and\n * `async () => handle` is TS1058. A non-callable `then` would not do it — the\n * compiler simply ignores those.\n */\nexport interface NotAwaitable {\n /** Not a promise. Nothing here has run yet; there is nothing to await. */\n then(doNotAwaitAPlanHandle: \"a transaction plan is built synchronously\"): never;\n}\n\n/**\n * A value the SERVER will produce, standing in for a column of a row this plan\n * writes or reads.\n *\n * Legal uses: write it into a later operation's `values`/`set`/`where`, or\n * return it from the callback (it is replaced by the real value before\n * `transaction()` resolves).\n *\n * Illegal, and caught: `await`, `String(ref)`, `` `${ref}` ``, `ref + 1`,\n * `JSON.stringify(ref)`, burying it inside a jsonb object.\n *\n * Illegal, and NOT caught: `if (ref)`. See the truthiness note at the top.\n */\nexport interface Ref<T> extends NotAwaitable {\n readonly [refBrand]: T;\n}\n\n/** The brand carried by a single-row handle, and the seam `Materialized` reads\n * to turn `return st` into the whole row. */\nexport interface TxRowHandle<Row> extends NotAwaitable {\n readonly [rowBrand]: Row;\n}\n\n/**\n * A row this plan is known to produce exactly one of. Every property is a\n * {@link Ref}; returning the handle itself yields the whole row.\n *\n * Only `.expectOne(err)` produces one — which is the design: a row you can read\n * fields from is a row whose absence you have already answered for.\n */\nexport type TxRow<Row> = { readonly [K in keyof Row]: Ref<Row[K]> } & TxRowHandle<Row>;\n\n/**\n * The result of one operation, before any expectation is declared about it.\n *\n * Deliberately not a row and not a list: an operation's row count is not known\n * until the server runs it, so the only thing that can be said about it here is\n * an EXPECTATION. Declaring one is also the only way to get a readable row.\n *\n * At most one expectation per operation — the wire carries one guard per op, and\n * a second call throws rather than silently dropping the first.\n */\nexport interface TxRows<Row> extends NotAwaitable {\n readonly [rowsBrand]: Row;\n /**\n * Require exactly one row, and read it. On any other count the server rolls\n * the whole transaction back and this `error` is thrown to the caller.\n *\n * This is the only way to reach a row's fields, and the only shape a `$ref`\n * may point at.\n */\n expectOne(error: Error): TxRow<Row>;\n /** Require zero rows (e.g. \"this membership must not already exist\"). */\n expectNone(error: Error): void;\n /** Require at least `n` rows. */\n expectAtLeast(n: number, error: Error): void;\n /** Require at most `n` rows. */\n expectAtMost(n: number, error: Error): void;\n}\n\n/** `now()` — the server's clock, usable wherever a value is. */\nexport interface TxNow extends NotAwaitable {\n readonly $expr: { fn: \"now\" };\n}\n\n/** `inc(n)` / `dec(n)` — read the column's CURRENT value and write it back\n * changed. Only meaningful in an update's `set`, which is where the types allow\n * it and where the server allows it. */\nexport interface TxColumnExpr extends NotAwaitable {\n readonly $expr: { fn: \"inc\" | \"dec\"; by: number | string };\n}\n\n/**\n * Resolve a callback's return type against what actually comes back: every\n * {@link Ref} becomes its value, every {@link TxRow} becomes its row, and\n * anything else keeps its shape.\n *\n * A {@link TxRows} resolves to an explanatory string type rather than a row\n * list: it has no single answer to give, and saying so in the type is louder\n * than a runtime throw.\n */\nexport type Materialized<T> = T extends Ref<infer U>\n ? U\n : T extends TxRowHandle<infer R>\n ? R\n : T extends TxRows<unknown>\n ? \"a TxRows cannot leave the transaction callback — read a row with .expectOne(err) first\"\n : T extends Date\n ? T\n : T extends object\n ? { [K in keyof T]: Materialized<T[K]> }\n : T;\n\n// ---------------------------------------------------------------------------\n// Author-facing value types\n// ---------------------------------------------------------------------------\n\n/** A value written by an INSERT: a literal, an earlier row's field, or `now()`.\n * `inc`/`dec` are absent on purpose — they read a current value, and an inserted\n * row has none. */\nexport type TxInsertValue<V> = V | Ref<V> | TxNow;\n\n/** A value written by an UPDATE's `set`: everything an insert takes, plus the\n * read-modify-write expressions. */\n/**\n * TEK KURAL: ifade tutamağı yalnız sayısal-benzeri kolonlarda.\n *\n * Bu tip KOŞULSUZDU ve doğrudan yolun `SetValue<V>`'si koşulluydu, yani aynı\n * nesne için İKİ tip kuralı vardı: `tx.tables.todos.updateWhere({id}, { done:\n * increment(1) })` (boolean kolon!) DERLENİYOR, `updateMany`'nin aynısı derleme\n * hatası veriyordu. Bu run'ın kapatmak için var olduğu şey \"aynı iş için iki\n * uyumsuz yazım\"dı; tip kuralı ikinci yazımın kendisi olmuştu (gözcü I6/I-1).\n */\nexport type TxSetValue<V> =\n | V\n | Ref<V>\n | TxNow\n | (NonNullable<V> extends number | string ? TxColumnExpr : never);\n\n/** An insert payload: the table's insert shape, with refs and `now()` allowed. */\nexport type TxInsertShape<Insert> = { [K in keyof Insert]: TxInsertValue<Insert[K]> };\n\n/** An update's `set`: any subset of the insert shape, with expressions allowed. */\nexport type TxSetShape<Insert> = { [K in keyof Insert]?: TxSetValue<Insert[K]> };\n\n/**\n * A filter. Every entry is an equality test and they are AND-ed; a `null`\n * becomes `IS NULL`, which is what makes `{ accepted_at: null }` a usable\n * \"not yet accepted\" guard rather than a clause that matches nothing.\n */\n/**\n * Plan filtresinin tipi — `WhereFilter<Row>` ile AYNI sözlük, artı `Ref`.\n *\n * Eskiden yalnız eşitlikti (`Row[K] | Ref<Row[K]>`), ve iki şeye mal oluyordu:\n * FR-014'ün amiral deseni (`{ balance: { gte: amount } }`) `$transaction`\n * İÇİNDE yazılamıyordu — koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — ve motor tarafında tip atlandığında aynı nesne SESSİZCE parametre\n * olarak bağlanıyordu.\n *\n * `Ref` fazladan üye ve öyle kalmalı: bir plan filtresi ÖNCEKİ bir işlemin\n * döndürdüğü değere bakabilir, `findMany` bakamaz — plan dışında böyle bir\n * \"önceki işlem\" yok.\n */\ntype TxWhereField<Row, K extends keyof Row> = WhereOpWith<\n Row[K],\n // `Ref` KOLON REFERANSININ YANINDA duruyor, `V`'nin içinde DEĞİL: `V`'ye\n // eklenseydi `TextOps<V>`'nin `V extends string` sorusu HAYIR olur ve\n // `contains`/`startsWith` sessizce kaybolurdu (ölçüldü).\n ColRefOf<Row, Row[K]> | Ref<Row[K]>\n>;\n\nexport type TxWhere<Row, Rels = unknown> = {\n [K in keyof Row]?: TxWhereField<Row, K>;\n} & {\n // Düz op'lardaki `WhereFilter` ile AYNI: dal bir `sqlFragment` de olabilir.\n // İki filtre dilinin bir dalda ayrışması, \"tek dil\" iddiasını tam da bileşim\n // anında boşa çıkarırdı — ve motor plan yolunda da fragment'i derliyor\n // (ölçüldü: `SELECT t.* FROM \"crew\" t WHERE true AND (((a > 1)) AND (…))`).\n OR?: (TxWhere<Row, Rels> | SqlFragment)[];\n AND?: (TxWhere<Row, Rels> | SqlFragment)[];\n NOT?: TxWhere<Row, Rels> | SqlFragment;\n} & HasOnly<Rels>;\n\n/** Options for a plan `select`. */\nexport interface TxSelectOptions {\n /** Cap the rows read. */\n limit?: number;\n /** Take a real `FOR UPDATE` row lock for the rest of the transaction. */\n lock?: \"update\";\n}\n\n/** One table, as the plan sees it. */\nexport interface TxTable<Row, Insert, Rels = unknown> {\n /** Insert one row. Returns a handle — call `.expectOne(err)` to read fields. */\n insert(values: TxInsertShape<Insert>): TxRows<Row>;\n /**\n * Insert many rows in ONE statement. Every row must set the same columns\n * (a row that omits one would silently take the column's default).\n *\n * An empty list writes nothing and sends nothing.\n */\n /**\n * Insert many rows in ONE statement, optionally choosing what a collision does.\n *\n * Without `opts` this is a plain multi-row INSERT and a collision aborts the\n * transaction — the behaviour every call had before the option existed.\n *\n * `action: \"ignore\"` emits `ON CONFLICT DO NOTHING`, which is how \"insert the\n * ones that are new\" becomes one round-trip instead of one per row with a\n * 23505 caught around each. **The returned rows are the ones actually\n * INSERTED**: a row that collided is skipped, so it is absent from the result\n * — Postgres does not return what it did not write.\n *\n * `action: \"update\"` emits `ON CONFLICT DO UPDATE`, setting every non-conflict\n * column from the incoming row, and every row comes back.\n */\n insertMany(\n rows: readonly TxInsertShape<Insert>[],\n opts?: {\n onConflict: readonly Extract<keyof Row, string>[];\n action?: \"ignore\" | \"update\";\n },\n ): TxRows<Row>;\n /**\n * Satırı yaz, `onConflict` kolonlarında çakışırsa üzerine yaz — planın\n * savepoint'i içinde, `Database.<şema>.<tablo>.put()` ile AYNI anlamda.\n *\n * Adı bilerek aynı: aynı iş için transaction içinde ve dışında iki farklı\n * yazım, bu run'ın kapatmak için var olduğu şeydir (P1). TEL şekli\n * (`op: \"upsert\"`) değişmedi — o iç sözleşme, yazarın gördüğü ad değil.\n *\n * Bir operasyon olmasının sebebi: alternatifi burada yazılamaz — başarısız\n * bir insert tüm transaction'ı abort eder, yani \"dene, sonra geri düş\" iki\n * plan adımı olamaz.\n */\n put(\n values: TxInsertShape<Insert>,\n options: { onConflict: readonly Extract<keyof Row, string>[] },\n ): TxRows<Row>;\n /**\n * Update every row matching `where`. The filter comes first because it is the\n * dangerous half: an update whose `where` you got wrong rewrites rows you\n * never looked at. The server refuses an update with no `where` at all.\n */\n updateWhere(where: TxWhere<Row, Rels>, set: TxSetShape<Insert>): TxRows<Row>;\n /** Delete every row matching `where`. The server refuses an unfiltered delete. */\n deleteWhere(where: TxWhere<Row, Rels>): TxRows<Row>;\n /** Read rows, optionally locking them for the rest of the transaction. */\n select(where?: TxWhere<Row, Rels>, options?: TxSelectOptions): TxRows<Row>;\n}\n\n/**\n * The handle a transaction callback receives.\n *\n * It carries tables and nothing else: no `query`, no `findById`, no `asService`.\n * A read whose value the plan does not write belongs OUTSIDE the transaction,\n * where it costs one round trip and can be branched on like an ordinary value.\n */\nexport interface TxPlanHandle<TTables> {\n /**\n * @deprecated `tx.public` kullanın. Bu ad public'in takma adı olarak DURUYOR\n * (göç notu onu öğretiyor ve her mevcut çağrı onu kullanıyor), ama ARTIK\n * ÖĞRETİLMİYOR: doğrudan yüzeyde `Database.tables` FR-001 ile kaldırıldı, ve\n * plan yüzeyinin onu öğretmeye devam etmesi yazarı bir yüzeyde çalışıp\n * diğerinde derlenmeyen bir yazıma alıştırıyordu (gözcü M-6).\n */\n tables: TTables;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — expressions\n// ---------------------------------------------------------------------------\n\n/** Internal marker read by the serialiser. */\nconst EXPR = Symbol.for(\"palbase.tx.expr\");\nconst REF = Symbol.for(\"palbase.tx.ref\");\nconst ROW = Symbol.for(\"palbase.tx.row\");\nconst ROWS = Symbol.for(\"palbase.tx.rows\");\n\ninterface RefDescriptor {\n op: number;\n field: string;\n}\n\n/** Property reads that must not silently produce a value on a plan handle.\n * `then` is the one that matters for correctness (it makes `await` a compile\n * error AND stops a handle from being adopted by a promise); the rest turn a\n * silent wrong answer — `\"[object Object]\"`, `NaN`, `{}` — into a thrown one. */\nconst TRAPPED_PROPS: readonly (string | symbol)[] = [\n \"then\",\n \"valueOf\",\n \"toString\",\n \"toJSON\",\n Symbol.toPrimitive,\n];\n\nfunction trap(prop: string | symbol, what: string, hint: string): never {\n const name = typeof prop === \"symbol\" ? prop.description ?? String(prop) : prop;\n throw new TxRefError(\n `${what} was used as a value (via \\`${name}\\`). Nothing in a transaction ` +\n `callback has run yet, so there is no value to read. ${hint}`,\n );\n}\n\n/** The server's `now()`. */\nexport function now(): TxNow {\n return makeExpr({ fn: \"now\" }) as TxNow;\n}\n\n/** Add `by` to the column's current value. Only valid in an update's `set`. */\nexport function increment(by: number | string): TxColumnExpr {\n assertAmount(by, \"increment\");\n return makeExpr({ fn: \"inc\", by }) as TxColumnExpr;\n}\n\n/**\n * `increment`'in eski adı. AYNI fabrikadır — iki uygulama değil, iki ad.\n *\n * @deprecated `increment()` kullanın; bu ad geriye dönük uyumluluk için duruyor.\n */\nexport const inc = increment;\n\n/** Subtract `by` from the column's current value. Only valid in an update's `set`. */\nexport function decrement(by: number | string): TxColumnExpr {\n assertAmount(by, \"decrement\");\n return makeExpr({ fn: \"dec\", by }) as TxColumnExpr;\n}\n\n/**\n * `decrement`'in eski adı. AYNI fabrikadır.\n *\n * @deprecated `decrement()` kullanın.\n */\nexport const dec = decrement;\n\n/**\n * Miktarın taşınabilir olduğunu doğrular.\n *\n * String kabul edilir ve KASITLIDIR (D-007): `numeric` bir kolonda miktar JS\n * `number`'a uğrarsa 0.1 + 0.2 orada 0.30000000000000004'tür ve para hesabı\n * sessizce kayar. String hem burada hem `renderValue`'da bound parametre olarak\n * taşınır — Postgres onu tam ondalık olarak okur.\n */\nfunction assertAmount(by: number | string, fn: string): void {\n if (typeof by === \"string\") {\n // Metin SQL'e girmiyor (bound parametre), ama şekli yine de doğrulanır:\n // \"abc\" bind edilirse hata Postgres'ten gelir, çağıranın diliyle değil.\n if (!/^-?\\d+(\\.\\d+)?$/.test(by)) {\n throw new TxPlanError(\n `${fn}() ondalık bir sayı metni bekliyor, \"${by}\" aldı — kabul edilen biçim: \"12\", \"-12\", \"12.50\"`,\n );\n }\n } else if (typeof by !== \"number\" || !Number.isFinite(by)) {\n // JSON has no NaN/Infinity: they would serialise to `null` and the server\n // would reject the plan with an unhelpful decode error.\n throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);\n }\n // NEGATİF MİKTAR REDDEDİLİR — ve bu şekil kontrolünden çok daha fazlası.\n // `decrement(\"-5\")` `SET c = c - $1` derliyordu, `$1 = -5`, yani beş EKLİYORDU.\n // FR-014'ün amiral deseninde (`where: { balance: { gte: amount } }`) miktar\n // istek gövdesinden geliyorsa `balance >= -5` her zaman doğru: hesap\n // KREDİLENDİRİLİR ve çağrı bunu 1 satırla \"başarı\" diye raporlar. Guard\n // okunduğunda işaret kontrol edilmiş gibi duruyordu (gözcü I9, ölçüldü).\n const negative = typeof by === \"string\" ? by.trimStart().startsWith(\"-\") : by < 0;\n if (negative) {\n const other = fn === \"increment\" ? \"decrement\" : \"increment\";\n throw new TxPlanError(\n `${fn}() negatif miktar almaz (\"${String(by)}\"). Ters yön için ${other}() kullanın — ` +\n `işaretin miktarda saklanması, yönü okuyan hiçbir kod tarafından görülmezdi.`,\n );\n }\n}\n\n/**\n * Bir değer `increment()`/`decrement()` ürünü mü? Öyleyse tel şekli.\n *\n * DOĞRUDAN yol (`updateMany`) da bu ifadeyi anlamak zorunda: aynı nesnenin iki\n * yerde çalışması, \"kolona ekle\"nin tek yazımı olmasının şartı (P1).\n */\nexport function columnExprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n return exprOf(v);\n}\n\nfunction makeExpr(expr: TxWireExpr[\"$expr\"]): unknown {\n return new Proxy(\n { [EXPR]: expr } as Record<string | symbol, unknown>,\n {\n get(target, prop) {\n if (prop === EXPR) return target[EXPR];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(prop, \"A plan expression\", \"Write it into an operation instead.\");\n }\n return undefined;\n },\n },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — refs and row handles\n// ---------------------------------------------------------------------------\n\nfunction makeRef(op: number, field: string): unknown {\n const target: Record<string | symbol, unknown> = { [REF]: { op, field } satisfies RefDescriptor };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === REF) return t[REF];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n `\\`${field}\\` of a row this transaction has not written yet`,\n \"Pass it to another operation in the same plan, or return it from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n return undefined;\n },\n });\n}\n\nfunction makeRowHandle(op: number): unknown {\n const target: Record<string | symbol, unknown> = { [ROW]: op };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === ROW) return t[ROW];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n \"A row this transaction has not written yet\",\n \"Read one of its columns to reference it, or return the row from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n if (typeof prop === \"symbol\") return undefined;\n return makeRef(op, prop);\n },\n });\n}\n\nfunction refDescriptor(v: unknown): RefDescriptor | null {\n if (typeof v !== \"object\" || v === null) return null;\n const d = (v as Record<symbol, unknown>)[REF];\n return isRefDescriptor(d) ? d : null;\n}\n\nfunction isRefDescriptor(d: unknown): d is RefDescriptor {\n return (\n typeof d === \"object\" &&\n d !== null &&\n typeof (d as RefDescriptor).op === \"number\" &&\n typeof (d as RefDescriptor).field === \"string\"\n );\n}\n\nfunction rowOpIndex(v: unknown): number | null {\n if (typeof v !== \"object\" || v === null) return null;\n const op = (v as Record<symbol, unknown>)[ROW];\n return typeof op === \"number\" ? op : null;\n}\n\nfunction exprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n if (typeof v !== \"object\" || v === null) return null;\n const e = (v as Record<symbol, unknown>)[EXPR];\n return typeof e === \"object\" && e !== null ? (e as TxWireExpr[\"$expr\"]) : null;\n}\n\nfunction isRowsHandle(v: unknown): boolean {\n return typeof v === \"object\" && v !== null && (v as Record<symbol, unknown>)[ROWS] !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — value encoding\n// ---------------------------------------------------------------------------\n\n/**\n * Encode one value of a `values`/`set`/`where` map.\n *\n * The nesting check is not defensive tidiness. The server treats `$ref` as a\n * tagged value only at the TOP of a column's value; a ref buried inside a jsonb\n * payload is just data, and would be stored as the literal object\n * `{\"$ref\":{...}}` — a write that succeeds, commits, and is wrong. So a nested\n * handle is a hard error here, where the line that wrote it is still on the\n * stack.\n */\nfunction encodeValue(value: unknown, column: string, allowColumnExpr: boolean): TxWireValue {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n // `now()` bir KARŞILAŞTIRMA değeri olarak geçer — sunucu saati. Diğer\n // ifadeler (increment/decrement) yazma ifadesidir ve aşağıda adıyla\n // reddediliyor. Düz op yolu ile aynı ayrım, aynı gerekçe.\n if (isNowExpr(value)) return { $expr: { fn: \"now\" } };\n const expr = exprOf(value);\n if (expr) {\n if (expr.fn !== \"now\" && !allowColumnExpr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() reads the column's current value, so it is ` +\n `only valid in updateWhere(where, set).`,\n );\n }\n return { $expr: expr } satisfies TxWireExpr;\n }\n\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant ` +\n `(e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n\n assertNoNestedHandles(value, column);\n return value;\n}\n\n/**\n * Encode a FİLTRE — `values`/`set` ile AYNI kodlayıcı değil, ve olmaması bir\n * düzeltme.\n *\n * `encodeValue` bir `$ref`'i yalnız kolonun EN ÜSTÜNDE kabul ediyor, çünkü bir\n * insert değerinin İÇİNE gömülü ref sunucuda çözülmez, literal JSON olarak\n * SAKLANIR — \"başarıyla commit olan ve yanlış olan bir yazma\". O kural DEĞER\n * yolu için doğru.\n *\n * FİLTREDE öyle değil: motorun `resolveRefsDeep`'i bir ref'i filtrenin HER\n * yerinde çözüyor — operatörün sağında, `OR`/`AND`/`NOT` dallarının içinde. Ama\n * kodlayıcı hâlâ değer kuralını uyguluyordu, yani üç katman üç farklı cevap\n * veriyordu (gözcü C-2): tip kabul, motor çözüyor, kodlayıcı REDDEDİYOR — ve\n * reddin metni değer-yuvalama vakasını anlatıyor, filtrede olmayan bir şeyi.\n *\n * İFADE TUTAMAĞI ve SATIR TUTAMAĞI filtrede HÂLÂ reddediliyor: onları motor\n * filtrede çözmüyor ve çözmemeli — `increment()` bir yazma ifadesi, bir\n * karşılaştırma değil.\n */\nfunction encodeFilterValue(value: unknown, column: string): unknown {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n const expr = exprOf(value);\n if (expr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() bir YAZMA ifadesi, karşılaştırma değil — ` +\n `filtrede kullanılamaz. Kolonu bir değerle ya da col() ile karşılaştırın.`,\n );\n }\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant (e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n if (Array.isArray(value)) return value.map((v) => encodeFilterValue(v, column));\n // `col()` ve `sqlFragment` OLDUĞU GİBİ geçer: markaları süreç içinde korunur\n // ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !(value instanceof Date) && !isColRef(value) && !isSqlFragment(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = encodeFilterValue(v, column);\n }\n return out;\n }\n return value;\n}\n\n/** Filtre haritası — anahtarlar SIRALI (aynı geri çağrı bayt-özdeş JSON üretsin). */\nfunction encodeFilterMap(map: Record<string, unknown>): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n if (value === undefined) continue;\n out[key] = encodeFilterValue(value, key) as TxWireValue;\n }\n return out;\n}\n\nfunction assertNoNestedHandles(value: unknown, column: string): void {\n if (typeof value !== \"object\" || value === null) return;\n if (value instanceof Date) return;\n if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: a plan handle is nested inside a value. The server would ` +\n `store it as literal JSON, not resolve it. Put the reference directly in ` +\n `the column.`,\n );\n }\n if (Array.isArray(value)) {\n for (const item of value) assertNoNestedHandles(item, column);\n return;\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n assertNoNestedHandles(item, column);\n }\n}\n\n/**\n * Encode a column map, dropping `undefined` and emitting keys SORTED.\n *\n * Sorting is what makes the same callback produce byte-identical JSON every\n * time, which is what lets the Go decoder be locked to goldens this SDK emits.\n * Dropping `undefined` mirrors what `JSON.stringify` would do anyway, but does\n * it where the resulting column list is still checkable.\n */\nfunction encodeMap(\n map: Record<string, unknown>,\n allowColumnExpr: boolean,\n): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n // AÇIK `undefined` REDDEDİLİR (D-017 kapandı).\n //\n // \"Kolon varsayılanını al\" demenin yolu anahtarı HİÇ KOYMAMAK; bu döngü\n // zaten yalnız var olan anahtarları geziyor, yani o niyet bozulmadan\n // çalışıyor. Ayırt edilen şey başka: anahtarın DURDUĞU ama değerinin\n // `undefined` olduğu hâl — yani `{ title: req.body.title }` gövdede\n // `title` yokken. O ölçülmüş bir olaydı: kolon sessizce yazılmadı ve\n // istek 200 döndü.\n //\n // Doğrudan yol bunu baştan beri adıyla reddediyordu; plan yolu sessizce\n // düşürüyordu. Aynı girdiye zıt iki cevap, \"tek filtre dili, tek cevap\"\n // iddiasını yazma tarafında boşa çıkarıyordu.\n if (value === undefined) {\n throw new TxPlanError(\n `${key} değeri undefined — bu bir yazma değeri değil. Anahtar duruyor ` +\n `ama değeri yok, yani kolon sessizce YAZILMAZDI (istek gövdesinden ` +\n `gelen bir alanın eksik olması bu şekilde görünür). Kolon ` +\n `varsayılanını istiyorsanız anahtarı hiç koymayın; NULL yazmak ` +\n `istiyorsanız açıkça null yazın.`,\n );\n }\n out[key] = encodeValue(value, key, allowColumnExpr);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the builder\n// ---------------------------------------------------------------------------\n\n/** How many rows an op can produce, as far as the CLIENT can tell before it\n * runs. Only the empty `insertMany` is knowable, and knowing it is what lets a\n * doomed expectation fail on the line that declared it. */\nconst SKIPPED_OP = -1;\n\nclass TxRowsImpl<Row> implements TxRows<Row> {\n // Present so `isRowsHandle` recognises the object; never read for its value.\n readonly [ROWS] = true;\n // Phantom: the type brand that stops a bare object passing as a TxRows. Never\n // present at run time, which is what `declare` says.\n declare readonly [rowsBrand]: Row;\n private guarded = false;\n\n constructor(\n private readonly builder: TxPlanBuilder,\n private readonly opIndex: number,\n private readonly what: string,\n ) {}\n\n // The type-level `await` guard made real: TS rejects `await rows` at compile\n // time, and reaching this means someone called `.then(...)` by hand.\n then(): never {\n throw new TxRefError(\n `${this.what} cannot be awaited: a transaction callback builds a plan, it ` +\n `does not run statements. Remove the \\`await\\`.`,\n );\n }\n\n expectOne(error: Error): TxRow<Row> {\n this.declareGuard(\"one\", 1, error);\n if (this.opIndex === SKIPPED_OP) throw error;\n return makeRowHandle(this.opIndex) as TxRow<Row>;\n }\n\n expectNone(error: Error): void {\n this.declareGuard(\"none\", 0, error);\n }\n\n expectAtLeast(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtLeast\");\n this.declareGuard(\"atLeast\", n, error);\n if (this.opIndex === SKIPPED_OP && n > 0) throw error;\n }\n\n expectAtMost(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtMost\");\n this.declareGuard(\"atMost\", n, error);\n }\n\n private declareGuard(kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n if (!(error instanceof Error)) {\n // The error object is the ONLY thing that describes this failure to the\n // caller — the server sends back an index, never a message.\n throw new TxPlanError(\n `${this.what}: an expectation needs the Error to throw when it does not ` +\n `hold (e.g. \\`.expect…(new Conflict(\"already accepted\"))\\`).`,\n );\n }\n if (this.guarded) {\n throw new TxPlanError(\n `${this.what} already has an expectation. One operation carries one ` +\n `expectation; declare the second one on its own operation.`,\n );\n }\n this.guarded = true;\n if (this.opIndex === SKIPPED_OP) return;\n this.builder.attachGuard(this.opIndex, kind, n, error);\n }\n}\n\nfunction assertGuardCount(n: number, fn: string): void {\n if (!Number.isInteger(n) || n < 0) {\n throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);\n }\n}\n\n/** Bounds mirrored from the plan executor so an over-sized plan is named here rather\n * than rejected as an opaque 400 after it has crossed the network. */\nconst MAX_OPS = 1000;\nconst MAX_ROWS = 5000;\n\n/**\n * Accumulates ops and the client-side error table while the callback runs.\n *\n * Exported for the runtime and for tests that need the serialised plan without\n * a server; author code never sees it.\n */\nexport class TxPlanBuilder {\n private readonly ops: TxWireOp[] = [];\n /** Errors handed to expectations, indexed by the `slot` the server echoes. */\n private readonly slots: Error[] = [];\n\n /** The table surface handed to the callback. Untyped here; the public\n * `transaction()` signatures put the schema types on top. */\n table(name: string): TxTable<Record<string, unknown>, Record<string, unknown>> {\n return {\n insert: (values) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.insert() needs at least one column`);\n }\n return this.push({ op: \"insert\", table: name, values: encoded }, `${name}.insert()`);\n },\n\n put: (values, options) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one column`);\n }\n if (options.onConflict.length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one onConflict column`);\n }\n return this.push(\n { op: \"upsert\", table: name, values: encoded, onConflict: options.onConflict },\n `${name}.upsert()`,\n );\n },\n\n insertMany: (rows, opts) => {\n if (rows.length === 0) {\n // Nothing to write. Emitting an op would be a guaranteed 400 (the\n // server requires rows), and refusing outright would punish the\n // ordinary \"filtered every candidate out\" case.\n return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);\n }\n if (rows.length > MAX_ROWS) {\n throw new TxPlanError(\n `${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. ` +\n `Split the write across requests.`,\n );\n }\n const encoded = rows.map((row) => encodeMap(row as Record<string, unknown>, false));\n assertUniformRows(encoded, name);\n if (opts !== undefined && opts.onConflict.length === 0) {\n throw new TxPlanError(\n `${name}.insertMany() was given a conflict action with no onConflict ` +\n `columns. Postgres matches a collision on columns, so name them.`,\n );\n }\n return this.push(\n {\n op: \"insertMany\",\n table: name,\n rows: encoded,\n // Omitted entirely when no options were given, so the op a plain\n // insertMany produces is byte-identical to the one it produced\n // before this option existed.\n ...(opts !== undefined\n ? { onConflict: opts.onConflict, action: opts.action ?? \"ignore\" }\n : {}),\n },\n `${name}.insertMany()`,\n );\n },\n\n updateWhere: (where, set) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n const encodedSet = encodeMap(set as Record<string, unknown>, true);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.updateWhere() needs a filter. An update with no filter ` +\n `rewrites the whole table.`,\n );\n }\n if (Object.keys(encodedSet).length === 0) {\n throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);\n }\n return this.push(\n { op: \"update\", table: name, set: encodedSet, where: encodedWhere },\n `${name}.updateWhere()`,\n );\n },\n\n deleteWhere: (where) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.deleteWhere() needs a filter. A delete with no filter empties ` +\n `the table.`,\n );\n }\n return this.push(\n { op: \"delete\", table: name, where: encodedWhere },\n `${name}.deleteWhere()`,\n );\n },\n\n select: (where, options) => {\n const op: TxWireOp = { op: \"select\", table: name };\n const encodedWhere = encodeFilterMap((where ?? {}) as Record<string, unknown>);\n if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;\n if (options?.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit < 0) {\n throw new TxPlanError(\n `${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`,\n );\n }\n op.limit = options.limit;\n }\n if (options?.lock !== undefined) op.lock = options.lock;\n return this.push(op, `${name}.select()`);\n },\n };\n }\n\n private push(op: TxWireOp, what: string): TxRows<Record<string, unknown>> {\n if (this.ops.length >= MAX_OPS) {\n throw new TxPlanError(\n `this transaction has ${MAX_OPS} operations, which is the limit. Use ` +\n `insertMany() for bulk writes, or split the work across requests.`,\n );\n }\n const index = this.ops.length;\n this.ops.push(op);\n return new TxRowsImpl(this, index, what);\n }\n\n /** Attach an expectation to an op and record its error in the slot table. */\n attachGuard(opIndex: number, kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n const op = this.ops[opIndex];\n // Unreachable: the index came from `push`. A loud failure beats a silently\n // unguarded write if that ever stops being true.\n if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);\n const slot = this.slots.length;\n this.slots.push(error);\n op.guard = { kind, n, slot };\n }\n\n /** The serialisable plan. Empty when the callback described no writes. */\n body(): TxPlanBody {\n return { ops: this.ops };\n }\n\n /** The error the server's `slot` selects, or `null` when it names one this\n * plan never declared (a server/client disagreement, not a tenant error). */\n errorForSlot(slot: number): Error | null {\n return this.slots[slot] ?? null;\n }\n}\n\nfunction assertUniformRows(rows: Record<string, TxWireValue>[], table: string): void {\n const first = rows[0];\n if (!first) return;\n const want = Object.keys(first);\n const wantKey = want.join(\",\");\n for (let i = 1; i < rows.length; i++) {\n const got = Object.keys(rows[i] as Record<string, TxWireValue>);\n if (got.join(\",\") !== wantKey) {\n // One statement, one column list. A ragged row would take the DB default\n // for the column it omitted — a write that succeeds and is wrong.\n throw new TxPlanError(\n `${table}.insertMany(): every row must set the same columns. Row 0 sets ` +\n `[${want.join(\", \")}] but row ${i} sets [${got.join(\", \")}]. ` +\n `(A property set to \\`undefined\\` counts as absent — use \\`null\\`.)`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — materialisation\n// ---------------------------------------------------------------------------\n\n/**\n * Replace every handle in the callback's return value with what the server\n * actually produced.\n *\n * Walks arrays and PLAIN objects only. Class instances (a Date, a Zod schema, a\n * domain object) are returned untouched — recursing into them would rebuild them\n * as bare objects, and nothing inside one can be a handle that this SDK created.\n */\nexport function materializeResult(value: unknown, results: TxPlanOpResult[]): unknown {\n const ref = refDescriptor(value);\n if (ref) {\n const row = rowOf(results, ref.op, `\\`${ref.field}\\``);\n if (!(ref.field in row)) {\n throw new TxPlanError(\n `the transaction's operation ${ref.op} returned no column \\`${ref.field}\\`.`,\n );\n }\n return row[ref.field];\n }\n\n const rowOp = rowOpIndex(value);\n if (rowOp !== null) return rowOf(results, rowOp, \"a row\");\n\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n \"an operation result cannot be returned from a transaction callback: its \" +\n \"row count is not known until the plan runs. Declare an expectation \" +\n \"(`.expectOne(err)`) and return the row, or a column of it.\",\n );\n }\n\n if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);\n return out;\n }\n\n return value;\n}\n\nfunction rowOf(results: TxPlanOpResult[], opIndex: number, what: string): Record<string, unknown> {\n const result = results[opIndex];\n if (!result) {\n throw new TxPlanError(\n `the transaction returned no result for operation ${opIndex}, so ${what} ` +\n `cannot be read.`,\n );\n }\n const row = result.rows[0];\n if (!row) {\n // Unreachable through the public API: a handle only exists behind an\n // `expectOne`, and the server rolls back rather than answering 200 with a\n // guard unmet. Loud, because the alternative is `undefined` in tenant data.\n throw new TxPlanError(\n `the transaction's operation ${opIndex} returned no row, so ${what} cannot ` +\n `be read.`,\n );\n }\n return row;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the driver\n// ---------------------------------------------------------------------------\n\n/** What {@link runTxPlan} needs from the runtime: one call, one transaction. */\nexport interface TxPlanTransport {\n txPlan(plan: TxPlanBody): Promise<TxPlanResponse>;\n}\n\n/**\n * Build the plan, send it, and resolve the callback's return value.\n *\n * A callback that throws never reaches the network: there is nothing to roll\n * back because nothing was sent. A callback that describes no writes also skips\n * the round trip entirely.\n *\n * The RETURN type is `unknown` here on purpose. `Materialized<T>` is a compile-\n * time rewrite of the callback's return type, and it belongs on the public\n * `transaction()` signatures where `T` is inferred from the author's callback;\n * threading it through this driver as well would mean inferring `T` twice, from\n * two different positions, and reconciling them. The public wrappers narrow\n * once, at the seam where the value types were erased anyway.\n */\nexport async function runTxPlan<THandle>(\n transport: TxPlanTransport,\n // TUTAMAĞIN TAMAMI, yalnız `tables` DEĞİL. Tutamak artık şema yüzeyini de\n // taşıyor (`tx.public.x`, `tx.<şema>.x`), ve onu BURADA `{ tables }` diye\n // yeniden kurmak o yüzeyi sessizce düşürürdü.\n handle: THandle,\n builder: TxPlanBuilder,\n fn: (tx: THandle) => unknown,\n): Promise<unknown> {\n const returned = fn(handle);\n const body = builder.body();\n if (body.ops.length === 0) {\n return materializeResult(returned, []);\n }\n\n let response: TxPlanResponse;\n try {\n response = await transport.txPlan(body);\n } catch (err) {\n throw translateRejection(err, builder);\n }\n return materializeResult(returned, response.results);\n}\n\n/**\n * Turn the broker's rejection back into the tenant's own error.\n *\n * The server never sees the `Error` an expectation was given — only its slot\n * index — so this is the only place the intended error can be produced. A\n * rejection this SDK does not recognise passes through untouched: inventing an\n * error for it would hide the real failure.\n */\nfunction translateRejection(err: unknown, builder: TxPlanBuilder): unknown {\n if (typeof err !== \"object\" || err === null) return err;\n const rejection = err as TxPlanRejection;\n if (rejection.error_code !== \"tx_guard_failed\" || typeof rejection.slot !== \"number\") {\n return err;\n }\n return builder.errorForSlot(rejection.slot) ?? err;\n}\n","/** A PostgreSQL isolation level supported by the explicit root transaction. */\nexport type TransactionIsolation = \"read committed\" | \"repeatable read\" | \"serializable\";\n\nexport interface AtomicOptions {\n /** Each retry opens a fresh transaction and reruns the complete callback.\n * Defaults to zero. Keep external effects outside it; persist an outbox instead. */\n retry?: number;\n isolation?: TransactionIsolation;\n readOnly?: boolean;\n /** Maximum wait for a PostgreSQL lock. Defaults to 5000 ms. */\n lockTimeoutMs?: number;\n /** PostgreSQL statement timeout; applies to every statement in this scope. */\n statementTimeoutMs?: number;\n /** Total work deadline including queueing and retries. Active Bun queries are\n * cancelled; rollback settles before release. An in-flight COMMIT is awaited. */\n timeoutMs?: number;\n signal?: AbortSignal;\n\n}\n\nexport function retryBudget(value: number | undefined): number {\n const n = value ?? 0;\n if (!Number.isInteger(n) || n < 0 || n > 10) {\n throw new Error(\"transaction retry must be an integer between 0 and 10\");\n }\n return n;\n}\n\nexport function validateAtomicOptions(options: AtomicOptions): void {\n retryBudget(options.retry);\n if (options.isolation !== undefined && ![\"read committed\", \"repeatable read\", \"serializable\"].includes(options.isolation)) {\n throw new Error(\"transaction isolation must be read committed, repeatable read or serializable\");\n }\n if (options.readOnly !== undefined && typeof options.readOnly !== \"boolean\") {\n throw new Error(\"transaction readOnly must be a boolean\");\n }\n for (const name of [\"lockTimeoutMs\", \"statementTimeoutMs\", \"timeoutMs\"] as const) {\n const n = options[name];\n if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 2_147_483_647)) {\n throw new Error(`transaction ${name} must be a positive integer in milliseconds`);\n }\n }\n if (options.signal !== undefined && (typeof options.signal.aborted !== \"boolean\" || typeof options.signal.addEventListener !== \"function\")) {\n throw new Error(\"transaction signal must be an AbortSignal\");\n }\n}\n\n/** A savepoint cannot replace the enclosing transaction's snapshot or retry COMMIT. */\nexport function assertPlanRetry(options: { retry?: number } | undefined): void {\n if (retryBudget(options?.retry) !== 0) {\n throw new Error(\n \"Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. \" +\n \"Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.\",\n );\n }\n}\n","// The wire shape of a declared schema — what the deploy reads.\n//\n// `defineSchema(...)` produces a value full of builders and phantom types, which\n// is the right shape for authoring and the wrong shape for anything outside this\n// process. The deploy is Go: it introspects the live database, diffs it against\n// the declaration, and applies the difference. So the declaration has to leave\n// TypeScript as data, and this file is where that happens.\n//\n// It lives in the SDK because the SDK owns the DSL. The alternative — a script\n// beside the deploy that reaches into `._def` — is a second reading of a private\n// shape, and it drifts the moment a column gains a property: the DSL keeps\n// working, the emitter silently omits it, and the database is missing something\n// nobody can see in the source.\n//\n// The field names below are a CONTRACT with Go's `schema.SchemaJSON`. Renaming\n// one here without renaming it there produces a declaration that parses to\n// something emptier than it was — the failure mode being a column, a policy, or\n// a whole table that quietly never gets created.\n// Politika ifadesinin tel şekli `policy.ts`'te TEK kez bildiriliyor. İki kopya\n// olsaydı biri `exists` düğümünü alır, diğeri almaz ve fark ancak Go tarafı\n// bilmediği bir `kind` gördüğünde ortaya çıkardı.\nimport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nexport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nimport type { ColumnBuilder, ColumnDef } from \"./columns.js\";\nimport type { PolicyDef } from \"./policy.js\";\nimport type { MemoryDecl, SchemaDef, SearchDecl, TableDef } from \"./schema.js\";\n\n/** One column, flattened. Mirrors Go's `schema.ColumnJSON`. */\nexport interface ColumnJSON {\n type: string;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n renamedFrom?: string;\n /** See Go's `schema.ColumnJSON.Ignored` — the contraction gate's only signal. */\n ignored?: boolean;\n owns?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: string;\n /** FR-044: türev FK index'i kapatılmışsa `false`. Bildirilmemişse alan YOK. */\n index?: boolean;\n /** FR-049: kolon increment() ile güncelleniyorsa `true`. Aksi hâlde alan YOK. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n dimensions?: number;\n}\n\n/** One RLS policy. Mirrors Go's `schema.PolicyJSON`. */\nexport interface PolicyJSON {\n name: string;\n command: string;\n roles: string[];\n /**\n * `USING (...)` — ham string (kaçış kapağı, FR-028) ya da YAPI (FR-022).\n *\n * Go tarafı ikisini de okur: string olan verbatim emit edilir, yapı olan\n * `generator.go`'da SQL'e çevrilir (C-6). Yapı hâli InitPlan sarmalamasını\n * ve `TO <rol>` daraltmasını GÜVENLE yapılabilir kılan şey — string üstünde\n * regex'le denemek yorum içindeki bir `auth.uid()`'yi de sarmalardı.\n */\n using: string | PolicyExprJSON | null;\n withCheck: string | PolicyExprJSON | null;\n permissive: boolean;\n}\n\n\n/** One table. Mirrors Go's `schema.TableJSON`. */\nexport interface TableJSON {\n /**\n * The schema this table lives in. `public` unless declared otherwise.\n *\n * The table carries it because the diff iterates over KEYS but passes the\n * VALUE around: a bare name inside a qualified key space writes the migration\n * into the wrong schema, silently.\n */\n schema: string;\n name: string;\n columns: Record<string, ColumnJSON>;\n rls: boolean;\n policies: PolicyJSON[];\n primaryKey?: string[];\n uniqueConstraints?: { name: string; columns: string[] }[];\n rawConstraints?: { name: string; up: string }[];\n checks?: { name: string; expr: string }[];\n indexes?: IndexJSON[];\n /** Canlıdan düşürülecek constraint adları (FR-008). Sıfır değerde OMIT. */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY'ler (FR-001). Sıfır değerde OMIT. */\n foreignKeys?: ForeignKeyJSON[];\n /** Koşullu FK'lar — donan demetler (FR-012). Sıfır değerde OMIT. */\n freeze?: FreezeJSON[];\n /** Guard'lar — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). Sıfır değerde OMIT. */\n guards?: GuardJSON[];\n /** Bir kez koşacak veri düzeltmeleri (FR-033). Sıfır değerde OMIT. */\n backfills?: BackfillJSON[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder. Sıfır değerde OMIT —\n * bildirmeyen tablolar wire'da bayt-aynı kalır.\n */\n appendOnly?: boolean;\n search?: SearchJSON;\n memory?: MemoryJSON;\n}\n\n/**\n * Bir index'in wire şekli — Go'nun `IndexJSON`'ıyla ALAN-ADI SÖZLEŞMESİ.\n *\n * `name` + `columns` bugünkü hâl; kalanı FR-041…043'ün taşıyıcısı. Hepsi sıfır\n * değerde OMIT edilir: bildirmeyen bir index wire'da eskisiyle bayt-aynı kalır,\n * yoksa dokunulmamış her şema diff'te değişmiş görünür ve her deploy churn üretir.\n */\nexport interface IndexJSON {\n name: string;\n /** `CREATE UNIQUE INDEX` (FR-007). Sıfır değerde OMIT. */\n unique?: boolean;\n columns: string[];\n /** Partial index koşulu (FR-042) — filtre şekli `WhereFilter` ile aynı. */\n where?: unknown;\n /** İfade index'i (FR-043), ör. `lower(email)`. `columns` ile birlikte kullanılmaz. */\n expression?: string;\n /** Kolon sırası (FR-043). */\n sort?: \"asc\" | \"desc\";\n /** NULL sırası (FR-043). */\n nulls?: \"first\" | \"last\";\n /** Covering index — `INCLUDE (...)` (FR-043). */\n include?: string[];\n}\n\n/**\n * Tablo düzeyi çok sütunlu FOREIGN KEY'in wire şekli — Go'nun `ForeignKeyJSON`'ı\n * ile ALAN-ADI SÖZLEŞMESİ (FR-001). Bir ad değişirse wire sessizce kopar.\n *\n * `onUpdate`/`onDelete`/`match` sıfır değerinde OMIT: bildirmeyen bir FK\n * Postgres'in varsayılanını (NO ACTION / MATCH SIMPLE) alır ve telde yer\n * kaplamaz (NFR-006).\n */\nexport interface ForeignKeyJSON {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: string;\n onDelete?: string;\n match?: string;\n}\n\n/**\n * Koşullu FK'nın (\"donan demet\") wire şekli — Go'nun `FreezeJSON`'ı ile\n * ALAN-ADI SÖZLEŞMESİ (C-8, FR-012).\n *\n * `when` politika ifade yapısının ta kendisi — `IndexJSON.where` ile aynı\n * duruş: üçüncü bir yüklem lehçesi açmak, aynı sorunun iki yazımı demekti.\n * Alanların hiçbiri opsiyonel değil: bir freeze'in koşulu, donan sütunları ve\n * hedefi olmadan anlamı yok ve `toFreezeDef` bunları bildirim anında şart\n * koşuyor. Sıfır değerde OMIT edilen şey DİZİNİN KENDİSİ (`TableJSON.freeze`).\n */\nexport interface FreezeJSON {\n name: string;\n when: unknown;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/**\n * Bir guard'ın wire şekli — Go'nun `GuardJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-4/C-8, FR-015).\n *\n * `when` ile `exists` AYRI alanlar: Postgres bir trigger'ın `WHEN` yan\n * tümcesinde alt sorguya izin vermiyor (`cannot use subquery in trigger WHEN\n * condition`), yani çapraz satır yüklemi gövdedeki `EXISTS` bloğuna inmek\n * zorunda (FR-019). Ayrımı emitter'ın yükleme bakıp tahmin etmesi yerine wire'da\n * taşımak, o kuralı bildirimin kendi şekline yazar.\n *\n * `detail`/`hint`/`column` sıfır değerde OMIT — bildirmeyen bir guard telde yer\n * kaplamaz (NFR-006). `message` her zaman var: reddin kullanıcıya ulaşan tek\n * çıktısı o.\n */\nexport interface GuardJSON {\n name: string;\n event: string;\n when?: unknown;\n exists?: unknown;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/**\n * Bir backfill'in wire şekli — Go'nun `BackfillJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-8, FR-033).\n *\n * `name` kimliğin TAMAMI: \"koştu mu\" sorusu ona göre cevaplanıyor, `sql`'e göre\n * değil. Aynı adın altında değişen bir gövde ikinci bir koşu üretmez.\n */\nexport interface BackfillJSON {\n name: string;\n sql: string;\n}\n\n/** C-11 wire şekli — Go'nun MemoryJSON'ıyla alan-adı sözleşmesi (D-019).\n * Beyansız tablolarda alan OMIT — eski şemalar bayt-aynı (NFR-B1). */\nexport interface MemoryJSON {\n from: string[];\n into: string;\n subject?: string;\n extract: { provider: string; model: string };\n}\n\n/** A whole declaration. Mirrors Go's `schema.SchemaJSON`. */\nexport interface SchemaJSON {\n tables: Record<string, TableJSON>;\n extensions: string[];\n /**\n * Every declared schema, with its HTTP reachability.\n *\n * The flag has nowhere else to live: `/v1/db` must know which schemas are\n * reachable, and introspection must know which schemas the project DECLARED —\n * a live database also contains internal module schemas that are none of the\n * diff's business.\n */\n schemas: SchemaMetaJSON[];\n}\n\nexport interface SchemaMetaJSON {\n name: string;\n exposed: boolean;\n}\n\n/** The definition behind a column, whichever side of the builder it arrives on. */\nfunction defOf(column: ColumnBuilder | ColumnDef): ColumnDef {\n return \"_def\" in column ? column._def : column;\n}\n\nfunction columnToJSON(column: ColumnBuilder | ColumnDef): ColumnJSON {\n const def = defOf(column);\n const out: ColumnJSON = {\n type: def.type,\n nullable: def.nullable,\n primaryKey: def.primaryKey,\n };\n // Every optional field is omitted rather than emitted as undefined: Go\n // distinguishes \"absent\" from \"present and empty\" on several of these, and a\n // `defaultValue: null` is a real default that says NULL.\n if (def.defaultValue !== undefined) out.defaultValue = def.defaultValue;\n if (def.defaultRandom === true) out.defaultRandom = true;\n if (def.defaultNow === true) out.defaultNow = true;\n if (def.renamedFrom !== undefined) out.renamedFrom = def.renamedFrom;\n // Go'daki schema.ColumnJSON'un aynası. `omitempty` karşılığı: yalnız TRUE ise yazılır,\n // böylece işaretsiz bir şemanın JSON'u bu alandan önceki hâliyle byte-eş kalır.\n if (def.ignored === true) out.ignored = true;\n // OWNERSHIP HAS TO CROSS THE WIRE, because the gate that enforces it is on the\n // other side. `ownedByUser()` sets `owns` on the column, and Go's\n // `validateOwnership` reads `ColumnJSON.Owns` to refuse a table that declares\n // two owners — but nothing was carrying the flag between them.\n //\n // Measured on the live cluster: a table with TWO `ownedByUser()` columns\n // pushed clean and both foreign keys landed on `auth.users` ON DELETE CASCADE.\n // The rule existed in the DSL and in the generator; the wire in between said\n // nothing, so the generator saw ZERO ownership columns and had nothing to\n // refuse. A flag with a reader and no writer is a dead wire.\n if (def.owns === true) out.owns = true;\n if (def.references !== undefined) {\n out.references = { table: def.references.table, column: def.references.column };\n }\n if (def.onDeleteAction !== undefined) out.onDeleteAction = def.onDeleteAction;\n // Yalnız `false` taşınıyor: \"bildirilmedi\" ile \"açık\" aynı şey ve wire'a\n // yazmak bildirmeyen her kolonu diff'te değişmiş gösterirdi.\n if (def.index === false) out.index = false;\n if (def.counter === true) out.counter = true;\n if (def.enumName !== undefined) out.enumName = def.enumName;\n if (def.enumValues !== undefined) out.enumValues = [...def.enumValues];\n if (def.unique === true) out.unique = true;\n if (def.dimensions !== undefined) out.dimensions = def.dimensions;\n return out;\n}\n\nfunction policyToJSON(policy: PolicyDef): PolicyJSON {\n return {\n name: policy.name,\n command: policy.command ?? \"all\",\n roles: policy.roles ? [...policy.roles] : [],\n // null rather than omitted: a policy with no USING clause is a different\n // thing from one whose clause the emitter forgot, and Go reads the\n // difference.\n using: policy.using ?? null,\n withCheck: policy.withCheck ?? null,\n permissive: policy.permissive !== false,\n };\n}\n\n/** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).\n * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);\n * satır-modu ve eski biçim bayt-aynı kalır (NFR-B1). */\nexport interface SearchJSON {\n text?: { columns: string[] };\n vector?: {\n column?: string;\n metric: string;\n embed?: { provider: string; model: string; from: string[]; apiKeyName?: string; dimensions?: number; baseURL?: string };\n staleness?: \"null\" | \"keep\";\n mode?: \"row\" | \"chunks\";\n chunks?: { sizeChars?: number; overlapChars?: number };\n }[];\n /** FR-026: sorgu-yeniden-yazımı haritası — beyan yoksa OMIT (NFR-B1). */\n synonyms?: Record<string, string[]>;\n /** C-1: sonuç yeniden-sıralama beyanı — beyan yoksa OMIT. */\n /** FR-029: geçerlilik türevleri — beyan yoksa OMIT. */\n validity?: boolean;\n}\n\n/** T020 (C-1): iki biçimin de üst-düzey ortak alanları — beyan yoksa OMIT,\n * boş synonyms haritası da OMIT (NFR-B1 baytları kımıldamaz). */\nfunction commonSearchFields(search: SearchDecl, out: SearchJSON): void {\n if (search.synonyms !== undefined && Object.keys(search.synonyms).length > 0) {\n out.synonyms = Object.fromEntries(\n Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]]),\n );\n }\n if (search.validity === true) out.validity = true;\n}\n\n/** Beyanı normalize eder: vector her zaman DİZİ, metric her zaman dolu (vars. cosine),\n * authoring'deki `from`/`model` wire'da `embed` altında toplanır. Alan yoksa OMIT —\n * search'süz şema bayt-aynı kalır (NFR-006). */\nfunction searchToJSON(search: SearchDecl, vectorColumn: string | undefined): SearchJSON {\n if (search.from !== undefined && search.model !== undefined) {\n // YENİ biçim (D-007): from tek listedir — FTS'i de embed'i de besler.\n // Mod ŞEMADAN türer (D-010): tabloda vector kolonu varsa satır-modu\n // (column yazılır, mode OMIT — eski davranışla aynı wire), yoksa\n // chunk-modu (mode:\"chunks\", column yok — vektörler türev tabloda).\n const out: SearchJSON = {};\n const textCols =\n search.text === false ? undefined : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;\n if (textCols !== undefined) out.text = { columns: [...textCols] };\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: search.metric ?? \"cosine\" };\n if (vectorColumn !== undefined) v.column = vectorColumn;\n v.embed = {\n provider: search.model.provider,\n model: search.model.model,\n from: [...search.from],\n ...(search.model.apiKeyName !== undefined ? { apiKeyName: search.model.apiKeyName } : {}),\n ...(search.model.dimensions !== undefined ? { dimensions: search.model.dimensions } : {}),\n ...(search.model.baseURL !== undefined ? { baseURL: search.model.baseURL } : {}),\n };\n if (search.staleness !== undefined) v.staleness = search.staleness;\n if (vectorColumn === undefined) {\n v.mode = \"chunks\";\n if (search.chunks !== undefined) {\n const c: NonNullable<typeof v.chunks> = {};\n if (search.chunks.size !== undefined && search.chunks.size > 0) c.sizeChars = search.chunks.size;\n if (search.chunks.overlap !== undefined && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;\n if (Object.keys(c).length > 0) v.chunks = c;\n }\n }\n out.vector = [v];\n commonSearchFields(search, out);\n return out;\n }\n const out: SearchJSON = {};\n // Eski biçimde text yalnız dizi olabilir (boolean'ı defineSchema zaten\n // reddediyor); Array.isArray hem tipi daraltır hem o sözleşmeyi belgeler.\n if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };\n const legs = search.vector === undefined ? []\n : Array.isArray(search.vector) ? search.vector : [search.vector];\n if (legs.length > 0) {\n out.vector = legs.map((leg) => {\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: leg.metric ?? \"cosine\" };\n if (leg.column !== undefined) v.column = leg.column;\n if (leg.staleness !== undefined) v.staleness = leg.staleness;\n if (leg.model !== undefined) {\n v.embed = {\n provider: leg.model.provider,\n model: leg.model.model,\n from: [...(leg.from ?? [])],\n ...(leg.model.apiKeyName !== undefined ? { apiKeyName: leg.model.apiKeyName } : {}),\n ...(leg.model.dimensions !== undefined ? { dimensions: leg.model.dimensions } : {}),\n ...(leg.model.baseURL !== undefined ? { baseURL: leg.model.baseURL } : {}),\n };\n }\n return v;\n });\n }\n commonSearchFields(search, out);\n return out;\n}\n\nfunction memoryToJSON(m: MemoryDecl): MemoryJSON {\n return {\n from: [...m.from],\n into: m.into,\n ...(m.subject !== undefined ? { subject: m.subject } : {}),\n extract: { provider: m.extract.provider, model: m.extract.model },\n };\n}\n\nfunction tableToJSON(table: TableDef, schemaName: string): TableJSON {\n const columns: Record<string, ColumnJSON> = {};\n for (const [name, column] of Object.entries(table.columns)) {\n columns[name] = columnToJSON(column);\n }\n\n const out: TableJSON = {\n name: table.name,\n schema: schemaName,\n columns,\n // Read, not re-derived. `defineSchema` already resolves the fail-closed\n // default (RLS on unless the author wrote `rls: false`, and forced on by any\n // policy), and a second copy of a SECURITY default is exactly the thing that\n // drifts — the direction it drifted last time was \"expose everything\", and\n // the live proof was one user reading another's rows.\n rls: table.rls,\n // KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.\n // `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.\n ...(table.ignored === true ? { ignored: true } : {}),\n policies: (table.policies ?? []).map(policyToJSON),\n };\n\n if (table.primaryKey !== undefined && table.primaryKey.length > 0) {\n out.primaryKey = [...table.primaryKey];\n }\n if (table.unique !== undefined && table.unique.length > 0) {\n out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));\n }\n if (table.raw !== undefined && table.raw.length > 0) {\n out.rawConstraints = table.raw.map((r) => ({ name: r.name, up: r.up }));\n }\n if (table.checks !== undefined && table.checks.length > 0) {\n out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));\n }\n if (table.indexes !== undefined && table.indexes.length > 0) {\n out.indexes = table.indexes.map((i) => {\n // `columns` expression-index'te YOKTUR (ikisi birbirinin alternatifi).\n // Boş dizi ile taşınır: Go tarafı `expression` doluysa onu kullanır.\n const ix: IndexJSON = { name: i.name, columns: i.columns ? [...i.columns] : [] };\n if (i.unique === true) ix.unique = true;\n if (i.where !== undefined) ix.where = i.where;\n if (i.expression !== undefined) ix.expression = i.expression;\n if (i.sort !== undefined) ix.sort = i.sort;\n if (i.nulls !== undefined) ix.nulls = i.nulls;\n if (i.include !== undefined) ix.include = [...i.include];\n return ix;\n });\n }\n if (table.dropConstraints !== undefined && table.dropConstraints.length > 0) {\n out.dropConstraints = [...table.dropConstraints];\n }\n if (table.foreignKeys !== undefined && table.foreignKeys.length > 0) {\n out.foreignKeys = table.foreignKeys.map((fk) => {\n const j: ForeignKeyJSON = {\n name: fk.name,\n columns: [...fk.columns],\n refTable: fk.refTable,\n refColumns: [...fk.refColumns],\n };\n if (fk.onUpdate !== undefined) j.onUpdate = fk.onUpdate;\n if (fk.onDelete !== undefined) j.onDelete = fk.onDelete;\n if (fk.match !== undefined) j.match = fk.match;\n return j;\n });\n }\n if (table.freeze !== undefined && table.freeze.length > 0) {\n out.freeze = table.freeze.map((f) => ({\n name: f.name,\n when: f.when,\n columns: [...f.columns],\n refTable: f.refTable,\n refColumns: [...f.refColumns],\n }));\n }\n if (table.guards !== undefined && table.guards.length > 0) {\n out.guards = table.guards.map((g) => ({\n name: g.name,\n event: g.event,\n ...(g.when !== undefined ? { when: g.when } : {}),\n ...(g.exists !== undefined ? { exists: g.exists } : {}),\n message: g.message,\n ...(g.detail !== undefined ? { detail: g.detail } : {}),\n ...(g.hint !== undefined ? { hint: g.hint } : {}),\n ...(g.column !== undefined ? { column: g.column } : {}),\n }));\n }\n if (table.backfills !== undefined && table.backfills.length > 0) {\n out.backfills = table.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n // Sıfır değerde YAZILMAZ: `appendOnly: false` ile \"bildirilmemiş\" wire'da\n // ayırt edilemez olmalı, yoksa her eski şema diff'te değişmiş görünür.\n if (table.appendOnly === true) out.appendOnly = true;\n if (table.search !== undefined) {\n // D-010 mod kararının tek girdisi: tabloda dimensions'lı (vector) kolon\n // adı. Birden çoksa ilkini yazmak YANLIŞ olurdu — o durum eski biçimin\n // işidir ve yeni biçim + çoklu vector kolonu apply'da reddedilir.\n const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== undefined)?.[0];\n const sj = searchToJSON(table.search, vectorColumn);\n if (sj.text !== undefined || sj.vector !== undefined) out.search = sj;\n }\n if (table.memory !== undefined) {\n out.memory = memoryToJSON(table.memory);\n }\n return out;\n}\n\n/**\n * The key a table answers to in `SchemaJSON.tables`.\n *\n * A public table is BARE, anything else is schema-qualified. This is not a new\n * convention: `RefJSON.Table` already carries `auth.users`, and introspection\n * already returns a public referent bare and a non-public one qualified. Adding\n * a second key space would make two interpreters of the same database.\n */\nexport function qualifiedTableKey(schemaName: string, tableName: string): string {\n // An ABSENT schema means public, exactly as Go's `isPublicSchema` says. This\n // branch used to be missing here and present in the engine's private copy, so\n // the two writers of one rule answered DIFFERENTLY for `\"\"`: one qualified it\n // into a schema literally named the empty string, the other left it bare.\n return schemaName === \"\" || schemaName === \"public\" ? tableName : `${schemaName}.${tableName}`;\n}\n\n/**\n * Serialize declared schemas into the JSON the deploy applies.\n *\n * Takes every schema the project declares — one file per schema — because a\n * cross-schema foreign key can only be checked when both ends are in hand.\n */\nexport function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON {\n const tables: Record<string, TableJSON> = {};\n const extensions: string[] = [];\n const meta: SchemaMetaJSON[] = [];\n const seen = new Set<string>();\n for (const schema of schemas) {\n if (seen.has(schema.name)) {\n throw new Error(`two schemas declare the name \"${schema.name}\" — schema names must be unique`);\n }\n seen.add(schema.name);\n for (const table of Object.values(schema.tables)) {\n const json = tableToJSON(table, schema.name);\n tables[qualifiedTableKey(schema.name, json.name)] = json;\n }\n extensions.push(...(schema.extensions ?? []));\n // The schema list travels because the flag has nowhere else to live: without\n // it /v1/db cannot know which schemas are reachable over HTTP, and nothing\n // downstream can read the DECLARED schema set that introspection needs.\n meta.push({ name: schema.name, exposed: schema.exposed });\n }\n return { tables, extensions: [...new Set(extensions)], schemas: meta };\n}\n","/**\n * http.ts — the transport every module client speaks over.\n *\n * WHY IT IS HERE. This code, and the five clients built on it, spent their life\n * in `v2/runtime/internal/runtime/module-clients.js`: 1,768 lines of untyped\n * CommonJS that entered the SDK through an `@ts-expect-error` and left through\n * `unknown` casts. The interfaces those clients implement were always in this\n * package — only the implementations were outside it, where nothing checked one\n * against the other. Two defects came through that gap on 2026-08-15 (a type\n * that described a different server's columns; an accessor that was `undefined`\n * in a deployed handler), and both were green on each side alone.\n *\n * WHAT IT IS NOT. Nothing Bun-specific lives here. The transport is a `fetch`\n * the caller may supply, so this package stays runtime-agnostic and the process\n * that knows which runtime it is decides what to hand in.\n */\n\nimport type { PalbaseResult } from \"../endpoint.js\";\n\n/** Per-request options a module client may pass. */\nexport interface RequestOptions {\n /** JSON-serialised unless it is a string, a Uint8Array, a Blob or FormData. */\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\n/**\n * What a module client is given. An INTERFACE rather than a class, because the\n * clients depend on this shape and not on the thing that implements it — which\n * is what lets a test drive a whole client without a server.\n */\nexport interface ModuleTransport {\n /** The platform's base URL, for the rare client that must build a URL. */\n readonly baseUrl: string;\n request<T = unknown>(\n method: string,\n path: string,\n options?: RequestOptions,\n ): Promise<PalbaseResult<T>>;\n}\n\nexport interface TransportConfig {\n baseUrl: string;\n apiKey: string;\n /**\n * The `fetch` to use. Omitted means the ambient one — resolved at CALL time,\n * never captured here: the egress fence replaces `globalThis.fetch` after the\n * clients are built, and a captured reference would keep calling the\n * un-fenced original.\n */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A module call that failed.\n *\n * `code` is the platform's own error code (`forbidden`, `not_found`, …) so a\n * caller can branch on it without matching message text.\n */\nexport class PalbaseModuleError extends Error {\n readonly code: string;\n readonly status: number;\n readonly details: Record<string, unknown>;\n\n constructor(code: string, message: string, status: number, details: Record<string, unknown> = {}) {\n super(message);\n this.name = \"PalbaseModuleError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function makeHttpClient(cfg: TransportConfig): ModuleTransport {\n async function request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<PalbaseResult<T>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers ?? {}),\n };\n if (cfg.apiKey) headers[\"apikey\"] = cfg.apiKey;\n\n const init: RequestInit = { method, headers };\n if (options.body !== undefined) {\n if (typeof options.body === \"string\" || options.body instanceof Uint8Array) {\n init.body = options.body as RequestInit[\"body\"];\n } else if (typeof FormData !== \"undefined\" && options.body instanceof FormData) {\n // The platform writes Content-Type itself, WITH the multipart boundary.\n // Setting it here omits the boundary, and the server then parses zero\n // parts from a request that looks perfectly well formed.\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else if (typeof Blob !== \"undefined\" && options.body instanceof Blob) {\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else {\n init.body = JSON.stringify(options.body);\n }\n }\n if (options.signal) init.signal = options.signal;\n\n // Resolved HERE, per call. See TransportConfig.fetchImpl.\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n\n let response: Response;\n try {\n response = await doFetch(`${cfg.baseUrl}${path}`, init);\n } catch (err) {\n // AN ENVELOPE, not an exception.\n //\n // This threw until 2026-08-15, and the throw made three separate claims\n // false at once:\n //\n // 1. The package's own rule — \"Response: { data, error }, no thrown API\n // errors\". Every client here is written to that contract.\n // 2. `Flags.get(key, default)`, whose documented behaviour is that the\n // default applies when the flag is absent AND when the service is\n // unreachable. It reads `resp.error !== null` to decide, and a throw\n // never reaches that branch: measured, `get(\"beta\", \"DEFAULT\")`\n // raised `connect ECONNREFUSED` instead of answering \"DEFAULT\". The\n // test that was supposed to cover it handed the client a hand-made\n // error envelope — a shape this code could not produce.\n // 3. Consistency with the Realtime client, which already envelopes a\n // network failure so a handler that wrote a row does not lose it\n // because pubsub was down.\n //\n // A caller destructuring { data, error } and checking `error` was being\n // defeated by an exception: the defensive code existed and did not help,\n // which is the worst kind of surprise to leave in a package.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"Network request failed\",\n 0,\n ),\n status: 0,\n };\n }\n\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n let parsed: unknown = null;\n if (method !== \"HEAD\" && contentType.includes(\"json\")) {\n parsed = await response.json().catch(() => null);\n } else if (method !== \"HEAD\" && contentType.startsWith(\"image/\")) {\n // QR codes and the like: hand back bytes the caller can write or forward.\n parsed = new Uint8Array(await response.arrayBuffer());\n } else if (method !== \"HEAD\" && response.body) {\n // A non-JSON error still says something; \"request failed\" says nothing.\n parsed = await response.text().catch(() => null);\n }\n\n if (!response.ok) {\n const body = (parsed && typeof parsed === \"object\" ? parsed : {}) as Record<string, unknown>;\n const code = typeof body.error === \"string\" && body.error ? body.error : \"unknown_error\";\n const message =\n (typeof body.error_description === \"string\" && body.error_description) ||\n response.statusText ||\n \"request failed\";\n return {\n data: null,\n error: new PalbaseModuleError(code, message, response.status, body),\n status: response.status,\n };\n }\n\n return { data: parsed as T, error: null, status: response.status };\n }\n\n return { baseUrl: cfg.baseUrl, request };\n}\n","/**\n * auth.ts — the role-assignment half of auth, as a backend handler reaches it.\n *\n * WHAT THIS IS NOT. It is not the client SDK's `auth` (sign-up, sign-in, MFA,\n * device attestation): those are a person acting on their OWN account, they run\n * in the app, and a server has no business holding them. This is the operator\n * verb — \"make this user an agent\" — and it exists because the product itself is\n * often where the promotion happens: a supervisor taps a button in the tenant's\n * own app, and the tenant's handler has to be able to write the assignment.\n *\n * THE CREDENTIAL IS THE POINT. `/admin/users/{uid}/roles/{role}` answers 403 to\n * anon and to `authenticated` alike (FR-013), so these calls ride the transport\n * built with the SERVICE-ROLE key. A backend is the only place that key exists;\n * putting this surface anywhere a client SDK could reach it would let an end\n * user grant themselves the permission the rest of the feature is about.\n *\n * IT THROWS, and the rest of this package envelopes. That is a deliberate split\n * and it comes from the SHAPE OF THE ANSWER: `assignRole` returns nothing, so a\n * failure it did not throw for would be indistinguishable from a write that\n * happened. The named `RoleNotDefined` is the one refusal a caller can act on —\n * the role names live in git, so a miss is a typo, not a runtime condition —\n * and every other refusal arrives as the transport's own `PalbaseModuleError`\n * with the platform's code on it.\n */\n\nimport type { PalbaseAuthAdminClient } from \"../clients.js\";\n\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * The named refusal: this stack declares no role by that name.\n *\n * A role's DEFINITION is committed (`palbase roles`, lowered into the generated\n * client as an enum), so a name that misses is a typo in code rather than a\n * state a retry could fix. It carries the name it was asked for, because the\n * message alone would make a handler parse text to log which one failed.\n */\nexport class RoleNotDefined extends Error {\n readonly role: string;\n\n constructor(role: string, message?: string) {\n super(message ?? `No role named \"${role}\" is defined for this stack`);\n this.name = \"RoleNotDefined\";\n this.role = role;\n }\n}\n\n/** The wire body all three routes answer with: the assignment's RESULT. */\ninterface UserRolesBody {\n roles?: string[];\n}\n\n/**\n * Raise whatever the platform refused with.\n *\n * `role_not_defined` becomes the named class; everything else keeps the\n * transport's error, which already carries the platform's code and status, so a\n * caller can branch on `err.code` without matching message text.\n */\nfunction refuse(error: { message?: string; code?: string }, role: string): never {\n if (error.code === \"role_not_defined\") throw new RoleNotDefined(role, error.message);\n if (error instanceof PalbaseModuleError) throw error;\n throw new PalbaseModuleError(error.code ?? \"unknown_error\", error.message ?? \"request failed\", 0);\n}\n\n/** `/admin/users/{uid}/roles[/{role}]`, with both ids escaped: an id that\n * carried a slash would otherwise reach a different route entirely. */\nfunction rolesPath(userId: string, role?: string): string {\n const base = `/admin/users/${encodeURIComponent(userId)}/roles`;\n return role === undefined ? base : `${base}/${encodeURIComponent(role)}`;\n}\n\nexport function buildAuthClient(http: ModuleTransport): PalbaseAuthAdminClient {\n return {\n async assignRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"PUT\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async revokeRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"DELETE\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async rolesOf(userId: string): Promise<string[]> {\n const { data, error } = await http.request<UserRolesBody>(\"GET\", rolesPath(userId));\n // A FAILED READ IS NOT AN EMPTY LIST. Answering `[]` here would tell a\n // handler that a user holds nothing when the truth is that nobody could\n // say — and the handler would then deny them everything they hold.\n if (error) refuse(error, \"\");\n return data?.roles ?? [];\n },\n };\n}\n","/**\n * documents.ts — the Documents client, Firestore-shaped.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:705-773` (plus\n * the `buildDocumentRef` / `buildCollectionRef` helpers above it) with its\n * behaviour intact: the same methods, the same paths, the same bodies. What\n * changed is that it now sits beside the interface it implements, so a drift\n * between the two is a compile error rather than a runtime surprise.\n */\n\nimport type {\n PalbaseCollectionRef,\n PalbaseDocsClient,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseResult,\n PalbaseWhereOperator,\n} from \"../endpoint.js\";\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * A path segment the platform will accept.\n *\n * Validated HERE rather than at the server, because a rejected segment is a\n * programming mistake and the useful moment to hear about it is the call.\n */\nconst SEGMENT_RE = /^[A-Za-z0-9_-]+$/;\n\nfunction validateSegment(segment: string, label: string): void {\n if (!SEGMENT_RE.test(segment)) {\n throw new Error(`Invalid ${label}: \"${segment}\". Must match ${SEGMENT_RE.source}`);\n }\n}\n\ninterface WhereClause {\n field: string;\n op: PalbaseWhereOperator;\n value: unknown;\n}\ninterface OrderClause {\n field: string;\n direction: \"asc\" | \"desc\";\n}\ninterface ChainState {\n where: WhereClause[];\n orderBy: OrderClause[];\n limit?: number;\n}\n\ninterface RawDocument {\n id?: string;\n exists?: boolean;\n data?: Record<string, unknown>;\n}\n\nfunction buildDocumentRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n): PalbaseDocumentRef<T> {\n return {\n path,\n async set(data: T) {\n return http.request<void>(\"PUT\", `/v1/docs/${path}`, { body: data });\n },\n async get(): Promise<PalbaseResult<PalbaseDocumentSnapshot<T>>> {\n const response = await http.request<RawDocument>(\"GET\", `/v1/docs/${path}`);\n if (response.error) return { data: null, error: response.error, status: response.status };\n const raw = response.data ?? {};\n const exists = raw.exists !== undefined ? raw.exists : Boolean(raw.data || raw.id);\n const segments = path.split(\"/\");\n const id = raw.id || segments[segments.length - 1] || \"\";\n return {\n data: { id, exists, data: () => raw.data as T | undefined, ref: { path } },\n error: null,\n status: response.status,\n };\n },\n async update(data: Partial<T>) {\n return http.request<void>(\"PATCH\", `/v1/docs/${path}`, { body: data });\n },\n async delete() {\n return http.request<void>(\"DELETE\", `/v1/docs/${path}`);\n },\n collection<C extends Record<string, unknown>>(name: string): PalbaseCollectionRef<C> {\n validateSegment(name, \"subcollection name\");\n return buildCollectionRef<C>(http, `${path}/${name}`);\n },\n };\n}\n\nfunction buildCollectionRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n state: ChainState = { where: [], orderBy: [] },\n): PalbaseCollectionRef<T> {\n function snapshot(doc: { id: string; data: Record<string, unknown> }): PalbaseDocumentSnapshot<T> {\n return {\n id: doc.id,\n exists: true,\n data: () => doc.data as T,\n ref: { path: `${path}/${doc.id}` },\n };\n }\n\n function querySnapshot(docs: PalbaseDocumentSnapshot<T>[]): PalbaseQuerySnapshot<T> {\n return {\n docs,\n empty: docs.length === 0,\n size: docs.length,\n docChanges: () => docs.map((doc) => ({ type: \"added\" as const, doc })),\n };\n }\n\n return {\n path,\n\n doc(id: string) {\n validateSegment(id, \"document ID\");\n return buildDocumentRef<T>(http, `${path}/${id}`);\n },\n\n async add(data: T) {\n const resp = await http.request<{ id: string }>(\"POST\", `/v1/docs/${path}`, { body: data });\n if (resp.error || !resp.data) {\n return { data: null, error: resp.error, status: resp.status };\n }\n return {\n data: buildDocumentRef<T>(http, `${path}/${resp.data.id}`),\n error: null,\n status: resp.status,\n };\n },\n\n // Each narrowing returns a NEW ref. A builder that mutated in place would\n // leak one caller's filter into a query another caller had already held.\n where(field: string, op: PalbaseWhereOperator, value: unknown) {\n return buildCollectionRef<T>(http, path, {\n ...state,\n where: [...state.where, { field, op, value }],\n });\n },\n orderBy(field: string, direction: \"asc\" | \"desc\" = \"asc\") {\n return buildCollectionRef<T>(http, path, {\n ...state,\n orderBy: [...state.orderBy, { field, direction }],\n });\n },\n limit(n: number) {\n return buildCollectionRef<T>(http, path, { ...state, limit: n });\n },\n\n async get(): Promise<PalbaseResult<PalbaseQuerySnapshot<T>>> {\n const narrowed =\n state.where.length > 0 || state.orderBy.length > 0 || state.limit !== undefined;\n\n const resp = narrowed\n ? await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"POST\",\n `/v1/docs/${path}/query`,\n { body: queryBody(state) },\n )\n : await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"GET\",\n `/v1/docs/${path}`,\n );\n\n if (resp.error) return { data: null, error: resp.error, status: resp.status };\n const docs = (resp.data?.documents ?? []).map(snapshot);\n return { data: querySnapshot(docs), error: null, status: resp.status };\n },\n };\n}\n\nfunction queryBody(state: ChainState): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (state.where.length > 0) {\n body.where = state.where.map((w) => ({ field: w.field, op: w.op, value: w.value }));\n }\n if (state.orderBy.length > 0) {\n body.orderBy = state.orderBy.map((o) => ({ field: o.field, direction: o.direction }));\n }\n if (state.limit !== undefined) body.limit = state.limit;\n return body;\n}\n\n/** The largest batch the platform accepts in one call. */\nconst MAX_BATCH = 500;\n\nexport function buildDocumentsClient(http: ModuleTransport): PalbaseDocsClient {\n return {\n /**\n * `Documents.doc(\"users/alice\")` — segments are collection/documentId PAIRS,\n * so an odd count addresses a COLLECTION and is refused. Accepting it would\n * write a document whose id happens to be a collection's name.\n */\n doc<T extends Record<string, unknown>>(path: string): PalbaseDocumentRef<T> {\n const segments = String(path)\n .split(\"/\")\n .filter((s) => s.length > 0);\n if (segments.length === 0 || segments.length % 2 !== 0) {\n throw new Error(\n `Invalid document path: \"${path}\". Expected collection/documentId pairs, got ${segments.length} segment(s).`,\n );\n }\n segments.forEach((s, i) => validateSegment(s, i % 2 === 0 ? \"collection name\" : \"document ID\"));\n return buildDocumentRef<T>(http, segments.join(\"/\"));\n },\n\n collection<T extends Record<string, unknown>>(name: string): PalbaseCollectionRef<T> {\n validateSegment(name, \"collection name\");\n return buildCollectionRef<T>(http, name);\n },\n\n async batch(operations) {\n // Refused HERE, without a request: the server would refuse it too, and\n // spending a round trip to be told so is the caller's time.\n if (operations.length > MAX_BATCH) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"batch_too_large\",\n `Batch size ${operations.length} exceeds maximum of ${MAX_BATCH}`,\n 400,\n ),\n status: 400,\n };\n }\n if (operations.length === 0) return { data: null, error: null, status: 200 };\n\n return http.request<void>(\"POST\", \"/v1/docs/batch\", {\n body: operations.map((op) => ({ op: op.op, path: op.ref.path, data: op.data })),\n });\n },\n };\n}\n","/**\n * flags.ts — feature flags, resolved for the request's own user.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:941-1164`.\n *\n * THE ONE RULE WORTH STATING: the user a flag resolves for comes from the\n * SDK's own request scope, never from anything the caller passed on the wire.\n * A handler can pass an explicit context (including an explicit `null` for a\n * deliberate anonymous read) and that wins — but the default is the person the\n * request is being served for, which is what makes `Flags.get(\"x\")` mean the\n * obvious thing inside a handler.\n *\n * Writes mirror the Database model: `setOverride` writes for the CURRENT user\n * and needs no admin power; cross-user writes live behind `asService()` so they\n * are explicit and greppable.\n */\n\nimport type {\n PalbaseBatchOverrideOperation,\n PalbaseFlagContext,\n PalbaseFlagValue,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\nconst FLAG_NAME_RE = /^[A-Za-z0-9_.-]+$/;\n\nexport interface FlagsConfig {\n /** The request's user, read from the SDK's ALS box — never from the caller. */\n getCurrentUserId: () => string | null;\n}\n\nfunction assertFlagName(flagName: string): void {\n if (!FLAG_NAME_RE.test(flagName)) {\n throw new Error(`Invalid flag name: \"${flagName}\". Flag names must match ${FLAG_NAME_RE.source}`);\n }\n}\n\n/** A truthy flag value, in the platform's own terms. */\nfunction flagEnabled(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n return value != null && value !== 0 && value !== \"\";\n}\n\nfunction flagVariant(value: unknown): { name: string } | null {\n return typeof value === \"string\" ? { name: value } : null;\n}\n\n/**\n * A context object carries `userId`/`properties`; anything else passed in that\n * position is a DEFAULT VALUE. This is what tells `Flags.get(key, ctx)` apart\n * from `Flags.get(key, someObjectDefault)`.\n */\nfunction isContextObject(v: unknown): v is PalbaseFlagContext {\n return (\n v !== null && typeof v === \"object\" && !Array.isArray(v) && (\"userId\" in v || \"properties\" in v)\n );\n}\n\ninterface MergedSnapshot {\n values?: Record<string, PalbaseFlagValue>;\n}\n\nexport function buildFlagsClient(http: ModuleTransport, cfg: FlagsConfig): PalbaseFlagsClient {\n /**\n * The effective user for a call. An explicit `userId` in the context wins —\n * INCLUDING an explicit `null`, which is a deliberate anonymous read.\n */\n function resolveUserId(context?: PalbaseFlagContext): string | null | undefined {\n if (context && \"userId\" in context) return context.userId ?? null;\n return cfg.getCurrentUserId() || undefined;\n }\n\n function mergedPath(context?: PalbaseFlagContext): string {\n const uid = resolveUserId(context);\n return uid ? `/v1/user-flags/users/${encodeURIComponent(uid)}` : \"/v1/user-flags\";\n }\n\n function fetchMerged(context?: PalbaseFlagContext) {\n return http.request<MergedSnapshot>(\"GET\", mergedPath(context));\n }\n\n const service: PalbaseFlagsServiceClient = {\n async setOverrideForUser(userId, key, value) {\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n async setOverridesForUser(userId, values) {\n return http.request(\"PUT\", `/v1/user-flags/users/${encodeURIComponent(userId)}`, {\n body: { values },\n });\n },\n async clearOverrideForUser(userId, key) {\n return http.request(\n \"DELETE\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n );\n },\n async clearAllOverridesForUser(userId) {\n return http.request(\"DELETE\", `/v1/user-flags/users/${encodeURIComponent(userId)}`);\n },\n async batchSetOverrides(operations: ReadonlyArray<PalbaseBatchOverrideOperation>) {\n // The argument is camelCase, the wire is snake_case. Mapped here so a\n // stray `userId` never reaches the server — and an explicit `user_id`, if\n // a caller already wrote one, is preserved.\n const ops = (operations ?? []).map((op) => {\n const raw = op as unknown as { userId?: string; user_id?: string; values: unknown };\n return { user_id: raw.userId ?? raw.user_id, values: raw.values };\n });\n return http.request(\"POST\", \"/v1/user-flags/batch\", { body: { operations: ops } });\n },\n };\n\n return {\n async isEnabled(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagEnabled(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n async getVariant(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n // A missing or non-string value is a NULL variant on a successful read;\n // errors and empty bodies pass through as null too, which is why this is\n // written out rather than mapped.\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagVariant(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n /**\n * `get(key)` · `get(key, default)` · `get(key, default, ctx)` · `get(key, ctx)`.\n *\n * The default is substituted when the flag is ABSENT or when the flags\n * service is unreachable — a product that hides a feature because a lookup\n * timed out is behaving correctly; one that crashes is not.\n */\n async get(\n flagName: string,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n assertFlagName(flagName);\n\n let defaultValue: PalbaseFlagValue | undefined;\n let context: PalbaseFlagContext | undefined;\n let hasDefault = false;\n if (maybeContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n context = maybeContext;\n } else if (isContextObject(defaultOrContext)) {\n context = defaultOrContext;\n } else if (defaultOrContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n }\n\n const resp = await fetchMerged(context);\n if (resp.error !== null) {\n if (hasDefault) return { data: defaultValue ?? null, error: null, status: resp.status };\n return { data: null, error: resp.error, status: resp.status };\n }\n const values = resp.data?.values ?? {};\n const value = values[flagName];\n // An absent key on a SUCCESSFUL read is not an error.\n if (value === undefined) {\n return { data: hasDefault ? (defaultValue ?? null) : null, error: null, status: resp.status };\n }\n return { data: value, error: null, status: resp.status };\n },\n\n async getAll(context?: PalbaseFlagContext) {\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n const values = res.data.values ?? {};\n return {\n data: Object.keys(values).map((name) => {\n const value = values[name];\n const flag: { name: string; enabled: boolean; variant?: { name: string } } = {\n name,\n enabled: flagEnabled(value),\n };\n if (typeof value === \"string\") flag.variant = { name: value };\n return flag;\n }),\n error: null,\n status: res.status,\n };\n },\n\n /**\n * Override a flag for the CURRENT request user.\n *\n * On an anonymous request this does not silently no-op and does not write\n * for nobody: it refuses and names the call that does cross-user writes.\n */\n async setOverride(key: string, value: PalbaseFlagValue) {\n const uid = cfg.getCurrentUserId();\n if (!uid) {\n return {\n data: null,\n error: {\n message:\n \"setOverride requires a signed-in user; use Flags.$asService().setOverrideForUser(userId, key, value) for cross-user writes\",\n },\n status: 400,\n };\n }\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(uid)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n\n asService() {\n return service;\n },\n };\n}\n","/**\n * notifications.ts — push, email, SMS, verifications, inbox, preferences and\n * the two template surfaces.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:1180-1379`.\n *\n * The theme of this file is a NAME GAP: the SDK speaks camelCase and palnotify\n * speaks snake_case, and every place they meet is a place a field can be\n * dropped in silence. One of them cost a live afternoon — `email.send({ html })`\n * was forwarded verbatim, palnotify reads `html_body`, and the answer was a 400\n * about a field the caller had supplied. The mappings below are that lesson,\n * and they are now checked against the declared parameter types instead of\n * being hand-carried across a package boundary.\n */\n\nimport type {\n PalbaseEmailClient,\n PalbaseEmailTemplate,\n PalbaseEmailTemplatesClient,\n PalbaseInboxClient,\n PalbaseNotificationsClient,\n PalbasePreferencesClient,\n PalbasePushClient,\n PalbaseSMSTemplate,\n PalbaseSMSTemplatesClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseVerificationsClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** Re-map the data of a SUCCESSFUL envelope; errors pass through untouched. */\nfunction mapEnvelope<In, Out>(res: PalbaseResult<In>, map: (data: In) => Out): PalbaseResult<Out> {\n if (res.error !== null || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\ntype Wire = Record<string, unknown>;\n\nfunction toEmailTemplate(wire: Wire): PalbaseEmailTemplate {\n const view: PalbaseEmailTemplate = {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n subject: wire.subject as string,\n htmlBody: wire.html_body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n if (wire.text_body !== undefined) view.textBody = wire.text_body as string;\n return view;\n}\n\nfunction toSmsTemplate(wire: Wire): PalbaseSMSTemplate {\n return {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n body: wire.body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n}\n\nexport function buildNotificationsClient(http: ModuleTransport): PalbaseNotificationsClient {\n const push: PalbasePushClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/push\", { body: params });\n },\n };\n\n const email: PalbaseEmailClient = {\n async send(params) {\n // `html`/`text` are what the SDK declares; palnotify reads\n // `html_body`/`text_body`. Forwarding them verbatim answered 400 about a\n // field the caller HAD supplied — live on todoapp, 2026-07-30.\n const { templateSlug, html, text, ...rest } = params;\n const body: Record<string, unknown> = { ...rest };\n if (templateSlug !== undefined) body.template_slug = templateSlug;\n if (html !== undefined) body.html_body = html;\n if (text !== undefined) body.text_body = text;\n return http.request(\"POST\", \"/v1/notifications/email\", { body });\n },\n };\n\n const sms: PalbaseSmsClient = {\n async send(params) {\n const { templateSlug, ...rest } = params;\n const body = templateSlug !== undefined ? { ...rest, template_slug: templateSlug } : rest;\n return http.request(\"POST\", \"/v1/notifications/sms\", { body });\n },\n };\n\n const whatsapp: PalbaseWhatsAppClient = {\n async send(params) {\n const { templateSlug, userId, ...rest } = params;\n const body = {\n ...rest,\n ...(templateSlug === undefined ? {} : { template_slug: templateSlug }),\n ...(userId === undefined ? {} : { user_id: userId }),\n };\n return http.request(\"POST\", \"/v1/notifications/whatsapp\", { body });\n },\n async events(options = {}) {\n const query = options.limit === undefined ? \"\" : `?limit=${encodeURIComponent(String(options.limit))}`;\n return http.request(\"GET\", `/v1/notifications/whatsapp/events${query}`);\n },\n };\n\n // Phone verification (OTP). Separate from sms.send on purpose: there is no\n // body here — the provider generates the code and the message text itself.\n const verifications: PalbaseVerificationsClient = {\n async start(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications\", { body: params });\n },\n async check(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications/check\", { body: params });\n },\n };\n\n const inbox: PalbaseInboxClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/inbox\", { body: params });\n },\n async list(options?: {\n cursor?: string;\n limit?: number;\n is_read?: boolean;\n category?: string;\n include_archived?: boolean;\n }) {\n const opts = options ?? {};\n const params = new URLSearchParams();\n if (opts.cursor) params.set(\"cursor\", opts.cursor);\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n if (opts.is_read !== undefined) params.set(\"is_read\", opts.is_read ? \"true\" : \"false\");\n if (opts.category) params.set(\"category\", opts.category);\n if (opts.include_archived) params.set(\"include_archived\", \"true\");\n const query = params.toString();\n return http.request(\"GET\", `/v1/notifications/inbox${query ? `?${query}` : \"\"}`);\n },\n async unreadCount() {\n return http.request(\"GET\", \"/v1/notifications/inbox/unread-count\");\n },\n async markRead(id: string) {\n return http.request(\"PATCH\", `/v1/notifications/inbox/${encodeURIComponent(id)}/read`);\n },\n async markAllRead() {\n return http.request(\"POST\", \"/v1/notifications/inbox/read-all\");\n },\n async archive(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/inbox/${encodeURIComponent(id)}`);\n },\n };\n\n const preferences: PalbasePreferencesClient = {\n async get() {\n return http.request(\"GET\", \"/v1/notifications/preferences\");\n },\n async update(params) {\n return http.request(\"PUT\", \"/v1/notifications/preferences\", { body: params });\n },\n };\n\n const emailTemplates: PalbaseEmailTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toEmailTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async create(input: { slug: string; subject: string; htmlBody: string; textBody?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {\n slug: input.slug,\n subject: input.subject,\n html_body: input.htmlBody,\n };\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/templates\", { body });\n return mapEnvelope(resp, toEmailTemplate);\n },\n async update(\n id: string,\n input: { subject?: string; htmlBody?: string; textBody?: string; variables?: string[] },\n ) {\n const body: Record<string, unknown> = {};\n if (input.subject !== undefined) body.subject = input.subject;\n if (input.htmlBody !== undefined) body.html_body = input.htmlBody;\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/templates/${encodeURIComponent(id)}`);\n },\n };\n\n const smsTemplates: PalbaseSMSTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/sms-templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toSmsTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async create(input: { slug: string; body: string; variables?: string[] }) {\n const body: Record<string, unknown> = { slug: input.slug, body: input.body };\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/sms-templates\", { body });\n return mapEnvelope(resp, toSmsTemplate);\n },\n async update(id: string, input: { body?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {};\n if (input.body !== undefined) body.body = input.body;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/sms-templates/${encodeURIComponent(id)}`);\n },\n };\n\n return {\n push,\n email,\n sms,\n whatsapp,\n verifications,\n inbox,\n preferences,\n templates: { email: emailTemplates, sms: smsTemplates },\n async registerDevice(params) {\n return http.request(\"POST\", \"/v1/notifications/devices\", { body: params });\n },\n async unregisterDevice(deviceId: string) {\n return http.request(\"DELETE\", `/v1/notifications/devices/${encodeURIComponent(deviceId)}`);\n },\n };\n}\n","/**\n * realtime.ts — broadcast, and only broadcast.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:811-883`.\n *\n * There is no `subscribe()` here, deliberately: a backend handler answers one\n * request and ends, so there is no honest place to hold a long-lived socket.\n * Subscription lives in the client SDKs; this side pushes.\n *\n * The V1 host/executor branch is GONE. It existed so an isolate could delegate\n * the secret-bearing token mint to a host that held the credential — and the\n * isolate was removed on 2026-08-14. A single-tenant process has nobody to hide\n * its own tenant's key from.\n */\n\nimport { createHmac } from \"node:crypto\";\n\nimport type { PalbaseRealtimeClient } from \"../clients.js\";\nimport { PalbaseModuleError } from \"./http.js\";\n\nexport interface RealtimeConfig {\n baseUrl: string;\n /**\n * The shared Realtime API secret. Empty means realtime is not provisioned for\n * this environment, and broadcast says so by name rather than failing oddly.\n */\n apiJwtSecret: string;\n /** Resolved at CALL time — see the note in http.ts. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A short-lived HS256 token Realtime's broadcast pipeline accepts.\n *\n * It needs a valid signature and a future `exp`, nothing more — this is a\n * service-to-service hop inside the stack, not a user session.\n */\nfunction mintToken(secret: string): string {\n const now = Math.floor(Date.now() / 1000);\n const header = Buffer.from(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" })).toString(\"base64url\");\n const payload = Buffer.from(\n JSON.stringify({ iss: \"backend-runtime\", role: \"service_role\", iat: now, exp: now + 60 }),\n ).toString(\"base64url\");\n const sig = createHmac(\"sha256\", secret).update(`${header}.${payload}`).digest(\"base64url\");\n return `${header}.${payload}.${sig}`;\n}\n\nexport function buildRealtimeClient(cfg: RealtimeConfig): PalbaseRealtimeClient {\n const url = `${cfg.baseUrl}/realtime/api/broadcast`;\n const stateUrl = `${cfg.baseUrl}/realtime/api/state`;\n\n /** One state write or clear. Same credential, same fire-and-forget contract\n * as broadcast: a handler that wrote a row must not lose it because the\n * pubsub layer was unreachable. */\n async function writeState(\n topic: string,\n key: string,\n value: Record<string, unknown> | undefined,\n del: boolean,\n ) {\n if (typeof topic !== \"string\" || topic.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"topic must be a non-empty string\", 400),\n };\n }\n if (typeof key !== \"string\" || key.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"key must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.state is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n const op = del ? { topic, key, del: true } : { topic, key, value: value ?? {} };\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(stateUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify({ ops: [op] }),\n });\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"state request failed\",\n 0,\n ),\n };\n }\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_state_failed\",\n `realtime state write returned ${response.status}${detail ? `: ${detail}` : \"\"}`,\n response.status,\n ),\n };\n }\n\n return {\n state: {\n /** Write one DURABLE entry on a channel's shared state.\n *\n * The difference from broadcast is WHO it reaches: a broadcast reaches\n * whoever is listening at that instant, while state is also handed to\n * whoever joins afterwards. \"This value is now X\" wants the second — a\n * client connecting a second later should not have to wait for the next\n * change to learn X. */\n set: (topic: string, key: string, value: Record<string, unknown>) =>\n writeState(topic, key, value, false),\n /** Remove one entry. */\n clear: (topic: string, key: string) => writeState(topic, key, undefined, true),\n },\n\n async broadcast(channel: string, event: string, payload?: Record<string, unknown>) {\n // Cheap argument checks first, locally: a bad call gets an answer without\n // spending a round trip to be told the obvious.\n if (typeof channel !== \"string\" || channel.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"channel must be a non-empty string\", 400),\n };\n }\n if (typeof event !== \"string\" || event.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"event must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.broadcast is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n // The BARE sub-topic. Realtime prepends \"realtime:\" on delivery, and a\n // pre-prefixed topic double-prefixes and is silently dropped — proven live.\n const body = JSON.stringify({\n messages: [{ topic: channel, event, payload: payload ?? {}, private: false }],\n });\n\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body,\n });\n } catch (err) {\n // FIRE AND FORGET: a handler that wrote a row and then broadcast must\n // not lose the row because the pubsub layer was unreachable. This is the\n // one client that answers with an envelope on a network failure rather\n // than throwing, and it is why.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"broadcast request failed\",\n 0,\n ),\n };\n }\n\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_broadcast_failed\",\n `broadcast returned ${response.status}: ${detail.slice(0, 200)}`,\n response.status,\n ),\n };\n },\n };\n}\n","/**\n * storage.ts — the Storage client.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:474-589`. That\n * code addressed the native Supabase Storage wire under `/storage/v1` until\n * 2026-08-15, when it was repointed at this stack's own module — measured\n * against the live stack, where the old path answers 404 and the new one 200.\n * It arrives here so the SHAPE it returns and the type that declares that shape\n * are checked against each other: they were not, and the type spent a major\n * version describing another server's columns.\n */\n\nimport type {\n PalbaseBucketClient,\n PalbaseFileObject,\n PalbaseListOptions,\n PalbaseSignedUrlResponse,\n PalbaseStorageClient,\n PalbaseUploadOptions,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** What the platform accepts as a bucket name (schema: `^[a-z][a-z0-9-]{1,62}$`). */\nconst BUCKET_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n/** What the platform accepts as an object path. */\nconst STORAGE_PATH_RE = /^[a-zA-Z0-9_./-]+$/;\nconst STORAGE_TRAVERSAL_RE = /(?:^|\\/)\\.\\.(?:\\/|$)/;\n\n/**\n * Refused HERE, before any request.\n *\n * A traversing path is a programming mistake, and the useful moment to hear\n * about it is the call that made it — not a 400 three layers away.\n */\nfunction validateStoragePath(p: string): void {\n if (!STORAGE_PATH_RE.test(p) || STORAGE_TRAVERSAL_RE.test(p)) {\n throw new Error(\n `Invalid file path: \"${p}\". Paths must not contain traversal sequences and must match ${STORAGE_PATH_RE.source}`,\n );\n }\n}\n\n/**\n * The wire's own shape, mapped onto what this package declares.\n *\n * v2's storage answers in camelCase with the variants and the thumbhash already\n * in it, so this maps rather than translates. The snake_case unwrapping that\n * used to live here (`metadata.mimetype`, `bucket_id`, `created_at`) belonged to\n * a different server, and reading those names off this wire produced an object\n * whose size was 0 and whose content type was \"\".\n */\nfunction toFileObject(bucket: string, row: Record<string, unknown>): PalbaseFileObject {\n return {\n name: (row.path as string) ?? \"\",\n path: (row.path as string) ?? \"\",\n bucket: (row.bucket as string) ?? bucket,\n size: typeof row.size === \"number\" ? row.size : 0,\n contentType: (row.contentType as string) ?? \"\",\n checksum: (row.checksum as string) ?? \"\",\n width: row.width as number | undefined,\n height: row.height as number | undefined,\n thumbhash: row.thumbhash as string | undefined,\n variants: (row.variants as Record<string, string>) ?? {},\n };\n}\n\n/** Re-map the data of a SUCCESSFUL envelope; pass errors through untouched. */\nfunction mapResponse<In, Out>(\n res: PalbaseResult<In>,\n map: (data: In) => Out,\n): PalbaseResult<Out> {\n if (res.error || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\nfunction buildBucketClient(\n http: ModuleTransport,\n bucketName: string,\n publicOrigin: string,\n): PalbaseBucketClient {\n const objectPath = (path: string) => `/v1/storage/object/${bucketName}/${path}`;\n\n return {\n async upload(path, file, options?: PalbaseUploadOptions) {\n validateStoragePath(path);\n const headers: Record<string, string> = {\n \"Content-Type\": options?.contentType ?? \"application/octet-stream\",\n };\n if (options?.upsert) headers[\"x-upsert\"] = \"true\";\n // The BYTES, as the body. Storage sniffs the content and decides for\n // itself what this is; the declared type is a hint it may overrule,\n // because a name and a header are both things a caller can be wrong about.\n const body = file instanceof ArrayBuffer ? new Uint8Array(file) : file;\n const res = await http.request<Record<string, unknown>>(\"PUT\", objectPath(path), {\n body,\n headers,\n });\n return mapResponse(res, (r) => toFileObject(bucketName, r ?? {}));\n },\n\n async download(path) {\n validateStoragePath(path);\n // The AUTHENTICATED read: the project already holds a credential this\n // stack verified, so it does not have to mint a signature to open its own\n // object — and this route serves private buckets, which the public one\n // refuses on purpose.\n return http.request<Blob>(\"GET\", objectPath(path), { headers: { Accept: \"*/*\" } });\n },\n\n getPublicUrl(path, options) {\n validateStoragePath(path);\n const variant = options?.variant ? `?variant=${encodeURIComponent(options.variant)}` : \"\";\n // ABSOLUTE — and the origin is a value the stack is TOLD, not the\n // transport's baseUrl.\n //\n // Those are two different addresses and conflating them is how this broke\n // once already: the transport points at palsvc over the loopback\n // (`http://127.0.0.1:8080`), and a URL built from it resolves nowhere\n // outside the pod. So this used to return the path alone.\n //\n // The path alone is not a smaller answer, it is a wrong one. A public URL\n // LEAVES the response body — into an <img>, an email, another app on\n // another host — and none of those have a base to resolve it against.\n // Measured live 24.08.2026: an iOS client handed the returned\n // `/v1/files/post-images/…` straight to URLSession and got\n // NSURLErrorUnsupportedURL (-1002). The upload had worked; only the URL\n // was unusable.\n //\n // `PALBASE_PUBLIC_ORIGIN` is set by whoever publishes the stack, because\n // only they know it: in the cloud the operator writes\n // `https://<ref>.<domain>`, and a self-hosted stack carries whatever\n // domain its certificate is for.\n if (!publicOrigin) {\n // NAMED, not silent — the same doctrine as the other unconfigured\n // modules in engine/config.ts (\"throw a named error on first use rather\n // than silently no-op\"). A returned path would pass every test here and\n // fail in the one place nobody is watching.\n throw new Error(\n `Storage.bucket(\"${bucketName}\").getPublicUrl() needs this stack's public origin, ` +\n \"and it was not configured. Set PALBASE_PUBLIC_ORIGIN to the address clients reach \" +\n \"this stack at (e.g. https://myproject.palbase.studio).\",\n );\n }\n return `${publicOrigin}/v1/files/${bucketName}/${path}${variant}`;\n },\n\n async createSignedUrl(path, options): Promise<PalbaseResult<PalbaseSignedUrlResponse>> {\n validateStoragePath(path);\n // A DURATION — `{ expiresIn: \"1h\" }`. A bare number is ambiguous between\n // seconds and minutes at every call site that reads it, and the ambiguity\n // is only discovered when a link outlives the object it opened.\n return http.request<PalbaseSignedUrlResponse>(\"POST\", `/v1/storage/sign/${bucketName}/${path}`, {\n body: { expiresIn: options.expiresIn },\n });\n },\n\n async list(prefix?: string, options?: PalbaseListOptions) {\n if (prefix) validateStoragePath(prefix);\n const params = new URLSearchParams();\n if (prefix) params.set(\"prefix\", prefix);\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n const query = params.toString();\n const res = await http.request<{ objects?: Record<string, unknown>[] }>(\n \"GET\",\n `/v1/storage/bucket/${bucketName}${query ? `?${query}` : \"\"}`,\n );\n // `{objects: [...]}`, not a bare array: the envelope leaves room for the\n // paging this will grow, and unwrapping it here keeps that off callers.\n return mapResponse(res, (body) => (body?.objects ?? []).map((row) => toFileObject(bucketName, row)));\n },\n\n async remove(paths) {\n for (const p of paths) validateStoragePath(p);\n // One request per object: the module deletes an object WITH its variants,\n // and a batch endpoint reporting partial success would need a result shape\n // nobody would read. The first refusal ends it — continuing would report a\n // partial delete as a whole one.\n const removed: PalbaseFileObject[] = [];\n for (const p of paths) {\n const res = await http.request<void>(\"DELETE\", objectPath(p));\n if (res.error) return { data: null, error: res.error, status: res.status };\n removed.push(toFileObject(bucketName, { path: p }));\n }\n return { data: removed, error: null, status: 200 };\n },\n\n async move(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/move/${bucketName}`, { body: { from, to } });\n },\n\n async copy(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/copy/${bucketName}`, { body: { from, to } });\n },\n };\n}\n\n/**\n * @param publicOrigin the address CLIENTS reach this stack at — never the\n * transport's base, which is this process's internal route to palsvc. Empty\n * means it was not configured, and `getPublicUrl` refuses by name.\n */\nexport function buildStorageClient(\n http: ModuleTransport,\n publicOrigin: string,\n): PalbaseStorageClient {\n return {\n bucket(name: string) {\n if (!BUCKET_NAME_RE.test(name)) {\n throw new Error(`Invalid bucket name: \"${name}\". Bucket names must match ${BUCKET_NAME_RE.source}`);\n }\n // Sondaki eğik çizgi BURADA kırpılır: `${origin}/v1/files/...` iki\n // eğik çizgiyle biten bir yol üretirdi ve bazı sunucular onu ayrı bir\n // nesne sayar.\n return buildBucketClient(http, name, publicOrigin.replace(/\\/+$/, \"\"));\n },\n };\n}\n","/**\n * clients/index.ts — the composition root for the module clients.\n *\n * This is what the process calls once at boot. It builds the five clients the\n * engine injects and nothing else.\n *\n * WHAT IS NOT BUILT HERE, and why each one is absent rather than forgotten:\n *\n * - `functions`, `analytics`, `links` — the SDK exports no singleton for any\n * of them, so no handler could reach them. They were constructed on every\n * boot and thrown away. `auth` was in this list until roles arrived: the\n * sign-in half still belongs to the client SDK, but the ASSIGNMENT half is\n * an operator verb a handler has to be able to call, so `Auth` is built\n * above — as `PalbaseAuthAdminClient`, three methods and no more.\n * - `Purchases` — its client talked to palstore, and v2 contains no palstore\n * at all. The surface was unbacked before it was untyped. Dropped from v2\n * by the user's decision on 2026-08-15, with the SDK's `src/purchases/`\n * tree left in place because that decision was \"deferred, not silently\n * taken\". It is taken now: the tree is GONE (2026-08-29), because a\n * decorator standing in front of a service nothing serves is the same\n * defect as `Resource` and `config/*`, which went with it.\n * - The V1 host/executor transport — the isolate it existed for was removed\n * on 2026-08-14. A single-tenant process has nobody to hide its own\n * tenant's credentials from.\n */\n\nimport type { ModuleClients } from \"../engine/index.js\";\nimport { buildAuthClient } from \"./auth.js\";\nimport { buildDocumentsClient } from \"./documents.js\";\nimport { buildFlagsClient } from \"./flags.js\";\nimport { makeHttpClient } from \"./http.js\";\nimport { buildNotificationsClient } from \"./notifications.js\";\nimport { buildRealtimeClient } from \"./realtime.js\";\nimport { buildStorageClient } from \"./storage.js\";\n\nexport interface ModuleClientsConfig {\n /** Where the platform answers. Empty means \"not configured\" — see below. */\n baseUrl: string;\n /** The publishable key. Used only when no service-role key is supplied. */\n apiKey: string;\n /**\n * The service-role key, which is what a backend actually holds. Preferred\n * over `apiKey`: this process IS the project's server.\n */\n serviceRoleKey: string;\n /** The shared Realtime secret. Empty means realtime is not provisioned. */\n realtimeApiJwtSecret: string;\n /**\n * The address CLIENTS reach this stack at. Used ONLY to build public object\n * URLs; every request this bundle makes still goes over `baseUrl`.\n */\n publicOrigin: string;\n /** The request's user, read from the SDK's own scope — never from a caller. */\n getCurrentUserId: () => string | null;\n /** Injected in tests; resolved at call time in production. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Build the module clients.\n *\n * Returns an EMPTY bundle when there is no base URL, deliberately: the engine\n * then injects its named stubs, so a handler that reaches for `Storage` gets an\n * error saying which module is unconfigured rather than a crash reading a\n * property of undefined. Booting is not blocked — a project that never touches\n * a module runs fine without one.\n */\nexport function buildModuleClients(cfg: ModuleClientsConfig): ModuleClients {\n const baseUrl = (cfg.baseUrl || \"\").replace(/\\/+$/, \"\");\n if (!baseUrl) return {};\n\n // The service-role key when present: this process is the project's own\n // server, and the publishable key would refuse half of what it needs.\n const apiKey = cfg.serviceRoleKey || cfg.apiKey || \"\";\n const http = makeHttpClient({ baseUrl, apiKey, fetchImpl: cfg.fetchImpl });\n\n return {\n // The ROLE half of auth only (`clients/auth.ts` says why the rest is not\n // here). It rides the same service-role transport, which is exactly the\n // credential the assignment routes demand.\n Auth: buildAuthClient(http),\n Documents: buildDocumentsClient(http),\n Storage: buildStorageClient(http, cfg.publicOrigin),\n Notifications: buildNotificationsClient(http),\n Flags: buildFlagsClient(http, { getCurrentUserId: cfg.getCurrentUserId }),\n Realtime: buildRealtimeClient({\n baseUrl,\n apiJwtSecret: cfg.realtimeApiJwtSecret,\n fetchImpl: cfg.fetchImpl,\n }),\n };\n}\n","import { z } from \"zod\";\nimport { TABLE_META } from \"./schema.js\";\nimport { REF_TARGET } from \"./foreign-key.js\";\nimport type { ColumnMap, TableDef, TableHandle } from \"./schema.js\";\n\n/**\n * policy.ts — the RLS policy authoring DSL.\n *\n * `policy(name)` returns a fluent builder that mirrors the `ColumnBuilder`\n * style in columns.ts: each chainable method mutates the underlying\n * definition and returns the builder so calls compose. The terminal value is\n * a plain {@link PolicyDef} — the exact JSON shape the runtime's\n * `schema_extract.js` reads off the bundled module and the Go side parses into\n * `PolicyJSON` (CONTRACT-POLICY).\n *\n * @example\n * import { policy } from \"@palbase/backend\";\n *\n * policy(\"owner_select\")\n * .for(\"select\")\n * .to(\"authenticated\")\n * .using(\"owner = (select auth.uid())\");\n */\n\n\n// ---------------------------------------------------------------------------\n// C-4 — politika ifadesinin YAPISI (FR-022). SÖZLEŞME BURADA DONAR.\n//\n// T016 (`existsIn`), T027 (Go emitter) ve T028 (korelasyonlu EXISTS) bu tipi\n// tüketir; şekli değiştirmek üç tarafı birden kırar.\n//\n// NEDEN string değil de yapı: bir string ifadeyi ne TypeScript ne Go okuyabilir.\n// Kolon adı yanlışsa hata `CREATE POLICY` anında Postgres'ten gelir — deploy\n// sırasında, yazma anında değil. Dahası InitPlan sarmalaması (`auth.uid()` →\n// `(select auth.uid())`, satır başına bir kez yerine statement başına bir kez)\n// ve `TO <rol>` daraltması ancak yapı üstünde GÜVENLE verilebilir; string\n// üzerinde regex'le yapmak, yorum içindeki bir `auth.uid()`'yi de sarmalar.\n// ---------------------------------------------------------------------------\n\n/** Politika ifadesinin düğümleri. DÜZ VERİ: tele bu şekilde gider. */\nexport type PolicyExpr =\n | {\n kind: \"col\";\n name: string;\n /**\n * Hangi tablonun kolonu (FR-023). Yoksa POLİTİKANIN KENDİ tablosu —\n * Postgres politika ifadesinde onu niteliksiz çözer. Doluysa bir\n * `existsIn` alt-sorgusunun takma adı.\n *\n * Bu ayrım korelasyonun tamamı: ayırt edilmezse `team_id = team_id`\n * üretilir, her satır için doğrudur, ve politika HİÇBİR ŞEYİ süzmez —\n * yani tüm belgeler herkese görünür.\n */\n alias?: string;\n }\n | { kind: \"authUid\" }\n | { kind: \"lit\"; value: string | number | boolean | null }\n | { kind: \"binop\"; op: PolicyBinOp; left: PolicyExpr; right: PolicyExpr }\n | { kind: \"and\"; parts: PolicyExpr[] }\n | { kind: \"or\"; parts: PolicyExpr[] }\n | { kind: \"not\"; expr: PolicyExpr }\n | { kind: \"isNull\"; expr: PolicyExpr; negated: boolean }\n | {\n /**\n * Korelasyonlu `EXISTS (SELECT 1 FROM <table> <alias> WHERE <predicate>)`.\n *\n * FR-024 BAĞLAYICI: alt-sorgu DOĞRUDAN üretilir, bir `SECURITY DEFINER`\n * fonksiyona SARILMAZ. Ölçüldü (spec Research Appendix, pg16): doğrudan\n * alt-sorguda hedef tablonun KENDİ RLS'i uygulanıyor — yani sızıntı\n * kanalı yok. Sarmalama ise onu bypass ederdi.\n */\n kind: \"exists\";\n table: string;\n alias: string;\n /**\n * POLİTİKANIN KENDİ tablosunun adı — korelasyonun çalışması için ŞART.\n *\n * ÖLÇÜLDÜ (canlı pg16): alt-sorgu içinde niteliksiz bir kolon adı\n * Postgres tarafından İÇ tabloya çözülüyor. Yani dış kolon niteliksiz\n * bırakılınca `pb_e1.team_id = pb_e1.team_id` üretiliyor — her satır\n * için doğru, ve politika HİÇBİR ŞEYİ süzmüyor: iki farklı kullanıcı\n * da tüm belgeleri gördü. Dış tablo adı burada taşınıyor ki emitter\n * `\"documents\".\"team_id\"` yazabilsin.\n */\n outer: string;\n predicate: PolicyExpr;\n };\n\n/** Karşılaştırma operatörleri. `in` sağ tarafta liste bekler. */\nexport type PolicyBinOp = \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\";\n\n/**\n * Bir ifadenin ETRAFINDAKİ akıcı sarmalayıcı.\n *\n * Düğüm (`expr`) düz veri kalıyor, metotlar sarmalayıcıda yaşıyor: `_def.using`\n * serileştiğinde metotlu bir nesne değil, tam olarak tele gidecek şekil olsun\n * diye. `.using()` sarmalayıcıyı açar.\n */\nexport class PolicyExprRef {\n constructor(readonly expr: PolicyExpr) {}\n\n private bin(op: PolicyBinOp, other: PolicyOperand): PolicyExprRef {\n return new PolicyExprRef({ kind: \"binop\", op, left: this.expr, right: toExpr(other) });\n }\n\n eq(other: PolicyOperand): PolicyExprRef { return this.bin(\"eq\", other); }\n neq(other: PolicyOperand): PolicyExprRef { return this.bin(\"neq\", other); }\n gt(other: PolicyOperand): PolicyExprRef { return this.bin(\"gt\", other); }\n gte(other: PolicyOperand): PolicyExprRef { return this.bin(\"gte\", other); }\n lt(other: PolicyOperand): PolicyExprRef { return this.bin(\"lt\", other); }\n lte(other: PolicyOperand): PolicyExprRef { return this.bin(\"lte\", other); }\n\n /**\n * `IS NULL` / `IS NOT NULL` — `= NULL` SQL'de her zaman UNKNOWN'dır, o yüzden\n * niyet ayrı bir düğümle yazılır. Partial index'in en sık koşulu\n * (`WHERE deleted_at IS NULL`) tam olarak bu.\n */\n isNull(negated = false): PolicyExprRef {\n return new PolicyExprRef({ kind: \"isNull\", expr: this.expr, negated });\n }\n\n and(...others: PolicyExprRef[]): PolicyExprRef {\n return new PolicyExprRef({ kind: \"and\", parts: [this.expr, ...others.map((o) => o.expr)] });\n }\n or(...others: PolicyExprRef[]): PolicyExprRef {\n return new PolicyExprRef({ kind: \"or\", parts: [this.expr, ...others.map((o) => o.expr)] });\n }\n not(): PolicyExprRef {\n return new PolicyExprRef({ kind: \"not\", expr: this.expr });\n }\n}\n\n/**\n * Bir tablonun `existsIn` için ANNOTATION hâli — iki bildirim birbirini\n * başlatırken çıkarım döngüsünü kıran şey.\n *\n * ÖLÇÜLDÜ: `memberships.household_id` `households.id`'ye referans verirken\n * `households`'ın politikası `existsIn(memberships, …)` yazarsa TypeScript\n * ikisini de TS7022 ile `any`'ye düşürüyor. Kesinti sadece hata mesajı değil:\n * `m.col(…)` de `any` olduğu için politika gövdesindeki YANLIŞ YAZILMIŞ bir\n * kolon adı sessizce derleniyor — RLS yolunda fail-open. Aynı ölçümde\n * `existsIn`'in jeneriğini kaldırmak (tamamen jeneriksiz imza dahil) döngüyü\n * KIRMADI: döngü çıkarımdan değil, iki `const`'un birbirini başlatmasından\n * geliyor ve TypeScript'te tek çaresi bir tip annotation'ı.\n *\n * Bu, `references((): AnyColumn => y.id)`'nin tablo düzeyindeki karşılığı — ama\n * `AnyColumn`'dan farklı olarak KOLON ADLARINI SİLMEZ:\n *\n * ```ts\n * const memberships: TableRef<\"id\" | \"household_id\" | \"user_id\", \"memberships\"> =\n * defineTable(\"memberships\", { columns: { … } });\n * ```\n *\n * Adlar `Cols`'ta durduğu için `m.col(\"user\")` hâlâ DERLENMEZ, ve `N` verildiği\n * için tablo `defineSchema` içinde anahtarını kaybetmez. Kolon adlarını silen\n * gevşek bir `AnyTable` KASITLI OLARAK YOK: onu yazan kişi döngüyü susturur ve\n * politikasının kolon denetimini kapattığını fark etmez.\n */\nexport type TableRef<Cols extends string, N extends string = string> =\n TableHandle<Record<Cols, ColumnMap[string]>, N>;\n\n/** `.eq()` gibi metotların sağ tarafı: başka bir ifade ya da düz bir değer. */\nexport type PolicyOperand = PolicyExprRef | string | number | boolean | null;\n\n/**\n * Düz değer LİTERAL olur, kolon referansı OLMAZ.\n *\n * `.eq(\"owner\")` bir string karşılaştırmasıdır — `owner` kolonuna referans\n * değil. İkisi karışırsa politika sessizce yanlış satırları gösterir ve RLS'te\n * bunun adı yetki atlamasıdır. Kolon istiyorsan `p.col(\"owner\")` yazacaksın.\n */\nfunction toExpr(v: PolicyOperand): PolicyExpr {\n return v instanceof PolicyExprRef ? v.expr : { kind: \"lit\", value: v };\n}\n\n/**\n * Politika ifadesi bağlamı — `defineTable`'ın `policies` callback'ine verilir.\n *\n * Kolon adları TABLONUN KENDİ kolonlarıyla sınırlıdır (FR-022). Bu, `policies`\n * bir dizi değil de callback olduğu için mümkün: TypeScript `columns`'tan\n * `C`'yi çıkarıp callback'i onunla bağlamlandırıyor. `policy(\"x\")` tek başına\n * çağrıldığında hangi tabloda olduğunu bilemezdi.\n */\nexport interface PolicyExprCtx<Cols extends string = string> {\n /** Bu tablonun bir kolonu. Bilinmeyen ad DERLENMEZ. */\n col(name: Cols): PolicyExprRef;\n /**\n * \"Bu satırın sahibi olduğum bir takıma ait mi?\" — üyelik tabanlı kiracılık\n * (FR-023), korelasyonlu bir `EXISTS` alt-sorgusu olarak.\n *\n * ```ts\n * policies: (p) => [\n * policy(\"team_read\").for(\"select\").using(\n * p.existsIn(teamMembers, (m) =>\n * m.col(\"team_id\").eq(p.col(\"team_id\"))\n * .and(m.col(\"user_id\").eq(p.auth.uid()))),\n * ),\n * ]\n * ```\n *\n * `m` ÜYELİK tablosunun kolonlarını, `p` bu tablonunkileri verir; ikisi de\n * tipli ve SQL'de farklı nitelenirler. Karışsalardı `team_id = team_id`\n * üretilir ve politika hiçbir şeyi süzmezdi.\n *\n * ÇIKARIM DÖNGÜSÜ: `table` iki bildirim birbirini başlatıyorsa (üyelik tablosu\n * bu tabloya `references` veriyor, bu tablo da ona `existsIn` atıyor) o\n * bildirime {@link TableRef} annotation'ı gerekir — yoksa TypeScript ikisini\n * de TS7022 ile `any`'ye düşürür ve `m.col(…)` sessizce her adı kabul eder.\n *\n * ÖZYİNELEME TUZAĞI: üyelik tablosunun KENDİ politikası `existsIn`\n * KULLANMAZ — `user_id = auth.uid()` yazar. İki tablo birbirini\n * sorgularsa Postgres sorgu anında\n * `infinite recursion detected in policy for relation …` der. Asimetri\n * kasıtlıdır: üyelik tablosu basit olanı alır, diğer her tablo ona\n * alt-sorgu ATAR.\n */\n existsIn<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef,\n ): PolicyExprRef;\n /** Çağıranın kimliği. SQL'e `(select auth.uid())` olarak iner (InitPlan). */\n auth: { uid(): PolicyExprRef };\n /** Düz bir değer — karşılaştırmanın sağ tarafında açıkça literal demek için. */\n lit(v: string | number | boolean | null): PolicyExprRef;\n and(...parts: PolicyExprRef[]): PolicyExprRef;\n or(...parts: PolicyExprRef[]): PolicyExprRef;\n not(part: PolicyExprRef): PolicyExprRef;\n}\n\n/**\n * İfade bağlamını kurar. `defineTable` bunu kendi kolon adlarıyla çağırır;\n * testler ve elle kullanım için de dışa açık.\n */\nexport function exprCtx<Cols extends string = string>(\n _columns?: readonly Cols[],\n depth = 0,\n /**\n * POLİTİKANIN KENDİ tablosu — her derinlikte AYNI kalır.\n *\n * Alt-sorgunun içinde takma adsız duran bir kolon, dış sorgudaki tabloya\n * bağlanmak zorundadır; Go tarafı onu bu adla nitelendiriyor. Değer iç içe\n * geçmede ORTA tablonun adına kayıyordu (`meta.name` aşağı veriliyordu) ve\n * sonuç canlıda `ERROR: missing FROM-clause entry for table \"…\"` oluyordu —\n * yani iç içe `existsIn` içinden politikanın kendi kolonuna erişmek imkânsızdı\n * (nihai inceleme I-1, ölçüldü). Kök tablo aşağı DEĞİŞMEDEN taşınır.\n */\n ownTable = \"\",\n): PolicyExprCtx<Cols> {\n // Takma ad DERİNLİKTEN türetiliyor, bir sayaçtan değil: aynı şema iki kez\n // yüklendiğinde (test, sonra deploy) sayaç farklı değer üretir ve golden\n // çıktı sebepsiz değişirdi. Derinlik ifadenin kendi şeklinden gelir.\n const alias = `pb_e${depth}`;\n return {\n col: (name) =>\n new PolicyExprRef(depth === 0 ? { kind: \"col\", name } : { kind: \"col\", name, alias }),\n auth: { uid: () => new PolicyExprRef({ kind: \"authUid\" }) },\n lit: (v) => new PolicyExprRef({ kind: \"lit\", value: v }),\n and: (...parts) => new PolicyExprRef({ kind: \"and\", parts: parts.map((p) => p.expr) }),\n or: (...parts) => new PolicyExprRef({ kind: \"or\", parts: parts.map((p) => p.expr) }),\n not: (part) => new PolicyExprRef({ kind: \"not\", expr: part.expr }),\n existsIn: (table, predicate) => {\n const meta = (table as { [TABLE_META]: { name: string; columns: ColumnMap } })[TABLE_META];\n const inner = exprCtx(Object.keys(meta.columns), depth + 1, ownTable);\n const node: PolicyExpr = {\n kind: \"exists\",\n table: meta.name,\n alias: `pb_e${depth + 1}`,\n outer: ownTable,\n predicate: predicate(inner as never).expr,\n };\n // Hedefin NESNESİ taşınıyor — bir POLİTİKA için çıplak ad yeterli\n // (`CREATE POLICY` anında çözülür), ama bir GUARD gövdesi ÇALIŞMA ANINDA\n // ayrıştırılıyor ve `SET search_path = pg_catalog, pg_temp` altında\n // niteliksiz ad hiç çözülmüyor (D-012). `resolveReferences` bunu\n // niteliyor; nitelenen şema YANLIŞ olursa hata kullanıcının yazması\n // sırasında gelir.\n Object.defineProperty(node, REF_TARGET, {\n value: meta, enumerable: false, configurable: true,\n });\n return new PolicyExprRef(node);\n },\n };\n}\n\n/** The SQL command a policy applies to. `\"all\"` covers SELECT/INSERT/UPDATE/DELETE. */\nexport type PolicyCommand = \"all\" | \"select\" | \"insert\" | \"update\" | \"delete\";\n\n/** Whether a policy is permissive (OR-combined, the default) or restrictive\n * (AND-combined). Mirrors Postgres `CREATE POLICY ... AS PERMISSIVE|RESTRICTIVE`. */\nexport type PolicyMode = \"permissive\" | \"restrictive\";\n\n/**\n * The compiled, serializable policy definition — the EXACT shape consumed by\n * `schema_extract.js` → Go `PolicyJSON` (CONTRACT-POLICY).\n *\n * - `roles`: the DB roles this policy applies to (`TO` clause). An empty array\n * means the policy applies to PUBLIC (all roles) — the Postgres default.\n * - `using`: the `USING (...)` row-visibility expression, or `null` when none.\n * - `withCheck`: the `WITH CHECK (...)` write-validation expression, or `null`.\n * - `permissive`: `true` for `AS PERMISSIVE` (default), `false` for restrictive.\n */\nexport interface PolicyDef {\n name: string;\n command: PolicyCommand;\n roles: string[];\n /** Yapı (FR-022) ya da ham string (FR-028 kaçış kapağı). */\n using: string | PolicyExpr | null;\n withCheck: string | PolicyExpr | null;\n permissive: boolean;\n}\n\n/**\n * Fluent RLS policy builder.\n *\n * Defaults (documented, applied at construction):\n * - `command`: `\"all\"` — applies to every SQL command unless `.for(...)` narrows it.\n * - `roles`: `[\"authenticated\"]` — the common case is \"rule applies to signed-in\n * users\". Call `.to(...)` to override; pass `.to()` with no roles (or never\n * call it after a reset) to target PUBLIC.\n * - `using` / `withCheck`: `null` — no row filter / write check until set.\n * - `permissive`: `true` — `AS PERMISSIVE` (policies OR together).\n *\n * Each method mutates `_def` in place and returns `this`, so the chain is a\n * single builder instance (no per-call allocation, like a tagged-template\n * compile target). The terminal `PolicyDef` is read directly off `_def` by\n * `schema_extract.js`.\n */\n/** Quote an identifier for the policy expression. Table and column names reach\n * here from the schema author; neither is allowed to become syntax. */\nfunction quote(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Bir politikanın adreslenebileceği Postgres rolleri.\n *\n * Serbest string DEĞİL, çünkü küme SABİT: bunları palbase provision ediyor,\n * kiracı yeni bir PG rolü yaratmıyor. Serbest bırakıldığında `authenitcated`\n * gibi bir harf hatası derlenip migration'a kadar gidiyordu — Drizzle'da da\n * aynı boşluk ölçüldü (`to` tipi `(string & {})`, yazım hatası DDL'e geçiyor).\n *\n * Çalışma anı zaten fail-closed (bilinmeyen rol kapıyı kapatıyor,\n * `session_rls_fail_closed_integration_test.go`); bu, aynı cevabı derleme\n * anına taşıyor.\n *\n * `backend_*` ikizleri elle YAZILMAZ — `NormalizeDeclaredPolicies` onları\n * kendisi ekliyor; yine de kabul ediliyor ki elle yazan kod kırılmasın.\n */\nexport type PolicyRole =\n | \"anon\"\n | \"authenticated\"\n | \"service_role\"\n | \"backend_anon\"\n | \"backend_authenticated\"\n | \"backend_service_role\";\n\nexport class PolicyBuilder {\n readonly _def: PolicyDef;\n\n constructor(name: string) {\n this._def = {\n name,\n command: \"all\",\n roles: [\"authenticated\"],\n using: null,\n withCheck: null,\n permissive: true,\n };\n }\n\n /** Restrict the policy to a single SQL command (default `\"all\"`). */\n for(command: PolicyCommand): this {\n this._def.command = command;\n return this;\n }\n\n /**\n * Set the DB roles the policy applies to (the `TO` clause), replacing any\n * previously-set roles. Call with no arguments to target PUBLIC (all roles).\n *\n * @example\n * policy(\"p\").to(\"authenticated\")\n * policy(\"p\").to(\"authenticated\", \"service_role\")\n * policy(\"p\").to() // PUBLIC\n */\n to(...roles: PolicyRole[]): this {\n this._def.roles = roles;\n return this;\n }\n\n /**\n * `USING (...)` satır görünürlüğü ifadesi.\n *\n * Tercih edilen biçim YAPI'dır (FR-022) — `policies` callback'inin verdiği\n * bağlamla kurulur ve kolon adları derlemede doğrulanır:\n *\n * ```ts\n * policies: (p) => [\n * policy(\"owner_read\").for(\"select\").using(p.col(\"owner\").eq(p.auth.uid())),\n * ]\n * ```\n *\n * Ham string KAÇIŞ KAPAĞI olarak kalır (FR-028): yapının ifade edemediği bir\n * şey gerektiğinde yol kapanmaz. Ama o yolda kolon adı doğrulaması yoktur ve\n * hata deploy anında Postgres'ten gelir.\n */\n using(expr: string | PolicyExprRef): this {\n this._def.using = expr instanceof PolicyExprRef ? expr.expr : expr;\n return this;\n }\n\n /**\n * \"Rows of THIS table whose owner the caller is a member of\" — the membership\n * pattern, written so it cannot recurse.\n *\n * THE TRAP IT EXISTS FOR. Written by hand, membership policies point at each\n * other: `channels` is visible to members, so its policy reads\n * `channel_members`; `channel_members` is visible to members, so its policy\n * reads `channels`. Postgres refuses the pair at query time with `infinite\n * recursion detected in policy for relation ...`, and the error names the\n * relation but not the cycle. The way out is asymmetry — the MEMBERSHIP table\n * is protected by `user_id = auth.uid()` and nothing else, and every other\n * table subqueries INTO it. That shape was in the platform's own schema and\n * written down nowhere; a customer recovered it by reading that schema.\n *\n * `(select auth.uid())` rather than a bare call: the scalar subquery is\n * evaluated ONCE per statement instead of per row.\n *\n * @example\n * // channels: visible to members. The membership table gets the simple one.\n * policy(\"member_read\").for(\"select\").to(\"authenticated\")\n * .memberOf(\"channel_members\", \"channel_id\")\n * // → id IN (SELECT \"channel_id\" FROM \"channel_members\"\n * // WHERE \"user_id\" = (select auth.uid()))\n */\n memberOf(\n membershipTable: string,\n foreignKey: string,\n options: { column?: string; userColumn?: string } = {},\n ): this {\n if (this._def.using !== null) {\n // Silently AND-ing the two would hide whichever the author meant; silently\n // replacing would hide the one they wrote. Neither is a thing to guess.\n throw new Error(\n `policy(${this._def.name}).memberOf(): this policy already has a using() expression. ` +\n \"Write one or the other — memberOf IS the using expression.\",\n );\n }\n const column = options.column ?? \"id\";\n const userColumn = options.userColumn ?? \"user_id\";\n this._def.using =\n `${quote(column)} IN (SELECT ${quote(foreignKey)} FROM ${quote(membershipTable)} ` +\n `WHERE ${quote(userColumn)} = (select auth.uid()))`;\n return this;\n }\n\n /** `WITH CHECK (...)` yazma doğrulaması — `using` ile aynı iki biçim. */\n withCheck(expr: string | PolicyExprRef): this {\n this._def.withCheck = expr instanceof PolicyExprRef ? expr.expr : expr;\n return this;\n }\n\n /** Set the policy mode: `\"permissive\"` (default, OR-combined) or\n * `\"restrictive\"` (AND-combined). */\n as(mode: PolicyMode): this {\n this._def.permissive = mode === \"permissive\";\n return this;\n }\n}\n\n/**\n * Start authoring an RLS policy. Returns a {@link PolicyBuilder}; the resulting\n * `PolicyBuilder` is accepted directly in a table's `policies: [...]` array\n * (its `_def` is read at schema-extract time).\n *\n * @param name The policy name. Palbase reconciliation keys policies by\n * `(table, name)`, so names must be unique per table.\n */\nexport function policy(name: string): PolicyBuilder {\n return new PolicyBuilder(name);\n}\n\n// ---------------------------------------------------------------------------\n// Tipli CHECK (FR-009, FR-010).\n// ---------------------------------------------------------------------------\n\n/**\n * Adlandırılmış bir CHECK kısıtı — telin bugünkü şekli, HARFİYEN.\n *\n * `expr` STRING kalıyor: `TableJSON.checks` bugün de `{ name, expr }[]` ve Go\n * tarafındaki `CheckJSON.Expr` bir string. Tipli `check()` ifadeyi bildirim\n * anında SQL'e derleyip aynı yere koyuyor, yani string dalıyla tipli dal telde\n * AYNI şeye iniyor: `NormalizeDeclaredChecks` ikisini de canlı Postgres'e\n * sorarak kanonikleştiriyor (böylece değişmemiş bir CHECK churn olarak\n * yeniden diff'lenmiyor) ve `schema-json.ts` yeni bir alan taşımıyor.\n */\nexport interface CheckDef {\n name: string;\n /** Derlenmiş SQL. Tipli dalda `check()` üretir, string dalda yazar verir. */\n expr: string;\n}\n\n/**\n * CHECK bağlamı POLİTİKA bağlamından DAR — Postgres'in kendi cümlesiyle:\n *\n * \"CHECK expressions cannot contain subqueries nor refer to variables other\n * than columns of the current row\" — sql-createtable\n *\n * `existsIn` doğrudan bir alt sorgu; `auth.uid()` da SQL'e `(SELECT auth.uid())`\n * olarak iniyor (InitPlan sarmalaması bir tercih değil — çıplak çağrı satır\n * başına yeniden değerlendiriliyor), yani o da alt sorgu. İkisi de BİLDİRİM\n * anında reddediliyor: reddi apply'a bırakmak, migration'ın ortasında\n * Postgres'in \"cannot use subquery in check constraint\" hatasıyla ölmesi\n * demekti — hangi tablo, hangi kısıt demeden.\n *\n * Go tarafındaki ikizi `validateCheckNode` (`policy_expr.go`); orada aynı küme\n * `freeze`'in `when` koşulu için dayatılıyor (generated sütun ifadesi de alt\n * sorgu içeremez).\n */\nfunction assertCheckNode(node: PolicyExpr, name: string): void {\n switch (node.kind) {\n case \"exists\":\n throw new Error(\n `check(${name}): \\`existsIn(...)\\` is a subquery and PostgreSQL forbids subqueries in a CHECK constraint — express a cross-table rule as a composite FOREIGN KEY (foreignKeys), or as a guard.`,\n );\n case \"authUid\":\n throw new Error(\n `check(${name}): \\`auth.uid()\\` renders as a subquery \\`(SELECT auth.uid())\\` and PostgreSQL forbids subqueries in a CHECK constraint — a caller-dependent rule belongs in an RLS policy, not a CHECK.`,\n );\n case \"binop\":\n assertCheckNode(node.left, name);\n assertCheckNode(node.right, name);\n return;\n case \"and\":\n case \"or\":\n for (const part of node.parts) assertCheckNode(part, name);\n return;\n case \"not\":\n case \"isNull\":\n assertCheckNode(node.expr, name);\n return;\n default:\n return;\n }\n}\n\n/** Karşılaştırma operatörlerinin SQL karşılığı — Go'daki `policyBinOps`'un ikizi. */\nconst CHECK_BIN_OPS: Partial<Record<PolicyBinOp, string>> = {\n eq: \"=\",\n neq: \"<>\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/** Literal — `policyLiteralSQL`'in (Go) ikizi. Tırnak KAÇILIR: değer sözdizimi olamaz. */\nfunction literalSQL(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"boolean\") return v ? \"true\" : \"false\";\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n // NaN/Infinity SQL'de bir sayı literali değil; sessizce `NaN` yazmak\n // Postgres'ten sözdizimi hatası getirirdi — deploy anında.\n throw new Error(`check(): ${v} bir SQL sayı literali değil.`);\n }\n return String(v);\n }\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** Doğrulanmış bir CHECK düğümünü SQL'e derler. */\nfunction checkNodeSQL(node: PolicyExpr, name: string): string {\n switch (node.kind) {\n case \"col\":\n // Takma ad YOK: CHECK yalnız GEÇERLİ SATIRIN kolonlarını görebiliyor, ve\n // takma ad ancak bir `exists` alt sorgusunun içinde doğardı — o da yasak.\n return quote(node.name);\n case \"lit\":\n return literalSQL(node.value);\n case \"binop\": {\n const op = CHECK_BIN_OPS[node.op];\n if (op === undefined) {\n throw new Error(`check(${name}): \\`${node.op}\\` bir CHECK ifadesinde desteklenmiyor.`);\n }\n return `(${checkNodeSQL(node.left, name)} ${op} ${checkNodeSQL(node.right, name)})`;\n }\n case \"and\":\n case \"or\": {\n if (node.parts.length === 0) {\n // Boş bir konjonksiyon `true`, boş bir disjonksiyon `false`. Anlamı\n // yazmak, hiçbir şey yazmayıp kısıtı sessizce genişletmekten iyi.\n return node.kind === \"and\" ? \"(true)\" : \"(false)\";\n }\n const joiner = node.kind === \"and\" ? \" AND \" : \" OR \";\n return `(${node.parts.map((p) => checkNodeSQL(p, name)).join(joiner)})`;\n }\n case \"not\":\n return `(NOT ${checkNodeSQL(node.expr, name)})`;\n case \"isNull\":\n return `(${checkNodeSQL(node.expr, name)} IS ${node.negated ? \"NOT NULL\" : \"NULL\"})`;\n default: {\n // `exists`/`authUid` yukarıda reddedildi; buraya düşen, cebre sonradan\n // eklenmiş ve CHECK için sınıflandırılmamış bir düğümdür. REDDEDİLİR:\n // sınıflandıramadığını geçiren bir kapı, kısıtı sessizce zayıflatır.\n const kind = (node as { kind: string }).kind;\n throw new Error(`check(${name}): \\`${kind}\\` düğümü bir CHECK ifadesinde tanınmıyor.`);\n }\n }\n}\n\n/**\n * `check(\"<ad>\", <ifade>)` — TİPLİ CHECK kısıtı (FR-009).\n *\n * İfade POLİTİKA ifade cebirinin ta kendisiyle yazılıyor; bu DSL'de iki ayrı\n * ifade dili olmaması kurulu ilke. Kolon adları `checks` callback'inin verdiği\n * bağlamdan geliyor, yani yanlış yazılmış bir ad DERLENMİYOR — bugün string\n * biçiminde o hata ancak `ALTER TABLE ... ADD CONSTRAINT` anında Postgres'ten\n * geliyor.\n *\n * ```ts\n * defineTable(\"payments\", {\n * columns: { amount: integer().notNull(), currency: text().notNull() },\n * checks: (c) => [\n * check(\"payments_amount_pos\", c.col(\"amount\").gt(0)),\n * check(\"payments_currency_set\", c.col(\"currency\").isNull(true)),\n * ],\n * })\n * ```\n *\n * @param name Kısıtın adı. CHECK'ler ADA göre uzlaştırılıyor (gövde farkı\n * DROP + ADD demek), o yüzden ad tablo başına tekil olmalı.\n */\nexport function check(name: string, expr: PolicyExprRef): CheckDef {\n if (name.trim() === \"\") {\n throw new Error(\"check(): kısıtın adı boş olamaz — CHECK'ler ADA göre uzlaştırılıyor.\");\n }\n assertCheckNode(expr.expr, name);\n return { name, expr: checkNodeSQL(expr.expr, name) };\n}\n\n/**\n * `can` alanının YANIT şeması (FR-004, D-14).\n *\n * Bir satırın `can`'i, tablonun adlandırılmış UPDATE policy'lerinden o satır ve\n * çağıran için `true` dönenlerin adıdır (engine `canColumns`). Yanıt şemaları\n * elle yazılan zod olduğu için (`dto/*.ts`) bu alan OpenAPI'ye ancak buradan\n * girer: `z.object({ …, can: can(transfers) })`. Enum değerleri policy\n * TANIMINDAN gelir — elle yazılan policy adı yoktur; iki codegen (`emitter.ts`\n * enum→union, swiftgen enum→`case`) tipli sabitleri buradan üretir.\n *\n * SÖZLEŞME (FR-005): `can` ARAYÜZ içindir; yetki kararı için kullanılamaz;\n * eksik olabilir (render edilemeyen policy düşer); sunucu her istekte yeniden\n * karar verir. Ham string policy'de kolon adlarını NİTELİKSİZ yazın — motor\n * ifadeyi `t` alias'ı altında seçer, `transfers.status` orada çözülmez; yorum\n * (`--`, `/*`) ve `auth.has_permission(...)`'ın `(select …)` sarmalı olmadan\n * çağrılması da o policy'yi `can`'den düşürür (warn ile). Yalnız `.for(\"update\")`\n * policy'leri `can`'e girer; `.for(\"all\")` UPDATE'i yönetir ama yankılanmaz.\n * `(select …)` sarmalayıcısını motor bir METİN kapısıyla arar (tırnaklı/boşluklu\n * yazımların sonlu olmayan kümesini DOĞRULAMAZ): bir çağrının satır başına\n * koşup koşmadığının ölçümü EXPLAIN ANALYZE'dır ve demo koşusunda (T016)\n * alınır — yavaş bir `can` yanlış değildir, kapı yalnız yaygın yanlışı yakalar.\n * `can` adı rezervedir: `can` kolonu olan tabloda yankı yok (bu fonksiyon fırlatır),\n * `can` adlı ilişki (`can` tablosu, `can_id` FK, `as`/`reverseAs: \"can\"`) ise\n * `defineTable`'da reddedilir.\n * AS RESTRICTIVE policy'ler Postgres'te olduğu gibi her izinli policy'ye AND'lenir;\n * `TO <rol>` listesi oturum rolüyle kapılanır.\n */\nexport function can<C extends ColumnMap>(table: TableDef<C>): z.ZodArray<z.ZodEnum<[string, ...string[]]>> {\n // `defineTable`'ın döndürdüğü tutamaç (kolonlar + sembol) TableDef DEĞİLDİR —\n // `columns` alanı yoktur; şablon bir zamanlar `can(notes)` öğretiyordu (W1 h1-r4 N-13).\n // `undefined`/`null` first, by name: `can(publicSchema.tables.transfers)` with a table the\n // schema does not declare must not die as a TypeError inside the bundle.\n if (table === undefined || table === null) {\n throw new Error(\n \"can(<table>): received \" + String(table) + \" — the schema declares no such table (check the name against db/*.ts; can(publicSchema.tables.<name>))\",\n );\n }\n const def = table as unknown as { name?: unknown; columns?: unknown; policies?: unknown };\n if (typeof def.name !== \"string\" || def.columns === null || typeof def.columns !== \"object\" || !Array.isArray(def.policies)) {\n throw new Error(\n \"can(<table>): expects the schema's table definition — can(publicSchema.tables.notes) — not the defineTable handle (`notes`)\",\n );\n }\n if (Object.prototype.hasOwnProperty.call(table.columns, \"can\")) {\n throw new Error(\n `can(${table.name}): the table declares a column named \"can\", so the row carries that column and no policy echo — rename the column to get can`,\n );\n }\n const rel = reservedCanRelation(table.name, table.columns);\n if (rel !== null) {\n throw new Error(`can(${table.name}): ${rel}`);\n }\n // Motorla aynı süzgeç (59 bayt): tipte/enum'da olup telde hiç gelmeyecek ad olmasın.\n const names = table.policies\n .filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63)\n .map((p) => p.name);\n if (names.length === 0) {\n const all = table.policies.filter((p) => p.command === \"all\").map((p) => p.name);\n const hint = all.length > 0\n ? ` The table's ${all.map((n) => `\"${n}\"`).join(\", \")} ${all.length === 1 ? \"policy is\" : \"policies are\"} for(\"all\") — for(\"all\") governs UPDATE but is not a named update policy and never appears in can.`\n : \"\";\n throw new Error(\n `can(${table.name}): the table declares no update policy — there is nothing a row could echo. ` +\n `Name one with policy(\"<name>\").for(\"update\").using(…) first.${hint}`,\n );\n }\n return z.array(z.enum(names as [string, ...string[]]));\n}\n\n/**\n * `can` bir İLİŞKİ adı olarak da rezervedir: `row.can` literal union'ı ile\n * `relations.can` aynı satırda iki ayrı şey olurdu ve `can(table)` yanıt\n * şemasına koyduğu enum'u çalışma zamanındaki ilişki dizisiyle 500'e çevirirdi\n * (W1 h2-r3 N-2). `defineTable` bunu beyan anında reddeder; burada aynı kural\n * ham `TableDef` için tekrar sorulur. Döneni bir hata cümlesidir, `null` = temiz.\n * Yalnız BU tablonun kendi kolonlarından türeyen adlar görülebilir: tablo adı\n * `can` (ters ilişkinin varsayılan adı) ve `reverseAs: \"can\"` de defineTable'da düşer.\n */\nexport function reservedCanRelation(tableName: string, columns: ColumnMap): string | null {\n if (tableName === \"can\") {\n return `a table named \"can\" would put a relation named \"can\" on every parent it references — rename the table`;\n }\n for (const [col, b] of Object.entries(columns)) {\n const def = (b as { _def: { referencesThunk?: unknown; selfRefColumn?: string; refAs?: string; reverseAs?: string; owns?: boolean } })._def;\n // `selfReferences` de bir ilişki doğurur (`references` şemada sonradan kurulur) — W1 h1-r4 N-10.\n if (def.referencesThunk === undefined && def.selfRefColumn === undefined) continue;\n if (def.reverseAs === \"can\") {\n return `column \"${col}\" names its reverse relation \"can\" — the parent's rows would carry a relation where can is reserved; pick another reverseAs`;\n }\n const forward = def.owns === true ? \"owner\" : (def.refAs ?? (col.endsWith(\"_id\") ? col.slice(0, -3) : col));\n if (forward === \"can\") {\n return `column \"${col}\" would be read as a relation named \"can\" (${def.refAs === undefined ? \"derived from the column name\" : \"its as: option\"}) — can is reserved for the policy echo; rename it`;\n }\n }\n return null;\n}\n","import type { PolicyExpr, PolicyExprRef } from \"./policy.js\";\nimport type { ColumnMap, TableHandle } from \"./schema.js\";\n\n// `schema.ts` bu modülü import ediyor, yani buradan ORAYA bir DEĞER import'u\n// döngü kurardı ve ESM'de biri diğerini `undefined` görürdü. `TABLE_META` zaten\n// `Symbol.for` ile kayıtlı bir global sembol — aynı anahtarı burada da sormak\n// tam olarak aynı sembolü verir ve döngüyü baştan siler. Tip import'u (`type`)\n// derlemede silindiği için döngü yaratmaz.\nconst TABLE_META: typeof import(\"./schema.js\").TABLE_META = Symbol.for(\n \"palbase.table.meta\",\n) as typeof import(\"./schema.js\").TABLE_META;\n\n/**\n * REF_TARGET, bir referansın HEDEF TABLO NESNESİ — serileştirilmez.\n *\n * Hedefin ADI builder anında biliniyor ama ŞEMASI bilinmiyor: şemayı\n * `defineSchema` damgalıyor ve o, `defineTable` callback'lerinden SONRA koşuyor.\n * Bu yüzden nesnenin kendisi taşınıyor ve niteleme `resolveReferences`'ta,\n * kolon başına yolun kullandığı AYNI `declaringSchemaOf` haritasıyla yapılıyor.\n *\n * Sembol anahtar: `JSON.stringify` sembol anahtarlarını atlar, yani wire'a\n * çıkmaz (NFR-006).\n */\nexport const REF_TARGET: unique symbol = Symbol.for(\"palbase.ref.target\");\n\n/** `ON UPDATE` / `ON DELETE` eylemleri — Postgres'in kabul ettiği kapalı küme. */\nexport type FkAction = \"cascade\" | \"restrict\" | \"set null\" | \"set default\" | \"no action\";\n\n/** `MATCH` türü. `partial` Postgres'te HENÜZ uygulanmadı, o yüzden yok. */\nexport type FkMatch = \"simple\" | \"full\";\n\n/** Bir tablo düzeyi FOREIGN KEY bildirimi — C-1/C-2 (FR-001). */\nexport interface ForeignKeyDef {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: FkAction;\n onDelete?: FkAction;\n match?: FkMatch;\n}\n\n/**\n * `foreignKey(\"<ad>\")` — tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY (C-1, FR-001).\n *\n * ```ts\n * foreignKeys: (c) => [\n * foreignKey(\"settlement_entry_household\")\n * .on(c.col(\"household_id\"), c.col(\"entry_id\"))\n * .references(entries, \"household_id\", \"id\")\n * .onDelete(\"cascade\"),\n * ]\n * ```\n *\n * NEDEN KOLON ÜZERİNDEKİ `.references()` YETMİYOR. O tek sütunlu ve tek\n * hedeflidir. Çok kiracılı bütünlüğün istediği şey\n * `FOREIGN KEY (household_id, entry_id) REFERENCES entries (household_id, id)`:\n * çocuğun ebeveyni yalnız var olmakla kalmaz, AYNI KİRACIYA ait olmak\n * zorundadır. Kolon başına model bunu ifade edemez.\n *\n * İki yol BİRBİRİNİ DÜŞÜRMEZ: bu bildirim kendi adıyla izlenir, kolon\n * üzerindekiler `<tablo>_<kolon>_fkey` ile. Aynı tabloda ikisi birden olabilir.\n */\nexport class ForeignKeyBuilder {\n readonly _def: ForeignKeyDef;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"foreignKey(ad): foreign key'in adı boş olamaz — Palbase kısıtları ADA göre uzlaştırır.\",\n );\n }\n this._def = { name, columns: [], refTable: \"\", refColumns: [] };\n }\n\n /** Yerel sütunlar. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */\n on(...cols: PolicyExprRef[]): this {\n this._def.columns = cols.map((c) => {\n const e = c.expr;\n if (e.kind !== \"col\") {\n throw new Error(\n `foreignKey(${this._def.name}).on(): yalnız kolon referansı alır — ifade bir FK'nın parçası olamaz.`,\n );\n }\n return e.name;\n });\n return this;\n }\n\n /**\n * Hedef tablo ve sütunları. Sütun sayısı `.on()`'unkiyle eşit OLMALI ve bu\n * burada, bildirim yazılırken kontrol edilir — bozuk bir FK wire'a hiç çıkmaz.\n */\n references<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n ...cols: (Extract<keyof C, string>)[]\n ): this {\n if (cols.length === 0) {\n throw new Error(\n `foreignKey(${this._def.name}).references(): en az bir hedef sütun gerekir.`,\n );\n }\n this._def.refTable = table[TABLE_META].name;\n this._def.refColumns = [...cols];\n // Hedefin NESNESİ de taşınıyor: şeması `defineSchema` damgalayana kadar\n // bilinmiyor ve `resolveReferences` orada nitelikli adı yazıyor.\n Object.defineProperty(this._def, REF_TARGET, {\n value: table[TABLE_META], enumerable: false, configurable: true,\n });\n return this;\n }\n\n onUpdate(action: FkAction): this {\n this._def.onUpdate = action;\n return this;\n }\n\n onDelete(action: FkAction): this {\n this._def.onDelete = action;\n return this;\n }\n\n /**\n * `MATCH FULL`: referans veren sütunların HEPSİ NULL olmadıkça kısıt\n * değerlendirilir. Varsayılan `MATCH SIMPLE`'da tek bir NULL kısıtı atlatır —\n * `freeze` bunu bilerek kullanır, sıradan bir FK'da genelde istenmez.\n */\n match(m: FkMatch): this {\n this._def.match = m;\n return this;\n }\n}\n\nexport function foreignKey(name: string): ForeignKeyBuilder {\n return new ForeignKeyBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI burada doğrular.\n *\n * Uzunluk uyuşmazlığı push'ta da reddediliyor (FR-002) ama orada mesaj canlıya\n * gidiyor; burada yazarın editöründe patlıyor ve bozuk bildirim wire'a hiç\n * çıkmıyor. İki kapı da gerekli: biri yazar için, biri deploy için.\n */\nexport function toForeignKeyDef(b: ForeignKeyBuilder | ForeignKeyDef): ForeignKeyDef {\n const def = b instanceof ForeignKeyBuilder ? b._def : b;\n if (def.columns.length === 0) {\n throw new Error(`foreignKey(${def.name}): en az bir yerel sütun gerekir — .on(...) çağırın.`);\n }\n if (def.refColumns.length === 0 || def.refTable === \"\") {\n throw new Error(`foreignKey(${def.name}): hedef tablo ve sütunlar gerekir — .references(...) çağırın.`);\n }\n if (def.columns.length !== def.refColumns.length) {\n throw new Error(\n `foreignKey(${def.name}): ${def.columns.length} yerel sütun (${def.columns.join(\", \")}) ` +\n `ama ${def.refColumns.length} hedef sütun (${def.refColumns.join(\", \")}) — iki liste eşit uzunlukta olmalı.`,\n );\n }\n return def;\n}\n\n/**\n * Bir KOŞULLU (\"donan\") FOREIGN KEY bildirimi — C-5 (FR-012).\n *\n * `columns` çocuğun donan sütunları, `refColumns` ebeveynin onlara karşılık\n * gelen anahtar sütunları; ikisi SIRAYLA eşleşir. `when` doğruyken FK\n * değerlendirilir, yanlışken hiç değerlendirilmez.\n */\nexport interface FreezeDef {\n name: string;\n when: PolicyExpr;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/** Builder'ın YAZILMAKTA olan hâli: `when` henüz atanmamış olabilir. */\ntype FreezeDraft = Omit<FreezeDef, \"when\"> & { when?: PolicyExpr };\n\n/**\n * `freeze(\"<ad>\")` — KOŞULLU FK: bir koşul sağlandığı sürece bir demeti dondurur\n * (C-5, FR-012).\n *\n * ```ts\n * freeze: (c) => [\n * freeze(\"pay_settled_inv\")\n * .when(c.col(\"status\").eq(\"settled\"))\n * .columns(\"inv_id\", \"amount\", \"currency\")\n * .references(invoices, \"id\", \"amount\", \"currency\"),\n * ]\n * ```\n *\n * NEDEN TRIGGER DEĞİL. Üretilen şey bir CONSTRAINT: ebeveyndeki demet üzerinde\n * bir UNIQUE, çocukta `when` sağlanmıyorken NULL veren `STORED` generated\n * sütunlar, ve bunlardan `ON UPDATE RESTRICT ON DELETE RESTRICT` bir FK.\n * `MATCH SIMPLE`'ın NULL kaçışı — \"referans veren sütunlardan biri NULL ise satır\n * kısıtı sağlamak zorunda değildir\" — \"koşullu FK\"yı `WHERE` olmadan veriyor.\n *\n * Trigger'a göre üç bedava üstünlük (canlı pg'de ölçüldü, spec Research\n * Appendix): TERS YÖN de kapanır (uyuşmayan bir çocuk `settled` yapılamaz —\n * trigger yalnız ebeveyni korurdu); koşul kalkınca donma KENDİLİĞİNDEN çözülür;\n * `pg_dump`/restore'da FK gibi davranır.\n *\n * Donan sütunlar `NOT NULL` OLMALI: nullable bir sütun `MATCH SIMPLE`'ın aynı\n * kaçışını koşuldan BAĞIMSIZ olarak açar ve donma sessizce hiç kurulmaz. Push o\n * bildirimi reddeder (FR-014).\n */\nexport class FreezeBuilder {\n readonly _def: FreezeDraft;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"freeze(ad): freeze kısıtının adı boş olamaz — Palbase kısıtları ADA göre uzlaştırır.\",\n );\n }\n this._def = { name, columns: [], refTable: \"\", refColumns: [] };\n }\n\n /**\n * DONMA KOŞULU — çocuk satırının kendi kolonları üzerinde bir yüklem.\n *\n * Generated sütunlara `CASE WHEN <koşul> THEN <sütun> END` olarak iner; yani\n * koşul yanlışken sütunlar NULL olur ve FK o satır için hiç değerlendirilmez.\n */\n when(pred: PolicyExprRef): this {\n this._def.when = pred.expr;\n return this;\n }\n\n /** Çocuğun DONAN sütunları. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */\n columns(...cols: string[]): this {\n if (cols.length === 0) {\n throw new Error(\n `freeze(${this._def.name}).columns(): en az bir donan sütun gerekir — hiçbirini vermeyen bir freeze hiçbir şeyi dondurmaz.`,\n );\n }\n this._def.columns = [...cols];\n return this;\n }\n\n /**\n * Ebeveyn tablo ve donan demetin ORADAKİ karşılığı. Zincirin SON halkası:\n * bildirim burada tamamlanır ve tutarlılığı burada doğrulanır, yani\n * `.references()`'ı unutmuş bir freeze `FreezeDef` üretmediği için tabloya\n * hiç giremez.\n */\n references<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n ...cols: (Extract<keyof C, string>)[]\n ): FreezeDef {\n if (cols.length === 0) {\n throw new Error(\n `freeze(${this._def.name}).references(): en az bir hedef sütun gerekir.`,\n );\n }\n this._def.refTable = table[TABLE_META].name;\n this._def.refColumns = [...cols];\n Object.defineProperty(this._def, REF_TARGET, {\n value: table[TABLE_META], enumerable: false, configurable: true,\n });\n return toFreezeDef(this);\n }\n}\n\nexport function freeze(name: string): FreezeBuilder {\n return new FreezeBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI burada doğrular — `toForeignKeyDef`\n * ile aynı gerekçe: bozuk bir bildirim yazarın editöründe patlar, wire'a hiç\n * çıkmaz.\n */\nexport function toFreezeDef(b: FreezeBuilder | FreezeDef): FreezeDef {\n const def: FreezeDraft = b instanceof FreezeBuilder ? b._def : b;\n if (def.columns.length === 0) {\n throw new Error(`freeze(${def.name}): en az bir donan sütun gerekir — .columns(...) çağırın.`);\n }\n if (def.refColumns.length === 0 || def.refTable === \"\") {\n throw new Error(`freeze(${def.name}): hedef tablo ve sütunlar gerekir — .references(...) çağırın.`);\n }\n if (def.columns.length !== def.refColumns.length) {\n throw new Error(\n `freeze(${def.name}): ${def.columns.length} donan sütun (${def.columns.join(\", \")}) ` +\n `ama ${def.refColumns.length} hedef sütun (${def.refColumns.join(\", \")}) — iki liste eşit uzunlukta olmalı.`,\n );\n }\n if (def.when === undefined) {\n throw new Error(\n `freeze(${def.name}): donma koşulu gerekir — .when(...) çağırın. Koşulsuz bir freeze sıradan bir FK'dır; onun için foreignKey(...) var.`,\n );\n }\n const out: FreezeDef = {\n name: def.name,\n when: def.when,\n columns: [...def.columns],\n refTable: def.refTable,\n refColumns: [...def.refColumns],\n };\n // Kopya hedefin nesnesini TAŞIMALI, yoksa niteleme yapılamaz ve çapraz\n // şemalı bir freeze sessizce `public`'e yazılır.\n const target = (def as { [REF_TARGET]?: object })[REF_TARGET];\n if (target !== undefined) {\n Object.defineProperty(out, REF_TARGET, { value: target, enumerable: false, configurable: true });\n }\n return out;\n}\n","import { exprCtx } from \"./policy.js\";\nimport type { PolicyExpr, PolicyExprCtx, PolicyExprRef } from \"./policy.js\";\nimport type { ColumnMap, TableHandle } from \"./schema.js\";\n\n/**\n * guard.ts — DAR REDDEDİCİ YÜZEY (C-3, FR-015…FR-021).\n *\n * Bildirimsel kısıtların yetişemediği beş madde kaldı: write-once alanlar,\n * durum makinesi geçişleri, sabit olmayan yüklemle çapraz satır kontrolü, işlem\n * düzeyinde toplam, ve alan diline ait teşhis. RLS yolu bunlara KAPALI: `OLD` ve\n * `NEW` bir politika ifadesinde ad olarak YOKTUR (ölçüldü — red, ad çözümleme\n * düzeyinde `CREATE POLICY` anında gelir: `missing FROM-clause entry for table\n * \"new\"`), ve `USING`/`WITH CHECK` iki ayrı satıra karşı ayrı ayrı\n * değerlendirilir; tek ifadede iki satırı yan yana getiren bir kapsam yok.\n *\n * YAZAR ÜÇ ŞEY YAZAR: hangi olay · hangi koşul · ne diyerek reddet. Kalan sekiz\n * knob'un güvenli varsayılanı var ve bu yüzeyde HİÇ görünmüyor: `BEFORE` ·\n * `FOR EACH ROW` (Postgres'in varsayılanı `STATEMENT` ve bir guard için yanlış) ·\n * `UPDATE OF` listesi `WHEN`'den türetilir · `SET search_path = pg_catalog,\n * pg_temp` HER ZAMAN · `SECURITY INVOKER` (asla `DEFINER`) · `NOT DEFERRABLE` ·\n * `REFERENCING`/`FROM` üretilmez · `DROP IF EXISTS` + `CREATE`. Bir yeteneği\n * yüzeye çıkarmak onu politika hâline getirir; bunlar politika DEĞİL, güvenli\n * varsayılan (FR-017).\n *\n * Global bir kaçış kapısı KASITLI OLARAK YOK: django-pgtrigger'ın\n * `SET pgtrigger.ignore`'u herhangi bir oturumun guard'ı atlamasına izin veriyor\n * ve bir BaaS'ta bu kabul edilemez.\n */\n\n// `schema.ts` bu modülü import ediyor, yani buradan ORAYA bir DEĞER import'u\n// ESM'de döngü kurardı — bu dosyada `schema.js`'ten gelen HER ŞEY `type`.\n// Tablonun adına inen tek yol `exprCtx().existsIn`, ve o `policy.ts`'te.\n\n/** Guard'ın tetiklendiği yazma fiili. */\nexport type GuardEvent = \"insert\" | \"update\" | \"delete\";\n\n/**\n * Bir guard bildirimi — C-3/C-4 (FR-015).\n *\n * `when` satırın KENDİ kolonları üzerinde bir yüklem (trigger'ın `WHEN` yan\n * tümcesine iner), `exists` ise çapraz satır yüklemi (gövdedeki `EXISTS`\n * bloğuna). İkisi ayrı alan çünkü Postgres bir trigger'ın `WHEN` yan tümcesinde\n * ALT SORGUYA İZİN VERMİYOR (`ERROR: cannot use subquery in trigger WHEN\n * condition` — ölçüldü); ayrımı wire'da yapmak, emitter'ın yükleme bakıp\n * tahmin etmesinden daha dürüst (FR-019).\n */\nexport interface GuardDef {\n name: string;\n event: GuardEvent;\n when?: PolicyExpr;\n exists?: PolicyExpr;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/** Builder'ın YAZILMAKTA olan hâli: olay ve mesaj henüz atanmamış olabilir. */\ntype GuardDraft = Omit<GuardDef, \"event\" | \"message\"> & {\n event?: GuardEvent;\n message?: string;\n};\n\n/**\n * `guard(\"<ad>\")` — bir yazmayı ALAN DİLİYLE reddeden trigger (C-3, FR-015).\n *\n * ```ts\n * guards: (g) => [\n * guard(\"documents_frozen_body\")\n * .on(\"update\")\n * .when(g.col(\"status\").eq(\"archived\"))\n * .refuse(\"Arşivlenmiş belgenin gövdesi değiştirilemez\", { column: \"body\" }),\n * ]\n * ```\n *\n * ADI ZORUNLU (FR-016). Postgres aynı olaya bağlı trigger'ları ADA GÖRE\n * alfabetik sırayla koşar ve başka bir sıra tutamacı YOKTUR: adsız üretilmiş bir\n * guard, sırası kendi kontrolünde olmayan bir guard demektir.\n *\n * Teşhis: red `PB001` SQLSTATE'i ile gelir — `23514` KULLANILMAZ, o gerçek bir\n * CHECK ihlalinin kodu ve istemci ikisini ayırt edemezdi. Guard'ın adı\n * `CONSTRAINT` alanına gider, yani istemci mesajı PARSE ETMEDEN hangi guard'ın\n * reddettiğini okur (FR-021).\n */\nexport class GuardBuilder {\n readonly _def: GuardDraft;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"guard(ad): guard'ın adı boş olamaz — Postgres aynı olaydaki trigger'ları ADA GÖRE alfabetik koşuyor ve başka sıra tutamacı yok.\",\n );\n }\n this._def = { name };\n }\n\n /** Hangi yazma fiilinde bakılacak. */\n on(event: GuardEvent): this {\n this._def.event = event;\n return this;\n }\n\n /**\n * Satırın KENDİ kolonları üzerinde koşul — trigger'ın `WHEN` yan tümcesi.\n *\n * Emitter karşılaştırmaları `IS DISTINCT FROM` ile yazar (`<>` NULL'da yanlış\n * cevap verir) ve geçen sütunlardan bir `UPDATE OF (…)` listesi türetir\n * (FR-018).\n */\n when(pred: PolicyExprRef): this {\n this._def.when = pred.expr;\n return this;\n }\n\n /**\n * ÇAPRAZ SATIR koşulu — gövdedeki `EXISTS` bloğuna iner, `WHEN`'e DEĞİL:\n * Postgres trigger `WHEN`'inde alt sorgu kabul etmiyor (FR-019).\n *\n * Yüklem içinde takma adsız kalan kolon guard'ın KENDİ satırıdır (`NEW`/`OLD`);\n * `r.col(...)` hedef tablonun kolonlarını verir ve ayrı nitelenir. Bu yüzden\n * düğümün `outer` alanı BOŞ kalır: bir guard'ın \"dış satır\"ı bir tablo takma\n * adı değildir.\n */\n exists<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef,\n ): this {\n // Politikaların `existsIn`'i ile AYNI makine: takma ad derinlikten türüyor,\n // iç bağlam hedef tablonun kolonlarıyla kuruluyor. İkinci bir kopyası\n // olsaydı iki korelasyon lehçesi doğardı.\n this._def.exists = exprCtx().existsIn(table, predicate).expr;\n return this;\n }\n\n /**\n * REDDİN KENDİSİ ve zincirin son halkası: mesaj olmadan bir guard tamamlanmaz.\n *\n * `detail`/`hint` Postgres'in aynı adlı alanlarına, `column` ise `COLUMN`\n * alanına gider — istemci hangi alanın reddedildiğini mesajı parse etmeden\n * okur.\n */\n refuse(\n message: string,\n opts?: { detail?: string; hint?: string; column?: string },\n ): GuardDef {\n this._def.message = message;\n if (opts?.detail !== undefined) this._def.detail = opts.detail;\n if (opts?.hint !== undefined) this._def.hint = opts.hint;\n if (opts?.column !== undefined) this._def.column = opts.column;\n return toGuardDef(this);\n }\n}\n\nexport function guard(name: string): GuardBuilder {\n return new GuardBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI bildirim anında doğrular —\n * `toForeignKeyDef` ile aynı gerekçe: eksik bir guard yazarın editöründe patlar,\n * wire'a hiç çıkmaz.\n */\nexport function toGuardDef(b: GuardBuilder | GuardDef): GuardDef {\n const def: GuardDraft = b instanceof GuardBuilder ? b._def : b;\n if (def.event === undefined) {\n throw new Error(`guard(${def.name}): hangi olayda bakacağı gerekir — .on(\"insert\"|\"update\"|\"delete\") çağırın.`);\n }\n if (def.when === undefined && def.exists === undefined) {\n throw new Error(\n `guard(${def.name}): bir koşul gerekir — .when(...) ya da .exists(...) çağırın. Koşulsuz bir guard o olaydaki HER yazmayı reddeder.`,\n );\n }\n if (def.message === undefined || def.message.trim() === \"\") {\n throw new Error(\n `guard(${def.name}): boş mesaj kabul edilmez — reddin mesajı guard'ın kullanıcıya ulaşan TEK çıktısı.`,\n );\n }\n return {\n name: def.name,\n event: def.event,\n ...(def.when !== undefined ? { when: def.when } : {}),\n ...(def.exists !== undefined ? { exists: def.exists } : {}),\n message: def.message,\n ...(def.detail !== undefined ? { detail: def.detail } : {}),\n ...(def.hint !== undefined ? { hint: def.hint } : {}),\n ...(def.column !== undefined ? { column: def.column } : {}),\n };\n}\n","/**\n * backfill.ts — DDL'DEN AYRI, İZLENEN, BİR KEZ KOŞAN fiil (C-6, FR-033/FR-034).\n *\n * Bir sütun eklemek bildirimseldir; o sütunu DOLDURMAK değildir. Doldurma\n * bugüne kadar `raw()` içinde yaşıyordu ve `raw()` her deploy'da yeniden\n * koşulan bir DDL bloğu — yani veri düzeltmesi ya elle bir kez çalıştırılıyor\n * (kayıt yok, tekrarı belirsiz) ya da idempotent yazılmak zorunda kalıyordu.\n *\n * `backfills:` o işi kendi aşamasına alır: DDL'den SONRA, kendi işleminde ve\n * ADI BAŞINA BİR KEZ. Kayıt `public.palbase_backfills` tablosunda tutulur, yani\n * \"koştu mu\" sorusunun cevabı veritabanının kendisinde durur.\n */\n\n/** Bir backfill bildirimi — C-6 (FR-033). */\nexport interface BackfillDef {\n name: string;\n sql: string;\n}\n\n/**\n * `backfill(\"<ad>\", \"<sql>\")` — bir kez koşacak veri düzeltmesi.\n *\n * ```ts\n * backfills: [\n * backfill(\"ledger_currency_try\", \"UPDATE ledger SET currency = 'TRY' WHERE currency IS NULL\"),\n * ]\n * ```\n *\n * AD, KAYDIN TA KENDİSİ. \"Bu koştu mu?\" sorusu ada göre cevaplanıyor, gövdeye\n * göre değil: adı sabit tutup SQL'i değiştirmek İKİNCİ bir koşu ÜRETMEZ. Bir\n * düzeltmeyi düzeltmek istiyorsan yeni bir ad verirsin — aynı adın altında\n * değişen bir gövde, canlıda hangi sürümün koştuğunu belirsiz bırakırdı.\n *\n * Bu yüzden BOŞ SQL de reddediliyor: boş bir gövde adı kayda geçirir ve o adı\n * KALICI olarak yakar — sonradan yazılan gerçek SQL \"zaten koştu\" diye hiç\n * çalışmaz, hiçbir yerde hata da vermez.\n *\n * SQL verbatim emit edilir (`raw()` ve `policy().using(\"…\")` ile aynı güven\n * duruşu) ve `raw()` ile AYNI ayrıcalıklı DDL bağlantısında koşar — yalnızca\n * KENDİ AŞAMASINDA, yani DDL'den ayrı bir `Exec`'te. Ayrım budur ve tek başına\n * bir güvenlik iddiası DEĞİLDİR.\n *\n * Bu yorum daha önce \"ayrıcalıklı DDL bağlantısında değil\" diyordu ve YANLIŞTI.\n * Yanlış olduğu ölçüldü, ve niçin kayda geçtiği önemli: tam olarak bir\n * inceleyicinin \"backfill güvenli\" diye geçmesine sebep olacak cümleydi.\n *\n * Bu yüzden gövde `raw()` ile AYNI AST yetki kapısından geçiyor: rol yaratan,\n * sahiplik devreden, yetki dağıtan ya da `search_path` kaydıran bir ifade\n * taşıyan bir backfill push'u reddeder. Veri düzeltmesi veri düzeltmesidir.\n */\nexport function backfill(name: string, sql: string): BackfillDef {\n if (name.trim() === \"\") {\n throw new Error(\n \"backfill(ad, sql): backfill'in adı boş olamaz — 'bir kez koştu' kaydı ADA göre tutuluyor.\",\n );\n }\n if (sql.trim() === \"\") {\n throw new Error(\n `backfill(${name}): SQL boş olamaz — boş bir gövde adı kayda geçirip KALICI olarak yakar; sonradan yazılan gerçek SQL \"zaten koştu\" diye hiç çalışmaz.`,\n );\n }\n return { name, sql };\n}\n","import type { ColumnBuilder } from \"./columns.js\";\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport { PolicyBuilder, check, exprCtx, reservedCanRelation } from \"./policy.js\";\nimport type { CheckDef, PolicyDef, PolicyExprCtx, PolicyExpr, PolicyExprRef } from \"./policy.js\";\nimport type { PalbaseExtension } from \"./extensions.js\";\nimport { ForeignKeyBuilder, FreezeBuilder, REF_TARGET, foreignKey, freeze, toForeignKeyDef, toFreezeDef } from \"./foreign-key.js\";\nimport type { ForeignKeyDef, FreezeDef } from \"./foreign-key.js\";\nimport { GuardBuilder, guard, toGuardDef } from \"./guard.js\";\nimport type { GuardDef } from \"./guard.js\";\nimport { backfill } from \"./backfill.js\";\nimport type { BackfillDef } from \"./backfill.js\";\nimport type { RawConstraintDef } from \"./raw.js\";\nimport type { ChatModelRef, EmbeddingModelRef } from \"./embedding.js\";\n\n/**\n * A map of column builders keyed by column name — the value you write under\n * the `columns` key of `defineTable(\"<name>\", { columns })`.\n *\n * The default `Record<string, ColumnBuilder>` keeps bare references compiling\n * without a type argument.\n */\nexport type ColumnMap = Record<string, ColumnBuilder>;\n\n/**\n * The author-facing value written under each table key:\n * `{ columns, rls?, policies? }`.\n *\n * - `columns`: the column map (required).\n * - `rls`: enable + FORCE row-level security on this table. **Defaults to\n * `true`**, and is forced on when `policies` is non-empty. A table with RLS\n * and no policies is deny-all, which is the starting state: nothing reads it\n * until a policy says who may. Set `rls: false` only for a genuinely public\n * table — it is an explicit opt-out that a reviewer can grep for, not\n * something you get by forgetting.\n * - `policies`: the RLS policies for this table, authored with `policy(name)`.\n * Each entry may be a {@link PolicyBuilder} (the normal `policy(...)` chain)\n * or a raw {@link PolicyDef} object.\n *\n * The `C` type parameter preserves the precise per-column phantom types so the\n * typed `Database.public.*` surface keeps inferring insert/row shapes.\n */\n/** Arama metriği — tek kelime; opclass ve operatör bundan türetilir, asla yüzeye çıkmaz (D-5/D-6). */\nexport type SearchMetric = \"cosine\" | \"euclidean\" | \"inner_product\";\n\n/** Bir vektör arama kolu. `model` varsa auto-embed: platform yazma+sorgu embedding'ini üstlenir (D-9). */\nexport interface VectorSearchDecl {\n /** Hedef vector kolonu; tabloda TEK vector kolonu varsa atlanabilir (Go apply çözer, FR-010). */\n column?: string;\n /** Varsa auto-embed. Deskriptor düz veridir — şemayla serileşir (C-3). */\n model?: EmbeddingModelRef;\n /** model varsa ZORUNLU: embed kaynak kolonları = trigger'ın UPDATE OF listesi (C-2). */\n from?: string[];\n metric?: SearchMetric;\n /** Kaynak metin değişince ara-dönem davranışı (yalnız auto-embed'de):\n * \"null\" (vars.) — embedding anında NULL'lanır; satır yeni vektör yazılana\n * dek anlamsal aramada aday değildir. Bayat eşleşme asla servis edilmez.\n * \"keep\" — eski vektör aramada kalır, platform yenisini yazınca sessizce\n * değişir. Görünürlük penceresi sıfır; bedeli saniyeler süren bayat\n * eşleşme riski (Confluence-tipi sync yükleri için). */\n staleness?: \"null\" | \"keep\";\n}\n\n/** Tablonun arama beyanı — İKİ biçim (D-007, tek yüzey):\n *\n * YENİ (önerilen): `{ from, model, ... }` — `from` kolonları hem FTS'e hem\n * embed'e girer. Tabloda vector kolonu declare edilmişse SATIR-modu; yoksa\n * CHUNK-modu otomatiktir (D-010): vektörler türev `__palbase_chunks`\n * tablosunda yaşar, içerik otomatik bölünür. `text: false` FTS'i kapatır,\n * `text: [..]` FTS kolonlarını from'dan ayırır. `chunks` yalnız ince ayar.\n *\n * ESKİ: `text: string[]` + `vector: {...}` — aynen çalışır, wire çıktısı\n * bayt-aynı kalır (NFR-B1). İki biçim KARIŞTIRILAMAZ. */\nexport interface SearchDecl {\n text?: string[] | boolean;\n vector?: VectorSearchDecl | VectorSearchDecl[];\n /** Yeni biçim: arama kaynağı kolonlar (FTS + embed). Varlığı yeni biçimi seçer. */\n from?: string[];\n /** Yeni biçim: auto-embed modeli (zorunlu — BYO için eski biçimi kullanın). */\n model?: EmbeddingModelRef;\n metric?: SearchMetric;\n staleness?: \"null\" | \"keep\";\n /** Chunk-modu ince ayarı (yalnız vector kolonsuz tabloda anlamlı). */\n chunks?: { size?: number; overlap?: number };\n /** Sorgu-yeniden-yazımı: tek yönlü eş anlamlı haritası (FR-026). */\n synonyms?: Record<string, string[]>;\n /** Geçerlilik kolonları türetilir; arama varsayılan yalnız günceli tarar (FR-029). */\n validity?: boolean;\n}\n\n/** Hafıza beyanı (FR-032, D-019): kaynak tablonun yazımlarından platform\n * fact damıtır ve `into` tablosuna yazar. Hedef NORMAL declared tablodur —\n * kendi search/unique/validity beyanlarıyla. Okuma = Database.$search(into).\n * subject default \"owner\": fact'in kime ait olduğu kolonu (iki tabloda da). */\nexport interface MemoryDecl {\n from: string[];\n into: string;\n extract: ChatModelRef;\n subject?: string;\n}\n\n/**\n * Bir index bildiriminin girdi şekli (FR-041…043).\n *\n * `columns` ile `expression` birbirinin alternatifidir: biri kolon listesi,\n * diğeri `lower(email)` gibi bir ifade. `where` partial index koşuludur ve\n * filtre şekli sorgu tarafındaki `WhereFilter` ile aynıdır — iki ayrı filtre\n * dili olmaz.\n */\n/**\n * Bir index'in TEL şekli — `IndexJSON` ile aynı alanlar (T002).\n *\n * Bildirilmeyen alan HİÇ yazılmaz: sıfır değer yazmak, bildirmeyen her index'i\n * diff'te değişmiş gösterir ve her deploy'a boş bir migration ekler.\n */\nexport interface IndexDef {\n name: string;\n /**\n * `CREATE UNIQUE INDEX` (FR-007). `unique: [{name, columns}]` bir UNIQUE\n * CONSTRAINT üretir ve constraint'in `WHERE`'i olamaz; `index()` partial\n * olabilir ama unique olamıyordu. İki yarım vardı, birleşmiyorlardı.\n */\n unique?: boolean;\n columns?: string[];\n expression?: string;\n where?: PolicyExpr;\n sort?: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n include?: string[];\n}\n\n/**\n * `index(\"<ad>\")` — C-5 (FR-041…043).\n *\n * ```ts\n * indexes: (c) => [\n * index(\"orders_open\")\n * .on(c.col(\"status\")) // kolon TİPLİ\n * .where(c.col(\"deleted_at\").isNull()) // partial\n * .include([\"total\"]), // covering\n * ]\n * ```\n *\n * `policy()` ile AYNI dili konuşur: `where` politika ifade yapısının ta kendisi.\n * Üçüncü bir filtre lehçesi açmak, aynı sorunun iki yazımı demekti.\n *\n * Kolon bağlamı callback'ten geliyor çünkü index tablo tanımının İÇİNDE\n * bildiriliyor — `orders.status` yazmak, `orders` bağlaması o noktada henüz\n * kurulmadığı için mümkün değil (T015'te `policies` için ölçülen aynı kısıt).\n */\nexport class IndexBuilder {\n readonly _def: IndexDef;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\"index(ad): index'in adı boş olamaz — Palbase index'leri ADA göre uzlaştırır.\");\n }\n this._def = { name };\n }\n\n /**\n * `CREATE UNIQUE INDEX` (FR-007). `.where()` ile birlikte PARTIAL UNIQUE\n * index verir (FR-007b) — \"NULL'lar serbest, non-NULL'lar tekil\" kalıbının\n * tek bildirimsel yolu.\n */\n unique(): this {\n this._def.unique = true;\n return this;\n }\n\n /** Index'in kolonları. SIRA KORUNUR — çok kolonlu bir index'in anlamı sırasıdır. */\n on(...cols: PolicyExprRef[]): this {\n this._def.columns = cols.map((c) => {\n const e = c.expr;\n if (e.kind !== \"col\") {\n throw new Error(`index(${this._def.name}).on(): yalnız kolon referansı alır — ifade için onExpression(\"…\") kullanın.`);\n }\n return e.name;\n });\n return this;\n }\n\n /**\n * İfade index'i (`lower(email)`), kolon yerine.\n *\n * Metin VERBATIM emit ediliyor — `policy().using(\"…\")` ile aynı güven duruşu.\n * Tipli yapı bunu ifade edemiyor ve kaçış kapağını kapatmak, yazarı elle\n * migration yazmaya iterdi.\n */\n onExpression(expr: string): this {\n this._def.expression = expr;\n return this;\n }\n\n /** Partial index koşulu — politika ifade dilinin ta kendisi. */\n where(expr: PolicyExprRef): this {\n this._def.where = expr.expr;\n return this;\n }\n\n /** Sıra. Tek yönlü index'te sıra genelde önemsizdir; ORDER BY ile eşleşen\n * bir index arandığında değildir. */\n desc(): this {\n this._def.sort = \"desc\";\n return this;\n }\n\n asc(): this {\n this._def.sort = \"asc\";\n return this;\n }\n\n /** NULL'ların yeri — `ORDER BY … NULLS LAST` ile eşleşmesi için. */\n nulls(where: \"first\" | \"last\"): this {\n this._def.nulls = where;\n return this;\n }\n\n /** Covering index (`INCLUDE`): index-only scan için taşınan ama\n * ARANMAYAN kolonlar. */\n include(cols: string[]): this {\n this._def.include = cols;\n return this;\n }\n}\n\nexport function index(name: string): IndexBuilder {\n return new IndexBuilder(name);\n}\n\nexport interface TableInput<C extends ColumnMap = ColumnMap> {\n columns: C;\n rls?: boolean;\n /**\n * Bu tablonun RLS politikaları — TABLONUN KENDİ KOLONLARININ bir fonksiyonu\n * olarak (FR-022).\n *\n * Callback olmasının sebebi tip: `columns`'tan çıkarılan `C`, TypeScript\n * tarafından buraya bağlamlandırılıyor, yani `p.col(\"ownerr\")` yazım hatası\n * DERLEME hatası oluyor. Düz bir dizide `policy(\"x\")` tek başına çağrıldığı\n * için hangi tabloda olduğunu bilemez, ve yanlış kolon adı ancak deploy\n * anında `CREATE POLICY` çalışırken Postgres'ten dönerdi. Bir RLS\n * politikasında yanlış kolon adı yetki hatasıdır; derlemede yakalanır.\n *\n * ```ts\n * policies: (p) => [\n * policy(\"owner_read\").for(\"select\").using(p.col(\"owner\").eq(p.auth.uid())),\n * ]\n * ```\n */\n policies?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (PolicyBuilder | PolicyDef)[];\n /**\n * KOŞAN SÜRÜMÜN \"BU TABLOYU ARTIK OKUMUYORUM\" SÖZÜ — düşürmenin ilk yarısı.\n *\n * `ColumnDef.ignored`'ın tablo karşılığı ve aynı sebeple var: şema rayı, koşan\n * sürümün hâlâ BEYAN ettiği bir şeyi düşürmeyi reddeder — sıfır satırlı bir\n * tablo için bile, çünkü koşan sürümün bir SELECT'i ona dokunuyor olabilir.\n *\n * ONSUZ TABLO HİÇ DÜŞMÜYORDU (ölçüldü, canlı push 06.09.2026): rayın tavsiyesi\n * *\"beyandan çıkar ve bir kez deploy et\"*ti, ama beyandan çıkarmak düşürmeyi\n * ÜRETEN şeyin ta kendisi — o deploy'da da koşan sürüm tabloyu beyan ediyor\n * olur ve aynı red gelir. Kolonun çıkış yolu vardı, tablonun yoktu.\n *\n * İşaretlemek hiçbir DDL üretmez; ilk deploy'u BEDAVA yapan şey bu.\n *\n * ```ts\n * const cloud_images = defineTable(\"cloud_images\", { ignored: true, columns: { … } });\n * ```\n */\n ignored?: boolean;\n /** Composite/named primary key (ordered column names). Omit for single-column inline .primaryKey(). */\n primaryKey?: string[];\n /** Named multi-column UNIQUE constraints. */\n unique?: { name: string; columns: string[] }[];\n /** Named raw-SQL DDL objects (EXCLUDE, triggers, views) that the typed DSL cannot express. */\n raw?: RawConstraintDef[];\n /**\n * Named first-class CHECK constraints. Diffed by NAME with a BODY compare:\n * a changed `expr` (after pg normalization) recreates the constraint\n * (DROP + ADD). `name` is identifier-validated.\n *\n * İKİ BİÇİM, TEK TEL (FR-009, FR-011):\n *\n * - DİZİ — `expr` verbatim yayılan güvenilen SQL (policy `using` gibi).\n * Bugünkü biçim, olduğu gibi kabul edilmeye devam ediyor.\n * - CALLBACK — `(c) => [check(name, c.col(\"amount\").gt(0))]`: ifade POLİTİKA\n * ifade cebiriyle yazılıyor ve kolon adları DERLEME anında doğrulanıyor.\n * Callback olması bunun şartı: `checks` düz bir dizi olsaydı TypeScript\n * `columns`'tan kolon adlarını çıkarıp ifadeyi onlarla bağlamlandıramazdı.\n *\n * Yanlış yazılmış bir kolon adı string biçiminde ancak\n * `ALTER TABLE … ADD CONSTRAINT` anında — deploy'un ORTASINDA — Postgres'ten\n * dönüyor. Tipli biçim aynı cevabı yazma anına taşıyor.\n *\n * Tipli ifade CHECK bağlamının DAR kümesine tabi: `existsIn` ve `auth.uid()`\n * alt sorgu oldukları için `check()` tarafından reddediliyor (FR-010).\n */\n checks?: CheckDef[] | ((c: PolicyExprCtx<Extract<keyof C, string>>) => CheckDef[]);\n /**\n * Plain (non-unique) btree indexes over an ordered column list, emitted as\n * standalone `CREATE INDEX [IF NOT EXISTS] name ON table (col1, col2)`\n * statements (NOT a table clause — a separate migration statement category).\n * Structural compare by NAME (no expression normalization). `name` and each\n * column are identifier-validated by the Go differ.\n *\n * NAME is the WHOLE diff key. Editing `.where()`, `.onExpression()`,\n * `.include()` or the sort under a name that is already live does NOTHING —\n * the deploy matches the name, sees the index, and skips. Give a changed\n * definition a new name.\n *\n * Scope, via `index(name)`: `.on(...cols)` · `.onExpression(sql)` (expression\n * index) · `.where(pred)` (partial index, typed predicate) · `.unique()`\n * (UNIQUE, and WITH `.where()` a PARTIAL UNIQUE index) · `.include(cols)`\n * (covering) · `.asc()`/`.desc()`/`.nulls()`. Predicates and expressions are\n * probed against the live database before the push — as a prepared statement\n * AND as a real CREATE INDEX on an empty `LIKE` clone, which is what catches\n * a subquery predicate or a non-IMMUTABLE function before the apply.\n *\n * `index(n).unique().where(p)` is the ONE declarative way to say \"NULLs are\n * free, non-NULLs are unique\" — the table-level `unique:` cannot carry a\n * predicate, because it renders a CONSTRAINT and PostgreSQL has no partial\n * unique CONSTRAINT (only a partial unique INDEX).\n *\n * NOT expressible here: another index method (gin/gist/brin/hash), an\n * opclass, or CONCURRENTLY.\n */\n indexes?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (IndexBuilder | IndexDef)[];\n /**\n * Canlıdan DÜŞÜRÜLECEK constraint adları (FR-008).\n *\n * Differ additive: canlıda olup bildirimde olmayan bir constraint asla\n * düşürülmez — beyan dosyası veritabanının nesnelerine sahip değildir. Bu\n * alan o kuralın TEK istisnası ve açıkça yazılmış olması gerekiyor.\n *\n * Ad bilinçli olarak `retired` DEĞİL: bu DSL'de `retired` zaten \"emekliye\n * ayrılmış ÇAĞRI biçimi\" demek (`schema-retired-call.test.ts`).\n */\n dropConstraints?: string[];\n /**\n * Tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY'ler (FR-001).\n *\n * Kolon üzerindeki `.references()` tek sütunlu ve tek hedeflidir; çok kiracılı\n * bütünlüğün istediği `FOREIGN KEY (tenant_id, child_id) REFERENCES parent\n * (tenant_id, id)`'yi ifade edemez. İki yol birbirini DÜŞÜRMEZ: bu bildirim\n * kendi adıyla, kolon üzerindekiler `<tablo>_<kolon>_fkey` ile izlenir.\n */\n foreignKeys?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (ForeignKeyBuilder | ForeignKeyDef)[];\n /**\n * KOŞULLU FK'lar — bir koşul sağlandığı sürece donan demetler (FR-012).\n *\n * \"Ödeme `settled` olduğu sürece faturanın tutarı değişemez\" bir trigger\n * istemiyor: koşul sağlanmıyorken NULL veren `STORED` generated sütunlar ve\n * onlardan `ON UPDATE RESTRICT` bir FK, `MATCH SIMPLE`'ın NULL kaçışı\n * üzerinden aynı şeyi CONSTRAINT olarak veriyor.\n *\n * `foreignKeys` ile aynı sebeple callback: `when` yüklemi TABLONUN KENDİ\n * kolonlarından çözülüyor ve yanlış ad derleme hatası oluyor.\n */\n freeze?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (FreezeBuilder | FreezeDef)[];\n /**\n * Bu tablonun GUARD'ları — bildirimsel kısıtın yetişemediği yazma redleri\n * (FR-015).\n *\n * Yazar üç şey yazar: hangi olay · hangi koşul · ne diyerek reddet. `BEFORE`,\n * `FOR EACH ROW`, `SECURITY INVOKER`, pinlenmiş `search_path` ve `UPDATE OF`\n * türetimi güvenli VARSAYILAN — bu yüzeyde görünmezler (FR-017).\n *\n * `policies` ile aynı sebeple callback: koşul TABLONUN KENDİ kolonlarından\n * çözülüyor ve yanlış bir ad derleme hatası oluyor. Bir guard'da yanlış kolon\n * adı, hiç ateşlemeyen bir guard demektir — güvenlik yolunda fail-open.\n */\n guards?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (GuardBuilder | GuardDef)[];\n /**\n * BİR KEZ koşacak veri düzeltmeleri — DDL'den AYRI bir aşamada (FR-033).\n *\n * Sütun eklemek bildirimseldir, o sütunu DOLDURMAK değildir: doldurma bugüne\n * kadar her deploy'da yeniden koşan bir `raw()` bloğunun içindeydi. Burası o\n * işin kendi aşaması; kayıt ada göre tutuluyor ve aynı ad ikinci kez koşmuyor\n * (FR-034).\n *\n * `policies`/`guards`'ın aksine düz bir dizi: bir backfill'in yüklemi yok,\n * gövdesi verbatim SQL — bağlamlandıracak bir kolon adı da yok.\n */\n backfills?: BackfillDef[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder — UPDATE/DELETE hem\n * veritabanı yetkisiyle hem üretilen tipte reddedilir (T017/T018).\n * Ledger deseninin veri katmanından istediği TEK şey budur: bakiye türetilmiş\n * bir değerdir ve entry log'u değiştirilebilirse doğruluğunu kaybeder.\n */\n appendOnly?: boolean;\n /** Arama beyanı — bkz. SearchDecl. */\n search?: SearchDecl;\n /** Hafıza beyanı — bkz. MemoryDecl (FR-032). */\n memory?: MemoryDecl;\n}\n\n/**\n * A table definition — the runtime value the Go runtime's `schema_extract.js`\n * reads. It keys tables by `tableDef.name`, reads `tableDef.columns` for the\n * column DDL, and `tableDef.rls` + `tableDef.policies` for RLS.\n *\n * `defineSchema` derives `name` from the object key, so authors never repeat\n * the table name. `rls`/`policies` are always present after normalization\n * (defaulted to `true`/`[]`).\n *\n * The `C` type parameter preserves the precise per-column phantom types so that\n * downstream mapped types (InsertShape, RowShape) can discriminate on them.\n */\nexport interface TableDef<C extends ColumnMap = ColumnMap> {\n name: string;\n columns: C;\n rls: boolean;\n /** Koşan sürümün \"bu tabloyu okumuyorum\" sözü — bkz. TableInput.ignored. */\n ignored?: boolean;\n policies: PolicyDef[];\n primaryKey?: string[];\n unique?: { name: string; columns: string[] }[];\n /** Named raw-SQL DDL objects emitted verbatim on deploy. Tracked by name. */\n raw?: RawConstraintDef[];\n /** Named first-class CHECK constraints. Diffed by name + (normalized) body.\n * İki yazım biçimi de (dizi / callback) BURAYA iner — bkz. TableInput.checks. */\n checks?: CheckDef[];\n /** Index bildirimleri; partial/expression/sıra/covering alanlarıyla (FR-041…043). */\n indexes?: IndexDef[];\n /** Canlıdan düşürülecek constraint adları (FR-008). */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY bildirimleri (FR-001). */\n foreignKeys?: ForeignKeyDef[];\n /** Koşullu FK (\"donan demet\") bildirimleri (FR-012). */\n freeze?: FreezeDef[];\n /** Guard bildirimleri — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). */\n guards?: GuardDef[];\n /** Bir kez koşacak veri düzeltmeleri, DDL'den ayrı aşamada (FR-033). */\n backfills?: BackfillDef[];\n /** appendOnly (FR-030) — bkz. TableInput. */\n appendOnly?: boolean;\n /** Arama beyanı, doğrulanmış ve taşınmış hali. */\n search?: SearchDecl;\n /** Hafıza beyanı, doğrulanmış ve taşınmış hali (FR-032). */\n memory?: MemoryDecl;\n}\n\n/**\n * A schema definition containing multiple tables, keyed by table name.\n *\n * The `T` type parameter preserves the exact `TableDef<...>` type for each\n * table so that `SchemaDef[\"tables\"][\"rooms\"]` resolves to the precise\n * `TableDef<{ id: ColumnBuilder<'uuid', false, true, never>; ... }>`.\n */\nexport interface SchemaDef<\n T extends Record<string, TableDef> = Record<string, TableDef>,\n> {\n /** The schema's own name — `public`, `billing`, … Declared, never derived. */\n name: string;\n /** Reachable over HTTP? False unless the author opts in. */\n exposed: boolean;\n tables: T;\n /** Postgres extensions to install on deploy. Normalized to `[]` when absent. */\n extensions: PalbaseExtension[];\n}\n\n/** The author-facing input to `defineSchema` — a `tables` map whose keys are\n * the table names and whose values are `{ columns, rls?, policies? }`, plus an\n * optional `extensions` allowlist. */\nexport interface SchemaInput<\n T extends Record<string, TableInput> = Record<string, TableInput>,\n> {\n tables: T;\n /**\n * Postgres extensions to enable for this project, e.g. `[\"vector\"]`.\n * Config-as-code: installed by the deploy (CREATE EXTENSION … SCHEMA\n * extensions) with the privileged deploy connection. The type is an\n * allowlist union, so unsupported names fail typecheck.\n */\n extensions?: PalbaseExtension[];\n}\n\n/** Map the author's `{ tables: { <name>: { columns } } }` input to the\n * `{ tables: { <name>: TableDef<columns> } }` runtime/type shape, threading the\n * per-table column map `T[K][\"columns\"]` so column-level inference survives. */\ntype TablesByName<T extends readonly TableHandle[]> = {\n [K in T[number] as K[typeof TABLE_META][\"name\"]]: K[typeof TABLE_META];\n};\n\n/** Normalize a single `policies` entry into a plain `PolicyDef` (read off a\n * `PolicyBuilder._def`, or passed through when already a `PolicyDef`). */\nfunction toPolicyDef(p: PolicyBuilder | PolicyDef): PolicyDef {\n return p instanceof PolicyBuilder ? p._def : p;\n}\n\n/**\n * How a schema file reads. One file per schema — `db/public.ts`, `db/billing.ts`\n * — and the schema says its own name:\n *\n * const todos = defineTable(\"todos\", {\n * columns: {\n * id: uuid().primaryKey().defaultRandom(),\n * owner: text().notNull(),\n * title: text().notNull(),\n * },\n * rls: true,\n * policies: (p) => [\n * policy(\"owner_all\").for(\"all\").to(\"authenticated\")\n * .using(p.col(\"owner\").eq(p.auth.uid()))\n * .withCheck(p.col(\"owner\").eq(p.auth.uid())),\n * ],\n * });\n *\n * export default defineSchema(\"public\", { tables: [todos] });\n *\n * The dictionary form `defineSchema({ tables: { todos: {…} } })` is RETIRED and\n * refused by name: a table whose name comes from a key does not know what it is\n * called while it is being built, so it cannot resolve `references(() =>\n * other.id)`, and a schema that does not say its own name cannot tell one\n * `invoices` from another schema's `invoices`.\n *\n * The returned value is `{ name, tables: { todos: { name, columns, rls,\n * policies } }, extensions, exposed }` — the exact shape the runtime schema\n * extractor parses. Per-column phantom types are preserved so\n * `Database.public.todos.insert({...})` stays typed.\n *\n * RLS normalization: `rls` defaults to **`true`**, `policies` to `[]`. A table\n * that declares neither is therefore deny-all — nothing reads it until a policy\n * says who may, which is the safe starting point rather than a bug. Declare\n * `rls: false` for a genuinely public table; that is an explicit, greppable\n * statement of intent instead of an omission. When `policies` is non-empty,\n * `rls` is forced on (ENABLE + FORCE) regardless of the declared flag — a table\n * with policies must have RLS enabled or the policies would be inert.\n */\n/**\n * Where a table's metadata lives.\n *\n * The table VALUE is its columns, so `lists.id` is the column — which means a\n * column called `name` would overwrite the table's own name if metadata sat in\n * a plain field. Measured, not imagined: the existing `users` / `rooms` tests\n * (both declare a `name` column) produced an `[object Object]` table key.\n * `columns`, `rls`, `search`, `memory`, `unique` and `indexes` are all plausible\n * column names too. A column cannot collide with a symbol.\n */\nexport const TABLE_META: unique symbol = Symbol.for(\"palbase.table.meta\");\n\n/** A value produced by `defineTable`: the columns, plus metadata behind the symbol. */\nexport type TableHandle<C extends ColumnMap = ColumnMap, N extends string = string> =\n C & { readonly [TABLE_META]: TableDef<C> & { name: N } };\n\n/**\n * Declare one table as a standalone value that KNOWS ITS OWN NAME.\n *\n * The name lives here, not in a dictionary key. A table whose name comes from a\n * key cannot resolve `references(() => other.id)` when it is built — it does not\n * know what to call itself — which forces a two-phase resolution with an\n * empty-name intermediate state. One name source, no empty identity.\n *\n * The returned object spreads its own columns, so a sibling can point at it:\n * `references(() => lists.id)`.\n */\nexport function defineTable<const N extends string, C extends ColumnMap>(\n name: N,\n input: TableInput<C>,\n): TableHandle<C, N> {\n if (name.trim() === \"\") {\n throw new Error(\"defineTable(name, …): name must not be empty\");\n }\n // `can` bir ilişki adı olarak rezerve (W1 h2-r3 N-2): beyan anında reddedilir,\n // motor/env-gen/can() aynı şeyi üç yerde ayrı ayrı kollamak zorunda kalmasın.\n {\n const reserved = reservedCanRelation(name, input.columns);\n if (reserved !== null) throw new Error(`defineTable(${JSON.stringify(name)}): ${reserved}`);\n }\n // İfade bağlamı TABLONUN KENDİ kolon adlarıyla kuruluyor (FR-022). Çalışma\n // zamanında `col()` adı doğrulamıyor — doğrulayan tip; burada yapılacak\n // ikinci bir kontrol, tipin zaten imkânsız kıldığı bir şeyi tekrar ederdi.\n const policies = (input.policies?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toPolicyDef);\n // Fail closed. RLS is on unless the author explicitly says `rls: false`, and\n // policies force it on regardless — a policy on a table without RLS enabled is\n // inert, so declaring both resolves towards the safe reading.\n //\n // This defaulted to `false` until 2026-08-07, which meant a table nobody\n // thought about had no row-level security while `typed-db.ts` documented the\n // default `Database.*` path as RLS-enforced. The live proof settled it: user B\n // read user A's row in full through the typed client, while the same request\n // against a table declaring `rls: true` returned 0 of 165 rows. With no\n // policies this is deny-all.\n const rls = policies.length > 0 || input.rls !== false;\n // EACH TABLE GETS ITS OWN COLUMN OBJECTS.\n //\n // A ColumnBuilder shares one `_def` with every builder derived from it, so a\n // shared column — `const audit = { created_at: timestamp() }` spread into two\n // tables, the most ordinary pattern this DSL has — would put BOTH tables'\n // stamps on one object and the second declaration would win. A reference\n // thunk written as `() => a.created_at` then resolved to table `b`: a\n // well-formed foreign key onto the WRONG table, with no error anywhere.\n //\n // Copying is what `.ignored()` already does about the same aliasing, and it\n // keeps the spread pattern working rather than banning it. The copies are\n // what the def AND the handle carry, so the identity match that resolves a\n // reference thunk still finds its column.\n const owned = {} as C;\n for (const [colName, b] of Object.entries(input.columns)) {\n const builder = b as { _def: ColumnDefLike };\n // Same class, same phantom type parameters, its own `_def`. Cloning through\n // the prototype rather than the constructor keeps this file free of a value\n // import from columns.ts — the two modules only ever exchanged types.\n const clone = Object.create(Object.getPrototypeOf(builder)) as { _def: ColumnDefLike };\n Object.defineProperty(clone, \"_def\", { value: { ...builder._def }, enumerable: true, writable: true });\n (owned as Record<string, unknown>)[colName] = clone;\n }\n\n const def = {\n name,\n columns: owned,\n rls,\n policies,\n } as TableDef<C> & { name: N };\n if (input.primaryKey !== undefined) def.primaryKey = input.primaryKey;\n if (input.unique !== undefined) def.unique = input.unique;\n if (input.raw !== undefined && input.raw.length > 0) def.raw = input.raw.slice();\n // İki dal da AYNI `CheckDef[]`'e iniyor (FR-009, FR-011): tipli dal ifadeyi\n // `check()` içinde SQL'e derliyor, string dal yazarın SQL'ini taşıyor. Telde\n // yeni bir alan doğmuyor — `TableJSON.checks` bugünkü `{ name, expr }[]`.\n const declaredChecks =\n typeof input.checks === \"function\"\n ? input.checks(exprCtx(Object.keys(input.columns), 0, name))\n : (input.checks?.slice() ?? []);\n if (declaredChecks.length > 0) def.checks = declaredChecks;\n // İfade bağlamı `policies` ile AYNI — index kolonları da tablonun kendi\n // kolonlarından çözülüyor ve yanlış ad derleme hatası (FR-041).\n const declaredIndexes = (input.indexes?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n (i) => (i instanceof IndexBuilder ? i._def : i),\n );\n if (declaredIndexes.length > 0) def.indexes = declaredIndexes;\n // Tablo düzeyi çok sütunlu FK'lar (FR-001). `toForeignKeyDef` tutarlılığı\n // BURADA doğruluyor: sütun sayıları eşleşmeyen bir bildirim yazarın\n // editöründe patlıyor ve wire'a hiç çıkmıyor. Push'taki red (FR-002) aynı\n // kuralı deploy tarafında tekrar kuruyor — iki kapı, iki farklı okuyucu için.\n const declaredFKs = (input.foreignKeys?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toForeignKeyDef,\n );\n if (declaredFKs.length > 0) def.foreignKeys = declaredFKs;\n // Koşullu FK'lar (FR-012). `toFreezeDef` tutarlılığı burada doğruluyor;\n // `.references()` zaten aynı fonksiyondan geçtiği için düz bir `FreezeDef`\n // yazan yol da aynı kapıdan geçer.\n const declaredFreezes = (input.freeze?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toFreezeDef,\n );\n if (declaredFreezes.length > 0) def.freeze = declaredFreezes;\n // SÜTUN ADLARI BU TABLONUN OLMALI — ve bu kontrol burada, bildirimin yazıldığı\n // yerde. `.columns(...)` serbest `string` alıyor (aynı builder'ın\n // `.references()`'ı tipli), yani bir typo editörde geçiyordu ve bedeli\n // push'ta ya da — yeni bir tabloda, canlı round-trip'in atlandığı yolda —\n // apply'ın ORTASINDA bir `CREATE`/`ALTER` hatası olarak çıkıyordu.\n for (const fz of declaredFreezes) {\n for (const c of fz.columns) {\n if (!(c in input.columns)) {\n throw new Error(\n `table \"${name}\": freeze(\"${fz.name}\").columns(\"${c}\") — no such column on this table. ` +\n `Declared columns: ${Object.keys(input.columns).join(\", \")}`,\n );\n }\n }\n }\n // Guard'lar (FR-015). `toGuardDef` olay/koşul/mesaj üçlüsünü bildirim anında\n // şart koşuyor — eksik bir guard hiç ateşlemeyen bir guard'dır ve güvenlik\n // yolunda sessiz bir fail-open olurdu.\n const declaredGuards = (input.guards?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toGuardDef,\n );\n if (declaredGuards.length > 0) def.guards = declaredGuards;\n // Aynı gerekçe: `refuse(msg, { column })` serbest `string` ve o sütun hem\n // reddin `COLUMN` alanına hem `UPDATE OF` listesine giriyor.\n for (const g of declaredGuards) {\n if (g.column !== undefined && !(g.column in input.columns)) {\n throw new Error(\n `table \"${name}\": guard(\"${g.name}\").refuse(…, { column: \"${g.column}\" }) — no such column on this table. ` +\n `Declared columns: ${Object.keys(input.columns).join(\", \")}`,\n );\n }\n }\n if (input.backfills !== undefined && input.backfills.length > 0) {\n // AYNI AD İKİ KEZ = ikincisi HİÇ koşmaz. Kayıt ada göre tutuluyor\n // (FR-034), yani ikinci bildirim sessizce atlanır ve hiçbir yerde hata\n // vermez. Beyan anında reddetmek bunun tek görünür hâli.\n const seen = new Set<string>();\n for (const b of input.backfills) {\n if (seen.has(b.name)) {\n throw new Error(\n `table ${name}: backfill adı iki kez bildirildi: ${b.name} — kayıt ADA göre tutuluyor, ikincisi hiç koşmazdı.`,\n );\n }\n seen.add(b.name);\n }\n def.backfills = input.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n if (input.dropConstraints !== undefined && input.dropConstraints.length > 0) {\n def.dropConstraints = [...input.dropConstraints];\n }\n if (input.appendOnly === true) def.appendOnly = true;\n // `omitempty` ile aynı sözleşme: işaretlenmemiş tablo alanı HİÇ taşımaz, yani\n // bugüne kadarki her beyanın telde bayt-aynı kalması garanti.\n if (input.ignored === true) def.ignored = true;\n if (input.search !== undefined) {\n const s = input.search;\n // Erken, beyan-anı doğrulama (apply doğrulamasını İKAME ETMEZ — yazım\n // hatası deploy'a gitmeden yazarın yüzüne söylenir).\n if (s.from !== undefined) {\n // YENİ biçim (D-007). Eski alanlarla karışım tek biçime zorlanır:\n // iki yarım beyanın hangisinin kazandığını okuyucu bilemez.\n if (s.vector !== undefined) {\n throw new Error(\n `table ${name}: search beyanında tek biçim kullanın — 'from' (yeni) ile 'vector' (eski) birlikte olamaz`,\n );\n }\n if (s.from.length === 0) {\n throw new Error(`table ${name}: search.from boş olamaz`);\n }\n if (s.model === undefined) {\n throw new Error(\n `table ${name}: search.from model'siz anlamsız — auto-embed için model verin (BYO için eski 'vector' biçimini kullanın)`,\n );\n }\n if (Array.isArray(s.text) && s.text.length === 0) {\n throw new Error(`table ${name}: search.text boş dizi olamaz — FTS istemiyorsan text: false yazın`);\n }\n } else {\n // ESKİ biçim — davranış ve hata metinleri aynen (NFR-B1'in DX yarısı).\n if (typeof s.text === \"boolean\") {\n throw new Error(`table ${name}: text:${String(s.text)} yalnız yeni biçimde ('from' ile) geçerli`);\n }\n if (s.text === undefined && s.vector === undefined) {\n throw new Error(\n `table ${name}: search beyanı boş — en az bir kol (text ya da vector) verin, yoksa alanı hiç yazmayın`,\n );\n }\n if (s.text !== undefined && s.text.length === 0) {\n throw new Error(`table ${name}: search.text boş olamaz — FTS kolu istemiyorsan alanı hiç yazma`);\n }\n const legs = s.vector === undefined ? [] : Array.isArray(s.vector) ? s.vector : [s.vector];\n for (const leg of legs) {\n if (leg.model !== undefined && (leg.from === undefined || leg.from.length === 0)) {\n throw new Error(`table ${name}: search.vector.model beyan edildi ama 'from' yok — embed kaynağı kolonlar zorunlu (C-2)`);\n }\n if (leg.model === undefined && leg.from !== undefined) {\n throw new Error(`table ${name}: search.vector.from model'siz anlamsız — auto-embed için model verin`);\n }\n }\n }\n def.search = s;\n }\n if (input.memory !== undefined) {\n if (input.memory.from.length === 0) {\n throw new Error(`table ${name}: memory.from boş olamaz`);\n }\n def.memory = input.memory;\n }\n // The stamp goes on the COPIES, after the def exists — that is how a\n // reference thunk names its target when `defineSchema` resolves it.\n for (const b of Object.values(owned as Record<string, unknown>)) {\n (b as { _def: { ownerTable?: unknown } })._def.ownerTable = def;\n }\n // Columns are the enumerable surface; metadata hangs off a non-enumerable\n // symbol so it survives spreads and cannot be shadowed by a column name.\n const handle = { ...(owned as Record<string, unknown>) } as TableHandle<C, N>;\n Object.defineProperty(handle, TABLE_META, { value: def, enumerable: false });\n return handle;\n}\n\n/**\n * Which schema declared a table.\n *\n * A `TableDef` cannot carry it: `defineTable` runs before any schema exists, and\n * `defineSchema` is where the answer arrives. It lives OUTSIDE the def rather\n * than on it because the def is serialized — a field here would either leak into\n * the wire shape or need a second rule saying not to. A WeakMap keyed by the def\n * object is the same fact with no surface.\n *\n * It exists because a foreign key names its target and that name is only half a\n * name without the schema. `resolveReferences` reads it to write the referent\n * the way `qualifiedTableKey` writes every other table name.\n */\nconst declaringSchemaOf = new WeakMap<object, string>();\n\n/**\n * Resolve every pending reference thunk.\n *\n * Runs inside `defineSchema`, where all table bindings exist and every table\n * already carries its name — which is why the name lives on the table and not in\n * a dictionary key: resolving against a table that does not yet know what it is\n * called would need a second pass over an empty-name intermediate state.\n *\n * The written referent follows the ONE naming convention (`qualifiedTableKey`):\n * a `public` table is bare, anything else is schema-qualified. The deciding fact\n * is the REFERENT's schema, not whether the key crosses a schema boundary —\n * exactly the CASE Go's introspection uses when it reads a live FK back\n * (`introspect.go`: `CASE WHEN rn.nspname = 'public' THEN rt.relname ELSE\n * rn.nspname || '.' || rt.relname END`). Writing `invoices` for a table that\n * lives in `billing` made Go read it as `public.invoices`: a FK onto a table\n * that does not exist, or — worse and silently — onto a DIFFERENT table that\n * happened to share the name.\n */\nfunction resolveReferences(tables: Record<string, TableDef>, schemaName: string): void {\n for (const table of Object.values(tables)) {\n // ÇAPRAZ ŞEMA HEDEFLERİ: bileşik FK, freeze ve guard'ın `.exists()`'i.\n //\n // Üçü de builder anında yalnız hedefin ADINI biliyordu ve ÇIPLAK yazıyordu.\n // Kolon başına yolun bu satırların hemen altında kapattığı sessizliğin ta\n // kendisi — ve Go tarafındaki bedeli üç katlı: `REFERENCES orders` ya 42P01\n // ya YANLIŞ tabloya FK; `compositeFKEqual` canlının nitelikli adıyla hiç\n // eşleşmiyor (her push DROP+ADD, kalıcı drift); `validateCompositeFKs`\n // anahtar denetimini sessizce atlıyor. Guard'da daha da kötü: gövde ÇALIŞMA\n // ANINDA ayrıştırılıyor, yani hata KULLANICININ yazması sırasında geliyor.\n qualifyRefTargets(table, `table \"${table.name}\"`);\n }\n for (const table of Object.values(tables)) {\n for (const [colName, builder] of Object.entries(table.columns)) {\n const def = (builder as { _def: ColumnDefLike })._def;\n if (def.selfRefColumn !== undefined) {\n if (!(def.selfRefColumn in table.columns)) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": selfReferences(\"${def.selfRefColumn}\") — no such column on this table`,\n );\n }\n // A self-reference is a reference: its referent is this table, in THIS\n // schema, so it is written by the same rule as any other.\n def.references = {\n table: qualifiedTableKey(schemaName, table.name),\n column: def.selfRefColumn,\n };\n continue;\n }\n if (def.referencesThunk === undefined) continue;\n const target = def.referencesThunk();\n const owner = (target as { _def?: ColumnDefLike } | undefined)?._def?.ownerTable;\n if (owner === undefined) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": references(() => …) must point at a column of a table declared with defineTable(...)`,\n );\n }\n const targetColumn = Object.entries(owner.columns).find(\n ([, b]) => (b as { _def: unknown })._def === (target as { _def: unknown })._def,\n )?.[0];\n if (targetColumn === undefined) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": the referenced column was not found on table \"${owner.name}\"`,\n );\n }\n const targetSchema = declaringSchemaOf.get(owner);\n if (targetSchema === undefined) {\n // Assuming `public` here is the exact silence this resolution closes:\n // it would produce a FK onto a table that does not exist, or onto a\n // same-named one that does. Name the gap instead.\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": references(() => …) points at table ` +\n `\"${owner.name}\", which no defineSchema(...) has claimed yet — a foreign key cannot ` +\n `be written without its target's schema. Declare that table's schema first ` +\n `(one file per schema: db/public.ts, db/billing.ts …, imported by this one).`,\n );\n }\n def.references = {\n table: qualifiedTableKey(targetSchema, owner.name),\n column: targetColumn,\n };\n }\n }\n}\n\ntype ColumnDefLike = {\n references?: { table: string; column: string };\n referencesThunk?: () => unknown;\n selfRefColumn?: string;\n ownerTable?: { name: string; columns: Record<string, unknown> };\n};\n\n/**\n * Collect declared tables into one schema.\n *\n * Takes an ARRAY, not a dictionary: the tables already carry their names, and a\n * second name source is a second thing that can disagree.\n */\nexport function defineSchema<const T extends readonly TableHandle[]>(\n name: string,\n input: { tables: T; exposed?: boolean; extensions?: PalbaseExtension[] },\n): SchemaDef<TablesByName<T>> {\n // The TYPE first, then the value. The retired one-argument form passes an\n // object here, and a guard that only asks whether the name is blank calls\n // `.trim()` on it — which threw `name.trim is not a function` out of the child\n // process that runs `db/*.ts` during push: no file, no form, nothing to act\n // on. `references(\"t\", \"c\")` already answers its own retirement by name.\n if (typeof name !== \"string\") {\n throw new Error(\n `defineSchema(...) takes the schema NAME first: ` +\n `defineSchema(\"public\", { tables: [todos, lists] }). ` +\n `The one-argument form defineSchema({ tables: { … } }) is gone — a schema that does not ` +\n `say its own name cannot be told apart from another schema's table of the same name, ` +\n `which is what a cross-schema foreign key has to do. ` +\n `Migrate db/public.ts (one file per schema: db/public.ts, db/billing.ts …): name the ` +\n `schema, and lift each table key onto the table itself with ` +\n `defineTable(\"todos\", { columns: { … } }), then list the tables in the array.`,\n );\n }\n if (name.trim() === \"\") {\n throw new Error(\"defineSchema(name, …): name must not be empty\");\n }\n const tables = {} as Record<string, TableDef>;\n for (const handle of input.tables) {\n const table = handle[TABLE_META];\n if (tables[table.name] !== undefined) {\n throw new Error(\n `defineSchema(\"${name}\"): two tables declare the name \"${table.name}\" — table names must be unique within a schema`,\n );\n }\n tables[table.name] = table;\n // Stamped BEFORE resolution: a reference from this schema to a sibling in it\n // must find the sibling's schema, and the sibling may be declared later in\n // the array than the table pointing at it.\n declaringSchemaOf.set(table, name);\n }\n // Thunks are invoked HERE: every binding exists and every name is already set.\n resolveReferences(tables, name);\n // memory beyanları TABLOLAR-ARASI doğrulanır (into/subject/fact) — tüm\n // tablolar kurulduktan sonra: beyan sırasına bağımlılık olmasın (FR-032).\n for (const [name, def] of Object.entries(tables)) {\n const m = (def as TableDef).memory;\n if (m === undefined) continue;\n const target = Object.values(tables).find((t) => (t as TableDef).name === m.into) as TableDef | undefined;\n if (target === undefined) {\n throw new Error(`table ${name}: memory.into \"${m.into}\" şemada declared değil`);\n }\n const subject = m.subject ?? \"owner\";\n if (!(subject in (def as TableDef).columns)) {\n throw new Error(`table ${name}: memory.subject \"${subject}\" kolonu kaynak tabloda yok`);\n }\n if (!(subject in target.columns)) {\n throw new Error(`table ${name}: memory.subject \"${subject}\" kolonu hedef \"${m.into}\" tablosunda yok`);\n }\n const factCol = target.columns[\"fact\"];\n const factDef = factCol !== undefined && \"_def\" in (factCol as object)\n ? (factCol as { _def: { type?: string } })._def\n : (factCol as { type?: string } | undefined);\n if (factDef === undefined || factDef.type !== \"text\") {\n throw new Error(`table ${name}: memory.into \"${m.into}\" tablosunda \"fact\" (text) kolonu zorunlu`);\n }\n for (const c of m.from) {\n if (!(c in (def as TableDef).columns)) {\n throw new Error(`table ${name}: memory.from kolonu \"${c}\" kaynak tabloda yok`);\n }\n }\n }\n // Dedupe + normalize extensions (order-independent; deploy resolves deps).\n const extensions = [...new Set(input.extensions ?? [])];\n // Declaring a schema is not the same as putting it on the internet, so\n // `exposed` is false unless the author says otherwise — EXCEPT for `public`,\n // which is reachable today and stays reachable. Making the default uniform\n // would silently 404 every existing project's /v1/db traffic on upgrade.\n return {\n name,\n tables: tables as TablesByName<T>,\n extensions,\n exposed: input.exposed ?? name === \"public\",\n };\n}\n\nexport { backfill, check, foreignKey, freeze, guard, toForeignKeyDef, toFreezeDef, toGuardDef };\nexport type { BackfillDef, CheckDef, ForeignKeyBuilder, ForeignKeyDef, FreezeBuilder, FreezeDef, GuardBuilder, GuardDef };\n\n/**\n * qualifyRefTargets, bir tablonun taşıdığı çapraz şema hedeflerini ŞEMASIYLA\n * niteler — ve şema bilinmiyorsa REDDEDER.\n *\n * `declaringSchemaOf` `defineSchema` tarafından damgalanıyor, yani bir hedefin\n * şeması ancak o tablo bir şemada bildirilmişse biliniyor. Bilinmiyorsa `public`\n * VARSAYMAK, kolon başına yolun adıyla kapattığı sessizliğin aynısı olurdu:\n * var olmayan bir tabloya ya da aynı adlı BAŞKA bir tabloya referans.\n */\nfunction qualifyRefTargets(table: TableDef, where: string): void {\n const qualify = (holder: { refTable?: string; table?: string }, what: string): void => {\n const target = (holder as { [REF_TARGET]?: TableDef })[REF_TARGET];\n if (target === undefined) return;\n const targetSchema = declaringSchemaOf.get(target);\n if (targetSchema === undefined) {\n throw new Error(\n `${where}: ${what} points at table \"${target.name}\", which no defineSchema(...) has claimed yet — ` +\n `a cross-table reference cannot be written without its target's schema. Declare that table's ` +\n `schema first (one file per schema: db/public.ts, db/billing.ts …, imported by this one).`,\n );\n }\n const qualified = qualifiedTableKey(targetSchema, target.name);\n if (holder.refTable !== undefined) holder.refTable = qualified;\n if (holder.table !== undefined) holder.table = qualified;\n };\n\n for (const fk of table.foreignKeys ?? []) qualify(fk, `foreignKey(\"${fk.name}\")`);\n for (const fz of table.freeze ?? []) qualify(fz, `freeze(\"${fz.name}\")`);\n for (const g of table.guards ?? []) {\n if (g.exists !== undefined) {\n qualifyExistsNodes(g.exists as Record<string, unknown>, `guard(\"${g.name}\").exists(...)`, where);\n }\n }\n}\n\n/** İç içe `exists` düğümlerini de niteler — yüklem başka bir tabloya bakabilir. */\nfunction qualifyExistsNodes(node: Record<string, unknown>, what: string, where: string): void {\n if (node === null || typeof node !== \"object\") return;\n if (node.kind === \"exists\") {\n const target = (node as { [REF_TARGET]?: TableDef })[REF_TARGET];\n if (target !== undefined) {\n const targetSchema = declaringSchemaOf.get(target);\n if (targetSchema === undefined) {\n throw new Error(\n `${where}: ${what} points at table \"${target.name}\", which no defineSchema(...) has claimed yet — ` +\n `a guard body is parsed at RUN TIME under a pinned search_path, so an unqualified name never resolves.`,\n );\n }\n node.table = qualifiedTableKey(targetSchema, target.name);\n }\n }\n for (const v of Object.values(node)) {\n if (Array.isArray(v)) {\n for (const e of v) qualifyExistsNodes(e as Record<string, unknown>, what, where);\n } else if (v !== null && typeof v === \"object\") {\n qualifyExistsNodes(v as Record<string, unknown>, what, where);\n }\n }\n}\n","/**\n * channels.ts — the realtime channel authorization DSL (spec C-5).\n *\n * `defineChannels({...})` is evaluated at bundle load; the declaration is\n * anchored on globalThis under Symbol.for (the error-registry.ts pattern) so\n * the runtime — a separate module instance — reads the SAME object. The runtime\n * empties that slot before each bundle import and puts it back afterwards, so\n * the declaration belongs to the bundle that made it and not to the process.\n * Entry ORDER is the object's key order and is semantic: first match wins.\n *\n * Undeclared channels are DENIED by the server (fail-closed). ownerOnly()\n * patterns resolve with ZERO server hops; custom entries' authorize() runs\n * in the customer's own runtime with the request scope a controller gets.\n */\n\nconst CHANNELS: unique symbol = Symbol.for(\"palbase.backend.channels\") as never;\n\nexport interface ChannelGrant {\n subscribe: boolean;\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n\nexport interface ChannelAuthorizeCtx {\n user: { id: string };\n params: Record<string, string>;\n}\n\ninterface OwnerEntry { kind: \"owner\" }\ninterface PublicEntry {\n kind: \"public\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n/** What a handler receives: who published, on which channel, and what. */\nexport interface ChannelHandlerCtx {\n user: { id: string };\n params: Record<string, string>;\n channel: string;\n event: string;\n payload: Record<string, unknown>;\n}\n\ninterface CustomEntry {\n authorize: (ctx: ChannelAuthorizeCtx) => ChannelGrant | null | Promise<ChannelGrant | null>;\n /**\n * Take over publishes on this channel instead of fanning them out.\n *\n * Without it, `channel.send(...)` is relayed to the other subscribers\n * verbatim — fine for a chat message, wrong for anything the client should\n * not be trusted to assert. A bid, a vote, a game move is a REQUEST, and the\n * result is whatever this function decides and then publishes (through\n * `Realtime.broadcast` or `Realtime.state.set`).\n *\n * A function rather than the name of a route: `authorize` is already one and\n * runs in this same scope, so naming an endpoint would mean inventing a\n * resolution step for no gain.\n */\n handler?: (ctx: ChannelHandlerCtx) => void | Promise<void>;\n}\nexport type ChannelEntry = OwnerEntry | PublicEntry | CustomEntry;\nexport type ChannelsInput = Record<string, ChannelEntry>;\n\nexport interface ChannelsDef {\n entries: Array<{\n pattern: string;\n kind: \"owner\" | \"public\" | \"custom\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n authorize?: CustomEntry[\"authorize\"];\n handler?: CustomEntry[\"handler\"];\n }>;\n}\n\n/** Full-access-to-the-owner pattern: the pattern must carry EXACTLY one {param};\n * the server compares its value to the verified token subject with zero hops. */\nexport function ownerOnly(): OwnerEntry {\n return { kind: \"owner\" };\n}\n\n/** Anyone with a valid token may subscribe; publish/state are explicit opt-ins. */\nexport function publicChannel(\n opts: { publish?: boolean; state?: { read?: boolean; write?: boolean } } = {},\n): PublicEntry {\n return { kind: \"public\", publish: opts.publish ?? false, state: opts.state };\n}\n\nfunction paramCount(pattern: string): number {\n return pattern.split(\":\").filter((s) => s.startsWith(\"{\") && s.endsWith(\"}\")).length;\n}\n\nexport function defineChannels(map: ChannelsInput): ChannelsDef {\n const entries: ChannelsDef[\"entries\"] = [];\n for (const [pattern, entry] of Object.entries(map)) {\n if (\"kind\" in entry && entry.kind === \"owner\") {\n if (paramCount(pattern) !== 1) {\n throw new Error(\n `defineChannels: ownerOnly() pattern \"${pattern}\" must carry exactly one {param} ` +\n `(its value is compared to the token subject)`,\n );\n }\n entries.push({ pattern, kind: \"owner\" });\n } else if (\"kind\" in entry && entry.kind === \"public\") {\n entries.push({ pattern, kind: \"public\", publish: entry.publish, state: entry.state });\n } else {\n const c = entry as CustomEntry;\n entries.push({ pattern, kind: \"custom\", authorize: c.authorize, handler: c.handler });\n }\n }\n const def: ChannelsDef = { entries };\n\n // A SECOND, DIFFERENT declaration is a hard error rather than an overwrite.\n //\n // The same bundle can legitimately be evaluated twice in one process — the\n // error registry beside this file documents exactly that case — so an\n // identical re-declaration passes silently. But two DIFFERENT declarations\n // mean two channels files, and overwriting would delete the first one's\n // channels. Undeclared channels are DENIED, so the symptom would be joins\n // refused in production for channels the developer can see declared in their\n // own source, with nothing anywhere saying why. Loud here beats silent there.\n //\n // \"Already\" means WITHIN ONE BUNDLE LOAD. The runtime hands each import an\n // empty slot, so this compares two calls from the same bundle — which is what\n // it was written for. It used to reach across imports as well, and then a\n // deploy that merely ADDED a channel was refused as a second channels file,\n // with a message pointing at a file the customer did not have.\n const carrier = globalThis as Record<symbol, unknown>;\n const existing = carrier[CHANNELS] as ChannelsDef | undefined;\n if (existing && !sameDeclaration(existing, def)) {\n throw new Error(\n `defineChannels: channels were already declared (${existing.entries.length} ` +\n `pattern(s): ${existing.entries.map((e) => e.pattern).join(\", \")}). ` +\n `A project declares its channels ONCE — a second call would overwrite the ` +\n `first, and channels nobody declared are refused.`,\n );\n }\n carrier[CHANNELS] = def;\n return def;\n}\n\n/**\n * One entry as the runtime will compile it, rendered for comparison.\n *\n * NORMALIZED, because the runtime normalizes: `collectChannels` applies\n * `?? false` to publish and both state flags before the table goes on the wire.\n * Comparing the raw entries called two spellings of ONE entry a conflict —\n * `publicChannel()` fills `publish: false` where a hand-written\n * `{ kind: \"public\" }` leaves it undefined, and the two produce a byte-identical\n * table. There is one source of truth for what an entry IS, and it is the row.\n *\n * The authorize function is compared by SOURCE TEXT. Comparing the closures\n * themselves is wrong — two evaluations of one module produce two distinct\n * functions for the same source, which is the case this guard has to let\n * through — but comparing only `Boolean(fn)` called two unrelated\n * authorization rules \"the same declaration\", so the guard stayed silent while\n * one channel's access rule was swapped for another's. Same source, same text;\n * different logic, different text. Not exhaustive (two closures over different\n * captured values share a source), and better than a boolean by the whole\n * distance between \"some rule\" and \"this rule\".\n */\nfunction wireRow(e: ChannelsDef[\"entries\"][number]): string {\n return JSON.stringify([\n e.pattern,\n e.kind,\n e.publish ?? false,\n e.state?.read ?? false,\n e.state?.write ?? false,\n // The handler is compared by SOURCE, like authorize: two evaluations of one\n // module give the same text, while different logic gives different text.\n e.handler ? e.handler.toString() : \"\",\n e.authorize ? e.authorize.toString() : \"\",\n ]);\n}\n\n/** Two declarations are the same when they compile to the same rows in the same\n * ORDER — order is semantic here (first match wins). */\nfunction sameDeclaration(a: ChannelsDef, b: ChannelsDef): boolean {\n if (a.entries.length !== b.entries.length) return false;\n return a.entries.every((x, i) => wireRow(x) === wireRow(b.entries[i]!));\n}\n","/**\n * Postgres extensions a Palbase project can enable from its schema.\n *\n * Extensions are config-as-code: declare them in `defineSchema({ extensions })`\n * and the deploy installs them (CREATE EXTENSION … SCHEMA extensions) using the\n * deploy path's privileged connection. They are NOT toggled live from Studio —\n * CREATE EXTENSION requires a superuser role that only the deploy path holds.\n *\n * The list is an allowlist (a string-literal union) so editors autocomplete the\n * supported names and a typo fails typecheck. It is intentionally extensible:\n * add a name here (+ confirm the base image ships it) to support more.\n */\nexport const PALBASE_EXTENSIONS = [\n // Search & text\n \"vector\", // pgvector: AI embeddings + vector similarity search (semantic search / RAG).\n // NB: the Postgres extension is named \"vector\", not \"pgvector\" — declare \"vector\".\n \"pg_trgm\", // trigram fuzzy / typo-tolerant text search\n \"unaccent\", // accent-insensitive text search\n \"citext\", // case-insensitive text type\n // Geospatial / location\n \"cube\", // multi-dimensional cubes (dependency of earthdistance)\n \"earthdistance\", // great-circle distance (needs cube)\n // Data types & structures\n \"hstore\", // key/value pairs in a single column\n \"ltree\", // hierarchical tree-structured labels\n // Indexing & constraints\n \"btree_gist\", // GiST operator classes for scalar types — needed for EXCLUDE\n // constraints that mix \"=\" with a range/&& overlap (e.g. no-double-booking).\n // Scheduling\n // Crypto / ids (also installed by default; listable for explicitness)\n \"pgcrypto\", // cryptographic functions (hashing, encryption)\n \"uuid-ossp\", // UUID generation functions\n] as const;\n\n/** A Postgres extension supported by Palbase (allowlist union). */\nexport type PalbaseExtension = (typeof PALBASE_EXTENSIONS)[number];\n\n/**\n * Extensions that depend on another extension. The deploy installs\n * dependencies first; declaring `earthdistance` without `cube` still works\n * because the deploy resolves the order, but listing both is clearer.\n */\nexport const EXTENSION_DEPENDENCIES: Partial<Record<PalbaseExtension, PalbaseExtension[]>> = {\n earthdistance: [\"cube\"],\n};\n\n/** Runtime guard: is `name` a supported Palbase extension? */\nexport function isPalbaseExtension(name: string): name is PalbaseExtension {\n return (PALBASE_EXTENSIONS as readonly string[]).includes(name);\n}\n","/** On delete action for foreign key references. */\nexport type OnDeleteAction = 'cascade' | 'set null' | 'restrict' | 'no action';\n\n/**\n * The ON DELETE actions permitted on a foreign key to the built-in auth users\n * (`auth.users`). Both let a user's rows be removed (`cascade`) or detached\n * (`set null`) when the account is erased; `restrict` / `no action` would BLOCK\n * erasure and are therefore excluded. This is the CLIENT-SIDE mirror of the\n * server's auth-FK deletion policy — the server (validateAuthUserFK) is the real\n * boundary, this narrows the type so the common mistake is caught at compile time.\n */\nexport type AuthUserOnDelete = Extract<OnDeleteAction, 'cascade' | 'set null'>;\n\n/** Column type identifiers. */\nexport type ColumnType =\n | 'uuid'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'numeric'\n | 'boolean'\n | 'timestamp'\n | 'jsonb'\n | 'enum'\n | 'vector';\n\n/** Base column definition shared by all column types. */\nexport interface ColumnDef {\n type: ColumnType;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n references?: { table: string; column: string };\n /** Pending FK target, resolved by `defineSchema` once every binding exists. */\n referencesThunk?: () => ColumnBuilder;\n /** FK onto THIS table — no thunk needed, the target is the declaring table. */\n selfRefColumn?: string;\n /** This column OWNS the row: erasure, RLS and the `owner` relation read it. */\n owns?: true;\n /** Explicit name for the FORWARD relation (child → parent), when the one\n * derived from the column would be ambiguous or unclear. */\n refAs?: string;\n /**\n * Explicit name for the REVERSE relation (parent → children).\n *\n * Separate from {@link refAs} because the two directions are different facts:\n * the forward name describes the parent this row points at (`author`), the\n * reverse one describes the rows hanging off the parent (`posts`). One option\n * naming both made an ordinary schema undeclarable — `posts.author_id` and\n * `comments.author_id` both named `{ as: \"author\" }` collided on `users`, and\n * the refusal asked for the `{ as }` they had both already written.\n */\n reverseAs?: string;\n /** The table this column belongs to; set by `defineTable`. */\n ownerTable?: { name: string; columns: Record<string, ColumnBuilder> };\n /**\n * The name this column used to have. A diff cannot tell a rename from a drop and\n * an add — both leave one name gone and another present — so the intent has to be\n * declared. Without it, renaming a column loses its data.\n */\n renamedFrom?: string;\n /**\n * This release's PROMISE that it does not reference this column — neither\n * reads it nor writes it, and never names it in a filter, a sort or a SET.\n *\n * The contraction gate reads it and nothing else does: dropping a column is\n * refused while the RUNNING release's declaration still lacks this mark, so\n * removing a column is two deploys — mark it, ship, then drop it.\n *\n * The word is `ignored` and not `deprecated` deliberately: RFC 9745 defines\n * deprecation as changing NO behaviour, and this changes what a deploy will\n * accept. Rails calls the same thing `ignored_columns`.\n */\n ignored?: boolean;\n onDeleteAction?: OnDeleteAction;\n /** FR-044: yalnız AÇIKÇA `false` bildirilince var. Türev FK index'ini kapatır. */\n index?: boolean;\n /** FR-049: kolon `increment()` ile güncelleniyor. Plan HOT çakışmasını uyarır. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n /**\n * The value is written by the DATABASE — a trigger, a rule, an identity — not by\n * the author and not by a DEFAULT this schema declares. It makes the column\n * optional on INSERT without putting a DEFAULT in the DDL.\n *\n * Before this existed the only way to keep a trigger-filled column off the\n * INSERT type was to give it a fake `default()`: a value the schema claimed to\n * write and the trigger immediately overwrote. That made the schema lie about\n * its own data.\n */\n dbAssigned?: boolean;\n /** vector(n): the declared dimension count — part of the TYPE (typmod), read\n * by the wire serializer and the deploy's auto-index (FR-001). */\n dimensions?: number;\n /**\n * How the stored value is projected in and out of this process (FR-009).\n *\n * NOT part of the DDL: the column's Postgres type is unchanged and this pair\n * is never serialized into a migration. It exists so the row surface can hand\n * back the type the application actually works with.\n */\n /**\n * The named codec this column declares (FR-001). Unlike `transform`, the NAME\n * survives into the runtime object, so `makeEnvDts` can emit the matching\n * TypeScript type instead of falling back to the storage type. Not part of\n * the DDL: the column's Postgres type is unchanged.\n */\n codec?: CodecName;\n transform?: ColumnTransform;\n}\n\n/**\n * The read/write pair a column may declare (FR-009).\n *\n * `fromDb` takes whatever the driver produced for this column and returns the\n * value the application sees; `toDb` is its inverse on the way out. Kept\n * deliberately unexported — a column declares one inline, nobody needs to name\n * the shape.\n */\ninterface ColumnTransform<T = unknown> {\n fromDb: (value: unknown) => T;\n toDb: (value: T) => unknown;\n}\n\n/**\n * The closed set of named column codecs (FR-001).\n *\n * WHY A CLOSED SET rather than `.transform<T>()`. A transform's target type is\n * a TYPE parameter — erased at runtime — so the generator that reads the\n * bundled schema object cannot learn it. `palbase-env.d.ts` therefore said\n * `string` while the engine handed the application a number, and a consumer\n * project wrote a hand-rolled codec module plus 141 call sites to compensate.\n *\n * A codec is NAMED instead of typed: the name lands in `_def.codec`, travels in\n * the runtime object to every reader, and BOTH the conversion and the emitted\n * TypeScript type are derived from it. One declaration, one truth, and no way\n * for the two to disagree.\n */\nexport type CodecName = 'number' | 'decimal';\n\nexport const CODECS: Record<\n CodecName,\n { fromDb: (value: unknown) => unknown; toDb: (value: unknown) => unknown; tsType: 'number' | 'string' }\n> = {\n // Exact-precision column → JS number. Safe below 2^53; a value above it is\n // not representable and the author wants `asDecimal()` instead.\n number: {\n fromDb: (v) => Number(v),\n // YAZMA YOLUNDA SESSİZ BOZULMA YOK. `toDb(9007199254740993)` bir zamanlar\n // \"9007199254740992\" yazıyordu: uygulamanın tuttuğundan BAŞKA bir sayı\n // kolona gidiyordu ve hiçbir şey söylemiyordu. `asNumber()`'ın JSDoc'u\n // \"2^53'ün altında güvenli\" diyordu ama bunu uygulayan bir şey yoktu.\n toDb: (v) => {\n if (typeof v === 'number' && !Number.isSafeInteger(v)) {\n throw new Error(\n `asNumber() cannot write ${v}: it is outside the safe integer range and would be stored as a different number. Declare .asDecimal() and hand this column a string.`,\n );\n }\n return String(v);\n },\n tsType: 'number',\n },\n // Exact-precision column → the string Postgres sent. It exists so the\n // DECLARATION is explicit: \"this column is a decimal I handle as text\",\n // rather than the ABSENCE of a declaration meaning the same thing by default.\n // NULL güvencesi ÇİFTİN KENDİSİNDE. Motor NULL'ı zaten atlıyor (üç ayrı\n // yerde), ama bir değişmez, onu koruyan üç `if`'in DIŞINDA yazılmalı: biri\n // düşerse `String(null)` kolonu \"null\" dizesine çevirirdi.\n decimal: {\n fromDb: (v) => (v === null || v === undefined ? v : String(v)),\n toDb: (v) => (v === null || v === undefined ? v : String(v)),\n tsType: 'string',\n },\n};\n\n/** FR-002: a vector column cannot carry keys/defaults/references — the modifier\n * is named in the error so the author fixes the right line. */\nfunction refuseOnVector(def: ColumnDef, modifier: string): void {\n if (def.type === 'vector') {\n throw new Error(`vector column: .${modifier}() is not supported (FR-002 — allowed: nullable()/notNull())`);\n }\n}\n\n// Phantom brand symbols — never have runtime values; exist only to force\n// TypeScript's structural type system to distinguish ColumnBuilder instances\n// with different type-param combinations. Without these, TS sees all\n// ColumnBuilder<K,...> as structurally identical and the first branch of\n// ColValue matches everything.\ndeclare const __colKind: unique symbol;\ndeclare const __colNullable: unique symbol;\ndeclare const __colHasDefault: unique symbol;\ndeclare const __colEnumValues: unique symbol;\ndeclare const __colPayload: unique symbol;\ndeclare const __colTransform: unique symbol;\n\n/**\n * Fluent column builder with phantom type params:\n * K — ColumnType literal (e.g. \"text\", \"integer\")\n * N — boolean: true when nullable() has been called last (false = NOT NULL)\n * D — boolean: true when a default has been set\n * E — enum value union (never for non-enum columns)\n * P — jsonb payload shape (unknown unless jsonb<T>() supplied one)\n * T — transform target type (`never` when the column declares no transform;\n * `never` is the sentinel because it is the only type that survives\n * `[T] extends [never]` and never collides with a real target type)\n *\n * All six params have defaults so bare `ColumnBuilder` (no args) still\n * satisfies `Record<string, ColumnBuilder>` in schema.ts without modification.\n *\n * The six `declare readonly` brand fields carry the phantom types into the\n * structural shape so that conditional types like ColValue<C> can discriminate\n * on K without requiring runtime values on those fields.\n */\nexport class ColumnBuilder<\n K extends ColumnType = ColumnType,\n N extends boolean = boolean,\n D extends boolean = boolean,\n E = unknown,\n P = unknown,\n // `unknown`, not `never`: the schema's own constraint is a BARE\n // `ColumnBuilder`, whose T lands on this default. With `never` there, a\n // column that declares `.transform<number>()` is not assignable to the\n // constraint at all — `number` does not extend `never` — so a transform\n // could not appear in a schema and the whole table's `RowShape` collapsed.\n // Measured: TS2322 on `defineSchema`.\n T = unknown,\n> {\n // These fields exist only in the type layer (declared, never initialised at\n // runtime — TypeScript allows declared class members without an initializer\n // in strict mode as long as they're never read at runtime).\n declare readonly [__colKind]: K;\n declare readonly [__colNullable]: N;\n declare readonly [__colHasDefault]: D;\n declare readonly [__colEnumValues]: E;\n declare readonly [__colPayload]: P;\n declare readonly [__colTransform]: T;\n\n readonly _def: ColumnDef;\n\n constructor(type: K, existingDef?: ColumnDef) {\n this._def = existingDef ?? {\n type,\n nullable: false,\n primaryKey: false,\n };\n }\n\n /** Mark this column as the primary key. */\n primaryKey(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'primaryKey');\n this._def.primaryKey = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Mark this column as NOT NULL (default). */\n notNull(): ColumnBuilder<K, false, D, E, P, T> {\n this._def.nullable = false;\n return new ColumnBuilder<K, false, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Allow NULL values. */\n nullable(): ColumnBuilder<K, true, D, E, P, T> {\n this._def.nullable = true;\n return new ColumnBuilder<K, true, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Set a default value. */\n default(value: unknown): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'default');\n this._def.defaultValue = value;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** UUID: generate a random default (gen_random_uuid()). */\n defaultRandom(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultRandom');\n this._def.defaultRandom = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Timestamp: default to now(). */\n defaultNow(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultNow');\n this._def.defaultNow = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * The DATABASE assigns this column's value — a trigger, a rule, an identity.\n *\n * The column becomes optional on INSERT (the author has nothing to send) while\n * the DDL stays free of a DEFAULT this schema would not honour. It is NOT\n * `default()`: that declares a value the schema promises to write.\n *\n * Naming: deliberately not `generated()`. Postgres has GENERATED columns and\n * they are a different thing; borrowing the word would send a reader — or a\n * model writing a schema — to the wrong feature.\n */\n dbAssigned(): ColumnBuilder<K, N, true, E, P, T> {\n this._def.dbAssigned = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a foreign key reference. */\n /**\n * Declares that this column used to be called `previous`.\n *\n * A schema diff sees one name gone and another present; it cannot know whether\n * you renamed a column or dropped one and added another, and the two are very\n * different — the second loses every value. Saying so here turns the plan into\n * `ALTER TABLE … RENAME COLUMN` instead.\n *\n * Once the rename has been applied the annotation is inert (the old name is no\n * longer there to rename), so it can be deleted at your leisure.\n */\n renamedFrom(previous: string): ColumnBuilder<K, N, D, E, P, T> {\n this._def.renamedFrom = previous;\n return this as unknown as ColumnBuilder<K, N, D, E, P, T>;\n }\n\n /**\n * See {@link ColumnDef.ignored}.\n *\n * COPIES the def rather than mutating it. The constructor takes an existing\n * def BY REFERENCE, so every builder derived from another shares one object —\n * `const a = slug.unique()` leaves `a._def === slug._def`. An in-place\n * `ignored = true` therefore marks every column sharing that def, including\n * one another table actively reads, and the gate would let THAT column be\n * dropped. Measured before this copy existed.\n *\n * The aliasing is older than this method and other fields leak through it too.\n * The reason this one cannot wait: every other leak produces a VISIBLE schema\n * difference — the plan shows it, the DDL shows it. This one is invisible by\n * design (no DDL, no diff, no plan line), so its only effect is to disarm a\n * safety gate in silence.\n */\n ignored(): ColumnBuilder<K, N, D, E, P, T> {\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, {\n ...this._def,\n ignored: true,\n });\n }\n\n /**\n * Foreign key onto another table's column.\n *\n * The target is a THUNK, not a direct reference. In a cycle (`x → y`, `y → x`)\n * the second table does not exist yet when the first is built; a direct\n * reference makes TypeScript chase its own tail (TS7022 — measured, and making\n * the return type independent of the target does NOT help). The thunk is\n * invoked in `defineSchema`, where every binding exists and every table\n * already knows its name.\n *\n * In a cycle, ONE side needs an explicit return type:\n * `references((): AnyColumn => y.id)`. One side is enough — measured.\n * For a self-reference use `selfReferences(column)`: no thunk, no annotation.\n *\n * `as` names the FORWARD relation (`author_id` → `author` by default);\n * `reverseAs` names the REVERSE one on the parent, whose default is this\n * table's own name (`users.posts`). Two foreign keys from one table onto one\n * parent therefore need a `reverseAs` on at least one of them — the reverse\n * names would otherwise both be this table's name.\n */\n references(\n target: () => AnyColumn,\n opts?: {\n as?: string;\n reverseAs?: string;\n onDelete?: OnDeleteAction;\n /**\n * Bu FK kolonu için TÜREVİ index üretilsin mi (FR-044). Varsayılan açık.\n *\n * Postgres bir foreign key'i otomatik indekslemez — yalnız hedef\n * taraftaki unique kısıt vardır. Bedeli FK üzerinden her JOIN'de ve her\n * `ON DELETE CASCADE`'de ödenir: bir parent silinirken child tablo tam\n * taranır.\n *\n * `false` demek gerçek bir ihtiyaç, nezaket değil (D-028): FK kolonu aynı\n * zamanda SIK GÜNCELLENEN bir kolonsa index HOT güncellemeyi kırar — ve\n * HOT, DEĞİŞEN kolon indeksliyse kırılır, tablo indeksli diye değil.\n */\n index?: boolean;\n },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'references');\n if (typeof target !== 'function') {\n // Fail where the mistake is. Storing a non-thunk here surfaces three\n // layers later as \"def.referencesThunk is not a function\", inside\n // defineSchema, naming neither the column nor the call that was wrong.\n throw new Error(\n `references(...) takes a callback: write references(() => otherTable.column). ` +\n `The two-string form references(\"table\", \"column\") is gone — a string cannot be type-checked ` +\n `and cannot point at a table that does not exist yet.`,\n );\n }\n this._def.referencesThunk = target;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.reverseAs !== undefined) this._def.reverseAs = opts.reverseAs;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n // Yalnız AÇIKÇA false bildirilince taşınıyor: `undefined` \"bildirilmedi,\n // türet\" demek ve wire'da hiç görünmemeli (bayt-aynılık).\n if (opts?.index === false) this._def.index = false;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Bu kolon `increment()` / `decrement()` ile güncelleniyor (FR-049).\n *\n * Deploy kontrolcü kodunu OKUMAZ, o yüzden bildirimin söylemesi gerekiyor —\n * ve söylediği anda plan bir şeyi görebiliyor: aynı kolon hem sayaç hem\n * indeksliyse her güncelleme HOT'u kaybeder.\n *\n * ZİNCİR (D-028+D-030): HOT kaybı → ölü tuple → autovacuum yükü → ve\n * autovacuum worker'ları KÜME GENELİNDE bir kaynak, yani bedeli başka\n * kiracıların tabloları da öder.\n *\n * Sektörde çare \"dokümana uyarı yaz\"dır, çünkü index'i ekleyen kişi\n * `increment()`'i yazan kişi değildir. Bu bildirimde ikisi de YAN YANA\n * duruyor.\n *\n * Uyarı, HATA DEĞİL: sayaç kolonunu indekslemek bazen doğru karardır.\n */\n counter(): ColumnBuilder<K, N, D, E, P, T> {\n this._def.counter = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Foreign key onto THIS table (`parent_id → id`) — category trees, comment\n * replies, org charts.\n *\n * No thunk and no type annotation: the target table is the one being declared,\n * so there is nothing to defer and nothing for TypeScript to chase in a circle.\n * Drizzle forces an explicit `(): AnyPgColumn =>` here because its reference\n * always goes through a callback; measured, we do not need one.\n */\n selfReferences(\n column: string,\n opts?: { as?: string; onDelete?: OnDeleteAction },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'selfReferences');\n this._def.selfRefColumn = column;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n\n\n /** Set the ON DELETE action for a foreign key reference. */\n onDelete(action: OnDeleteAction): ColumnBuilder<K, N, D, E, P, T> {\n this._def.onDeleteAction = action;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a single-column UNIQUE constraint. */\n unique(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'unique');\n this._def.unique = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Declare how this column's value is projected in and out of the process.\n *\n * The DDL does not move: `numeric` stays `numeric`, and the driver still hands\n * back what Postgres sent. What changes is the type the row surface exposes —\n * it becomes `Target`:\n *\n * amount: numeric().transform<number>({ fromDb: Number, toDb: String })\n *\n * `numeric` surfacing as `string` is CORRECT (a JS number cannot hold\n * arbitrary precision), and that is exactly why this exists: application code\n * that does arithmetic on the column otherwise rewrites the same\n * `Number(row.amount)` / `String(x)` pair in every controller that touches it,\n * and each rewrite is a place the two directions can drift apart.\n *\n * A transform is a PROJECTION, never a constraint: it lives only in this\n * process, so it can neither validate nor migrate what is stored.\n */\n /**\n * Surface this exact-precision column as a JS `number` (FR-001).\n *\n * `numeric`/`bigint` arrive as strings because a JS number cannot hold their\n * full range — correct, and exactly why this exists: application code that\n * does arithmetic on the column otherwise rewrites the same `Number(row.x)` /\n * `String(v)` pair in every caller, and each rewrite is a place the two\n * directions can drift apart.\n */\n asNumber(): ColumnBuilder<K, N, D, E, P, number> {\n return this.withCodec<number>('number', 'asNumber');\n }\n\n /**\n * Surface this exact-precision column as a `string` — the value Postgres\n * sent, DECLARED rather than defaulted (FR-001).\n */\n asDecimal(): ColumnBuilder<K, N, D, E, P, string> {\n return this.withCodec<string>('decimal', 'asDecimal');\n }\n\n private withCodec<Target>(codec: CodecName, method: string): ColumnBuilder<K, N, D, E, P, Target> {\n if (this._def.type !== 'bigint' && this._def.type !== 'numeric') {\n throw new Error(\n `${this._def.type} column: .${method}() is only available on bigint()/numeric() — ` +\n `those are the exact-precision types that surface as string.`,\n );\n }\n if (this._def.transform !== undefined) {\n throw new Error(\n `.${method}() and .transform() are two ways to say the same thing on one column — keep .${method}().`,\n );\n }\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares .as${this._def.codec === 'number' ? 'Number' : 'Decimal'}(); a column has ONE codec.`,\n );\n }\n // KOPYA, MUTASYON DEĞİL — `ignored()` gibi.\n //\n // `this._def.codec = codec` yazmak, ORTAK bir temelden çatallanan iki\n // kolonun ikisine de SON codec'i verirdi. Ölçüldü:\n // const money = numeric().notNull();\n // money.asNumber(); money.asDecimal();\n // → ikisinin de _def.codec === 'decimal', ve AYNI nesne.\n // Birincinin TİPİ `number`, üretecin bastığı tip `string` olurdu — yani bu\n // özelliğin kapatmak için var olduğu ayrışmanın ta kendisi.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n codec,\n });\n }\n\n transform<Target>(fns: ColumnTransform<Target>): ColumnBuilder<K, N, D, E, P, Target> {\n // AYNA KONTROLÜ. `asNumber()` mevcut bir transform'u reddediyor; burası da\n // mevcut bir codec'i reddetmeli, yoksa kapı TEK YÖNLÜ olur:\n // `numeric().asNumber().transform<Date>(…)` üç ayrı cevap üretirdi —\n // builder tipi `Date`, üretilen tip `number`, motor `Number()` uygular —\n // ve hiçbir şey adını söyleyerek reddetmezdi.\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares a named codec; .transform() and .as*() are two ways to say the same thing — keep the codec.`,\n );\n }\n // The cast is the variance, not a shortcut: `toDb` takes `Target`, and a\n // `ColumnTransform<unknown>` would have to accept anything. The stored pair\n // is only ever called with this column's own values.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n transform: fns as ColumnTransform,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Type extractors — imported by Task 2 to derive insert/row shapes.\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the TypeScript value type for a column, respecting nullability.\n * - \"uuid\" | \"text\" | \"timestamp\" | \"bigint\" | \"numeric\" → string (or string | null when N = true)\n * Note: bigint/numeric surface as string — JS number loses precision past 2^53,\n * and pgx/PostgREST serialize int8/numeric as strings. App code uses\n * BigInt(row.amount) for bigint, or a decimal lib for numeric.\n * - \"integer\" → number\n * - \"boolean\" → boolean\n * - \"jsonb\" → P (the dev-supplied payload shape from jsonb<T>(), else unknown)\n * - \"enum\" → E (the union of literal values)\n *\n * A declared `.transform<T>()` OVERRIDES the table above: the column then\n * surfaces as T (or T | null when nullable), because that is the value the\n * application is handed. Nullability is still the column's, not the\n * transform's — `fromDb` is not called for a NULL.\n */\nexport type ColValue<C> =\n C extends ColumnBuilder<ColumnType, infer N, boolean, unknown, unknown, infer T>\n ? [unknown] extends [T]\n ? ColStoredValue<C>\n : N extends true\n ? T | null\n : T\n : never;\n\n/** The value as the DATABASE hands it over — the branch table above, before any\n * transform. This is what a column's `fromDb` receives. */\ntype ColStoredValue<C> =\n C extends ColumnBuilder<'uuid' | 'text' | 'timestamp' | 'bigint' | 'numeric', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? string | null\n : string\n : C extends ColumnBuilder<'integer', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number | null\n : number\n : C extends ColumnBuilder<'boolean', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? boolean | null\n : boolean\n : C extends ColumnBuilder<'jsonb', infer N, infer _D, infer _E, infer P>\n ? N extends true\n ? P | null\n : P\n : C extends ColumnBuilder<'vector', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number[] | null\n : number[]\n : C extends ColumnBuilder<'enum', infer N, infer _D, infer E, infer _P>\n ? N extends true\n ? E | null\n : E\n : never;\n\n/**\n * True when a column is optional on INSERT:\n * - nullable columns (N = true) — the DB allows NULL so the field may be omitted\n * - columns with a default (D = true) — the DB fills in the value when absent\n */\nexport type ColIsOptionalOnInsert<C> =\n C extends ColumnBuilder<ColumnType, true, boolean, unknown, unknown, unknown>\n ? true\n : C extends ColumnBuilder<ColumnType, boolean, true, unknown, unknown, unknown>\n ? true\n : false;\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\n/** Create a UUID column. */\nexport function uuid(): ColumnBuilder<'uuid', false, false, never> {\n return new ColumnBuilder('uuid');\n}\n\n/** Create a TEXT column. */\nexport function text(): ColumnBuilder<'text', false, false, never> {\n return new ColumnBuilder('text');\n}\n\n/** Create an INTEGER column. Emits int4 (max ~2.1B). */\nexport function integer(): ColumnBuilder<'integer', false, false, never> {\n return new ColumnBuilder('integer');\n}\n\n/**\n * Create a BIGINT column (Postgres int8, max ~9.2×10^18).\n * Surfaces as `string` in row/insert types — JS number loses precision past 2^53\n * and pgx/PostgREST serialize int8 as a JSON string. Use BigInt(row.column) in app code.\n */\nexport function bigint(): ColumnBuilder<'bigint', false, false, never> {\n return new ColumnBuilder('bigint');\n}\n\n/**\n * Create a NUMERIC column (Postgres `numeric`/`decimal`, arbitrary precision).\n * For exact fractional values (money with cents as a decimal, rates, weights)\n * where int4/int8 don't fit. Surfaces as `string` in row/insert types — JS\n * number can't hold arbitrary-precision decimals without rounding, and\n * pgx/PostgREST serialize numeric as a JSON string. Parse with a decimal lib\n * (or BigInt for scaled integers) in app code.\n */\nexport function numeric(): ColumnBuilder<'numeric', false, false, never> {\n return new ColumnBuilder('numeric');\n}\n\n/** Create a BOOLEAN column. */\nexport function boolean(): ColumnBuilder<'boolean', false, false, never> {\n return new ColumnBuilder('boolean');\n}\n\n/** Create a TIMESTAMP column. */\nexport function timestamp(): ColumnBuilder<'timestamp', false, false, never> {\n return new ColumnBuilder('timestamp');\n}\n\n/**\n * Create a JSONB column. Pass a payload type to make the generated row/insert\n * type concrete instead of `unknown`:\n *\n * tags: jsonb<string[]>() // row.tags: string[]\n * meta: jsonb<{ tier: string }>() // row.meta: { tier: string }\n * raw: jsonb() // row.raw: unknown (back-compat)\n *\n * The runtime accepts a plain JS object/array directly (no JSON.stringify); the\n * generic only refines the TYPE the env codegen emits.\n */\nexport function jsonb<T = unknown>(): ColumnBuilder<'jsonb', false, false, never, T> {\n return new ColumnBuilder('jsonb');\n}\n\n/**\n * Create an ENUM column.\n * @param name The PostgreSQL enum type name (used in DDL).\n * @param values A readonly tuple of valid string values — kept `const` so the\n * union `V[number]` is as narrow as possible.\n */\nexport function enumType<const V extends readonly string[]>(\n name: string,\n values: V,\n): ColumnBuilder<'enum', false, false, V[number]> {\n const builder = new ColumnBuilder<'enum', false, false, V[number]>('enum');\n builder._def.enumName = name;\n builder._def.enumValues = [...values];\n return builder;\n}\n\n/** vector(n) — pgvector kolonu. n TİPİN parçasıdır (typmod) ve [1, 2000] —\n * 2000 = pgvector'ün HNSW-indekslenebilir tavanı; auto-index bu beyanla bağlı\n * (spec FR-001, D-3). */\nexport function vector(dimensions: number): ColumnBuilder<'vector', false, false, unknown, number[]> {\n if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 2000) {\n throw new Error(`vector(): dimensions must be an integer in [1, 2000], got ${String(dimensions)}`);\n }\n const b = new ColumnBuilder('vector') as ColumnBuilder<'vector', false, false, unknown, number[]>;\n (b._def as { dimensions?: number }).dimensions = dimensions;\n return b;\n}\n\n/**\n * Any column, whatever its type parameters.\n *\n * Exported so a cycle can be broken from ONE side:\n * `references((): AnyColumn => y.id)`.\n */\nexport type AnyColumn = ColumnBuilder;\n\n/**\n * The column that OWNS this row: a `text` FK onto `auth.users(id)`, NOT NULL,\n * ON DELETE CASCADE.\n *\n * Ownership drives account erasure, so cascade is the only correct action and\n * takes no argument. The referencing column must be `text` (palauth ids are\n * `usr_<uuid>`) and NOT NULL — both are implied here rather than left to the\n * caller, so three rules the type could not express before become UNWRITABLE.\n *\n * At most ONE per table. The old shape let several columns reference\n * `auth.users` and picked the FIRST IN DECLARATION ORDER as the owner — moving a\n * `created_by` above a `user_id` silently changed which rows an account deletion\n * took with it. A second one is now rejected at push.\n *\n * For a column that merely POINTS at a user without owning the row\n * (`created_by`, `edited_by`), use `userRef({ onDelete })`.\n */\nexport function ownedByUser(): ColumnBuilder<'text', false, false, never> {\n const b = new ColumnBuilder<'text', false, false, never>('text');\n b._def.nullable = false;\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = 'cascade';\n b._def.owns = true;\n return b;\n}\n\n/**\n * A plain FK onto `auth.users(id)` that does NOT own the row.\n *\n * `created_by` / `edited_by`: deleting that user must not delete the row. ON\n * DELETE is required and limited to `cascade | set null` so an erasure request\n * is never blocked by a lingering FK; `set null` needs a nullable column.\n */\nexport function userRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\n}\n\n/**\n * A plain FK onto `auth.installations(id)` — the app-scoped verified-device\n * anchor.\n *\n * An installation is an APP INSTALL, not a user: this is NOT ownership. A\n * user-owned row still needs its own `ownedByUser()` so account erasure removes\n * it; an installation reference alone does not tie a row to a user's deletion.\n */\nexport function installationRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.installations', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\n}\n","/**\n * A named raw-SQL DDL object declared in a schema file (`db/public.ts`,\n * `db/billing.ts`, …) for what the typed DSL cannot express: an index method\n * other than btree (`gin`, `gist`, `brin`, `hash`), an opclass, `CONCURRENTLY`,\n * `EXCLUDE` constraints, views, and PL/pgSQL functions.\n *\n * REACH FOR THE TYPED FIELD FIRST. Most of what this list used to name is\n * declarative today and should not come through here:\n * - a CHECK constraint → `checks: [{ name, expr }]`, or the typed\n * `checks: (c) => [check(name, c.col(\"n\").gt(0))]`\n * - a partial index → `index(n).on(…).where(…)`\n * - an expression index → `index(n).onExpression(\"lower(email)\")`\n * - a covering index → `index(n).on(…).include([…])`\n * - a UNIQUE or PARTIAL UNIQUE index → `index(n).unique().where(…)`\n * - a composite FOREIGN KEY → `foreignKeys: (c) => [foreignKey(n).on(…).references(…)]`\n * - a conditional FK → `freeze: (c) => [freeze(n).when(…).columns(…).references(…)]`\n * - a trigger that refuses a write → `guards: (g) => [guard(n).on(…).refuse(…)]`\n * - a one-off data fix → `backfills: [backfill(name, sql)]`\n * - dropping a constraint → `dropConstraints: [\"name\"]`\n * Those are diffed, validated against the live database before the push, and\n * their mistakes answer you where you write them. A `raw()` is none of that.\n *\n * The deploy emits `up` verbatim on the privileged DDL connection — same trust\n * posture as policy().using(). How a CHANGED body is treated depends on what\n * `name` addresses:\n * - names a constraint or an index → tracked by NAME only; the deploy sees\n * the catalog object and skips, so an edited body does nothing. Use a new\n * name, or drop and re-add explicitly.\n * - names nothing in the catalog (functions, triggers, grants, compound\n * statements) → the last applied body is recorded in\n * `public.palbase_raw_objects` in the same DDL transaction, and an edited\n * body IS re-applied.\n *\n * There is no teardown option — not on the call, and not on this type. One used\n * to be accepted and was carried into a generated `Down` that NOTHING ever ran:\n * the engine's `MigrationFiles.Down` has no consumer and the rollback path names\n * a `runner.go` that does not exist, so an author who wrote one believed they had\n * a teardown they did not have. `raw()` stopped ACCEPTING it first, and the field\n * outlived the parameter — an object literal (`raw: [{ name, up, down }]`) still\n * compiled and still set a field nothing read. Drop what a `raw()` created by\n * declaring the drop as its own `raw()`.\n */\nexport interface RawConstraintDef {\n name: string;\n up: string;\n}\n\nexport function raw(name: string, up: string): RawConstraintDef {\n return { name, up };\n}\n","/** Embedding sağlayıcı DESKRIPTORU — canlı istemci değil, düz veri: şemayla\n * birlikte serileşir, çağrıyı Go worker (yazma) ve engine (sorgu) yapar.\n * Adlandırma Vercel AI SDK'nın aynasıdır (openai.embedding(\"...\")) ama paket\n * bağımlılığı bilinçli olarak YOKTUR (spec C-3, UD-016). v1 sağlayıcı: openai (D-10). */\nexport interface EmbeddingModelRef {\n provider: \"openai\";\n model: string;\n dimensions?: number;\n apiKeyName?: string;\n baseURL?: string;\n}\n/** Chat/damıtma modeli DESKRIPTORU (C-11, D-019) — memory beyanının extract'i.\n * Embedding gibi düz veridir; çağrıyı worker yapar, anahtar vault'taki\n * OPENAI_API_KEY'dir (D-017: aynı sağlayıcı, yeni dış sistem yok). */\nexport interface ChatModelRef {\n provider: \"openai\";\n model: string;\n}\nexport const openai = {\n embedding(\n model: string,\n opts?: { dimensions?: number; apiKeyName?: string; baseURL?: string },\n ): EmbeddingModelRef {\n return { provider: \"openai\", model, apiKeyName: opts?.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(opts?.dimensions !== undefined ? { dimensions: opts.dimensions } : {}),\n ...(opts?.baseURL !== undefined ? { baseURL: opts.baseURL } : {}) };\n },\n chat(model: string): ChatModelRef {\n return { provider: \"openai\", model };\n },\n};\n","/** PostgreSQL protocol identifiers, shared by error mapping and retry policy. */\nexport const SQLSTATE = Object.freeze({\n serializationFailure: \"40001\",\n deadlockDetected: \"40P01\",\n queryCancelled: \"57014\",\n commandGuardFailed: \"PBC01\",\n} as const);\n\n/** These errors confirm that PostgreSQL aborted the transaction. A connection\n * failure does not: the COMMIT may already have succeeded. */\nexport function isTransactionRollbackState(state: unknown): boolean {\n return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;\n}\n","import { SQLSTATE, isTransactionRollbackState } from \"./db/sqlstate.js\";\n\n/**\n * The brand that identifies an HttpError ACROSS SDK instances.\n *\n * A process legitimately holds more than one copy of this SDK — the runtime\n * loads the engine from its own node_modules while the tenant's bundle carries\n * an inlined copy, which is why the controller registry and the error registry\n * are both anchored on `Symbol.for`. The one place that did not follow the\n * pattern was the engine's catch: `err instanceof HttpError` compares CLASS\n * IDENTITY, so a `throw new NotFound()` from the bundle's copy did not match\n * the engine's copy and every typed error in every deployed backend degraded to\n * `500 internal_error`. Measured through the edge on a real deploy: a route\n * throwing `NotFound` answered 500 while the runtime's own log printed the\n * error object with `status: 404` right beside it.\n *\n * `Symbol.for` puts this in the cross-realm registry, so every copy of the SDK\n * agrees on it by VALUE rather than by identity.\n */\nexport const HTTP_ERROR_BRAND: unique symbol = Symbol.for(\"palbase.backend.httpError\");\n\n/**\n * Set on an `HttpError` the ENGINE built out of a driver failure, as opposed to\n * one the author constructed to ANSWER a request.\n *\n * The distinction cannot be read off the status, and 409 is why. The scaffold\n * teaches `throw new Conflict(\"title already taken\")` as the way to answer\n * (template/AGENTS.md), and the engine raises `UniqueViolation` — also a 409 —\n * when a write hits a unique index. Logging by status therefore either loses the\n * engine's event or writes an \"unhandled\" line every time an author takes the\n * documented path. Measured: it did the second.\n *\n * `Symbol.for` so the mark survives the bundle/runtime SDK split, the same way\n * {@link HTTP_ERROR_BRAND} does.\n */\nexport const ENGINE_RAISED: unique symbol = Symbol.for(\"palbase.backend.engineRaised\") as never;\n\n/** Mark `e` as engine-raised and return it, so a conversion site reads as one expression. */\nexport function markEngineRaised<E extends object>(e: E): E {\n (e as Record<symbol, unknown>)[ENGINE_RAISED] = true;\n return e;\n}\n\n/** Whether the engine built this error, rather than the author throwing it to answer. */\nexport function isEngineRaised(e: unknown): boolean {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[ENGINE_RAISED] === true;\n}\n\n/**\n * Whether a thrown value is an HttpError from ANY copy of this SDK.\n *\n * The shape is checked as well as the brand: the brand says \"this claims to be\n * one of ours\", the fields say the envelope can actually be built from it, and\n * a half-formed object must fall through to the 500 path rather than produce a\n * malformed response.\n */\nexport function isHttpError(err: unknown): err is HttpError {\n if (typeof err !== \"object\" || err === null) return false;\n const e = err as Record<PropertyKey, unknown>;\n return (\n e[HTTP_ERROR_BRAND] === true &&\n typeof e.status === \"number\" &&\n typeof e.error === \"string\" &&\n typeof e.errorDescription === \"string\"\n );\n}\n\n/** HTTP error with structured error response format.\n *\n * The base class for the throwable error classes (`PalError`, `Conflict`,\n * `NotFound`, …). Construct one directly with `throw new HttpError(404,\n * \"todo_not_found\", \"No such todo\")`, or throw a named subclass\n * (`throw new NotFound(\"todo not found\")`). The runtime catches any `HttpError`\n * and emits the standard envelope; on the wire (and to iOS) it surfaces as\n * `BackendError.server(code, status, message, requestId)`.\n *\n * The optional `data` field carries a structured payload alongside the\n * standard envelope — for errors that need to ship extra context\n * (e.g. `new Conflict(\"locked\", \"title_locked\", { retryAfter: 30 })`). It rides\n * through to the iOS typed enum's associated value.\n */\nexport class HttpError extends Error {\n public readonly status: number;\n public readonly error: string;\n public readonly errorDescription: string;\n public readonly data?: unknown;\n /** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */\n public readonly [HTTP_ERROR_BRAND] = true;\n\n constructor(status: number, error: string, errorDescription: string, data?: unknown) {\n super(errorDescription);\n this.name = \"HttpError\";\n this.status = status;\n this.error = error;\n this.errorDescription = errorDescription;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Serialize to the standard Palbase error response format.\n * The `requestId` is injected by the runtime layer from the request context.\n * When called without arguments (e.g. JSON.stringify), request_id is omitted.\n * When `data` is set, it is appended as a strict-superset field.\n */\n toJSON(requestId?: string): {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } {\n const result: {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } = {\n error: this.error,\n error_description: this.errorDescription,\n status: this.status,\n };\n if (requestId) {\n result.request_id = requestId;\n }\n if (this.data !== undefined) {\n result.data = this.data;\n }\n return result;\n }\n}\n\n/**\n * Throw with a custom HTTP status + wire code. The general-purpose escape hatch\n * when none of the named classes (`Conflict`/`NotFound`/…) fits.\n *\n * @example\n * throw new PalError(418, \"teapot\", \"I'm a teapot\");\n */\nexport class PalError extends HttpError {\n constructor(status: number, code: string, description: string, data?: unknown) {\n super(status, code, description, data);\n this.name = \"PalError\";\n }\n}\n\n/** Base for the named status classes. Each subclass fixes its HTTP status; the\n * `code` defaults to the class's canonical wire code (overridable), and the\n * `message` defaults to a human-readable label (overridable). */\nabstract class NamedHttpError extends HttpError {\n protected constructor(\n status: number,\n defaultCode: string,\n name: string,\n message?: string,\n code?: string,\n data?: unknown,\n ) {\n super(status, code ?? defaultCode, message ?? defaultMessage(name), data);\n this.name = name;\n }\n}\n\n/** Derive a default human-readable message from a class name\n * (\"NotFound\" → \"Not found\", \"TooManyRequests\" → \"Too many requests\"). */\nfunction defaultMessage(name: string): string {\n const spaced = name.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();\n}\n\n/**\n * 400 — the request was malformed or failed validation. Carries a fixed typed\n * payload: `new BadRequest({ fields: [{ field: \"email\", message: \"invalid\" }] })`.\n * The shape is declared once in the SDK so codegen surfaces `error.data.fields`\n * typed on the client.\n */\nexport class BadRequest extends NamedHttpError {\n public declare readonly data: BadRequestData;\n constructor(data: BadRequestData, message?: string) {\n super(400, \"bad_request\", \"BadRequest\", message, undefined, data);\n }\n}\n\n/** 401 — the caller is not authenticated. */\nexport class Unauthorized extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(401, \"unauthorized\", \"Unauthorized\", message, code, data);\n }\n}\n\n/** 403 — the caller is authenticated but not allowed. */\nexport class Forbidden extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(403, \"forbidden\", \"Forbidden\", message, code, data);\n }\n}\n\n/** 404 — the requested resource does not exist. */\nexport class NotFound extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(404, \"not_found\", \"NotFound\", message, code, data);\n }\n}\n\n/** 409 — the request conflicts with the current state. */\nexport class Conflict extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(409, \"conflict\", \"Conflict\", message, code, data);\n }\n}\n\n/**\n * 409 — a write was refused because it would duplicate an existing row.\n * Carries the NAME of the unique constraint Postgres named (`users_email_key`).\n *\n * The engine produces it: a statement rejected with SQLSTATE `23505` is\n * converted here rather than surfacing as an opaque driver error (see\n * `engine/db.ts`, `diagnosingDriver`). What that removes is the string match —\n * before this, the only way to act on a duplicate was to test the driver\n * message for \"duplicate key value violates unique constraint\", a contract\n * nobody signed that breaks on a Postgres upgrade, a locale, or a constraint\n * rename, silently and in production.\n *\n * THE NAME IS A FIELD AND STAYS OUT OF THE DEFAULT MESSAGE. The two are not\n * the same audience. `constraint` is read by the code that catches this — the\n * developer, who already knows the schema. `errorDescription` is the HTTP\n * response body, and an UNCAUGHT duplicate puts it in front of the\n * application's end user: `users_email_key` there discloses how the schema is\n * built to whoever sent the request. The platform's own data API took the same\n * decision one surface over and wrote down why —\n * `v2/internal/modules/database/internal/handler/pgerror.go:83-87` collapses\n * every 23xxx to a generic conflict, \"never disclose the constraint/column\n * name\". A thrower who WANTS the name on the wire passes it deliberately\n * (`new UniqueViolation(c, \\`\\${c} already exists\\`)`, or through `data`).\n *\n * @example\n * try {\n * await Database.public.users.insert({ email });\n * } catch (e) {\n * if (UniqueViolation.is(e) && e.constraint === \"users_email_key\") {\n * throw new Conflict(\"That email is taken\", \"email_taken\");\n * }\n * throw e;\n * }\n */\nexport class UniqueViolation extends Conflict {\n /**\n * Whether `e` is a unique violation — REGARDLESS of which copy of this SDK\n * constructed it.\n *\n * Use this instead of `instanceof`. Measured on a live stack: a controller\n * bundle INLINES its own copy of `@palbase/backend`, and the engine that\n * raises this error is the runtime's copy. Two copies, two class identities,\n * and `e instanceof UniqueViolation` is false in the one place a caller\n * writes it — a check that reads as correct and silently never matches.\n */\n static is(e: unknown): e is UniqueViolation {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { name?: unknown }).name === \"UniqueViolation\" &&\n typeof (e as { constraint?: unknown }).constraint === \"string\"\n );\n }\n\n /** The unique constraint the statement violated, as Postgres named it.\n * `\"\"` when the driver did not say which — see `engine/db.ts`. */\n public readonly constraint: string;\n\n constructor(constraint: string, message?: string, code?: string, data?: unknown) {\n super(message ?? \"Unique constraint violated\", code ?? \"unique_violation\", data);\n this.name = \"UniqueViolation\";\n this.constraint = constraint;\n }\n}\n\n/**\n * Eşzamanlılık yüzünden BAŞARISIZ OLAN, ama TEKRAR DENENİRSE başarılı olabilecek\n * hataların ortak yüzeyi (FR-036).\n *\n * `retryable: true` bir tahmin değil, Postgres'in söylediği şey: `40001` ve\n * `40P01` \"bu işlemi baştan çalıştır\" anlamına gelir. Kümenin DAR tutulması\n * kasıtlı — `23505` buraya girseydi, tekrar denemek aynı cevabı verir ve\n * döngü sonsuza kadar dönerdi.\n */\nexport interface RetryableError extends Error {\n readonly retryable: true;\n /** Beş karakterlik SQLSTATE — hangi eşzamanlılık hatası olduğunu SÖYLER. */\n readonly sqlstate: string;\n}\n\n/**\n * `e` tekrar denenebilir mi?\n *\n * `instanceof` DEĞİL şekil kontrolü — ve sebebi ÖLÇÜLMÜŞ (bkz. {@link\n * UniqueViolation.is}): bir controller bundle'ı kendi `@palbase/backend`\n * kopyasını inline'lıyor, hatayı fırlatan motor ise runtime'ın kopyası. İki\n * sınıf kimliği, ve `e instanceof SerializationFailure` yazan tek yerde\n * sessizce hiç eşleşmiyor.\n */\nexport function isRetryable(e: unknown): e is RetryableError {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { retryable?: unknown }).retryable === true &&\n isTransactionRollbackState((e as { sqlstate?: unknown }).sqlstate)\n );\n}\n\n/**\n * `40001 serialization_failure` — SERIALIZABLE ya da REPEATABLE READ altında\n * eşzamanlı bir işlem bu işlemi geçersiz kıldı.\n *\n * D-016: bu hata BLOKLANMIYOR, FIRLATILIYOR. Retry'sız bir izolasyon\n * yükseltmesi sunmak defect'tir — kullanıcıya çalışmayan bir düğme vermektir:\n * SERIALIZABLE'a çıkıp `40001`'i yakalamayan kod, önceden çalışan işlemleri\n * rastgele kaybetmeye başlar.\n */\nexport class SerializationFailure extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is SerializationFailure {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"SerializationFailure\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.serializationFailure, message?: string, data?: unknown) {\n super(\n message ??\n \"işlem eşzamanlı bir işlemle serileştirilemedi — aynı işlemi baştan çalıştırın \" +\n \"(karar okumaları ve yazmaları $atomic içine alıp { retry: n } verin)\",\n \"serialization_failure\",\n data,\n );\n this.name = \"SerializationFailure\";\n this.sqlstate = sqlstate;\n }\n}\n\n/**\n * `40P01 deadlock_detected` — iki işlem birbirinin kilidini bekliyordu;\n * Postgres birini seçip iptal etti.\n *\n * Bu hatayı GÖRMEK bir tasarım sinyali: kilit sırası deterministik değilse\n * tekrar denemek yalnız maliyeti öteler. Sırayı sabitleyen üç şey var ve\n * hangisinin geçerli olduğunu ELİNDEKİ belirler: satırların id'leri elindeyse\n * `Database.$lockRows(tablo, id'ler)`, elinde bir FİLTRE varsa\n * `Database.$lockRowsWhere(tablo, filtre)` (FR-037 — birincil anahtara göre\n * sıralayarak kilitler, yani `updateMany` ile aynı sırayı paylaşır), ya da çok\n * satırlı yazmanın CTE'si (FR-015).\n */\nexport class DeadlockDetected extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is DeadlockDetected {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"DeadlockDetected\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.deadlockDetected, message?: string, data?: unknown) {\n super(\n message ??\n \"deadlock: iki işlem birbirinin kilidini bekledi ve bu işlem iptal edildi — \" +\n \"kilit sırasını sabitleyin: id'ler elinizdeyse Database.$lockRows(tablo, id'ler), \" +\n \"elinizde bir filtre varsa Database.$lockRowsWhere(tablo, filtre) kullanın\",\n \"deadlock_detected\",\n data,\n );\n this.name = \"DeadlockDetected\";\n this.sqlstate = sqlstate;\n }\n}\n\n/** A single field-level validation failure carried by {@link BadRequest}. */\nexport interface FieldError {\n /** The offending field's name (dotted path for nested fields). */\n field: string;\n /** Human-readable reason the field failed. */\n message: string;\n}\n\n/** The fixed, typed payload {@link BadRequest} ships. */\nexport interface BadRequestData {\n /** The fields that failed validation. */\n fields: FieldError[];\n}\n\n/** The fixed, typed payload {@link TooManyRequests} ships. */\nexport interface TooManyRequestsData {\n /** Seconds the caller should wait before retrying. */\n retryAfter: number;\n}\n\n/**\n * 429 — the caller has exceeded the rate limit. Carries a fixed typed payload:\n * `new TooManyRequests({ retryAfter: 30 })`. The shape is declared once in the\n * SDK (error-registry pre-seed) so codegen surfaces `error.data.retryAfter`\n * typed on the client — no per-project definition needed.\n */\nexport class TooManyRequests extends NamedHttpError {\n public declare readonly data: TooManyRequestsData;\n constructor(data: TooManyRequestsData, message?: string) {\n super(429, \"too_many_requests\", \"TooManyRequests\", message, undefined, data);\n }\n}\n","/**\n * typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.\n *\n * Derives INSERT and full-row TypeScript types from a `defineSchema()` result\n * and wraps the untyped runtime `DBClient` with a typed facade.\n *\n * No value-any. No `as unknown as X`. The two narrow `as` casts in\n * `makeTypedTable` are safe because:\n * - `data as Record<string, unknown>`: InsertShape<T> maps string keys to\n * typed values; all value types are subsets of `unknown`, so the cast is\n * structurally sound.\n * - `result as RowShape<T>`: The runtime DBClient returns `Record<string,\n * unknown>` which is the erased form of the typed row; we're narrowing back\n * to the precise shape that the schema declared.\n * Both casts are narrowing only (not widening) and correctness is guaranteed\n * by the schema the caller provides.\n */\n\nimport type { ColValue, ColIsOptionalOnInsert, ColumnBuilder } from \"./columns.js\";\nimport type { TableDef, SchemaDef } from \"./schema.js\";\nimport type { Tables, Schemas, TableTypes } from \"./env.js\";\nimport type { DBClient, DBOps, AtomicClient } from \"../endpoint.js\";\nimport type { RecoOps } from \"../runtime.js\";\nimport type { Materialized, TxPlanHandle, TxTable, TxColumnExpr, TxNow } from \"./tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./tx-plan.js\";\nimport { isColRef, brandRef } from \"./input-guards.js\";\nimport { isRetryable } from \"../errors.js\";\nimport { retryBudget, type AtomicOptions } from \"./transaction-options.js\";\nimport { qualifiedTableKey } from \"./schema-json.js\";\n\n// ---------------------------------------------------------------------------\n// Key discriminators — split a column map into required vs optional keys.\n// ---------------------------------------------------------------------------\n\n/** Keys of C whose columns are required on INSERT (not nullable, no default). */\ntype RequiredKeys<C> = {\n [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? never : K;\n}[keyof C];\n\n/** Keys of C whose columns are optional on INSERT (nullable or has a default). */\ntype OptionalKeys<C> = {\n [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? K : never;\n}[keyof C];\n\n// ---------------------------------------------------------------------------\n// Public shape types — exported so callers can reference them directly.\n// ---------------------------------------------------------------------------\n\n/**\n * The TypeScript type for an INSERT payload for table `T`.\n * - Required: columns that are NOT NULL and have no DB-level default.\n * - Optional: columns that are nullable or carry a default.\n *\n * When all columns are optional, `RequiredKeys<C>` resolves to `never` and\n * the first part becomes `{}`, which is a neutral element for `&`.\n */\nexport type InsertShape<T extends TableDef> = {\n [K in RequiredKeys<T[\"columns\"]>]: ColValue<T[\"columns\"][K]>;\n} & {\n [K in OptionalKeys<T[\"columns\"]>]?: ColValue<T[\"columns\"][K]>;\n};\n\n/**\n * The TypeScript type for a full row returned by the DB for table `T`.\n * Every column is present; nullable columns resolve to `T | null`.\n */\nexport type RowShape<T extends TableDef> = {\n [K in keyof T[\"columns\"]]: ColValue<T[\"columns\"][K]>;\n};\n\n// ---------------------------------------------------------------------------\n// TypedTable + TypedDB interfaces.\n// ---------------------------------------------------------------------------\n\n/** A typed table accessor that mirrors the runtime DBClient surface. */\nexport interface TypedTable<T extends TableDef> {\n /** Runtime validates the key against the installed schema. Generated env tables\n * also check the complete unique/composite key at compile time. */\n findUnique<K extends keyof RowShape<T> = keyof RowShape<T>>(q: {\n where: Partial<RowShape<T>>; select?: readonly K[];\n }): Promise<Pick<RowShape<T>, K> | null>;\n page<K extends keyof RowShape<T> = keyof RowShape<T>>(\n q?: PageInput<RowShape<T>, K>,\n ): Promise<import(\"./page.js\").Page<Pick<RowShape<T>, K>>>;\n insert(data: InsertValues<InsertShape<T>>): Promise<RowShape<T>>;\n /** Çok satır, TEK statement. Satırların anahtar kümesi aynı olmalı. */\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts: import(\"./bulk.js\").InsertManyOptions & { returning: false }): Promise<number>;\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions & { returning?: true }): Promise<RowShape<T>[]>;\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions): Promise<RowShape<T>[] | number>;\n put(q: { data: InsertShape<T>; onConflict: readonly string[] }): Promise<RowShape<T>>;\n /** Update the row by id; resolves to the updated row, or `null` if no row\n * matched (absent or RLS-hidden) — an idempotent outcome, mirroring\n * `findById`. The runtime returns a null row rather than throwing. */\n update(q: { where: { id: string }; set: SetShape<InsertShape<T>> }): Promise<RowShape<T> | null>;\n delete(id: string): Promise<void>;\n findById(id: string): Promise<RowShape<T> | null>;\n /** Rows matching the filter. Operators, ordering and paging are the ENGINE's\n * surface — this declaration is what makes them callable. */\n findMany<K extends keyof RowShape<T> = keyof RowShape<T>>(\n q?: QueryInput<RowShape<T>, K>,\n ): Promise<Pick<RowShape<T>, K>[]>;\n /**\n * Update every matching row in one statement; an empty filter is refused.\n *\n * **0 satır dönmesi hata DEĞİL, başarı da değil** (FR-014): koşulu `where`'e\n * koyup dönen diziyi kontrol etmek, \"önce oku sonra yaz\"ın yarış koşulu\n * olmayan hâlidir.\n *\n * ```ts\n * const [row] = await Database.public.accounts.updateMany({\n * where: { id, balance: { gte: amount } },\n * set: { balance: decrement(amount) },\n * });\n * if (row === undefined) throw new Conflict(\"yetersiz bakiye\");\n * ```\n */\n updateMany<const Q extends MutateInput<RowShape<T>, InsertShape<T>>>(\n q: Q,\n ): Promise<Q extends { returning: false } ? number : RowShape<T>[]>;\n /** Delete every matching row; resolves to how many. Empty filter refused. */\n deleteMany(q: { where: WhereFilter<RowShape<T>> | SqlFragment }): Promise<number>;\n /**\n * Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.\n *\n * ```ts\n * const r = await Database.public.entries.aggregate({\n * where: { account_id },\n * sum: [\"amount_kurus\"],\n * count: true,\n * });\n * r.sum.amount_kurus; // string | null — KAYIPSIZ\n * r.count; // number\n * ```\n *\n * `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS\n * `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres\n * boş kümede NULL döndürür — \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı.\n *\n * `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.\n */\n aggregate<const Q extends AggregateInput<RowShape<T>>>(\n q: Q,\n ): Promise<AggregateResult<Q, RowShape<T>>>;\n /** How many rows match. An empty filter is legitimate: counting is a read. */\n count(q?: { where?: WhereFilter<RowShape<T>> | SqlFragment }): Promise<number>;\n}\n\n/** A typed DB facade covering all tables declared in schema `S`. */\nexport interface TypedDB<S extends SchemaDef> {\n diagnostics: DBOps[\"diagnostics\"];\n command<T>(fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n tables: {\n [K in keyof S[\"tables\"]]: TypedTable<S[\"tables\"][K]>;\n };\n /** Run a transaction plan. See {@link EnvTypedDatabase.transaction}. */\n transaction<T>(\n fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T,\n ): Promise<Materialized<T>>;\n}\n\n/** The plan-building handle a `TypedDB<S>` transaction callback receives: the\n * schema's tables, expressed as plan operations rather than awaited calls.\n *\n * YALNIZ `tables`, ve ÇALIŞMA ZAMANI DA yalnız onu veriyor.\n *\n * Bir süre runtime `{ tables, public }` döndürüyordu ama tip yalnız `tables`\n * söylüyordu: `tx.public.x` derlenmiyor, koşsaydı çalışacaktı — tipin çalışma\n * zamanından AZ söylemesi (gözcü M-8). Tipe `public` EKLEMEK yanlış düzeltmeydi\n * ve `check:api` onu adıyla reddetti: `TypedTx` dışa açık, ve zorunlu bir üye\n * eklemek onu İNŞA EDEN müşterinin kodunu kırar — \"the new shape demands more\n * than the recorded one\". Yalan runtime'dan kaldırılarak kapatıldı; ikisi artık\n * aynı şeyi söylüyor. `Database.$transaction`'ın `tx.public`'i ayrı bir yüzey\n * (`TxPlan`) ve orada tip de runtime da onu taşıyor. */\nexport type TypedTx<S extends SchemaDef> = TxPlanHandle<{\n [K in keyof S[\"tables\"]]: TxTable<RowShape<S[\"tables\"][K]>, InsertShape<S[\"tables\"][K]>>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Runtime factory.\n// ---------------------------------------------------------------------------\n\n/**\n * Builds a typed table accessor that delegates every call to `raw` using the\n * runtime table name string. Two narrow `as` casts bridge the mapped-type\n * shapes to/from `Record<string, unknown>` — see module-level doc comment.\n *\n * The `raw` param is typed `DBOps` (the six string-keyed ops) because this only\n * ever calls those — never `txPlan`, which builds its own operations rather than\n * delegating to these.\n */\nfunction makeTypedTable<T extends TableDef<Record<string, ColumnBuilder>>>(\n name: string,\n raw: DBOps,\n): TypedTable<T> {\n return {\n insert: (data: InsertShape<T>) =>\n raw.insert(name, data as Record<string, unknown>) as Promise<RowShape<T>>,\n\n aggregate: ((q: Record<string, unknown>) =>\n raw.aggregate(name, q)) as TypedTable<T>[\"aggregate\"],\n\n insertMany: ((rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions) =>\n raw.insertMany(name, rows as readonly Record<string, unknown>[], opts)) as TypedTable<T>[\"insertMany\"],\n\n put: (q: { data: InsertShape<T>; onConflict: readonly string[] }) =>\n raw.put(name, q.data as Record<string, unknown>, { onConflict: q.onConflict }) as Promise<RowShape<T>>,\n\n update: (q: { where: { id: string }; set: Partial<InsertShape<T>> }) =>\n raw.update(name, q.where.id, q.set as Record<string, unknown>) as Promise<RowShape<T> | null>,\n\n delete: (id: string) => raw.delete(name, id),\n\n findUnique: ((q: { where: Record<string, unknown>; select?: readonly string[] }) =>\n raw.findUnique(name, q.where, { select: q.select })) as TypedTable<T>[\"findUnique\"],\n findById: (id: string) =>\n raw.findById(name, id) as Promise<RowShape<T> | null>,\n\n page: (q?: PageInput<RowShape<T>>) => {\n const { where, ...opts } = q ?? {};\n return raw.page(name, where as Record<string, unknown> | undefined, opts as import(\"./page.js\").RawPageOptions) as Promise<import(\"./page.js\").Page<RowShape<T>>>;\n },\n findMany: (q?: QueryInput<RowShape<T>>) => {\n // `where` AYIKLANIR: kalan alanlar (orderBy/limit/offset) opts'a gider.\n // Tümünü opts diye geçirmek `where`'i tel üstünde İKİ KEZ gönderirdi.\n const { where, ...opts } = q ?? {};\n return raw.findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<typeof raw.findMany>[2],\n ) as Promise<RowShape<T>[]>;\n },\n\n updateMany: ((q: MutateInput<RowShape<T>, InsertShape<T>>) =>\n raw.updateMany(\n name,\n q.where as Record<string, unknown>,\n q.set as Record<string, unknown>,\n q.returning === undefined ? undefined : { returning: q.returning },\n )) as TypedTable<T>[\"updateMany\"],\n\n deleteMany: (q: { where: WhereFilter<RowShape<T>> | SqlFragment }) =>\n raw.deleteMany(name, q.where as Record<string, unknown>),\n\n count: (q?: { where?: WhereFilter<RowShape<T>> }) =>\n raw.count(name, q?.where as Record<string, unknown> | undefined),\n };\n}\n\n/**\n * Wraps a raw `DBClient` with the type-safe `TypedDB<S>` facade derived from\n * the provided schema. No behavior change for the direct ops — all calls\n * delegate to `raw` with the table name as a plain string.\n *\n * `transaction` does NOT delegate to a per-op client: the callback describes a\n * plan against a fresh {@link TxPlanBuilder}, and the whole plan travels in one\n * `raw.txPlan` call. The schema is used only for its table NAMES; the values\n * are typed by `S` at compile time and are plain strings at run time.\n *\n * The `as` casts are single structural narrowings from a dynamically-built\n * object to the precise mapped type (TS cannot infer the mapped-type result\n * through `Object.keys` iteration) — see the module-level doc comment.\n */\nexport function makeTypedDB<S extends SchemaDef>(\n schema: S,\n raw: AtomicClient,\n): TypedDB<S> {\n const tables = {} as Record<string, TypedTable<TableDef>>;\n for (const key of Object.keys(schema.tables)) {\n const tableDef = schema.tables[key];\n if (tableDef !== undefined) {\n tables[key] = makeTypedTable(qualifiedTableKey(schema.name, tableDef.name), raw);\n }\n }\n\n const result = {\n tables,\n diagnostics: () => raw.diagnostics(),\n command<T>(fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n const planTables = Object.fromEntries(Object.entries(schema.tables).map(([key, table]) => [key, builder.table(qualifiedTableKey(schema.name, table.name))]));\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, { tables: planTables } as TypedTx<S>, builder, fn) as Promise<Materialized<T>>;\n },\n transaction<T>(\n fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T,\n ): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n const planTables: Record<string, unknown> = {};\n for (const key of Object.keys(schema.tables)) {\n const tableDef = schema.tables[key];\n if (tableDef !== undefined) planTables[key] = builder.table(qualifiedTableKey(schema.name, tableDef.name));\n }\n // Two narrowings at the same seam: the plan tables are built by NAME, so\n // TS cannot see the mapped type through the loop, and the driver erases\n // the callback's return type (see runTxPlan's doc). Both are the erasure\n // this facade exists to undo.\n // `runTxPlan` artık TUTAMAĞIN TAMAMINI alıyor (şema yüzeyi dahil).\n //\n // Burada tutamak YALNIZ `tables` taşıyor, çünkü `TypedTx<S>` de yalnız\n // onu söylüyor. Bir ara `public`'i de veriyordu ve tip onu bilmiyordu —\n // çalışma zamanının tipten FAZLA sunması da bir yalan. `makeTypedDB` tek\n // şemalı bir cephe; çok şemalı yüzey `Database.$transaction`.\n return runTxPlan(\n raw,\n { tables: planTables } as TypedTx<S>,\n builder,\n fn,\n ) as Promise<Materialized<T>>;\n },\n };\n\n // Narrow cast: `result.tables` is structurally identical to\n // TypedDB<S>[\"tables\"] — each key maps to a TypedTable for the matching\n // TableDef. TS cannot infer the mapped-type result through Object.keys\n // iteration, so a single `as` bridges the gap.\n return result as TypedDB<S>;\n}\n\n// ---------------------------------------------------------------------------\n// Env-augmentation-driven typed surface — the typed-by-default `Database`.\n//\n// These types read the globally-augmented `Tables` interface from\n// `@palbase/backend/env` (filled by the generated `palbase-env.d.ts`). They\n// back `Database.public.<name>` so handler code is typed with no import and no\n// generic (C5). They DELIBERATELY do not reference `ColumnBuilder` — the env\n// `Tables` interface carries flat `row`/`insert` object types.\n// ---------------------------------------------------------------------------\n\n/** Bir where değeri: düz eşitlik YA DA operatör nesnesi (FR-016). */\n/**\n * Metin operatörleri YALNIZ metin kolonlarında görünür (FR-005).\n *\n * `contains` bir sayı kolonunda anlamsızdır ve onu tipte sunmak \"ifade edilemez\n * kıl\" ilkesinin tersidir: derleme anında yakalanabilecek bir hata çalışma\n * zamanına ertelenir. Koşullu tip ÖZYİNELEMESİZDİR (N-2).\n */\n/**\n * Bir KOLONA yapılan referans (FR-011) — karşılaştırmanın sağ tarafında değer\n * yerine durabilen tek şey.\n *\n * Şekli okunabilir (`{ $col: \"…\" }`) ama KİMLİĞİ şekli değil: nesne\n * `Symbol.for(\"palbase.db.ref\")` ile markalanır. Şekil tek başına yetseydi\n * güvenilmeyen bir istek gövdesi `{\"$col\":\"tenant_id\"}` gönderip kiracılık\n * predikatını `t.\"tenant_id\" = t.\"tenant_id\"` totolojisine çevirebilirdi —\n * ölçüldü (W2-A/C1). Marka enumerable olmadığı için JSON round-trip'i onu\n * düşürür; süreç içinde (transaction planı dahil) korunur.\n */\nexport type ColRef<N extends string = string> = { readonly $col: N };\n\nexport { isColRef };\n\n/**\n * `total > amount_paid` — bugün bunu yazmanın tek yolu ham SQL'e düşmekti,\n * çünkü sağ taraf bir DEĞER değil.\n *\n * Ad literal olarak yakalanır (`const N`), ve doğruluğu ÇAĞRIDA değil\n * KULLANIM YERİNDE kanıtlanır: filtre `WhereFilter<Row>` beklediği için\n * `ColRef<\"yok_boyle\">` oraya atanamaz. Yani `col()`'a satır tipini elle\n * vermek gerekmiyor, yanlış ad yine de derleme hatası (P5).\n *\n * Dönen nesne MARKALIDIR (`brandRef`): telden gelen `{\"$col\":\"x\"}` bir kolon\n * referansı SAYILMAZ, \"bilinmeyen operatör\" diye reddedilir. Gerekçe\n * `db/input-guards.ts`'te ölçümüyle birlikte yazılı.\n */\nexport function col<const N extends string>(name: N): ColRef<N> {\n return brandRef({ $col: name }, \"col\");\n}\n\n/** Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri. */\n/**\n * Bir kolonun karşılaştırma AİLESİ — ve neden PG tipi değil de bu.\n *\n * ÖLÇÜLDÜ (gözcü, canlı pg16): TS tarafı PG tipini TAŞIMIYOR. `numeric`,\n * `bigint`, `text`, `uuid` ve `timestamp` hepsi `string`'e, `integer` `number`'a\n * düşüyor (`env-gen.ts:30-60`). Bu yüzden TS tipine kurulan HİÇBİR kural doğru\n * olamaz — kural ne olursa olsun bir taraf yanlışa düşer:\n *\n * { qty: { gt: col(\"amount\") } } integer ↔ numeric PG: GEÇERLİ\n * { total: { gt: col(\"note\") } } integer ↔ text PG: GEÇERSİZ\n *\n * İkisi de TS'te \"number ↔ string\". Ayırt edecek bilgi tipte YOK.\n *\n * YANLIŞ RET, YANLIŞ KABULDEN KÖTÜDÜR — ve tercih buna göre yapıldı. Yanlış bir\n * ret meşru bir sorguyu İFADE EDİLEMEZ kılar, yani yazarı `$query`'ye düşürür:\n * bu yüzeyin kapatmak için var olduğu şey. Yanlış bir kabul ise Postgres'in\n * GÜRÜLTÜLÜ hatasına çıkar (`operator does not exist: integer > text`) — kötü\n * ama sessiz değil.\n *\n * O yüzden aile ayrımı yalnız TS'in GERÇEKTEN ayırdığı yerlerde yapılıyor:\n * `boolean`, vektör dizisi ve `Date` kendi başlarına; metin ve sayı ise TEK\n * ailede, çünkü aralarındaki PG ayrımı tipte yok.\n *\n * KALICI ÇÖZÜM tipte değil ÜRETİMDE: `env-gen` kolon başına bir PG-tip markası\n * bassın (`string & { readonly __pg?: \"numeric\" }`). O zaman `numeric ↔ integer`\n * kabul, `numeric ↔ text` ret olur ve ikisi de DOĞRU olur. Defterde teklif.\n */\ntype PgFamily<V> = [NonNullable<V>] extends [boolean]\n ? \"bool\"\n : [NonNullable<V>] extends [readonly (number | string)[]]\n ? \"array\"\n : [NonNullable<V>] extends [Date]\n ? \"date\"\n : [NonNullable<V>] extends [string | number]\n ? \"scalar\"\n : \"opaque\";\n\n/**\n * Kolonun BİLDİRİLMİŞ Postgres tipi — `env-gen`'in bastığı markadan.\n *\n * Marka yoksa `\"?\"`: elle yazılmış bir `Tables` (testler) ya da yeniden\n * üretilmemiş bir `palbase-env.d.ts`. O durumda eski TS-tipi sezgiseline\n * düşülüyor, çünkü marka olmadan söylenebilecek daha doğru bir şey yok.\n */\ntype PgTag<V> = [NonNullable<V>] extends [{ readonly __pg?: infer N }]\n ? [N] extends [string]\n ? N\n : \"?\"\n : \"?\";\n\n/**\n * Postgres'te birbirleriyle karşılaştırılabilen tipler tek \"cins\".\n *\n * `integer`, `bigint` ve `numeric` örtük sayısal dönüşümle karşılaştırılır;\n * geri kalan her tip yalnız kendisiyle. `uuid ↔ text` ve `enum ↔ text`\n * Postgres'te `operator does not exist` verir — D-021'de CANLI ölçülmüştü ve\n * tip bunu göremediği için kabul ediyordu.\n */\ntype PgKind<P> = P extends \"integer\" | \"bigint\" | \"numeric\" ? \"num\" : P;\n\n/** İki tarafın da markası var mı — yoksa sezgisele düşülür. */\ntype BothBranded<A, B> = \"?\" extends PgTag<A> ? false : \"?\" extends PgTag<B> ? false : true;\n\ntype PgSameKind<A, B> = [PgKind<PgTag<A>>] extends [PgKind<PgTag<B>>]\n ? [PgKind<PgTag<B>>] extends [PgKind<PgTag<A>>]\n ? true\n : false\n : false;\n\n/**\n * `A` kolonu `B` ile karşılaştırılabilir mi.\n *\n * Marka varsa CEVAP KESİN: ne yanlış ret ne yanlış kabul. D-021 bu kuralı\n * \"doğru olamaz\" diye kaydetmişti çünkü tipte ayırt edecek bilgi yoktu; bilgi\n * artık tipte.\n */\ntype ColComparable<A, B> = BothBranded<A, B> extends true\n ? PgSameKind<A, B>\n : [PgFamily<A>] extends [PgFamily<B>]\n ? true\n : false;\n\n/** `Row`'un `V` ile karşılaştırılabilir kolonları. */\ntype ColumnsComparableTo<Row, V> = {\n [K in keyof Row]-?: ColComparable<Row[K], V> extends true ? K : never;\n}[keyof Row];\n\n/**\n * Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri.\n *\n * İKİNCİ PARAMETRE kolonun tipi. Verilmezse (`unknown`) KISIT YOKTUR — bu\n * `findMany`'nin `Row`'u bilmediği yolların ve jsonb kolonlarının hâli, ve\n * ikisinde de tipin söyleyebileceği bir şey yok.\n */\n/**\n * \"Kısıt verilmedi\" için AYRI bir işaret — `unknown` DEĞİL.\n *\n * Eskiden varsayılan `unknown`'dı ve dal `[unknown] extends [V]` ile\n * seçiliyordu. Ama `jsonb` kolonlarının DEĞER TİPİ de `unknown`: yani gerçek\n * bir jsonb kolonu \"kısıt verilmedi\" sanılıp TÜM kolonlarla karşılaştırılabilir\n * hâle geliyordu. D-021 bunu \"jsonb ↔ text derleniyor\" diye kaydetmişti ve PG\n * markası tek başına kapatmadı — `unknown & X` kesişimi `X`'e çöktüğü için\n * jsonb markalanamıyor (markalamak kolonu daraltıp meşru yazmaları kırdı,\n * gerçek projede ölçüldü).\n *\n * Ayrı bir işaretle iki durum artık ayrışıyor: kısıtsız yol kısıtsız kalıyor,\n * jsonb ise KENDİ ailesine düşüyor — yani yalnız başka bir jsonb ile\n * karşılaştırılabiliyor.\n */\ndeclare const NO_CONSTRAINT: unique symbol;\nexport type NoColConstraint = { readonly [NO_CONSTRAINT]: true };\n\nexport type ColRefOf<Row, V = NoColConstraint> = [keyof Row] extends [never]\n ? never\n : [V] extends [NoColConstraint]\n ? ColRef<Extract<keyof Row, string>>\n : ColRef<Extract<ColumnsComparableTo<Row, V>, string>>;\n\n/**\n * Doğrulanmış, GÖMÜLEBİLİR bir SQL parçası (FR-018, FR-019).\n *\n * Wire şekli `{ $sql: { text, values } }`: `text` parçalar hâlinde tutulur ve\n * değerler ARADA durur, çünkü birleştirilmiş tek bir string'in içinden hangi\n * kısmın kullanıcı verisi olduğunu bir daha kimse çıkaramaz — enjeksiyonun\n * doğduğu yer tam olarak orasıdır.\n */\nexport type SqlFragment = {\n readonly $sql: { readonly text: readonly string[]; readonly values: readonly unknown[] };\n};\n\n/**\n * Retryable bir hatada işlemi yeniden dener (FR-037).\n *\n * `fn` must open and settle a NEW transaction on each invocation. Repeating\n * a savepoint retains the old snapshot and cannot retry a failed COMMIT.\n * Database.$atomic owns that boundary for ordinary application code.\n *\n * VARSAYILAN SIFIR. Sessiz bir varsayılan retry, idempotent OLMAYAN bir işlemi\n * çağıranın haberi olmadan iki kez çalıştırırdı — bir para transferini iki kez.\n * Tekrar denemek çağıranın kararı.\n *\n * Yalnız `isRetryable(e)` olan hatalar tekrarlanır. Küme dar tutuluyor: `23505`\n * buraya girseydi tekrar denemek aynı cevabı verir ve döngü boşuna dönerdi.\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n opts: { retry?: number } = {},\n): Promise<T> {\n const budget = retryBudget(opts.retry);\n let attempt = 0;\n for (;;) {\n try {\n return await fn();\n } catch (e) {\n // Bütçe bittiğinde SON hata fırlatılıyor, sarmalanmıyor: çağıranın\n // gördüğü şey Postgres'in söylediği şey olsun.\n if (attempt >= budget || !isRetryable(e)) throw e;\n attempt += 1;\n }\n }\n}\n\n/**\n * K3: sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için kaçış kapağı.\n *\n * ```ts\n * Database.public.notes.findMany({\n * where: sqlFragment`similarity(title, ${q}) > 0.3`,\n * orderBy: { column: \"created_at\", direction: \"desc\" },\n * limit: 20,\n * })\n * ```\n *\n * `select` / `orderBy` / `limit` / RLS aynen çalışmaya devam eder — \"yetmedi,\n * ham SQL'e geçeyim\" anının bugünkü maliyeti tam olarak bunları kaybetmekti.\n *\n * TANIMLAYICI GÖMME YÜZEYİ YOK (`.raw` / `.unsafe` / `.identifier`). Drizzle'ın\n * CVE-2026-39356'sı ve Knex'in CVE-2019-10757'si tam o kapakta doğdu.\n *\n * Ve kapak fonksiyonun ÜSTÜNDE olmakla bitmiyordu: parça MARKALI değilken\n * `{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}` düz JSON'dan uydurulup\n * guard'ın tamamını atlıyordu (W2-B/C3, ölçüldü). Marka o kapağı wire ŞEKLİNE\n * de koyuyor — parça yalnız bu template tag'inden çıkabilir.\n */\nexport function sqlFragment(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): SqlFragment {\n return brandRef({ $sql: { text: [...strings], values } }, \"sql\");\n}\n\nexport type TextOps<V> = V extends string\n ? { contains?: string; icontains?: string; startsWith?: string; endsWith?: string }\n : { contains?: never; icontains?: never; startsWith?: never; endsWith?: never };\n\n/** Operatör gövdesi, kolon-referans tipi DIŞARIDAN verilmiş hâliyle.\n *\n * `C` bir parametre, çünkü `ColRefOf<Row, V>` aksi hâlde altı operatör\n * konumunda AYRI AYRI instantiate edilirdi — kolon başına altı mapped type.\n * Böyle kolon başına BİR tane (N-2). */\n/**\n * `now()` HANGİ kolonlarda karşılaştırma değeri olabilir.\n *\n * `timestamp` TypeScript'e `string` olarak geliyor — `text` ile aynı tip. Yani\n * \"yalnız zaman kolonları\" tip düzeyinde İFADE EDİLEMEZ (D-021'in tam olarak\n * kaydettiği sınır: TS numeric/bigint/text/uuid/timestamp'ı `string`'e\n * çöktürüyor). İki seçenekten yanlış KABUL, yanlış RET'e tercih ediliyor:\n * `now()`'ı bir metin kolonunda yazmak Postgres hatası verir, ama zaman\n * kolonunda YASAKLAMAK yazarı bu yüzden `sqlFragment`e düşürürdü — ve bu\n * özelliğin var olma nedeni tam olarak o düşüşü kaldırmak.\n */\ntype NowComparable<V> = \"?\" extends PgTag<V>\n ? [NonNullable<V>] extends [string | Date]\n ? TxNow\n : never\n : PgTag<V> extends \"timestamp\"\n ? TxNow\n : never;\n\ntype WhereOpBody<V, C> = {\n gt?: V | C | NowComparable<V>;\n gte?: V | C | NowComparable<V>;\n lt?: V | C | NowComparable<V>;\n lte?: V | C | NowComparable<V>;\n neq?: V | C | NowComparable<V>;\n in?: V[];\n /** `IS NULL` / `IS NOT NULL` (FR-006) — `= NULL` SQL'de her zaman UNKNOWN'dır. */\n isNull?: boolean;\n} & TextOps<V>;\n\nexport type WhereOp<V, Row = unknown> = WhereOpWith<V, ColRefOf<Row, V>>;\n\n/**\n * Operatör sözlüğü, kolon-referans/plan-tutamağı konumu DIŞARIDAN verilmiş.\n *\n * `export`, çünkü plan yüzeyi (`tx-plan.ts`) aynı sözlüğü `C = ColRefOf<…> |\n * Ref<…>` ile kuruyor: bir plan filtresi ÖNCEKİ bir işlemin sonucuna\n * bakabiliyor, `findMany` bakamıyor. Ref'i `V`'ye eklemek YANLIŞ olurdu —\n * `TextOps<V>` `V extends string` diye soruyor ve `string | Ref<string>` o\n * soruya HAYIR der, yani `contains`/`startsWith` sessizce KAYBOLURDU.\n */\nexport type WhereOpWith<V, C> = V | C | NowComparable<V> | WhereOpBody<V, C>;\n\n/**\n * A filter over a row: every field optional, each one a plain value (equality)\n * or an operator object. THE filter language — `findMany`, `updateMany`,\n * `deleteMany` and `count` all take this one, because two spellings of a filter\n * is how the two come to disagree.\n */\nexport type WhereFilter<Row> = { [K in keyof Row]?: WhereOp<Row[K], Row> } & {\n /**\n * Boolean bileşimi (FR-007). Dallar aynı filtre dilidir — iki yazım olmaz.\n *\n * ÖZYİNELEME BURADA BAŞLIYOR ve N-2'nin izlediği şey tam olarak budur:\n * Kysely'nin TS7'de 9,8M instantiation üreten vakası derin generic\n * özyinelemeydi. Burada derinlik yazarın filtresi kadardır ve pratikte\n * bir-iki seviyedir; tip maliyeti T001'in tavanına karşı ölçülür.\n *\n * Dal bir `sqlFragment` DE olabilir. Motor bunu zaten derliyordu — parantezli\n * ve parametreli (`… AND (((expires_at > now())) AND (t.\"city\" = $2))`) —\n * ama tip yalnız üst düzey `where`'de fragment'e izin veriyordu. Yani\n * \"fragment sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için\" sözü tam\n * da bileşim anında kırılıyordu: bir koşulu bir fragment'le birleştirmek\n * isteyen yazar SORGUNUN TAMAMINI ham SQL'e taşımak zorunda kalıyordu.\n * Ölçüldü: bir müşteri sorgusunda tam olarak bu oldu.\n */\n OR?: (WhereFilter<Row> | SqlFragment)[];\n AND?: (WhereFilter<Row> | SqlFragment)[];\n NOT?: WhereFilter<Row> | SqlFragment;\n};\n\n/**\n * Ordering and paging for a read.\n *\n * `column` is `keyof Row`, not `string`: a mistyped column name is a compile\n * error here rather than a runtime rejection three layers down. `offset`\n * without `limit` is refused by the engine — a page with no size is not a page.\n */\nexport type OrderBySpec<Row> = {\n column: Extract<keyof Row, string>;\n direction?: \"asc\" | \"desc\";\n /** NULL'ların yeri (FR-008). Verilmezse Postgres varsayılanı geçerlidir ve o\n * varsayılan YÖNE GÖRE DEĞİŞİR: ASC'de NULLS LAST, DESC'te NULLS FIRST. */\n nulls?: \"first\" | \"last\";\n};\n\nexport type FindManyOpts<Row> = {\n /** Tek sıralama ya da SIRALI liste — sıra korunur (FR-008). */\n orderBy?: OrderBySpec<Row> | OrderBySpec<Row>[];\n limit?: number;\n offset?: number;\n};\n\n/**\n * Bir okumanın TEK parametresi (FR-004b).\n *\n * `where` bir ALAN, konumsal bir argüman değil. Kullanıcının kararı: \"deterministik\n * olması lazım, tek düzlem\" — aynı bilginin iki yere dağılması, alanlar çoğaldıkça\n * (select/include/orderBy) \"hangisi nereye\" sorusunu ezberlenecek bir şeye çevirir.\n * Prisma ve Drizzle de tek obje kullanıyor. Bedeli açık ve kabul edildi: en sık\n * kullanım uzuyor — `findMany({ where: { owner: uid } })`.\n *\n * ÖZYİNELEMESİZ kalmak zorunda (N-2): tip maliyeti şekilden değil özyineleme\n * derinliğinden geliyor (Kysely'nin TS7'de 9,8M instantiation vakası).\n */\n/**\n * `has` — İLİŞKİ ÜZERİNDEN SÜZME, JOIN'in ihtiyaç duyulmayan hâli.\n *\n * ```ts\n * Database.public.interests.findMany({\n * where: { has: { user_interests: { user_id: uid } } },\n * orderBy: [{ column: \"sort_order\" }, { column: \"name\" }],\n * })\n * ```\n * → `… WHERE t.\"id\" IN (SELECT r1.\"interest_id\" FROM \"user_interests\" r1\n * WHERE r1.\"user_id\" = $1)`\n *\n * İlişki ADLARI ve gittikleri kolonlar `palbase-env.d.ts`'in ZATEN bastığı\n * `relations` bloğundan geliyor — yabancı anahtarlardan türetiliyorlar, yazar\n * hiçbir kolon adı yazmıyor. O blok üretiliyordu ve HİÇBİR okuma onu\n * kullanmıyordu; `has` onun karşılığı.\n *\n * İç filtre AYNI dil: bir tablo ötesinde de `gt`, `icontains`, `OR`, ve iç içe\n * `has` yazılabiliyor.\n */\n/**\n * İlişkinin HEDEF TABLOSU — anahtar ŞEMA NİTELİKLİ gelir.\n *\n * `buildRelations` `to`'yu `qualifiedTableKey` ile yazıyor: public için düz ad\n * (`\"interests\"`), başka şema için noktalı (`\"billing.invoices\"`). `Tables`\n * yalnız public'i taşır, diğerleri `Schemas`'tadır — noktalı anahtarı doğrudan\n * `Tables`'ta aramak HER ZAMAN ıskalar ve iç filtre sessizce `Record<string,\n * unknown>`'a düşerdi: bilinmeyen kolon da, yanlış tip de derlenirdi (ölçüldü).\n */\ntype RelatedTable<To> = To extends `${infer S}.${infer T}`\n ? S extends keyof Schemas\n ? T extends keyof Schemas[S]\n ? Schemas[S][T]\n : never\n : never\n : To extends keyof Tables\n ? Tables[To]\n : never;\n\ntype RelatedRow<To> = RelatedTable<To> extends { row: infer R } ? R : Record<string, unknown>;\ntype RelatedRels<To> = RelatedTable<To> extends { relations: infer R } ? R : unknown;\n\n/**\n * İç içe `has` ÜÇ seviyeyle sınırlı.\n *\n * Üretilen `relations` bloğu ÇİFT YÖNLÜ: `customers.invoices` ile\n * `invoices.customer` birbirini gösteriyor, yani grafiğin kendisi döngülü.\n * Sınırsız açılım bu döngüyü sonsuz bir tipe çevirirdi — TypeScript'in\n * \"excessively deep\" hatası, yazılan sorgunun karmaşıklığından değil ŞEMANIN\n * şeklinden gelirdi. Üç seviye, ölçtüğümüz tüm gerçek sorguların üstünde.\n */\ntype HasDepth = 0 | 1 | 2 | 3;\ntype HasDec = [0, 0, 1, 2];\ntype HasNest<Rels, D extends HasDepth> = [keyof Rels] extends [never]\n ? unknown\n : D extends 0\n ? unknown\n : { has?: HasFilter<Rels, HasDec[D]> };\n\ntype HasFilter<Rels, D extends HasDepth = 3> = {\n [R in keyof Rels]?: Rels[R] extends { to: infer To }\n ? WhereFilter<RelatedRow<To>> & HasNest<RelatedRels<To>, D>\n : never;\n};\n\n/** İlişki bilgisi taşıyan bir tablo tipinin filtre yüzeyi. */\nexport type WhereWithRelations<Row, Rels> = WhereFilter<Row> & { has?: HasFilter<Rels> };\n\n/**\n * `has` dalı — SADECE `has`, satır filtresi olmadan.\n *\n * Plan yolunun filtre dili (`TxWhere`) düz op'unkiyle aynı değil: orada bir\n * alan ÖNCEKİ bir işlemin satırına referans (`Ref`) taşıyabiliyor. `has`'ı\n * plana taşımak için o dili kopyalamak gerekmiyor — kesişimle EKLENİYOR.\n * İlişki yoksa `unknown` dönüyor, çünkü `X & unknown = X`: dal yok olur ve\n * `has` fazla-alan denetimine takılır.\n */\nexport type HasOnly<Rels> = [unknown] extends [Rels]\n ? unknown\n : [keyof Rels] extends [never]\n ? unknown\n : { has?: HasFilter<Rels> };\n\n/**\n * `has` dalı NE ZAMAN var olur.\n *\n * İlişkisi OLMAYAN bir tabloda `has` hiç yazılamamalı. `HasFilter<{}>` boş bir\n * nesne tipidir ve boş nesne tipi HER nesneyi kabul eder — yani dalı koşulsuz\n * eklemek, ilişkisiz bir tabloda `has: { neyse_ne: {} }`'yi SESSİZCE geçirirdi\n * (ölçüldü: kapı yeşil, çalışma anında \"böyle bir ilişki yok\" hatası).\n */\ntype HasBranch<Row, Rels> = [unknown] extends [Rels]\n ? never\n : [keyof Rels] extends [never]\n ? never\n : WhereWithRelations<Row, Rels>;\n\n/**\n * `with` — İLİŞKİLİ SATIRLARI GETİR (`has` süzer, `with` getirir).\n *\n * `true` bütün kolonları, bir nesne ise `select`/`where`/`orderBy`/`limit` ile\n * daraltılmış hâlini getiriyor. Tek sorgu: LATERAL + `json_agg`.\n */\ntype WithOpts<To, D extends HasDepth> = {\n select?: readonly Extract<keyof RelatedRow<To>, string>[];\n where?: WhereFilter<RelatedRow<To>>;\n orderBy?: OrderBySpec<RelatedRow<To>> | readonly OrderBySpec<RelatedRow<To>>[];\n limit?: number;\n with?: D extends 1 ? never : [keyof RelatedRels<To>] extends [never] ? never : WithInput<RelatedRels<To>, HasDec[D]>;\n};\n\nexport type WithInput<Rels, D extends HasDepth = 3> = {\n [R in keyof Rels]?: Rels[R] extends { to: infer To } ? true | WithOpts<To, D> : never;\n};\n\n/** Bir `with` dalının DÖNÜŞ tipi — `many` dizi, `one` tekil ya da null. */\ntype WithRowOf<Rels, R extends keyof Rels, Q> = Rels[R] extends { to: infer To; kind: infer K }\n ? (Q extends { select: readonly (infer C extends keyof RelatedRow<To>)[] }\n ? Pick<RelatedRow<To>, C>\n : RelatedRow<To>) & (Q extends { with: infer W } ? WithResult<RelatedRels<To>, W> : unknown) extends infer Row\n ? [K] extends [\"many\"]\n ? Row[]\n : Row | null\n : never\n : never;\n\n/**\n * `with` istenmediğinde `unknown` — kesişimde YOK OLSUN diye.\n *\n * Boş bir nesne (`{}`) dönseydi `Pick<Row, K> & {}` satır tipini \"aynı ama\n * özdeş değil\" hâle getirirdi ve tam eşitlik iddiaları kırılırdı. Ölçüldü:\n * `toEqualTypeOf` dört yerde düştü.\n */\n/**\n * Yalnız GERÇEKTEN istenen dallar. `undefined extends W[R]` olan anahtarlar\n * düşüyor — ve bu, `ReturnType<typeof t.findMany>` yazan herkes için kritik:\n * generic bir imzada `ReturnType` tip parametrelerini VARSAYILANLA değil\n * KISITLA örnekliyor, yani `W = WithInput<Rels>` oluyor ve her ilişki\n * (`?:` ile, dolayısıyla `| undefined`) zorunlu bir alana dönüşüyordu.\n * Gerçek projede ölçüldü: `type MemberRow = Awaited<ReturnType<…findMany>>[number]`\n * 32 ilişkiyi birden ister hâle geldi ve 4 yerde kırıldı.\n */\ntype RequestedWith<W> = { [R in keyof W]-?: undefined extends W[R] ? never : R }[keyof W];\n\nexport type WithResult<Rels, W> = [RequestedWith<W>] extends [never]\n ? unknown\n : { [R in RequestedWith<W> & keyof Rels]: WithRowOf<Rels, R, W[R]> };\n\nexport type QueryInput<Row, K extends keyof Row = keyof Row, Rels = unknown> = {\n /**\n * Filtre — ya tipli filtre dili ya da bir `sqlFragment` (FR-018). İkisi de\n * AYNI alandır: kademe atlamak bir parametre değişikliği, ayrı bir çağrı\n * yolu değil (P1).\n */\n where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n /**\n * İlişkili satırları da getir — TEK sorguda.\n *\n * ```ts\n * const rows = await Database.public.users.findMany({\n * where: { active: true },\n * with: { orders: { select: [\"id\", \"amount\"], limit: 5 } },\n * });\n * rows[0].orders[0].amount; // string — KAYIPSIZ\n * ```\n *\n * `many` ilişki DİZİ döner (boşsa `[]`, `null` değil — `.map()` guard\n * istemesin); `one` ilişki tekil satır ya da `null`.\n *\n * PARA: `numeric`/`bigint` kolonları JSON'a `::text` ile giriyor. Cast\n * olmadan `numeric` bir JSON SAYISI olur ve kesinliğini kaybeder — ölçüldü,\n * `100000000000000000000000000` → `1e+26`.\n */\n // `HasBranch` ile AYNI iki koşul, aynı gerekçe: `unknown` ise kısıt yok\n // demektir, ve `WithInput<{}>` boş bir nesne tipidir — boş nesne HER nesneyi\n // kabul eder, yani ilişkisiz bir tabloda `with` sessizce geçerdi.\n with?: [unknown] extends [Rels] ? never : [keyof Rels] extends [never] ? never : WithInput<Rels>;\n /**\n * Projeksiyon (FR-009): yalnız bu kolonlar çekilir ve DÖNÜŞ TİPİ buna daralır.\n *\n * Tip `Pick<Row, K>` ile TÜRETİLİR, üretilmez: `select` kombinasyonları için\n * tip basmak, üretilen `.d.ts`'i kombinatoryal olarak şişirirdi (N-1: tablo\n * başına ≤ 25 satır).\n */\n select?: readonly K[];\n} & FindManyOpts<Row>;\n\nexport type PageInput<Row, K extends keyof Row = keyof Row, Rels = unknown> =\n Omit<QueryInput<Row, keyof Row, Rels>, \"limit\" | \"offset\" | \"select\"> &\n { select?: readonly K[] } & import(\"./page.js\").PageNavigation;\n\n/** Bir yazmanın TEK parametresi: neyi (`where`) neye çevirdiğin (`set`). */\nexport type MutateInput<Row, Insert, Rels = unknown> = {\n where: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n set: SetShape<Insert>;\n /**\n * `false` verilirse SATIRLAR değil SAYI döner — `deleteMany` ile aynı şekil.\n *\n * ÖLÇÜLDÜ (200 bin satır, canlı pg16): `RETURNING *` sunucuda %55 daha\n * pahalı (7,2 sn → 11,1 sn) ve JS'te 45 MB yığın tutuyor — satır başına 236\n * bayt, yani bir milyon satırda 225 MB. Çoğu çağrı için dönen diziyi okumak\n * DOĞRU ve varsayılan odur; toplu bir iş için çıkış yolu olması gerekiyordu.\n */\n returning?: boolean;\n};\n\n/**\n * `set`'e yazılabilen değer (FR-012): kolonun kendi tipi ya da — sayısal\n * kolonlarda — kolonun ŞU ANKİ değerini okuyan bir ifade.\n *\n * `increment()` metin ya da boolean kolonda YOK: \"kolona ekle\"nin orada bir\n * anlamı olmadığı için ifade edilemez kılınıyor (P5 — anlatmak değil, ifade\n * edilemez kılmak). `numeric` kolonlar TypeScript'te `string` taşır, o yüzden\n * string de sayısal sayılır; ayrımı burada yapamayız, ama D-007 zaten miktarın\n * JS `number`'a hiç uğramamasını istiyor.\n */\n/** `increment()`/`decrement()` HANGİ kolonlarda anlamlı — bildirilmiş PG tipine\n * göre. Marka yoksa eski sezgisel (`number | string`), ki o `text` kolonda da\n * izin veriyordu: Postgres `text + 1` demez. */\ntype NumericCol<V> = \"?\" extends PgTag<V>\n ? NonNullable<V> extends number | string\n ? TxColumnExpr\n : never\n : PgKind<PgTag<V>> extends \"num\"\n ? TxColumnExpr\n : never;\n\n/**\n * Bir EKLEME yolunda yazılabilecek değer.\n *\n * Kolonun kendi tipi ya da — zaman kolonlarında — sunucu saati. `increment()`\n * burada YOK ve olamaz: satır henüz yokken \"kolonun şu anki değeri\" diye bir\n * şey yok, motor da bunu adıyla reddediyor.\n *\n * Var olma nedeni ölçülmüş: introspect edilmiş şemalarda zaman kolonlarının\n * çoğu varsayılansız (`timestamp()`), yani \"eklerken sunucu saatini yaz\"ın tek\n * karşılığı istemci saatiydi — 33 tablolu bir projede 12 yerde.\n */\nexport type InsertValues<Insert> = {\n [K in keyof Insert]: Insert[K] | NowComparable<Insert[K]>;\n};\n\nexport type SetValue<V> =\n | V\n | NumericCol<V>\n // `now()` doğrudan yolda da geçerli: motor onu `SET col = now()` diye\n // derliyor (plan yolunun her zaman yaptığı gibi). Tipte yasaklamak, çalışan\n // bir çağrıyı ifade edilemez kılardı — P5'in tersi.\n //\n // VE TAM OLARAK BUNU YAPIYORDU: koşul `Date` idi, oysa `timestamp` kolonlar\n // TypeScript'e `string` geliyor. Yani `set: { updated_at: now() }` —\n // yazılabilecek en sık yazma ifadesi — HİÇBİR üretilmiş şemada derlenmiyordu\n // (ölçüldü). Marka o koşulu doğru yazılabilir kıldı.\n | NowComparable<V>;\n\n/** Bir update'in `set`'i: insert şeklinin herhangi bir alt kümesi, ifadelerle. */\nexport type SetShape<Insert> = { [K in keyof Insert]?: SetValue<Insert[K]> };\n\n/** search() parametreleri, satır tipiyle koşullanmış (FR-013). `offset` BİLEREK yok (UD-013). */\nexport interface SearchParamsTyped<T extends TableTypes> {\n /** Metin sorgusu: FTS kolunu besler; embed beyanlıysa sorgu vektörü de bundan üretilir. */\n query?: string;\n /** Hazır sorgu vektörü — verilirse embed çağrısı olmaz (FR-025). */\n vector?: number[];\n /** `findMany`'nin filtre dili — İKİNCİ tip argümanıyla, yoksa `Row` sessizce\n * `unknown`'a düşer ve `col()` burada ifade edilemez olurdu. Motor `search`\n * için aynı `compileWhereBare`'i kullanıyor; yetenek orada (gözcü I7). */\n where?: { [K in keyof T[\"row\"]]?: WhereOp<T[\"row\"][K], T[\"row\"]> };\n /** default 20, tavan 100 (engine uygular). */\n limit?: number;\n /** Birden çok vektör kolonunda hedef seçimi (model geçişi, FR-013/using). */\n using?: string;\n mode?: \"hybrid\" | \"text\" | \"vector\";\n /** Nihai (RRF-sonrası) skor alt eşiği — süzme LIMIT'ten önce uygulanır (FR-001). */\n minScore?: number;\n /** Chunk-modunda satır başına en iyi blok sayısı (1..10, vars. 3; FR-015). */\n blocksPerRow?: number;\n /** Tazelik çürümesi: nihai skor RRF-sonrası exp(-ln(2)*yaş/halfLife) ile çarpılır;\n * field bir timestamp kolonu, halfLife \"90s\" | \"15m\" | \"12h\" | \"30d\" biçiminde (FR-004). */\n recency?: { field: Extract<keyof T[\"row\"], string>; halfLife: string };\n /** Satır-modunda FTS eşleşme vurgusu: sonuç satırına `_highlight` ekler;\n * chunk-modda no-op — bloklar zaten eşleşen kesittir (FR-025). */\n highlight?: boolean;\n /** Validity'li tabloda zaman penceresi: varsayılan yalnız güncel versiyon;\n * \"all\" tüm versiyonlar; {asOf} o anda geçerli olan (FR-029). */\n validity?: \"all\" | { asOf: string };\n /** Alan-boost (FR-030): skor * (1 + w·x/(1+x)) — sayısal kolonla sınırlı\n * çarpan, dış servissiz; bileşim RRF → boost → recency → minScore. */\n boost?: { field: Extract<keyof T[\"row\"], string>; weight: number };\n}\n\n/**\n * `facets()` dönüşü (FR-027, FR-058): kolon adı → o kolonun top-20 değeri ve\n * sayacı.\n *\n * Bu tip bir zamanlar `search()` dönüş DİZİSİNİN üstünde taşınıyordu; dizi-üstü\n * özellik `JSON.stringify`'da kayboluyor, yani bir kontrolcü onu döndürmeye\n * çalıştığında yanıt gövdesinde hiç görünmüyordu. Sayaçlar artık BAĞIMSIZ\n * dönüşle geliyor ve tip de o dönüşü adlandırıyor.\n */\nexport type SearchFacets = Record<string, { value: string | null; count: number }[]>;\n\n/** similar()/recommend() taşıyıcı opsiyonları (T018, FR-022): search'ün\n * paramlarından query/vector/mode düşer — hedef vektörü metodun kendisi\n * DB'den kurar; facets/highlight de düşer (T020) — engine bu ikisini\n * similar/recommend'e geçirmez, tip vaadi gerçekle aynı kalır. */\nexport type SimilarParamsTyped<T extends TableTypes> = Omit<\n SearchParamsTyped<T>,\n \"query\" | \"vector\" | \"mode\" | \"facets\" | \"highlight\"\n>;\n\n/** recommend() parametreleri (T018, FR-023). */\nexport type RecommendParamsTyped<T extends TableTypes> = SimilarParamsTyped<T> & {\n /** Kaynak beğeniler — hedef vektör bunların DB-içi avg'ı; boş olamaz. */\n positive: string[];\n /** İtilen örnekler — hedef pos.v + (pos.v - neg.v) ile yönlenir. */\n negative?: string[];\n};\n\n/**\n * Tablonun ilişki bloğu — env `Tables` girdisinden.\n *\n * TEK yerde türetiliyor ve HER op'a aynısı veriliyor: `has` yalnız `findMany`'de\n * olsaydı, \"aynı filtre dili her op'ta\" sözü ilk `deleteMany`'de kırılırdı.\n */\ntype RelsOf<T> = T extends { relations: infer R } ? R : unknown;\n\n/**\n * TOPLAMA — dönüş tipi PG markasından TÜRETİLİR, tahmin edilmez.\n *\n * Para bu SDK'dan geçecek, ve toplamada kaybedilecek tek şey kesinliktir:\n * `sum(numeric)` Postgres'te `numeric`, `sum(integer)` `bigint` — İKİSİ DE JS\n * `number`'ında kayıplı. Bu yüzden `sum`/`avg` HER ZAMAN `string` döner ve\n * motor `::text` ile döker. D-007'nin kapattığı hata buydu:\n * 41.00821234567890123 canlıda 41.0082123456789 oluyordu.\n *\n * `| null` bir süs değil: Postgres BOŞ kümede NULL döndürür, 0 değil. \"Hiç\n * satır yoktu\" ile \"toplam sıfırdı\" farklı şeyler, ve tip bunu sormaya\n * ZORLUYOR.\n */\ntype SummableCols<Row> = {\n [K in keyof Row]-?: \"?\" extends PgTag<Row[K]>\n ? NonNullable<Row[K]> extends number | string\n ? K\n : never\n : PgKind<PgTag<Row[K]>> extends \"num\"\n ? K\n : never;\n}[keyof Row];\n\n/** `min`/`max` sıralanabilir her kolonda — jsonb ve vektör hariç. */\ntype OrderableCols<Row> = {\n [K in keyof Row]-?: \"?\" extends PgTag<Row[K]>\n ? NonNullable<Row[K]> extends number | string | Date\n ? K\n : never\n : PgTag<Row[K]> extends \"jsonb\" | \"vector\"\n ? never\n : K;\n}[keyof Row];\n\ntype AggCols<Row> = Extract<SummableCols<Row>, string>;\ntype AggOrderCols<Row> = Extract<OrderableCols<Row>, string>;\n\nexport type AggregateInput<Row, Rels = unknown> = {\n where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n /** Toplam — yalnız sayısal kolonlarda; sonuç `string | null` (kayıpsız). */\n sum?: readonly AggCols<Row>[];\n /** Ortalama — sonuç `numeric`, yani `string | null`. */\n avg?: readonly AggCols<Row>[];\n min?: readonly AggOrderCols<Row>[];\n max?: readonly AggOrderCols<Row>[];\n /** Kaç satır — `count()` ile aynı sayı, ama AYNI turda. */\n count?: boolean;\n /** Verilirse SATIRLAR döner ve her satır grup kolonlarını taşır. */\n groupBy?: readonly Extract<keyof Row, string>[];\n};\n\ntype AggPart<Q, Row, F extends \"sum\" | \"avg\" | \"min\" | \"max\"> = Q extends {\n [K in F]: readonly (infer C extends keyof Row)[];\n}\n ? { [P in C]: F extends \"sum\" | \"avg\" ? string | null : Row[P] | null }\n : never;\n\ntype AggBody<Q, Row> = ([AggPart<Q, Row, \"sum\">] extends [never] ? unknown : { sum: AggPart<Q, Row, \"sum\"> }) &\n ([AggPart<Q, Row, \"avg\">] extends [never] ? unknown : { avg: AggPart<Q, Row, \"avg\"> }) &\n ([AggPart<Q, Row, \"min\">] extends [never] ? unknown : { min: AggPart<Q, Row, \"min\"> }) &\n ([AggPart<Q, Row, \"max\">] extends [never] ? unknown : { max: AggPart<Q, Row, \"max\"> }) &\n (Q extends { count: true } ? { count: number } : unknown);\n\nexport type AggregateResult<Q, Row> = Q extends {\n groupBy: readonly (infer G extends keyof Row)[];\n}\n ? ({ [P in G]: Row[P] } & AggBody<Q, Row>)[]\n : AggBody<Q, Row>;\n\n/** Temel tablo erişimcisi — search'süz beş op. */\nexport interface EnvTypedTableBase<T extends TableTypes> {\n findUnique<K extends keyof T[\"row\"] = keyof T[\"row\"], W extends WithInput<RelsOf<T>> = Record<never, never>>(q: {\n where: import(\"./unique.js\").UniqueWhere<T[\"row\"], T[\"uniqueKeys\"]>;\n select?: readonly K[]; with?: QueryInput<T[\"row\"], keyof T[\"row\"], RelsOf<T>>[\"with\"] & W;\n }): Promise<(Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>) | null>;\n /** Index-backed pagination. The engine appends the declared primary key to\n * orderBy, encrypts cursor values and validates the query and caller scope. */\n page<K extends keyof T[\"row\"] = keyof T[\"row\"], W extends WithInput<RelsOf<T>> = Record<never, never>>(\n q?: PageInput<T[\"row\"], K, RelsOf<T>> & { with?: W },\n ): Promise<import(\"./page.js\").Page<Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>>>;\n insert(data: InsertValues<T[\"insert\"]>): Promise<T[\"row\"]>;\n /**\n * Çok satırı TEK statement'la ekle (tek gidiş-dönüş).\n *\n * ```ts\n * await Database.public.journey_stops.insertMany(\n * stops.map((s, i) => ({ journey_id, name: s.name, sort_order: i })),\n * );\n * ```\n *\n * Satırların anahtar kümesi AYNI olmalı: tek statement kolon listesini\n * paylaşır, yani farklı şekilli bir satırın fazla kolonu sessizce yazılmaz\n * ve eksiği yanlış sütuna kayardı. Eksik alan için `null` yazın.\n *\n * Boş dizi boş sonuç döner — hata değil: \"eklenecek bir şey yoktu\".\n */\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>> & { returning: false }): Promise<number>;\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts?: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>> & { returning?: true }): Promise<T[\"row\"][]>;\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts?: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>>): Promise<T[\"row\"][] | number>;\n /**\n * Bir idempotency anahtarını sahiplen (FR-033).\n *\n * ```ts\n * const { inserted, row } = await Database.public.payments.claim(\n * { idem_key: req.headers[\"idempotency-key\"] },\n * { amount, user_id },\n * );\n * if (!inserted) return row; // aynı istek ikinci kez geldi\n * ```\n *\n * `inserted: false` bir HATA DEĞİL: dönen satır ilk çağrının satırıdır.\n * İlk argüman satırı BULAN alanlar, ikincisi yalnız yazılanlar — ikinci çağrı\n * farklı bir yük gönderse bile satır anahtarla bulunur.\n */\n claim(\n unique: Partial<T[\"insert\"]>,\n extra?: Partial<InsertValues<T[\"insert\"]>>,\n ): Promise<{ inserted: boolean; row: T[\"row\"] }>;\n /**\n * Satırı yaz; `onConflict` kolonlarında çakışırsa ÜZERİNE yaz (FR-034).\n *\n * ```ts\n * await Database.public.settings.put({\n * data: { user_id, theme: \"dark\" },\n * onConflict: [\"user_id\"],\n * });\n * ```\n *\n * `onConflict` kolonları benzersiz bir kısıt ya da index taşımalı — Postgres\n * onlarla eşleştirir — ve güncellemeden dışlanırlar, çünkü eşleşen şey onlar.\n *\n * **`upsert`'ün yerine geldi ve adı bilerek değişti.** `upsert` tek isim\n * altında iki niyet taşıyordu: \"yoksa ekle varsa güncelle\" (bu) ve \"idempotent\n * yaz\" (artık {@link EnvTypedTableBase.claim}). İkincisi için ÖLÇÜLMÜŞ biçimde\n * yanlıştı: `DO UPDATE` ikinci çağrının verisiyle birincininkini EZİYOR\n * (10.00 → 999.00 ölçüldü). İki niyeti tek isimde tutmak, yanlış olanı\n * seçmeyi kolay yapıyordu.\n */\n put(q: {\n data: InsertValues<T[\"insert\"]>;\n onConflict: readonly Extract<keyof T[\"row\"], string>[];\n }): Promise<T[\"row\"]>;\n /** Update the row by id; resolves to the updated row, or `null` if no row\n * matched (absent or RLS-hidden) — an idempotent outcome, mirroring\n * `findById`. The runtime returns a null row rather than throwing. */\n update(q: { where: { id: string }; set: SetShape<T[\"insert\"]> }): Promise<T[\"row\"] | null>;\n delete(id: string): Promise<void>;\n findById(id: string): Promise<T[\"row\"] | null>;\n /** Rows matching the filter. See {@link WhereFilter} / {@link FindManyOpts} —\n * this declaration is what makes the engine's operators callable. */\n findMany<\n K extends keyof T[\"row\"] = keyof T[\"row\"],\n W extends WithInput<RelsOf<T>> = Record<never, never>,\n >(\n // `K` ve `W` AYRI çıkarım noktaları. Tek bir `const Q` generic'i denendi ve\n // ESKİ BİR KAPIYI ÖLDÜRDÜ: `where: { note: { contains: 5 } }` — metin\n // olmayan bir değerle `contains` — derlenmeye başladı, çünkü kısıt denetimi\n // literal çıkarımın altında kayboluyordu. Ölçüldü ve geri alındı.\n q?: QueryInput<T[\"row\"], K, RelsOf<T>> & { with?: W },\n ): Promise<Array<Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>>>;\n /**\n * Update every matching row in one statement; an empty filter is refused.\n *\n * **0 satır dönmesi hata DEĞİL, başarı da değil** (FR-014): koşulu `where`'e\n * koyup dönen diziyi kontrol etmek, \"önce oku sonra yaz\"ın yarış koşulu\n * olmayan hâlidir.\n *\n * ```ts\n * const [row] = await Database.public.accounts.updateMany({\n * where: { id, balance: { gte: amount } },\n * set: { balance: decrement(amount) },\n * });\n * if (row === undefined) throw new Conflict(\"yetersiz bakiye\");\n * ```\n */\n updateMany<const Q extends MutateInput<T[\"row\"], T[\"insert\"], RelsOf<T>>>(\n q: Q,\n ): Promise<Q extends { returning: false } ? number : T[\"row\"][]>;\n /** Delete every matching row; resolves to how many. Empty filter refused. */\n deleteMany(q: { where: WhereFilter<T[\"row\"]> | SqlFragment | HasBranch<T[\"row\"], RelsOf<T>> }): Promise<number>;\n /**\n * Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.\n *\n * ```ts\n * const r = await Database.public.entries.aggregate({\n * where: { account_id },\n * sum: [\"amount_kurus\"],\n * count: true,\n * });\n * r.sum.amount_kurus; // string | null — KAYIPSIZ\n * r.count; // number\n * ```\n *\n * `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS\n * `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres\n * boş kümede NULL döndürür — \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı\n * şeyler ve tip bunu sormaya zorluyor.\n *\n * `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.\n */\n aggregate<const Q extends AggregateInput<T[\"row\"], RelsOf<T>>>(\n q: Q,\n ): Promise<AggregateResult<Q, T[\"row\"]>>;\n /** How many rows match. An empty filter is legitimate: counting is a read. */\n count(q?: { where?: WhereFilter<T[\"row\"]> | SqlFragment | HasBranch<T[\"row\"], RelsOf<T>> }): Promise<number>;\n /** Validity'li tabloda satırın yeni versiyonu (FR-029, C-9): eski satır\n * kapanır (valid_to/superseded_by), yenisi TEK savepoint'te eklenir; dönüş\n * yeni satır. Validity beyanı olmayan tabloda adlandırılmış çalışma-zamanı\n * hatası — tip düzeyinde ayrım env `Tables` bayrağı taşımadığından yapılamaz. */\n supersede(id: string, row: InsertValues<T[\"insert\"]>): Promise<T[\"row\"]>;\n}\n\n/** Tablo erişimcisi: env girdisi `searchable: true` taşıyorsa (vector kolonu ya da\n * search beyanı — env-gen üretir) `search()` üyesi VARDIR; yoksa üye hiç yoktur ve\n * çağrı derleme hatasıdır (FR-013). Yapısal koşul TableTypes'ı genişletmeden çalışır. */\n/**\n * `appendOnly` tabloda YAYIMLANMAYAN üyeler (FR-031).\n *\n * Altısı da ayrı ayrı: biri unutulursa append-only sözü o üye üzerinden sessizce\n * delinir. `insert` ve okuma üyeleri kalır — düzeltme SİLMEKLE değil, telafi\n * kaydı EKLEMEKLE yapılır (FR-032).\n */\ntype AppendOnlyForbidden = \"update\" | \"updateMany\" | \"delete\" | \"deleteMany\" | \"put\" | \"supersede\";\n\nexport type EnvTypedTable<T extends TableTypes> = (T extends { appendOnly: true }\n ? Omit<EnvTypedTableBase<T>, AppendOnlyForbidden>\n : EnvTypedTableBase<T>) &\n (T extends { searchable: true }\n ? {\n search(\n params: SearchParamsTyped<T>,\n ): Promise<Array<T[\"row\"] & { _score: number; _highlight?: string }>>;\n /** \"Bu satıra benzeyenler\" (FR-022): hedef vektör DB'den okunur,\n * kaynak satır sonuçta yoktur; id yoksa adlandırılmış hata. */\n similar(id: string, params?: SimilarParamsTyped<T>): Promise<Array<T[\"row\"] & { _score: number }>>;\n /** D-021: sayaçlar bağımsız dönüşle — search'ün dizi-üstü _facets'i\n * JSON.stringify'da kaybolur; ciddi sözleşme budur. */\n facets(params: { facets: Array<keyof T[\"row\"] & string>; where?: Partial<T[\"row\"]>; validity?: \"all\" | { asOf: string } }): Promise<SearchFacets>;\n /** positive/negative beğenilerden öneri (FR-023): hedef vektör DB-içi\n * avg CTE'leriyle; kaynak id'ler sonuçta yoktur. */\n recommend(params: RecommendParamsTyped<T>): Promise<Array<T[\"row\"] & { _score: number }>>;\n }\n : Record<never, never>);\n\n/** The `tables` map exposed on `Database`/`tx`, keyed by the env `Tables`\n * interface. When no schema is declared `Tables` is empty, so `tables` is an\n * empty object — accessing `.tables.foo` is then a compile error (no member). */\nexport type EnvTables = {\n [K in keyof Tables]: EnvTypedTable<Tables[K]>;\n};\n\n/**\n * The project's NON-public schemas, keyed by schema name, each exposing its own\n * `tables` map — the shape `Database.schema(\"billing\")` returns.\n *\n * The intermediate `tables` is there for the reason {@link EnvTables} sits under\n * `.tables`: a schema's table names must not share a namespace with anything the\n * accessor itself might grow.\n *\n * Empty by default. The generated `palbase-env.d.ts` augments `Schemas` with one\n * member per declared schema other than `public`, so a project that declares\n * none has `keyof Schemas = never` and every `schema(...)` call is a compile\n * error rather than a runtime surprise.\n */\n/**\n * @deprecated ARTIK VAR OLMAYAN BİR ŞEKLİ tarif ediyor. Bu tip her şemayı\n * `{ tables: … }` altında gösteriyor; yüzey FR-001 ile `Database.<şema>.<tablo>`\n * oldu ve `.tables` ara katmanı KALKTI. Güncel şekil: {@link EnvSchemaSurface}.\n *\n * Kaldırılmadı çünkü dışa açık bir tip ve kaldırmak SEKİZİNCİ bir kırıcı olurdu;\n * ama bir tip, çalışma zamanının ÜRETMEDİĞİ bir şekli tarif ediyorsa yalan\n * söylüyor demektir — `const x: EnvSchemas[\"billing\"] = Database.billing`\n * açıklanamayan bir derleme hatası verir. Bir sonraki kırıcı sürümde silinmeli\n * (defter D-18).\n *\n * Bu tipi ÜRETEN iki fonksiyon (`makeTablesAccessor`, `makeSchemaAccessor`)\n * ölçüldü: hiçbir yerden çağrılmıyorlardı ve silindiler. Canlı yol\n * `makeTypedSurface`'ın proxy'si.\n */\nexport type EnvSchemas = {\n [S in keyof Schemas]: {\n tables: {\n [T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;\n };\n };\n};\n\n/** The project's tables as PLAN operations, keyed by the env `Tables`\n * interface. The transaction twin of {@link EnvTables}. */\n/** `appendOnly` bir tabloda transaction planının da kaybettiği üyeler. Doğrudan\n * yüzeyin `AppendOnlyForbidden`'ının plan-yolu ikizi; adlar farklı çünkü plan\n * yüzeyinin üye adları farklı. */\ntype TxAppendOnlyForbidden = \"put\" | \"updateWhere\" | \"deleteWhere\";\n\n/**\n * Plan yüzeyi de `appendOnly`'yi UYGULUYOR — ve uygulamıyor olması bir kusurdu.\n *\n * `EnvTypedTable` altı üyeyi Omit ediyordu, ama `TxTables` hiçbirini: yani\n * `tx.tables.entries.updateWhere(…)` ve `.put(…)` DERLENİYORDU. Tip bir şeyi\n * \"ifade edilemez\" ilan edip ikinci bir kapıda ifade edilebilir bırakırsa,\n * ilan yalandır (doğrulayıcı gözcü, FR-031).\n *\n * Motor da aynı üçünü adıyla reddediyor — tip atlanınca susmaması için.\n */\nexport type TxTables = {\n [K in keyof Tables]: Tables[K] extends { appendOnly: true }\n ? Omit<TxTable<Tables[K][\"row\"], Tables[K][\"insert\"], RelsOf<Tables[K]>>, TxAppendOnlyForbidden>\n : TxTable<Tables[K][\"row\"], Tables[K][\"insert\"], RelsOf<Tables[K]>>;\n};\n\n/** Bir şemanın tabloları PLAN operasyonları olarak — `TxTables`'ın public\n * DIŞI şemalar için ikizi. */\ntype TxTablesOf<S> = {\n [T in keyof S]: Extract<S[T], TableTypes> extends { appendOnly: true }\n ? Omit<\n TxTable<\n Extract<S[T], TableTypes>[\"row\"],\n Extract<S[T], TableTypes>[\"insert\"],\n RelsOf<Extract<S[T], TableTypes>>\n >,\n TxAppendOnlyForbidden\n >\n : TxTable<\n Extract<S[T], TableTypes>[\"row\"],\n Extract<S[T], TableTypes>[\"insert\"],\n RelsOf<Extract<S[T], TableTypes>>\n >;\n};\n\n/**\n * Plan tutamağının şema yüzeyi — `EnvSchemaSurface`'ın BİREBİR ikizi.\n *\n * NEDEN AYNI ŞEKİL: `Database.billing.invoices` yazılabiliyorken\n * `tx.billing.invoices` yazılamıyordu, yani `billing` şemasındaki iki tabloyu\n * TEK ATOMİK PLANDA yazmak imkânsızdı — yazar `$query`'ye düşüyor, tipi ve RLS\n * yardımını kaybediyordu. Bu yüzeyin kapatmak için var olduğu düşüşün ta\n * kendisi, ve GOAL'ün \"ciddi ölçekli fintech\" yarısının tam ortasında\n * (nihai inceleme I-6).\n */\nexport type TxSchemaSurface = { public: TxTables } & {\n [S in keyof Schemas]: TxTablesOf<Schemas[S]>;\n};\n\n/**\n * The handle a `Database.$transaction(…)` callback receives.\n *\n * Tables only — no `query`, no `findById`, no `asService`. A read whose value\n * the plan does not write belongs outside the transaction, where it costs one\n * round trip and is an ordinary value you can branch on.\n *\n * `tx.public.x` ve `tx.<şema>.x`, `Database` ile aynı şekil. `tx.tables.x`\n * public'in TAKMA ADI olarak duruyor: bu run'ın göç notu onu öğretiyor ve her\n * mevcut çağrı onu kullanıyor — kaldırmak sekizinci bir kırıcı olurdu ve\n * hiçbir şey kazandırmazdı.\n */\nexport type TxPlan = TxPlanHandle<TxTables> & TxSchemaSurface;\n\n/**\n * The RLS-bypass sibling returned by `Database.$asService()`. Same typed surface\n * as {@link EnvTypedDatabase} — `tables`, the raw string ops, and a typed\n * `transaction` — but it does NOT re-expose `asService` (no double-bypass).\n * Every op it performs runs as the `service_role` (BYPASSRLS).\n */\nexport type EnvServiceDatabase = EnvSchemaSurface & {\n /** Commits independently of the request. All decision reads and writes belong\n * inside this callback; each retry includes a new BEGIN and COMMIT. */\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T>;\n /** Ham SQL. Generic verilmezse `unknown[]` döner (FR-021). */\n $query: DBClient[\"query\"];\n $insert: DBClient[\"insert\"];\n $update: DBClient[\"update\"];\n $delete: DBClient[\"delete\"];\n $findById: DBClient[\"findById\"];\n $findUnique: DBClient[\"findUnique\"];\n $diagnostics: DBClient[\"diagnostics\"];\n $findMany: DBClient[\"findMany\"];\n $page: DBClient[\"page\"];\n $put: DBClient[\"put\"];\n $updateMany: DBClient[\"updateMany\"];\n $deleteMany: DBClient[\"deleteMany\"];\n $count: DBClient[\"count\"];\n $search: DBClient[\"search\"];\n $similar: RecoOps[\"similar\"];\n $recommend: RecoOps[\"recommend\"];\n $facets: DBClient[\"facets\"];\n $supersede: DBClient[\"supersede\"];\n $claim: DBClient[\"claim\"];\n $lockRows: DBClient[\"lockRows\"];\n $lockRowsWhere: DBClient[\"lockRowsWhere\"];\n $advisoryXactLock: DBClient[\"advisoryXactLock\"];\n $attempt: DBClient[\"attempt\"];\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n /** Bkz. {@link EnvTypedDatabase.$transaction}. */\n /**\n * A plan is a savepoint in the current transaction. Nonzero `retry` is\n * refused; use $atomic for whole-transaction retry, including decision reads\n * and COMMIT. The default plan keeps request-scoped commit/rollback behavior.\n */\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>>;\n }\n\n/**\n * The typed-by-default Database surface: the `$`-prefixed string-keyed\n * `DBClient` ops PLUS one property per schema — `public` and every schema the\n * project declares — typed against the generated `palbase-env.d.ts`, a\n * `$transaction` that runs a whole plan in one request, and `$asService()` for\n * the explicit RLS-bypass sibling.\n *\n * NOT `tables`: that intermediate layer was removed (FR-001) and this sentence\n * outlived it by two majors, teaching a spelling that is TS2339. Pinned in\n * `src/database-ambient.test-d.ts`.\n *\n * The low-level `txPlan` op is deliberately NOT re-exposed here: `$transaction`\n * is the surface, and a hand-built plan would bypass the ref/guard machinery\n * that makes one safe to write.\n */\nexport type EnvSchemaSurface = { public: EnvTables } & {\n [S in keyof Schemas]: {\n [T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;\n };\n};\n\n/**\n * `$` öneki, sistem üyelerini kullanıcı adlarından AYIRAN şeydir (FR-002/003).\n *\n * `Database` altında on beşten fazla string-anahtarlı op var ve çoğu son derece\n * makul bir tablo adı — `transaction` bir fintech şemasında neredeyse kaçınılmaz.\n * Şema doğrulayıcısı bir tablo/şema adının `$` ile başlamasına izin vermediği\n * için (`^[a-zA-Z_][a-zA-Z0-9_]*`), önek çakışmayı MATEMATİKSEL olarak imkânsız\n * kılar: bir isim ya `$`'la başlar (sistem) ya başlamaz (kullanıcı).\n */\nexport type DollarOps<T> = { [K in keyof T as `$${string & K}`]: T[K] };\n\n// NOT: `EnvTypedDatabase` bu yardımcıyı KULLANMIYOR, üyelerini AÇIKÇA yazıyor.\n// Sebep ölçüldü: `database.test.ts`'in sayımı TypeScript checker'ıyla yürüyor ve\n// her property'nin declaration'ını arıyor; mapped type ile yeniden adlandırılan\n// property'ler SYNTHETIC'tir, declaration taşımaz, dolayısıyla sayımda GÖRÜNMEZ.\n// Görünmeyen bir yüzey denetlenemez — o testin varlık sebebi de bu. Yardımcı,\n// runtime tarafındaki `satisfies` kontrolü için duruyor.\n\n/**\n * Projenin veri yüzeyi: `Database.<şema>.<tablo>` + `$` önekli sistem üyeleri.\n *\n * Bugünkü `tables` ve `schema(\"x\")` ikilisinin yerine geçer (FR-001). İki yol\n * tek yola iner: `public` de diğer şemalar gibi adıyla anılır, ara katman yoktur.\n *\n * @example\n * await Database.public.notes.findMany({ where: { owner: uid } });\n * await Database.billing.invoices.findMany({ where: { paid: false } });\n * await Database.$transaction((tx) => { … });\n */\nexport type EnvTypedDatabase = EnvSchemaSurface & {\n /** Commits independently of the request. A later handler failure does not\n * undo this scope. The callback cannot switch RLS identity or nest a root. */\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T>;\n /** Ham SQL. Generic verilmezse `unknown[]` döner (FR-021). */\n $query: DBClient[\"query\"];\n $insert: DBClient[\"insert\"];\n $update: DBClient[\"update\"];\n $delete: DBClient[\"delete\"];\n $findById: DBClient[\"findById\"];\n $findUnique: DBClient[\"findUnique\"];\n $diagnostics: DBClient[\"diagnostics\"];\n $findMany: DBClient[\"findMany\"];\n $page: DBClient[\"page\"];\n $put: DBClient[\"put\"];\n $updateMany: DBClient[\"updateMany\"];\n $deleteMany: DBClient[\"deleteMany\"];\n $count: DBClient[\"count\"];\n $search: DBClient[\"search\"];\n $similar: RecoOps[\"similar\"];\n $recommend: RecoOps[\"recommend\"];\n $facets: DBClient[\"facets\"];\n $supersede: DBClient[\"supersede\"];\n $claim: DBClient[\"claim\"];\n $lockRows: DBClient[\"lockRows\"];\n $lockRowsWhere: DBClient[\"lockRowsWhere\"];\n $advisoryXactLock: DBClient[\"advisoryXactLock\"];\n $attempt: DBClient[\"attempt\"];\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n /** RLS'i bypass eden kardeş yüzey. Kendisi `$asService` TAŞIMAZ — çift bypass yok. */\n $asService(): EnvServiceDatabase;\n /**\n * Bir transaction çalıştırır. Callback işlemleri TARİF eder; tarifin tamamı\n * tek istekte gider ve broker onu tek bir transaction içinde koşturur.\n * Callback SENKRONDUR: döndüğünde hiçbir şey çalışmamıştır.\n */\n /**\n * A plan is a savepoint in the current transaction. Nonzero `retry` is\n * refused; use $atomic for whole-transaction retry, including decision reads\n * and COMMIT. The default plan keeps request-scoped commit/rollback behavior.\n */\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>>;\n }\n\n/** The same typed table/query surface on one active physical transaction. */\nexport type AtomicDatabase = Omit<EnvServiceDatabase, \"$atomic\">;\n","import { NotFound } from \"../errors.js\";\n\n/**\n * repository.ts — kiracıya kapsanmış CRUD'un TEK yazımı.\n *\n * Ölçülen kusur: tüketici katmanında 61 forwarding metodu vardı ve her biri\n * aynı iki satırı tekrar ediyordu — kiracı kolonunu yükleme ekle, sonucu\n * çevir. Aynı olan bir şeyi 61 kez yazmak onu 61 kez UNUTULABİLİR yapar; ve\n * unutulan tek bir yüklem, RLS'in altında bir kiracının satırını başka bir\n * kiracıya gösterir.\n *\n * ```ts\n * export class TodoRepository extends defineRepository(\n * Database.public.todos,\n * { tenant: \"household_id\" },\n * ) {}\n * ```\n *\n * Satır anahtarı `id` DEĞİLSE adıyla verilir — `defineTable` bir `id` kolonu\n * şart koşmuyor, birincil anahtar herhangi bir kolonda olabilir:\n *\n * ```ts\n * export class DocRepository extends defineRepository(\n * Database.public.docs,\n * { tenant: \"org_id\", key: \"slug\" },\n * ) {}\n * ```\n *\n * `Database` AMBIENT kalır ve enjekte EDİLMEZ: istek kapsamlıdır, yani bir\n * kurucuya kapatılan bir referans bir isteğin istemcisini bir başkasına\n * taşırdı. Tablo erişimcisi argüman olarak geçer ve her çağrıda güncel istek\n * kapsamını çözen proxy'ye iner; taban sınıfın kurucusu ARGÜMANSIZ kalır, o\n * yüzden container onu ek metadata olmadan çözer.\n */\n\n/**\n * Repo'nun tablodan İSTEDİĞİ dört üye — `Database.public.<t>`'nin alt kümesi.\n *\n * Yüklemler `Record<string, unknown>`: kiracı kolonunun adı ÇALIŞMA ANINDA\n * gelen bir değer, ve TypeScript jenerik bir anahtarla kurulan nesne\n * literalini mapped type'a bağlayamaz (ölçüldü: `{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye atanamaz). Kapsamı DAR tutup burada gevşetmek,\n * çağıranın tarafında `as` yazmaktan farklıdır: dışa bakan yüzey — `list`,\n * `find`, `insert`, `update`, `updateScoped`, `delete` — tamamen tipli kalır.\n *\n * `NoInfer`: `Row` YALNIZ `insert`'ün dönüşünden çıkarılır. `findMany` motorda\n * jenerik (`select`/`with`) ve kısıtlarıyla örneklendiğinde ilişki anahtarları\n * taşıyan BAŞKA bir satır tipi önerir; iki aday birleşince satır tipi sessizce\n * genişlerdi.\n */\nexport interface RepositoryTable<Row, Insert, Patch> {\n insert(data: Insert): Promise<Row>;\n findMany(q: { where: Record<string, unknown>; limit?: number }): Promise<NoInfer<Row>[]>;\n updateMany(q: { where: Record<string, unknown>; set: Patch }): Promise<NoInfer<Row>[]>;\n deleteMany(q: { where: Record<string, unknown> }): Promise<number>;\n}\n\n/**\n * Satır anahtarının VARSAYILANI: tablo bir `id` kolonu taşıyorsa `\"id\"`.\n *\n * `defineTable` bir `id` kolonu ŞART KOŞMUYOR — birincil anahtar herhangi bir\n * kolonda `.primaryKey()` ile ya da `primaryKey: [...]` ile bildirilebiliyor.\n * Bu yüzden anahtar sabit değil, PARAMETRE; ama `id` taşıyan tabloların\n * (çoğunluk) hiçbir şey yazmaması gerekiyor.\n */\nexport type DefaultRowKey<Row> = Extract<keyof Row & string, \"id\">;\n\n/**\n * Anahtar bulunamadığında REDDİ ADIYLA söyleyen tip.\n *\n * `id`'si olmayan bir tabloda `key` verilmezse {@link DefaultRowKey} `never`\n * olur ve `Row[never]` de `never`'dır: kapı doğru kapanır ama \"type 'string' is\n * not assignable to type 'never'\" diyerek ÇAREYİ söylemez. Buradaki tek alanlı\n * arayüz aynı reddi verir ve alanın adı hatanın içinde çareyi yazar.\n */\nexport interface MissingRowKey {\n \"defineRepository: bu satırda `id` kolonu yok — anahtarı { key: \\\"...\\\" } ile adlandır\": never;\n}\n\n/** Anahtar kolonunun DEĞER tipi; anahtar bilinmiyorsa {@link MissingRowKey}. */\nexport type RowKey<Row, PK extends keyof Row & string> = [PK] extends [never]\n ? MissingRowKey\n : Row[PK];\n\n/**\n * Kiracıya kapsanmış repo yüzeyi. `K` kiracı kolonu, `Row[K]` onun DEĞERİ.\n *\n * `insert` yükünde kiracı kolonu YOKTUR: onu repo yazar — `Omit` bunu ifade\n * edilemez kılıyor, anlatmıyor. `update`/`updateScoped` patch'i tablonun kendi\n * `set` şeklidir ve kiracı kolonunu DIŞLAMAZ: satırı başka bir kiracıya\n * taşımak tablonun `WITH CHECK` politikasının kararıdır, repo'nun değil — ve\n * repo'nun yüklemi zaten çağıranın kiracısına kapanmış durumda.\n */\nexport interface RepositoryOf<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n> {\n /** Kiracının tüm satırları. */\n list(tenant: Row[K]): Promise<Row[]>;\n /** Kiracının bu anahtarlı satırı, ya da yoksa `null` — yokluk bir DEĞER. */\n find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null>;\n /** Satırı kiracıya YAZAR: kiracı kolonu yükte değil, burada. */\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row>;\n /**\n * Kiracının bu id'li satırını günceller ve GÜNCEL satırı döner.\n *\n * Eşleşen satır yoksa `NotFound` ATAR — çağıran `!` yazmak ya da `null`\n * dallanması yazmak zorunda kalmasın. Yokluğu DEĞER olarak isteyen\n * {@link RepositoryOf.updateScoped} kullanır.\n */\n update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row>;\n /**\n * {@link RepositoryOf.update} ile AYNI yüklem, ama bulunamazsa `null` döner.\n *\n * Tüketicinin bugün elle yazdığı `updateMany(…).then(rows => rows[0] ?? null)`\n * kalıbının adı budur.\n */\n updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null>;\n /** Kiracının bu anahtarlı satırını siler. Yoksa bir şey olmaz. */\n delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void>;\n}\n\n/**\n * Kiracıya kapsanmış bir repo TABAN SINIFI üretir.\n *\n * Dönen sınıf `abstract`: doğrudan `new` edilemez, çünkü DI'ın çözeceği ad alt\n * sınıfın adıdır (`TodoRepository`), üretilen anonim sınıfınki değil.\n */\nexport function defineRepository<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n>(\n table: RepositoryTable<Row, Insert, Patch>,\n opts: { tenant: K; key?: PK },\n): abstract new () => RepositoryOf<Row, Insert, Patch, K, PK> {\n const tenantColumn = opts.tenant;\n // Anahtar `string` olarak tutuluyor: yüklemler zaten `Record<string, unknown>`\n // ve `opts.key ?? \"id\"`'yi `PK`'ye daraltmak bir `as` gerektirirdi — tipin\n // taşıdığı güvence dışa bakan imzalarda, burada değil.\n const rowKey: string = opts.key ?? \"id\";\n\n // Yüklem TEK yerde kuruluyor. 61 forwarding metodunun her birinde ayrı ayrı\n // yazılıyor olması, birinde unutulmasını mümkün kılan şeydi.\n const scope = (tenant: Row[K]): Record<string, unknown> => ({ [tenantColumn]: tenant });\n const scopeRow = (tenant: Row[K], id: RowKey<Row, PK>): Record<string, unknown> => ({\n [tenantColumn]: tenant,\n [rowKey]: id,\n });\n\n /**\n * Kiracı kolonunu YAZMA yüküne ekleyen tek yer — ve bu dosyadaki tek\n * daraltma.\n *\n * Gerekçesi TypeScript'in ölçülmüş bir sınırı: jenerik bir anahtarla kurulan\n * nesne literali mapped type'a bağlanmıyor (`{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye TS2322 ile atanamıyor). Daraltma TEK satırda ve\n * çağıranın göremediği bir yerde duruyor; dışa bakan altı metodun imzası\n * tamamen tipli.\n *\n * Kiracı SONRA yazılıyor: yükte aynı adda bir alan kalmışsa (tip onu\n * yasaklıyor, ama bu yol JavaScript'ten de çağrılabilir) repo'nunki kazanır.\n * Kapsamı çağıranın verisi belirlemez.\n */\n const scopedPayload = (values: Omit<Insert, K>, tenant: Row[K]): Insert =>\n ({ ...values, [tenantColumn]: tenant }) as Insert;\n\n abstract class Repository implements RepositoryOf<Row, Insert, Patch, K, PK> {\n list(tenant: Row[K]): Promise<Row[]> {\n return table.findMany({ where: scope(tenant) });\n }\n\n async find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null> {\n const rows = await table.findMany({ where: scopeRow(tenant, id), limit: 1 });\n return rows[0] ?? null;\n }\n\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row> {\n return table.insert(scopedPayload(values, tenant));\n }\n\n async update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row> {\n const row = await this.updateScoped(tenant, id, patch);\n if (row === null) {\n throw new NotFound(\n `${String(tenantColumn)}=${String(tenant)} kapsamında ${rowKey}=${String(id)} bulunamadı`,\n );\n }\n return row;\n }\n\n async updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null> {\n const rows = await table.updateMany({ where: scopeRow(tenant, id), set: patch });\n return rows[0] ?? null;\n }\n\n async delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void> {\n await table.deleteMany({ where: scopeRow(tenant, id) });\n }\n }\n\n return Repository;\n}\n","/**\n * The two ways a stack refuses to boot — and they are two because their CURES\n * are two.\n *\n * A LEAF MODULE ON PURPOSE. `db/` does not import from `engine/` and must not\n * start: the schema layer is below the engine, and a refusal both of them raise\n * cannot live in either. Anything imported here would invert that.\n *\n * WHY THE SPLIT EXISTS AT ALL — measured live on 2026-09-04.\n *\n * `8qitbtucm` ran for days on an image whose `setSchema` did not build\n * relations. Moved onto one that does, the same artifact hit\n * `buildRelations` at boot, threw a bare `Error`, and the runtime — which waits\n * only on its own `ArtifactRefused` — treated it as fatal. The supervisor took\n * the pod down, palsvc with it. CrashLoopBackOff, back-off 5m, and palsvc is\n * THE PROCESS THAT ACCEPTS THE PUSH the message asks for.\n *\n * That is verbatim the lesson `v2/runtime/src/loader.ts` already carries for\n * ABI refusals: *\"the cure was named in the error and made impossible by the\n * exit that carried it.\"* It cost a tenant a third time because the second\n * refusal had no type to be recognised by.\n *\n * SO THE RULE IS THE CURE, NOT THE SEVERITY:\n *\n * {@link DeclarationRefused} — what was PUSHED cannot be built. Restarting\n * re-reads the same bytes and fails identically; only a new artifact\n * changes the answer. The runtime WAITS on this, keeps palsvc alive, and\n * says the reason out loud.\n *\n * {@link BootRefused} — the ENVIRONMENT this stack was handed is unusable\n * (no DATABASE_URL, an unparseable PORT, no SQL driver). No push fixes it;\n * waiting for one would be a lie told in a log line forever. Stays fatal.\n *\n * NOT A MESSAGE PATTERN. The runtime's loader already says why: *\"The\n * distinction is the loader's TYPE, not a pattern over its wording.\"* A gate\n * that reads wording drifts from the thing it claims to measure the first time\n * someone improves an error message.\n */\n\n/**\n * The tag that survives a realm boundary.\n *\n * `instanceof` compares constructor identity, and identity is per module\n * instance. In the pod today the runtime and the bundle share one install\n * (measured: both frames resolve to `/app/node_modules/@palbase/backend`), so\n * `instanceof` would work — but it works by a coincidence of packaging, and a\n * bundle that ever carries its own copy would make every declaration refusal\n * silently fatal again. `Symbol.for` reads from the process-wide registry, so\n * the tag means the same thing in every copy.\n *\n * Exported so the runtime can recognise the refusal without importing the\n * class — see {@link isDeclarationRefused}.\n */\nexport const DECLARATION_REFUSAL = Symbol.for(\"palbase.backend.declarationRefusal\");\n\n/**\n * What was pushed cannot be built. The cure is a NEW ARTIFACT.\n *\n * Thrown by the declaration layer — relation naming, ownership, entry points —\n * wherever a fact about the author's code makes the app impossible to\n * construct. Never thrown for anything the environment could change.\n */\nexport class DeclarationRefused extends Error {\n /** @see DECLARATION_REFUSAL — realm-safe, unlike `instanceof`. */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(message: string) {\n super(message);\n this.name = \"DeclarationRefused\";\n }\n}\n\n/**\n * True for a refusal whose only cure is a new artifact — across realms.\n *\n * Takes `unknown` because every caller is a `catch`. A non-object, a null, a\n * plain `Error`: all false, and false is the safe answer — it means \"keep\n * treating this as fatal\", which is what the code did before this type existed.\n */\nexport function isDeclarationRefused(e: unknown): e is DeclarationRefused {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[DECLARATION_REFUSAL] === true;\n}\n","/** Column and table UNIQUE declarations, including composite primary keys. */\nexport function uniqueKeysOf(table: {\n columns?: Record<string, unknown>;\n primaryKey?: readonly string[];\n unique?: readonly { columns: readonly string[] }[];\n}): string[][] {\n const columns = table.columns ?? {};\n const inlinePrimary: string[] = [], keys: string[][] = [];\n for (const [name, value] of Object.entries(columns)) {\n const col = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { primaryKey?: boolean; unique?: boolean } | undefined;\n if (col?.primaryKey) inlinePrimary.push(name);\n if (col?.unique) keys.push([name]);\n }\n const primary = table.primaryKey ?? inlinePrimary;\n if (primary.length) keys.unshift([...primary]);\n for (const key of table.unique ?? []) keys.push([...key.columns]);\n const seen = new Set<string>();\n return keys.filter(key => {\n if (!key.length || new Set(key).size !== key.length || key.some(col => !Object.hasOwn(columns, col))) {\n throw new Error(\"Unique lookup requires a nonempty declared key of distinct, known columns\");\n }\n const identity = JSON.stringify([...key].sort());\n if (seen.has(identity)) return false;\n seen.add(identity); return true;\n });\n}\n\n/** Nulls in ordinary PostgreSQL UNIQUE constraints are not unique. */\nexport function assertUniqueLookup(table: string, keys: readonly (readonly string[])[], where: Record<string, unknown>): void {\n if (!where || typeof where !== \"object\" || Array.isArray(where)) throw new Error(`findUnique(${table}): where must contain one declared unique key`);\n const columns = Object.keys(where);\n if (!keys.some(key => key.length === columns.length && key.every(col => Object.hasOwn(where, col)))) {\n throw new Error(`findUnique(${table}): supply exactly one declared unique key (${keys.map(key => key.join(\" + \")).join(\"; \") || \"none declared\"}); use findMany for other filters`);\n }\n for (const [name, value] of Object.entries(where)) {\n if (value === null || value === undefined || (typeof value === \"object\" && !(value instanceof Date)) || typeof value === \"function\" || typeof value === \"symbol\") {\n throw new Error(`findUnique(${table}): ${name} requires a non-null scalar equality value`);\n }\n }\n}\n\n/** A union of exact keys, not a partial row that could match many records. */\nexport type UniqueWhere<Row, Keys> = Keys extends readonly (infer Key extends readonly string[])[]\n ? Key extends unknown\n ? { [K in Extract<Key[number], keyof Row>]-?: NonNullable<Row[K]> } &\n { [K in Exclude<keyof Row, Key[number]>]?: never }\n : never\n : never;\n","/**\n * env-gen.ts — generate the `palbase-env.d.ts` text from a `defineSchema()`\n * result.\n *\n * The CLI (`palbase build`) and the deploy pipeline call\n * {@link makeEnvDts} with the project's schema and write the returned string to\n * `palbase-env.d.ts` at the project root. That file AUGMENTS the\n * `@palbase/backend/env` `Tables` interface (controlled global augmentation,\n * C5) so `Database.public.<name>` is typed with no import and no generic.\n *\n * The output is FLAT: each table gets a `{ row: {...}; insert: {...} }` entry\n * with plain TypeScript object types. The phantom `ColumnBuilder<...>` type\n * NEVER appears in the generated `.d.ts` — that type only lives at authoring\n * time inside the project's `db/*.ts` schema files.\n */\nimport { DeclarationRefused } from \"../refusals.js\";\n\nimport type { ColumnDef } from \"./columns.js\";\n// FR-058: the \"public is bare, everything else is qualified\" rule lives in ONE\n// helper. This file used to carry two more copies of it — a module-level\n// `qualify` and a second, identical local one inside `makeEnvDts` — and the\n// duplication was not cosmetic: re-deriving the key here instead of reading the\n// one `resolveReferences` already wrote is exactly how a public foreign key got\n// relabelled onto another schema's table. Two names for one truth are two\n// interpreters of it.\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\nimport { uniqueKeysOf } from \"./unique.js\";\nimport { CODECS } from \"./columns.js\";\n\n/** The TypeScript value type for a column, ignoring nullability (added by the\n * caller). Mirrors the `ColValue` mapped type in columns.ts exactly. */\nfunction baseTsType(def: ColumnDef): string {\n // A NAMED CODEC DECIDES THE SURFACED TYPE, and it is read BEFORE the switch\n // because the codec is exactly the declaration that overrides the storage\n // type. `numeric` surfacing as `string` is correct by default; `asNumber()`\n // is the author saying \"in this process it is a number\", and the engine\n // already makes that true (FR-003).\n if (def.codec !== undefined && def.codec in CODECS) {\n return CODECS[def.codec].tsType;\n }\n switch (def.type) {\n case \"uuid\":\n case \"text\":\n case \"timestamp\":\n return \"string\";\n case \"integer\":\n return \"number\";\n // Both are exact-precision in Postgres and lossy as a JSON number, so the\n // database proxy serializes them as strings — measured: 9007199254740993\n // used to arrive as ...992 and 41.00821234567890123 as 41.0082123456789.\n // numeric had no case at all and fell through to `unknown`, which typed\n // every numeric column out of existence.\n case \"bigint\":\n case \"numeric\":\n return \"string\";\n case \"boolean\":\n return \"boolean\";\n case \"jsonb\":\n // `unknown` DEĞİL: `unknown` taşıyan bir kolonda filtre birleşimi\n // (`V | ColRef | …`) tamamen `unknown`'a çöker, yani HİÇBİR kural\n // tutunamaz — `col()` o kolonu her şeyle karşılaştırabiliyordu\n // (D-021'in açık bıraktığı son delik). `Json` gerçek kısıtı söylüyor ve\n // markalanabiliyor.\n return \"Json\";\n // FR-008: the authoring type of a pgvector column. The default `unknown`\n // branch below STAYS — an unknown wire type is refused on the Go side\n // (FR-005), never papered over here.\n case \"vector\":\n return \"number[]\";\n case \"enum\": {\n const values = def.enumValues ?? [];\n if (values.length === 0) return \"string\";\n return values.map((v) => JSON.stringify(v)).join(\" | \");\n }\n default: {\n // TÜKETİCİLİK KAPISI. `ColumnType`'a yeni bir değer eklenip burası\n // güncellenmezse BU SATIR DERLEME HATASI verir.\n //\n // Eskiden burası sessizce `unknown` döndürüyordu ve `unknown` taşıyan bir\n // kolonda filtre birleşimi tamamen `unknown`'a çöker — yani `col()`,\n // `now()`, toplama, hepsi o kolonda kuralsız kalırdı. `numeric` bir\n // zamanlar tam olarak buraya düşmüştü (\"numeric had no case at all\"),\n // ve `jsonb` aynı çöküşü 28.0.0'a kadar yaşadı. Üçüncüsü olmasın.\n const unhandled: never = def.type;\n throw new Error(\n `env-gen: \"${String(unhandled)}\" kolon tipinin TypeScript karşılığı ` +\n `bildirilmemiş. baseTsType'a bir case ekleyin — sessizce \\`unknown\\` ` +\n `dönmek o kolonu her kuralın dışına çıkarır.`,\n );\n }\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\n/**\n * Kolonun POSTGRES tipi, tipin İÇİNDE taşınan bir marka olarak.\n *\n * TypeScript `numeric`, `bigint`, `text`, `uuid` ve `timestamp`'i tek bir\n * `string`'e düşürüyor. Yani `integer ↔ numeric` (Postgres'te geçerli) ile\n * `integer ↔ text` (geçersiz) tipte AYNI görünüyordu ve `col()` hangi kuralı\n * koyarsa koysun bir tarafta yanılıyordu (D-021: yanlış ret mi yanlış kabul mü\n * seçilecekti — ikisi de yanlıştı).\n *\n * Marka o bilgiyi geri getiriyor. `& { readonly __pg?: \"…\" }` seçilmesinin\n * nedeni ÖLÇÜLDÜ: isteğe bağlı bir alanla kesişim, satırı hâlâ düz `string`\n * olarak okunabilir ve düz bir değerle YAZILABİLİR bırakıyor — yani marka\n * yalnız karşılaştırma kurallarının gördüğü, kullanıcının hiç görmediği bir\n * bilgi. Zorunlu bir alan olsaydı `{ balance: \"10.00\" }` derlenmezdi.\n *\n * `enum` KİMLİĞİYLE markalanıyor: iki FARKLI enum'u Postgres de karşılaştırmaz,\n * ve düz `\"enum\"` markası onları aynı sayardı.\n */\nfunction pgBrand(def: ColumnDef): string {\n if (def.type === \"enum\") {\n const values = [...(def.enumValues ?? [])].sort();\n return values.length === 0 ? \"enum\" : `enum:${values.join(\"|\")}`;\n }\n return def.type;\n}\n\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n // `unknown` MARKALANAMAZ: marka bir kesişim ve `unknown & X` doğrudan `X`'e\n // çöker. `jsonb` kolonu `Pg<unknown, \"jsonb\">` yazılınca tipi\n // `{ readonly __pg?: \"jsonb\" }` oluyordu — yani kolon DARALDI ve meşru bir\n // nesne yazılamaz hâle geldi. GERÇEK bir projede ölçüldü: 33 tablolu bir\n // şemada `user_preferences`'ın jsonb kolonlarına yazan iki çağrı kırıldı.\n //\n // Markasız kalan kolon eski (gevşek) kurala düşer — jsonb için bu zaten\n // bugünkü davranış, yani hiçbir şey kötüleşmiyor.\n\n // Takma ad, ham kesişim yerine: bu dosyayı GELİŞTİRİCİ de açıyor ve\n // `(string) & { readonly __pg?: \"uuid\" }` satırları okunmaz kılıyordu.\n // `Pg<string, \"uuid\">` hem kısa hem kolonun Postgres tipini SÖYLÜYOR.\n // Takma ad ayrıca `enum` birleşimlerini tip argümanı olarak sarmalıyor —\n // ham kesişimde `A | B & C`, `A | (B & C)` diye ayrışıp bir dalı markasız\n // bırakırdı.\n const branded = `Pg<${base}, ${JSON.stringify(pgBrand(def))}>`;\n return def.nullable ? `${branded} | null` : branded;\n}\n\n/** True when a column may be omitted on INSERT — nullable OR has any default.\n * Mirrors `ColIsOptionalOnInsert` in columns.ts. */\nfunction optionalOnInsert(def: ColumnDef): boolean {\n return (\n def.nullable === true ||\n def.defaultRandom === true ||\n def.defaultNow === true ||\n def.defaultValue !== undefined\n );\n}\n\n\n\nexport type Relation = {\n name: string;\n to: string;\n kind: \"one\" | \"many\";\n /**\n * The foreign-key COLUMN the relation runs through.\n *\n * Without it \"there is a relation\" is half the fact, and everything that\n * consumes the map — the query builder, the seed engine, the cross-boundary\n * lock — has to re-derive the column: a second interpreter of the same graph.\n */\n via: string;\n};\n\n/** `list_id` → `list`; anything else keeps its column name (FR-019). */\nfunction forwardName(column: string): string {\n return column.endsWith(\"_id\") ? column.slice(0, -3) : column;\n}\n\n/**\n * Where a relation name came from, so a refusal can say it out loud.\n *\n * A collision on a parent table can be between two REVERSE edges, or between a\n * reverse edge and the parent's own FORWARD one — `lists.todos_id` names a\n * forward `todos`, and `todos.list_id` reverses onto `lists` as `todos` too.\n * The old message called both sides \"reverse relations\", which sent the reader\n * looking for a second reverse edge that was never there.\n */\ntype NameOrigin = {\n /** The table the foreign-key COLUMN is declared on. */\n table: string;\n column: string;\n direction: \"forward\" | \"reverse\";\n def: ColumnDef;\n};\n\nfunction describeOrigin(o: NameOrigin): string {\n return o.direction === \"forward\"\n ? `the foreign key \"${o.table}.${o.column}\"`\n : `the reverse of \"${o.table}.${o.column}\"`;\n}\n\n/**\n * The call that renames THIS relation — named per verb, because the verbs do\n * not take the same options.\n *\n * NFR-002 asks every refusal to name a remedy the reader can apply. The old\n * message said `references(() => …, { as: \"…\" })` for every case, and\n * `ownedByUser()` takes no arguments at all while `userRef` /\n * `installationRef` take `{ onDelete, as }` — so following it literally was\n * impossible for exactly the columns that most often collide.\n *\n * A reverse edge only ever exists for a target that is a DECLARED table, and\n * only `references()` can point at one: `auth.*` is not declared (no reverse\n * edge) and a self-reference has no separate parent (skipped). So the reverse\n * remedy has one form and it is always the right one.\n */\nfunction renameCall(o: NameOrigin): string {\n if (o.direction === \"reverse\") return `references(() => …, { reverseAs: \"…\" })`;\n if (o.def.owns === true) {\n return `ownedByUser() takes no { as } — if \"${o.column}\" only POINTS at a user, declare it userRef({ onDelete: … }) instead`;\n }\n const target = o.def.references?.table;\n if (target === \"auth.users\") return `userRef({ onDelete: …, as: \"…\" })`;\n if (target === \"auth.installations\") return `installationRef({ onDelete: …, as: \"…\" })`;\n if (o.def.selfRefColumn !== undefined) return `selfReferences(\"…\", { as: \"…\" })`;\n return `references(() => …, { as: \"…\" })`;\n}\n\n/**\n * Derive the relation graph from the declared foreign keys.\n *\n * Until now a SECOND foreign key onto the same parent was silently dropped: only\n * the first column in declaration order was recorded, and the other one quietly\n * became an ordinary writable column. Which relation you got was decided by the\n * order somebody happened to type the columns in. That silence is what this\n * function exists to end — ambiguity is rejected and named, never resolved by\n * declaration order.\n *\n * THE HAZARD IS ONE NAME WITH TWO RELATIONS (FR-022), not two foreign keys onto\n * one target. Those are not the same set, and treating them as one refused the\n * package's own documented shape: a table with `ownedByUser()` beside a\n * `userRef()` has two foreign keys onto `auth.users` and no ambiguity whatever —\n * the names are `owner` and the pointing column's own, and `auth.users` is not a\n * declared table, so neither takes a reverse edge to collide over. The gate\n * counted the owner toward the total while exempting it from the naming\n * requirement, so `docs/schema.md`'s example threw, naming a remedy no verb in\n * it accepts.\n *\n * The two directions are named SEPARATELY. `as` sets the forward name (FR-019),\n * `reverseAs` sets the reverse one (FR-020, whose default is the child table's\n * name). One option cannot set both: two children that each name their forward\n * edge `author` collided on the parent as `author`, and the refusal asked for\n * the `{ as }` they had both already written — a refusal with no exit.\n */\nexport function buildRelations(schemas: readonly SchemaDef[]): Map<string, Relation[]> {\n const out = new Map<string, Relation[]>();\n /** Per table key: relation name → where that name came from. */\n const taken = new Map<string, Map<string, NameOrigin>>();\n for (const schema of schemas) {\n for (const t of Object.values(schema.tables)) {\n const key = qualifiedTableKey(schema.name, t.name);\n out.set(key, []);\n taken.set(key, new Map());\n }\n }\n\n /** Record one edge on `tableKey`, or refuse the name it would take twice. */\n const claim = (tableKey: string, name: string, origin: NameOrigin, edge: Relation): void => {\n const names = taken.get(tableKey);\n if (names === undefined) return;\n const held = names.get(name);\n if (held !== undefined) {\n // FR-015 asks this one to LIST the conflicting columns; it used to name\n // neither, so the reader had to find them.\n if (held.def.owns === true && origin.def.owns === true) {\n throw new DeclarationRefused(\n `table \"${tableKey}\" declares TWO owner columns (${held.column}, ${origin.column}) — a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: … }) instead.`,\n );\n }\n const heldFix = renameCall(held);\n const originFix = renameCall(origin);\n const remedy =\n heldFix === originFix\n ? `rename one of them: ${heldFix}`\n : `rename one of them — \"${held.table}.${held.column}\": ${heldFix}; \"${origin.table}.${origin.column}\": ${originFix}`;\n throw new DeclarationRefused(\n `table \"${tableKey}\": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name \"${name}\" — ${remedy}.`,\n );\n }\n names.set(name, origin);\n out.get(tableKey)?.push(edge);\n };\n\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n const childKey = qualifiedTableKey(schema.name, table.name);\n if (!out.has(childKey)) continue;\n\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.references === undefined) continue;\n // `references.table` IS the canonical key — `resolveReferences` wrote it\n // with `qualifiedTableKey`, so public is bare and everything else is\n // qualified, `auth.users` included.\n //\n // It used to be re-derived here from a bare-name → key map, which gave a\n // DIFFERENT answer in exactly one case: two schemas declaring the same\n // table name. The map kept whichever was declared LAST, so a public FK\n // was relabelled onto another schema's table and the real parent got no\n // reverse edge — silently, while RefJSON (and therefore the DDL) went on\n // pointing at the right one. The generated type and the database\n // disagreed, and nothing said so.\n const targetKey = def.references.table;\n\n const name = def.owns === true ? \"owner\" : (def.refAs ?? forwardName(col));\n claim(\n childKey,\n name,\n { table: table.name, column: col, direction: \"forward\", def },\n { name, to: targetKey, kind: \"one\", via: col },\n );\n\n // Reverse edge, unless the FK points outside the declared schemas (auth.users)\n // or back at the declaring table (a self-reference has no separate parent).\n if (!out.has(targetKey) || targetKey === childKey) continue;\n // FR-020: the reverse name is the CHILD TABLE's, not the forward name.\n // `as` used to set this too, which both broke FR-020 for a single named\n // FK (`users.author` where `users.posts` was required) and left two\n // children that chose the same forward name with no way to be declared.\n const reverse = def.reverseAs ?? table.name;\n claim(\n targetKey,\n reverse,\n { table: table.name, column: col, direction: \"reverse\", def },\n { name: reverse, to: childKey, kind: \"many\", via: col },\n );\n }\n }\n }\n return out;\n}\n\n\n\n\n/** Emit the `row` / `insert` / `relations` blocks for one table at the given\n * base indentation. */\nfunction tableBlock(table: TableDef, relations: Relation[], indent: string): string {\n const cols = Object.entries(table.columns);\n const rowLines = cols.map(([col, builder]) => {\n return `${indent} ${col}: ${rowType(builder._def)};`;\n });\n // FR-004: `can` — adlandırılmış UPDATE policy adlarının literal union'ı.\n // Policy'siz tabloda `never[]`: alan hep var (motor `[]` yazar), eleman yok.\n // Gerçek bir `can` kolonu varsa yankı yoktur (motor da kolonu korur): ikinci\n // bir `can:` satırı `skipLibCheck` altında sessizce İLK bildirime çözülürdü.\n // İlişki de aynı rezervasyon (defineTable reddeder; ham TableDef için kemer).\n const hasCanColumn =\n Object.prototype.hasOwnProperty.call(table.columns, \"can\") || relations.some((r) => r.name === \"can\");\n // Motorla aynı süzgeç: 59 baytı aşan ad (`can:` + ad > NAMEDATALEN 63) telde asla gelmez.\n const canNames = (table.policies ?? []).filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63).map((p) => JSON.stringify(p.name));\n // The contract travels with the type (final review M-2): a reader of the .d.ts\n // sees what `can` is for without opening the docs.\n const canDoc = `${indent} /** Names of this table's UPDATE policies whose \\`using\\` is true for THIS row and caller — an AFFORDANCE for the interface (draw or hide a control); never an authorization decision, may be incomplete, the server decides again on every request. */`;\n const canLine = hasCanColumn ? null : `${canDoc}\\n${indent} can: ${canNames.length === 0 ? \"never[]\" : `(${canNames.join(\" | \")})[]`};`;\n const insertLines = cols.map(([col, builder]) => {\n const def = builder._def;\n const opt = optionalOnInsert(def) ? \"?\" : \"\";\n return `${indent} ${col}${opt}: ${rowType(def)};`;\n });\n const relEntries = relations\n .map(\n (r) =>\n `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`,\n )\n .join(\"; \");\n return [\n `${indent}${table.name}: {`,\n `${indent} row: {`,\n ...rowLines,\n ...(canLine === null ? [] : [canLine]),\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n `${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,\n // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()\n // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki\n // mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(cols.some(([, b]) => b._def.type === \"vector\") || table.search !== undefined\n ? [`${indent} searchable: true;`]\n : []),\n // appendOnly (FR-031): EnvTypedTable'ın altı yazma üyesini KALDIRAN yapısal\n // bayrak. `searchable` ile aynı desen ve aynı OMIT disiplini — bayrak yokken\n // satır hiç üretilmez ki mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(table.appendOnly === true ? [`${indent} appendOnly: true;`] : []),\n `${indent}};`,\n ].join(\"\\n\");\n}\n\n/**\n * Generate the full `palbase-env.d.ts` text for the project's schemas.\n *\n * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the\n * `.d.ts` is a global script, and `declare module \"…\"` there DECLARES an ambient\n * module (shadowing the real one, so every export of `@palbase/backend/env`\n * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc\n * repro: with the line, exit 0; without it, `TS2305: Module '\"…\"' has no\n * exported member`. The line was dropped once in a rewrite and nothing caught\n * it, so `env-gen.test.ts` now gates it directly.\n *\n * @example\n * import { makeEnvDts } from \"@palbase/backend\";\n * import publicSchema from \"./db/public.js\";\n * import billing from \"./db/billing.js\";\n * writeFileSync(\"palbase-env.d.ts\", makeEnvDts([publicSchema, billing]));\n */\n/**\n * A free-form `.transform<T>()` CANNOT be typed here, and must not be typed\n * WRONG (FR-004).\n *\n * The target type is a TYPE PARAMETER — erased at runtime. This generator reads\n * the bundled runtime object, so it only ever saw `{ fromDb, toDb }` and fell\n * through to the storage type: it emitted `string` for a column the engine hands\n * back as a number. A consumer project measured exactly this and wrote a\n * hand-rolled codec module plus 141 call sites rather than trust the types.\n *\n * Refusing is the fix, not a limitation: the remedy is named in the message and\n * produces BOTH the conversion and the type from one declaration.\n */\nfunction refuseFreeFormTransforms(schemas: readonly SchemaDef[]): void {\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.transform === undefined || def.codec !== undefined) continue;\n const where = qualifiedTableKey(schema.name, table.name);\n // `DeclarationRefused`, NOT a bare Error. `refusals.ts` carries the\n // measured reason: a bare Error from this layer is treated as FATAL by\n // the runtime, the supervisor takes the pod down and palsvc with it —\n // and palsvc is THE PROCESS THAT ACCEPTS THE PUSH this message asks\n // for. The cure must not kill the thing that delivers it.\n throw new DeclarationRefused(\n `table \"${where}\" column \"${col}\" declares .transform<T>(): its target type does not exist at ` +\n `runtime, so the generated types would say something the engine contradicts. Declare a named ` +\n `codec instead — .asNumber() for a JS number, .asDecimal() for the exact string.`,\n );\n }\n }\n }\n}\n\nexport function makeEnvDts(schemas: readonly SchemaDef[]): string {\n refuseFreeFormTransforms(schemas);\n // No pruning: `relations` is a flat literal map, so it cannot expand into an\n // infinite type the way the old recursive `children` could. Dropping a back-edge\n // here would delete a REAL relation and make the type lie about the schema.\n const relations = buildRelations(schemas);\n\n const publicSchema = schemas.find((s) => s.name === \"public\");\n const others = schemas.filter((s) => s.name !== \"public\");\n\n const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map((name) =>\n tableBlock(publicSchema!.tables[name]!, relations.get(name) ?? [], \" \"),\n );\n const body = publicBlocks.length > 0 ? `\\n${publicBlocks.join(\"\\n\")}\\n ` : \"\";\n\n const schemaBlocks = others.map((schema) => {\n const inner = Object.keys(schema.tables).map((name) =>\n tableBlock(schema.tables[name]!, relations.get(qualifiedTableKey(schema.name, name)) ?? [], \" \"),\n );\n return ` ${schema.name}: {\\n${inner.join(\"\\n\")}\\n };`;\n });\n const schemasBody = schemaBlocks.length > 0 ? `\\n${schemaBlocks.join(\"\\n\")}\\n ` : \"\";\n\n return `// AUTO-GENERATED by @palbase/backend — DO NOT EDIT.\n// Regenerated from db/*.ts by \\`palbase build\\` and by every deploy.\n// Augments the @palbase/backend/env \\`Tables\\` interface so \\`Database.public.*\\`\n// is typed with no import and no generic. Schemas other than \\`public\\` land\n// under \\`Schemas\\`, reached with \\`Database.schema(\"<name>\").tables.*\\`.\n\n/**\n * Kolonun POSTGRES tipini tipte tasiyan marka.\n *\n * __pg ISTEGE BAGLI oldugu icin satir hala duz string/number gibi okunur ve duz\n * bir degerle yazilir — marka yalniz col() ve now() karsilastirma kurallarinin\n * gordugu bir bilgidir. TypeScript numeric, bigint, text, uuid ve timestamp'i\n * tek string'e dusurdugu icin bu bilgi olmadan integer<->numeric (gecerli) ile\n * integer<->text (gecersiz) ayirt edilemiyordu.\n */\ntype Pg<T, N extends string> = T & { readonly __pg?: N };\n\n/**\n * Bir jsonb kolonunun tasiyabilecegi deger.\n *\n * undefined DAHIL, cunku JSON.stringify undefined alanlari duserur ve\n * { a: undefined } yazan kod her yerde var — reddetmek dogru olmazdi.\n */\ntype Json = string | number | boolean | null | undefined | Json[] | { [k: string]: Json };\n\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n\nexport {};\n`;\n}\n","/**\n * stack-gen.ts — generate the `palbase-stack.d.ts` text from the names the\n * linked environment's stack holds.\n *\n * The twin of `db/env-gen.ts`: the CLI calls\n * {@link makeStackDts} with the three name sets it read off the stack and\n * writes the result to `palbase-stack.d.ts` at the project root. That file\n * augments the `@palbase/backend/stack` interfaces, so `Secrets.get(...)`, the\n * Flags client and `@Upload({ bucket })` accept the project's real names and\n * nothing else.\n *\n * The generator does NOT reach the network and does NOT decide what a name is:\n * it renders what it is handed. The stack is the authority on which names exist\n * (`GET /v1/management/secrets`, `/flags`, `/storage/buckets`); re-deciding that\n * here would be a second, weaker copy of it.\n *\n * The emitted file ends in `export {};` — same as `makeEnvDts` and\n * `makePurchasesDts`. Without it the `.d.ts` is a global script, and\n * `declare module \"…\"` there DECLARES an ambient module (shadowing the real one,\n * so every name silently becomes invalid) instead of AUGMENTING it.\n */\n\n/** The three name sets read off the stack. Order is irrelevant — each set is\n * sorted here so the same stack always renders the same bytes and a diff shows\n * what CHANGED rather than how the API happened to order its answer. */\n/** One bucket and the renditions it declares. */\nexport interface BucketInput {\n name: string;\n variants: readonly string[];\n}\n\nexport interface StackNames {\n /** Secret names from the project's vault. */\n secrets: readonly string[];\n /** Flag keys from the project's flag store. */\n flags: readonly string[];\n /**\n * Buckets from the project's storage — a bare name, or a name with the\n * renditions it declares.\n *\n * A bucket is not only a NAME: `Storage.buckets.docs.getPublicUrl(p, {\n * variant })` refuses a rendition the bucket does not have, so the variant\n * union has to travel with it. The bare-string form is shorthand for \"no\n * variants\", which renders `never` and accepts none.\n */\n buckets: readonly (string | BucketInput)[];\n}\n\n/** Sorted, de-duplicated names. A stack that reports one twice (two pages of a\n * listing overlapping, say) must not render a duplicate member — TypeScript\n * accepts it, but the file stops being a function of the stack's contents. */\nfunction liveNames(names: readonly string[]): string[] {\n return [...new Set(names)].sort();\n}\n\n/** A bare identifier stays bare; anything else is quoted. Bucket names carry\n * dashes and dots (the Storage module's allowed shape), and an unquoted\n * `my-bucket` parses as a subtraction rather than a member name. */\nfunction memberName(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction members(names: string[]): string {\n if (names.length === 0) return \"\";\n return `\\n${names.map((n) => ` ${memberName(n)}: true;`).join(\"\\n\")}\\n `;\n}\n\n/** Buckets render a SHAPE rather than a marker, because each carries its variant\n * union. `never` for a bucket with none: the type then accepts no variant name\n * at all, which is exactly what a bucket without renditions offers. */\nfunction bucketMembers(buckets: readonly (string | BucketInput)[]): string {\n const normalized = buckets.map((b) => (typeof b === \"string\" ? { name: b, variants: [] as readonly string[] } : b));\n const byName = new Map<string, readonly string[]>();\n for (const b of normalized) byName.set(b.name, b.variants);\n const names = [...byName.keys()].sort();\n if (names.length === 0) return \"\";\n const rows = names.map((name) => {\n const variants = [...new Set(byName.get(name) ?? [])].sort();\n const union = variants.length === 0 ? \"never\" : variants.map((v) => JSON.stringify(v)).join(\" | \");\n return ` ${memberName(name)}: { variants: ${union} };`;\n });\n return `\\n${rows.join(\"\\n\")}\\n `;\n}\n\n/**\n * Render the project's `palbase-stack.d.ts`.\n *\n * An empty set renders an empty interface, which is a MEANINGFUL value: the\n * stack holds no such names, so the corresponding union is `never` and every\n * call spelling one fails to compile. It is not the same as \"the file was never\n * generated\" only in that the file exists — both states refuse every name, and\n * both are correct.\n */\nexport function makeStackDts(names: StackNames): string {\n const secrets = liveNames(names.secrets);\n const flags = liveNames(names.flags);\n\n\n return `// palbase-stack.d.ts — GENERATED by @palbase/backend. Do not edit.\n// Source: the linked environment's stack.\n\ndeclare module \"@palbase/backend/stack\" {\n interface Secrets {${members(secrets)}}\n\n interface Flags {${members(flags)}}\n\n interface Buckets {${bucketMembers(names.buckets)}}\n}\n\nexport {};\n`;\n}\n","// The decorator registry — the single plain-data store the method + parameter\n// decorators write into, and the deploy/dispatch pipeline reads back. No\n// `reflect-metadata`, no `emitDecoratorMetadata`: the registry is built from the\n// decorator arguments + the parameter INDEX that esbuild/tsc preserve for legacy\n// parameter decorators (verified — see the design spec §0/§4.1).\n//\n// A controller class carries its route metadata on a symbol-keyed static\n// property (`ROUTES`). `@Get`/`@Post`/… append a {@link RouteMeta} entry;\n// `@Body`/`@User`/… append a {@link ParamMeta} entry onto the route for the\n// method they decorate. Because parameter decorators run BEFORE the method\n// decorator for the same member (TS evaluates innermost-first, params before the\n// method), the route entry may not exist yet when a param decorator fires — so\n// param metadata is buffered per method name and merged when the method\n// decorator creates the route entry.\nimport type { AuthSpec, RateLimitConfig } from \"../endpoint.js\";\nimport type { UploadConfig } from \"./upload.js\";\nimport type { SseConfig } from \"./sse.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** The HTTP verbs a route may declare, upper-cased (the runtime router +\n * OpenAPI lower-case on their own). */\nexport type HttpMethodUpper = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"QUERY\";\n\n/** Route-level options accepted by the method decorators (`@Get`/`@Post`/…). */\nexport interface RouteOptions {\n /** Enforced before statements and COMMIT; include retries and service queries. */\n databaseBudget?: import(\"../db/diagnostics.js\").DatabaseBudget;\n /** OVERRIDES the controller-level default auth for this one route. */\n auth?: AuthSpec;\n /** Per-route rate limit. */\n rateLimit?: RateLimitConfig;\n /** Direct-storage upload config — present ONLY on `@Upload` routes (the\n * `@Get`/`@Post`/… decorators never set it). Its presence is what MARKS a\n * route as an upload route through the whole pipeline (registry → flatten →\n * openapi → codegen). The bytes go client→storage directly; the method body\n * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */\n uploadConfig?: UploadConfig;\n /** Streaming config — present ONLY on `@Sse` routes (the `@Get`/`@Post`/…\n * decorators never set it). Its presence is what MARKS a route as a streaming\n * route through the whole pipeline (registry → flatten → openapi → codegen),\n * exactly as `uploadConfig` does for uploads — never a special HTTP verb. An\n * `@Sse` route registers POST like any input-bearing route, so the verb cannot\n * carry the distinction. See {@link SseConfig} (decorators/sse.ts). */\n sseConfig?: SseConfig;\n}\n\n/** The kind of value a parameter decorator injects. Drives both dispatch\n * (which request slice to inject) and codegen (which OpenAPI parameter source a\n * schema-bearing kind maps to). */\nexport type ParamKind =\n | \"body\"\n | \"query\"\n | \"param\"\n | \"headers\"\n | \"user\"\n | \"optionalUser\"\n | \"client\"\n | \"requestId\"\n | \"traceId\"\n | \"req\"\n // `@UploadedObject()` — injects the uploaded object (completion input) on an\n // `@Upload` route. No schema (the shape is the fixed UploadedObject type).\n | \"uploadedObject\"\n // `@SseOut()` — injects the frame writer on an `@Sse` route. No schema (the\n // shape is the fixed SseWriter type).\n | \"sseOut\"\n // `@Signal()` — injects the request's AbortSignal, which aborts when the\n // client disconnects. No schema. NOT derivable from `@Req()`: PBRequest\n // carries only request-scoped data and has no signal (endpoint.ts:358-363).\n | \"signal\";\n\n/** One parameter decorator's recorded metadata. `index` is the parameter\n * position esbuild/tsc preserve; `schema` is present for the schema-bearing\n * kinds (`body`/`query`/`headers`); `name` is the path-param name for `param`. */\nexport interface ParamMeta {\n index: number;\n kind: ParamKind;\n /** Zod schema for `body`/`query`/`headers` (validation + codegen source). */\n schema?: ZodTypeAny;\n /** Path-param name for `@Param(\"id\")`. */\n name?: string;\n}\n\n/** One inferred throw site: the error CLASS name (e.g. \"TodoLocked\") and its\n * wire code (e.g. \"todo_locked\"). `status`, `hasData`, and the data JSON schema\n * are NOT carried here — they resolve from the error registry by `code` at\n * extract/openapi time (single source of truth). */\nexport interface ThrowDescriptor {\n name: string;\n code: string;\n}\n\n/** One route's recorded metadata: the verb + subpath + method name + options,\n * the ordered parameter metas, and the resolved return schema (injected by the\n * codegen step — see `returnSchema`). */\nexport interface RouteMeta {\n method: HttpMethodUpper;\n subpath: string;\n fnName: string;\n options: RouteOptions;\n params: ParamMeta[];\n /** Response schema for the route, if any. Derived from the method's RETURN\n * TYPE by codegen and written here via `recordReturn` (a generated top-level\n * IIFE injected per controller), not by an author-written decorator. */\n returnSchema?: ZodTypeAny;\n /** Error classes this route can throw, if inferred. Derived from the method\n * body + service call graph by the deploy stager's throw analysis and written\n * here via `recordThrows` (a generated top-level IIFE injected per controller,\n * the `recordReturn` twin), not by an author-written decorator. */\n throws?: ThrowDescriptor[];\n}\n\n/** Symbol the route metadata list is stored under on a controller class. Using\n * a symbol (not a string key) keeps it off the public structural surface and\n * avoids any chance of an authored property collision. */\nexport const ROUTES: unique symbol = Symbol.for(\"palbase.backend.routes\");\n\n/** Symbol the per-method buffered parameter metas are stored under while a class\n * is being decorated. Parameter decorators fire before the method decorator, so\n * they buffer here keyed by method name; the method decorator drains the buffer\n * into the route entry it creates. */\nconst PARAM_BUFFER: unique symbol = Symbol.for(\"palbase.backend.paramBuffer\");\n\n/** A room's own slots. Rooms are NOT routes — no verb, no path, no params — so\n * they get their own carrier slots instead of being squeezed into RouteMeta. */\nconst ROOM: unique symbol = Symbol.for(\"palbase.backend.room\");\nconst ROOM_HOOKS: unique symbol = Symbol.for(\"palbase.backend.roomHooks\");\n\n/** Symbol the per-method buffered return-type schemas are stored under while a\n * class's registry is being populated. The codegen-injected `recordReturn` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordReturn`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its return schema — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst RETURN_BUFFER: unique symbol = Symbol.for(\"palbase.backend.returnBuffer\");\n\n/** Symbol the per-method buffered throw descriptors are stored under while a\n * class's registry is being populated. The stager-injected `recordThrows` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordThrows`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its throw descriptors — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst THROWS_BUFFER: unique symbol = Symbol.for(\"palbase.backend.throwsBuffer\");\n\n/** A class constructor carrying the symbol-keyed registry slots. We type the\n * registry-bearing class as this so the decorators can read/write the slots\n * without `any` — a plain `Function` does not carry index signatures. */\ninterface RegistryCarrier {\n [ROUTES]?: RouteMeta[];\n [PARAM_BUFFER]?: Record<string, ParamMeta[]>;\n [ROOM]?: RoomMeta;\n [ROOM_HOOKS]?: RoomBuffer;\n [RETURN_BUFFER]?: Record<string, ZodTypeAny>;\n [THROWS_BUFFER]?: Record<string, ThrowDescriptor[]>;\n}\n\n/** Coerce a decorated target (class constructor or its prototype) into the\n * registry carrier that owns the slots. Method/param decorators receive the\n * PROTOTYPE as their target; the class decorator receives the constructor. We\n * always anchor the registry on the CONSTRUCTOR so `getRoutes(ctor)` finds it. */\nfunction carrierOf(target: object): RegistryCarrier {\n // For instance-member decorators, `target` is the prototype; its `.constructor`\n // is the class. For a static member or the class decorator, `target` is the\n // constructor already. Resolve to the constructor either way.\n const ctor =\n typeof target === \"function\"\n ? (target as unknown as RegistryCarrier)\n : (((target as { constructor?: unknown }).constructor ??\n target) as unknown as RegistryCarrier);\n return ctor;\n}\n\n/** Get (creating if absent) the own route list for a class constructor. Own —\n * not inherited — so a subclass does not mutate its base's routes. */\nfunction ownRoutes(carrier: RegistryCarrier): RouteMeta[] {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROUTES)) {\n carrier[ROUTES] = [];\n }\n return carrier[ROUTES] as RouteMeta[];\n}\n\n/** Get (creating if absent) the own per-method param buffer for a class. */\nfunction ownParamBuffer(carrier: RegistryCarrier): Record<string, ParamMeta[]> {\n if (!Object.prototype.hasOwnProperty.call(carrier, PARAM_BUFFER)) {\n carrier[PARAM_BUFFER] = {};\n }\n return carrier[PARAM_BUFFER] as Record<string, ParamMeta[]>;\n}\n\n/** Record a route (called by the method decorators). Drains any parameter\n * metas already buffered for `fnName` into the new route entry, then sorts them\n * by parameter index so dispatch can inject positionally. */\nexport function recordRoute(\n target: object,\n fnName: string,\n method: HttpMethodUpper,\n subpath: string,\n options: RouteOptions,\n): void {\n const carrier = carrierOf(target);\n const routes = ownRoutes(carrier);\n const buffer = ownParamBuffer(carrier);\n const params = (buffer[fnName] ?? []).slice().sort((a, b) => a.index - b.index);\n const route: RouteMeta = { method, subpath, fnName, options, params };\n // Drain a buffered return schema (the recordReturn-ran-first ordering) so the\n // route entry is complete the moment it's created — a raw-symbol consumer\n // (the runtime extractor/worker) sees the return schema without re-merging.\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer && returnBuffer[fnName] !== undefined) {\n route.returnSchema = returnBuffer[fnName];\n }\n // Same drain for buffered throw descriptors (the recordThrows-ran-first\n // ordering) — the route entry is complete the moment it's created.\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer && throwsBuffer[fnName] !== undefined) {\n route.throws = throwsBuffer[fnName];\n }\n routes.push(route);\n}\n\n/** Record one parameter decorator (called by `@Body`/`@User`/…). Buffers per\n * method name; the method decorator merges the buffer into the route entry. If\n * the route already exists (method decorator ran first — TS does evaluate the\n * method decorator AFTER its parameter decorators, but we stay order-robust),\n * the meta is also appended directly so neither ordering loses it. */\nexport function recordParam(target: object, fnName: string, meta: ParamMeta): void {\n const carrier = carrierOf(target);\n const buffer = ownParamBuffer(carrier);\n (buffer[fnName] ??= []).push(meta);\n\n // Order-robust: if the route already exists, merge in place + keep sorted.\n const routes = carrier[ROUTES];\n if (routes) {\n const route = routes.find((r) => r.fnName === fnName);\n if (route) {\n route.params.push(meta);\n route.params.sort((a, b) => a.index - b.index);\n }\n }\n}\n\n/** Attach a return schema to the route for `fnName` (called by the codegen\n * injection that reads the method's return type). If the route does not exist\n * yet, the schema is buffered (RETURN_BUFFER) and drained into the route by\n * `recordRoute` when the method decorator runs. */\nexport function recordReturn(target: object, fnName: string, schema: ZodTypeAny): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.returnSchema = schema;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, RETURN_BUFFER)) {\n carrier[RETURN_BUFFER] = {};\n }\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) returnBuffer[fnName] = schema;\n}\n\n/** Attach the inferred throw descriptors to the route for `fnName` (called by\n * the stager-injected IIFE that carries the throw analysis result — the\n * `recordReturn` twin). If the route does not exist yet, the descriptors are\n * buffered (THROWS_BUFFER) and drained into the route by `recordRoute` when the\n * method decorator runs. */\nexport function recordThrows(target: object, fnName: string, throws: ThrowDescriptor[]): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.throws = throws;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, THROWS_BUFFER)) {\n carrier[THROWS_BUFFER] = {};\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) throwsBuffer[fnName] = throws;\n}\n\n/** Read the route metadata for a controller class (the deploy/dispatch entry\n * point). Applies any buffered return schemas + throw descriptors (for the\n * recordReturn/recordThrows-runs-before orderings) and returns a defensive copy\n * so callers cannot mutate the registry.\n */\nexport function getRoutes(ctor: object): RouteMeta[] {\n const carrier = carrierOf(ctor);\n const routes = carrier[ROUTES] ?? [];\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) {\n for (const route of routes) {\n const buffered = returnBuffer[route.fnName];\n if (buffered && route.returnSchema === undefined) {\n route.returnSchema = buffered;\n }\n }\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) {\n for (const route of routes) {\n const buffered = throwsBuffer[route.fnName];\n if (buffered && route.throws === undefined) {\n route.throws = buffered;\n }\n }\n }\n return routes.map((r) => ({\n ...r,\n params: r.params.slice(),\n ...(r.throws !== undefined ? { throws: r.throws.slice() } : {}),\n }));\n}\n\n// ── rooms ───────────────────────────────────────────────────────────────────\n\n/** Which lifecycle hook a method is bound to. */\nexport type RoomHook = \"authorize\" | \"first\" | \"join\" | \"leave\" | \"empty\";\n\nexport interface RoomMessageMeta {\n fnName: string;\n schema: ZodTypeAny;\n}\n\nexport interface RoomMeta {\n pattern: string;\n events: Record<string, ZodTypeAny>;\n graceMs: number;\n /** hook → the method name that implements it. */\n hooks: Partial<Record<RoomHook, string>>;\n /** inbound message name → its method and payload schema. */\n messages: Record<string, RoomMessageMeta>;\n}\n\ninterface RoomBuffer {\n hooks: Partial<Record<RoomHook, string>>;\n messages: Record<string, RoomMessageMeta>;\n}\n\n/** Get (creating if absent) the own hook buffer. Own — not inherited — so a\n * subclass never mutates its base's hooks. Member decorators fill this BEFORE\n * the class decorator runs; controller.ts:203 depends on the same ordering. */\nfunction ownRoomBuffer(carrier: RegistryCarrier): RoomBuffer {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM_HOOKS)) {\n carrier[ROOM_HOOKS] = { hooks: {}, messages: {} };\n }\n return carrier[ROOM_HOOKS] as RoomBuffer;\n}\n\n/** Record a lifecycle hook. A second method for the same hook is refused: two\n * answers to \"who handles this\" cannot be resolved at dispatch, and silently\n * keeping one is how a hook stops running without anyone being told. */\nexport function recordRoomHook(target: object, hook: RoomHook, fnName: string): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.hooks[hook];\n if (existing !== undefined && existing !== fnName) {\n const label = `On${hook.charAt(0).toUpperCase()}${hook.slice(1)}`;\n throw new Error(\n `@${label} is declared twice in one room (${existing} and ${fnName}). ` +\n `A room has one of each hook.`,\n );\n }\n buffer.hooks[hook] = fnName;\n}\n\n/** Record an inbound message handler. */\nexport function recordRoomMessage(\n target: object,\n name: string,\n fnName: string,\n schema: ZodTypeAny,\n): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.messages[name];\n if (existing !== undefined && existing.fnName !== fnName) {\n throw new Error(\n `@OnMessage(\"${name}\") is declared twice in one room (${existing.fnName} and ${fnName}).`,\n );\n }\n buffer.messages[name] = { fnName, schema };\n}\n\n/** Record the room itself (called by the class decorator), draining the buffer\n * the member decorators already filled. */\nexport function recordRoom(\n ctor: object,\n meta: Omit<RoomMeta, \"hooks\" | \"messages\">,\n): void {\n const carrier = carrierOf(ctor);\n const buffer = ownRoomBuffer(carrier);\n carrier[ROOM] = { ...meta, hooks: buffer.hooks, messages: buffer.messages };\n // AND into the shared class registry, the same slot @Controller pushes to.\n //\n // Without this line a room compiles, bundles and deploys, and is never called:\n // the bundler's entry exports `SDK.getRegisteredControllers()` and the runtime\n // reads its rooms out of THAT list (server.ts's `collectRooms`). A room that\n // only marks its own constructor is a room nobody can find — measured, on the\n // fixture, at the last gate before it would have worked.\n //\n // Rooms and controllers share one list because they are one thing to the\n // loader: classes a bundle declared. What each IS is decided by the marker it\n // carries, never by which list it arrived in.\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const REGISTRY = Symbol.for(\"palbase.backend.allControllers\");\n const all = (g[REGISTRY] ??= []);\n if (!all.includes(ctor)) all.push(ctor);\n}\n\n/** The room a class declares, or undefined. A class with no `@Room` is not a\n * room — the marker is the CONFIG's presence, never a name or a base class\n * (the rule upload.ts:13-16 states for uploads). */\nexport function getRoom(ctor: object): RoomMeta | undefined {\n const carrier = carrierOf(ctor);\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM)) return undefined;\n return carrier[ROOM] as RoomMeta;\n}\n","// `@Controller(basePath, options?)` — the class decorator that marks a class as\n// a Palbase backend controller. It stamps a non-enumerable `__palbase`\n// discriminant + the resolved controller metadata onto the class so the\n// deploy/dispatch pipeline (and `isController`/`resolveController`) can detect\n// and read it without `reflect-metadata`.\nimport type { AuthSpec } from \"../endpoint.js\";\nimport { getRoutes } from \"./registry.js\";\n\n/** The controller metadata stamped onto a `@Controller`-decorated class. The\n * default export of a `controllers/*.controller.ts` file resolves to this via\n * {@link resolveController}. */\nexport interface ControllerMeta {\n /** Discriminant the runtime + tooling read. */\n readonly __palbase: \"controller\";\n /** The base path every route in this controller mounts under (e.g. \"/todos\"). */\n basePath: string;\n /** Controller-level default auth, applied to routes that don't set their own\n * (`@Get(\"/x\", { auth })` overrides this). `undefined` ⇒ the application\n * default ({@link defineDefaultAuth}), and secure-by-default below that —\n * see {@link resolveEffectiveAuth} for the whole cascade. */\n defaultAuth?: AuthSpec;\n}\n\n/** Options accepted by `@Controller`. */\nexport interface ControllerOptions {\n /** Default auth for ALL routes in this controller (route-level overrides;\n * omitting it falls through to the application default declared with\n * {@link defineDefaultAuth}). */\n auth?: AuthSpec;\n}\n\n/** Symbol the controller metadata is stamped under. Symbol-keyed (not a string\n * property) so it never collides with an authored member and stays off the\n * structural surface. */\nexport const CONTROLLER_META: unique symbol = Symbol.for(\"palbase.backend.controllerMeta\");\n\n/**\n * Every class `@Controller` has decorated, in decoration order.\n *\n * This is what lets a controller file need no export at all: importing the file\n * runs the decorator, the decorator records the class here, and the runtime\n * reads the list. Without it the only handle on a class is its export name, so\n * every controller had to be exported AND named in a generated entry — the\n * ceremony NestJS still charges (`export class` PLUS\n * `@Module({controllers:[…]})`).\n *\n * Keyed on a well-known Symbol against globalThis rather than held in a module\n * variable, because a deployed bundle inlines its own copy of this package: two\n * copies would keep two lists, and the runtime would read the empty one. The\n * same hazard `runtimeHooks` exists for, closed the same way — one shared slot.\n */\nconst REGISTRY: unique symbol = Symbol.for(\"palbase.backend.allControllers\") as never;\n\nfunction registry(): unknown[] {\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const existing = g[REGISTRY];\n if (existing) return existing;\n const fresh: unknown[] = [];\n g[REGISTRY] = fresh;\n return fresh;\n}\n\n/**\n * The controller classes this process has loaded, in decoration order.\n *\n * Decoration order is import order, which the bundler fixes by sorting the\n * files it emits imports for — so two builds of one tree produce the same\n * route table, and route precedence is not a function of module-resolution\n * accidents.\n */\nexport function getRegisteredControllers(): readonly unknown[] {\n return registry().slice();\n}\n\n/** Empty the registry. For tests, which load controllers repeatedly. */\nexport function __resetRegisteredControllers(): void {\n registry().length = 0;\n}\n\n/**\n * The APPLICATION-level default auth.\n *\n * Held on globalThis under a well-known Symbol for exactly the reason\n * {@link REGISTRY} is: a deployed bundle inlines its own copy of this package,\n * and two copies keeping two defaults is how a security setting silently\n * becomes two different settings.\n */\nconst APP_DEFAULT_AUTH: unique symbol = Symbol.for(\"palbase.backend.appDefaultAuth\") as never;\n\nfunction appAuthSlot(): Record<symbol, AuthSpec | undefined> {\n return globalThis as unknown as Record<symbol, AuthSpec | undefined>;\n}\n\n/**\n * Declare the default auth for EVERY route in the application — the ring the\n * cascade consults when neither the route nor its controller says anything.\n *\n * The measured problem it removes: `auth: { verifiedEmail: true }` repeated by\n * hand on ten `@Controller`s. A security setting that must be repeated is a\n * security setting that will be forgotten — the eleventh controller opens the\n * door and nothing says so.\n *\n * Call it at MODULE SCOPE in a file the application imports (the controllers'\n * own barrel, or a module a controller imports). The cascade reads this slot\n * when the route table is built and when the spec is emitted — both of which\n * run after module loading — so declaration order does not matter, but being\n * imported at all does.\n *\n * @example\n * defineDefaultAuth({ verifiedEmail: true }); // every route, unless it says otherwise\n */\nexport function defineDefaultAuth(auth: AuthSpec): void {\n appAuthSlot()[APP_DEFAULT_AUTH] = auth;\n}\n\n/** The declared application default, or `undefined` when none was declared. */\nexport function getDefaultAuth(): AuthSpec | undefined {\n return appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/** Clear the application default. For tests, which declare it repeatedly. */\nexport function __resetDefaultAuth(): void {\n delete appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/**\n * THE auth cascade: route → controller → application → `true`.\n *\n * One function, every caller — the route table (`engine/router.ts`) and the\n * spec emitter (`openapi/controllers.ts`) ASK for the answer instead of\n * spelling the chain themselves. Two hand-written copies of a cascade is how\n * the build-time answer and the runtime answer come to disagree about who may\n * call an endpoint, and the disagreement shows up as an open door.\n *\n * The terminal `true` is secure-by-default and is load-bearing: a route that\n * declared nothing, under a controller that declared nothing, in an\n * application that declared nothing, is CLOSED.\n */\nexport function resolveEffectiveAuth(\n routeAuth: AuthSpec | undefined,\n controllerAuth: AuthSpec | undefined,\n): AuthSpec {\n return routeAuth ?? controllerAuth ?? getDefaultAuth() ?? true;\n}\n\n/** A class carrying the stamped controller metadata + discriminant. */\ninterface ControllerCarrier {\n __palbase?: \"controller\";\n [CONTROLLER_META]?: ControllerMeta;\n}\n\n/** The one path segment the platform owns. The isolate matches\n * `^/webhooks/([^/]+)$` on the raw request path BEFORE controller dispatch, so\n * anything a controller resolves to under it answers `404 webhook_not_found`\n * and never runs. */\nconst RESERVED_FIRST_SEGMENT = \"webhooks\";\n\n/**\n * Throw if `path` resolves under the reserved segment. Segments are compared the\n * way the isolate compares them — `split(\"/\").filter(Boolean)` — NOT by string\n * prefix, because empty segments collapse there: `@Controller(\"/\")` +\n * `@Post(\"/webhooks/x\")` composes to `//webhooks/x`, which the isolate serves as\n * `/webhooks/x`. A prefix check reads that as safe; the segment check does not.\n * `/webhooksy` stays allowed for the same reason — it is a different segment.\n *\n * Every verb is refused, not just the POST the isolate currently intercepts: the\n * reservation is of the URL namespace, so a `@Get(\"/webhooks/x\")` that happens\n * to work today would be silently shadowed the moment the isolate's method gate\n * widens. Refusing at build is recoverable; discovering it as a 404 is not.\n */\nfunction assertNotReserved(path: string, subject: string): void {\n const [first] = path.split(\"/\").filter(Boolean);\n if (first === RESERVED_FIRST_SEGMENT) {\n throw new Error(\n `${subject} resolves under the reserved /${RESERVED_FIRST_SEGMENT} path — ` +\n \"inbound webhooks are served there and would shadow this route\",\n );\n }\n}\n\n/**\n * Mark a class as a Palbase backend controller. `basePath` is the mount path\n * for every route the class declares; `options.auth` sets the controller-level\n * default auth (a route's own `auth` overrides it; absent ⇒ secure-by-default).\n *\n * @example\n * \\@Controller(\"/todos\", { auth: false })\n * export class TodosController {\n * \\@Get(\"\") list(\\@QueryParams(ListTodosQuery) q: ListTodosQuery): TodoSchema[] { … }\n * }\n */\nexport function Controller(basePath: string, options: ControllerOptions = {}) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n // /webhooks/* belongs to the platform: the isolate matches the inbound\n // webhook route before controller dispatch, so a controller mounted here\n // would never receive a request. Silent shadowing is the failure mode this\n // whole change exists to remove, so refuse it at build.\n //\n // The COMPOSED path is what gets shadowed, not the base path. `@Controller(\"\")`\n // and `@Controller(\"/\")` both pass a base-path-only check while a\n // `@Post(\"/webhooks/stripe\")` inside them resolves to exactly the path the\n // isolate intercepts. Method decorators run BEFORE the class decorator (TS\n // evaluates members first), so every route this class declares is already in\n // the registry here — which is why the composed check can live at this one\n // seam instead of on the dispatch read path. The `@Controller(\"\") +\n // @Post(\"/webhooks/stripe\")` test is the lock on that ordering: if it ever\n // stopped holding, that test goes red.\n assertNotReserved(basePath, `@Controller(\"${basePath}\")`);\n for (const route of getRoutes(ctor)) {\n assertNotReserved(\n `${basePath}${route.subpath}`,\n `@${route.method}(\"${route.subpath}\") in @Controller(\"${basePath}\")`,\n );\n }\n\n const carrier = ctor as unknown as ControllerCarrier;\n const meta: ControllerMeta = {\n __palbase: \"controller\",\n basePath,\n ...(options.auth !== undefined ? { defaultAuth: options.auth } : {}),\n };\n // Non-enumerable so it doesn't leak onto instances / structural checks.\n Object.defineProperty(carrier, CONTROLLER_META, {\n value: meta,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // The bare `__palbase` discriminant is the cheap detection marker the\n // runtime/extractor checks; keep it readable but non-enumerable.\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"controller\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // Record it, so importing the file is enough and exporting is optional.\n // Guarded against a double-decoration re-entering the same class twice.\n const all = registry();\n if (!all.includes(ctor)) all.push(ctor);\n return ctor;\n };\n}\n\n/** True when `value` is a `@Controller`-decorated class (cheap discriminant\n * check). Accepts the class constructor (the default export of a controller\n * file). */\nexport function isController(value: unknown): boolean {\n if (typeof value !== \"function\" && (typeof value !== \"object\" || value === null)) {\n return false;\n }\n const carrier = value as ControllerCarrier;\n return carrier.__palbase === \"controller\" && carrier[CONTROLLER_META] !== undefined;\n}\n\n/** Read the resolved controller metadata off a `@Controller`-decorated class.\n * Throws if the class was not decorated — callers should gate with\n * {@link isController} first (the loader does). */\nexport function resolveController(ctor: unknown): ControllerMeta {\n if (typeof ctor !== \"function\" && (typeof ctor !== \"object\" || ctor === null)) {\n throw new TypeError(\"resolveController: value is not a class\");\n }\n const meta = (ctor as ControllerCarrier)[CONTROLLER_META];\n if (!meta) {\n throw new TypeError(\n \"resolveController: class is not a @Controller — decorate it with `@Controller(path)` and list it in a module's `controllers`\",\n );\n }\n return meta;\n}\n\n/**\n * A class the runtime constructs takes NO constructor parameters.\n *\n * ONE writer, four callers (controller, hook, job, webhook) and the build's own\n * check. Four hand-written copies of this message is how the four come to\n * disagree about what is refused — and the disagreement is silent, because a\n * class that slips past one of them still ends up with `undefined` fields.\n *\n * Why it is refused rather than injected: there is no container. The parameter\n * would arrive `undefined`, the code would compile, deploy, and fail at the\n * first request that touches the field — the most expensive place to learn it.\n */\nexport function assertZeroArgConstructor(Ctrl: unknown, kind: string): void {\n const arity = (Ctrl as { length?: number }).length ?? 0;\n if (arity === 0) return;\n\n // This function's NAME is a promise: whatever reaches it will be constructed\n // with a zero-argument constructor. Letting a class with parameters through\n // would make the name a lie — worse than the rename FR-029 guards against.\n //\n // An earlier design made it \"declaration-aware\": pass when metadata matches\n // arity. Measured, that re-opens the exact silence this exists to close.\n // ANY decorator triggers metadata emission, not just `@Injectable`:\n //\n // @Job(...) class J { constructor(repo: unknown) {} }\n // → design:paramtypes = [Object] ← matches arity\n //\n // so J would pass, then be built with `new J()`, and `repo` would be\n // `undefined` at the first scheduled run. Four tests in this repo asserted\n // that refusal and all four went red; the tests were right.\n //\n // What changed instead is the MESSAGE, and who calls this. Callers holding a\n // container resolve from it and never come here (router.ts, job/hook/webhook);\n // this stays the guard for the container-less path, and keeps its promise.\n const name = (Ctrl as { name?: string }).name ?? \"<anonymous>\";\n throw new Error(\n `${kind} ${name} declares a constructor with ${arity} parameter(s), and this path ` +\n `builds it with a zero-argument constructor — every parameter would arrive as ` +\n `undefined. If you meant to inject them, add @Injectable() to ${name} and list it ` +\n `in a module's providers, so the container builds it instead.`,\n );\n}\n","// Method decorators: `@Get` / `@Post` / `@Put` / `@Patch` / `@Delete` /\n// `@Query` declare a route (verb + subpath + options) on a controller method. These are LEGACY\n// method decorators (`experimentalDecorators`), receiving\n// `(prototype, methodName, descriptor)`. They write into the per-class registry\n// (registry.ts). The success-response schema is NOT declared here: it is derived\n// from the method's RETURN TYPE by a codegen step and injected onto the route at\n// runtime via `recordReturn` (registry.ts).\nimport {\n recordRoute,\n type HttpMethodUpper,\n type RouteOptions,\n} from \"./registry.js\";\n\n/** A legacy method decorator.\n *\n * The third argument is typed `unknown`, not `PropertyDescriptor`, on purpose:\n * when the decorator is applied to a PARAMETER (`m(@Query(\"q\") q: string)`),\n * TypeScript calls it with the parameter INDEX there. The type would let the\n * runtime pretend that cannot happen; the runtime measures it instead. */\n// `descriptor` is OPTIONAL but stays a PropertyDescriptor: optional so a\n// property-position call (descriptor undefined) type-checks, narrow so a\n// parameter-position call (`m(@Query(\"q\") q)`, third argument a number) is\n// still TS1239 at compile time. `unknown` here would trade that compile-time\n// refusal for the runtime one below; keeping both is the point (W4 r2 I-3).\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol | undefined,\n descriptor?: PropertyDescriptor,\n) => void;\n\n/** Build a method decorator for one HTTP verb. The decorated method's name is\n * the route `fnName` — and it is PUBLIC API, not authoring sugar: the runtime\n * derives the operationId as `<controllerName>.<fnName>` (the dotted namespace\n * the SDKs expose as `pb.todos.list()`), so renaming this method renames every\n * client call. The flat verb+path id is only the fallback for routes with no\n * controller metadata. See openapi/discover.ts. */\nfunction makeMethodDecorator(method: HttpMethodUpper) {\n return function (subpath: string, options: RouteOptions = {}): MethodDecorator {\n // Runtime guard for stale pre-9.0.0 code: `@Query(zodSchema)` used to be\n // the query-string PARAM decorator. Applied against this SDK it would\n // silently record a garbage route (schema-as-subpath) and fail the deploy\n // with a baffling self-conflict — fail loud and name the migration instead.\n if (typeof subpath !== \"string\") {\n throw new Error(\n `@${method[0]}${method.slice(1).toLowerCase()}(subpath) expects a string subpath, got ${typeof subpath}.` +\n (method === \"QUERY\"\n ? \" If this is a zod schema on a method parameter: the query-string param decorator was renamed @QueryParams(schema) in @palbase/backend 9.0.0.\"\n : \"\"),\n );\n }\n return function (target, propertyKey, descriptor?: PropertyDescriptor) {\n const verb = `${method[0]}${method.slice(1).toLowerCase()}`;\n // POSITION guard, and it runs BEFORE `recordRoute`: `m(@Query(\"q\") q)`\n // passes the subpath guard above (the argument IS a string) and arrives\n // here as a parameter-decorator call — the third argument is the\n // parameter index, not a descriptor. Recording it would register a\n // route the author never wrote, named after the method, and the deploy\n // would fail later, elsewhere, on that route. Refuse here, by position,\n // and name the decorators that DO go on a parameter.\n if (typeof (descriptor as unknown) === \"number\") {\n throw new Error(\n `@${verb}(...) is a ROUTE decorator and was applied to parameter #${descriptor} of ${propertyKey === undefined ? \"the constructor\" : String(propertyKey)}; ` +\n \"for query-string params use @QueryParams(schema), for the body @Body(schema), for a path segment @Param(name)\",\n );\n }\n // CLASS position: `@Get(\"/x\") class C {}` arrives with no propertyKey\n // and would record a route literally named \"undefined\". AFTER the\n // parameter check: a constructor parameter (`constructor(@Get(\"/x\") x)`)\n // arrives as (C, undefined, 0) and deserves the parameter message.\n if (propertyKey === undefined) {\n throw new Error(`@${verb}(...) goes on a METHOD, not on a class; put it on the handler method inside @Controller`);\n }\n recordRoute(target, String(propertyKey), method, subpath, options);\n };\n };\n}\n\n/** `@Get(subpath, options?)` — declare a GET route. */\nexport const Get = makeMethodDecorator(\"GET\");\n/** `@Post(subpath, options?)` — declare a POST route. */\nexport const Post = makeMethodDecorator(\"POST\");\n/** `@Put(subpath, options?)` — declare a PUT route. */\nexport const Put = makeMethodDecorator(\"PUT\");\n/** `@Patch(subpath, options?)` — declare a PATCH route. */\nexport const Patch = makeMethodDecorator(\"PATCH\");\n/** `@Delete(subpath, options?)` — declare a DELETE route. */\nexport const Delete = makeMethodDecorator(\"DELETE\");\n/** `@Query(subpath, options?)` — declare an HTTP QUERY route (RFC 10008):\n * safe + idempotent like GET, body-carrying like POST. Input rides `@Body`. */\nexport const Query = makeMethodDecorator(\"QUERY\");\n","/**\n * The one rule for a declared surface name.\n *\n * A job's name is the row the scheduler holds it under; a webhook's name is the\n * path segment its endpoint is served at. Both used to be the FILE's name, which\n * made a public identity a property of where a class happened to sit — rename\n * the file and the scheduler starts a different job, or a sender's configured\n * URL stops resolving.\n *\n * Declaring it puts the identity beside the schedule and the secret, where a\n * reader is already looking. There is no default: a default would be a SECOND\n * source for the identity, and the whole design rests on there being one.\n */\nconst SHAPE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\nexport function assertSurfaceName(name: unknown, decorator: string, kind: string): void {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n throw new Error(\n `${decorator} requires a \\`name\\` — it is this ${kind}'s identity, and it is ` +\n `declared rather than taken from the file name.`,\n );\n }\n if (!SHAPE.test(name)) {\n throw new Error(\n `${decorator} name \"${name}\" is not usable: it reaches a URL and a log line, so it ` +\n `must be lowercase letters, digits and dashes, starting and ending with one of those.`,\n );\n }\n}\n","// @Webhook / @On — the inbound-webhook half of the decorator surface.\n//\n// Mirrors decorators/controller.ts exactly: symbol-keyed, non-enumerable\n// metadata on the constructor plus a `__palbase` discriminant, read back by a\n// resolver. The resolver is the ONLY translation point — it returns the shape\n// the runtime already consumes, so the isolate's dispatch and the signature\n// engine's cross-binding golden are untouched by the authoring change.\nimport type { WebhookMeta, WebhookProvider } from \"../webhook.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\n/** A signature scheme spelled out, for a service with no preset. The presets\n * (`provider`) are named configurations of this same shape. */\nexport interface SignatureSpec {\n /** Header carrying the signature. */\n header: string;\n /** Stripped before comparison (e.g. `sha256=`). Omit when absent. */\n prefix?: string;\n algo: \"hmac-sha256\" | \"hmac-sha1\";\n encoding: \"hex\" | \"base64\";\n /** What the HMAC covers. Exactly two placeholders: `{body}` and `{ts}`.\n * Everything else is literal. `{ts}` requires `timestampHeader` and brings\n * the five-minute replay window with it. */\n signs: string;\n timestampHeader?: string;\n}\n\nexport interface WebhookOptions {\n /**\n * The path segment this webhook is served at: `/webhooks/<name>`.\n *\n * DECLARED, not derived. It used to be the file's name, which put a PUBLIC\n * URL — the one a sender is configured with — in the file system rather than\n * beside the provider and the secret, where a reader looks for it.\n */\n name: string;\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n /** Env-var REFERENCE for the signing secret — the platform never holds it. */\n secret: { env: string };\n}\n\nexport type WebhookEventHandler = (event: unknown, meta: WebhookMeta) => Promise<void>;\n\nexport interface ResolvedWebhook {\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n secret: { env: string };\n events: Record<string, WebhookEventHandler>;\n}\n\nexport const WEBHOOK_META: unique symbol = Symbol.for(\"palbase.backend.webhookMeta\");\nexport const WEBHOOK_EVENTS: unique symbol = Symbol.for(\"palbase.backend.webhookEvents\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\ninterface WebhookCarrier {\n __palbase?: \"webhook\";\n [WEBHOOK_META]?: WebhookOptions;\n [WEBHOOK_EVENTS]?: EventEntry[];\n}\n\nfunction carrierOf(ctor: object): WebhookCarrier {\n return ctor as WebhookCarrier;\n}\n\n/** Mark a class as an inbound webhook. The mount name is the FILE name — there\n * is deliberately no `name` option, because the file name IS the public URL. */\nexport function Webhook(options: WebhookOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = carrierOf(ctor);\n Object.defineProperty(carrier, WEBHOOK_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"webhook\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/** Bind a method to one event name. Any string is valid: presets provide\n * autocomplete, never a constraint, because we do not carry provider catalogs. */\nexport function On(event: string) {\n return function (target: object, fnName: string | symbol): void {\n // Method decorators receive the PROTOTYPE; metadata belongs on the ctor.\n const carrier = carrierOf((target as { constructor: object }).constructor);\n const existing = carrier[WEBHOOK_EVENTS];\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, WEBHOOK_EVENTS, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Read a decorated class back as the resolved config the runtime consumes.\n * Every misuse throws HERE, at build time, rather than becoming a webhook that\n * answers 200 and does nothing.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every delivery. */\n/**\n * Everything a webhook DECLARES — provider or signature template, the secret's\n * env var, and the event names — validated, without constructing the class.\n *\n * Same split as jobs and hooks: reading a declaration should not build an\n * object. `getWebhookConfig` is what needs an instance, and it needs a\n * container to get one.\n */\nexport function getWebhookManifest(ctor: object): {\n name: string;\n provider: string | undefined;\n secretEnv: string;\n events: string[];\n} {\n const { meta, entries } = validateWebhook(ctor);\n return {\n name: meta.name,\n provider: meta.provider,\n secretEnv: meta.secret.env,\n events: entries.map((e) => e.event),\n };\n}\n\n/** The declaration half: every refusal, and no construction. */\nfunction validateWebhook(ctor: object): {\n meta: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_META]>;\n entries: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_EVENTS]>;\n} {\n const carrier = carrierOf(ctor);\n const meta = carrier[WEBHOOK_META];\n const entries = carrier[WEBHOOK_EVENTS] ?? [];\n\n if (!meta) {\n throw new Error(\n `@On used on a class that is not decorated with @Webhook (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Webhook\", \"webhook\");\n if (!meta.provider && !meta.signature) {\n throw new Error(\n \"@Webhook requires either a `provider` preset or an explicit `signature` — \" +\n \"an endpoint with no verification would accept forged deliveries\",\n );\n }\n // EITHER, not both. The isolate picks `provider` when both are present and\n // never looks at `signature`, so a tenant that wrote both gets deliveries\n // verified against a scheme they did not choose — silently, and with no way to\n // tell from the outside which one ran. Ambiguity about WHICH signature check\n // guards an endpoint is not something to resolve by precedence.\n if (meta.provider && meta.signature) {\n throw new Error(\n \"@Webhook declares BOTH a `provider` preset and an explicit `signature` — \" +\n \"these are alternatives; keep the one that describes the sender, because only `provider` would be used\",\n );\n }\n if (meta.signature) {\n const sig = meta.signature;\n // Mirrors Go's NewTemplateVerifier (internal/webhook/verify.go). Both sides\n // reject the same specs; this one rejects at build, which is the only place\n // a tenant can still act on it.\n if (!sig.header) {\n throw new Error(\"@Webhook signature requires `header` — the header the signature arrives in\");\n }\n if (sig.algo !== \"hmac-sha256\" && sig.algo !== \"hmac-sha1\") {\n throw new Error(`@Webhook signature has an unsupported algo \"${sig.algo}\"`);\n }\n if (sig.encoding !== \"hex\" && sig.encoding !== \"base64\") {\n throw new Error(`@Webhook signature has an unsupported encoding \"${sig.encoding}\"`);\n }\n if (!sig.signs?.includes(\"{body}\")) {\n throw new Error(\"@Webhook signature `signs` must contain {body} — signing a constant is not a signature\");\n }\n if (sig.signs.includes(\"{ts}\") && !sig.timestampHeader) {\n throw new Error(\"@Webhook signature uses {ts} but declares no `timestampHeader` to read it from\");\n }\n }\n if (!meta.secret?.env) {\n throw new Error(\"@Webhook requires `secret: { env: \\\"VAR_NAME\\\" }`\");\n }\n if (entries.length === 0) {\n throw new Error(\"@Webhook requires at least one @On handler\");\n }\n return { meta, entries };\n}\n\nexport function getWebhookConfig(ctor: object, container: Container): ResolvedWebhook {\n const { meta, entries } = validateWebhook(ctor);\n\n const instance = container.get(ctor as never) as Record<string, WebhookEventHandler>;\n // Object.create(null), not {} — event names are free-form, so `@On(\"constructor\")`\n // and `@On(\"toString\")` are legal. A plain literal inherits those keys from\n // Object.prototype, and the duplicate check below would reject the FIRST and\n // only handler for them as a redeclaration.\n const events: Record<string, WebhookEventHandler> = Object.create(null) as Record<string, WebhookEventHandler>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(events, entry.event)) {\n throw new Error(`@On(\"${entry.event}\") declared twice on the same webhook`);\n }\n events[entry.event] = (event, metaArg) =>\n (instance[entry.fnName] as WebhookEventHandler).call(instance, event, metaArg);\n }\n\n return {\n ...(meta.provider ? { provider: meta.provider } : {}),\n ...(meta.signature ? { signature: meta.signature } : {}),\n secret: meta.secret,\n events,\n };\n}\n","// @Hook — the BLOCKING half of the internal-event surface.\n//\n// Two axes decide which decorator a handler wants. Where does the event come\n// from, and can the handler stop it?\n//\n// @Webhook + @On an OUTSIDE service (Stripe, GitHub…) — cannot block\n// @Hook an event this stack raised — CAN block: `throw` cancels it\n// @On an event this stack raised — listens only, a monitor\n//\n// The blocking power lives in the NAME `@Hook`, not in the method decorator's\n// shape, which is why `@On` keeps meaning \"listener\" in both worlds and needs\n// no change. `@Upload` is the same pattern already shipped: the storage module\n// calls the tenant's method, and a method that answers 4xx discards the object\n// and hands its exact status, body and content-type back to the client.\n//\n// Mirrors decorators/webhook.ts: symbol-keyed, non-enumerable metadata on the\n// constructor, read back by one resolver. The resolver is the only translation\n// point, so the runtime consumes a shape the authoring surface never leaks.\nimport type { HookMeta } from \"../hooks.js\";\nimport { WEBHOOK_EVENTS } from \"./webhook.js\";\nimport type { Container } from \"../container.js\";\n\n/** A hook handler. Returning quietly ALLOWS; throwing DENIES (blocking hooks). */\nexport type HookFn = (event: unknown, meta: HookMeta) => Promise<unknown>;\n\nexport interface ResolvedHookClass {\n /** `@Hook` handlers, by event. A throw here cancels the operation. */\n blocking: Record<string, HookFn>;\n /** `@On` handlers, by event. A throw here reaches nobody but the log. */\n listeners: Record<string, HookFn>;\n}\n\n/** A hook's refusal, with the reason the caller will see.\n *\n * Any thrown error denies — this class exists so the REASON travels as a\n * deliberate message rather than as whatever a stray TypeError happened to say.\n * The engine is fail-closed by design (an unreachable hook denies), so a hook\n * body should stay narrow: an accidental throw refuses a real user. */\nexport class Deny extends Error {\n constructor(reason: string) {\n super(reason);\n this.name = \"Deny\";\n }\n}\n\nexport const HOOK_BLOCKING: unique symbol = Symbol.for(\"palbase.backend.hookBlocking\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\n/** `@Hook(\"before.user.create\")` — a blocking handler for one stack event. */\nexport function Hook(event: string) {\n return function (target: object, fnName: string | symbol): void {\n const carrier = (target as { constructor: object }).constructor as Record<symbol, unknown>;\n const existing = carrier[HOOK_BLOCKING] as EventEntry[] | undefined;\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, HOOK_BLOCKING, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Binds one decorator's entries onto a single instance of the class.\n *\n * ONE instance for the whole class, built here rather than per call: a hook\n * that opens a client or reads a list in its constructor would otherwise pay\n * for it on every signup. */\nfunction bind(instance: Record<string, HookFn>, entries: EventEntry[], kind: string) {\n const out: Record<string, HookFn> = Object.create(null) as Record<string, HookFn>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(out, entry.event)) {\n throw new Error(`${kind}(\"${entry.event}\") declared twice on the same hook class`);\n }\n // Resolved ONCE, here, so a decorator naming a method that does not exist\n // fails at build time with the name in the message — rather than at the\n // first signup, as \"instance[fnName] is not a function\".\n const fn = instance[entry.fnName];\n if (typeof fn !== \"function\") {\n throw new Error(`${kind}(\"${entry.event}\") names no method \"${entry.fnName}\" on the class`);\n }\n out[entry.event] = (event, meta) => fn.call(instance, event, meta);\n }\n return out;\n}\n\n/** Resolves a hook class into the two maps the runtime dispatches from.\n *\n * Every misuse throws HERE, at build time, rather than becoming a hook that is\n * silently never called — the failure mode this whole change exists to end.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every event. */\nexport function getHookConfig(ctor: object, container: Container): ResolvedHookClass {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n\n const instance = container.get(ctor as never) as Record<string, HookFn>;\n return {\n blocking: bind(instance, blockingEntries, \"@Hook\"),\n listeners: bind(instance, listenerEntries, \"@On\"),\n };\n}\n\n/**\n * Which events a hook class declares, and which of them BLOCK.\n *\n * Metadata only — the class is not constructed. Deploy's `hooks.manifest.json`\n * needs exactly this and has no container to build with.\n */\nexport function getHookManifest(ctor: object): { blocking: string[]; listeners: string[] } {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n return {\n blocking: blockingEntries.map((e) => e.event),\n listeners: listenerEntries.map((e) => e.event),\n };\n}\n","// `@Upload` — the single-method direct-storage upload decorator, and its\n// `@UploadedObject` parameter companion + `UploadConfig`/`UploadedObject` types.\n//\n// Unlike `@Get`/`@Post`/… (where bytes flow THROUGH the br-pod), an `@Upload`\n// route never sees the file bytes: the client uploads DIRECTLY to storage via a\n// signed URL the br-pod mints in an authorize pre-flight. The decorated method\n// body is the COMPLETION handler — it runs once, after storage confirms the\n// object landed (via an HMAC-signed completion webhook), and returns the typed\n// result the client awaits. There is exactly one method: it is BOTH the\n// authorize gate (its uploadConfig drives the guard + signed-URL pinning) AND\n// the completion handler (its body).\n//\n// On the wire the authorize pre-flight is a POST; what marks a route as an\n// upload route through the whole pipeline (registry → flatten → openapi →\n// codegen) is the PRESENCE of `uploadConfig` on the route — never a special HTTP\n// verb. The `@Get`/`@Post`/… decorators never set it.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { PalbaseBucketName } from \"../stack.js\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Direct-storage upload settings for an `@Upload` route. The br-pod validates an\n * authorize request against these (size/type), then mints a signed upload URL\n * that PINS the limits so storage itself rejects an over-limit / wrong-type PUT\n * — the client cannot exceed what it declared.\n */\nexport interface UploadConfig {\n /**\n * Target bucket NAME — one the STACK holds.\n *\n * The union comes from the generated `palbase-stack.d.ts`, so a bucket the\n * stack does not carry is a compile error. It used to say \"MUST exist in\n * `config/storage.ts` defineStorage(...)\", and that invariant was carried by\n * this sentence plus a cross-check nothing called; it is carried by the type\n * now.\n *\n * The bucket is the SINGLE SOURCE OF TRUTH for the size limit + MIME allowlist:\n * `bucket({ fileSizeLimit, allowedMimeTypes })`. Storage enforces those at the\n * actual PUT (the only guard a client cannot skip), so `@Upload` deliberately\n * does NOT take its own `maxSize`/`allowedTypes` — duplicating them here would\n * let a route declare a tighter limit than its bucket that storage would not\n * enforce (a real bypass: declare 10 bytes at authorize, then PUT up to the\n * bucket ceiling straight at the signed URL). One bucket, one limit, enforced.\n */\n bucket: PalbaseBucketName;\n /**\n * SERVER-side object key template. The client NEVER chooses the path. Tokens:\n * `{userId}` (authenticated user id), `{uploadId}` (server-minted), and\n * `{filename}` (the client-declared filename, sanitized). e.g.\n * `\"{userId}/{uploadId}-{filename}\"`.\n */\n pathTemplate: string;\n}\n\n/**\n * The uploaded object, injected into an `@Upload` method body by\n * `@UploadedObject()` once storage confirms the upload. Bytes are NOT present\n * (they went straight to storage) — this is the metadata the completion handler\n * persists.\n */\nexport interface UploadedObject {\n /** Server-minted id correlating authorize ↔ completion (idempotency key). */\n uploadId: string;\n /** Final object key in the bucket (rendered from `pathTemplate`). */\n path: string;\n /** Bucket the object landed in. */\n bucket: string;\n /** Object size in bytes, as reported by storage. */\n size: number;\n /** Object MIME type, as reported by storage — detected from the BYTES, not\n * from the filename or from what the client claimed. */\n contentType: string;\n /** SHA-256 of the stored bytes, hex. The same value the object's ETag is\n * derived from, so a client that has it can tell whether it already holds\n * these bytes. */\n checksum: string;\n /** Pixel width, for an image. Absent otherwise — a PDF has no dimensions,\n * and reporting 0 would be a measurement rather than an absence. */\n width?: number;\n /** Pixel height, for an image. */\n height?: number;\n /**\n * A ~25-byte placeholder the client paints INSTANTLY while the real image\n * downloads — the thing that replaces a grey skeleton with something already\n * shaped like the picture. Absent for non-images.\n *\n * Persist it beside the object's path: it costs a column and saves a request\n * per picture on every gallery render.\n */\n thumbhash?: string;\n /**\n * The renditions the bucket declared, by name, as URLs ready to use.\n *\n * Present on the completion input so the handler that stores the row has\n * everything it needs in one place — asking for them afterwards would be a\n * second call per upload, and per picture on every read.\n */\n variants: Record<string, string>;\n}\n\n/**\n * `@Upload(subpath, config)` — declare a direct-storage upload route. The method\n * body is the completion handler; `config.uploadConfig` drives the authorize\n * guard + signed-URL pinning.\n *\n * @example\n * @Upload(\"/\", { bucket: \"docs\", pathTemplate: \"{userId}/{uploadId}-{filename}\" })\n * async upload(@UploadedObject() obj: UploadedObject, @User() user): Promise<DocResult> { ... }\n * // The size limit + MIME allowlist come from the \"docs\" bucket ON THE STACK\n * // — storage enforces them at the PUT.\n */\nexport function Upload(\n subpath: string,\n config: UploadConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...uploadConfig } = config;\n validateUploadConfigShape(uploadConfig);\n const options: RouteOptions = {\n uploadConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n // On the wire the authorize pre-flight is a POST; `uploadConfig` is what\n // marks this as an upload route downstream.\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@UploadedObject()` — inject the uploaded object (`: UploadedObject`) into an\n * `@Upload` method body (the completion input). Only valid on an `@Upload`\n * route; the bytes are NOT present (they went directly to storage), this is the\n * confirmed object's metadata.\n *\n * Co-located with the {@link UploadedObject} TYPE so a single exported name\n * `UploadedObject` carries BOTH the decorator value and the type annotation.\n */\nexport function UploadedObject(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind: \"uploadedObject\",\n });\n };\n}\n\n/**\n * Shape-validate an UploadConfig at decoration time (author-time failure beats a\n * silent deploy bug). Does NOT check that the bucket EXISTS — the generated\n * `palbase-stack.d.ts` union does that, and it does it at compile time rather\n * than at deploy.\n */\nexport function validateUploadConfigShape(c: UploadConfig): void {\n if (c === null || typeof c !== \"object\") {\n throw new Error(\"@Upload config must be an object { bucket, pathTemplate, ... }\");\n }\n // Read the bucket through a WIDENED view on purpose. Its declared type is\n // `PalbaseBucketName`, which is `never` until the project generates\n // `palbase-stack.d.ts` — and `never.length` does not typecheck. This function\n // is a RUNTIME guard against a shape the compiler never saw (a plain-JS\n // caller, a bundle boundary), so the value arriving here is genuinely unknown\n // and reading it as such is the honest signature, not a cast to dodge an error.\n const bucket: unknown = (c as { bucket?: unknown }).bucket;\n if (typeof bucket !== \"string\" || bucket.length === 0) {\n throw new Error(\"@Upload config.bucket must be a non-empty bucket name\");\n }\n if (typeof c.pathTemplate !== \"string\" || c.pathTemplate.length === 0) {\n throw new Error(\"@Upload config.pathTemplate must be a non-empty key template\");\n }\n}\n\n","// `@Sse` — the streaming-response decorator, and its `@SseOut` / `@Signal`\n// parameter companions.\n//\n// Unlike `@Get`/`@Post`/… (where the handler's RETURN VALUE is serialised to\n// JSON), an `@Sse` route's method body WRITES frames as it goes and its return\n// value is discarded. The response is `text/event-stream` and stays open until\n// the body returns or the client disconnects.\n//\n// On the wire an `@Sse` route is a POST — a stream is started by a request that\n// carries input. What marks it as a streaming route through the whole pipeline\n// (registry → flatten → openapi → codegen) is the PRESENCE of `sseConfig` on the\n// route, NEVER the verb: an ordinary `@Post` route is also POST, so the verb\n// cannot carry the distinction. This is the same rule `@Upload` states, for the\n// same reason.\n//\n// The problem this solves: a provider on the server (an AI client, a job queue,\n// any long-running producer) streams from a session; while a client is connected\n// the frames reach it, and when the client disconnects the provider must stop\n// being pulled. That last half is what `@Signal()` exists for.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Settings for an `@Sse` route.\n *\n * EMPTY in v1, and deliberately so: the pipeline keys off this object's\n * PRESENCE, not its contents (see the file header). Declaring the type now means\n * a later setting arrives as a field on an existing marker rather than as a\n * second marker nothing downstream reads.\n */\nexport interface SseConfig {\n /**\n * The shape of ONE frame — what a single `out.write(value)` carries.\n *\n * REQUIRED, not optional, and that is the whole point. An `@Sse` handler\n * returns `Promise<void>`, so the codegen-injected `recordReturn` has no type\n * to record and nothing downstream can infer what a frame is. A route without\n * this declares a stream whose element type is unknown, and every generated\n * client from that contract is opaque — which is precisely the failure\n * `x-palbase-sse` exists to prevent. Making it optional would have left that\n * failure one forgotten field away.\n *\n * Measured live on a real pushed stack (2026-08-29): the contract gate refused\n * the deploy with \"2 untyped response(s) — every generated client from it is\n * opaque\", naming both routes that omitted it.\n */\n frame: ZodTypeAny;\n}\n\n/**\n * The writer injected by `@SseOut()`. Each `write` emits ONE SSE `data:` frame\n * carrying `value` JSON-encoded.\n *\n * The FIRST `write` is load-bearing beyond its frame: it settles the request's\n * database transaction. A streaming response may run for minutes, and the\n * handler runs inside the request's transaction — holding one open for the life\n * of a stream exhausts the connection pool, a failure invisible to a unit test\n * that only dies under load. So the first frame is the point at which the\n * request phase is declared over, and database access after it is refused by\n * name rather than silently run against a settled transaction.\n *\n * The practical rule for a handler: do the database work BEFORE the first write.\n */\nexport interface SseWriter {\n write(value: unknown): void;\n}\n\n/**\n * `@Sse(subpath, config)` — declare a streaming route.\n *\n * @example\n * @Sse(\"/chat\", { frame: ChatFrame })\n * async chat(@Body() b: ChatInput, @SseOut() out: SseWriter, @Signal() signal: AbortSignal) {\n * const stream = await openai.chat.completions.create(\n * { model: \"gpt-5.6\", messages: b.messages, stream: true },\n * { signal },\n * );\n * for await (const chunk of stream) out.write(chunk);\n * }\n * // The client disconnects → `signal` aborts → the provider stops being pulled.\n * // The signal is a plain AbortSignal, so it goes wherever the provider takes\n * // one: `{ signal }` for the OpenAI and Anthropic SDKs, `abortSignal:` for the\n * // Vercel AI SDK, `fetch(url, { signal })` for a raw call.\n */\nexport function Sse(\n subpath = \"\",\n config: SseConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...sseConfig } = config;\n const options: RouteOptions = {\n sseConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@SseOut()` — inject the frame writer (`: SseWriter`) into an `@Sse` method\n * body. Only meaningful on an `@Sse` route.\n */\nexport function SseOut(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"sseOut\" });\n };\n}\n\n/**\n * `@Signal()` — inject the request's `AbortSignal`, which enters the aborted\n * state when the client disconnects.\n *\n * NOT derivable from `@Req()`: `PBRequest` carries only request-scoped data —\n * the typed input, route/query params, headers, the authenticated user, calling\n * client metadata, trace ids, and the declared error throwers — and no signal\n * (endpoint.ts:358-363).\n *\n * Measured 2026-08-29 on Bun: an infinite producer guarded by this signal\n * stopped four frames after the client was killed, and the handler's `finally`\n * ran. It is the same mechanism a NestJS handler reaches through\n * `req.on(\"close\")`.\n */\nexport function Signal(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"signal\" });\n };\n}\n","// @Room — the realtime surface a backend can actually MANAGE.\n//\n// palbase's realtime lets a backend TALK (broadcast, state.set, push.send) and\n// lets it INTERCEPT a client's publish (defineChannels' handler). What it never\n// let a backend do is SEE the connection: who joined, who left, whether anyone\n// is still watching. A room is that missing half, in the shape this SDK already\n// uses for HTTP — a class with decorated methods.\n//\n// The cost of the gap was concrete: nothing could tell a project that the last\n// device left, so an expensive upstream (an AI session, a market feed, a game\n// loop) kept running and kept billing with nobody reading it. `@OnFirst` and\n// `@OnEmpty` exist for exactly that pair of moments.\n//\n// WHAT A ROOM IS NOT: it does not know where the room id came from, what the\n// history is, or what `@OnFirst` starts. All three belong to the project. The\n// primitive is infrastructure; it carries messages both ways and reports who is\n// present.\n\nimport type { ZodTypeAny } from \"zod\";\nimport {\n recordRoom,\n recordRoomHook,\n recordRoomMessage,\n type RoomHook,\n} from \"./registry.js\";\n\nexport interface RoomOptions {\n /**\n * The events this room sends to its clients, by name.\n *\n * Declared rather than inferred, because a room emits from anywhere in the\n * class — there is no return type to read. The map is the room's public\n * surface: it becomes a Swift enum and a TypeScript union in the generated\n * clients, so a device gets `case .tick(n:)` instead of an opaque bag.\n *\n * Per-event rather than one blob because realtime is event-ADDRESSED all the\n * way down (`Realtime.broadcast(channel, EVENT, payload)`).\n */\n events: Record<string, ZodTypeAny>;\n\n /**\n * How long a room is held after its last sign of life, in milliseconds.\n *\n * Default 60_000, and the floor is not a matter of taste: the decision must\n * survive the SLOWEST client's heartbeat gap twice over, and the web SDK\n * beats every 25 s (palbe/src/realtime/connection.ts:133) against iOS's 2 s\n * (RealtimeConnection.swift:162). A shorter default would declare healthy web\n * clients dead between two beats.\n *\n * Raise it for an upstream that is expensive to restart; lower it (never\n * below ~50 s while web beats at 25 s) for one that is cheap.\n */\n graceMs?: number;\n}\n\n/** Twice the slowest client heartbeat, plus margin. See RoomOptions.graceMs. */\nconst DEFAULT_GRACE_MS = 60_000;\n\n/**\n * A room pattern IS a channel pattern, so it obeys the channel matcher's rules.\n *\n * Both ends of the wire split on `:` — Go's `matchPattern`\n * (internal/modules/rt/channels.go) and this SDK's `matchDeclared` — so a\n * pattern written with slashes matches NO live topic. It fails silently: the\n * room compiles, ships, and simply never fires. Refused here, by name, at the\n * only moment a human is looking.\n *\n * The duplicate-param rule is carried over for the reason channels.ts states:\n * `dm:{uid}:{uid}` against `dm:victim:attacker` lets the last segment win, and\n * an owner check then compares the attacker's id with itself and passes.\n */\nfunction assertPattern(pattern: string): void {\n if (pattern.includes(\"/\")) {\n throw new Error(\n `@Room(\"${pattern}\"): channel patterns are colon-separated, not slash-separated. ` +\n `Write \"${pattern.replace(/\\//g, \":\")}\" — a slash matches no live topic.`,\n );\n }\n const segments = pattern.split(\":\");\n if (segments.some((s) => s === \"\")) {\n throw new Error(`@Room(\"${pattern}\"): empty segment — every segment must be non-empty.`);\n }\n const seen = new Set<string>();\n for (const s of segments) {\n if (!s.startsWith(\"{\") || !s.endsWith(\"}\")) continue;\n const name = s.slice(1, -1);\n if (name === \"\") throw new Error(`@Room(\"${pattern}\"): \"{}\" names no parameter.`);\n if (seen.has(name)) {\n throw new Error(`@Room(\"${pattern}\"): parameter \"{${name}}\" appears twice.`);\n }\n seen.add(name);\n }\n}\n\n/**\n * Declare a class as a room.\n *\n * ```ts\n * @Room(\"chat:{roomId}\", { events: { message: Message } })\n * class ChatRoom {\n * @OnAuthorize() can({ user, params }) { … }\n * @OnFirst() open(ctx) { … } // the room filled\n * @OnEmpty() close(ctx) { … } // nobody is watching any more\n * @OnMessage(\"say\", Say) say(ctx) { … }\n * }\n * ```\n *\n * The pattern is the topic: `chat:{roomId}` addresses `chat:42`. A room is\n * marked by the PRESENCE of this config — never by a name, a base class or a\n * naming convention.\n */\nexport function Room(pattern: string, options: RoomOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n assertPattern(pattern);\n // Member decorators have already run (TypeScript evaluates members before\n // the class), so the hook buffer is complete here and `recordRoom` drains\n // it. controller.ts:203 documents and depends on the same ordering.\n recordRoom(ctor, {\n pattern,\n events: options.events,\n graceMs: options.graceMs ?? DEFAULT_GRACE_MS,\n });\n return ctor;\n };\n}\n\nfunction hookDecorator(hook: RoomHook): () => MethodDecorator {\n return () =>\n function (target: object, propertyKey: string | symbol): void {\n recordRoomHook(target, hook, String(propertyKey));\n };\n}\n\n/** Who may enter. Return a grant to admit, `null` to refuse. */\nexport const OnAuthorize = hookDecorator(\"authorize\");\n\n/**\n * The room is occupied and nobody owns it — start whatever the room needs.\n *\n * Deliberately a CONDITION rather than a 0→1 transition, and the difference is\n * load-bearing: a runtime restart, a deploy pointer swap (the previous release\n * is never torn down) and an owner that died all leave a full room with nobody\n * holding it. A transition would fire once and never again; a condition\n * recovers every time.\n *\n * Exactly one runtime in the cluster enters this hook for a given room, so\n * three devices never open three upstreams.\n */\nexport const OnFirst = hookDecorator(\"first\");\n\n/** A device arrived. Anything emitted here reaches ONLY that device. */\nexport const OnJoin = hookDecorator(\"join\");\n\n/** A device left. */\nexport const OnLeave = hookDecorator(\"leave\");\n\n/** Nobody is watching any more — stop whatever `@OnFirst` started. */\nexport const OnEmpty = hookDecorator(\"empty\");\n\n/**\n * A message from a client, validated against `schema` before the method runs.\n *\n * A payload that fails the schema never reaches the method: the client is told\n * why, and the room's code only ever sees the shape it declared.\n */\nexport function OnMessage(name: string, schema: ZodTypeAny): MethodDecorator {\n return function (target: object, propertyKey: string | symbol): void {\n recordRoomMessage(target, name, String(propertyKey), schema);\n };\n}\n","// Parameter decorators: `@Body` / `@QueryParams` / `@Param` / `@Headers` / `@User` /\n// `@OptionalUser` / `@Client` / `@RequestId` / `@TraceId` / `@Req`. Each records\n// `{ index, kind, schema?, name? }` into the per-class registry for the method\n// it decorates. These are LEGACY parameter decorators\n// (`experimentalDecorators`), receiving `(prototype, methodName, paramIndex)` —\n// esbuild/tsc preserve the param index at runtime (verified, design §0), which\n// is how dispatch injects positionally. No type reflection\n// (`emitDecoratorMetadata`) is used: validation comes from the zod schema, the\n// type annotation the developer writes is purely for autocomplete.\nimport type { ZodTypeAny } from \"zod\";\nimport { recordParam, type ParamKind } from \"./registry.js\";\n\n/** A legacy parameter decorator. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/** Build a parameter decorator that records the given kind (+ optional schema /\n * name) at the decorated parameter's index. */\nfunction makeParamDecorator(\n kind: ParamKind,\n extra?: { schema?: ZodTypeAny; name?: string },\n): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind,\n ...(extra?.schema !== undefined ? { schema: extra.schema } : {}),\n ...(extra?.name !== undefined ? { name: extra.name } : {}),\n });\n };\n}\n\n/** `@Body(schema)` — inject the request body, validated against `schema`. The\n * developer writes `: T` (= `z.infer<schema>`, same name) for autocomplete. */\nexport function Body(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"body\", { schema });\n}\n\n/** `@QueryParams(schema)` — inject the parsed query params, validated against\n * `schema`. */\nexport function QueryParams(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"query\", { schema });\n}\n\n/** `@Headers(schema?)` — inject the request headers (lowercase keys). With a\n * schema, headers are validated + the codegen emits header parameters. */\nexport function Headers(schema?: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"headers\", schema !== undefined ? { schema } : undefined);\n}\n\n/** `@Param(\"id\")` — inject one matched path param by name. */\nexport function Param(name: string): ParameterDecorator {\n return makeParamDecorator(\"param\", { name });\n}\n\n/** `@User()` — inject the authenticated user (`: User`, non-null for an\n * effective-required route). The runtime resolves the effective auth. */\nexport function User(): ParameterDecorator {\n return makeParamDecorator(\"user\");\n}\n\n/** `@OptionalUser()` — inject the user as `User | null` (for routes whose\n * effective auth is `false` / `{ required: false }`). */\nexport function OptionalUser(): ParameterDecorator {\n return makeParamDecorator(\"optionalUser\");\n}\n\n/** `@Client()` — inject the parsed calling-client metadata (`: ClientInfo`). */\nexport function Client(): ParameterDecorator {\n return makeParamDecorator(\"client\");\n}\n\n/** `@RequestId()` — inject the per-request id (`: string`). */\nexport function RequestId(): ParameterDecorator {\n return makeParamDecorator(\"requestId\");\n}\n\n/** `@TraceId()` — inject the W3C trace id (`: string`). */\nexport function TraceId(): ParameterDecorator {\n return makeParamDecorator(\"traceId\");\n}\n\n/** `@Req()` — inject the raw request object (escape hatch, `: PBRequest`). */\nexport function Req(): ParameterDecorator {\n return makeParamDecorator(\"req\");\n}\n\n// NOTE: `@UploadedObject()` lives in decorators/upload.ts (co-located with the\n// `UploadedObject` TYPE) so a single exported name carries both the value (the\n// decorator) and the type — TS can only merge value+type under one export name\n// when both are declared in the SAME module.\n","import type { DBClient, Logger, CacheClient, PalbaseModuleClients } from \"./endpoint.js\";\nimport type { User } from \"./types.js\";\n\n/** Middleware context — subset of EndpointContext without input (not yet validated). */\nexport interface MiddlewareContext extends PalbaseModuleClients {\n params: Record<string, string>;\n query: Record<string, string>;\n headers: Record<string, string>;\n user: User | null;\n db: DBClient;\n env: Record<string, string>;\n log: Logger;\n cache: CacheClient;\n requestId: string;\n environmentId: string;\n}\n\n/** Middleware function signature — receives context and next function. */\nexport type MiddlewareHandler = (\n ctx: MiddlewareContext,\n next: () => Promise<void>,\n) => Promise<void>;\n\n/**\n * REMOVED IN BEHAVIOUR, KEPT IN NAME.\n *\n * There is no middleware pipeline in this runtime. No bundler reads a\n * `middleware/` directory, the engine never calls a handler defined here, and\n * measured on 2026-08-31 this function had no caller anywhere in the runtime or\n * the CLI. It returned its argument unchanged, so code written against it\n * compiled, deployed, and then never ran — with nothing reporting that.\n *\n * A silent shell is the worst version of a retired feature: it lets a user (or a\n * coding assistant, which is how this surfaced) ship a request logger, an auth\n * check or a rate limiter that simply does not exist in production. So the call\n * refuses, and says where the work belongs.\n *\n * The SYMBOL survives because removing a published export costs a major and\n * 25.0.1 had just shipped. Deleting it is a proposal for the next one; the types\n * below stay either way, so a file that only annotates with them still compiles.\n *\n * This is the shape the SDK already uses for a retired surface: `@Query(schema)`\n * on a parameter throws at decoration time with a message naming its\n * replacement.\n */\nexport function defineMiddleware(_fn: MiddlewareHandler): never {\n throw new Error(\n \"defineMiddleware() is not wired to anything: no bundler reads a `middleware/` \" +\n \"directory and the engine has no middleware pipeline, so a handler defined \" +\n \"here deploys and never runs. Put cross-cutting work in a service the \" +\n \"controllers call, and use route options for auth (`@Controller(path, { auth })`) \" +\n \"and rate limits (`@Get(path, { rateLimit })`).\",\n );\n}\n","// defineError — project-defined typed error classes + the module-global error\n// registry the OpenAPI spec twins join against.\n//\n// `defineError(code, status, dataSchema?)` returns an `HttpError` subclass whose\n// constructor is typed by the zod schema (`new TodoLocked({ retryAfter: 30 })`).\n// Each call self-registers `{ code, status, className, dataSchema }` in a\n// registry anchored on `globalThis` under `Symbol.for(...)` — mirroring the\n// ROUTES pattern — so the deploy bundle's registrations land on the single SDK\n// instance the extractor `require()`s. The registry is pre-seeded with the named\n// built-in classes (`NotFound`, `Conflict`, …) so throw inference can resolve\n// ad-hoc `throw new NotFound(...)` sites by their canonical wire codes.\n//\n// Duplicate code with a DIFFERENT shape (status OR converted data schema) is a\n// hard error at registration time (deploy fails loudly — error codes are\n// project-unique); structurally-identical re-registration is idempotent (each\n// controller BUNDLE carries its own copy of a shared models/errors.ts, so the\n// same defineError line legitimately runs once per bundle in one process).\nimport {\n OpenAPIRegistry,\n OpenApiGeneratorV31,\n extendZodWithOpenApi,\n} from \"@asteasolutions/zod-to-openapi\";\nimport { z, type ZodTypeAny } from \"zod\";\nimport { HttpError } from \"./errors.js\";\n\nextendZodWithOpenApi(z);\n\n/** One registered error: the wire code, HTTP status, the class name the\n * analyzer sees, the optional data payload schema, and whether it is one of the\n * pre-seeded built-in named classes. */\nexport interface RegisteredError {\n code: string;\n status: number;\n className: string;\n dataSchema?: ZodTypeAny;\n /** JSON.stringify of the converted JSON schema — equal digest ⇔ the spec\n * twins would emit an identical `data` schema for this error. */\n dataDigest?: string;\n builtin: boolean;\n}\n\n/** The cross-module-instance registry anchor (the pinned contract symbol). */\nconst ERROR_REGISTRY: unique symbol = Symbol.for(\"palbase.backend.errorRegistry\");\n\ninterface RegistryCarrier {\n [ERROR_REGISTRY]?: Map<string, RegisteredError>;\n}\n\n/** Get (creating + pre-seeding if absent) the project-global error registry,\n * keyed by wire code. Anchored on `globalThis` so every copy of the SDK in a\n * process shares the one registry. */\n/** The fixed data schemas the built-in named errors ship. Declared HERE (not in\n * errors.ts, which stays zod-free) because this is where the registry converts\n * them to JSON-schema for the spec — keying codegen's typed `error.data`. Only\n * the errors that semantically carry a payload have a schema; the rest are\n * data-less. `.int()` is preserved so the wire/codegen sees an integer. */\nconst BUILTIN_DATA_SCHEMAS: Record<string, ZodTypeAny> = {\n bad_request: z.object({\n fields: z.array(z.object({ field: z.string(), message: z.string() })),\n }),\n too_many_requests: z.object({ retryAfter: z.number().int() }),\n};\n\nexport function getErrorRegistry(): Map<string, RegisteredError> {\n const g = globalThis as RegistryCarrier;\n if (!g[ERROR_REGISTRY]) {\n const m = new Map<string, RegisteredError>();\n for (const [code, status, className] of [\n [\"bad_request\", 400, \"BadRequest\"],\n [\"unauthorized\", 401, \"Unauthorized\"],\n [\"forbidden\", 403, \"Forbidden\"],\n [\"not_found\", 404, \"NotFound\"],\n [\"conflict\", 409, \"Conflict\"],\n // The engine's own 23505 conversion (engine/db.ts) throws this, and an\n // author may too. Registered like every other built-in so the spec\n // emitter resolves it — an unregistered code is SKIPPED silently there\n // (openapi/convert.ts) and would degrade to the client's `.other` case.\n [\"unique_violation\", 409, \"UniqueViolation\"],\n [\"too_many_requests\", 429, \"TooManyRequests\"],\n ] as const) {\n const dataSchema = BUILTIN_DATA_SCHEMAS[code];\n m.set(code, {\n code,\n status,\n className,\n builtin: true,\n ...(dataSchema ? { dataSchema, dataDigest: digestOf(code, dataSchema) } : {}),\n });\n }\n g[ERROR_REGISTRY] = m;\n }\n return g[ERROR_REGISTRY];\n}\n\n/** Class returned for schema-bearing errors: ctor(data, message?). */\nexport interface DefinedErrorWithData<S extends ZodTypeAny> {\n new (data: z.input<S>, message?: string): HttpError;\n readonly code: string;\n readonly status: number;\n}\n\n/** Class returned for schema-less errors: ctor(message?). */\nexport interface DefinedError {\n new (message?: string): HttpError;\n readonly code: string;\n readonly status: number;\n}\n\n/**\n * Define a project error class. MUST be called with literal args (string\n * literal `code`, numeric literal `status`) at module top level — the deploy\n * stager's static analyzer reads those literals to resolve throw sites.\n *\n * @example\n * // models/todos/errors.ts\n * export const TodoLocked = defineError(\"todo_locked\", 409, z.object({ retryAfter: z.number() }));\n * // services/todo.service.ts\n * throw new TodoLocked({ retryAfter: 30 });\n */\nexport function defineError<S extends ZodTypeAny>(\n code: string,\n status: number,\n dataSchema: S,\n): DefinedErrorWithData<S>;\nexport function defineError(code: string, status: number): DefinedError;\nexport function defineError(code: string, status: number, dataSchema?: ZodTypeAny): unknown {\n if (!Number.isInteger(status) || status < 400 || status > 599) {\n throw new Error(\n `defineError: status for \"${code}\" must be a 4xx/5xx integer, got ${status} — ` +\n `error responses must not clobber success responses in the project spec.`,\n );\n }\n const registry = getErrorRegistry();\n const existing = registry.get(code);\n const className = defaultClassName(code);\n const dataDigest = dataSchema ? digestOf(code, dataSchema) : undefined;\n if (existing) {\n const sameShape =\n existing.status === status && !existing.builtin && existing.dataDigest === dataDigest;\n if (!sameShape) {\n throw new Error(\n `defineError: duplicate error code \"${code}\" with a different shape ` +\n `(existing: status ${existing.status}${existing.builtin ? \", built-in\" : \"\"}` +\n `${existing.status === status && !existing.builtin ? \", different data schema\" : \"\"}). ` +\n `Error codes are project-unique.`,\n );\n }\n }\n // Local factories so the class-constructor closures capture a NON-optional\n // schema binding (narrowing does not flow into closures created in a branch).\n const makeWithData = (schema: ZodTypeAny) =>\n class extends HttpError {\n static readonly code = code;\n static readonly status = status;\n constructor(data: unknown, message?: string) {\n super(status, code, message ?? humanize(code), schema.parse(data));\n this.name = className;\n }\n };\n const makeWithoutData = () =>\n class extends HttpError {\n static readonly code = code;\n static readonly status = status;\n constructor(message?: string) {\n super(status, code, message ?? humanize(code));\n this.name = className;\n }\n };\n const cls = dataSchema ? makeWithData(dataSchema) : makeWithoutData();\n Object.defineProperty(cls, \"name\", { value: className });\n registry.set(code, {\n code,\n status,\n className,\n builtin: false,\n ...(dataSchema ? { dataSchema } : {}),\n ...(dataDigest !== undefined ? { dataDigest } : {}),\n });\n return cls;\n}\n\n/** Convert a data schema through the SAME library the spec twins use and\n * return its JSON-schema digest (the duplicate-shape comparison key). Doubles\n * as the self-containment guard: a schema carrying `.openapi(refId)` metadata\n * (top-level or nested) converts to `$ref` pointers into components the\n * project spec never emits — a dangling ref every spec consumer would choke\n * on — so it is rejected here, at the definition site, with a fixable message. */\nfunction digestOf(code: string, dataSchema: ZodTypeAny): string {\n const TMP_REF = \"__PalbaseErrorDataDigest\";\n const tmpRegistry = new OpenAPIRegistry();\n // Wrap the schema as a property — exactly how the envelope embeds it — so a\n // TOP-LEVEL .openapi(refId) is not masked by the registration refId and\n // surfaces as the same $ref the real emission would produce.\n tmpRegistry.register(TMP_REF, z.object({ data: dataSchema }).openapi(TMP_REF));\n const generated = new OpenApiGeneratorV31(tmpRegistry.definitions).generateComponents();\n const out = generated.components?.schemas?.[TMP_REF];\n const digest = JSON.stringify(out ?? null);\n if (digest.includes('\"$ref\"')) {\n throw new Error(\n `defineError: dataSchema for \"${code}\" carries .openapi(refId) metadata — ` +\n `it would emit dangling $ref pointers in the project spec. ` +\n `Use a plain zod schema (z.object({...})) without .openapi(...).`,\n );\n }\n return digest;\n}\n\n/** \"todo_locked\" → \"TodoLocked\" (used as Error.name; the source class NAME the\n * analyzer sees is whatever the user assigned the const to — they should match\n * by convention, and the descriptor carries the analyzed const name anyway). */\nfunction defaultClassName(code: string): string {\n return code\n .split(\"_\")\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join(\"\");\n}\n\n/** \"todo_locked\" → \"Todo locked\" — the default human-readable message. */\nfunction humanize(code: string): string {\n const s = code.replace(/_/g, \" \");\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n","import { type Token } from \"./module.js\";\n\n/**\n * The slot injectable declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol for the same reason `DI_MODULES` is\n * (see `module.ts`): a tenant bundle inlines its OWN copy of `@palbase/backend`\n * and the engine that loads it carries another, so a module-local array would\n * have the decorators push into one and the container read the other.\n */\nexport const DI_INJECTABLES: unique symbol = Symbol.for(\n \"palbase.backend.diInjectables\",\n) as never;\n\n/**\n * The marker `@Injectable()` leaves ON the class.\n *\n * Two signals, because two questions are being asked and only one of them can be\n * answered by a list. \"WHICH classes were declared in this build\" needs an\n * enumeration and gets the claimable slot below. \"IS this class decorated\" needs\n * an answer that survives Bun's module cache: a rollback re-imports an artifact\n * whose body does not run again, so the slot comes back empty while the modules\n * still list the same classes. Reading the slot for that question refused a\n * correct app — measured in `engine.test.ts`, where the second `createApp` in\n * one process saw an emptied slot and called every provider undecorated.\n */\nexport const INJECTABLE: unique symbol = Symbol.for(\"palbase.backend.injectable\") as never;\n\n/** Does this class carry `@Injectable()`? Reads the class, not a registry. */\nexport const isInjectable = (c: unknown): boolean =>\n (c as Record<symbol, unknown> | null)?.[INJECTABLE] === true;\n\nfunction slot(): Token[] {\n const g = globalThis as unknown as Record<symbol, Token[] | undefined>;\n return (g[DI_INJECTABLES] ??= []);\n}\n\n/**\n * Marks a class the container can resolve.\n *\n * TWO JOBS, and the first one is why the decorator has to exist at all:\n * TypeScript under `emitDecoratorMetadata` emits `design:paramtypes` for\n * DECORATED classes only. Measured — an undecorated class with the same\n * constructor carries no metadata, and `Reflect.getMetadata` answers\n * `undefined`.\n *\n * The second is being COUNTABLE. Ownership, visibility and permission are still\n * read from a single `@Module` and never from this decorator — recording the\n * class here decides nothing. It only makes \"carries `@Injectable()` and\n * appears in no module\" a question the build can ask, which FR-010 requires it\n * to answer by name. The body was empty until 2026-09-02, and the consequence\n * was measured through the CLI: an `@Injectable()` service in no module built\n * clean, while this file's own comment claimed the build named it.\n */\nexport function Injectable(): ClassDecorator {\n return (target) => {\n (target as unknown as Record<symbol, unknown>)[INJECTABLE] = true;\n slot().push(target as unknown as Token);\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same claim semantics as `__claimModules`, and for the same reason: a\n * candidate bundle is imported into the SAME process as the live app it might\n * replace, so reading would let a candidate be judged against the live app's\n * classes and a discarded candidate would leave its own behind.\n */\nexport function __claimInjectables(): Token[] {\n return slot().splice(0);\n}\n","import type { Container, Token } from \"../container.js\";\n\n/**\n * Which of a container's classes are entry points of each kind.\n *\n * Discovery used to be a DIRECTORY: `jobs/*.ts` was the list of jobs, and\n * `@Job` recorded metadata but registered nothing. That made the file system a\n * second declaration — a class could carry `@Job`, sit outside `jobs/`, and\n * never run; or sit inside it, be listed in no module, and run anyway.\n *\n * Now a module lists it and the decorator says what it is. One declaration\n * answers ownership, and the metadata answers kind. These four predicates are\n * the only place that mapping lives.\n */\nconst JOB = Symbol.for(\"palbase.backend.jobMeta\");\nconst WEBHOOK = Symbol.for(\"palbase.backend.webhookMeta\");\nconst HOOK_BLOCKING = Symbol.for(\"palbase.backend.hookBlocking\");\nconst HOOK_LISTENERS = Symbol.for(\"palbase.backend.webhookEvents\");\nconst ROOM = Symbol.for(\"palbase.backend.room\");\nconst CONTROLLER = Symbol.for(\"palbase.backend.controllerMeta\");\n\nconst has = (c: unknown, s: symbol): boolean =>\n (c as Record<symbol, unknown>)[s] !== undefined;\n\n/**\n * Does this class carry one of the surface decorators?\n *\n * The container asks, because `providers` legitimately holds `@Job`, `@Hook`,\n * `@Webhook` and `@Room` classes alongside `@Injectable()` ones, and the rule it\n * enforces there — a provider must be DECORATED, so it is constructible and its\n * constructor's types were emitted — has to know that. The predicate lives here\n * because this file is the one place the marker symbols are named.\n */\nexport const isEntryPointClass = (c: unknown): boolean =>\n has(c, JOB) || has(c, WEBHOOK) || has(c, ROOM) || has(c, CONTROLLER) ||\n has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS);\n\nconst owned = (container: Container): Token[] => [...container.owned];\n\nexport const jobsOf = (container: Container): Token[] => owned(container).filter((c) => has(c, JOB));\n\nexport const webhooksOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, WEBHOOK));\n\n/**\n * A hook class carries handler entries and NO class-level marker, so it is\n * recognised by having handlers while being neither a webhook nor a controller.\n * `@On` is shared with `@Webhook`, which is why the webhook marker is what\n * separates them.\n */\nexport const hooksOf = (container: Container): Token[] =>\n owned(container).filter(\n (c) =>\n !has(c, WEBHOOK) &&\n !has(c, CONTROLLER) &&\n (has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS)),\n );\n\nexport const roomsOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, ROOM));\n\nexport const controllersOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, CONTROLLER));\n","/**\n * A class the container can resolve, named by its own constructor.\n *\n * There is NO separate token concept — no strings, no symbols, no `@Inject`.\n * An abstraction is an `abstract class`, which is still a runtime value and so\n * is still a token. `never[]` on the parameters makes a token something you can\n * NAME but not call: `Token` is an identity, not a factory.\n */\nexport type Token<T = unknown> = abstract new (...args: never[]) => T;\n\n/**\n * The four lists a module declares.\n *\n * `providers` is OWNERSHIP — a class belongs to exactly one module and this is\n * where that is said. `exports` is VISIBILITY — what other modules may reach.\n * `imports` is PERMISSION — whose exports this module may reach. `controllers`\n * are the entry points the module owns.\n *\n * Position in a list means nothing; ownership is read from this declaration and\n * from nowhere else — not from a directory, not from a file name, not from the\n * class's own decorator (spec FR-009).\n */\nexport interface ModuleDef {\n imports?: Token[];\n controllers?: Token[];\n providers?: Token[];\n exports?: Token[];\n}\n\n/**\n * The slot module declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol, for the same reason\n * `lifecycleHooks` is (runtime.ts:210): a tenant bundle inlines its OWN copy of\n * `@palbase/backend`, and the engine that loads it carries another. Two\n * module-local arrays would mean the engine reads the empty one — decorators\n * push into the bundle's copy, `createApp` claims from the engine's, and every\n * module silently disappears.\n */\nexport const DI_MODULES: unique symbol = Symbol.for(\"palbase.backend.diModules\") as never;\n\n/** One `@Module` declaration: the class that carried it, and what it declared. */\nexport interface ModuleEntry {\n mod: Token;\n def: ModuleDef;\n}\n\nfunction slot(): ModuleEntry[] {\n const g = globalThis as unknown as Record<symbol, ModuleEntry[] | undefined>;\n return (g[DI_MODULES] ??= []);\n}\n\n/**\n * Declares a module.\n *\n * There is no root module and nothing to mount it into: registration IS the\n * decorator running, which happens when the file is imported. A project with no\n * module file at all is not an error — it simply owns nothing, and every entry\n * point it declares is refused by name (FR-035) rather than quietly served.\n */\nexport function Module(def: ModuleDef): ClassDecorator {\n return (target) => {\n slot().push({ mod: target as unknown as Token, def });\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same reason `__runStartHooks` splices (runtime.ts:297): a candidate bundle is\n * imported into the SAME process as the live app it might replace. Reading\n * would let the candidate build a container out of the live app's modules, and\n * a discarded candidate would leave its own behind for the next release to\n * adopt. Claiming makes each `createApp` see exactly the modules imported since\n * the last one, and a rollback leave nothing behind.\n */\nexport function __claimModules(): ModuleEntry[] {\n return slot().splice(0);\n}\n","import \"reflect-metadata\";\n\nimport { DECLARATION_REFUSAL } from \"./refusals.js\";\n\nimport { __claimInjectables, isInjectable } from \"./decorators/injectable.js\";\nimport { isEntryPointClass } from \"./decorators/kinds.js\";\nimport { __claimModules, type ModuleDef, type Token } from \"./decorators/module.js\";\n\n/**\n * `Token` is born in `decorators/module.ts` — the atom of a module's lists — and\n * re-exported here so a reader meets it on the container's surface too. ONE\n * definition: two would be two `abstract new (...)` signatures free to drift.\n */\nexport type { Token };\n\n/**\n * How a container refuses.\n *\n * Every refusal is one of these, and every one names the class involved. There\n * is deliberately no \"unknown\" member: a failure this list cannot classify is a\n * failure the error surface has not been taught to explain, and that is a defect\n * rather than a category.\n */\nexport type DiKind =\n | \"unresolvable dependency\"\n | \"private dependency\"\n | \"missing import\"\n | \"unowned class\"\n | \"dependency cycle\"\n | \"metadata missing\"\n | \"generic dependency\"\n | \"duplicate ownership\"\n | \"unknown export\"\n | \"unknown import\"\n | \"undeclared provider\";\n\n/**\n * A refusal carries four parts: what kind, the full resolution path, where\n * exactly, and what to do about it.\n *\n * The shape is borrowed on purpose — Angular's path, Awilix's failure kind, and\n * Nest's list of potential solutions — because each of the three answers a\n * question the other two leave open: what broke, where in the graph, and what\n * the author should type next.\n */\nexport class DiError extends Error {\n /**\n * EVERY `DiKind` IS A FACT ABOUT THE AUTHOR'S DECLARATIONS — an unresolvable\n * dependency, a cycle, a class no module owns. Not one of them is something\n * the environment could change, so restarting re-reads the same bytes and\n * fails identically. The cure is a new artifact, and the tag is how the\n * runtime learns that without matching on wording.\n */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(\n readonly kind: DiKind,\n readonly path: string[],\n readonly at: string,\n detail: string,\n readonly fixes: string[],\n ) {\n super(\n `\\nKind: ${kind}\\n` +\n `Path: ${path.length > 0 ? path.join(\" -> \") : \"(none)\"}\\n` +\n `At: ${at}\\n` +\n `${detail}\\n\\n` +\n `Potential solutions:\\n${fixes.map((f) => ` - ${f}`).join(\"\\n\")}\\n`,\n );\n this.name = \"DiError\";\n }\n}\n\n/** How often a module appears in the OTHERS' `imports`. */\nexport interface ModulePressure {\n module: string;\n pct: number;\n /**\n * How many OTHER modules there were — the denominator.\n *\n * Without it the percentage cannot be read. Measured 2026-09-02: a project\n * with two modules, one importing the other, reports 100% — which is true and\n * says nothing, because \"all of the others\" is one module. A reader deciding\n * whether a module has become ambient needs to know whether 80% was four\n * modules or one.\n */\n of: number;\n}\n\nexport interface Container {\n get<T>(t: Token<T>): T;\n /** Every class a module claimed — the set an entry point must be in. */\n readonly owned: ReadonlySet<Token>;\n /**\n * Where `@Global()` pressure is accumulating.\n *\n * A module that appears in more than ~80% of the others' `imports` is one the\n * design is asking to be ambient. That is a JUDGEMENT — how much sharing is\n * too much depends on the domain — so this is reported as a number and never\n * enforced as a gate. Lives on the container rather than in a module-level\n * variable: the runtime builds a candidate's container beside the live app's,\n * and a shared variable would have one overwrite the other's report.\n */\n readonly pressure: readonly ModulePressure[];\n}\n\nconst nameOf = (c: unknown): string => (c as { name?: string } | null)?.name ?? String(c);\n\n/**\n * Values a transpiler emits when a parameter's type has no runtime class.\n *\n * `Object` is the sentinel — an interface, a type alias and a union all collapse\n * to it — and that it is DISTINGUISHABLE from a real class is what lets the\n * container refuse loudly instead of injecting something arbitrary. The\n * primitives are here for the same reason: they are runtime values, so a naive\n * check would happily try to `new` them.\n */\nconst UNRESOLVABLE = new Set<unknown>([\n Object,\n Function,\n String,\n Number,\n Boolean,\n Array,\n Symbol,\n Promise,\n Date,\n undefined,\n null,\n]);\n\n/** The subset worth naming separately: these say \"you passed DATA\" (FR-036). */\nconst DATA = new Set<unknown>([String, Number, Boolean, Date, Symbol]);\n\n/**\n * Does this class SAY what its constructor asks for?\n *\n * The one predicate for the metadata-against-arity cross-check.\n * `assertZeroArgConstructor` calls this rather than re-deriving it: two copies\n * of the rule are two rules, free to drift the moment one is edited.\n */\nexport function declaresDependencies(ctor: unknown): boolean {\n const arity = (ctor as { length?: number } | null)?.length ?? 0;\n if (arity === 0) return true;\n const meta = Reflect.getMetadata(\"design:paramtypes\", ctor as object) as unknown[] | undefined;\n return meta !== undefined && meta.length === arity;\n}\n\n/**\n * Validates the declared modules and returns a container over them.\n *\n * Validation runs in a fixed order, and the order is the point: each stage may\n * assume the previous one held, so a message never has to hedge. Ownership\n * before exports, exports before dependencies, dependencies before cycles,\n * cycles before construction.\n *\n * Stages 3-5 (dependencies and visibility, cycles, resolution) are added by the\n * tasks that follow; this file grows, it is not replaced.\n */\nexport function buildContainer(): Container {\n // CLAIMS the declarations rather than reading them — see `__claimModules`.\n const entries = __claimModules();\n // Claimed HERE even when the graph is about to be refused below, so a failed\n // build cannot leave a previous import's classes for the next one to inherit.\n const declared = __claimInjectables();\n\n // 0 · a project declares at least one module.\n //\n // There is no implicit module. An implicit one would be a SECOND way for a\n // class to become owned, and the whole design rests on there being one: read\n // the module, know the answer.\n if (entries.length === 0) {\n throw new DiError(\n \"unowned class\",\n [],\n \"project\",\n \"no module was declared — every project declares at least one @Module.\",\n [\n \"create `<domain>.module.ts` with @Module({ controllers: [...], providers: [...] })\",\n \"`palbase init` scaffolds one for you\",\n ],\n );\n }\n\n // 1 · ownership — a class belongs to at most one module.\n //\n // `providers` and `controllers` share ONE namespace: a class is owned or it is\n // not, and being listed as both would make \"which module owns it\" a question\n // with two answers.\n const declaredModules = new Set<Token>(entries.map((e) => e.mod));\n\n const owner = new Map<Token, string>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const c of [...(def.providers ?? []), ...(def.controllers ?? [])]) {\n const prev = owner.get(c);\n if (prev !== undefined) {\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(c)],\n `${prev} & ${m}`,\n `${nameOf(c)} is listed by two modules, so which one owns it has two answers.`,\n [\n `remove ${nameOf(c)} from ${prev}`,\n `or remove it from ${m}`,\n `if both modules need it, keep ONE owner and export it, then import that module`,\n ],\n );\n }\n owner.set(c, m);\n }\n }\n\n // 1a · every provider is a class the container can actually BUILD.\n //\n // Measured 02.09.2026: a module that listed an `abstract class` in its\n // `providers` got `new Clock()` — which succeeds in JavaScript and returns an\n // object missing every abstract member — injected into everything that asked\n // for it, and the failure surfaced mid-request as `c.now is not a function`.\n // FR-055 already refuses that shape when the abstraction is named as a\n // DEPENDENCY; this is the same defect coming in through the other door, and\n // the SDK's own test asserted the broken shape was legal.\n //\n // The signal is the decorator. An abstraction in this design is an UNDECORATED\n // `abstract class` (the scaffold's `NoteRepo`), and an implementation carries\n // `@Injectable()`; surfaces carry `@Job`/`@Hook`/`@Webhook`/`@Room`. So a\n // provider carrying none of them is either an abstraction listed in the wrong\n // place or a class somebody forgot to decorate — and the second is not benign\n // either: without a decorator TypeScript emits no `design:paramtypes`, so\n // every constructor parameter it asks for would arrive `undefined`.\n {\n for (const { mod, def } of entries) {\n for (const p of def.providers ?? []) {\n if (isInjectable(p) || isEntryPointClass(p)) continue;\n // A class whose constructor ASKS for something but carries no emitted\n // types is a different fault with a better message — `metadata missing`\n // in stage 3, which explains `emitDecoratorMetadata` and the bundler.\n // Leaving it to that stage keeps each refusal pointed at one cause. The\n // abstract seam this rule is for has a zero-argument constructor\n // (`abstract class NoteRepo { abstract findMany(…) }`), so it lands\n // here.\n if (!declaresDependencies(p)) continue;\n throw new DiError(\n \"undeclared provider\",\n [nameOf(mod), nameOf(p)],\n `${nameOf(mod)}.providers`,\n `${nameOf(p)} is listed in ${nameOf(mod)}.providers but carries no decorator, ` +\n `so the container cannot know it is constructible or what its constructor asks for.`,\n [\n `mark ${nameOf(p)} \\`@Injectable()\\` if it is a concrete class`,\n `if ${nameOf(p)} is an \\`abstract class\\`, list the class that \\`extends\\` it instead — ` +\n `name the abstraction as the DEPENDENCY and the container resolves it`,\n ],\n );\n }\n }\n }\n\n // 1b · every declared class is OWNED by a module (FR-010).\n //\n // `@Injectable()` decides nothing — ownership is read from a module and from\n // nowhere else — but it makes the class COUNTABLE, and this is the question\n // that needs counting: a service written, imported, and listed in no module.\n // It has no entry point, so `assertNoOrphanEntryPoints` never sees it; it has\n // no dependent, so the resolution stages never reach it. It simply does not\n // exist, silently, which is the one outcome this design refuses everywhere\n // else. Measured through the CLI on 2026-09-02: the build said \"build OK\".\n //\n // Not in `isolated()`: that builds a graph without consulting this file at\n // all, deliberately, because a unit test is not a second opinion about the\n // architecture.\n {\n const orphans = declared.filter((c) => !owner.has(c));\n if (orphans.length > 0) {\n const names = orphans.map(nameOf);\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} marked @Injectable() ` +\n `but listed in no module's providers, so nothing can reach ${orphans.length === 1 ? \"it\" : \"them\"}.`,\n [\n `add ${names.length === 1 ? names[0] : \"each of them\"} to a module's \\`providers\\``,\n \"or delete the class — one no module lists is never built\",\n ],\n );\n }\n }\n\n // 2 · exports — a module may only open up what it OWNS.\n //\n // Re-exporting someone else's class would be a hole in the boundary the\n // module system exists to draw: the owner's decision about who may reach it\n // would stop being the owner's.\n const exported = new Map<string, Set<Token>>();\n const importsOf = new Map<string, Set<string>>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const e of def.exports ?? []) {\n if (owner.get(e) !== m) {\n const holder = owner.get(e);\n throw new DiError(\n \"unknown export\",\n [m],\n `${m}.exports`,\n holder === undefined\n ? `${m} exports ${nameOf(e)}, but no module owns it.`\n : `${m} exports ${nameOf(e)}, but ${holder} owns it — a module cannot re-export another's class.`,\n holder === undefined\n ? [`add ${nameOf(e)} to ${m}.providers`, `or remove it from ${m}.exports`]\n : [\n `remove ${nameOf(e)} from ${m}.exports`,\n `and have ${holder} export it instead, then add ${holder} to the importing module's imports`,\n ],\n );\n }\n }\n // An `imports` entry must BE a module. Measured before this check existed:\n // `@Module({ imports: [NotAModule] })` built cleanly and did nothing — the\n // name simply never matched an owner, so every dependency it was meant to\n // unlock kept being refused for a reason that pointed elsewhere.\n for (const i of def.imports ?? []) {\n // Self-import is expressible — legacy decorators run after the class\n // binding exists, so `@Module({ imports: [M] }) class M {}` compiles and\n // ran silently before this check. It grants a module access to its own\n // exports, which it already has, so it is always a typo for another name.\n if (i === mod) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports itself, which grants nothing it does not already have.`,\n [`remove ${m} from its own imports`, \"or name the module you meant instead\"],\n );\n }\n if (!declaredModules.has(i)) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports ${nameOf(i)}, which is not a module.`,\n [\n `add @Module({ ... }) to ${nameOf(i)}`,\n `or remove ${nameOf(i)} from ${m}.imports — to reach a class, import the module that OWNS it`,\n ],\n );\n }\n }\n\n exported.set(m, new Set(def.exports ?? []));\n importsOf.set(m, new Set((def.imports ?? []).map(nameOf)));\n }\n\n // 3 · dependencies — metadata against arity, then type validity, then module\n // visibility. In that order, because each answer makes the next question\n // meaningful.\n const deps = new Map<Token, Token[]>();\n\n /**\n * The owned classes that EXTEND `t`.\n *\n * `abstract` does not exist at runtime — JavaScript happily runs `new Clock()`\n * and returns an object missing every abstract member. Measured before this\n * existed: the container injected exactly that, the build was green, and the\n * failure surfaced mid-request as `c.now is not a function`.\n *\n * So an abstraction is resolved through its implementation, and the\n * relationship is read from the prototype chain — which is what `extends`\n * builds. That is a DECLARATION the class makes about itself, not an\n * inference from where its file sits.\n *\n * Only consulted for a token NOTHING owns. A class that IS owned is the\n * answer to its own name, so an unrelated `extends` elsewhere can never\n * change what an existing dependency resolves to.\n */\n const implementorsOf = (t: Token): Token[] =>\n [...owner.keys()].filter(\n (c) => c !== t && Object.prototype.isPrototypeOf.call(t as object, c as object),\n );\n\n // Is missing metadata GLOBAL or local? Decided BEFORE any per-class message,\n // because the two faults look identical one class at a time and lead to\n // opposite fixes: all of them missing means the build ran without\n // `emitDecoratorMetadata` (or without `reflect-metadata`, whose absence makes\n // the emitted helper a silent no-op); some of them missing means the author\n // forgot `@Injectable()` on those. Telling someone to decorate a class when\n // the flag is off sends them to edit a file that is not the problem.\n //\n // NOT a synthetic canary. An earlier design embedded a probe class in the SDK\n // and asked whether IT carried metadata — but the SDK is built with tsup, and\n // esbuild emits zero `__metadata` (measured), so that probe would report a\n // global fault on every healthy boot. The tenant's OWN classes are the only\n // honest sample of the tenant's build.\n const withArity = [...owner.keys()].filter(\n (c) => (c as unknown as { length: number }).length > 0,\n );\n const missingMeta = withArity.filter(\n (c) => Reflect.getMetadata(\"design:paramtypes\", c) === undefined,\n );\n // TWO is the smallest sample this inference is honest on. With ONE class,\n // \"all of them are missing\" is also what a single forgotten `@Injectable()`\n // looks like, and telling that author their build is broken sends them to the\n // wrong file. Below the threshold the per-class message runs, which names the\n // class and the decorator.\n if (withArity.length >= 2 && missingMeta.length === withArity.length) {\n throw new DiError(\n \"metadata missing\",\n withArity.map(nameOf),\n \"the whole build\",\n `no class carries constructor metadata — every one of the ${withArity.length} ` +\n `class(es) that asks for a dependency is missing it, so this is the build, ` +\n `not the classes.`,\n [\n \"set `emitDecoratorMetadata: true` in the project's tsconfig.json\",\n \"and import `reflect-metadata` before any decorated class evaluates — without it the emitted helper is a silent no-op\",\n \"if the build is fine, then none of these classes carries @Injectable()\",\n ],\n );\n }\n\n for (const [cls, m] of owner) {\n const arity = (cls as unknown as { length: number }).length;\n\n // ARITY IS THE GROUND TRUTH. It survives every transpile; metadata does not.\n // Measured: a decorated class with no constructor carries `undefined`\n // metadata and a decorated one with an empty constructor carries `[]` —\n // both ask for nothing, and only arity says so. Treating absent metadata as\n // a fault would refuse every dependency-free class that never wrote a\n // constructor, which is most of them.\n if (arity === 0) {\n deps.set(cls, []);\n continue;\n }\n\n // Asked through the shared predicate, so \"does this class say what it needs\"\n // has ONE definition — the same one `assertZeroArgConstructor` answers with.\n if (!declaresDependencies(cls)) {\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[] | undefined;\n throw new DiError(\n \"metadata missing\",\n [nameOf(cls)],\n `${nameOf(cls)} constructor`,\n `${nameOf(cls)} declares ${arity} parameter(s) but carries ` +\n `${meta === undefined ? \"no\" : String(meta.length)} metadata entries, ` +\n `so every parameter would arrive as undefined.`,\n [\n `add @Injectable() to ${nameOf(cls)} — metadata is emitted for DECORATED classes only`,\n \"or the build ran without emitDecoratorMetadata: check tsconfig.json\",\n ],\n );\n }\n\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[];\n const list: Token[] = [];\n meta.forEach((t, i) => {\n const at = `${nameOf(cls)} constructor, parameter ${i}`;\n\n if (typeof t !== \"function\" || UNRESOLVABLE.has(t)) {\n throw new DiError(\n \"unresolvable dependency\",\n [nameOf(cls)],\n at,\n `parameter ${i} has no runtime class — an interface, a type alias, a ` +\n `union, or a data type. The container has nothing to construct.`,\n DATA.has(t)\n ? [\n \"an injectable's constructor takes dependencies, not data\",\n \"move the value to a method argument instead\",\n \"or make this a plain value class (no @Injectable, in no module) and `new` it yourself\",\n ]\n : [\n \"depend on a concrete class or an abstract class\",\n \"a TypeScript interface does not exist at runtime — there is nothing to inject\",\n ],\n );\n }\n\n const dep = t as Token;\n\n {\n let dm = owner.get(dep);\n if (dm === undefined) {\n // An ABSTRACTION, resolved to its one implementation (FR-055).\n //\n // Read from `extends`, not from a second syntax: `class SystemClock\n // extends Clock` is the class declaring \"I am a Clock\", and that is a\n // declaration — not an inference from where a file sits.\n const impls = implementorsOf(dep);\n if (impls.length === 1) {\n const impl = impls[0] as Token;\n list.push(impl);\n dm = owner.get(impl) as string;\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} and is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(impl)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} but is internal to ${dm}.`,\n [`add ${nameOf(impl)} to ${dm}.exports (and say why)`],\n );\n }\n }\n return;\n }\n if (impls.length > 1) {\n const names = impls.map(nameOf).sort();\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${names.join(\" and \")} both extend ${nameOf(dep)}, so which one ` +\n `${nameOf(cls)} should receive has two answers.`,\n [\n `keep ONE class extending ${nameOf(dep)} in this graph`,\n `or depend on ${names[0]} or ${names[1]} directly, by name`,\n ],\n );\n }\n throw new DiError(\n \"unowned class\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} belongs to no module, and nothing in this graph extends it — ` +\n `so there is nothing to construct. (An abstract class cannot be built: ` +\n `\\`abstract\\` is a type-level claim, and \\`new\\` on one returns an object ` +\n `missing every abstract member.)`,\n [\n `add ${nameOf(dep)} to a module's providers if it is concrete`,\n `or add a class that \\`extends ${nameOf(dep)}\\` to a module's providers`,\n ],\n );\n }\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(dep)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is internal to ${dm} — it is not exported.`,\n [\n `use one of ${dm}'s exported classes`,\n `or add ${nameOf(dep)} to ${dm}.exports (and say why it should be public)`,\n ],\n );\n }\n }\n }\n\n list.push(dep);\n });\n\n deps.set(cls, list);\n }\n\n // 4 · cycles — refused, with the path written out by name.\n //\n // There is NO `forwardRef`-style escape, and the reason is that the shape one\n // exists to rescue cannot be built: a real ESM cycle dies at import. Measured\n // in the spike — Bun throws `Cannot access 'CB' before initialization` before\n // the container is ever consulted. What CAN still be assembled is a cycle\n // inside one file, so the detector earns its place; what it never has to do is\n // offer a way to keep one.\n const state = new Map<Token, 0 | 1 | 2>();\n const stack: Token[] = [];\n const walk = (c: Token): void => {\n if (state.get(c) === 1) {\n // Slice from where this class first entered the stack, so the message is\n // the CYCLE and not the path that happened to reach it.\n const cyc = [...stack.slice(stack.indexOf(c)), c].map(nameOf);\n throw new DiError(\n \"dependency cycle\",\n cyc,\n `${cyc[0]} constructor`,\n `the dependency graph contains a cycle: ${cyc.join(\" -> \")}.`,\n [\n \"extract the shared part into a third class both can depend on\",\n \"or invert one direction — have the callee raise an event the caller listens for\",\n ],\n );\n }\n if (state.get(c) === 2) return;\n state.set(c, 1);\n stack.push(c);\n // A platform token needs no special case: it has no `deps` entry, so the\n // walk reaches it, finds nothing to follow, and marks it done. A guard here\n // would be an inert check — it was written, measured against a mutation, and\n // removed when removing it changed nothing.\n for (const d of deps.get(c) ?? []) walk(d);\n stack.pop();\n state.set(c, 2);\n };\n for (const c of owner.keys()) walk(c);\n\n // 5 · resolution — ONE lifetime, singleton.\n //\n // No `transient`, no `request`. Request scope already exists and it is an\n // AsyncLocalStorage, not an object lifetime: what varies per request is the\n // database handle and the claims, and the engine opens that scope around the\n // handler. Making the OBJECTS per-request would duplicate that mechanism and\n // then have to keep the two in agreement.\n //\n // The consequence is a rule about constructors: they stay synchronous and do\n // nothing but wiring. Real I/O belongs in `onStart`, where it can fail loudly\n // at boot instead of halfway through the first request.\n const cache = new Map<Token, unknown>();\n const make = (c: Token): unknown => {\n // A token this container never validated is NOT built. Measured before this\n // check existed: `get(Stranger)` found no `deps` entry, fell through to\n // `new Stranger()` with zero arguments, and returned it — so a class in no\n // module could still be constructed through the container's own front door,\n // which is the hole the module system exists to close (FR-053).\n //\n // There is no platform escape hatch here: platform services (Database, Log,\n // …) are AMBIENT — imported, not injected — because they are request-scoped\n // and a boot-time singleton holding one would capture the first request's\n // client forever (FR-005). Nothing supplies a platform map, so having one\n // would be an inert extension point.\n if (!owner.has(c)) {\n throw new DiError(\n \"unowned class\",\n [nameOf(c)],\n \"container.get\",\n `${nameOf(c)} belongs to no module, so this container never validated it ` +\n `and will not build it.`,\n [\n `add ${nameOf(c)} to a module's providers`,\n \"or, if it is a plain value class, construct it yourself with `new`\",\n ],\n );\n }\n const hit = cache.get(c);\n if (hit !== undefined) return hit;\n const args = (deps.get(c) ?? []).map(make);\n const inst = new (c as unknown as new (...a: unknown[]) => unknown)(...args);\n cache.set(c, inst);\n return inst;\n };\n\n return {\n get: <T,>(t: Token<T>): T => make(t) as T,\n owned: new Set(owner.keys()),\n pressure: computePressure(entries),\n };\n}\n\n/**\n * What fraction of the OTHER modules import each module.\n *\n * `total - 1` is the denominator because a module never imports itself, so the\n * most any module can reach is everyone else. Under two modules there is nothing\n * to compare and the answer is an empty list rather than a misleading 100%.\n */\nfunction computePressure(entries: { mod: Token; def: ModuleDef }[]): ModulePressure[] {\n // No `total < 2` guard, and none is needed: a single module cannot import\n // anything (there is no other module, and both self-import and non-module\n // imports are refused above), so `count` is empty and the division below never\n // runs. The guard was written, measured against a mutation, and removed when\n // removing it changed nothing — an inert check still draws a number.\n const total = entries.length;\n const count = new Map<string, number>();\n for (const { def } of entries) {\n for (const i of def.imports ?? []) {\n const n = nameOf(i);\n count.set(n, (count.get(n) ?? 0) + 1);\n }\n }\n return [...count]\n .map(([module, c]) => ({ module, pct: Math.round((c / (total - 1)) * 100), of: total - 1 }))\n .sort((a, b) => b.pct - a.pct);\n}\n\n/** Kept so the module surface is stable while stages 3-5 land. */\nexport type { ModuleDef };\n\n/**\n * Refuses an entry point that no module lists (FR-035).\n *\n * A decorated class registers itself — `@Controller` pushes into a globalThis\n * slot the moment its file is imported — so before this check a class listed in\n * no module still reached the route table, the dispatcher and the OpenAPI\n * document. It worked, which is the problem: nothing said the module system had\n * been bypassed.\n *\n * After this, a successful boot means the two sets are EQUAL: what decorated\n * itself and what a module claimed. That equality is what lets `src/openapi/`\n * stay untouched — it renders the list it is handed, and the list is now the\n * module's.\n */\nexport function assertNoOrphanEntryPoints(\n registered: readonly unknown[],\n owned: ReadonlySet<Token>,\n): void {\n const orphans = registered.filter((c) => !owned.has(c as Token));\n if (orphans.length === 0) return;\n const names = orphans.map((c) => (c as { name?: string }).name ?? \"<anonymous>\");\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} decorated as an entry ` +\n `point but listed in no module, so nothing decides whether it should be served.`,\n [\n \"add it to a module's `controllers` (for @Controller) or `providers` (for @Room/@Job/@Hook/@Webhook)\",\n \"an entry point no module lists is never mounted and never reaches the OpenAPI document\",\n ],\n );\n}\n","/** Non-service, per-invocation data for job handlers.\n * Services (Database, Log, …) are imported as singletons, not passed here. */\nexport interface JobMeta {\n /** Environment-scoped env vars. */\n env: Record<string, string>;\n /** The globally unique Environment runtime identifier. */\n environmentId: string;\n}\n\n/**\n * Cron expression validation.\n * Supports standard 5-field cron: minute hour day-of-month month day-of-week.\n * Each field allows: number, *, ranges (1-5), steps (star/2), lists (1,3,5).\n */\nexport function validateCronExpression(expression: string): string | null {\n const trimmed = expression.trim();\n if (trimmed === \"\") {\n return \"Cron expression is required\";\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5) {\n return `Invalid cron expression \"${trimmed}\": expected 5 fields (minute hour day month weekday), got ${parts.length}`;\n }\n\n const fieldNames = [\"minute\", \"hour\", \"day of month\", \"month\", \"day of week\"];\n const fieldRanges: [number, number][] = [\n [0, 59],\n [0, 23],\n [1, 31],\n [1, 12],\n [0, 7],\n ];\n\n for (let i = 0; i < 5; i++) {\n const field = parts[i]!;\n const name = fieldNames[i]!;\n const [min, max] = fieldRanges[i]!;\n\n const error = validateCronField(field, name, min, max);\n if (error !== null) {\n return error;\n }\n }\n\n return null;\n}\n\nfunction validateCronField(\n field: string,\n name: string,\n min: number,\n max: number,\n): string | null {\n // Split by comma for lists\n const listParts = field.split(\",\");\n for (const part of listParts) {\n // Check for step: */2, 1-5/2\n const stepParts = part.split(\"/\");\n if (stepParts.length > 2) {\n return `Invalid ${name} field: \"${field}\"`;\n }\n\n const base = stepParts[0]!;\n const step = stepParts[1];\n\n if (step !== undefined) {\n const stepNum = Number(step);\n if (!Number.isInteger(stepNum) || stepNum < 1) {\n return `Invalid step value in ${name} field: \"${field}\"`;\n }\n }\n\n if (base === \"*\") {\n continue;\n }\n\n // Check for range: 1-5\n if (base.includes(\"-\")) {\n const rangeParts = base.split(\"-\");\n if (rangeParts.length !== 2) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n const rangeStart = Number(rangeParts[0]);\n const rangeEnd = Number(rangeParts[1]);\n if (\n !Number.isInteger(rangeStart) ||\n !Number.isInteger(rangeEnd) ||\n rangeStart < min ||\n rangeEnd > max ||\n rangeStart > rangeEnd\n ) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n continue;\n }\n\n // Single number\n const num = Number(base);\n if (!Number.isInteger(num) || num < min || num > max) {\n return `Invalid value in ${name} field: \"${field}\"`;\n }\n }\n\n return null;\n}\n","// @Job — the cron half of the decorator surface. Same metadata mechanism as\n// @Webhook/@Controller. The job's NAME is not here on purpose: it is the file\n// name, which is also what the Temporal schedule id is built from. Two names\n// with nothing reconciling them is what this replaces.\nimport type { JobMeta } from \"../job.js\";\nimport { validateCronExpression } from \"../job.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\nexport interface JobOptions {\n /**\n * The job's identity, and the name the scheduler holds its rows under.\n *\n * DECLARED, not derived. It used to be the file's name, which made the\n * identity a property of where the class sat — rename the file and the\n * scheduler starts a different job. Ownership and identity both come from a\n * declaration now, and this is where a reader looks for it.\n *\n * Lowercase, digits and dashes: it reaches a scheduler row and a log line.\n */\n name: string;\n /** Cron expression, five fields (e.g. \"0 3 * * *\"). */\n schedule: string;\n /** Execution timeout in seconds. Defaults to 30, ceiling 300 (sandbox limit). */\n timeout?: number;\n /**\n * How many times a FAILED run is retried before the run is recorded failed.\n * Defaults to 5, ceiling 10; 0 disables retrying entirely.\n *\n * Retries exist for the transient half of the failure space — the runtime\n * still waking, a network blip — not for a job that is wrong. A permanent\n * failure still lands in the run history, it just lands after the retries\n * are spent rather than instead of them.\n */\n retry?: number;\n}\n\nexport interface ResolvedJob {\n /** The declared identity — the scheduler's row name. */\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n handler: (meta: JobMeta) => Promise<void>;\n}\n\nconst DEFAULT_TIMEOUT_SECONDS = 30;\nconst MAX_TIMEOUT_SECONDS = 300;\nconst DEFAULT_RETRY = 5;\nconst MAX_RETRY = 10;\n\nexport const JOB_META: unique symbol = Symbol.for(\"palbase.backend.jobMeta\");\n\ninterface JobCarrier {\n __palbase?: \"job\";\n [JOB_META]?: JobOptions;\n}\n\nexport function Job(options: JobOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = ctor as unknown as JobCarrier;\n Object.defineProperty(carrier, JOB_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"job\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/**\n * What a job DECLARES — schedule, timeout, retry. Reads metadata and nothing\n * else: the class is NOT constructed.\n *\n * Deploy's manifest script needs exactly this and no instance (stack_bundle.go\n * writes `jobs.manifest.json` from it, with no runtime and therefore no\n * container). Constructing a class to read a cron string was a side effect, and\n * it is the side effect that made the container look optional — which in turn\n * let a caller that never passes one compile quietly.\n */\nexport interface JobManifest {\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n}\n\nexport function getJobManifest(ctor: object): JobManifest {\n const meta = (ctor as JobCarrier)[JOB_META];\n if (!meta) {\n throw new Error(\n `getJobConfig on a class with no @Job decorator (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Job\", \"job\");\n if (!meta.schedule || meta.schedule.trim() === \"\") {\n throw new Error(\"@Job requires a `schedule` cron expression\");\n }\n const cronError = validateCronExpression(meta.schedule);\n if (cronError) {\n throw new Error(`@Job has an invalid cron schedule: ${cronError}`);\n }\n\n const timeout = meta.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n if (!Number.isInteger(timeout) || timeout <= 0) {\n throw new Error(\"@Job `timeout` must be a positive whole number of seconds\");\n }\n if (timeout > MAX_TIMEOUT_SECONDS) {\n throw new Error(`@Job \\`timeout\\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);\n }\n\n const retry = meta.retry ?? DEFAULT_RETRY;\n if (!Number.isInteger(retry) || retry < 0) {\n throw new Error(\"@Job `retry` must be a whole number of attempts, zero or more\");\n }\n if (retry > MAX_RETRY) {\n throw new Error(`@Job \\`retry\\` exceeds the ceiling of ${MAX_RETRY}`);\n }\n\n return { name: meta.name, schedule: meta.schedule, timeout, retry };\n}\n\n/**\n * The job, ready to run — manifest plus a bound `run`.\n *\n * `container` is REQUIRED. It used to be absent (the class was built with\n * `new`), and then briefly optional, which is worse: an optional parameter lets\n * a caller that forgot it compile, and the job would receive `undefined` for\n * every dependency at its first scheduled run, hours after deploy, in a process\n * nobody is watching. Required makes the two runtime call sites a TYPE error.\n */\nexport function getJobConfig(ctor: object, container: Container): ResolvedJob {\n const { name, schedule, timeout, retry } = getJobManifest(ctor);\n\n const instance = container.get(ctor as never) as { run?: (meta: JobMeta) => Promise<void> };\n if (typeof instance.run !== \"function\") {\n throw new Error(\"@Job class must declare an async run() method\");\n }\n const run = instance.run.bind(instance);\n\n return { name, schedule, timeout, retry, handler: run };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAsBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACqBA,8BAAkC;;;ACElC,IAAMC,YAAYC,uBAAOC,IAAI,gBAAA;AAGtB,SAASC,SAA2BC,GAAMC,MAA2B;AAC1EC,SAAOC,eAAeH,GAAGJ,WAAW;IAAEQ,OAAOH;IAAMI,YAAY;EAAM,CAAA;AACrE,SAAOL;AACT;AAHgBD;AAKhB,SAASO,QAAQN,GAAU;AACzB,MAAI,OAAOA,MAAM,YAAYA,MAAM,KAAM,QAAOO;AAMhD,SAAOL,OAAOM,OAAOR,GAAGJ,SAAAA,IAAcI,EAA8BJ,SAAAA,IAAaW;AACnF;AARSD;AA2CF,SAASG,SAASC,GAAU;AACjC,SAAOC,QAAQD,CAAAA,MAAO,SAAS,OAAQA,EAAyBE,SAAS;AAC3E;AAFgBH;AAyCT,SAASI,cAAcC,GAAU;AACtC,MAAIC,QAAQD,CAAAA,MAAO,MAAO,QAAO;AACjC,QAAME,IAAKF,EAAsDG;AACjE,SAAOD,MAAME,UAAaC,MAAMC,QAAQJ,EAAEK,IAAI,KAAKF,MAAMC,QAAQJ,EAAEM,MAAM;AAC3E;AAJgBT;AAoBhB,IAAMU,UAAUC,uBAAOC,IAAI,iBAAA;AAcpB,SAASC,UAAUZ,GAAU;AAClC,MAAI,CAACa,aAAab,CAAAA,EAAI,QAAO;AAC7B,MAAI;AACF,UAAMc,IAAKd,EAA8BS,OAAAA;AACzC,WAAO,OAAOK,MAAM,YAAYA,MAAM,QAASA,EAAuBC,OAAO;EAC/E,QAAQ;AACN,WAAO;EACT;AACF;AARgBH;AAUT,SAASC,aAAab,GAAU;AACrC,MAAI,OAAOA,MAAM,YAAY,OAAOA,MAAM,WAAY,QAAO;AAC7D,MAAIA,MAAM,KAAM,QAAO;AACvB,MAAI;AACF,WAAQA,EAA8BS,OAAAA,MAAaL;EACrD,QAAQ;AAEN,WAAO;EACT;AACF;AATgBS;;;AC1FT,IAAMG,aAAN,cAAyBC,MAAAA;EA3FhC,OA2FgCA;;;EAC9B,YAAYC,SAAiB;AAC3B,UAAMA,OAAAA;AACN,SAAKC,OAAO;EACd;AACF;AAOO,IAAMC,cAAN,cAA0BH,MAAAA;EAvGjC,OAuGiCA;;;EAC/B,YAAYC,SAAiB;AAC3B,UAAMA,OAAAA;AACN,SAAKC,OAAO;EACd;AACF;AAoWA,IAAME,OAAOC,uBAAOC,IAAI,iBAAA;AACxB,IAAMC,MAAMF,uBAAOC,IAAI,gBAAA;AACvB,IAAME,MAAMH,uBAAOC,IAAI,gBAAA;AACvB,IAAMG,OAAOJ,uBAAOC,IAAI,iBAAA;AAWxB,IAAMI,gBAA8C;EAClD;EACA;EACA;EACA;EACAL,OAAOM;;AAGT,SAASC,KAAKC,MAAuBC,MAAcC,MAAY;AAC7D,QAAMb,OAAO,OAAOW,SAAS,WAAWA,KAAKG,eAAeC,OAAOJ,IAAAA,IAAQA;AAC3E,QAAM,IAAId,WACR,GAAGe,IAAAA,+BAAmCZ,IAAAA,qFACmBa,IAAAA,EAAM;AAEnE;AANSH;AASF,SAASM,MAAAA;AACd,SAAOC,SAAS;IAAEC,IAAI;EAAM,CAAA;AAC9B;AAFgBF;AAKT,SAASG,UAAUC,IAAmB;AAC3CC,eAAaD,IAAI,WAAA;AACjB,SAAOH,SAAS;IAAEC,IAAI;IAAOE;EAAG,CAAA;AAClC;AAHgBD;AAUT,IAAMG,MAAMH;AAGZ,SAASI,UAAUH,IAAmB;AAC3CC,eAAaD,IAAI,WAAA;AACjB,SAAOH,SAAS;IAAEC,IAAI;IAAOE;EAAG,CAAA;AAClC;AAHgBG;AAUT,IAAMC,MAAMD;AAUnB,SAASF,aAAaD,IAAqBF,IAAU;AACnD,MAAI,OAAOE,OAAO,UAAU;AAG1B,QAAI,CAAC,kBAAkBK,KAAKL,EAAAA,GAAK;AAC/B,YAAM,IAAInB,YACR,GAAGiB,EAAAA,kDAA0CE,EAAAA,gEAAqD;IAEtG;EACF,WAAW,OAAOA,OAAO,YAAY,CAACM,OAAOC,SAASP,EAAAA,GAAK;AAGzD,UAAM,IAAInB,YAAY,GAAGiB,EAAAA,iCAAmCH,OAAOK,EAAAA,CAAAA,EAAK;EAC1E;AAOA,QAAMQ,WAAW,OAAOR,OAAO,WAAWA,GAAGS,UAAS,EAAGC,WAAW,GAAA,IAAOV,KAAK;AAChF,MAAIQ,UAAU;AACZ,UAAMG,QAAQb,OAAO,cAAc,cAAc;AACjD,UAAM,IAAIjB,YACR,GAAGiB,EAAAA,6BAA+BH,OAAOK,EAAAA,CAAAA,2BAAwBW,KAAAA,mIACc;EAEnF;AACF;AA5BSV;AAwCT,SAASW,SAASC,MAAyB;AACzC,SAAO,IAAIC,MACT;IAAE,CAACC,IAAAA,GAAOF;EAAK,GACf;IACEG,IAAIC,QAAQC,MAAI;AACd,UAAIA,SAASH,KAAM,QAAOE,OAAOF,IAAAA;AACjC,UAAII,cAAcC,SAASF,IAAAA,GAAO;AAChCG,aAAKH,MAAM,qBAAqB,qCAAA;MAClC;AACA,aAAOI;IACT;EACF,CAAA;AAEJ;AAbSV;AAmBT,SAASW,QAAQC,IAAYC,OAAa;AACxC,QAAMR,SAA2C;IAAE,CAACS,GAAAA,GAAM;MAAEF;MAAIC;IAAM;EAA0B;AAChG,SAAO,IAAIX,MAAMG,QAAQ;IACvBD,IAAIW,GAAGT,MAAI;AACT,UAAIA,SAASQ,IAAK,QAAOC,EAAED,GAAAA;AAC3B,UAAIP,cAAcC,SAASF,IAAAA,GAAO;AAChCG,aACEH,MACA,KAAKO,KAAAA,oDACL,2HACE;MAEN;AACA,aAAOH;IACT;EACF,CAAA;AACF;AAhBSC;AAkBT,SAASK,cAAcJ,IAAU;AAC/B,QAAMP,SAA2C;IAAE,CAACY,GAAAA,GAAML;EAAG;AAC7D,SAAO,IAAIV,MAAMG,QAAQ;IACvBD,IAAIW,GAAGT,MAAI;AACT,UAAIA,SAASW,IAAK,QAAOF,EAAEE,GAAAA;AAC3B,UAAIV,cAAcC,SAASF,IAAAA,GAAO;AAChCG,aACEH,MACA,8CACA,0HACE;MAEN;AACA,UAAI,OAAOA,SAAS,SAAU,QAAOI;AACrC,aAAOC,QAAQC,IAAIN,IAAAA;IACrB;EACF,CAAA;AACF;AAjBSU;AAmBT,SAASE,cAAcC,GAAU;AAC/B,MAAI,OAAOA,MAAM,YAAYA,MAAM,KAAM,QAAO;AAChD,QAAMC,IAAKD,EAA8BL,GAAAA;AACzC,SAAOO,gBAAgBD,CAAAA,IAAKA,IAAI;AAClC;AAJSF;AAMT,SAASG,gBAAgBD,GAAU;AACjC,SACE,OAAOA,MAAM,YACbA,MAAM,QACN,OAAQA,EAAoBR,OAAO,YACnC,OAAQQ,EAAoBP,UAAU;AAE1C;AAPSQ;AAST,SAASC,WAAWH,GAAU;AAC5B,MAAI,OAAOA,MAAM,YAAYA,MAAM,KAAM,QAAO;AAChD,QAAMP,KAAMO,EAA8BF,GAAAA;AAC1C,SAAO,OAAOL,OAAO,WAAWA,KAAK;AACvC;AAJSU;AAMT,SAASC,OAAOJ,GAAU;AACxB,MAAI,OAAOA,MAAM,YAAYA,MAAM,KAAM,QAAO;AAChD,QAAMK,IAAKL,EAA8BhB,IAAAA;AACzC,SAAO,OAAOqB,MAAM,YAAYA,MAAM,OAAQA,IAA4B;AAC5E;AAJSD;AAMT,SAASE,aAAaN,GAAU;AAC9B,SAAO,OAAOA,MAAM,YAAYA,MAAM,QAASA,EAA8BO,IAAAA,MAAUhB;AACzF;AAFSe;AAkBT,SAASE,YAAYC,OAAgBC,QAAgBC,iBAAwB;AAC3E,QAAMC,MAAMb,cAAcU,KAAAA;AAC1B,MAAIG,IAAK,QAAOC,SAAS;IAAEC,MAAM;MAAErB,IAAImB,IAAInB;MAAIC,OAAOkB,IAAIlB;IAAM;EAAE,GAAG,KAAA;AAKrE,MAAIqB,UAAUN,KAAAA,EAAQ,QAAO;IAAEO,OAAO;MAAEC,IAAI;IAAM;EAAE;AACpD,QAAMnC,OAAOsB,OAAOK,KAAAA;AACpB,MAAI3B,MAAM;AACR,QAAIA,KAAKmC,OAAO,SAAS,CAACN,iBAAiB;AACzC,YAAM,IAAIO,YACR,KAAKR,MAAAA,OAAa5B,KAAKmC,EAAE,sFACiB;IAE9C;AACA,WAAO;MAAED,OAAOlC;IAAK;EACvB;AAEA,MAAIqB,WAAWM,KAAAA,MAAW,MAAM;AAC9B,UAAM,IAAIS,YACR,KAAKR,MAAAA,+EACiB;EAE1B;AACA,MAAIJ,aAAaG,KAAAA,GAAQ;AACvB,UAAM,IAAIS,YACR,KAAKR,MAAAA,4HAC0D;EAEnE;AAEAS,wBAAsBV,OAAOC,MAAAA;AAC7B,SAAOD;AACT;AAlCSD;AAuDT,SAASY,kBAAkBX,OAAgBC,QAAc;AACvD,QAAME,MAAMb,cAAcU,KAAAA;AAC1B,MAAIG,IAAK,QAAOC,SAAS;IAAEC,MAAM;MAAErB,IAAImB,IAAInB;MAAIC,OAAOkB,IAAIlB;IAAM;EAAE,GAAG,KAAA;AAErE,QAAMZ,OAAOsB,OAAOK,KAAAA;AACpB,MAAI3B,MAAM;AACR,UAAM,IAAIoC,YACR,KAAKR,MAAAA,OAAa5B,KAAKmC,EAAE,uLACmD;EAEhF;AACA,MAAId,WAAWM,KAAAA,MAAW,MAAM;AAC9B,UAAM,IAAIS,YACR,KAAKR,MAAAA,+EAAqF;EAE9F;AACA,MAAIJ,aAAaG,KAAAA,GAAQ;AACvB,UAAM,IAAIS,YACR,KAAKR,MAAAA,4HAC0D;EAEnE;AACA,MAAIW,MAAMC,QAAQb,KAAAA,EAAQ,QAAOA,MAAMc,IAAI,CAACvB,MAAMoB,kBAAkBpB,GAAGU,MAAAA,CAAAA;AAGvE,MAAID,UAAU,QAAQ,OAAOA,UAAU,YAAY,EAAEA,iBAAiBe,SAAS,CAACC,SAAShB,KAAAA,KAAU,CAACiB,cAAcjB,KAAAA,GAAQ;AACxH,UAAMkB,MAA+B,CAAC;AACtC,eAAW,CAACC,GAAG5B,CAAAA,KAAM6B,OAAOC,QAAQrB,KAAAA,GAAmC;AACrEkB,UAAIC,CAAAA,IAAKR,kBAAkBpB,GAAGU,MAAAA;IAChC;AACA,WAAOiB;EACT;AACA,SAAOlB;AACT;AAjCSW;AAoCT,SAASW,gBAAgBR,KAA4B;AACnD,QAAMI,MAAmC,CAAC;AAC1C,aAAWK,OAAOH,OAAOI,KAAKV,GAAAA,EAAKW,KAAI,GAAI;AACzC,UAAMzB,QAAQc,IAAIS,GAAAA;AAClB,QAAIvB,UAAUlB,OAAW;AACzBoC,QAAIK,GAAAA,IAAOZ,kBAAkBX,OAAOuB,GAAAA;EACtC;AACA,SAAOL;AACT;AARSI;AAUT,SAASZ,sBAAsBV,OAAgBC,QAAc;AAC3D,MAAI,OAAOD,UAAU,YAAYA,UAAU,KAAM;AACjD,MAAIA,iBAAiBe,KAAM;AAC3B,MAAIzB,cAAcU,KAAAA,KAAUL,OAAOK,KAAAA,KAAUN,WAAWM,KAAAA,MAAW,QAAQH,aAAaG,KAAAA,GAAQ;AAC9F,UAAM,IAAIS,YACR,KAAKR,MAAAA,kJAEU;EAEnB;AACA,MAAIW,MAAMC,QAAQb,KAAAA,GAAQ;AACxB,eAAW0B,QAAQ1B,MAAOU,uBAAsBgB,MAAMzB,MAAAA;AACtD;EACF;AACA,aAAWyB,QAAQN,OAAOO,OAAO3B,KAAAA,GAAmC;AAClEU,0BAAsBgB,MAAMzB,MAAAA;EAC9B;AACF;AAjBSS;AA2BT,SAASkB,UACPd,KACAZ,iBAAwB;AAExB,QAAMgB,MAAmC,CAAC;AAC1C,aAAWK,OAAOH,OAAOI,KAAKV,GAAAA,EAAKW,KAAI,GAAI;AACzC,UAAMzB,QAAQc,IAAIS,GAAAA;AAalB,QAAIvB,UAAUlB,QAAW;AACvB,YAAM,IAAI2B,YACR,GAAGc,GAAAA,mYAIgC;IAEvC;AACAL,QAAIK,GAAAA,IAAOxB,YAAYC,OAAOuB,KAAKrB,eAAAA;EACrC;AACA,SAAOgB;AACT;AA/BSU;AAwCT,IAAMC,aAAa;AAEnB,IAAMC,aAAN,MAAMA,YAAAA;EA50BN,OA40BMA;;;;;;;EAEK,CAAChC,IAAAA,IAAQ;EAIViC,UAAU;EAElB,YACmBC,SACAC,SACAC,MACjB;SAHiBF,UAAAA;SACAC,UAAAA;SACAC,OAAAA;EAChB;;;EAIHC,OAAc;AACZ,UAAM,IAAIC,WACR,GAAG,KAAKF,IAAI,6GACsC;EAEtD;EAEAG,UAAUC,OAA0B;AAClC,SAAKC,aAAa,OAAO,GAAGD,KAAAA;AAC5B,QAAI,KAAKL,YAAYJ,WAAY,OAAMS;AACvC,WAAOlD,cAAc,KAAK6C,OAAO;EACnC;EAEAO,WAAWF,OAAoB;AAC7B,SAAKC,aAAa,QAAQ,GAAGD,KAAAA;EAC/B;EAEAG,cAAcC,GAAWJ,OAAoB;AAC3CK,qBAAiBD,GAAG,eAAA;AACpB,SAAKH,aAAa,WAAWG,GAAGJ,KAAAA;AAChC,QAAI,KAAKL,YAAYJ,cAAca,IAAI,EAAG,OAAMJ;EAClD;EAEAM,aAAaF,GAAWJ,OAAoB;AAC1CK,qBAAiBD,GAAG,cAAA;AACpB,SAAKH,aAAa,UAAUG,GAAGJ,KAAAA;EACjC;EAEQC,aAAaM,MAA2BH,GAAWJ,OAAoB;AAC7E,QAAI,EAAEA,iBAAiBQ,QAAQ;AAG7B,YAAM,IAAIrC,YACR,GAAG,KAAKyB,IAAI,6HACmD;IAEnE;AACA,QAAI,KAAKH,SAAS;AAChB,YAAM,IAAItB,YACR,GAAG,KAAKyB,IAAI,kHACiD;IAEjE;AACA,SAAKH,UAAU;AACf,QAAI,KAAKE,YAAYJ,WAAY;AACjC,SAAKG,QAAQe,YAAY,KAAKd,SAASY,MAAMH,GAAGJ,KAAAA;EAClD;AACF;AAEA,SAASK,iBAAiBD,GAAWlC,IAAU;AAC7C,MAAI,CAACwC,OAAOC,UAAUP,CAAAA,KAAMA,IAAI,GAAG;AACjC,UAAM,IAAIjC,YAAY,GAAGD,EAAAA,yCAA2C0C,OAAOR,CAAAA,CAAAA,EAAI;EACjF;AACF;AAJSC;AAQT,IAAMQ,UAAU;AAChB,IAAMC,WAAW;AAQV,IAAMC,gBAAN,MAAMA;EA95Bb,OA85BaA;;;EACMC,MAAkB,CAAA;;EAElBC,QAAiB,CAAA;;;EAIlCC,MAAMC,MAAyE;AAC7E,WAAO;MACLC,QAAQ,wBAAC/B,WAAAA;AACP,cAAMgC,UAAU/B,UAAUD,QAAmC,KAAA;AAC7D,YAAIP,OAAOI,KAAKmC,OAAAA,EAASC,WAAW,GAAG;AACrC,gBAAM,IAAInD,YAAY,GAAGgD,IAAAA,qCAAyC;QACpE;AACA,eAAO,KAAKI,KAAK;UAAE7E,IAAI;UAAUwE,OAAOC;UAAM9B,QAAQgC;QAAQ,GAAG,GAAGF,IAAAA,WAAe;MACrF,GANQ;MAQRK,KAAK,wBAACnC,QAAQoC,YAAAA;AACZ,cAAMJ,UAAU/B,UAAUD,QAAmC,KAAA;AAC7D,YAAIP,OAAOI,KAAKmC,OAAAA,EAASC,WAAW,GAAG;AACrC,gBAAM,IAAInD,YAAY,GAAGgD,IAAAA,kCAAsC;QACjE;AACA,YAAIM,QAAQC,WAAWJ,WAAW,GAAG;AACnC,gBAAM,IAAInD,YAAY,GAAGgD,IAAAA,6CAAiD;QAC5E;AACA,eAAO,KAAKI,KACV;UAAE7E,IAAI;UAAUwE,OAAOC;UAAM9B,QAAQgC;UAASK,YAAYD,QAAQC;QAAW,GAC7E,GAAGP,IAAAA,WAAe;MAEtB,GAZK;MAcLQ,YAAY,wBAACC,MAAMC,SAAAA;AACjB,YAAID,KAAKN,WAAW,GAAG;AAIrB,iBAAO,IAAI9B,WAAW,MAAMD,YAAY,GAAG4B,IAAAA,eAAmB;QAChE;AACA,YAAIS,KAAKN,SAASR,UAAU;AAC1B,gBAAM,IAAI3C,YACR,GAAGgD,IAAAA,qBAAyBS,KAAKN,MAAM,uBAAuBR,QAAAA,oCAC1B;QAExC;AACA,cAAMO,UAAUO,KAAKpD,IAAI,CAACsD,QAAQxC,UAAUwC,KAAgC,KAAA,CAAA;AAC5EC,0BAAkBV,SAASF,IAAAA;AAC3B,YAAIU,SAASrF,UAAaqF,KAAKH,WAAWJ,WAAW,GAAG;AACtD,gBAAM,IAAInD,YACR,GAAGgD,IAAAA,8HACgE;QAEvE;AACA,eAAO,KAAKI,KACV;UACE7E,IAAI;UACJwE,OAAOC;UACPS,MAAMP;;;;UAIN,GAAIQ,SAASrF,SACT;YAAEkF,YAAYG,KAAKH;YAAYM,QAAQH,KAAKG,UAAU;UAAS,IAC/D,CAAC;QACP,GACA,GAAGb,IAAAA,eAAmB;MAE1B,GAnCY;MAqCZc,aAAa,wBAACC,OAAOC,QAAAA;AACnB,cAAMC,eAAepD,gBAAgBkD,KAAAA;AACrC,cAAMG,aAAa/C,UAAU6C,KAAgC,IAAA;AAC7D,YAAIrD,OAAOI,KAAKkD,YAAAA,EAAcd,WAAW,GAAG;AAC1C,gBAAM,IAAInD,YACR,GAAGgD,IAAAA,mFAC0B;QAEjC;AACA,YAAIrC,OAAOI,KAAKmD,UAAAA,EAAYf,WAAW,GAAG;AACxC,gBAAM,IAAInD,YAAY,GAAGgD,IAAAA,iDAAqD;QAChF;AACA,eAAO,KAAKI,KACV;UAAE7E,IAAI;UAAUwE,OAAOC;UAAMgB,KAAKE;UAAYH,OAAOE;QAAa,GAClE,GAAGjB,IAAAA,gBAAoB;MAE3B,GAhBa;MAkBbmB,aAAa,wBAACJ,UAAAA;AACZ,cAAME,eAAepD,gBAAgBkD,KAAAA;AACrC,YAAIpD,OAAOI,KAAKkD,YAAAA,EAAcd,WAAW,GAAG;AAC1C,gBAAM,IAAInD,YACR,GAAGgD,IAAAA,2EACW;QAElB;AACA,eAAO,KAAKI,KACV;UAAE7E,IAAI;UAAUwE,OAAOC;UAAMe,OAAOE;QAAa,GACjD,GAAGjB,IAAAA,gBAAoB;MAE3B,GAZa;MAcboB,QAAQ,wBAACL,OAAOT,YAAAA;AACd,cAAM/E,KAAe;UAAEA,IAAI;UAAUwE,OAAOC;QAAK;AACjD,cAAMiB,eAAepD,gBAAiBkD,SAAS,CAAC,CAAA;AAChD,YAAIpD,OAAOI,KAAKkD,YAAAA,EAAcd,SAAS,EAAG5E,IAAGwF,QAAQE;AACrD,YAAIX,SAASe,UAAUhG,QAAW;AAChC,cAAI,CAACkE,OAAOC,UAAUc,QAAQe,KAAK,KAAKf,QAAQe,QAAQ,GAAG;AACzD,kBAAM,IAAIrE,YACR,GAAGgD,IAAAA,sDAA0DP,OAAOa,QAAQe,KAAK,CAAA,EAAG;UAExF;AACA9F,aAAG8F,QAAQf,QAAQe;QACrB;AACA,YAAIf,SAASgB,SAASjG,OAAWE,IAAG+F,OAAOhB,QAAQgB;AACnD,eAAO,KAAKlB,KAAK7E,IAAI,GAAGyE,IAAAA,WAAe;MACzC,GAdQ;IAeV;EACF;EAEQI,KAAK7E,IAAckD,MAA+C;AACxE,QAAI,KAAKoB,IAAIM,UAAUT,SAAS;AAC9B,YAAM,IAAI1C,YACR,wBAAwB0C,OAAAA,uGAC4C;IAExE;AACA,UAAM6B,SAAQ,KAAK1B,IAAIM;AACvB,SAAKN,IAAIO,KAAK7E,EAAAA;AACd,WAAO,IAAI8C,WAAW,MAAMkD,QAAO9C,IAAAA;EACrC;;EAGAa,YAAYd,SAAiBY,MAA2BH,GAAWJ,OAAoB;AACrF,UAAMtD,KAAK,KAAKsE,IAAIrB,OAAAA;AAGpB,QAAI,CAACjD,GAAI,OAAM,IAAIyB,YAAY,8CAA8CwB,OAAAA,EAAS;AACtF,UAAMgD,QAAO,KAAK1B,MAAMK;AACxB,SAAKL,MAAMM,KAAKvB,KAAAA;AAChBtD,OAAGkG,QAAQ;MAAErC;MAAMH;MAAGuC,MAAAA;IAAK;EAC7B;;EAGAE,OAAmB;AACjB,WAAO;MAAE7B,KAAK,KAAKA;IAAI;EACzB;;;EAIA8B,aAAaH,OAA4B;AACvC,WAAO,KAAK1B,MAAM0B,KAAAA,KAAS;EAC7B;AACF;AAEA,SAASZ,kBAAkBH,MAAqCV,OAAa;AAC3E,QAAM6B,QAAQnB,KAAK,CAAA;AACnB,MAAI,CAACmB,MAAO;AACZ,QAAMC,OAAOlE,OAAOI,KAAK6D,KAAAA;AACzB,QAAME,UAAUD,KAAKE,KAAK,GAAA;AAC1B,WAASC,IAAI,GAAGA,IAAIvB,KAAKN,QAAQ6B,KAAK;AACpC,UAAMC,MAAMtE,OAAOI,KAAK0C,KAAKuB,CAAAA,CAAE;AAC/B,QAAIC,IAAIF,KAAK,GAAA,MAASD,SAAS;AAG7B,YAAM,IAAI9E,YACR,GAAG+C,KAAAA,mEACG8B,KAAKE,KAAK,IAAA,CAAA,aAAkBC,CAAAA,UAAWC,IAAIF,KAAK,IAAA,CAAA,4EACgB;IAE1E;EACF;AACF;AAjBSnB;AA+BF,SAASsB,kBAAkB3F,OAAgB4F,SAAyB;AACzE,QAAMzF,MAAMb,cAAcU,KAAAA;AAC1B,MAAIG,KAAK;AACP,UAAMiE,MAAMyB,MAAMD,SAASzF,IAAInB,IAAI,KAAKmB,IAAIlB,KAAK,IAAI;AACrD,QAAI,EAAEkB,IAAIlB,SAASmF,MAAM;AACvB,YAAM,IAAI3D,YACR,+BAA+BN,IAAInB,EAAE,yBAAyBmB,IAAIlB,KAAK,KAAK;IAEhF;AACA,WAAOmF,IAAIjE,IAAIlB,KAAK;EACtB;AAEA,QAAM6G,QAAQpG,WAAWM,KAAAA;AACzB,MAAI8F,UAAU,KAAM,QAAOD,MAAMD,SAASE,OAAO,OAAA;AAEjD,MAAIjG,aAAaG,KAAAA,GAAQ;AACvB,UAAM,IAAIS,YACR,uMAEE;EAEN;AAEA,MAAIG,MAAMC,QAAQb,KAAAA,EAAQ,QAAOA,MAAMc,IAAI,CAACY,SAASiE,kBAAkBjE,MAAMkE,OAAAA,CAAAA;AAE7E,MAAIG,cAAc/F,KAAAA,GAAQ;AACxB,UAAMkB,MAA+B,CAAC;AACtC,eAAW,CAACK,KAAKG,IAAAA,KAASN,OAAOC,QAAQrB,KAAAA,EAAQkB,KAAIK,GAAAA,IAAOoE,kBAAkBjE,MAAMkE,OAAAA;AACpF,WAAO1E;EACT;AAEA,SAAOlB;AACT;AAhCgB2F;AAkChB,SAASE,MAAMD,SAA2B3D,SAAiBC,MAAY;AACrE,QAAM8D,SAASJ,QAAQ3D,OAAAA;AACvB,MAAI,CAAC+D,QAAQ;AACX,UAAM,IAAIvF,YACR,oDAAoDwB,OAAAA,QAAeC,IAAAA,kBAChD;EAEvB;AACA,QAAMkC,MAAM4B,OAAO9B,KAAK,CAAA;AACxB,MAAI,CAACE,KAAK;AAIR,UAAM,IAAI3D,YACR,+BAA+BwB,OAAAA,wBAA+BC,IAAAA,kBAClD;EAEhB;AACA,SAAOkC;AACT;AAnBSyB;AAqBT,SAASE,cAAc/F,OAAc;AACnC,MAAI,OAAOA,UAAU,YAAYA,UAAU,KAAM,QAAO;AACxD,QAAMiG,QAAiB7E,OAAO8E,eAAelG,KAAAA;AAC7C,SAAOiG,UAAU7E,OAAO+E,aAAaF,UAAU;AACjD;AAJSF;AA6BT,eAAsBK,UACpBC,WAIAC,QACAtE,SACAxB,IAA4B;AAE5B,QAAM+F,WAAW/F,GAAG8F,MAAAA;AACpB,QAAMnB,OAAOnD,QAAQmD,KAAI;AACzB,MAAIA,KAAK7B,IAAIM,WAAW,GAAG;AACzB,WAAO+B,kBAAkBY,UAAU,CAAA,CAAE;EACvC;AAEA,MAAIC;AACJ,MAAI;AACFA,eAAW,MAAMH,UAAUI,OAAOtB,IAAAA;EACpC,SAASuB,KAAK;AACZ,UAAMC,mBAAmBD,KAAK1E,OAAAA;EAChC;AACA,SAAO2D,kBAAkBY,UAAUC,SAASZ,OAAO;AACrD;AAtBsBQ;AAgCtB,SAASO,mBAAmBD,KAAc1E,SAAsB;AAC9D,MAAI,OAAO0E,QAAQ,YAAYA,QAAQ,KAAM,QAAOA;AACpD,QAAME,YAAYF;AAClB,MAAIE,UAAUC,eAAe,qBAAqB,OAAOD,UAAU3B,SAAS,UAAU;AACpF,WAAOyB;EACT;AACA,SAAO1E,QAAQoD,aAAawB,UAAU3B,IAAI,KAAKyB;AACjD;AAPSC;;;ACtrCF,SAASG,YAAYC,OAAyB;AACnD,QAAMC,IAAID,SAAS;AACnB,MAAI,CAACE,OAAOC,UAAUF,CAAAA,KAAMA,IAAI,KAAKA,IAAI,IAAI;AAC3C,UAAM,IAAIG,MAAM,uDAAA;EAClB;AACA,SAAOH;AACT;AANgBF;AA4BT,SAASM,gBAAgBC,SAAuC;AACrE,MAAIC,YAAYD,SAASE,KAAAA,MAAW,GAAG;AACrC,UAAM,IAAIC,MACR,2OACA;EAEJ;AACF;AAPgBJ;;;AC2LhB,SAASK,MAAMC,QAAiC;AAC9C,SAAO,UAAUA,SAASA,OAAOC,OAAOD;AAC1C;AAFSD;AAIT,SAASG,aAAaF,QAAiC;AACrD,QAAMG,MAAMJ,MAAMC,MAAAA;AAClB,QAAMI,MAAkB;IACtBC,MAAMF,IAAIE;IACVC,UAAUH,IAAIG;IACdC,YAAYJ,IAAII;EAClB;AAIA,MAAIJ,IAAIK,iBAAiBC,OAAWL,KAAII,eAAeL,IAAIK;AAC3D,MAAIL,IAAIO,kBAAkB,KAAMN,KAAIM,gBAAgB;AACpD,MAAIP,IAAIQ,eAAe,KAAMP,KAAIO,aAAa;AAC9C,MAAIR,IAAIS,gBAAgBH,OAAWL,KAAIQ,cAAcT,IAAIS;AAGzD,MAAIT,IAAIU,YAAY,KAAMT,KAAIS,UAAU;AAWxC,MAAIV,IAAIW,SAAS,KAAMV,KAAIU,OAAO;AAClC,MAAIX,IAAIY,eAAeN,QAAW;AAChCL,QAAIW,aAAa;MAAEC,OAAOb,IAAIY,WAAWC;MAAOhB,QAAQG,IAAIY,WAAWf;IAAO;EAChF;AACA,MAAIG,IAAIc,mBAAmBR,OAAWL,KAAIa,iBAAiBd,IAAIc;AAG/D,MAAId,IAAIe,UAAU,MAAOd,KAAIc,QAAQ;AACrC,MAAIf,IAAIgB,YAAY,KAAMf,KAAIe,UAAU;AACxC,MAAIhB,IAAIiB,aAAaX,OAAWL,KAAIgB,WAAWjB,IAAIiB;AACnD,MAAIjB,IAAIkB,eAAeZ,OAAWL,KAAIiB,aAAa;OAAIlB,IAAIkB;;AAC3D,MAAIlB,IAAImB,WAAW,KAAMlB,KAAIkB,SAAS;AACtC,MAAInB,IAAIoB,eAAed,OAAWL,KAAImB,aAAapB,IAAIoB;AACvD,SAAOnB;AACT;AAzCSF;AA2CT,SAASsB,aAAaC,SAAiB;AACrC,SAAO;IACLC,MAAMD,QAAOC;IACbC,SAASF,QAAOE,WAAW;IAC3BC,OAAOH,QAAOG,QAAQ;SAAIH,QAAOG;QAAS,CAAA;;;;IAI1CC,OAAOJ,QAAOI,SAAS;IACvBC,WAAWL,QAAOK,aAAa;IAC/BC,YAAYN,QAAOM,eAAe;EACpC;AACF;AAZSP;AAoCT,SAASQ,mBAAmBC,QAAoB7B,KAAe;AAC7D,MAAI6B,OAAOC,aAAazB,UAAa0B,OAAOC,KAAKH,OAAOC,QAAQ,EAAEG,SAAS,GAAG;AAC5EjC,QAAI8B,WAAWC,OAAOG,YACpBH,OAAOI,QAAQN,OAAOC,QAAQ,EAAEM,IAAI,CAAC,CAACC,MAAMC,IAAAA,MAAU;MAACD;MAAM;WAAIC;;KAAM,CAAA;EAE3E;AACA,MAAIT,OAAOU,aAAa,KAAMvC,KAAIuC,WAAW;AAC/C;AAPSX;AAYT,SAASY,aAAaX,QAAoBY,cAAgC;AACxE,MAAIZ,OAAOa,SAASrC,UAAawB,OAAOc,UAAUtC,QAAW;AAK3D,UAAML,OAAkB,CAAC;AACzB,UAAM4C,WACJf,OAAOgB,SAAS,QAAQxC,SAAYyC,MAAMC,QAAQlB,OAAOgB,IAAI,KAAKhB,OAAOgB,KAAKZ,SAAS,IAAIJ,OAAOgB,OAAOhB,OAAOa;AAClH,QAAIE,aAAavC,OAAWL,CAAAA,KAAI6C,OAAO;MAAEG,SAAS;WAAIJ;;IAAU;AAChE,UAAMK,IAA+C;MAAEC,QAAQrB,OAAOqB,UAAU;IAAS;AACzF,QAAIT,iBAAiBpC,OAAW4C,GAAErD,SAAS6C;AAC3CQ,MAAEE,QAAQ;MACRC,UAAUvB,OAAOc,MAAMS;MACvBT,OAAOd,OAAOc,MAAMA;MACpBD,MAAM;WAAIb,OAAOa;;MACjB,GAAIb,OAAOc,MAAMU,eAAehD,SAAY;QAAEgD,YAAYxB,OAAOc,MAAMU;MAAW,IAAI,CAAC;MACvF,GAAIxB,OAAOc,MAAMxB,eAAed,SAAY;QAAEc,YAAYU,OAAOc,MAAMxB;MAAW,IAAI,CAAC;MACvF,GAAIU,OAAOc,MAAMW,YAAYjD,SAAY;QAAEiD,SAASzB,OAAOc,MAAMW;MAAQ,IAAI,CAAC;IAChF;AACA,QAAIzB,OAAO0B,cAAclD,OAAW4C,GAAEM,YAAY1B,OAAO0B;AACzD,QAAId,iBAAiBpC,QAAW;AAC9B4C,QAAEO,OAAO;AACT,UAAI3B,OAAO4B,WAAWpD,QAAW;AAC/B,cAAMqD,IAAkC,CAAC;AACzC,YAAI7B,OAAO4B,OAAOE,SAAStD,UAAawB,OAAO4B,OAAOE,OAAO,EAAGD,GAAEE,YAAY/B,OAAO4B,OAAOE;AAC5F,YAAI9B,OAAO4B,OAAOI,YAAYxD,UAAawB,OAAO4B,OAAOI,UAAU,EAAGH,GAAEI,eAAejC,OAAO4B,OAAOI;AACrG,YAAI9B,OAAOC,KAAK0B,CAAAA,EAAGzB,SAAS,EAAGgB,GAAEQ,SAASC;MAC5C;IACF;AACA1D,IAAAA,KAAI+D,SAAS;MAACd;;AACdrB,uBAAmBC,QAAQ7B,IAAAA;AAC3B,WAAOA;EACT;AACA,QAAMA,MAAkB,CAAC;AAGzB,MAAI8C,MAAMC,QAAQlB,OAAOgB,IAAI,KAAKhB,OAAOgB,KAAKZ,SAAS,EAAGjC,KAAI6C,OAAO;IAAEG,SAAS;SAAInB,OAAOgB;;EAAM;AACjG,QAAMmB,OAAOnC,OAAOkC,WAAW1D,SAAY,CAAA,IACvCyC,MAAMC,QAAQlB,OAAOkC,MAAM,IAAIlC,OAAOkC,SAAS;IAAClC,OAAOkC;;AAC3D,MAAIC,KAAK/B,SAAS,GAAG;AACnBjC,QAAI+D,SAASC,KAAK5B,IAAI,CAAC6B,QAAAA;AACrB,YAAMhB,IAA+C;QAAEC,QAAQe,IAAIf,UAAU;MAAS;AACtF,UAAIe,IAAIrE,WAAWS,OAAW4C,GAAErD,SAASqE,IAAIrE;AAC7C,UAAIqE,IAAIV,cAAclD,OAAW4C,GAAEM,YAAYU,IAAIV;AACnD,UAAIU,IAAItB,UAAUtC,QAAW;AAC3B4C,UAAEE,QAAQ;UACRC,UAAUa,IAAItB,MAAMS;UACpBT,OAAOsB,IAAItB,MAAMA;UACjBD,MAAM;eAAKuB,IAAIvB,QAAQ,CAAA;;UACvB,GAAIuB,IAAItB,MAAMU,eAAehD,SAAY;YAAEgD,YAAYY,IAAItB,MAAMU;UAAW,IAAI,CAAC;UACjF,GAAIY,IAAItB,MAAMxB,eAAed,SAAY;YAAEc,YAAY8C,IAAItB,MAAMxB;UAAW,IAAI,CAAC;UACjF,GAAI8C,IAAItB,MAAMW,YAAYjD,SAAY;YAAEiD,SAASW,IAAItB,MAAMW;UAAQ,IAAI,CAAC;QAC1E;MACF;AACA,aAAOL;IACT,CAAA;EACF;AACArB,qBAAmBC,QAAQ7B,GAAAA;AAC3B,SAAOA;AACT;AA5DSwC;AA8DT,SAAS0B,aAAaC,GAAa;AACjC,SAAO;IACLzB,MAAM;SAAIyB,EAAEzB;;IACZ0B,MAAMD,EAAEC;IACR,GAAID,EAAEE,YAAYhE,SAAY;MAAEgE,SAASF,EAAEE;IAAQ,IAAI,CAAC;IACxDC,SAAS;MAAElB,UAAUe,EAAEG,QAAQlB;MAAUT,OAAOwB,EAAEG,QAAQ3B;IAAM;EAClE;AACF;AAPSuB;AAST,SAASK,YAAY3D,OAAiB4D,YAAkB;AACtD,QAAMxB,UAAsC,CAAC;AAC7C,aAAW,CAAC1B,MAAM1B,MAAAA,KAAWmC,OAAOI,QAAQvB,MAAMoC,OAAO,GAAG;AAC1DA,YAAQ1B,IAAAA,IAAQxB,aAAaF,MAAAA;EAC/B;AAEA,QAAMI,MAAiB;IACrBsB,MAAMV,MAAMU;IACZmD,QAAQD;IACRxB;;;;;;IAMA0B,KAAK9D,MAAM8D;;;IAGX,GAAI9D,MAAMH,YAAY,OAAO;MAAEA,SAAS;IAAK,IAAI,CAAC;IAClDkE,WAAW/D,MAAM+D,YAAY,CAAA,GAAIvC,IAAIhB,YAAAA;EACvC;AAEA,MAAIR,MAAMT,eAAeE,UAAaO,MAAMT,WAAW8B,SAAS,GAAG;AACjEjC,QAAIG,aAAa;SAAIS,MAAMT;;EAC7B;AACA,MAAIS,MAAMM,WAAWb,UAAaO,MAAMM,OAAOe,SAAS,GAAG;AACzDjC,QAAI4E,oBAAoBhE,MAAMM,OAAOkB,IAAI,CAACyC,OAAO;MAAEvD,MAAMuD,EAAEvD;MAAM0B,SAAS;WAAI6B,EAAE7B;;IAAS,EAAA;EAC3F;AACA,MAAIpC,MAAMkE,QAAQzE,UAAaO,MAAMkE,IAAI7C,SAAS,GAAG;AACnDjC,QAAI+E,iBAAiBnE,MAAMkE,IAAI1C,IAAI,CAAC4C,OAAO;MAAE1D,MAAM0D,EAAE1D;MAAM2D,IAAID,EAAEC;IAAG,EAAA;EACtE;AACA,MAAIrE,MAAMsE,WAAW7E,UAAaO,MAAMsE,OAAOjD,SAAS,GAAG;AACzDjC,QAAIkF,SAAStE,MAAMsE,OAAO9C,IAAI,CAACsB,OAAO;MAAEpC,MAAMoC,EAAEpC;MAAM6D,MAAMzB,EAAEyB;IAAK,EAAA;EACrE;AACA,MAAIvE,MAAMwE,YAAY/E,UAAaO,MAAMwE,QAAQnD,SAAS,GAAG;AAC3DjC,QAAIoF,UAAUxE,MAAMwE,QAAQhD,IAAI,CAACiD,MAAAA;AAG/B,YAAMC,KAAgB;QAAEhE,MAAM+D,EAAE/D;QAAM0B,SAASqC,EAAErC,UAAU;aAAIqC,EAAErC;YAAW,CAAA;MAAG;AAC/E,UAAIqC,EAAEnE,WAAW,KAAMoE,IAAGpE,SAAS;AACnC,UAAImE,EAAEE,UAAUlF,OAAWiF,IAAGC,QAAQF,EAAEE;AACxC,UAAIF,EAAEG,eAAenF,OAAWiF,IAAGE,aAAaH,EAAEG;AAClD,UAAIH,EAAEI,SAASpF,OAAWiF,IAAGG,OAAOJ,EAAEI;AACtC,UAAIJ,EAAEK,UAAUrF,OAAWiF,IAAGI,QAAQL,EAAEK;AACxC,UAAIL,EAAEM,YAAYtF,OAAWiF,IAAGK,UAAU;WAAIN,EAAEM;;AAChD,aAAOL;IACT,CAAA;EACF;AACA,MAAI1E,MAAMgF,oBAAoBvF,UAAaO,MAAMgF,gBAAgB3D,SAAS,GAAG;AAC3EjC,QAAI4F,kBAAkB;SAAIhF,MAAMgF;;EAClC;AACA,MAAIhF,MAAMiF,gBAAgBxF,UAAaO,MAAMiF,YAAY5D,SAAS,GAAG;AACnEjC,QAAI6F,cAAcjF,MAAMiF,YAAYzD,IAAI,CAAC0D,OAAAA;AACvC,YAAMC,IAAoB;QACxBzE,MAAMwE,GAAGxE;QACT0B,SAAS;aAAI8C,GAAG9C;;QAChBgD,UAAUF,GAAGE;QACbC,YAAY;aAAIH,GAAGG;;MACrB;AACA,UAAIH,GAAGI,aAAa7F,OAAW0F,GAAEG,WAAWJ,GAAGI;AAC/C,UAAIJ,GAAGK,aAAa9F,OAAW0F,GAAEI,WAAWL,GAAGK;AAC/C,UAAIL,GAAGM,UAAU/F,OAAW0F,GAAEK,QAAQN,GAAGM;AACzC,aAAOL;IACT,CAAA;EACF;AACA,MAAInF,MAAMyF,WAAWhG,UAAaO,MAAMyF,OAAOpE,SAAS,GAAG;AACzDjC,QAAIqG,SAASzF,MAAMyF,OAAOjE,IAAI,CAACkE,OAAO;MACpChF,MAAMgF,EAAEhF;MACRiF,MAAMD,EAAEC;MACRvD,SAAS;WAAIsD,EAAEtD;;MACfgD,UAAUM,EAAEN;MACZC,YAAY;WAAIK,EAAEL;;IACpB,EAAA;EACF;AACA,MAAIrF,MAAM4F,WAAWnG,UAAaO,MAAM4F,OAAOvE,SAAS,GAAG;AACzDjC,QAAIwG,SAAS5F,MAAM4F,OAAOpE,IAAI,CAACqE,OAAO;MACpCnF,MAAMmF,EAAEnF;MACRoF,OAAOD,EAAEC;MACT,GAAID,EAAEF,SAASlG,SAAY;QAAEkG,MAAME,EAAEF;MAAK,IAAI,CAAC;MAC/C,GAAIE,EAAEE,WAAWtG,SAAY;QAAEsG,QAAQF,EAAEE;MAAO,IAAI,CAAC;MACrDC,SAASH,EAAEG;MACX,GAAIH,EAAEI,WAAWxG,SAAY;QAAEwG,QAAQJ,EAAEI;MAAO,IAAI,CAAC;MACrD,GAAIJ,EAAEK,SAASzG,SAAY;QAAEyG,MAAML,EAAEK;MAAK,IAAI,CAAC;MAC/C,GAAIL,EAAE7G,WAAWS,SAAY;QAAET,QAAQ6G,EAAE7G;MAAO,IAAI,CAAC;IACvD,EAAA;EACF;AACA,MAAIgB,MAAMmG,cAAc1G,UAAaO,MAAMmG,UAAU9E,SAAS,GAAG;AAC/DjC,QAAI+G,YAAYnG,MAAMmG,UAAU3E,IAAI,CAAC4E,OAAO;MAAE1F,MAAM0F,EAAE1F;MAAM2F,KAAKD,EAAEC;IAAI,EAAA;EACzE;AAGA,MAAIrG,MAAMsG,eAAe,KAAMlH,KAAIkH,aAAa;AAChD,MAAItG,MAAMiB,WAAWxB,QAAW;AAI9B,UAAMoC,eAAeV,OAAOI,QAAQa,OAAAA,EAASmE,KAAK,CAAC,CAAA,EAAGzD,CAAAA,MAAOA,EAAEvC,eAAed,MAAAA,IAAa,CAAA;AAC3F,UAAM+G,KAAK5E,aAAa5B,MAAMiB,QAAQY,YAAAA;AACtC,QAAI2E,GAAGvE,SAASxC,UAAa+G,GAAGrD,WAAW1D,OAAWL,KAAI6B,SAASuF;EACrE;AACA,MAAIxG,MAAMyG,WAAWhH,QAAW;AAC9BL,QAAIqH,SAASnD,aAAatD,MAAMyG,MAAM;EACxC;AACA,SAAOrH;AACT;AAxGSuE;AAkHF,SAAS+C,kBAAkB9C,YAAoB+C,WAAiB;AAKrE,SAAO/C,eAAe,MAAMA,eAAe,WAAW+C,YAAY,GAAG/C,UAAAA,IAAc+C,SAAAA;AACrF;AANgBD;AAcT,SAASE,aAAaC,SAA6B;AACxD,QAAMC,SAAoC,CAAC;AAC3C,QAAMC,aAAuB,CAAA;AAC7B,QAAMC,OAAyB,CAAA;AAC/B,QAAMC,OAAO,oBAAIC,IAAAA;AACjB,aAAWrD,UAAUgD,SAAS;AAC5B,QAAII,KAAKE,IAAItD,OAAOnD,IAAI,GAAG;AACzB,YAAM,IAAI0G,MAAM,iCAAiCvD,OAAOnD,IAAI,sCAAiC;IAC/F;AACAuG,SAAKI,IAAIxD,OAAOnD,IAAI;AACpB,eAAWV,SAASmB,OAAOmG,OAAOzD,OAAOiD,MAAM,GAAG;AAChD,YAAMS,OAAO5D,YAAY3D,OAAO6D,OAAOnD,IAAI;AAC3CoG,aAAOJ,kBAAkB7C,OAAOnD,MAAM6G,KAAK7G,IAAI,CAAA,IAAK6G;IACtD;AACAR,eAAWS,KAAI,GAAK3D,OAAOkD,cAAc,CAAA,CAAE;AAI3CC,SAAKQ,KAAK;MAAE9G,MAAMmD,OAAOnD;MAAM+G,SAAS5D,OAAO4D;IAAQ,CAAA;EACzD;AACA,SAAO;IAAEX;IAAQC,YAAY;SAAI,IAAIG,IAAIH,UAAAA;;IAAcF,SAASG;EAAK;AACvE;AArBgBJ;;;AJzWhB,IAAMc,cAA6BC,uBAAOC,IAAI,4BAAA;AAEvC,IAAMC,gBAAiD,MAAA;AAC5D,QAAMC,IAAIC;AACV,SAAQD,EAAEJ,WAAAA,MAAiB,IAAIM,0CAAAA;AACjC,GAAA;AAKA,IAAIC,UAAkC;AAO/B,SAASC,aAAaC,UAAyB;AACpDF,YAAUE;AACZ;AAFgBD;AAQT,SAASE,iBAAoBD,UAA2BE,IAAW;AACxE,SAAOR,aAAaS,IAAI;IAAEL,SAASE;EAAS,GAAGE,EAAAA;AACjD;AAFgBD;AAiBhB,IAAMG,oBAAoB;EACxB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAgBF,SAASC,oBAAoBL,UAAyB;AACpD,QAAMM,UAAUF,kBAAkBG,OAAO,CAACC,MAAMR,SAASQ,CAAAA,MAAOC,MAAAA;AAChE,MAAIH,QAAQI,SAAS,GAAG;AACtB,UAAM,IAAIC,MACR,gCAAgCL,QAAQM,KAAK,IAAA,CAAA,wSAGkC;EAEnF;AACA,SAAOZ;AACT;AAXSK;AAaF,SAASQ,eAAAA;AACd,QAAMC,SAASpB,aAAaqB,SAAQ;AACpC,MAAID,OAAQ,QAAOT,oBAAoBS,OAAOhB,OAAO;AACrD,MAAIA,YAAY,MAAM;AACpB,UAAM,IAAIa,MACR,8MAEE;EAEN;AACA,SAAOb;AACT;AAXgBe;AAmDhB,IAAMG,YAA2BxB,uBAAOC,IAAI,gCAAA;AAE5C,SAASwB,oBAAAA;AACP,QAAMtB,IAAIC;AACV,SAAQD,EAAEqB,SAAAA,MAAe;IAAEE,OAAO,CAAA;IAAIC,UAAU,CAAA;EAAG;AACrD;AAHSF;AA8BF,SAASG,QAAQC,MAAcC,MAAmB;AACvDL,oBAAAA,EAAoBC,MAAMK,KAAK;IAAEF;IAAMlB,KAAKmB;EAAK,CAAA;AACnD;AAFgBF;AAgBT,SAASI,WAAWH,MAAcC,MAAmB;AAC1DL,oBAAAA,EAAoBE,SAASI,KAAK;IAAEF;IAAMlB,KAAKmB;EAAK,CAAA;AACtD;AAFgBE;AAIhB,SAASC,OAAOC,KAAY;AAC1B,SAAOA,eAAef,QAAQe,IAAIC,UAAUC,OAAOF,GAAAA;AACrD;AAFSD;AAKT,eAAeI,MAAMC,OAAqB;AACxC,aAAWC,KAAK;OAAID;IAAOE,QAAO,GAAI;AACpC,QAAI;AACF,YAAMD,EAAE5B,IAAG;IACb,SAASuB,KAAK;AACZO,cAAQC,MAAM,4BAA4BH,EAAEV,IAAI,aAAaI,OAAOC,GAAAA,CAAAA,IAAQA,GAAAA;IAC9E;EACF;AACF;AAReG;AA4Bf,eAAsBM,kBAAAA;AACpB,QAAMC,QAAOnB,kBAAAA;AACb,QAAMC,QAAQkB,MAAKlB,MAAMmB,OAAO,CAAA;AAChC,QAAMlB,WAAWiB,MAAKjB,SAASkB,OAAO,CAAA;AAEtC,aAAWN,KAAKb,OAAO;AACrB,QAAI;AACF,YAAMa,EAAE5B,IAAG;IACb,SAASuB,KAAK;AACZ,YAAMG,MAAMV,QAAAA;AACZ,YAAM,IAAIR,MAAM,yBAAyBoB,EAAEV,IAAI,aAAaI,OAAOC,GAAAA,CAAAA,IAAQ;QAAEY,OAAOZ;MAAI,CAAA;IAC1F;EACF;AAEA,MAAIa,UAAU;AACd,SAAO,YAAA;AAEL,QAAIA,QAAS;AACbA,cAAU;AACV,UAAMV,MAAMV,QAAAA;EACd;AACF;AArBsBgB;AAyBf,SAASK,wBAAAA;AACd,QAAM7C,IAAIC;AACV,SAAOD,EAAEqB,SAAAA;AACX;AAHgBwB;AAchB,SAASC,iBAAkDC,KAAM;AAC/D,QAAMC,UAA4C;IAChDC,IAAIC,SAASC,MAAMC,UAAQ;AACzB,YAAMC,SAASnC,aAAAA,EAAe6B,GAAAA;AAC9B,YAAMO,QAAQC,QAAQN,IAAII,QAAkBF,MAAMC,QAAAA;AAGlD,aAAO,OAAOE,UAAU,aAAaA,MAAME,KAAKH,MAAAA,IAAUC;IAC5D;EACF;AAGA,SAAO,IAAIG,MAAM,CAAC,GAAyBT,OAAAA;AAC7C;AAbSF;AA8CT,SAASY,eAAeC,KAA4BC,QAAc;AAChE,SAAO,IAAIH,MACT,CAAC,GACD;IACER,IAAIY,IAAIV,MAAqB;AAC3B,UAAI,OAAOA,SAAS,SAAU,QAAOrC;AACrC,YAAMY,OAAO,GAAGkC,MAAAA,GAAST,IAAAA;AACzB,aAAO;QACLW,QAAQ,wBAACC,SAAkCJ,IAAAA,EAAMG,OAAOpC,MAAMqC,IAAAA,GAAtD;;;;QAIRC,WAAW,wBAACC,MAAyCN,IAAAA,EAAMK,UAAUtC,MAAMuC,CAAAA,GAAhE;QACXC,YAAY,wBACVC,MACAC,SACGT,IAAAA,EAAMO,WAAWxC,MAAMyC,MAAMC,IAAAA,GAHtB;QAIZC,QAAQ,wBAACJ,MACPN,IAAAA,EAAMU,OAAO3C,MAAMuC,EAAEK,MAAMC,IAAIN,EAAEO,GAAG,GAD9B;QAERC,QAAQ,wBAACF,OAAeZ,IAAAA,EAAMc,OAAO/C,MAAM6C,EAAAA,GAAnC;QACRG,UAAU,wBAACH,OAAeZ,IAAAA,EAAMe,SAAShD,MAAM6C,EAAAA,GAArC;QACVI,YAAY,wBAACV,MACXN,IAAAA,EAAMgB,WAAWjD,MAAMuC,EAAEK,OAAO;UAAEM,QAAQX,EAAEW;UAAQC,MAAMZ,EAAEY;QAAK,CAAA,GADvD;QAEZC,MAAM,wBAACb,MAAAA;AACL,gBAAM,EAAEK,OAAO,GAAGF,KAAAA,IAASH,KAAK,CAAC;AACjC,iBAAON,IAAAA,EAAMmB,KAAKpD,MAAM4C,OAA8CF,IAAAA;QACxE,GAHM;QAINW,UAAU,wBAACd,MAAAA;AAIT,gBAAM,EAAEK,OAAO,GAAGF,KAAAA,IAASH,KAAK,CAAC;AACjC,iBAAON,IAAAA,EAAMoB,SACXrD,MACA4C,OACAF,IAAAA;QAEJ,GAVU;QAWVY,KAAK,wBAACf,MACJN,IAAAA,EAAMqB,IAAItD,MAAMuC,EAAEF,MAAM;UAAEkB,YAAYhB,EAAEgB;QAAW,CAAA,GADhD;;;;;;;;;;;;QAaLC,YAAY,wBAACjB,MACXN,IAAAA,EAAMuB,WAAWxD,MAAMuC,EAAEK,OAAOL,EAAEO,KAAKP,EAAEkB,cAAcrE,SAAYA,SAAY;UAAEqE,WAAWlB,EAAEkB;QAAU,CAAA,GAD9F;QAEZC,YAAY,wBAACnB,MAA0CN,IAAAA,EAAMyB,WAAW1D,MAAMuC,EAAEK,KAAK,GAAzE;QACZe,OAAO,wBAACpB,MAA4CN,IAAAA,EAAM0B,MAAM3D,MAAMuC,GAAGK,KAAAA,GAAlE;QACPgB,QAAQ,wBAACC,WAAqC5B,IAAAA,EAAM2B,OAAO5D,MAAM6D,MAAAA,GAAzD;QACRC,SAAS,wBAACjB,IAAYgB,WAAqC5B,IAAAA,EAAM6B,QAAQ9D,MAAM6C,IAAIgB,MAAAA,GAA1E;QACTE,WAAW,wBAACF,WAAoC5B,IAAAA,EAAM8B,UAAU/D,MAAM6D,MAAAA,GAA3D;QACXG,QAAQ,wBAACH,WAA2D5B,IAAAA,EAAM+B,OAAOhE,MAAM6D,MAAAA,GAA/E;QACRI,WAAW,wBAACpB,IAAYqB,QAAiCjC,IAAAA,EAAMgC,UAAUjE,MAAM6C,IAAIqB,GAAAA,GAAxE;QACXC,OAAO,wBAACC,QAAiCC,UACvCpC,IAAAA,EAAMkC,MAAMnE,MAAMoE,QAAQC,KAAAA,GADrB;MAET;IACF;EACF,CAAA;AAEJ;AAlESrC;AAsET,IAAMsC,cAAwBlD,iBAAiB,UAAA;AAoBxC,SAASmD,iBAAiBC,MAAqD;AAGpF,QAAMC,OAAOD;AAQb,QAAMvC,MAAM;IACVyC,QAAQ,wBAACC,KAAad,WAAuBW,KAAII,MAAMD,KAAKd,MAAAA,GAApD;IACRgB,cAAc,6BAAML,KAAIM,YAAW,GAArB;IACdC,SAAS,wBAACC,OAAe3C,SAAkCmC,KAAIpC,OAAO4C,OAAO3C,IAAAA,GAApE;IACT4C,SAAS,wBAACD,OAAenC,IAAYR,SACnCmC,KAAI7B,OAAOqC,OAAOnC,IAAIR,IAAAA,GADf;IAET6C,SAAS,wBAACF,OAAenC,OAAe2B,KAAIzB,OAAOiC,OAAOnC,EAAAA,GAAjD;IACTsC,WAAW,wBAACH,OAAenC,OAAe2B,KAAIxB,SAASgC,OAAOnC,EAAAA,GAAnD;IACXuC,aAAa,wBAACJ,OAAepC,OAAgCF,SAA8C8B,KAAIvB,WAAW+B,OAAOpC,OAAOF,IAAAA,GAA3H;IACb2C,OAAO,wBAACL,OAAeJ,OAAiClC,SAAiD8B,KAAIpB,KAAK4B,OAAOJ,OAAOlC,IAAAA,GAAzH;IACP4C,WAAW,wBAACN,OAAeJ,OAAiClC,SAC1D8B,KAAInB,SAAS2B,OAAOJ,OAAOlC,IAAAA,GADlB;IAEX6C,MAAM,wBAACP,OAAe3C,MAA+BK,SACnD8B,KAAIlB,IAAI0B,OAAO3C,MAAMK,IAAAA,GADjB;;;;;;IAON8C,aAAa,wBACXR,OACApC,OACAE,KACAJ,SACG8B,KAAIhB,WAAWwB,OAAOpC,OAAOE,KAAKJ,IAAAA,GAL1B;IAMb+C,aAAa,wBAACT,OAAepC,UAAmC4B,KAAId,WAAWsB,OAAOpC,KAAAA,GAAzE;IACb8C,QAAQ,wBAACV,OAAepC,UAAoC4B,KAAIb,MAAMqB,OAAOpC,KAAAA,GAArE;IACR+C,SAAS,wBAACX,OAAenB,WAAqCW,KAAIZ,OAAOoB,OAAOnB,MAAAA,GAAvE;IACT+B,UAAU,wBAACZ,OAAenC,IAAYgB,WACpCY,KAAKX,QAAQkB,OAAOnC,IAAIgB,MAAAA,GADhB;IAEVgC,YAAY,wBAACb,OAAenB,WAAoCY,KAAKV,UAAUiB,OAAOnB,MAAAA,GAA1E;IACZiC,SAAS,wBAACd,OAAenB,WAA2DY,KAAKT,OAAOgB,OAAOnB,MAAAA,GAA9F;IACTkC,QAAQ,wBAACf,OAAeZ,QAAiCC,UACvDI,KAAKN,MAAMa,OAAOZ,QAAQC,KAAAA,GADpB;IAER2B,WAAW,wBAAChB,OAAeiB,QAA2BxB,KAAKyB,SAASlB,OAAOiB,GAAAA,GAAhE;IACXE,gBAAgB,wBACdnB,OACApC,OACAF,SACG+B,KAAK2B,cAAcpB,OAAOpC,OAAOF,IAAAA,GAJtB;IAKhB2D,mBAAmB,wBAAChF,QAAgBoD,KAAK6B,iBAAiBjF,GAAAA,GAAvC;IACnBkF,YAAY,wBAACvB,OAAezC,MAAyCiC,KAAIlC,UAAU0C,OAAOzC,CAAAA,GAA9E;IACZiE,aAAc,wBACZxB,OACAvC,MACAC,SACG8B,KAAIhC,WAAWwC,OAAOvC,MAAMC,IAAAA,GAJnB;IAKd+D,YAAY,wBAACzB,OAAenC,IAAYqB,QACtCM,KAAIP,UAAUe,OAAOnC,IAAIqB,GAAAA,GADf;EAEd;AAIA,QAAMwC,OAAOC,OAAOC,OAAO3E,KAA2C;IACpE4E,QAAWhI,IAAwCiI,SAAuB;AACxE,UAAI,OAAOtC,KAAIuC,WAAW,YAAY;AACpC,cAAM,IAAIzH,MAAM,sFAAA;MAClB;AAIA,YAAM0H,SAAS3I,aAAaqB,SAAQ;AACpC,UAAIjB;AACJ,UAAI;AAAEA,QAAAA,WAAUe,aAAAA;MAAgB,QAAQ;MAA6D;AACrG,aAAOgF,KAAIuC,OAAO,OAAOE,OAAAA;AACvB,cAAMC,QAAQ3C,iBAAiB0C,EAAAA;AAC/B,cAAME,SAAS,6BAAMtI,GAAGqI,KAAAA,GAAT;AACf,YAAI,CAACzI,SAAS,QAAO0I,OAAAA;AACrB,cAAMC,UAAS,6BAAA;AAAe,gBAAM,IAAI9H,MAAM,iGAAA;QAAoG,GAAnI;AACf,cAAM+H,UAAUV,OAAOC,OAAO,CAAC,GAAGK,IAAI;UAAEF,QAAQK;UAAQE,WAAWF;QAAO,CAAA;AAC1E,eAAO/I,aAAaS,IAAI;UAAE,GAAGkI;UAAQvI,SAAS;YAAE,GAAGA;YAAS8I,UAAUF;UAAQ;QAAE,GAAGF,MAAAA;MACrF,GAAGL,OAAAA;IACL;;;IAGAU,UAAU,wBAAK3I,OAAkC2F,KAAIiD,QAAQ5I,EAAAA,GAAnD;IACV6I,aACE7I,IACA6D,MAAyB;AAMzBiF,sBAAgBjF,IAAAA;AAChB,YAAMkF,UAAU,IAAIC,cAAAA;AACpB,aAAOC,UAAUtD,MAAKuD,iBAAiBH,OAAAA,GAAUA,SAAS/I,EAAAA;IAC5D;IACAmJ,SAAYnJ,IAA4DiI,SAAkD;AACxH,YAAMc,UAAU,IAAIC,cAAAA;AACpB,aAAOC,UAAU;QAAEG,QAAQC,wBAAAA,SAAQ1D,KAAI2D,QAAQD,MAAMpB,OAAAA,GAA1BoB;MAAmC,GAAGH,iBAAiBH,OAAAA,GAAUA,SAAS/I,EAAAA;IACvG;EACF,CAAA;AAKA,SAAO,IAAIkD,MAAM2E,MAAM;IACrBnF,IAAI6G,QAAQ3G,MAAMC,UAAQ;AASxB,UAAID,SAAS,SAAU,QAAOO,eAAe,MAAMyC,MAAM,EAAA;AACzD,UAAI,OAAOhD,SAAS,YAAY,CAACA,KAAK4G,WAAW,GAAA,KAAQ,EAAE5G,QAAQ2G,SAAS;AAK1E,eAAOpG,eAAe,MAAMyC,MAAM6D,kBAAkB7G,MAAM,EAAA,CAAA;MAC5D;AACA,aAAOI,QAAQN,IAAI6G,QAAQ3G,MAAMC,QAAAA;IACnC;EACF,CAAA;AACF;AAjIgB6C;AA0IhB,SAASgE,qBAAqBX,SAAwB1F,SAAS,IAAE;AAC/D,QAAMsG,cAAc,IAAIzG,MACtB,CAAC,GACD;IACER,IAAIY,IAAIV,MAAqB;AAC3B,UAAI,OAAOA,SAAS,SAAU,QAAOrC;AACrC,aAAOwI,QAAQ5C,MAAM9C,SAAST,IAAAA;IAChC;EACF,CAAA;AAEF,SAAO+G;AACT;AAXSD;AAiCT,SAASR,iBAAiBH,SAAsB;AAC9C,QAAMa,eAAeF,qBAAqBX,OAAAA;AAC1C,SAAO,IAAI7F,MACT,CAAC,GACD;IACER,IAAIY,IAAIV,MAAqB;AAC3B,UAAI,OAAOA,SAAS,SAAU,QAAOrC;AACrC,UAAIqC,SAAS,SAAU,QAAOgH;AAU9B,aAAOF,qBAAqBX,SAASU,kBAAkB7G,MAAM,EAAA,CAAA;IAC/D;EACF,CAAA;AAEJ;AArBSsG;AA6CF,IAAMR,WAA6BZ,OAAOC,OAAOrC,iBAAiBD,WAAAA,GAAc;;;;;;;;EAQrFoE,aAAAA;AACE,WAAOnE,iBAAiBD,YAAYgD,UAAS,CAAA;EAC/C;AACF,CAAA;AAGO,IAAMqB,YAA+BvH,iBAAiB,WAAA;AAuB7D,SAASwH,oBAAoBC,SAAmC;AAC9D,SAAO,IAAI9G,MACT,CAAC,GACD;IACER,IAAIY,IAAIV,MAAqB;AAC3B,UAAI,OAAOA,SAAS,SAAU,QAAOrC;AACrC,aAAOyJ,QAAAA,EAAUC,OAAOrH,IAAAA;IAC1B;EACF,CAAA;AAEJ;AAVSmH;AAYT,IAAMG,aAAmC3H,iBAAiB,SAAA;AASnD,IAAM4H,UAA0DrC,OAAOC,OAC5E;;;;;;;;;;EAUEkC,QAAQ,wBAAC9I,SAAiB+I,WAAWD,OAAO9I,IAAAA,GAApC;AACV,GACA;EAAEiJ,SAASL,oBAAoB,MAAMG,UAAAA;AAAY,CAAA;AAI5C,IAAMG,QAAqB9H,iBAAiB,OAAA;AAa5C,IAAM+H,UAA0B/H,iBAAiB,SAAA;AAejD,IAAMgI,OAA+BhI,iBAAiB,MAAA;AAGtD,IAAMiI,MAAcjI,iBAAiB,KAAA;AAGrC,IAAMkI,gBAA4ClI,iBAAiB,eAAA;AAU1E,IAAMmI,WAA+BnI,iBAAiB,OAAA;AA6C/C,IAAMoI,QAA6B7C,OAAOC,OAC/C;EACE6C,UACEC,UACAC,SAA4B;AAE5B,WAAOJ,SAASE,UAAUC,UAAUC,OAAAA;EACtC;EACAC,WACEF,UACAC,SAA4B;AAE5B,WAAOJ,SAASK,WAAWF,UAAUC,OAAAA;EACvC;EACAE,OAAOF,SAA4B;AACjC,WAAOJ,SAASM,OAAOF,OAAAA;EACzB;;;;;;;;;;;EAWApI,IACEmI,UACAI,kBACAC,cAAiC;AAEjC,WAAOR,SAAShI,IAAImI,UAAUI,kBAAkBC,YAAAA;EAClD;EACAC,YACE3I,KACAO,OAAuB;AAEvB,WAAO2H,SAASS,YAAY3I,KAAKO,KAAAA;EACnC;AACF,GACA;;;;;;;EAOE8G,aAAAA;AACE,WAAOa,SAASjC,UAAS;EAC3B;;;;;;;;;;;EAWAA,YAAAA;AACE,UAAM,IAAIhI,MACR,uIAAA;EAEJ;AACF,CAAA;AAeK,IAAM2K,WAAkC7I,iBAAiB,UAAA;;;AKj8BzD,IAAM8I,qBAAN,cAAiCC,MAAAA;EA5DxC,OA4DwCA;;;EAC7BC;EACAC;EACAC;EAET,YAAYF,MAAcG,SAAiBF,QAAgBC,UAAmC,CAAC,GAAG;AAChG,UAAMC,OAAAA;AACN,SAAKC,OAAO;AACZ,SAAKJ,OAAOA;AACZ,SAAKC,SAASA;AACd,SAAKC,UAAUA;EACjB;AACF;AAEO,SAASG,eAAeC,KAAoB;AACjD,iBAAeC,QACbC,QACAC,MACAC,UAA0B,CAAC,GAAC;AAE5B,UAAMC,UAAkC;MACtC,gBAAgB;MAChB,GAAID,QAAQC,WAAW,CAAC;IAC1B;AACA,QAAIL,IAAIM,OAAQD,SAAQ,QAAA,IAAYL,IAAIM;AAExC,UAAMC,OAAoB;MAAEL;MAAQG;IAAQ;AAC5C,QAAID,QAAQI,SAASC,QAAW;AAC9B,UAAI,OAAOL,QAAQI,SAAS,YAAYJ,QAAQI,gBAAgBE,YAAY;AAC1EH,aAAKC,OAAOJ,QAAQI;MACtB,WAAW,OAAOG,aAAa,eAAeP,QAAQI,gBAAgBG,UAAU;AAI9E,eAAON,QAAQ,cAAA;AACfE,aAAKC,OAAOJ,QAAQI;MACtB,WAAW,OAAOI,SAAS,eAAeR,QAAQI,gBAAgBI,MAAM;AACtE,eAAOP,QAAQ,cAAA;AACfE,aAAKC,OAAOJ,QAAQI;MACtB,OAAO;AACLD,aAAKC,OAAOK,KAAKC,UAAUV,QAAQI,IAAI;MACzC;IACF;AACA,QAAIJ,QAAQW,OAAQR,MAAKQ,SAASX,QAAQW;AAG1C,UAAMC,UAAUhB,IAAIiB,aAAaC,WAAWC;AAE5C,QAAIC;AACJ,QAAI;AACFA,iBAAW,MAAMJ,QAAQ,GAAGhB,IAAIqB,OAAO,GAAGlB,IAAAA,IAAQI,IAAAA;IACpD,SAASe,KAAK;AAsBZ,aAAO;QACLC,MAAM;QACNC,OAAO,IAAIhC,mBACT,iBACA8B,eAAe7B,QAAQ6B,IAAIzB,UAAU,0BACrC,CAAA;QAEFF,QAAQ;MACV;IACF;AAEA,UAAM8B,cAAcL,SAASf,QAAQqB,IAAI,cAAA,KAAmB;AAC5D,QAAIC,SAAkB;AACtB,QAAIzB,WAAW,UAAUuB,YAAYG,SAAS,MAAA,GAAS;AACrDD,eAAS,MAAMP,SAASS,KAAI,EAAGC,MAAM,MAAM,IAAA;IAC7C,WAAW5B,WAAW,UAAUuB,YAAYM,WAAW,QAAA,GAAW;AAEhEJ,eAAS,IAAIjB,WAAW,MAAMU,SAASY,YAAW,CAAA;IACpD,WAAW9B,WAAW,UAAUkB,SAASZ,MAAM;AAE7CmB,eAAS,MAAMP,SAASa,KAAI,EAAGH,MAAM,MAAM,IAAA;IAC7C;AAEA,QAAI,CAACV,SAASc,IAAI;AAChB,YAAM1B,OAAQmB,UAAU,OAAOA,WAAW,WAAWA,SAAS,CAAC;AAC/D,YAAMjC,OAAO,OAAOc,KAAKgB,UAAU,YAAYhB,KAAKgB,QAAQhB,KAAKgB,QAAQ;AACzE,YAAM3B,UACH,OAAOW,KAAK2B,sBAAsB,YAAY3B,KAAK2B,qBACpDf,SAASgB,cACT;AACF,aAAO;QACLb,MAAM;QACNC,OAAO,IAAIhC,mBAAmBE,MAAMG,SAASuB,SAASzB,QAAQa,IAAAA;QAC9Db,QAAQyB,SAASzB;MACnB;IACF;AAEA,WAAO;MAAE4B,MAAMI;MAAaH,OAAO;MAAM7B,QAAQyB,SAASzB;IAAO;EACnE;AAhGeM;AAkGf,SAAO;IAAEoB,SAASrB,IAAIqB;IAASpB;EAAQ;AACzC;AApGgBF;;;ACrCT,IAAMsC,iBAAN,cAA6BC,MAAAA;EArCpC,OAqCoCA;;;EACzBC;EAET,YAAYA,MAAcC,SAAkB;AAC1C,UAAMA,WAAW,kBAAkBD,IAAAA,6BAAiC;AACpE,SAAKE,OAAO;AACZ,SAAKF,OAAOA;EACd;AACF;AAcA,SAASG,OAAOC,OAA4CJ,MAAY;AACtE,MAAII,MAAMC,SAAS,mBAAoB,OAAM,IAAIP,eAAeE,MAAMI,MAAMH,OAAO;AACnF,MAAIG,iBAAiBE,mBAAoB,OAAMF;AAC/C,QAAM,IAAIE,mBAAmBF,MAAMC,QAAQ,iBAAiBD,MAAMH,WAAW,kBAAkB,CAAA;AACjG;AAJSE;AAQT,SAASI,UAAUC,QAAgBR,MAAa;AAC9C,QAAMS,OAAO,gBAAgBC,mBAAmBF,MAAAA,CAAAA;AAChD,SAAOR,SAASW,SAAYF,OAAO,GAAGA,IAAAA,IAAQC,mBAAmBV,IAAAA,CAAAA;AACnE;AAHSO;AAKF,SAASK,gBAAgBC,MAAqB;AACnD,SAAO;IACL,MAAMC,WAAWN,QAAgBR,MAAY;AAC3C,YAAM,EAAEI,MAAK,IAAK,MAAMS,KAAKE,QAAuB,OAAOR,UAAUC,QAAQR,IAAAA,CAAAA;AAC7E,UAAII,MAAOD,QAAOC,OAAOJ,IAAAA;IAC3B;IAEA,MAAMgB,WAAWR,QAAgBR,MAAY;AAC3C,YAAM,EAAEI,MAAK,IAAK,MAAMS,KAAKE,QAAuB,UAAUR,UAAUC,QAAQR,IAAAA,CAAAA;AAChF,UAAII,MAAOD,QAAOC,OAAOJ,IAAAA;IAC3B;IAEA,MAAMiB,QAAQT,QAAc;AAC1B,YAAM,EAAEU,MAAMd,MAAK,IAAK,MAAMS,KAAKE,QAAuB,OAAOR,UAAUC,MAAAA,CAAAA;AAI3E,UAAIJ,MAAOD,QAAOC,OAAO,EAAA;AACzB,aAAOc,MAAMC,SAAS,CAAA;IACxB;EACF;AACF;AArBgBP;;;AC7ChB,IAAMQ,aAAa;AAEnB,SAASC,gBAAgBC,SAAiBC,OAAa;AACrD,MAAI,CAACH,WAAWI,KAAKF,OAAAA,GAAU;AAC7B,UAAM,IAAIG,MAAM,WAAWF,KAAAA,MAAWD,OAAAA,iBAAwBF,WAAWM,MAAM,EAAE;EACnF;AACF;AAJSL;AA2BT,SAASM,iBACPC,MACAC,MAAY;AAEZ,SAAO;IACLA;IACA,MAAMC,IAAIC,MAAO;AACf,aAAOH,KAAKI,QAAc,OAAO,YAAYH,IAAAA,IAAQ;QAAEI,MAAMF;MAAK,CAAA;IACpE;IACA,MAAMG,MAAAA;AACJ,YAAMC,WAAW,MAAMP,KAAKI,QAAqB,OAAO,YAAYH,IAAAA,EAAM;AAC1E,UAAIM,SAASC,MAAO,QAAO;QAAEL,MAAM;QAAMK,OAAOD,SAASC;QAAOC,QAAQF,SAASE;MAAO;AACxF,YAAMC,OAAMH,SAASJ,QAAQ,CAAC;AAC9B,YAAMQ,SAASD,KAAIC,WAAWC,SAAYF,KAAIC,SAASE,QAAQH,KAAIP,QAAQO,KAAII,EAAE;AACjF,YAAMC,WAAWd,KAAKe,MAAM,GAAA;AAC5B,YAAMF,KAAKJ,KAAII,MAAMC,SAASA,SAASE,SAAS,CAAA,KAAM;AACtD,aAAO;QACLd,MAAM;UAAEW;UAAIH;UAAQR,MAAM,6BAAMO,KAAIP,MAAV;UAAiCe,KAAK;YAAEjB;UAAK;QAAE;QACzEO,OAAO;QACPC,QAAQF,SAASE;MACnB;IACF;IACA,MAAMU,OAAOhB,MAAgB;AAC3B,aAAOH,KAAKI,QAAc,SAAS,YAAYH,IAAAA,IAAQ;QAAEI,MAAMF;MAAK,CAAA;IACtE;IACA,MAAMiB,SAAAA;AACJ,aAAOpB,KAAKI,QAAc,UAAU,YAAYH,IAAAA,EAAM;IACxD;IACAoB,WAA8CC,MAAY;AACxD7B,sBAAgB6B,MAAM,oBAAA;AACtB,aAAOC,mBAAsBvB,MAAM,GAAGC,IAAAA,IAAQqB,IAAAA,EAAM;IACtD;EACF;AACF;AAjCSvB;AAmCT,SAASwB,mBACPvB,MACAC,MACAuB,QAAoB;EAAEC,OAAO,CAAA;EAAIC,SAAS,CAAA;AAAG,GAAC;AAE9C,WAASC,SAASC,KAAkD;AAClE,WAAO;MACLd,IAAIc,IAAId;MACRH,QAAQ;MACRR,MAAM,6BAAMyB,IAAIzB,MAAV;MACNe,KAAK;QAAEjB,MAAM,GAAGA,IAAAA,IAAQ2B,IAAId,EAAE;MAAG;IACnC;EACF;AAPSa;AAST,WAASE,cAAcC,MAAkC;AACvD,WAAO;MACLA;MACAC,OAAOD,KAAKb,WAAW;MACvBe,MAAMF,KAAKb;MACXgB,YAAY,6BAAMH,KAAKI,IAAI,CAACN,SAAS;QAAEO,MAAM;QAAkBP;MAAI,EAAA,GAAvD;IACd;EACF;AAPSC;AAST,SAAO;IACL5B;IAEA2B,IAAId,IAAU;AACZrB,sBAAgBqB,IAAI,aAAA;AACpB,aAAOf,iBAAoBC,MAAM,GAAGC,IAAAA,IAAQa,EAAAA,EAAI;IAClD;IAEA,MAAMsB,IAAIjC,MAAO;AACf,YAAMkC,OAAO,MAAMrC,KAAKI,QAAwB,QAAQ,YAAYH,IAAAA,IAAQ;QAAEI,MAAMF;MAAK,CAAA;AACzF,UAAIkC,KAAK7B,SAAS,CAAC6B,KAAKlC,MAAM;AAC5B,eAAO;UAAEA,MAAM;UAAMK,OAAO6B,KAAK7B;UAAOC,QAAQ4B,KAAK5B;QAAO;MAC9D;AACA,aAAO;QACLN,MAAMJ,iBAAoBC,MAAM,GAAGC,IAAAA,IAAQoC,KAAKlC,KAAKW,EAAE,EAAE;QACzDN,OAAO;QACPC,QAAQ4B,KAAK5B;MACf;IACF;;;IAIAgB,MAAMa,OAAeC,IAA0BC,OAAc;AAC3D,aAAOjB,mBAAsBvB,MAAMC,MAAM;QACvC,GAAGuB;QACHC,OAAO;aAAID,MAAMC;UAAO;YAAEa;YAAOC;YAAIC;UAAM;;MAC7C,CAAA;IACF;IACAd,QAAQY,OAAeG,YAA4B,OAAK;AACtD,aAAOlB,mBAAsBvB,MAAMC,MAAM;QACvC,GAAGuB;QACHE,SAAS;aAAIF,MAAME;UAAS;YAAEY;YAAOG;UAAU;;MACjD,CAAA;IACF;IACAC,MAAMC,GAAS;AACb,aAAOpB,mBAAsBvB,MAAMC,MAAM;QAAE,GAAGuB;QAAOkB,OAAOC;MAAE,CAAA;IAChE;IAEA,MAAMrC,MAAAA;AACJ,YAAMsC,WACJpB,MAAMC,MAAMR,SAAS,KAAKO,MAAME,QAAQT,SAAS,KAAKO,MAAMkB,UAAU9B;AAExE,YAAMyB,OAAOO,WACT,MAAM5C,KAAKI,QACT,QACA,YAAYH,IAAAA,UACZ;QAAEI,MAAMwC,UAAUrB,KAAAA;MAAO,CAAA,IAE3B,MAAMxB,KAAKI,QACT,OACA,YAAYH,IAAAA,EAAM;AAGxB,UAAIoC,KAAK7B,MAAO,QAAO;QAAEL,MAAM;QAAMK,OAAO6B,KAAK7B;QAAOC,QAAQ4B,KAAK5B;MAAO;AAC5E,YAAMqB,QAAQO,KAAKlC,MAAM2C,aAAa,CAAA,GAAIZ,IAAIP,QAAAA;AAC9C,aAAO;QAAExB,MAAM0B,cAAcC,IAAAA;QAAOtB,OAAO;QAAMC,QAAQ4B,KAAK5B;MAAO;IACvE;EACF;AACF;AAjFSc;AAmFT,SAASsB,UAAUrB,OAAiB;AAClC,QAAMnB,OAAgC,CAAC;AACvC,MAAImB,MAAMC,MAAMR,SAAS,GAAG;AAC1BZ,SAAKoB,QAAQD,MAAMC,MAAMS,IAAI,CAACa,OAAO;MAAET,OAAOS,EAAET;MAAOC,IAAIQ,EAAER;MAAIC,OAAOO,EAAEP;IAAM,EAAA;EAClF;AACA,MAAIhB,MAAME,QAAQT,SAAS,GAAG;AAC5BZ,SAAKqB,UAAUF,MAAME,QAAQQ,IAAI,CAACc,OAAO;MAAEV,OAAOU,EAAEV;MAAOG,WAAWO,EAAEP;IAAU,EAAA;EACpF;AACA,MAAIjB,MAAMkB,UAAU9B,OAAWP,MAAKqC,QAAQlB,MAAMkB;AAClD,SAAOrC;AACT;AAVSwC;AAaT,IAAMI,YAAY;AAEX,SAASC,qBAAqBlD,MAAqB;AACxD,SAAO;;;;;;IAML4B,IAAuC3B,MAAY;AACjD,YAAMc,WAAWoC,OAAOlD,IAAAA,EACrBe,MAAM,GAAA,EACNoC,OAAO,CAACC,MAAMA,EAAEpC,SAAS,CAAA;AAC5B,UAAIF,SAASE,WAAW,KAAKF,SAASE,SAAS,MAAM,GAAG;AACtD,cAAM,IAAIpB,MACR,2BAA2BI,IAAAA,gDAAoDc,SAASE,MAAM,cAAc;MAEhH;AACAF,eAASuC,QAAQ,CAACD,GAAGE,MAAM9D,gBAAgB4D,GAAGE,IAAI,MAAM,IAAI,oBAAoB,aAAA,CAAA;AAChF,aAAOxD,iBAAoBC,MAAMe,SAASyC,KAAK,GAAA,CAAA;IACjD;IAEAnC,WAA8CC,MAAY;AACxD7B,sBAAgB6B,MAAM,iBAAA;AACtB,aAAOC,mBAAsBvB,MAAMsB,IAAAA;IACrC;IAEA,MAAMmC,MAAMC,YAAU;AAGpB,UAAIA,WAAWzC,SAASgC,WAAW;AACjC,eAAO;UACL9C,MAAM;UACNK,OAAO,IAAImD,mBACT,mBACA,cAAcD,WAAWzC,MAAM,uBAAuBgC,SAAAA,IACtD,GAAA;UAEFxC,QAAQ;QACV;MACF;AACA,UAAIiD,WAAWzC,WAAW,EAAG,QAAO;QAAEd,MAAM;QAAMK,OAAO;QAAMC,QAAQ;MAAI;AAE3E,aAAOT,KAAKI,QAAc,QAAQ,kBAAkB;QAClDC,MAAMqD,WAAWxB,IAAI,CAACK,QAAQ;UAAEA,IAAIA,GAAGA;UAAItC,MAAMsC,GAAGrB,IAAIjB;UAAME,MAAMoC,GAAGpC;QAAK,EAAA;MAC9E,CAAA;IACF;EACF;AACF;AA9CgB+C;;;AClKhB,IAAMU,eAAe;AAOrB,SAASC,eAAeC,UAAgB;AACtC,MAAI,CAACF,aAAaG,KAAKD,QAAAA,GAAW;AAChC,UAAM,IAAIE,MAAM,uBAAuBF,QAAAA,4BAAoCF,aAAaK,MAAM,EAAE;EAClG;AACF;AAJSJ;AAOT,SAASK,YAAYC,OAAc;AACjC,MAAI,OAAOA,UAAU,UAAW,QAAOA;AACvC,SAAOA,SAAS,QAAQA,UAAU,KAAKA,UAAU;AACnD;AAHSD;AAKT,SAASE,YAAYD,OAAc;AACjC,SAAO,OAAOA,UAAU,WAAW;IAAEE,MAAMF;EAAM,IAAI;AACvD;AAFSC;AAST,SAASE,gBAAgBC,GAAU;AACjC,SACEA,MAAM,QAAQ,OAAOA,MAAM,YAAY,CAACC,MAAMC,QAAQF,CAAAA,MAAO,YAAYA,KAAK,gBAAgBA;AAElG;AAJSD;AAUF,SAASI,iBAAiBC,MAAuBC,KAAgB;AAKtE,WAASC,cAAcC,SAA4B;AACjD,QAAIA,WAAW,YAAYA,QAAS,QAAOA,QAAQC,UAAU;AAC7D,WAAOH,IAAII,iBAAgB,KAAMC;EACnC;AAHSJ;AAKT,WAASK,WAAWJ,SAA4B;AAC9C,UAAMK,MAAMN,cAAcC,OAAAA;AAC1B,WAAOK,MAAM,wBAAwBC,mBAAmBD,GAAAA,CAAAA,KAAS;EACnE;AAHSD;AAKT,WAASG,YAAYP,SAA4B;AAC/C,WAAOH,KAAKW,QAAwB,OAAOJ,WAAWJ,OAAAA,CAAAA;EACxD;AAFSO;AAIT,QAAME,UAAqC;IACzC,MAAMC,mBAAmBT,QAAQU,KAAKtB,OAAK;AACzC,aAAOQ,KAAKW,QACV,OACA,wBAAwBF,mBAAmBL,MAAAA,CAAAA,IAAWK,mBAAmBK,GAAAA,CAAAA,IACzE;QAAEC,MAAM;UAAEvB;QAAM;MAAE,CAAA;IAEtB;IACA,MAAMwB,oBAAoBZ,QAAQa,QAAM;AACtC,aAAOjB,KAAKW,QAAQ,OAAO,wBAAwBF,mBAAmBL,MAAAA,CAAAA,IAAW;QAC/EW,MAAM;UAAEE;QAAO;MACjB,CAAA;IACF;IACA,MAAMC,qBAAqBd,QAAQU,KAAG;AACpC,aAAOd,KAAKW,QACV,UACA,wBAAwBF,mBAAmBL,MAAAA,CAAAA,IAAWK,mBAAmBK,GAAAA,CAAAA,EAAM;IAEnF;IACA,MAAMK,yBAAyBf,QAAM;AACnC,aAAOJ,KAAKW,QAAQ,UAAU,wBAAwBF,mBAAmBL,MAAAA,CAAAA,EAAS;IACpF;IACA,MAAMgB,kBAAkBC,YAAwD;AAI9E,YAAMC,OAAOD,cAAc,CAAA,GAAIE,IAAI,CAACC,OAAAA;AAClC,cAAMC,OAAMD;AACZ,eAAO;UAAEE,SAASD,KAAIrB,UAAUqB,KAAIC;UAAST,QAAQQ,KAAIR;QAAO;MAClE,CAAA;AACA,aAAOjB,KAAKW,QAAQ,QAAQ,wBAAwB;QAAEI,MAAM;UAAEM,YAAYC;QAAI;MAAE,CAAA;IAClF;EACF;AAEA,SAAO;IACL,MAAMK,UAAUxC,UAAkBgB,SAA4B;AAC5DjB,qBAAeC,QAAAA;AACf,YAAMyC,MAAM,MAAMlB,YAAYP,OAAAA;AAC9B,UAAIyB,IAAIC,SAASD,IAAIE,QAAQ,KAAM,QAAO;QAAEA,MAAM;QAAMD,OAAOD,IAAIC;QAAOE,QAAQH,IAAIG;MAAO;AAC7F,aAAO;QAAED,MAAMvC,YAAYqC,IAAIE,KAAKb,SAAS9B,QAAAA,CAAS;QAAG0C,OAAO;QAAME,QAAQH,IAAIG;MAAO;IAC3F;IAEA,MAAMC,WAAW7C,UAAkBgB,SAA4B;AAC7DjB,qBAAeC,QAAAA;AACf,YAAMyC,MAAM,MAAMlB,YAAYP,OAAAA;AAI9B,UAAIyB,IAAIC,SAASD,IAAIE,QAAQ,KAAM,QAAO;QAAEA,MAAM;QAAMD,OAAOD,IAAIC;QAAOE,QAAQH,IAAIG;MAAO;AAC7F,aAAO;QAAED,MAAMrC,YAAYmC,IAAIE,KAAKb,SAAS9B,QAAAA,CAAS;QAAG0C,OAAO;QAAME,QAAQH,IAAIG;MAAO;IAC3F;;;;;;;;IASA,MAAME,IACJ9C,UACA+C,kBACAC,cAAiC;AAEjCjD,qBAAeC,QAAAA;AAEf,UAAIiD;AACJ,UAAIjC;AACJ,UAAIkC,aAAa;AACjB,UAAIF,iBAAiB7B,QAAW;AAC9B8B,uBAAeF;AACfG,qBAAa;AACblC,kBAAUgC;MACZ,WAAWxC,gBAAgBuC,gBAAAA,GAAmB;AAC5C/B,kBAAU+B;MACZ,WAAWA,qBAAqB5B,QAAW;AACzC8B,uBAAeF;AACfG,qBAAa;MACf;AAEA,YAAMC,OAAO,MAAM5B,YAAYP,OAAAA;AAC/B,UAAImC,KAAKT,UAAU,MAAM;AACvB,YAAIQ,WAAY,QAAO;UAAEP,MAAMM,gBAAgB;UAAMP,OAAO;UAAME,QAAQO,KAAKP;QAAO;AACtF,eAAO;UAAED,MAAM;UAAMD,OAAOS,KAAKT;UAAOE,QAAQO,KAAKP;QAAO;MAC9D;AACA,YAAMd,SAASqB,KAAKR,MAAMb,UAAU,CAAC;AACrC,YAAMzB,QAAQyB,OAAO9B,QAAAA;AAErB,UAAIK,UAAUc,QAAW;AACvB,eAAO;UAAEwB,MAAMO,aAAcD,gBAAgB,OAAQ;UAAMP,OAAO;UAAME,QAAQO,KAAKP;QAAO;MAC9F;AACA,aAAO;QAAED,MAAMtC;QAAOqC,OAAO;QAAME,QAAQO,KAAKP;MAAO;IACzD;IAEA,MAAMQ,OAAOpC,SAA4B;AACvC,YAAMyB,MAAM,MAAMlB,YAAYP,OAAAA;AAC9B,UAAIyB,IAAIC,SAASD,IAAIE,QAAQ,KAAM,QAAO;QAAEA,MAAM;QAAMD,OAAOD,IAAIC;QAAOE,QAAQH,IAAIG;MAAO;AAC7F,YAAMd,SAASW,IAAIE,KAAKb,UAAU,CAAC;AACnC,aAAO;QACLa,MAAMU,OAAOC,KAAKxB,MAAAA,EAAQM,IAAI,CAAC7B,SAAAA;AAC7B,gBAAMF,QAAQyB,OAAOvB,IAAAA;AACrB,gBAAMgD,OAAuE;YAC3EhD;YACAiD,SAASpD,YAAYC,KAAAA;UACvB;AACA,cAAI,OAAOA,UAAU,SAAUkD,MAAKE,UAAU;YAAElD,MAAMF;UAAM;AAC5D,iBAAOkD;QACT,CAAA;QACAb,OAAO;QACPE,QAAQH,IAAIG;MACd;IACF;;;;;;;IAQA,MAAMc,YAAY/B,KAAatB,OAAuB;AACpD,YAAMgB,MAAMP,IAAII,iBAAgB;AAChC,UAAI,CAACG,KAAK;AACR,eAAO;UACLsB,MAAM;UACND,OAAO;YACLiB,SACE;UACJ;UACAf,QAAQ;QACV;MACF;AACA,aAAO/B,KAAKW,QACV,OACA,wBAAwBF,mBAAmBD,GAAAA,CAAAA,IAAQC,mBAAmBK,GAAAA,CAAAA,IACtE;QAAEC,MAAM;UAAEvB;QAAM;MAAE,CAAA;IAEtB;IAEAuD,YAAAA;AACE,aAAOnC;IACT;EACF;AACF;AAjKgBb;;;AChChB,SAASiD,YAAqBC,KAAwBC,KAAsB;AAC1E,MAAID,IAAIE,UAAU,QAAQF,IAAIG,SAAS,QAAQH,IAAIG,SAASC,QAAW;AACrE,WAAO;MAAED,MAAM;MAAMD,OAAOF,IAAIE;MAAOG,QAAQL,IAAIK;IAAO;EAC5D;AACA,SAAO;IAAEF,MAAMF,IAAID,IAAIG,IAAI;IAAGD,OAAO;IAAMG,QAAQL,IAAIK;EAAO;AAChE;AALSN;AAST,SAASO,gBAAgBC,MAAU;AACjC,QAAMC,OAA6B;IACjCC,IAAIF,KAAKE;IACTC,MAAMH,KAAKG;IACXC,QAAQJ,KAAKI;IACbC,SAASL,KAAKK;IACdC,UAAUN,KAAKO;IACfC,WAAYR,KAAKQ,aAA0B,CAAA;IAC3CC,WAAWT,KAAKU;IAChBC,WAAWX,KAAKY;IAChBC,WAAWb,KAAKc;EAClB;AACA,MAAId,KAAKe,cAAclB,OAAWI,MAAKe,WAAWhB,KAAKe;AACvD,SAAOd;AACT;AAdSF;AAgBT,SAASkB,cAAcjB,MAAU;AAC/B,SAAO;IACLE,IAAIF,KAAKE;IACTC,MAAMH,KAAKG;IACXC,QAAQJ,KAAKI;IACbc,MAAMlB,KAAKkB;IACXV,WAAYR,KAAKQ,aAA0B,CAAA;IAC3CC,WAAWT,KAAKU;IAChBC,WAAWX,KAAKY;IAChBC,WAAWb,KAAKc;EAClB;AACF;AAXSG;AAaF,SAASE,yBAAyBC,MAAqB;AAC5D,QAAMC,OAA0B;IAC9B,MAAMC,KAAKC,QAAM;AACf,aAAOH,KAAKI,QAAQ,QAAQ,0BAA0B;QAAEN,MAAMK;MAAO,CAAA;IACvE;EACF;AAEA,QAAME,QAA4B;IAChC,MAAMH,KAAKC,QAAM;AAIf,YAAM,EAAEG,cAAcC,MAAMC,MAAAA,OAAM,GAAGC,KAAAA,IAASN;AAC9C,YAAML,OAAgC;QAAE,GAAGW;MAAK;AAChD,UAAIH,iBAAiB7B,OAAWqB,MAAKY,gBAAgBJ;AACrD,UAAIC,SAAS9B,OAAWqB,MAAKX,YAAYoB;AACzC,UAAIC,UAAS/B,OAAWqB,MAAKH,YAAYa;AACzC,aAAOR,KAAKI,QAAQ,QAAQ,2BAA2B;QAAEN;MAAK,CAAA;IAChE;EACF;AAEA,QAAMa,MAAwB;IAC5B,MAAMT,KAAKC,QAAM;AACf,YAAM,EAAEG,cAAc,GAAGG,KAAAA,IAASN;AAClC,YAAML,OAAOQ,iBAAiB7B,SAAY;QAAE,GAAGgC;QAAMC,eAAeJ;MAAa,IAAIG;AACrF,aAAOT,KAAKI,QAAQ,QAAQ,yBAAyB;QAAEN;MAAK,CAAA;IAC9D;EACF;AAEA,QAAMc,WAAkC;IACtC,MAAMV,KAAKC,QAAM;AACf,YAAM,EAAEG,cAAcO,QAAQ,GAAGJ,KAAAA,IAASN;AAC1C,YAAML,OAAO;QACX,GAAGW;QACH,GAAIH,iBAAiB7B,SAAY,CAAC,IAAI;UAAEiC,eAAeJ;QAAa;QACpE,GAAIO,WAAWpC,SAAY,CAAC,IAAI;UAAEqC,SAASD;QAAO;MACpD;AACA,aAAOb,KAAKI,QAAQ,QAAQ,8BAA8B;QAAEN;MAAK,CAAA;IACnE;IACA,MAAMiB,OAAOC,UAAU,CAAC,GAAC;AACvB,YAAMC,QAAQD,QAAQE,UAAUzC,SAAY,KAAK,UAAU0C,mBAAmBC,OAAOJ,QAAQE,KAAK,CAAA,CAAA;AAClG,aAAOlB,KAAKI,QAAQ,OAAO,oCAAoCa,KAAAA,EAAO;IACxE;EACF;AAIA,QAAMI,gBAA4C;IAChD,MAAMC,MAAMnB,QAAM;AAChB,aAAOH,KAAKI,QAAQ,QAAQ,mCAAmC;QAAEN,MAAMK;MAAO,CAAA;IAChF;IACA,MAAMoB,MAAMpB,QAAM;AAChB,aAAOH,KAAKI,QAAQ,QAAQ,yCAAyC;QAAEN,MAAMK;MAAO,CAAA;IACtF;EACF;AAEA,QAAMqB,QAA4B;IAChC,MAAMtB,KAAKC,QAAM;AACf,aAAOH,KAAKI,QAAQ,QAAQ,2BAA2B;QAAEN,MAAMK;MAAO,CAAA;IACxE;IACA,MAAMsB,KAAKT,SAMV;AACC,YAAMU,OAAOV,WAAW,CAAC;AACzB,YAAMb,SAAS,IAAIwB,gBAAAA;AACnB,UAAID,KAAKE,OAAQzB,QAAO0B,IAAI,UAAUH,KAAKE,MAAM;AACjD,UAAIF,KAAKR,UAAUzC,OAAW0B,QAAO0B,IAAI,SAAST,OAAOM,KAAKR,KAAK,CAAA;AACnE,UAAIQ,KAAKI,YAAYrD,OAAW0B,QAAO0B,IAAI,WAAWH,KAAKI,UAAU,SAAS,OAAA;AAC9E,UAAIJ,KAAKK,SAAU5B,QAAO0B,IAAI,YAAYH,KAAKK,QAAQ;AACvD,UAAIL,KAAKM,iBAAkB7B,QAAO0B,IAAI,oBAAoB,MAAA;AAC1D,YAAMZ,QAAQd,OAAO8B,SAAQ;AAC7B,aAAOjC,KAAKI,QAAQ,OAAO,0BAA0Ba,QAAQ,IAAIA,KAAAA,KAAU,EAAA,EAAI;IACjF;IACA,MAAMiB,cAAAA;AACJ,aAAOlC,KAAKI,QAAQ,OAAO,sCAAA;IAC7B;IACA,MAAM+B,SAASrD,IAAU;AACvB,aAAOkB,KAAKI,QAAQ,SAAS,2BAA2Be,mBAAmBrC,EAAAA,CAAAA,OAAU;IACvF;IACA,MAAMsD,cAAAA;AACJ,aAAOpC,KAAKI,QAAQ,QAAQ,kCAAA;IAC9B;IACA,MAAMiC,QAAQvD,IAAU;AACtB,aAAOkB,KAAKI,QAAQ,UAAU,2BAA2Be,mBAAmBrC,EAAAA,CAAAA,EAAK;IACnF;EACF;AAEA,QAAMwD,cAAwC;IAC5C,MAAMC,MAAAA;AACJ,aAAOvC,KAAKI,QAAQ,OAAO,+BAAA;IAC7B;IACA,MAAMoC,OAAOrC,QAAM;AACjB,aAAOH,KAAKI,QAAQ,OAAO,iCAAiC;QAAEN,MAAMK;MAAO,CAAA;IAC7E;EACF;AAEA,QAAMsC,iBAA8C;IAClD,MAAMhB,OAAAA;AACJ,YAAMiB,OAAO,MAAM1C,KAAKI,QAAgB,OAAO,6BAAA;AAC/C,aAAOhC,YAAYsE,MAAM,CAACC,UAAUA,QAAQ,CAAA,GAAIrE,IAAIK,eAAAA,CAAAA;IACtD;IACA,MAAM4D,IAAIzD,IAAU;AAClB,YAAM4D,OAAO,MAAM1C,KAAKI,QACtB,OACA,+BAA+Be,mBAAmBrC,EAAAA,CAAAA,EAAK;AAEzD,aAAOV,YAAYsE,MAAM/D,eAAAA;IAC3B;IACA,MAAMiE,OAAOC,OAAmG;AAC9G,YAAM/C,OAAgC;QACpCf,MAAM8D,MAAM9D;QACZE,SAAS4D,MAAM5D;QACfE,WAAW0D,MAAM3D;MACnB;AACA,UAAI2D,MAAMjD,aAAanB,OAAWqB,MAAKH,YAAYkD,MAAMjD;AACzD,UAAIiD,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QAAc,QAAQ,+BAA+B;QAAEN;MAAK,CAAA;AACpF,aAAO1B,YAAYsE,MAAM/D,eAAAA;IAC3B;IACA,MAAM6D,OACJ1D,IACA+D,OAAuF;AAEvF,YAAM/C,OAAgC,CAAC;AACvC,UAAI+C,MAAM5D,YAAYR,OAAWqB,MAAKb,UAAU4D,MAAM5D;AACtD,UAAI4D,MAAM3D,aAAaT,OAAWqB,MAAKX,YAAY0D,MAAM3D;AACzD,UAAI2D,MAAMjD,aAAanB,OAAWqB,MAAKH,YAAYkD,MAAMjD;AACzD,UAAIiD,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QACtB,OACA,+BAA+Be,mBAAmBrC,EAAAA,CAAAA,IAClD;QAAEgB;MAAK,CAAA;AAET,aAAO1B,YAAYsE,MAAM/D,eAAAA;IAC3B;IACA,MAAMmE,OAAOhE,IAAU;AACrB,aAAOkB,KAAKI,QAAQ,UAAU,+BAA+Be,mBAAmBrC,EAAAA,CAAAA,EAAK;IACvF;EACF;AAEA,QAAMiE,eAA0C;IAC9C,MAAMtB,OAAAA;AACJ,YAAMiB,OAAO,MAAM1C,KAAKI,QAAgB,OAAO,iCAAA;AAC/C,aAAOhC,YAAYsE,MAAM,CAACC,UAAUA,QAAQ,CAAA,GAAIrE,IAAIuB,aAAAA,CAAAA;IACtD;IACA,MAAM0C,IAAIzD,IAAU;AAClB,YAAM4D,OAAO,MAAM1C,KAAKI,QACtB,OACA,mCAAmCe,mBAAmBrC,EAAAA,CAAAA,EAAK;AAE7D,aAAOV,YAAYsE,MAAM7C,aAAAA;IAC3B;IACA,MAAM+C,OAAOC,OAA2D;AACtE,YAAM/C,OAAgC;QAAEf,MAAM8D,MAAM9D;QAAMe,MAAM+C,MAAM/C;MAAK;AAC3E,UAAI+C,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QAAc,QAAQ,mCAAmC;QAAEN;MAAK,CAAA;AACxF,aAAO1B,YAAYsE,MAAM7C,aAAAA;IAC3B;IACA,MAAM2C,OAAO1D,IAAY+D,OAA8C;AACrE,YAAM/C,OAAgC,CAAC;AACvC,UAAI+C,MAAM/C,SAASrB,OAAWqB,MAAKA,OAAO+C,MAAM/C;AAChD,UAAI+C,MAAMzD,cAAcX,OAAWqB,MAAKV,YAAYyD,MAAMzD;AAC1D,YAAMsD,OAAO,MAAM1C,KAAKI,QACtB,OACA,mCAAmCe,mBAAmBrC,EAAAA,CAAAA,IACtD;QAAEgB;MAAK,CAAA;AAET,aAAO1B,YAAYsE,MAAM7C,aAAAA;IAC3B;IACA,MAAMiD,OAAOhE,IAAU;AACrB,aAAOkB,KAAKI,QAAQ,UAAU,mCAAmCe,mBAAmBrC,EAAAA,CAAAA,EAAK;IAC3F;EACF;AAEA,SAAO;IACLmB;IACAI;IACAM;IACAC;IACAS;IACAG;IACAc;IACAU,WAAW;MAAE3C,OAAOoC;MAAgB9B,KAAKoC;IAAa;IACtD,MAAME,eAAe9C,QAAM;AACzB,aAAOH,KAAKI,QAAQ,QAAQ,6BAA6B;QAAEN,MAAMK;MAAO,CAAA;IAC1E;IACA,MAAM+C,iBAAiBC,UAAgB;AACrC,aAAOnD,KAAKI,QAAQ,UAAU,6BAA6Be,mBAAmBgC,QAAAA,CAAAA,EAAW;IAC3F;EACF;AACF;AAlMgBpD;;;ACxDhB,yBAA2B;AAsB3B,SAASqD,UAAUC,QAAc;AAC/B,QAAMC,OAAMC,KAAKC,MAAMC,KAAKH,IAAG,IAAK,GAAA;AACpC,QAAMI,SAASC,OAAOC,KAAKC,KAAKC,UAAU;IAAEC,KAAK;IAASC,KAAK;EAAM,CAAA,CAAA,EAAIC,SAAS,WAAA;AAClF,QAAMC,UAAUP,OAAOC,KACrBC,KAAKC,UAAU;IAAEK,KAAK;IAAmBC,MAAM;IAAgBC,KAAKf;IAAKgB,KAAKhB,OAAM;EAAG,CAAA,CAAA,EACvFW,SAAS,WAAA;AACX,QAAMM,UAAMC,+BAAW,UAAUnB,MAAAA,EAAQoB,OAAO,GAAGf,MAAAA,IAAUQ,OAAAA,EAAS,EAAEQ,OAAO,WAAA;AAC/E,SAAO,GAAGhB,MAAAA,IAAUQ,OAAAA,IAAWK,GAAAA;AACjC;AARSnB;AAUF,SAASuB,oBAAoBC,KAAmB;AACrD,QAAMC,MAAM,GAAGD,IAAIE,OAAO;AAC1B,QAAMC,WAAW,GAAGH,IAAIE,OAAO;AAK/B,iBAAeE,WACbC,OACAC,KACAC,OACAC,KAAY;AAEZ,QAAI,OAAOH,UAAU,YAAYA,MAAMI,WAAW,GAAG;AACnD,aAAO;QACLC,MAAM;QACNC,OAAO,IAAIC,mBAAmB,oBAAoB,oCAAoC,GAAA;MACxF;IACF;AACA,QAAI,OAAON,QAAQ,YAAYA,IAAIG,WAAW,GAAG;AAC/C,aAAO;QACLC,MAAM;QACNC,OAAO,IAAIC,mBAAmB,oBAAoB,kCAAkC,GAAA;MACtF;IACF;AACA,QAAI,CAACZ,IAAIa,cAAc;AACrB,aAAO;QACLH,MAAM;QACNC,OAAO,IAAIC,mBACT,yBACA,4HAEA,GAAA;MAEJ;IACF;AAEA,QAAIE;AACJ,QAAI;AACFA,cAAQtC,UAAUwB,IAAIa,YAAY;IACpC,SAASE,KAAK;AACZ,aAAO;QACLL,MAAM;QACNC,OAAO,IAAIC,mBACT,wBACAG,eAAeC,QAAQD,IAAIE,UAAU,qBACrC,GAAA;MAEJ;IACF;AAEA,UAAMC,KAAKV,MAAM;MAAEH;MAAOC;MAAKE,KAAK;IAAK,IAAI;MAAEH;MAAOC;MAAKC,OAAOA,SAAS,CAAC;IAAE;AAC9E,UAAMY,UAAUnB,IAAIoB,aAAaC,WAAWC;AAC5C,QAAIC;AACJ,QAAI;AACFA,iBAAW,MAAMJ,QAAQhB,UAAU;QACjCqB,QAAQ;QACRC,SAAS;UAAE,gBAAgB;UAAoBC,eAAe,UAAUZ,KAAAA;QAAQ;QAChFa,MAAM1C,KAAKC,UAAU;UAAE0C,KAAK;YAACV;;QAAI,CAAA;MACnC,CAAA;IACF,SAASH,KAAK;AACZ,aAAO;QACLL,MAAM;QACNC,OAAO,IAAIC,mBACT,iBACAG,eAAeC,QAAQD,IAAIE,UAAU,wBACrC,CAAA;MAEJ;IACF;AACA,QAAIM,SAASM,WAAW,OAAON,SAASM,WAAW,KAAK;AACtD,aAAO;QAAEnB,MAAMoB;QAAWnB,OAAO;MAAK;IACxC;AACA,UAAMoB,SAAS,MAAMR,SAASS,KAAI,EAAGC,MAAM,MAAM,EAAA;AACjD,WAAO;MACLvB,MAAM;MACNC,OAAO,IAAIC,mBACT,yBACA,iCAAiCW,SAASM,MAAM,GAAGE,SAAS,KAAKA,MAAAA,KAAW,EAAA,IAC5ER,SAASM,MAAM;IAEnB;EACF;AA3EezB;AA6Ef,SAAO;IACL8B,OAAO;;;;;;;;MAQLC,KAAK,wBAAC9B,OAAeC,KAAaC,UAChCH,WAAWC,OAAOC,KAAKC,OAAO,KAAA,GAD3B;;MAGL6B,OAAO,wBAAC/B,OAAeC,QAAgBF,WAAWC,OAAOC,KAAKwB,QAAW,IAAA,GAAlE;IACT;IAEA,MAAMO,UAAUC,SAAiBC,OAAejD,SAAiC;AAG/E,UAAI,OAAOgD,YAAY,YAAYA,QAAQ7B,WAAW,GAAG;AACvD,eAAO;UACLC,MAAM;UACNC,OAAO,IAAIC,mBAAmB,oBAAoB,sCAAsC,GAAA;QAC1F;MACF;AACA,UAAI,OAAO2B,UAAU,YAAYA,MAAM9B,WAAW,GAAG;AACnD,eAAO;UACLC,MAAM;UACNC,OAAO,IAAIC,mBAAmB,oBAAoB,oCAAoC,GAAA;QACxF;MACF;AACA,UAAI,CAACZ,IAAIa,cAAc;AACrB,eAAO;UACLH,MAAM;UACNC,OAAO,IAAIC,mBACT,yBACA,gIAEA,GAAA;QAEJ;MACF;AAEA,UAAIE;AACJ,UAAI;AACFA,gBAAQtC,UAAUwB,IAAIa,YAAY;MACpC,SAASE,KAAK;AACZ,eAAO;UACLL,MAAM;UACNC,OAAO,IAAIC,mBACT,wBACAG,eAAeC,QAAQD,IAAIE,UAAU,qBACrC,GAAA;QAEJ;MACF;AAIA,YAAMU,OAAO1C,KAAKC,UAAU;QAC1BsD,UAAU;UAAC;YAAEnC,OAAOiC;YAASC;YAAOjD,SAASA,WAAW,CAAC;YAAGmD,SAAS;UAAM;;MAC7E,CAAA;AAEA,YAAMtB,UAAUnB,IAAIoB,aAAaC,WAAWC;AAC5C,UAAIC;AACJ,UAAI;AACFA,mBAAW,MAAMJ,QAAQlB,KAAK;UAC5BuB,QAAQ;UACRC,SAAS;YAAE,gBAAgB;YAAoBC,eAAe,UAAUZ,KAAAA;UAAQ;UAChFa;QACF,CAAA;MACF,SAASZ,KAAK;AAKZ,eAAO;UACLL,MAAM;UACNC,OAAO,IAAIC,mBACT,iBACAG,eAAeC,QAAQD,IAAIE,UAAU,4BACrC,CAAA;QAEJ;MACF;AAEA,UAAIM,SAASM,WAAW,OAAON,SAASM,WAAW,KAAK;AACtD,eAAO;UAAEnB,MAAMoB;UAAWnB,OAAO;QAAK;MACxC;AAEA,YAAMoB,SAAS,MAAMR,SAASS,KAAI,EAAGC,MAAM,MAAM,EAAA;AACjD,aAAO;QACLvB,MAAM;QACNC,OAAO,IAAIC,mBACT,6BACA,sBAAsBW,SAASM,MAAM,KAAKE,OAAOW,MAAM,GAAG,GAAA,CAAA,IAC1DnB,SAASM,MAAM;MAEnB;IACF;EACF;AACF;AAxLgB9B;;;ACvBhB,IAAM4C,iBAAiB;AAEvB,IAAMC,kBAAkB;AACxB,IAAMC,uBAAuB;AAQ7B,SAASC,oBAAoBC,GAAS;AACpC,MAAI,CAACH,gBAAgBI,KAAKD,CAAAA,KAAMF,qBAAqBG,KAAKD,CAAAA,GAAI;AAC5D,UAAM,IAAIE,MACR,uBAAuBF,CAAAA,gEAAiEH,gBAAgBM,MAAM,EAAE;EAEpH;AACF;AANSJ;AAiBT,SAASK,aAAaC,QAAgBC,KAA4B;AAChE,SAAO;IACLC,MAAOD,IAAIE,QAAmB;IAC9BA,MAAOF,IAAIE,QAAmB;IAC9BH,QAASC,IAAID,UAAqBA;IAClCI,MAAM,OAAOH,IAAIG,SAAS,WAAWH,IAAIG,OAAO;IAChDC,aAAcJ,IAAII,eAA0B;IAC5CC,UAAWL,IAAIK,YAAuB;IACtCC,OAAON,IAAIM;IACXC,QAAQP,IAAIO;IACZC,WAAWR,IAAIQ;IACfC,UAAWT,IAAIS,YAAuC,CAAC;EACzD;AACF;AAbSX;AAgBT,SAASY,YACPC,KACAC,KAAsB;AAEtB,MAAID,IAAIE,SAASF,IAAIG,SAAS,QAAQH,IAAIG,SAASC,QAAW;AAC5D,WAAO;MAAED,MAAM;MAAMD,OAAOF,IAAIE;MAAOG,QAAQL,IAAIK;IAAO;EAC5D;AACA,SAAO;IAAEF,MAAMF,IAAID,IAAIG,IAAI;IAAGD,OAAO;IAAMG,QAAQL,IAAIK;EAAO;AAChE;AARSN;AAUT,SAASO,kBACPC,MACAC,YACAC,cAAoB;AAEpB,QAAMC,aAAa,wBAACnB,SAAiB,sBAAsBiB,UAAAA,IAAcjB,IAAAA,IAAtD;AAEnB,SAAO;IACL,MAAMoB,OAAOpB,MAAMqB,MAAMC,SAA8B;AACrD/B,0BAAoBS,IAAAA;AACpB,YAAMuB,UAAkC;QACtC,gBAAgBD,SAASpB,eAAe;MAC1C;AACA,UAAIoB,SAASE,OAAQD,SAAQ,UAAA,IAAc;AAI3C,YAAME,OAAOJ,gBAAgBK,cAAc,IAAIC,WAAWN,IAAAA,IAAQA;AAClE,YAAMZ,MAAM,MAAMO,KAAKY,QAAiC,OAAOT,WAAWnB,IAAAA,GAAO;QAC/EyB;QACAF;MACF,CAAA;AACA,aAAOf,YAAYC,KAAK,CAACoB,MAAMjC,aAAaqB,YAAYY,KAAK,CAAC,CAAA,CAAA;IAChE;IAEA,MAAMC,SAAS9B,MAAI;AACjBT,0BAAoBS,IAAAA;AAKpB,aAAOgB,KAAKY,QAAc,OAAOT,WAAWnB,IAAAA,GAAO;QAAEuB,SAAS;UAAEQ,QAAQ;QAAM;MAAE,CAAA;IAClF;IAEAC,aAAahC,MAAMsB,SAAO;AACxB/B,0BAAoBS,IAAAA;AACpB,YAAMiC,UAAUX,SAASW,UAAU,YAAYC,mBAAmBZ,QAAQW,OAAO,CAAA,KAAM;AAqBvF,UAAI,CAACf,cAAc;AAKjB,cAAM,IAAIxB,MACR,mBAAmBuB,UAAAA,8LAEjB;MAEN;AACA,aAAO,GAAGC,YAAAA,aAAyBD,UAAAA,IAAcjB,IAAAA,GAAOiC,OAAAA;IAC1D;IAEA,MAAME,gBAAgBnC,MAAMsB,SAAO;AACjC/B,0BAAoBS,IAAAA;AAIpB,aAAOgB,KAAKY,QAAkC,QAAQ,oBAAoBX,UAAAA,IAAcjB,IAAAA,IAAQ;QAC9FyB,MAAM;UAAEW,WAAWd,QAAQc;QAAU;MACvC,CAAA;IACF;IAEA,MAAMC,KAAKC,QAAiBhB,SAA4B;AACtD,UAAIgB,OAAQ/C,qBAAoB+C,MAAAA;AAChC,YAAMC,SAAS,IAAIC,gBAAAA;AACnB,UAAIF,OAAQC,QAAOE,IAAI,UAAUH,MAAAA;AACjC,UAAIhB,SAASoB,UAAU7B,OAAW0B,QAAOE,IAAI,SAASE,OAAOrB,QAAQoB,KAAK,CAAA;AAC1E,YAAME,QAAQL,OAAOM,SAAQ;AAC7B,YAAMpC,MAAM,MAAMO,KAAKY,QACrB,OACA,sBAAsBX,UAAAA,GAAa2B,QAAQ,IAAIA,KAAAA,KAAU,EAAA,EAAI;AAI/D,aAAOpC,YAAYC,KAAK,CAACgB,UAAUA,MAAMqB,WAAW,CAAA,GAAIpC,IAAI,CAACZ,QAAQF,aAAaqB,YAAYnB,GAAAA,CAAAA,CAAAA;IAChG;IAEA,MAAMiD,OAAOC,OAAK;AAChB,iBAAWxD,KAAKwD,MAAOzD,qBAAoBC,CAAAA;AAK3C,YAAMyD,UAA+B,CAAA;AACrC,iBAAWzD,KAAKwD,OAAO;AACrB,cAAMvC,MAAM,MAAMO,KAAKY,QAAc,UAAUT,WAAW3B,CAAAA,CAAAA;AAC1D,YAAIiB,IAAIE,MAAO,QAAO;UAAEC,MAAM;UAAMD,OAAOF,IAAIE;UAAOG,QAAQL,IAAIK;QAAO;AACzEmC,gBAAQC,KAAKtD,aAAaqB,YAAY;UAAEjB,MAAMR;QAAE,CAAA,CAAA;MAClD;AACA,aAAO;QAAEoB,MAAMqC;QAAStC,OAAO;QAAMG,QAAQ;MAAI;IACnD;IAEA,MAAMqC,KAAKC,MAAMC,IAAE;AACjB9D,0BAAoB6D,IAAAA;AACpB7D,0BAAoB8D,EAAAA;AACpB,aAAOrC,KAAKY,QAAc,QAAQ,oBAAoBX,UAAAA,IAAc;QAAEQ,MAAM;UAAE2B;UAAMC;QAAG;MAAE,CAAA;IAC3F;IAEA,MAAMC,KAAKF,MAAMC,IAAE;AACjB9D,0BAAoB6D,IAAAA;AACpB7D,0BAAoB8D,EAAAA;AACpB,aAAOrC,KAAKY,QAAc,QAAQ,oBAAoBX,UAAAA,IAAc;QAAEQ,MAAM;UAAE2B;UAAMC;QAAG;MAAE,CAAA;IAC3F;EACF;AACF;AA3HStC;AAkIF,SAASwC,mBACdvC,MACAE,cAAoB;AAEpB,SAAO;IACLrB,OAAOE,MAAY;AACjB,UAAI,CAACX,eAAeK,KAAKM,IAAAA,GAAO;AAC9B,cAAM,IAAIL,MAAM,yBAAyBK,IAAAA,8BAAkCX,eAAeO,MAAM,EAAE;MACpG;AAIA,aAAOoB,kBAAkBC,MAAMjB,MAAMmB,aAAasC,QAAQ,QAAQ,EAAA,CAAA;IACpE;EACF;AACF;AAfgBD;;;AC7IT,SAASE,mBAAmBC,KAAwB;AACzD,QAAMC,WAAWD,IAAIC,WAAW,IAAIC,QAAQ,QAAQ,EAAA;AACpD,MAAI,CAACD,QAAS,QAAO,CAAC;AAItB,QAAME,SAASH,IAAII,kBAAkBJ,IAAIG,UAAU;AACnD,QAAME,OAAOC,eAAe;IAAEL;IAASE;IAAQI,WAAWP,IAAIO;EAAU,CAAA;AAExE,SAAO;;;;IAILC,MAAMC,gBAAgBJ,IAAAA;IACtBK,WAAWC,qBAAqBN,IAAAA;IAChCO,SAASC,mBAAmBR,MAAML,IAAIc,YAAY;IAClDC,eAAeC,yBAAyBX,IAAAA;IACxCY,OAAOC,iBAAiBb,MAAM;MAAEc,kBAAkBnB,IAAImB;IAAiB,CAAA;IACvEC,UAAUC,oBAAoB;MAC5BpB;MACAqB,cAActB,IAAIuB;MAClBhB,WAAWP,IAAIO;IACjB,CAAA;EACF;AACF;AAxBgBR;;;ACnEhB,iBAAkB;;;ACQlB,IAAMyB,aAAsDC,uBAAOC,IACjE,oBAAA;AAcK,IAAMC,aAA4BF,uBAAOC,IAAI,oBAAA;AAwC7C,IAAME,oBAAN,MAAMA;EA5Db,OA4DaA;;;EACFC;EAET,YAAYC,MAAc;AACxB,QAAIA,KAAKC,KAAI,MAAO,IAAI;AACtB,YAAM,IAAIC,MACR,wIAAA;IAEJ;AACA,SAAKH,OAAO;MAAEC;MAAMG,SAAS,CAAA;MAAIC,UAAU;MAAIC,YAAY,CAAA;IAAG;EAChE;;EAGAC,MAAMC,MAA6B;AACjC,SAAKR,KAAKI,UAAUI,KAAKC,IAAI,CAACC,MAAAA;AAC5B,YAAMC,IAAID,EAAEE;AACZ,UAAID,EAAEE,SAAS,OAAO;AACpB,cAAM,IAAIV,MACR,cAAc,KAAKH,KAAKC,IAAI,yGAAwE;MAExG;AACA,aAAOU,EAAEV;IACX,CAAA;AACA,WAAO;EACT;;;;;EAMAa,WACEC,UACGP,MACG;AACN,QAAIA,KAAKQ,WAAW,GAAG;AACrB,YAAM,IAAIb,MACR,cAAc,KAAKH,KAAKC,IAAI,mDAAgD;IAEhF;AACA,SAAKD,KAAKK,WAAWU,MAAMpB,UAAAA,EAAYM;AACvC,SAAKD,KAAKM,aAAa;SAAIE;;AAG3BS,WAAOC,eAAe,KAAKlB,MAAMF,YAAY;MAC3CqB,OAAOJ,MAAMpB,UAAAA;MAAayB,YAAY;MAAOC,cAAc;IAC7D,CAAA;AACA,WAAO;EACT;EAEAC,SAASC,QAAwB;AAC/B,SAAKvB,KAAKsB,WAAWC;AACrB,WAAO;EACT;EAEAC,SAASD,QAAwB;AAC/B,SAAKvB,KAAKwB,WAAWD;AACrB,WAAO;EACT;;;;;;EAOAE,MAAMC,GAAkB;AACtB,SAAK1B,KAAKyB,QAAQC;AAClB,WAAO;EACT;AACF;AAEO,SAASC,WAAW1B,MAAY;AACrC,SAAO,IAAIF,kBAAkBE,IAAAA;AAC/B;AAFgB0B;AAWT,SAASC,gBAAgBC,GAAoC;AAClE,QAAMC,MAAMD,aAAa9B,oBAAoB8B,EAAE7B,OAAO6B;AACtD,MAAIC,IAAI1B,QAAQY,WAAW,GAAG;AAC5B,UAAM,IAAIb,MAAM,cAAc2B,IAAI7B,IAAI,gFAAsD;EAC9F;AACA,MAAI6B,IAAIxB,WAAWU,WAAW,KAAKc,IAAIzB,aAAa,IAAI;AACtD,UAAM,IAAIF,MAAM,cAAc2B,IAAI7B,IAAI,0FAAgE;EACxG;AACA,MAAI6B,IAAI1B,QAAQY,WAAWc,IAAIxB,WAAWU,QAAQ;AAChD,UAAM,IAAIb,MACR,cAAc2B,IAAI7B,IAAI,MAAM6B,IAAI1B,QAAQY,MAAM,oBAAiBc,IAAI1B,QAAQ2B,KAAK,IAAA,CAAA,SACvED,IAAIxB,WAAWU,MAAM,oBAAiBc,IAAIxB,WAAWyB,KAAK,IAAA,CAAA,qDAA2C;EAElH;AACA,SAAOD;AACT;AAfgBF;AA+DT,IAAMI,gBAAN,MAAMA;EA5Mb,OA4MaA;;;EACFhC;EAET,YAAYC,MAAc;AACxB,QAAIA,KAAKC,KAAI,MAAO,IAAI;AACtB,YAAM,IAAIC,MACR,0JAAA;IAEJ;AACA,SAAKH,OAAO;MAAEC;MAAMG,SAAS,CAAA;MAAIC,UAAU;MAAIC,YAAY,CAAA;IAAG;EAChE;;;;;;;EAQA2B,KAAKC,MAA2B;AAC9B,SAAKlC,KAAKiC,OAAOC,KAAKtB;AACtB,WAAO;EACT;;EAGAR,WAAWI,MAAsB;AAC/B,QAAIA,KAAKQ,WAAW,GAAG;AACrB,YAAM,IAAIb,MACR,UAAU,KAAKH,KAAKC,IAAI,sHAAmG;IAE/H;AACA,SAAKD,KAAKI,UAAU;SAAII;;AACxB,WAAO;EACT;;;;;;;EAQAM,WACEC,UACGP,MACQ;AACX,QAAIA,KAAKQ,WAAW,GAAG;AACrB,YAAM,IAAIb,MACR,UAAU,KAAKH,KAAKC,IAAI,mDAAgD;IAE5E;AACA,SAAKD,KAAKK,WAAWU,MAAMpB,UAAAA,EAAYM;AACvC,SAAKD,KAAKM,aAAa;SAAIE;;AAC3BS,WAAOC,eAAe,KAAKlB,MAAMF,YAAY;MAC3CqB,OAAOJ,MAAMpB,UAAAA;MAAayB,YAAY;MAAOC,cAAc;IAC7D,CAAA;AACA,WAAOc,YAAY,IAAI;EACzB;AACF;AAEO,SAASC,OAAOnC,MAAY;AACjC,SAAO,IAAI+B,cAAc/B,IAAAA;AAC3B;AAFgBmC;AAST,SAASD,YAAYN,GAA4B;AACtD,QAAMC,MAAmBD,aAAaG,gBAAgBH,EAAE7B,OAAO6B;AAC/D,MAAIC,IAAI1B,QAAQY,WAAW,GAAG;AAC5B,UAAM,IAAIb,MAAM,UAAU2B,IAAI7B,IAAI,qFAA2D;EAC/F;AACA,MAAI6B,IAAIxB,WAAWU,WAAW,KAAKc,IAAIzB,aAAa,IAAI;AACtD,UAAM,IAAIF,MAAM,UAAU2B,IAAI7B,IAAI,0FAAgE;EACpG;AACA,MAAI6B,IAAI1B,QAAQY,WAAWc,IAAIxB,WAAWU,QAAQ;AAChD,UAAM,IAAIb,MACR,UAAU2B,IAAI7B,IAAI,MAAM6B,IAAI1B,QAAQY,MAAM,oBAAiBc,IAAI1B,QAAQ2B,KAAK,IAAA,CAAA,SACnED,IAAIxB,WAAWU,MAAM,oBAAiBc,IAAIxB,WAAWyB,KAAK,IAAA,CAAA,qDAA2C;EAElH;AACA,MAAID,IAAIG,SAASI,QAAW;AAC1B,UAAM,IAAIlC,MACR,UAAU2B,IAAI7B,IAAI,oKAAsH;EAE5I;AACA,QAAMqC,MAAiB;IACrBrC,MAAM6B,IAAI7B;IACVgC,MAAMH,IAAIG;IACV7B,SAAS;SAAI0B,IAAI1B;;IACjBC,UAAUyB,IAAIzB;IACdC,YAAY;SAAIwB,IAAIxB;;EACtB;AAGA,QAAMiC,SAAUT,IAAkChC,UAAAA;AAClD,MAAIyC,WAAWF,QAAW;AACxBpB,WAAOC,eAAeoB,KAAKxC,YAAY;MAAEqB,OAAOoB;MAAQnB,YAAY;MAAOC,cAAc;IAAK,CAAA;EAChG;AACA,SAAOiB;AACT;AAjCgBH;;;ADhLT,IAAMK,gBAAN,MAAMA,eAAAA;EAlGb,OAkGaA;;;;EACX,YAAqBC,MAAkB;SAAlBA,OAAAA;EAAmB;EAEhCC,IAAIC,IAAiBC,OAAqC;AAChE,WAAO,IAAIJ,eAAc;MAAEK,MAAM;MAASF;MAAIG,MAAM,KAAKL;MAAMM,OAAOC,OAAOJ,KAAAA;IAAO,CAAA;EACtF;EAEAK,GAAGL,OAAqC;AAAE,WAAO,KAAKF,IAAI,MAAME,KAAAA;EAAQ;EACxEM,IAAIN,OAAqC;AAAE,WAAO,KAAKF,IAAI,OAAOE,KAAAA;EAAQ;EAC1EO,GAAGP,OAAqC;AAAE,WAAO,KAAKF,IAAI,MAAME,KAAAA;EAAQ;EACxEQ,IAAIR,OAAqC;AAAE,WAAO,KAAKF,IAAI,OAAOE,KAAAA;EAAQ;EAC1ES,GAAGT,OAAqC;AAAE,WAAO,KAAKF,IAAI,MAAME,KAAAA;EAAQ;EACxEU,IAAIV,OAAqC;AAAE,WAAO,KAAKF,IAAI,OAAOE,KAAAA;EAAQ;;;;;;EAO1EW,OAAOC,UAAU,OAAsB;AACrC,WAAO,IAAIhB,eAAc;MAAEK,MAAM;MAAUJ,MAAM,KAAKA;MAAMe;IAAQ,CAAA;EACtE;EAEAC,OAAOC,QAAwC;AAC7C,WAAO,IAAIlB,eAAc;MAAEK,MAAM;MAAOc,OAAO;QAAC,KAAKlB;WAASiB,OAAOE,IAAI,CAACC,MAAMA,EAAEpB,IAAI;;IAAG,CAAA;EAC3F;EACAqB,MAAMJ,QAAwC;AAC5C,WAAO,IAAIlB,eAAc;MAAEK,MAAM;MAAMc,OAAO;QAAC,KAAKlB;WAASiB,OAAOE,IAAI,CAACC,MAAMA,EAAEpB,IAAI;;IAAG,CAAA;EAC1F;EACAsB,MAAqB;AACnB,WAAO,IAAIvB,eAAc;MAAEK,MAAM;MAAOJ,MAAM,KAAKA;IAAK,CAAA;EAC1D;AACF;AAyCA,SAASO,OAAOgB,GAAgB;AAC9B,SAAOA,aAAaxB,gBAAgBwB,EAAEvB,OAAO;IAAEI,MAAM;IAAOoB,OAAOD;EAAE;AACvE;AAFShB;AA8DF,SAASkB,QACdC,UACAC,QAAQ,GAWRC,WAAW,IAAE;AAKb,QAAMC,QAAQ,OAAOF,KAAAA;AACrB,SAAO;IACLG,KAAK,wBAACC,SACJ,IAAIhC,cAAc4B,UAAU,IAAI;MAAEvB,MAAM;MAAO2B;IAAK,IAAI;MAAE3B,MAAM;MAAO2B;MAAMF;IAAM,CAAA,GADhF;IAELG,MAAM;MAAEC,KAAK,6BAAM,IAAIlC,cAAc;QAAEK,MAAM;MAAU,CAAA,GAA1C;IAA6C;IAC1D8B,KAAK,wBAACX,MAAM,IAAIxB,cAAc;MAAEK,MAAM;MAAOoB,OAAOD;IAAE,CAAA,GAAjD;IACLP,KAAK,2BAAIE,UAAU,IAAInB,cAAc;MAAEK,MAAM;MAAOc,OAAOA,MAAMC,IAAI,CAACgB,MAAMA,EAAEnC,IAAI;IAAE,CAAA,GAA/E;IACLqB,IAAI,2BAAIH,UAAU,IAAInB,cAAc;MAAEK,MAAM;MAAMc,OAAOA,MAAMC,IAAI,CAACgB,MAAMA,EAAEnC,IAAI;IAAE,CAAA,GAA9E;IACJsB,KAAK,wBAACc,SAAS,IAAIrC,cAAc;MAAEK,MAAM;MAAOJ,MAAMoC,KAAKpC;IAAK,CAAA,GAA3D;IACLqC,UAAU,wBAACC,OAAOC,cAAAA;AAChB,YAAMC,OAAQF,MAAiEG,WAAAA;AAC/E,YAAMC,QAAQjB,QAAQkB,OAAOC,KAAKJ,KAAKK,OAAO,GAAGlB,QAAQ,GAAGC,QAAAA;AAC5D,YAAMkB,OAAmB;QACvB1C,MAAM;QACNkC,OAAOE,KAAKT;QACZF,OAAO,OAAOF,QAAQ,CAAA;QACtBoB,OAAOnB;QACPW,WAAWA,UAAUG,KAAAA,EAAgB1C;MACvC;AAOA2C,aAAOK,eAAeF,MAAMG,YAAY;QACtCzB,OAAOgB;QAAMU,YAAY;QAAOC,cAAc;MAChD,CAAA;AACA,aAAO,IAAIpD,cAAc+C,IAAAA;IAC3B,GApBU;EAqBZ;AACF;AAjDgBrB;AAgGhB,SAAS2B,MAAMrB,MAAY;AACzB,SAAO,IAAIA,KAAKsB,QAAQ,MAAM,IAAA,CAAA;AAChC;AAFSD;AA2BF,IAAME,gBAAN,MAAMA;EApWb,OAoWaA;;;EACFC;EAET,YAAYxB,MAAc;AACxB,SAAKwB,OAAO;MACVxB;MACAyB,SAAS;MACTC,OAAO;QAAC;;MACRC,OAAO;MACPC,WAAW;MACXC,YAAY;IACd;EACF;;EAGAC,IAAIL,SAA8B;AAChC,SAAKD,KAAKC,UAAUA;AACpB,WAAO;EACT;;;;;;;;;;EAWAM,MAAML,OAA2B;AAC/B,SAAKF,KAAKE,QAAQA;AAClB,WAAO;EACT;;;;;;;;;;;;;;;;;EAkBAC,MAAM1D,MAAoC;AACxC,SAAKuD,KAAKG,QAAQ1D,gBAAgBD,gBAAgBC,KAAKA,OAAOA;AAC9D,WAAO;EACT;;;;;;;;;;;;;;;;;;;;;;;;;EA0BA+D,SACEC,iBACAC,aACAC,UAAoD,CAAC,GAC/C;AACN,QAAI,KAAKX,KAAKG,UAAU,MAAM;AAG5B,YAAM,IAAIS,MACR,UAAU,KAAKZ,KAAKxB,IAAI,6HACtB;IAEN;AACA,UAAMqC,SAASF,QAAQE,UAAU;AACjC,UAAMC,aAAaH,QAAQG,cAAc;AACzC,SAAKd,KAAKG,QACR,GAAGN,MAAMgB,MAAAA,CAAAA,eAAsBhB,MAAMa,WAAAA,CAAAA,SAAoBb,MAAMY,eAAAA,CAAAA,UACtDZ,MAAMiB,UAAAA,CAAAA;AACjB,WAAO;EACT;;EAGAV,UAAU3D,MAAoC;AAC5C,SAAKuD,KAAKI,YAAY3D,gBAAgBD,gBAAgBC,KAAKA,OAAOA;AAClE,WAAO;EACT;;;EAIAsE,GAAGC,MAAwB;AACzB,SAAKhB,KAAKK,aAAaW,SAAS;AAChC,WAAO;EACT;AACF;AAUO,SAASC,OAAOzC,MAAY;AACjC,SAAO,IAAIuB,cAAcvB,IAAAA;AAC3B;AAFgByC;AAyChB,SAASC,gBAAgB3B,MAAkBf,MAAY;AACrD,UAAQe,KAAK1C,MAAI;IACf,KAAK;AACH,YAAM,IAAI+D,MACR,SAASpC,IAAAA,uLAAsL;IAEnM,KAAK;AACH,YAAM,IAAIoC,MACR,SAASpC,IAAAA,+LAA8L;IAE3M,KAAK;AACH0C,sBAAgB3B,KAAKzC,MAAM0B,IAAAA;AAC3B0C,sBAAgB3B,KAAKxC,OAAOyB,IAAAA;AAC5B;IACF,KAAK;IACL,KAAK;AACH,iBAAWK,QAAQU,KAAK5B,MAAOuD,iBAAgBrC,MAAML,IAAAA;AACrD;IACF,KAAK;IACL,KAAK;AACH0C,sBAAgB3B,KAAK9C,MAAM+B,IAAAA;AAC3B;IACF;AACE;EACJ;AACF;AAzBS0C;AA4BT,IAAMC,gBAAsD;EAC1DlE,IAAI;EACJC,KAAK;EACLC,IAAI;EACJC,KAAK;EACLC,IAAI;EACJC,KAAK;AACP;AAGA,SAAS8D,WAAWpD,GAAmC;AACrD,MAAIA,MAAM,KAAM,QAAO;AACvB,MAAI,OAAOA,MAAM,UAAW,QAAOA,IAAI,SAAS;AAChD,MAAI,OAAOA,MAAM,UAAU;AACzB,QAAI,CAACqD,OAAOC,SAAStD,CAAAA,GAAI;AAGvB,YAAM,IAAI4C,MAAM,YAAY5C,CAAAA,yCAAgC;IAC9D;AACA,WAAOuD,OAAOvD,CAAAA;EAChB;AACA,SAAO,IAAIA,EAAE8B,QAAQ,MAAM,IAAA,CAAA;AAC7B;AAZSsB;AAeT,SAASI,aAAajC,MAAkBf,MAAY;AAClD,UAAQe,KAAK1C,MAAI;IACf,KAAK;AAGH,aAAOgD,MAAMN,KAAKf,IAAI;IACxB,KAAK;AACH,aAAO4C,WAAW7B,KAAKtB,KAAK;IAC9B,KAAK,SAAS;AACZ,YAAMtB,KAAKwE,cAAc5B,KAAK5C,EAAE;AAChC,UAAIA,OAAO8E,QAAW;AACpB,cAAM,IAAIb,MAAM,SAASpC,IAAAA,QAAYe,KAAK5C,EAAE,yCAAyC;MACvF;AACA,aAAO,IAAI6E,aAAajC,KAAKzC,MAAM0B,IAAAA,CAAAA,IAAS7B,EAAAA,IAAM6E,aAAajC,KAAKxC,OAAOyB,IAAAA,CAAAA;IAC7E;IACA,KAAK;IACL,KAAK,MAAM;AACT,UAAIe,KAAK5B,MAAM+D,WAAW,GAAG;AAG3B,eAAOnC,KAAK1C,SAAS,QAAQ,WAAW;MAC1C;AACA,YAAM8E,SAASpC,KAAK1C,SAAS,QAAQ,UAAU;AAC/C,aAAO,IAAI0C,KAAK5B,MAAMC,IAAI,CAACgB,MAAM4C,aAAa5C,GAAGJ,IAAAA,CAAAA,EAAOoD,KAAKD,MAAAA,CAAAA;IAC/D;IACA,KAAK;AACH,aAAO,QAAQH,aAAajC,KAAK9C,MAAM+B,IAAAA,CAAAA;IACzC,KAAK;AACH,aAAO,IAAIgD,aAAajC,KAAK9C,MAAM+B,IAAAA,CAAAA,OAAYe,KAAK/B,UAAU,aAAa,MAAA;IAC7E,SAAS;AAIP,YAAMX,OAAQ0C,KAA0B1C;AACxC,YAAM,IAAI+D,MAAM,SAASpC,IAAAA,QAAY3B,IAAAA,oEAAgD;IACvF;EACF;AACF;AArCS2E;AA6DF,SAASK,MAAMrD,MAAc/B,MAAmB;AACrD,MAAI+B,KAAKsD,KAAI,MAAO,IAAI;AACtB,UAAM,IAAIlB,MAAM,2HAAA;EAClB;AACAM,kBAAgBzE,KAAKA,MAAM+B,IAAAA;AAC3B,SAAO;IAAEA;IAAM/B,MAAM+E,aAAa/E,KAAKA,MAAM+B,IAAAA;EAAM;AACrD;AANgBqD;AAmCT,SAASE,IAAyBhD,OAAkB;AAKzD,MAAIA,UAAU0C,UAAa1C,UAAU,MAAM;AACzC,UAAM,IAAI6B,MACR,4BAA4BW,OAAOxC,KAAAA,IAAS,6GAAA;EAEhD;AACA,QAAMiD,MAAMjD;AACZ,MAAI,OAAOiD,IAAIxD,SAAS,YAAYwD,IAAI1C,YAAY,QAAQ,OAAO0C,IAAI1C,YAAY,YAAY,CAAC2C,MAAMC,QAAQF,IAAIG,QAAQ,GAAG;AAC3H,UAAM,IAAIvB,MACR,uIAAA;EAEJ;AACA,MAAIxB,OAAOgD,UAAUC,eAAeC,KAAKvD,MAAMO,SAAS,KAAA,GAAQ;AAC9D,UAAM,IAAIsB,MACR,OAAO7B,MAAMP,IAAI,mIAA8H;EAEnJ;AACA,QAAM+D,MAAMC,oBAAoBzD,MAAMP,MAAMO,MAAMO,OAAO;AACzD,MAAIiD,QAAQ,MAAM;AAChB,UAAM,IAAI3B,MAAM,OAAO7B,MAAMP,IAAI,MAAM+D,GAAAA,EAAK;EAC9C;AAEA,QAAME,QAAQ1D,MAAMoD,SACjBO,OAAO,CAAC9D,MAAMA,EAAEqB,YAAY,YAAYrB,EAAEyB,eAAe,SAASsC,OAAOC,WAAW,OAAOhE,EAAEJ,IAAI,IAAI,MAAA,KAAW,EAAA,EAChHZ,IAAI,CAACgB,MAAMA,EAAEJ,IAAI;AACpB,MAAIiE,MAAMf,WAAW,GAAG;AACtB,UAAMmB,MAAM9D,MAAMoD,SAASO,OAAO,CAAC9D,MAAMA,EAAEqB,YAAY,KAAA,EAAOrC,IAAI,CAACgB,MAAMA,EAAEJ,IAAI;AAC/E,UAAMsE,OAAOD,IAAInB,SAAS,IACtB,gBAAgBmB,IAAIjF,IAAI,CAACmF,MAAM,IAAIA,CAAAA,GAAI,EAAEnB,KAAK,IAAA,CAAA,IAASiB,IAAInB,WAAW,IAAI,cAAc,cAAA,4GACxF;AACJ,UAAM,IAAId,MACR,OAAO7B,MAAMP,IAAI,qJACgDsE,IAAAA,EAAM;EAE3E;AACA,SAAOE,aAAEC,MAAMD,aAAEE,KAAKT,KAAAA,CAAAA;AACxB;AAxCgBV;AAmDT,SAASS,oBAAoBW,WAAmB7D,SAAkB;AACvE,MAAI6D,cAAc,OAAO;AACvB,WAAO;EACT;AACA,aAAW,CAAC5E,MAAK6E,CAAAA,KAAMhE,OAAOiE,QAAQ/D,OAAAA,GAAU;AAC9C,UAAM0C,MAAOoB,EAA0HpD;AAEvI,QAAIgC,IAAIsB,oBAAoB7B,UAAaO,IAAIuB,kBAAkB9B,OAAW;AAC1E,QAAIO,IAAIwB,cAAc,OAAO;AAC3B,aAAO,WAAWjF,IAAAA;IACpB;AACA,UAAMkF,UAAUzB,IAAI0B,SAAS,OAAO,UAAW1B,IAAI2B,UAAUpF,KAAIqF,SAAS,KAAA,IAASrF,KAAIsF,MAAM,GAAG,EAAC,IAAKtF;AACtG,QAAIkF,YAAY,OAAO;AACrB,aAAO,WAAWlF,IAAAA,8CAAiDyD,IAAI2B,UAAUlC,SAAY,iCAAiC,gBAAA;IAChI;EACF;AACA,SAAO;AACT;AAjBgBe;;;AE3nBT,IAAMsB,eAAN,MAAMA;EApFb,OAoFaA;;;EACFC;EAET,YAAYC,MAAc;AACxB,QAAIA,KAAKC,KAAI,MAAO,IAAI;AACtB,YAAM,IAAIC,MACR,sLAAA;IAEJ;AACA,SAAKH,OAAO;MAAEC;IAAK;EACrB;;EAGAG,GAAGC,OAAyB;AAC1B,SAAKL,KAAKK,QAAQA;AAClB,WAAO;EACT;;;;;;;;EASAC,KAAKC,MAA2B;AAC9B,SAAKP,KAAKM,OAAOC,KAAKC;AACtB,WAAO;EACT;;;;;;;;;;EAWAC,OACEC,OACAC,WACM;AAIN,SAAKX,KAAKS,SAASG,QAAAA,EAAUC,SAASH,OAAOC,SAAAA,EAAWH;AACxD,WAAO;EACT;;;;;;;;EASAM,OACEC,SACAC,MACU;AACV,SAAKhB,KAAKe,UAAUA;AACpB,QAAIC,MAAMC,WAAWC,OAAW,MAAKlB,KAAKiB,SAASD,KAAKC;AACxD,QAAID,MAAMG,SAASD,OAAW,MAAKlB,KAAKmB,OAAOH,KAAKG;AACpD,QAAIH,MAAMI,WAAWF,OAAW,MAAKlB,KAAKoB,SAASJ,KAAKI;AACxD,WAAOC,WAAW,IAAI;EACxB;AACF;AAEO,SAASC,MAAMrB,MAAY;AAChC,SAAO,IAAIF,aAAaE,IAAAA;AAC1B;AAFgBqB;AAST,SAASD,WAAWE,GAA0B;AACnD,QAAMC,MAAkBD,aAAaxB,eAAewB,EAAEvB,OAAOuB;AAC7D,MAAIC,IAAInB,UAAUa,QAAW;AAC3B,UAAM,IAAIf,MAAM,SAASqB,IAAIvB,IAAI,8GAA6E;EAChH;AACA,MAAIuB,IAAIlB,SAASY,UAAaM,IAAIf,WAAWS,QAAW;AACtD,UAAM,IAAIf,MACR,SAASqB,IAAIvB,IAAI,yJAAmH;EAExI;AACA,MAAIuB,IAAIT,YAAYG,UAAaM,IAAIT,QAAQb,KAAI,MAAO,IAAI;AAC1D,UAAM,IAAIC,MACR,SAASqB,IAAIvB,IAAI,0IAAqF;EAE1G;AACA,SAAO;IACLA,MAAMuB,IAAIvB;IACVI,OAAOmB,IAAInB;IACX,GAAImB,IAAIlB,SAASY,SAAY;MAAEZ,MAAMkB,IAAIlB;IAAK,IAAI,CAAC;IACnD,GAAIkB,IAAIf,WAAWS,SAAY;MAAET,QAAQe,IAAIf;IAAO,IAAI,CAAC;IACzDM,SAASS,IAAIT;IACb,GAAIS,IAAIP,WAAWC,SAAY;MAAED,QAAQO,IAAIP;IAAO,IAAI,CAAC;IACzD,GAAIO,IAAIL,SAASD,SAAY;MAAEC,MAAMK,IAAIL;IAAK,IAAI,CAAC;IACnD,GAAIK,IAAIJ,WAAWF,SAAY;MAAEE,QAAQI,IAAIJ;IAAO,IAAI,CAAC;EAC3D;AACF;AAzBgBC;;;AChHT,SAASI,SAASC,MAAcC,KAAW;AAChD,MAAID,KAAKE,KAAI,MAAO,IAAI;AACtB,UAAM,IAAIC,MACR,uHAAA;EAEJ;AACA,MAAIF,IAAIC,KAAI,MAAO,IAAI;AACrB,UAAM,IAAIC,MACR,YAAYH,IAAAA,8LAA2I;EAE3J;AACA,SAAO;IAAEA;IAAMC;EAAI;AACrB;AAZgBF;;;ACmGT,IAAMK,eAAN,MAAMA;EApJb,OAoJaA;;;EACFC;EAET,YAAYC,MAAc;AACxB,QAAIA,KAAKC,KAAI,MAAO,IAAI;AACtB,YAAM,IAAIC,MAAM,+GAAA;IAClB;AACA,SAAKH,OAAO;MAAEC;IAAK;EACrB;;;;;;EAOAG,SAAe;AACb,SAAKJ,KAAKI,SAAS;AACnB,WAAO;EACT;;EAGAC,MAAMC,MAA6B;AACjC,SAAKN,KAAKO,UAAUD,KAAKE,IAAI,CAACC,MAAAA;AAC5B,YAAMC,IAAID,EAAEE;AACZ,UAAID,EAAEE,SAAS,OAAO;AACpB,cAAM,IAAIT,MAAM,SAAS,KAAKH,KAAKC,IAAI,+GAA8E;MACvH;AACA,aAAOS,EAAET;IACX,CAAA;AACA,WAAO;EACT;;;;;;;;EASAY,aAAaF,MAAoB;AAC/B,SAAKX,KAAKc,aAAaH;AACvB,WAAO;EACT;;EAGAI,MAAMJ,MAA2B;AAC/B,SAAKX,KAAKe,QAAQJ,KAAKA;AACvB,WAAO;EACT;;;EAIAK,OAAa;AACX,SAAKhB,KAAKiB,OAAO;AACjB,WAAO;EACT;EAEAC,MAAY;AACV,SAAKlB,KAAKiB,OAAO;AACjB,WAAO;EACT;;EAGAE,MAAMJ,OAA+B;AACnC,SAAKf,KAAKmB,QAAQJ;AAClB,WAAO;EACT;;;EAIAK,QAAQd,MAAsB;AAC5B,SAAKN,KAAKoB,UAAUd;AACpB,WAAO;EACT;AACF;AAEO,SAASe,MAAMpB,MAAY;AAChC,SAAO,IAAIF,aAAaE,IAAAA;AAC1B;AAFgBoB;AAqQhB,SAASC,YAAYC,GAA4B;AAC/C,SAAOA,aAAaC,gBAAgBD,EAAEvB,OAAOuB;AAC/C;AAFSD;AAqDF,IAAMG,cAA4BC,uBAAOC,IAAI,oBAAA;AAiB7C,SAASC,YACd3B,MACA4B,OAAoB;AAEpB,MAAI5B,KAAKC,KAAI,MAAO,IAAI;AACtB,UAAM,IAAIC,MAAM,mDAAA;EAClB;AAGA;AACE,UAAM2B,WAAWC,oBAAoB9B,MAAM4B,MAAMtB,OAAO;AACxD,QAAIuB,aAAa,KAAM,OAAM,IAAI3B,MAAM,eAAe6B,KAAKC,UAAUhC,IAAAA,CAAAA,MAAW6B,QAAAA,EAAU;EAC5F;AAIA,QAAMI,YAAYL,MAAMK,WAAWC,QAAQC,OAAOC,KAAKR,MAAMtB,OAAO,GAAG,GAAGN,IAAAA,CAAAA,KAAU,CAAA,GAAIO,IAAIc,WAAAA;AAW5F,QAAMgB,MAAMJ,SAASK,SAAS,KAAKV,MAAMS,QAAQ;AAcjD,QAAME,SAAQ,CAAC;AACf,aAAW,CAACC,SAASC,CAAAA,KAAMN,OAAOO,QAAQd,MAAMtB,OAAO,GAAG;AACxD,UAAMqC,UAAUF;AAIhB,UAAMG,QAAQT,OAAOU,OAAOV,OAAOW,eAAeH,OAAAA,CAAAA;AAClDR,WAAOY,eAAeH,OAAO,QAAQ;MAAEI,OAAO;QAAE,GAAGL,QAAQ5C;MAAK;MAAGkD,YAAY;MAAMC,UAAU;IAAK,CAAA;AACnGX,IAAAA,OAAkCC,OAAAA,IAAWI;EAChD;AAEA,QAAMO,MAAM;IACVnD;IACAM,SAASiC;IACTF;IACAJ;EACF;AACA,MAAIL,MAAMwB,eAAeC,OAAWF,KAAIC,aAAaxB,MAAMwB;AAC3D,MAAIxB,MAAMzB,WAAWkD,OAAWF,KAAIhD,SAASyB,MAAMzB;AACnD,MAAIyB,MAAM0B,QAAQD,UAAazB,MAAM0B,IAAIhB,SAAS,EAAGa,KAAIG,MAAM1B,MAAM0B,IAAIC,MAAK;AAI9E,QAAMC,iBACJ,OAAO5B,MAAM6B,WAAW,aACpB7B,MAAM6B,OAAOvB,QAAQC,OAAOC,KAAKR,MAAMtB,OAAO,GAAG,GAAGN,IAAAA,CAAAA,IACnD4B,MAAM6B,QAAQF,MAAAA,KAAW,CAAA;AAChC,MAAIC,eAAelB,SAAS,EAAGa,KAAIM,SAASD;AAG5C,QAAME,mBAAmB9B,MAAM+B,UAAUzB,QAAQC,OAAOC,KAAKR,MAAMtB,OAAO,GAAG,GAAGN,IAAAA,CAAAA,KAAU,CAAA,GAAIO,IAC5F,CAACqD,MAAOA,aAAa9D,eAAe8D,EAAE7D,OAAO6D,CAAAA;AAE/C,MAAIF,gBAAgBpB,SAAS,EAAGa,KAAIQ,UAAUD;AAK9C,QAAMG,eAAejC,MAAMkC,cAAc5B,QAAQC,OAAOC,KAAKR,MAAMtB,OAAO,GAAG,GAAGN,IAAAA,CAAAA,KAAU,CAAA,GAAIO,IAC5FwD,eAAAA;AAEF,MAAIF,YAAYvB,SAAS,EAAGa,KAAIW,cAAcD;AAI9C,QAAMG,mBAAmBpC,MAAMqC,SAAS/B,QAAQC,OAAOC,KAAKR,MAAMtB,OAAO,GAAG,GAAGN,IAAAA,CAAAA,KAAU,CAAA,GAAIO,IAC3F2D,WAAAA;AAEF,MAAIF,gBAAgB1B,SAAS,EAAGa,KAAIc,SAASD;AAM7C,aAAWG,MAAMH,iBAAiB;AAChC,eAAWxD,KAAK2D,GAAG7D,SAAS;AAC1B,UAAI,EAAEE,KAAKoB,MAAMtB,UAAU;AACzB,cAAM,IAAIJ,MACR,UAAUF,IAAAA,cAAkBmE,GAAGnE,IAAI,eAAeQ,CAAAA,6DAC3B2B,OAAOC,KAAKR,MAAMtB,OAAO,EAAE8D,KAAK,IAAA,CAAA,EAAO;MAElE;IACF;EACF;AAIA,QAAMC,kBAAkBzC,MAAM0C,SAASpC,QAAQC,OAAOC,KAAKR,MAAMtB,OAAO,GAAG,GAAGN,IAAAA,CAAAA,KAAU,CAAA,GAAIO,IAC1FgE,UAAAA;AAEF,MAAIF,eAAe/B,SAAS,EAAGa,KAAImB,SAASD;AAG5C,aAAWG,KAAKH,gBAAgB;AAC9B,QAAIG,EAAEC,WAAWpB,UAAa,EAAEmB,EAAEC,UAAU7C,MAAMtB,UAAU;AAC1D,YAAM,IAAIJ,MACR,UAAUF,IAAAA,aAAiBwE,EAAExE,IAAI,gCAA2BwE,EAAEC,MAAM,+DAC7CtC,OAAOC,KAAKR,MAAMtB,OAAO,EAAE8D,KAAK,IAAA,CAAA,EAAO;IAElE;EACF;AACA,MAAIxC,MAAM8C,cAAcrB,UAAazB,MAAM8C,UAAUpC,SAAS,GAAG;AAI/D,UAAMqC,OAAO,oBAAIC,IAAAA;AACjB,eAAWnC,KAAKb,MAAM8C,WAAW;AAC/B,UAAIC,KAAKE,IAAIpC,EAAEzC,IAAI,GAAG;AACpB,cAAM,IAAIE,MACR,SAASF,IAAAA,2CAA0CyC,EAAEzC,IAAI,+EAAqD;MAElH;AACA2E,WAAKG,IAAIrC,EAAEzC,IAAI;IACjB;AACAmD,QAAIuB,YAAY9C,MAAM8C,UAAUnE,IAAI,CAACkC,OAAO;MAAEzC,MAAMyC,EAAEzC;MAAM+E,KAAKtC,EAAEsC;IAAI,EAAA;EACzE;AACA,MAAInD,MAAMoD,oBAAoB3B,UAAazB,MAAMoD,gBAAgB1C,SAAS,GAAG;AAC3Ea,QAAI6B,kBAAkB;SAAIpD,MAAMoD;;EAClC;AACA,MAAIpD,MAAMqD,eAAe,KAAM9B,KAAI8B,aAAa;AAGhD,MAAIrD,MAAMsD,YAAY,KAAM/B,KAAI+B,UAAU;AACxC,MAAItD,MAAMuD,WAAW9B,QAAW;AAC9B,UAAM+B,IAAIxD,MAAMuD;AAGhB,QAAIC,EAAEC,SAAShC,QAAW;AAGxB,UAAI+B,EAAEE,WAAWjC,QAAW;AAC1B,cAAM,IAAInD,MACR,SAASF,IAAAA,6GAA+F;MAE5G;AACA,UAAIoF,EAAEC,KAAK/C,WAAW,GAAG;AACvB,cAAM,IAAIpC,MAAM,SAASF,IAAAA,+BAA8B;MACzD;AACA,UAAIoF,EAAEG,UAAUlC,QAAW;AACzB,cAAM,IAAInD,MACR,SAASF,IAAAA,mIAA+G;MAE5H;AACA,UAAIwF,MAAMC,QAAQL,EAAEM,IAAI,KAAKN,EAAEM,KAAKpD,WAAW,GAAG;AAChD,cAAM,IAAIpC,MAAM,SAASF,IAAAA,mFAAwE;MACnG;IACF,OAAO;AAEL,UAAI,OAAOoF,EAAEM,SAAS,WAAW;AAC/B,cAAM,IAAIxF,MAAM,SAASF,IAAAA,UAAc2F,OAAOP,EAAEM,IAAI,CAAA,sDAA4C;MAClG;AACA,UAAIN,EAAEM,SAASrC,UAAa+B,EAAEE,WAAWjC,QAAW;AAClD,cAAM,IAAInD,MACR,SAASF,IAAAA,qHAA6F;MAE1G;AACA,UAAIoF,EAAEM,SAASrC,UAAa+B,EAAEM,KAAKpD,WAAW,GAAG;AAC/C,cAAM,IAAIpC,MAAM,SAASF,IAAAA,oFAAsE;MACjG;AACA,YAAM4F,OAAOR,EAAEE,WAAWjC,SAAY,CAAA,IAAKmC,MAAMC,QAAQL,EAAEE,MAAM,IAAIF,EAAEE,SAAS;QAACF,EAAEE;;AACnF,iBAAWO,OAAOD,MAAM;AACtB,YAAIC,IAAIN,UAAUlC,WAAcwC,IAAIR,SAAShC,UAAawC,IAAIR,KAAK/C,WAAW,IAAI;AAChF,gBAAM,IAAIpC,MAAM,SAASF,IAAAA,yGAA8F;QACzH;AACA,YAAI6F,IAAIN,UAAUlC,UAAawC,IAAIR,SAAShC,QAAW;AACrD,gBAAM,IAAInD,MAAM,SAASF,IAAAA,oFAA2E;QACtG;MACF;IACF;AACAmD,QAAIgC,SAASC;EACf;AACA,MAAIxD,MAAMkE,WAAWzC,QAAW;AAC9B,QAAIzB,MAAMkE,OAAOT,KAAK/C,WAAW,GAAG;AAClC,YAAM,IAAIpC,MAAM,SAASF,IAAAA,+BAA8B;IACzD;AACAmD,QAAI2C,SAASlE,MAAMkE;EACrB;AAGF,aAAWrD,KAAKN,OAAO4D,OAAOxD,MAAAA,GAAmC;AAC9DE,MAAyC1C,KAAKiG,aAAa7C;EAC9D;AAGA,QAAM8C,SAAS;IAAE,GAAI1D;EAAkC;AACvDJ,SAAOY,eAAekD,QAAQzE,aAAY;IAAEwB,OAAOG;IAAKF,YAAY;EAAM,CAAA;AAC1E,SAAOgD;AACT;AAhNgBtE;AA+NhB,IAAMuE,oBAAoB,oBAAIC,QAAAA;AAoB9B,SAASC,kBAAkBC,QAAkCC,YAAkB;AAC7E,aAAWC,SAASpE,OAAO4D,OAAOM,MAAAA,GAAS;AAUzCG,sBAAkBD,OAAO,UAAUA,MAAMvG,IAAI,GAAG;EAClD;AACA,aAAWuG,SAASpE,OAAO4D,OAAOM,MAAAA,GAAS;AACzC,eAAW,CAAC7D,SAASG,OAAAA,KAAYR,OAAOO,QAAQ6D,MAAMjG,OAAO,GAAG;AAC9D,YAAM6C,MAAOR,QAAoC5C;AACjD,UAAIoD,IAAIsD,kBAAkBpD,QAAW;AACnC,YAAI,EAAEF,IAAIsD,iBAAiBF,MAAMjG,UAAU;AACzC,gBAAM,IAAIJ,MACR,UAAUqG,MAAMvG,IAAI,aAAawC,OAAAA,sBAA6BW,IAAIsD,aAAa,wCAAmC;QAEtH;AAGAtD,YAAIuD,aAAa;UACfH,OAAOI,kBAAkBL,YAAYC,MAAMvG,IAAI;UAC/CyE,QAAQtB,IAAIsD;QACd;AACA;MACF;AACA,UAAItD,IAAIyD,oBAAoBvD,OAAW;AACvC,YAAMwD,SAAS1D,IAAIyD,gBAAe;AAClC,YAAME,QAASD,QAAiD9G,MAAMiG;AACtE,UAAIc,UAAUzD,QAAW;AACvB,cAAM,IAAInD,MACR,UAAUqG,MAAMvG,IAAI,aAAawC,OAAAA,8FAAgG;MAErI;AACA,YAAMuE,eAAe5E,OAAOO,QAAQoE,MAAMxG,OAAO,EAAE0G,KACjD,CAAC,CAAA,EAAGvE,CAAAA,MAAQA,EAAwB1C,SAAU8G,OAA6B9G,IAAI,IAC7E,CAAA;AACJ,UAAIgH,iBAAiB1D,QAAW;AAC9B,cAAM,IAAInD,MACR,UAAUqG,MAAMvG,IAAI,aAAawC,OAAAA,oDAA2DsE,MAAM9G,IAAI,GAAG;MAE7G;AACA,YAAMiH,eAAef,kBAAkBgB,IAAIJ,KAAAA;AAC3C,UAAIG,iBAAiB5D,QAAW;AAI9B,cAAM,IAAInD,MACR,UAAUqG,MAAMvG,IAAI,aAAawC,OAAAA,gDAC3BsE,MAAM9G,IAAI,sOAE+D;MAEnF;AACAmD,UAAIuD,aAAa;QACfH,OAAOI,kBAAkBM,cAAcH,MAAM9G,IAAI;QACjDyE,QAAQsC;MACV;IACF;EACF;AACF;AAhESX;AA+EF,SAASe,aACdnH,MACA4B,OAAwE;AAOxE,MAAI,OAAO5B,SAAS,UAAU;AAC5B,UAAM,IAAIE,MACR,mjBAOgF;EAEpF;AACA,MAAIF,KAAKC,KAAI,MAAO,IAAI;AACtB,UAAM,IAAIC,MAAM,oDAAA;EAClB;AACA,QAAMmG,SAAS,CAAC;AAChB,aAAWJ,UAAUrE,MAAMyE,QAAQ;AACjC,UAAME,QAAQN,OAAOzE,WAAAA;AACrB,QAAI6E,OAAOE,MAAMvG,IAAI,MAAMqD,QAAW;AACpC,YAAM,IAAInD,MACR,iBAAiBF,IAAAA,oCAAwCuG,MAAMvG,IAAI,qDAAgD;IAEvH;AACAqG,WAAOE,MAAMvG,IAAI,IAAIuG;AAIrBL,sBAAkBkB,IAAIb,OAAOvG,IAAAA;EAC/B;AAEAoG,oBAAkBC,QAAQrG,IAAAA;AAG1B,aAAW,CAACA,OAAMmD,GAAAA,KAAQhB,OAAOO,QAAQ2D,MAAAA,GAAS;AAChD,UAAMgB,IAAKlE,IAAiB2C;AAC5B,QAAIuB,MAAMhE,OAAW;AACrB,UAAMwD,SAAS1E,OAAO4D,OAAOM,MAAAA,EAAQW,KAAK,CAACM,MAAOA,EAAetH,SAASqH,EAAEE,IAAI;AAChF,QAAIV,WAAWxD,QAAW;AACxB,YAAM,IAAInD,MAAM,SAASF,KAAAA,kBAAsBqH,EAAEE,IAAI,mCAAyB;IAChF;AACA,UAAMC,UAAUH,EAAEG,WAAW;AAC7B,QAAI,EAAEA,WAAYrE,IAAiB7C,UAAU;AAC3C,YAAM,IAAIJ,MAAM,SAASF,KAAAA,qBAAyBwH,OAAAA,6BAAoC;IACxF;AACA,QAAI,EAAEA,WAAWX,OAAOvG,UAAU;AAChC,YAAM,IAAIJ,MAAM,SAASF,KAAAA,qBAAyBwH,OAAAA,mBAA0BH,EAAEE,IAAI,kBAAkB;IACtG;AACA,UAAME,UAAUZ,OAAOvG,QAAQ,MAAA;AAC/B,UAAMoH,UAAUD,YAAYpE,UAAa,UAAWoE,UAC/CA,QAAwC1H,OACxC0H;AACL,QAAIC,YAAYrE,UAAaqE,QAAQC,SAAS,QAAQ;AACpD,YAAM,IAAIzH,MAAM,SAASF,KAAAA,kBAAsBqH,EAAEE,IAAI,2CAA2C;IAClG;AACA,eAAW/G,KAAK6G,EAAEhC,MAAM;AACtB,UAAI,EAAE7E,KAAM2C,IAAiB7C,UAAU;AACrC,cAAM,IAAIJ,MAAM,SAASF,KAAAA,yBAA6BQ,CAAAA,sBAAuB;MAC/E;IACF;EACF;AAEA,QAAMoH,aAAa;OAAI,IAAIhD,IAAIhD,MAAMgG,cAAc,CAAA,CAAE;;AAKrD,SAAO;IACL5H;IACAqG;IACAuB;IACAC,SAASjG,MAAMiG,WAAW7H,SAAS;EACrC;AACF;AAjFgBmH;AA+FhB,SAASW,kBAAkBC,OAAiBC,OAAa;AACvD,QAAMC,UAAU,wBAACC,QAA+CC,SAAAA;AAC9D,UAAMC,SAAUF,OAAuCG,UAAAA;AACvD,QAAID,WAAWE,OAAW;AAC1B,UAAMC,eAAeC,kBAAkBC,IAAIL,MAAAA;AAC3C,QAAIG,iBAAiBD,QAAW;AAC9B,YAAM,IAAII,MACR,GAAGV,KAAAA,KAAUG,IAAAA,qBAAyBC,OAAOO,IAAI,gPAE2C;IAEhG;AACA,UAAMC,YAAYC,kBAAkBN,cAAcH,OAAOO,IAAI;AAC7D,QAAIT,OAAOY,aAAaR,OAAWJ,QAAOY,WAAWF;AACrD,QAAIV,OAAOH,UAAUO,OAAWJ,QAAOH,QAAQa;EACjD,GAdgB;AAgBhB,aAAWG,MAAMhB,MAAMiB,eAAe,CAAA,EAAIf,SAAQc,IAAI,eAAeA,GAAGJ,IAAI,IAAI;AAChF,aAAWM,MAAMlB,MAAMmB,UAAU,CAAA,EAAIjB,SAAQgB,IAAI,WAAWA,GAAGN,IAAI,IAAI;AACvE,aAAWQ,KAAKpB,MAAMqB,UAAU,CAAA,GAAI;AAClC,QAAID,EAAEE,WAAWf,QAAW;AAC1BgB,yBAAmBH,EAAEE,QAAmC,UAAUF,EAAER,IAAI,kBAAkBX,KAAAA;IAC5F;EACF;AACF;AAxBSF;AA2BT,SAASwB,mBAAmBC,MAA+BpB,MAAcH,OAAa;AACpF,MAAIuB,SAAS,QAAQ,OAAOA,SAAS,SAAU;AAC/C,MAAIA,KAAKC,SAAS,UAAU;AAC1B,UAAMpB,SAAUmB,KAAqClB,UAAAA;AACrD,QAAID,WAAWE,QAAW;AACxB,YAAMC,eAAeC,kBAAkBC,IAAIL,MAAAA;AAC3C,UAAIG,iBAAiBD,QAAW;AAC9B,cAAM,IAAII,MACR,GAAGV,KAAAA,KAAUG,IAAAA,qBAAyBC,OAAOO,IAAI,4JACwD;MAE7G;AACAY,WAAKxB,QAAQc,kBAAkBN,cAAcH,OAAOO,IAAI;IAC1D;EACF;AACA,aAAWc,KAAKC,OAAOC,OAAOJ,IAAAA,GAAO;AACnC,QAAIK,MAAMC,QAAQJ,CAAAA,GAAI;AACpB,iBAAWK,KAAKL,EAAGH,oBAAmBQ,GAA8B3B,MAAMH,KAAAA;IAC5E,WAAWyB,MAAM,QAAQ,OAAOA,MAAM,UAAU;AAC9CH,yBAAmBG,GAA8BtB,MAAMH,KAAAA;IACzD;EACF;AACF;AAtBSsB;;;ACz9BT,IAAMS,WAA0BC,uBAAOC,IAAI,0BAAA;AA6DpC,SAASC,YAAAA;AACd,SAAO;IAAEC,MAAM;EAAQ;AACzB;AAFgBD;AAKT,SAASE,cACdC,OAA2E,CAAC,GAAC;AAE7E,SAAO;IAAEF,MAAM;IAAUG,SAASD,KAAKC,WAAW;IAAOC,OAAOF,KAAKE;EAAM;AAC7E;AAJgBH;AAMhB,SAASI,WAAWC,SAAe;AACjC,SAAOA,QAAQC,MAAM,GAAA,EAAKC,OAAO,CAACC,MAAMA,EAAEC,WAAW,GAAA,KAAQD,EAAEE,SAAS,GAAA,CAAA,EAAMC;AAChF;AAFSP;AAIF,SAASQ,eAAeC,KAAkB;AAC/C,QAAMC,UAAkC,CAAA;AACxC,aAAW,CAACT,SAASU,KAAAA,KAAUC,OAAOF,QAAQD,GAAAA,GAAM;AAClD,QAAI,UAAUE,SAASA,MAAMhB,SAAS,SAAS;AAC7C,UAAIK,WAAWC,OAAAA,MAAa,GAAG;AAC7B,cAAM,IAAIY,MACR,wCAAwCZ,OAAAA,+EACM;MAElD;AACAS,cAAQI,KAAK;QAAEb;QAASN,MAAM;MAAQ,CAAA;IACxC,WAAW,UAAUgB,SAASA,MAAMhB,SAAS,UAAU;AACrDe,cAAQI,KAAK;QAAEb;QAASN,MAAM;QAAUG,SAASa,MAAMb;QAASC,OAAOY,MAAMZ;MAAM,CAAA;IACrF,OAAO;AACL,YAAMgB,IAAIJ;AACVD,cAAQI,KAAK;QAAEb;QAASN,MAAM;QAAUqB,WAAWD,EAAEC;QAAWC,SAASF,EAAEE;MAAQ,CAAA;IACrF;EACF;AACA,QAAMC,MAAmB;IAAER;EAAQ;AAiBnC,QAAMS,UAAUC;AAChB,QAAMC,WAAWF,QAAQ5B,QAAAA;AACzB,MAAI8B,YAAY,CAACC,gBAAgBD,UAAUH,GAAAA,GAAM;AAC/C,UAAM,IAAIL,MACR,mDAAmDQ,SAASX,QAAQH,MAAM,gBACzDc,SAASX,QAAQD,IAAI,CAACc,MAAMA,EAAEtB,OAAO,EAAEuB,KAAK,IAAA,CAAA,mIAET;EAExD;AACAL,UAAQ5B,QAAAA,IAAY2B;AACpB,SAAOA;AACT;AA/CgBV;AAqEhB,SAASiB,QAAQF,GAAiC;AAChD,SAAOG,KAAKC,UAAU;IACpBJ,EAAEtB;IACFsB,EAAE5B;IACF4B,EAAEzB,WAAW;IACbyB,EAAExB,OAAO6B,QAAQ;IACjBL,EAAExB,OAAO8B,SAAS;;;IAGlBN,EAAEN,UAAUM,EAAEN,QAAQa,SAAQ,IAAK;IACnCP,EAAEP,YAAYO,EAAEP,UAAUc,SAAQ,IAAK;GACxC;AACH;AAZSL;AAgBT,SAASH,gBAAgBS,GAAgBC,GAAc;AACrD,MAAID,EAAErB,QAAQH,WAAWyB,EAAEtB,QAAQH,OAAQ,QAAO;AAClD,SAAOwB,EAAErB,QAAQuB,MAAM,CAACC,GAAGC,MAAMV,QAAQS,CAAAA,MAAOT,QAAQO,EAAEtB,QAAQyB,CAAAA,CAAE,CAAA;AACtE;AAHSb;;;ACpKF,IAAMc,qBAAqB;;EAEhC;;EAEA;EACA;EACA;;EAEA;EACA;;EAEA;EACA;;EAEA;;;;EAIA;EACA;;AAWK,IAAMC,yBAAgF;EAC3FC,eAAe;IAAC;;AAClB;AAGO,SAASC,mBAAmBC,MAAY;AAC7C,SAAQJ,mBAAyCK,SAASD,IAAAA;AAC5D;AAFgBD;;;ACiGT,IAAMG,SAGT;;;EAGFC,QAAQ;IACNC,QAAQ,wBAACC,MAAMC,OAAOD,CAAAA,GAAd;;;;;IAKRE,MAAM,wBAACF,MAAAA;AACL,UAAI,OAAOA,MAAM,YAAY,CAACC,OAAOE,cAAcH,CAAAA,GAAI;AACrD,cAAM,IAAII,MACR,2BAA2BJ,CAAAA,uIAAwI;MAEvK;AACA,aAAOK,OAAOL,CAAAA;IAChB,GAPM;IAQNM,QAAQ;EACV;;;;;;;EAOAC,SAAS;IACPR,QAAQ,wBAACC,MAAOA,MAAM,QAAQA,MAAMQ,SAAYR,IAAIK,OAAOL,CAAAA,GAAnD;IACRE,MAAM,wBAACF,MAAOA,MAAM,QAAQA,MAAMQ,SAAYR,IAAIK,OAAOL,CAAAA,GAAnD;IACNM,QAAQ;EACV;AACF;AAIA,SAASG,eAAeC,KAAgBC,UAAgB;AACtD,MAAID,IAAIE,SAAS,UAAU;AACzB,UAAM,IAAIR,MAAM,mBAAmBO,QAAAA,mEAAsE;EAC3G;AACF;AAJSF;AAoCF,IAAMI,gBAAN,MAAMA,eAAAA;EAzNb,OAyNaA;;;EAwBFC;EAET,YAAYF,MAASG,aAAyB;AAC5C,SAAKD,OAAOC,eAAe;MACzBH;MACAI,UAAU;MACVC,YAAY;IACd;EACF;;EAGAA,aAA8C;AAC5CR,mBAAe,KAAKK,MAAM,YAAA;AAC1B,SAAKA,KAAKG,aAAa;AACvB,WAAO,IAAIJ,eAAgC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC3E;;EAGAI,UAA+C;AAC7C,SAAKJ,KAAKE,WAAW;AACrB,WAAO,IAAIH,eAAoC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC/E;;EAGAE,WAA+C;AAC7C,SAAKF,KAAKE,WAAW;AACrB,WAAO,IAAIH,eAAmC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC9E;;EAGAK,QAAQC,OAAoD;AAC1DX,mBAAe,KAAKK,MAAM,SAAA;AAC1B,SAAKA,KAAKO,eAAeD;AACzB,WAAO,IAAIP,eAAmC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC9E;;EAGAQ,gBAAoD;AAClDb,mBAAe,KAAKK,MAAM,eAAA;AAC1B,SAAKA,KAAKQ,gBAAgB;AAC1B,WAAO,IAAIT,eAAmC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC9E;;EAGAS,aAAiD;AAC/Cd,mBAAe,KAAKK,MAAM,YAAA;AAC1B,SAAKA,KAAKS,aAAa;AACvB,WAAO,IAAIV,eAAmC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC9E;;;;;;;;;;;;EAaAU,aAAiD;AAC/C,SAAKV,KAAKU,aAAa;AACvB,WAAO,IAAIX,eAAmC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC9E;;;;;;;;;;;;;EAcAW,YAAYC,UAAmD;AAC7D,SAAKZ,KAAKW,cAAcC;AACxB,WAAO;EACT;;;;;;;;;;;;;;;;;EAkBAC,UAA2C;AACzC,WAAO,IAAId,eAAgC,KAAKC,KAAKF,MAAW;MAC9D,GAAG,KAAKE;MACRa,SAAS;IACX,CAAA;EACF;;;;;;;;;;;;;;;;;;;;;EAsBAC,WACEC,QACAC,MAkBiC;AACjCrB,mBAAe,KAAKK,MAAM,YAAA;AAC1B,QAAI,OAAOe,WAAW,YAAY;AAIhC,YAAM,IAAIzB,MACR,oOAEwD;IAE5D;AACA,SAAKU,KAAKiB,kBAAkBF;AAC5B,QAAIC,MAAME,OAAOxB,OAAW,MAAKM,KAAKmB,QAAQH,KAAKE;AACnD,QAAIF,MAAMI,cAAc1B,OAAW,MAAKM,KAAKoB,YAAYJ,KAAKI;AAC9D,QAAIJ,MAAMK,aAAa3B,OAAW,MAAKM,KAAKsB,iBAAiBN,KAAKK;AAGlE,QAAIL,MAAMO,UAAU,MAAO,MAAKvB,KAAKuB,QAAQ;AAC7C,WAAO,IAAIxB,eAAgC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC3E;;;;;;;;;;;;;;;;;;EAmBAwB,UAA2C;AACzC,SAAKxB,KAAKwB,UAAU;AACpB,WAAO,IAAIzB,eAAgC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC3E;;;;;;;;;;EAWAyB,eACEC,QACAV,MACiC;AACjCrB,mBAAe,KAAKK,MAAM,gBAAA;AAC1B,SAAKA,KAAK2B,gBAAgBD;AAC1B,QAAIV,MAAME,OAAOxB,OAAW,MAAKM,KAAKmB,QAAQH,KAAKE;AACnD,QAAIF,MAAMK,aAAa3B,OAAW,MAAKM,KAAKsB,iBAAiBN,KAAKK;AAClE,WAAO,IAAItB,eAAgC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC3E;;EAKAqB,SAASO,QAAyD;AAChE,SAAK5B,KAAKsB,iBAAiBM;AAC3B,WAAO,IAAI7B,eAAgC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC3E;;EAGA6B,SAA0C;AACxClC,mBAAe,KAAKK,MAAM,QAAA;AAC1B,SAAKA,KAAK6B,SAAS;AACnB,WAAO,IAAI9B,eAAgC,KAAKC,KAAKF,MAAW,KAAKE,IAAI;EAC3E;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6BA8B,WAAiD;AAC/C,WAAO,KAAKC,UAAkB,UAAU,UAAA;EAC1C;;;;;EAMAC,YAAkD;AAChD,WAAO,KAAKD,UAAkB,WAAW,WAAA;EAC3C;EAEQA,UAAkBE,OAAkBC,QAAsD;AAChG,QAAI,KAAKlC,KAAKF,SAAS,YAAY,KAAKE,KAAKF,SAAS,WAAW;AAC/D,YAAM,IAAIR,MACR,GAAG,KAAKU,KAAKF,IAAI,aAAaoC,MAAAA,+GACiC;IAEnE;AACA,QAAI,KAAKlC,KAAKmC,cAAczC,QAAW;AACrC,YAAM,IAAIJ,MACR,IAAI4C,MAAAA,qFAAsFA,MAAAA,KAAW;IAEzG;AACA,QAAI,KAAKlC,KAAKiC,UAAUvC,QAAW;AACjC,YAAM,IAAIJ,MACR,8BAA8B,KAAKU,KAAKiC,UAAU,WAAW,WAAW,SAAA,6BAAsC;IAElH;AAUA,WAAO,IAAIlC,eAAqC,KAAKC,KAAKF,MAAW;MACnE,GAAG,KAAKE;MACRiC;IACF,CAAA;EACF;EAEAE,UAAkBC,KAAoE;AAMpF,QAAI,KAAKpC,KAAKiC,UAAUvC,QAAW;AACjC,YAAM,IAAIJ,MACR,0HAAqH;IAEzH;AAIA,WAAO,IAAIS,eAAqC,KAAKC,KAAKF,MAAW;MACnE,GAAG,KAAKE;MACRmC,WAAWC;IACb,CAAA;EACF;AACF;AA6EO,SAASC,OAAAA;AACd,SAAO,IAAItC,cAAc,MAAA;AAC3B;AAFgBsC;AAKT,SAASC,OAAAA;AACd,SAAO,IAAIvC,cAAc,MAAA;AAC3B;AAFgBuC;AAKT,SAASC,UAAAA;AACd,SAAO,IAAIxC,cAAc,SAAA;AAC3B;AAFgBwC;AAST,SAASC,SAAAA;AACd,SAAO,IAAIzC,cAAc,QAAA;AAC3B;AAFgByC;AAYT,SAASC,UAAAA;AACd,SAAO,IAAI1C,cAAc,SAAA;AAC3B;AAFgB0C;AAKT,SAASC,UAAAA;AACd,SAAO,IAAI3C,cAAc,SAAA;AAC3B;AAFgB2C;AAKT,SAASC,YAAAA;AACd,SAAO,IAAI5C,cAAc,WAAA;AAC3B;AAFgB4C;AAeT,SAASC,QAAAA;AACd,SAAO,IAAI7C,cAAc,OAAA;AAC3B;AAFgB6C;AAUT,SAASC,SACdC,MACAC,QAAS;AAET,QAAMC,UAAU,IAAIjD,cAA+C,MAAA;AACnEiD,UAAQhD,KAAKiD,WAAWH;AACxBE,UAAQhD,KAAKkD,aAAa;OAAIH;;AAC9B,SAAOC;AACT;AARgBH;AAaT,SAASM,OAAOC,YAAkB;AACvC,MAAI,CAACjE,OAAOkE,UAAUD,UAAAA,KAAeA,aAAa,KAAKA,aAAa,KAAM;AACxE,UAAM,IAAI9D,MAAM,6DAA6DC,OAAO6D,UAAAA,CAAAA,EAAa;EACnG;AACA,QAAME,IAAI,IAAIvD,cAAc,QAAA;AAC3BuD,IAAEtD,KAAiCoD,aAAaA;AACjD,SAAOE;AACT;AAPgBH;AAkCT,SAASI,cAAAA;AACd,QAAMD,IAAI,IAAIvD,cAA2C,MAAA;AACzDuD,IAAEtD,KAAKE,WAAW;AAClBoD,IAAEtD,KAAKc,aAAa;IAAE0C,OAAO;IAAc9B,QAAQ;EAAK;AACxD4B,IAAEtD,KAAKsB,iBAAiB;AACxBgC,IAAEtD,KAAKyD,OAAO;AACd,SAAOH;AACT;AAPgBC;AAgBT,SAASG,QAAQ1C,MAAiD;AACvE,QAAMsC,IAAI,IAAIvD,cAA6C,MAAA;AAC3DuD,IAAEtD,KAAKc,aAAa;IAAE0C,OAAO;IAAc9B,QAAQ;EAAK;AACxD4B,IAAEtD,KAAKsB,iBAAiBN,KAAKK;AAC7B,MAAIL,KAAKE,OAAOxB,OAAW4D,GAAEtD,KAAKmB,QAAQH,KAAKE;AAC/C,SAAOoC;AACT;AANgBI;AAgBT,SAASC,gBAAgB3C,MAAiD;AAC/E,QAAMsC,IAAI,IAAIvD,cAA6C,MAAA;AAC3DuD,IAAEtD,KAAKc,aAAa;IAAE0C,OAAO;IAAsB9B,QAAQ;EAAK;AAChE4B,IAAEtD,KAAKsB,iBAAiBN,KAAKK;AAC7B,MAAIL,KAAKE,OAAOxB,OAAW4D,GAAEtD,KAAKmB,QAAQH,KAAKE;AAC/C,SAAOoC;AACT;AANgBK;;;AC3tBT,SAASC,IAAIC,MAAcC,IAAU;AAC1C,SAAO;IAAED;IAAMC;EAAG;AACpB;AAFgBF;;;AC7BT,IAAMG,SAAS;EACpBC,UACEC,OACAC,MAAqE;AAErE,WAAO;MAAEC,UAAU;MAAUF;MAAOG,YAAYF,MAAME,cAAc;MAClE,GAAIF,MAAMG,eAAeC,SAAY;QAAED,YAAYH,KAAKG;MAAW,IAAI,CAAC;MACxE,GAAIH,MAAMK,YAAYD,SAAY;QAAEC,SAASL,KAAKK;MAAQ,IAAI,CAAC;IAAG;EACtE;EACAC,KAAKP,OAAa;AAChB,WAAO;MAAEE,UAAU;MAAUF;IAAM;EACrC;AACF;;;AC7BO,IAAMQ,WAAWC,OAAOC,OAAO;EACpCC,sBAAsB;EACtBC,kBAAkB;EAClBC,gBAAgB;EAChBC,oBAAoB;AACtB,CAAA;AAIO,SAASC,2BAA2BC,OAAc;AACvD,SAAOA,UAAUR,SAASG,wBAAwBK,UAAUR,SAASI;AACvE;AAFgBG;;;ACST,IAAME,mBAAkCC,uBAAOC,IAAI,2BAAA;AA8DnD,IAAMC,YAAN,cAAwBC,MAAAA;EAjF/B,OAiF+BA;;;EACbC;EACAC;EACAC;EACAC;;EAEA,CAACC,gBAAAA,IAAoB;EAErC,YAAYJ,QAAgBC,OAAeC,kBAA0BC,MAAgB;AACnF,UAAMD,gBAAAA;AACN,SAAKG,OAAO;AACZ,SAAKL,SAASA;AACd,SAAKC,QAAQA;AACb,SAAKC,mBAAmBA;AACxB,QAAIC,SAASG,QAAW;AACtB,WAAKH,OAAOA;IACd;EACF;;;;;;;EAQAI,OAAOC,WAML;AACA,UAAMC,SAMF;MACFR,OAAO,KAAKA;MACZS,mBAAmB,KAAKR;MACxBF,QAAQ,KAAKA;IACf;AACA,QAAIQ,WAAW;AACbC,aAAOE,aAAaH;IACtB;AACA,QAAI,KAAKL,SAASG,QAAW;AAC3BG,aAAON,OAAO,KAAKA;IACrB;AACA,WAAOM;EACT;AACF;AASO,IAAMG,WAAN,cAAuBd,UAAAA;EA7I9B,OA6I8BA;;;EAC5B,YAAYE,QAAgBa,MAAcC,aAAqBX,MAAgB;AAC7E,UAAMH,QAAQa,MAAMC,aAAaX,IAAAA;AACjC,SAAKE,OAAO;EACd;AACF;AAKA,IAAeU,iBAAf,MAAeA,wBAAuBjB,UAAAA;EAvJtC,OAuJsCA;;;EACpC,YACEE,QACAgB,aACAX,MACAY,SACAJ,MACAV,MACA;AACA,UAAMH,QAAQa,QAAQG,aAAaC,WAAWC,eAAeb,IAAAA,GAAOF,IAAAA;AACpE,SAAKE,OAAOA;EACd;AACF;AAIA,SAASa,eAAeb,MAAY;AAClC,QAAMc,SAASd,KAAKe,QAAQ,sBAAsB,OAAA;AAClD,SAAOD,OAAOE,OAAO,CAAA,EAAGC,YAAW,IAAKH,OAAOI,MAAM,CAAA,EAAGC,YAAW;AACrE;AAHSN;AAWF,IAAMO,aAAN,cAAyBV,eAAAA;EAlLhC,OAkLgCA;;;EAE9B,YAAYZ,MAAsBc,SAAkB;AAClD,UAAM,KAAK,eAAe,cAAcA,SAASX,QAAWH,IAAAA;EAC9D;AACF;AAGO,IAAMuB,eAAN,cAA2BX,eAAAA;EA1LlC,OA0LkCA;;;EAChC,YAAYE,SAAkBJ,MAAeV,MAAgB;AAC3D,UAAM,KAAK,gBAAgB,gBAAgBc,SAASJ,MAAMV,IAAAA;EAC5D;AACF;AAGO,IAAMwB,YAAN,cAAwBZ,eAAAA;EAjM/B,OAiM+BA;;;EAC7B,YAAYE,SAAkBJ,MAAeV,MAAgB;AAC3D,UAAM,KAAK,aAAa,aAAac,SAASJ,MAAMV,IAAAA;EACtD;AACF;AAGO,IAAMyB,WAAN,cAAuBb,eAAAA;EAxM9B,OAwM8BA;;;EAC5B,YAAYE,SAAkBJ,MAAeV,MAAgB;AAC3D,UAAM,KAAK,aAAa,YAAYc,SAASJ,MAAMV,IAAAA;EACrD;AACF;AAGO,IAAM0B,WAAN,cAAuBd,eAAAA;EA/M9B,OA+M8BA;;;EAC5B,YAAYE,SAAkBJ,MAAeV,MAAgB;AAC3D,UAAM,KAAK,YAAY,YAAYc,SAASJ,MAAMV,IAAAA;EACpD;AACF;AAoCO,IAAM2B,kBAAN,cAA8BD,SAAAA;EAvPrC,OAuPqCA;;;;;;;;;;;;;EAWnC,OAAOE,GAAGC,GAAkC;AAC1C,WACE,OAAOA,MAAM,YACbA,MAAM,QACLA,EAAyB3B,SAAS,qBACnC,OAAQ2B,EAA+BC,eAAe;EAE1D;;;EAIgBA;EAEhB,YAAYA,YAAoBhB,SAAkBJ,MAAeV,MAAgB;AAC/E,UAAMc,WAAW,8BAA8BJ,QAAQ,oBAAoBV,IAAAA;AAC3E,SAAKE,OAAO;AACZ,SAAK4B,aAAaA;EACpB;AACF;AA0BO,SAASC,YAAYF,GAAU;AACpC,SACE,OAAOA,MAAM,YACbA,MAAM,QACLA,EAA8BG,cAAc,QAC7CC,2BAA4BJ,EAA6BK,QAAQ;AAErE;AAPgBH;AAkBT,IAAMI,uBAAN,cAAmCT,SAAAA;EAhU1C,OAgU0CA;;;EACxBM,YAAY;EACZE;EAEhB,OAAON,GAAGC,GAAuC;AAC/C,WACE,OAAOA,MAAM,YAAYA,MAAM,QAC9BA,EAAyB3B,SAAS;EAEvC;EAEA,YAAYgC,WAAmBE,SAASC,sBAAsBvB,SAAkBd,MAAgB;AAC9F,UACEc,WACE,4OAEF,yBACAd,IAAAA;AAEF,SAAKE,OAAO;AACZ,SAAKgC,WAAWA;EAClB;AACF;AAcO,IAAMI,mBAAN,cAA+BZ,SAAAA;EApWtC,OAoWsCA;;;EACpBM,YAAY;EACZE;EAEhB,OAAON,GAAGC,GAAmC;AAC3C,WACE,OAAOA,MAAM,YAAYA,MAAM,QAC9BA,EAAyB3B,SAAS;EAEvC;EAEA,YAAYgC,WAAmBE,SAASG,kBAAkBzB,SAAkBd,MAAgB;AAC1F,UACEc,WACE,4QAGF,qBACAd,IAAAA;AAEF,SAAKE,OAAO;AACZ,SAAKgC,WAAWA;EAClB;AACF;AA4BO,IAAMM,kBAAN,cAA8B5B,eAAAA;EAvZrC,OAuZqCA;;;EAEnC,YAAYZ,MAA2Bc,SAAkB;AACvD,UAAM,KAAK,qBAAqB,mBAAmBA,SAASX,QAAWH,IAAAA;EACzE;AACF;;;AC9NA,SAASyC,eACPC,MACAC,MAAU;AAEV,SAAO;IACLC,QAAQ,wBAACC,SACPF,KAAIC,OAAOF,MAAMG,IAAAA,GADX;IAGRC,WAAY,wBAACC,MACXJ,KAAIG,UAAUJ,MAAMK,CAAAA,GADV;IAGZC,YAAa,wBAACC,MAA+CC,SAC3DP,KAAIK,WAAWN,MAAMO,MAA4CC,IAAAA,GADtD;IAGbC,KAAK,wBAACJ,MACJJ,KAAIQ,IAAIT,MAAMK,EAAEF,MAAiC;MAAEO,YAAYL,EAAEK;IAAW,CAAA,GADzE;IAGLC,QAAQ,wBAACN,MACPJ,KAAIU,OAAOX,MAAMK,EAAEO,MAAMC,IAAIR,EAAES,GAAG,GAD5B;IAGRC,QAAQ,wBAACF,OAAeZ,KAAIc,OAAOf,MAAMa,EAAAA,GAAjC;IAERG,YAAa,wBAACX,MACZJ,KAAIe,WAAWhB,MAAMK,EAAEO,OAAO;MAAEK,QAAQZ,EAAEY;IAAO,CAAA,GADtC;IAEbC,UAAU,wBAACL,OACTZ,KAAIiB,SAASlB,MAAMa,EAAAA,GADX;IAGVM,MAAM,wBAACd,MAAAA;AACL,YAAM,EAAEO,OAAO,GAAGJ,KAAAA,IAASH,KAAK,CAAC;AACjC,aAAOJ,KAAIkB,KAAKnB,MAAMY,OAA8CJ,IAAAA;IACtE,GAHM;IAINY,UAAU,wBAACf,MAAAA;AAGT,YAAM,EAAEO,OAAO,GAAGJ,KAAAA,IAASH,KAAK,CAAC;AACjC,aAAOJ,KAAImB,SACTpB,MACAY,OACAJ,IAAAA;IAEJ,GATU;IAWVa,YAAa,wBAAChB,MACZJ,KAAIoB,WACFrB,MACAK,EAAEO,OACFP,EAAES,KACFT,EAAEiB,cAAcC,SAAYA,SAAY;MAAED,WAAWjB,EAAEiB;IAAU,CAAA,GALxD;IAQbE,YAAY,wBAACnB,MACXJ,KAAIuB,WAAWxB,MAAMK,EAAEO,KAAK,GADlB;IAGZa,OAAO,wBAACpB,MACNJ,KAAIwB,MAAMzB,MAAMK,GAAGO,KAAAA,GADd;EAET;AACF;AAxDSb;AAwEF,SAAS2B,YACdC,QACA1B,MAAiB;AAEjB,QAAM2B,SAAS,CAAC;AAChB,aAAWC,OAAOC,OAAOC,KAAKJ,OAAOC,MAAM,GAAG;AAC5C,UAAMI,WAAWL,OAAOC,OAAOC,GAAAA;AAC/B,QAAIG,aAAaT,QAAW;AAC1BK,aAAOC,GAAAA,IAAO9B,eAAekC,kBAAkBN,OAAO3B,MAAMgC,SAAShC,IAAI,GAAGC,IAAAA;IAC9E;EACF;AAEA,QAAMiC,SAAS;IACbN;IACAO,aAAa,6BAAMlC,KAAIkC,YAAW,GAArB;IACbC,QAAWC,IAAgEC,SAA+C;AACxH,YAAMC,UAAU,IAAIC,cAAAA;AACpB,YAAMC,aAAaX,OAAOY,YAAYZ,OAAOa,QAAQhB,OAAOC,MAAM,EAAEgB,IAAI,CAAC,CAACf,KAAKgB,KAAAA,MAAW;QAAChB;QAAKU,QAAQM,MAAMZ,kBAAkBN,OAAO3B,MAAM6C,MAAM7C,IAAI,CAAA;OAAG,CAAA;AAC1J,aAAO8C,UAAU;QAAEC,QAAQC,wBAAAA,SAAQ/C,KAAImC,QAAQY,MAAMV,OAAAA,GAA1BU;MAAmC,GAAG;QAAEpB,QAAQa;MAAW,GAAiBF,SAASF,EAAAA;IAClH;IACAY,YACEZ,IAA8D;AAE9D,YAAME,UAAU,IAAIC,cAAAA;AACpB,YAAMC,aAAsC,CAAC;AAC7C,iBAAWZ,OAAOC,OAAOC,KAAKJ,OAAOC,MAAM,GAAG;AAC5C,cAAMI,WAAWL,OAAOC,OAAOC,GAAAA;AAC/B,YAAIG,aAAaT,OAAWkB,YAAWZ,GAAAA,IAAOU,QAAQM,MAAMZ,kBAAkBN,OAAO3B,MAAMgC,SAAShC,IAAI,CAAA;MAC1G;AAWA,aAAO8C,UACL7C,MACA;QAAE2B,QAAQa;MAAW,GACrBF,SACAF,EAAAA;IAEJ;EACF;AAMA,SAAOH;AACT;AArDgBR;AAqGT,SAASwB,IAA4BC,MAAO;AACjD,SAAOC,SAAS;IAAEC,MAAMF;EAAK,GAAG,KAAA;AAClC;AAFgBD;AAqJhB,eAAsBI,UACpBC,IACAC,OAA2B,CAAC,GAAC;AAE7B,QAAMC,SAASC,YAAYF,KAAKG,KAAK;AACrC,MAAIC,UAAU;AACd,aAAS;AACP,QAAI;AACF,aAAO,MAAML,GAAAA;IACf,SAASM,GAAG;AAGV,UAAID,WAAWH,UAAU,CAACK,YAAYD,CAAAA,EAAI,OAAMA;AAChDD,iBAAW;IACb;EACF;AACF;AAhBsBN;AAwCf,SAASS,YACdC,YACGC,QAAiB;AAEpB,SAAOb,SAAS;IAAEc,MAAM;MAAEC,MAAM;WAAIH;;MAAUC;IAAO;EAAE,GAAG,KAAA;AAC5D;AALgBF;;;ACraT,SAASK,iBAOdC,OACAC,MAA6B;AAE7B,QAAMC,eAAeD,KAAKE;AAI1B,QAAMC,SAAiBH,KAAKI,OAAO;AAInC,QAAMC,QAAQ,wBAACH,YAA6C;IAAE,CAACD,YAAAA,GAAeC;EAAO,IAAvE;AACd,QAAMI,WAAW,wBAACJ,QAAgBK,QAAkD;IAClF,CAACN,YAAAA,GAAeC;IAChB,CAACC,MAAAA,GAASI;EACZ,IAHiB;AAmBjB,QAAMC,gBAAgB,wBAACC,QAAyBP,YAC7C;IAAE,GAAGO;IAAQ,CAACR,YAAAA,GAAeC;EAAO,IADjB;AAGtB,MAAeQ,aAAf,MAAeA,WAAAA;IA5KjB,OA4KiBA;;;IACbC,KAAKT,QAAgC;AACnC,aAAOH,MAAMa,SAAS;QAAEC,OAAOR,MAAMH,MAAAA;MAAQ,CAAA;IAC/C;IAEA,MAAMY,KAAKZ,QAAgBK,IAA0C;AACnE,YAAMQ,OAAO,MAAMhB,MAAMa,SAAS;QAAEC,OAAOP,SAASJ,QAAQK,EAAAA;QAAKS,OAAO;MAAE,CAAA;AAC1E,aAAOD,KAAK,CAAA,KAAM;IACpB;IAEAE,OAAOf,QAAgBO,QAAuC;AAC5D,aAAOV,MAAMkB,OAAOT,cAAcC,QAAQP,MAAAA,CAAAA;IAC5C;IAEA,MAAMgB,OAAOhB,QAAgBK,IAAqBY,OAA4B;AAC5E,YAAMC,MAAM,MAAM,KAAKC,aAAanB,QAAQK,IAAIY,KAAAA;AAChD,UAAIC,QAAQ,MAAM;AAChB,cAAM,IAAIE,SACR,GAAGC,OAAOtB,YAAAA,CAAAA,IAAiBsB,OAAOrB,MAAAA,CAAAA,oBAAsBC,MAAAA,IAAUoB,OAAOhB,EAAAA,CAAAA,kBAAgB;MAE7F;AACA,aAAOa;IACT;IAEA,MAAMC,aAAanB,QAAgBK,IAAqBY,OAAmC;AACzF,YAAMJ,OAAO,MAAMhB,MAAMyB,WAAW;QAAEX,OAAOP,SAASJ,QAAQK,EAAAA;QAAKkB,KAAKN;MAAM,CAAA;AAC9E,aAAOJ,KAAK,CAAA,KAAM;IACpB;IAEA,MAAMW,OAAOxB,QAAgBK,IAAoC;AAC/D,YAAMR,MAAM4B,WAAW;QAAEd,OAAOP,SAASJ,QAAQK,EAAAA;MAAI,CAAA;IACvD;EACF;AAEA,SAAOG;AACT;AA5EgBZ;;;AC9ET,IAAM8B,sBAAsBC,uBAAOC,IAAI,oCAAA;AASvC,IAAMC,qBAAN,cAAiCC,MAAAA;EA9DxC,OA8DwCA;;;;EAE7B,CAACJ,mBAAAA,IAAuB;EAEjC,YAAYK,SAAiB;AAC3B,UAAMA,OAAAA;AACN,SAAKC,OAAO;EACd;AACF;AASO,SAASC,qBAAqBC,GAAU;AAC7C,SAAO,OAAOA,MAAM,YAAYA,MAAM,QAASA,EAA8BR,mBAAAA,MAAyB;AACxG;AAFgBO;;;AC9ET,SAASE,aAAaC,OAI5B;AACC,QAAMC,UAAUD,MAAMC,WAAW,CAAC;AAClC,QAAMC,gBAA0B,CAAA,GAAIC,OAAmB,CAAA;AACvD,aAAW,CAACC,MAAMC,KAAAA,KAAUC,OAAOC,QAAQN,OAAAA,GAAU;AACnD,UAAMO,OAAOH,SAAS,OAAOA,UAAU,YAAY,UAAUA,QAAQA,MAAMI,OAAOJ;AAElF,QAAIG,MAAKE,WAAYR,eAAcS,KAAKP,IAAAA;AACxC,QAAII,MAAKI,OAAQT,MAAKQ,KAAK;MAACP;KAAK;EACnC;AACA,QAAMS,UAAUb,MAAMU,cAAcR;AACpC,MAAIW,QAAQC,OAAQX,MAAKY,QAAQ;OAAIF;GAAQ;AAC7C,aAAWG,OAAOhB,MAAMY,UAAU,CAAA,EAAIT,MAAKQ,KAAK;OAAIK,IAAIf;GAAQ;AAChE,QAAMgB,OAAO,oBAAIC,IAAAA;AACjB,SAAOf,KAAKgB,OAAOH,CAAAA,QAAAA;AACjB,QAAI,CAACA,IAAIF,UAAU,IAAII,IAAIF,GAAAA,EAAKI,SAASJ,IAAIF,UAAUE,IAAIK,KAAKb,CAAAA,SAAO,CAACF,OAAOgB,OAAOrB,SAASO,IAAAA,CAAAA,GAAO;AACpG,YAAM,IAAIe,MAAM,2EAAA;IAClB;AACA,UAAMC,WAAWC,KAAKC,UAAU;SAAIV;MAAKW,KAAI,CAAA;AAC7C,QAAIV,KAAKW,IAAIJ,QAAAA,EAAW,QAAO;AAC/BP,SAAKY,IAAIL,QAAAA;AAAW,WAAO;EAC7B,CAAA;AACF;AAzBgBzB;;;AC+BhB,SAAS+B,WAAWC,KAAc;AAMhC,MAAIA,IAAIC,UAAUC,UAAaF,IAAIC,SAASE,QAAQ;AAClD,WAAOA,OAAOH,IAAIC,KAAK,EAAEG;EAC3B;AACA,UAAQJ,IAAIK,MAAI;IACd,KAAK;IACL,KAAK;IACL,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO;;;;;;IAMT,KAAK;IACL,KAAK;AACH,aAAO;IACT,KAAK;AACH,aAAO;IACT,KAAK;AAMH,aAAO;;;;IAIT,KAAK;AACH,aAAO;IACT,KAAK,QAAQ;AACX,YAAMC,SAASN,IAAIO,cAAc,CAAA;AACjC,UAAID,OAAOE,WAAW,EAAG,QAAO;AAChC,aAAOF,OAAOG,IAAI,CAACC,MAAMC,KAAKC,UAAUF,CAAAA,CAAAA,EAAIG,KAAK,KAAA;IACnD;IACA,SAAS;AASP,YAAMC,YAAmBd,IAAIK;AAC7B,YAAM,IAAIU,MACR,aAAaC,OAAOF,SAAAA,CAAAA,6NAE2B;IAEnD;EACF;AACF;AA5DSf;AAiFT,SAASkB,QAAQjB,KAAc;AAC7B,MAAIA,IAAIK,SAAS,QAAQ;AACvB,UAAMC,SAAS;SAAKN,IAAIO,cAAc,CAAA;MAAKW,KAAI;AAC/C,WAAOZ,OAAOE,WAAW,IAAI,SAAS,QAAQF,OAAOO,KAAK,GAAA,CAAA;EAC5D;AACA,SAAOb,IAAIK;AACb;AANSY;AAQT,SAASE,QAAQnB,KAAc;AAC7B,QAAMoB,OAAOrB,WAAWC,GAAAA;AAgBxB,QAAMqB,UAAU,MAAMD,IAAAA,KAAST,KAAKC,UAAUK,QAAQjB,GAAAA,CAAAA,CAAAA;AACtD,SAAOA,IAAIsB,WAAW,GAAGD,OAAAA,YAAmBA;AAC9C;AAnBSF;AAuBT,SAASI,iBAAiBvB,KAAc;AACtC,SACEA,IAAIsB,aAAa,QACjBtB,IAAIwB,kBAAkB,QACtBxB,IAAIyB,eAAe,QACnBzB,IAAI0B,iBAAiBxB;AAEzB;AAPSqB;AA0BT,SAASI,YAAYC,QAAc;AACjC,SAAOA,OAAOC,SAAS,KAAA,IAASD,OAAOE,MAAM,GAAG,EAAC,IAAKF;AACxD;AAFSD;AAqBT,SAASI,eAAeC,GAAa;AACnC,SAAOA,EAAEC,cAAc,YACnB,oBAAoBD,EAAEE,KAAK,IAAIF,EAAEJ,MAAM,MACvC,mBAAmBI,EAAEE,KAAK,IAAIF,EAAEJ,MAAM;AAC5C;AAJSG;AAqBT,SAASI,WAAWH,GAAa;AAC/B,MAAIA,EAAEC,cAAc,UAAW,QAAO;AACtC,MAAID,EAAEhC,IAAIoC,SAAS,MAAM;AACvB,WAAO,4CAAuCJ,EAAEJ,MAAM;EACxD;AACA,QAAMS,SAASL,EAAEhC,IAAIsC,YAAYJ;AACjC,MAAIG,WAAW,aAAc,QAAO;AACpC,MAAIA,WAAW,qBAAsB,QAAO;AAC5C,MAAIL,EAAEhC,IAAIuC,kBAAkBrC,OAAW,QAAO;AAC9C,SAAO;AACT;AAVSiC;AAsCF,SAASK,eAAeC,SAA6B;AAC1D,QAAMC,MAAM,oBAAIC,IAAAA;AAEhB,QAAMC,QAAQ,oBAAID,IAAAA;AAClB,aAAWE,UAAUJ,SAAS;AAC5B,eAAWK,KAAKC,OAAOzC,OAAOuC,OAAOG,MAAM,GAAG;AAC5C,YAAMC,MAAMC,kBAAkBL,OAAOM,MAAML,EAAEK,IAAI;AACjDT,UAAIU,IAAIH,KAAK,CAAA,CAAE;AACfL,YAAMQ,IAAIH,KAAK,oBAAIN,IAAAA,CAAAA;IACrB;EACF;AAGA,QAAMU,QAAQ,wBAACC,UAAkBH,MAAcI,QAAoBC,SAAAA;AACjE,UAAMC,QAAQb,MAAMc,IAAIJ,QAAAA;AACxB,QAAIG,UAAUvD,OAAW;AACzB,UAAMyD,OAAOF,MAAMC,IAAIP,IAAAA;AACvB,QAAIQ,SAASzD,QAAW;AAGtB,UAAIyD,KAAK3D,IAAIoC,SAAS,QAAQmB,OAAOvD,IAAIoC,SAAS,MAAM;AACtD,cAAM,IAAIwB,mBACR,UAAUN,QAAAA,iCAAyCK,KAAK/B,MAAM,KAAK2B,OAAO3B,MAAM,8IAAoI;MAExN;AACA,YAAMiC,UAAU1B,WAAWwB,IAAAA;AAC3B,YAAMG,YAAY3B,WAAWoB,MAAAA;AAC7B,YAAMQ,SACJF,YAAYC,YACR,uBAAuBD,OAAAA,KACvB,8BAAyBF,KAAKzB,KAAK,IAAIyB,KAAK/B,MAAM,MAAMiC,OAAAA,MAAaN,OAAOrB,KAAK,IAAIqB,OAAO3B,MAAM,MAAMkC,SAAAA;AAC9G,YAAM,IAAIF,mBACR,UAAUN,QAAAA,MAAcvB,eAAe4B,IAAAA,CAAAA,QAAa5B,eAAewB,MAAAA,CAAAA,uCAA8CJ,IAAAA,YAAWY,MAAAA,GAAS;IAEzI;AACAN,UAAML,IAAID,MAAMI,MAAAA;AAChBb,QAAIgB,IAAIJ,QAAAA,GAAWU,KAAKR,IAAAA;EAC1B,GAxBc;AA0Bd,aAAWX,UAAUJ,SAAS;AAC5B,eAAWP,SAASa,OAAOzC,OAAOuC,OAAOG,MAAM,GAAG;AAChD,YAAMiB,WAAWf,kBAAkBL,OAAOM,MAAMjB,MAAMiB,IAAI;AAC1D,UAAI,CAACT,IAAIwB,IAAID,QAAAA,EAAW;AAExB,iBAAW,CAACE,MAAKC,OAAAA,KAAYrB,OAAOsB,QAAQnC,MAAMoC,OAAO,GAAG;AAC1D,cAAMtE,MAAMoE,QAAQG;AACpB,YAAIvE,IAAIsC,eAAepC,OAAW;AAYlC,cAAMsE,YAAYxE,IAAIsC,WAAWJ;AAEjC,cAAMiB,OAAOnD,IAAIoC,SAAS,OAAO,UAAWpC,IAAIyE,SAAS9C,YAAYwC,IAAAA;AACrEd,cACEY,UACAd,MACA;UAAEjB,OAAOA,MAAMiB;UAAMvB,QAAQuC;UAAKlC,WAAW;UAAWjC;QAAI,GAC5D;UAAEmD;UAAMuB,IAAIF;UAAWG,MAAM;UAAOC,KAAKT;QAAI,CAAA;AAK/C,YAAI,CAACzB,IAAIwB,IAAIM,SAAAA,KAAcA,cAAcP,SAAU;AAKnD,cAAMY,UAAU7E,IAAI8E,aAAa5C,MAAMiB;AACvCE,cACEmB,WACAK,SACA;UAAE3C,OAAOA,MAAMiB;UAAMvB,QAAQuC;UAAKlC,WAAW;UAAWjC;QAAI,GAC5D;UAAEmD,MAAM0B;UAASH,IAAIT;UAAUU,MAAM;UAAQC,KAAKT;QAAI,CAAA;MAE1D;IACF;EACF;AACA,SAAOzB;AACT;AAtFgBF;AA6FhB,SAASuC,WAAW7C,OAAiB8C,WAAuBC,QAAc;AACxE,QAAMC,OAAOnC,OAAOsB,QAAQnC,MAAMoC,OAAO;AACzC,QAAMa,WAAWD,KAAKzE,IAAI,CAAC,CAAC0D,MAAKC,OAAAA,MAAQ;AACvC,WAAO,GAAGa,MAAAA,OAAad,IAAAA,KAAQhD,QAAQiD,QAAQG,IAAI,CAAA;EACrD,CAAA;AAMA,QAAMa,eACJrC,OAAOsC,UAAUC,eAAeC,KAAKrD,MAAMoC,SAAS,KAAA,KAAUU,UAAUQ,KAAK,CAACC,MAAMA,EAAEtC,SAAS,KAAA;AAEjG,QAAMuC,YAAYxD,MAAMyD,YAAY,CAAA,GAAIC,OAAO,CAACC,MAAMA,EAAEC,YAAY,YAAYD,EAAEE,eAAe,SAASC,OAAOC,WAAW,OAAOJ,EAAE1C,IAAI,IAAI,MAAA,KAAW,EAAA,EAAI1C,IAAI,CAACoF,MAAMlF,KAAKC,UAAUiF,EAAE1C,IAAI,CAAA;AAG5L,QAAM+C,SAAS,GAAGjB,MAAAA;AAClB,QAAMkB,UAAUf,eAAe,OAAO,GAAGc,MAAAA;EAAWjB,MAAAA,YAAkBS,SAASlF,WAAW,IAAI,YAAY,IAAIkF,SAAS7E,KAAK,KAAA,CAAA,KAAW;AACvI,QAAMuF,cAAclB,KAAKzE,IAAI,CAAC,CAAC0D,MAAKC,OAAAA,MAAQ;AAC1C,UAAMpE,MAAMoE,QAAQG;AACpB,UAAM8B,MAAM9E,iBAAiBvB,GAAAA,IAAO,MAAM;AAC1C,WAAO,GAAGiF,MAAAA,OAAad,IAAAA,GAAMkC,GAAAA,KAAQlF,QAAQnB,GAAAA,CAAAA;EAC/C,CAAA;AACA,QAAMsG,aAAatB,UAChBvE,IACC,CAACgF,MACC,GAAGA,EAAEtC,IAAI,WAAWxC,KAAKC,UAAU6E,EAAEf,EAAE,CAAA,WAAY/D,KAAKC,UAAU6E,EAAEd,IAAI,CAAA,UAAWhE,KAAKC,UAAU6E,EAAEb,GAAG,CAAA,IAAK,EAE/G/D,KAAK,IAAA;AACR,SAAO;IACL,GAAGoE,MAAAA,GAAS/C,MAAMiB,IAAI;IACtB,GAAG8B,MAAAA;OACAE;OACCgB,YAAY,OAAO,CAAA,IAAK;MAACA;;IAC7B,GAAGlB,MAAAA;IACH,GAAGA,MAAAA;OACAmB;IACH,GAAGnB,MAAAA;IACH,GAAGA,MAAAA,iBAAuBqB,eAAe,KAAK,KAAK,IAAIA,UAAAA,GAAa;IACpE,GAAGrB,MAAAA,iBAAuBtE,KAAKC,UAAU2F,aAAarE,KAAAA,CAAAA,CAAAA;;;;OAIlDgD,KAAKM,KAAK,CAAC,CAAA,EAAGgB,CAAAA,MAAOA,EAAEjC,KAAKlE,SAAS,QAAA,KAAa6B,MAAMuE,WAAWvG,SACnE;MAAC,GAAG+E,MAAAA;QACJ,CAAA;;;;OAIA/C,MAAMwE,eAAe,OAAO;MAAC,GAAGzB,MAAAA;QAA+B,CAAA;IACnE,GAAGA,MAAAA;IACHpE,KAAK,IAAA;AACT;AApDSkE;AAoFT,SAAS4B,yBAAyBlE,SAA6B;AAC7D,aAAWI,UAAUJ,SAAS;AAC5B,eAAWP,SAASa,OAAOzC,OAAOuC,OAAOG,MAAM,GAAG;AAChD,iBAAW,CAACmB,MAAKC,OAAAA,KAAYrB,OAAOsB,QAAQnC,MAAMoC,OAAO,GAAG;AAC1D,cAAMtE,MAAMoE,QAAQG;AACpB,YAAIvE,IAAI4G,cAAc1G,UAAaF,IAAIC,UAAUC,OAAW;AAC5D,cAAM2G,QAAQ3D,kBAAkBL,OAAOM,MAAMjB,MAAMiB,IAAI;AAMvD,cAAM,IAAIS,mBACR,UAAUiD,KAAAA,aAAkB1C,IAAAA,gPAEuD;MAEvF;IACF;EACF;AACF;AApBSwC;AAsBF,SAASG,WAAWrE,SAA6B;AACtDkE,2BAAyBlE,OAAAA;AAIzB,QAAMuC,YAAYxC,eAAeC,OAAAA;AAEjC,QAAMsE,eAAetE,QAAQuE,KAAK,CAACC,MAAMA,EAAE9D,SAAS,QAAA;AACpD,QAAM+D,SAASzE,QAAQmD,OAAO,CAACqB,MAAMA,EAAE9D,SAAS,QAAA;AAEhD,QAAMgE,eAAepE,OAAOqE,KAAKL,cAAc/D,UAAU,CAAC,CAAA,EAAGvC,IAAI,CAAC0C,SAChE4B,WAAWgC,aAAc/D,OAAOG,IAAAA,GAAQ6B,UAAUtB,IAAIP,IAAAA,KAAS,CAAA,GAAI,MAAA,CAAA;AAErE,QAAMkE,OAAOF,aAAa3G,SAAS,IAAI;EAAK2G,aAAatG,KAAK,IAAA,CAAA;MAAc;AAE5E,QAAMyG,eAAeJ,OAAOzG,IAAI,CAACoC,WAAAA;AAC/B,UAAM0E,QAAQxE,OAAOqE,KAAKvE,OAAOG,MAAM,EAAEvC,IAAI,CAAC0C,SAC5C4B,WAAWlC,OAAOG,OAAOG,IAAAA,GAAQ6B,UAAUtB,IAAIR,kBAAkBL,OAAOM,MAAMA,IAAAA,CAAAA,KAAU,CAAA,GAAI,QAAA,CAAA;AAE9F,WAAO,OAAON,OAAOM,IAAI;EAAQoE,MAAM1G,KAAK,IAAA,CAAA;;EAC9C,CAAA;AACA,QAAM2G,cAAcF,aAAa9G,SAAS,IAAI;EAAK8G,aAAazG,KAAK,IAAA,CAAA;MAAc;AAEnF,SAAO;;;;;;;;;;;;;;;;;;;;;;;;;;sBA0BawG,IAAAA;uBACCG,WAAAA;;;;;AAKvB;AAvDgBV;;;AC9YhB,SAASW,UAAUC,OAAwB;AACzC,SAAO;OAAI,IAAIC,IAAID,KAAAA;IAAQE,KAAI;AACjC;AAFSH;AAOT,SAASI,WAAWC,MAAY;AAC9B,SAAO,6BAA6BC,KAAKD,IAAAA,IAAQA,OAAOE,KAAKC,UAAUH,IAAAA;AACzE;AAFSD;AAIT,SAASK,QAAQR,OAAe;AAC9B,MAAIA,MAAMS,WAAW,EAAG,QAAO;AAC/B,SAAO;EAAKT,MAAMU,IAAI,CAACC,MAAM,OAAOR,WAAWQ,CAAAA,CAAAA,SAAW,EAAEC,KAAK,IAAA,CAAA;;AACnE;AAHSJ;AAQT,SAASK,cAAcC,SAA0C;AAC/D,QAAMC,aAAaD,QAAQJ,IAAI,CAACM,MAAO,OAAOA,MAAM,WAAW;IAAEZ,MAAMY;IAAGC,UAAU,CAAA;EAAwB,IAAID,CAAAA;AAChH,QAAME,SAAS,oBAAIC,IAAAA;AACnB,aAAWH,KAAKD,WAAYG,QAAOE,IAAIJ,EAAEZ,MAAMY,EAAEC,QAAQ;AACzD,QAAMjB,QAAQ;OAAIkB,OAAOG,KAAI;IAAInB,KAAI;AACrC,MAAIF,MAAMS,WAAW,EAAG,QAAO;AAC/B,QAAMa,OAAOtB,MAAMU,IAAI,CAACN,SAAAA;AACtB,UAAMa,WAAW;SAAI,IAAIhB,IAAIiB,OAAOK,IAAInB,IAAAA,KAAS,CAAA,CAAE;MAAGF,KAAI;AAC1D,UAAMsB,QAAQP,SAASR,WAAW,IAAI,UAAUQ,SAASP,IAAI,CAACe,MAAMnB,KAAKC,UAAUkB,CAAAA,CAAAA,EAAIb,KAAK,KAAA;AAC5F,WAAO,OAAOT,WAAWC,IAAAA,CAAAA,iBAAsBoB,KAAAA;EACjD,CAAA;AACA,SAAO;EAAKF,KAAKV,KAAK,IAAA,CAAA;;AACxB;AAZSC;AAuBF,SAASa,aAAa1B,OAAiB;AAC5C,QAAM2B,UAAU5B,UAAUC,MAAM2B,OAAO;AACvC,QAAMC,QAAQ7B,UAAUC,MAAM4B,KAAK;AAGnC,SAAO;;;;uBAIcpB,QAAQmB,OAAAA,CAAAA;;qBAEVnB,QAAQoB,KAAAA,CAAAA;;uBAENf,cAAcb,MAAMc,OAAO,CAAA;;;;;AAKlD;AAlBgBY;;;ACsBT,IAAMG,SAAwBC,uBAAOC,IAAI,wBAAA;AAMhD,IAAMC,eAA8BF,uBAAOC,IAAI,6BAAA;AAI/C,IAAME,OAAsBH,uBAAOC,IAAI,sBAAA;AACvC,IAAMG,aAA4BJ,uBAAOC,IAAI,2BAAA;AAS7C,IAAMI,gBAA+BL,uBAAOC,IAAI,8BAAA;AAShD,IAAMK,gBAA+BN,uBAAOC,IAAI,8BAAA;AAkBhD,SAASM,UAAUC,QAAc;AAI/B,QAAMC,OACJ,OAAOD,WAAW,aACbA,SACEA,OAAqC,eACtCA;AACR,SAAOC;AACT;AAVSF;AAcT,SAASG,UAAUC,SAAwB;AACzC,MAAI,CAACC,OAAOC,UAAUC,eAAeC,KAAKJ,SAASZ,MAAAA,GAAS;AAC1DY,YAAQZ,MAAAA,IAAU,CAAA;EACpB;AACA,SAAOY,QAAQZ,MAAAA;AACjB;AALSW;AAQT,SAASM,eAAeL,SAAwB;AAC9C,MAAI,CAACC,OAAOC,UAAUC,eAAeC,KAAKJ,SAAST,YAAAA,GAAe;AAChES,YAAQT,YAAAA,IAAgB,CAAC;EAC3B;AACA,SAAOS,QAAQT,YAAAA;AACjB;AALSc;AAUF,SAASC,YACdT,QACAU,QACAC,QACAC,SACAC,SAAqB;AAErB,QAAMV,UAAUJ,UAAUC,MAAAA;AAC1B,QAAMc,SAASZ,UAAUC,OAAAA;AACzB,QAAMY,SAASP,eAAeL,OAAAA;AAC9B,QAAMa,UAAUD,OAAOL,MAAAA,KAAW,CAAA,GAAIO,MAAK,EAAGC,KAAK,CAACC,GAAGC,MAAMD,EAAEE,QAAQD,EAAEC,KAAK;AAC9E,QAAMC,QAAmB;IAAEX;IAAQC;IAASF;IAAQG;IAASG;EAAO;AAIpE,QAAMO,eAAepB,QAAQN,aAAAA;AAC7B,MAAI0B,gBAAgBA,aAAab,MAAAA,MAAYc,QAAW;AACtDF,UAAMG,eAAeF,aAAab,MAAAA;EACpC;AAGA,QAAMgB,eAAevB,QAAQL,aAAAA;AAC7B,MAAI4B,gBAAgBA,aAAahB,MAAAA,MAAYc,QAAW;AACtDF,UAAMK,SAASD,aAAahB,MAAAA;EAC9B;AACAI,SAAOc,KAAKN,KAAAA;AACd;AA1BgBb;AAiCT,SAASoB,YAAY7B,QAAgBU,QAAgBoB,MAAe;AACzE,QAAM3B,UAAUJ,UAAUC,MAAAA;AAC1B,QAAMe,SAASP,eAAeL,OAAAA;AAC7BY,GAAAA,OAAOL,MAAAA,MAAY,CAAA,GAAIkB,KAAKE,IAAAA;AAG7B,QAAMhB,SAASX,QAAQZ,MAAAA;AACvB,MAAIuB,QAAQ;AACV,UAAMQ,QAAQR,OAAOiB,KAAK,CAACC,MAAMA,EAAEtB,WAAWA,MAAAA;AAC9C,QAAIY,OAAO;AACTA,YAAMN,OAAOY,KAAKE,IAAAA;AAClBR,YAAMN,OAAOE,KAAK,CAACC,GAAGC,MAAMD,EAAEE,QAAQD,EAAEC,KAAK;IAC/C;EACF;AACF;AAdgBQ;AAwCT,SAASI,aAAaC,QAAgBC,QAAgBC,QAAyB;AACpF,QAAMC,UAAUC,UAAUJ,MAAAA;AAC1B,QAAMK,SAASF,QAAQG,MAAAA;AACvB,QAAMC,QAAQF,QAAQG,KAAK,CAACC,MAAMA,EAAER,WAAWA,MAAAA;AAC/C,MAAIM,OAAO;AACTA,UAAML,SAASA;AACf;EACF;AACA,MAAI,CAACQ,OAAOC,UAAUC,eAAeC,KAAKV,SAASW,aAAAA,GAAgB;AACjEX,YAAQW,aAAAA,IAAiB,CAAC;EAC5B;AACA,QAAMC,eAAeZ,QAAQW,aAAAA;AAC7B,MAAIC,aAAcA,cAAad,MAAAA,IAAUC;AAC3C;AAbgBH;AAoBT,SAASiB,UAAUC,MAAY;AACpC,QAAMd,UAAUC,UAAUa,IAAAA;AAC1B,QAAMZ,SAASF,QAAQG,MAAAA,KAAW,CAAA;AAClC,QAAMY,eAAef,QAAQgB,aAAAA;AAC7B,MAAID,cAAc;AAChB,eAAWX,SAASF,QAAQ;AAC1B,YAAMe,WAAWF,aAAaX,MAAMN,MAAM;AAC1C,UAAImB,YAAYb,MAAMc,iBAAiBC,QAAW;AAChDf,cAAMc,eAAeD;MACvB;IACF;EACF;AACA,QAAML,eAAeZ,QAAQW,aAAAA;AAC7B,MAAIC,cAAc;AAChB,eAAWR,SAASF,QAAQ;AAC1B,YAAMe,WAAWL,aAAaR,MAAMN,MAAM;AAC1C,UAAImB,YAAYb,MAAML,WAAWoB,QAAW;AAC1Cf,cAAML,SAASkB;MACjB;IACF;EACF;AACA,SAAOf,OAAOkB,IAAI,CAACd,OAAO;IACxB,GAAGA;IACHe,QAAQf,EAAEe,OAAOC,MAAK;IACtB,GAAIhB,EAAEP,WAAWoB,SAAY;MAAEpB,QAAQO,EAAEP,OAAOuB,MAAK;IAAG,IAAI,CAAC;EAC/D,EAAA;AACF;AA1BgBT;AAwDhB,SAASU,cAAcvB,SAAwB;AAC7C,MAAI,CAACO,OAAOC,UAAUC,eAAeC,KAAKV,SAASwB,UAAAA,GAAa;AAC9DxB,YAAQwB,UAAAA,IAAc;MAAEC,OAAO,CAAC;MAAGC,UAAU,CAAC;IAAE;EAClD;AACA,SAAO1B,QAAQwB,UAAAA;AACjB;AALSD;AAUF,SAASI,eAAe9B,QAAgB+B,MAAgB9B,QAAc;AAC3E,QAAM+B,SAASN,cAActB,UAAUJ,MAAAA,CAAAA;AACvC,QAAMiC,WAAWD,OAAOJ,MAAMG,IAAAA;AAC9B,MAAIE,aAAaX,UAAaW,aAAahC,QAAQ;AACjD,UAAMiC,QAAQ,KAAKH,KAAKI,OAAO,CAAA,EAAGC,YAAW,CAAA,GAAKL,KAAKN,MAAM,CAAA,CAAA;AAC7D,UAAM,IAAIY,MACR,IAAIH,KAAAA,mCAAwCD,QAAAA,QAAgBhC,MAAAA,iCAC5B;EAEpC;AACA+B,SAAOJ,MAAMG,IAAAA,IAAQ9B;AACvB;AAXgB6B;AAcT,SAASQ,kBACdtC,QACAuC,MACAtC,QACAuC,QAAkB;AAElB,QAAMR,SAASN,cAActB,UAAUJ,MAAAA,CAAAA;AACvC,QAAMiC,WAAWD,OAAOH,SAASU,IAAAA;AACjC,MAAIN,aAAaX,UAAaW,SAAShC,WAAWA,QAAQ;AACxD,UAAM,IAAIoC,MACR,eAAeE,IAAAA,qCAAyCN,SAAShC,MAAM,QAAQA,MAAAA,IAAU;EAE7F;AACA+B,SAAOH,SAASU,IAAAA,IAAQ;IAAEtC;IAAQuC;EAAO;AAC3C;AAdgBF;AAkBT,SAASG,WACdxB,MACAyB,MAA0C;AAE1C,QAAMvC,UAAUC,UAAUa,IAAAA;AAC1B,QAAMe,SAASN,cAAcvB,OAAAA;AAC7BA,UAAQwC,IAAAA,IAAQ;IAAE,GAAGD;IAAMd,OAAOI,OAAOJ;IAAOC,UAAUG,OAAOH;EAAS;AAY1E,QAAMe,IAAIC;AACV,QAAMC,YAAWC,uBAAOC,IAAI,gCAAA;AAC5B,QAAMC,MAAOL,EAAEE,SAAAA,MAAc,CAAA;AAC7B,MAAI,CAACG,IAAIC,SAASjC,IAAAA,EAAOgC,KAAIE,KAAKlC,IAAAA;AACpC;AAtBgBwB;;;AC/VT,IAAMW,kBAAiCC,uBAAOC,IAAI,gCAAA;AAiBzD,IAAMC,WAA0BF,uBAAOC,IAAI,gCAAA;AAE3C,SAASE,WAAAA;AACP,QAAMC,IAAIC;AACV,QAAMC,WAAWF,EAAEF,QAAAA;AACnB,MAAII,SAAU,QAAOA;AACrB,QAAMC,QAAmB,CAAA;AACzBH,IAAEF,QAAAA,IAAYK;AACd,SAAOA;AACT;AAPSJ;AAiBF,SAASK,2BAAAA;AACd,SAAOL,SAAAA,EAAWM,MAAK;AACzB;AAFgBD;AAKT,SAASE,+BAAAA;AACdP,WAAAA,EAAWQ,SAAS;AACtB;AAFgBD;AAYhB,IAAME,mBAAkCZ,uBAAOC,IAAI,gCAAA;AAEnD,SAASY,cAAAA;AACP,SAAOR;AACT;AAFSQ;AAsBF,SAASC,kBAAkBC,MAAc;AAC9CF,cAAAA,EAAcD,gBAAAA,IAAoBG;AACpC;AAFgBD;AAKT,SAASE,iBAAAA;AACd,SAAOH,YAAAA,EAAcD,gBAAAA;AACvB;AAFgBI;AAKT,SAASC,qBAAAA;AACd,SAAOJ,YAAAA,EAAcD,gBAAAA;AACvB;AAFgBK;AAiBT,SAASC,qBACdC,WACAC,gBAAoC;AAEpC,SAAOD,aAAaC,kBAAkBJ,eAAAA,KAAoB;AAC5D;AALgBE;AAiBhB,IAAMG,yBAAyB;AAe/B,SAASC,kBAAkBC,MAAcC,SAAe;AACtD,QAAM,CAACC,KAAAA,IAASF,KAAKG,MAAM,GAAA,EAAKC,OAAOC,OAAAA;AACvC,MAAIH,UAAUJ,wBAAwB;AACpC,UAAM,IAAIQ,MACR,GAAGL,OAAAA,iCAAwCH,sBAAAA,4EACzC;EAEN;AACF;AARSC;AAqBF,SAASQ,WAAWC,UAAkBC,UAA6B,CAAC,GAAC;AAC1E,SAAO,SAA+DC,MAAO;AAe3EX,sBAAkBS,UAAU,gBAAgBA,QAAAA,IAAY;AACxD,eAAWG,SAASC,UAAUF,IAAAA,GAAO;AACnCX,wBACE,GAAGS,QAAAA,GAAWG,MAAME,OAAO,IAC3B,IAAIF,MAAMG,MAAM,KAAKH,MAAME,OAAO,sBAAsBL,QAAAA,IAAY;IAExE;AAEA,UAAMO,UAAUL;AAChB,UAAMM,OAAuB;MAC3BC,WAAW;MACXT;MACA,GAAIC,QAAQjB,SAAS0B,SAAY;QAAEC,aAAaV,QAAQjB;MAAK,IAAI,CAAC;IACpE;AAEA4B,WAAOC,eAAeN,SAASvC,iBAAiB;MAC9C8C,OAAON;MACPO,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AAGAL,WAAOC,eAAeN,SAAS,aAAa;MAC1CO,OAAO;MACPC,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AAGA,UAAMC,MAAM9C,SAAAA;AACZ,QAAI,CAAC8C,IAAIC,SAASjB,IAAAA,EAAOgB,KAAIE,KAAKlB,IAAAA;AAClC,WAAOA;EACT;AACF;AAnDgBH;AA4FT,SAASsB,yBAAyBC,MAAeC,MAAY;AAClE,QAAMC,QAASF,KAA6BG,UAAU;AACtD,MAAID,UAAU,EAAG;AAoBjB,QAAME,OAAQJ,KAA2BI,QAAQ;AACjD,QAAM,IAAIC,MACR,GAAGJ,IAAAA,IAAQG,IAAAA,gCAAoCF,KAAAA,+KAEmBE,IAAAA,2EACF;AAEpE;AA7BgBL;;;ACvPhB,SAASO,oBAAoBC,QAAuB;AAClD,SAAO,SAAUC,SAAiBC,UAAwB,CAAC,GAAC;AAK1D,QAAI,OAAOD,YAAY,UAAU;AAC/B,YAAM,IAAIE,MACR,IAAIH,OAAO,CAAA,CAAE,GAAGA,OAAOI,MAAM,CAAA,EAAGC,YAAW,CAAA,2CAA6C,OAAOJ,OAAAA,OAC5FD,WAAW,UACR,iJACA,GAAC;IAEX;AACA,WAAO,SAAUM,QAAQC,aAAaC,YAA+B;AACnE,YAAMC,OAAO,GAAGT,OAAO,CAAA,CAAE,GAAGA,OAAOI,MAAM,CAAA,EAAGC,YAAW,CAAA;AAQvD,UAAI,OAAQG,eAA2B,UAAU;AAC/C,cAAM,IAAIL,MACR,IAAIM,IAAAA,4DAAgED,UAAAA,OAAiBD,gBAAgBG,SAAY,oBAAoBC,OAAOJ,WAAAA,CAAAA,iHAC1I;MAEN;AAKA,UAAIA,gBAAgBG,QAAW;AAC7B,cAAM,IAAIP,MAAM,IAAIM,IAAAA,yFAA6F;MACnH;AACAG,kBAAYN,QAAQK,OAAOJ,WAAAA,GAAcP,QAAQC,SAASC,OAAAA;IAC5D;EACF;AACF;AAvCSH;AA0CF,IAAMc,MAAMd,oBAAoB,KAAA;AAEhC,IAAMe,OAAOf,oBAAoB,MAAA;AAEjC,IAAMgB,MAAMhB,oBAAoB,KAAA;AAEhC,IAAMiB,QAAQjB,oBAAoB,OAAA;AAElC,IAAMkB,SAASlB,oBAAoB,QAAA;AAGnC,IAAMmB,QAAQnB,oBAAoB,OAAA;;;AC5EzC,IAAMoB,QAAQ;AAEP,SAASC,kBAAkBC,MAAeC,WAAmBC,MAAY;AAC9E,MAAI,OAAOF,SAAS,YAAYA,KAAKG,KAAI,MAAO,IAAI;AAClD,UAAM,IAAIC,MACR,GAAGH,SAAAA,0CAA8CC,IAAAA,uEACC;EAEtD;AACA,MAAI,CAACJ,MAAMO,KAAKL,IAAAA,GAAO;AACrB,UAAM,IAAII,MACR,GAAGH,SAAAA,UAAmBD,IAAAA,8IACkE;EAE5F;AACF;AAbgBD;;;ACoCT,IAAMO,eAA8BC,uBAAOC,IAAI,6BAAA;AAC/C,IAAMC,iBAAgCF,uBAAOC,IAAI,+BAAA;AAaxD,SAASE,WAAUC,MAAY;AAC7B,SAAOA;AACT;AAFSD,OAAAA,YAAAA;AAMF,SAASE,QAAQC,SAAuB;AAC7C,SAAO,SAA+DF,MAAO;AAC3E,UAAMG,UAAUJ,WAAUC,IAAAA;AAC1BI,WAAOC,eAAeF,SAASR,cAAc;MAC3CW,OAAOJ;MACPK,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACAL,WAAOC,eAAeF,SAAS,aAAa;MAC1CG,OAAO;MACPC,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACA,WAAOT;EACT;AACF;AAjBgBC;AAqBT,SAASS,GAAGC,OAAa;AAC9B,SAAO,SAAUC,QAAgBC,QAAuB;AAEtD,UAAMV,UAAUJ,WAAWa,OAAmC,WAAW;AACzE,UAAME,WAAWX,QAAQL,cAAAA;AACzB,UAAMiB,UAAwBD,WAAW;SAAIA;QAAY,CAAA;AACzDC,YAAQC,KAAK;MAAEL;MAAOE,QAAQI,OAAOJ,MAAAA;IAAQ,CAAA;AAC7CT,WAAOC,eAAeF,SAASL,gBAAgB;MAC7CQ,OAAOS;MACPR,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;EACF;AACF;AAdgBC;AA8BT,SAASQ,mBAAmBlB,MAAY;AAM7C,QAAM,EAAEmB,MAAMJ,QAAO,IAAKK,gBAAgBpB,IAAAA;AAC1C,SAAO;IACLqB,MAAMF,KAAKE;IACXC,UAAUH,KAAKG;IACfC,WAAWJ,KAAKK,OAAOC;IACvBC,QAAQX,QAAQY,IAAI,CAACC,MAAMA,EAAEjB,KAAK;EACpC;AACF;AAbgBO;AAgBhB,SAASE,gBAAgBpB,MAAY;AAInC,QAAMG,UAAUJ,WAAUC,IAAAA;AAC1B,QAAMmB,OAAOhB,QAAQR,YAAAA;AACrB,QAAMoB,UAAUZ,QAAQL,cAAAA,KAAmB,CAAA;AAE3C,MAAI,CAACqB,MAAM;AACT,UAAM,IAAIU,MACR,4DAA6D7B,KAA2BqB,QAAQ,WAAA,GAAc;EAElH;AACAS,oBAAkBX,KAAKE,MAAM,YAAY,SAAA;AACzC,MAAI,CAACF,KAAKG,YAAY,CAACH,KAAKY,WAAW;AACrC,UAAM,IAAIF,MACR,gJACE;EAEN;AAMA,MAAIV,KAAKG,YAAYH,KAAKY,WAAW;AACnC,UAAM,IAAIF,MACR,qLACE;EAEN;AACA,MAAIV,KAAKY,WAAW;AAClB,UAAMC,MAAMb,KAAKY;AAIjB,QAAI,CAACC,IAAIC,QAAQ;AACf,YAAM,IAAIJ,MAAM,iFAAA;IAClB;AACA,QAAIG,IAAIE,SAAS,iBAAiBF,IAAIE,SAAS,aAAa;AAC1D,YAAM,IAAIL,MAAM,+CAA+CG,IAAIE,IAAI,GAAG;IAC5E;AACA,QAAIF,IAAIG,aAAa,SAASH,IAAIG,aAAa,UAAU;AACvD,YAAM,IAAIN,MAAM,mDAAmDG,IAAIG,QAAQ,GAAG;IACpF;AACA,QAAI,CAACH,IAAII,OAAOC,SAAS,QAAA,GAAW;AAClC,YAAM,IAAIR,MAAM,6FAAA;IAClB;AACA,QAAIG,IAAII,MAAMC,SAAS,MAAA,KAAW,CAACL,IAAIM,iBAAiB;AACtD,YAAM,IAAIT,MAAM,gFAAA;IAClB;EACF;AACA,MAAI,CAACV,KAAKK,QAAQC,KAAK;AACrB,UAAM,IAAII,MAAM,iDAAA;EAClB;AACA,MAAId,QAAQwB,WAAW,GAAG;AACxB,UAAM,IAAIV,MAAM,4CAAA;EAClB;AACA,SAAO;IAAEV;IAAMJ;EAAQ;AACzB;AA3DSK;AA6DF,SAASoB,iBAAiBxC,MAAcyC,WAAoB;AACjE,QAAM,EAAEtB,MAAMJ,QAAO,IAAKK,gBAAgBpB,IAAAA;AAE1C,QAAM0C,WAAWD,UAAUE,IAAI3C,IAAAA;AAK/B,QAAM0B,SAA8CtB,uBAAOwC,OAAO,IAAA;AAClE,aAAWC,SAAS9B,SAAS;AAC3B,QAAIX,OAAO0C,UAAUC,eAAeC,KAAKtB,QAAQmB,MAAMlC,KAAK,GAAG;AAC7D,YAAM,IAAIkB,MAAM,QAAQgB,MAAMlC,KAAK,uCAAuC;IAC5E;AACAe,WAAOmB,MAAMlC,KAAK,IAAI,CAACA,OAAOsC,YAC3BP,SAASG,MAAMhC,MAAM,EAA0BmC,KAAKN,UAAU/B,OAAOsC,OAAAA;EAC1E;AAEA,SAAO;IACL,GAAI9B,KAAKG,WAAW;MAAEA,UAAUH,KAAKG;IAAS,IAAI,CAAC;IACnD,GAAIH,KAAKY,YAAY;MAAEA,WAAWZ,KAAKY;IAAU,IAAI,CAAC;IACtDP,QAAQL,KAAKK;IACbE;EACF;AACF;AAvBgBc;;;ACjKT,IAAMU,OAAN,cAAmBC,MAAAA;EAtC1B,OAsC0BA;;;EACxB,YAAYC,SAAgB;AAC1B,UAAMA,OAAAA;AACN,SAAKC,OAAO;EACd;AACF;AAEO,IAAMC,gBAA+BC,uBAAOC,IAAI,8BAAA;AAQhD,SAASC,KAAKC,OAAa;AAChC,SAAO,SAAUC,QAAgBC,QAAuB;AACtD,UAAMC,UAAWF,OAAmC;AACpD,UAAMG,WAAWD,QAAQP,aAAAA;AACzB,UAAMS,UAAwBD,WAAW;SAAIA;QAAY,CAAA;AACzDC,YAAQC,KAAK;MAAEN;MAAOE,QAAQK,OAAOL,MAAAA;IAAQ,CAAA;AAC7CM,WAAOC,eAAeN,SAASP,eAAe;MAC5Cc,OAAOL;MACPM,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;EACF;AACF;AAbgBd;AAoBhB,SAASe,KAAKC,UAAkCV,SAAuBW,MAAY;AACjF,QAAMC,MAA8BT,uBAAOU,OAAO,IAAA;AAClD,aAAWC,SAASd,SAAS;AAC3B,QAAIG,OAAOY,UAAUC,eAAeC,KAAKL,KAAKE,MAAMnB,KAAK,GAAG;AAC1D,YAAM,IAAIP,MAAM,GAAGuB,IAAAA,KAASG,MAAMnB,KAAK,0CAA0C;IACnF;AAIA,UAAMuB,KAAKR,SAASI,MAAMjB,MAAM;AAChC,QAAI,OAAOqB,OAAO,YAAY;AAC5B,YAAM,IAAI9B,MAAM,GAAGuB,IAAAA,KAASG,MAAMnB,KAAK,uBAAuBmB,MAAMjB,MAAM,gBAAgB;IAC5F;AACAe,QAAIE,MAAMnB,KAAK,IAAI,CAACA,OAAOwB,SAASD,GAAGD,KAAKP,UAAUf,OAAOwB,IAAAA;EAC/D;AACA,SAAOP;AACT;AAhBSH;AAyBF,SAASW,cAAcC,MAAcC,WAAoB;AAC9D,QAAMxB,UAAUuB;AAChB,QAAME,kBAAmBzB,QAAQP,aAAAA,KAAkB,CAAA;AACnD,QAAMiC,kBAAmB1B,QAAQ2B,cAAAA,KAAmB,CAAA;AAEpD,MAAIF,gBAAgBG,WAAW,KAAKF,gBAAgBE,WAAW,GAAG;AAChE,UAAM,IAAItC,MACR,GAAIiC,KAA2B/B,QAAQ,cAAA,4GACrC;EAEN;AAEA,QAAMoB,WAAWY,UAAUK,IAAIN,IAAAA;AAC/B,SAAO;IACLO,UAAUnB,KAAKC,UAAUa,iBAAiB,OAAA;IAC1CM,WAAWpB,KAAKC,UAAUc,iBAAiB,KAAA;EAC7C;AACF;AAjBgBJ;AAyBT,SAASU,gBAAgBT,MAAY;AAC1C,QAAMvB,UAAUuB;AAChB,QAAME,kBAAmBzB,QAAQP,aAAAA,KAAkB,CAAA;AACnD,QAAMiC,kBAAmB1B,QAAQ2B,cAAAA,KAAmB,CAAA;AACpD,MAAIF,gBAAgBG,WAAW,KAAKF,gBAAgBE,WAAW,GAAG;AAChE,UAAM,IAAItC,MACR,GAAIiC,KAA2B/B,QAAQ,cAAA,4GACrC;EAEN;AACA,SAAO;IACLsC,UAAUL,gBAAgBQ,IAAI,CAACC,MAAMA,EAAErC,KAAK;IAC5CkC,WAAWL,gBAAgBO,IAAI,CAACC,MAAMA,EAAErC,KAAK;EAC/C;AACF;AAdgBmC;;;ACGT,SAASG,OACdC,SACAC,QAA+D;AAE/D,QAAM,EAAEC,MAAMC,WAAW,GAAGC,aAAAA,IAAiBH;AAC7CI,4BAA0BD,YAAAA;AAC1B,QAAME,UAAwB;IAC5BF;IACA,GAAIF,SAASK,SAAY;MAAEL;IAAK,IAAI,CAAC;IACrC,GAAIC,cAAcI,SAAY;MAAEJ;IAAU,IAAI,CAAC;EACjD;AACA,SAAO,SAAUK,QAAQC,aAAW;AAGlCC,gBAAYF,QAAQG,OAAOF,WAAAA,GAAc,QAAQT,SAASM,OAAAA;EAC5D;AACF;AAhBgBP;AA2BT,SAASa,iBAAAA;AACd,SAAO,SAAUJ,QAAQC,aAAaI,gBAAc;AAClDC,gBAAYN,QAAQG,OAAOF,WAAAA,GAAc;MACvCM,OAAOF;MACPG,MAAM;IACR,CAAA;EACF;AACF;AAPgBJ;AAeT,SAASP,0BAA0BY,GAAe;AACvD,MAAIA,MAAM,QAAQ,OAAOA,MAAM,UAAU;AACvC,UAAM,IAAIC,MAAM,gEAAA;EAClB;AAOA,QAAMC,SAAmBF,EAA2BE;AACpD,MAAI,OAAOA,WAAW,YAAYA,OAAOC,WAAW,GAAG;AACrD,UAAM,IAAIF,MAAM,uDAAA;EAClB;AACA,MAAI,OAAOD,EAAEI,iBAAiB,YAAYJ,EAAEI,aAAaD,WAAW,GAAG;AACrE,UAAM,IAAIF,MAAM,8DAAA;EAClB;AACF;AAjBgBb;;;ACpET,SAASiB,IACdC,UAAU,IACVC,QAA4D;AAE5D,QAAM,EAAEC,MAAMC,WAAW,GAAGC,UAAAA,IAAcH;AAC1C,QAAMI,UAAwB;IAC5BD;IACA,GAAIF,SAASI,SAAY;MAAEJ;IAAK,IAAI,CAAC;IACrC,GAAIC,cAAcG,SAAY;MAAEH;IAAU,IAAI,CAAC;EACjD;AACA,SAAO,SAAUI,QAAQC,aAAW;AAClCC,gBAAYF,QAAQG,OAAOF,WAAAA,GAAc,QAAQR,SAASK,OAAAA;EAC5D;AACF;AAbgBN;AAmBT,SAASY,SAAAA;AACd,SAAO,SAAUJ,QAAQC,aAAaI,gBAAc;AAClDC,gBAAYN,QAAQG,OAAOF,WAAAA,GAAc;MAAEM,OAAOF;MAAgBG,MAAM;IAAS,CAAA;EACnF;AACF;AAJgBJ;AAoBT,SAASK,SAAAA;AACd,SAAO,SAAUT,QAAQC,aAAaI,gBAAc;AAClDC,gBAAYN,QAAQG,OAAOF,WAAAA,GAAc;MAAEM,OAAOF;MAAgBG,MAAM;IAAS,CAAA;EACnF;AACF;AAJgBC;;;ACnFhB,IAAMC,mBAAmB;AAezB,SAASC,cAAcC,SAAe;AACpC,MAAIA,QAAQC,SAAS,GAAA,GAAM;AACzB,UAAM,IAAIC,MACR,UAAUF,OAAAA,yEACEA,QAAQG,QAAQ,OAAO,GAAA,CAAA,yCAAwC;EAE/E;AACA,QAAMC,WAAWJ,QAAQK,MAAM,GAAA;AAC/B,MAAID,SAASE,KAAK,CAACC,MAAMA,MAAM,EAAA,GAAK;AAClC,UAAM,IAAIL,MAAM,UAAUF,OAAAA,2DAA6D;EACzF;AACA,QAAMQ,OAAO,oBAAIC,IAAAA;AACjB,aAAWF,KAAKH,UAAU;AACxB,QAAI,CAACG,EAAEG,WAAW,GAAA,KAAQ,CAACH,EAAEI,SAAS,GAAA,EAAM;AAC5C,UAAMC,OAAOL,EAAEM,MAAM,GAAG,EAAC;AACzB,QAAID,SAAS,GAAI,OAAM,IAAIV,MAAM,UAAUF,OAAAA,8BAAqC;AAChF,QAAIQ,KAAKM,IAAIF,IAAAA,GAAO;AAClB,YAAM,IAAIV,MAAM,UAAUF,OAAAA,mBAA0BY,IAAAA,mBAAuB;IAC7E;AACAJ,SAAKO,IAAIH,IAAAA;EACX;AACF;AArBSb;AAwCF,SAASiB,KAAKhB,SAAiBiB,SAAoB;AACxD,SAAO,SAA+DC,MAAO;AAC3EnB,kBAAcC,OAAAA;AAIdmB,eAAWD,MAAM;MACflB;MACAoB,QAAQH,QAAQG;MAChBC,SAASJ,QAAQI,WAAWvB;IAC9B,CAAA;AACA,WAAOoB;EACT;AACF;AAbgBF;AAehB,SAASM,cAAcC,MAAc;AACnC,SAAO,MACL,SAAUC,QAAgBC,aAA4B;AACpDC,mBAAeF,QAAQD,MAAMI,OAAOF,WAAAA,CAAAA;EACtC;AACJ;AALSH;AAQF,IAAMM,cAAcN,cAAc,WAAA;AAclC,IAAMO,UAAUP,cAAc,OAAA;AAG9B,IAAMQ,SAASR,cAAc,MAAA;AAG7B,IAAMS,UAAUT,cAAc,OAAA;AAG9B,IAAMU,UAAUV,cAAc,OAAA;AAQ9B,SAASW,UAAUrB,MAAcsB,QAAkB;AACxD,SAAO,SAAUV,QAAgBC,aAA4B;AAC3DU,sBAAkBX,QAAQZ,MAAMe,OAAOF,WAAAA,GAAcS,MAAAA;EACvD;AACF;AAJgBD;;;AChJhB,SAASG,mBACPC,MACAC,OAA8C;AAE9C,SAAO,SAAUC,QAAQC,aAAaC,gBAAc;AAClDC,gBAAYH,QAAQI,OAAOH,WAAAA,GAAc;MACvCI,OAAOH;MACPJ;MACA,GAAIC,OAAOO,WAAWC,SAAY;QAAED,QAAQP,MAAMO;MAAO,IAAI,CAAC;MAC9D,GAAIP,OAAOS,SAASD,SAAY;QAAEC,MAAMT,MAAMS;MAAK,IAAI,CAAC;IAC1D,CAAA;EACF;AACF;AAZSX;AAgBF,SAASY,KAAKH,QAAkB;AACrC,SAAOT,mBAAmB,QAAQ;IAAES;EAAO,CAAA;AAC7C;AAFgBG;AAMT,SAASC,YAAYJ,QAAkB;AAC5C,SAAOT,mBAAmB,SAAS;IAAES;EAAO,CAAA;AAC9C;AAFgBI;AAMT,SAASC,QAAQL,QAAmB;AACzC,SAAOT,mBAAmB,WAAWS,WAAWC,SAAY;IAAED;EAAO,IAAIC,MAAAA;AAC3E;AAFgBI;AAKT,SAASC,MAAMJ,MAAY;AAChC,SAAOX,mBAAmB,SAAS;IAAEW;EAAK,CAAA;AAC5C;AAFgBI;AAMT,SAASC,OAAAA;AACd,SAAOhB,mBAAmB,MAAA;AAC5B;AAFgBgB;AAMT,SAASC,eAAAA;AACd,SAAOjB,mBAAmB,cAAA;AAC5B;AAFgBiB;AAKT,SAASC,SAAAA;AACd,SAAOlB,mBAAmB,QAAA;AAC5B;AAFgBkB;AAKT,SAASC,YAAAA;AACd,SAAOnB,mBAAmB,WAAA;AAC5B;AAFgBmB;AAKT,SAASC,UAAAA;AACd,SAAOpB,mBAAmB,SAAA;AAC5B;AAFgBoB;AAKT,SAASC,MAAAA;AACd,SAAOrB,mBAAmB,KAAA;AAC5B;AAFgBqB;;;ACzCT,SAASC,iBAAiBC,KAAsB;AACrD,QAAM,IAAIC,MACR,8VAIE;AAEN;AARgBF;;;AC5BhB,4BAIO;AACP,IAAAG,cAAmC;IAGnCC,4CAAqBC,aAAAA;AAiBrB,IAAMC,iBAAgCC,uBAAOC,IAAI,+BAAA;AAcjD,IAAMC,uBAAmD;EACvDC,aAAaL,cAAEM,OAAO;IACpBC,QAAQP,cAAEQ,MAAMR,cAAEM,OAAO;MAAEG,OAAOT,cAAEU,OAAM;MAAIC,SAASX,cAAEU,OAAM;IAAG,CAAA,CAAA;EACpE,CAAA;EACAE,mBAAmBZ,cAAEM,OAAO;IAAEO,YAAYb,cAAEc,OAAM,EAAGC,IAAG;EAAG,CAAA;AAC7D;AAEO,SAASC,mBAAAA;AACd,QAAMC,IAAIC;AACV,MAAI,CAACD,EAAEhB,cAAAA,GAAiB;AACtB,UAAMkB,IAAI,oBAAIC,IAAAA;AACd,eAAW,CAACC,MAAMC,QAAQC,SAAAA,KAAc;MACtC;QAAC;QAAe;QAAK;;MACrB;QAAC;QAAgB;QAAK;;MACtB;QAAC;QAAa;QAAK;;MACnB;QAAC;QAAa;QAAK;;MACnB;QAAC;QAAY;QAAK;;;;;;MAKlB;QAAC;QAAoB;QAAK;;MAC1B;QAAC;QAAqB;QAAK;;OACjB;AACV,YAAMC,aAAapB,qBAAqBiB,IAAAA;AACxCF,QAAEM,IAAIJ,MAAM;QACVA;QACAC;QACAC;QACAG,SAAS;QACT,GAAIF,aAAa;UAAEA;UAAYG,YAAYC,SAASP,MAAMG,UAAAA;QAAY,IAAI,CAAC;MAC7E,CAAA;IACF;AACAP,MAAEhB,cAAAA,IAAkBkB;EACtB;AACA,SAAOF,EAAEhB,cAAAA;AACX;AA7BgBe;AA8DT,SAASa,YAAYR,MAAcC,QAAgBE,YAAuB;AAC/E,MAAI,CAACM,OAAOC,UAAUT,MAAAA,KAAWA,SAAS,OAAOA,SAAS,KAAK;AAC7D,UAAM,IAAIU,MACR,4BAA4BX,IAAAA,oCAAwCC,MAAAA,iFACO;EAE/E;AACA,QAAMW,YAAWjB,iBAAAA;AACjB,QAAMkB,WAAWD,UAASE,IAAId,IAAAA;AAC9B,QAAME,YAAYa,iBAAiBf,IAAAA;AACnC,QAAMM,aAAaH,aAAaI,SAASP,MAAMG,UAAAA,IAAca;AAC7D,MAAIH,UAAU;AACZ,UAAMI,YACJJ,SAASZ,WAAWA,UAAU,CAACY,SAASR,WAAWQ,SAASP,eAAeA;AAC7E,QAAI,CAACW,WAAW;AACd,YAAM,IAAIN,MACR,sCAAsCX,IAAAA,8CACfa,SAASZ,MAAM,GAAGY,SAASR,UAAU,eAAe,EAAA,GACtEQ,SAASZ,WAAWA,UAAU,CAACY,SAASR,UAAU,4BAA4B,EAAA,oCAChD;IAEvC;EACF;AAGA,QAAMa,eAAe,wBAACC,WACpB,cAAcC,UAAAA;IACZ,OAAgBpB,OAAOA;IACvB,OAAgBC,SAASA;IACzB,YAAYoB,MAAe/B,SAAkB;AAC3C,YAAMW,QAAQD,MAAMV,WAAWgC,SAAStB,IAAAA,GAAOmB,OAAOI,MAAMF,IAAAA,CAAAA;AAC5D,WAAKG,OAAOtB;IACd;EACF,GARmB;AASrB,QAAMuB,kBAAkB,6BACtB,cAAcL,UAAAA;IACZ,OAAgBpB,OAAOA;IACvB,OAAgBC,SAASA;IACzB,YAAYX,SAAkB;AAC5B,YAAMW,QAAQD,MAAMV,WAAWgC,SAAStB,IAAAA,CAAAA;AACxC,WAAKwB,OAAOtB;IACd;EACF,GARsB;AASxB,QAAMwB,MAAMvB,aAAae,aAAaf,UAAAA,IAAcsB,gBAAAA;AACpDE,SAAOC,eAAeF,KAAK,QAAQ;IAAEG,OAAO3B;EAAU,CAAA;AACtDU,EAAAA,UAASR,IAAIJ,MAAM;IACjBA;IACAC;IACAC;IACAG,SAAS;IACT,GAAIF,aAAa;MAAEA;IAAW,IAAI,CAAC;IACnC,GAAIG,eAAeU,SAAY;MAAEV;IAAW,IAAI,CAAC;EACnD,CAAA;AACA,SAAOoB;AACT;AAtDgBlB;AA8DhB,SAASD,SAASP,MAAcG,YAAsB;AACpD,QAAM2B,UAAU;AAChB,QAAMC,cAAc,IAAIC,sCAAAA;AAIxBD,cAAYE,SAASH,SAASnD,cAAEM,OAAO;IAAEoC,MAAMlB;EAAW,CAAA,EAAG+B,QAAQJ,OAAAA,CAAAA;AACrE,QAAMK,YAAY,IAAIC,0CAAoBL,YAAYM,WAAW,EAAEC,mBAAkB;AACrF,QAAMC,MAAMJ,UAAUK,YAAYC,UAAUX,OAAAA;AAC5C,QAAMY,SAASC,KAAKC,UAAUL,OAAO,IAAA;AACrC,MAAIG,OAAOG,SAAS,QAAA,GAAW;AAC7B,UAAM,IAAIlC,MACR,gCAAgCX,IAAAA,qKAEmC;EAEvE;AACA,SAAO0C;AACT;AAlBSnC;AAuBT,SAASQ,iBAAiBf,MAAY;AACpC,SAAOA,KACJ8C,MAAM,GAAA,EACNC,IAAI,CAACC,MAAMA,EAAEC,OAAO,CAAA,EAAGC,YAAW,IAAKF,EAAEG,MAAM,CAAA,CAAA,EAC/CC,KAAK,EAAA;AACV;AALSrC;AAQT,SAASO,SAAStB,MAAY;AAC5B,QAAMqD,IAAIrD,KAAKsD,QAAQ,MAAM,GAAA;AAC7B,SAAOD,EAAEJ,OAAO,CAAA,EAAGC,YAAW,IAAKG,EAAEF,MAAM,CAAA;AAC7C;AAHS7B;;;AChNF,IAAMiC,iBAAgCC,uBAAOC,IAClD,+BAAA;AAeK,IAAMC,aAA4BF,uBAAOC,IAAI,4BAAA;AAG7C,IAAME,eAAe,wBAACC,MAC1BA,IAAuCF,UAAAA,MAAgB,MAD9B;AAG5B,SAASG,OAAAA;AACP,QAAMC,IAAIC;AACV,SAAQD,EAAEP,cAAAA,MAAoB,CAAA;AAChC;AAHSM;AAsBF,SAASG,aAAAA;AACd,SAAO,CAACC,WAAAA;AACLA,WAA8CP,UAAAA,IAAc;AAC7DG,SAAAA,EAAOK,KAAKD,MAAAA;EACd;AACF;AALgBD;AAeT,SAASG,qBAAAA;AACd,SAAON,KAAAA,EAAOO,OAAO,CAAA;AACvB;AAFgBD;;;ACvDhB,IAAME,MAAMC,uBAAOC,IAAI,yBAAA;AACvB,IAAMC,UAAUF,uBAAOC,IAAI,6BAAA;AAC3B,IAAME,iBAAgBH,uBAAOC,IAAI,8BAAA;AACjC,IAAMG,iBAAiBJ,uBAAOC,IAAI,+BAAA;AAClC,IAAMI,QAAOL,uBAAOC,IAAI,sBAAA;AACxB,IAAMK,aAAaN,uBAAOC,IAAI,gCAAA;AAE9B,IAAMM,MAAM,wBAACC,GAAYC,MACtBD,EAA8BC,CAAAA,MAAOC,QAD5B;AAYL,IAAMC,oBAAoB,wBAACH,MAChCD,IAAIC,GAAGT,GAAAA,KAAQQ,IAAIC,GAAGN,OAAAA,KAAYK,IAAIC,GAAGH,KAAAA,KAASE,IAAIC,GAAGF,UAAAA,KACzDC,IAAIC,GAAGL,cAAAA,KAAkBI,IAAIC,GAAGJ,cAAAA,GAFD;AAIjC,IAAMQ,QAAQ,wBAACC,cAAkC;KAAIA,UAAUD;GAAjD;AAEP,IAAME,SAAS,wBAACD,cAAkCD,MAAMC,SAAAA,EAAWE,OAAO,CAACP,MAAMD,IAAIC,GAAGT,GAAAA,CAAAA,GAAzE;AAEf,IAAMiB,aAAa,wBAACH,cACzBD,MAAMC,SAAAA,EAAWE,OAAO,CAACP,MAAMD,IAAIC,GAAGN,OAAAA,CAAAA,GADd;AASnB,IAAMe,UAAU,wBAACJ,cACtBD,MAAMC,SAAAA,EAAWE,OACf,CAACP,MACC,CAACD,IAAIC,GAAGN,OAAAA,KACR,CAACK,IAAIC,GAAGF,UAAAA,MACPC,IAAIC,GAAGL,cAAAA,KAAkBI,IAAIC,GAAGJ,cAAAA,EAAc,GAL9B;AAQhB,IAAMc,UAAU,wBAACL,cACtBD,MAAMC,SAAAA,EAAWE,OAAO,CAACP,MAAMD,IAAIC,GAAGH,KAAAA,CAAAA,GADjB;AAGhB,IAAMc,gBAAgB,wBAACN,cAC5BD,MAAMC,SAAAA,EAAWE,OAAO,CAACP,MAAMD,IAAIC,GAAGF,UAAAA,CAAAA,GADX;;;ACtBtB,IAAMc,aAA4BC,uBAAOC,IAAI,2BAAA;AAQpD,SAASC,QAAAA;AACP,QAAMC,IAAIC;AACV,SAAQD,EAAEJ,UAAAA,MAAgB,CAAA;AAC5B;AAHSG,OAAAA,OAAAA;AAaF,SAASG,OAAOC,KAAc;AACnC,SAAO,CAACC,WAAAA;AACNL,IAAAA,MAAAA,EAAOM,KAAK;MAAEC,KAAKF;MAA4BD;IAAI,CAAA;EACrD;AACF;AAJgBD;AAgBT,SAASK,iBAAAA;AACd,SAAOR,MAAAA,EAAOS,OAAO,CAAA;AACvB;AAFgBD;;;AC5EhB,8BAAO;AA6CA,IAAME,UAAN,cAAsBC,MAAAA;EA7C7B,OA6C6BA;;;;;;;;;;;;;;EAQlB,CAACC,mBAAAA,IAAuB;EAEjC,YACWC,MACAC,MACAC,IACTC,QACSC,OACT;AACA,UACE;SAAYJ,IAAAA;SACAC,KAAKI,SAAS,IAAIJ,KAAKK,KAAK,MAAA,IAAU,QAAA;SACtCJ,EAAAA;EACPC,MAAAA;;;EACsBC,MAAMG,IAAI,CAACC,MAAM,OAAOA,CAAAA,EAAG,EAAEF,KAAK,IAAA,CAAA;CAAS,GAAA,KAX/DN,OAAAA,MAAAA,KACAC,OAAAA,MAAAA,KACAC,KAAAA,IAAAA,KAEAE,QAAAA;AAST,SAAKK,OAAO;EACd;AACF;AAmCA,IAAMC,SAAS,wBAACC,MAAwBA,GAAgCF,QAAQG,OAAOD,CAAAA,GAAxE;AAWf,IAAME,eAAe,oBAAIC,IAAa;EACpCC;EACAC;EACAJ;EACAK;EACAC;EACAC;EACAC;EACAC;EACAC;EACAC;EACA;CACD;AAGD,IAAMC,OAAO,oBAAIV,IAAa;EAACF;EAAQK;EAAQC;EAASI;EAAMF;CAAO;AAS9D,SAASK,qBAAqBC,MAAa;AAChD,QAAMC,QAASD,MAAqCrB,UAAU;AAC9D,MAAIsB,UAAU,EAAG,QAAO;AACxB,QAAMC,OAAOC,QAAQC,YAAY,qBAAqBJ,IAAAA;AACtD,SAAOE,SAASL,UAAaK,KAAKvB,WAAWsB;AAC/C;AALgBF;AAkBT,SAASM,iBAAAA;AAEd,QAAMC,UAAUC,eAAAA;AAGhB,QAAMC,WAAWC,mBAAAA;AAOjB,MAAIH,QAAQ3B,WAAW,GAAG;AACxB,UAAM,IAAIR,QACR,iBACA,CAAA,GACA,WACA,8EACA;MACE;MACA;KACD;EAEL;AAOA,QAAMuC,kBAAkB,IAAItB,IAAWkB,QAAQzB,IAAI,CAAC8B,MAAMA,EAAEC,GAAG,CAAA;AAE/D,QAAMC,QAAQ,oBAAIC,IAAAA;AAClB,aAAW,EAAEF,KAAKG,IAAG,KAAMT,SAAS;AAClC,UAAMU,IAAIhC,OAAO4B,GAAAA;AACjB,eAAW3B,KAAK;SAAK8B,IAAIE,aAAa,CAAA;SAASF,IAAIG,eAAe,CAAA;OAAM;AACtE,YAAMC,OAAON,MAAMO,IAAInC,CAAAA;AACvB,UAAIkC,SAAStB,QAAW;AACtB,cAAM,IAAI1B,QACR,uBACA;UAACa,OAAOC,CAAAA;WACR,GAAGkC,IAAAA,MAAUH,CAAAA,IACb,GAAGhC,OAAOC,CAAAA,CAAAA,oEACV;UACE,UAAUD,OAAOC,CAAAA,CAAAA,SAAWkC,IAAAA;UAC5B,qBAAqBH,CAAAA;UACrB;SACD;MAEL;AACAH,YAAMQ,IAAIpC,GAAG+B,CAAAA;IACf;EACF;AAmBA;AACE,eAAW,EAAEJ,KAAKG,IAAG,KAAMT,SAAS;AAClC,iBAAWgB,KAAKP,IAAIE,aAAa,CAAA,GAAI;AACnC,YAAIM,aAAaD,CAAAA,KAAME,kBAAkBF,CAAAA,EAAI;AAQ7C,YAAI,CAACvB,qBAAqBuB,CAAAA,EAAI;AAC9B,cAAM,IAAInD,QACR,uBACA;UAACa,OAAO4B,GAAAA;UAAM5B,OAAOsC,CAAAA;WACrB,GAAGtC,OAAO4B,GAAAA,CAAAA,cACV,GAAG5B,OAAOsC,CAAAA,CAAAA,iBAAmBtC,OAAO4B,GAAAA,CAAAA,2HAEpC;UACE,QAAQ5B,OAAOsC,CAAAA,CAAAA;UACf,MAAMtC,OAAOsC,CAAAA,CAAAA;SAEd;MAEL;IACF;EACF;AAeA;AACE,UAAMG,UAAUjB,SAASkB,OAAO,CAACzC,MAAM,CAAC4B,MAAMc,IAAI1C,CAAAA,CAAAA;AAClD,QAAIwC,QAAQ9C,SAAS,GAAG;AACtB,YAAMiD,QAAQH,QAAQ5C,IAAIG,MAAAA;AAC1B,YAAM,IAAIb,QACR,iBACAyD,OACA,uBACA,GAAGA,MAAMhD,KAAK,IAAA,CAAA,IAAS6C,QAAQ9C,WAAW,IAAI,OAAO,KAAA,mFACU8C,QAAQ9C,WAAW,IAAI,OAAO,MAAA,KAC7F;QACE,OAAOiD,MAAMjD,WAAW,IAAIiD,MAAM,CAAA,IAAK,cAAA;QACvC;OACD;IAEL;EACF;AAOA,QAAMC,WAAW,oBAAIf,IAAAA;AACrB,QAAMgB,YAAY,oBAAIhB,IAAAA;AACtB,aAAW,EAAEF,KAAKG,IAAG,KAAMT,SAAS;AAClC,UAAMU,IAAIhC,OAAO4B,GAAAA;AACjB,eAAWD,KAAKI,IAAIgB,WAAW,CAAA,GAAI;AACjC,UAAIlB,MAAMO,IAAIT,CAAAA,MAAOK,GAAG;AACtB,cAAMgB,SAASnB,MAAMO,IAAIT,CAAAA;AACzB,cAAM,IAAIxC,QACR,kBACA;UAAC6C;WACD,GAAGA,CAAAA,YACHgB,WAAWnC,SACP,GAAGmB,CAAAA,YAAahC,OAAO2B,CAAAA,CAAAA,6BACvB,GAAGK,CAAAA,YAAahC,OAAO2B,CAAAA,CAAAA,SAAWqB,MAAAA,8DACtCA,WAAWnC,SACP;UAAC,OAAOb,OAAO2B,CAAAA,CAAAA,OAASK,CAAAA;UAAe,qBAAqBA,CAAAA;YAC5D;UACE,UAAUhC,OAAO2B,CAAAA,CAAAA,SAAWK,CAAAA;UAC5B,YAAYgB,MAAAA,gCAAsCA,MAAAA;SACnD;MAET;IACF;AAKA,eAAWC,KAAKlB,IAAImB,WAAW,CAAA,GAAI;AAKjC,UAAID,MAAMrB,KAAK;AACb,cAAM,IAAIzC,QACR,kBACA;UAAC6C;WACD,GAAGA,CAAAA,YACH,GAAGA,CAAAA,mEACH;UAAC,UAAUA,CAAAA;UAA0B;SAAuC;MAEhF;AACA,UAAI,CAACN,gBAAgBiB,IAAIM,CAAAA,GAAI;AAC3B,cAAM,IAAI9D,QACR,kBACA;UAAC6C;WACD,GAAGA,CAAAA,YACH,GAAGA,CAAAA,YAAahC,OAAOiD,CAAAA,CAAAA,4BACvB;UACE,2BAA2BjD,OAAOiD,CAAAA,CAAAA;UAClC,aAAajD,OAAOiD,CAAAA,CAAAA,SAAWjB,CAAAA;SAChC;MAEL;IACF;AAEAa,aAASR,IAAIL,GAAG,IAAI5B,IAAI2B,IAAIgB,WAAW,CAAA,CAAE,CAAA;AACzCD,cAAUT,IAAIL,GAAG,IAAI5B,KAAK2B,IAAImB,WAAW,CAAA,GAAIrD,IAAIG,MAAAA,CAAAA,CAAAA;EACnD;AAKA,QAAMmD,OAAO,oBAAIrB,IAAAA;AAmBjB,QAAMsB,iBAAiB,wBAACC,MACtB;OAAIxB,MAAMyB,KAAI;IAAIZ,OAChB,CAACzC,MAAMA,MAAMoD,KAAKhD,OAAOkD,UAAUC,cAAcC,KAAKJ,GAAapD,CAAAA,CAAAA,GAFhD;AAkBvB,QAAMyD,YAAY;OAAI7B,MAAMyB,KAAI;IAAIZ,OAClC,CAACzC,MAAOA,EAAoCN,SAAS,CAAA;AAEvD,QAAMgE,cAAcD,UAAUhB,OAC5B,CAACzC,MAAMkB,QAAQC,YAAY,qBAAqBnB,CAAAA,MAAOY,MAAAA;AAOzD,MAAI6C,UAAU/D,UAAU,KAAKgE,YAAYhE,WAAW+D,UAAU/D,QAAQ;AACpE,UAAM,IAAIR,QACR,oBACAuE,UAAU7D,IAAIG,MAAAA,GACd,mBACA,iEAA4D0D,UAAU/D,MAAM,+FAG5E;MACE;MACA;MACA;KACD;EAEL;AAEA,aAAW,CAACiE,KAAK5B,CAAAA,KAAMH,OAAO;AAC5B,UAAMZ,QAAS2C,IAAsCjE;AAQrD,QAAIsB,UAAU,GAAG;AACfkC,WAAKd,IAAIuB,KAAK,CAAA,CAAE;AAChB;IACF;AAIA,QAAI,CAAC7C,qBAAqB6C,GAAAA,GAAM;AAC9B,YAAM1C,QAAOC,QAAQC,YAAY,qBAAqBwC,GAAAA;AACtD,YAAM,IAAIzE,QACR,oBACA;QAACa,OAAO4D,GAAAA;SACR,GAAG5D,OAAO4D,GAAAA,CAAAA,gBACV,GAAG5D,OAAO4D,GAAAA,CAAAA,aAAiB3C,KAAAA,6BACtBC,UAASL,SAAY,OAAOX,OAAOgB,MAAKvB,MAAM,CAAA,oEAEnD;QACE,wBAAwBK,OAAO4D,GAAAA,CAAAA;QAC/B;OACD;IAEL;AAEA,UAAM1C,OAAOC,QAAQC,YAAY,qBAAqBwC,GAAAA;AACtD,UAAMC,OAAgB,CAAA;AACtB3C,SAAK4C,QAAQ,CAACT,GAAGJ,MAAAA;AACf,YAAMzD,KAAK,GAAGQ,OAAO4D,GAAAA,CAAAA,2BAA+BX,CAAAA;AAEpD,UAAI,OAAOI,MAAM,cAAclD,aAAawC,IAAIU,CAAAA,GAAI;AAClD,cAAM,IAAIlE,QACR,2BACA;UAACa,OAAO4D,GAAAA;WACRpE,IACA,aAAayD,CAAAA,6HAEbnC,KAAK6B,IAAIU,CAAAA,IACL;UACE;UACA;UACA;YAEF;UACE;UACA;SACD;MAET;AAEA,YAAMU,MAAMV;AAEZ;AACE,YAAIW,KAAKnC,MAAMO,IAAI2B,GAAAA;AACnB,YAAIC,OAAOnD,QAAW;AAMpB,gBAAMoD,QAAQb,eAAeW,GAAAA;AAC7B,cAAIE,MAAMtE,WAAW,GAAG;AACtB,kBAAMuE,OAAOD,MAAM,CAAA;AACnBJ,iBAAKM,KAAKD,IAAAA;AACVF,iBAAKnC,MAAMO,IAAI8B,IAAAA;AACf,gBAAIF,OAAOhC,GAAG;AACZ,kBAAI,CAACc,UAAUV,IAAIJ,CAAAA,GAAIW,IAAIqB,EAAAA,GAAK;AAC9B,sBAAM,IAAI7E,QACR,kBACA;kBAACa,OAAO4D,GAAAA;kBAAM5D,OAAOkE,IAAAA;mBACrB1E,IACA,GAAGQ,OAAOkE,IAAAA,CAAAA,eAAoBlE,OAAO+D,GAAAA,CAAAA,oBAAwBC,EAAAA,WAAahC,CAAAA,qBAC1E;kBAAC,OAAOgC,EAAAA,OAAShC,CAAAA;iBAAY;cAEjC;AACA,kBAAI,CAACa,SAAST,IAAI4B,EAAAA,GAAKrB,IAAIuB,IAAAA,GAAO;AAChC,sBAAM,IAAI/E,QACR,sBACA;kBAACa,OAAO4D,GAAAA;kBAAM5D,OAAOkE,IAAAA;mBACrB1E,IACA,GAAGQ,OAAOkE,IAAAA,CAAAA,eAAoBlE,OAAO+D,GAAAA,CAAAA,uBAA2BC,EAAAA,KAChE;kBAAC,OAAOhE,OAAOkE,IAAAA,CAAAA,OAAYF,EAAAA;iBAA2B;cAE1D;YACF;AACA;UACF;AACA,cAAIC,MAAMtE,SAAS,GAAG;AACpB,kBAAMiD,QAAQqB,MAAMpE,IAAIG,MAAAA,EAAQoE,KAAI;AACpC,kBAAM,IAAIjF,QACR,uBACA;cAACa,OAAO4D,GAAAA;cAAM5D,OAAO+D,GAAAA;eACrBvE,IACA,GAAGoD,MAAMhD,KAAK,OAAA,CAAA,gBAAwBI,OAAO+D,GAAAA,CAAAA,kBACxC/D,OAAO4D,GAAAA,CAAAA,oCACZ;cACE,4BAA4B5D,OAAO+D,GAAAA,CAAAA;cACnC,gBAAgBnB,MAAM,CAAA,CAAE,OAAOA,MAAM,CAAA,CAAE;aACxC;UAEL;AACA,gBAAM,IAAIzD,QACR,iBACA;YAACa,OAAO4D,GAAAA;YAAM5D,OAAO+D,GAAAA;aACrBvE,IACA,GAAGQ,OAAO+D,GAAAA,CAAAA,qPAIV;YACE,OAAO/D,OAAO+D,GAAAA,CAAAA;YACd,iCAAiC/D,OAAO+D,GAAAA,CAAAA;WACzC;QAEL;AACA,YAAIC,OAAOhC,GAAG;AACZ,cAAI,CAACc,UAAUV,IAAIJ,CAAAA,GAAIW,IAAIqB,EAAAA,GAAK;AAC9B,kBAAM,IAAI7E,QACR,kBACA;cAACa,OAAO4D,GAAAA;cAAM5D,OAAO+D,GAAAA;eACrBvE,IACA,GAAGQ,OAAO+D,GAAAA,CAAAA,gBAAoBC,EAAAA,WAAahC,CAAAA,qBAC3C;cAAC,OAAOgC,EAAAA,OAAShC,CAAAA;aAAY;UAEjC;AACA,cAAI,CAACa,SAAST,IAAI4B,EAAAA,GAAKrB,IAAIoB,GAAAA,GAAM;AAC/B,kBAAM,IAAI5E,QACR,sBACA;cAACa,OAAO4D,GAAAA;cAAM5D,OAAO+D,GAAAA;eACrBvE,IACA,GAAGQ,OAAO+D,GAAAA,CAAAA,mBAAuBC,EAAAA,+BACjC;cACE,cAAcA,EAAAA;cACd,UAAUhE,OAAO+D,GAAAA,CAAAA,OAAWC,EAAAA;aAC7B;UAEL;QACF;MACF;AAEAH,WAAKM,KAAKJ,GAAAA;IACZ,CAAA;AAEAZ,SAAKd,IAAIuB,KAAKC,IAAAA;EAChB;AAUA,QAAMQ,QAAQ,oBAAIvC,IAAAA;AAClB,QAAMwC,QAAiB,CAAA;AACvB,QAAMC,OAAO,wBAACtE,MAAAA;AACZ,QAAIoE,MAAMjC,IAAInC,CAAAA,MAAO,GAAG;AAGtB,YAAMuE,MAAM;WAAIF,MAAMG,MAAMH,MAAMI,QAAQzE,CAAAA,CAAAA;QAAKA;QAAGJ,IAAIG,MAAAA;AACtD,YAAM,IAAIb,QACR,oBACAqF,KACA,GAAGA,IAAI,CAAA,CAAE,gBACT,0CAA0CA,IAAI5E,KAAK,MAAA,CAAA,KACnD;QACE;QACA;OACD;IAEL;AACA,QAAIyE,MAAMjC,IAAInC,CAAAA,MAAO,EAAG;AACxBoE,UAAMhC,IAAIpC,GAAG,CAAA;AACbqE,UAAMH,KAAKlE,CAAAA;AAKX,eAAW0E,KAAKxB,KAAKf,IAAInC,CAAAA,KAAM,CAAA,EAAIsE,MAAKI,CAAAA;AACxCL,UAAMM,IAAG;AACTP,UAAMhC,IAAIpC,GAAG,CAAA;EACf,GA1Ba;AA2Bb,aAAWA,KAAK4B,MAAMyB,KAAI,EAAIiB,MAAKtE,CAAAA;AAanC,QAAM4E,QAAQ,oBAAI/C,IAAAA;AAClB,QAAMgD,OAAO,wBAAC7E,MAAAA;AAYZ,QAAI,CAAC4B,MAAMc,IAAI1C,CAAAA,GAAI;AACjB,YAAM,IAAId,QACR,iBACA;QAACa,OAAOC,CAAAA;SACR,iBACA,GAAGD,OAAOC,CAAAA,CAAAA,sFAEV;QACE,OAAOD,OAAOC,CAAAA,CAAAA;QACd;OACD;IAEL;AACA,UAAM8E,MAAMF,MAAMzC,IAAInC,CAAAA;AACtB,QAAI8E,QAAQlE,OAAW,QAAOkE;AAC9B,UAAMC,QAAQ7B,KAAKf,IAAInC,CAAAA,KAAM,CAAA,GAAIJ,IAAIiF,IAAAA;AACrC,UAAMG,OAAO,IAAKhF,EAAAA,GAAqD+E,IAAAA;AACvEH,UAAMxC,IAAIpC,GAAGgF,IAAAA;AACb,WAAOA;EACT,GA/Ba;AAiCb,SAAO;IACL7C,KAAK,wBAAKiB,MAAmByB,KAAKzB,CAAAA,GAA7B;IACL6B,OAAO,IAAI9E,IAAIyB,MAAMyB,KAAI,CAAA;IACzB6B,UAAUC,gBAAgB9D,OAAAA;EAC5B;AACF;AAvfgBD;AAggBhB,SAAS+D,gBAAgB9D,SAAyC;AAMhE,QAAM+D,QAAQ/D,QAAQ3B;AACtB,QAAM2F,QAAQ,oBAAIxD,IAAAA;AAClB,aAAW,EAAEC,IAAG,KAAMT,SAAS;AAC7B,eAAW2B,KAAKlB,IAAImB,WAAW,CAAA,GAAI;AACjC,YAAMqC,IAAIvF,OAAOiD,CAAAA;AACjBqC,YAAMjD,IAAIkD,IAAID,MAAMlD,IAAImD,CAAAA,KAAM,KAAK,CAAA;IACrC;EACF;AACA,SAAO;OAAID;IACRzF,IAAI,CAAC,CAAC2F,SAAQvF,CAAAA,OAAQ;IAAEuF,QAAAA;IAAQC,KAAKC,KAAKC,MAAO1F,KAAKoF,QAAQ,KAAM,GAAA;IAAMO,IAAIP,QAAQ;EAAE,EAAA,EACxFjB,KAAK,CAACyB,GAAGC,MAAMA,EAAEL,MAAMI,EAAEJ,GAAG;AACjC;AAjBSL;AAoCF,SAASW,0BACdC,YACAd,QAAyB;AAEzB,QAAMzC,UAAUuD,WAAWtD,OAAO,CAACzC,MAAM,CAACiF,OAAMvC,IAAI1C,CAAAA,CAAAA;AACpD,MAAIwC,QAAQ9C,WAAW,EAAG;AAC1B,QAAMiD,QAAQH,QAAQ5C,IAAI,CAACI,MAAOA,EAAwBF,QAAQ,aAAA;AAClE,QAAM,IAAIZ,QACR,iBACAyD,OACA,uBACA,GAAGA,MAAMhD,KAAK,IAAA,CAAA,IAAS6C,QAAQ9C,WAAW,IAAI,OAAO,KAAA,yGAErD;IACE;IACA;GACD;AAEL;AAlBgBoG;;;ACrrBT,SAASE,uBAAuBC,YAAkB;AACvD,QAAMC,UAAUD,WAAWE,KAAI;AAC/B,MAAID,YAAY,IAAI;AAClB,WAAO;EACT;AAEA,QAAME,QAAQF,QAAQG,MAAM,KAAA;AAC5B,MAAID,MAAME,WAAW,GAAG;AACtB,WAAO,4BAA4BJ,OAAAA,6DAAoEE,MAAME,MAAM;EACrH;AAEA,QAAMC,aAAa;IAAC;IAAU;IAAQ;IAAgB;IAAS;;AAC/D,QAAMC,cAAkC;IACtC;MAAC;MAAG;;IACJ;MAAC;MAAG;;IACJ;MAAC;MAAG;;IACJ;MAAC;MAAG;;IACJ;MAAC;MAAG;;;AAGN,WAASC,IAAI,GAAGA,IAAI,GAAGA,KAAK;AAC1B,UAAMC,QAAQN,MAAMK,CAAAA;AACpB,UAAME,OAAOJ,WAAWE,CAAAA;AACxB,UAAM,CAACG,KAAKC,GAAAA,IAAOL,YAAYC,CAAAA;AAE/B,UAAMK,QAAQC,kBAAkBL,OAAOC,MAAMC,KAAKC,GAAAA;AAClD,QAAIC,UAAU,MAAM;AAClB,aAAOA;IACT;EACF;AAEA,SAAO;AACT;AAhCgBd;AAkChB,SAASe,kBACPL,OACAC,MACAC,KACAC,KAAW;AAGX,QAAMG,YAAYN,MAAML,MAAM,GAAA;AAC9B,aAAWY,QAAQD,WAAW;AAE5B,UAAME,YAAYD,KAAKZ,MAAM,GAAA;AAC7B,QAAIa,UAAUZ,SAAS,GAAG;AACxB,aAAO,WAAWK,IAAAA,YAAgBD,KAAAA;IACpC;AAEA,UAAMS,OAAOD,UAAU,CAAA;AACvB,UAAME,OAAOF,UAAU,CAAA;AAEvB,QAAIE,SAASC,QAAW;AACtB,YAAMC,UAAUC,OAAOH,IAAAA;AACvB,UAAI,CAACG,OAAOC,UAAUF,OAAAA,KAAYA,UAAU,GAAG;AAC7C,eAAO,yBAAyBX,IAAAA,YAAgBD,KAAAA;MAClD;IACF;AAEA,QAAIS,SAAS,KAAK;AAChB;IACF;AAGA,QAAIA,KAAKM,SAAS,GAAA,GAAM;AACtB,YAAMC,aAAaP,KAAKd,MAAM,GAAA;AAC9B,UAAIqB,WAAWpB,WAAW,GAAG;AAC3B,eAAO,oBAAoBK,IAAAA,YAAgBD,KAAAA;MAC7C;AACA,YAAMiB,aAAaJ,OAAOG,WAAW,CAAA,CAAE;AACvC,YAAME,WAAWL,OAAOG,WAAW,CAAA,CAAE;AACrC,UACE,CAACH,OAAOC,UAAUG,UAAAA,KAClB,CAACJ,OAAOC,UAAUI,QAAAA,KAClBD,aAAaf,OACbgB,WAAWf,OACXc,aAAaC,UACb;AACA,eAAO,oBAAoBjB,IAAAA,YAAgBD,KAAAA;MAC7C;AACA;IACF;AAGA,UAAMmB,MAAMN,OAAOJ,IAAAA;AACnB,QAAI,CAACI,OAAOC,UAAUK,GAAAA,KAAQA,MAAMjB,OAAOiB,MAAMhB,KAAK;AACpD,aAAO,oBAAoBF,IAAAA,YAAgBD,KAAAA;IAC7C;EACF;AAEA,SAAO;AACT;AAzDSK;;;ACFT,IAAMe,0BAA0B;AAChC,IAAMC,sBAAsB;AAC5B,IAAMC,gBAAgB;AACtB,IAAMC,YAAY;AAEX,IAAMC,WAA0BC,uBAAOC,IAAI,yBAAA;AAO3C,SAASC,IAAIC,SAAmB;AACrC,SAAO,SAA+DC,MAAO;AAC3E,UAAMC,UAAUD;AAChBE,WAAOC,eAAeF,SAASN,UAAU;MACvCS,OAAOL;MACPM,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACAL,WAAOC,eAAeF,SAAS,aAAa;MAC1CG,OAAO;MACPC,YAAY;MACZC,cAAc;MACdC,UAAU;IACZ,CAAA;AACA,WAAOP;EACT;AACF;AAjBgBF;AAoCT,SAASU,eAAeR,MAAY;AACzC,QAAMS,OAAQT,KAAoBL,QAAAA;AAClC,MAAI,CAACc,MAAM;AACT,UAAM,IAAIC,MACR,mDAAoDV,KAA2BW,QAAQ,WAAA,GAAc;EAEzG;AACAC,oBAAkBH,KAAKE,MAAM,QAAQ,KAAA;AACrC,MAAI,CAACF,KAAKI,YAAYJ,KAAKI,SAASC,KAAI,MAAO,IAAI;AACjD,UAAM,IAAIJ,MAAM,4CAAA;EAClB;AACA,QAAMK,YAAYC,uBAAuBP,KAAKI,QAAQ;AACtD,MAAIE,WAAW;AACb,UAAM,IAAIL,MAAM,sCAAsCK,SAAAA,EAAW;EACnE;AAEA,QAAME,UAAUR,KAAKQ,WAAW1B;AAChC,MAAI,CAAC2B,OAAOC,UAAUF,OAAAA,KAAYA,WAAW,GAAG;AAC9C,UAAM,IAAIP,MAAM,2DAAA;EAClB;AACA,MAAIO,UAAUzB,qBAAqB;AACjC,UAAM,IAAIkB,MAAM,gCAAgClB,mBAAAA,mBAAsC;EACxF;AAEA,QAAM4B,QAAQX,KAAKW,SAAS3B;AAC5B,MAAI,CAACyB,OAAOC,UAAUC,KAAAA,KAAUA,QAAQ,GAAG;AACzC,UAAM,IAAIV,MAAM,+DAAA;EAClB;AACA,MAAIU,QAAQ1B,WAAW;AACrB,UAAM,IAAIgB,MAAM,yCAAyChB,SAAAA,EAAW;EACtE;AAEA,SAAO;IAAEiB,MAAMF,KAAKE;IAAME,UAAUJ,KAAKI;IAAUI;IAASG;EAAM;AACpE;AAjCgBZ;AA4CT,SAASa,aAAarB,MAAcsB,WAAoB;AAC7D,QAAM,EAAEX,MAAME,UAAUI,SAASG,MAAK,IAAKZ,eAAeR,IAAAA;AAE1D,QAAMuB,WAAWD,UAAUE,IAAIxB,IAAAA;AAC/B,MAAI,OAAOuB,SAASE,QAAQ,YAAY;AACtC,UAAM,IAAIf,MAAM,+CAAA;EAClB;AACA,QAAMe,MAAMF,SAASE,IAAIC,KAAKH,QAAAA;AAE9B,SAAO;IAAEZ;IAAME;IAAUI;IAASG;IAAOO,SAASF;EAAI;AACxD;AAVgBJ;;;AjD2VhB,IAAAO,cAAkB;","names":["TABLE_META","REF_BRAND","Symbol","for","brandRef","v","kind","Object","defineProperty","value","enumerable","brandOf","undefined","hasOwn","isColRef","v","brandOf","$col","isSqlFragment","v","brandOf","f","$sql","undefined","Array","isArray","text","values","TX_EXPR","Symbol","for","isNowExpr","isColumnExpr","e","fn","TxRefError","Error","message","name","TxPlanError","EXPR","Symbol","for","REF","ROW","ROWS","TRAPPED_PROPS","toPrimitive","trap","prop","what","hint","description","String","now","makeExpr","fn","increment","by","assertAmount","inc","decrement","dec","test","Number","isFinite","negative","trimStart","startsWith","other","makeExpr","expr","Proxy","EXPR","get","target","prop","TRAPPED_PROPS","includes","trap","undefined","makeRef","op","field","REF","t","makeRowHandle","ROW","refDescriptor","v","d","isRefDescriptor","rowOpIndex","exprOf","e","isRowsHandle","ROWS","encodeValue","value","column","allowColumnExpr","ref","brandRef","$ref","isNowExpr","$expr","fn","TxPlanError","assertNoNestedHandles","encodeFilterValue","Array","isArray","map","Date","isColRef","isSqlFragment","out","k","Object","entries","encodeFilterMap","key","keys","sort","item","values","encodeMap","SKIPPED_OP","TxRowsImpl","guarded","builder","opIndex","what","then","TxRefError","expectOne","error","declareGuard","expectNone","expectAtLeast","n","assertGuardCount","expectAtMost","kind","Error","attachGuard","Number","isInteger","String","MAX_OPS","MAX_ROWS","TxPlanBuilder","ops","slots","table","name","insert","encoded","length","push","put","options","onConflict","insertMany","rows","opts","row","assertUniformRows","action","updateWhere","where","set","encodedWhere","encodedSet","deleteWhere","select","limit","lock","index","slot","guard","body","errorForSlot","first","want","wantKey","join","i","got","materializeResult","results","rowOf","rowOp","isPlainObject","result","proto","getPrototypeOf","prototype","runTxPlan","transport","handle","returned","response","txPlan","err","translateRejection","rejection","error_code","retryBudget","value","n","Number","isInteger","Error","assertPlanRetry","options","retryBudget","retry","Error","defOf","column","_def","columnToJSON","def","out","type","nullable","primaryKey","defaultValue","undefined","defaultRandom","defaultNow","renamedFrom","ignored","owns","references","table","onDeleteAction","index","counter","enumName","enumValues","unique","dimensions","policyToJSON","policy","name","command","roles","using","withCheck","permissive","commonSearchFields","search","synonyms","Object","keys","length","fromEntries","entries","map","word","alts","validity","searchToJSON","vectorColumn","from","model","textCols","text","Array","isArray","columns","v","metric","embed","provider","apiKeyName","baseURL","staleness","mode","chunks","c","size","sizeChars","overlap","overlapChars","vector","legs","leg","memoryToJSON","m","into","subject","extract","tableToJSON","schemaName","schema","rls","policies","uniqueConstraints","u","raw","rawConstraints","r","up","checks","expr","indexes","i","ix","where","expression","sort","nulls","include","dropConstraints","foreignKeys","fk","j","refTable","refColumns","onUpdate","onDelete","match","freeze","f","when","guards","g","event","exists","message","detail","hint","backfills","b","sql","appendOnly","find","sj","memory","qualifiedTableKey","tableName","toSchemaJSON","schemas","tables","extensions","meta","seen","Set","has","Error","add","values","json","push","exposed","REQUEST_ALS","Symbol","for","__requestALS","g","globalThis","AsyncLocalStorage","runtime","__setRuntime","services","__runWithRuntime","fn","run","REQUIRED_SERVICES","refuseIncompleteBox","missing","filter","k","undefined","length","Error","join","__getRuntime","scoped","getStore","LIFECYCLE","declaredLifecycle","start","shutdown","onStart","name","hook","push","onShutdown","reason","err","message","String","drain","hooks","h","reverse","console","error","__runStartHooks","slot","splice","cause","drained","__resetLifecycleHooks","makeServiceProxy","key","handler","get","_target","prop","receiver","client","value","Reflect","bind","Proxy","makeTableProxy","ops","prefix","_t","insert","data","aggregate","q","insertMany","rows","opts","update","where","id","set","delete","findById","findUnique","select","with","page","findMany","put","onConflict","updateMany","returning","deleteMany","count","search","params","similar","recommend","facets","supersede","row","claim","unique","extra","rawDatabase","makeTypedSurface","raw","reco","$query","sql","query","$diagnostics","diagnostics","$insert","table","$update","$delete","$findById","$findUnique","$page","$findMany","$put","$updateMany","$deleteMany","$count","$search","$similar","$recommend","$facets","$claim","$lockRows","ids","lockRows","$lockRowsWhere","lockRowsWhere","$advisoryXactLock","advisoryXactLock","$aggregate","$insertMany","$supersede","base","Object","assign","$atomic","options","atomic","parent","tx","typed","invoke","refuse","ambient","asService","Database","$attempt","attempt","$transaction","assertPlanRetry","builder","TxPlanBuilder","runTxPlan","makeTxPlanHandle","$command","txPlan","plan","command","target","startsWith","qualifiedTableKey","makeTxTablesAccessor","tablesProxy","publicTables","$asService","Documents","makeBucketsAccessor","storage","bucket","rawStorage","Storage","buckets","Cache","Secrets","Auth","Log","Notifications","rawFlags","Flags","isEnabled","flagName","context","getVariant","getAll","defaultOrContext","maybeContext","setOverride","Realtime","PalbaseModuleError","Error","code","status","details","message","name","makeHttpClient","cfg","request","method","path","options","headers","apiKey","init","body","undefined","Uint8Array","FormData","Blob","JSON","stringify","signal","doFetch","fetchImpl","globalThis","fetch","response","baseUrl","err","data","error","contentType","get","parsed","includes","json","catch","startsWith","arrayBuffer","text","ok","error_description","statusText","RoleNotDefined","Error","role","message","name","refuse","error","code","PalbaseModuleError","rolesPath","userId","base","encodeURIComponent","undefined","buildAuthClient","http","assignRole","request","revokeRole","rolesOf","data","roles","SEGMENT_RE","validateSegment","segment","label","test","Error","source","buildDocumentRef","http","path","set","data","request","body","get","response","error","status","raw","exists","undefined","Boolean","id","segments","split","length","ref","update","delete","collection","name","buildCollectionRef","state","where","orderBy","snapshot","doc","querySnapshot","docs","empty","size","docChanges","map","type","add","resp","field","op","value","direction","limit","n","narrowed","queryBody","documents","w","o","MAX_BATCH","buildDocumentsClient","String","filter","s","forEach","i","join","batch","operations","PalbaseModuleError","FLAG_NAME_RE","assertFlagName","flagName","test","Error","source","flagEnabled","value","flagVariant","name","isContextObject","v","Array","isArray","buildFlagsClient","http","cfg","resolveUserId","context","userId","getCurrentUserId","undefined","mergedPath","uid","encodeURIComponent","fetchMerged","request","service","setOverrideForUser","key","body","setOverridesForUser","values","clearOverrideForUser","clearAllOverridesForUser","batchSetOverrides","operations","ops","map","op","raw","user_id","isEnabled","res","error","data","status","getVariant","get","defaultOrContext","maybeContext","defaultValue","hasDefault","resp","getAll","Object","keys","flag","enabled","variant","setOverride","message","asService","mapEnvelope","res","map","error","data","undefined","status","toEmailTemplate","wire","view","id","slug","locale","subject","htmlBody","html_body","variables","isDefault","is_default","createdAt","created_at","updatedAt","updated_at","text_body","textBody","toSmsTemplate","body","buildNotificationsClient","http","push","send","params","request","email","templateSlug","html","text","rest","template_slug","sms","whatsapp","userId","user_id","events","options","query","limit","encodeURIComponent","String","verifications","start","check","inbox","list","opts","URLSearchParams","cursor","set","is_read","category","include_archived","toString","unreadCount","markRead","markAllRead","archive","preferences","get","update","emailTemplates","resp","rows","create","input","delete","smsTemplates","templates","registerDevice","unregisterDevice","deviceId","mintToken","secret","now","Math","floor","Date","header","Buffer","from","JSON","stringify","alg","typ","toString","payload","iss","role","iat","exp","sig","createHmac","update","digest","buildRealtimeClient","cfg","url","baseUrl","stateUrl","writeState","topic","key","value","del","length","data","error","PalbaseModuleError","apiJwtSecret","token","err","Error","message","op","doFetch","fetchImpl","globalThis","fetch","response","method","headers","Authorization","body","ops","status","undefined","detail","text","catch","state","set","clear","broadcast","channel","event","messages","private","slice","BUCKET_NAME_RE","STORAGE_PATH_RE","STORAGE_TRAVERSAL_RE","validateStoragePath","p","test","Error","source","toFileObject","bucket","row","name","path","size","contentType","checksum","width","height","thumbhash","variants","mapResponse","res","map","error","data","undefined","status","buildBucketClient","http","bucketName","publicOrigin","objectPath","upload","file","options","headers","upsert","body","ArrayBuffer","Uint8Array","request","r","download","Accept","getPublicUrl","variant","encodeURIComponent","createSignedUrl","expiresIn","list","prefix","params","URLSearchParams","set","limit","String","query","toString","objects","remove","paths","removed","push","move","from","to","copy","buildStorageClient","replace","buildModuleClients","cfg","baseUrl","replace","apiKey","serviceRoleKey","http","makeHttpClient","fetchImpl","Auth","buildAuthClient","Documents","buildDocumentsClient","Storage","buildStorageClient","publicOrigin","Notifications","buildNotificationsClient","Flags","buildFlagsClient","getCurrentUserId","Realtime","buildRealtimeClient","apiJwtSecret","realtimeApiJwtSecret","TABLE_META","Symbol","for","REF_TARGET","ForeignKeyBuilder","_def","name","trim","Error","columns","refTable","refColumns","on","cols","map","c","e","expr","kind","references","table","length","Object","defineProperty","value","enumerable","configurable","onUpdate","action","onDelete","match","m","foreignKey","toForeignKeyDef","b","def","join","FreezeBuilder","when","pred","toFreezeDef","freeze","undefined","out","target","PolicyExprRef","expr","bin","op","other","kind","left","right","toExpr","eq","neq","gt","gte","lt","lte","isNull","negated","and","others","parts","map","o","or","not","v","value","exprCtx","_columns","depth","ownTable","alias","col","name","auth","uid","lit","p","part","existsIn","table","predicate","meta","TABLE_META","inner","Object","keys","columns","node","outer","defineProperty","REF_TARGET","enumerable","configurable","quote","replace","PolicyBuilder","_def","command","roles","using","withCheck","permissive","for","to","memberOf","membershipTable","foreignKey","options","Error","column","userColumn","as","mode","policy","assertCheckNode","CHECK_BIN_OPS","literalSQL","Number","isFinite","String","checkNodeSQL","undefined","length","joiner","join","check","trim","can","def","Array","isArray","policies","prototype","hasOwnProperty","call","rel","reservedCanRelation","names","filter","Buffer","byteLength","all","hint","n","z","array","enum","tableName","b","entries","referencesThunk","selfRefColumn","reverseAs","forward","owns","refAs","endsWith","slice","GuardBuilder","_def","name","trim","Error","on","event","when","pred","expr","exists","table","predicate","exprCtx","existsIn","refuse","message","opts","detail","undefined","hint","column","toGuardDef","guard","b","def","backfill","name","sql","trim","Error","IndexBuilder","_def","name","trim","Error","unique","on","cols","columns","map","c","e","expr","kind","onExpression","expression","where","desc","sort","asc","nulls","include","index","toPolicyDef","p","PolicyBuilder","TABLE_META","Symbol","for","defineTable","input","reserved","reservedCanRelation","JSON","stringify","policies","exprCtx","Object","keys","rls","length","owned","colName","b","entries","builder","clone","create","getPrototypeOf","defineProperty","value","enumerable","writable","def","primaryKey","undefined","raw","slice","declaredChecks","checks","declaredIndexes","indexes","i","declaredFKs","foreignKeys","toForeignKeyDef","declaredFreezes","freeze","toFreezeDef","fz","join","declaredGuards","guards","toGuardDef","g","column","backfills","seen","Set","has","add","sql","dropConstraints","appendOnly","ignored","search","s","from","vector","model","Array","isArray","text","String","legs","leg","memory","values","ownerTable","handle","declaringSchemaOf","WeakMap","resolveReferences","tables","schemaName","table","qualifyRefTargets","selfRefColumn","references","qualifiedTableKey","referencesThunk","target","owner","targetColumn","find","targetSchema","get","defineSchema","set","m","t","into","subject","factCol","factDef","type","extensions","exposed","qualifyRefTargets","table","where","qualify","holder","what","target","REF_TARGET","undefined","targetSchema","declaringSchemaOf","get","Error","name","qualified","qualifiedTableKey","refTable","fk","foreignKeys","fz","freeze","g","guards","exists","qualifyExistsNodes","node","kind","v","Object","values","Array","isArray","e","CHANNELS","Symbol","for","ownerOnly","kind","publicChannel","opts","publish","state","paramCount","pattern","split","filter","s","startsWith","endsWith","length","defineChannels","map","entries","entry","Object","Error","push","c","authorize","handler","def","carrier","globalThis","existing","sameDeclaration","e","join","wireRow","JSON","stringify","read","write","toString","a","b","every","x","i","PALBASE_EXTENSIONS","EXTENSION_DEPENDENCIES","earthdistance","isPalbaseExtension","name","includes","CODECS","number","fromDb","v","Number","toDb","isSafeInteger","Error","String","tsType","decimal","undefined","refuseOnVector","def","modifier","type","ColumnBuilder","_def","existingDef","nullable","primaryKey","notNull","default","value","defaultValue","defaultRandom","defaultNow","dbAssigned","renamedFrom","previous","ignored","references","target","opts","referencesThunk","as","refAs","reverseAs","onDelete","onDeleteAction","index","counter","selfReferences","column","selfRefColumn","action","unique","asNumber","withCodec","asDecimal","codec","method","transform","fns","uuid","text","integer","bigint","numeric","boolean","timestamp","jsonb","enumType","name","values","builder","enumName","enumValues","vector","dimensions","isInteger","b","ownedByUser","table","owns","userRef","installationRef","raw","name","up","openai","embedding","model","opts","provider","apiKeyName","dimensions","undefined","baseURL","chat","SQLSTATE","Object","freeze","serializationFailure","deadlockDetected","queryCancelled","commandGuardFailed","isTransactionRollbackState","state","HTTP_ERROR_BRAND","Symbol","for","HttpError","Error","status","error","errorDescription","data","HTTP_ERROR_BRAND","name","undefined","toJSON","requestId","result","error_description","request_id","PalError","code","description","NamedHttpError","defaultCode","message","defaultMessage","spaced","replace","charAt","toUpperCase","slice","toLowerCase","BadRequest","Unauthorized","Forbidden","NotFound","Conflict","UniqueViolation","is","e","constraint","isRetryable","retryable","isTransactionRollbackState","sqlstate","SerializationFailure","SQLSTATE","serializationFailure","DeadlockDetected","deadlockDetected","TooManyRequests","makeTypedTable","name","raw","insert","data","aggregate","q","insertMany","rows","opts","put","onConflict","update","where","id","set","delete","findUnique","select","findById","page","findMany","updateMany","returning","undefined","deleteMany","count","makeTypedDB","schema","tables","key","Object","keys","tableDef","qualifiedTableKey","result","diagnostics","command","fn","options","builder","TxPlanBuilder","planTables","fromEntries","entries","map","table","runTxPlan","txPlan","plan","transaction","col","name","brandRef","$col","withRetry","fn","opts","budget","retryBudget","retry","attempt","e","isRetryable","sqlFragment","strings","values","$sql","text","defineRepository","table","opts","tenantColumn","tenant","rowKey","key","scope","scopeRow","id","scopedPayload","values","Repository","list","findMany","where","find","rows","limit","insert","update","patch","row","updateScoped","NotFound","String","updateMany","set","delete","deleteMany","DECLARATION_REFUSAL","Symbol","for","DeclarationRefused","Error","message","name","isDeclarationRefused","e","uniqueKeysOf","table","columns","inlinePrimary","keys","name","value","Object","entries","col","_def","primaryKey","push","unique","primary","length","unshift","key","seen","Set","filter","size","some","hasOwn","Error","identity","JSON","stringify","sort","has","add","baseTsType","def","codec","undefined","CODECS","tsType","type","values","enumValues","length","map","v","JSON","stringify","join","unhandled","Error","String","pgBrand","sort","rowType","base","branded","nullable","optionalOnInsert","defaultRandom","defaultNow","defaultValue","forwardName","column","endsWith","slice","describeOrigin","o","direction","table","renameCall","owns","target","references","selfRefColumn","buildRelations","schemas","out","Map","taken","schema","t","Object","tables","key","qualifiedTableKey","name","set","claim","tableKey","origin","edge","names","get","held","DeclarationRefused","heldFix","originFix","remedy","push","childKey","has","col","builder","entries","columns","_def","targetKey","refAs","to","kind","via","reverse","reverseAs","tableBlock","relations","indent","cols","rowLines","hasCanColumn","prototype","hasOwnProperty","call","some","r","canNames","policies","filter","p","command","permissive","Buffer","byteLength","canDoc","canLine","insertLines","opt","relEntries","uniqueKeysOf","b","search","appendOnly","refuseFreeFormTransforms","transform","where","makeEnvDts","publicSchema","find","s","others","publicBlocks","keys","body","schemaBlocks","inner","schemasBody","liveNames","names","Set","sort","memberName","name","test","JSON","stringify","members","length","map","n","join","bucketMembers","buckets","normalized","b","variants","byName","Map","set","keys","rows","get","union","v","makeStackDts","secrets","flags","ROUTES","Symbol","for","PARAM_BUFFER","ROOM","ROOM_HOOKS","RETURN_BUFFER","THROWS_BUFFER","carrierOf","target","ctor","ownRoutes","carrier","Object","prototype","hasOwnProperty","call","ownParamBuffer","recordRoute","fnName","method","subpath","options","routes","buffer","params","slice","sort","a","b","index","route","returnBuffer","undefined","returnSchema","throwsBuffer","throws","push","recordParam","meta","find","r","recordThrows","target","fnName","throws","carrier","carrierOf","routes","ROUTES","route","find","r","Object","prototype","hasOwnProperty","call","THROWS_BUFFER","throwsBuffer","getRoutes","ctor","returnBuffer","RETURN_BUFFER","buffered","returnSchema","undefined","map","params","slice","ownRoomBuffer","ROOM_HOOKS","hooks","messages","recordRoomHook","hook","buffer","existing","label","charAt","toUpperCase","Error","recordRoomMessage","name","schema","recordRoom","meta","ROOM","g","globalThis","REGISTRY","Symbol","for","all","includes","push","CONTROLLER_META","Symbol","for","REGISTRY","registry","g","globalThis","existing","fresh","getRegisteredControllers","slice","__resetRegisteredControllers","length","APP_DEFAULT_AUTH","appAuthSlot","defineDefaultAuth","auth","getDefaultAuth","__resetDefaultAuth","resolveEffectiveAuth","routeAuth","controllerAuth","RESERVED_FIRST_SEGMENT","assertNotReserved","path","subject","first","split","filter","Boolean","Error","Controller","basePath","options","ctor","route","getRoutes","subpath","method","carrier","meta","__palbase","undefined","defaultAuth","Object","defineProperty","value","enumerable","configurable","writable","all","includes","push","assertZeroArgConstructor","Ctrl","kind","arity","length","name","Error","makeMethodDecorator","method","subpath","options","Error","slice","toLowerCase","target","propertyKey","descriptor","verb","undefined","String","recordRoute","Get","Post","Put","Patch","Delete","Query","SHAPE","assertSurfaceName","name","decorator","kind","trim","Error","test","WEBHOOK_META","Symbol","for","WEBHOOK_EVENTS","carrierOf","ctor","Webhook","options","carrier","Object","defineProperty","value","enumerable","configurable","writable","On","event","target","fnName","existing","entries","push","String","getWebhookManifest","meta","validateWebhook","name","provider","secretEnv","secret","env","events","map","e","Error","assertSurfaceName","signature","sig","header","algo","encoding","signs","includes","timestampHeader","length","getWebhookConfig","container","instance","get","create","entry","prototype","hasOwnProperty","call","metaArg","Deny","Error","reason","name","HOOK_BLOCKING","Symbol","for","Hook","event","target","fnName","carrier","existing","entries","push","String","Object","defineProperty","value","enumerable","configurable","writable","bind","instance","kind","out","create","entry","prototype","hasOwnProperty","call","fn","meta","getHookConfig","ctor","container","blockingEntries","listenerEntries","WEBHOOK_EVENTS","length","get","blocking","listeners","getHookManifest","map","e","Upload","subpath","config","auth","rateLimit","uploadConfig","validateUploadConfigShape","options","undefined","target","propertyKey","recordRoute","String","UploadedObject","parameterIndex","recordParam","index","kind","c","Error","bucket","length","pathTemplate","Sse","subpath","config","auth","rateLimit","sseConfig","options","undefined","target","propertyKey","recordRoute","String","SseOut","parameterIndex","recordParam","index","kind","Signal","DEFAULT_GRACE_MS","assertPattern","pattern","includes","Error","replace","segments","split","some","s","seen","Set","startsWith","endsWith","name","slice","has","add","Room","options","ctor","recordRoom","events","graceMs","hookDecorator","hook","target","propertyKey","recordRoomHook","String","OnAuthorize","OnFirst","OnJoin","OnLeave","OnEmpty","OnMessage","schema","recordRoomMessage","makeParamDecorator","kind","extra","target","propertyKey","parameterIndex","recordParam","String","index","schema","undefined","name","Body","QueryParams","Headers","Param","User","OptionalUser","Client","RequestId","TraceId","Req","defineMiddleware","_fn","Error","import_zod","extendZodWithOpenApi","z","ERROR_REGISTRY","Symbol","for","BUILTIN_DATA_SCHEMAS","bad_request","object","fields","array","field","string","message","too_many_requests","retryAfter","number","int","getErrorRegistry","g","globalThis","m","Map","code","status","className","dataSchema","set","builtin","dataDigest","digestOf","defineError","Number","isInteger","Error","registry","existing","get","defaultClassName","undefined","sameShape","makeWithData","schema","HttpError","data","humanize","parse","name","makeWithoutData","cls","Object","defineProperty","value","TMP_REF","tmpRegistry","OpenAPIRegistry","register","openapi","generated","OpenApiGeneratorV31","definitions","generateComponents","out","components","schemas","digest","JSON","stringify","includes","split","map","p","charAt","toUpperCase","slice","join","s","replace","DI_INJECTABLES","Symbol","for","INJECTABLE","isInjectable","c","slot","g","globalThis","Injectable","target","push","__claimInjectables","splice","JOB","Symbol","for","WEBHOOK","HOOK_BLOCKING","HOOK_LISTENERS","ROOM","CONTROLLER","has","c","s","undefined","isEntryPointClass","owned","container","jobsOf","filter","webhooksOf","hooksOf","roomsOf","controllersOf","DI_MODULES","Symbol","for","slot","g","globalThis","Module","def","target","push","mod","__claimModules","splice","DiError","Error","DECLARATION_REFUSAL","kind","path","at","detail","fixes","length","join","map","f","name","nameOf","c","String","UNRESOLVABLE","Set","Object","Function","Number","Boolean","Array","Symbol","Promise","Date","undefined","DATA","declaresDependencies","ctor","arity","meta","Reflect","getMetadata","buildContainer","entries","__claimModules","declared","__claimInjectables","declaredModules","e","mod","owner","Map","def","m","providers","controllers","prev","get","set","p","isInjectable","isEntryPointClass","orphans","filter","has","names","exported","importsOf","exports","holder","i","imports","deps","implementorsOf","t","keys","prototype","isPrototypeOf","call","withArity","missingMeta","cls","list","forEach","dep","dm","impls","impl","push","sort","state","stack","walk","cyc","slice","indexOf","d","pop","cache","make","hit","args","inst","owned","pressure","computePressure","total","count","n","module","pct","Math","round","of","a","b","assertNoOrphanEntryPoints","registered","validateCronExpression","expression","trimmed","trim","parts","split","length","fieldNames","fieldRanges","i","field","name","min","max","error","validateCronField","listParts","part","stepParts","base","step","undefined","stepNum","Number","isInteger","includes","rangeParts","rangeStart","rangeEnd","num","DEFAULT_TIMEOUT_SECONDS","MAX_TIMEOUT_SECONDS","DEFAULT_RETRY","MAX_RETRY","JOB_META","Symbol","for","Job","options","ctor","carrier","Object","defineProperty","value","enumerable","configurable","writable","getJobManifest","meta","Error","name","assertSurfaceName","schedule","trim","cronError","validateCronExpression","timeout","Number","isInteger","retry","getJobConfig","container","instance","get","run","bind","handler","import_zod"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/runtime.ts","../src/db/input-guards.ts","../src/db/tx-plan.ts","../src/db/transaction-options.ts","../src/db/schema-json.ts","../src/clients/http.ts","../src/clients/auth.ts","../src/clients/documents.ts","../src/clients/flags.ts","../src/clients/notifications.ts","../src/clients/realtime.ts","../src/clients/storage.ts","../src/clients/index.ts","../src/db/policy.ts","../src/db/foreign-key.ts","../src/db/guard.ts","../src/db/backfill.ts","../src/db/schema.ts","../src/channels.ts","../src/db/extensions.ts","../src/db/columns.ts","../src/db/raw.ts","../src/db/embedding.ts","../src/db/sqlstate.ts","../src/errors.ts","../src/db/typed-db.ts","../src/db/repository.ts","../src/refusals.ts","../src/stack-gen.ts","../src/db/unique.ts","../src/db/env-gen.ts","../src/decorators/registry.ts","../src/decorators/controller.ts","../src/decorators/methods.ts","../src/decorators/surface-name.ts","../src/decorators/webhook.ts","../src/decorators/hook.ts","../src/decorators/upload.ts","../src/decorators/sse.ts","../src/decorators/room.ts","../src/decorators/params.ts","../src/middleware.ts","../src/error-registry.ts","../src/decorators/injectable.ts","../src/decorators/kinds.ts","../src/decorators/module.ts","../src/container.ts","../src/job.ts","../src/decorators/job.ts"],"sourcesContent":["export type {\n PBRequest,\n ClientInfo,\n RateLimitConfig,\n DBClient,\n DBOps,\n FileContext,\n Logger,\n CacheClient,\n SecretsService,\n PalbaseDocsClient,\n PalbaseCollectionRef,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseWhereOperator,\n PalbaseResult,\n Middleware,\n ErrorDef,\n ErrorMap,\n ErrorThrowers,\n} from \"./endpoint.js\";\nexport {\n Database,\n Auth,\n Documents,\n Storage,\n Cache,\n Secrets,\n Log,\n Notifications,\n Flags,\n Realtime,\n __setRuntime,\n __runWithRuntime,\n __requestALS,\n __getRuntime,\n // Where a long-lived resource lives: opened once as the app comes up, closed\n // when it goes away. `__runStartHooks` is the engine's door to them (it\n // CLAIMS the declarations, so a candidate release loaded beside the live one\n // never closes the live one's pool); `__resetLifecycleHooks` is for tests.\n onStart,\n onShutdown,\n __runStartHooks,\n __resetLifecycleHooks,\n} from \"./runtime.js\";\nexport type {\n RuntimeServices,\n RequestStore,\n LifecycleHook,\n ShutdownRunner,\n} from \"./runtime.js\";\n\n// The module clients and their composition root. The PROCESS calls\n// buildModuleClients once at boot and hands the result to createApp — which is\n// the whole reason this package now contains the implementations and not just\n// the interfaces they were being checked against by nobody.\nexport { buildModuleClients } from \"./clients/index.js\";\nexport type { ModuleClientsConfig } from \"./clients/index.js\";\nexport { makeHttpClient, PalbaseModuleError } from \"./clients/http.js\";\n// The one named refusal the role surface raises. Exported because a handler\n// branches on it: a role name that misses is a typo in committed code.\nexport { RoleNotDefined } from \"./clients/auth.js\";\nexport type { ModuleTransport, RequestOptions, TransportConfig } from \"./clients/http.js\";\n\nexport type {\n PalbaseAuthClient,\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseRealtimeClient,\n PalbaseFunctionsClient,\n PalbaseInvokeOptions,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseFlagSource,\n PalbaseSetOverrideResult,\n PalbaseSetOverridesResult,\n PalbaseClearOverrideResult,\n PalbaseClearAllOverridesResult,\n PalbaseBatchOverrideOperation,\n PalbaseBatchSetOverridesResult,\n PalbaseNotificationsClient,\n PalbasePushClient,\n PalbaseEmailClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseInboxClient,\n PalbasePreferencesClient,\n PalbaseAnalyticsClient,\n PalbaseAnalyticsQueryNamespace,\n PalbaseAnalyticsManagementNamespace,\n PalbaseLinksClient,\n // Shared local types\n PalbaseUser,\n PalbaseSession,\n PalbaseDeviceInfo,\n PalbaseAttestAndroidParams,\n PalbaseAttestAndroidResult,\n PalbaseAttestiOSParams,\n PalbaseAttestiOSResult,\n PalbaseBindDeviceParams,\n PalbaseVerifyRequestSignatureParams,\n PalbaseFileObject,\n PalbaseSignedUrlResponse,\n PalbaseUploadOptions,\n PalbaseTransformOptions,\n PalbaseListOptions,\n PalbasePushSendParams,\n PalbasePushSendResponse,\n PalbaseEmailSendParams,\n PalbaseEmailSendResponse,\n PalbaseSmsSendParams,\n PalbaseSmsSendResponse,\n PalbaseWhatsAppTemplate,\n PalbaseWhatsAppSendParams,\n PalbaseWhatsAppSendResponse,\n PalbaseWhatsAppEvent,\n PalbaseInboxSendParams,\n PalbaseInboxSendResponse,\n PalbaseInboxMessage,\n PalbaseInboxListOptions,\n PalbaseInboxListResult,\n PalbasePreferences,\n PalbaseNotificationChannel,\n PalbaseRegisterDeviceParams,\n PalbaseDeviceTokenView,\n PalbaseMultiChannelResponse,\n PalbaseAnalyticsProperties,\n PalbaseIdentifyTraits,\n PalbaseCountQueryInput,\n PalbaseCountResult,\n PalbaseEventsQueryInput,\n PalbaseEventsResult,\n PalbaseUsersQueryInput,\n PalbaseUsersResult,\n PalbaseFunnelQueryInput,\n PalbaseFunnelResult,\n PalbaseRetentionQueryInput,\n PalbaseRetentionResult,\n PalbaseCohortQueryInput,\n PalbaseCohortResult,\n PalbaseOverviewResult,\n PalbaseEventNamesResult,\n PalbaseUserDetailResult,\n PalbaseCreateLinkParams,\n PalbaseUpdateLinkParams,\n PalbaseLink,\n PalbaseLinkDetails,\n PalbaseLinkAnalytics,\n PalbaseQrCodeOptions,\n PalbaseMatchParams,\n PalbaseInitialLink,\n PalbaseListLinksOptions,\n PalbaseListLinksResult,\n} from \"./clients.js\";\nexport { defineSchema, defineTable, TABLE_META, index, IndexBuilder, foreignKey, freeze, guard, backfill } from \"./db/schema.js\";\nexport type { ForeignKeyBuilder, ForeignKeyDef, FkAction, FkMatch, FreezeBuilder, FreezeDef } from \"./db/foreign-key.js\";\nexport type { GuardBuilder, GuardDef, GuardEvent } from \"./db/guard.js\";\nexport type { BackfillDef } from \"./db/backfill.js\";\n// The declaration as DATA — what the deploy reads to build the database. The\n// bundler calls this; a project never has to.\nexport { toSchemaJSON } from \"./db/schema-json.js\";\nexport type { SchemaJSON, TableJSON, ColumnJSON, PolicyJSON, ForeignKeyJSON, FreezeJSON, GuardJSON, BackfillJSON } from \"./db/schema-json.js\";\n// `SchemaInput` is NOT here. It typed the retired dictionary form —\n// `defineSchema({ tables: { todos: { columns } } })` — which `defineSchema`\n// now refuses by name (FR-061), so nothing can be assigned to it and nothing\n// ever imported it. Publishing the type of a shape the code rejects is a\n// second way in that only exists in the editor: its JSDoc taught the old\n// layout to anyone who hovered it.\nexport type { SchemaDef, TableDef, TableInput, ColumnMap, TableHandle, IndexDef } from \"./db/schema.js\";\nexport { policy, can, check, PolicyBuilder, PolicyExprRef, exprCtx } from \"./db/policy.js\";\n// `TableRef` bir tablo bildiriminin ANNOTATION'ı: iki tablo birbirinin\n// kolonuna `existsIn` ile bakınca TypeScript ikisini de birbirinden\n// çıkarmaya çalışır ve döngüyü `any` ile keser. Annotation döngüyü kırar ve\n// kolon adlarını tipli bırakır — bu yüzden TÜKETİCİNİN yazabilmesi gerekir.\nexport type { PolicyDef, PolicyCommand, PolicyMode, PolicyExpr, PolicyBinOp, PolicyExprCtx, PolicyOperand, CheckDef, TableRef } from \"./db/policy.js\";\n// The realtime twin of `policy`: which channels exist and who may join them.\n// Undeclared channels are denied by the server, so this declaration is the\n// whole surface — the runtime reads it back off globalThis at boot.\nexport { defineChannels, ownerOnly, publicChannel } from \"./channels.js\";\nexport type { ChannelsDef, ChannelEntry, ChannelsInput, ChannelGrant, ChannelAuthorizeCtx } from \"./channels.js\";\nexport { PALBASE_EXTENSIONS, EXTENSION_DEPENDENCIES, isPalbaseExtension } from \"./db/extensions.js\";\nexport type { PalbaseExtension } from \"./db/extensions.js\";\nexport {\n uuid, text, integer, bigint, numeric, boolean, timestamp, jsonb, enumType, vector,\n ownedByUser, userRef, installationRef,\n} from \"./db/columns.js\";\nexport type { ColumnBuilder, ColumnDef, ColumnType, OnDeleteAction, AnyColumn } from \"./db/columns.js\";\nexport { raw } from \"./db/raw.js\";\nexport type { RawConstraintDef } from \"./db/raw.js\";\nexport { openai } from \"./db/embedding.js\";\nexport type { EmbeddingModelRef } from \"./db/embedding.js\";\nexport { makeTypedDB, col, sqlFragment, withRetry } from \"./db/typed-db.js\";\nexport type { AtomicDatabase, PageInput } from \"./db/typed-db.js\";\nexport type { Page, PageInfo, PageNavigation, RawPageOptions } from \"./db/page.js\";\nexport type { InsertManyOptions } from \"./db/bulk.js\";\nexport type { CommandOptions } from \"./db/command.js\";\nexport type { AtomicOptions, TransactionIsolation } from \"./db/transaction-options.js\";\nexport type {\n TypedDB,\n TypedTx,\n TypedTable,\n InsertShape,\n RowShape,\n EnvTypedDatabase,\n EnvServiceDatabase,\n EnvTypedTable,\n EnvTables,\n EnvSchemas,\n TxPlan,\n TxTables,\n ColRef,\n SqlFragment,\n SetValue,\n SetShape,\n // FİLTRE TİPLERİ — bir sorguyu parça parça kurup fonksiyonlar arasında\n // geçirebilmek için ADLANDIRILABİLİR olmaları gerekiyor. Yoksa\n // `function siparisFiltresi(): ???` yazılamıyor ve yazar ya `Parameters<...>`\n // gibi bir kaçamağa ya da her şeyi tek çağrıda toplamaya mecbur kalıyor.\n // (`TxWhere` — plan yolunun filtresi — zaten dışa aktarılıyordu; düz yolunki\n // atlanmıştı.)\n WhereFilter,\n WhereOp,\n QueryInput,\n MutateInput,\n AggregateInput,\n AggregateResult,\n InsertValues,\n OrderBySpec,\n FindManyOpts,\n} from \"./db/typed-db.js\";\n// Transaction plans: the `tx.tables.*` operation surface, its handles, and the\n// expressions a plan may write. `Database.$transaction()` is on `Database`.\nexport { increment, decrement, inc, dec, now, TxRefError, TxPlanError } from \"./db/tx-plan.js\";\nexport type {\n Ref,\n TxRow,\n TxRows,\n TxTable,\n TxPlanHandle,\n Materialized,\n TxNow,\n TxColumnExpr,\n TxInsertValue,\n TxSetValue,\n TxInsertShape,\n TxSetShape,\n TxWhere,\n TxSelectOptions,\n TxPlanBody,\n TxPlanResponse,\n TxPlanOpResult,\n TxPlanRejection,\n TxWireOp,\n TxWireRef,\n TxWireExpr,\n TxWireGuard,\n TxWireValue,\n} from \"./db/tx-plan.js\";\n// Kiracıya kapsanmış CRUD'un TEK yazımı. `defineRepository` bir TABAN SINIFI\n// üretir (`class TodoRepository extends defineRepository(Database.public.todos,\n// { tenant: \"household_id\" }) {}`); `RepositoryOf` onun yüzeyi, `RepositoryTable`\n// ise repo'nun tablodan istediği alt küme — kendi tablo sarmalayıcısını yazan\n// bir proje ona göre yazar. Satır anahtarı varsayılan olarak `id`, ama SABİT\n// DEĞİL: `defineTable` bir `id` kolonu şart koşmadığı için `{ key: \"slug\" }`\n// ile adlandırılabiliyor (`DefaultRowKey`/`RowKey` o seçimin tipleri).\nexport { defineRepository } from \"./db/repository.js\";\nexport type {\n DefaultRowKey,\n MissingRowKey,\n RepositoryOf,\n RepositoryTable,\n RowKey,\n} from \"./db/repository.js\";\nexport type { Tables, TableTypes } from \"./db/env.js\";\nexport { makeEnvDts } from \"./db/env-gen.js\";\n// `config/` IS GONE, and so is the purchases family. Both were author-facing\n// surfaces with nothing behind them.\n//\n// The five config declarations nobody applied — storage, flags, notifications,\n// egress, auth — stopped being applied when the server-side declaration applier\n// was retired (v2 S-005, \"settings have one door, and a second one is how the\n// two disagree\"); `contract_lock_test.go` keeps it retired, and its own comment\n// records that the applier produced that silent failure FIVE times. The two that\n// still worked travelled by CLI courier: `config/secrets.ts` gated the push and\n// `config/test-users.ts` was PUT at the stack. Both jobs are now done where the\n// setting lives — `palbase secret set`, `palbase test-user templates set` — and\n// what a controller may SPELL comes back as a type instead of a declaration.\n//\n// `purchases` never had a v2 backend at all: v2 contains no palstore, which\n// `clients/index.ts` recorded on 2026-08-15 while deliberately leaving the tree\n// in place. It is taken now.\n//\n// The rule that replaced all of it: the schema files under `db/` and\n// behaviour-carrying code\n// live in the repo; everything else is CONFIGURATION and is set through the CLI\n// (later MCP) against the stack. Codegen exists so that code can be written\n// against it — a generated type is not a declaration, and it produces no file an\n// author edits.\nexport type { PalbaseSecretName, PalbaseFlagKey, PalbaseBucketName, PalbaseRoleName, Roles } from \"./stack.js\";\nexport { makeStackDts } from \"./stack-gen.js\";\nexport type { StackNames } from \"./stack-gen.js\";\n// Class-controller decorator model (replaces defineController/defineHandler/route).\n// `getRegisteredControllers` is what makes exporting a controller OPTIONAL:\n// importing the file registers it. `Controller` stays exported for authoring.\nexport { Controller, getRegisteredControllers, __resetRegisteredControllers } from \"./decorators/controller.js\";\n// The APPLICATION-level ring of the auth cascade (route → controller →\n// application → true). Declared once at module scope instead of repeating the\n// same `auth` on every @Controller — the repetition is what gets forgotten.\nexport { defineDefaultAuth, __resetDefaultAuth, assertZeroArgConstructor, resolveEffectiveAuth } from \"./decorators/controller.js\";\nexport type { ControllerOptions } from \"./decorators/controller.js\";\nexport { Get, Post, Put, Patch, Delete, Query } from \"./decorators/methods.js\";\nexport { Deny, getHookConfig, getHookManifest, Hook } from \"./decorators/hook.js\";\nexport type { HookFn, ResolvedHookClass } from \"./decorators/hook.js\";\nexport { Upload } from \"./decorators/upload.js\";\nexport type { UploadConfig } from \"./decorators/upload.js\";\n// `UploadedObject` is exported from upload.js, where BOTH the `@UploadedObject()`\n// decorator value AND the `UploadedObject` type are declared. One module → one\n// export name carries both — authors write `@UploadedObject()` (value) and\n// `: UploadedObject` (type) with a single imported name.\nexport { UploadedObject } from \"./decorators/upload.js\";\n// `@Sse` + its two parameter companions. `SseWriter` is the writer `@SseOut()`\n// injects; `SseConfig` is the route marker's type. The pipeline keys off the\n// config's PRESENCE, not the HTTP verb — see decorators/sse.ts.\nexport { Sse, SseOut, Signal } from \"./decorators/sse.js\";\nexport type { SseConfig, SseWriter } from \"./decorators/sse.js\";\n\n// `@Room` + its six lifecycle hooks. A room is the realtime surface a backend\n// can MANAGE rather than only talk on: it sees who joined, who left, and when\n// nobody is watching any more. Marked by the config's PRESENCE, like every\n// other decorator here — see decorators/room.ts.\nexport {\n Room,\n OnAuthorize,\n OnFirst,\n OnJoin,\n OnLeave,\n OnEmpty,\n OnMessage,\n} from \"./decorators/room.js\";\nexport type { RoomOptions } from \"./decorators/room.js\";\nexport {\n Body,\n QueryParams,\n Headers,\n Param,\n User,\n OptionalUser,\n Client,\n RequestId,\n TraceId,\n Req,\n} from \"./decorators/params.js\";\nexport type { RouteOptions, HttpMethodUpper, ThrowDescriptor, RouteMeta, ParamMeta, ParamKind } from \"./decorators/registry.js\";\n// recordThrows is the stager-injected carrier for inferred throw descriptors\n// (the recordReturn twin) — public so the injected IIFE in a deployed bundle\n// can call it via `require(\"@palbase/backend\").recordThrows(...)`.\nexport { recordThrows } from \"./decorators/registry.js\";\n// getRoutes reads a controller's RouteMeta[] straight from the registry — the\n// isolate runtime enumerates routes with it instead of the worker.js raw-Symbol\n// fallback (the ROUTES symbol stays, both fallbacks keep reading it).\nexport { getRoutes } from \"./decorators/registry.js\";\nexport { defineMiddleware } from \"./middleware.js\";\nexport type { MiddlewareContext, MiddlewareHandler } from \"./middleware.js\";\n// The authenticated-user TYPE is exported as `UserT` (not `User`) because the\n// value name `User` is the @User() parameter decorator (exported above). A\n// controller annotates `@User() user: UserT` — decorator for the value\n// position, `UserT` for the type. (NestJS-style: same name as the decorator\n// would collide in the value+type namespaces.)\nexport type { User as UserT, VerifiedDevice, HttpMethod, AuthConfig } from \"./types.js\";\nexport {\n HttpError,\n PalError,\n BadRequest,\n Unauthorized,\n Forbidden,\n NotFound,\n Conflict,\n TooManyRequests,\n // 23505, typed. The engine throws it; a caller branches on `.constraint`\n // instead of matching the driver's message string.\n UniqueViolation,\n SerializationFailure,\n DeadlockDetected,\n isRetryable,\n} from \"./errors.js\";\n// Typed project errors — defineError returns an HttpError subclass and\n// self-registers {code, status, dataSchema} in the project-global error\n// registry (the OpenAPI spec twins join `RouteMeta.throws` against it).\nexport { defineError, getErrorRegistry } from \"./error-registry.js\";\nexport type { RegisteredError, DefinedError, DefinedErrorWithData } from \"./error-registry.js\";\nexport type { JobMeta } from \"./job.js\";\nexport type { WebhookProvider, WebhookMeta, WebhookRequest } from \"./webhook.js\";\n// Webhooks and jobs are classes: `@Webhook`/`@On` for inbound webhooks,\n// `@Job` for cron. Both take their name from their file — see decorators/*.\nexport { getWebhookConfig, getWebhookManifest, On, Webhook } from \"./decorators/webhook.js\";\n\n// ── dependency injection ───────────────────────────────────────────────────\n//\n// `Injectable` and `Module` are the whole authoring surface: a class says it can\n// be resolved, and ONE module says who owns it, what it exports and what it may\n// reach. There is no `inject()`, no `@Inject`, no token registry — a dependency\n// is named by its constructor parameter's type and by nothing else.\nexport { Injectable } from \"./decorators/injectable.js\";\n// Which of a container's owned classes are entry points of each kind. Discovery\n// used to be a DIRECTORY (jobs/*.ts); now a module lists the class and the\n// decorator says what it is.\nexport { controllersOf, hooksOf, jobsOf, roomsOf, webhooksOf } from \"./decorators/kinds.js\";\nexport { Module } from \"./decorators/module.js\";\nexport type { ModuleDef, Token } from \"./decorators/module.js\";\n// Internal seam, exported for the same reason __runStartHooks is: the engine and\n// the bundle carry SEPARATE copies of this package, and claiming has to be done\n// by the copy that builds the container.\nexport { __claimModules } from \"./decorators/module.js\";\n// The `@Injectable()` half of the same seam. It is what FR-010 counts, and a\n// test fixture that builds two containers in one process has to drain it\n// between them the way it drains modules — a leftover fails the NEXT build with\n// a true refusal about the wrong test.\nexport { __claimInjectables } from \"./decorators/injectable.js\";\nexport { DiError } from \"./container.js\";\n// THE ORPHAN CHECK, and it was a READER WITH NO WRITER.\n//\n// `build-check.js` has always guarded its call with\n// `typeof sdk.assertNoOrphanEntryPoints === 'function'` — and this line was\n// missing, so the guard was false every time and the check never ran on the\n// build path. Measured 2026-09-02 through the real CLI: a `@Controller` that no\n// module lists entered the route table and `palbase build` printed\n// \"build OK — 6 route(s)\", exit 0. The runtime refuses it at boot, which is\n// exactly the failure `palbase build` exists to catch first.\n//\n// `createApp` calls it too; it is exported because the LOCAL build has to reach\n// the same decision with the same code, which is the whole premise of that file.\nexport { assertNoOrphanEntryPoints } from \"./container.js\";\n// `createApp` calls this and hands the result back as `App.container`; a project\n// almost never needs it directly. It is exported because the runtime is the\n// framework's OTHER HALF and builds containers of its own, and because a\n// hand-built one is validated exactly like the engine's — same claim, same\n// refusals, no second way to get an unvalidated graph.\nexport { buildContainer } from \"./container.js\";\nexport type { Container, DiKind, ModulePressure } from \"./container.js\";\nexport type { ResolvedWebhook, SignatureSpec, WebhookEventHandler, WebhookOptions } from \"./decorators/webhook.js\";\nexport { getJobConfig, getJobManifest, Job } from \"./decorators/job.js\";\nexport type { JobOptions, ResolvedJob } from \"./decorators/job.js\";\n// `Resource` is GONE, not deprecated. Its boot registry was never wired: nothing\n// in the runtime ever called `__runResourceBoot` (measured 2026-08-29 —\n// `grep -rn \"ResourceBoot\"` across v2/runtime and palsvc returned nothing), so\n// `init(env)` never ran, the declared secrets never arrived, and a project that\n// wrote one got an object whose fields sat at their initializers with no error\n// anywhere. That is the same silence the `auth`/`storage`/`documents` hook\n// helpers were removed for, one surface down.\n//\n// Nothing replaces it, because the thing it was ceremony around is already the\n// stack's: the VAULT holds what a backend may read, the runtime lists those names\n// off it and mirrors them into `process.env` at boot, and `Secrets.get()` reads a\n// value with the rotation the deploy generation already carries. A field frozen\n// once inside `init(env)` could not have that. `static secrets` was therefore a\n// third list of names, behind the vault and behind `config/secrets.ts` — which is\n// itself down to a hint rather than a constraint (v2/runtime/src/server.ts:517).\n// `config/egress.ts` fences the calls a resource would have made and\n// `openai.embedding(...)` in the schema puts the one vendor client the platform\n// actually runs where the platform runs it. `resources/` stays exactly what the\n// bundler already treats it as — a directory of plain modules a controller\n// imports.\n// Types only. A hook is declared with @Hook/@On in hooks/*.ts.\n//\n// The `auth`/`storage`/`documents` helpers that used to live here are gone, not\n// deprecated: they returned a record nothing in the runtime or the bundler ever\n// read, so a project that called one got a handler that never ran and no error\n// anywhere. api-surface.mjs asks for a deprecation bridge because a major locks\n// every tenant's deploy — a real cost, and the reason this shipped as a bridge\n// in 20.0.0. There are no production tenants to lock yet (owner's call,\n// 2026-08-22), so the bridge is spending a release to soften a break nobody can\n// feel, and the honest surface is the one with no dead names in it.\nexport type {\n HookMeta,\n AuthHookEvent,\n DocumentHookEvent,\n FileUploadedEvent,\n FileDeletedEvent,\n} from \"./hooks.js\";\nexport { z } from \"zod\";\n\nexport { DeclarationRefused, isDeclarationRefused, DECLARATION_REFUSAL } from \"./refusals.js\";\nexport type { UniqueWhere } from \"./db/unique.js\";\nexport type { DatabaseBudget, DatabaseDiagnostics, DatabaseDiagnosticsOptions, DatabaseQueryEvent } from \"./db/diagnostics.js\";\n","/**\n * runtime.ts — request-scoped service singletons.\n *\n * The backend SDK no longer threads a `ctx` god-object through every handler.\n * Instead, controller methods import PascalCase service singletons directly:\n *\n * import { Controller, Post, Body, Database } from \"@palbase/backend\";\n *\n * \\@Controller(\"/todos\")\n * export default class TodosController {\n * \\@Post(\"\") create(\\@Body(CreateTodoBody) body: CreateTodoBody): unknown {\n * return Database.public.todos.insert({ title: body.title });\n * }\n * }\n *\n * The singletons are thin Proxies. Every property access forwards to the live\n * client for the CURRENT request scope, resolved through {@link __getRuntime}.\n *\n * # Request-scope resolution (persistent app-server)\n *\n * The runtime is a long-running Node process that serves many concurrent\n * requests on one event loop (NOT a fresh subprocess per request). A single\n * module-global slot would let one in-flight request's services bleed into\n * another's. So the services are carried in an {@link AsyncLocalStorage} store\n * ({@link __requestALS}) that the runtime sets per request with\n * {@link __runWithRuntime}; every async continuation of that request reads its\n * own store. `__getRuntime` reads the ALS store first; the module-global slot\n * (set by {@link __setRuntime}) is only a fallback for callers that run OUTSIDE\n * an ALS scope (dev-server, unit tests, the legacy single-shot path). Because\n * each `br-<ref>` pod is single-tenant, there is no cross-tenant leakage; the\n * ALS store is what prevents cross-REQUEST leakage within the shared process.\n *\n * The seam that makes `import { Database } from \"@palbase/backend\"` resolve to\n * the runtime-injected client: `@palbase/backend` is marked esbuild-EXTERNAL\n * when the tenant bundle is built, and the package is installed globally in the\n * pod (NODE_PATH=/usr/local/lib/node_modules). So worker.js's\n * `require('@palbase/backend')` and the bundle's `import` resolve to ONE shared\n * module instance — the ALS store and `__setRuntime` slot on that instance are\n * visible to the singletons the bundle imported.\n */\n\nimport type { PalbaseFlagKey } from \"./stack.js\";\nimport type { Buckets, BucketTypes, Schemas } from \"./db/env.js\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type {\n DBClient,\n AtomicClient,\n DBOps,\n CacheClient,\n Logger,\n PalbaseDocsClient,\n SecretsService,\n} from \"./endpoint.js\";\nimport type {\n PalbaseAuthAdminClient,\n PalbaseStorageClient,\n PalbaseBucketClient,\n PalbaseNotificationsClient,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n PalbaseFlagContext,\n PalbaseFlagVariant,\n PalbaseFlag,\n PalbaseFlagValue,\n PalbaseSetOverrideResult,\n PalbaseRealtimeClient,\n} from \"./clients.js\";\nimport type { PalbaseResult } from \"./endpoint.js\";\nimport type {\n EnvTypedDatabase,\n EnvServiceDatabase,\n AtomicDatabase,\n EnvTables,\n TxPlan,\n TxTables,\n} from \"./db/typed-db.js\";\nimport type { Materialized } from \"./db/tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./db/tx-plan.js\";\nimport { assertPlanRetry, type AtomicOptions } from \"./db/transaction-options.js\";\nimport { qualifiedTableKey } from \"./db/schema-json.js\";\nimport type { DollarOps } from \"./db/typed-db.js\";\n\n/** The set of live clients the runtime injects per request scope.\n *\n * Realtime is BROADCAST-ONLY here (a stateless handler can push an event but\n * cannot hold a subscription socket — `subscribe()` lives on the client SDK).\n *\n * EXCLUDED on purpose: Functions, Links, Analytics. They are not exposed as\n * backend handler singletons — out of scope for backend endpoints. `Auth` is\n * here in its ROLE-ASSIGNMENT shape only: signing in is the client SDK's job,\n * but granting a role is an operator verb the tenant's own handler needs\n * (FR-009). */\nexport interface RuntimeServices {\n Database: DBClient;\n Auth: PalbaseAuthAdminClient;\n Secrets: SecretsService;\n Documents: PalbaseDocsClient;\n Storage: PalbaseStorageClient;\n Cache: CacheClient;\n Log: Logger;\n Notifications: PalbaseNotificationsClient;\n Flags: PalbaseFlagsClient;\n Realtime: PalbaseRealtimeClient;\n}\n\n/**\n * The per-request ALS box.\n *\n * `runtime` is the service bundle. `userId` is the request's authenticated user\n * id, written by the runtime immediately after it assembles the request object\n * (worker.js: `requestALS.getStore().userId = pbReq.user?.id || null`) and\n * `null` on an anonymous request. It was already being written there for the\n * Flags client's auto-bind; declaring it here makes the existing contract typed\n * instead of implicit, which is what lets `currentSubjectId()` read a\n * server-owned identity rather than trusting anything the caller sent.\n */\nexport interface RequestStore {\n runtime: RuntimeServices;\n userId?: string | null;\n /** This request's id (`req_…`), written by the runtime. Used as the spend\n * idempotency scope when the caller supplied no `Idempotency-Key`. */\n requestId?: string;\n /** The caller's `Idempotency-Key` header, or `null` when absent. What makes a\n * client's retry replay its first result instead of charging twice. */\n idempotencyKey?: string | null;\n}\n\n/**\n * Per-request store. The persistent runtime runs each request inside\n * {@link __runWithRuntime}, so every async continuation of that request reads\n * its OWN `runtime` (and any other request-scoped fields the runtime adds).\n *\n * Exported with a `__` prefix so the runtime (worker.js) shares the SAME ALS\n * instance across the one module instance — two ALS instances would silently\n * not see each other's stores. NOT part of the public author-facing API.\n */\n/**\n * The per-request store — ON globalThis under a well-known Symbol, for the same\n * reason `lifecycleHooks` and the controller registry are.\n *\n * MEASURED, through the production package gate: `tsup` emits `dist/index.cjs`\n * and `dist/test/index.cjs` as SEPARATE bundles and each inlines this module.\n * With a module-local `AsyncLocalStorage`, `withServices` (which ships from the\n * `/test` subpath) opened a scope in ITS copy while the `Database` singleton\n * (which ships from the root) read the OTHER copy's — and the ambient service a\n * test had just installed was invisible:\n *\n * Error: Palbase services accessed outside a request scope.\n *\n * The unit tests could not see it: inside the package there is only ever one\n * copy. It took calling the built artifact the way a consumer does. Same class\n * as the defect `@Module`'s slot comment describes — two module-local values\n * where the two halves of one contract must agree.\n *\n * SÜRÜMSÜZ, VE BU BİLİNÇLİ. Anahtar `…requestALS@32` gibi sürümlenseydi iki\n * major aynı süreçte ALS'i paylaşmayı BIRAKIRDI — yani yukarıda anlatılan kusur\n * sürüm sınırında geri gelirdi. Bedeli de gerçek ve burada yazılı:\n * `RequestStore.runtime` zorunlu bir `RuntimeServices` ve o küme büyüyor\n * (30.0.0 `Auth` ile 9→10). Eski bir majorün yazdığı kutuyu yeni bir major\n * okursa yeni alan `undefined` gelir.\n *\n * Bu pakette YEDİ well-known Symbol var ve hepsi sürümsüz (`httpError`,\n * `engineRaised`, `channels`, `errorRegistry`, `declarationRefusal`,\n * `lifecycleHooks`, ve bu). Yalnız BİRİNİ sürümlemek tutarsızlıktan başka bir\n * şey üretmez: karar paket geneli olmalı ve `RequestStore`'un şekil\n * sözleşmesiyle birlikte alınmalı (sapma defteri D-05).\n */\nconst REQUEST_ALS: unique symbol = Symbol.for(\"palbase.backend.requestALS\") as never;\n\nexport const __requestALS: AsyncLocalStorage<RequestStore> = ((): AsyncLocalStorage<RequestStore> => {\n const g = globalThis as unknown as Record<symbol, AsyncLocalStorage<RequestStore> | undefined>;\n return (g[REQUEST_ALS] ??= new AsyncLocalStorage<RequestStore>());\n})();\n\n/** Process-global fallback slot. Used only OUTSIDE an ALS scope (dev-server,\n * unit tests, legacy single-shot worker). Inside the persistent server every\n * request runs in {@link __requestALS}, which takes precedence. */\nlet runtime: RuntimeServices | null = null;\n\n/** Install the live clients in the process-global fallback slot.\n *\n * Persistent-server requests should use {@link __runWithRuntime} instead; this\n * remains for dev-server / tests / the legacy single-shot path that run without\n * an ALS scope. NOT part of the public author-facing API. */\nexport function __setRuntime(services: RuntimeServices): void {\n runtime = services;\n}\n\n/** Run `fn` with `services` bound as the request-scoped runtime.\n *\n * The persistent worker calls this once per request so concurrent requests\n * never share a services slot. NOT part of the public author-facing API. */\nexport function __runWithRuntime<T>(services: RuntimeServices, fn: () => T): T {\n return __requestALS.run({ runtime: services }, fn);\n}\n\n/** Read the live clients, throwing if accessed outside a request scope.\n *\n * Resolves the ALS store first (persistent server, per-request), then the\n * process-global fallback (dev-server / tests). NOT part of the public\n * author-facing API — used by the runtime and the singleton Proxies. */\n/**\n * Bir kutunun TAŞIMASI GEREKEN servisler.\n *\n * `withServices`'in listesiyle aynı gerçeği söylüyor ama BURADA yaşamak\n * zorunda: `test/` yalnız test yüzeyinde, bu kontrol ise her isteğin yolunda.\n * İkisi de `satisfies` ile `RuntimeServices`'a pinli, yani biri eksik kalırsa\n * derleme durur.\n */\nconst REQUIRED_SERVICES = [\n \"Database\",\n \"Auth\",\n \"Secrets\",\n \"Documents\",\n \"Storage\",\n \"Cache\",\n \"Log\",\n \"Notifications\",\n \"Flags\",\n \"Realtime\",\n] as const satisfies readonly (keyof RuntimeServices)[];\n\n/**\n * ÇAPRAZ-MAJOR KUTUYU ADIYLA REDDET (sapma defteri D-05).\n *\n * `__requestALS` sürümSÜZ bir `Symbol.for` altında ve bu bilinçli: iki bundle\n * (`dist/index.cjs` ve `dist/test/index.cjs`) ambient kapsamı ancak öyle\n * paylaşır. Bedeli de gerçek — tek süreçte iki major varsa ESKİ olanın yazdığı\n * kutuyu YENİ olan okur, ve servis kümesi büyümüşse (30.0.0'da 9→10, `Auth`)\n * yeni alan `undefined` gelir.\n *\n * `undefined` bir servis, erişildiğinde `Reflect.get called on non-object`\n * verir: ne eksik olanın adı, ne sebebi. Bu kontrol o sessizliği bir cümleye\n * çevirir. Maliyeti istek başına on `in` kontrolü.\n */\nfunction refuseIncompleteBox(services: RuntimeServices): RuntimeServices {\n const missing = REQUIRED_SERVICES.filter((k) => services[k] === undefined);\n if (missing.length > 0) {\n throw new Error(\n `the request scope is missing ${missing.join(\", \")} — this box was most likely written by a ` +\n `DIFFERENT @palbase/backend major sharing the same process (the request store is a ` +\n `process-wide well-known Symbol, deliberately, so two bundles of ONE version can share it). ` +\n `Align the versions, or pass every service when building the scope yourself.`,\n );\n }\n return services;\n}\n\nexport function __getRuntime(): RuntimeServices {\n const scoped = __requestALS.getStore();\n if (scoped) return refuseIncompleteBox(scoped.runtime);\n if (runtime === null) {\n throw new Error(\n \"Palbase services accessed outside a request scope. The Database/Documents/… \" +\n \"singletons are only available inside an endpoint handler (or after the \" +\n \"runtime has called __runWithRuntime / __setRuntime).\",\n );\n }\n return runtime;\n}\n\n// ─── lifecycle: where a long-lived resource lives (FR-013) ─────────────────\n//\n// `Resource` was removed in 23.0.0 and nothing replaced the LIFECYCLE half of\n// it. What that left behind is measurable: a connection pool (the driver in\n// `docs/resources.md`'s own example was Neo4j) had no documented place to be\n// opened and NO WAY AT ALL to be closed, so every deploy left the pool it\n// opened behind. These two hooks are that half — and only that half. The\n// secret-distribution half does not come back: a handler reads `Secrets.get`,\n// and a start hook, which runs before any request scope exists, reads the\n// `process.env` the runtime mirrors the vault into at boot.\n\n/** A lifecycle hook. Sync or async; the runtime awaits what it returns. */\nexport type LifecycleHook = () => void | Promise<void>;\n\n/** Runs one release's shutdown hooks. Handed back by {@link __runStartHooks}\n * and called by the engine's `app.shutdown()`. Idempotent. */\nexport type ShutdownRunner = () => Promise<void>;\n\ninterface DeclaredHook {\n name: string;\n run: LifecycleHook;\n}\n\ninterface DeclaredLifecycle {\n start: DeclaredHook[];\n shutdown: DeclaredHook[];\n}\n\n/**\n * What has been DECLARED and not yet claimed by an app.\n *\n * On globalThis under a well-known Symbol for the reason the controller\n * registry is (`decorators/controller.ts`): a deployed bundle inlines its own\n * copy of this package, and the engine that has to RUN these hooks holds the\n * other copy. Two module-local arrays would mean the engine reads the empty one\n * and every declared hook is silently never run — which is exactly how\n * `Resource`'s `init(env)` died.\n */\nconst LIFECYCLE: unique symbol = Symbol.for(\"palbase.backend.lifecycleHooks\") as never;\n\nfunction declaredLifecycle(): DeclaredLifecycle {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n return (g[LIFECYCLE] ??= { start: [], shutdown: [] });\n}\n\n/**\n * Run `hook` ONCE while the application comes up, before it serves anything.\n *\n * Call it at MODULE SCOPE in a file the application imports — the same rule\n * `defineDefaultAuth` and `@Controller` follow, and for the same reason: the\n * declaration is claimed when the app boots, which is after module loading and\n * before the first request. `name` is not decoration: a hook that throws is\n * reported by that name and the boot is REFUSED, so it is what tells an\n * operator which resource did not come up.\n *\n * There is no request scope yet, so the `Database`/`Secrets`/… singletons are\n * NOT available inside a start hook. A secret is read from `process.env` here\n * (the runtime mirrors the vault into it at boot).\n *\n * @example\n * // resources/graph.ts\n * import neo4j from \"neo4j-driver\";\n * import { onStart, onShutdown } from \"@palbase/backend\";\n *\n * export let graph: Driver;\n * onStart(\"graph\", () => {\n * graph = neo4j.driver(process.env.NEO4J_URL!, neo4j.auth.basic(\"neo4j\", process.env.NEO4J_PASSWORD!));\n * });\n * onShutdown(\"graph\", () => graph.close());\n */\nexport function onStart(name: string, hook: LifecycleHook): void {\n declaredLifecycle().start.push({ name, run: hook });\n}\n\n/**\n * Run `hook` while the application shuts down — the place a pool opened in\n * {@link onStart} is closed.\n *\n * Shutdown is BEST-EFFORT by design: a hook that throws is reported by name and\n * the rest still run. A drain that abandoned the remaining hooks on the first\n * failure would leak exactly what this exists to release, and the process is\n * leaving anyway.\n *\n * Hooks run in REVERSE declaration order, so a resource is released before what\n * it was built on.\n */\nexport function onShutdown(name: string, hook: LifecycleHook): void {\n declaredLifecycle().shutdown.push({ name, run: hook });\n}\n\nfunction reason(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** Best-effort drain: every hook runs, a failure is reported, none is silent. */\nasync function drain(hooks: DeclaredHook[]): Promise<void> {\n for (const h of [...hooks].reverse()) {\n try {\n await h.run();\n } catch (err) {\n console.error(`[palbase] shutdown hook \"${h.name}\" failed: ${reason(err)}`, err);\n }\n }\n}\n\n/**\n * CLAIM what has been declared, run the start hooks, and hand back the runner\n * for this release's shutdown hooks. Called by the engine's `createApp`; the\n * `App.shutdown()` it builds calls what comes back. NOT part of the public\n * author-facing API.\n *\n * IT CLAIMS RATHER THAN READS, which is what makes it correct in this runtime:\n * a candidate release is loaded BESIDE the live one in one process\n * (`v2/runtime/src/registry-scope.ts`), and both bundles append to the one\n * shared slot above. If each app read the whole list, the live app's shutdown\n * would close the candidate's pool and the candidate's would close the live\n * app's. Taking the declarations leaves each app holding exactly its own.\n *\n * A start hook that throws REFUSES THE BOOT — with the hook's name in the\n * message — after releasing whatever the earlier hooks already opened. Serving\n * from a half-initialised app is the silence this whole surface replaces, and a\n * boot that dies holding an open pool is the leak it replaces.\n */\nexport async function __runStartHooks(): Promise<ShutdownRunner> {\n const slot = declaredLifecycle();\n const start = slot.start.splice(0);\n const shutdown = slot.shutdown.splice(0);\n\n for (const h of start) {\n try {\n await h.run();\n } catch (err) {\n await drain(shutdown);\n throw new Error(`[palbase] start hook \"${h.name}\" failed: ${reason(err)}`, { cause: err });\n }\n }\n\n let drained = false;\n return async () => {\n // SIGTERM racing a redeploy asks twice; a pool is closed once.\n if (drained) return;\n drained = true;\n await drain(shutdown);\n };\n}\n\n/** Drop every declaration. For tests, which declare repeatedly in one process.\n * NOT part of the public author-facing API. */\nexport function __resetLifecycleHooks(): void {\n const g = globalThis as unknown as Record<symbol, DeclaredLifecycle | undefined>;\n delete g[LIFECYCLE];\n}\n\n/**\n * Build a Proxy singleton that forwards every property access to the live\n * client named `key` on the current runtime.\n *\n * The single `as RuntimeServices[K]` is the only contained cast in the surface:\n * `Reflect.get` on a typed object returns `unknown` for a `string | symbol`\n * key, but `prop` is constrained to keys of the client interface at the call\n * sites (the exported singletons are typed below), so the forward is sound.\n */\nfunction makeServiceProxy<K extends keyof RuntimeServices>(key: K): RuntimeServices[K] {\n const handler: ProxyHandler<RuntimeServices[K]> = {\n get(_target, prop, receiver) {\n const client = __getRuntime()[key];\n const value = Reflect.get(client as object, prop, receiver) as unknown;\n // Bind methods to their owning client so `this` stays correct when the\n // author destructures or calls `Database.query(...)`.\n return typeof value === \"function\" ? value.bind(client) : value;\n },\n };\n // The Proxy target is irrelevant (all access goes through `get`); the cast\n // names the surface type the singleton presents to authors.\n return new Proxy({} as RuntimeServices[K], handler);\n}\n\n/**\n * Build the `.tables` accessor for the top-level `Database`. Each\n * `tables.<name>` access returns a small object that forwards the five CRUD ops\n * to the underlying client using `name` as the string table identifier. The\n * shapes are typed against the generated `palbase-env.d.ts` (`EnvTables`); at\n * runtime they are plain string-keyed calls, so no schema value is needed here.\n *\n * Returns `EnvTables` — TS cannot infer the mapped type through the Proxy, so\n * a single structural narrowing names the surface (the proxy returns a\n * correctly-shaped accessor for whatever string member is read).\n */\n/** T018 (C-8): similar/recommend'in string-keyed yüzü. DBOps'a (endpoint.ts)\n * BİLEREK eklenmedi — search-param imza üçlüsü (engine/db + typed-db +\n * endpoint) büyümesin: proxy dispatch runtime'da engine ops'una zaten ulaşır,\n * derleme güvenliğini typed yüzey (EnvTypedTable) verir. */\nexport interface RecoOps {\n similar(table: string, id: string, params?: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n recommend(table: string, params: Record<string, unknown>): Promise<Record<string, unknown>[]>;\n}\n\n/**\n * The Proxy behind EVERY `.tables` map — public's and every other schema's.\n *\n * `prefix` is what the wire name is built from: `\"\"` for `public`, so its tables\n * stay BARE, and `\"<schema>.\"` for any other, so `schema(\"billing\").tables\n * .invoices` reaches the broker as `billing.invoices` (D-10 — the same\n * schema-qualified key `toSchemaJSON` and the generated `relations` use).\n *\n * One trap for both surfaces: two copies would be two op lists that can drift,\n * and the one that forgets an op does not complain — it answers `undefined`.\n */\nfunction makeTableProxy(ops: () => DBOps & RecoOps, prefix: string): object {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n const name = `${prefix}${prop}`;\n return {\n insert: (data: Record<string, unknown>) => ops().insert(name, data),\n // DÖRDÜNCÜ FİİL, aynı gerekçeyle: tip söz veriyor, ops katmanı\n // uyguluyor, ve bir handler'ın gerçekten dokunduğu yer BURASI.\n // `runtime-table-verbs` kapısı bunu adıyla saydı.\n aggregate: (q: Parameters<DBOps[\"aggregate\"]>[1]) => ops().aggregate(name, q),\n insertMany: (\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => ops().insertMany(name, rows, opts),\n update: (q: { where: { id: string }; set: Record<string, unknown> }) =>\n ops().update(name, q.where.id, q.set),\n delete: (id: string) => ops().delete(name, id),\n findById: (id: string) => ops().findById(name, id),\n findUnique: (q: { where: Record<string, unknown>; select?: readonly string[]; with?: Record<string, unknown> }) =>\n ops().findUnique(name, q.where, { select: q.select, with: q.with }),\n page: (q?: Record<string, unknown>) => {\n const { where, ...opts } = q ?? {};\n return ops().page(name, where as Record<string, unknown> | undefined, opts as import(\"./db/page.js\").RawPageOptions);\n },\n findMany: (q?: Record<string, unknown>) => {\n // `where` AYIKLANIR; kalan alanlar (orderBy/limit/offset) ham op'un\n // ikinci parametresine gider. Tümünü geçirmek `where`'i tel üstünde\n // ikinci kez gönderirdi — `typed-db.test.ts` bunu yakalıyor.\n const { where, ...opts } = q ?? {};\n return ops().findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<DBOps[\"findMany\"]>[2],\n );\n },\n put: (q: { data: Record<string, unknown>; onConflict: readonly string[] }) =>\n ops().put(name, q.data, { onConflict: q.onConflict }),\n // THREE VERBS THE TYPE PROMISED AND THIS PROXY DID NOT EMIT.\n //\n // `EnvTypedTableBase` declares `updateMany`, `deleteMany` and `count`\n // (typed-db.ts) and the ops layer implements all three — only this\n // proxy, which is what a handler actually touches, left them out. So\n // the type said the verb exists, autocomplete offered it, and the call\n // answered `undefined is not a function`.\n //\n // Older than this run, but the run rewrote this proxy for\n // `Database.schema(name).tables.*` and would have carried the gap onto\n // the new surface too.\n updateMany: (q: { where: Record<string, unknown>; set: Record<string, unknown>; returning?: boolean }) =>\n ops().updateMany(name, q.where, q.set, q.returning === undefined ? undefined : { returning: q.returning }),\n deleteMany: (q: { where: Record<string, unknown> }) => ops().deleteMany(name, q.where),\n count: (q?: { where?: Record<string, unknown> }) => ops().count(name, q?.where),\n search: (params?: Record<string, unknown>) => ops().search(name, params),\n similar: (id: string, params?: Record<string, unknown>) => ops().similar(name, id, params),\n recommend: (params: Record<string, unknown>) => ops().recommend(name, params),\n facets: (params: { facets: string[] } & Record<string, unknown>) => ops().facets(name, params),\n supersede: (id: string, row: Record<string, unknown>) => ops().supersede(name, id, row),\n claim: (unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n ops().claim(name, unique, extra),\n };\n },\n },\n );\n}\n\n\n/** The raw string-keyed `DBClient` for the current request scope. */\nconst rawDatabase: DBClient = makeServiceProxy(\"Database\");\n\n/**\n * Wrap a raw `DBClient` into the typed `{ ...ops, tables, transaction }`\n * surface. The five string ops forward straight through; `tables` is the\n * env-typed accessor; `transaction` yields typed tables. Reused for both the\n * default (RLS-enforced) `Database` and the `asService()` sibling — each is\n * fed its own raw client (the default proxy vs `rawDatabase.asService()`).\n *\n * The `satisfies` pins the op surface so a missing/renamed op is a compile\n * error; the assembled object carries `tables`/`transaction` alongside.\n */\n/**\n * PACKAGE-INTERNAL, and deliberately NOT re-exported from `index.ts`.\n *\n * `test/fake-db.ts` builds the fake's surface with the SAME constructor\n * production uses, so the two cannot drift: the day a `$op` is added here, the\n * fake grows it in the same commit. Exporting it from the public index instead\n * would put a runtime-assembly detail on the author-facing API (FR-006).\n */\nexport function makeTypedSurface(raw: AtomicClient & Partial<Pick<DBClient, \"atomic\">>): EnvServiceDatabase {\n // Proxy dispatch her üyeyi taşır; RecoOps tipi DBClient'a eklenmediğinden\n // (yukarıdaki karar) similar/recommend erişimi bu daraltmadan geçer.\n const reco = raw as Omit<DBClient, \"asService\"> & RecoOps;\n // `$` ÖNEKİ AÇIKÇA YAZILIR, dinamik üretilmez.\n //\n // Bir tur `Object.fromEntries(Object.entries(ops).map(…))` ile üretilmişti ve\n // `database.test.ts`'in sayımı onu göremedi: sayım DEKLARASYONLARI okuyor,\n // string literal'leri değil. Görünmeyen bir yüzey denetlenemez — ve o testin\n // varlık sebebi tam olarak budur (FR-044: yüzeyde bağlantı bilgisi olmadığını\n // kanıtlamak, ama önce yüzeye gerçekten ULAŞTIĞINI kanıtlamak).\n const ops = {\n $query: (sql: string, params?: unknown[]) => raw.query(sql, params),\n $diagnostics: () => raw.diagnostics(),\n $insert: (table: string, data: Record<string, unknown>) => raw.insert(table, data),\n $update: (table: string, id: string, data: Record<string, unknown>) =>\n raw.update(table, id, data),\n $delete: (table: string, id: string) => raw.delete(table, id),\n $findById: (table: string, id: string) => raw.findById(table, id),\n $findUnique: (table: string, where: Record<string, unknown>, opts?: Parameters<DBOps[\"findUnique\"]>[2]) => raw.findUnique(table, where, opts),\n $page: (table: string, query?: Record<string, unknown>, opts?: import(\"./db/page.js\").RawPageOptions) => raw.page(table, query, opts),\n $findMany: (table: string, query?: Record<string, unknown>, opts?: Parameters<DBOps[\"findMany\"]>[2]) =>\n raw.findMany(table, query, opts),\n $put: (table: string, data: Record<string, unknown>, opts: { onConflict: readonly string[] }) =>\n raw.put(table, data, opts),\n // `opts` İLETİLİR. Düşürüldüğü sürece `Database.$updateMany(t, w, s,\n // { returning: false })` sessizce SATIRLARI döndürüyordu, sayıyı değil —\n // ve `if (n === 0) throw new Conflict(...)` guard'ı HİÇ çalışmıyordu,\n // çünkü `[] === 0` yanlıştır. Komşu forwarder'lar (`$findMany`, `$put`)\n // kendi opsiyonlarını zaten iletiyordu; bu biri unutulmuştu.\n $updateMany: (\n table: string,\n where: Record<string, unknown>,\n set: Record<string, unknown>,\n opts?: Parameters<DBOps[\"updateMany\"]>[3],\n ) => raw.updateMany(table, where, set, opts),\n $deleteMany: (table: string, where: Record<string, unknown>) => raw.deleteMany(table, where),\n $count: (table: string, where?: Record<string, unknown>) => raw.count(table, where),\n $search: (table: string, params?: Record<string, unknown>) => raw.search(table, params),\n $similar: (table: string, id: string, params?: Record<string, unknown>) =>\n reco.similar(table, id, params),\n $recommend: (table: string, params: Record<string, unknown>) => reco.recommend(table, params),\n $facets: (table: string, params: { facets: string[] } & Record<string, unknown>) => reco.facets(table, params),\n $claim: (table: string, unique: Record<string, unknown>, extra?: Record<string, unknown>) =>\n reco.claim(table, unique, extra),\n $lockRows: (table: string, ids: readonly string[]) => reco.lockRows(table, ids),\n $lockRowsWhere: (\n table: string,\n where: Record<string, unknown>,\n opts?: Parameters<DBOps[\"lockRowsWhere\"]>[2],\n ) => reco.lockRowsWhere(table, where, opts),\n $advisoryXactLock: (key: string) => reco.advisoryXactLock(key),\n $aggregate: (table: string, q: Parameters<DBOps[\"aggregate\"]>[1]) => raw.aggregate(table, q),\n $insertMany: ((\n table: string,\n rows: readonly Record<string, unknown>[],\n opts?: import(\"./db/bulk.js\").InsertManyOptions,\n ) => raw.insertMany(table, rows, opts)) as DBOps[\"insertMany\"],\n $supersede: (table: string, id: string, row: Record<string, unknown>) =>\n raw.supersede(table, id, row),\n } satisfies DollarOps<Omit<DBOps & RecoOps, \"attempt\">>;\n // `ops` DOĞRUDAN verilir, spread edilmez: sayım (`database.test.ts`) nesneyi\n // deklarasyonundan takip ediyor ve bir spread onu kaybettiriyor. Görünmeyen\n // yüzey denetlenemez.\n const base = Object.assign(ops as unknown as Record<string, unknown>, {\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T> {\n if (typeof raw.atomic !== \"function\") {\n throw new Error(\"This Database handle cannot open a root transaction; nested $atomic is not supported\");\n }\n // ALS.run scopes only this callback and its continuations, never another\n // Promise.all branch. Calls made by ordinary services through Database\n // therefore share the callback's physical transaction and identity.\n const parent = __requestALS.getStore();\n let runtime: RuntimeServices | undefined;\n try { runtime = __getRuntime(); } catch { /* Direct typed engine handles need no ambient runtime. */ }\n return raw.atomic(async (tx) => {\n const typed = makeTypedSurface(tx);\n const invoke = () => fn(typed);\n if (!runtime) return invoke();\n const refuse = (): never => { throw new Error(\"Database.$atomic owns one transaction and identity; nested roots and $asService are not allowed\"); };\n const ambient = Object.assign({}, tx, { atomic: refuse, asService: refuse });\n return __requestALS.run({ ...parent, runtime: { ...runtime, Database: ambient } }, invoke);\n }, options);\n },\n // Both surfaces get it: a savepoint on the service transaction is as useful\n // as one on the request's, and each is bound to its own connection.\n $attempt: <T,>(fn: (tx: DBOps) => Promise<T>) => raw.attempt(fn),\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>> {\n // A FRESH builder per call: it holds this transaction's ops and its error\n // slot table, and the runtime serves concurrent requests on one event loop.\n // A shared builder would splice one request's writes into another's plan.\n //\n assertPlanRetry(opts);\n const builder = new TxPlanBuilder();\n return runTxPlan(raw, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./db/command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, makeTxPlanHandle(builder), builder, fn) as Promise<Materialized<T>>;\n },\n });\n // ŞEMA ERİŞİMİ BİR PROXY'DİR, çünkü hangi şemaların bildirildiğini yalnız TİP\n // bilir — runtime'da `Database.billing` diye bir üye yoktur, o ada dokunulduğu\n // anda üretilir. `$`'la başlamayan her ad bir ŞEMA adıdır; ayrım tam olarak\n // budur ve tip tarafındaki DollarOps ile aynı kuralı uygular.\n return new Proxy(base, {\n get(target, prop, receiver) {\n // `tables` DOĞRUDAN YÜZEYDE DE public'in takma adı.\n //\n // Plan tutamağı `tx.tables.todos`'u öğretiyor (göç notu da öyle), ama\n // `Database.public.todos` aynı kelimeyi ADI `tables` OLAN BİR ŞEMA sanıp\n // tele `tables.todos` yazıyordu. Tip onu reddettiği için derlenen kodda\n // erişilemezdi — ama `as any` ya da düz JS ile geçen biri sessizce\n // olmayan bir şemaya gidiyordu, ve iki yüzeyin aynı kelimeye zıt cevap\n // vermesi bu run'ın kapattığı sınıfın kendisi (gözcü M-6).\n if (prop === \"tables\") return makeTableProxy(() => reco, \"\");\n if (typeof prop === \"string\" && !prop.startsWith(\"$\") && !(prop in target)) {\n // Nitelikli tablo anahtarının kuralı BURADA TEKRARLANMAZ (FR-058): tek\n // yazıcı `qualifiedTableKey` ve `table-key-single-source.test.ts` ikinci\n // bir yazıcıyı reddediyor. Prefix ondan türetilir — boş tablo adıyla\n // çağrıldığında geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTableProxy(() => reco, qualifiedTableKey(prop, \"\"));\n }\n return Reflect.get(target, prop, receiver);\n },\n }) as unknown as EnvServiceDatabase;\n}\n\n/**\n * `makeTableProxy`'nin plan ikizi: `tables.<name>` yields the\n * table's PLAN operations, recorded into `builder` instead of sent one by one.\n *\n * Same Proxy shape and same reason for the single narrowing — TS cannot infer a\n * mapped type through a Proxy, so the cast names what the trap returns.\n */\nfunction makeTxTablesAccessor(builder: TxPlanBuilder, prefix = \"\"): TxTables {\n const tablesProxy = new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return builder.table(prefix + prop);\n },\n },\n );\n return tablesProxy as TxTables;\n}\n\n/**\n * Plan tutamağı — `Database` ile AYNI şekil: `tx.public.x`, `tx.<şema>.x`, ve\n * geriye dönük `tx.tables.x`.\n *\n * Şema adı tablo adının ÖNÜNE geçiyor (`billing.invoices`), tıpkı doğrudan\n * yüzeyin `makeTypedSurface` proxy'sinin yaptığı gibi — ve motor artık onu\n * `quoteTable` ile İKİ parça hâlinde tırnaklıyor. Bu ikisi olmadan `billing`\n * şemasındaki iki tabloyu tek atomik planda yazmak imkânsızdı.\n *\n * `tables` ve `public` DIŞINDAKİ HER ad şema kabul edilir ve altındaki tablolar\n * `<ad>.<tablo>` diye adlanır. Yanlış bir şema adı TİPTE yakalanıyor\n * (`keyof Schemas`) — `tx.constructor.x` ve `tx.toString.x` dahil, ölçüldü.\n *\n * TİPTEN KAÇAN bir ad için savunma `quoteTable`'ın KAÇIŞIDIR, başka bir şey\n * değil: `runPlanOp` `op.table`'ı doğrulamadan ona veriyor ve `quoteTable`\n * tırnak ikizleyerek tek bir tanımlayıcı üretiyor. Ölçüldü: `a\"; DROP TABLE t; --`\n * → `\"a\"\"; DROP TABLE t; --\"`, yani enjeksiyon değil, `relation does not exist`.\n * (Bu yorum bir zamanlar `validateSchemaIdentifier`'a atıf yapıyordu — o\n * fonksiyon Go tarafında yaşıyor ve BU yolu hiç görmüyor; gözcü yakaladı.)\n */\nfunction makeTxPlanHandle(builder: TxPlanBuilder): TxPlan {\n const publicTables = makeTxTablesAccessor(builder);\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n if (prop === \"tables\") return publicTables;\n // ÖNEK TEK YAZICIDAN (FR-058): `qualifiedTableKey`. Bu kuralı burada\n // elle yazmıştım — public'i çıplak bırakıp diğerine nokta ekleyen bir\n // if/return çifti — ve FR-058 kapısı onu GÖRMEDİ, çünkü kapı yalnız\n // ternary arıyordu. (Kural burada KELİMEYLE anlatılıyor, kod biçiminde\n // DEĞİL: kapı metni tarıyor ve bir yorumdaki kopya da onu tetikler.)\n // İkinci bir yazıcı, kapının var olma sebebi olan sınıfın kendisi:\n // `env-gen.ts`'in kendi kopyası bir public FK'yi başka bir şemanın\n // tablosuna etiketlemişti ve hiçbir şey bunu söylememişti.\n // Boş tablo adıyla çağrılınca geriye ya \"\" (public) ya \"<şema>.\" kalır.\n return makeTxTablesAccessor(builder, qualifiedTableKey(prop, \"\"));\n },\n },\n ) as TxPlan;\n}\n\n/**\n * The project's own Postgres (pgx, schema `env_<envId>`).\n *\n * Typed by default: `Database.public.<name>.insert({...})` is typed against\n * the project's generated `palbase-env.d.ts` with NO import and NO generic.\n * The raw string ops (`Database.$query`/`$insert`/`$update`/`$delete`/\n * `$findById`/`$findMany`) are also available for read-only SQL and for a table\n * name only known at runtime — which the typed surface cannot express past\n * seven tables (see `db/tx-union-key.test-d.ts`).\n *\n * RLS is enforced by default (the runtime runs each op as `authenticated` with\n * the verified user's claims). To bypass RLS, call `Database.$asService()` —\n * explicit and greppable — which runs as the `service_role` (BYPASSRLS).\n *\n * @example\n * import { Database } from \"@palbase/backend\";\n *\n * const todo = await Database.public.todos.insert({ title: req.input.title });\n * todo.id; // string ✓\n * const rows = await Database.$query(\"SELECT id FROM todos WHERE done = $1\", [false]);\n * const all = await Database.$asService().public.todos.findMany({}); // RLS bypass\n */\nexport const Database: EnvTypedDatabase = Object.assign(makeTypedSurface(rawDatabase), {\n /**\n * Lazily resolve the runtime's service-role sibling on each call. We do NOT\n * cache it: `rawDatabase.asService()` reads the CURRENT request scope through\n * the runtime proxy, and the per-request runtime injects a service client\n * bound to that request's identity headers — caching would leak one request's\n * sibling into another concurrent request.\n */\n $asService(): EnvServiceDatabase {\n return makeTypedSurface(rawDatabase.asService());\n },\n}) as unknown as EnvTypedDatabase;\n\n/** Firestore-like document client (PalDocs). */\nexport const Documents: PalbaseDocsClient = makeServiceProxy(\"Documents\");\n\n/**\n * `buckets.<name>` — the storage twin of `Database.public.<name>`, and the same\n * mechanism: `config/storage.ts` generates a `Buckets` augmentation into\n * `palbase-env.d.ts`, so a bucket name is a property with no import and no\n * generic, and a typo is a compile error.\n *\n * The intermediate `.buckets` is there for the reason `.tables` is: bucket\n * names must not share a namespace with the client's own methods, or the day\n * somebody declares a bucket called `bucket` the surface breaks.\n */\nexport type EnvBuckets = {\n [K in keyof Buckets]: TypedBucketClient<Buckets[K] extends BucketTypes ? Buckets[K] : BucketTypes>;\n};\n\n/** One bucket, with its declared variant names in the type. */\nexport interface TypedBucketClient<B extends BucketTypes> extends Omit<PalbaseBucketClient, \"getPublicUrl\"> {\n /** The public URL for the object, or for one of THIS bucket's declared\n * renditions. A name the bucket does not declare is a compile error. */\n getPublicUrl(path: string, options?: { variant?: B[\"variants\"] }): string;\n}\n\nfunction makeBucketsAccessor(storage: () => PalbaseStorageClient): EnvBuckets {\n return new Proxy(\n {},\n {\n get(_t, prop: string | symbol) {\n if (typeof prop !== \"string\") return undefined;\n return storage().bucket(prop);\n },\n },\n ) as EnvBuckets;\n}\n\nconst rawStorage: PalbaseStorageClient = makeServiceProxy(\"Storage\");\n\n/**\n * Object storage: buckets, objects, renditions and signed URLs.\n *\n * `Storage.buckets.posts.upload(...)` is the typed path. `Storage.bucket(name)`\n * remains for a name computed at runtime — rare, and it gives up the typing,\n * which is the honest trade rather than a second blessed way to do it.\n */\nexport const Storage: PalbaseStorageClient & { buckets: EnvBuckets } = Object.assign(\n {\n // FORWARDED explicitly, not assigned onto the service proxy.\n //\n // `Object.assign(rawStorage, {buckets})` writes onto the proxy's TARGET, and\n // the proxy's only trap is `get`, which forwards every read to the module\n // client — so the property landed somewhere nothing reads and\n // `Storage.buckets.docs` was `undefined` in a deployed handler. It\n // typechecked, every test passed, and the live call answered\n // \"TypeError: undefined is not an object\". `Database` never had the bug\n // because it builds a plain surface the same way this now does.\n bucket: (name: string) => rawStorage.bucket(name),\n },\n { buckets: makeBucketsAccessor(() => rawStorage) },\n);\n\n/** JSON-typed cache (get/set/incr/getOrSet). */\nexport const Cache: CacheClient = makeServiceProxy(\"Cache\");\n\n\n/**\n * This tenant's secrets — API keys, provider credentials, signing material the\n * BACKEND owns.\n *\n * `await Secrets.get(\"STRIPE_KEY\")` in a handler. There is no `.env` to read\n * and no file to mount: a secret is written through the vault's authenticated\n * API (or the CLI/MCP that calls it), and this is how the deployed code reads\n * it back. A name this tenant has not set answers null — as does every name\n * the STACK holds, because no route returns a platform secret's value at all.\n */\nexport const Secrets: SecretsService = makeServiceProxy(\"Secrets\");\n\n/**\n * Role assignment, as an operator — `Auth.assignRole(userId, \"agent\")`.\n *\n * The half of auth a SERVER owns. Signing in, MFA and device attestation are a\n * person acting on their own account and live on the client SDK; granting a\n * role is the tenant's product doing something to somebody else, which is\n * exactly what a handler is for. It writes with the service-role credential,\n * because an end user who could write their own assignment would make every\n * permission underneath it meaningless.\n *\n * The write is visible to the very next request: authority is read from the\n * table on each call, never carried on a token.\n */\nexport const Auth: PalbaseAuthAdminClient = makeServiceProxy(\"Auth\");\n\n/** Structured logger. */\nexport const Log: Logger = makeServiceProxy(\"Log\");\n\n/** Push / email / SMS / in-app notifications. */\nexport const Notifications: PalbaseNotificationsClient = makeServiceProxy(\"Notifications\");\n\n\n/**\n * The raw runtime Flags client for the current request scope. Carries the\n * default-surface reads + `setOverride` AND the runtime's `asService()` sibling\n * (the br-pod's `buildFlagsClient` returns both). The default `Flags` singleton\n * below forwards reads + `setOverride` through here; `Flags.$asService()`\n * forwards to this client's own `asService()`.\n */\nconst rawFlags: PalbaseFlagsClient = makeServiceProxy(\"Flags\");\n\n/**\n * Feature flags.\n *\n * Mirrors the `Database` / `Database.$asService()` model. The default surface is\n * RLS-equivalent for flags: reads resolve against the CURRENT request user and\n * `Flags.setOverride(key, value)` writes an override for that same signed-in\n * user (no userId argument, no admin power). Cross-user admin writes\n * (`setOverrideForUser`, …) live behind `Flags.$asService()` — explicit and\n * greppable, just like `Database.$asService()`.\n *\n * @example\n * import { Flags } from \"@palbase/backend\";\n *\n * if (await Flags.isEnabled(\"new_checkout\")) { ... } // current user\n * await Flags.setOverride(\"new_checkout\", true); // current user\n * await Flags.$asService().setOverrideForUser(\"u_9\", \"x\", true); // cross-user\n */\n/**\n * The ambient `Flags` singleton's own surface — NOT the raw client's.\n *\n * MEASURED, as a consumer, against the built tarball: annotating the singleton\n * as `PalbaseFlagsClient` ERASED the `$asService` that `Object.assign` adds, so\n * `Flags.$asService()` did not exist for anyone outside this package —\n *\n * TS2551: Property '$asService' does not exist on type 'PalbaseFlagsClient'.\n * Did you mean 'asService'?\n *\n * — while the only path that DID compile (`asService()`) throws by design. The\n * feature was written and unreachable, which is the defect class this surface\n * exists to remove.\n *\n * `Database` never had the problem because its singleton carries its OWN type\n * (`EnvTypedDatabase`) rather than the raw client's (`DBClient`). This is that,\n * for `Flags`. The raw `PalbaseFlagsClient.asService()` is untouched (FR-023) —\n * it is the seam this forwards to.\n */\nexport type PalbaseFlagsAmbient = Omit<PalbaseFlagsClient, \"asService\"> & {\n /** RLS'i aşan, kullanıcılar arası yazma yüzeyi. */\n $asService(): PalbaseFlagsServiceClient;\n /** 31.0.0 öncesinin adı — SESSİZCE çalışmaz, yerini söyleyerek fırlatır. */\n asService(): never;\n};\n\nexport const Flags: PalbaseFlagsAmbient = Object.assign(\n {\n isEnabled(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<boolean>> {\n return rawFlags.isEnabled(flagName, context);\n },\n getVariant(\n flagName: PalbaseFlagKey,\n context?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagVariant>> {\n return rawFlags.getVariant(flagName, context);\n },\n getAll(context?: PalbaseFlagContext): Promise<PalbaseResult<PalbaseFlag[]>> {\n return rawFlags.getAll(context);\n },\n /**\n * Resolve a flag's value, with an optional fallback.\n *\n * FORWARDED as of 2026-08-15. This surface is written out by hand, method\n * by method, and `get` was missing from it — so the client implemented it,\n * thirty assertions covered it, and `Flags.get(\"x\")` was `undefined` in a\n * deployed handler. Exactly the shape of the `Storage.buckets` defect found\n * the same day: a hand-maintained forwarding list is a list somebody has to\n * remember to update.\n */\n get(\n flagName: PalbaseFlagKey,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n return rawFlags.get(flagName, defaultOrContext, maybeContext);\n },\n setOverride(\n key: PalbaseFlagKey,\n value: PalbaseFlagValue,\n ): Promise<PalbaseResult<PalbaseSetOverrideResult>> {\n return rawFlags.setOverride(key, value);\n },\n },\n {\n /**\n * Lazily resolve the runtime's cross-user sibling on each call. We do NOT\n * cache it: `rawFlags.asService()` reads the CURRENT request scope through\n * the runtime proxy, so caching would leak one request's sibling into\n * another concurrent request. Mirrors `Database.$asService()`.\n */\n $asService(): PalbaseFlagsServiceClient {\n return rawFlags.asService();\n },\n /**\n * The name this member carried before 32.0.0.\n *\n * It does NOT work silently. A retired member that quietly keeps returning\n * is how a rename becomes a mystery: the old call site goes on compiling,\n * the new name never spreads, and the two live side by side until somebody\n * greps for one and misses half the codebase. `Database` made this split\n * first (`$asService`), and this JSDoc promised \"exactly like\n * Database.$asService()\" while the promise went unkept.\n */\n asService(): never {\n throw new Error(\n \"Flags.asService() was renamed to Flags.$asService() in 32.0.0 — system members carry the `$` prefix, like Database.$asService().\",\n );\n },\n },\n);\n\n/**\n * The Realtime broadcast singleton for the current request scope. Backend-side\n * Realtime is BROADCAST-ONLY (a stateless handler can push but not subscribe —\n * `subscribe()` lives on the client SDK's `pb.realtime`). Fire-and-forget:\n * `broadcast` resolves once accepted (or with an `error`), never blocking the\n * handler on subscribers.\n *\n * @example\n * import { Realtime } from \"@palbase/backend\";\n *\n * await Realtime.broadcast(\"room:42\", \"message\", { text, from: user.id });\n */\nexport const Realtime: PalbaseRealtimeClient = makeServiceProxy(\"Realtime\");\n","/**\n * The refusals a Database call gets BEFORE any SQL exists — written once, so the\n * engine and the test double cannot disagree about them.\n *\n * WHY THIS FILE EXISTS. `fakeDatabase()` is a second implementation of the same\n * surface (`__tests__/helpers/mock-db.ts`), and it never touched `compileWhere`\n * or `asBindParams`. Measured against the published 24.1.0: all four of the\n * calls that release had just started refusing went through the fake SILENTLY —\n * `update{title:undefined}`, `insert{title:undefined}`, `findMany{done:{}}`,\n * `deleteMany{owner,created_at:{}}`.\n *\n * The scaffold tells authors to test the service layer against exactly that\n * fake. So a test went green on a call production would throw on, and the\n * author found out in production instead — the same \"the surface does not match\n * the engine\" shape these refusals exist to end, arriving through the door the\n * SDK hands people for testing.\n *\n * These are pure and SQL-free on purpose: an in-memory store can run them as\n * easily as the driver path can.\n */\n\n/**\n * İşaretçilerin MARKASI — `col()` ve `sqlFragment()` ürünlerini bu süreçte\n * üretilmiş olmakla tanımlar.\n *\n * NEDEN ŞEKİL DEĞİL DE MARKA (gözcü W2-A/C1 ve W2-B/C3, ikisi de ÖLÇTÜ):\n * şekil kontrolü, işaretçiyi güvenilmeyen bir istek gövdesinden UYDURULABİLİR\n * kılıyordu. Ölçülen iki sonuç:\n *\n * findMany(\"docs\", { owner_id: JSON.parse('{\"$col\":\"owner_id\"}') })\n * → WHERE true AND t.\"owner_id\" = t.\"owner_id\" ← kiracılık predikatı totoloji\n * findMany(\"todos\", JSON.parse('{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}'))\n * → WHERE true AND 1=1 -- pwned ← saldırganın metni SQL'e HARFİYEN\n *\n * `{ where: { tenant_id: tid, ...req.body.filter } }` bu SDK'nın öğrettiği\n * desen; T010/T014 öncesinde aynı anahtarlar \"bilinmeyen operatör\" diye\n * REDDEDİLİYORDU. Marka o reddi geri getiriyor.\n *\n * Sembol GLOBAL kayıttan (`Symbol.for`) ve ENUMERABLE DEĞİL. İkisi de kasıtlı:\n * global kayıt paketin iki kopyası arasında da eşleşir; enumerable olmaması ise\n * `JSON.stringify` ve `{...ref, gt: 5}` yayılımının markayı DÜŞÜRMESİNİ sağlar —\n * yani telden geçen ya da elle karıştırılan hiçbir şey işaretçi sayılmaz.\n * Kardeş özellik (`increment`) zaten `Symbol.for(\"palbase.tx.expr\")` kullanıyor;\n * bu onun aynısı.\n */\nconst REF_BRAND = Symbol.for(\"palbase.db.ref\");\n\n/** İşaretçiyi markalar. Yalnız `col()` ve `sqlFragment()` çağırır. */\nexport function brandRef<T extends object>(v: T, kind: \"col\" | \"sql\" | \"ref\"): T {\n Object.defineProperty(v, REF_BRAND, { value: kind, enumerable: false });\n return v;\n}\n\nfunction brandOf(v: unknown): unknown {\n if (typeof v !== \"object\" || v === null) return undefined;\n // KENDİ özelliği olmalı, prototip zincirinden MİRAS ALINMIŞ değil:\n // `Object.create(col(\"x\"))` markayı zincirden okuyup işaretçi sayılıyordu\n // (gözcü ölçtü). Telden erişilemez — JSON `__proto__` üstünden sembol\n // yazamaz — ama daraltmak bedava ve \"işaretçi bu süreçte ÜRETİLDİ\"\n // iddiasının tam karşılığı budur.\n return Object.hasOwn(v, REF_BRAND) ? (v as Record<symbol, unknown>)[REF_BRAND] : undefined;\n}\n\n/**\n * Bir değer, MARKASIZ bir işaretçi taklidi mi? (`{$col:…}` / `{$sql:…}`)\n *\n * Üst düzeyde bunlar zaten \"bilinmeyen operatör\" diye reddediliyor. Ama\n * operatörün SAĞINDA — `{ amount: { gt: {\"$col\":\"other\"} } }` — sessizce\n * PARAMETRE olarak bağlanıyorlardı: sayısal kolonda sürücünün 22P02'si,\n * jsonb/text kolonunda ise HİÇBİR SATIR, hatasız (gözcü ölçtü).\n *\n * `in` listesindeki aynı kusur adıyla reddediliyor; bu onun bir seviye\n * yanındaki hâli ve aynı cevabı hak ediyor.\n */\nexport function looksLikeUnbrandedRef(v: unknown): \"col\" | \"sql\" | \"expr\" | null {\n if (typeof v !== \"object\" || v === null) return null;\n if (brandOf(v) !== undefined) return null; // gerçek işaretçi\n if (isColumnExpr(v)) return null; // gerçek ifade tutamağı (kendi markası var)\n const o = v as { $col?: unknown; $sql?: unknown; $expr?: unknown };\n if (typeof o.$col === \"string\") return \"col\";\n if (o.$sql !== undefined && typeof o.$sql === \"object\" && o.$sql !== null) return \"sql\";\n // `$expr` `now()`/`increment()`'in TEL BİÇİMİ. `now()` filtrede geçerli bir\n // değer olduğu andan itibaren bu şekil de uydurulabilir hâle geldi: ÖLÇÜLDÜ,\n // gövdeden gelen `{\"$expr\":{\"fn\":\"now\"}}` sessizce PARAMETRE olarak bağlanıp\n // sorguyu hatasız biçimde boş sonuca çeviriyordu. `$col`/`$sql`/`$ref` ile\n // aynı kapı, aynı gerekçe.\n if (o.$expr !== undefined && typeof o.$expr === \"object\" && o.$expr !== null) return \"expr\";\n return null;\n}\n\n/**\n * `col()` ürünü mü? (FR-011)\n *\n * Burada, çünkü bu dosya \"iki uygulamanın da okuduğu kurallar\" dosyası: motor,\n * `fakeDatabase` ve guard AYNI cevabı vermek zorunda.\n */\nexport function isColRef(v: unknown): v is { readonly $col: string } {\n return brandOf(v) === \"col\" && typeof (v as { $col?: unknown }).$col === \"string\";\n}\n\n/**\n * `sqlFragment` ürünü mü? (FR-018)\n *\n * `isColRef` ile aynı gerekçeyle burada: motor, guard ve `fakeDatabase` üçü de\n * aynı cevabı vermek zorunda — biri fragment'i \"kolon haritası\" sanarsa filtre\n * sessizce düşer.\n */\n/**\n * Plan REFERANSI mı? (`{ $ref: { op, field } }`)\n *\n * `$ref` bu dilin MARKASIZ KALAN TEK işaretçisiydi — `engine/db.ts` onu\n * `\"$ref\" in v` diye tanıyordu — ve SDK'nın öğrettiği desen\n * `{ where: { tenant_id: tid, ...req.body.filter } }`. Ölçüldü (gözcü):\n * istek gövdesinden gelen `{\"id\":{\"$ref\":{\"op\":0,\"field\":\"id\"}}}` filtreyi\n * ÖNCEKİ bir işlemin satır değeriyle karşılaştırtıyor —\n * DELETE … WHERE t.\"tenant_id\" = $1 AND t.\"id\" = $2 PRM [\"t1\",\"SIZAN_DEGER\"]\n * gövdenin hiç görmediği bir değer. Enjeksiyon değil (değerler bound) ama bir\n * ORACLE: `op`/`field` seçip `rows_affected`'tan o değeri öğrenmek.\n *\n * Marka `Symbol.for` olduğu için SDK'nın İKİ KOPYASI arasında da eşleşiyor —\n * kontrolcü bundle'ı kendi kopyasını inline ediyor, planı çalıştıran ise\n * runtime'ınki. Ve plan gövdesi JSON'lanmıyor: tek üretim `txPlan` uygulaması\n * süreç içi (`engine/db.ts`), doğrulandı.\n */\nexport function isPlanRef(v: unknown): v is { readonly $ref: { op: number; field: string } } {\n if (brandOf(v) !== \"ref\") return false;\n const r = (v as { $ref?: { op?: unknown; field?: unknown } }).$ref;\n return r !== undefined && typeof r.op === \"number\" && typeof r.field === \"string\";\n}\n\n/** Markasız bir `{ $ref: … }` taklidi mi? Adıyla reddedilmesi için. */\nexport function looksLikeUnbrandedPlanRef(v: unknown): boolean {\n if (typeof v !== \"object\" || v === null || brandOf(v) !== undefined) return false;\n const r = (v as { $ref?: unknown }).$ref;\n return r !== undefined && typeof r === \"object\" && r !== null;\n}\n\nexport function isSqlFragment(v: unknown): v is { readonly $sql: { text: string[]; values: unknown[] } } {\n if (brandOf(v) !== \"sql\") return false;\n const f = (v as { $sql?: { text?: unknown; values?: unknown } }).$sql;\n return f !== undefined && Array.isArray(f.text) && Array.isArray(f.values);\n}\n\n/**\n * İFADE TUTAMAĞI DEĞER DEĞİLDİR — değer bekleyen yollarda adıyla reddedilir.\n *\n * `increment()` / `decrement()` / `now()` bir Proxy döndürür ve yalnız\n * `updateMany` ile plan yolunun `updateWhere`'i onu SQL'e derler. `insert` /\n * `update` / `put` / `supersede` derlemez; oralarda tutamak bound parametre\n * olarak sürücüye gidiyordu ve reddi SÜRÜCÜ veriyordu (\"Unknown object is not\n * a valid PostgreSQL type\") — yazarın yazdığı hiçbir şeyi adlandırmayan bir\n * mesaj (inceleme I-2/I8, ölçüldü). Plan yolu aynı hatayı kendi diliyle\n * reddediyor; bu, doğrudan yolun karşılığı.\n *\n * Sembol `tx-plan.ts`'in markasıyla AYNI global kayıttan okunuyor; bu dosya\n * kural dosyası olduğu için oraya bağımlılık kurmuyor.\n */\nconst TX_EXPR = Symbol.for(\"palbase.tx.expr\");\n\n/**\n * `now()` — SUNUCU SAATİ, karşılaştırma değeri olarak.\n *\n * `increment()`/`decrement()` bir YAZMA ifadesidir ve filtrede anlamsızdır;\n * `now()` öyle değil: `expires_at > now()` sıradan bir karşılaştırma ve her\n * backend'in en sık yazdığı yüklemlerden biri. Filtrede TÜM ifade tutamaklarını\n * reddetmek, yazarı bunun için `sqlFragment`e düşürüyordu — yani sorgunun\n * içine giren parça, en sıradan koşul için gerekiyordu.\n *\n * Ayrım MARKAYLA: bir istek gövdesinden gelen `{\"$expr\":{\"fn\":\"now\"}}` bu\n * süreçte `now()` ile üretilmediği için marka taşımaz ve reddedilir.\n */\nexport function isNowExpr(v: unknown): boolean {\n if (!isColumnExpr(v)) return false;\n try {\n const e = (v as Record<symbol, unknown>)[TX_EXPR];\n return typeof e === \"object\" && e !== null && (e as { fn?: unknown }).fn === \"now\";\n } catch {\n return false;\n }\n}\n\nexport function isColumnExpr(v: unknown): boolean {\n if (typeof v !== \"object\" && typeof v !== \"function\") return false;\n if (v === null) return false;\n try {\n return (v as Record<symbol, unknown>)[TX_EXPR] !== undefined;\n } catch {\n // Tutamak bir Proxy; bilinmeyen bir prop'ta trap fırlatabilir.\n return false;\n }\n}\n\n/**\n * Değer bekleyen bir yazma yolunda ifade tutamağı ya da `col()` var mı?\n *\n * Motor ve `fakeDatabase` AYNI cevabı vermek zorunda: fake tutamağı satıra\n * YAZIYORDU (`row[k] = proxy`) ve satır artık JSON'a bile çevrilemiyordu, motor\n * ise sürücüde patlıyordu. İki farklı yanlış, tek doğru.\n */\nexport function assertNoExpressionHandles(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n const v = data[c];\n // `now()` ile sayaç ifadeleri AYRI cevaplar hak ediyor: ikisinin de\n // çalışan alternatifi var ama farklı (P6 — hata çalışan bir alternatifi\n // ADIYLA söyler). Tek bir \"ifade tutamağı\" mesajı, `now()` yazan kişiye\n // `increment()` öneriyordu.\n if (isNowExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" now() aldı — bu yolda değer beklenir. ` +\n `Satır EKLENİRKEN sunucu saatini yazmanın yolu kolonu defaultNow() ile ` +\n `bildirmek (varsayılan kolonun yanında durur, her çağrıda tekrarlanmaz); ` +\n `var olan bir satırı damgalamak için updateMany({ where, set: { ${c}: now() } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: now() }).`,\n );\n }\n if (isColumnExpr(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir ifade tutamağı aldı (increment()/decrement()). ` +\n `Bu yolda değer beklenir. Sayaç artışı için updateMany({ where, set: { ${c}: increment(n) } }) ` +\n `ya da $transaction içinde tx.public.${table}.updateWhere(where, { ${c}: increment(n) }) kullanın.`,\n );\n }\n if (isColRef(v)) {\n throw new Error(\n `${caller}(${table}): \"${c}\" bir col() aldı. Kolon referansı yalnız FİLTREDE durabilir; ` +\n `bir kolonun değerini başka bir kolona yazmak için $query kullanın.`,\n );\n }\n }\n}\n\n/** The comparison operators a filter value may carry. Kept here because the\n * guard has to tell an operator object from a plain value. */\nconst KNOWN_OPS = new Set([\n \"gt\", \"gte\", \"lt\", \"lte\", \"neq\", \"in\",\n // K1 metin operatörleri (FR-005) ve null testi (FR-006). Bu küme\n // `fakeDatabase()` ile ORTAK kaynaktır: fake bir çağrıyı motorun reddettiği\n // yerde kabul ederse, yazarın testi üretimde patlayan koda karşı yeşil verir.\n \"contains\", \"icontains\", \"startsWith\", \"endsWith\", \"isNull\",\n]);\n\n/**\n * `eq` ADIYLA reddedilir, ve reddi buradadır çünkü guard'ı motor da fake de\n * okuyor.\n *\n * Eşitliğin yazımı ÇIPLAK DEĞERDİR: `{ owner: \"u1\" }`. `eq`'i ikinci bir yazım\n * olarak eklemek, bu run'ın kapatmak için var olduğu şeyi — aynı iş için iki\n * uyumsuz yazım — filtre dilinin İÇİNDE yeniden açardı. Ve eskiden kabul eden\n * ile reddeden ayrışıyordu: guard `eq`'i geçiriyor, derleyici\n * `bilinmeyen operatör \"eq\"` diyordu (gözcü ölçtü).\n */\nconst REFUSED_OPS: Record<string, string> = {\n eq: 'eşitlik ÇIPLAK yazılır: { <kolon>: <değer> } (ya da kolon karşılaştırması için { <kolon>: col(\"…\") })',\n};\n\n/**\n * Refuse a filter that would compile to something other than what it reads like.\n *\n * Three shapes, each measured in production before it was closed:\n *\n * `{ col: undefined }` binds NULL; `= NULL` matches no row, so the query\n * answered \"no records\" and said nothing.\n * `{ col: {} }` produces no term at all — every row on the read\n * path, a dropped condition on the write path.\n * `{ col: { gte: undefined } }` and an `undefined` inside `in`: the same NULL,\n * one level down.\n */\nexport function assertUsableFilter(\n caller: string,\n table: string,\n where: Record<string, unknown> | undefined,\n): void {\n // Bileşim anahtarları (FR-007) bir KOLON adı değildir; kolon doğrulamasından\n // ve operatör kontrolünden muaftır, kendi dalları özyinelemeli olarak aynı\n // kurallardan geçer.\n const COMPOSITES = new Set([\"OR\", \"AND\", \"NOT\"]);\n\n if (!where) return;\n // Fragment bir kolon haritası DEĞİLDİR (FR-018): içeriği SQL'dir, kolon\n // doğrulaması ona uygulanamaz. Değerleri zaten bound gidiyor.\n if (isSqlFragment(where)) return;\n for (const [col, cond] of Object.entries(where)) {\n // Bileşim anahtarları (FR-007) kolon DEĞİLDİR: dalları aynı kurallardan\n // özyinelemeli geçer, ama kendileri operatör kontrolüne girmez.\n if (COMPOSITES.has(col)) {\n const branches = col === \"NOT\" ? [cond] : cond;\n if (!Array.isArray(branches) && col !== \"NOT\") {\n throw new Error(`${caller}(${table}): where.${col} bir dizi olmalı`);\n }\n for (const b of branches as unknown[]) {\n if (b === null || typeof b !== \"object\") {\n throw new Error(`${caller}(${table}): where.${col} dalları filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, b as Record<string, unknown>);\n }\n continue;\n }\n // `has` de kolon DEĞİLDİR: anahtarları İLİŞKİ adları, değerleri BİR TABLO\n // ÖTESİNİN filtresi. İç filtre aynı kurallardan geçiyor — `has` ikinci bir\n // filtre dili değil, aynı dilin bir tablo ötesi.\n //\n // İlişki ADI burada doğrulanMIYOR: grafiği yalnız motor tanıyor (ve tip,\n // derleme anında). Guard'ın onu bilmesi ilişki grafiğinin İKİNCİ bir\n // yorumcusu demekti — `buildRelations`'ın yorumunun adıyla yasakladığı şey.\n if (col === \"has\") {\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) {\n throw new Error(`${caller}(${table}): where.has bir ilişki haritası olmalı ({ <ilişki>: { … } })`);\n }\n for (const [rel, inner] of Object.entries(cond as Record<string, unknown>)) {\n if (inner === null || typeof inner !== \"object\" || Array.isArray(inner)) {\n throw new Error(`${caller}(${table}): where.has.${rel} bir filtre nesnesi olmalı`);\n }\n assertUsableFilter(caller, table, inner as Record<string, unknown>);\n }\n continue;\n }\n if (cond === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col} değeri undefined — bu bir filtre değeri değil. ` +\n `Bağlanınca NULL olur ve '= NULL' hiçbir satıra uymaz, yani sorgu sessizce ` +\n `boş sonuç dönerdi. Değer yoksa anahtarı filtreye hiç koymayın.`,\n );\n }\n if (cond === null || typeof cond !== \"object\" || Array.isArray(cond)) continue;\n // `col()` ürünü bir DEĞER'dir, operatör nesnesi değil (FR-011). Ayırt\n // edilmezse `{ $col: \"x\" }` bir operatör haritası sanılır ve \"bilinmeyen\n // operatör $col\" diye reddedilirdi.\n if (isColRef(cond)) continue;\n // `now()` de bir DEĞER'dir, aynı gerekçeyle — ve tutamak bir Proxy olduğu\n // için `Object.entries` BOŞ döner: ayırt edilmezse \"boş operatör nesnesi\"\n // diye reddedilirdi, yani doğru yazım yanlış bir hatayla karşılanırdı.\n if (isNowExpr(cond)) continue;\n\n const entries = Object.entries(cond as Record<string, unknown>);\n if (entries.length === 0) {\n throw new Error(\n `${caller}(${table}): where.${col} boş bir operatör nesnesi ({}) — hiçbir koşul ` +\n `üretmez, yani bu alan filtreden sessizce DÜŞERDİ. Koşul kurulmayacaksa ` +\n `anahtarı filtreye hiç koymayın (D-21).`,\n );\n }\n for (const [op, v] of entries) {\n if (op === \"in\") {\n if (!Array.isArray(v)) throw new Error(`${caller}(${table}): where.${col}.in bir dizi olmalı`);\n if (v.some((x) => x === undefined)) {\n throw new Error(\n `${caller}(${table}): where.${col}.in listesinde undefined var — sessizce NULL'a ` +\n `bağlanır ve o eleman hiçbir satırla eşleşmez. Listeyi kurarken eleyin.`,\n );\n }\n continue;\n }\n // Sağ tarafta kolon durabilir: `{ total: { gt: col(\"amount_paid\") } }`.\n // Değer kontrolleri (undefined) ona da uygulanır, ama `in` gibi şekil\n // kontrolleri değil — o dal aşağıda zaten ayrı.\n if (REFUSED_OPS[op] !== undefined) {\n // Bilinmeyen değil — BİLİNEREK reddedilen. Hata çalışan yazımı söylüyor.\n throw new Error(`${caller}(${table}): where.${col}.${op} bu filtre dilinde yok — ${REFUSED_OPS[op]}`);\n }\n if (!KNOWN_OPS.has(op)) {\n throw new Error(\n `${caller}(${table}): where.${col} bilinmeyen operatör \"${op}\" (gt/gte/lt/lte/neq/in/contains/icontains/startsWith/endsWith/isNull)`,\n );\n }\n if (v === undefined) {\n throw new Error(\n `${caller}(${table}): where.${col}.${op} değeri undefined — karşılaştırmanın ` +\n `sağ tarafı NULL olur ve sonuç hiçbir satıra uymaz. Koşulu kurmayın.`,\n );\n }\n }\n }\n}\n\n/**\n * Refuse a write whose value never arrived.\n *\n * `{ title: req.body.title }` with no `title` in the body bound NULL and\n * answered 200 — the column was ERASED. `null` is untouched, and the difference\n * is the whole point: null is an author SAYING \"empty this column\"; undefined is\n * nobody saying anything.\n */\nexport function assertUsableWriteValues(\n caller: string,\n table: string,\n cols: readonly string[],\n data: Record<string, unknown>,\n): void {\n for (const c of cols) {\n if (data[c] === undefined) {\n throw new Error(\n `${caller}(${table}): \"${c}\" değeri undefined — bu bir yazma değeri değil. ` +\n `Kolonu boşaltmak istiyorsan null yaz; kolonu değiştirmek istemiyorsan nesneye hiç koyma ` +\n `(bir eksik istek alanı sessizce NULL yazıyordu — FR-016).`,\n );\n }\n }\n}\n","/**\n * tx-plan.ts — `Database.$transaction()` as a PLAN, not a pinned session.\n *\n * A transaction used to be a conversation: BEGIN, then one network round trip\n * per operation, then COMMIT. Each of those round trips cost ~4 ms and, because\n * the pooler runs in transaction mode, an open transaction pinned a Postgres\n * backend for the whole conversation. A 121-operation statement upload pinned\n * one backend for ~490 ms.\n *\n * So the callback no longer TALKS to the database. It DESCRIBES what should\n * happen; the description is serialised and sent once; the broker runs the whole\n * thing inside one transaction and answers once. Committing on return and\n * rolling back on throw is unchanged — that is the only property tenant code\n * actually asked for.\n *\n * The consequences, stated plainly, because they are the whole design:\n *\n * - The callback is SYNCHRONOUS. There is nothing to await: no statement has\n * run yet when it returns. `async` on the callback and `await` inside it are\n * both compile errors (see {@link TxPlan} and {@link NotAwaitable}).\n * - `insert()` does not hand back a row, it hands back {@link TxRows}. Reading\n * a field requires `.expectOne(err)` first, which makes \"what if the row\n * isn't there\" a question you cannot route around: it is the argument.\n * - A field read from a row is a {@link Ref} — a PROMISE OF A VALUE THE SERVER\n * WILL PRODUCE, not the value. It can be written into a later operation and\n * it can be returned from the callback (it is substituted for the real value\n * before `transaction()` resolves). It cannot be branched on. See the\n * \"Truthiness\" note below — this is the sharp edge of the whole design.\n * - Control flow that needs a real value must move OUT of the callback: read\n * before the transaction, or express the condition as a guard\n * (`updateWhere({ id, accepted_at: null }, …).expectOne(new Conflict(…))`)\n * which the server evaluates and which rolls the whole plan back.\n *\n * # Truthiness — the hole this file CANNOT close\n *\n * JavaScript does not let a Proxy trap truthiness. `if (ref)` takes the true\n * branch, always, for every Ref, and no `get` handler ever runs. `tsc` is silent\n * because a Ref is a perfectly good object. So:\n *\n * const pot = tx.tables.pots.select({ id }, { limit: 1 }).expectOne(e);\n * if (!pot.balance) { … } // ← ALWAYS false. Silently wrong data.\n *\n * What this file does close: coercion (`Symbol.toPrimitive`/`valueOf`/\n * `toString`), awaiting (`then` is a callable member with a non-thenable\n * signature, which is a *compile* error), serialisation (`toJSON`), and nesting\n * a Ref inside a literal value where the server would store it as data. What it\n * cannot close is a bare truthiness test. The real defence is the build-time\n * static analysis (`tx_analysis.js`, phase P4); until that ships, this hole is\n * open and this comment is the only warning.\n *\n * # Wire contract\n *\n * The JSON this file emits is consumed by\n * the plan executor in `engine/db.ts`. That executor rejects\n * unknown fields at every level, so an op carries EXACTLY the fields its kind\n * takes. Everything here that looks like a needless restriction is one of the\n * server's rules made visible early:\n *\n * - `$ref` only points BACKWARDS, and only at an op statically known to yield\n * at most one row (insert, or a `one`/`atMost 1` guard, or `select limit 1`).\n * `.expectOne()` is what this file uses to satisfy that, always.\n * - `$expr` is a closed set: `inc`/`dec` (update only — they read the column's\n * current value) and `now()`.\n * - `update`/`delete` require a `where`; `insert` refuses one.\n * - `insertMany` rows must all set the same columns.\n * - ≤1000 ops, ≤5000 rows per insertMany, ≤8 MiB of JSON.\n *\n * Column keys are emitted SORTED, so the same callback always produces byte-\n * identical JSON. That is what lets the Go decoder be locked to golden files\n * this SDK emits (`testdata/tx_plan_golden/`).\n */\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/**\n * A plan handle was used as if it were a value: awaited, coerced to a string or\n * number, serialised, or nested inside another value.\n *\n * Thrown while the callback is still BUILDING the plan, so nothing has been sent\n * and nothing has been written.\n */\n// TİP-ONLY, ve döngü kasıtlı: `typed-db.ts` bu dosyadan tip alıyor, bu dosya\n// ondan `WhereOp` alıyor. Çalışma zamanında hiçbir şey ithal edilmiyor (import\n// type), yani modül döngüsü yok — paylaşılan olan şey TEK FİLTRE DİLİ, ve onu\n// iki yerde ayrı ayrı tanımlamak bu run'ın kapattığı \"iki yazım\"ın tipteki\n// hâli olurdu.\nimport type { WhereOpWith, ColRefOf, HasOnly, SqlFragment } from \"./typed-db.js\";\nimport { isColRef, isSqlFragment, brandRef, isNowExpr } from \"./input-guards.js\";\n\nexport class TxRefError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxRefError\";\n }\n}\n\n/**\n * The plan the callback described cannot be sent: it breaks a rule the server\n * would reject, and rejecting it here names the line that wrote it instead of\n * returning a 400 about an op index.\n */\nexport class TxPlanError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TxPlanError\";\n }\n}\n\n// ---------------------------------------------------------------------------\n// Wire types — mirror the plan executor in `engine/db.ts` exactly.\n// ---------------------------------------------------------------------------\n\n/** A backwards reference to an earlier op's single-row result. */\nexport interface TxWireRef {\n $ref: { op: number; field: string };\n}\n\n/** A call from the server's closed function set. */\nexport interface TxWireExpr {\n $expr: { fn: \"inc\" | \"dec\"; by: number | string } | { fn: \"now\" };\n}\n\n/** One value in a `values`/`set`/`where` map: a literal, a `$ref` or a `$expr`. */\nexport type TxWireValue = TxWireRef | TxWireExpr | unknown;\n\n/** The tenant's declared expectation about an op's row count. `slot` indexes the\n * client-side error table — the error OBJECT never travels. */\nexport interface TxWireGuard {\n kind: \"one\" | \"none\" | \"atLeast\" | \"atMost\";\n n: number;\n slot: number;\n}\n\n/** One operation in the wire plan. Fields are omitted, never null: the decoder\n * rejects a field that does not belong to the op's kind. */\nexport interface TxWireOp {\n /** upsert and insertMany: the columns Postgres matches on. */\n onConflict?: readonly string[];\n /** insertMany only: what a collision does. Absent means no ON CONFLICT clause\n * at all, which is what every insertMany did before this option existed. */\n action?: \"ignore\" | \"update\";\n op: \"insert\" | \"insertMany\" | \"upsert\" | \"update\" | \"delete\" | \"select\";\n table: string;\n values?: Record<string, TxWireValue>;\n rows?: Record<string, TxWireValue>[];\n set?: Record<string, TxWireValue>;\n where?: Record<string, TxWireValue>;\n limit?: number;\n lock?: \"update\";\n guard?: TxWireGuard;\n}\n\n/** The plan the engine executes on the request's own transaction. */\nexport interface TxPlanBody {\n ops: TxWireOp[];\n}\n\n/** One op's outcome, positionally matched to the plan's ops. */\nexport interface TxPlanOpResult {\n rows: Record<string, unknown>[];\n rows_affected: number;\n}\n\n/** One result per op, in plan order. */\nexport interface TxPlanResponse {\n results: TxPlanOpResult[];\n}\n\n/**\n * The fields the runtime must copy from the broker's error envelope onto the\n * rejection it throws out of {@link DBClient.txPlan}.\n *\n * `slot` is the whole point: on a guard failure the server answers with the\n * INDEX of the expectation that did not hold, never with an error message of its\n * own, and this SDK maps that index back to the `Error` the callback handed to\n * `.expectOne(…)`. Without `slot` a guard failure degrades to a generic 409.\n */\nexport interface TxPlanRejection {\n status?: number;\n /** `tx_plan_invalid` | `tx_guard_failed` | `tx_ref_unresolved` | a pg class. */\n error_code?: string;\n /** Present only for `tx_guard_failed`: the client-side error table index. */\n slot?: number;\n /** Present on a database error: which op failed. */\n op?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Handle types\n// ---------------------------------------------------------------------------\n\ndeclare const refBrand: unique symbol;\ndeclare const rowBrand: unique symbol;\ndeclare const rowsBrand: unique symbol;\n\n/**\n * Makes a handle a compile error to `await`.\n *\n * `then` is declared as a CALLABLE member whose signature is not `PromiseLike`,\n * which is precisely the shape TypeScript rejects: `await handle` is TS1320 and\n * `async () => handle` is TS1058. A non-callable `then` would not do it — the\n * compiler simply ignores those.\n */\nexport interface NotAwaitable {\n /** Not a promise. Nothing here has run yet; there is nothing to await. */\n then(doNotAwaitAPlanHandle: \"a transaction plan is built synchronously\"): never;\n}\n\n/**\n * A value the SERVER will produce, standing in for a column of a row this plan\n * writes or reads.\n *\n * Legal uses: write it into a later operation's `values`/`set`/`where`, or\n * return it from the callback (it is replaced by the real value before\n * `transaction()` resolves).\n *\n * Illegal, and caught: `await`, `String(ref)`, `` `${ref}` ``, `ref + 1`,\n * `JSON.stringify(ref)`, burying it inside a jsonb object.\n *\n * Illegal, and NOT caught: `if (ref)`. See the truthiness note at the top.\n */\nexport interface Ref<T> extends NotAwaitable {\n readonly [refBrand]: T;\n}\n\n/** The brand carried by a single-row handle, and the seam `Materialized` reads\n * to turn `return st` into the whole row. */\nexport interface TxRowHandle<Row> extends NotAwaitable {\n readonly [rowBrand]: Row;\n}\n\n/**\n * A row this plan is known to produce exactly one of. Every property is a\n * {@link Ref}; returning the handle itself yields the whole row.\n *\n * Only `.expectOne(err)` produces one — which is the design: a row you can read\n * fields from is a row whose absence you have already answered for.\n */\nexport type TxRow<Row> = { readonly [K in keyof Row]: Ref<Row[K]> } & TxRowHandle<Row>;\n\n/**\n * The result of one operation, before any expectation is declared about it.\n *\n * Deliberately not a row and not a list: an operation's row count is not known\n * until the server runs it, so the only thing that can be said about it here is\n * an EXPECTATION. Declaring one is also the only way to get a readable row.\n *\n * At most one expectation per operation — the wire carries one guard per op, and\n * a second call throws rather than silently dropping the first.\n */\nexport interface TxRows<Row> extends NotAwaitable {\n readonly [rowsBrand]: Row;\n /**\n * Require exactly one row, and read it. On any other count the server rolls\n * the whole transaction back and this `error` is thrown to the caller.\n *\n * This is the only way to reach a row's fields, and the only shape a `$ref`\n * may point at.\n */\n expectOne(error: Error): TxRow<Row>;\n /** Require zero rows (e.g. \"this membership must not already exist\"). */\n expectNone(error: Error): void;\n /** Require at least `n` rows. */\n expectAtLeast(n: number, error: Error): void;\n /** Require at most `n` rows. */\n expectAtMost(n: number, error: Error): void;\n}\n\n/** `now()` — the server's clock, usable wherever a value is. */\nexport interface TxNow extends NotAwaitable {\n readonly $expr: { fn: \"now\" };\n}\n\n/** `inc(n)` / `dec(n)` — read the column's CURRENT value and write it back\n * changed. Only meaningful in an update's `set`, which is where the types allow\n * it and where the server allows it. */\nexport interface TxColumnExpr extends NotAwaitable {\n readonly $expr: { fn: \"inc\" | \"dec\"; by: number | string };\n}\n\n/**\n * Resolve a callback's return type against what actually comes back: every\n * {@link Ref} becomes its value, every {@link TxRow} becomes its row, and\n * anything else keeps its shape.\n *\n * A {@link TxRows} resolves to an explanatory string type rather than a row\n * list: it has no single answer to give, and saying so in the type is louder\n * than a runtime throw.\n */\nexport type Materialized<T> = T extends Ref<infer U>\n ? U\n : T extends TxRowHandle<infer R>\n ? R\n : T extends TxRows<unknown>\n ? \"a TxRows cannot leave the transaction callback — read a row with .expectOne(err) first\"\n : T extends Date\n ? T\n : T extends object\n ? { [K in keyof T]: Materialized<T[K]> }\n : T;\n\n// ---------------------------------------------------------------------------\n// Author-facing value types\n// ---------------------------------------------------------------------------\n\n/** A value written by an INSERT: a literal, an earlier row's field, or `now()`.\n * `inc`/`dec` are absent on purpose — they read a current value, and an inserted\n * row has none. */\nexport type TxInsertValue<V> = V | Ref<V> | TxNow;\n\n/** A value written by an UPDATE's `set`: everything an insert takes, plus the\n * read-modify-write expressions. */\n/**\n * TEK KURAL: ifade tutamağı yalnız sayısal-benzeri kolonlarda.\n *\n * Bu tip KOŞULSUZDU ve doğrudan yolun `SetValue<V>`'si koşulluydu, yani aynı\n * nesne için İKİ tip kuralı vardı: `tx.tables.todos.updateWhere({id}, { done:\n * increment(1) })` (boolean kolon!) DERLENİYOR, `updateMany`'nin aynısı derleme\n * hatası veriyordu. Bu run'ın kapatmak için var olduğu şey \"aynı iş için iki\n * uyumsuz yazım\"dı; tip kuralı ikinci yazımın kendisi olmuştu (gözcü I6/I-1).\n */\nexport type TxSetValue<V> =\n | V\n | Ref<V>\n | TxNow\n | (NonNullable<V> extends number | string ? TxColumnExpr : never);\n\n/** An insert payload: the table's insert shape, with refs and `now()` allowed. */\nexport type TxInsertShape<Insert> = { [K in keyof Insert]: TxInsertValue<Insert[K]> };\n\n/** An update's `set`: any subset of the insert shape, with expressions allowed. */\nexport type TxSetShape<Insert> = { [K in keyof Insert]?: TxSetValue<Insert[K]> };\n\n/**\n * A filter. Every entry is an equality test and they are AND-ed; a `null`\n * becomes `IS NULL`, which is what makes `{ accepted_at: null }` a usable\n * \"not yet accepted\" guard rather than a clause that matches nothing.\n */\n/**\n * Plan filtresinin tipi — `WhereFilter<Row>` ile AYNI sözlük, artı `Ref`.\n *\n * Eskiden yalnız eşitlikti (`Row[K] | Ref<Row[K]>`), ve iki şeye mal oluyordu:\n * FR-014'ün amiral deseni (`{ balance: { gte: amount } }`) `$transaction`\n * İÇİNDE yazılamıyordu — koşullu bir yazmayı plana koyamayan yazar `$query`'ye\n * düşüyordu — ve motor tarafında tip atlandığında aynı nesne SESSİZCE parametre\n * olarak bağlanıyordu.\n *\n * `Ref` fazladan üye ve öyle kalmalı: bir plan filtresi ÖNCEKİ bir işlemin\n * döndürdüğü değere bakabilir, `findMany` bakamaz — plan dışında böyle bir\n * \"önceki işlem\" yok.\n */\ntype TxWhereField<Row, K extends keyof Row> = WhereOpWith<\n Row[K],\n // `Ref` KOLON REFERANSININ YANINDA duruyor, `V`'nin içinde DEĞİL: `V`'ye\n // eklenseydi `TextOps<V>`'nin `V extends string` sorusu HAYIR olur ve\n // `contains`/`startsWith` sessizce kaybolurdu (ölçüldü).\n ColRefOf<Row, Row[K]> | Ref<Row[K]>\n>;\n\nexport type TxWhere<Row, Rels = unknown> = {\n [K in keyof Row]?: TxWhereField<Row, K>;\n} & {\n // Düz op'lardaki `WhereFilter` ile AYNI: dal bir `sqlFragment` de olabilir.\n // İki filtre dilinin bir dalda ayrışması, \"tek dil\" iddiasını tam da bileşim\n // anında boşa çıkarırdı — ve motor plan yolunda da fragment'i derliyor\n // (ölçüldü: `SELECT t.* FROM \"crew\" t WHERE true AND (((a > 1)) AND (…))`).\n OR?: (TxWhere<Row, Rels> | SqlFragment)[];\n AND?: (TxWhere<Row, Rels> | SqlFragment)[];\n NOT?: TxWhere<Row, Rels> | SqlFragment;\n} & HasOnly<Rels>;\n\n/** Options for a plan `select`. */\nexport interface TxSelectOptions {\n /** Cap the rows read. */\n limit?: number;\n /** Take a real `FOR UPDATE` row lock for the rest of the transaction. */\n lock?: \"update\";\n}\n\n/** One table, as the plan sees it. */\nexport interface TxTable<Row, Insert, Rels = unknown> {\n /** Insert one row. Returns a handle — call `.expectOne(err)` to read fields. */\n insert(values: TxInsertShape<Insert>): TxRows<Row>;\n /**\n * Insert many rows in ONE statement. Every row must set the same columns\n * (a row that omits one would silently take the column's default).\n *\n * An empty list writes nothing and sends nothing.\n */\n /**\n * Insert many rows in ONE statement, optionally choosing what a collision does.\n *\n * Without `opts` this is a plain multi-row INSERT and a collision aborts the\n * transaction — the behaviour every call had before the option existed.\n *\n * `action: \"ignore\"` emits `ON CONFLICT DO NOTHING`, which is how \"insert the\n * ones that are new\" becomes one round-trip instead of one per row with a\n * 23505 caught around each. **The returned rows are the ones actually\n * INSERTED**: a row that collided is skipped, so it is absent from the result\n * — Postgres does not return what it did not write.\n *\n * `action: \"update\"` emits `ON CONFLICT DO UPDATE`, setting every non-conflict\n * column from the incoming row, and every row comes back.\n */\n insertMany(\n rows: readonly TxInsertShape<Insert>[],\n opts?: {\n onConflict: readonly Extract<keyof Row, string>[];\n action?: \"ignore\" | \"update\";\n },\n ): TxRows<Row>;\n /**\n * Satırı yaz, `onConflict` kolonlarında çakışırsa üzerine yaz — planın\n * savepoint'i içinde, `Database.<şema>.<tablo>.put()` ile AYNI anlamda.\n *\n * Adı bilerek aynı: aynı iş için transaction içinde ve dışında iki farklı\n * yazım, bu run'ın kapatmak için var olduğu şeydir (P1). TEL şekli\n * (`op: \"upsert\"`) değişmedi — o iç sözleşme, yazarın gördüğü ad değil.\n *\n * Bir operasyon olmasının sebebi: alternatifi burada yazılamaz — başarısız\n * bir insert tüm transaction'ı abort eder, yani \"dene, sonra geri düş\" iki\n * plan adımı olamaz.\n */\n put(\n values: TxInsertShape<Insert>,\n options: { onConflict: readonly Extract<keyof Row, string>[] },\n ): TxRows<Row>;\n /**\n * Update every row matching `where`. The filter comes first because it is the\n * dangerous half: an update whose `where` you got wrong rewrites rows you\n * never looked at. The server refuses an update with no `where` at all.\n */\n updateWhere(where: TxWhere<Row, Rels>, set: TxSetShape<Insert>): TxRows<Row>;\n /** Delete every row matching `where`. The server refuses an unfiltered delete. */\n deleteWhere(where: TxWhere<Row, Rels>): TxRows<Row>;\n /** Read rows, optionally locking them for the rest of the transaction. */\n select(where?: TxWhere<Row, Rels>, options?: TxSelectOptions): TxRows<Row>;\n}\n\n/**\n * The handle a transaction callback receives.\n *\n * It carries tables and nothing else: no `query`, no `findById`, no `asService`.\n * A read whose value the plan does not write belongs OUTSIDE the transaction,\n * where it costs one round trip and can be branched on like an ordinary value.\n */\nexport interface TxPlanHandle<TTables> {\n /**\n * @deprecated `tx.public` kullanın. Bu ad public'in takma adı olarak DURUYOR\n * (göç notu onu öğretiyor ve her mevcut çağrı onu kullanıyor), ama ARTIK\n * ÖĞRETİLMİYOR: doğrudan yüzeyde `Database.tables` FR-001 ile kaldırıldı, ve\n * plan yüzeyinin onu öğretmeye devam etmesi yazarı bir yüzeyde çalışıp\n * diğerinde derlenmeyen bir yazıma alıştırıyordu (gözcü M-6).\n */\n tables: TTables;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — expressions\n// ---------------------------------------------------------------------------\n\n/** Internal marker read by the serialiser. */\nconst EXPR = Symbol.for(\"palbase.tx.expr\");\nconst REF = Symbol.for(\"palbase.tx.ref\");\nconst ROW = Symbol.for(\"palbase.tx.row\");\nconst ROWS = Symbol.for(\"palbase.tx.rows\");\n\ninterface RefDescriptor {\n op: number;\n field: string;\n}\n\n/** Property reads that must not silently produce a value on a plan handle.\n * `then` is the one that matters for correctness (it makes `await` a compile\n * error AND stops a handle from being adopted by a promise); the rest turn a\n * silent wrong answer — `\"[object Object]\"`, `NaN`, `{}` — into a thrown one. */\nconst TRAPPED_PROPS: readonly (string | symbol)[] = [\n \"then\",\n \"valueOf\",\n \"toString\",\n \"toJSON\",\n Symbol.toPrimitive,\n];\n\nfunction trap(prop: string | symbol, what: string, hint: string): never {\n const name = typeof prop === \"symbol\" ? prop.description ?? String(prop) : prop;\n throw new TxRefError(\n `${what} was used as a value (via \\`${name}\\`). Nothing in a transaction ` +\n `callback has run yet, so there is no value to read. ${hint}`,\n );\n}\n\n/** The server's `now()`. */\nexport function now(): TxNow {\n return makeExpr({ fn: \"now\" }) as TxNow;\n}\n\n/** Add `by` to the column's current value. Only valid in an update's `set`. */\nexport function increment(by: number | string): TxColumnExpr {\n assertAmount(by, \"increment\");\n return makeExpr({ fn: \"inc\", by }) as TxColumnExpr;\n}\n\n/**\n * `increment`'in eski adı. AYNI fabrikadır — iki uygulama değil, iki ad.\n *\n * @deprecated `increment()` kullanın; bu ad geriye dönük uyumluluk için duruyor.\n */\nexport const inc = increment;\n\n/** Subtract `by` from the column's current value. Only valid in an update's `set`. */\nexport function decrement(by: number | string): TxColumnExpr {\n assertAmount(by, \"decrement\");\n return makeExpr({ fn: \"dec\", by }) as TxColumnExpr;\n}\n\n/**\n * `decrement`'in eski adı. AYNI fabrikadır.\n *\n * @deprecated `decrement()` kullanın.\n */\nexport const dec = decrement;\n\n/**\n * Miktarın taşınabilir olduğunu doğrular.\n *\n * String kabul edilir ve KASITLIDIR (D-007): `numeric` bir kolonda miktar JS\n * `number`'a uğrarsa 0.1 + 0.2 orada 0.30000000000000004'tür ve para hesabı\n * sessizce kayar. String hem burada hem `renderValue`'da bound parametre olarak\n * taşınır — Postgres onu tam ondalık olarak okur.\n */\nfunction assertAmount(by: number | string, fn: string): void {\n if (typeof by === \"string\") {\n // Metin SQL'e girmiyor (bound parametre), ama şekli yine de doğrulanır:\n // \"abc\" bind edilirse hata Postgres'ten gelir, çağıranın diliyle değil.\n if (!/^-?\\d+(\\.\\d+)?$/.test(by)) {\n throw new TxPlanError(\n `${fn}() ondalık bir sayı metni bekliyor, \"${by}\" aldı — kabul edilen biçim: \"12\", \"-12\", \"12.50\"`,\n );\n }\n } else if (typeof by !== \"number\" || !Number.isFinite(by)) {\n // JSON has no NaN/Infinity: they would serialise to `null` and the server\n // would reject the plan with an unhelpful decode error.\n throw new TxPlanError(`${fn}() needs a finite number, got ${String(by)}`);\n }\n // NEGATİF MİKTAR REDDEDİLİR — ve bu şekil kontrolünden çok daha fazlası.\n // `decrement(\"-5\")` `SET c = c - $1` derliyordu, `$1 = -5`, yani beş EKLİYORDU.\n // FR-014'ün amiral deseninde (`where: { balance: { gte: amount } }`) miktar\n // istek gövdesinden geliyorsa `balance >= -5` her zaman doğru: hesap\n // KREDİLENDİRİLİR ve çağrı bunu 1 satırla \"başarı\" diye raporlar. Guard\n // okunduğunda işaret kontrol edilmiş gibi duruyordu (gözcü I9, ölçüldü).\n const negative = typeof by === \"string\" ? by.trimStart().startsWith(\"-\") : by < 0;\n if (negative) {\n const other = fn === \"increment\" ? \"decrement\" : \"increment\";\n throw new TxPlanError(\n `${fn}() negatif miktar almaz (\"${String(by)}\"). Ters yön için ${other}() kullanın — ` +\n `işaretin miktarda saklanması, yönü okuyan hiçbir kod tarafından görülmezdi.`,\n );\n }\n}\n\n/**\n * Bir değer `increment()`/`decrement()` ürünü mü? Öyleyse tel şekli.\n *\n * DOĞRUDAN yol (`updateMany`) da bu ifadeyi anlamak zorunda: aynı nesnenin iki\n * yerde çalışması, \"kolona ekle\"nin tek yazımı olmasının şartı (P1).\n */\nexport function columnExprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n return exprOf(v);\n}\n\nfunction makeExpr(expr: TxWireExpr[\"$expr\"]): unknown {\n return new Proxy(\n { [EXPR]: expr } as Record<string | symbol, unknown>,\n {\n get(target, prop) {\n if (prop === EXPR) return target[EXPR];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(prop, \"A plan expression\", \"Write it into an operation instead.\");\n }\n return undefined;\n },\n },\n );\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — refs and row handles\n// ---------------------------------------------------------------------------\n\nfunction makeRef(op: number, field: string): unknown {\n const target: Record<string | symbol, unknown> = { [REF]: { op, field } satisfies RefDescriptor };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === REF) return t[REF];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n `\\`${field}\\` of a row this transaction has not written yet`,\n \"Pass it to another operation in the same plan, or return it from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n return undefined;\n },\n });\n}\n\nfunction makeRowHandle(op: number): unknown {\n const target: Record<string | symbol, unknown> = { [ROW]: op };\n return new Proxy(target, {\n get(t, prop) {\n if (prop === ROW) return t[ROW];\n if (TRAPPED_PROPS.includes(prop)) {\n trap(\n prop,\n \"A row this transaction has not written yet\",\n \"Read one of its columns to reference it, or return the row from the \" +\n \"callback and read it after `transaction()` resolves.\",\n );\n }\n if (typeof prop === \"symbol\") return undefined;\n return makeRef(op, prop);\n },\n });\n}\n\nfunction refDescriptor(v: unknown): RefDescriptor | null {\n if (typeof v !== \"object\" || v === null) return null;\n const d = (v as Record<symbol, unknown>)[REF];\n return isRefDescriptor(d) ? d : null;\n}\n\nfunction isRefDescriptor(d: unknown): d is RefDescriptor {\n return (\n typeof d === \"object\" &&\n d !== null &&\n typeof (d as RefDescriptor).op === \"number\" &&\n typeof (d as RefDescriptor).field === \"string\"\n );\n}\n\nfunction rowOpIndex(v: unknown): number | null {\n if (typeof v !== \"object\" || v === null) return null;\n const op = (v as Record<symbol, unknown>)[ROW];\n return typeof op === \"number\" ? op : null;\n}\n\nfunction exprOf(v: unknown): TxWireExpr[\"$expr\"] | null {\n if (typeof v !== \"object\" || v === null) return null;\n const e = (v as Record<symbol, unknown>)[EXPR];\n return typeof e === \"object\" && e !== null ? (e as TxWireExpr[\"$expr\"]) : null;\n}\n\nfunction isRowsHandle(v: unknown): boolean {\n return typeof v === \"object\" && v !== null && (v as Record<symbol, unknown>)[ROWS] !== undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — value encoding\n// ---------------------------------------------------------------------------\n\n/**\n * Encode one value of a `values`/`set`/`where` map.\n *\n * The nesting check is not defensive tidiness. The server treats `$ref` as a\n * tagged value only at the TOP of a column's value; a ref buried inside a jsonb\n * payload is just data, and would be stored as the literal object\n * `{\"$ref\":{...}}` — a write that succeeds, commits, and is wrong. So a nested\n * handle is a hard error here, where the line that wrote it is still on the\n * stack.\n */\nfunction encodeValue(value: unknown, column: string, allowColumnExpr: boolean): TxWireValue {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n // `now()` bir KARŞILAŞTIRMA değeri olarak geçer — sunucu saati. Diğer\n // ifadeler (increment/decrement) yazma ifadesidir ve aşağıda adıyla\n // reddediliyor. Düz op yolu ile aynı ayrım, aynı gerekçe.\n if (isNowExpr(value)) return { $expr: { fn: \"now\" } };\n const expr = exprOf(value);\n if (expr) {\n if (expr.fn !== \"now\" && !allowColumnExpr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() reads the column's current value, so it is ` +\n `only valid in updateWhere(where, set).`,\n );\n }\n return { $expr: expr } satisfies TxWireExpr;\n }\n\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant ` +\n `(e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n\n assertNoNestedHandles(value, column);\n return value;\n}\n\n/**\n * Encode a FİLTRE — `values`/`set` ile AYNI kodlayıcı değil, ve olmaması bir\n * düzeltme.\n *\n * `encodeValue` bir `$ref`'i yalnız kolonun EN ÜSTÜNDE kabul ediyor, çünkü bir\n * insert değerinin İÇİNE gömülü ref sunucuda çözülmez, literal JSON olarak\n * SAKLANIR — \"başarıyla commit olan ve yanlış olan bir yazma\". O kural DEĞER\n * yolu için doğru.\n *\n * FİLTREDE öyle değil: motorun `resolveRefsDeep`'i bir ref'i filtrenin HER\n * yerinde çözüyor — operatörün sağında, `OR`/`AND`/`NOT` dallarının içinde. Ama\n * kodlayıcı hâlâ değer kuralını uyguluyordu, yani üç katman üç farklı cevap\n * veriyordu (gözcü C-2): tip kabul, motor çözüyor, kodlayıcı REDDEDİYOR — ve\n * reddin metni değer-yuvalama vakasını anlatıyor, filtrede olmayan bir şeyi.\n *\n * İFADE TUTAMAĞI ve SATIR TUTAMAĞI filtrede HÂLÂ reddediliyor: onları motor\n * filtrede çözmüyor ve çözmemeli — `increment()` bir yazma ifadesi, bir\n * karşılaştırma değil.\n */\nfunction encodeFilterValue(value: unknown, column: string): unknown {\n const ref = refDescriptor(value);\n if (ref) return brandRef({ $ref: { op: ref.op, field: ref.field } }, \"ref\") satisfies TxWireRef;\n\n const expr = exprOf(value);\n if (expr) {\n throw new TxPlanError(\n `\\`${column}\\`: ${expr.fn}() bir YAZMA ifadesi, karşılaştırma değil — ` +\n `filtrede kullanılamaz. Kolonu bir değerle ya da col() ile karşılaştırın.`,\n );\n }\n if (rowOpIndex(value) !== null) {\n throw new TxPlanError(\n `\\`${column}\\`: a row handle is not a value. Read the column you meant (e.g. \\`row.id\\`).`,\n );\n }\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: an operation result is not a value. Declare an expectation ` +\n `first (\\`.expectOne(err)\\`) and read a column from the row.`,\n );\n }\n if (Array.isArray(value)) return value.map((v) => encodeFilterValue(v, column));\n // `col()` ve `sqlFragment` OLDUĞU GİBİ geçer: markaları süreç içinde korunur\n // ve derleyici ikisini de kendi tanıyor.\n if (value !== null && typeof value === \"object\" && !(value instanceof Date) && !isColRef(value) && !isSqlFragment(value)) {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = encodeFilterValue(v, column);\n }\n return out;\n }\n return value;\n}\n\n/** Filtre haritası — anahtarlar SIRALI (aynı geri çağrı bayt-özdeş JSON üretsin). */\nfunction encodeFilterMap(map: Record<string, unknown>): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n if (value === undefined) continue;\n out[key] = encodeFilterValue(value, key) as TxWireValue;\n }\n return out;\n}\n\nfunction assertNoNestedHandles(value: unknown, column: string): void {\n if (typeof value !== \"object\" || value === null) return;\n if (value instanceof Date) return;\n if (refDescriptor(value) || exprOf(value) || rowOpIndex(value) !== null || isRowsHandle(value)) {\n throw new TxPlanError(\n `\\`${column}\\`: a plan handle is nested inside a value. The server would ` +\n `store it as literal JSON, not resolve it. Put the reference directly in ` +\n `the column.`,\n );\n }\n if (Array.isArray(value)) {\n for (const item of value) assertNoNestedHandles(item, column);\n return;\n }\n for (const item of Object.values(value as Record<string, unknown>)) {\n assertNoNestedHandles(item, column);\n }\n}\n\n/**\n * Encode a column map, dropping `undefined` and emitting keys SORTED.\n *\n * Sorting is what makes the same callback produce byte-identical JSON every\n * time, which is what lets the Go decoder be locked to goldens this SDK emits.\n * Dropping `undefined` mirrors what `JSON.stringify` would do anyway, but does\n * it where the resulting column list is still checkable.\n */\nfunction encodeMap(\n map: Record<string, unknown>,\n allowColumnExpr: boolean,\n): Record<string, TxWireValue> {\n const out: Record<string, TxWireValue> = {};\n for (const key of Object.keys(map).sort()) {\n const value = map[key];\n // AÇIK `undefined` REDDEDİLİR (D-017 kapandı).\n //\n // \"Kolon varsayılanını al\" demenin yolu anahtarı HİÇ KOYMAMAK; bu döngü\n // zaten yalnız var olan anahtarları geziyor, yani o niyet bozulmadan\n // çalışıyor. Ayırt edilen şey başka: anahtarın DURDUĞU ama değerinin\n // `undefined` olduğu hâl — yani `{ title: req.body.title }` gövdede\n // `title` yokken. O ölçülmüş bir olaydı: kolon sessizce yazılmadı ve\n // istek 200 döndü.\n //\n // Doğrudan yol bunu baştan beri adıyla reddediyordu; plan yolu sessizce\n // düşürüyordu. Aynı girdiye zıt iki cevap, \"tek filtre dili, tek cevap\"\n // iddiasını yazma tarafında boşa çıkarıyordu.\n if (value === undefined) {\n throw new TxPlanError(\n `${key} değeri undefined — bu bir yazma değeri değil. Anahtar duruyor ` +\n `ama değeri yok, yani kolon sessizce YAZILMAZDI (istek gövdesinden ` +\n `gelen bir alanın eksik olması bu şekilde görünür). Kolon ` +\n `varsayılanını istiyorsanız anahtarı hiç koymayın; NULL yazmak ` +\n `istiyorsanız açıkça null yazın.`,\n );\n }\n out[key] = encodeValue(value, key, allowColumnExpr);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the builder\n// ---------------------------------------------------------------------------\n\n/** How many rows an op can produce, as far as the CLIENT can tell before it\n * runs. Only the empty `insertMany` is knowable, and knowing it is what lets a\n * doomed expectation fail on the line that declared it. */\nconst SKIPPED_OP = -1;\n\nclass TxRowsImpl<Row> implements TxRows<Row> {\n // Present so `isRowsHandle` recognises the object; never read for its value.\n readonly [ROWS] = true;\n // Phantom: the type brand that stops a bare object passing as a TxRows. Never\n // present at run time, which is what `declare` says.\n declare readonly [rowsBrand]: Row;\n private guarded = false;\n\n constructor(\n private readonly builder: TxPlanBuilder,\n private readonly opIndex: number,\n private readonly what: string,\n ) {}\n\n // The type-level `await` guard made real: TS rejects `await rows` at compile\n // time, and reaching this means someone called `.then(...)` by hand.\n then(): never {\n throw new TxRefError(\n `${this.what} cannot be awaited: a transaction callback builds a plan, it ` +\n `does not run statements. Remove the \\`await\\`.`,\n );\n }\n\n expectOne(error: Error): TxRow<Row> {\n this.declareGuard(\"one\", 1, error);\n if (this.opIndex === SKIPPED_OP) throw error;\n return makeRowHandle(this.opIndex) as TxRow<Row>;\n }\n\n expectNone(error: Error): void {\n this.declareGuard(\"none\", 0, error);\n }\n\n expectAtLeast(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtLeast\");\n this.declareGuard(\"atLeast\", n, error);\n if (this.opIndex === SKIPPED_OP && n > 0) throw error;\n }\n\n expectAtMost(n: number, error: Error): void {\n assertGuardCount(n, \"expectAtMost\");\n this.declareGuard(\"atMost\", n, error);\n }\n\n private declareGuard(kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n if (!(error instanceof Error)) {\n // The error object is the ONLY thing that describes this failure to the\n // caller — the server sends back an index, never a message.\n throw new TxPlanError(\n `${this.what}: an expectation needs the Error to throw when it does not ` +\n `hold (e.g. \\`.expect…(new Conflict(\"already accepted\"))\\`).`,\n );\n }\n if (this.guarded) {\n throw new TxPlanError(\n `${this.what} already has an expectation. One operation carries one ` +\n `expectation; declare the second one on its own operation.`,\n );\n }\n this.guarded = true;\n if (this.opIndex === SKIPPED_OP) return;\n this.builder.attachGuard(this.opIndex, kind, n, error);\n }\n}\n\nfunction assertGuardCount(n: number, fn: string): void {\n if (!Number.isInteger(n) || n < 0) {\n throw new TxPlanError(`${fn}(n) needs a non-negative integer, got ${String(n)}`);\n }\n}\n\n/** Bounds mirrored from the plan executor so an over-sized plan is named here rather\n * than rejected as an opaque 400 after it has crossed the network. */\nconst MAX_OPS = 1000;\nconst MAX_ROWS = 5000;\n\n/**\n * Accumulates ops and the client-side error table while the callback runs.\n *\n * Exported for the runtime and for tests that need the serialised plan without\n * a server; author code never sees it.\n */\nexport class TxPlanBuilder {\n private readonly ops: TxWireOp[] = [];\n /** Errors handed to expectations, indexed by the `slot` the server echoes. */\n private readonly slots: Error[] = [];\n\n /** The table surface handed to the callback. Untyped here; the public\n * `transaction()` signatures put the schema types on top. */\n table(name: string): TxTable<Record<string, unknown>, Record<string, unknown>> {\n return {\n insert: (values) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.insert() needs at least one column`);\n }\n return this.push({ op: \"insert\", table: name, values: encoded }, `${name}.insert()`);\n },\n\n put: (values, options) => {\n const encoded = encodeMap(values as Record<string, unknown>, false);\n if (Object.keys(encoded).length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one column`);\n }\n if (options.onConflict.length === 0) {\n throw new TxPlanError(`${name}.put() needs at least one onConflict column`);\n }\n return this.push(\n { op: \"upsert\", table: name, values: encoded, onConflict: options.onConflict },\n `${name}.upsert()`,\n );\n },\n\n insertMany: (rows, opts) => {\n if (rows.length === 0) {\n // Nothing to write. Emitting an op would be a guaranteed 400 (the\n // server requires rows), and refusing outright would punish the\n // ordinary \"filtered every candidate out\" case.\n return new TxRowsImpl(this, SKIPPED_OP, `${name}.insertMany()`);\n }\n if (rows.length > MAX_ROWS) {\n throw new TxPlanError(\n `${name}.insertMany() has ${rows.length} rows; the limit is ${MAX_ROWS}. ` +\n `Split the write across requests.`,\n );\n }\n const encoded = rows.map((row) => encodeMap(row as Record<string, unknown>, false));\n assertUniformRows(encoded, name);\n if (opts !== undefined && opts.onConflict.length === 0) {\n throw new TxPlanError(\n `${name}.insertMany() was given a conflict action with no onConflict ` +\n `columns. Postgres matches a collision on columns, so name them.`,\n );\n }\n return this.push(\n {\n op: \"insertMany\",\n table: name,\n rows: encoded,\n // Omitted entirely when no options were given, so the op a plain\n // insertMany produces is byte-identical to the one it produced\n // before this option existed.\n ...(opts !== undefined\n ? { onConflict: opts.onConflict, action: opts.action ?? \"ignore\" }\n : {}),\n },\n `${name}.insertMany()`,\n );\n },\n\n updateWhere: (where, set) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n const encodedSet = encodeMap(set as Record<string, unknown>, true);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.updateWhere() needs a filter. An update with no filter ` +\n `rewrites the whole table.`,\n );\n }\n if (Object.keys(encodedSet).length === 0) {\n throw new TxPlanError(`${name}.updateWhere() needs at least one column to set`);\n }\n return this.push(\n { op: \"update\", table: name, set: encodedSet, where: encodedWhere },\n `${name}.updateWhere()`,\n );\n },\n\n deleteWhere: (where) => {\n const encodedWhere = encodeFilterMap(where as Record<string, unknown>);\n if (Object.keys(encodedWhere).length === 0) {\n throw new TxPlanError(\n `${name}.deleteWhere() needs a filter. A delete with no filter empties ` +\n `the table.`,\n );\n }\n return this.push(\n { op: \"delete\", table: name, where: encodedWhere },\n `${name}.deleteWhere()`,\n );\n },\n\n select: (where, options) => {\n const op: TxWireOp = { op: \"select\", table: name };\n const encodedWhere = encodeFilterMap((where ?? {}) as Record<string, unknown>);\n if (Object.keys(encodedWhere).length > 0) op.where = encodedWhere;\n if (options?.limit !== undefined) {\n if (!Number.isInteger(options.limit) || options.limit < 0) {\n throw new TxPlanError(\n `${name}.select(): limit needs a non-negative integer, got ${String(options.limit)}`,\n );\n }\n op.limit = options.limit;\n }\n if (options?.lock !== undefined) op.lock = options.lock;\n return this.push(op, `${name}.select()`);\n },\n };\n }\n\n private push(op: TxWireOp, what: string): TxRows<Record<string, unknown>> {\n if (this.ops.length >= MAX_OPS) {\n throw new TxPlanError(\n `this transaction has ${MAX_OPS} operations, which is the limit. Use ` +\n `insertMany() for bulk writes, or split the work across requests.`,\n );\n }\n const index = this.ops.length;\n this.ops.push(op);\n return new TxRowsImpl(this, index, what);\n }\n\n /** Attach an expectation to an op and record its error in the slot table. */\n attachGuard(opIndex: number, kind: TxWireGuard[\"kind\"], n: number, error: Error): void {\n const op = this.ops[opIndex];\n // Unreachable: the index came from `push`. A loud failure beats a silently\n // unguarded write if that ever stops being true.\n if (!op) throw new TxPlanError(`internal: expectation on unknown operation ${opIndex}`);\n const slot = this.slots.length;\n this.slots.push(error);\n op.guard = { kind, n, slot };\n }\n\n /** The serialisable plan. Empty when the callback described no writes. */\n body(): TxPlanBody {\n return { ops: this.ops };\n }\n\n /** The error the server's `slot` selects, or `null` when it names one this\n * plan never declared (a server/client disagreement, not a tenant error). */\n errorForSlot(slot: number): Error | null {\n return this.slots[slot] ?? null;\n }\n}\n\nfunction assertUniformRows(rows: Record<string, TxWireValue>[], table: string): void {\n const first = rows[0];\n if (!first) return;\n const want = Object.keys(first);\n const wantKey = want.join(\",\");\n for (let i = 1; i < rows.length; i++) {\n const got = Object.keys(rows[i] as Record<string, TxWireValue>);\n if (got.join(\",\") !== wantKey) {\n // One statement, one column list. A ragged row would take the DB default\n // for the column it omitted — a write that succeeds and is wrong.\n throw new TxPlanError(\n `${table}.insertMany(): every row must set the same columns. Row 0 sets ` +\n `[${want.join(\", \")}] but row ${i} sets [${got.join(\", \")}]. ` +\n `(A property set to \\`undefined\\` counts as absent — use \\`null\\`.)`,\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — materialisation\n// ---------------------------------------------------------------------------\n\n/**\n * Replace every handle in the callback's return value with what the server\n * actually produced.\n *\n * Walks arrays and PLAIN objects only. Class instances (a Date, a Zod schema, a\n * domain object) are returned untouched — recursing into them would rebuild them\n * as bare objects, and nothing inside one can be a handle that this SDK created.\n */\nexport function materializeResult(value: unknown, results: TxPlanOpResult[]): unknown {\n const ref = refDescriptor(value);\n if (ref) {\n const row = rowOf(results, ref.op, `\\`${ref.field}\\``);\n if (!(ref.field in row)) {\n throw new TxPlanError(\n `the transaction's operation ${ref.op} returned no column \\`${ref.field}\\`.`,\n );\n }\n return row[ref.field];\n }\n\n const rowOp = rowOpIndex(value);\n if (rowOp !== null) return rowOf(results, rowOp, \"a row\");\n\n if (isRowsHandle(value)) {\n throw new TxPlanError(\n \"an operation result cannot be returned from a transaction callback: its \" +\n \"row count is not known until the plan runs. Declare an expectation \" +\n \"(`.expectOne(err)`) and return the row, or a column of it.\",\n );\n }\n\n if (Array.isArray(value)) return value.map((item) => materializeResult(item, results));\n\n if (isPlainObject(value)) {\n const out: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) out[key] = materializeResult(item, results);\n return out;\n }\n\n return value;\n}\n\nfunction rowOf(results: TxPlanOpResult[], opIndex: number, what: string): Record<string, unknown> {\n const result = results[opIndex];\n if (!result) {\n throw new TxPlanError(\n `the transaction returned no result for operation ${opIndex}, so ${what} ` +\n `cannot be read.`,\n );\n }\n const row = result.rows[0];\n if (!row) {\n // Unreachable through the public API: a handle only exists behind an\n // `expectOne`, and the server rolls back rather than answering 200 with a\n // guard unmet. Loud, because the alternative is `undefined` in tenant data.\n throw new TxPlanError(\n `the transaction's operation ${opIndex} returned no row, so ${what} cannot ` +\n `be read.`,\n );\n }\n return row;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto: unknown = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\n// ---------------------------------------------------------------------------\n// Runtime — the driver\n// ---------------------------------------------------------------------------\n\n/** What {@link runTxPlan} needs from the runtime: one call, one transaction. */\nexport interface TxPlanTransport {\n txPlan(plan: TxPlanBody): Promise<TxPlanResponse>;\n}\n\n/**\n * Build the plan, send it, and resolve the callback's return value.\n *\n * A callback that throws never reaches the network: there is nothing to roll\n * back because nothing was sent. A callback that describes no writes also skips\n * the round trip entirely.\n *\n * The RETURN type is `unknown` here on purpose. `Materialized<T>` is a compile-\n * time rewrite of the callback's return type, and it belongs on the public\n * `transaction()` signatures where `T` is inferred from the author's callback;\n * threading it through this driver as well would mean inferring `T` twice, from\n * two different positions, and reconciling them. The public wrappers narrow\n * once, at the seam where the value types were erased anyway.\n */\nexport async function runTxPlan<THandle>(\n transport: TxPlanTransport,\n // TUTAMAĞIN TAMAMI, yalnız `tables` DEĞİL. Tutamak artık şema yüzeyini de\n // taşıyor (`tx.public.x`, `tx.<şema>.x`), ve onu BURADA `{ tables }` diye\n // yeniden kurmak o yüzeyi sessizce düşürürdü.\n handle: THandle,\n builder: TxPlanBuilder,\n fn: (tx: THandle) => unknown,\n): Promise<unknown> {\n const returned = fn(handle);\n const body = builder.body();\n if (body.ops.length === 0) {\n return materializeResult(returned, []);\n }\n\n let response: TxPlanResponse;\n try {\n response = await transport.txPlan(body);\n } catch (err) {\n throw translateRejection(err, builder);\n }\n return materializeResult(returned, response.results);\n}\n\n/**\n * Turn the broker's rejection back into the tenant's own error.\n *\n * The server never sees the `Error` an expectation was given — only its slot\n * index — so this is the only place the intended error can be produced. A\n * rejection this SDK does not recognise passes through untouched: inventing an\n * error for it would hide the real failure.\n */\nfunction translateRejection(err: unknown, builder: TxPlanBuilder): unknown {\n if (typeof err !== \"object\" || err === null) return err;\n const rejection = err as TxPlanRejection;\n if (rejection.error_code !== \"tx_guard_failed\" || typeof rejection.slot !== \"number\") {\n return err;\n }\n return builder.errorForSlot(rejection.slot) ?? err;\n}\n","/** A PostgreSQL isolation level supported by the explicit root transaction. */\nexport type TransactionIsolation = \"read committed\" | \"repeatable read\" | \"serializable\";\n\nexport interface AtomicOptions {\n /** Each retry opens a fresh transaction and reruns the complete callback.\n * Defaults to zero. Keep external effects outside it; persist an outbox instead. */\n retry?: number;\n isolation?: TransactionIsolation;\n readOnly?: boolean;\n /** Maximum wait for a PostgreSQL lock. Defaults to 5000 ms. */\n lockTimeoutMs?: number;\n /** PostgreSQL statement timeout; applies to every statement in this scope. */\n statementTimeoutMs?: number;\n /** Total work deadline including queueing and retries. Active Bun queries are\n * cancelled; rollback settles before release. An in-flight COMMIT is awaited. */\n timeoutMs?: number;\n signal?: AbortSignal;\n\n}\n\nexport function retryBudget(value: number | undefined): number {\n const n = value ?? 0;\n if (!Number.isInteger(n) || n < 0 || n > 10) {\n throw new Error(\"transaction retry must be an integer between 0 and 10\");\n }\n return n;\n}\n\nexport function validateAtomicOptions(options: AtomicOptions): void {\n retryBudget(options.retry);\n if (options.isolation !== undefined && ![\"read committed\", \"repeatable read\", \"serializable\"].includes(options.isolation)) {\n throw new Error(\"transaction isolation must be read committed, repeatable read or serializable\");\n }\n if (options.readOnly !== undefined && typeof options.readOnly !== \"boolean\") {\n throw new Error(\"transaction readOnly must be a boolean\");\n }\n for (const name of [\"lockTimeoutMs\", \"statementTimeoutMs\", \"timeoutMs\"] as const) {\n const n = options[name];\n if (n !== undefined && (!Number.isInteger(n) || n < 1 || n > 2_147_483_647)) {\n throw new Error(`transaction ${name} must be a positive integer in milliseconds`);\n }\n }\n if (options.signal !== undefined && (typeof options.signal.aborted !== \"boolean\" || typeof options.signal.addEventListener !== \"function\")) {\n throw new Error(\"transaction signal must be an AbortSignal\");\n }\n}\n\n/** A savepoint cannot replace the enclosing transaction's snapshot or retry COMMIT. */\nexport function assertPlanRetry(options: { retry?: number } | undefined): void {\n if (retryBudget(options?.retry) !== 0) {\n throw new Error(\n \"Database.$transaction is a savepoint plan on the request transaction and cannot retry its snapshot or COMMIT. \" +\n \"Use Database.$atomic(async tx => { ... }, { retry, isolation }) and put all decision reads and writes inside that callback.\",\n );\n }\n}\n","// The wire shape of a declared schema — what the deploy reads.\n//\n// `defineSchema(...)` produces a value full of builders and phantom types, which\n// is the right shape for authoring and the wrong shape for anything outside this\n// process. The deploy is Go: it introspects the live database, diffs it against\n// the declaration, and applies the difference. So the declaration has to leave\n// TypeScript as data, and this file is where that happens.\n//\n// It lives in the SDK because the SDK owns the DSL. The alternative — a script\n// beside the deploy that reaches into `._def` — is a second reading of a private\n// shape, and it drifts the moment a column gains a property: the DSL keeps\n// working, the emitter silently omits it, and the database is missing something\n// nobody can see in the source.\n//\n// The field names below are a CONTRACT with Go's `schema.SchemaJSON`. Renaming\n// one here without renaming it there produces a declaration that parses to\n// something emptier than it was — the failure mode being a column, a policy, or\n// a whole table that quietly never gets created.\n// Politika ifadesinin tel şekli `policy.ts`'te TEK kez bildiriliyor. İki kopya\n// olsaydı biri `exists` düğümünü alır, diğeri almaz ve fark ancak Go tarafı\n// bilmediği bir `kind` gördüğünde ortaya çıkardı.\nimport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nexport type { PolicyExpr as PolicyExprJSON } from \"./policy.js\";\nimport type { ColumnBuilder, ColumnDef } from \"./columns.js\";\nimport type { PolicyDef } from \"./policy.js\";\nimport type { MemoryDecl, SchemaDef, SearchDecl, TableDef } from \"./schema.js\";\n\n/** One column, flattened. Mirrors Go's `schema.ColumnJSON`. */\nexport interface ColumnJSON {\n type: string;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n renamedFrom?: string;\n /** See Go's `schema.ColumnJSON.Ignored` — the contraction gate's only signal. */\n ignored?: boolean;\n owns?: boolean;\n references?: { table: string; column: string };\n onDeleteAction?: string;\n /** FR-044: türev FK index'i kapatılmışsa `false`. Bildirilmemişse alan YOK. */\n index?: boolean;\n /** FR-049: kolon increment() ile güncelleniyorsa `true`. Aksi hâlde alan YOK. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n dimensions?: number;\n}\n\n/** One RLS policy. Mirrors Go's `schema.PolicyJSON`. */\nexport interface PolicyJSON {\n name: string;\n command: string;\n roles: string[];\n /**\n * `USING (...)` — ham string (kaçış kapağı, FR-028) ya da YAPI (FR-022).\n *\n * Go tarafı ikisini de okur: string olan verbatim emit edilir, yapı olan\n * `generator.go`'da SQL'e çevrilir (C-6). Yapı hâli InitPlan sarmalamasını\n * ve `TO <rol>` daraltmasını GÜVENLE yapılabilir kılan şey — string üstünde\n * regex'le denemek yorum içindeki bir `auth.uid()`'yi de sarmalardı.\n */\n using: string | PolicyExprJSON | null;\n withCheck: string | PolicyExprJSON | null;\n permissive: boolean;\n}\n\n\n/** One table. Mirrors Go's `schema.TableJSON`. */\nexport interface TableJSON {\n /**\n * The schema this table lives in. `public` unless declared otherwise.\n *\n * The table carries it because the diff iterates over KEYS but passes the\n * VALUE around: a bare name inside a qualified key space writes the migration\n * into the wrong schema, silently.\n */\n schema: string;\n name: string;\n columns: Record<string, ColumnJSON>;\n rls: boolean;\n policies: PolicyJSON[];\n primaryKey?: string[];\n uniqueConstraints?: { name: string; columns: string[] }[];\n rawConstraints?: { name: string; up: string }[];\n checks?: { name: string; expr: string }[];\n indexes?: IndexJSON[];\n /** Canlıdan düşürülecek constraint adları (FR-008). Sıfır değerde OMIT. */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY'ler (FR-001). Sıfır değerde OMIT. */\n foreignKeys?: ForeignKeyJSON[];\n /** Koşullu FK'lar — donan demetler (FR-012). Sıfır değerde OMIT. */\n freeze?: FreezeJSON[];\n /** Guard'lar — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). Sıfır değerde OMIT. */\n guards?: GuardJSON[];\n /** Bir kez koşacak veri düzeltmeleri (FR-033). Sıfır değerde OMIT. */\n backfills?: BackfillJSON[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder. Sıfır değerde OMIT —\n * bildirmeyen tablolar wire'da bayt-aynı kalır.\n */\n appendOnly?: boolean;\n search?: SearchJSON;\n memory?: MemoryJSON;\n}\n\n/**\n * Bir index'in wire şekli — Go'nun `IndexJSON`'ıyla ALAN-ADI SÖZLEŞMESİ.\n *\n * `name` + `columns` bugünkü hâl; kalanı FR-041…043'ün taşıyıcısı. Hepsi sıfır\n * değerde OMIT edilir: bildirmeyen bir index wire'da eskisiyle bayt-aynı kalır,\n * yoksa dokunulmamış her şema diff'te değişmiş görünür ve her deploy churn üretir.\n */\nexport interface IndexJSON {\n name: string;\n /** `CREATE UNIQUE INDEX` (FR-007). Sıfır değerde OMIT. */\n unique?: boolean;\n columns: string[];\n /** Partial index koşulu (FR-042) — filtre şekli `WhereFilter` ile aynı. */\n where?: unknown;\n /** İfade index'i (FR-043), ör. `lower(email)`. `columns` ile birlikte kullanılmaz. */\n expression?: string;\n /** Kolon sırası (FR-043). */\n sort?: \"asc\" | \"desc\";\n /** NULL sırası (FR-043). */\n nulls?: \"first\" | \"last\";\n /** Covering index — `INCLUDE (...)` (FR-043). */\n include?: string[];\n}\n\n/**\n * Tablo düzeyi çok sütunlu FOREIGN KEY'in wire şekli — Go'nun `ForeignKeyJSON`'ı\n * ile ALAN-ADI SÖZLEŞMESİ (FR-001). Bir ad değişirse wire sessizce kopar.\n *\n * `onUpdate`/`onDelete`/`match` sıfır değerinde OMIT: bildirmeyen bir FK\n * Postgres'in varsayılanını (NO ACTION / MATCH SIMPLE) alır ve telde yer\n * kaplamaz (NFR-006).\n */\nexport interface ForeignKeyJSON {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: string;\n onDelete?: string;\n match?: string;\n}\n\n/**\n * Koşullu FK'nın (\"donan demet\") wire şekli — Go'nun `FreezeJSON`'ı ile\n * ALAN-ADI SÖZLEŞMESİ (C-8, FR-012).\n *\n * `when` politika ifade yapısının ta kendisi — `IndexJSON.where` ile aynı\n * duruş: üçüncü bir yüklem lehçesi açmak, aynı sorunun iki yazımı demekti.\n * Alanların hiçbiri opsiyonel değil: bir freeze'in koşulu, donan sütunları ve\n * hedefi olmadan anlamı yok ve `toFreezeDef` bunları bildirim anında şart\n * koşuyor. Sıfır değerde OMIT edilen şey DİZİNİN KENDİSİ (`TableJSON.freeze`).\n */\nexport interface FreezeJSON {\n name: string;\n when: unknown;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/**\n * Bir guard'ın wire şekli — Go'nun `GuardJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-4/C-8, FR-015).\n *\n * `when` ile `exists` AYRI alanlar: Postgres bir trigger'ın `WHEN` yan\n * tümcesinde alt sorguya izin vermiyor (`cannot use subquery in trigger WHEN\n * condition`), yani çapraz satır yüklemi gövdedeki `EXISTS` bloğuna inmek\n * zorunda (FR-019). Ayrımı emitter'ın yükleme bakıp tahmin etmesi yerine wire'da\n * taşımak, o kuralı bildirimin kendi şekline yazar.\n *\n * `detail`/`hint`/`column` sıfır değerde OMIT — bildirmeyen bir guard telde yer\n * kaplamaz (NFR-006). `message` her zaman var: reddin kullanıcıya ulaşan tek\n * çıktısı o.\n */\nexport interface GuardJSON {\n name: string;\n event: string;\n when?: unknown;\n exists?: unknown;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/**\n * Bir backfill'in wire şekli — Go'nun `BackfillJSON`'ı ile ALAN-ADI SÖZLEŞMESİ\n * (C-8, FR-033).\n *\n * `name` kimliğin TAMAMI: \"koştu mu\" sorusu ona göre cevaplanıyor, `sql`'e göre\n * değil. Aynı adın altında değişen bir gövde ikinci bir koşu üretmez.\n */\nexport interface BackfillJSON {\n name: string;\n sql: string;\n}\n\n/** C-11 wire şekli — Go'nun MemoryJSON'ıyla alan-adı sözleşmesi (D-019).\n * Beyansız tablolarda alan OMIT — eski şemalar bayt-aynı (NFR-B1). */\nexport interface MemoryJSON {\n from: string[];\n into: string;\n subject?: string;\n extract: { provider: string; model: string };\n}\n\n/** A whole declaration. Mirrors Go's `schema.SchemaJSON`. */\nexport interface SchemaJSON {\n tables: Record<string, TableJSON>;\n extensions: string[];\n /**\n * Every declared schema, with its HTTP reachability.\n *\n * The flag has nowhere else to live: `/v1/db` must know which schemas are\n * reachable, and introspection must know which schemas the project DECLARED —\n * a live database also contains internal module schemas that are none of the\n * diff's business.\n */\n schemas: SchemaMetaJSON[];\n}\n\nexport interface SchemaMetaJSON {\n name: string;\n exposed: boolean;\n}\n\n/** The definition behind a column, whichever side of the builder it arrives on. */\nfunction defOf(column: ColumnBuilder | ColumnDef): ColumnDef {\n return \"_def\" in column ? column._def : column;\n}\n\nfunction columnToJSON(column: ColumnBuilder | ColumnDef): ColumnJSON {\n const def = defOf(column);\n const out: ColumnJSON = {\n type: def.type,\n nullable: def.nullable,\n primaryKey: def.primaryKey,\n };\n // Every optional field is omitted rather than emitted as undefined: Go\n // distinguishes \"absent\" from \"present and empty\" on several of these, and a\n // `defaultValue: null` is a real default that says NULL.\n if (def.defaultValue !== undefined) out.defaultValue = def.defaultValue;\n if (def.defaultRandom === true) out.defaultRandom = true;\n if (def.defaultNow === true) out.defaultNow = true;\n if (def.renamedFrom !== undefined) out.renamedFrom = def.renamedFrom;\n // Go'daki schema.ColumnJSON'un aynası. `omitempty` karşılığı: yalnız TRUE ise yazılır,\n // böylece işaretsiz bir şemanın JSON'u bu alandan önceki hâliyle byte-eş kalır.\n if (def.ignored === true) out.ignored = true;\n // OWNERSHIP HAS TO CROSS THE WIRE, because the gate that enforces it is on the\n // other side. `ownedByUser()` sets `owns` on the column, and Go's\n // `validateOwnership` reads `ColumnJSON.Owns` to refuse a table that declares\n // two owners — but nothing was carrying the flag between them.\n //\n // Measured on the live cluster: a table with TWO `ownedByUser()` columns\n // pushed clean and both foreign keys landed on `auth.users` ON DELETE CASCADE.\n // The rule existed in the DSL and in the generator; the wire in between said\n // nothing, so the generator saw ZERO ownership columns and had nothing to\n // refuse. A flag with a reader and no writer is a dead wire.\n if (def.owns === true) out.owns = true;\n if (def.references !== undefined) {\n out.references = { table: def.references.table, column: def.references.column };\n }\n if (def.onDeleteAction !== undefined) out.onDeleteAction = def.onDeleteAction;\n // Yalnız `false` taşınıyor: \"bildirilmedi\" ile \"açık\" aynı şey ve wire'a\n // yazmak bildirmeyen her kolonu diff'te değişmiş gösterirdi.\n if (def.index === false) out.index = false;\n if (def.counter === true) out.counter = true;\n if (def.enumName !== undefined) out.enumName = def.enumName;\n if (def.enumValues !== undefined) out.enumValues = [...def.enumValues];\n if (def.unique === true) out.unique = true;\n if (def.dimensions !== undefined) out.dimensions = def.dimensions;\n return out;\n}\n\nfunction policyToJSON(policy: PolicyDef): PolicyJSON {\n return {\n name: policy.name,\n command: policy.command ?? \"all\",\n roles: policy.roles ? [...policy.roles] : [],\n // null rather than omitted: a policy with no USING clause is a different\n // thing from one whose clause the emitter forgot, and Go reads the\n // difference.\n using: policy.using ?? null,\n withCheck: policy.withCheck ?? null,\n permissive: policy.permissive !== false,\n };\n}\n\n/** C-4 wire şekli — Go'nun SearchJSON'ıyla ALAN ADI sözleşmesi (C-5).\n * `mode`/`chunks` yalnız yeni-biçim chunk-modunda emit edilir (D-010);\n * satır-modu ve eski biçim bayt-aynı kalır (NFR-B1). */\nexport interface SearchJSON {\n text?: { columns: string[] };\n vector?: {\n column?: string;\n metric: string;\n embed?: { provider: string; model: string; from: string[]; apiKeyName?: string; dimensions?: number; baseURL?: string };\n staleness?: \"null\" | \"keep\";\n mode?: \"row\" | \"chunks\";\n chunks?: { sizeChars?: number; overlapChars?: number };\n }[];\n /** FR-026: sorgu-yeniden-yazımı haritası — beyan yoksa OMIT (NFR-B1). */\n synonyms?: Record<string, string[]>;\n /** C-1: sonuç yeniden-sıralama beyanı — beyan yoksa OMIT. */\n /** FR-029: geçerlilik türevleri — beyan yoksa OMIT. */\n validity?: boolean;\n}\n\n/** T020 (C-1): iki biçimin de üst-düzey ortak alanları — beyan yoksa OMIT,\n * boş synonyms haritası da OMIT (NFR-B1 baytları kımıldamaz). */\nfunction commonSearchFields(search: SearchDecl, out: SearchJSON): void {\n if (search.synonyms !== undefined && Object.keys(search.synonyms).length > 0) {\n out.synonyms = Object.fromEntries(\n Object.entries(search.synonyms).map(([word, alts]) => [word, [...alts]]),\n );\n }\n if (search.validity === true) out.validity = true;\n}\n\n/** Beyanı normalize eder: vector her zaman DİZİ, metric her zaman dolu (vars. cosine),\n * authoring'deki `from`/`model` wire'da `embed` altında toplanır. Alan yoksa OMIT —\n * search'süz şema bayt-aynı kalır (NFR-006). */\nfunction searchToJSON(search: SearchDecl, vectorColumn: string | undefined): SearchJSON {\n if (search.from !== undefined && search.model !== undefined) {\n // YENİ biçim (D-007): from tek listedir — FTS'i de embed'i de besler.\n // Mod ŞEMADAN türer (D-010): tabloda vector kolonu varsa satır-modu\n // (column yazılır, mode OMIT — eski davranışla aynı wire), yoksa\n // chunk-modu (mode:\"chunks\", column yok — vektörler türev tabloda).\n const out: SearchJSON = {};\n const textCols =\n search.text === false ? undefined : Array.isArray(search.text) && search.text.length > 0 ? search.text : search.from;\n if (textCols !== undefined) out.text = { columns: [...textCols] };\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: search.metric ?? \"cosine\" };\n if (vectorColumn !== undefined) v.column = vectorColumn;\n v.embed = {\n provider: search.model.provider,\n model: search.model.model,\n from: [...search.from],\n ...(search.model.apiKeyName !== undefined ? { apiKeyName: search.model.apiKeyName } : {}),\n ...(search.model.dimensions !== undefined ? { dimensions: search.model.dimensions } : {}),\n ...(search.model.baseURL !== undefined ? { baseURL: search.model.baseURL } : {}),\n };\n if (search.staleness !== undefined) v.staleness = search.staleness;\n if (vectorColumn === undefined) {\n v.mode = \"chunks\";\n if (search.chunks !== undefined) {\n const c: NonNullable<typeof v.chunks> = {};\n if (search.chunks.size !== undefined && search.chunks.size > 0) c.sizeChars = search.chunks.size;\n if (search.chunks.overlap !== undefined && search.chunks.overlap > 0) c.overlapChars = search.chunks.overlap;\n if (Object.keys(c).length > 0) v.chunks = c;\n }\n }\n out.vector = [v];\n commonSearchFields(search, out);\n return out;\n }\n const out: SearchJSON = {};\n // Eski biçimde text yalnız dizi olabilir (boolean'ı defineSchema zaten\n // reddediyor); Array.isArray hem tipi daraltır hem o sözleşmeyi belgeler.\n if (Array.isArray(search.text) && search.text.length > 0) out.text = { columns: [...search.text] };\n const legs = search.vector === undefined ? []\n : Array.isArray(search.vector) ? search.vector : [search.vector];\n if (legs.length > 0) {\n out.vector = legs.map((leg) => {\n const v: NonNullable<SearchJSON[\"vector\"]>[number] = { metric: leg.metric ?? \"cosine\" };\n if (leg.column !== undefined) v.column = leg.column;\n if (leg.staleness !== undefined) v.staleness = leg.staleness;\n if (leg.model !== undefined) {\n v.embed = {\n provider: leg.model.provider,\n model: leg.model.model,\n from: [...(leg.from ?? [])],\n ...(leg.model.apiKeyName !== undefined ? { apiKeyName: leg.model.apiKeyName } : {}),\n ...(leg.model.dimensions !== undefined ? { dimensions: leg.model.dimensions } : {}),\n ...(leg.model.baseURL !== undefined ? { baseURL: leg.model.baseURL } : {}),\n };\n }\n return v;\n });\n }\n commonSearchFields(search, out);\n return out;\n}\n\nfunction memoryToJSON(m: MemoryDecl): MemoryJSON {\n return {\n from: [...m.from],\n into: m.into,\n ...(m.subject !== undefined ? { subject: m.subject } : {}),\n extract: { provider: m.extract.provider, model: m.extract.model },\n };\n}\n\nfunction tableToJSON(table: TableDef, schemaName: string): TableJSON {\n const columns: Record<string, ColumnJSON> = {};\n for (const [name, column] of Object.entries(table.columns)) {\n columns[name] = columnToJSON(column);\n }\n\n const out: TableJSON = {\n name: table.name,\n schema: schemaName,\n columns,\n // Read, not re-derived. `defineSchema` already resolves the fail-closed\n // default (RLS on unless the author wrote `rls: false`, and forced on by any\n // policy), and a second copy of a SECURITY default is exactly the thing that\n // drifts — the direction it drifted last time was \"expose everything\", and\n // the live proof was one user reading another's rows.\n rls: table.rls,\n // KOŞAN SÜRÜMÜN SÖZÜ TELE ÇIKAR — yoksa daralma kapısı onu göremez.\n // `ColumnJSON.ignored` ile aynı sözleşme: işaretlenmemişse alan YOK.\n ...(table.ignored === true ? { ignored: true } : {}),\n policies: (table.policies ?? []).map(policyToJSON),\n };\n\n if (table.primaryKey !== undefined && table.primaryKey.length > 0) {\n out.primaryKey = [...table.primaryKey];\n }\n if (table.unique !== undefined && table.unique.length > 0) {\n out.uniqueConstraints = table.unique.map((u) => ({ name: u.name, columns: [...u.columns] }));\n }\n if (table.raw !== undefined && table.raw.length > 0) {\n out.rawConstraints = table.raw.map((r) => ({ name: r.name, up: r.up }));\n }\n if (table.checks !== undefined && table.checks.length > 0) {\n out.checks = table.checks.map((c) => ({ name: c.name, expr: c.expr }));\n }\n if (table.indexes !== undefined && table.indexes.length > 0) {\n out.indexes = table.indexes.map((i) => {\n // `columns` expression-index'te YOKTUR (ikisi birbirinin alternatifi).\n // Boş dizi ile taşınır: Go tarafı `expression` doluysa onu kullanır.\n const ix: IndexJSON = { name: i.name, columns: i.columns ? [...i.columns] : [] };\n if (i.unique === true) ix.unique = true;\n if (i.where !== undefined) ix.where = i.where;\n if (i.expression !== undefined) ix.expression = i.expression;\n if (i.sort !== undefined) ix.sort = i.sort;\n if (i.nulls !== undefined) ix.nulls = i.nulls;\n if (i.include !== undefined) ix.include = [...i.include];\n return ix;\n });\n }\n if (table.dropConstraints !== undefined && table.dropConstraints.length > 0) {\n out.dropConstraints = [...table.dropConstraints];\n }\n if (table.foreignKeys !== undefined && table.foreignKeys.length > 0) {\n out.foreignKeys = table.foreignKeys.map((fk) => {\n const j: ForeignKeyJSON = {\n name: fk.name,\n columns: [...fk.columns],\n refTable: fk.refTable,\n refColumns: [...fk.refColumns],\n };\n if (fk.onUpdate !== undefined) j.onUpdate = fk.onUpdate;\n if (fk.onDelete !== undefined) j.onDelete = fk.onDelete;\n if (fk.match !== undefined) j.match = fk.match;\n return j;\n });\n }\n if (table.freeze !== undefined && table.freeze.length > 0) {\n out.freeze = table.freeze.map((f) => ({\n name: f.name,\n when: f.when,\n columns: [...f.columns],\n refTable: f.refTable,\n refColumns: [...f.refColumns],\n }));\n }\n if (table.guards !== undefined && table.guards.length > 0) {\n out.guards = table.guards.map((g) => ({\n name: g.name,\n event: g.event,\n ...(g.when !== undefined ? { when: g.when } : {}),\n ...(g.exists !== undefined ? { exists: g.exists } : {}),\n message: g.message,\n ...(g.detail !== undefined ? { detail: g.detail } : {}),\n ...(g.hint !== undefined ? { hint: g.hint } : {}),\n ...(g.column !== undefined ? { column: g.column } : {}),\n }));\n }\n if (table.backfills !== undefined && table.backfills.length > 0) {\n out.backfills = table.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n // Sıfır değerde YAZILMAZ: `appendOnly: false` ile \"bildirilmemiş\" wire'da\n // ayırt edilemez olmalı, yoksa her eski şema diff'te değişmiş görünür.\n if (table.appendOnly === true) out.appendOnly = true;\n if (table.search !== undefined) {\n // D-010 mod kararının tek girdisi: tabloda dimensions'lı (vector) kolon\n // adı. Birden çoksa ilkini yazmak YANLIŞ olurdu — o durum eski biçimin\n // işidir ve yeni biçim + çoklu vector kolonu apply'da reddedilir.\n const vectorColumn = Object.entries(columns).find(([, c]) => c.dimensions !== undefined)?.[0];\n const sj = searchToJSON(table.search, vectorColumn);\n if (sj.text !== undefined || sj.vector !== undefined) out.search = sj;\n }\n if (table.memory !== undefined) {\n out.memory = memoryToJSON(table.memory);\n }\n return out;\n}\n\n/**\n * The key a table answers to in `SchemaJSON.tables`.\n *\n * A public table is BARE, anything else is schema-qualified. This is not a new\n * convention: `RefJSON.Table` already carries `auth.users`, and introspection\n * already returns a public referent bare and a non-public one qualified. Adding\n * a second key space would make two interpreters of the same database.\n */\nexport function qualifiedTableKey(schemaName: string, tableName: string): string {\n // An ABSENT schema means public, exactly as Go's `isPublicSchema` says. This\n // branch used to be missing here and present in the engine's private copy, so\n // the two writers of one rule answered DIFFERENTLY for `\"\"`: one qualified it\n // into a schema literally named the empty string, the other left it bare.\n return schemaName === \"\" || schemaName === \"public\" ? tableName : `${schemaName}.${tableName}`;\n}\n\n/**\n * Serialize declared schemas into the JSON the deploy applies.\n *\n * Takes every schema the project declares — one file per schema — because a\n * cross-schema foreign key can only be checked when both ends are in hand.\n */\nexport function toSchemaJSON(schemas: readonly SchemaDef[]): SchemaJSON {\n const tables: Record<string, TableJSON> = {};\n const extensions: string[] = [];\n const meta: SchemaMetaJSON[] = [];\n const seen = new Set<string>();\n for (const schema of schemas) {\n if (seen.has(schema.name)) {\n throw new Error(`two schemas declare the name \"${schema.name}\" — schema names must be unique`);\n }\n seen.add(schema.name);\n for (const table of Object.values(schema.tables)) {\n const json = tableToJSON(table, schema.name);\n tables[qualifiedTableKey(schema.name, json.name)] = json;\n }\n extensions.push(...(schema.extensions ?? []));\n // The schema list travels because the flag has nowhere else to live: without\n // it /v1/db cannot know which schemas are reachable over HTTP, and nothing\n // downstream can read the DECLARED schema set that introspection needs.\n meta.push({ name: schema.name, exposed: schema.exposed });\n }\n return { tables, extensions: [...new Set(extensions)], schemas: meta };\n}\n","/**\n * http.ts — the transport every module client speaks over.\n *\n * WHY IT IS HERE. This code, and the five clients built on it, spent their life\n * in `v2/runtime/internal/runtime/module-clients.js`: 1,768 lines of untyped\n * CommonJS that entered the SDK through an `@ts-expect-error` and left through\n * `unknown` casts. The interfaces those clients implement were always in this\n * package — only the implementations were outside it, where nothing checked one\n * against the other. Two defects came through that gap on 2026-08-15 (a type\n * that described a different server's columns; an accessor that was `undefined`\n * in a deployed handler), and both were green on each side alone.\n *\n * WHAT IT IS NOT. Nothing Bun-specific lives here. The transport is a `fetch`\n * the caller may supply, so this package stays runtime-agnostic and the process\n * that knows which runtime it is decides what to hand in.\n */\n\nimport type { PalbaseResult } from \"../endpoint.js\";\n\n/** Per-request options a module client may pass. */\nexport interface RequestOptions {\n /** JSON-serialised unless it is a string, a Uint8Array, a Blob or FormData. */\n body?: unknown;\n headers?: Record<string, string>;\n signal?: AbortSignal;\n}\n\n/**\n * What a module client is given. An INTERFACE rather than a class, because the\n * clients depend on this shape and not on the thing that implements it — which\n * is what lets a test drive a whole client without a server.\n */\nexport interface ModuleTransport {\n /** The platform's base URL, for the rare client that must build a URL. */\n readonly baseUrl: string;\n request<T = unknown>(\n method: string,\n path: string,\n options?: RequestOptions,\n ): Promise<PalbaseResult<T>>;\n}\n\nexport interface TransportConfig {\n baseUrl: string;\n apiKey: string;\n /**\n * The `fetch` to use. Omitted means the ambient one — resolved at CALL time,\n * never captured here: the egress fence replaces `globalThis.fetch` after the\n * clients are built, and a captured reference would keep calling the\n * un-fenced original.\n */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A module call that failed.\n *\n * `code` is the platform's own error code (`forbidden`, `not_found`, …) so a\n * caller can branch on it without matching message text.\n */\nexport class PalbaseModuleError extends Error {\n readonly code: string;\n readonly status: number;\n readonly details: Record<string, unknown>;\n\n constructor(code: string, message: string, status: number, details: Record<string, unknown> = {}) {\n super(message);\n this.name = \"PalbaseModuleError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function makeHttpClient(cfg: TransportConfig): ModuleTransport {\n async function request<T>(\n method: string,\n path: string,\n options: RequestOptions = {},\n ): Promise<PalbaseResult<T>> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...(options.headers ?? {}),\n };\n if (cfg.apiKey) headers[\"apikey\"] = cfg.apiKey;\n\n const init: RequestInit = { method, headers };\n if (options.body !== undefined) {\n if (typeof options.body === \"string\" || options.body instanceof Uint8Array) {\n init.body = options.body as RequestInit[\"body\"];\n } else if (typeof FormData !== \"undefined\" && options.body instanceof FormData) {\n // The platform writes Content-Type itself, WITH the multipart boundary.\n // Setting it here omits the boundary, and the server then parses zero\n // parts from a request that looks perfectly well formed.\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else if (typeof Blob !== \"undefined\" && options.body instanceof Blob) {\n delete headers[\"Content-Type\"];\n init.body = options.body;\n } else {\n init.body = JSON.stringify(options.body);\n }\n }\n if (options.signal) init.signal = options.signal;\n\n // Resolved HERE, per call. See TransportConfig.fetchImpl.\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n\n let response: Response;\n try {\n response = await doFetch(`${cfg.baseUrl}${path}`, init);\n } catch (err) {\n // AN ENVELOPE, not an exception.\n //\n // This threw until 2026-08-15, and the throw made three separate claims\n // false at once:\n //\n // 1. The package's own rule — \"Response: { data, error }, no thrown API\n // errors\". Every client here is written to that contract.\n // 2. `Flags.get(key, default)`, whose documented behaviour is that the\n // default applies when the flag is absent AND when the service is\n // unreachable. It reads `resp.error !== null` to decide, and a throw\n // never reaches that branch: measured, `get(\"beta\", \"DEFAULT\")`\n // raised `connect ECONNREFUSED` instead of answering \"DEFAULT\". The\n // test that was supposed to cover it handed the client a hand-made\n // error envelope — a shape this code could not produce.\n // 3. Consistency with the Realtime client, which already envelopes a\n // network failure so a handler that wrote a row does not lose it\n // because pubsub was down.\n //\n // A caller destructuring { data, error } and checking `error` was being\n // defeated by an exception: the defensive code existed and did not help,\n // which is the worst kind of surprise to leave in a package.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"Network request failed\",\n 0,\n ),\n status: 0,\n };\n }\n\n const contentType = response.headers.get(\"Content-Type\") ?? \"\";\n let parsed: unknown = null;\n if (method !== \"HEAD\" && contentType.includes(\"json\")) {\n parsed = await response.json().catch(() => null);\n } else if (method !== \"HEAD\" && contentType.startsWith(\"image/\")) {\n // QR codes and the like: hand back bytes the caller can write or forward.\n parsed = new Uint8Array(await response.arrayBuffer());\n } else if (method !== \"HEAD\" && response.body) {\n // A non-JSON error still says something; \"request failed\" says nothing.\n parsed = await response.text().catch(() => null);\n }\n\n if (!response.ok) {\n const body = (parsed && typeof parsed === \"object\" ? parsed : {}) as Record<string, unknown>;\n const code = typeof body.error === \"string\" && body.error ? body.error : \"unknown_error\";\n const message =\n (typeof body.error_description === \"string\" && body.error_description) ||\n response.statusText ||\n \"request failed\";\n return {\n data: null,\n error: new PalbaseModuleError(code, message, response.status, body),\n status: response.status,\n };\n }\n\n return { data: parsed as T, error: null, status: response.status };\n }\n\n return { baseUrl: cfg.baseUrl, request };\n}\n","/**\n * auth.ts — the role-assignment half of auth, as a backend handler reaches it.\n *\n * WHAT THIS IS NOT. It is not the client SDK's `auth` (sign-up, sign-in, MFA,\n * device attestation): those are a person acting on their OWN account, they run\n * in the app, and a server has no business holding them. This is the operator\n * verb — \"make this user an agent\" — and it exists because the product itself is\n * often where the promotion happens: a supervisor taps a button in the tenant's\n * own app, and the tenant's handler has to be able to write the assignment.\n *\n * THE CREDENTIAL IS THE POINT. `/admin/users/{uid}/roles/{role}` answers 403 to\n * anon and to `authenticated` alike (FR-013), so these calls ride the transport\n * built with the SERVICE-ROLE key. A backend is the only place that key exists;\n * putting this surface anywhere a client SDK could reach it would let an end\n * user grant themselves the permission the rest of the feature is about.\n *\n * IT THROWS, and the rest of this package envelopes. That is a deliberate split\n * and it comes from the SHAPE OF THE ANSWER: `assignRole` returns nothing, so a\n * failure it did not throw for would be indistinguishable from a write that\n * happened. The named `RoleNotDefined` is the one refusal a caller can act on —\n * the role names live in git, so a miss is a typo, not a runtime condition —\n * and every other refusal arrives as the transport's own `PalbaseModuleError`\n * with the platform's code on it.\n */\n\nimport type { PalbaseAuthAdminClient } from \"../clients.js\";\n\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * The named refusal: this stack declares no role by that name.\n *\n * A role's DEFINITION is committed (`palbase roles`, lowered into the generated\n * client as an enum), so a name that misses is a typo in code rather than a\n * state a retry could fix. It carries the name it was asked for, because the\n * message alone would make a handler parse text to log which one failed.\n */\nexport class RoleNotDefined extends Error {\n readonly role: string;\n\n constructor(role: string, message?: string) {\n super(message ?? `No role named \"${role}\" is defined for this stack`);\n this.name = \"RoleNotDefined\";\n this.role = role;\n }\n}\n\n/** The wire body all three routes answer with: the assignment's RESULT. */\ninterface UserRolesBody {\n roles?: string[];\n}\n\n/**\n * Raise whatever the platform refused with.\n *\n * `role_not_defined` becomes the named class; everything else keeps the\n * transport's error, which already carries the platform's code and status, so a\n * caller can branch on `err.code` without matching message text.\n */\nfunction refuse(error: { message?: string; code?: string }, role: string): never {\n if (error.code === \"role_not_defined\") throw new RoleNotDefined(role, error.message);\n if (error instanceof PalbaseModuleError) throw error;\n throw new PalbaseModuleError(error.code ?? \"unknown_error\", error.message ?? \"request failed\", 0);\n}\n\n/** `/admin/users/{uid}/roles[/{role}]`, with both ids escaped: an id that\n * carried a slash would otherwise reach a different route entirely. */\nfunction rolesPath(userId: string, role?: string): string {\n const base = `/admin/users/${encodeURIComponent(userId)}/roles`;\n return role === undefined ? base : `${base}/${encodeURIComponent(role)}`;\n}\n\nexport function buildAuthClient(http: ModuleTransport): PalbaseAuthAdminClient {\n return {\n async assignRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"PUT\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async revokeRole(userId: string, role: string): Promise<void> {\n const { error } = await http.request<UserRolesBody>(\"DELETE\", rolesPath(userId, role));\n if (error) refuse(error, role);\n },\n\n async rolesOf(userId: string): Promise<string[]> {\n const { data, error } = await http.request<UserRolesBody>(\"GET\", rolesPath(userId));\n // A FAILED READ IS NOT AN EMPTY LIST. Answering `[]` here would tell a\n // handler that a user holds nothing when the truth is that nobody could\n // say — and the handler would then deny them everything they hold.\n if (error) refuse(error, \"\");\n return data?.roles ?? [];\n },\n };\n}\n","/**\n * documents.ts — the Documents client, Firestore-shaped.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:705-773` (plus\n * the `buildDocumentRef` / `buildCollectionRef` helpers above it) with its\n * behaviour intact: the same methods, the same paths, the same bodies. What\n * changed is that it now sits beside the interface it implements, so a drift\n * between the two is a compile error rather than a runtime surprise.\n */\n\nimport type {\n PalbaseCollectionRef,\n PalbaseDocsClient,\n PalbaseDocumentRef,\n PalbaseDocumentSnapshot,\n PalbaseQuerySnapshot,\n PalbaseResult,\n PalbaseWhereOperator,\n} from \"../endpoint.js\";\nimport { PalbaseModuleError, type ModuleTransport } from \"./http.js\";\n\n/**\n * A path segment the platform will accept.\n *\n * Validated HERE rather than at the server, because a rejected segment is a\n * programming mistake and the useful moment to hear about it is the call.\n */\nconst SEGMENT_RE = /^[A-Za-z0-9_-]+$/;\n\nfunction validateSegment(segment: string, label: string): void {\n if (!SEGMENT_RE.test(segment)) {\n throw new Error(`Invalid ${label}: \"${segment}\". Must match ${SEGMENT_RE.source}`);\n }\n}\n\ninterface WhereClause {\n field: string;\n op: PalbaseWhereOperator;\n value: unknown;\n}\ninterface OrderClause {\n field: string;\n direction: \"asc\" | \"desc\";\n}\ninterface ChainState {\n where: WhereClause[];\n orderBy: OrderClause[];\n limit?: number;\n}\n\ninterface RawDocument {\n id?: string;\n exists?: boolean;\n data?: Record<string, unknown>;\n}\n\nfunction buildDocumentRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n): PalbaseDocumentRef<T> {\n return {\n path,\n async set(data: T) {\n return http.request<void>(\"PUT\", `/v1/docs/${path}`, { body: data });\n },\n async get(): Promise<PalbaseResult<PalbaseDocumentSnapshot<T>>> {\n const response = await http.request<RawDocument>(\"GET\", `/v1/docs/${path}`);\n if (response.error) return { data: null, error: response.error, status: response.status };\n const raw = response.data ?? {};\n const exists = raw.exists !== undefined ? raw.exists : Boolean(raw.data || raw.id);\n const segments = path.split(\"/\");\n const id = raw.id || segments[segments.length - 1] || \"\";\n return {\n data: { id, exists, data: () => raw.data as T | undefined, ref: { path } },\n error: null,\n status: response.status,\n };\n },\n async update(data: Partial<T>) {\n return http.request<void>(\"PATCH\", `/v1/docs/${path}`, { body: data });\n },\n async delete() {\n return http.request<void>(\"DELETE\", `/v1/docs/${path}`);\n },\n collection<C extends Record<string, unknown>>(name: string): PalbaseCollectionRef<C> {\n validateSegment(name, \"subcollection name\");\n return buildCollectionRef<C>(http, `${path}/${name}`);\n },\n };\n}\n\nfunction buildCollectionRef<T extends Record<string, unknown>>(\n http: ModuleTransport,\n path: string,\n state: ChainState = { where: [], orderBy: [] },\n): PalbaseCollectionRef<T> {\n function snapshot(doc: { id: string; data: Record<string, unknown> }): PalbaseDocumentSnapshot<T> {\n return {\n id: doc.id,\n exists: true,\n data: () => doc.data as T,\n ref: { path: `${path}/${doc.id}` },\n };\n }\n\n function querySnapshot(docs: PalbaseDocumentSnapshot<T>[]): PalbaseQuerySnapshot<T> {\n return {\n docs,\n empty: docs.length === 0,\n size: docs.length,\n docChanges: () => docs.map((doc) => ({ type: \"added\" as const, doc })),\n };\n }\n\n return {\n path,\n\n doc(id: string) {\n validateSegment(id, \"document ID\");\n return buildDocumentRef<T>(http, `${path}/${id}`);\n },\n\n async add(data: T) {\n const resp = await http.request<{ id: string }>(\"POST\", `/v1/docs/${path}`, { body: data });\n if (resp.error || !resp.data) {\n return { data: null, error: resp.error, status: resp.status };\n }\n return {\n data: buildDocumentRef<T>(http, `${path}/${resp.data.id}`),\n error: null,\n status: resp.status,\n };\n },\n\n // Each narrowing returns a NEW ref. A builder that mutated in place would\n // leak one caller's filter into a query another caller had already held.\n where(field: string, op: PalbaseWhereOperator, value: unknown) {\n return buildCollectionRef<T>(http, path, {\n ...state,\n where: [...state.where, { field, op, value }],\n });\n },\n orderBy(field: string, direction: \"asc\" | \"desc\" = \"asc\") {\n return buildCollectionRef<T>(http, path, {\n ...state,\n orderBy: [...state.orderBy, { field, direction }],\n });\n },\n limit(n: number) {\n return buildCollectionRef<T>(http, path, { ...state, limit: n });\n },\n\n async get(): Promise<PalbaseResult<PalbaseQuerySnapshot<T>>> {\n const narrowed =\n state.where.length > 0 || state.orderBy.length > 0 || state.limit !== undefined;\n\n const resp = narrowed\n ? await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"POST\",\n `/v1/docs/${path}/query`,\n { body: queryBody(state) },\n )\n : await http.request<{ documents?: { id: string; data: Record<string, unknown> }[] }>(\n \"GET\",\n `/v1/docs/${path}`,\n );\n\n if (resp.error) return { data: null, error: resp.error, status: resp.status };\n const docs = (resp.data?.documents ?? []).map(snapshot);\n return { data: querySnapshot(docs), error: null, status: resp.status };\n },\n };\n}\n\nfunction queryBody(state: ChainState): Record<string, unknown> {\n const body: Record<string, unknown> = {};\n if (state.where.length > 0) {\n body.where = state.where.map((w) => ({ field: w.field, op: w.op, value: w.value }));\n }\n if (state.orderBy.length > 0) {\n body.orderBy = state.orderBy.map((o) => ({ field: o.field, direction: o.direction }));\n }\n if (state.limit !== undefined) body.limit = state.limit;\n return body;\n}\n\n/** The largest batch the platform accepts in one call. */\nconst MAX_BATCH = 500;\n\nexport function buildDocumentsClient(http: ModuleTransport): PalbaseDocsClient {\n return {\n /**\n * `Documents.doc(\"users/alice\")` — segments are collection/documentId PAIRS,\n * so an odd count addresses a COLLECTION and is refused. Accepting it would\n * write a document whose id happens to be a collection's name.\n */\n doc<T extends Record<string, unknown>>(path: string): PalbaseDocumentRef<T> {\n const segments = String(path)\n .split(\"/\")\n .filter((s) => s.length > 0);\n if (segments.length === 0 || segments.length % 2 !== 0) {\n throw new Error(\n `Invalid document path: \"${path}\". Expected collection/documentId pairs, got ${segments.length} segment(s).`,\n );\n }\n segments.forEach((s, i) => validateSegment(s, i % 2 === 0 ? \"collection name\" : \"document ID\"));\n return buildDocumentRef<T>(http, segments.join(\"/\"));\n },\n\n collection<T extends Record<string, unknown>>(name: string): PalbaseCollectionRef<T> {\n validateSegment(name, \"collection name\");\n return buildCollectionRef<T>(http, name);\n },\n\n async batch(operations) {\n // Refused HERE, without a request: the server would refuse it too, and\n // spending a round trip to be told so is the caller's time.\n if (operations.length > MAX_BATCH) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"batch_too_large\",\n `Batch size ${operations.length} exceeds maximum of ${MAX_BATCH}`,\n 400,\n ),\n status: 400,\n };\n }\n if (operations.length === 0) return { data: null, error: null, status: 200 };\n\n return http.request<void>(\"POST\", \"/v1/docs/batch\", {\n body: operations.map((op) => ({ op: op.op, path: op.ref.path, data: op.data })),\n });\n },\n };\n}\n","/**\n * flags.ts — feature flags, resolved for the request's own user.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:941-1164`.\n *\n * THE ONE RULE WORTH STATING: the user a flag resolves for comes from the\n * SDK's own request scope, never from anything the caller passed on the wire.\n * A handler can pass an explicit context (including an explicit `null` for a\n * deliberate anonymous read) and that wins — but the default is the person the\n * request is being served for, which is what makes `Flags.get(\"x\")` mean the\n * obvious thing inside a handler.\n *\n * Writes mirror the Database model: `setOverride` writes for the CURRENT user\n * and needs no admin power; cross-user writes live behind `asService()` so they\n * are explicit and greppable.\n */\n\nimport type {\n PalbaseBatchOverrideOperation,\n PalbaseFlagContext,\n PalbaseFlagValue,\n PalbaseFlagsClient,\n PalbaseFlagsServiceClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\nconst FLAG_NAME_RE = /^[A-Za-z0-9_.-]+$/;\n\nexport interface FlagsConfig {\n /** The request's user, read from the SDK's ALS box — never from the caller. */\n getCurrentUserId: () => string | null;\n}\n\nfunction assertFlagName(flagName: string): void {\n if (!FLAG_NAME_RE.test(flagName)) {\n throw new Error(`Invalid flag name: \"${flagName}\". Flag names must match ${FLAG_NAME_RE.source}`);\n }\n}\n\n/** A truthy flag value, in the platform's own terms. */\nfunction flagEnabled(value: unknown): boolean {\n if (typeof value === \"boolean\") return value;\n return value != null && value !== 0 && value !== \"\";\n}\n\nfunction flagVariant(value: unknown): { name: string } | null {\n return typeof value === \"string\" ? { name: value } : null;\n}\n\n/**\n * A context object carries `userId`/`properties`; anything else passed in that\n * position is a DEFAULT VALUE. This is what tells `Flags.get(key, ctx)` apart\n * from `Flags.get(key, someObjectDefault)`.\n */\nfunction isContextObject(v: unknown): v is PalbaseFlagContext {\n return (\n v !== null && typeof v === \"object\" && !Array.isArray(v) && (\"userId\" in v || \"properties\" in v)\n );\n}\n\ninterface MergedSnapshot {\n values?: Record<string, PalbaseFlagValue>;\n}\n\nexport function buildFlagsClient(http: ModuleTransport, cfg: FlagsConfig): PalbaseFlagsClient {\n /**\n * The effective user for a call. An explicit `userId` in the context wins —\n * INCLUDING an explicit `null`, which is a deliberate anonymous read.\n */\n function resolveUserId(context?: PalbaseFlagContext): string | null | undefined {\n if (context && \"userId\" in context) return context.userId ?? null;\n return cfg.getCurrentUserId() || undefined;\n }\n\n function mergedPath(context?: PalbaseFlagContext): string {\n const uid = resolveUserId(context);\n return uid ? `/v1/user-flags/users/${encodeURIComponent(uid)}` : \"/v1/user-flags\";\n }\n\n function fetchMerged(context?: PalbaseFlagContext) {\n return http.request<MergedSnapshot>(\"GET\", mergedPath(context));\n }\n\n const service: PalbaseFlagsServiceClient = {\n async setOverrideForUser(userId, key, value) {\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n async setOverridesForUser(userId, values) {\n return http.request(\"PUT\", `/v1/user-flags/users/${encodeURIComponent(userId)}`, {\n body: { values },\n });\n },\n async clearOverrideForUser(userId, key) {\n return http.request(\n \"DELETE\",\n `/v1/user-flags/users/${encodeURIComponent(userId)}/${encodeURIComponent(key)}`,\n );\n },\n async clearAllOverridesForUser(userId) {\n return http.request(\"DELETE\", `/v1/user-flags/users/${encodeURIComponent(userId)}`);\n },\n async batchSetOverrides(operations: ReadonlyArray<PalbaseBatchOverrideOperation>) {\n // The argument is camelCase, the wire is snake_case. Mapped here so a\n // stray `userId` never reaches the server — and an explicit `user_id`, if\n // a caller already wrote one, is preserved.\n const ops = (operations ?? []).map((op) => {\n const raw = op as unknown as { userId?: string; user_id?: string; values: unknown };\n return { user_id: raw.userId ?? raw.user_id, values: raw.values };\n });\n return http.request(\"POST\", \"/v1/user-flags/batch\", { body: { operations: ops } });\n },\n };\n\n return {\n async isEnabled(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagEnabled(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n async getVariant(flagName: string, context?: PalbaseFlagContext) {\n assertFlagName(flagName);\n const res = await fetchMerged(context);\n // A missing or non-string value is a NULL variant on a successful read;\n // errors and empty bodies pass through as null too, which is why this is\n // written out rather than mapped.\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n return { data: flagVariant(res.data.values?.[flagName]), error: null, status: res.status };\n },\n\n /**\n * `get(key)` · `get(key, default)` · `get(key, default, ctx)` · `get(key, ctx)`.\n *\n * The default is substituted when the flag is ABSENT or when the flags\n * service is unreachable — a product that hides a feature because a lookup\n * timed out is behaving correctly; one that crashes is not.\n */\n async get(\n flagName: string,\n defaultOrContext?: PalbaseFlagValue | PalbaseFlagContext,\n maybeContext?: PalbaseFlagContext,\n ): Promise<PalbaseResult<PalbaseFlagValue>> {\n assertFlagName(flagName);\n\n let defaultValue: PalbaseFlagValue | undefined;\n let context: PalbaseFlagContext | undefined;\n let hasDefault = false;\n if (maybeContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n context = maybeContext;\n } else if (isContextObject(defaultOrContext)) {\n context = defaultOrContext;\n } else if (defaultOrContext !== undefined) {\n defaultValue = defaultOrContext as PalbaseFlagValue;\n hasDefault = true;\n }\n\n const resp = await fetchMerged(context);\n if (resp.error !== null) {\n if (hasDefault) return { data: defaultValue ?? null, error: null, status: resp.status };\n return { data: null, error: resp.error, status: resp.status };\n }\n const values = resp.data?.values ?? {};\n const value = values[flagName];\n // An absent key on a SUCCESSFUL read is not an error.\n if (value === undefined) {\n return { data: hasDefault ? (defaultValue ?? null) : null, error: null, status: resp.status };\n }\n return { data: value, error: null, status: resp.status };\n },\n\n async getAll(context?: PalbaseFlagContext) {\n const res = await fetchMerged(context);\n if (res.error || res.data == null) return { data: null, error: res.error, status: res.status };\n const values = res.data.values ?? {};\n return {\n data: Object.keys(values).map((name) => {\n const value = values[name];\n const flag: { name: string; enabled: boolean; variant?: { name: string } } = {\n name,\n enabled: flagEnabled(value),\n };\n if (typeof value === \"string\") flag.variant = { name: value };\n return flag;\n }),\n error: null,\n status: res.status,\n };\n },\n\n /**\n * Override a flag for the CURRENT request user.\n *\n * On an anonymous request this does not silently no-op and does not write\n * for nobody: it refuses and names the call that does cross-user writes.\n */\n async setOverride(key: string, value: PalbaseFlagValue) {\n const uid = cfg.getCurrentUserId();\n if (!uid) {\n return {\n data: null,\n error: {\n message:\n \"setOverride requires a signed-in user; use Flags.$asService().setOverrideForUser(userId, key, value) for cross-user writes\",\n },\n status: 400,\n };\n }\n return http.request(\n \"PUT\",\n `/v1/user-flags/users/${encodeURIComponent(uid)}/${encodeURIComponent(key)}`,\n { body: { value } },\n );\n },\n\n asService() {\n return service;\n },\n };\n}\n","/**\n * notifications.ts — push, email, SMS, verifications, inbox, preferences and\n * the two template surfaces.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:1180-1379`.\n *\n * The theme of this file is a NAME GAP: the SDK speaks camelCase and palnotify\n * speaks snake_case, and every place they meet is a place a field can be\n * dropped in silence. One of them cost a live afternoon — `email.send({ html })`\n * was forwarded verbatim, palnotify reads `html_body`, and the answer was a 400\n * about a field the caller had supplied. The mappings below are that lesson,\n * and they are now checked against the declared parameter types instead of\n * being hand-carried across a package boundary.\n */\n\nimport type {\n PalbaseEmailClient,\n PalbaseEmailTemplate,\n PalbaseEmailTemplatesClient,\n PalbaseInboxClient,\n PalbaseNotificationsClient,\n PalbasePreferencesClient,\n PalbasePushClient,\n PalbaseSMSTemplate,\n PalbaseSMSTemplatesClient,\n PalbaseSmsClient,\n PalbaseWhatsAppClient,\n PalbaseVerificationsClient,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** Re-map the data of a SUCCESSFUL envelope; errors pass through untouched. */\nfunction mapEnvelope<In, Out>(res: PalbaseResult<In>, map: (data: In) => Out): PalbaseResult<Out> {\n if (res.error !== null || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\ntype Wire = Record<string, unknown>;\n\nfunction toEmailTemplate(wire: Wire): PalbaseEmailTemplate {\n const view: PalbaseEmailTemplate = {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n subject: wire.subject as string,\n htmlBody: wire.html_body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n if (wire.text_body !== undefined) view.textBody = wire.text_body as string;\n return view;\n}\n\nfunction toSmsTemplate(wire: Wire): PalbaseSMSTemplate {\n return {\n id: wire.id as string,\n slug: wire.slug as string,\n locale: wire.locale as string,\n body: wire.body as string,\n variables: (wire.variables as string[]) ?? [],\n isDefault: wire.is_default as boolean,\n createdAt: wire.created_at as string,\n updatedAt: wire.updated_at as string,\n };\n}\n\nexport function buildNotificationsClient(http: ModuleTransport): PalbaseNotificationsClient {\n const push: PalbasePushClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/push\", { body: params });\n },\n };\n\n const email: PalbaseEmailClient = {\n async send(params) {\n // `html`/`text` are what the SDK declares; palnotify reads\n // `html_body`/`text_body`. Forwarding them verbatim answered 400 about a\n // field the caller HAD supplied — live on todoapp, 2026-07-30.\n const { templateSlug, html, text, ...rest } = params;\n const body: Record<string, unknown> = { ...rest };\n if (templateSlug !== undefined) body.template_slug = templateSlug;\n if (html !== undefined) body.html_body = html;\n if (text !== undefined) body.text_body = text;\n return http.request(\"POST\", \"/v1/notifications/email\", { body });\n },\n };\n\n const sms: PalbaseSmsClient = {\n async send(params) {\n const { templateSlug, ...rest } = params;\n const body = templateSlug !== undefined ? { ...rest, template_slug: templateSlug } : rest;\n return http.request(\"POST\", \"/v1/notifications/sms\", { body });\n },\n };\n\n const whatsapp: PalbaseWhatsAppClient = {\n async send(params) {\n const { templateSlug, userId, ...rest } = params;\n const body = {\n ...rest,\n ...(templateSlug === undefined ? {} : { template_slug: templateSlug }),\n ...(userId === undefined ? {} : { user_id: userId }),\n };\n return http.request(\"POST\", \"/v1/notifications/whatsapp\", { body });\n },\n async events(options = {}) {\n const query = options.limit === undefined ? \"\" : `?limit=${encodeURIComponent(String(options.limit))}`;\n return http.request(\"GET\", `/v1/notifications/whatsapp/events${query}`);\n },\n };\n\n // Phone verification (OTP). Separate from sms.send on purpose: there is no\n // body here — the provider generates the code and the message text itself.\n const verifications: PalbaseVerificationsClient = {\n async start(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications\", { body: params });\n },\n async check(params) {\n return http.request(\"POST\", \"/v1/notifications/verifications/check\", { body: params });\n },\n };\n\n const inbox: PalbaseInboxClient = {\n async send(params) {\n return http.request(\"POST\", \"/v1/notifications/inbox\", { body: params });\n },\n async list(options?: {\n cursor?: string;\n limit?: number;\n is_read?: boolean;\n category?: string;\n include_archived?: boolean;\n }) {\n const opts = options ?? {};\n const params = new URLSearchParams();\n if (opts.cursor) params.set(\"cursor\", opts.cursor);\n if (opts.limit !== undefined) params.set(\"limit\", String(opts.limit));\n if (opts.is_read !== undefined) params.set(\"is_read\", opts.is_read ? \"true\" : \"false\");\n if (opts.category) params.set(\"category\", opts.category);\n if (opts.include_archived) params.set(\"include_archived\", \"true\");\n const query = params.toString();\n return http.request(\"GET\", `/v1/notifications/inbox${query ? `?${query}` : \"\"}`);\n },\n async unreadCount() {\n return http.request(\"GET\", \"/v1/notifications/inbox/unread-count\");\n },\n async markRead(id: string) {\n return http.request(\"PATCH\", `/v1/notifications/inbox/${encodeURIComponent(id)}/read`);\n },\n async markAllRead() {\n return http.request(\"POST\", \"/v1/notifications/inbox/read-all\");\n },\n async archive(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/inbox/${encodeURIComponent(id)}`);\n },\n };\n\n const preferences: PalbasePreferencesClient = {\n async get() {\n return http.request(\"GET\", \"/v1/notifications/preferences\");\n },\n async update(params) {\n return http.request(\"PUT\", \"/v1/notifications/preferences\", { body: params });\n },\n };\n\n const emailTemplates: PalbaseEmailTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toEmailTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async create(input: { slug: string; subject: string; htmlBody: string; textBody?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {\n slug: input.slug,\n subject: input.subject,\n html_body: input.htmlBody,\n };\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/templates\", { body });\n return mapEnvelope(resp, toEmailTemplate);\n },\n async update(\n id: string,\n input: { subject?: string; htmlBody?: string; textBody?: string; variables?: string[] },\n ) {\n const body: Record<string, unknown> = {};\n if (input.subject !== undefined) body.subject = input.subject;\n if (input.htmlBody !== undefined) body.html_body = input.htmlBody;\n if (input.textBody !== undefined) body.text_body = input.textBody;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toEmailTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/templates/${encodeURIComponent(id)}`);\n },\n };\n\n const smsTemplates: PalbaseSMSTemplatesClient = {\n async list() {\n const resp = await http.request<Wire[]>(\"GET\", \"/v1/notifications/sms-templates\");\n return mapEnvelope(resp, (rows) => (rows ?? []).map(toSmsTemplate));\n },\n async get(id: string) {\n const resp = await http.request<Wire>(\n \"GET\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async create(input: { slug: string; body: string; variables?: string[] }) {\n const body: Record<string, unknown> = { slug: input.slug, body: input.body };\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\"POST\", \"/v1/notifications/sms-templates\", { body });\n return mapEnvelope(resp, toSmsTemplate);\n },\n async update(id: string, input: { body?: string; variables?: string[] }) {\n const body: Record<string, unknown> = {};\n if (input.body !== undefined) body.body = input.body;\n if (input.variables !== undefined) body.variables = input.variables;\n const resp = await http.request<Wire>(\n \"PUT\",\n `/v1/notifications/sms-templates/${encodeURIComponent(id)}`,\n { body },\n );\n return mapEnvelope(resp, toSmsTemplate);\n },\n async delete(id: string) {\n return http.request(\"DELETE\", `/v1/notifications/sms-templates/${encodeURIComponent(id)}`);\n },\n };\n\n return {\n push,\n email,\n sms,\n whatsapp,\n verifications,\n inbox,\n preferences,\n templates: { email: emailTemplates, sms: smsTemplates },\n async registerDevice(params) {\n return http.request(\"POST\", \"/v1/notifications/devices\", { body: params });\n },\n async unregisterDevice(deviceId: string) {\n return http.request(\"DELETE\", `/v1/notifications/devices/${encodeURIComponent(deviceId)}`);\n },\n };\n}\n","/**\n * realtime.ts — broadcast, and only broadcast.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:811-883`.\n *\n * There is no `subscribe()` here, deliberately: a backend handler answers one\n * request and ends, so there is no honest place to hold a long-lived socket.\n * Subscription lives in the client SDKs; this side pushes.\n *\n * The V1 host/executor branch is GONE. It existed so an isolate could delegate\n * the secret-bearing token mint to a host that held the credential — and the\n * isolate was removed on 2026-08-14. A single-tenant process has nobody to hide\n * its own tenant's key from.\n */\n\nimport { createHmac } from \"node:crypto\";\n\nimport type { PalbaseRealtimeClient } from \"../clients.js\";\nimport { PalbaseModuleError } from \"./http.js\";\n\nexport interface RealtimeConfig {\n baseUrl: string;\n /**\n * The shared Realtime API secret. Empty means realtime is not provisioned for\n * this environment, and broadcast says so by name rather than failing oddly.\n */\n apiJwtSecret: string;\n /** Resolved at CALL time — see the note in http.ts. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * A short-lived HS256 token Realtime's broadcast pipeline accepts.\n *\n * It needs a valid signature and a future `exp`, nothing more — this is a\n * service-to-service hop inside the stack, not a user session.\n */\nfunction mintToken(secret: string): string {\n const now = Math.floor(Date.now() / 1000);\n const header = Buffer.from(JSON.stringify({ alg: \"HS256\", typ: \"JWT\" })).toString(\"base64url\");\n const payload = Buffer.from(\n JSON.stringify({ iss: \"backend-runtime\", role: \"service_role\", iat: now, exp: now + 60 }),\n ).toString(\"base64url\");\n const sig = createHmac(\"sha256\", secret).update(`${header}.${payload}`).digest(\"base64url\");\n return `${header}.${payload}.${sig}`;\n}\n\nexport function buildRealtimeClient(cfg: RealtimeConfig): PalbaseRealtimeClient {\n const url = `${cfg.baseUrl}/realtime/api/broadcast`;\n const stateUrl = `${cfg.baseUrl}/realtime/api/state`;\n\n /** One state write or clear. Same credential, same fire-and-forget contract\n * as broadcast: a handler that wrote a row must not lose it because the\n * pubsub layer was unreachable. */\n async function writeState(\n topic: string,\n key: string,\n value: Record<string, unknown> | undefined,\n del: boolean,\n ) {\n if (typeof topic !== \"string\" || topic.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"topic must be a non-empty string\", 400),\n };\n }\n if (typeof key !== \"string\" || key.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"key must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.state is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n const op = del ? { topic, key, del: true } : { topic, key, value: value ?? {} };\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(stateUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body: JSON.stringify({ ops: [op] }),\n });\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"state request failed\",\n 0,\n ),\n };\n }\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_state_failed\",\n `realtime state write returned ${response.status}${detail ? `: ${detail}` : \"\"}`,\n response.status,\n ),\n };\n }\n\n return {\n state: {\n /** Write one DURABLE entry on a channel's shared state.\n *\n * The difference from broadcast is WHO it reaches: a broadcast reaches\n * whoever is listening at that instant, while state is also handed to\n * whoever joins afterwards. \"This value is now X\" wants the second — a\n * client connecting a second later should not have to wait for the next\n * change to learn X. */\n set: (topic: string, key: string, value: Record<string, unknown>) =>\n writeState(topic, key, value, false),\n /** Remove one entry. */\n clear: (topic: string, key: string) => writeState(topic, key, undefined, true),\n },\n\n async broadcast(channel: string, event: string, payload?: Record<string, unknown>) {\n // Cheap argument checks first, locally: a bad call gets an answer without\n // spending a round trip to be told the obvious.\n if (typeof channel !== \"string\" || channel.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"channel must be a non-empty string\", 400),\n };\n }\n if (typeof event !== \"string\" || event.length === 0) {\n return {\n data: null,\n error: new PalbaseModuleError(\"invalid_argument\", \"event must be a non-empty string\", 400),\n };\n }\n if (!cfg.apiJwtSecret) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_unconfigured\",\n \"Realtime.broadcast is unavailable: realtime is not provisioned for this Environment \" +\n \"(PALBASE_REALTIME_API_JWT_SECRET unset).\",\n 503,\n ),\n };\n }\n\n let token: string;\n try {\n token = mintToken(cfg.apiJwtSecret);\n } catch (err) {\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_token_error\",\n err instanceof Error ? err.message : \"token mint failed\",\n 500,\n ),\n };\n }\n\n // The BARE sub-topic. Realtime prepends \"realtime:\" on delivery, and a\n // pre-prefixed topic double-prefixes and is silently dropped — proven live.\n const body = JSON.stringify({\n messages: [{ topic: channel, event, payload: payload ?? {}, private: false }],\n });\n\n const doFetch = cfg.fetchImpl ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", Authorization: `Bearer ${token}` },\n body,\n });\n } catch (err) {\n // FIRE AND FORGET: a handler that wrote a row and then broadcast must\n // not lose the row because the pubsub layer was unreachable. This is the\n // one client that answers with an envelope on a network failure rather\n // than throwing, and it is why.\n return {\n data: null,\n error: new PalbaseModuleError(\n \"network_error\",\n err instanceof Error ? err.message : \"broadcast request failed\",\n 0,\n ),\n };\n }\n\n if (response.status === 202 || response.status === 200) {\n return { data: undefined, error: null };\n }\n\n const detail = await response.text().catch(() => \"\");\n return {\n data: null,\n error: new PalbaseModuleError(\n \"realtime_broadcast_failed\",\n `broadcast returned ${response.status}: ${detail.slice(0, 200)}`,\n response.status,\n ),\n };\n },\n };\n}\n","/**\n * storage.ts — the Storage client.\n *\n * Moved in from `v2/runtime/internal/runtime/module-clients.js:474-589`. That\n * code addressed the native Supabase Storage wire under `/storage/v1` until\n * 2026-08-15, when it was repointed at this stack's own module — measured\n * against the live stack, where the old path answers 404 and the new one 200.\n * It arrives here so the SHAPE it returns and the type that declares that shape\n * are checked against each other: they were not, and the type spent a major\n * version describing another server's columns.\n */\n\nimport type {\n PalbaseBucketClient,\n PalbaseFileObject,\n PalbaseListOptions,\n PalbaseSignedUrlResponse,\n PalbaseStorageClient,\n PalbaseUploadOptions,\n} from \"../clients.js\";\nimport type { PalbaseResult } from \"../endpoint.js\";\nimport type { ModuleTransport } from \"./http.js\";\n\n/** What the platform accepts as a bucket name (schema: `^[a-z][a-z0-9-]{1,62}$`). */\nconst BUCKET_NAME_RE = /^[a-zA-Z0-9_-]+$/;\n/** What the platform accepts as an object path. */\nconst STORAGE_PATH_RE = /^[a-zA-Z0-9_./-]+$/;\nconst STORAGE_TRAVERSAL_RE = /(?:^|\\/)\\.\\.(?:\\/|$)/;\n\n/**\n * Refused HERE, before any request.\n *\n * A traversing path is a programming mistake, and the useful moment to hear\n * about it is the call that made it — not a 400 three layers away.\n */\nfunction validateStoragePath(p: string): void {\n if (!STORAGE_PATH_RE.test(p) || STORAGE_TRAVERSAL_RE.test(p)) {\n throw new Error(\n `Invalid file path: \"${p}\". Paths must not contain traversal sequences and must match ${STORAGE_PATH_RE.source}`,\n );\n }\n}\n\n/**\n * The wire's own shape, mapped onto what this package declares.\n *\n * v2's storage answers in camelCase with the variants and the thumbhash already\n * in it, so this maps rather than translates. The snake_case unwrapping that\n * used to live here (`metadata.mimetype`, `bucket_id`, `created_at`) belonged to\n * a different server, and reading those names off this wire produced an object\n * whose size was 0 and whose content type was \"\".\n */\nfunction toFileObject(bucket: string, row: Record<string, unknown>): PalbaseFileObject {\n return {\n name: (row.path as string) ?? \"\",\n path: (row.path as string) ?? \"\",\n bucket: (row.bucket as string) ?? bucket,\n size: typeof row.size === \"number\" ? row.size : 0,\n contentType: (row.contentType as string) ?? \"\",\n checksum: (row.checksum as string) ?? \"\",\n width: row.width as number | undefined,\n height: row.height as number | undefined,\n thumbhash: row.thumbhash as string | undefined,\n variants: (row.variants as Record<string, string>) ?? {},\n };\n}\n\n/** Re-map the data of a SUCCESSFUL envelope; pass errors through untouched. */\nfunction mapResponse<In, Out>(\n res: PalbaseResult<In>,\n map: (data: In) => Out,\n): PalbaseResult<Out> {\n if (res.error || res.data === null || res.data === undefined) {\n return { data: null, error: res.error, status: res.status };\n }\n return { data: map(res.data), error: null, status: res.status };\n}\n\nfunction buildBucketClient(\n http: ModuleTransport,\n bucketName: string,\n publicOrigin: string,\n): PalbaseBucketClient {\n const objectPath = (path: string) => `/v1/storage/object/${bucketName}/${path}`;\n\n return {\n async upload(path, file, options?: PalbaseUploadOptions) {\n validateStoragePath(path);\n const headers: Record<string, string> = {\n \"Content-Type\": options?.contentType ?? \"application/octet-stream\",\n };\n if (options?.upsert) headers[\"x-upsert\"] = \"true\";\n // The BYTES, as the body. Storage sniffs the content and decides for\n // itself what this is; the declared type is a hint it may overrule,\n // because a name and a header are both things a caller can be wrong about.\n const body = file instanceof ArrayBuffer ? new Uint8Array(file) : file;\n const res = await http.request<Record<string, unknown>>(\"PUT\", objectPath(path), {\n body,\n headers,\n });\n return mapResponse(res, (r) => toFileObject(bucketName, r ?? {}));\n },\n\n async download(path) {\n validateStoragePath(path);\n // The AUTHENTICATED read: the project already holds a credential this\n // stack verified, so it does not have to mint a signature to open its own\n // object — and this route serves private buckets, which the public one\n // refuses on purpose.\n return http.request<Blob>(\"GET\", objectPath(path), { headers: { Accept: \"*/*\" } });\n },\n\n getPublicUrl(path, options) {\n validateStoragePath(path);\n const variant = options?.variant ? `?variant=${encodeURIComponent(options.variant)}` : \"\";\n // ABSOLUTE — and the origin is a value the stack is TOLD, not the\n // transport's baseUrl.\n //\n // Those are two different addresses and conflating them is how this broke\n // once already: the transport points at palsvc over the loopback\n // (`http://127.0.0.1:8080`), and a URL built from it resolves nowhere\n // outside the pod. So this used to return the path alone.\n //\n // The path alone is not a smaller answer, it is a wrong one. A public URL\n // LEAVES the response body — into an <img>, an email, another app on\n // another host — and none of those have a base to resolve it against.\n // Measured live 24.08.2026: an iOS client handed the returned\n // `/v1/files/post-images/…` straight to URLSession and got\n // NSURLErrorUnsupportedURL (-1002). The upload had worked; only the URL\n // was unusable.\n //\n // `PALBASE_PUBLIC_ORIGIN` is set by whoever publishes the stack, because\n // only they know it: in the cloud the operator writes\n // `https://<ref>.<domain>`, and a self-hosted stack carries whatever\n // domain its certificate is for.\n if (!publicOrigin) {\n // NAMED, not silent — the same doctrine as the other unconfigured\n // modules in engine/config.ts (\"throw a named error on first use rather\n // than silently no-op\"). A returned path would pass every test here and\n // fail in the one place nobody is watching.\n throw new Error(\n `Storage.bucket(\"${bucketName}\").getPublicUrl() needs this stack's public origin, ` +\n \"and it was not configured. Set PALBASE_PUBLIC_ORIGIN to the address clients reach \" +\n \"this stack at (e.g. https://myproject.palbase.studio).\",\n );\n }\n return `${publicOrigin}/v1/files/${bucketName}/${path}${variant}`;\n },\n\n async createSignedUrl(path, options): Promise<PalbaseResult<PalbaseSignedUrlResponse>> {\n validateStoragePath(path);\n // A DURATION — `{ expiresIn: \"1h\" }`. A bare number is ambiguous between\n // seconds and minutes at every call site that reads it, and the ambiguity\n // is only discovered when a link outlives the object it opened.\n return http.request<PalbaseSignedUrlResponse>(\"POST\", `/v1/storage/sign/${bucketName}/${path}`, {\n body: { expiresIn: options.expiresIn },\n });\n },\n\n async list(prefix?: string, options?: PalbaseListOptions) {\n if (prefix) validateStoragePath(prefix);\n const params = new URLSearchParams();\n if (prefix) params.set(\"prefix\", prefix);\n if (options?.limit !== undefined) params.set(\"limit\", String(options.limit));\n const query = params.toString();\n const res = await http.request<{ objects?: Record<string, unknown>[] }>(\n \"GET\",\n `/v1/storage/bucket/${bucketName}${query ? `?${query}` : \"\"}`,\n );\n // `{objects: [...]}`, not a bare array: the envelope leaves room for the\n // paging this will grow, and unwrapping it here keeps that off callers.\n return mapResponse(res, (body) => (body?.objects ?? []).map((row) => toFileObject(bucketName, row)));\n },\n\n async remove(paths) {\n for (const p of paths) validateStoragePath(p);\n // One request per object: the module deletes an object WITH its variants,\n // and a batch endpoint reporting partial success would need a result shape\n // nobody would read. The first refusal ends it — continuing would report a\n // partial delete as a whole one.\n const removed: PalbaseFileObject[] = [];\n for (const p of paths) {\n const res = await http.request<void>(\"DELETE\", objectPath(p));\n if (res.error) return { data: null, error: res.error, status: res.status };\n removed.push(toFileObject(bucketName, { path: p }));\n }\n return { data: removed, error: null, status: 200 };\n },\n\n async move(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/move/${bucketName}`, { body: { from, to } });\n },\n\n async copy(from, to) {\n validateStoragePath(from);\n validateStoragePath(to);\n return http.request<void>(\"POST\", `/v1/storage/copy/${bucketName}`, { body: { from, to } });\n },\n };\n}\n\n/**\n * @param publicOrigin the address CLIENTS reach this stack at — never the\n * transport's base, which is this process's internal route to palsvc. Empty\n * means it was not configured, and `getPublicUrl` refuses by name.\n */\nexport function buildStorageClient(\n http: ModuleTransport,\n publicOrigin: string,\n): PalbaseStorageClient {\n return {\n bucket(name: string) {\n if (!BUCKET_NAME_RE.test(name)) {\n throw new Error(`Invalid bucket name: \"${name}\". Bucket names must match ${BUCKET_NAME_RE.source}`);\n }\n // Sondaki eğik çizgi BURADA kırpılır: `${origin}/v1/files/...` iki\n // eğik çizgiyle biten bir yol üretirdi ve bazı sunucular onu ayrı bir\n // nesne sayar.\n return buildBucketClient(http, name, publicOrigin.replace(/\\/+$/, \"\"));\n },\n };\n}\n","/**\n * clients/index.ts — the composition root for the module clients.\n *\n * This is what the process calls once at boot. It builds the five clients the\n * engine injects and nothing else.\n *\n * WHAT IS NOT BUILT HERE, and why each one is absent rather than forgotten:\n *\n * - `functions`, `analytics`, `links` — the SDK exports no singleton for any\n * of them, so no handler could reach them. They were constructed on every\n * boot and thrown away. `auth` was in this list until roles arrived: the\n * sign-in half still belongs to the client SDK, but the ASSIGNMENT half is\n * an operator verb a handler has to be able to call, so `Auth` is built\n * above — as `PalbaseAuthAdminClient`, three methods and no more.\n * - `Purchases` — its client talked to palstore, and v2 contains no palstore\n * at all. The surface was unbacked before it was untyped. Dropped from v2\n * by the user's decision on 2026-08-15, with the SDK's `src/purchases/`\n * tree left in place because that decision was \"deferred, not silently\n * taken\". It is taken now: the tree is GONE (2026-08-29), because a\n * decorator standing in front of a service nothing serves is the same\n * defect as `Resource` and `config/*`, which went with it.\n * - The V1 host/executor transport — the isolate it existed for was removed\n * on 2026-08-14. A single-tenant process has nobody to hide its own\n * tenant's credentials from.\n */\n\nimport type { ModuleClients } from \"../engine/index.js\";\nimport { buildAuthClient } from \"./auth.js\";\nimport { buildDocumentsClient } from \"./documents.js\";\nimport { buildFlagsClient } from \"./flags.js\";\nimport { makeHttpClient } from \"./http.js\";\nimport { buildNotificationsClient } from \"./notifications.js\";\nimport { buildRealtimeClient } from \"./realtime.js\";\nimport { buildStorageClient } from \"./storage.js\";\n\nexport interface ModuleClientsConfig {\n /** Where the platform answers. Empty means \"not configured\" — see below. */\n baseUrl: string;\n /** The publishable key. Used only when no service-role key is supplied. */\n apiKey: string;\n /**\n * The service-role key, which is what a backend actually holds. Preferred\n * over `apiKey`: this process IS the project's server.\n */\n serviceRoleKey: string;\n /** The shared Realtime secret. Empty means realtime is not provisioned. */\n realtimeApiJwtSecret: string;\n /**\n * The address CLIENTS reach this stack at. Used ONLY to build public object\n * URLs; every request this bundle makes still goes over `baseUrl`.\n */\n publicOrigin: string;\n /** The request's user, read from the SDK's own scope — never from a caller. */\n getCurrentUserId: () => string | null;\n /** Injected in tests; resolved at call time in production. */\n fetchImpl?: typeof fetch;\n}\n\n/**\n * Build the module clients.\n *\n * Returns an EMPTY bundle when there is no base URL, deliberately: the engine\n * then injects its named stubs, so a handler that reaches for `Storage` gets an\n * error saying which module is unconfigured rather than a crash reading a\n * property of undefined. Booting is not blocked — a project that never touches\n * a module runs fine without one.\n */\nexport function buildModuleClients(cfg: ModuleClientsConfig): ModuleClients {\n const baseUrl = (cfg.baseUrl || \"\").replace(/\\/+$/, \"\");\n if (!baseUrl) return {};\n\n // The service-role key when present: this process is the project's own\n // server, and the publishable key would refuse half of what it needs.\n const apiKey = cfg.serviceRoleKey || cfg.apiKey || \"\";\n const http = makeHttpClient({ baseUrl, apiKey, fetchImpl: cfg.fetchImpl });\n\n return {\n // The ROLE half of auth only (`clients/auth.ts` says why the rest is not\n // here). It rides the same service-role transport, which is exactly the\n // credential the assignment routes demand.\n Auth: buildAuthClient(http),\n Documents: buildDocumentsClient(http),\n Storage: buildStorageClient(http, cfg.publicOrigin),\n Notifications: buildNotificationsClient(http),\n Flags: buildFlagsClient(http, { getCurrentUserId: cfg.getCurrentUserId }),\n Realtime: buildRealtimeClient({\n baseUrl,\n apiJwtSecret: cfg.realtimeApiJwtSecret,\n fetchImpl: cfg.fetchImpl,\n }),\n };\n}\n","import { z } from \"zod\";\nimport { TABLE_META } from \"./schema.js\";\nimport { REF_TARGET } from \"./foreign-key.js\";\nimport type { ColumnMap, TableDef, TableHandle } from \"./schema.js\";\n\n/**\n * policy.ts — the RLS policy authoring DSL.\n *\n * `policy(name)` returns a fluent builder that mirrors the `ColumnBuilder`\n * style in columns.ts: each chainable method mutates the underlying\n * definition and returns the builder so calls compose. The terminal value is\n * a plain {@link PolicyDef} — the exact JSON shape the runtime's\n * `schema_extract.js` reads off the bundled module and the Go side parses into\n * `PolicyJSON` (CONTRACT-POLICY).\n *\n * @example\n * import { policy } from \"@palbase/backend\";\n *\n * policy(\"owner_select\")\n * .for(\"select\")\n * .to(\"authenticated\")\n * .using(\"owner = (select auth.uid())\");\n */\n\n\n// ---------------------------------------------------------------------------\n// C-4 — politika ifadesinin YAPISI (FR-022). SÖZLEŞME BURADA DONAR.\n//\n// T016 (`existsIn`), T027 (Go emitter) ve T028 (korelasyonlu EXISTS) bu tipi\n// tüketir; şekli değiştirmek üç tarafı birden kırar.\n//\n// NEDEN string değil de yapı: bir string ifadeyi ne TypeScript ne Go okuyabilir.\n// Kolon adı yanlışsa hata `CREATE POLICY` anında Postgres'ten gelir — deploy\n// sırasında, yazma anında değil. Dahası InitPlan sarmalaması (`auth.uid()` →\n// `(select auth.uid())`, satır başına bir kez yerine statement başına bir kez)\n// ve `TO <rol>` daraltması ancak yapı üstünde GÜVENLE verilebilir; string\n// üzerinde regex'le yapmak, yorum içindeki bir `auth.uid()`'yi de sarmalar.\n// ---------------------------------------------------------------------------\n\n/** Politika ifadesinin düğümleri. DÜZ VERİ: tele bu şekilde gider. */\nexport type PolicyExpr =\n | {\n kind: \"col\";\n name: string;\n /**\n * Hangi tablonun kolonu (FR-023). Yoksa POLİTİKANIN KENDİ tablosu —\n * Postgres politika ifadesinde onu niteliksiz çözer. Doluysa bir\n * `existsIn` alt-sorgusunun takma adı.\n *\n * Bu ayrım korelasyonun tamamı: ayırt edilmezse `team_id = team_id`\n * üretilir, her satır için doğrudur, ve politika HİÇBİR ŞEYİ süzmez —\n * yani tüm belgeler herkese görünür.\n */\n alias?: string;\n }\n | { kind: \"authUid\" }\n | { kind: \"lit\"; value: string | number | boolean | null }\n | { kind: \"binop\"; op: PolicyBinOp; left: PolicyExpr; right: PolicyExpr }\n | { kind: \"and\"; parts: PolicyExpr[] }\n | { kind: \"or\"; parts: PolicyExpr[] }\n | { kind: \"not\"; expr: PolicyExpr }\n | { kind: \"isNull\"; expr: PolicyExpr; negated: boolean }\n | {\n /**\n * Korelasyonlu `EXISTS (SELECT 1 FROM <table> <alias> WHERE <predicate>)`.\n *\n * FR-024 BAĞLAYICI: alt-sorgu DOĞRUDAN üretilir, bir `SECURITY DEFINER`\n * fonksiyona SARILMAZ. Ölçüldü (spec Research Appendix, pg16): doğrudan\n * alt-sorguda hedef tablonun KENDİ RLS'i uygulanıyor — yani sızıntı\n * kanalı yok. Sarmalama ise onu bypass ederdi.\n */\n kind: \"exists\";\n table: string;\n alias: string;\n /**\n * POLİTİKANIN KENDİ tablosunun adı — korelasyonun çalışması için ŞART.\n *\n * ÖLÇÜLDÜ (canlı pg16): alt-sorgu içinde niteliksiz bir kolon adı\n * Postgres tarafından İÇ tabloya çözülüyor. Yani dış kolon niteliksiz\n * bırakılınca `pb_e1.team_id = pb_e1.team_id` üretiliyor — her satır\n * için doğru, ve politika HİÇBİR ŞEYİ süzmüyor: iki farklı kullanıcı\n * da tüm belgeleri gördü. Dış tablo adı burada taşınıyor ki emitter\n * `\"documents\".\"team_id\"` yazabilsin.\n */\n outer: string;\n predicate: PolicyExpr;\n };\n\n/** Karşılaştırma operatörleri. `in` sağ tarafta liste bekler. */\nexport type PolicyBinOp = \"eq\" | \"neq\" | \"gt\" | \"gte\" | \"lt\" | \"lte\" | \"in\";\n\n/**\n * Bir ifadenin ETRAFINDAKİ akıcı sarmalayıcı.\n *\n * Düğüm (`expr`) düz veri kalıyor, metotlar sarmalayıcıda yaşıyor: `_def.using`\n * serileştiğinde metotlu bir nesne değil, tam olarak tele gidecek şekil olsun\n * diye. `.using()` sarmalayıcıyı açar.\n */\nexport class PolicyExprRef {\n constructor(readonly expr: PolicyExpr) {}\n\n private bin(op: PolicyBinOp, other: PolicyOperand): PolicyExprRef {\n return new PolicyExprRef({ kind: \"binop\", op, left: this.expr, right: toExpr(other) });\n }\n\n eq(other: PolicyOperand): PolicyExprRef { return this.bin(\"eq\", other); }\n neq(other: PolicyOperand): PolicyExprRef { return this.bin(\"neq\", other); }\n gt(other: PolicyOperand): PolicyExprRef { return this.bin(\"gt\", other); }\n gte(other: PolicyOperand): PolicyExprRef { return this.bin(\"gte\", other); }\n lt(other: PolicyOperand): PolicyExprRef { return this.bin(\"lt\", other); }\n lte(other: PolicyOperand): PolicyExprRef { return this.bin(\"lte\", other); }\n\n /**\n * `IS NULL` / `IS NOT NULL` — `= NULL` SQL'de her zaman UNKNOWN'dır, o yüzden\n * niyet ayrı bir düğümle yazılır. Partial index'in en sık koşulu\n * (`WHERE deleted_at IS NULL`) tam olarak bu.\n */\n isNull(negated = false): PolicyExprRef {\n return new PolicyExprRef({ kind: \"isNull\", expr: this.expr, negated });\n }\n\n and(...others: PolicyExprRef[]): PolicyExprRef {\n return new PolicyExprRef({ kind: \"and\", parts: [this.expr, ...others.map((o) => o.expr)] });\n }\n or(...others: PolicyExprRef[]): PolicyExprRef {\n return new PolicyExprRef({ kind: \"or\", parts: [this.expr, ...others.map((o) => o.expr)] });\n }\n not(): PolicyExprRef {\n return new PolicyExprRef({ kind: \"not\", expr: this.expr });\n }\n}\n\n/**\n * Bir tablonun `existsIn` için ANNOTATION hâli — iki bildirim birbirini\n * başlatırken çıkarım döngüsünü kıran şey.\n *\n * ÖLÇÜLDÜ: `memberships.household_id` `households.id`'ye referans verirken\n * `households`'ın politikası `existsIn(memberships, …)` yazarsa TypeScript\n * ikisini de TS7022 ile `any`'ye düşürüyor. Kesinti sadece hata mesajı değil:\n * `m.col(…)` de `any` olduğu için politika gövdesindeki YANLIŞ YAZILMIŞ bir\n * kolon adı sessizce derleniyor — RLS yolunda fail-open. Aynı ölçümde\n * `existsIn`'in jeneriğini kaldırmak (tamamen jeneriksiz imza dahil) döngüyü\n * KIRMADI: döngü çıkarımdan değil, iki `const`'un birbirini başlatmasından\n * geliyor ve TypeScript'te tek çaresi bir tip annotation'ı.\n *\n * Bu, `references((): AnyColumn => y.id)`'nin tablo düzeyindeki karşılığı — ama\n * `AnyColumn`'dan farklı olarak KOLON ADLARINI SİLMEZ:\n *\n * ```ts\n * const memberships: TableRef<\"id\" | \"household_id\" | \"user_id\", \"memberships\"> =\n * defineTable(\"memberships\", { columns: { … } });\n * ```\n *\n * Adlar `Cols`'ta durduğu için `m.col(\"user\")` hâlâ DERLENMEZ, ve `N` verildiği\n * için tablo `defineSchema` içinde anahtarını kaybetmez. Kolon adlarını silen\n * gevşek bir `AnyTable` KASITLI OLARAK YOK: onu yazan kişi döngüyü susturur ve\n * politikasının kolon denetimini kapattığını fark etmez.\n */\nexport type TableRef<Cols extends string, N extends string = string> =\n TableHandle<Record<Cols, ColumnMap[string]>, N>;\n\n/** `.eq()` gibi metotların sağ tarafı: başka bir ifade ya da düz bir değer. */\nexport type PolicyOperand = PolicyExprRef | string | number | boolean | null;\n\n/**\n * Düz değer LİTERAL olur, kolon referansı OLMAZ.\n *\n * `.eq(\"owner\")` bir string karşılaştırmasıdır — `owner` kolonuna referans\n * değil. İkisi karışırsa politika sessizce yanlış satırları gösterir ve RLS'te\n * bunun adı yetki atlamasıdır. Kolon istiyorsan `p.col(\"owner\")` yazacaksın.\n */\nfunction toExpr(v: PolicyOperand): PolicyExpr {\n return v instanceof PolicyExprRef ? v.expr : { kind: \"lit\", value: v };\n}\n\n/**\n * Politika ifadesi bağlamı — `defineTable`'ın `policies` callback'ine verilir.\n *\n * Kolon adları TABLONUN KENDİ kolonlarıyla sınırlıdır (FR-022). Bu, `policies`\n * bir dizi değil de callback olduğu için mümkün: TypeScript `columns`'tan\n * `C`'yi çıkarıp callback'i onunla bağlamlandırıyor. `policy(\"x\")` tek başına\n * çağrıldığında hangi tabloda olduğunu bilemezdi.\n */\nexport interface PolicyExprCtx<Cols extends string = string> {\n /** Bu tablonun bir kolonu. Bilinmeyen ad DERLENMEZ. */\n col(name: Cols): PolicyExprRef;\n /**\n * \"Bu satırın sahibi olduğum bir takıma ait mi?\" — üyelik tabanlı kiracılık\n * (FR-023), korelasyonlu bir `EXISTS` alt-sorgusu olarak.\n *\n * ```ts\n * policies: (p) => [\n * policy(\"team_read\").for(\"select\").using(\n * p.existsIn(teamMembers, (m) =>\n * m.col(\"team_id\").eq(p.col(\"team_id\"))\n * .and(m.col(\"user_id\").eq(p.auth.uid()))),\n * ),\n * ]\n * ```\n *\n * `m` ÜYELİK tablosunun kolonlarını, `p` bu tablonunkileri verir; ikisi de\n * tipli ve SQL'de farklı nitelenirler. Karışsalardı `team_id = team_id`\n * üretilir ve politika hiçbir şeyi süzmezdi.\n *\n * ÇIKARIM DÖNGÜSÜ: `table` iki bildirim birbirini başlatıyorsa (üyelik tablosu\n * bu tabloya `references` veriyor, bu tablo da ona `existsIn` atıyor) o\n * bildirime {@link TableRef} annotation'ı gerekir — yoksa TypeScript ikisini\n * de TS7022 ile `any`'ye düşürür ve `m.col(…)` sessizce her adı kabul eder.\n *\n * ÖZYİNELEME TUZAĞI: üyelik tablosunun KENDİ politikası `existsIn`\n * KULLANMAZ — `user_id = auth.uid()` yazar. İki tablo birbirini\n * sorgularsa Postgres sorgu anında\n * `infinite recursion detected in policy for relation …` der. Asimetri\n * kasıtlıdır: üyelik tablosu basit olanı alır, diğer her tablo ona\n * alt-sorgu ATAR.\n */\n existsIn<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef,\n ): PolicyExprRef;\n /** Çağıranın kimliği. SQL'e `(select auth.uid())` olarak iner (InitPlan). */\n auth: { uid(): PolicyExprRef };\n /** Düz bir değer — karşılaştırmanın sağ tarafında açıkça literal demek için. */\n lit(v: string | number | boolean | null): PolicyExprRef;\n and(...parts: PolicyExprRef[]): PolicyExprRef;\n or(...parts: PolicyExprRef[]): PolicyExprRef;\n not(part: PolicyExprRef): PolicyExprRef;\n}\n\n/**\n * İfade bağlamını kurar. `defineTable` bunu kendi kolon adlarıyla çağırır;\n * testler ve elle kullanım için de dışa açık.\n */\nexport function exprCtx<Cols extends string = string>(\n _columns?: readonly Cols[],\n depth = 0,\n /**\n * POLİTİKANIN KENDİ tablosu — her derinlikte AYNI kalır.\n *\n * Alt-sorgunun içinde takma adsız duran bir kolon, dış sorgudaki tabloya\n * bağlanmak zorundadır; Go tarafı onu bu adla nitelendiriyor. Değer iç içe\n * geçmede ORTA tablonun adına kayıyordu (`meta.name` aşağı veriliyordu) ve\n * sonuç canlıda `ERROR: missing FROM-clause entry for table \"…\"` oluyordu —\n * yani iç içe `existsIn` içinden politikanın kendi kolonuna erişmek imkânsızdı\n * (nihai inceleme I-1, ölçüldü). Kök tablo aşağı DEĞİŞMEDEN taşınır.\n */\n ownTable = \"\",\n): PolicyExprCtx<Cols> {\n // Takma ad DERİNLİKTEN türetiliyor, bir sayaçtan değil: aynı şema iki kez\n // yüklendiğinde (test, sonra deploy) sayaç farklı değer üretir ve golden\n // çıktı sebepsiz değişirdi. Derinlik ifadenin kendi şeklinden gelir.\n const alias = `pb_e${depth}`;\n return {\n col: (name) =>\n new PolicyExprRef(depth === 0 ? { kind: \"col\", name } : { kind: \"col\", name, alias }),\n auth: { uid: () => new PolicyExprRef({ kind: \"authUid\" }) },\n lit: (v) => new PolicyExprRef({ kind: \"lit\", value: v }),\n and: (...parts) => new PolicyExprRef({ kind: \"and\", parts: parts.map((p) => p.expr) }),\n or: (...parts) => new PolicyExprRef({ kind: \"or\", parts: parts.map((p) => p.expr) }),\n not: (part) => new PolicyExprRef({ kind: \"not\", expr: part.expr }),\n existsIn: (table, predicate) => {\n const meta = (table as { [TABLE_META]: { name: string; columns: ColumnMap } })[TABLE_META];\n const inner = exprCtx(Object.keys(meta.columns), depth + 1, ownTable);\n const node: PolicyExpr = {\n kind: \"exists\",\n table: meta.name,\n alias: `pb_e${depth + 1}`,\n outer: ownTable,\n predicate: predicate(inner as never).expr,\n };\n // Hedefin NESNESİ taşınıyor — bir POLİTİKA için çıplak ad yeterli\n // (`CREATE POLICY` anında çözülür), ama bir GUARD gövdesi ÇALIŞMA ANINDA\n // ayrıştırılıyor ve `SET search_path = pg_catalog, pg_temp` altında\n // niteliksiz ad hiç çözülmüyor (D-012). `resolveReferences` bunu\n // niteliyor; nitelenen şema YANLIŞ olursa hata kullanıcının yazması\n // sırasında gelir.\n Object.defineProperty(node, REF_TARGET, {\n value: meta, enumerable: false, configurable: true,\n });\n return new PolicyExprRef(node);\n },\n };\n}\n\n/** The SQL command a policy applies to. `\"all\"` covers SELECT/INSERT/UPDATE/DELETE. */\nexport type PolicyCommand = \"all\" | \"select\" | \"insert\" | \"update\" | \"delete\";\n\n/** Whether a policy is permissive (OR-combined, the default) or restrictive\n * (AND-combined). Mirrors Postgres `CREATE POLICY ... AS PERMISSIVE|RESTRICTIVE`. */\nexport type PolicyMode = \"permissive\" | \"restrictive\";\n\n/**\n * The compiled, serializable policy definition — the EXACT shape consumed by\n * `schema_extract.js` → Go `PolicyJSON` (CONTRACT-POLICY).\n *\n * - `roles`: the DB roles this policy applies to (`TO` clause). An empty array\n * means the policy applies to PUBLIC (all roles) — the Postgres default.\n * - `using`: the `USING (...)` row-visibility expression, or `null` when none.\n * - `withCheck`: the `WITH CHECK (...)` write-validation expression, or `null`.\n * - `permissive`: `true` for `AS PERMISSIVE` (default), `false` for restrictive.\n */\nexport interface PolicyDef {\n name: string;\n command: PolicyCommand;\n roles: string[];\n /** Yapı (FR-022) ya da ham string (FR-028 kaçış kapağı). */\n using: string | PolicyExpr | null;\n withCheck: string | PolicyExpr | null;\n permissive: boolean;\n}\n\n/**\n * Fluent RLS policy builder.\n *\n * Defaults (documented, applied at construction):\n * - `command`: `\"all\"` — applies to every SQL command unless `.for(...)` narrows it.\n * - `roles`: `[\"authenticated\"]` — the common case is \"rule applies to signed-in\n * users\". Call `.to(...)` to override; pass `.to()` with no roles (or never\n * call it after a reset) to target PUBLIC.\n * - `using` / `withCheck`: `null` — no row filter / write check until set.\n * - `permissive`: `true` — `AS PERMISSIVE` (policies OR together).\n *\n * Each method mutates `_def` in place and returns `this`, so the chain is a\n * single builder instance (no per-call allocation, like a tagged-template\n * compile target). The terminal `PolicyDef` is read directly off `_def` by\n * `schema_extract.js`.\n */\n/** Quote an identifier for the policy expression. Table and column names reach\n * here from the schema author; neither is allowed to become syntax. */\nfunction quote(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n}\n\n/**\n * Bir politikanın adreslenebileceği Postgres rolleri.\n *\n * Serbest string DEĞİL, çünkü küme SABİT: bunları palbase provision ediyor,\n * kiracı yeni bir PG rolü yaratmıyor. Serbest bırakıldığında `authenitcated`\n * gibi bir harf hatası derlenip migration'a kadar gidiyordu — Drizzle'da da\n * aynı boşluk ölçüldü (`to` tipi `(string & {})`, yazım hatası DDL'e geçiyor).\n *\n * Çalışma anı zaten fail-closed (bilinmeyen rol kapıyı kapatıyor,\n * `session_rls_fail_closed_integration_test.go`); bu, aynı cevabı derleme\n * anına taşıyor.\n *\n * `backend_*` ikizleri elle YAZILMAZ — `NormalizeDeclaredPolicies` onları\n * kendisi ekliyor; yine de kabul ediliyor ki elle yazan kod kırılmasın.\n */\nexport type PolicyRole =\n | \"anon\"\n | \"authenticated\"\n | \"service_role\"\n | \"backend_anon\"\n | \"backend_authenticated\"\n | \"backend_service_role\";\n\nexport class PolicyBuilder {\n readonly _def: PolicyDef;\n\n constructor(name: string) {\n this._def = {\n name,\n command: \"all\",\n roles: [\"authenticated\"],\n using: null,\n withCheck: null,\n permissive: true,\n };\n }\n\n /** Restrict the policy to a single SQL command (default `\"all\"`). */\n for(command: PolicyCommand): this {\n this._def.command = command;\n return this;\n }\n\n /**\n * Set the DB roles the policy applies to (the `TO` clause), replacing any\n * previously-set roles. Call with no arguments to target PUBLIC (all roles).\n *\n * @example\n * policy(\"p\").to(\"authenticated\")\n * policy(\"p\").to(\"authenticated\", \"service_role\")\n * policy(\"p\").to() // PUBLIC\n */\n to(...roles: PolicyRole[]): this {\n this._def.roles = roles;\n return this;\n }\n\n /**\n * `USING (...)` satır görünürlüğü ifadesi.\n *\n * Tercih edilen biçim YAPI'dır (FR-022) — `policies` callback'inin verdiği\n * bağlamla kurulur ve kolon adları derlemede doğrulanır:\n *\n * ```ts\n * policies: (p) => [\n * policy(\"owner_read\").for(\"select\").using(p.col(\"owner\").eq(p.auth.uid())),\n * ]\n * ```\n *\n * Ham string KAÇIŞ KAPAĞI olarak kalır (FR-028): yapının ifade edemediği bir\n * şey gerektiğinde yol kapanmaz. Ama o yolda kolon adı doğrulaması yoktur ve\n * hata deploy anında Postgres'ten gelir.\n */\n using(expr: string | PolicyExprRef): this {\n this._def.using = expr instanceof PolicyExprRef ? expr.expr : expr;\n return this;\n }\n\n /**\n * \"Rows of THIS table whose owner the caller is a member of\" — the membership\n * pattern, written so it cannot recurse.\n *\n * THE TRAP IT EXISTS FOR. Written by hand, membership policies point at each\n * other: `channels` is visible to members, so its policy reads\n * `channel_members`; `channel_members` is visible to members, so its policy\n * reads `channels`. Postgres refuses the pair at query time with `infinite\n * recursion detected in policy for relation ...`, and the error names the\n * relation but not the cycle. The way out is asymmetry — the MEMBERSHIP table\n * is protected by `user_id = auth.uid()` and nothing else, and every other\n * table subqueries INTO it. That shape was in the platform's own schema and\n * written down nowhere; a customer recovered it by reading that schema.\n *\n * `(select auth.uid())` rather than a bare call: the scalar subquery is\n * evaluated ONCE per statement instead of per row.\n *\n * @example\n * // channels: visible to members. The membership table gets the simple one.\n * policy(\"member_read\").for(\"select\").to(\"authenticated\")\n * .memberOf(\"channel_members\", \"channel_id\")\n * // → id IN (SELECT \"channel_id\" FROM \"channel_members\"\n * // WHERE \"user_id\" = (select auth.uid()))\n */\n memberOf(\n membershipTable: string,\n foreignKey: string,\n options: { column?: string; userColumn?: string } = {},\n ): this {\n if (this._def.using !== null) {\n // Silently AND-ing the two would hide whichever the author meant; silently\n // replacing would hide the one they wrote. Neither is a thing to guess.\n throw new Error(\n `policy(${this._def.name}).memberOf(): this policy already has a using() expression. ` +\n \"Write one or the other — memberOf IS the using expression.\",\n );\n }\n const column = options.column ?? \"id\";\n const userColumn = options.userColumn ?? \"user_id\";\n this._def.using =\n `${quote(column)} IN (SELECT ${quote(foreignKey)} FROM ${quote(membershipTable)} ` +\n `WHERE ${quote(userColumn)} = (select auth.uid()))`;\n return this;\n }\n\n /** `WITH CHECK (...)` yazma doğrulaması — `using` ile aynı iki biçim. */\n withCheck(expr: string | PolicyExprRef): this {\n this._def.withCheck = expr instanceof PolicyExprRef ? expr.expr : expr;\n return this;\n }\n\n /** Set the policy mode: `\"permissive\"` (default, OR-combined) or\n * `\"restrictive\"` (AND-combined). */\n as(mode: PolicyMode): this {\n this._def.permissive = mode === \"permissive\";\n return this;\n }\n}\n\n/**\n * Start authoring an RLS policy. Returns a {@link PolicyBuilder}; the resulting\n * `PolicyBuilder` is accepted directly in a table's `policies: [...]` array\n * (its `_def` is read at schema-extract time).\n *\n * @param name The policy name. Palbase reconciliation keys policies by\n * `(table, name)`, so names must be unique per table.\n */\nexport function policy(name: string): PolicyBuilder {\n return new PolicyBuilder(name);\n}\n\n// ---------------------------------------------------------------------------\n// Tipli CHECK (FR-009, FR-010).\n// ---------------------------------------------------------------------------\n\n/**\n * Adlandırılmış bir CHECK kısıtı — telin bugünkü şekli, HARFİYEN.\n *\n * `expr` STRING kalıyor: `TableJSON.checks` bugün de `{ name, expr }[]` ve Go\n * tarafındaki `CheckJSON.Expr` bir string. Tipli `check()` ifadeyi bildirim\n * anında SQL'e derleyip aynı yere koyuyor, yani string dalıyla tipli dal telde\n * AYNI şeye iniyor: `NormalizeDeclaredChecks` ikisini de canlı Postgres'e\n * sorarak kanonikleştiriyor (böylece değişmemiş bir CHECK churn olarak\n * yeniden diff'lenmiyor) ve `schema-json.ts` yeni bir alan taşımıyor.\n */\nexport interface CheckDef {\n name: string;\n /** Derlenmiş SQL. Tipli dalda `check()` üretir, string dalda yazar verir. */\n expr: string;\n}\n\n/**\n * CHECK bağlamı POLİTİKA bağlamından DAR — Postgres'in kendi cümlesiyle:\n *\n * \"CHECK expressions cannot contain subqueries nor refer to variables other\n * than columns of the current row\" — sql-createtable\n *\n * `existsIn` doğrudan bir alt sorgu; `auth.uid()` da SQL'e `(SELECT auth.uid())`\n * olarak iniyor (InitPlan sarmalaması bir tercih değil — çıplak çağrı satır\n * başına yeniden değerlendiriliyor), yani o da alt sorgu. İkisi de BİLDİRİM\n * anında reddediliyor: reddi apply'a bırakmak, migration'ın ortasında\n * Postgres'in \"cannot use subquery in check constraint\" hatasıyla ölmesi\n * demekti — hangi tablo, hangi kısıt demeden.\n *\n * Go tarafındaki ikizi `validateCheckNode` (`policy_expr.go`); orada aynı küme\n * `freeze`'in `when` koşulu için dayatılıyor (generated sütun ifadesi de alt\n * sorgu içeremez).\n */\nfunction assertCheckNode(node: PolicyExpr, name: string): void {\n switch (node.kind) {\n case \"exists\":\n throw new Error(\n `check(${name}): \\`existsIn(...)\\` is a subquery and PostgreSQL forbids subqueries in a CHECK constraint — express a cross-table rule as a composite FOREIGN KEY (foreignKeys), or as a guard.`,\n );\n case \"authUid\":\n throw new Error(\n `check(${name}): \\`auth.uid()\\` renders as a subquery \\`(SELECT auth.uid())\\` and PostgreSQL forbids subqueries in a CHECK constraint — a caller-dependent rule belongs in an RLS policy, not a CHECK.`,\n );\n case \"binop\":\n assertCheckNode(node.left, name);\n assertCheckNode(node.right, name);\n return;\n case \"and\":\n case \"or\":\n for (const part of node.parts) assertCheckNode(part, name);\n return;\n case \"not\":\n case \"isNull\":\n assertCheckNode(node.expr, name);\n return;\n default:\n return;\n }\n}\n\n/** Karşılaştırma operatörlerinin SQL karşılığı — Go'daki `policyBinOps`'un ikizi. */\nconst CHECK_BIN_OPS: Partial<Record<PolicyBinOp, string>> = {\n eq: \"=\",\n neq: \"<>\",\n gt: \">\",\n gte: \">=\",\n lt: \"<\",\n lte: \"<=\",\n};\n\n/** Literal — `policyLiteralSQL`'in (Go) ikizi. Tırnak KAÇILIR: değer sözdizimi olamaz. */\nfunction literalSQL(v: string | number | boolean | null): string {\n if (v === null) return \"NULL\";\n if (typeof v === \"boolean\") return v ? \"true\" : \"false\";\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n // NaN/Infinity SQL'de bir sayı literali değil; sessizce `NaN` yazmak\n // Postgres'ten sözdizimi hatası getirirdi — deploy anında.\n throw new Error(`check(): ${v} bir SQL sayı literali değil.`);\n }\n return String(v);\n }\n return `'${v.replace(/'/g, \"''\")}'`;\n}\n\n/** Doğrulanmış bir CHECK düğümünü SQL'e derler. */\nfunction checkNodeSQL(node: PolicyExpr, name: string): string {\n switch (node.kind) {\n case \"col\":\n // Takma ad YOK: CHECK yalnız GEÇERLİ SATIRIN kolonlarını görebiliyor, ve\n // takma ad ancak bir `exists` alt sorgusunun içinde doğardı — o da yasak.\n return quote(node.name);\n case \"lit\":\n return literalSQL(node.value);\n case \"binop\": {\n const op = CHECK_BIN_OPS[node.op];\n if (op === undefined) {\n throw new Error(`check(${name}): \\`${node.op}\\` bir CHECK ifadesinde desteklenmiyor.`);\n }\n return `(${checkNodeSQL(node.left, name)} ${op} ${checkNodeSQL(node.right, name)})`;\n }\n case \"and\":\n case \"or\": {\n if (node.parts.length === 0) {\n // Boş bir konjonksiyon `true`, boş bir disjonksiyon `false`. Anlamı\n // yazmak, hiçbir şey yazmayıp kısıtı sessizce genişletmekten iyi.\n return node.kind === \"and\" ? \"(true)\" : \"(false)\";\n }\n const joiner = node.kind === \"and\" ? \" AND \" : \" OR \";\n return `(${node.parts.map((p) => checkNodeSQL(p, name)).join(joiner)})`;\n }\n case \"not\":\n return `(NOT ${checkNodeSQL(node.expr, name)})`;\n case \"isNull\":\n return `(${checkNodeSQL(node.expr, name)} IS ${node.negated ? \"NOT NULL\" : \"NULL\"})`;\n default: {\n // `exists`/`authUid` yukarıda reddedildi; buraya düşen, cebre sonradan\n // eklenmiş ve CHECK için sınıflandırılmamış bir düğümdür. REDDEDİLİR:\n // sınıflandıramadığını geçiren bir kapı, kısıtı sessizce zayıflatır.\n const kind = (node as { kind: string }).kind;\n throw new Error(`check(${name}): \\`${kind}\\` düğümü bir CHECK ifadesinde tanınmıyor.`);\n }\n }\n}\n\n/**\n * `check(\"<ad>\", <ifade>)` — TİPLİ CHECK kısıtı (FR-009).\n *\n * İfade POLİTİKA ifade cebirinin ta kendisiyle yazılıyor; bu DSL'de iki ayrı\n * ifade dili olmaması kurulu ilke. Kolon adları `checks` callback'inin verdiği\n * bağlamdan geliyor, yani yanlış yazılmış bir ad DERLENMİYOR — bugün string\n * biçiminde o hata ancak `ALTER TABLE ... ADD CONSTRAINT` anında Postgres'ten\n * geliyor.\n *\n * ```ts\n * defineTable(\"payments\", {\n * columns: { amount: integer().notNull(), currency: text().notNull() },\n * checks: (c) => [\n * check(\"payments_amount_pos\", c.col(\"amount\").gt(0)),\n * check(\"payments_currency_set\", c.col(\"currency\").isNull(true)),\n * ],\n * })\n * ```\n *\n * @param name Kısıtın adı. CHECK'ler ADA göre uzlaştırılıyor (gövde farkı\n * DROP + ADD demek), o yüzden ad tablo başına tekil olmalı.\n */\nexport function check(name: string, expr: PolicyExprRef): CheckDef {\n if (name.trim() === \"\") {\n throw new Error(\"check(): kısıtın adı boş olamaz — CHECK'ler ADA göre uzlaştırılıyor.\");\n }\n assertCheckNode(expr.expr, name);\n return { name, expr: checkNodeSQL(expr.expr, name) };\n}\n\n/**\n * `can` alanının YANIT şeması (FR-004, D-14).\n *\n * Bir satırın `can`'i, tablonun adlandırılmış UPDATE policy'lerinden o satır ve\n * çağıran için `true` dönenlerin adıdır (engine `canColumns`). Yanıt şemaları\n * elle yazılan zod olduğu için (`dto/*.ts`) bu alan OpenAPI'ye ancak buradan\n * girer: `z.object({ …, can: can(transfers) })`. Enum değerleri policy\n * TANIMINDAN gelir — elle yazılan policy adı yoktur; iki codegen (`emitter.ts`\n * enum→union, swiftgen enum→`case`) tipli sabitleri buradan üretir.\n *\n * SÖZLEŞME (FR-005): `can` ARAYÜZ içindir; yetki kararı için kullanılamaz;\n * eksik olabilir (render edilemeyen policy düşer); sunucu her istekte yeniden\n * karar verir. Ham string policy'de kolon adlarını NİTELİKSİZ yazın — motor\n * ifadeyi `t` alias'ı altında seçer, `transfers.status` orada çözülmez; yorum\n * (`--`, `/*`) ve `auth.has_permission(...)`'ın `(select …)` sarmalı olmadan\n * çağrılması da o policy'yi `can`'den düşürür (warn ile). Yalnız `.for(\"update\")`\n * policy'leri `can`'e girer; `.for(\"all\")` UPDATE'i yönetir ama yankılanmaz.\n * `(select …)` sarmalayıcısını motor bir METİN kapısıyla arar (tırnaklı/boşluklu\n * yazımların sonlu olmayan kümesini DOĞRULAMAZ): bir çağrının satır başına\n * koşup koşmadığının ölçümü EXPLAIN ANALYZE'dır ve demo koşusunda (T016)\n * alınır — yavaş bir `can` yanlış değildir, kapı yalnız yaygın yanlışı yakalar.\n * `can` adı rezervedir: `can` kolonu olan tabloda yankı yok (bu fonksiyon fırlatır),\n * `can` adlı ilişki (`can` tablosu, `can_id` FK, `as`/`reverseAs: \"can\"`) ise\n * `defineTable`'da reddedilir.\n * AS RESTRICTIVE policy'ler Postgres'te olduğu gibi her izinli policy'ye AND'lenir;\n * `TO <rol>` listesi oturum rolüyle kapılanır.\n */\nexport function can<C extends ColumnMap>(table: TableDef<C>): z.ZodArray<z.ZodEnum<[string, ...string[]]>> {\n // `defineTable`'ın döndürdüğü tutamaç (kolonlar + sembol) TableDef DEĞİLDİR —\n // `columns` alanı yoktur; şablon bir zamanlar `can(notes)` öğretiyordu (W1 h1-r4 N-13).\n // `undefined`/`null` first, by name: `can(publicSchema.tables.transfers)` with a table the\n // schema does not declare must not die as a TypeError inside the bundle.\n if (table === undefined || table === null) {\n throw new Error(\n \"can(<table>): received \" + String(table) + \" — the schema declares no such table (check the name against db/*.ts; can(publicSchema.tables.<name>))\",\n );\n }\n const def = table as unknown as { name?: unknown; columns?: unknown; policies?: unknown };\n if (typeof def.name !== \"string\" || def.columns === null || typeof def.columns !== \"object\" || !Array.isArray(def.policies)) {\n throw new Error(\n \"can(<table>): expects the schema's table definition — can(publicSchema.tables.notes) — not the defineTable handle (`notes`)\",\n );\n }\n if (Object.prototype.hasOwnProperty.call(table.columns, \"can\")) {\n throw new Error(\n `can(${table.name}): the table declares a column named \"can\", so the row carries that column and no policy echo — rename the column to get can`,\n );\n }\n const rel = reservedCanRelation(table.name, table.columns);\n if (rel !== null) {\n throw new Error(`can(${table.name}): ${rel}`);\n }\n // Motorla aynı süzgeç (59 bayt): tipte/enum'da olup telde hiç gelmeyecek ad olmasın.\n const names = table.policies\n .filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63)\n .map((p) => p.name);\n if (names.length === 0) {\n const all = table.policies.filter((p) => p.command === \"all\").map((p) => p.name);\n const hint = all.length > 0\n ? ` The table's ${all.map((n) => `\"${n}\"`).join(\", \")} ${all.length === 1 ? \"policy is\" : \"policies are\"} for(\"all\") — for(\"all\") governs UPDATE but is not a named update policy and never appears in can.`\n : \"\";\n throw new Error(\n `can(${table.name}): the table declares no update policy — there is nothing a row could echo. ` +\n `Name one with policy(\"<name>\").for(\"update\").using(…) first.${hint}`,\n );\n }\n return z.array(z.enum(names as [string, ...string[]]));\n}\n\n/**\n * `can` bir İLİŞKİ adı olarak da rezervedir: `row.can` literal union'ı ile\n * `relations.can` aynı satırda iki ayrı şey olurdu ve `can(table)` yanıt\n * şemasına koyduğu enum'u çalışma zamanındaki ilişki dizisiyle 500'e çevirirdi\n * (W1 h2-r3 N-2). `defineTable` bunu beyan anında reddeder; burada aynı kural\n * ham `TableDef` için tekrar sorulur. Döneni bir hata cümlesidir, `null` = temiz.\n * Yalnız BU tablonun kendi kolonlarından türeyen adlar görülebilir: tablo adı\n * `can` (ters ilişkinin varsayılan adı) ve `reverseAs: \"can\"` de defineTable'da düşer.\n */\nexport function reservedCanRelation(tableName: string, columns: ColumnMap): string | null {\n if (tableName === \"can\") {\n return `a table named \"can\" would put a relation named \"can\" on every parent it references — rename the table`;\n }\n for (const [col, b] of Object.entries(columns)) {\n const def = (b as { _def: { referencesThunk?: unknown; selfRefColumn?: string; refAs?: string; reverseAs?: string; owns?: boolean } })._def;\n // `selfReferences` de bir ilişki doğurur (`references` şemada sonradan kurulur) — W1 h1-r4 N-10.\n if (def.referencesThunk === undefined && def.selfRefColumn === undefined) continue;\n if (def.reverseAs === \"can\") {\n return `column \"${col}\" names its reverse relation \"can\" — the parent's rows would carry a relation where can is reserved; pick another reverseAs`;\n }\n const forward = def.owns === true ? \"owner\" : (def.refAs ?? (col.endsWith(\"_id\") ? col.slice(0, -3) : col));\n if (forward === \"can\") {\n return `column \"${col}\" would be read as a relation named \"can\" (${def.refAs === undefined ? \"derived from the column name\" : \"its as: option\"}) — can is reserved for the policy echo; rename it`;\n }\n }\n return null;\n}\n","import type { PolicyExpr, PolicyExprRef } from \"./policy.js\";\nimport type { ColumnMap, TableHandle } from \"./schema.js\";\n\n// `schema.ts` bu modülü import ediyor, yani buradan ORAYA bir DEĞER import'u\n// döngü kurardı ve ESM'de biri diğerini `undefined` görürdü. `TABLE_META` zaten\n// `Symbol.for` ile kayıtlı bir global sembol — aynı anahtarı burada da sormak\n// tam olarak aynı sembolü verir ve döngüyü baştan siler. Tip import'u (`type`)\n// derlemede silindiği için döngü yaratmaz.\nconst TABLE_META: typeof import(\"./schema.js\").TABLE_META = Symbol.for(\n \"palbase.table.meta\",\n) as typeof import(\"./schema.js\").TABLE_META;\n\n/**\n * REF_TARGET, bir referansın HEDEF TABLO NESNESİ — serileştirilmez.\n *\n * Hedefin ADI builder anında biliniyor ama ŞEMASI bilinmiyor: şemayı\n * `defineSchema` damgalıyor ve o, `defineTable` callback'lerinden SONRA koşuyor.\n * Bu yüzden nesnenin kendisi taşınıyor ve niteleme `resolveReferences`'ta,\n * kolon başına yolun kullandığı AYNI `declaringSchemaOf` haritasıyla yapılıyor.\n *\n * Sembol anahtar: `JSON.stringify` sembol anahtarlarını atlar, yani wire'a\n * çıkmaz (NFR-006).\n */\nexport const REF_TARGET: unique symbol = Symbol.for(\"palbase.ref.target\");\n\n/** `ON UPDATE` / `ON DELETE` eylemleri — Postgres'in kabul ettiği kapalı küme. */\nexport type FkAction = \"cascade\" | \"restrict\" | \"set null\" | \"set default\" | \"no action\";\n\n/** `MATCH` türü. `partial` Postgres'te HENÜZ uygulanmadı, o yüzden yok. */\nexport type FkMatch = \"simple\" | \"full\";\n\n/** Bir tablo düzeyi FOREIGN KEY bildirimi — C-1/C-2 (FR-001). */\nexport interface ForeignKeyDef {\n name: string;\n columns: string[];\n refTable: string;\n refColumns: string[];\n onUpdate?: FkAction;\n onDelete?: FkAction;\n match?: FkMatch;\n}\n\n/**\n * `foreignKey(\"<ad>\")` — tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY (C-1, FR-001).\n *\n * ```ts\n * foreignKeys: (c) => [\n * foreignKey(\"settlement_entry_household\")\n * .on(c.col(\"household_id\"), c.col(\"entry_id\"))\n * .references(entries, \"household_id\", \"id\")\n * .onDelete(\"cascade\"),\n * ]\n * ```\n *\n * NEDEN KOLON ÜZERİNDEKİ `.references()` YETMİYOR. O tek sütunlu ve tek\n * hedeflidir. Çok kiracılı bütünlüğün istediği şey\n * `FOREIGN KEY (household_id, entry_id) REFERENCES entries (household_id, id)`:\n * çocuğun ebeveyni yalnız var olmakla kalmaz, AYNI KİRACIYA ait olmak\n * zorundadır. Kolon başına model bunu ifade edemez.\n *\n * İki yol BİRBİRİNİ DÜŞÜRMEZ: bu bildirim kendi adıyla izlenir, kolon\n * üzerindekiler `<tablo>_<kolon>_fkey` ile. Aynı tabloda ikisi birden olabilir.\n */\nexport class ForeignKeyBuilder {\n readonly _def: ForeignKeyDef;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"foreignKey(ad): foreign key'in adı boş olamaz — Palbase kısıtları ADA göre uzlaştırır.\",\n );\n }\n this._def = { name, columns: [], refTable: \"\", refColumns: [] };\n }\n\n /** Yerel sütunlar. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */\n on(...cols: PolicyExprRef[]): this {\n this._def.columns = cols.map((c) => {\n const e = c.expr;\n if (e.kind !== \"col\") {\n throw new Error(\n `foreignKey(${this._def.name}).on(): yalnız kolon referansı alır — ifade bir FK'nın parçası olamaz.`,\n );\n }\n return e.name;\n });\n return this;\n }\n\n /**\n * Hedef tablo ve sütunları. Sütun sayısı `.on()`'unkiyle eşit OLMALI ve bu\n * burada, bildirim yazılırken kontrol edilir — bozuk bir FK wire'a hiç çıkmaz.\n */\n references<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n ...cols: (Extract<keyof C, string>)[]\n ): this {\n if (cols.length === 0) {\n throw new Error(\n `foreignKey(${this._def.name}).references(): en az bir hedef sütun gerekir.`,\n );\n }\n this._def.refTable = table[TABLE_META].name;\n this._def.refColumns = [...cols];\n // Hedefin NESNESİ de taşınıyor: şeması `defineSchema` damgalayana kadar\n // bilinmiyor ve `resolveReferences` orada nitelikli adı yazıyor.\n Object.defineProperty(this._def, REF_TARGET, {\n value: table[TABLE_META], enumerable: false, configurable: true,\n });\n return this;\n }\n\n onUpdate(action: FkAction): this {\n this._def.onUpdate = action;\n return this;\n }\n\n onDelete(action: FkAction): this {\n this._def.onDelete = action;\n return this;\n }\n\n /**\n * `MATCH FULL`: referans veren sütunların HEPSİ NULL olmadıkça kısıt\n * değerlendirilir. Varsayılan `MATCH SIMPLE`'da tek bir NULL kısıtı atlatır —\n * `freeze` bunu bilerek kullanır, sıradan bir FK'da genelde istenmez.\n */\n match(m: FkMatch): this {\n this._def.match = m;\n return this;\n }\n}\n\nexport function foreignKey(name: string): ForeignKeyBuilder {\n return new ForeignKeyBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI burada doğrular.\n *\n * Uzunluk uyuşmazlığı push'ta da reddediliyor (FR-002) ama orada mesaj canlıya\n * gidiyor; burada yazarın editöründe patlıyor ve bozuk bildirim wire'a hiç\n * çıkmıyor. İki kapı da gerekli: biri yazar için, biri deploy için.\n */\nexport function toForeignKeyDef(b: ForeignKeyBuilder | ForeignKeyDef): ForeignKeyDef {\n const def = b instanceof ForeignKeyBuilder ? b._def : b;\n if (def.columns.length === 0) {\n throw new Error(`foreignKey(${def.name}): en az bir yerel sütun gerekir — .on(...) çağırın.`);\n }\n if (def.refColumns.length === 0 || def.refTable === \"\") {\n throw new Error(`foreignKey(${def.name}): hedef tablo ve sütunlar gerekir — .references(...) çağırın.`);\n }\n if (def.columns.length !== def.refColumns.length) {\n throw new Error(\n `foreignKey(${def.name}): ${def.columns.length} yerel sütun (${def.columns.join(\", \")}) ` +\n `ama ${def.refColumns.length} hedef sütun (${def.refColumns.join(\", \")}) — iki liste eşit uzunlukta olmalı.`,\n );\n }\n return def;\n}\n\n/**\n * Bir KOŞULLU (\"donan\") FOREIGN KEY bildirimi — C-5 (FR-012).\n *\n * `columns` çocuğun donan sütunları, `refColumns` ebeveynin onlara karşılık\n * gelen anahtar sütunları; ikisi SIRAYLA eşleşir. `when` doğruyken FK\n * değerlendirilir, yanlışken hiç değerlendirilmez.\n */\nexport interface FreezeDef {\n name: string;\n when: PolicyExpr;\n columns: string[];\n refTable: string;\n refColumns: string[];\n}\n\n/** Builder'ın YAZILMAKTA olan hâli: `when` henüz atanmamış olabilir. */\ntype FreezeDraft = Omit<FreezeDef, \"when\"> & { when?: PolicyExpr };\n\n/**\n * `freeze(\"<ad>\")` — KOŞULLU FK: bir koşul sağlandığı sürece bir demeti dondurur\n * (C-5, FR-012).\n *\n * ```ts\n * freeze: (c) => [\n * freeze(\"pay_settled_inv\")\n * .when(c.col(\"status\").eq(\"settled\"))\n * .columns(\"inv_id\", \"amount\", \"currency\")\n * .references(invoices, \"id\", \"amount\", \"currency\"),\n * ]\n * ```\n *\n * NEDEN TRIGGER DEĞİL. Üretilen şey bir CONSTRAINT: ebeveyndeki demet üzerinde\n * bir UNIQUE, çocukta `when` sağlanmıyorken NULL veren `STORED` generated\n * sütunlar, ve bunlardan `ON UPDATE RESTRICT ON DELETE RESTRICT` bir FK.\n * `MATCH SIMPLE`'ın NULL kaçışı — \"referans veren sütunlardan biri NULL ise satır\n * kısıtı sağlamak zorunda değildir\" — \"koşullu FK\"yı `WHERE` olmadan veriyor.\n *\n * Trigger'a göre üç bedava üstünlük (canlı pg'de ölçüldü, spec Research\n * Appendix): TERS YÖN de kapanır (uyuşmayan bir çocuk `settled` yapılamaz —\n * trigger yalnız ebeveyni korurdu); koşul kalkınca donma KENDİLİĞİNDEN çözülür;\n * `pg_dump`/restore'da FK gibi davranır.\n *\n * Donan sütunlar `NOT NULL` OLMALI: nullable bir sütun `MATCH SIMPLE`'ın aynı\n * kaçışını koşuldan BAĞIMSIZ olarak açar ve donma sessizce hiç kurulmaz. Push o\n * bildirimi reddeder (FR-014).\n */\nexport class FreezeBuilder {\n readonly _def: FreezeDraft;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"freeze(ad): freeze kısıtının adı boş olamaz — Palbase kısıtları ADA göre uzlaştırır.\",\n );\n }\n this._def = { name, columns: [], refTable: \"\", refColumns: [] };\n }\n\n /**\n * DONMA KOŞULU — çocuk satırının kendi kolonları üzerinde bir yüklem.\n *\n * Generated sütunlara `CASE WHEN <koşul> THEN <sütun> END` olarak iner; yani\n * koşul yanlışken sütunlar NULL olur ve FK o satır için hiç değerlendirilmez.\n */\n when(pred: PolicyExprRef): this {\n this._def.when = pred.expr;\n return this;\n }\n\n /** Çocuğun DONAN sütunları. SIRA KORUNUR — hedef sütunlarla birebir eşleşir. */\n columns(...cols: string[]): this {\n if (cols.length === 0) {\n throw new Error(\n `freeze(${this._def.name}).columns(): en az bir donan sütun gerekir — hiçbirini vermeyen bir freeze hiçbir şeyi dondurmaz.`,\n );\n }\n this._def.columns = [...cols];\n return this;\n }\n\n /**\n * Ebeveyn tablo ve donan demetin ORADAKİ karşılığı. Zincirin SON halkası:\n * bildirim burada tamamlanır ve tutarlılığı burada doğrulanır, yani\n * `.references()`'ı unutmuş bir freeze `FreezeDef` üretmediği için tabloya\n * hiç giremez.\n */\n references<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n ...cols: (Extract<keyof C, string>)[]\n ): FreezeDef {\n if (cols.length === 0) {\n throw new Error(\n `freeze(${this._def.name}).references(): en az bir hedef sütun gerekir.`,\n );\n }\n this._def.refTable = table[TABLE_META].name;\n this._def.refColumns = [...cols];\n Object.defineProperty(this._def, REF_TARGET, {\n value: table[TABLE_META], enumerable: false, configurable: true,\n });\n return toFreezeDef(this);\n }\n}\n\nexport function freeze(name: string): FreezeBuilder {\n return new FreezeBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI burada doğrular — `toForeignKeyDef`\n * ile aynı gerekçe: bozuk bir bildirim yazarın editöründe patlar, wire'a hiç\n * çıkmaz.\n */\nexport function toFreezeDef(b: FreezeBuilder | FreezeDef): FreezeDef {\n const def: FreezeDraft = b instanceof FreezeBuilder ? b._def : b;\n if (def.columns.length === 0) {\n throw new Error(`freeze(${def.name}): en az bir donan sütun gerekir — .columns(...) çağırın.`);\n }\n if (def.refColumns.length === 0 || def.refTable === \"\") {\n throw new Error(`freeze(${def.name}): hedef tablo ve sütunlar gerekir — .references(...) çağırın.`);\n }\n if (def.columns.length !== def.refColumns.length) {\n throw new Error(\n `freeze(${def.name}): ${def.columns.length} donan sütun (${def.columns.join(\", \")}) ` +\n `ama ${def.refColumns.length} hedef sütun (${def.refColumns.join(\", \")}) — iki liste eşit uzunlukta olmalı.`,\n );\n }\n if (def.when === undefined) {\n throw new Error(\n `freeze(${def.name}): donma koşulu gerekir — .when(...) çağırın. Koşulsuz bir freeze sıradan bir FK'dır; onun için foreignKey(...) var.`,\n );\n }\n const out: FreezeDef = {\n name: def.name,\n when: def.when,\n columns: [...def.columns],\n refTable: def.refTable,\n refColumns: [...def.refColumns],\n };\n // Kopya hedefin nesnesini TAŞIMALI, yoksa niteleme yapılamaz ve çapraz\n // şemalı bir freeze sessizce `public`'e yazılır.\n const target = (def as { [REF_TARGET]?: object })[REF_TARGET];\n if (target !== undefined) {\n Object.defineProperty(out, REF_TARGET, { value: target, enumerable: false, configurable: true });\n }\n return out;\n}\n","import { exprCtx } from \"./policy.js\";\nimport type { PolicyExpr, PolicyExprCtx, PolicyExprRef } from \"./policy.js\";\nimport type { ColumnMap, TableHandle } from \"./schema.js\";\n\n/**\n * guard.ts — DAR REDDEDİCİ YÜZEY (C-3, FR-015…FR-021).\n *\n * Bildirimsel kısıtların yetişemediği beş madde kaldı: write-once alanlar,\n * durum makinesi geçişleri, sabit olmayan yüklemle çapraz satır kontrolü, işlem\n * düzeyinde toplam, ve alan diline ait teşhis. RLS yolu bunlara KAPALI: `OLD` ve\n * `NEW` bir politika ifadesinde ad olarak YOKTUR (ölçüldü — red, ad çözümleme\n * düzeyinde `CREATE POLICY` anında gelir: `missing FROM-clause entry for table\n * \"new\"`), ve `USING`/`WITH CHECK` iki ayrı satıra karşı ayrı ayrı\n * değerlendirilir; tek ifadede iki satırı yan yana getiren bir kapsam yok.\n *\n * YAZAR ÜÇ ŞEY YAZAR: hangi olay · hangi koşul · ne diyerek reddet. Kalan sekiz\n * knob'un güvenli varsayılanı var ve bu yüzeyde HİÇ görünmüyor: `BEFORE` ·\n * `FOR EACH ROW` (Postgres'in varsayılanı `STATEMENT` ve bir guard için yanlış) ·\n * `UPDATE OF` listesi `WHEN`'den türetilir · `SET search_path = pg_catalog,\n * pg_temp` HER ZAMAN · `SECURITY INVOKER` (asla `DEFINER`) · `NOT DEFERRABLE` ·\n * `REFERENCING`/`FROM` üretilmez · `DROP IF EXISTS` + `CREATE`. Bir yeteneği\n * yüzeye çıkarmak onu politika hâline getirir; bunlar politika DEĞİL, güvenli\n * varsayılan (FR-017).\n *\n * Global bir kaçış kapısı KASITLI OLARAK YOK: django-pgtrigger'ın\n * `SET pgtrigger.ignore`'u herhangi bir oturumun guard'ı atlamasına izin veriyor\n * ve bir BaaS'ta bu kabul edilemez.\n */\n\n// `schema.ts` bu modülü import ediyor, yani buradan ORAYA bir DEĞER import'u\n// ESM'de döngü kurardı — bu dosyada `schema.js`'ten gelen HER ŞEY `type`.\n// Tablonun adına inen tek yol `exprCtx().existsIn`, ve o `policy.ts`'te.\n\n/** Guard'ın tetiklendiği yazma fiili. */\nexport type GuardEvent = \"insert\" | \"update\" | \"delete\";\n\n/**\n * Bir guard bildirimi — C-3/C-4 (FR-015).\n *\n * `when` satırın KENDİ kolonları üzerinde bir yüklem (trigger'ın `WHEN` yan\n * tümcesine iner), `exists` ise çapraz satır yüklemi (gövdedeki `EXISTS`\n * bloğuna). İkisi ayrı alan çünkü Postgres bir trigger'ın `WHEN` yan tümcesinde\n * ALT SORGUYA İZİN VERMİYOR (`ERROR: cannot use subquery in trigger WHEN\n * condition` — ölçüldü); ayrımı wire'da yapmak, emitter'ın yükleme bakıp\n * tahmin etmesinden daha dürüst (FR-019).\n */\nexport interface GuardDef {\n name: string;\n event: GuardEvent;\n when?: PolicyExpr;\n exists?: PolicyExpr;\n message: string;\n detail?: string;\n hint?: string;\n column?: string;\n}\n\n/** Builder'ın YAZILMAKTA olan hâli: olay ve mesaj henüz atanmamış olabilir. */\ntype GuardDraft = Omit<GuardDef, \"event\" | \"message\"> & {\n event?: GuardEvent;\n message?: string;\n};\n\n/**\n * `guard(\"<ad>\")` — bir yazmayı ALAN DİLİYLE reddeden trigger (C-3, FR-015).\n *\n * ```ts\n * guards: (g) => [\n * guard(\"documents_frozen_body\")\n * .on(\"update\")\n * .when(g.col(\"status\").eq(\"archived\"))\n * .refuse(\"Arşivlenmiş belgenin gövdesi değiştirilemez\", { column: \"body\" }),\n * ]\n * ```\n *\n * ADI ZORUNLU (FR-016). Postgres aynı olaya bağlı trigger'ları ADA GÖRE\n * alfabetik sırayla koşar ve başka bir sıra tutamacı YOKTUR: adsız üretilmiş bir\n * guard, sırası kendi kontrolünde olmayan bir guard demektir.\n *\n * Teşhis: red `PB001` SQLSTATE'i ile gelir — `23514` KULLANILMAZ, o gerçek bir\n * CHECK ihlalinin kodu ve istemci ikisini ayırt edemezdi. Guard'ın adı\n * `CONSTRAINT` alanına gider, yani istemci mesajı PARSE ETMEDEN hangi guard'ın\n * reddettiğini okur (FR-021).\n */\nexport class GuardBuilder {\n readonly _def: GuardDraft;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\n \"guard(ad): guard'ın adı boş olamaz — Postgres aynı olaydaki trigger'ları ADA GÖRE alfabetik koşuyor ve başka sıra tutamacı yok.\",\n );\n }\n this._def = { name };\n }\n\n /** Hangi yazma fiilinde bakılacak. */\n on(event: GuardEvent): this {\n this._def.event = event;\n return this;\n }\n\n /**\n * Satırın KENDİ kolonları üzerinde koşul — trigger'ın `WHEN` yan tümcesi.\n *\n * Emitter karşılaştırmaları `IS DISTINCT FROM` ile yazar (`<>` NULL'da yanlış\n * cevap verir) ve geçen sütunlardan bir `UPDATE OF (…)` listesi türetir\n * (FR-018).\n */\n when(pred: PolicyExprRef): this {\n this._def.when = pred.expr;\n return this;\n }\n\n /**\n * ÇAPRAZ SATIR koşulu — gövdedeki `EXISTS` bloğuna iner, `WHEN`'e DEĞİL:\n * Postgres trigger `WHEN`'inde alt sorgu kabul etmiyor (FR-019).\n *\n * Yüklem içinde takma adsız kalan kolon guard'ın KENDİ satırıdır (`NEW`/`OLD`);\n * `r.col(...)` hedef tablonun kolonlarını verir ve ayrı nitelenir. Bu yüzden\n * düğümün `outer` alanı BOŞ kalır: bir guard'ın \"dış satır\"ı bir tablo takma\n * adı değildir.\n */\n exists<C extends ColumnMap, N extends string>(\n table: TableHandle<C, N>,\n predicate: (row: PolicyExprCtx<Extract<keyof C, string>>) => PolicyExprRef,\n ): this {\n // Politikaların `existsIn`'i ile AYNI makine: takma ad derinlikten türüyor,\n // iç bağlam hedef tablonun kolonlarıyla kuruluyor. İkinci bir kopyası\n // olsaydı iki korelasyon lehçesi doğardı.\n this._def.exists = exprCtx().existsIn(table, predicate).expr;\n return this;\n }\n\n /**\n * REDDİN KENDİSİ ve zincirin son halkası: mesaj olmadan bir guard tamamlanmaz.\n *\n * `detail`/`hint` Postgres'in aynı adlı alanlarına, `column` ise `COLUMN`\n * alanına gider — istemci hangi alanın reddedildiğini mesajı parse etmeden\n * okur.\n */\n refuse(\n message: string,\n opts?: { detail?: string; hint?: string; column?: string },\n ): GuardDef {\n this._def.message = message;\n if (opts?.detail !== undefined) this._def.detail = opts.detail;\n if (opts?.hint !== undefined) this._def.hint = opts.hint;\n if (opts?.column !== undefined) this._def.column = opts.column;\n return toGuardDef(this);\n }\n}\n\nexport function guard(name: string): GuardBuilder {\n return new GuardBuilder(name);\n}\n\n/**\n * Bildirimi normalize eder ve TUTARLILIĞINI bildirim anında doğrular —\n * `toForeignKeyDef` ile aynı gerekçe: eksik bir guard yazarın editöründe patlar,\n * wire'a hiç çıkmaz.\n */\nexport function toGuardDef(b: GuardBuilder | GuardDef): GuardDef {\n const def: GuardDraft = b instanceof GuardBuilder ? b._def : b;\n if (def.event === undefined) {\n throw new Error(`guard(${def.name}): hangi olayda bakacağı gerekir — .on(\"insert\"|\"update\"|\"delete\") çağırın.`);\n }\n if (def.when === undefined && def.exists === undefined) {\n throw new Error(\n `guard(${def.name}): bir koşul gerekir — .when(...) ya da .exists(...) çağırın. Koşulsuz bir guard o olaydaki HER yazmayı reddeder.`,\n );\n }\n if (def.message === undefined || def.message.trim() === \"\") {\n throw new Error(\n `guard(${def.name}): boş mesaj kabul edilmez — reddin mesajı guard'ın kullanıcıya ulaşan TEK çıktısı.`,\n );\n }\n return {\n name: def.name,\n event: def.event,\n ...(def.when !== undefined ? { when: def.when } : {}),\n ...(def.exists !== undefined ? { exists: def.exists } : {}),\n message: def.message,\n ...(def.detail !== undefined ? { detail: def.detail } : {}),\n ...(def.hint !== undefined ? { hint: def.hint } : {}),\n ...(def.column !== undefined ? { column: def.column } : {}),\n };\n}\n","/**\n * backfill.ts — DDL'DEN AYRI, İZLENEN, BİR KEZ KOŞAN fiil (C-6, FR-033/FR-034).\n *\n * Bir sütun eklemek bildirimseldir; o sütunu DOLDURMAK değildir. Doldurma\n * bugüne kadar `raw()` içinde yaşıyordu ve `raw()` her deploy'da yeniden\n * koşulan bir DDL bloğu — yani veri düzeltmesi ya elle bir kez çalıştırılıyor\n * (kayıt yok, tekrarı belirsiz) ya da idempotent yazılmak zorunda kalıyordu.\n *\n * `backfills:` o işi kendi aşamasına alır: DDL'den SONRA, kendi işleminde ve\n * ADI BAŞINA BİR KEZ. Kayıt `public.palbase_backfills` tablosunda tutulur, yani\n * \"koştu mu\" sorusunun cevabı veritabanının kendisinde durur.\n */\n\n/** Bir backfill bildirimi — C-6 (FR-033). */\nexport interface BackfillDef {\n name: string;\n sql: string;\n}\n\n/**\n * `backfill(\"<ad>\", \"<sql>\")` — bir kez koşacak veri düzeltmesi.\n *\n * ```ts\n * backfills: [\n * backfill(\"ledger_currency_try\", \"UPDATE ledger SET currency = 'TRY' WHERE currency IS NULL\"),\n * ]\n * ```\n *\n * AD, KAYDIN TA KENDİSİ. \"Bu koştu mu?\" sorusu ada göre cevaplanıyor, gövdeye\n * göre değil: adı sabit tutup SQL'i değiştirmek İKİNCİ bir koşu ÜRETMEZ. Bir\n * düzeltmeyi düzeltmek istiyorsan yeni bir ad verirsin — aynı adın altında\n * değişen bir gövde, canlıda hangi sürümün koştuğunu belirsiz bırakırdı.\n *\n * Bu yüzden BOŞ SQL de reddediliyor: boş bir gövde adı kayda geçirir ve o adı\n * KALICI olarak yakar — sonradan yazılan gerçek SQL \"zaten koştu\" diye hiç\n * çalışmaz, hiçbir yerde hata da vermez.\n *\n * SQL verbatim emit edilir (`raw()` ve `policy().using(\"…\")` ile aynı güven\n * duruşu) ve `raw()` ile AYNI ayrıcalıklı DDL bağlantısında koşar — yalnızca\n * KENDİ AŞAMASINDA, yani DDL'den ayrı bir `Exec`'te. Ayrım budur ve tek başına\n * bir güvenlik iddiası DEĞİLDİR.\n *\n * Bu yorum daha önce \"ayrıcalıklı DDL bağlantısında değil\" diyordu ve YANLIŞTI.\n * Yanlış olduğu ölçüldü, ve niçin kayda geçtiği önemli: tam olarak bir\n * inceleyicinin \"backfill güvenli\" diye geçmesine sebep olacak cümleydi.\n *\n * Bu yüzden gövde `raw()` ile AYNI AST yetki kapısından geçiyor: rol yaratan,\n * sahiplik devreden, yetki dağıtan ya da `search_path` kaydıran bir ifade\n * taşıyan bir backfill push'u reddeder. Veri düzeltmesi veri düzeltmesidir.\n */\nexport function backfill(name: string, sql: string): BackfillDef {\n if (name.trim() === \"\") {\n throw new Error(\n \"backfill(ad, sql): backfill'in adı boş olamaz — 'bir kez koştu' kaydı ADA göre tutuluyor.\",\n );\n }\n if (sql.trim() === \"\") {\n throw new Error(\n `backfill(${name}): SQL boş olamaz — boş bir gövde adı kayda geçirip KALICI olarak yakar; sonradan yazılan gerçek SQL \"zaten koştu\" diye hiç çalışmaz.`,\n );\n }\n return { name, sql };\n}\n","import type { ColumnBuilder } from \"./columns.js\";\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport { PolicyBuilder, check, exprCtx, reservedCanRelation } from \"./policy.js\";\nimport type { CheckDef, PolicyDef, PolicyExprCtx, PolicyExpr, PolicyExprRef } from \"./policy.js\";\nimport type { PalbaseExtension } from \"./extensions.js\";\nimport { ForeignKeyBuilder, FreezeBuilder, REF_TARGET, foreignKey, freeze, toForeignKeyDef, toFreezeDef } from \"./foreign-key.js\";\nimport type { ForeignKeyDef, FreezeDef } from \"./foreign-key.js\";\nimport { GuardBuilder, guard, toGuardDef } from \"./guard.js\";\nimport type { GuardDef } from \"./guard.js\";\nimport { backfill } from \"./backfill.js\";\nimport type { BackfillDef } from \"./backfill.js\";\nimport type { RawConstraintDef } from \"./raw.js\";\nimport type { ChatModelRef, EmbeddingModelRef } from \"./embedding.js\";\n\n/**\n * A map of column builders keyed by column name — the value you write under\n * the `columns` key of `defineTable(\"<name>\", { columns })`.\n *\n * The default `Record<string, ColumnBuilder>` keeps bare references compiling\n * without a type argument.\n */\nexport type ColumnMap = Record<string, ColumnBuilder>;\n\n/**\n * The author-facing value written under each table key:\n * `{ columns, rls?, policies? }`.\n *\n * - `columns`: the column map (required).\n * - `rls`: enable + FORCE row-level security on this table. **Defaults to\n * `true`**, and is forced on when `policies` is non-empty. A table with RLS\n * and no policies is deny-all, which is the starting state: nothing reads it\n * until a policy says who may. Set `rls: false` only for a genuinely public\n * table — it is an explicit opt-out that a reviewer can grep for, not\n * something you get by forgetting.\n * - `policies`: the RLS policies for this table, authored with `policy(name)`.\n * Each entry may be a {@link PolicyBuilder} (the normal `policy(...)` chain)\n * or a raw {@link PolicyDef} object.\n *\n * The `C` type parameter preserves the precise per-column phantom types so the\n * typed `Database.public.*` surface keeps inferring insert/row shapes.\n */\n/** Arama metriği — tek kelime; opclass ve operatör bundan türetilir, asla yüzeye çıkmaz (D-5/D-6). */\nexport type SearchMetric = \"cosine\" | \"euclidean\" | \"inner_product\";\n\n/** Bir vektör arama kolu. `model` varsa auto-embed: platform yazma+sorgu embedding'ini üstlenir (D-9). */\nexport interface VectorSearchDecl {\n /** Hedef vector kolonu; tabloda TEK vector kolonu varsa atlanabilir (Go apply çözer, FR-010). */\n column?: string;\n /** Varsa auto-embed. Deskriptor düz veridir — şemayla serileşir (C-3). */\n model?: EmbeddingModelRef;\n /** model varsa ZORUNLU: embed kaynak kolonları = trigger'ın UPDATE OF listesi (C-2). */\n from?: string[];\n metric?: SearchMetric;\n /** Kaynak metin değişince ara-dönem davranışı (yalnız auto-embed'de):\n * \"null\" (vars.) — embedding anında NULL'lanır; satır yeni vektör yazılana\n * dek anlamsal aramada aday değildir. Bayat eşleşme asla servis edilmez.\n * \"keep\" — eski vektör aramada kalır, platform yenisini yazınca sessizce\n * değişir. Görünürlük penceresi sıfır; bedeli saniyeler süren bayat\n * eşleşme riski (Confluence-tipi sync yükleri için). */\n staleness?: \"null\" | \"keep\";\n}\n\n/** Tablonun arama beyanı — İKİ biçim (D-007, tek yüzey):\n *\n * YENİ (önerilen): `{ from, model, ... }` — `from` kolonları hem FTS'e hem\n * embed'e girer. Tabloda vector kolonu declare edilmişse SATIR-modu; yoksa\n * CHUNK-modu otomatiktir (D-010): vektörler türev `__palbase_chunks`\n * tablosunda yaşar, içerik otomatik bölünür. `text: false` FTS'i kapatır,\n * `text: [..]` FTS kolonlarını from'dan ayırır. `chunks` yalnız ince ayar.\n *\n * ESKİ: `text: string[]` + `vector: {...}` — aynen çalışır, wire çıktısı\n * bayt-aynı kalır (NFR-B1). İki biçim KARIŞTIRILAMAZ. */\nexport interface SearchDecl {\n text?: string[] | boolean;\n vector?: VectorSearchDecl | VectorSearchDecl[];\n /** Yeni biçim: arama kaynağı kolonlar (FTS + embed). Varlığı yeni biçimi seçer. */\n from?: string[];\n /** Yeni biçim: auto-embed modeli (zorunlu — BYO için eski biçimi kullanın). */\n model?: EmbeddingModelRef;\n metric?: SearchMetric;\n staleness?: \"null\" | \"keep\";\n /** Chunk-modu ince ayarı (yalnız vector kolonsuz tabloda anlamlı). */\n chunks?: { size?: number; overlap?: number };\n /** Sorgu-yeniden-yazımı: tek yönlü eş anlamlı haritası (FR-026). */\n synonyms?: Record<string, string[]>;\n /** Geçerlilik kolonları türetilir; arama varsayılan yalnız günceli tarar (FR-029). */\n validity?: boolean;\n}\n\n/** Hafıza beyanı (FR-032, D-019): kaynak tablonun yazımlarından platform\n * fact damıtır ve `into` tablosuna yazar. Hedef NORMAL declared tablodur —\n * kendi search/unique/validity beyanlarıyla. Okuma = Database.$search(into).\n * subject default \"owner\": fact'in kime ait olduğu kolonu (iki tabloda da). */\nexport interface MemoryDecl {\n from: string[];\n into: string;\n extract: ChatModelRef;\n subject?: string;\n}\n\n/**\n * Bir index bildiriminin girdi şekli (FR-041…043).\n *\n * `columns` ile `expression` birbirinin alternatifidir: biri kolon listesi,\n * diğeri `lower(email)` gibi bir ifade. `where` partial index koşuludur ve\n * filtre şekli sorgu tarafındaki `WhereFilter` ile aynıdır — iki ayrı filtre\n * dili olmaz.\n */\n/**\n * Bir index'in TEL şekli — `IndexJSON` ile aynı alanlar (T002).\n *\n * Bildirilmeyen alan HİÇ yazılmaz: sıfır değer yazmak, bildirmeyen her index'i\n * diff'te değişmiş gösterir ve her deploy'a boş bir migration ekler.\n */\nexport interface IndexDef {\n name: string;\n /**\n * `CREATE UNIQUE INDEX` (FR-007). `unique: [{name, columns}]` bir UNIQUE\n * CONSTRAINT üretir ve constraint'in `WHERE`'i olamaz; `index()` partial\n * olabilir ama unique olamıyordu. İki yarım vardı, birleşmiyorlardı.\n */\n unique?: boolean;\n columns?: string[];\n expression?: string;\n where?: PolicyExpr;\n sort?: \"asc\" | \"desc\";\n nulls?: \"first\" | \"last\";\n include?: string[];\n}\n\n/**\n * `index(\"<ad>\")` — C-5 (FR-041…043).\n *\n * ```ts\n * indexes: (c) => [\n * index(\"orders_open\")\n * .on(c.col(\"status\")) // kolon TİPLİ\n * .where(c.col(\"deleted_at\").isNull()) // partial\n * .include([\"total\"]), // covering\n * ]\n * ```\n *\n * `policy()` ile AYNI dili konuşur: `where` politika ifade yapısının ta kendisi.\n * Üçüncü bir filtre lehçesi açmak, aynı sorunun iki yazımı demekti.\n *\n * Kolon bağlamı callback'ten geliyor çünkü index tablo tanımının İÇİNDE\n * bildiriliyor — `orders.status` yazmak, `orders` bağlaması o noktada henüz\n * kurulmadığı için mümkün değil (T015'te `policies` için ölçülen aynı kısıt).\n */\nexport class IndexBuilder {\n readonly _def: IndexDef;\n\n constructor(name: string) {\n if (name.trim() === \"\") {\n throw new Error(\"index(ad): index'in adı boş olamaz — Palbase index'leri ADA göre uzlaştırır.\");\n }\n this._def = { name };\n }\n\n /**\n * `CREATE UNIQUE INDEX` (FR-007). `.where()` ile birlikte PARTIAL UNIQUE\n * index verir (FR-007b) — \"NULL'lar serbest, non-NULL'lar tekil\" kalıbının\n * tek bildirimsel yolu.\n */\n unique(): this {\n this._def.unique = true;\n return this;\n }\n\n /** Index'in kolonları. SIRA KORUNUR — çok kolonlu bir index'in anlamı sırasıdır. */\n on(...cols: PolicyExprRef[]): this {\n this._def.columns = cols.map((c) => {\n const e = c.expr;\n if (e.kind !== \"col\") {\n throw new Error(`index(${this._def.name}).on(): yalnız kolon referansı alır — ifade için onExpression(\"…\") kullanın.`);\n }\n return e.name;\n });\n return this;\n }\n\n /**\n * İfade index'i (`lower(email)`), kolon yerine.\n *\n * Metin VERBATIM emit ediliyor — `policy().using(\"…\")` ile aynı güven duruşu.\n * Tipli yapı bunu ifade edemiyor ve kaçış kapağını kapatmak, yazarı elle\n * migration yazmaya iterdi.\n */\n onExpression(expr: string): this {\n this._def.expression = expr;\n return this;\n }\n\n /** Partial index koşulu — politika ifade dilinin ta kendisi. */\n where(expr: PolicyExprRef): this {\n this._def.where = expr.expr;\n return this;\n }\n\n /** Sıra. Tek yönlü index'te sıra genelde önemsizdir; ORDER BY ile eşleşen\n * bir index arandığında değildir. */\n desc(): this {\n this._def.sort = \"desc\";\n return this;\n }\n\n asc(): this {\n this._def.sort = \"asc\";\n return this;\n }\n\n /** NULL'ların yeri — `ORDER BY … NULLS LAST` ile eşleşmesi için. */\n nulls(where: \"first\" | \"last\"): this {\n this._def.nulls = where;\n return this;\n }\n\n /** Covering index (`INCLUDE`): index-only scan için taşınan ama\n * ARANMAYAN kolonlar. */\n include(cols: string[]): this {\n this._def.include = cols;\n return this;\n }\n}\n\nexport function index(name: string): IndexBuilder {\n return new IndexBuilder(name);\n}\n\nexport interface TableInput<C extends ColumnMap = ColumnMap> {\n columns: C;\n rls?: boolean;\n /**\n * Bu tablonun RLS politikaları — TABLONUN KENDİ KOLONLARININ bir fonksiyonu\n * olarak (FR-022).\n *\n * Callback olmasının sebebi tip: `columns`'tan çıkarılan `C`, TypeScript\n * tarafından buraya bağlamlandırılıyor, yani `p.col(\"ownerr\")` yazım hatası\n * DERLEME hatası oluyor. Düz bir dizide `policy(\"x\")` tek başına çağrıldığı\n * için hangi tabloda olduğunu bilemez, ve yanlış kolon adı ancak deploy\n * anında `CREATE POLICY` çalışırken Postgres'ten dönerdi. Bir RLS\n * politikasında yanlış kolon adı yetki hatasıdır; derlemede yakalanır.\n *\n * ```ts\n * policies: (p) => [\n * policy(\"owner_read\").for(\"select\").using(p.col(\"owner\").eq(p.auth.uid())),\n * ]\n * ```\n */\n policies?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (PolicyBuilder | PolicyDef)[];\n /**\n * KOŞAN SÜRÜMÜN \"BU TABLOYU ARTIK OKUMUYORUM\" SÖZÜ — düşürmenin ilk yarısı.\n *\n * `ColumnDef.ignored`'ın tablo karşılığı ve aynı sebeple var: şema rayı, koşan\n * sürümün hâlâ BEYAN ettiği bir şeyi düşürmeyi reddeder — sıfır satırlı bir\n * tablo için bile, çünkü koşan sürümün bir SELECT'i ona dokunuyor olabilir.\n *\n * ONSUZ TABLO HİÇ DÜŞMÜYORDU (ölçüldü, canlı push 06.09.2026): rayın tavsiyesi\n * *\"beyandan çıkar ve bir kez deploy et\"*ti, ama beyandan çıkarmak düşürmeyi\n * ÜRETEN şeyin ta kendisi — o deploy'da da koşan sürüm tabloyu beyan ediyor\n * olur ve aynı red gelir. Kolonun çıkış yolu vardı, tablonun yoktu.\n *\n * İşaretlemek hiçbir DDL üretmez; ilk deploy'u BEDAVA yapan şey bu.\n *\n * ```ts\n * const cloud_images = defineTable(\"cloud_images\", { ignored: true, columns: { … } });\n * ```\n */\n ignored?: boolean;\n /** Composite/named primary key (ordered column names). Omit for single-column inline .primaryKey(). */\n primaryKey?: string[];\n /** Named multi-column UNIQUE constraints. */\n unique?: { name: string; columns: string[] }[];\n /** Named raw-SQL DDL objects (EXCLUDE, triggers, views) that the typed DSL cannot express. */\n raw?: RawConstraintDef[];\n /**\n * Named first-class CHECK constraints. Diffed by NAME with a BODY compare:\n * a changed `expr` (after pg normalization) recreates the constraint\n * (DROP + ADD). `name` is identifier-validated.\n *\n * İKİ BİÇİM, TEK TEL (FR-009, FR-011):\n *\n * - DİZİ — `expr` verbatim yayılan güvenilen SQL (policy `using` gibi).\n * Bugünkü biçim, olduğu gibi kabul edilmeye devam ediyor.\n * - CALLBACK — `(c) => [check(name, c.col(\"amount\").gt(0))]`: ifade POLİTİKA\n * ifade cebiriyle yazılıyor ve kolon adları DERLEME anında doğrulanıyor.\n * Callback olması bunun şartı: `checks` düz bir dizi olsaydı TypeScript\n * `columns`'tan kolon adlarını çıkarıp ifadeyi onlarla bağlamlandıramazdı.\n *\n * Yanlış yazılmış bir kolon adı string biçiminde ancak\n * `ALTER TABLE … ADD CONSTRAINT` anında — deploy'un ORTASINDA — Postgres'ten\n * dönüyor. Tipli biçim aynı cevabı yazma anına taşıyor.\n *\n * Tipli ifade CHECK bağlamının DAR kümesine tabi: `existsIn` ve `auth.uid()`\n * alt sorgu oldukları için `check()` tarafından reddediliyor (FR-010).\n */\n checks?: CheckDef[] | ((c: PolicyExprCtx<Extract<keyof C, string>>) => CheckDef[]);\n /**\n * Plain (non-unique) btree indexes over an ordered column list, emitted as\n * standalone `CREATE INDEX [IF NOT EXISTS] name ON table (col1, col2)`\n * statements (NOT a table clause — a separate migration statement category).\n * Structural compare by NAME (no expression normalization). `name` and each\n * column are identifier-validated by the Go differ.\n *\n * NAME is the WHOLE diff key. Editing `.where()`, `.onExpression()`,\n * `.include()` or the sort under a name that is already live does NOTHING —\n * the deploy matches the name, sees the index, and skips. Give a changed\n * definition a new name.\n *\n * Scope, via `index(name)`: `.on(...cols)` · `.onExpression(sql)` (expression\n * index) · `.where(pred)` (partial index, typed predicate) · `.unique()`\n * (UNIQUE, and WITH `.where()` a PARTIAL UNIQUE index) · `.include(cols)`\n * (covering) · `.asc()`/`.desc()`/`.nulls()`. Predicates and expressions are\n * probed against the live database before the push — as a prepared statement\n * AND as a real CREATE INDEX on an empty `LIKE` clone, which is what catches\n * a subquery predicate or a non-IMMUTABLE function before the apply.\n *\n * `index(n).unique().where(p)` is the ONE declarative way to say \"NULLs are\n * free, non-NULLs are unique\" — the table-level `unique:` cannot carry a\n * predicate, because it renders a CONSTRAINT and PostgreSQL has no partial\n * unique CONSTRAINT (only a partial unique INDEX).\n *\n * NOT expressible here: another index method (gin/gist/brin/hash), an\n * opclass, or CONCURRENTLY.\n */\n indexes?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (IndexBuilder | IndexDef)[];\n /**\n * Canlıdan DÜŞÜRÜLECEK constraint adları (FR-008).\n *\n * Differ additive: canlıda olup bildirimde olmayan bir constraint asla\n * düşürülmez — beyan dosyası veritabanının nesnelerine sahip değildir. Bu\n * alan o kuralın TEK istisnası ve açıkça yazılmış olması gerekiyor.\n *\n * Ad bilinçli olarak `retired` DEĞİL: bu DSL'de `retired` zaten \"emekliye\n * ayrılmış ÇAĞRI biçimi\" demek (`schema-retired-call.test.ts`).\n */\n dropConstraints?: string[];\n /**\n * Tablo düzeyinde, ÇOK SÜTUNLU FOREIGN KEY'ler (FR-001).\n *\n * Kolon üzerindeki `.references()` tek sütunlu ve tek hedeflidir; çok kiracılı\n * bütünlüğün istediği `FOREIGN KEY (tenant_id, child_id) REFERENCES parent\n * (tenant_id, id)`'yi ifade edemez. İki yol birbirini DÜŞÜRMEZ: bu bildirim\n * kendi adıyla, kolon üzerindekiler `<tablo>_<kolon>_fkey` ile izlenir.\n */\n foreignKeys?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (ForeignKeyBuilder | ForeignKeyDef)[];\n /**\n * KOŞULLU FK'lar — bir koşul sağlandığı sürece donan demetler (FR-012).\n *\n * \"Ödeme `settled` olduğu sürece faturanın tutarı değişemez\" bir trigger\n * istemiyor: koşul sağlanmıyorken NULL veren `STORED` generated sütunlar ve\n * onlardan `ON UPDATE RESTRICT` bir FK, `MATCH SIMPLE`'ın NULL kaçışı\n * üzerinden aynı şeyi CONSTRAINT olarak veriyor.\n *\n * `foreignKeys` ile aynı sebeple callback: `when` yüklemi TABLONUN KENDİ\n * kolonlarından çözülüyor ve yanlış ad derleme hatası oluyor.\n */\n freeze?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (FreezeBuilder | FreezeDef)[];\n /**\n * Bu tablonun GUARD'ları — bildirimsel kısıtın yetişemediği yazma redleri\n * (FR-015).\n *\n * Yazar üç şey yazar: hangi olay · hangi koşul · ne diyerek reddet. `BEFORE`,\n * `FOR EACH ROW`, `SECURITY INVOKER`, pinlenmiş `search_path` ve `UPDATE OF`\n * türetimi güvenli VARSAYILAN — bu yüzeyde görünmezler (FR-017).\n *\n * `policies` ile aynı sebeple callback: koşul TABLONUN KENDİ kolonlarından\n * çözülüyor ve yanlış bir ad derleme hatası oluyor. Bir guard'da yanlış kolon\n * adı, hiç ateşlemeyen bir guard demektir — güvenlik yolunda fail-open.\n */\n guards?: (p: PolicyExprCtx<Extract<keyof C, string>>) => (GuardBuilder | GuardDef)[];\n /**\n * BİR KEZ koşacak veri düzeltmeleri — DDL'den AYRI bir aşamada (FR-033).\n *\n * Sütun eklemek bildirimseldir, o sütunu DOLDURMAK değildir: doldurma bugüne\n * kadar her deploy'da yeniden koşan bir `raw()` bloğunun içindeydi. Burası o\n * işin kendi aşaması; kayıt ada göre tutuluyor ve aynı ad ikinci kez koşmuyor\n * (FR-034).\n *\n * `policies`/`guards`'ın aksine düz bir dizi: bir backfill'in yüklemi yok,\n * gövdesi verbatim SQL — bağlamlandıracak bir kolon adı da yok.\n */\n backfills?: BackfillDef[];\n /**\n * appendOnly (FR-030): tablo yalnız INSERT kabul eder — UPDATE/DELETE hem\n * veritabanı yetkisiyle hem üretilen tipte reddedilir (T017/T018).\n * Ledger deseninin veri katmanından istediği TEK şey budur: bakiye türetilmiş\n * bir değerdir ve entry log'u değiştirilebilirse doğruluğunu kaybeder.\n */\n appendOnly?: boolean;\n /** Arama beyanı — bkz. SearchDecl. */\n search?: SearchDecl;\n /** Hafıza beyanı — bkz. MemoryDecl (FR-032). */\n memory?: MemoryDecl;\n}\n\n/**\n * A table definition — the runtime value the Go runtime's `schema_extract.js`\n * reads. It keys tables by `tableDef.name`, reads `tableDef.columns` for the\n * column DDL, and `tableDef.rls` + `tableDef.policies` for RLS.\n *\n * `defineSchema` derives `name` from the object key, so authors never repeat\n * the table name. `rls`/`policies` are always present after normalization\n * (defaulted to `true`/`[]`).\n *\n * The `C` type parameter preserves the precise per-column phantom types so that\n * downstream mapped types (InsertShape, RowShape) can discriminate on them.\n */\nexport interface TableDef<C extends ColumnMap = ColumnMap> {\n name: string;\n columns: C;\n rls: boolean;\n /** Koşan sürümün \"bu tabloyu okumuyorum\" sözü — bkz. TableInput.ignored. */\n ignored?: boolean;\n policies: PolicyDef[];\n primaryKey?: string[];\n unique?: { name: string; columns: string[] }[];\n /** Named raw-SQL DDL objects emitted verbatim on deploy. Tracked by name. */\n raw?: RawConstraintDef[];\n /** Named first-class CHECK constraints. Diffed by name + (normalized) body.\n * İki yazım biçimi de (dizi / callback) BURAYA iner — bkz. TableInput.checks. */\n checks?: CheckDef[];\n /** Index bildirimleri; partial/expression/sıra/covering alanlarıyla (FR-041…043). */\n indexes?: IndexDef[];\n /** Canlıdan düşürülecek constraint adları (FR-008). */\n dropConstraints?: string[];\n /** Tablo düzeyi çok sütunlu FOREIGN KEY bildirimleri (FR-001). */\n foreignKeys?: ForeignKeyDef[];\n /** Koşullu FK (\"donan demet\") bildirimleri (FR-012). */\n freeze?: FreezeDef[];\n /** Guard bildirimleri — bildirimsel kısıtın yetişemediği yazma redleri (FR-015). */\n guards?: GuardDef[];\n /** Bir kez koşacak veri düzeltmeleri, DDL'den ayrı aşamada (FR-033). */\n backfills?: BackfillDef[];\n /** appendOnly (FR-030) — bkz. TableInput. */\n appendOnly?: boolean;\n /** Arama beyanı, doğrulanmış ve taşınmış hali. */\n search?: SearchDecl;\n /** Hafıza beyanı, doğrulanmış ve taşınmış hali (FR-032). */\n memory?: MemoryDecl;\n}\n\n/**\n * A schema definition containing multiple tables, keyed by table name.\n *\n * The `T` type parameter preserves the exact `TableDef<...>` type for each\n * table so that `SchemaDef[\"tables\"][\"rooms\"]` resolves to the precise\n * `TableDef<{ id: ColumnBuilder<'uuid', false, true, never>; ... }>`.\n */\nexport interface SchemaDef<\n T extends Record<string, TableDef> = Record<string, TableDef>,\n> {\n /** The schema's own name — `public`, `billing`, … Declared, never derived. */\n name: string;\n /** Reachable over HTTP? False unless the author opts in. */\n exposed: boolean;\n tables: T;\n /** Postgres extensions to install on deploy. Normalized to `[]` when absent. */\n extensions: PalbaseExtension[];\n}\n\n/** The author-facing input to `defineSchema` — a `tables` map whose keys are\n * the table names and whose values are `{ columns, rls?, policies? }`, plus an\n * optional `extensions` allowlist. */\nexport interface SchemaInput<\n T extends Record<string, TableInput> = Record<string, TableInput>,\n> {\n tables: T;\n /**\n * Postgres extensions to enable for this project, e.g. `[\"vector\"]`.\n * Config-as-code: installed by the deploy (CREATE EXTENSION … SCHEMA\n * extensions) with the privileged deploy connection. The type is an\n * allowlist union, so unsupported names fail typecheck.\n */\n extensions?: PalbaseExtension[];\n}\n\n/** Map the author's `{ tables: { <name>: { columns } } }` input to the\n * `{ tables: { <name>: TableDef<columns> } }` runtime/type shape, threading the\n * per-table column map `T[K][\"columns\"]` so column-level inference survives. */\ntype TablesByName<T extends readonly TableHandle[]> = {\n [K in T[number] as K[typeof TABLE_META][\"name\"]]: K[typeof TABLE_META];\n};\n\n/** Normalize a single `policies` entry into a plain `PolicyDef` (read off a\n * `PolicyBuilder._def`, or passed through when already a `PolicyDef`). */\nfunction toPolicyDef(p: PolicyBuilder | PolicyDef): PolicyDef {\n return p instanceof PolicyBuilder ? p._def : p;\n}\n\n/**\n * How a schema file reads. One file per schema — `db/public.ts`, `db/billing.ts`\n * — and the schema says its own name:\n *\n * const todos = defineTable(\"todos\", {\n * columns: {\n * id: uuid().primaryKey().defaultRandom(),\n * owner: text().notNull(),\n * title: text().notNull(),\n * },\n * rls: true,\n * policies: (p) => [\n * policy(\"owner_all\").for(\"all\").to(\"authenticated\")\n * .using(p.col(\"owner\").eq(p.auth.uid()))\n * .withCheck(p.col(\"owner\").eq(p.auth.uid())),\n * ],\n * });\n *\n * export default defineSchema(\"public\", { tables: [todos] });\n *\n * The dictionary form `defineSchema({ tables: { todos: {…} } })` is RETIRED and\n * refused by name: a table whose name comes from a key does not know what it is\n * called while it is being built, so it cannot resolve `references(() =>\n * other.id)`, and a schema that does not say its own name cannot tell one\n * `invoices` from another schema's `invoices`.\n *\n * The returned value is `{ name, tables: { todos: { name, columns, rls,\n * policies } }, extensions, exposed }` — the exact shape the runtime schema\n * extractor parses. Per-column phantom types are preserved so\n * `Database.public.todos.insert({...})` stays typed.\n *\n * RLS normalization: `rls` defaults to **`true`**, `policies` to `[]`. A table\n * that declares neither is therefore deny-all — nothing reads it until a policy\n * says who may, which is the safe starting point rather than a bug. Declare\n * `rls: false` for a genuinely public table; that is an explicit, greppable\n * statement of intent instead of an omission. When `policies` is non-empty,\n * `rls` is forced on (ENABLE + FORCE) regardless of the declared flag — a table\n * with policies must have RLS enabled or the policies would be inert.\n */\n/**\n * Where a table's metadata lives.\n *\n * The table VALUE is its columns, so `lists.id` is the column — which means a\n * column called `name` would overwrite the table's own name if metadata sat in\n * a plain field. Measured, not imagined: the existing `users` / `rooms` tests\n * (both declare a `name` column) produced an `[object Object]` table key.\n * `columns`, `rls`, `search`, `memory`, `unique` and `indexes` are all plausible\n * column names too. A column cannot collide with a symbol.\n */\nexport const TABLE_META: unique symbol = Symbol.for(\"palbase.table.meta\");\n\n/** A value produced by `defineTable`: the columns, plus metadata behind the symbol. */\nexport type TableHandle<C extends ColumnMap = ColumnMap, N extends string = string> =\n C & { readonly [TABLE_META]: TableDef<C> & { name: N } };\n\n/**\n * Declare one table as a standalone value that KNOWS ITS OWN NAME.\n *\n * The name lives here, not in a dictionary key. A table whose name comes from a\n * key cannot resolve `references(() => other.id)` when it is built — it does not\n * know what to call itself — which forces a two-phase resolution with an\n * empty-name intermediate state. One name source, no empty identity.\n *\n * The returned object spreads its own columns, so a sibling can point at it:\n * `references(() => lists.id)`.\n */\nexport function defineTable<const N extends string, C extends ColumnMap>(\n name: N,\n input: TableInput<C>,\n): TableHandle<C, N> {\n if (name.trim() === \"\") {\n throw new Error(\"defineTable(name, …): name must not be empty\");\n }\n // `can` bir ilişki adı olarak rezerve (W1 h2-r3 N-2): beyan anında reddedilir,\n // motor/env-gen/can() aynı şeyi üç yerde ayrı ayrı kollamak zorunda kalmasın.\n {\n const reserved = reservedCanRelation(name, input.columns);\n if (reserved !== null) throw new Error(`defineTable(${JSON.stringify(name)}): ${reserved}`);\n }\n // İfade bağlamı TABLONUN KENDİ kolon adlarıyla kuruluyor (FR-022). Çalışma\n // zamanında `col()` adı doğrulamıyor — doğrulayan tip; burada yapılacak\n // ikinci bir kontrol, tipin zaten imkânsız kıldığı bir şeyi tekrar ederdi.\n const policies = (input.policies?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(toPolicyDef);\n // Fail closed. RLS is on unless the author explicitly says `rls: false`, and\n // policies force it on regardless — a policy on a table without RLS enabled is\n // inert, so declaring both resolves towards the safe reading.\n //\n // This defaulted to `false` until 2026-08-07, which meant a table nobody\n // thought about had no row-level security while `typed-db.ts` documented the\n // default `Database.*` path as RLS-enforced. The live proof settled it: user B\n // read user A's row in full through the typed client, while the same request\n // against a table declaring `rls: true` returned 0 of 165 rows. With no\n // policies this is deny-all.\n const rls = policies.length > 0 || input.rls !== false;\n // EACH TABLE GETS ITS OWN COLUMN OBJECTS.\n //\n // A ColumnBuilder shares one `_def` with every builder derived from it, so a\n // shared column — `const audit = { created_at: timestamp() }` spread into two\n // tables, the most ordinary pattern this DSL has — would put BOTH tables'\n // stamps on one object and the second declaration would win. A reference\n // thunk written as `() => a.created_at` then resolved to table `b`: a\n // well-formed foreign key onto the WRONG table, with no error anywhere.\n //\n // Copying is what `.ignored()` already does about the same aliasing, and it\n // keeps the spread pattern working rather than banning it. The copies are\n // what the def AND the handle carry, so the identity match that resolves a\n // reference thunk still finds its column.\n const owned = {} as C;\n for (const [colName, b] of Object.entries(input.columns)) {\n const builder = b as { _def: ColumnDefLike };\n // Same class, same phantom type parameters, its own `_def`. Cloning through\n // the prototype rather than the constructor keeps this file free of a value\n // import from columns.ts — the two modules only ever exchanged types.\n const clone = Object.create(Object.getPrototypeOf(builder)) as { _def: ColumnDefLike };\n Object.defineProperty(clone, \"_def\", { value: { ...builder._def }, enumerable: true, writable: true });\n (owned as Record<string, unknown>)[colName] = clone;\n }\n\n const def = {\n name,\n columns: owned,\n rls,\n policies,\n } as TableDef<C> & { name: N };\n if (input.primaryKey !== undefined) def.primaryKey = input.primaryKey;\n if (input.unique !== undefined) def.unique = input.unique;\n if (input.raw !== undefined && input.raw.length > 0) def.raw = input.raw.slice();\n // İki dal da AYNI `CheckDef[]`'e iniyor (FR-009, FR-011): tipli dal ifadeyi\n // `check()` içinde SQL'e derliyor, string dal yazarın SQL'ini taşıyor. Telde\n // yeni bir alan doğmuyor — `TableJSON.checks` bugünkü `{ name, expr }[]`.\n const declaredChecks =\n typeof input.checks === \"function\"\n ? input.checks(exprCtx(Object.keys(input.columns), 0, name))\n : (input.checks?.slice() ?? []);\n if (declaredChecks.length > 0) def.checks = declaredChecks;\n // İfade bağlamı `policies` ile AYNI — index kolonları da tablonun kendi\n // kolonlarından çözülüyor ve yanlış ad derleme hatası (FR-041).\n const declaredIndexes = (input.indexes?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n (i) => (i instanceof IndexBuilder ? i._def : i),\n );\n if (declaredIndexes.length > 0) def.indexes = declaredIndexes;\n // Tablo düzeyi çok sütunlu FK'lar (FR-001). `toForeignKeyDef` tutarlılığı\n // BURADA doğruluyor: sütun sayıları eşleşmeyen bir bildirim yazarın\n // editöründe patlıyor ve wire'a hiç çıkmıyor. Push'taki red (FR-002) aynı\n // kuralı deploy tarafında tekrar kuruyor — iki kapı, iki farklı okuyucu için.\n const declaredFKs = (input.foreignKeys?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toForeignKeyDef,\n );\n if (declaredFKs.length > 0) def.foreignKeys = declaredFKs;\n // Koşullu FK'lar (FR-012). `toFreezeDef` tutarlılığı burada doğruluyor;\n // `.references()` zaten aynı fonksiyondan geçtiği için düz bir `FreezeDef`\n // yazan yol da aynı kapıdan geçer.\n const declaredFreezes = (input.freeze?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toFreezeDef,\n );\n if (declaredFreezes.length > 0) def.freeze = declaredFreezes;\n // SÜTUN ADLARI BU TABLONUN OLMALI — ve bu kontrol burada, bildirimin yazıldığı\n // yerde. `.columns(...)` serbest `string` alıyor (aynı builder'ın\n // `.references()`'ı tipli), yani bir typo editörde geçiyordu ve bedeli\n // push'ta ya da — yeni bir tabloda, canlı round-trip'in atlandığı yolda —\n // apply'ın ORTASINDA bir `CREATE`/`ALTER` hatası olarak çıkıyordu.\n for (const fz of declaredFreezes) {\n for (const c of fz.columns) {\n if (!(c in input.columns)) {\n throw new Error(\n `table \"${name}\": freeze(\"${fz.name}\").columns(\"${c}\") — no such column on this table. ` +\n `Declared columns: ${Object.keys(input.columns).join(\", \")}`,\n );\n }\n }\n }\n // Guard'lar (FR-015). `toGuardDef` olay/koşul/mesaj üçlüsünü bildirim anında\n // şart koşuyor — eksik bir guard hiç ateşlemeyen bir guard'dır ve güvenlik\n // yolunda sessiz bir fail-open olurdu.\n const declaredGuards = (input.guards?.(exprCtx(Object.keys(input.columns), 0, name)) ?? []).map(\n toGuardDef,\n );\n if (declaredGuards.length > 0) def.guards = declaredGuards;\n // Aynı gerekçe: `refuse(msg, { column })` serbest `string` ve o sütun hem\n // reddin `COLUMN` alanına hem `UPDATE OF` listesine giriyor.\n for (const g of declaredGuards) {\n if (g.column !== undefined && !(g.column in input.columns)) {\n throw new Error(\n `table \"${name}\": guard(\"${g.name}\").refuse(…, { column: \"${g.column}\" }) — no such column on this table. ` +\n `Declared columns: ${Object.keys(input.columns).join(\", \")}`,\n );\n }\n }\n if (input.backfills !== undefined && input.backfills.length > 0) {\n // AYNI AD İKİ KEZ = ikincisi HİÇ koşmaz. Kayıt ada göre tutuluyor\n // (FR-034), yani ikinci bildirim sessizce atlanır ve hiçbir yerde hata\n // vermez. Beyan anında reddetmek bunun tek görünür hâli.\n const seen = new Set<string>();\n for (const b of input.backfills) {\n if (seen.has(b.name)) {\n throw new Error(\n `table ${name}: backfill adı iki kez bildirildi: ${b.name} — kayıt ADA göre tutuluyor, ikincisi hiç koşmazdı.`,\n );\n }\n seen.add(b.name);\n }\n def.backfills = input.backfills.map((b) => ({ name: b.name, sql: b.sql }));\n }\n if (input.dropConstraints !== undefined && input.dropConstraints.length > 0) {\n def.dropConstraints = [...input.dropConstraints];\n }\n if (input.appendOnly === true) def.appendOnly = true;\n // `omitempty` ile aynı sözleşme: işaretlenmemiş tablo alanı HİÇ taşımaz, yani\n // bugüne kadarki her beyanın telde bayt-aynı kalması garanti.\n if (input.ignored === true) def.ignored = true;\n if (input.search !== undefined) {\n const s = input.search;\n // Erken, beyan-anı doğrulama (apply doğrulamasını İKAME ETMEZ — yazım\n // hatası deploy'a gitmeden yazarın yüzüne söylenir).\n if (s.from !== undefined) {\n // YENİ biçim (D-007). Eski alanlarla karışım tek biçime zorlanır:\n // iki yarım beyanın hangisinin kazandığını okuyucu bilemez.\n if (s.vector !== undefined) {\n throw new Error(\n `table ${name}: search beyanında tek biçim kullanın — 'from' (yeni) ile 'vector' (eski) birlikte olamaz`,\n );\n }\n if (s.from.length === 0) {\n throw new Error(`table ${name}: search.from boş olamaz`);\n }\n if (s.model === undefined) {\n throw new Error(\n `table ${name}: search.from model'siz anlamsız — auto-embed için model verin (BYO için eski 'vector' biçimini kullanın)`,\n );\n }\n if (Array.isArray(s.text) && s.text.length === 0) {\n throw new Error(`table ${name}: search.text boş dizi olamaz — FTS istemiyorsan text: false yazın`);\n }\n } else {\n // ESKİ biçim — davranış ve hata metinleri aynen (NFR-B1'in DX yarısı).\n if (typeof s.text === \"boolean\") {\n throw new Error(`table ${name}: text:${String(s.text)} yalnız yeni biçimde ('from' ile) geçerli`);\n }\n if (s.text === undefined && s.vector === undefined) {\n throw new Error(\n `table ${name}: search beyanı boş — en az bir kol (text ya da vector) verin, yoksa alanı hiç yazmayın`,\n );\n }\n if (s.text !== undefined && s.text.length === 0) {\n throw new Error(`table ${name}: search.text boş olamaz — FTS kolu istemiyorsan alanı hiç yazma`);\n }\n const legs = s.vector === undefined ? [] : Array.isArray(s.vector) ? s.vector : [s.vector];\n for (const leg of legs) {\n if (leg.model !== undefined && (leg.from === undefined || leg.from.length === 0)) {\n throw new Error(`table ${name}: search.vector.model beyan edildi ama 'from' yok — embed kaynağı kolonlar zorunlu (C-2)`);\n }\n if (leg.model === undefined && leg.from !== undefined) {\n throw new Error(`table ${name}: search.vector.from model'siz anlamsız — auto-embed için model verin`);\n }\n }\n }\n def.search = s;\n }\n if (input.memory !== undefined) {\n if (input.memory.from.length === 0) {\n throw new Error(`table ${name}: memory.from boş olamaz`);\n }\n def.memory = input.memory;\n }\n // The stamp goes on the COPIES, after the def exists — that is how a\n // reference thunk names its target when `defineSchema` resolves it.\n for (const b of Object.values(owned as Record<string, unknown>)) {\n (b as { _def: { ownerTable?: unknown } })._def.ownerTable = def;\n }\n // Columns are the enumerable surface; metadata hangs off a non-enumerable\n // symbol so it survives spreads and cannot be shadowed by a column name.\n const handle = { ...(owned as Record<string, unknown>) } as TableHandle<C, N>;\n Object.defineProperty(handle, TABLE_META, { value: def, enumerable: false });\n return handle;\n}\n\n/**\n * Which schema declared a table.\n *\n * A `TableDef` cannot carry it: `defineTable` runs before any schema exists, and\n * `defineSchema` is where the answer arrives. It lives OUTSIDE the def rather\n * than on it because the def is serialized — a field here would either leak into\n * the wire shape or need a second rule saying not to. A WeakMap keyed by the def\n * object is the same fact with no surface.\n *\n * It exists because a foreign key names its target and that name is only half a\n * name without the schema. `resolveReferences` reads it to write the referent\n * the way `qualifiedTableKey` writes every other table name.\n */\nconst declaringSchemaOf = new WeakMap<object, string>();\n\n/**\n * Resolve every pending reference thunk.\n *\n * Runs inside `defineSchema`, where all table bindings exist and every table\n * already carries its name — which is why the name lives on the table and not in\n * a dictionary key: resolving against a table that does not yet know what it is\n * called would need a second pass over an empty-name intermediate state.\n *\n * The written referent follows the ONE naming convention (`qualifiedTableKey`):\n * a `public` table is bare, anything else is schema-qualified. The deciding fact\n * is the REFERENT's schema, not whether the key crosses a schema boundary —\n * exactly the CASE Go's introspection uses when it reads a live FK back\n * (`introspect.go`: `CASE WHEN rn.nspname = 'public' THEN rt.relname ELSE\n * rn.nspname || '.' || rt.relname END`). Writing `invoices` for a table that\n * lives in `billing` made Go read it as `public.invoices`: a FK onto a table\n * that does not exist, or — worse and silently — onto a DIFFERENT table that\n * happened to share the name.\n */\nfunction resolveReferences(tables: Record<string, TableDef>, schemaName: string): void {\n for (const table of Object.values(tables)) {\n // ÇAPRAZ ŞEMA HEDEFLERİ: bileşik FK, freeze ve guard'ın `.exists()`'i.\n //\n // Üçü de builder anında yalnız hedefin ADINI biliyordu ve ÇIPLAK yazıyordu.\n // Kolon başına yolun bu satırların hemen altında kapattığı sessizliğin ta\n // kendisi — ve Go tarafındaki bedeli üç katlı: `REFERENCES orders` ya 42P01\n // ya YANLIŞ tabloya FK; `compositeFKEqual` canlının nitelikli adıyla hiç\n // eşleşmiyor (her push DROP+ADD, kalıcı drift); `validateCompositeFKs`\n // anahtar denetimini sessizce atlıyor. Guard'da daha da kötü: gövde ÇALIŞMA\n // ANINDA ayrıştırılıyor, yani hata KULLANICININ yazması sırasında geliyor.\n qualifyRefTargets(table, `table \"${table.name}\"`);\n }\n for (const table of Object.values(tables)) {\n for (const [colName, builder] of Object.entries(table.columns)) {\n const def = (builder as { _def: ColumnDefLike })._def;\n if (def.selfRefColumn !== undefined) {\n if (!(def.selfRefColumn in table.columns)) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": selfReferences(\"${def.selfRefColumn}\") — no such column on this table`,\n );\n }\n // A self-reference is a reference: its referent is this table, in THIS\n // schema, so it is written by the same rule as any other.\n def.references = {\n table: qualifiedTableKey(schemaName, table.name),\n column: def.selfRefColumn,\n };\n continue;\n }\n if (def.referencesThunk === undefined) continue;\n const target = def.referencesThunk();\n const owner = (target as { _def?: ColumnDefLike } | undefined)?._def?.ownerTable;\n if (owner === undefined) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": references(() => …) must point at a column of a table declared with defineTable(...)`,\n );\n }\n const targetColumn = Object.entries(owner.columns).find(\n ([, b]) => (b as { _def: unknown })._def === (target as { _def: unknown })._def,\n )?.[0];\n if (targetColumn === undefined) {\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": the referenced column was not found on table \"${owner.name}\"`,\n );\n }\n const targetSchema = declaringSchemaOf.get(owner);\n if (targetSchema === undefined) {\n // Assuming `public` here is the exact silence this resolution closes:\n // it would produce a FK onto a table that does not exist, or onto a\n // same-named one that does. Name the gap instead.\n throw new Error(\n `table \"${table.name}\" column \"${colName}\": references(() => …) points at table ` +\n `\"${owner.name}\", which no defineSchema(...) has claimed yet — a foreign key cannot ` +\n `be written without its target's schema. Declare that table's schema first ` +\n `(one file per schema: db/public.ts, db/billing.ts …, imported by this one).`,\n );\n }\n def.references = {\n table: qualifiedTableKey(targetSchema, owner.name),\n column: targetColumn,\n };\n }\n }\n}\n\ntype ColumnDefLike = {\n references?: { table: string; column: string };\n referencesThunk?: () => unknown;\n selfRefColumn?: string;\n ownerTable?: { name: string; columns: Record<string, unknown> };\n};\n\n/**\n * Collect declared tables into one schema.\n *\n * Takes an ARRAY, not a dictionary: the tables already carry their names, and a\n * second name source is a second thing that can disagree.\n */\nexport function defineSchema<const T extends readonly TableHandle[]>(\n name: string,\n input: { tables: T; exposed?: boolean; extensions?: PalbaseExtension[] },\n): SchemaDef<TablesByName<T>> {\n // The TYPE first, then the value. The retired one-argument form passes an\n // object here, and a guard that only asks whether the name is blank calls\n // `.trim()` on it — which threw `name.trim is not a function` out of the child\n // process that runs `db/*.ts` during push: no file, no form, nothing to act\n // on. `references(\"t\", \"c\")` already answers its own retirement by name.\n if (typeof name !== \"string\") {\n throw new Error(\n `defineSchema(...) takes the schema NAME first: ` +\n `defineSchema(\"public\", { tables: [todos, lists] }). ` +\n `The one-argument form defineSchema({ tables: { … } }) is gone — a schema that does not ` +\n `say its own name cannot be told apart from another schema's table of the same name, ` +\n `which is what a cross-schema foreign key has to do. ` +\n `Migrate db/public.ts (one file per schema: db/public.ts, db/billing.ts …): name the ` +\n `schema, and lift each table key onto the table itself with ` +\n `defineTable(\"todos\", { columns: { … } }), then list the tables in the array.`,\n );\n }\n if (name.trim() === \"\") {\n throw new Error(\"defineSchema(name, …): name must not be empty\");\n }\n const tables = {} as Record<string, TableDef>;\n for (const handle of input.tables) {\n const table = handle[TABLE_META];\n if (tables[table.name] !== undefined) {\n throw new Error(\n `defineSchema(\"${name}\"): two tables declare the name \"${table.name}\" — table names must be unique within a schema`,\n );\n }\n tables[table.name] = table;\n // Stamped BEFORE resolution: a reference from this schema to a sibling in it\n // must find the sibling's schema, and the sibling may be declared later in\n // the array than the table pointing at it.\n declaringSchemaOf.set(table, name);\n }\n // Thunks are invoked HERE: every binding exists and every name is already set.\n resolveReferences(tables, name);\n // memory beyanları TABLOLAR-ARASI doğrulanır (into/subject/fact) — tüm\n // tablolar kurulduktan sonra: beyan sırasına bağımlılık olmasın (FR-032).\n for (const [name, def] of Object.entries(tables)) {\n const m = (def as TableDef).memory;\n if (m === undefined) continue;\n const target = Object.values(tables).find((t) => (t as TableDef).name === m.into) as TableDef | undefined;\n if (target === undefined) {\n throw new Error(`table ${name}: memory.into \"${m.into}\" şemada declared değil`);\n }\n const subject = m.subject ?? \"owner\";\n if (!(subject in (def as TableDef).columns)) {\n throw new Error(`table ${name}: memory.subject \"${subject}\" kolonu kaynak tabloda yok`);\n }\n if (!(subject in target.columns)) {\n throw new Error(`table ${name}: memory.subject \"${subject}\" kolonu hedef \"${m.into}\" tablosunda yok`);\n }\n const factCol = target.columns[\"fact\"];\n const factDef = factCol !== undefined && \"_def\" in (factCol as object)\n ? (factCol as { _def: { type?: string } })._def\n : (factCol as { type?: string } | undefined);\n if (factDef === undefined || factDef.type !== \"text\") {\n throw new Error(`table ${name}: memory.into \"${m.into}\" tablosunda \"fact\" (text) kolonu zorunlu`);\n }\n for (const c of m.from) {\n if (!(c in (def as TableDef).columns)) {\n throw new Error(`table ${name}: memory.from kolonu \"${c}\" kaynak tabloda yok`);\n }\n }\n }\n // Dedupe + normalize extensions (order-independent; deploy resolves deps).\n const extensions = [...new Set(input.extensions ?? [])];\n // Declaring a schema is not the same as putting it on the internet, so\n // `exposed` is false unless the author says otherwise — EXCEPT for `public`,\n // which is reachable today and stays reachable. Making the default uniform\n // would silently 404 every existing project's /v1/db traffic on upgrade.\n return {\n name,\n tables: tables as TablesByName<T>,\n extensions,\n exposed: input.exposed ?? name === \"public\",\n };\n}\n\nexport { backfill, check, foreignKey, freeze, guard, toForeignKeyDef, toFreezeDef, toGuardDef };\nexport type { BackfillDef, CheckDef, ForeignKeyBuilder, ForeignKeyDef, FreezeBuilder, FreezeDef, GuardBuilder, GuardDef };\n\n/**\n * qualifyRefTargets, bir tablonun taşıdığı çapraz şema hedeflerini ŞEMASIYLA\n * niteler — ve şema bilinmiyorsa REDDEDER.\n *\n * `declaringSchemaOf` `defineSchema` tarafından damgalanıyor, yani bir hedefin\n * şeması ancak o tablo bir şemada bildirilmişse biliniyor. Bilinmiyorsa `public`\n * VARSAYMAK, kolon başına yolun adıyla kapattığı sessizliğin aynısı olurdu:\n * var olmayan bir tabloya ya da aynı adlı BAŞKA bir tabloya referans.\n */\nfunction qualifyRefTargets(table: TableDef, where: string): void {\n const qualify = (holder: { refTable?: string; table?: string }, what: string): void => {\n const target = (holder as { [REF_TARGET]?: TableDef })[REF_TARGET];\n if (target === undefined) return;\n const targetSchema = declaringSchemaOf.get(target);\n if (targetSchema === undefined) {\n throw new Error(\n `${where}: ${what} points at table \"${target.name}\", which no defineSchema(...) has claimed yet — ` +\n `a cross-table reference cannot be written without its target's schema. Declare that table's ` +\n `schema first (one file per schema: db/public.ts, db/billing.ts …, imported by this one).`,\n );\n }\n const qualified = qualifiedTableKey(targetSchema, target.name);\n if (holder.refTable !== undefined) holder.refTable = qualified;\n if (holder.table !== undefined) holder.table = qualified;\n };\n\n for (const fk of table.foreignKeys ?? []) qualify(fk, `foreignKey(\"${fk.name}\")`);\n for (const fz of table.freeze ?? []) qualify(fz, `freeze(\"${fz.name}\")`);\n for (const g of table.guards ?? []) {\n if (g.exists !== undefined) {\n qualifyExistsNodes(g.exists as Record<string, unknown>, `guard(\"${g.name}\").exists(...)`, where);\n }\n }\n}\n\n/** İç içe `exists` düğümlerini de niteler — yüklem başka bir tabloya bakabilir. */\nfunction qualifyExistsNodes(node: Record<string, unknown>, what: string, where: string): void {\n if (node === null || typeof node !== \"object\") return;\n if (node.kind === \"exists\") {\n const target = (node as { [REF_TARGET]?: TableDef })[REF_TARGET];\n if (target !== undefined) {\n const targetSchema = declaringSchemaOf.get(target);\n if (targetSchema === undefined) {\n throw new Error(\n `${where}: ${what} points at table \"${target.name}\", which no defineSchema(...) has claimed yet — ` +\n `a guard body is parsed at RUN TIME under a pinned search_path, so an unqualified name never resolves.`,\n );\n }\n node.table = qualifiedTableKey(targetSchema, target.name);\n }\n }\n for (const v of Object.values(node)) {\n if (Array.isArray(v)) {\n for (const e of v) qualifyExistsNodes(e as Record<string, unknown>, what, where);\n } else if (v !== null && typeof v === \"object\") {\n qualifyExistsNodes(v as Record<string, unknown>, what, where);\n }\n }\n}\n","/**\n * channels.ts — the realtime channel authorization DSL (spec C-5).\n *\n * `defineChannels({...})` is evaluated at bundle load; the declaration is\n * anchored on globalThis under Symbol.for (the error-registry.ts pattern) so\n * the runtime — a separate module instance — reads the SAME object. The runtime\n * empties that slot before each bundle import and puts it back afterwards, so\n * the declaration belongs to the bundle that made it and not to the process.\n * Entry ORDER is the object's key order and is semantic: first match wins.\n *\n * Undeclared channels are DENIED by the server (fail-closed). ownerOnly()\n * patterns resolve with ZERO server hops; custom entries' authorize() runs\n * in the customer's own runtime with the request scope a controller gets.\n */\n\nconst CHANNELS: unique symbol = Symbol.for(\"palbase.backend.channels\") as never;\n\nexport interface ChannelGrant {\n subscribe: boolean;\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n\nexport interface ChannelAuthorizeCtx {\n user: { id: string };\n params: Record<string, string>;\n}\n\ninterface OwnerEntry { kind: \"owner\" }\ninterface PublicEntry {\n kind: \"public\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n}\n/** What a handler receives: who published, on which channel, and what. */\nexport interface ChannelHandlerCtx {\n user: { id: string };\n params: Record<string, string>;\n channel: string;\n event: string;\n payload: Record<string, unknown>;\n}\n\ninterface CustomEntry {\n authorize: (ctx: ChannelAuthorizeCtx) => ChannelGrant | null | Promise<ChannelGrant | null>;\n /**\n * Take over publishes on this channel instead of fanning them out.\n *\n * Without it, `channel.send(...)` is relayed to the other subscribers\n * verbatim — fine for a chat message, wrong for anything the client should\n * not be trusted to assert. A bid, a vote, a game move is a REQUEST, and the\n * result is whatever this function decides and then publishes (through\n * `Realtime.broadcast` or `Realtime.state.set`).\n *\n * A function rather than the name of a route: `authorize` is already one and\n * runs in this same scope, so naming an endpoint would mean inventing a\n * resolution step for no gain.\n */\n handler?: (ctx: ChannelHandlerCtx) => void | Promise<void>;\n}\nexport type ChannelEntry = OwnerEntry | PublicEntry | CustomEntry;\nexport type ChannelsInput = Record<string, ChannelEntry>;\n\nexport interface ChannelsDef {\n entries: Array<{\n pattern: string;\n kind: \"owner\" | \"public\" | \"custom\";\n publish?: boolean;\n state?: { read?: boolean; write?: boolean };\n authorize?: CustomEntry[\"authorize\"];\n handler?: CustomEntry[\"handler\"];\n }>;\n}\n\n/** Full-access-to-the-owner pattern: the pattern must carry EXACTLY one {param};\n * the server compares its value to the verified token subject with zero hops. */\nexport function ownerOnly(): OwnerEntry {\n return { kind: \"owner\" };\n}\n\n/** Anyone with a valid token may subscribe; publish/state are explicit opt-ins. */\nexport function publicChannel(\n opts: { publish?: boolean; state?: { read?: boolean; write?: boolean } } = {},\n): PublicEntry {\n return { kind: \"public\", publish: opts.publish ?? false, state: opts.state };\n}\n\nfunction paramCount(pattern: string): number {\n return pattern.split(\":\").filter((s) => s.startsWith(\"{\") && s.endsWith(\"}\")).length;\n}\n\nexport function defineChannels(map: ChannelsInput): ChannelsDef {\n const entries: ChannelsDef[\"entries\"] = [];\n for (const [pattern, entry] of Object.entries(map)) {\n if (\"kind\" in entry && entry.kind === \"owner\") {\n if (paramCount(pattern) !== 1) {\n throw new Error(\n `defineChannels: ownerOnly() pattern \"${pattern}\" must carry exactly one {param} ` +\n `(its value is compared to the token subject)`,\n );\n }\n entries.push({ pattern, kind: \"owner\" });\n } else if (\"kind\" in entry && entry.kind === \"public\") {\n entries.push({ pattern, kind: \"public\", publish: entry.publish, state: entry.state });\n } else {\n const c = entry as CustomEntry;\n entries.push({ pattern, kind: \"custom\", authorize: c.authorize, handler: c.handler });\n }\n }\n const def: ChannelsDef = { entries };\n\n // A SECOND, DIFFERENT declaration is a hard error rather than an overwrite.\n //\n // The same bundle can legitimately be evaluated twice in one process — the\n // error registry beside this file documents exactly that case — so an\n // identical re-declaration passes silently. But two DIFFERENT declarations\n // mean two channels files, and overwriting would delete the first one's\n // channels. Undeclared channels are DENIED, so the symptom would be joins\n // refused in production for channels the developer can see declared in their\n // own source, with nothing anywhere saying why. Loud here beats silent there.\n //\n // \"Already\" means WITHIN ONE BUNDLE LOAD. The runtime hands each import an\n // empty slot, so this compares two calls from the same bundle — which is what\n // it was written for. It used to reach across imports as well, and then a\n // deploy that merely ADDED a channel was refused as a second channels file,\n // with a message pointing at a file the customer did not have.\n const carrier = globalThis as Record<symbol, unknown>;\n const existing = carrier[CHANNELS] as ChannelsDef | undefined;\n if (existing && !sameDeclaration(existing, def)) {\n throw new Error(\n `defineChannels: channels were already declared (${existing.entries.length} ` +\n `pattern(s): ${existing.entries.map((e) => e.pattern).join(\", \")}). ` +\n `A project declares its channels ONCE — a second call would overwrite the ` +\n `first, and channels nobody declared are refused.`,\n );\n }\n carrier[CHANNELS] = def;\n return def;\n}\n\n/**\n * One entry as the runtime will compile it, rendered for comparison.\n *\n * NORMALIZED, because the runtime normalizes: `collectChannels` applies\n * `?? false` to publish and both state flags before the table goes on the wire.\n * Comparing the raw entries called two spellings of ONE entry a conflict —\n * `publicChannel()` fills `publish: false` where a hand-written\n * `{ kind: \"public\" }` leaves it undefined, and the two produce a byte-identical\n * table. There is one source of truth for what an entry IS, and it is the row.\n *\n * The authorize function is compared by SOURCE TEXT. Comparing the closures\n * themselves is wrong — two evaluations of one module produce two distinct\n * functions for the same source, which is the case this guard has to let\n * through — but comparing only `Boolean(fn)` called two unrelated\n * authorization rules \"the same declaration\", so the guard stayed silent while\n * one channel's access rule was swapped for another's. Same source, same text;\n * different logic, different text. Not exhaustive (two closures over different\n * captured values share a source), and better than a boolean by the whole\n * distance between \"some rule\" and \"this rule\".\n */\nfunction wireRow(e: ChannelsDef[\"entries\"][number]): string {\n return JSON.stringify([\n e.pattern,\n e.kind,\n e.publish ?? false,\n e.state?.read ?? false,\n e.state?.write ?? false,\n // The handler is compared by SOURCE, like authorize: two evaluations of one\n // module give the same text, while different logic gives different text.\n e.handler ? e.handler.toString() : \"\",\n e.authorize ? e.authorize.toString() : \"\",\n ]);\n}\n\n/** Two declarations are the same when they compile to the same rows in the same\n * ORDER — order is semantic here (first match wins). */\nfunction sameDeclaration(a: ChannelsDef, b: ChannelsDef): boolean {\n if (a.entries.length !== b.entries.length) return false;\n return a.entries.every((x, i) => wireRow(x) === wireRow(b.entries[i]!));\n}\n","/**\n * Postgres extensions a Palbase project can enable from its schema.\n *\n * Extensions are config-as-code: declare them in `defineSchema({ extensions })`\n * and the deploy installs them (CREATE EXTENSION … SCHEMA extensions) using the\n * deploy path's privileged connection. They are NOT toggled live from Studio —\n * CREATE EXTENSION requires a superuser role that only the deploy path holds.\n *\n * The list is an allowlist (a string-literal union) so editors autocomplete the\n * supported names and a typo fails typecheck. It is intentionally extensible:\n * add a name here (+ confirm the base image ships it) to support more.\n */\nexport const PALBASE_EXTENSIONS = [\n // Search & text\n \"vector\", // pgvector: AI embeddings + vector similarity search (semantic search / RAG).\n // NB: the Postgres extension is named \"vector\", not \"pgvector\" — declare \"vector\".\n \"pg_trgm\", // trigram fuzzy / typo-tolerant text search\n \"unaccent\", // accent-insensitive text search\n \"citext\", // case-insensitive text type\n // Geospatial / location\n \"cube\", // multi-dimensional cubes (dependency of earthdistance)\n \"earthdistance\", // great-circle distance (needs cube)\n // Data types & structures\n \"hstore\", // key/value pairs in a single column\n \"ltree\", // hierarchical tree-structured labels\n // Indexing & constraints\n \"btree_gist\", // GiST operator classes for scalar types — needed for EXCLUDE\n // constraints that mix \"=\" with a range/&& overlap (e.g. no-double-booking).\n // Scheduling\n // Crypto / ids (also installed by default; listable for explicitness)\n \"pgcrypto\", // cryptographic functions (hashing, encryption)\n \"uuid-ossp\", // UUID generation functions\n] as const;\n\n/** A Postgres extension supported by Palbase (allowlist union). */\nexport type PalbaseExtension = (typeof PALBASE_EXTENSIONS)[number];\n\n/**\n * Extensions that depend on another extension. The deploy installs\n * dependencies first; declaring `earthdistance` without `cube` still works\n * because the deploy resolves the order, but listing both is clearer.\n */\nexport const EXTENSION_DEPENDENCIES: Partial<Record<PalbaseExtension, PalbaseExtension[]>> = {\n earthdistance: [\"cube\"],\n};\n\n/** Runtime guard: is `name` a supported Palbase extension? */\nexport function isPalbaseExtension(name: string): name is PalbaseExtension {\n return (PALBASE_EXTENSIONS as readonly string[]).includes(name);\n}\n","/** On delete action for foreign key references. */\nexport type OnDeleteAction = 'cascade' | 'set null' | 'restrict' | 'no action';\n\n/**\n * The ON DELETE actions permitted on a foreign key to the built-in auth users\n * (`auth.users`). Both let a user's rows be removed (`cascade`) or detached\n * (`set null`) when the account is erased; `restrict` / `no action` would BLOCK\n * erasure and are therefore excluded. This is the CLIENT-SIDE mirror of the\n * server's auth-FK deletion policy — the server (validateAuthUserFK) is the real\n * boundary, this narrows the type so the common mistake is caught at compile time.\n */\nexport type AuthUserOnDelete = Extract<OnDeleteAction, 'cascade' | 'set null'>;\n\n/** Column type identifiers. */\nexport type ColumnType =\n | 'uuid'\n | 'text'\n | 'integer'\n | 'bigint'\n | 'numeric'\n | 'boolean'\n | 'timestamp'\n | 'jsonb'\n | 'enum'\n | 'vector';\n\n/** Base column definition shared by all column types. */\nexport interface ColumnDef {\n type: ColumnType;\n nullable: boolean;\n primaryKey: boolean;\n defaultValue?: unknown;\n defaultRandom?: boolean;\n defaultNow?: boolean;\n references?: { table: string; column: string };\n /** Pending FK target, resolved by `defineSchema` once every binding exists. */\n referencesThunk?: () => ColumnBuilder;\n /** FK onto THIS table — no thunk needed, the target is the declaring table. */\n selfRefColumn?: string;\n /** This column OWNS the row: erasure, RLS and the `owner` relation read it. */\n owns?: true;\n /** Explicit name for the FORWARD relation (child → parent), when the one\n * derived from the column would be ambiguous or unclear. */\n refAs?: string;\n /**\n * Explicit name for the REVERSE relation (parent → children).\n *\n * Separate from {@link refAs} because the two directions are different facts:\n * the forward name describes the parent this row points at (`author`), the\n * reverse one describes the rows hanging off the parent (`posts`). One option\n * naming both made an ordinary schema undeclarable — `posts.author_id` and\n * `comments.author_id` both named `{ as: \"author\" }` collided on `users`, and\n * the refusal asked for the `{ as }` they had both already written.\n */\n reverseAs?: string;\n /** The table this column belongs to; set by `defineTable`. */\n ownerTable?: { name: string; columns: Record<string, ColumnBuilder> };\n /**\n * The name this column used to have. A diff cannot tell a rename from a drop and\n * an add — both leave one name gone and another present — so the intent has to be\n * declared. Without it, renaming a column loses its data.\n */\n renamedFrom?: string;\n /**\n * This release's PROMISE that it does not reference this column — neither\n * reads it nor writes it, and never names it in a filter, a sort or a SET.\n *\n * The contraction gate reads it and nothing else does: dropping a column is\n * refused while the RUNNING release's declaration still lacks this mark, so\n * removing a column is two deploys — mark it, ship, then drop it.\n *\n * The word is `ignored` and not `deprecated` deliberately: RFC 9745 defines\n * deprecation as changing NO behaviour, and this changes what a deploy will\n * accept. Rails calls the same thing `ignored_columns`.\n */\n ignored?: boolean;\n onDeleteAction?: OnDeleteAction;\n /** FR-044: yalnız AÇIKÇA `false` bildirilince var. Türev FK index'ini kapatır. */\n index?: boolean;\n /** FR-049: kolon `increment()` ile güncelleniyor. Plan HOT çakışmasını uyarır. */\n counter?: boolean;\n enumName?: string;\n enumValues?: string[];\n unique?: boolean;\n /**\n * The value is written by the DATABASE — a trigger, a rule, an identity — not by\n * the author and not by a DEFAULT this schema declares. It makes the column\n * optional on INSERT without putting a DEFAULT in the DDL.\n *\n * Before this existed the only way to keep a trigger-filled column off the\n * INSERT type was to give it a fake `default()`: a value the schema claimed to\n * write and the trigger immediately overwrote. That made the schema lie about\n * its own data.\n */\n dbAssigned?: boolean;\n /** vector(n): the declared dimension count — part of the TYPE (typmod), read\n * by the wire serializer and the deploy's auto-index (FR-001). */\n dimensions?: number;\n /**\n * How the stored value is projected in and out of this process (FR-009).\n *\n * NOT part of the DDL: the column's Postgres type is unchanged and this pair\n * is never serialized into a migration. It exists so the row surface can hand\n * back the type the application actually works with.\n */\n /**\n * The named codec this column declares (FR-001). Unlike `transform`, the NAME\n * survives into the runtime object, so `makeEnvDts` can emit the matching\n * TypeScript type instead of falling back to the storage type. Not part of\n * the DDL: the column's Postgres type is unchanged.\n */\n codec?: CodecName;\n transform?: ColumnTransform;\n}\n\n/**\n * The read/write pair a column may declare (FR-009).\n *\n * `fromDb` takes whatever the driver produced for this column and returns the\n * value the application sees; `toDb` is its inverse on the way out. Kept\n * deliberately unexported — a column declares one inline, nobody needs to name\n * the shape.\n */\ninterface ColumnTransform<T = unknown> {\n fromDb: (value: unknown) => T;\n toDb: (value: T) => unknown;\n}\n\n/**\n * The closed set of named column codecs (FR-001).\n *\n * WHY A CLOSED SET rather than `.transform<T>()`. A transform's target type is\n * a TYPE parameter — erased at runtime — so the generator that reads the\n * bundled schema object cannot learn it. `palbase-env.d.ts` therefore said\n * `string` while the engine handed the application a number, and a consumer\n * project wrote a hand-rolled codec module plus 141 call sites to compensate.\n *\n * A codec is NAMED instead of typed: the name lands in `_def.codec`, travels in\n * the runtime object to every reader, and BOTH the conversion and the emitted\n * TypeScript type are derived from it. One declaration, one truth, and no way\n * for the two to disagree.\n */\nexport type CodecName = 'number' | 'decimal';\n\nexport const CODECS: Record<\n CodecName,\n { fromDb: (value: unknown) => unknown; toDb: (value: unknown) => unknown; tsType: 'number' | 'string' }\n> = {\n // Exact-precision column → JS number. Safe below 2^53; a value above it is\n // not representable and the author wants `asDecimal()` instead.\n number: {\n fromDb: (v) => Number(v),\n // YAZMA YOLUNDA SESSİZ BOZULMA YOK. `toDb(9007199254740993)` bir zamanlar\n // \"9007199254740992\" yazıyordu: uygulamanın tuttuğundan BAŞKA bir sayı\n // kolona gidiyordu ve hiçbir şey söylemiyordu. `asNumber()`'ın JSDoc'u\n // \"2^53'ün altında güvenli\" diyordu ama bunu uygulayan bir şey yoktu.\n toDb: (v) => {\n if (typeof v === 'number' && !Number.isSafeInteger(v)) {\n throw new Error(\n `asNumber() cannot write ${v}: it is outside the safe integer range and would be stored as a different number. Declare .asDecimal() and hand this column a string.`,\n );\n }\n return String(v);\n },\n tsType: 'number',\n },\n // Exact-precision column → the string Postgres sent. It exists so the\n // DECLARATION is explicit: \"this column is a decimal I handle as text\",\n // rather than the ABSENCE of a declaration meaning the same thing by default.\n // NULL güvencesi ÇİFTİN KENDİSİNDE. Motor NULL'ı zaten atlıyor (üç ayrı\n // yerde), ama bir değişmez, onu koruyan üç `if`'in DIŞINDA yazılmalı: biri\n // düşerse `String(null)` kolonu \"null\" dizesine çevirirdi.\n decimal: {\n fromDb: (v) => (v === null || v === undefined ? v : String(v)),\n toDb: (v) => (v === null || v === undefined ? v : String(v)),\n tsType: 'string',\n },\n};\n\n/** FR-002: a vector column cannot carry keys/defaults/references — the modifier\n * is named in the error so the author fixes the right line. */\nfunction refuseOnVector(def: ColumnDef, modifier: string): void {\n if (def.type === 'vector') {\n throw new Error(`vector column: .${modifier}() is not supported (FR-002 — allowed: nullable()/notNull())`);\n }\n}\n\n// Phantom brand symbols — never have runtime values; exist only to force\n// TypeScript's structural type system to distinguish ColumnBuilder instances\n// with different type-param combinations. Without these, TS sees all\n// ColumnBuilder<K,...> as structurally identical and the first branch of\n// ColValue matches everything.\ndeclare const __colKind: unique symbol;\ndeclare const __colNullable: unique symbol;\ndeclare const __colHasDefault: unique symbol;\ndeclare const __colEnumValues: unique symbol;\ndeclare const __colPayload: unique symbol;\ndeclare const __colTransform: unique symbol;\n\n/**\n * Fluent column builder with phantom type params:\n * K — ColumnType literal (e.g. \"text\", \"integer\")\n * N — boolean: true when nullable() has been called last (false = NOT NULL)\n * D — boolean: true when a default has been set\n * E — enum value union (never for non-enum columns)\n * P — jsonb payload shape (unknown unless jsonb<T>() supplied one)\n * T — transform target type (`never` when the column declares no transform;\n * `never` is the sentinel because it is the only type that survives\n * `[T] extends [never]` and never collides with a real target type)\n *\n * All six params have defaults so bare `ColumnBuilder` (no args) still\n * satisfies `Record<string, ColumnBuilder>` in schema.ts without modification.\n *\n * The six `declare readonly` brand fields carry the phantom types into the\n * structural shape so that conditional types like ColValue<C> can discriminate\n * on K without requiring runtime values on those fields.\n */\nexport class ColumnBuilder<\n K extends ColumnType = ColumnType,\n N extends boolean = boolean,\n D extends boolean = boolean,\n E = unknown,\n P = unknown,\n // `unknown`, not `never`: the schema's own constraint is a BARE\n // `ColumnBuilder`, whose T lands on this default. With `never` there, a\n // column that declares `.transform<number>()` is not assignable to the\n // constraint at all — `number` does not extend `never` — so a transform\n // could not appear in a schema and the whole table's `RowShape` collapsed.\n // Measured: TS2322 on `defineSchema`.\n T = unknown,\n> {\n // These fields exist only in the type layer (declared, never initialised at\n // runtime — TypeScript allows declared class members without an initializer\n // in strict mode as long as they're never read at runtime).\n declare readonly [__colKind]: K;\n declare readonly [__colNullable]: N;\n declare readonly [__colHasDefault]: D;\n declare readonly [__colEnumValues]: E;\n declare readonly [__colPayload]: P;\n declare readonly [__colTransform]: T;\n\n readonly _def: ColumnDef;\n\n constructor(type: K, existingDef?: ColumnDef) {\n this._def = existingDef ?? {\n type,\n nullable: false,\n primaryKey: false,\n };\n }\n\n /** Mark this column as the primary key. */\n primaryKey(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'primaryKey');\n this._def.primaryKey = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Mark this column as NOT NULL (default). */\n notNull(): ColumnBuilder<K, false, D, E, P, T> {\n this._def.nullable = false;\n return new ColumnBuilder<K, false, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Allow NULL values. */\n nullable(): ColumnBuilder<K, true, D, E, P, T> {\n this._def.nullable = true;\n return new ColumnBuilder<K, true, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Set a default value. */\n default(value: unknown): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'default');\n this._def.defaultValue = value;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** UUID: generate a random default (gen_random_uuid()). */\n defaultRandom(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultRandom');\n this._def.defaultRandom = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Timestamp: default to now(). */\n defaultNow(): ColumnBuilder<K, N, true, E, P, T> {\n refuseOnVector(this._def, 'defaultNow');\n this._def.defaultNow = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * The DATABASE assigns this column's value — a trigger, a rule, an identity.\n *\n * The column becomes optional on INSERT (the author has nothing to send) while\n * the DDL stays free of a DEFAULT this schema would not honour. It is NOT\n * `default()`: that declares a value the schema promises to write.\n *\n * Naming: deliberately not `generated()`. Postgres has GENERATED columns and\n * they are a different thing; borrowing the word would send a reader — or a\n * model writing a schema — to the wrong feature.\n */\n dbAssigned(): ColumnBuilder<K, N, true, E, P, T> {\n this._def.dbAssigned = true;\n return new ColumnBuilder<K, N, true, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a foreign key reference. */\n /**\n * Declares that this column used to be called `previous`.\n *\n * A schema diff sees one name gone and another present; it cannot know whether\n * you renamed a column or dropped one and added another, and the two are very\n * different — the second loses every value. Saying so here turns the plan into\n * `ALTER TABLE … RENAME COLUMN` instead.\n *\n * Once the rename has been applied the annotation is inert (the old name is no\n * longer there to rename), so it can be deleted at your leisure.\n */\n renamedFrom(previous: string): ColumnBuilder<K, N, D, E, P, T> {\n this._def.renamedFrom = previous;\n return this as unknown as ColumnBuilder<K, N, D, E, P, T>;\n }\n\n /**\n * See {@link ColumnDef.ignored}.\n *\n * COPIES the def rather than mutating it. The constructor takes an existing\n * def BY REFERENCE, so every builder derived from another shares one object —\n * `const a = slug.unique()` leaves `a._def === slug._def`. An in-place\n * `ignored = true` therefore marks every column sharing that def, including\n * one another table actively reads, and the gate would let THAT column be\n * dropped. Measured before this copy existed.\n *\n * The aliasing is older than this method and other fields leak through it too.\n * The reason this one cannot wait: every other leak produces a VISIBLE schema\n * difference — the plan shows it, the DDL shows it. This one is invisible by\n * design (no DDL, no diff, no plan line), so its only effect is to disarm a\n * safety gate in silence.\n */\n ignored(): ColumnBuilder<K, N, D, E, P, T> {\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, {\n ...this._def,\n ignored: true,\n });\n }\n\n /**\n * Foreign key onto another table's column.\n *\n * The target is a THUNK, not a direct reference. In a cycle (`x → y`, `y → x`)\n * the second table does not exist yet when the first is built; a direct\n * reference makes TypeScript chase its own tail (TS7022 — measured, and making\n * the return type independent of the target does NOT help). The thunk is\n * invoked in `defineSchema`, where every binding exists and every table\n * already knows its name.\n *\n * In a cycle, ONE side needs an explicit return type:\n * `references((): AnyColumn => y.id)`. One side is enough — measured.\n * For a self-reference use `selfReferences(column)`: no thunk, no annotation.\n *\n * `as` names the FORWARD relation (`author_id` → `author` by default);\n * `reverseAs` names the REVERSE one on the parent, whose default is this\n * table's own name (`users.posts`). Two foreign keys from one table onto one\n * parent therefore need a `reverseAs` on at least one of them — the reverse\n * names would otherwise both be this table's name.\n */\n references(\n target: () => AnyColumn,\n opts?: {\n as?: string;\n reverseAs?: string;\n onDelete?: OnDeleteAction;\n /**\n * Bu FK kolonu için TÜREVİ index üretilsin mi (FR-044). Varsayılan açık.\n *\n * Postgres bir foreign key'i otomatik indekslemez — yalnız hedef\n * taraftaki unique kısıt vardır. Bedeli FK üzerinden her JOIN'de ve her\n * `ON DELETE CASCADE`'de ödenir: bir parent silinirken child tablo tam\n * taranır.\n *\n * `false` demek gerçek bir ihtiyaç, nezaket değil (D-028): FK kolonu aynı\n * zamanda SIK GÜNCELLENEN bir kolonsa index HOT güncellemeyi kırar — ve\n * HOT, DEĞİŞEN kolon indeksliyse kırılır, tablo indeksli diye değil.\n */\n index?: boolean;\n },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'references');\n if (typeof target !== 'function') {\n // Fail where the mistake is. Storing a non-thunk here surfaces three\n // layers later as \"def.referencesThunk is not a function\", inside\n // defineSchema, naming neither the column nor the call that was wrong.\n throw new Error(\n `references(...) takes a callback: write references(() => otherTable.column). ` +\n `The two-string form references(\"table\", \"column\") is gone — a string cannot be type-checked ` +\n `and cannot point at a table that does not exist yet.`,\n );\n }\n this._def.referencesThunk = target;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.reverseAs !== undefined) this._def.reverseAs = opts.reverseAs;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n // Yalnız AÇIKÇA false bildirilince taşınıyor: `undefined` \"bildirilmedi,\n // türet\" demek ve wire'da hiç görünmemeli (bayt-aynılık).\n if (opts?.index === false) this._def.index = false;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Bu kolon `increment()` / `decrement()` ile güncelleniyor (FR-049).\n *\n * Deploy kontrolcü kodunu OKUMAZ, o yüzden bildirimin söylemesi gerekiyor —\n * ve söylediği anda plan bir şeyi görebiliyor: aynı kolon hem sayaç hem\n * indeksliyse her güncelleme HOT'u kaybeder.\n *\n * ZİNCİR (D-028+D-030): HOT kaybı → ölü tuple → autovacuum yükü → ve\n * autovacuum worker'ları KÜME GENELİNDE bir kaynak, yani bedeli başka\n * kiracıların tabloları da öder.\n *\n * Sektörde çare \"dokümana uyarı yaz\"dır, çünkü index'i ekleyen kişi\n * `increment()`'i yazan kişi değildir. Bu bildirimde ikisi de YAN YANA\n * duruyor.\n *\n * Uyarı, HATA DEĞİL: sayaç kolonunu indekslemek bazen doğru karardır.\n */\n counter(): ColumnBuilder<K, N, D, E, P, T> {\n this._def.counter = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Foreign key onto THIS table (`parent_id → id`) — category trees, comment\n * replies, org charts.\n *\n * No thunk and no type annotation: the target table is the one being declared,\n * so there is nothing to defer and nothing for TypeScript to chase in a circle.\n * Drizzle forces an explicit `(): AnyPgColumn =>` here because its reference\n * always goes through a callback; measured, we do not need one.\n */\n selfReferences(\n column: string,\n opts?: { as?: string; onDelete?: OnDeleteAction },\n ): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'selfReferences');\n this._def.selfRefColumn = column;\n if (opts?.as !== undefined) this._def.refAs = opts.as;\n if (opts?.onDelete !== undefined) this._def.onDeleteAction = opts.onDelete;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n\n\n /** Set the ON DELETE action for a foreign key reference. */\n onDelete(action: OnDeleteAction): ColumnBuilder<K, N, D, E, P, T> {\n this._def.onDeleteAction = action;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /** Add a single-column UNIQUE constraint. */\n unique(): ColumnBuilder<K, N, D, E, P, T> {\n refuseOnVector(this._def, 'unique');\n this._def.unique = true;\n return new ColumnBuilder<K, N, D, E, P, T>(this._def.type as K, this._def);\n }\n\n /**\n * Declare how this column's value is projected in and out of the process.\n *\n * The DDL does not move: `numeric` stays `numeric`, and the driver still hands\n * back what Postgres sent. What changes is the type the row surface exposes —\n * it becomes `Target`:\n *\n * amount: numeric().transform<number>({ fromDb: Number, toDb: String })\n *\n * `numeric` surfacing as `string` is CORRECT (a JS number cannot hold\n * arbitrary precision), and that is exactly why this exists: application code\n * that does arithmetic on the column otherwise rewrites the same\n * `Number(row.amount)` / `String(x)` pair in every controller that touches it,\n * and each rewrite is a place the two directions can drift apart.\n *\n * A transform is a PROJECTION, never a constraint: it lives only in this\n * process, so it can neither validate nor migrate what is stored.\n */\n /**\n * Surface this exact-precision column as a JS `number` (FR-001).\n *\n * `numeric`/`bigint` arrive as strings because a JS number cannot hold their\n * full range — correct, and exactly why this exists: application code that\n * does arithmetic on the column otherwise rewrites the same `Number(row.x)` /\n * `String(v)` pair in every caller, and each rewrite is a place the two\n * directions can drift apart.\n */\n asNumber(): ColumnBuilder<K, N, D, E, P, number> {\n return this.withCodec<number>('number', 'asNumber');\n }\n\n /**\n * Surface this exact-precision column as a `string` — the value Postgres\n * sent, DECLARED rather than defaulted (FR-001).\n */\n asDecimal(): ColumnBuilder<K, N, D, E, P, string> {\n return this.withCodec<string>('decimal', 'asDecimal');\n }\n\n private withCodec<Target>(codec: CodecName, method: string): ColumnBuilder<K, N, D, E, P, Target> {\n if (this._def.type !== 'bigint' && this._def.type !== 'numeric') {\n throw new Error(\n `${this._def.type} column: .${method}() is only available on bigint()/numeric() — ` +\n `those are the exact-precision types that surface as string.`,\n );\n }\n if (this._def.transform !== undefined) {\n throw new Error(\n `.${method}() and .transform() are two ways to say the same thing on one column — keep .${method}().`,\n );\n }\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares .as${this._def.codec === 'number' ? 'Number' : 'Decimal'}(); a column has ONE codec.`,\n );\n }\n // KOPYA, MUTASYON DEĞİL — `ignored()` gibi.\n //\n // `this._def.codec = codec` yazmak, ORTAK bir temelden çatallanan iki\n // kolonun ikisine de SON codec'i verirdi. Ölçüldü:\n // const money = numeric().notNull();\n // money.asNumber(); money.asDecimal();\n // → ikisinin de _def.codec === 'decimal', ve AYNI nesne.\n // Birincinin TİPİ `number`, üretecin bastığı tip `string` olurdu — yani bu\n // özelliğin kapatmak için var olduğu ayrışmanın ta kendisi.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n codec,\n });\n }\n\n transform<Target>(fns: ColumnTransform<Target>): ColumnBuilder<K, N, D, E, P, Target> {\n // AYNA KONTROLÜ. `asNumber()` mevcut bir transform'u reddediyor; burası da\n // mevcut bir codec'i reddetmeli, yoksa kapı TEK YÖNLÜ olur:\n // `numeric().asNumber().transform<Date>(…)` üç ayrı cevap üretirdi —\n // builder tipi `Date`, üretilen tip `number`, motor `Number()` uygular —\n // ve hiçbir şey adını söyleyerek reddetmezdi.\n if (this._def.codec !== undefined) {\n throw new Error(\n `column already declares a named codec; .transform() and .as*() are two ways to say the same thing — keep the codec.`,\n );\n }\n // The cast is the variance, not a shortcut: `toDb` takes `Target`, and a\n // `ColumnTransform<unknown>` would have to accept anything. The stored pair\n // is only ever called with this column's own values.\n return new ColumnBuilder<K, N, D, E, P, Target>(this._def.type as K, {\n ...this._def,\n transform: fns as ColumnTransform,\n });\n }\n}\n\n// ---------------------------------------------------------------------------\n// Type extractors — imported by Task 2 to derive insert/row shapes.\n// ---------------------------------------------------------------------------\n\n/**\n * Extracts the TypeScript value type for a column, respecting nullability.\n * - \"uuid\" | \"text\" | \"timestamp\" | \"bigint\" | \"numeric\" → string (or string | null when N = true)\n * Note: bigint/numeric surface as string — JS number loses precision past 2^53,\n * and pgx/PostgREST serialize int8/numeric as strings. App code uses\n * BigInt(row.amount) for bigint, or a decimal lib for numeric.\n * - \"integer\" → number\n * - \"boolean\" → boolean\n * - \"jsonb\" → P (the dev-supplied payload shape from jsonb<T>(), else unknown)\n * - \"enum\" → E (the union of literal values)\n *\n * A declared `.transform<T>()` OVERRIDES the table above: the column then\n * surfaces as T (or T | null when nullable), because that is the value the\n * application is handed. Nullability is still the column's, not the\n * transform's — `fromDb` is not called for a NULL.\n */\nexport type ColValue<C> =\n C extends ColumnBuilder<ColumnType, infer N, boolean, unknown, unknown, infer T>\n ? [unknown] extends [T]\n ? ColStoredValue<C>\n : N extends true\n ? T | null\n : T\n : never;\n\n/** The value as the DATABASE hands it over — the branch table above, before any\n * transform. This is what a column's `fromDb` receives. */\ntype ColStoredValue<C> =\n C extends ColumnBuilder<'uuid' | 'text' | 'timestamp' | 'bigint' | 'numeric', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? string | null\n : string\n : C extends ColumnBuilder<'integer', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number | null\n : number\n : C extends ColumnBuilder<'boolean', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? boolean | null\n : boolean\n : C extends ColumnBuilder<'jsonb', infer N, infer _D, infer _E, infer P>\n ? N extends true\n ? P | null\n : P\n : C extends ColumnBuilder<'vector', infer N, infer _D, infer _E, infer _P>\n ? N extends true\n ? number[] | null\n : number[]\n : C extends ColumnBuilder<'enum', infer N, infer _D, infer E, infer _P>\n ? N extends true\n ? E | null\n : E\n : never;\n\n/**\n * True when a column is optional on INSERT:\n * - nullable columns (N = true) — the DB allows NULL so the field may be omitted\n * - columns with a default (D = true) — the DB fills in the value when absent\n */\nexport type ColIsOptionalOnInsert<C> =\n C extends ColumnBuilder<ColumnType, true, boolean, unknown, unknown, unknown>\n ? true\n : C extends ColumnBuilder<ColumnType, boolean, true, unknown, unknown, unknown>\n ? true\n : false;\n\n// ---------------------------------------------------------------------------\n// Factory functions\n// ---------------------------------------------------------------------------\n\n/** Create a UUID column. */\nexport function uuid(): ColumnBuilder<'uuid', false, false, never> {\n return new ColumnBuilder('uuid');\n}\n\n/** Create a TEXT column. */\nexport function text(): ColumnBuilder<'text', false, false, never> {\n return new ColumnBuilder('text');\n}\n\n/** Create an INTEGER column. Emits int4 (max ~2.1B). */\nexport function integer(): ColumnBuilder<'integer', false, false, never> {\n return new ColumnBuilder('integer');\n}\n\n/**\n * Create a BIGINT column (Postgres int8, max ~9.2×10^18).\n * Surfaces as `string` in row/insert types — JS number loses precision past 2^53\n * and pgx/PostgREST serialize int8 as a JSON string. Use BigInt(row.column) in app code.\n */\nexport function bigint(): ColumnBuilder<'bigint', false, false, never> {\n return new ColumnBuilder('bigint');\n}\n\n/**\n * Create a NUMERIC column (Postgres `numeric`/`decimal`, arbitrary precision).\n * For exact fractional values (money with cents as a decimal, rates, weights)\n * where int4/int8 don't fit. Surfaces as `string` in row/insert types — JS\n * number can't hold arbitrary-precision decimals without rounding, and\n * pgx/PostgREST serialize numeric as a JSON string. Parse with a decimal lib\n * (or BigInt for scaled integers) in app code.\n */\nexport function numeric(): ColumnBuilder<'numeric', false, false, never> {\n return new ColumnBuilder('numeric');\n}\n\n/** Create a BOOLEAN column. */\nexport function boolean(): ColumnBuilder<'boolean', false, false, never> {\n return new ColumnBuilder('boolean');\n}\n\n/** Create a TIMESTAMP column. */\nexport function timestamp(): ColumnBuilder<'timestamp', false, false, never> {\n return new ColumnBuilder('timestamp');\n}\n\n/**\n * Create a JSONB column. Pass a payload type to make the generated row/insert\n * type concrete instead of `unknown`:\n *\n * tags: jsonb<string[]>() // row.tags: string[]\n * meta: jsonb<{ tier: string }>() // row.meta: { tier: string }\n * raw: jsonb() // row.raw: unknown (back-compat)\n *\n * The runtime accepts a plain JS object/array directly (no JSON.stringify); the\n * generic only refines the TYPE the env codegen emits.\n */\nexport function jsonb<T = unknown>(): ColumnBuilder<'jsonb', false, false, never, T> {\n return new ColumnBuilder('jsonb');\n}\n\n/**\n * Create an ENUM column.\n * @param name The PostgreSQL enum type name (used in DDL).\n * @param values A readonly tuple of valid string values — kept `const` so the\n * union `V[number]` is as narrow as possible.\n */\nexport function enumType<const V extends readonly string[]>(\n name: string,\n values: V,\n): ColumnBuilder<'enum', false, false, V[number]> {\n const builder = new ColumnBuilder<'enum', false, false, V[number]>('enum');\n builder._def.enumName = name;\n builder._def.enumValues = [...values];\n return builder;\n}\n\n/** vector(n) — pgvector kolonu. n TİPİN parçasıdır (typmod) ve [1, 2000] —\n * 2000 = pgvector'ün HNSW-indekslenebilir tavanı; auto-index bu beyanla bağlı\n * (spec FR-001, D-3). */\nexport function vector(dimensions: number): ColumnBuilder<'vector', false, false, unknown, number[]> {\n if (!Number.isInteger(dimensions) || dimensions < 1 || dimensions > 2000) {\n throw new Error(`vector(): dimensions must be an integer in [1, 2000], got ${String(dimensions)}`);\n }\n const b = new ColumnBuilder('vector') as ColumnBuilder<'vector', false, false, unknown, number[]>;\n (b._def as { dimensions?: number }).dimensions = dimensions;\n return b;\n}\n\n/**\n * Any column, whatever its type parameters.\n *\n * Exported so a cycle can be broken from ONE side:\n * `references((): AnyColumn => y.id)`.\n */\nexport type AnyColumn = ColumnBuilder;\n\n/**\n * The column that OWNS this row: a `text` FK onto `auth.users(id)`, NOT NULL,\n * ON DELETE CASCADE.\n *\n * Ownership drives account erasure, so cascade is the only correct action and\n * takes no argument. The referencing column must be `text` (palauth ids are\n * `usr_<uuid>`) and NOT NULL — both are implied here rather than left to the\n * caller, so three rules the type could not express before become UNWRITABLE.\n *\n * At most ONE per table. The old shape let several columns reference\n * `auth.users` and picked the FIRST IN DECLARATION ORDER as the owner — moving a\n * `created_by` above a `user_id` silently changed which rows an account deletion\n * took with it. A second one is now rejected at push.\n *\n * For a column that merely POINTS at a user without owning the row\n * (`created_by`, `edited_by`), use `userRef({ onDelete })`.\n */\nexport function ownedByUser(): ColumnBuilder<'text', false, false, never> {\n const b = new ColumnBuilder<'text', false, false, never>('text');\n b._def.nullable = false;\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = 'cascade';\n b._def.owns = true;\n return b;\n}\n\n/**\n * A plain FK onto `auth.users(id)` that does NOT own the row.\n *\n * `created_by` / `edited_by`: deleting that user must not delete the row. ON\n * DELETE is required and limited to `cascade | set null` so an erasure request\n * is never blocked by a lingering FK; `set null` needs a nullable column.\n */\nexport function userRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.users', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\n}\n\n/**\n * A plain FK onto `auth.installations(id)` — the app-scoped verified-device\n * anchor.\n *\n * An installation is an APP INSTALL, not a user: this is NOT ownership. A\n * user-owned row still needs its own `ownedByUser()` so account erasure removes\n * it; an installation reference alone does not tie a row to a user's deletion.\n */\nexport function installationRef(opts: { onDelete: AuthUserOnDelete; as?: string }): ColumnBuilder<'text', boolean, false, never> {\n const b = new ColumnBuilder<'text', boolean, false, never>('text');\n b._def.references = { table: 'auth.installations', column: 'id' };\n b._def.onDeleteAction = opts.onDelete;\n if (opts.as !== undefined) b._def.refAs = opts.as;\n return b;\n}\n","/**\n * A named raw-SQL DDL object declared in a schema file (`db/public.ts`,\n * `db/billing.ts`, …) for what the typed DSL cannot express: an index method\n * other than btree (`gin`, `gist`, `brin`, `hash`), an opclass, `CONCURRENTLY`,\n * `EXCLUDE` constraints, views, and PL/pgSQL functions.\n *\n * REACH FOR THE TYPED FIELD FIRST. Most of what this list used to name is\n * declarative today and should not come through here:\n * - a CHECK constraint → `checks: [{ name, expr }]`, or the typed\n * `checks: (c) => [check(name, c.col(\"n\").gt(0))]`\n * - a partial index → `index(n).on(…).where(…)`\n * - an expression index → `index(n).onExpression(\"lower(email)\")`\n * - a covering index → `index(n).on(…).include([…])`\n * - a UNIQUE or PARTIAL UNIQUE index → `index(n).unique().where(…)`\n * - a composite FOREIGN KEY → `foreignKeys: (c) => [foreignKey(n).on(…).references(…)]`\n * - a conditional FK → `freeze: (c) => [freeze(n).when(…).columns(…).references(…)]`\n * - a trigger that refuses a write → `guards: (g) => [guard(n).on(…).refuse(…)]`\n * - a one-off data fix → `backfills: [backfill(name, sql)]`\n * - dropping a constraint → `dropConstraints: [\"name\"]`\n * Those are diffed, validated against the live database before the push, and\n * their mistakes answer you where you write them. A `raw()` is none of that.\n *\n * The deploy emits `up` verbatim on the privileged DDL connection — same trust\n * posture as policy().using(). How a CHANGED body is treated depends on what\n * `name` addresses:\n * - names a constraint or an index → tracked by NAME only; the deploy sees\n * the catalog object and skips, so an edited body does nothing. Use a new\n * name, or drop and re-add explicitly.\n * - names nothing in the catalog (functions, triggers, grants, compound\n * statements) → the last applied body is recorded in\n * `public.palbase_raw_objects` in the same DDL transaction, and an edited\n * body IS re-applied.\n *\n * There is no teardown option — not on the call, and not on this type. One used\n * to be accepted and was carried into a generated `Down` that NOTHING ever ran:\n * the engine's `MigrationFiles.Down` has no consumer and the rollback path names\n * a `runner.go` that does not exist, so an author who wrote one believed they had\n * a teardown they did not have. `raw()` stopped ACCEPTING it first, and the field\n * outlived the parameter — an object literal (`raw: [{ name, up, down }]`) still\n * compiled and still set a field nothing read. Drop what a `raw()` created by\n * declaring the drop as its own `raw()`.\n */\nexport interface RawConstraintDef {\n name: string;\n up: string;\n}\n\nexport function raw(name: string, up: string): RawConstraintDef {\n return { name, up };\n}\n","/** Embedding sağlayıcı DESKRIPTORU — canlı istemci değil, düz veri: şemayla\n * birlikte serileşir, çağrıyı Go worker (yazma) ve engine (sorgu) yapar.\n * Adlandırma Vercel AI SDK'nın aynasıdır (openai.embedding(\"...\")) ama paket\n * bağımlılığı bilinçli olarak YOKTUR (spec C-3, UD-016). v1 sağlayıcı: openai (D-10). */\nexport interface EmbeddingModelRef {\n provider: \"openai\";\n model: string;\n dimensions?: number;\n apiKeyName?: string;\n baseURL?: string;\n}\n/** Chat/damıtma modeli DESKRIPTORU (C-11, D-019) — memory beyanının extract'i.\n * Embedding gibi düz veridir; çağrıyı worker yapar, anahtar vault'taki\n * OPENAI_API_KEY'dir (D-017: aynı sağlayıcı, yeni dış sistem yok). */\nexport interface ChatModelRef {\n provider: \"openai\";\n model: string;\n}\nexport const openai = {\n embedding(\n model: string,\n opts?: { dimensions?: number; apiKeyName?: string; baseURL?: string },\n ): EmbeddingModelRef {\n return { provider: \"openai\", model, apiKeyName: opts?.apiKeyName ?? \"OPENAI_API_KEY\",\n ...(opts?.dimensions !== undefined ? { dimensions: opts.dimensions } : {}),\n ...(opts?.baseURL !== undefined ? { baseURL: opts.baseURL } : {}) };\n },\n chat(model: string): ChatModelRef {\n return { provider: \"openai\", model };\n },\n};\n","/** PostgreSQL protocol identifiers, shared by error mapping and retry policy. */\nexport const SQLSTATE = Object.freeze({\n serializationFailure: \"40001\",\n deadlockDetected: \"40P01\",\n queryCancelled: \"57014\",\n commandGuardFailed: \"PBC01\",\n} as const);\n\n/** These errors confirm that PostgreSQL aborted the transaction. A connection\n * failure does not: the COMMIT may already have succeeded. */\nexport function isTransactionRollbackState(state: unknown): boolean {\n return state === SQLSTATE.serializationFailure || state === SQLSTATE.deadlockDetected;\n}\n","import { SQLSTATE, isTransactionRollbackState } from \"./db/sqlstate.js\";\n\n/**\n * The brand that identifies an HttpError ACROSS SDK instances.\n *\n * A process legitimately holds more than one copy of this SDK — the runtime\n * loads the engine from its own node_modules while the tenant's bundle carries\n * an inlined copy, which is why the controller registry and the error registry\n * are both anchored on `Symbol.for`. The one place that did not follow the\n * pattern was the engine's catch: `err instanceof HttpError` compares CLASS\n * IDENTITY, so a `throw new NotFound()` from the bundle's copy did not match\n * the engine's copy and every typed error in every deployed backend degraded to\n * `500 internal_error`. Measured through the edge on a real deploy: a route\n * throwing `NotFound` answered 500 while the runtime's own log printed the\n * error object with `status: 404` right beside it.\n *\n * `Symbol.for` puts this in the cross-realm registry, so every copy of the SDK\n * agrees on it by VALUE rather than by identity.\n */\nexport const HTTP_ERROR_BRAND: unique symbol = Symbol.for(\"palbase.backend.httpError\");\n\n/**\n * Set on an `HttpError` the ENGINE built out of a driver failure, as opposed to\n * one the author constructed to ANSWER a request.\n *\n * The distinction cannot be read off the status, and 409 is why. The scaffold\n * teaches `throw new Conflict(\"title already taken\")` as the way to answer\n * (template/AGENTS.md), and the engine raises `UniqueViolation` — also a 409 —\n * when a write hits a unique index. Logging by status therefore either loses the\n * engine's event or writes an \"unhandled\" line every time an author takes the\n * documented path. Measured: it did the second.\n *\n * `Symbol.for` so the mark survives the bundle/runtime SDK split, the same way\n * {@link HTTP_ERROR_BRAND} does.\n */\nexport const ENGINE_RAISED: unique symbol = Symbol.for(\"palbase.backend.engineRaised\") as never;\n\n/** Mark `e` as engine-raised and return it, so a conversion site reads as one expression. */\nexport function markEngineRaised<E extends object>(e: E): E {\n (e as Record<symbol, unknown>)[ENGINE_RAISED] = true;\n return e;\n}\n\n/** Whether the engine built this error, rather than the author throwing it to answer. */\nexport function isEngineRaised(e: unknown): boolean {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[ENGINE_RAISED] === true;\n}\n\n/**\n * Whether a thrown value is an HttpError from ANY copy of this SDK.\n *\n * The shape is checked as well as the brand: the brand says \"this claims to be\n * one of ours\", the fields say the envelope can actually be built from it, and\n * a half-formed object must fall through to the 500 path rather than produce a\n * malformed response.\n */\nexport function isHttpError(err: unknown): err is HttpError {\n if (typeof err !== \"object\" || err === null) return false;\n const e = err as Record<PropertyKey, unknown>;\n return (\n e[HTTP_ERROR_BRAND] === true &&\n typeof e.status === \"number\" &&\n typeof e.error === \"string\" &&\n typeof e.errorDescription === \"string\"\n );\n}\n\n/** HTTP error with structured error response format.\n *\n * The base class for the throwable error classes (`PalError`, `Conflict`,\n * `NotFound`, …). Construct one directly with `throw new HttpError(404,\n * \"todo_not_found\", \"No such todo\")`, or throw a named subclass\n * (`throw new NotFound(\"todo not found\")`). The runtime catches any `HttpError`\n * and emits the standard envelope; on the wire (and to iOS) it surfaces as\n * `BackendError.server(code, status, message, requestId)`.\n *\n * The optional `data` field carries a structured payload alongside the\n * standard envelope — for errors that need to ship extra context\n * (e.g. `new Conflict(\"locked\", \"title_locked\", { retryAfter: 30 })`). It rides\n * through to the iOS typed enum's associated value.\n */\nexport class HttpError extends Error {\n public readonly status: number;\n public readonly error: string;\n public readonly errorDescription: string;\n public readonly data?: unknown;\n /** See {@link HTTP_ERROR_BRAND} — how the engine recognises this across SDK copies. */\n public readonly [HTTP_ERROR_BRAND] = true;\n\n constructor(status: number, error: string, errorDescription: string, data?: unknown) {\n super(errorDescription);\n this.name = \"HttpError\";\n this.status = status;\n this.error = error;\n this.errorDescription = errorDescription;\n if (data !== undefined) {\n this.data = data;\n }\n }\n\n /**\n * Serialize to the standard Palbase error response format.\n * The `requestId` is injected by the runtime layer from the request context.\n * When called without arguments (e.g. JSON.stringify), request_id is omitted.\n * When `data` is set, it is appended as a strict-superset field.\n */\n toJSON(requestId?: string): {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } {\n const result: {\n error: string;\n error_description: string;\n status: number;\n request_id?: string;\n data?: unknown;\n } = {\n error: this.error,\n error_description: this.errorDescription,\n status: this.status,\n };\n if (requestId) {\n result.request_id = requestId;\n }\n if (this.data !== undefined) {\n result.data = this.data;\n }\n return result;\n }\n}\n\n/**\n * Throw with a custom HTTP status + wire code. The general-purpose escape hatch\n * when none of the named classes (`Conflict`/`NotFound`/…) fits.\n *\n * @example\n * throw new PalError(418, \"teapot\", \"I'm a teapot\");\n */\nexport class PalError extends HttpError {\n constructor(status: number, code: string, description: string, data?: unknown) {\n super(status, code, description, data);\n this.name = \"PalError\";\n }\n}\n\n/** Base for the named status classes. Each subclass fixes its HTTP status; the\n * `code` defaults to the class's canonical wire code (overridable), and the\n * `message` defaults to a human-readable label (overridable). */\nabstract class NamedHttpError extends HttpError {\n protected constructor(\n status: number,\n defaultCode: string,\n name: string,\n message?: string,\n code?: string,\n data?: unknown,\n ) {\n super(status, code ?? defaultCode, message ?? defaultMessage(name), data);\n this.name = name;\n }\n}\n\n/** Derive a default human-readable message from a class name\n * (\"NotFound\" → \"Not found\", \"TooManyRequests\" → \"Too many requests\"). */\nfunction defaultMessage(name: string): string {\n const spaced = name.replace(/([a-z0-9])([A-Z])/g, \"$1 $2\");\n return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();\n}\n\n/**\n * 400 — the request was malformed or failed validation. Carries a fixed typed\n * payload: `new BadRequest({ fields: [{ field: \"email\", message: \"invalid\" }] })`.\n * The shape is declared once in the SDK so codegen surfaces `error.data.fields`\n * typed on the client.\n */\nexport class BadRequest extends NamedHttpError {\n public declare readonly data: BadRequestData;\n constructor(data: BadRequestData, message?: string) {\n super(400, \"bad_request\", \"BadRequest\", message, undefined, data);\n }\n}\n\n/** 401 — the caller is not authenticated. */\nexport class Unauthorized extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(401, \"unauthorized\", \"Unauthorized\", message, code, data);\n }\n}\n\n/** 403 — the caller is authenticated but not allowed. */\nexport class Forbidden extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(403, \"forbidden\", \"Forbidden\", message, code, data);\n }\n}\n\n/** 404 — the requested resource does not exist. */\nexport class NotFound extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(404, \"not_found\", \"NotFound\", message, code, data);\n }\n}\n\n/** 409 — the request conflicts with the current state. */\nexport class Conflict extends NamedHttpError {\n constructor(message?: string, code?: string, data?: unknown) {\n super(409, \"conflict\", \"Conflict\", message, code, data);\n }\n}\n\n/**\n * 409 — a write was refused because it would duplicate an existing row.\n * Carries the NAME of the unique constraint Postgres named (`users_email_key`).\n *\n * The engine produces it: a statement rejected with SQLSTATE `23505` is\n * converted here rather than surfacing as an opaque driver error (see\n * `engine/db.ts`, `diagnosingDriver`). What that removes is the string match —\n * before this, the only way to act on a duplicate was to test the driver\n * message for \"duplicate key value violates unique constraint\", a contract\n * nobody signed that breaks on a Postgres upgrade, a locale, or a constraint\n * rename, silently and in production.\n *\n * THE NAME IS A FIELD AND STAYS OUT OF THE DEFAULT MESSAGE. The two are not\n * the same audience. `constraint` is read by the code that catches this — the\n * developer, who already knows the schema. `errorDescription` is the HTTP\n * response body, and an UNCAUGHT duplicate puts it in front of the\n * application's end user: `users_email_key` there discloses how the schema is\n * built to whoever sent the request. The platform's own data API took the same\n * decision one surface over and wrote down why —\n * `v2/internal/modules/database/internal/handler/pgerror.go:83-87` collapses\n * every 23xxx to a generic conflict, \"never disclose the constraint/column\n * name\". A thrower who WANTS the name on the wire passes it deliberately\n * (`new UniqueViolation(c, \\`\\${c} already exists\\`)`, or through `data`).\n *\n * @example\n * try {\n * await Database.public.users.insert({ email });\n * } catch (e) {\n * if (UniqueViolation.is(e) && e.constraint === \"users_email_key\") {\n * throw new Conflict(\"That email is taken\", \"email_taken\");\n * }\n * throw e;\n * }\n */\nexport class UniqueViolation extends Conflict {\n /**\n * Whether `e` is a unique violation — REGARDLESS of which copy of this SDK\n * constructed it.\n *\n * Use this instead of `instanceof`. Measured on a live stack: a controller\n * bundle INLINES its own copy of `@palbase/backend`, and the engine that\n * raises this error is the runtime's copy. Two copies, two class identities,\n * and `e instanceof UniqueViolation` is false in the one place a caller\n * writes it — a check that reads as correct and silently never matches.\n */\n static is(e: unknown): e is UniqueViolation {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { name?: unknown }).name === \"UniqueViolation\" &&\n typeof (e as { constraint?: unknown }).constraint === \"string\"\n );\n }\n\n /** The unique constraint the statement violated, as Postgres named it.\n * `\"\"` when the driver did not say which — see `engine/db.ts`. */\n public readonly constraint: string;\n\n constructor(constraint: string, message?: string, code?: string, data?: unknown) {\n super(message ?? \"Unique constraint violated\", code ?? \"unique_violation\", data);\n this.name = \"UniqueViolation\";\n this.constraint = constraint;\n }\n}\n\n/**\n * Eşzamanlılık yüzünden BAŞARISIZ OLAN, ama TEKRAR DENENİRSE başarılı olabilecek\n * hataların ortak yüzeyi (FR-036).\n *\n * `retryable: true` bir tahmin değil, Postgres'in söylediği şey: `40001` ve\n * `40P01` \"bu işlemi baştan çalıştır\" anlamına gelir. Kümenin DAR tutulması\n * kasıtlı — `23505` buraya girseydi, tekrar denemek aynı cevabı verir ve\n * döngü sonsuza kadar dönerdi.\n */\nexport interface RetryableError extends Error {\n readonly retryable: true;\n /** Beş karakterlik SQLSTATE — hangi eşzamanlılık hatası olduğunu SÖYLER. */\n readonly sqlstate: string;\n}\n\n/**\n * `e` tekrar denenebilir mi?\n *\n * `instanceof` DEĞİL şekil kontrolü — ve sebebi ÖLÇÜLMÜŞ (bkz. {@link\n * UniqueViolation.is}): bir controller bundle'ı kendi `@palbase/backend`\n * kopyasını inline'lıyor, hatayı fırlatan motor ise runtime'ın kopyası. İki\n * sınıf kimliği, ve `e instanceof SerializationFailure` yazan tek yerde\n * sessizce hiç eşleşmiyor.\n */\nexport function isRetryable(e: unknown): e is RetryableError {\n return (\n typeof e === \"object\" &&\n e !== null &&\n (e as { retryable?: unknown }).retryable === true &&\n isTransactionRollbackState((e as { sqlstate?: unknown }).sqlstate)\n );\n}\n\n/**\n * `40001 serialization_failure` — SERIALIZABLE ya da REPEATABLE READ altında\n * eşzamanlı bir işlem bu işlemi geçersiz kıldı.\n *\n * D-016: bu hata BLOKLANMIYOR, FIRLATILIYOR. Retry'sız bir izolasyon\n * yükseltmesi sunmak defect'tir — kullanıcıya çalışmayan bir düğme vermektir:\n * SERIALIZABLE'a çıkıp `40001`'i yakalamayan kod, önceden çalışan işlemleri\n * rastgele kaybetmeye başlar.\n */\nexport class SerializationFailure extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is SerializationFailure {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"SerializationFailure\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.serializationFailure, message?: string, data?: unknown) {\n super(\n message ??\n \"işlem eşzamanlı bir işlemle serileştirilemedi — aynı işlemi baştan çalıştırın \" +\n \"(karar okumaları ve yazmaları $atomic içine alıp { retry: n } verin)\",\n \"serialization_failure\",\n data,\n );\n this.name = \"SerializationFailure\";\n this.sqlstate = sqlstate;\n }\n}\n\n/**\n * `40P01 deadlock_detected` — iki işlem birbirinin kilidini bekliyordu;\n * Postgres birini seçip iptal etti.\n *\n * Bu hatayı GÖRMEK bir tasarım sinyali: kilit sırası deterministik değilse\n * tekrar denemek yalnız maliyeti öteler. Sırayı sabitleyen üç şey var ve\n * hangisinin geçerli olduğunu ELİNDEKİ belirler: satırların id'leri elindeyse\n * `Database.$lockRows(tablo, id'ler)`, elinde bir FİLTRE varsa\n * `Database.$lockRowsWhere(tablo, filtre)` (FR-037 — birincil anahtara göre\n * sıralayarak kilitler, yani `updateMany` ile aynı sırayı paylaşır), ya da çok\n * satırlı yazmanın CTE'si (FR-015).\n */\nexport class DeadlockDetected extends Conflict implements RetryableError {\n public readonly retryable = true as const;\n public readonly sqlstate: string;\n\n static is(e: unknown): e is DeadlockDetected {\n return (\n typeof e === \"object\" && e !== null &&\n (e as { name?: unknown }).name === \"DeadlockDetected\"\n );\n }\n\n constructor(sqlstate: string = SQLSTATE.deadlockDetected, message?: string, data?: unknown) {\n super(\n message ??\n \"deadlock: iki işlem birbirinin kilidini bekledi ve bu işlem iptal edildi — \" +\n \"kilit sırasını sabitleyin: id'ler elinizdeyse Database.$lockRows(tablo, id'ler), \" +\n \"elinizde bir filtre varsa Database.$lockRowsWhere(tablo, filtre) kullanın\",\n \"deadlock_detected\",\n data,\n );\n this.name = \"DeadlockDetected\";\n this.sqlstate = sqlstate;\n }\n}\n\n/** A single field-level validation failure carried by {@link BadRequest}. */\nexport interface FieldError {\n /** The offending field's name (dotted path for nested fields). */\n field: string;\n /** Human-readable reason the field failed. */\n message: string;\n}\n\n/** The fixed, typed payload {@link BadRequest} ships. */\nexport interface BadRequestData {\n /** The fields that failed validation. */\n fields: FieldError[];\n}\n\n/** The fixed, typed payload {@link TooManyRequests} ships. */\nexport interface TooManyRequestsData {\n /** Seconds the caller should wait before retrying. */\n retryAfter: number;\n}\n\n/**\n * 429 — the caller has exceeded the rate limit. Carries a fixed typed payload:\n * `new TooManyRequests({ retryAfter: 30 })`. The shape is declared once in the\n * SDK (error-registry pre-seed) so codegen surfaces `error.data.retryAfter`\n * typed on the client — no per-project definition needed.\n */\nexport class TooManyRequests extends NamedHttpError {\n public declare readonly data: TooManyRequestsData;\n constructor(data: TooManyRequestsData, message?: string) {\n super(429, \"too_many_requests\", \"TooManyRequests\", message, undefined, data);\n }\n}\n","/**\n * typed-db.ts — Task 2: TypedDB schema-derived insert/row shapes.\n *\n * Derives INSERT and full-row TypeScript types from a `defineSchema()` result\n * and wraps the untyped runtime `DBClient` with a typed facade.\n *\n * No value-any. No `as unknown as X`. The two narrow `as` casts in\n * `makeTypedTable` are safe because:\n * - `data as Record<string, unknown>`: InsertShape<T> maps string keys to\n * typed values; all value types are subsets of `unknown`, so the cast is\n * structurally sound.\n * - `result as RowShape<T>`: The runtime DBClient returns `Record<string,\n * unknown>` which is the erased form of the typed row; we're narrowing back\n * to the precise shape that the schema declared.\n * Both casts are narrowing only (not widening) and correctness is guaranteed\n * by the schema the caller provides.\n */\n\nimport type { ColValue, ColIsOptionalOnInsert, ColumnBuilder } from \"./columns.js\";\nimport type { TableDef, SchemaDef } from \"./schema.js\";\nimport type { Tables, Schemas, TableTypes } from \"./env.js\";\nimport type { DBClient, DBOps, AtomicClient } from \"../endpoint.js\";\nimport type { RecoOps } from \"../runtime.js\";\nimport type { Materialized, TxPlanHandle, TxTable, TxColumnExpr, TxNow } from \"./tx-plan.js\";\nimport { TxPlanBuilder, runTxPlan } from \"./tx-plan.js\";\nimport { isColRef, brandRef } from \"./input-guards.js\";\nimport { isRetryable } from \"../errors.js\";\nimport { retryBudget, type AtomicOptions } from \"./transaction-options.js\";\nimport { qualifiedTableKey } from \"./schema-json.js\";\n\n// ---------------------------------------------------------------------------\n// Key discriminators — split a column map into required vs optional keys.\n// ---------------------------------------------------------------------------\n\n/** Keys of C whose columns are required on INSERT (not nullable, no default). */\ntype RequiredKeys<C> = {\n [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? never : K;\n}[keyof C];\n\n/** Keys of C whose columns are optional on INSERT (nullable or has a default). */\ntype OptionalKeys<C> = {\n [K in keyof C]: ColIsOptionalOnInsert<C[K]> extends true ? K : never;\n}[keyof C];\n\n// ---------------------------------------------------------------------------\n// Public shape types — exported so callers can reference them directly.\n// ---------------------------------------------------------------------------\n\n/**\n * The TypeScript type for an INSERT payload for table `T`.\n * - Required: columns that are NOT NULL and have no DB-level default.\n * - Optional: columns that are nullable or carry a default.\n *\n * When all columns are optional, `RequiredKeys<C>` resolves to `never` and\n * the first part becomes `{}`, which is a neutral element for `&`.\n */\nexport type InsertShape<T extends TableDef> = {\n [K in RequiredKeys<T[\"columns\"]>]: ColValue<T[\"columns\"][K]>;\n} & {\n [K in OptionalKeys<T[\"columns\"]>]?: ColValue<T[\"columns\"][K]>;\n};\n\n/**\n * The TypeScript type for a full row returned by the DB for table `T`.\n * Every column is present; nullable columns resolve to `T | null`.\n */\nexport type RowShape<T extends TableDef> = {\n [K in keyof T[\"columns\"]]: ColValue<T[\"columns\"][K]>;\n};\n\n// ---------------------------------------------------------------------------\n// TypedTable + TypedDB interfaces.\n// ---------------------------------------------------------------------------\n\n/** A typed table accessor that mirrors the runtime DBClient surface. */\nexport interface TypedTable<T extends TableDef> {\n /** Runtime validates the key against the installed schema. Generated env tables\n * also check the complete unique/composite key at compile time. */\n findUnique<K extends keyof RowShape<T> = keyof RowShape<T>>(q: {\n where: Partial<RowShape<T>>; select?: readonly K[];\n }): Promise<Pick<RowShape<T>, K> | null>;\n page<K extends keyof RowShape<T> = keyof RowShape<T>>(\n q?: PageInput<RowShape<T>, K>,\n ): Promise<import(\"./page.js\").Page<Pick<RowShape<T>, K>>>;\n insert(data: InsertValues<InsertShape<T>>): Promise<RowShape<T>>;\n /** Çok satır, TEK statement. Satırların anahtar kümesi aynı olmalı. */\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts: import(\"./bulk.js\").InsertManyOptions & { returning: false }): Promise<number>;\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions & { returning?: true }): Promise<RowShape<T>[]>;\n insertMany(rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions): Promise<RowShape<T>[] | number>;\n put(q: { data: InsertShape<T>; onConflict: readonly string[] }): Promise<RowShape<T>>;\n /** Update the row by id; resolves to the updated row, or `null` if no row\n * matched (absent or RLS-hidden) — an idempotent outcome, mirroring\n * `findById`. The runtime returns a null row rather than throwing. */\n update(q: { where: { id: string }; set: SetShape<InsertShape<T>> }): Promise<RowShape<T> | null>;\n delete(id: string): Promise<void>;\n findById(id: string): Promise<RowShape<T> | null>;\n /** Rows matching the filter. Operators, ordering and paging are the ENGINE's\n * surface — this declaration is what makes them callable. */\n findMany<K extends keyof RowShape<T> = keyof RowShape<T>>(\n q?: QueryInput<RowShape<T>, K>,\n ): Promise<Pick<RowShape<T>, K>[]>;\n /**\n * Update every matching row in one statement; an empty filter is refused.\n *\n * **0 satır dönmesi hata DEĞİL, başarı da değil** (FR-014): koşulu `where`'e\n * koyup dönen diziyi kontrol etmek, \"önce oku sonra yaz\"ın yarış koşulu\n * olmayan hâlidir.\n *\n * ```ts\n * const [row] = await Database.public.accounts.updateMany({\n * where: { id, balance: { gte: amount } },\n * set: { balance: decrement(amount) },\n * });\n * if (row === undefined) throw new Conflict(\"yetersiz bakiye\");\n * ```\n */\n updateMany<const Q extends MutateInput<RowShape<T>, InsertShape<T>>>(\n q: Q,\n ): Promise<Q extends { returning: false } ? number : RowShape<T>[]>;\n /** Delete every matching row; resolves to how many. Empty filter refused. */\n deleteMany(q: { where: WhereFilter<RowShape<T>> | SqlFragment }): Promise<number>;\n /**\n * Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.\n *\n * ```ts\n * const r = await Database.public.entries.aggregate({\n * where: { account_id },\n * sum: [\"amount_kurus\"],\n * count: true,\n * });\n * r.sum.amount_kurus; // string | null — KAYIPSIZ\n * r.count; // number\n * ```\n *\n * `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS\n * `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres\n * boş kümede NULL döndürür — \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı.\n *\n * `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.\n */\n aggregate<const Q extends AggregateInput<RowShape<T>>>(\n q: Q,\n ): Promise<AggregateResult<Q, RowShape<T>>>;\n /** How many rows match. An empty filter is legitimate: counting is a read. */\n count(q?: { where?: WhereFilter<RowShape<T>> | SqlFragment }): Promise<number>;\n}\n\n/** A typed DB facade covering all tables declared in schema `S`. */\nexport interface TypedDB<S extends SchemaDef> {\n diagnostics: DBOps[\"diagnostics\"];\n command<T>(fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n tables: {\n [K in keyof S[\"tables\"]]: TypedTable<S[\"tables\"][K]>;\n };\n /** Run a transaction plan. See {@link EnvTypedDatabase.transaction}. */\n transaction<T>(\n fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T,\n ): Promise<Materialized<T>>;\n}\n\n/** The plan-building handle a `TypedDB<S>` transaction callback receives: the\n * schema's tables, expressed as plan operations rather than awaited calls.\n *\n * YALNIZ `tables`, ve ÇALIŞMA ZAMANI DA yalnız onu veriyor.\n *\n * Bir süre runtime `{ tables, public }` döndürüyordu ama tip yalnız `tables`\n * söylüyordu: `tx.public.x` derlenmiyor, koşsaydı çalışacaktı — tipin çalışma\n * zamanından AZ söylemesi (gözcü M-8). Tipe `public` EKLEMEK yanlış düzeltmeydi\n * ve `check:api` onu adıyla reddetti: `TypedTx` dışa açık, ve zorunlu bir üye\n * eklemek onu İNŞA EDEN müşterinin kodunu kırar — \"the new shape demands more\n * than the recorded one\". Yalan runtime'dan kaldırılarak kapatıldı; ikisi artık\n * aynı şeyi söylüyor. `Database.$transaction`'ın `tx.public`'i ayrı bir yüzey\n * (`TxPlan`) ve orada tip de runtime da onu taşıyor. */\nexport type TypedTx<S extends SchemaDef> = TxPlanHandle<{\n [K in keyof S[\"tables\"]]: TxTable<RowShape<S[\"tables\"][K]>, InsertShape<S[\"tables\"][K]>>;\n}>;\n\n// ---------------------------------------------------------------------------\n// Runtime factory.\n// ---------------------------------------------------------------------------\n\n/**\n * Builds a typed table accessor that delegates every call to `raw` using the\n * runtime table name string. Two narrow `as` casts bridge the mapped-type\n * shapes to/from `Record<string, unknown>` — see module-level doc comment.\n *\n * The `raw` param is typed `DBOps` (the six string-keyed ops) because this only\n * ever calls those — never `txPlan`, which builds its own operations rather than\n * delegating to these.\n */\nfunction makeTypedTable<T extends TableDef<Record<string, ColumnBuilder>>>(\n name: string,\n raw: DBOps,\n): TypedTable<T> {\n return {\n insert: (data: InsertShape<T>) =>\n raw.insert(name, data as Record<string, unknown>) as Promise<RowShape<T>>,\n\n aggregate: ((q: Record<string, unknown>) =>\n raw.aggregate(name, q)) as TypedTable<T>[\"aggregate\"],\n\n insertMany: ((rows: readonly InsertValues<InsertShape<T>>[], opts?: import(\"./bulk.js\").InsertManyOptions) =>\n raw.insertMany(name, rows as readonly Record<string, unknown>[], opts)) as TypedTable<T>[\"insertMany\"],\n\n put: (q: { data: InsertShape<T>; onConflict: readonly string[] }) =>\n raw.put(name, q.data as Record<string, unknown>, { onConflict: q.onConflict }) as Promise<RowShape<T>>,\n\n update: (q: { where: { id: string }; set: Partial<InsertShape<T>> }) =>\n raw.update(name, q.where.id, q.set as Record<string, unknown>) as Promise<RowShape<T> | null>,\n\n delete: (id: string) => raw.delete(name, id),\n\n findUnique: ((q: { where: Record<string, unknown>; select?: readonly string[] }) =>\n raw.findUnique(name, q.where, { select: q.select })) as TypedTable<T>[\"findUnique\"],\n findById: (id: string) =>\n raw.findById(name, id) as Promise<RowShape<T> | null>,\n\n page: (q?: PageInput<RowShape<T>>) => {\n const { where, ...opts } = q ?? {};\n return raw.page(name, where as Record<string, unknown> | undefined, opts as import(\"./page.js\").RawPageOptions) as Promise<import(\"./page.js\").Page<RowShape<T>>>;\n },\n findMany: (q?: QueryInput<RowShape<T>>) => {\n // `where` AYIKLANIR: kalan alanlar (orderBy/limit/offset) opts'a gider.\n // Tümünü opts diye geçirmek `where`'i tel üstünde İKİ KEZ gönderirdi.\n const { where, ...opts } = q ?? {};\n return raw.findMany(\n name,\n where as Record<string, unknown> | undefined,\n opts as Parameters<typeof raw.findMany>[2],\n ) as Promise<RowShape<T>[]>;\n },\n\n updateMany: ((q: MutateInput<RowShape<T>, InsertShape<T>>) =>\n raw.updateMany(\n name,\n q.where as Record<string, unknown>,\n q.set as Record<string, unknown>,\n q.returning === undefined ? undefined : { returning: q.returning },\n )) as TypedTable<T>[\"updateMany\"],\n\n deleteMany: (q: { where: WhereFilter<RowShape<T>> | SqlFragment }) =>\n raw.deleteMany(name, q.where as Record<string, unknown>),\n\n count: (q?: { where?: WhereFilter<RowShape<T>> }) =>\n raw.count(name, q?.where as Record<string, unknown> | undefined),\n };\n}\n\n/**\n * Wraps a raw `DBClient` with the type-safe `TypedDB<S>` facade derived from\n * the provided schema. No behavior change for the direct ops — all calls\n * delegate to `raw` with the table name as a plain string.\n *\n * `transaction` does NOT delegate to a per-op client: the callback describes a\n * plan against a fresh {@link TxPlanBuilder}, and the whole plan travels in one\n * `raw.txPlan` call. The schema is used only for its table NAMES; the values\n * are typed by `S` at compile time and are plain strings at run time.\n *\n * The `as` casts are single structural narrowings from a dynamically-built\n * object to the precise mapped type (TS cannot infer the mapped-type result\n * through `Object.keys` iteration) — see the module-level doc comment.\n */\nexport function makeTypedDB<S extends SchemaDef>(\n schema: S,\n raw: AtomicClient,\n): TypedDB<S> {\n const tables = {} as Record<string, TypedTable<TableDef>>;\n for (const key of Object.keys(schema.tables)) {\n const tableDef = schema.tables[key];\n if (tableDef !== undefined) {\n tables[key] = makeTypedTable(qualifiedTableKey(schema.name, tableDef.name), raw);\n }\n }\n\n const result = {\n tables,\n diagnostics: () => raw.diagnostics(),\n command<T>(fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n const planTables = Object.fromEntries(Object.entries(schema.tables).map(([key, table]) => [key, builder.table(qualifiedTableKey(schema.name, table.name))]));\n return runTxPlan({ txPlan: plan => raw.command(plan, options) }, { tables: planTables } as TypedTx<S>, builder, fn) as Promise<Materialized<T>>;\n },\n transaction<T>(\n fn: (tx: TypedTx<S>) => T extends Promise<unknown> ? never : T,\n ): Promise<Materialized<T>> {\n const builder = new TxPlanBuilder();\n const planTables: Record<string, unknown> = {};\n for (const key of Object.keys(schema.tables)) {\n const tableDef = schema.tables[key];\n if (tableDef !== undefined) planTables[key] = builder.table(qualifiedTableKey(schema.name, tableDef.name));\n }\n // Two narrowings at the same seam: the plan tables are built by NAME, so\n // TS cannot see the mapped type through the loop, and the driver erases\n // the callback's return type (see runTxPlan's doc). Both are the erasure\n // this facade exists to undo.\n // `runTxPlan` artık TUTAMAĞIN TAMAMINI alıyor (şema yüzeyi dahil).\n //\n // Burada tutamak YALNIZ `tables` taşıyor, çünkü `TypedTx<S>` de yalnız\n // onu söylüyor. Bir ara `public`'i de veriyordu ve tip onu bilmiyordu —\n // çalışma zamanının tipten FAZLA sunması da bir yalan. `makeTypedDB` tek\n // şemalı bir cephe; çok şemalı yüzey `Database.$transaction`.\n return runTxPlan(\n raw,\n { tables: planTables } as TypedTx<S>,\n builder,\n fn,\n ) as Promise<Materialized<T>>;\n },\n };\n\n // Narrow cast: `result.tables` is structurally identical to\n // TypedDB<S>[\"tables\"] — each key maps to a TypedTable for the matching\n // TableDef. TS cannot infer the mapped-type result through Object.keys\n // iteration, so a single `as` bridges the gap.\n return result as TypedDB<S>;\n}\n\n// ---------------------------------------------------------------------------\n// Env-augmentation-driven typed surface — the typed-by-default `Database`.\n//\n// These types read the globally-augmented `Tables` interface from\n// `@palbase/backend/env` (filled by the generated `palbase-env.d.ts`). They\n// back `Database.public.<name>` so handler code is typed with no import and no\n// generic (C5). They DELIBERATELY do not reference `ColumnBuilder` — the env\n// `Tables` interface carries flat `row`/`insert` object types.\n// ---------------------------------------------------------------------------\n\n/** Bir where değeri: düz eşitlik YA DA operatör nesnesi (FR-016). */\n/**\n * Metin operatörleri YALNIZ metin kolonlarında görünür (FR-005).\n *\n * `contains` bir sayı kolonunda anlamsızdır ve onu tipte sunmak \"ifade edilemez\n * kıl\" ilkesinin tersidir: derleme anında yakalanabilecek bir hata çalışma\n * zamanına ertelenir. Koşullu tip ÖZYİNELEMESİZDİR (N-2).\n */\n/**\n * Bir KOLONA yapılan referans (FR-011) — karşılaştırmanın sağ tarafında değer\n * yerine durabilen tek şey.\n *\n * Şekli okunabilir (`{ $col: \"…\" }`) ama KİMLİĞİ şekli değil: nesne\n * `Symbol.for(\"palbase.db.ref\")` ile markalanır. Şekil tek başına yetseydi\n * güvenilmeyen bir istek gövdesi `{\"$col\":\"tenant_id\"}` gönderip kiracılık\n * predikatını `t.\"tenant_id\" = t.\"tenant_id\"` totolojisine çevirebilirdi —\n * ölçüldü (W2-A/C1). Marka enumerable olmadığı için JSON round-trip'i onu\n * düşürür; süreç içinde (transaction planı dahil) korunur.\n */\nexport type ColRef<N extends string = string> = { readonly $col: N };\n\nexport { isColRef };\n\n/**\n * `total > amount_paid` — bugün bunu yazmanın tek yolu ham SQL'e düşmekti,\n * çünkü sağ taraf bir DEĞER değil.\n *\n * Ad literal olarak yakalanır (`const N`), ve doğruluğu ÇAĞRIDA değil\n * KULLANIM YERİNDE kanıtlanır: filtre `WhereFilter<Row>` beklediği için\n * `ColRef<\"yok_boyle\">` oraya atanamaz. Yani `col()`'a satır tipini elle\n * vermek gerekmiyor, yanlış ad yine de derleme hatası (P5).\n *\n * Dönen nesne MARKALIDIR (`brandRef`): telden gelen `{\"$col\":\"x\"}` bir kolon\n * referansı SAYILMAZ, \"bilinmeyen operatör\" diye reddedilir. Gerekçe\n * `db/input-guards.ts`'te ölçümüyle birlikte yazılı.\n */\nexport function col<const N extends string>(name: N): ColRef<N> {\n return brandRef({ $col: name }, \"col\");\n}\n\n/** Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri. */\n/**\n * Bir kolonun karşılaştırma AİLESİ — ve neden PG tipi değil de bu.\n *\n * ÖLÇÜLDÜ (gözcü, canlı pg16): TS tarafı PG tipini TAŞIMIYOR. `numeric`,\n * `bigint`, `text`, `uuid` ve `timestamp` hepsi `string`'e, `integer` `number`'a\n * düşüyor (`env-gen.ts:30-60`). Bu yüzden TS tipine kurulan HİÇBİR kural doğru\n * olamaz — kural ne olursa olsun bir taraf yanlışa düşer:\n *\n * { qty: { gt: col(\"amount\") } } integer ↔ numeric PG: GEÇERLİ\n * { total: { gt: col(\"note\") } } integer ↔ text PG: GEÇERSİZ\n *\n * İkisi de TS'te \"number ↔ string\". Ayırt edecek bilgi tipte YOK.\n *\n * YANLIŞ RET, YANLIŞ KABULDEN KÖTÜDÜR — ve tercih buna göre yapıldı. Yanlış bir\n * ret meşru bir sorguyu İFADE EDİLEMEZ kılar, yani yazarı `$query`'ye düşürür:\n * bu yüzeyin kapatmak için var olduğu şey. Yanlış bir kabul ise Postgres'in\n * GÜRÜLTÜLÜ hatasına çıkar (`operator does not exist: integer > text`) — kötü\n * ama sessiz değil.\n *\n * O yüzden aile ayrımı yalnız TS'in GERÇEKTEN ayırdığı yerlerde yapılıyor:\n * `boolean`, vektör dizisi ve `Date` kendi başlarına; metin ve sayı ise TEK\n * ailede, çünkü aralarındaki PG ayrımı tipte yok.\n *\n * KALICI ÇÖZÜM tipte değil ÜRETİMDE: `env-gen` kolon başına bir PG-tip markası\n * bassın (`string & { readonly __pg?: \"numeric\" }`). O zaman `numeric ↔ integer`\n * kabul, `numeric ↔ text` ret olur ve ikisi de DOĞRU olur. Defterde teklif.\n */\ntype PgFamily<V> = [NonNullable<V>] extends [boolean]\n ? \"bool\"\n : [NonNullable<V>] extends [readonly (number | string)[]]\n ? \"array\"\n : [NonNullable<V>] extends [Date]\n ? \"date\"\n : [NonNullable<V>] extends [string | number]\n ? \"scalar\"\n : \"opaque\";\n\n/**\n * Kolonun BİLDİRİLMİŞ Postgres tipi — `env-gen`'in bastığı markadan.\n *\n * Marka yoksa `\"?\"`: elle yazılmış bir `Tables` (testler) ya da yeniden\n * üretilmemiş bir `palbase-env.d.ts`. O durumda eski TS-tipi sezgiseline\n * düşülüyor, çünkü marka olmadan söylenebilecek daha doğru bir şey yok.\n */\ntype PgTag<V> = [NonNullable<V>] extends [{ readonly __pg?: infer N }]\n ? [N] extends [string]\n ? N\n : \"?\"\n : \"?\";\n\n/**\n * Postgres'te birbirleriyle karşılaştırılabilen tipler tek \"cins\".\n *\n * `integer`, `bigint` ve `numeric` örtük sayısal dönüşümle karşılaştırılır;\n * geri kalan her tip yalnız kendisiyle. `uuid ↔ text` ve `enum ↔ text`\n * Postgres'te `operator does not exist` verir — D-021'de CANLI ölçülmüştü ve\n * tip bunu göremediği için kabul ediyordu.\n */\ntype PgKind<P> = P extends \"integer\" | \"bigint\" | \"numeric\" ? \"num\" : P;\n\n/** İki tarafın da markası var mı — yoksa sezgisele düşülür. */\ntype BothBranded<A, B> = \"?\" extends PgTag<A> ? false : \"?\" extends PgTag<B> ? false : true;\n\ntype PgSameKind<A, B> = [PgKind<PgTag<A>>] extends [PgKind<PgTag<B>>]\n ? [PgKind<PgTag<B>>] extends [PgKind<PgTag<A>>]\n ? true\n : false\n : false;\n\n/**\n * `A` kolonu `B` ile karşılaştırılabilir mi.\n *\n * Marka varsa CEVAP KESİN: ne yanlış ret ne yanlış kabul. D-021 bu kuralı\n * \"doğru olamaz\" diye kaydetmişti çünkü tipte ayırt edecek bilgi yoktu; bilgi\n * artık tipte.\n */\ntype ColComparable<A, B> = BothBranded<A, B> extends true\n ? PgSameKind<A, B>\n : [PgFamily<A>] extends [PgFamily<B>]\n ? true\n : false;\n\n/** `Row`'un `V` ile karşılaştırılabilir kolonları. */\ntype ColumnsComparableTo<Row, V> = {\n [K in keyof Row]-?: ColComparable<Row[K], V> extends true ? K : never;\n}[keyof Row];\n\n/**\n * Bu satırın kolonlarından birine referans. `Row` bilinmiyorsa hiçbiri.\n *\n * İKİNCİ PARAMETRE kolonun tipi. Verilmezse (`unknown`) KISIT YOKTUR — bu\n * `findMany`'nin `Row`'u bilmediği yolların ve jsonb kolonlarının hâli, ve\n * ikisinde de tipin söyleyebileceği bir şey yok.\n */\n/**\n * \"Kısıt verilmedi\" için AYRI bir işaret — `unknown` DEĞİL.\n *\n * Eskiden varsayılan `unknown`'dı ve dal `[unknown] extends [V]` ile\n * seçiliyordu. Ama `jsonb` kolonlarının DEĞER TİPİ de `unknown`: yani gerçek\n * bir jsonb kolonu \"kısıt verilmedi\" sanılıp TÜM kolonlarla karşılaştırılabilir\n * hâle geliyordu. D-021 bunu \"jsonb ↔ text derleniyor\" diye kaydetmişti ve PG\n * markası tek başına kapatmadı — `unknown & X` kesişimi `X`'e çöktüğü için\n * jsonb markalanamıyor (markalamak kolonu daraltıp meşru yazmaları kırdı,\n * gerçek projede ölçüldü).\n *\n * Ayrı bir işaretle iki durum artık ayrışıyor: kısıtsız yol kısıtsız kalıyor,\n * jsonb ise KENDİ ailesine düşüyor — yani yalnız başka bir jsonb ile\n * karşılaştırılabiliyor.\n */\ndeclare const NO_CONSTRAINT: unique symbol;\nexport type NoColConstraint = { readonly [NO_CONSTRAINT]: true };\n\nexport type ColRefOf<Row, V = NoColConstraint> = [keyof Row] extends [never]\n ? never\n : [V] extends [NoColConstraint]\n ? ColRef<Extract<keyof Row, string>>\n : ColRef<Extract<ColumnsComparableTo<Row, V>, string>>;\n\n/**\n * Doğrulanmış, GÖMÜLEBİLİR bir SQL parçası (FR-018, FR-019).\n *\n * Wire şekli `{ $sql: { text, values } }`: `text` parçalar hâlinde tutulur ve\n * değerler ARADA durur, çünkü birleştirilmiş tek bir string'in içinden hangi\n * kısmın kullanıcı verisi olduğunu bir daha kimse çıkaramaz — enjeksiyonun\n * doğduğu yer tam olarak orasıdır.\n */\nexport type SqlFragment = {\n readonly $sql: { readonly text: readonly string[]; readonly values: readonly unknown[] };\n};\n\n/**\n * Retryable bir hatada işlemi yeniden dener (FR-037).\n *\n * `fn` must open and settle a NEW transaction on each invocation. Repeating\n * a savepoint retains the old snapshot and cannot retry a failed COMMIT.\n * Database.$atomic owns that boundary for ordinary application code.\n *\n * VARSAYILAN SIFIR. Sessiz bir varsayılan retry, idempotent OLMAYAN bir işlemi\n * çağıranın haberi olmadan iki kez çalıştırırdı — bir para transferini iki kez.\n * Tekrar denemek çağıranın kararı.\n *\n * Yalnız `isRetryable(e)` olan hatalar tekrarlanır. Küme dar tutuluyor: `23505`\n * buraya girseydi tekrar denemek aynı cevabı verir ve döngü boşuna dönerdi.\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n opts: { retry?: number } = {},\n): Promise<T> {\n const budget = retryBudget(opts.retry);\n let attempt = 0;\n for (;;) {\n try {\n return await fn();\n } catch (e) {\n // Bütçe bittiğinde SON hata fırlatılıyor, sarmalanmıyor: çağıranın\n // gördüğü şey Postgres'in söylediği şey olsun.\n if (attempt >= budget || !isRetryable(e)) throw e;\n attempt += 1;\n }\n }\n}\n\n/**\n * K3: sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için kaçış kapağı.\n *\n * ```ts\n * Database.public.notes.findMany({\n * where: sqlFragment`similarity(title, ${q}) > 0.3`,\n * orderBy: { column: \"created_at\", direction: \"desc\" },\n * limit: 20,\n * })\n * ```\n *\n * `select` / `orderBy` / `limit` / RLS aynen çalışmaya devam eder — \"yetmedi,\n * ham SQL'e geçeyim\" anının bugünkü maliyeti tam olarak bunları kaybetmekti.\n *\n * TANIMLAYICI GÖMME YÜZEYİ YOK (`.raw` / `.unsafe` / `.identifier`). Drizzle'ın\n * CVE-2026-39356'sı ve Knex'in CVE-2019-10757'si tam o kapakta doğdu.\n *\n * Ve kapak fonksiyonun ÜSTÜNDE olmakla bitmiyordu: parça MARKALI değilken\n * `{\"$sql\":{\"text\":[\"1=1 -- pwned\"],\"values\":[]}}` düz JSON'dan uydurulup\n * guard'ın tamamını atlıyordu (W2-B/C3, ölçüldü). Marka o kapağı wire ŞEKLİNE\n * de koyuyor — parça yalnız bu template tag'inden çıkabilir.\n */\nexport function sqlFragment(\n strings: TemplateStringsArray,\n ...values: unknown[]\n): SqlFragment {\n return brandRef({ $sql: { text: [...strings], values } }, \"sql\");\n}\n\nexport type TextOps<V> = V extends string\n ? { contains?: string; icontains?: string; startsWith?: string; endsWith?: string }\n : { contains?: never; icontains?: never; startsWith?: never; endsWith?: never };\n\n/** Operatör gövdesi, kolon-referans tipi DIŞARIDAN verilmiş hâliyle.\n *\n * `C` bir parametre, çünkü `ColRefOf<Row, V>` aksi hâlde altı operatör\n * konumunda AYRI AYRI instantiate edilirdi — kolon başına altı mapped type.\n * Böyle kolon başına BİR tane (N-2). */\n/**\n * `now()` HANGİ kolonlarda karşılaştırma değeri olabilir.\n *\n * `timestamp` TypeScript'e `string` olarak geliyor — `text` ile aynı tip. Yani\n * \"yalnız zaman kolonları\" tip düzeyinde İFADE EDİLEMEZ (D-021'in tam olarak\n * kaydettiği sınır: TS numeric/bigint/text/uuid/timestamp'ı `string`'e\n * çöktürüyor). İki seçenekten yanlış KABUL, yanlış RET'e tercih ediliyor:\n * `now()`'ı bir metin kolonunda yazmak Postgres hatası verir, ama zaman\n * kolonunda YASAKLAMAK yazarı bu yüzden `sqlFragment`e düşürürdü — ve bu\n * özelliğin var olma nedeni tam olarak o düşüşü kaldırmak.\n */\ntype NowComparable<V> = \"?\" extends PgTag<V>\n ? [NonNullable<V>] extends [string | Date]\n ? TxNow\n : never\n : PgTag<V> extends \"timestamp\"\n ? TxNow\n : never;\n\ntype WhereOpBody<V, C> = {\n gt?: V | C | NowComparable<V>;\n gte?: V | C | NowComparable<V>;\n lt?: V | C | NowComparable<V>;\n lte?: V | C | NowComparable<V>;\n neq?: V | C | NowComparable<V>;\n in?: V[];\n /** `IS NULL` / `IS NOT NULL` (FR-006) — `= NULL` SQL'de her zaman UNKNOWN'dır. */\n isNull?: boolean;\n} & TextOps<V>;\n\nexport type WhereOp<V, Row = unknown> = WhereOpWith<V, ColRefOf<Row, V>>;\n\n/**\n * Operatör sözlüğü, kolon-referans/plan-tutamağı konumu DIŞARIDAN verilmiş.\n *\n * `export`, çünkü plan yüzeyi (`tx-plan.ts`) aynı sözlüğü `C = ColRefOf<…> |\n * Ref<…>` ile kuruyor: bir plan filtresi ÖNCEKİ bir işlemin sonucuna\n * bakabiliyor, `findMany` bakamıyor. Ref'i `V`'ye eklemek YANLIŞ olurdu —\n * `TextOps<V>` `V extends string` diye soruyor ve `string | Ref<string>` o\n * soruya HAYIR der, yani `contains`/`startsWith` sessizce KAYBOLURDU.\n */\nexport type WhereOpWith<V, C> = V | C | NowComparable<V> | WhereOpBody<V, C>;\n\n/**\n * A filter over a row: every field optional, each one a plain value (equality)\n * or an operator object. THE filter language — `findMany`, `updateMany`,\n * `deleteMany` and `count` all take this one, because two spellings of a filter\n * is how the two come to disagree.\n */\nexport type WhereFilter<Row> = { [K in keyof Row]?: WhereOp<Row[K], Row> } & {\n /**\n * Boolean bileşimi (FR-007). Dallar aynı filtre dilidir — iki yazım olmaz.\n *\n * ÖZYİNELEME BURADA BAŞLIYOR ve N-2'nin izlediği şey tam olarak budur:\n * Kysely'nin TS7'de 9,8M instantiation üreten vakası derin generic\n * özyinelemeydi. Burada derinlik yazarın filtresi kadardır ve pratikte\n * bir-iki seviyedir; tip maliyeti T001'in tavanına karşı ölçülür.\n *\n * Dal bir `sqlFragment` DE olabilir. Motor bunu zaten derliyordu — parantezli\n * ve parametreli (`… AND (((expires_at > now())) AND (t.\"city\" = $2))`) —\n * ama tip yalnız üst düzey `where`'de fragment'e izin veriyordu. Yani\n * \"fragment sorgudan KAÇMAK için değil, sorgunun İÇİNE girmek için\" sözü tam\n * da bileşim anında kırılıyordu: bir koşulu bir fragment'le birleştirmek\n * isteyen yazar SORGUNUN TAMAMINI ham SQL'e taşımak zorunda kalıyordu.\n * Ölçüldü: bir müşteri sorgusunda tam olarak bu oldu.\n */\n OR?: (WhereFilter<Row> | SqlFragment)[];\n AND?: (WhereFilter<Row> | SqlFragment)[];\n NOT?: WhereFilter<Row> | SqlFragment;\n};\n\n/**\n * Ordering and paging for a read.\n *\n * `column` is `keyof Row`, not `string`: a mistyped column name is a compile\n * error here rather than a runtime rejection three layers down. `offset`\n * without `limit` is refused by the engine — a page with no size is not a page.\n */\nexport type OrderBySpec<Row> = {\n column: Extract<keyof Row, string>;\n direction?: \"asc\" | \"desc\";\n /** NULL'ların yeri (FR-008). Verilmezse Postgres varsayılanı geçerlidir ve o\n * varsayılan YÖNE GÖRE DEĞİŞİR: ASC'de NULLS LAST, DESC'te NULLS FIRST. */\n nulls?: \"first\" | \"last\";\n};\n\nexport type FindManyOpts<Row> = {\n /** Tek sıralama ya da SIRALI liste — sıra korunur (FR-008). */\n orderBy?: OrderBySpec<Row> | OrderBySpec<Row>[];\n limit?: number;\n offset?: number;\n};\n\n/**\n * Bir okumanın TEK parametresi (FR-004b).\n *\n * `where` bir ALAN, konumsal bir argüman değil. Kullanıcının kararı: \"deterministik\n * olması lazım, tek düzlem\" — aynı bilginin iki yere dağılması, alanlar çoğaldıkça\n * (select/include/orderBy) \"hangisi nereye\" sorusunu ezberlenecek bir şeye çevirir.\n * Prisma ve Drizzle de tek obje kullanıyor. Bedeli açık ve kabul edildi: en sık\n * kullanım uzuyor — `findMany({ where: { owner: uid } })`.\n *\n * ÖZYİNELEMESİZ kalmak zorunda (N-2): tip maliyeti şekilden değil özyineleme\n * derinliğinden geliyor (Kysely'nin TS7'de 9,8M instantiation vakası).\n */\n/**\n * `has` — İLİŞKİ ÜZERİNDEN SÜZME, JOIN'in ihtiyaç duyulmayan hâli.\n *\n * ```ts\n * Database.public.interests.findMany({\n * where: { has: { user_interests: { user_id: uid } } },\n * orderBy: [{ column: \"sort_order\" }, { column: \"name\" }],\n * })\n * ```\n * → `… WHERE t.\"id\" IN (SELECT r1.\"interest_id\" FROM \"user_interests\" r1\n * WHERE r1.\"user_id\" = $1)`\n *\n * İlişki ADLARI ve gittikleri kolonlar `palbase-env.d.ts`'in ZATEN bastığı\n * `relations` bloğundan geliyor — yabancı anahtarlardan türetiliyorlar, yazar\n * hiçbir kolon adı yazmıyor. O blok üretiliyordu ve HİÇBİR okuma onu\n * kullanmıyordu; `has` onun karşılığı.\n *\n * İç filtre AYNI dil: bir tablo ötesinde de `gt`, `icontains`, `OR`, ve iç içe\n * `has` yazılabiliyor.\n */\n/**\n * İlişkinin HEDEF TABLOSU — anahtar ŞEMA NİTELİKLİ gelir.\n *\n * `buildRelations` `to`'yu `qualifiedTableKey` ile yazıyor: public için düz ad\n * (`\"interests\"`), başka şema için noktalı (`\"billing.invoices\"`). `Tables`\n * yalnız public'i taşır, diğerleri `Schemas`'tadır — noktalı anahtarı doğrudan\n * `Tables`'ta aramak HER ZAMAN ıskalar ve iç filtre sessizce `Record<string,\n * unknown>`'a düşerdi: bilinmeyen kolon da, yanlış tip de derlenirdi (ölçüldü).\n */\ntype RelatedTable<To> = To extends `${infer S}.${infer T}`\n ? S extends keyof Schemas\n ? T extends keyof Schemas[S]\n ? Schemas[S][T]\n : never\n : never\n : To extends keyof Tables\n ? Tables[To]\n : never;\n\ntype RelatedRow<To> = RelatedTable<To> extends { row: infer R } ? R : Record<string, unknown>;\ntype RelatedRels<To> = RelatedTable<To> extends { relations: infer R } ? R : unknown;\n\n/**\n * İç içe `has` ÜÇ seviyeyle sınırlı.\n *\n * Üretilen `relations` bloğu ÇİFT YÖNLÜ: `customers.invoices` ile\n * `invoices.customer` birbirini gösteriyor, yani grafiğin kendisi döngülü.\n * Sınırsız açılım bu döngüyü sonsuz bir tipe çevirirdi — TypeScript'in\n * \"excessively deep\" hatası, yazılan sorgunun karmaşıklığından değil ŞEMANIN\n * şeklinden gelirdi. Üç seviye, ölçtüğümüz tüm gerçek sorguların üstünde.\n */\ntype HasDepth = 0 | 1 | 2 | 3;\ntype HasDec = [0, 0, 1, 2];\ntype HasNest<Rels, D extends HasDepth> = [keyof Rels] extends [never]\n ? unknown\n : D extends 0\n ? unknown\n : { has?: HasFilter<Rels, HasDec[D]> };\n\ntype HasFilter<Rels, D extends HasDepth = 3> = {\n [R in keyof Rels]?: Rels[R] extends { to: infer To }\n ? WhereFilter<RelatedRow<To>> & HasNest<RelatedRels<To>, D>\n : never;\n};\n\n/** İlişki bilgisi taşıyan bir tablo tipinin filtre yüzeyi. */\nexport type WhereWithRelations<Row, Rels> = WhereFilter<Row> & { has?: HasFilter<Rels> };\n\n/**\n * `has` dalı — SADECE `has`, satır filtresi olmadan.\n *\n * Plan yolunun filtre dili (`TxWhere`) düz op'unkiyle aynı değil: orada bir\n * alan ÖNCEKİ bir işlemin satırına referans (`Ref`) taşıyabiliyor. `has`'ı\n * plana taşımak için o dili kopyalamak gerekmiyor — kesişimle EKLENİYOR.\n * İlişki yoksa `unknown` dönüyor, çünkü `X & unknown = X`: dal yok olur ve\n * `has` fazla-alan denetimine takılır.\n */\nexport type HasOnly<Rels> = [unknown] extends [Rels]\n ? unknown\n : [keyof Rels] extends [never]\n ? unknown\n : { has?: HasFilter<Rels> };\n\n/**\n * `has` dalı NE ZAMAN var olur.\n *\n * İlişkisi OLMAYAN bir tabloda `has` hiç yazılamamalı. `HasFilter<{}>` boş bir\n * nesne tipidir ve boş nesne tipi HER nesneyi kabul eder — yani dalı koşulsuz\n * eklemek, ilişkisiz bir tabloda `has: { neyse_ne: {} }`'yi SESSİZCE geçirirdi\n * (ölçüldü: kapı yeşil, çalışma anında \"böyle bir ilişki yok\" hatası).\n */\ntype HasBranch<Row, Rels> = [unknown] extends [Rels]\n ? never\n : [keyof Rels] extends [never]\n ? never\n : WhereWithRelations<Row, Rels>;\n\n/**\n * `with` — İLİŞKİLİ SATIRLARI GETİR (`has` süzer, `with` getirir).\n *\n * `true` bütün kolonları, bir nesne ise `select`/`where`/`orderBy`/`limit` ile\n * daraltılmış hâlini getiriyor. Tek sorgu: LATERAL + `json_agg`.\n */\ntype WithOpts<To, D extends HasDepth> = {\n select?: readonly Extract<keyof RelatedRow<To>, string>[];\n where?: WhereFilter<RelatedRow<To>>;\n orderBy?: OrderBySpec<RelatedRow<To>> | readonly OrderBySpec<RelatedRow<To>>[];\n limit?: number;\n with?: D extends 1 ? never : [keyof RelatedRels<To>] extends [never] ? never : WithInput<RelatedRels<To>, HasDec[D]>;\n};\n\nexport type WithInput<Rels, D extends HasDepth = 3> = {\n [R in keyof Rels]?: Rels[R] extends { to: infer To } ? true | WithOpts<To, D> : never;\n};\n\n/** Bir `with` dalının DÖNÜŞ tipi — `many` dizi, `one` tekil ya da null. */\ntype WithRowOf<Rels, R extends keyof Rels, Q> = Rels[R] extends { to: infer To; kind: infer K }\n ? (Q extends { select: readonly (infer C extends keyof RelatedRow<To>)[] }\n ? Pick<RelatedRow<To>, C>\n : RelatedRow<To>) & (Q extends { with: infer W } ? WithResult<RelatedRels<To>, W> : unknown) extends infer Row\n ? [K] extends [\"many\"]\n ? Row[]\n : Row | null\n : never\n : never;\n\n/**\n * `with` istenmediğinde `unknown` — kesişimde YOK OLSUN diye.\n *\n * Boş bir nesne (`{}`) dönseydi `Pick<Row, K> & {}` satır tipini \"aynı ama\n * özdeş değil\" hâle getirirdi ve tam eşitlik iddiaları kırılırdı. Ölçüldü:\n * `toEqualTypeOf` dört yerde düştü.\n */\n/**\n * Yalnız GERÇEKTEN istenen dallar. `undefined extends W[R]` olan anahtarlar\n * düşüyor — ve bu, `ReturnType<typeof t.findMany>` yazan herkes için kritik:\n * generic bir imzada `ReturnType` tip parametrelerini VARSAYILANLA değil\n * KISITLA örnekliyor, yani `W = WithInput<Rels>` oluyor ve her ilişki\n * (`?:` ile, dolayısıyla `| undefined`) zorunlu bir alana dönüşüyordu.\n * Gerçek projede ölçüldü: `type MemberRow = Awaited<ReturnType<…findMany>>[number]`\n * 32 ilişkiyi birden ister hâle geldi ve 4 yerde kırıldı.\n */\ntype RequestedWith<W> = { [R in keyof W]-?: undefined extends W[R] ? never : R }[keyof W];\n\nexport type WithResult<Rels, W> = [RequestedWith<W>] extends [never]\n ? unknown\n : { [R in RequestedWith<W> & keyof Rels]: WithRowOf<Rels, R, W[R]> };\n\nexport type QueryInput<Row, K extends keyof Row = keyof Row, Rels = unknown> = {\n /**\n * Filtre — ya tipli filtre dili ya da bir `sqlFragment` (FR-018). İkisi de\n * AYNI alandır: kademe atlamak bir parametre değişikliği, ayrı bir çağrı\n * yolu değil (P1).\n */\n where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n /**\n * İlişkili satırları da getir — TEK sorguda.\n *\n * ```ts\n * const rows = await Database.public.users.findMany({\n * where: { active: true },\n * with: { orders: { select: [\"id\", \"amount\"], limit: 5 } },\n * });\n * rows[0].orders[0].amount; // string — KAYIPSIZ\n * ```\n *\n * `many` ilişki DİZİ döner (boşsa `[]`, `null` değil — `.map()` guard\n * istemesin); `one` ilişki tekil satır ya da `null`.\n *\n * PARA: `numeric`/`bigint` kolonları JSON'a `::text` ile giriyor. Cast\n * olmadan `numeric` bir JSON SAYISI olur ve kesinliğini kaybeder — ölçüldü,\n * `100000000000000000000000000` → `1e+26`.\n */\n // `HasBranch` ile AYNI iki koşul, aynı gerekçe: `unknown` ise kısıt yok\n // demektir, ve `WithInput<{}>` boş bir nesne tipidir — boş nesne HER nesneyi\n // kabul eder, yani ilişkisiz bir tabloda `with` sessizce geçerdi.\n with?: [unknown] extends [Rels] ? never : [keyof Rels] extends [never] ? never : WithInput<Rels>;\n /**\n * Projeksiyon (FR-009): yalnız bu kolonlar çekilir ve DÖNÜŞ TİPİ buna daralır.\n *\n * Tip `Pick<Row, K>` ile TÜRETİLİR, üretilmez: `select` kombinasyonları için\n * tip basmak, üretilen `.d.ts`'i kombinatoryal olarak şişirirdi (N-1: tablo\n * başına ≤ 25 satır).\n */\n select?: readonly K[];\n} & FindManyOpts<Row>;\n\nexport type PageInput<Row, K extends keyof Row = keyof Row, Rels = unknown> =\n Omit<QueryInput<Row, keyof Row, Rels>, \"limit\" | \"offset\" | \"select\"> &\n { select?: readonly K[] } & import(\"./page.js\").PageNavigation;\n\n/** Bir yazmanın TEK parametresi: neyi (`where`) neye çevirdiğin (`set`). */\nexport type MutateInput<Row, Insert, Rels = unknown> = {\n where: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n set: SetShape<Insert>;\n /**\n * `false` verilirse SATIRLAR değil SAYI döner — `deleteMany` ile aynı şekil.\n *\n * ÖLÇÜLDÜ (200 bin satır, canlı pg16): `RETURNING *` sunucuda %55 daha\n * pahalı (7,2 sn → 11,1 sn) ve JS'te 45 MB yığın tutuyor — satır başına 236\n * bayt, yani bir milyon satırda 225 MB. Çoğu çağrı için dönen diziyi okumak\n * DOĞRU ve varsayılan odur; toplu bir iş için çıkış yolu olması gerekiyordu.\n */\n returning?: boolean;\n};\n\n/**\n * `set`'e yazılabilen değer (FR-012): kolonun kendi tipi ya da — sayısal\n * kolonlarda — kolonun ŞU ANKİ değerini okuyan bir ifade.\n *\n * `increment()` metin ya da boolean kolonda YOK: \"kolona ekle\"nin orada bir\n * anlamı olmadığı için ifade edilemez kılınıyor (P5 — anlatmak değil, ifade\n * edilemez kılmak). `numeric` kolonlar TypeScript'te `string` taşır, o yüzden\n * string de sayısal sayılır; ayrımı burada yapamayız, ama D-007 zaten miktarın\n * JS `number`'a hiç uğramamasını istiyor.\n */\n/** `increment()`/`decrement()` HANGİ kolonlarda anlamlı — bildirilmiş PG tipine\n * göre. Marka yoksa eski sezgisel (`number | string`), ki o `text` kolonda da\n * izin veriyordu: Postgres `text + 1` demez. */\ntype NumericCol<V> = \"?\" extends PgTag<V>\n ? NonNullable<V> extends number | string\n ? TxColumnExpr\n : never\n : PgKind<PgTag<V>> extends \"num\"\n ? TxColumnExpr\n : never;\n\n/**\n * Bir EKLEME yolunda yazılabilecek değer.\n *\n * Kolonun kendi tipi ya da — zaman kolonlarında — sunucu saati. `increment()`\n * burada YOK ve olamaz: satır henüz yokken \"kolonun şu anki değeri\" diye bir\n * şey yok, motor da bunu adıyla reddediyor.\n *\n * Var olma nedeni ölçülmüş: introspect edilmiş şemalarda zaman kolonlarının\n * çoğu varsayılansız (`timestamp()`), yani \"eklerken sunucu saatini yaz\"ın tek\n * karşılığı istemci saatiydi — 33 tablolu bir projede 12 yerde.\n */\nexport type InsertValues<Insert> = {\n [K in keyof Insert]: Insert[K] | NowComparable<Insert[K]>;\n};\n\nexport type SetValue<V> =\n | V\n | NumericCol<V>\n // `now()` doğrudan yolda da geçerli: motor onu `SET col = now()` diye\n // derliyor (plan yolunun her zaman yaptığı gibi). Tipte yasaklamak, çalışan\n // bir çağrıyı ifade edilemez kılardı — P5'in tersi.\n //\n // VE TAM OLARAK BUNU YAPIYORDU: koşul `Date` idi, oysa `timestamp` kolonlar\n // TypeScript'e `string` geliyor. Yani `set: { updated_at: now() }` —\n // yazılabilecek en sık yazma ifadesi — HİÇBİR üretilmiş şemada derlenmiyordu\n // (ölçüldü). Marka o koşulu doğru yazılabilir kıldı.\n | NowComparable<V>;\n\n/** Bir update'in `set`'i: insert şeklinin herhangi bir alt kümesi, ifadelerle. */\nexport type SetShape<Insert> = { [K in keyof Insert]?: SetValue<Insert[K]> };\n\n/** search() parametreleri, satır tipiyle koşullanmış (FR-013). `offset` BİLEREK yok (UD-013). */\nexport interface SearchParamsTyped<T extends TableTypes> {\n /** Metin sorgusu: FTS kolunu besler; embed beyanlıysa sorgu vektörü de bundan üretilir. */\n query?: string;\n /** Hazır sorgu vektörü — verilirse embed çağrısı olmaz (FR-025). */\n vector?: number[];\n /** `findMany`'nin filtre dili — İKİNCİ tip argümanıyla, yoksa `Row` sessizce\n * `unknown`'a düşer ve `col()` burada ifade edilemez olurdu. Motor `search`\n * için aynı `compileWhereBare`'i kullanıyor; yetenek orada (gözcü I7). */\n where?: { [K in keyof T[\"row\"]]?: WhereOp<T[\"row\"][K], T[\"row\"]> };\n /** default 20, tavan 100 (engine uygular). */\n limit?: number;\n /** Birden çok vektör kolonunda hedef seçimi (model geçişi, FR-013/using). */\n using?: string;\n mode?: \"hybrid\" | \"text\" | \"vector\";\n /** Nihai (RRF-sonrası) skor alt eşiği — süzme LIMIT'ten önce uygulanır (FR-001). */\n minScore?: number;\n /** Chunk-modunda satır başına en iyi blok sayısı (1..10, vars. 3; FR-015). */\n blocksPerRow?: number;\n /** Tazelik çürümesi: nihai skor RRF-sonrası exp(-ln(2)*yaş/halfLife) ile çarpılır;\n * field bir timestamp kolonu, halfLife \"90s\" | \"15m\" | \"12h\" | \"30d\" biçiminde (FR-004). */\n recency?: { field: Extract<keyof T[\"row\"], string>; halfLife: string };\n /** Satır-modunda FTS eşleşme vurgusu: sonuç satırına `_highlight` ekler;\n * chunk-modda no-op — bloklar zaten eşleşen kesittir (FR-025). */\n highlight?: boolean;\n /** Validity'li tabloda zaman penceresi: varsayılan yalnız güncel versiyon;\n * \"all\" tüm versiyonlar; {asOf} o anda geçerli olan (FR-029). */\n validity?: \"all\" | { asOf: string };\n /** Alan-boost (FR-030): skor * (1 + w·x/(1+x)) — sayısal kolonla sınırlı\n * çarpan, dış servissiz; bileşim RRF → boost → recency → minScore. */\n boost?: { field: Extract<keyof T[\"row\"], string>; weight: number };\n}\n\n/**\n * `facets()` dönüşü (FR-027, FR-058): kolon adı → o kolonun top-20 değeri ve\n * sayacı.\n *\n * Bu tip bir zamanlar `search()` dönüş DİZİSİNİN üstünde taşınıyordu; dizi-üstü\n * özellik `JSON.stringify`'da kayboluyor, yani bir kontrolcü onu döndürmeye\n * çalıştığında yanıt gövdesinde hiç görünmüyordu. Sayaçlar artık BAĞIMSIZ\n * dönüşle geliyor ve tip de o dönüşü adlandırıyor.\n */\nexport type SearchFacets = Record<string, { value: string | null; count: number }[]>;\n\n/** similar()/recommend() taşıyıcı opsiyonları (T018, FR-022): search'ün\n * paramlarından query/vector/mode düşer — hedef vektörü metodun kendisi\n * DB'den kurar; facets/highlight de düşer (T020) — engine bu ikisini\n * similar/recommend'e geçirmez, tip vaadi gerçekle aynı kalır. */\nexport type SimilarParamsTyped<T extends TableTypes> = Omit<\n SearchParamsTyped<T>,\n \"query\" | \"vector\" | \"mode\" | \"facets\" | \"highlight\"\n>;\n\n/** recommend() parametreleri (T018, FR-023). */\nexport type RecommendParamsTyped<T extends TableTypes> = SimilarParamsTyped<T> & {\n /** Kaynak beğeniler — hedef vektör bunların DB-içi avg'ı; boş olamaz. */\n positive: string[];\n /** İtilen örnekler — hedef pos.v + (pos.v - neg.v) ile yönlenir. */\n negative?: string[];\n};\n\n/**\n * Tablonun ilişki bloğu — env `Tables` girdisinden.\n *\n * TEK yerde türetiliyor ve HER op'a aynısı veriliyor: `has` yalnız `findMany`'de\n * olsaydı, \"aynı filtre dili her op'ta\" sözü ilk `deleteMany`'de kırılırdı.\n */\ntype RelsOf<T> = T extends { relations: infer R } ? R : unknown;\n\n/**\n * TOPLAMA — dönüş tipi PG markasından TÜRETİLİR, tahmin edilmez.\n *\n * Para bu SDK'dan geçecek, ve toplamada kaybedilecek tek şey kesinliktir:\n * `sum(numeric)` Postgres'te `numeric`, `sum(integer)` `bigint` — İKİSİ DE JS\n * `number`'ında kayıplı. Bu yüzden `sum`/`avg` HER ZAMAN `string` döner ve\n * motor `::text` ile döker. D-007'nin kapattığı hata buydu:\n * 41.00821234567890123 canlıda 41.0082123456789 oluyordu.\n *\n * `| null` bir süs değil: Postgres BOŞ kümede NULL döndürür, 0 değil. \"Hiç\n * satır yoktu\" ile \"toplam sıfırdı\" farklı şeyler, ve tip bunu sormaya\n * ZORLUYOR.\n */\ntype SummableCols<Row> = {\n [K in keyof Row]-?: \"?\" extends PgTag<Row[K]>\n ? NonNullable<Row[K]> extends number | string\n ? K\n : never\n : PgKind<PgTag<Row[K]>> extends \"num\"\n ? K\n : never;\n}[keyof Row];\n\n/** `min`/`max` sıralanabilir her kolonda — jsonb ve vektör hariç. */\ntype OrderableCols<Row> = {\n [K in keyof Row]-?: \"?\" extends PgTag<Row[K]>\n ? NonNullable<Row[K]> extends number | string | Date\n ? K\n : never\n : PgTag<Row[K]> extends \"jsonb\" | \"vector\"\n ? never\n : K;\n}[keyof Row];\n\ntype AggCols<Row> = Extract<SummableCols<Row>, string>;\ntype AggOrderCols<Row> = Extract<OrderableCols<Row>, string>;\n\nexport type AggregateInput<Row, Rels = unknown> = {\n where?: WhereFilter<Row> | SqlFragment | HasBranch<Row, Rels>;\n /** Toplam — yalnız sayısal kolonlarda; sonuç `string | null` (kayıpsız). */\n sum?: readonly AggCols<Row>[];\n /** Ortalama — sonuç `numeric`, yani `string | null`. */\n avg?: readonly AggCols<Row>[];\n min?: readonly AggOrderCols<Row>[];\n max?: readonly AggOrderCols<Row>[];\n /** Kaç satır — `count()` ile aynı sayı, ama AYNI turda. */\n count?: boolean;\n /** Verilirse SATIRLAR döner ve her satır grup kolonlarını taşır. */\n groupBy?: readonly Extract<keyof Row, string>[];\n};\n\ntype AggPart<Q, Row, F extends \"sum\" | \"avg\" | \"min\" | \"max\"> = Q extends {\n [K in F]: readonly (infer C extends keyof Row)[];\n}\n ? { [P in C]: F extends \"sum\" | \"avg\" ? string | null : Row[P] | null }\n : never;\n\ntype AggBody<Q, Row> = ([AggPart<Q, Row, \"sum\">] extends [never] ? unknown : { sum: AggPart<Q, Row, \"sum\"> }) &\n ([AggPart<Q, Row, \"avg\">] extends [never] ? unknown : { avg: AggPart<Q, Row, \"avg\"> }) &\n ([AggPart<Q, Row, \"min\">] extends [never] ? unknown : { min: AggPart<Q, Row, \"min\"> }) &\n ([AggPart<Q, Row, \"max\">] extends [never] ? unknown : { max: AggPart<Q, Row, \"max\"> }) &\n (Q extends { count: true } ? { count: number } : unknown);\n\nexport type AggregateResult<Q, Row> = Q extends {\n groupBy: readonly (infer G extends keyof Row)[];\n}\n ? ({ [P in G]: Row[P] } & AggBody<Q, Row>)[]\n : AggBody<Q, Row>;\n\n/** Temel tablo erişimcisi — search'süz beş op. */\nexport interface EnvTypedTableBase<T extends TableTypes> {\n findUnique<K extends keyof T[\"row\"] = keyof T[\"row\"], W extends WithInput<RelsOf<T>> = Record<never, never>>(q: {\n where: import(\"./unique.js\").UniqueWhere<T[\"row\"], T[\"uniqueKeys\"]>;\n select?: readonly K[]; with?: QueryInput<T[\"row\"], keyof T[\"row\"], RelsOf<T>>[\"with\"] & W;\n }): Promise<(Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>) | null>;\n /** Index-backed pagination. The engine appends the declared primary key to\n * orderBy, encrypts cursor values and validates the query and caller scope. */\n page<K extends keyof T[\"row\"] = keyof T[\"row\"], W extends WithInput<RelsOf<T>> = Record<never, never>>(\n q?: PageInput<T[\"row\"], K, RelsOf<T>> & { with?: W },\n ): Promise<import(\"./page.js\").Page<Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>>>;\n insert(data: InsertValues<T[\"insert\"]>): Promise<T[\"row\"]>;\n /**\n * Çok satırı TEK statement'la ekle (tek gidiş-dönüş).\n *\n * ```ts\n * await Database.public.journey_stops.insertMany(\n * stops.map((s, i) => ({ journey_id, name: s.name, sort_order: i })),\n * );\n * ```\n *\n * Satırların anahtar kümesi AYNI olmalı: tek statement kolon listesini\n * paylaşır, yani farklı şekilli bir satırın fazla kolonu sessizce yazılmaz\n * ve eksiği yanlış sütuna kayardı. Eksik alan için `null` yazın.\n *\n * Boş dizi boş sonuç döner — hata değil: \"eklenecek bir şey yoktu\".\n */\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>> & { returning: false }): Promise<number>;\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts?: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>> & { returning?: true }): Promise<T[\"row\"][]>;\n insertMany(rows: readonly InsertValues<T[\"insert\"]>[], opts?: import(\"./bulk.js\").InsertManyOptions<Extract<keyof T[\"row\"], string>>): Promise<T[\"row\"][] | number>;\n /**\n * Bir idempotency anahtarını sahiplen (FR-033).\n *\n * ```ts\n * const { inserted, row } = await Database.public.payments.claim(\n * { idem_key: req.headers[\"idempotency-key\"] },\n * { amount, user_id },\n * );\n * if (!inserted) return row; // aynı istek ikinci kez geldi\n * ```\n *\n * `inserted: false` bir HATA DEĞİL: dönen satır ilk çağrının satırıdır.\n * İlk argüman satırı BULAN alanlar, ikincisi yalnız yazılanlar — ikinci çağrı\n * farklı bir yük gönderse bile satır anahtarla bulunur.\n */\n claim(\n unique: Partial<T[\"insert\"]>,\n extra?: Partial<InsertValues<T[\"insert\"]>>,\n ): Promise<{ inserted: boolean; row: T[\"row\"] }>;\n /**\n * Satırı yaz; `onConflict` kolonlarında çakışırsa ÜZERİNE yaz (FR-034).\n *\n * ```ts\n * await Database.public.settings.put({\n * data: { user_id, theme: \"dark\" },\n * onConflict: [\"user_id\"],\n * });\n * ```\n *\n * `onConflict` kolonları benzersiz bir kısıt ya da index taşımalı — Postgres\n * onlarla eşleştirir — ve güncellemeden dışlanırlar, çünkü eşleşen şey onlar.\n *\n * **`upsert`'ün yerine geldi ve adı bilerek değişti.** `upsert` tek isim\n * altında iki niyet taşıyordu: \"yoksa ekle varsa güncelle\" (bu) ve \"idempotent\n * yaz\" (artık {@link EnvTypedTableBase.claim}). İkincisi için ÖLÇÜLMÜŞ biçimde\n * yanlıştı: `DO UPDATE` ikinci çağrının verisiyle birincininkini EZİYOR\n * (10.00 → 999.00 ölçüldü). İki niyeti tek isimde tutmak, yanlış olanı\n * seçmeyi kolay yapıyordu.\n */\n put(q: {\n data: InsertValues<T[\"insert\"]>;\n onConflict: readonly Extract<keyof T[\"row\"], string>[];\n }): Promise<T[\"row\"]>;\n /** Update the row by id; resolves to the updated row, or `null` if no row\n * matched (absent or RLS-hidden) — an idempotent outcome, mirroring\n * `findById`. The runtime returns a null row rather than throwing. */\n update(q: { where: { id: string }; set: SetShape<T[\"insert\"]> }): Promise<T[\"row\"] | null>;\n delete(id: string): Promise<void>;\n findById(id: string): Promise<T[\"row\"] | null>;\n /** Rows matching the filter. See {@link WhereFilter} / {@link FindManyOpts} —\n * this declaration is what makes the engine's operators callable. */\n findMany<\n K extends keyof T[\"row\"] = keyof T[\"row\"],\n W extends WithInput<RelsOf<T>> = Record<never, never>,\n >(\n // `K` ve `W` AYRI çıkarım noktaları. Tek bir `const Q` generic'i denendi ve\n // ESKİ BİR KAPIYI ÖLDÜRDÜ: `where: { note: { contains: 5 } }` — metin\n // olmayan bir değerle `contains` — derlenmeye başladı, çünkü kısıt denetimi\n // literal çıkarımın altında kayboluyordu. Ölçüldü ve geri alındı.\n q?: QueryInput<T[\"row\"], K, RelsOf<T>> & { with?: W },\n ): Promise<Array<Pick<T[\"row\"], K> & WithResult<RelsOf<T>, W>>>;\n /**\n * Update every matching row in one statement; an empty filter is refused.\n *\n * **0 satır dönmesi hata DEĞİL, başarı da değil** (FR-014): koşulu `where`'e\n * koyup dönen diziyi kontrol etmek, \"önce oku sonra yaz\"ın yarış koşulu\n * olmayan hâlidir.\n *\n * ```ts\n * const [row] = await Database.public.accounts.updateMany({\n * where: { id, balance: { gte: amount } },\n * set: { balance: decrement(amount) },\n * });\n * if (row === undefined) throw new Conflict(\"yetersiz bakiye\");\n * ```\n */\n updateMany<const Q extends MutateInput<T[\"row\"], T[\"insert\"], RelsOf<T>>>(\n q: Q,\n ): Promise<Q extends { returning: false } ? number : T[\"row\"][]>;\n /** Delete every matching row; resolves to how many. Empty filter refused. */\n deleteMany(q: { where: WhereFilter<T[\"row\"]> | SqlFragment | HasBranch<T[\"row\"], RelsOf<T>> }): Promise<number>;\n /**\n * Toplama — `sum` / `avg` / `min` / `max` / `count`, isteğe bağlı `groupBy`.\n *\n * ```ts\n * const r = await Database.public.entries.aggregate({\n * where: { account_id },\n * sum: [\"amount_kurus\"],\n * count: true,\n * });\n * r.sum.amount_kurus; // string | null — KAYIPSIZ\n * r.count; // number\n * ```\n *\n * `sum`/`avg` yalnız sayısal kolonlarda ve HER ZAMAN `string` döner: para JS\n * `number`'ına uğradığı anda kesinliğini kaybeder. `| null` çünkü Postgres\n * boş kümede NULL döndürür — \"hiç satır yoktu\" ile \"toplam sıfırdı\" farklı\n * şeyler ve tip bunu sormaya zorluyor.\n *\n * `groupBy` verilirse dönüş bir DİZİ ve her satır grup kolonlarını taşır.\n */\n aggregate<const Q extends AggregateInput<T[\"row\"], RelsOf<T>>>(\n q: Q,\n ): Promise<AggregateResult<Q, T[\"row\"]>>;\n /** How many rows match. An empty filter is legitimate: counting is a read. */\n count(q?: { where?: WhereFilter<T[\"row\"]> | SqlFragment | HasBranch<T[\"row\"], RelsOf<T>> }): Promise<number>;\n /** Validity'li tabloda satırın yeni versiyonu (FR-029, C-9): eski satır\n * kapanır (valid_to/superseded_by), yenisi TEK savepoint'te eklenir; dönüş\n * yeni satır. Validity beyanı olmayan tabloda adlandırılmış çalışma-zamanı\n * hatası — tip düzeyinde ayrım env `Tables` bayrağı taşımadığından yapılamaz. */\n supersede(id: string, row: InsertValues<T[\"insert\"]>): Promise<T[\"row\"]>;\n}\n\n/** Tablo erişimcisi: env girdisi `searchable: true` taşıyorsa (vector kolonu ya da\n * search beyanı — env-gen üretir) `search()` üyesi VARDIR; yoksa üye hiç yoktur ve\n * çağrı derleme hatasıdır (FR-013). Yapısal koşul TableTypes'ı genişletmeden çalışır. */\n/**\n * `appendOnly` tabloda YAYIMLANMAYAN üyeler (FR-031).\n *\n * Altısı da ayrı ayrı: biri unutulursa append-only sözü o üye üzerinden sessizce\n * delinir. `insert` ve okuma üyeleri kalır — düzeltme SİLMEKLE değil, telafi\n * kaydı EKLEMEKLE yapılır (FR-032).\n */\ntype AppendOnlyForbidden = \"update\" | \"updateMany\" | \"delete\" | \"deleteMany\" | \"put\" | \"supersede\";\n\nexport type EnvTypedTable<T extends TableTypes> = (T extends { appendOnly: true }\n ? Omit<EnvTypedTableBase<T>, AppendOnlyForbidden>\n : EnvTypedTableBase<T>) &\n (T extends { searchable: true }\n ? {\n search(\n params: SearchParamsTyped<T>,\n ): Promise<Array<T[\"row\"] & { _score: number; _highlight?: string }>>;\n /** \"Bu satıra benzeyenler\" (FR-022): hedef vektör DB'den okunur,\n * kaynak satır sonuçta yoktur; id yoksa adlandırılmış hata. */\n similar(id: string, params?: SimilarParamsTyped<T>): Promise<Array<T[\"row\"] & { _score: number }>>;\n /** D-021: sayaçlar bağımsız dönüşle — search'ün dizi-üstü _facets'i\n * JSON.stringify'da kaybolur; ciddi sözleşme budur. */\n facets(params: { facets: Array<keyof T[\"row\"] & string>; where?: Partial<T[\"row\"]>; validity?: \"all\" | { asOf: string } }): Promise<SearchFacets>;\n /** positive/negative beğenilerden öneri (FR-023): hedef vektör DB-içi\n * avg CTE'leriyle; kaynak id'ler sonuçta yoktur. */\n recommend(params: RecommendParamsTyped<T>): Promise<Array<T[\"row\"] & { _score: number }>>;\n }\n : Record<never, never>);\n\n/** The `tables` map exposed on `Database`/`tx`, keyed by the env `Tables`\n * interface. When no schema is declared `Tables` is empty, so `tables` is an\n * empty object — accessing `.tables.foo` is then a compile error (no member). */\nexport type EnvTables = {\n [K in keyof Tables]: EnvTypedTable<Tables[K]>;\n};\n\n/**\n * The project's NON-public schemas, keyed by schema name, each exposing its own\n * `tables` map — the shape `Database.schema(\"billing\")` returns.\n *\n * The intermediate `tables` is there for the reason {@link EnvTables} sits under\n * `.tables`: a schema's table names must not share a namespace with anything the\n * accessor itself might grow.\n *\n * Empty by default. The generated `palbase-env.d.ts` augments `Schemas` with one\n * member per declared schema other than `public`, so a project that declares\n * none has `keyof Schemas = never` and every `schema(...)` call is a compile\n * error rather than a runtime surprise.\n */\n/**\n * @deprecated ARTIK VAR OLMAYAN BİR ŞEKLİ tarif ediyor. Bu tip her şemayı\n * `{ tables: … }` altında gösteriyor; yüzey FR-001 ile `Database.<şema>.<tablo>`\n * oldu ve `.tables` ara katmanı KALKTI. Güncel şekil: {@link EnvSchemaSurface}.\n *\n * Kaldırılmadı çünkü dışa açık bir tip ve kaldırmak SEKİZİNCİ bir kırıcı olurdu;\n * ama bir tip, çalışma zamanının ÜRETMEDİĞİ bir şekli tarif ediyorsa yalan\n * söylüyor demektir — `const x: EnvSchemas[\"billing\"] = Database.billing`\n * açıklanamayan bir derleme hatası verir. Bir sonraki kırıcı sürümde silinmeli\n * (defter D-18).\n *\n * Bu tipi ÜRETEN iki fonksiyon (`makeTablesAccessor`, `makeSchemaAccessor`)\n * ölçüldü: hiçbir yerden çağrılmıyorlardı ve silindiler. Canlı yol\n * `makeTypedSurface`'ın proxy'si.\n */\nexport type EnvSchemas = {\n [S in keyof Schemas]: {\n tables: {\n [T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;\n };\n };\n};\n\n/** The project's tables as PLAN operations, keyed by the env `Tables`\n * interface. The transaction twin of {@link EnvTables}. */\n/** `appendOnly` bir tabloda transaction planının da kaybettiği üyeler. Doğrudan\n * yüzeyin `AppendOnlyForbidden`'ının plan-yolu ikizi; adlar farklı çünkü plan\n * yüzeyinin üye adları farklı. */\ntype TxAppendOnlyForbidden = \"put\" | \"updateWhere\" | \"deleteWhere\";\n\n/**\n * Plan yüzeyi de `appendOnly`'yi UYGULUYOR — ve uygulamıyor olması bir kusurdu.\n *\n * `EnvTypedTable` altı üyeyi Omit ediyordu, ama `TxTables` hiçbirini: yani\n * `tx.tables.entries.updateWhere(…)` ve `.put(…)` DERLENİYORDU. Tip bir şeyi\n * \"ifade edilemez\" ilan edip ikinci bir kapıda ifade edilebilir bırakırsa,\n * ilan yalandır (doğrulayıcı gözcü, FR-031).\n *\n * Motor da aynı üçünü adıyla reddediyor — tip atlanınca susmaması için.\n */\nexport type TxTables = {\n [K in keyof Tables]: Tables[K] extends { appendOnly: true }\n ? Omit<TxTable<Tables[K][\"row\"], Tables[K][\"insert\"], RelsOf<Tables[K]>>, TxAppendOnlyForbidden>\n : TxTable<Tables[K][\"row\"], Tables[K][\"insert\"], RelsOf<Tables[K]>>;\n};\n\n/** Bir şemanın tabloları PLAN operasyonları olarak — `TxTables`'ın public\n * DIŞI şemalar için ikizi. */\ntype TxTablesOf<S> = {\n [T in keyof S]: Extract<S[T], TableTypes> extends { appendOnly: true }\n ? Omit<\n TxTable<\n Extract<S[T], TableTypes>[\"row\"],\n Extract<S[T], TableTypes>[\"insert\"],\n RelsOf<Extract<S[T], TableTypes>>\n >,\n TxAppendOnlyForbidden\n >\n : TxTable<\n Extract<S[T], TableTypes>[\"row\"],\n Extract<S[T], TableTypes>[\"insert\"],\n RelsOf<Extract<S[T], TableTypes>>\n >;\n};\n\n/**\n * Plan tutamağının şema yüzeyi — `EnvSchemaSurface`'ın BİREBİR ikizi.\n *\n * NEDEN AYNI ŞEKİL: `Database.billing.invoices` yazılabiliyorken\n * `tx.billing.invoices` yazılamıyordu, yani `billing` şemasındaki iki tabloyu\n * TEK ATOMİK PLANDA yazmak imkânsızdı — yazar `$query`'ye düşüyor, tipi ve RLS\n * yardımını kaybediyordu. Bu yüzeyin kapatmak için var olduğu düşüşün ta\n * kendisi, ve GOAL'ün \"ciddi ölçekli fintech\" yarısının tam ortasında\n * (nihai inceleme I-6).\n */\nexport type TxSchemaSurface = { public: TxTables } & {\n [S in keyof Schemas]: TxTablesOf<Schemas[S]>;\n};\n\n/**\n * The handle a `Database.$transaction(…)` callback receives.\n *\n * Tables only — no `query`, no `findById`, no `asService`. A read whose value\n * the plan does not write belongs outside the transaction, where it costs one\n * round trip and is an ordinary value you can branch on.\n *\n * `tx.public.x` ve `tx.<şema>.x`, `Database` ile aynı şekil. `tx.tables.x`\n * public'in TAKMA ADI olarak duruyor: bu run'ın göç notu onu öğretiyor ve her\n * mevcut çağrı onu kullanıyor — kaldırmak sekizinci bir kırıcı olurdu ve\n * hiçbir şey kazandırmazdı.\n */\nexport type TxPlan = TxPlanHandle<TxTables> & TxSchemaSurface;\n\n/**\n * The RLS-bypass sibling returned by `Database.$asService()`. Same typed surface\n * as {@link EnvTypedDatabase} — `tables`, the raw string ops, and a typed\n * `transaction` — but it does NOT re-expose `asService` (no double-bypass).\n * Every op it performs runs as the `service_role` (BYPASSRLS).\n */\nexport type EnvServiceDatabase = EnvSchemaSurface & {\n /** Commits independently of the request. All decision reads and writes belong\n * inside this callback; each retry includes a new BEGIN and COMMIT. */\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T>;\n /** Ham SQL. Generic verilmezse `unknown[]` döner (FR-021). */\n $query: DBClient[\"query\"];\n $insert: DBClient[\"insert\"];\n $update: DBClient[\"update\"];\n $delete: DBClient[\"delete\"];\n $findById: DBClient[\"findById\"];\n $findUnique: DBClient[\"findUnique\"];\n $diagnostics: DBClient[\"diagnostics\"];\n $findMany: DBClient[\"findMany\"];\n $page: DBClient[\"page\"];\n $put: DBClient[\"put\"];\n $updateMany: DBClient[\"updateMany\"];\n $deleteMany: DBClient[\"deleteMany\"];\n $count: DBClient[\"count\"];\n $search: DBClient[\"search\"];\n $similar: RecoOps[\"similar\"];\n $recommend: RecoOps[\"recommend\"];\n $facets: DBClient[\"facets\"];\n $supersede: DBClient[\"supersede\"];\n $claim: DBClient[\"claim\"];\n $lockRows: DBClient[\"lockRows\"];\n $lockRowsWhere: DBClient[\"lockRowsWhere\"];\n $advisoryXactLock: DBClient[\"advisoryXactLock\"];\n $attempt: DBClient[\"attempt\"];\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n /** Bkz. {@link EnvTypedDatabase.$transaction}. */\n /**\n * A plan is a savepoint in the current transaction. Nonzero `retry` is\n * refused; use $atomic for whole-transaction retry, including decision reads\n * and COMMIT. The default plan keeps request-scoped commit/rollback behavior.\n */\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>>;\n }\n\n/**\n * The typed-by-default Database surface: the `$`-prefixed string-keyed\n * `DBClient` ops PLUS one property per schema — `public` and every schema the\n * project declares — typed against the generated `palbase-env.d.ts`, a\n * `$transaction` that runs a whole plan in one request, and `$asService()` for\n * the explicit RLS-bypass sibling.\n *\n * NOT `tables`: that intermediate layer was removed (FR-001) and this sentence\n * outlived it by two majors, teaching a spelling that is TS2339. Pinned in\n * `src/database-ambient.test-d.ts`.\n *\n * The low-level `txPlan` op is deliberately NOT re-exposed here: `$transaction`\n * is the surface, and a hand-built plan would bypass the ref/guard machinery\n * that makes one safe to write.\n */\nexport type EnvSchemaSurface = { public: EnvTables } & {\n [S in keyof Schemas]: {\n [T in keyof Schemas[S]]: EnvTypedTable<Extract<Schemas[S][T], TableTypes>>;\n };\n};\n\n/**\n * `$` öneki, sistem üyelerini kullanıcı adlarından AYIRAN şeydir (FR-002/003).\n *\n * `Database` altında on beşten fazla string-anahtarlı op var ve çoğu son derece\n * makul bir tablo adı — `transaction` bir fintech şemasında neredeyse kaçınılmaz.\n * Şema doğrulayıcısı bir tablo/şema adının `$` ile başlamasına izin vermediği\n * için (`^[a-zA-Z_][a-zA-Z0-9_]*`), önek çakışmayı MATEMATİKSEL olarak imkânsız\n * kılar: bir isim ya `$`'la başlar (sistem) ya başlamaz (kullanıcı).\n */\nexport type DollarOps<T> = { [K in keyof T as `$${string & K}`]: T[K] };\n\n// NOT: `EnvTypedDatabase` bu yardımcıyı KULLANMIYOR, üyelerini AÇIKÇA yazıyor.\n// Sebep ölçüldü: `database.test.ts`'in sayımı TypeScript checker'ıyla yürüyor ve\n// her property'nin declaration'ını arıyor; mapped type ile yeniden adlandırılan\n// property'ler SYNTHETIC'tir, declaration taşımaz, dolayısıyla sayımda GÖRÜNMEZ.\n// Görünmeyen bir yüzey denetlenemez — o testin varlık sebebi de bu. Yardımcı,\n// runtime tarafındaki `satisfies` kontrolü için duruyor.\n\n/**\n * Projenin veri yüzeyi: `Database.<şema>.<tablo>` + `$` önekli sistem üyeleri.\n *\n * Bugünkü `tables` ve `schema(\"x\")` ikilisinin yerine geçer (FR-001). İki yol\n * tek yola iner: `public` de diğer şemalar gibi adıyla anılır, ara katman yoktur.\n *\n * @example\n * await Database.public.notes.findMany({ where: { owner: uid } });\n * await Database.billing.invoices.findMany({ where: { paid: false } });\n * await Database.$transaction((tx) => { … });\n */\nexport type EnvTypedDatabase = EnvSchemaSurface & {\n /** Commits independently of the request. A later handler failure does not\n * undo this scope. The callback cannot switch RLS identity or nest a root. */\n $atomic<T>(fn: (tx: AtomicDatabase) => Promise<T>, options?: AtomicOptions): Promise<T>;\n /** Ham SQL. Generic verilmezse `unknown[]` döner (FR-021). */\n $query: DBClient[\"query\"];\n $insert: DBClient[\"insert\"];\n $update: DBClient[\"update\"];\n $delete: DBClient[\"delete\"];\n $findById: DBClient[\"findById\"];\n $findUnique: DBClient[\"findUnique\"];\n $diagnostics: DBClient[\"diagnostics\"];\n $findMany: DBClient[\"findMany\"];\n $page: DBClient[\"page\"];\n $put: DBClient[\"put\"];\n $updateMany: DBClient[\"updateMany\"];\n $deleteMany: DBClient[\"deleteMany\"];\n $count: DBClient[\"count\"];\n $search: DBClient[\"search\"];\n $similar: RecoOps[\"similar\"];\n $recommend: RecoOps[\"recommend\"];\n $facets: DBClient[\"facets\"];\n $supersede: DBClient[\"supersede\"];\n $claim: DBClient[\"claim\"];\n $lockRows: DBClient[\"lockRows\"];\n $lockRowsWhere: DBClient[\"lockRowsWhere\"];\n $advisoryXactLock: DBClient[\"advisoryXactLock\"];\n $attempt: DBClient[\"attempt\"];\n $command<T>(fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T, options?: import(\"./command.js\").CommandOptions): Promise<Materialized<T>>;\n /** RLS'i bypass eden kardeş yüzey. Kendisi `$asService` TAŞIMAZ — çift bypass yok. */\n $asService(): EnvServiceDatabase;\n /**\n * Bir transaction çalıştırır. Callback işlemleri TARİF eder; tarifin tamamı\n * tek istekte gider ve broker onu tek bir transaction içinde koşturur.\n * Callback SENKRONDUR: döndüğünde hiçbir şey çalışmamıştır.\n */\n /**\n * A plan is a savepoint in the current transaction. Nonzero `retry` is\n * refused; use $atomic for whole-transaction retry, including decision reads\n * and COMMIT. The default plan keeps request-scoped commit/rollback behavior.\n */\n $transaction<T>(\n fn: (tx: TxPlan) => T extends Promise<unknown> ? never : T,\n opts?: { retry?: number },\n ): Promise<Materialized<T>>;\n }\n\n/** The same typed table/query surface on one active physical transaction. */\nexport type AtomicDatabase = Omit<EnvServiceDatabase, \"$atomic\">;\n","import { NotFound } from \"../errors.js\";\n\n/**\n * repository.ts — kiracıya kapsanmış CRUD'un TEK yazımı.\n *\n * Ölçülen kusur: tüketici katmanında 61 forwarding metodu vardı ve her biri\n * aynı iki satırı tekrar ediyordu — kiracı kolonunu yükleme ekle, sonucu\n * çevir. Aynı olan bir şeyi 61 kez yazmak onu 61 kez UNUTULABİLİR yapar; ve\n * unutulan tek bir yüklem, RLS'in altında bir kiracının satırını başka bir\n * kiracıya gösterir.\n *\n * ```ts\n * export class TodoRepository extends defineRepository(\n * Database.public.todos,\n * { tenant: \"household_id\" },\n * ) {}\n * ```\n *\n * Satır anahtarı `id` DEĞİLSE adıyla verilir — `defineTable` bir `id` kolonu\n * şart koşmuyor, birincil anahtar herhangi bir kolonda olabilir:\n *\n * ```ts\n * export class DocRepository extends defineRepository(\n * Database.public.docs,\n * { tenant: \"org_id\", key: \"slug\" },\n * ) {}\n * ```\n *\n * `Database` AMBIENT kalır ve enjekte EDİLMEZ: istek kapsamlıdır, yani bir\n * kurucuya kapatılan bir referans bir isteğin istemcisini bir başkasına\n * taşırdı. Tablo erişimcisi argüman olarak geçer ve her çağrıda güncel istek\n * kapsamını çözen proxy'ye iner; taban sınıfın kurucusu ARGÜMANSIZ kalır, o\n * yüzden container onu ek metadata olmadan çözer.\n */\n\n/**\n * Repo'nun tablodan İSTEDİĞİ dört üye — `Database.public.<t>`'nin alt kümesi.\n *\n * Yüklemler `Record<string, unknown>`: kiracı kolonunun adı ÇALIŞMA ANINDA\n * gelen bir değer, ve TypeScript jenerik bir anahtarla kurulan nesne\n * literalini mapped type'a bağlayamaz (ölçüldü: `{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye atanamaz). Kapsamı DAR tutup burada gevşetmek,\n * çağıranın tarafında `as` yazmaktan farklıdır: dışa bakan yüzey — `list`,\n * `find`, `insert`, `update`, `updateScoped`, `delete` — tamamen tipli kalır.\n *\n * `NoInfer`: `Row` YALNIZ `insert`'ün dönüşünden çıkarılır. `findMany` motorda\n * jenerik (`select`/`with`) ve kısıtlarıyla örneklendiğinde ilişki anahtarları\n * taşıyan BAŞKA bir satır tipi önerir; iki aday birleşince satır tipi sessizce\n * genişlerdi.\n */\nexport interface RepositoryTable<Row, Insert, Patch> {\n insert(data: Insert): Promise<Row>;\n findMany(q: { where: Record<string, unknown>; limit?: number }): Promise<NoInfer<Row>[]>;\n updateMany(q: { where: Record<string, unknown>; set: Patch }): Promise<NoInfer<Row>[]>;\n deleteMany(q: { where: Record<string, unknown> }): Promise<number>;\n}\n\n/**\n * Satır anahtarının VARSAYILANI: tablo bir `id` kolonu taşıyorsa `\"id\"`.\n *\n * `defineTable` bir `id` kolonu ŞART KOŞMUYOR — birincil anahtar herhangi bir\n * kolonda `.primaryKey()` ile ya da `primaryKey: [...]` ile bildirilebiliyor.\n * Bu yüzden anahtar sabit değil, PARAMETRE; ama `id` taşıyan tabloların\n * (çoğunluk) hiçbir şey yazmaması gerekiyor.\n */\nexport type DefaultRowKey<Row> = Extract<keyof Row & string, \"id\">;\n\n/**\n * Anahtar bulunamadığında REDDİ ADIYLA söyleyen tip.\n *\n * `id`'si olmayan bir tabloda `key` verilmezse {@link DefaultRowKey} `never`\n * olur ve `Row[never]` de `never`'dır: kapı doğru kapanır ama \"type 'string' is\n * not assignable to type 'never'\" diyerek ÇAREYİ söylemez. Buradaki tek alanlı\n * arayüz aynı reddi verir ve alanın adı hatanın içinde çareyi yazar.\n */\nexport interface MissingRowKey {\n \"defineRepository: bu satırda `id` kolonu yok — anahtarı { key: \\\"...\\\" } ile adlandır\": never;\n}\n\n/** Anahtar kolonunun DEĞER tipi; anahtar bilinmiyorsa {@link MissingRowKey}. */\nexport type RowKey<Row, PK extends keyof Row & string> = [PK] extends [never]\n ? MissingRowKey\n : Row[PK];\n\n/**\n * Kiracıya kapsanmış repo yüzeyi. `K` kiracı kolonu, `Row[K]` onun DEĞERİ.\n *\n * `insert` yükünde kiracı kolonu YOKTUR: onu repo yazar — `Omit` bunu ifade\n * edilemez kılıyor, anlatmıyor. `update`/`updateScoped` patch'i tablonun kendi\n * `set` şeklidir ve kiracı kolonunu DIŞLAMAZ: satırı başka bir kiracıya\n * taşımak tablonun `WITH CHECK` politikasının kararıdır, repo'nun değil — ve\n * repo'nun yüklemi zaten çağıranın kiracısına kapanmış durumda.\n */\nexport interface RepositoryOf<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n> {\n /** Kiracının tüm satırları. */\n list(tenant: Row[K]): Promise<Row[]>;\n /** Kiracının bu anahtarlı satırı, ya da yoksa `null` — yokluk bir DEĞER. */\n find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null>;\n /** Satırı kiracıya YAZAR: kiracı kolonu yükte değil, burada. */\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row>;\n /**\n * Kiracının bu id'li satırını günceller ve GÜNCEL satırı döner.\n *\n * Eşleşen satır yoksa `NotFound` ATAR — çağıran `!` yazmak ya da `null`\n * dallanması yazmak zorunda kalmasın. Yokluğu DEĞER olarak isteyen\n * {@link RepositoryOf.updateScoped} kullanır.\n */\n update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row>;\n /**\n * {@link RepositoryOf.update} ile AYNI yüklem, ama bulunamazsa `null` döner.\n *\n * Tüketicinin bugün elle yazdığı `updateMany(…).then(rows => rows[0] ?? null)`\n * kalıbının adı budur.\n */\n updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null>;\n /** Kiracının bu anahtarlı satırını siler. Yoksa bir şey olmaz. */\n delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void>;\n}\n\n/**\n * Kiracıya kapsanmış bir repo TABAN SINIFI üretir.\n *\n * Dönen sınıf `abstract`: doğrudan `new` edilemez, çünkü DI'ın çözeceği ad alt\n * sınıfın adıdır (`TodoRepository`), üretilen anonim sınıfınki değil.\n */\nexport function defineRepository<\n Row,\n Insert,\n Patch,\n K extends keyof Row & string,\n PK extends keyof Row & string = DefaultRowKey<Row>,\n>(\n table: RepositoryTable<Row, Insert, Patch>,\n opts: { tenant: K; key?: PK },\n): abstract new () => RepositoryOf<Row, Insert, Patch, K, PK> {\n const tenantColumn = opts.tenant;\n // Anahtar `string` olarak tutuluyor: yüklemler zaten `Record<string, unknown>`\n // ve `opts.key ?? \"id\"`'yi `PK`'ye daraltmak bir `as` gerektirirdi — tipin\n // taşıdığı güvence dışa bakan imzalarda, burada değil.\n const rowKey: string = opts.key ?? \"id\";\n\n // Yüklem TEK yerde kuruluyor. 61 forwarding metodunun her birinde ayrı ayrı\n // yazılıyor olması, birinde unutulmasını mümkün kılan şeydi.\n const scope = (tenant: Row[K]): Record<string, unknown> => ({ [tenantColumn]: tenant });\n const scopeRow = (tenant: Row[K], id: RowKey<Row, PK>): Record<string, unknown> => ({\n [tenantColumn]: tenant,\n [rowKey]: id,\n });\n\n /**\n * Kiracı kolonunu YAZMA yüküne ekleyen tek yer — ve bu dosyadaki tek\n * daraltma.\n *\n * Gerekçesi TypeScript'in ölçülmüş bir sınırı: jenerik bir anahtarla kurulan\n * nesne literali mapped type'a bağlanmıyor (`{ [k]: v }` → `{ [x: string]:\n * V }`, `{ [P in K]: V }`'ye TS2322 ile atanamıyor). Daraltma TEK satırda ve\n * çağıranın göremediği bir yerde duruyor; dışa bakan altı metodun imzası\n * tamamen tipli.\n *\n * Kiracı SONRA yazılıyor: yükte aynı adda bir alan kalmışsa (tip onu\n * yasaklıyor, ama bu yol JavaScript'ten de çağrılabilir) repo'nunki kazanır.\n * Kapsamı çağıranın verisi belirlemez.\n */\n const scopedPayload = (values: Omit<Insert, K>, tenant: Row[K]): Insert =>\n ({ ...values, [tenantColumn]: tenant }) as Insert;\n\n abstract class Repository implements RepositoryOf<Row, Insert, Patch, K, PK> {\n list(tenant: Row[K]): Promise<Row[]> {\n return table.findMany({ where: scope(tenant) });\n }\n\n async find(tenant: Row[K], id: RowKey<Row, PK>): Promise<Row | null> {\n const rows = await table.findMany({ where: scopeRow(tenant, id), limit: 1 });\n return rows[0] ?? null;\n }\n\n insert(tenant: Row[K], values: Omit<Insert, K>): Promise<Row> {\n return table.insert(scopedPayload(values, tenant));\n }\n\n async update(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row> {\n const row = await this.updateScoped(tenant, id, patch);\n if (row === null) {\n throw new NotFound(\n `${String(tenantColumn)}=${String(tenant)} kapsamında ${rowKey}=${String(id)} bulunamadı`,\n );\n }\n return row;\n }\n\n async updateScoped(tenant: Row[K], id: RowKey<Row, PK>, patch: Patch): Promise<Row | null> {\n const rows = await table.updateMany({ where: scopeRow(tenant, id), set: patch });\n return rows[0] ?? null;\n }\n\n async delete(tenant: Row[K], id: RowKey<Row, PK>): Promise<void> {\n await table.deleteMany({ where: scopeRow(tenant, id) });\n }\n }\n\n return Repository;\n}\n","/**\n * The two ways a stack refuses to boot — and they are two because their CURES\n * are two.\n *\n * A LEAF MODULE ON PURPOSE. `db/` does not import from `engine/` and must not\n * start: the schema layer is below the engine, and a refusal both of them raise\n * cannot live in either. Anything imported here would invert that.\n *\n * WHY THE SPLIT EXISTS AT ALL — measured live on 2026-09-04.\n *\n * `8qitbtucm` ran for days on an image whose `setSchema` did not build\n * relations. Moved onto one that does, the same artifact hit\n * `buildRelations` at boot, threw a bare `Error`, and the runtime — which waits\n * only on its own `ArtifactRefused` — treated it as fatal. The supervisor took\n * the pod down, palsvc with it. CrashLoopBackOff, back-off 5m, and palsvc is\n * THE PROCESS THAT ACCEPTS THE PUSH the message asks for.\n *\n * That is verbatim the lesson `v2/runtime/src/loader.ts` already carries for\n * ABI refusals: *\"the cure was named in the error and made impossible by the\n * exit that carried it.\"* It cost a tenant a third time because the second\n * refusal had no type to be recognised by.\n *\n * SO THE RULE IS THE CURE, NOT THE SEVERITY:\n *\n * {@link DeclarationRefused} — what was PUSHED cannot be built. Restarting\n * re-reads the same bytes and fails identically; only a new artifact\n * changes the answer. The runtime WAITS on this, keeps palsvc alive, and\n * says the reason out loud.\n *\n * {@link BootRefused} — the ENVIRONMENT this stack was handed is unusable\n * (no DATABASE_URL, an unparseable PORT, no SQL driver). No push fixes it;\n * waiting for one would be a lie told in a log line forever. Stays fatal.\n *\n * NOT A MESSAGE PATTERN. The runtime's loader already says why: *\"The\n * distinction is the loader's TYPE, not a pattern over its wording.\"* A gate\n * that reads wording drifts from the thing it claims to measure the first time\n * someone improves an error message.\n */\n\n/**\n * The tag that survives a realm boundary.\n *\n * `instanceof` compares constructor identity, and identity is per module\n * instance. In the pod today the runtime and the bundle share one install\n * (measured: both frames resolve to `/app/node_modules/@palbase/backend`), so\n * `instanceof` would work — but it works by a coincidence of packaging, and a\n * bundle that ever carries its own copy would make every declaration refusal\n * silently fatal again. `Symbol.for` reads from the process-wide registry, so\n * the tag means the same thing in every copy.\n *\n * Exported so the runtime can recognise the refusal without importing the\n * class — see {@link isDeclarationRefused}.\n */\nexport const DECLARATION_REFUSAL = Symbol.for(\"palbase.backend.declarationRefusal\");\n\n/**\n * What was pushed cannot be built. The cure is a NEW ARTIFACT.\n *\n * Thrown by the declaration layer — relation naming, ownership, entry points —\n * wherever a fact about the author's code makes the app impossible to\n * construct. Never thrown for anything the environment could change.\n */\nexport class DeclarationRefused extends Error {\n /** @see DECLARATION_REFUSAL — realm-safe, unlike `instanceof`. */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(message: string) {\n super(message);\n this.name = \"DeclarationRefused\";\n }\n}\n\n/**\n * True for a refusal whose only cure is a new artifact — across realms.\n *\n * Takes `unknown` because every caller is a `catch`. A non-object, a null, a\n * plain `Error`: all false, and false is the safe answer — it means \"keep\n * treating this as fatal\", which is what the code did before this type existed.\n */\nexport function isDeclarationRefused(e: unknown): e is DeclarationRefused {\n return typeof e === \"object\" && e !== null && (e as Record<symbol, unknown>)[DECLARATION_REFUSAL] === true;\n}\n","/**\n * stack-gen.ts — generate the `palbase-stack.d.ts` text from the names the\n * linked environment's stack holds.\n *\n * The twin of `db/env-gen.ts`: the CLI calls\n * {@link makeStackDts} with the three name sets it read off the stack and\n * writes the result to `palbase-stack.d.ts` at the project root. That file\n * augments the `@palbase/backend/stack` interfaces, so `Secrets.get(...)`, the\n * Flags client and `@Upload({ bucket })` accept the project's real names and\n * nothing else.\n *\n * The generator does NOT reach the network and does NOT decide what a name is:\n * it renders what it is handed. The stack is the authority on which names exist\n * (`GET /v1/management/secrets`, `/flags`, `/storage/buckets`); re-deciding that\n * here would be a second, weaker copy of it.\n *\n * The emitted file ends in `export {};` — same as `makeEnvDts` and\n * `makePurchasesDts`. Without it the `.d.ts` is a global script, and\n * `declare module \"…\"` there DECLARES an ambient module (shadowing the real one,\n * so every name silently becomes invalid) instead of AUGMENTING it.\n */\n\n/** The three name sets read off the stack. Order is irrelevant — each set is\n * sorted here so the same stack always renders the same bytes and a diff shows\n * what CHANGED rather than how the API happened to order its answer. */\n/** One bucket and the renditions it declares. */\nexport interface BucketInput {\n name: string;\n variants: readonly string[];\n}\n\nexport interface StackNames {\n /** Secret names from the project's vault. */\n secrets: readonly string[];\n /** Flag keys from the project's flag store. */\n flags: readonly string[];\n /**\n * Buckets from the project's storage — a bare name, or a name with the\n * renditions it declares.\n *\n * A bucket is not only a NAME: `Storage.buckets.docs.getPublicUrl(p, {\n * variant })` refuses a rendition the bucket does not have, so the variant\n * union has to travel with it. The bare-string form is shorthand for \"no\n * variants\", which renders `never` and accepts none.\n */\n buckets: readonly (string | BucketInput)[];\n /**\n * Application role names the stack declares (`palbase roles`).\n *\n * OPTIONAL — omitted by every caller that predates FR-002a (this file's own\n * golden tests included). A missing set renders `interface Roles {}`, the\n * same closed default as an empty one; no existing caller breaks.\n */\n roles?: readonly string[];\n}\n\n/** Sorted, de-duplicated names. A stack that reports one twice (two pages of a\n * listing overlapping, say) must not render a duplicate member — TypeScript\n * accepts it, but the file stops being a function of the stack's contents. */\nfunction liveNames(names: readonly string[]): string[] {\n return [...new Set(names)].sort();\n}\n\n/** A bare identifier stays bare; anything else is quoted. Bucket names carry\n * dashes and dots (the Storage module's allowed shape), and an unquoted\n * `my-bucket` parses as a subtraction rather than a member name. */\nfunction memberName(name: string): string {\n return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name) ? name : JSON.stringify(name);\n}\n\nfunction members(names: string[]): string {\n if (names.length === 0) return \"\";\n return `\\n${names.map((n) => ` ${memberName(n)}: true;`).join(\"\\n\")}\\n `;\n}\n\n/** Buckets render a SHAPE rather than a marker, because each carries its variant\n * union. `never` for a bucket with none: the type then accepts no variant name\n * at all, which is exactly what a bucket without renditions offers. */\nfunction bucketMembers(buckets: readonly (string | BucketInput)[]): string {\n const normalized = buckets.map((b) => (typeof b === \"string\" ? { name: b, variants: [] as readonly string[] } : b));\n const byName = new Map<string, readonly string[]>();\n for (const b of normalized) byName.set(b.name, b.variants);\n const names = [...byName.keys()].sort();\n if (names.length === 0) return \"\";\n const rows = names.map((name) => {\n const variants = [...new Set(byName.get(name) ?? [])].sort();\n const union = variants.length === 0 ? \"never\" : variants.map((v) => JSON.stringify(v)).join(\" | \");\n return ` ${memberName(name)}: { variants: ${union} };`;\n });\n return `\\n${rows.join(\"\\n\")}\\n `;\n}\n\n/**\n * The four interface members of `declare module \"@palbase/backend/stack\"`,\n * with NO surrounding `declare module` wrapper and NO leading/trailing blank\n * line — just the body, indented two spaces, ready to be dropped inside\n * someone else's `declare module \"@palbase/backend/stack\" { … }`.\n *\n * Shared by {@link makeStackDts} (the standalone file) and `db/env-gen.ts`'s\n * `makeEnvDts` (the single combined file, T008/FR-002): two renderers writing\n * two copies of \"how a name becomes a member\" is exactly the drift `Roles`\n * must not repeat what happened to `Secrets`/`Flags`/`Buckets` — ONE function\n * owns the shape, both files call it.\n *\n * An empty set renders an empty interface, which is a MEANINGFUL value: the\n * stack holds no such names, so the corresponding union is `never` and every\n * call spelling one fails to compile. It is not the same as \"the file was\n * never generated\" only in that the file exists — both states refuse every\n * name, and both are correct.\n */\nexport function stackInterfaceBody(names: StackNames): string {\n const secrets = liveNames(names.secrets);\n const flags = liveNames(names.flags);\n const roles = liveNames(names.roles ?? []);\n\n return ` interface Secrets {${members(secrets)}}\n\n interface Flags {${members(flags)}}\n\n interface Buckets {${bucketMembers(names.buckets)}}\n\n interface Roles {${members(roles)}}`;\n}\n\n/** Render the project's standalone `palbase-stack.d.ts` (pre-T008 shape; kept\n * for the direct callers `index.ts` still exports it to). See\n * {@link stackInterfaceBody} for what actually decides the four interfaces. */\nexport function makeStackDts(names: StackNames): string {\n return `// palbase-stack.d.ts — GENERATED by @palbase/backend. Do not edit.\n// Source: the linked environment's stack.\n\ndeclare module \"@palbase/backend/stack\" {\n${stackInterfaceBody(names)}\n}\n\nexport {};\n`;\n}\n","/** Column and table UNIQUE declarations, including composite primary keys. */\nexport function uniqueKeysOf(table: {\n columns?: Record<string, unknown>;\n primaryKey?: readonly string[];\n unique?: readonly { columns: readonly string[] }[];\n}): string[][] {\n const columns = table.columns ?? {};\n const inlinePrimary: string[] = [], keys: string[][] = [];\n for (const [name, value] of Object.entries(columns)) {\n const col = (value && typeof value === \"object\" && \"_def\" in value ? value._def : value) as\n { primaryKey?: boolean; unique?: boolean } | undefined;\n if (col?.primaryKey) inlinePrimary.push(name);\n if (col?.unique) keys.push([name]);\n }\n const primary = table.primaryKey ?? inlinePrimary;\n if (primary.length) keys.unshift([...primary]);\n for (const key of table.unique ?? []) keys.push([...key.columns]);\n const seen = new Set<string>();\n return keys.filter(key => {\n if (!key.length || new Set(key).size !== key.length || key.some(col => !Object.hasOwn(columns, col))) {\n throw new Error(\"Unique lookup requires a nonempty declared key of distinct, known columns\");\n }\n const identity = JSON.stringify([...key].sort());\n if (seen.has(identity)) return false;\n seen.add(identity); return true;\n });\n}\n\n/** Nulls in ordinary PostgreSQL UNIQUE constraints are not unique. */\nexport function assertUniqueLookup(table: string, keys: readonly (readonly string[])[], where: Record<string, unknown>): void {\n if (!where || typeof where !== \"object\" || Array.isArray(where)) throw new Error(`findUnique(${table}): where must contain one declared unique key`);\n const columns = Object.keys(where);\n if (!keys.some(key => key.length === columns.length && key.every(col => Object.hasOwn(where, col)))) {\n throw new Error(`findUnique(${table}): supply exactly one declared unique key (${keys.map(key => key.join(\" + \")).join(\"; \") || \"none declared\"}); use findMany for other filters`);\n }\n for (const [name, value] of Object.entries(where)) {\n if (value === null || value === undefined || (typeof value === \"object\" && !(value instanceof Date)) || typeof value === \"function\" || typeof value === \"symbol\") {\n throw new Error(`findUnique(${table}): ${name} requires a non-null scalar equality value`);\n }\n }\n}\n\n/** A union of exact keys, not a partial row that could match many records. */\nexport type UniqueWhere<Row, Keys> = Keys extends readonly (infer Key extends readonly string[])[]\n ? Key extends unknown\n ? { [K in Extract<Key[number], keyof Row>]-?: NonNullable<Row[K]> } &\n { [K in Exclude<keyof Row, Key[number]>]?: never }\n : never\n : never;\n","/**\n * env-gen.ts — generate the `palbase-env.d.ts` text from a `defineSchema()`\n * result.\n *\n * The CLI (`palbase build`) and the deploy pipeline call\n * {@link makeEnvDts} with the project's schema and write the returned string to\n * `palbase-env.d.ts` at the project root. That file AUGMENTS the\n * `@palbase/backend/env` `Tables` interface (controlled global augmentation,\n * C5) so `Database.public.<name>` is typed with no import and no generic.\n *\n * The output is FLAT: each table gets a `{ row: {...}; insert: {...} }` entry\n * with plain TypeScript object types. The phantom `ColumnBuilder<...>` type\n * NEVER appears in the generated `.d.ts` — that type only lives at authoring\n * time inside the project's `db/*.ts` schema files.\n */\nimport { DeclarationRefused } from \"../refusals.js\";\nimport { stackInterfaceBody, type StackNames } from \"../stack-gen.js\";\n\nimport type { ColumnDef } from \"./columns.js\";\n// FR-058: the \"public is bare, everything else is qualified\" rule lives in ONE\n// helper. This file used to carry two more copies of it — a module-level\n// `qualify` and a second, identical local one inside `makeEnvDts` — and the\n// duplication was not cosmetic: re-deriving the key here instead of reading the\n// one `resolveReferences` already wrote is exactly how a public foreign key got\n// relabelled onto another schema's table. Two names for one truth are two\n// interpreters of it.\nimport { qualifiedTableKey } from \"./schema-json.js\";\nimport type { SchemaDef, TableDef } from \"./schema.js\";\nimport { uniqueKeysOf } from \"./unique.js\";\nimport { CODECS } from \"./columns.js\";\n\n/** The TypeScript value type for a column, ignoring nullability (added by the\n * caller). Mirrors the `ColValue` mapped type in columns.ts exactly. */\nfunction baseTsType(def: ColumnDef): string {\n // A NAMED CODEC DECIDES THE SURFACED TYPE, and it is read BEFORE the switch\n // because the codec is exactly the declaration that overrides the storage\n // type. `numeric` surfacing as `string` is correct by default; `asNumber()`\n // is the author saying \"in this process it is a number\", and the engine\n // already makes that true (FR-003).\n if (def.codec !== undefined && def.codec in CODECS) {\n return CODECS[def.codec].tsType;\n }\n switch (def.type) {\n case \"uuid\":\n case \"text\":\n case \"timestamp\":\n return \"string\";\n case \"integer\":\n return \"number\";\n // Both are exact-precision in Postgres and lossy as a JSON number, so the\n // database proxy serializes them as strings — measured: 9007199254740993\n // used to arrive as ...992 and 41.00821234567890123 as 41.0082123456789.\n // numeric had no case at all and fell through to `unknown`, which typed\n // every numeric column out of existence.\n case \"bigint\":\n case \"numeric\":\n return \"string\";\n case \"boolean\":\n return \"boolean\";\n case \"jsonb\":\n // `unknown` DEĞİL: `unknown` taşıyan bir kolonda filtre birleşimi\n // (`V | ColRef | …`) tamamen `unknown`'a çöker, yani HİÇBİR kural\n // tutunamaz — `col()` o kolonu her şeyle karşılaştırabiliyordu\n // (D-021'in açık bıraktığı son delik). `Json` gerçek kısıtı söylüyor ve\n // markalanabiliyor.\n return \"Json\";\n // FR-008: the authoring type of a pgvector column. The default `unknown`\n // branch below STAYS — an unknown wire type is refused on the Go side\n // (FR-005), never papered over here.\n case \"vector\":\n return \"number[]\";\n case \"enum\": {\n const values = def.enumValues ?? [];\n if (values.length === 0) return \"string\";\n return values.map((v) => JSON.stringify(v)).join(\" | \");\n }\n default: {\n // TÜKETİCİLİK KAPISI. `ColumnType`'a yeni bir değer eklenip burası\n // güncellenmezse BU SATIR DERLEME HATASI verir.\n //\n // Eskiden burası sessizce `unknown` döndürüyordu ve `unknown` taşıyan bir\n // kolonda filtre birleşimi tamamen `unknown`'a çöker — yani `col()`,\n // `now()`, toplama, hepsi o kolonda kuralsız kalırdı. `numeric` bir\n // zamanlar tam olarak buraya düşmüştü (\"numeric had no case at all\"),\n // ve `jsonb` aynı çöküşü 28.0.0'a kadar yaşadı. Üçüncüsü olmasın.\n const unhandled: never = def.type;\n throw new Error(\n `env-gen: \"${String(unhandled)}\" kolon tipinin TypeScript karşılığı ` +\n `bildirilmemiş. baseTsType'a bir case ekleyin — sessizce \\`unknown\\` ` +\n `dönmek o kolonu her kuralın dışına çıkarır.`,\n );\n }\n }\n}\n\n/** The full row type for a column: base type, `| null` when nullable. */\n/**\n * Kolonun POSTGRES tipi, tipin İÇİNDE taşınan bir marka olarak.\n *\n * TypeScript `numeric`, `bigint`, `text`, `uuid` ve `timestamp`'i tek bir\n * `string`'e düşürüyor. Yani `integer ↔ numeric` (Postgres'te geçerli) ile\n * `integer ↔ text` (geçersiz) tipte AYNI görünüyordu ve `col()` hangi kuralı\n * koyarsa koysun bir tarafta yanılıyordu (D-021: yanlış ret mi yanlış kabul mü\n * seçilecekti — ikisi de yanlıştı).\n *\n * Marka o bilgiyi geri getiriyor. `& { readonly __pg?: \"…\" }` seçilmesinin\n * nedeni ÖLÇÜLDÜ: isteğe bağlı bir alanla kesişim, satırı hâlâ düz `string`\n * olarak okunabilir ve düz bir değerle YAZILABİLİR bırakıyor — yani marka\n * yalnız karşılaştırma kurallarının gördüğü, kullanıcının hiç görmediği bir\n * bilgi. Zorunlu bir alan olsaydı `{ balance: \"10.00\" }` derlenmezdi.\n *\n * `enum` KİMLİĞİYLE markalanıyor: iki FARKLI enum'u Postgres de karşılaştırmaz,\n * ve düz `\"enum\"` markası onları aynı sayardı.\n */\nfunction pgBrand(def: ColumnDef): string {\n if (def.type === \"enum\") {\n const values = [...(def.enumValues ?? [])].sort();\n return values.length === 0 ? \"enum\" : `enum:${values.join(\"|\")}`;\n }\n return def.type;\n}\n\nfunction rowType(def: ColumnDef): string {\n const base = baseTsType(def);\n // `unknown` MARKALANAMAZ: marka bir kesişim ve `unknown & X` doğrudan `X`'e\n // çöker. `jsonb` kolonu `Pg<unknown, \"jsonb\">` yazılınca tipi\n // `{ readonly __pg?: \"jsonb\" }` oluyordu — yani kolon DARALDI ve meşru bir\n // nesne yazılamaz hâle geldi. GERÇEK bir projede ölçüldü: 33 tablolu bir\n // şemada `user_preferences`'ın jsonb kolonlarına yazan iki çağrı kırıldı.\n //\n // Markasız kalan kolon eski (gevşek) kurala düşer — jsonb için bu zaten\n // bugünkü davranış, yani hiçbir şey kötüleşmiyor.\n\n // Takma ad, ham kesişim yerine: bu dosyayı GELİŞTİRİCİ de açıyor ve\n // `(string) & { readonly __pg?: \"uuid\" }` satırları okunmaz kılıyordu.\n // `Pg<string, \"uuid\">` hem kısa hem kolonun Postgres tipini SÖYLÜYOR.\n // Takma ad ayrıca `enum` birleşimlerini tip argümanı olarak sarmalıyor —\n // ham kesişimde `A | B & C`, `A | (B & C)` diye ayrışıp bir dalı markasız\n // bırakırdı.\n const branded = `Pg<${base}, ${JSON.stringify(pgBrand(def))}>`;\n return def.nullable ? `${branded} | null` : branded;\n}\n\n/** True when a column may be omitted on INSERT — nullable OR has any default.\n * Mirrors `ColIsOptionalOnInsert` in columns.ts. */\nfunction optionalOnInsert(def: ColumnDef): boolean {\n return (\n def.nullable === true ||\n def.defaultRandom === true ||\n def.defaultNow === true ||\n def.defaultValue !== undefined\n );\n}\n\n\n\nexport type Relation = {\n name: string;\n to: string;\n kind: \"one\" | \"many\";\n /**\n * The foreign-key COLUMN the relation runs through.\n *\n * Without it \"there is a relation\" is half the fact, and everything that\n * consumes the map — the query builder, the seed engine, the cross-boundary\n * lock — has to re-derive the column: a second interpreter of the same graph.\n */\n via: string;\n};\n\n/** `list_id` → `list`; anything else keeps its column name (FR-019). */\nfunction forwardName(column: string): string {\n return column.endsWith(\"_id\") ? column.slice(0, -3) : column;\n}\n\n/**\n * Where a relation name came from, so a refusal can say it out loud.\n *\n * A collision on a parent table can be between two REVERSE edges, or between a\n * reverse edge and the parent's own FORWARD one — `lists.todos_id` names a\n * forward `todos`, and `todos.list_id` reverses onto `lists` as `todos` too.\n * The old message called both sides \"reverse relations\", which sent the reader\n * looking for a second reverse edge that was never there.\n */\ntype NameOrigin = {\n /** The table the foreign-key COLUMN is declared on. */\n table: string;\n column: string;\n direction: \"forward\" | \"reverse\";\n def: ColumnDef;\n};\n\nfunction describeOrigin(o: NameOrigin): string {\n return o.direction === \"forward\"\n ? `the foreign key \"${o.table}.${o.column}\"`\n : `the reverse of \"${o.table}.${o.column}\"`;\n}\n\n/**\n * The call that renames THIS relation — named per verb, because the verbs do\n * not take the same options.\n *\n * NFR-002 asks every refusal to name a remedy the reader can apply. The old\n * message said `references(() => …, { as: \"…\" })` for every case, and\n * `ownedByUser()` takes no arguments at all while `userRef` /\n * `installationRef` take `{ onDelete, as }` — so following it literally was\n * impossible for exactly the columns that most often collide.\n *\n * A reverse edge only ever exists for a target that is a DECLARED table, and\n * only `references()` can point at one: `auth.*` is not declared (no reverse\n * edge) and a self-reference has no separate parent (skipped). So the reverse\n * remedy has one form and it is always the right one.\n */\nfunction renameCall(o: NameOrigin): string {\n if (o.direction === \"reverse\") return `references(() => …, { reverseAs: \"…\" })`;\n if (o.def.owns === true) {\n return `ownedByUser() takes no { as } — if \"${o.column}\" only POINTS at a user, declare it userRef({ onDelete: … }) instead`;\n }\n const target = o.def.references?.table;\n if (target === \"auth.users\") return `userRef({ onDelete: …, as: \"…\" })`;\n if (target === \"auth.installations\") return `installationRef({ onDelete: …, as: \"…\" })`;\n if (o.def.selfRefColumn !== undefined) return `selfReferences(\"…\", { as: \"…\" })`;\n return `references(() => …, { as: \"…\" })`;\n}\n\n/**\n * Derive the relation graph from the declared foreign keys.\n *\n * Until now a SECOND foreign key onto the same parent was silently dropped: only\n * the first column in declaration order was recorded, and the other one quietly\n * became an ordinary writable column. Which relation you got was decided by the\n * order somebody happened to type the columns in. That silence is what this\n * function exists to end — ambiguity is rejected and named, never resolved by\n * declaration order.\n *\n * THE HAZARD IS ONE NAME WITH TWO RELATIONS (FR-022), not two foreign keys onto\n * one target. Those are not the same set, and treating them as one refused the\n * package's own documented shape: a table with `ownedByUser()` beside a\n * `userRef()` has two foreign keys onto `auth.users` and no ambiguity whatever —\n * the names are `owner` and the pointing column's own, and `auth.users` is not a\n * declared table, so neither takes a reverse edge to collide over. The gate\n * counted the owner toward the total while exempting it from the naming\n * requirement, so `docs/schema.md`'s example threw, naming a remedy no verb in\n * it accepts.\n *\n * The two directions are named SEPARATELY. `as` sets the forward name (FR-019),\n * `reverseAs` sets the reverse one (FR-020, whose default is the child table's\n * name). One option cannot set both: two children that each name their forward\n * edge `author` collided on the parent as `author`, and the refusal asked for\n * the `{ as }` they had both already written — a refusal with no exit.\n */\nexport function buildRelations(schemas: readonly SchemaDef[]): Map<string, Relation[]> {\n const out = new Map<string, Relation[]>();\n /** Per table key: relation name → where that name came from. */\n const taken = new Map<string, Map<string, NameOrigin>>();\n for (const schema of schemas) {\n for (const t of Object.values(schema.tables)) {\n const key = qualifiedTableKey(schema.name, t.name);\n out.set(key, []);\n taken.set(key, new Map());\n }\n }\n\n /** Record one edge on `tableKey`, or refuse the name it would take twice. */\n const claim = (tableKey: string, name: string, origin: NameOrigin, edge: Relation): void => {\n const names = taken.get(tableKey);\n if (names === undefined) return;\n const held = names.get(name);\n if (held !== undefined) {\n // FR-015 asks this one to LIST the conflicting columns; it used to name\n // neither, so the reader had to find them.\n if (held.def.owns === true && origin.def.owns === true) {\n throw new DeclarationRefused(\n `table \"${tableKey}\" declares TWO owner columns (${held.column}, ${origin.column}) — a table has at most ONE ownedByUser(). If the other column only POINTS at a user, declare it userRef({ onDelete: … }) instead.`,\n );\n }\n const heldFix = renameCall(held);\n const originFix = renameCall(origin);\n const remedy =\n heldFix === originFix\n ? `rename one of them: ${heldFix}`\n : `rename one of them — \"${held.table}.${held.column}\": ${heldFix}; \"${origin.table}.${origin.column}\": ${originFix}`;\n throw new DeclarationRefused(\n `table \"${tableKey}\": ${describeOrigin(held)} and ${describeOrigin(origin)} both resolve to the relation name \"${name}\" — ${remedy}.`,\n );\n }\n names.set(name, origin);\n out.get(tableKey)?.push(edge);\n };\n\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n const childKey = qualifiedTableKey(schema.name, table.name);\n if (!out.has(childKey)) continue;\n\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.references === undefined) continue;\n // `references.table` IS the canonical key — `resolveReferences` wrote it\n // with `qualifiedTableKey`, so public is bare and everything else is\n // qualified, `auth.users` included.\n //\n // It used to be re-derived here from a bare-name → key map, which gave a\n // DIFFERENT answer in exactly one case: two schemas declaring the same\n // table name. The map kept whichever was declared LAST, so a public FK\n // was relabelled onto another schema's table and the real parent got no\n // reverse edge — silently, while RefJSON (and therefore the DDL) went on\n // pointing at the right one. The generated type and the database\n // disagreed, and nothing said so.\n const targetKey = def.references.table;\n\n const name = def.owns === true ? \"owner\" : (def.refAs ?? forwardName(col));\n claim(\n childKey,\n name,\n { table: table.name, column: col, direction: \"forward\", def },\n { name, to: targetKey, kind: \"one\", via: col },\n );\n\n // Reverse edge, unless the FK points outside the declared schemas (auth.users)\n // or back at the declaring table (a self-reference has no separate parent).\n if (!out.has(targetKey) || targetKey === childKey) continue;\n // FR-020: the reverse name is the CHILD TABLE's, not the forward name.\n // `as` used to set this too, which both broke FR-020 for a single named\n // FK (`users.author` where `users.posts` was required) and left two\n // children that chose the same forward name with no way to be declared.\n const reverse = def.reverseAs ?? table.name;\n claim(\n targetKey,\n reverse,\n { table: table.name, column: col, direction: \"reverse\", def },\n { name: reverse, to: childKey, kind: \"many\", via: col },\n );\n }\n }\n }\n return out;\n}\n\n\n\n\n/** Emit the `row` / `insert` / `relations` blocks for one table at the given\n * base indentation. */\nfunction tableBlock(table: TableDef, relations: Relation[], indent: string): string {\n const cols = Object.entries(table.columns);\n const rowLines = cols.map(([col, builder]) => {\n return `${indent} ${col}: ${rowType(builder._def)};`;\n });\n // FR-004: `can` — adlandırılmış UPDATE policy adlarının literal union'ı.\n // Policy'siz tabloda `never[]`: alan hep var (motor `[]` yazar), eleman yok.\n // Gerçek bir `can` kolonu varsa yankı yoktur (motor da kolonu korur): ikinci\n // bir `can:` satırı `skipLibCheck` altında sessizce İLK bildirime çözülürdü.\n // İlişki de aynı rezervasyon (defineTable reddeder; ham TableDef için kemer).\n const hasCanColumn =\n Object.prototype.hasOwnProperty.call(table.columns, \"can\") || relations.some((r) => r.name === \"can\");\n // Motorla aynı süzgeç: 59 baytı aşan ad (`can:` + ad > NAMEDATALEN 63) telde asla gelmez.\n const canNames = (table.policies ?? []).filter((p) => p.command === \"update\" && p.permissive !== false && Buffer.byteLength(`can:${p.name}`, \"utf8\") <= 63).map((p) => JSON.stringify(p.name));\n // The contract travels with the type (final review M-2): a reader of the .d.ts\n // sees what `can` is for without opening the docs.\n const canDoc = `${indent} /** Names of this table's UPDATE policies whose \\`using\\` is true for THIS row and caller — an AFFORDANCE for the interface (draw or hide a control); never an authorization decision, may be incomplete, the server decides again on every request. */`;\n const canLine = hasCanColumn ? null : `${canDoc}\\n${indent} can: ${canNames.length === 0 ? \"never[]\" : `(${canNames.join(\" | \")})[]`};`;\n const insertLines = cols.map(([col, builder]) => {\n const def = builder._def;\n const opt = optionalOnInsert(def) ? \"?\" : \"\";\n return `${indent} ${col}${opt}: ${rowType(def)};`;\n });\n const relEntries = relations\n .map(\n (r) =>\n `${r.name}: { to: ${JSON.stringify(r.to)}; kind: ${JSON.stringify(r.kind)}; via: ${JSON.stringify(r.via)} }`,\n )\n .join(\"; \");\n return [\n `${indent}${table.name}: {`,\n `${indent} row: {`,\n ...rowLines,\n ...(canLine === null ? [] : [canLine]),\n `${indent} };`,\n `${indent} insert: {`,\n ...insertLines,\n `${indent} };`,\n `${indent} relations: {${relEntries === \"\" ? \"\" : ` ${relEntries} `}};`,\n `${indent} uniqueKeys: ${JSON.stringify(uniqueKeysOf(table))};`,\n // searchable: vector kolonu YA DA search beyanı → EnvTypedTable'da search()\n // üyesini açan yapısal bayrak (FR-013). Yokken satır hiç üretilmez ki\n // mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(cols.some(([, b]) => b._def.type === \"vector\") || table.search !== undefined\n ? [`${indent} searchable: true;`]\n : []),\n // appendOnly (FR-031): EnvTypedTable'ın altı yazma üyesini KALDIRAN yapısal\n // bayrak. `searchable` ile aynı desen ve aynı OMIT disiplini — bayrak yokken\n // satır hiç üretilmez ki mevcut şemaların d.ts'i bayt-aynı kalsın.\n ...(table.appendOnly === true ? [`${indent} appendOnly: true;`] : []),\n `${indent}};`,\n ].join(\"\\n\");\n}\n\n/**\n * Generate the full `palbase-env.d.ts` text for the project's schemas.\n *\n * The emitted file ends in `export {};` — same as `makeStackDts`. Without it the\n * `.d.ts` is a global script, and `declare module \"…\"` there DECLARES an ambient\n * module (shadowing the real one, so every export of `@palbase/backend/env`\n * silently becomes invalid) instead of AUGMENTING it. Measured on a minimal tsc\n * repro: with the line, exit 0; without it, `TS2305: Module '\"…\"' has no\n * exported member`. The line was dropped once in a rewrite and nothing caught\n * it, so `env-gen.test.ts` now gates it directly.\n *\n * @example\n * import { makeEnvDts } from \"@palbase/backend\";\n * import publicSchema from \"./db/public.js\";\n * import billing from \"./db/billing.js\";\n * writeFileSync(\"palbase-env.d.ts\", makeEnvDts([publicSchema, billing]));\n */\n/**\n * A free-form `.transform<T>()` CANNOT be typed here, and must not be typed\n * WRONG (FR-004).\n *\n * The target type is a TYPE PARAMETER — erased at runtime. This generator reads\n * the bundled runtime object, so it only ever saw `{ fromDb, toDb }` and fell\n * through to the storage type: it emitted `string` for a column the engine hands\n * back as a number. A consumer project measured exactly this and wrote a\n * hand-rolled codec module plus 141 call sites rather than trust the types.\n *\n * Refusing is the fix, not a limitation: the remedy is named in the message and\n * produces BOTH the conversion and the type from one declaration.\n */\nfunction refuseFreeFormTransforms(schemas: readonly SchemaDef[]): void {\n for (const schema of schemas) {\n for (const table of Object.values(schema.tables)) {\n for (const [col, builder] of Object.entries(table.columns)) {\n const def = builder._def;\n if (def.transform === undefined || def.codec !== undefined) continue;\n const where = qualifiedTableKey(schema.name, table.name);\n // `DeclarationRefused`, NOT a bare Error. `refusals.ts` carries the\n // measured reason: a bare Error from this layer is treated as FATAL by\n // the runtime, the supervisor takes the pod down and palsvc with it —\n // and palsvc is THE PROCESS THAT ACCEPTS THE PUSH this message asks\n // for. The cure must not kill the thing that delivers it.\n throw new DeclarationRefused(\n `table \"${where}\" column \"${col}\" declares .transform<T>(): its target type does not exist at ` +\n `runtime, so the generated types would say something the engine contradicts. Declare a named ` +\n `codec instead — .asNumber() for a JS number, .asDecimal() for the exact string.`,\n );\n }\n }\n }\n}\n\n/**\n * Fixed marker comments that wrap each `declare module` block in the single\n * generated file (FR-002, C-1/C-8). They are the ONLY thing the CLI's\n * `preserveStackBlock` (T010, `sdk/cli/internal/backend/build.go`) reads: that\n * function does not parse this file as TypeScript, it slices bytes between\n * these exact lines. This literal text is a cross-repo contract — T010 hardcodes\n * the same four strings and a Go test (`TestPreserveStackBlockMarkersAreTheRenderers`)\n * greps this file for them; changing it here without changing it there breaks\n * that gate silently.\n */\nexport const ENV_BLOCK_START = \"// palbase:env:begin\";\nexport const ENV_BLOCK_END = \"// palbase:env:end\";\nexport const STACK_BLOCK_START = \"// palbase:stack:begin\";\nexport const STACK_BLOCK_END = \"// palbase:stack:end\";\n\n/** What a checkout with no linked stack (and no machine-local cache) renders:\n * four empty interfaces, same as a stack that reports no names at all\n * (FR-003a's \"never generated\" and \"generated empty\" cases render identically\n * on purpose — both correctly refuse every name). */\nconst EMPTY_STACK_NAMES: StackNames = { secrets: [], flags: [], buckets: [], roles: [] };\n\nexport function makeEnvDts(schemas: readonly SchemaDef[], names?: StackNames): string {\n refuseFreeFormTransforms(schemas);\n // No pruning: `relations` is a flat literal map, so it cannot expand into an\n // infinite type the way the old recursive `children` could. Dropping a back-edge\n // here would delete a REAL relation and make the type lie about the schema.\n const relations = buildRelations(schemas);\n\n const publicSchema = schemas.find((s) => s.name === \"public\");\n const others = schemas.filter((s) => s.name !== \"public\");\n\n const publicBlocks = Object.keys(publicSchema?.tables ?? {}).map((name) =>\n tableBlock(publicSchema!.tables[name]!, relations.get(name) ?? [], \" \"),\n );\n const body = publicBlocks.length > 0 ? `\\n${publicBlocks.join(\"\\n\")}\\n ` : \"\";\n\n const schemaBlocks = others.map((schema) => {\n const inner = Object.keys(schema.tables).map((name) =>\n tableBlock(schema.tables[name]!, relations.get(qualifiedTableKey(schema.name, name)) ?? [], \" \"),\n );\n return ` ${schema.name}: {\\n${inner.join(\"\\n\")}\\n };`;\n });\n const schemasBody = schemaBlocks.length > 0 ? `\\n${schemaBlocks.join(\"\\n\")}\\n ` : \"\";\n\n return `// AUTO-GENERATED by @palbase/backend — DO NOT EDIT.\n// Regenerated from db/*.ts by \\`palbase build\\` and by every deploy.\n// Augments the @palbase/backend/env \\`Tables\\` interface so \\`Database.public.*\\`\n// is typed with no import and no generic. Schemas other than \\`public\\` land\n// under \\`Schemas\\`, reached with \\`Database.schema(\"<name>\").tables.*\\`.\n\n/**\n * Kolonun POSTGRES tipini tipte tasiyan marka.\n *\n * __pg ISTEGE BAGLI oldugu icin satir hala duz string/number gibi okunur ve duz\n * bir degerle yazilir — marka yalniz col() ve now() karsilastirma kurallarinin\n * gordugu bir bilgidir. TypeScript numeric, bigint, text, uuid ve timestamp'i\n * tek string'e dusurdugu icin bu bilgi olmadan integer<->numeric (gecerli) ile\n * integer<->text (gecersiz) ayirt edilemiyordu.\n */\ntype Pg<T, N extends string> = T & { readonly __pg?: N };\n\n/**\n * Bir jsonb kolonunun tasiyabilecegi deger.\n *\n * undefined DAHIL, cunku JSON.stringify undefined alanlari duserur ve\n * { a: undefined } yazan kod her yerde var — reddetmek dogru olmazdi.\n */\ntype Json = string | number | boolean | null | undefined | Json[] | { [k: string]: Json };\n\n${ENV_BLOCK_START}\ndeclare module \"@palbase/backend/env\" {\n interface Tables {${body}}\n interface Schemas {${schemasBody}}\n}\n${ENV_BLOCK_END}\n\n${STACK_BLOCK_START}\ndeclare module \"@palbase/backend/stack\" {\n${stackInterfaceBody(names ?? EMPTY_STACK_NAMES)}\n}\n${STACK_BLOCK_END}\n\nexport {};\n`;\n}\n","// The decorator registry — the single plain-data store the method + parameter\n// decorators write into, and the deploy/dispatch pipeline reads back. No\n// `reflect-metadata`, no `emitDecoratorMetadata`: the registry is built from the\n// decorator arguments + the parameter INDEX that esbuild/tsc preserve for legacy\n// parameter decorators (verified — see the design spec §0/§4.1).\n//\n// A controller class carries its route metadata on a symbol-keyed static\n// property (`ROUTES`). `@Get`/`@Post`/… append a {@link RouteMeta} entry;\n// `@Body`/`@User`/… append a {@link ParamMeta} entry onto the route for the\n// method they decorate. Because parameter decorators run BEFORE the method\n// decorator for the same member (TS evaluates innermost-first, params before the\n// method), the route entry may not exist yet when a param decorator fires — so\n// param metadata is buffered per method name and merged when the method\n// decorator creates the route entry.\nimport type { AuthSpec, RateLimitConfig } from \"../endpoint.js\";\nimport type { UploadConfig } from \"./upload.js\";\nimport type { SseConfig } from \"./sse.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** The HTTP verbs a route may declare, upper-cased (the runtime router +\n * OpenAPI lower-case on their own). */\nexport type HttpMethodUpper = \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\" | \"QUERY\";\n\n/** Route-level options accepted by the method decorators (`@Get`/`@Post`/…). */\nexport interface RouteOptions {\n /** Enforced before statements and COMMIT; include retries and service queries. */\n databaseBudget?: import(\"../db/diagnostics.js\").DatabaseBudget;\n /** OVERRIDES the controller-level default auth for this one route. */\n auth?: AuthSpec;\n /** Per-route rate limit. */\n rateLimit?: RateLimitConfig;\n /** Direct-storage upload config — present ONLY on `@Upload` routes (the\n * `@Get`/`@Post`/… decorators never set it). Its presence is what MARKS a\n * route as an upload route through the whole pipeline (registry → flatten →\n * openapi → codegen). The bytes go client→storage directly; the method body\n * runs as the completion handler. See {@link UploadConfig} (decorators/upload.ts). */\n uploadConfig?: UploadConfig;\n /** Streaming config — present ONLY on `@Sse` routes (the `@Get`/`@Post`/…\n * decorators never set it). Its presence is what MARKS a route as a streaming\n * route through the whole pipeline (registry → flatten → openapi → codegen),\n * exactly as `uploadConfig` does for uploads — never a special HTTP verb. An\n * `@Sse` route registers POST like any input-bearing route, so the verb cannot\n * carry the distinction. See {@link SseConfig} (decorators/sse.ts). */\n sseConfig?: SseConfig;\n}\n\n/** The kind of value a parameter decorator injects. Drives both dispatch\n * (which request slice to inject) and codegen (which OpenAPI parameter source a\n * schema-bearing kind maps to). */\nexport type ParamKind =\n | \"body\"\n | \"query\"\n | \"param\"\n | \"headers\"\n | \"user\"\n | \"optionalUser\"\n | \"client\"\n | \"requestId\"\n | \"traceId\"\n | \"req\"\n // `@UploadedObject()` — injects the uploaded object (completion input) on an\n // `@Upload` route. No schema (the shape is the fixed UploadedObject type).\n | \"uploadedObject\"\n // `@SseOut()` — injects the frame writer on an `@Sse` route. No schema (the\n // shape is the fixed SseWriter type).\n | \"sseOut\"\n // `@Signal()` — injects the request's AbortSignal, which aborts when the\n // client disconnects. No schema. NOT derivable from `@Req()`: PBRequest\n // carries only request-scoped data and has no signal (endpoint.ts:358-363).\n | \"signal\";\n\n/** One parameter decorator's recorded metadata. `index` is the parameter\n * position esbuild/tsc preserve; `schema` is present for the schema-bearing\n * kinds (`body`/`query`/`headers`); `name` is the path-param name for `param`. */\nexport interface ParamMeta {\n index: number;\n kind: ParamKind;\n /** Zod schema for `body`/`query`/`headers` (validation + codegen source). */\n schema?: ZodTypeAny;\n /** Path-param name for `@Param(\"id\")`. */\n name?: string;\n}\n\n/** One inferred throw site: the error CLASS name (e.g. \"TodoLocked\") and its\n * wire code (e.g. \"todo_locked\"). `status`, `hasData`, and the data JSON schema\n * are NOT carried here — they resolve from the error registry by `code` at\n * extract/openapi time (single source of truth). */\nexport interface ThrowDescriptor {\n name: string;\n code: string;\n}\n\n/** One route's recorded metadata: the verb + subpath + method name + options,\n * the ordered parameter metas, and the resolved return schema (injected by the\n * codegen step — see `returnSchema`). */\nexport interface RouteMeta {\n method: HttpMethodUpper;\n subpath: string;\n fnName: string;\n options: RouteOptions;\n params: ParamMeta[];\n /** Response schema for the route, if any. Derived from the method's RETURN\n * TYPE by codegen and written here via `recordReturn` (a generated top-level\n * IIFE injected per controller), not by an author-written decorator. */\n returnSchema?: ZodTypeAny;\n /** Error classes this route can throw, if inferred. Derived from the method\n * body + service call graph by the deploy stager's throw analysis and written\n * here via `recordThrows` (a generated top-level IIFE injected per controller,\n * the `recordReturn` twin), not by an author-written decorator. */\n throws?: ThrowDescriptor[];\n}\n\n/** Symbol the route metadata list is stored under on a controller class. Using\n * a symbol (not a string key) keeps it off the public structural surface and\n * avoids any chance of an authored property collision. */\nexport const ROUTES: unique symbol = Symbol.for(\"palbase.backend.routes\");\n\n/** Symbol the per-method buffered parameter metas are stored under while a class\n * is being decorated. Parameter decorators fire before the method decorator, so\n * they buffer here keyed by method name; the method decorator drains the buffer\n * into the route entry it creates. */\nconst PARAM_BUFFER: unique symbol = Symbol.for(\"palbase.backend.paramBuffer\");\n\n/** A room's own slots. Rooms are NOT routes — no verb, no path, no params — so\n * they get their own carrier slots instead of being squeezed into RouteMeta. */\nconst ROOM: unique symbol = Symbol.for(\"palbase.backend.room\");\nconst ROOM_HOOKS: unique symbol = Symbol.for(\"palbase.backend.roomHooks\");\n\n/** Symbol the per-method buffered return-type schemas are stored under while a\n * class's registry is being populated. The codegen-injected `recordReturn` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordReturn`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its return schema — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst RETURN_BUFFER: unique symbol = Symbol.for(\"palbase.backend.returnBuffer\");\n\n/** Symbol the per-method buffered throw descriptors are stored under while a\n * class's registry is being populated. The stager-injected `recordThrows` call\n * can fire before OR after the method decorator; it buffers here keyed by method\n * name and `recordRoute` drains it into the route entry (and `recordThrows`\n * writes through if the route already exists). Buffering on BOTH sides means a\n * fully-formed route entry always carries its throw descriptors — a raw-symbol\n * reader (the runtime) never has to re-merge. */\nconst THROWS_BUFFER: unique symbol = Symbol.for(\"palbase.backend.throwsBuffer\");\n\n/** A class constructor carrying the symbol-keyed registry slots. We type the\n * registry-bearing class as this so the decorators can read/write the slots\n * without `any` — a plain `Function` does not carry index signatures. */\ninterface RegistryCarrier {\n [ROUTES]?: RouteMeta[];\n [PARAM_BUFFER]?: Record<string, ParamMeta[]>;\n [ROOM]?: RoomMeta;\n [ROOM_HOOKS]?: RoomBuffer;\n [RETURN_BUFFER]?: Record<string, ZodTypeAny>;\n [THROWS_BUFFER]?: Record<string, ThrowDescriptor[]>;\n}\n\n/** Coerce a decorated target (class constructor or its prototype) into the\n * registry carrier that owns the slots. Method/param decorators receive the\n * PROTOTYPE as their target; the class decorator receives the constructor. We\n * always anchor the registry on the CONSTRUCTOR so `getRoutes(ctor)` finds it. */\nfunction carrierOf(target: object): RegistryCarrier {\n // For instance-member decorators, `target` is the prototype; its `.constructor`\n // is the class. For a static member or the class decorator, `target` is the\n // constructor already. Resolve to the constructor either way.\n const ctor =\n typeof target === \"function\"\n ? (target as unknown as RegistryCarrier)\n : (((target as { constructor?: unknown }).constructor ??\n target) as unknown as RegistryCarrier);\n return ctor;\n}\n\n/** Get (creating if absent) the own route list for a class constructor. Own —\n * not inherited — so a subclass does not mutate its base's routes. */\nfunction ownRoutes(carrier: RegistryCarrier): RouteMeta[] {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROUTES)) {\n carrier[ROUTES] = [];\n }\n return carrier[ROUTES] as RouteMeta[];\n}\n\n/** Get (creating if absent) the own per-method param buffer for a class. */\nfunction ownParamBuffer(carrier: RegistryCarrier): Record<string, ParamMeta[]> {\n if (!Object.prototype.hasOwnProperty.call(carrier, PARAM_BUFFER)) {\n carrier[PARAM_BUFFER] = {};\n }\n return carrier[PARAM_BUFFER] as Record<string, ParamMeta[]>;\n}\n\n/** Record a route (called by the method decorators). Drains any parameter\n * metas already buffered for `fnName` into the new route entry, then sorts them\n * by parameter index so dispatch can inject positionally. */\nexport function recordRoute(\n target: object,\n fnName: string,\n method: HttpMethodUpper,\n subpath: string,\n options: RouteOptions,\n): void {\n const carrier = carrierOf(target);\n const routes = ownRoutes(carrier);\n const buffer = ownParamBuffer(carrier);\n const params = (buffer[fnName] ?? []).slice().sort((a, b) => a.index - b.index);\n const route: RouteMeta = { method, subpath, fnName, options, params };\n // Drain a buffered return schema (the recordReturn-ran-first ordering) so the\n // route entry is complete the moment it's created — a raw-symbol consumer\n // (the runtime extractor/worker) sees the return schema without re-merging.\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer && returnBuffer[fnName] !== undefined) {\n route.returnSchema = returnBuffer[fnName];\n }\n // Same drain for buffered throw descriptors (the recordThrows-ran-first\n // ordering) — the route entry is complete the moment it's created.\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer && throwsBuffer[fnName] !== undefined) {\n route.throws = throwsBuffer[fnName];\n }\n routes.push(route);\n}\n\n/** Record one parameter decorator (called by `@Body`/`@User`/…). Buffers per\n * method name; the method decorator merges the buffer into the route entry. If\n * the route already exists (method decorator ran first — TS does evaluate the\n * method decorator AFTER its parameter decorators, but we stay order-robust),\n * the meta is also appended directly so neither ordering loses it. */\nexport function recordParam(target: object, fnName: string, meta: ParamMeta): void {\n const carrier = carrierOf(target);\n const buffer = ownParamBuffer(carrier);\n (buffer[fnName] ??= []).push(meta);\n\n // Order-robust: if the route already exists, merge in place + keep sorted.\n const routes = carrier[ROUTES];\n if (routes) {\n const route = routes.find((r) => r.fnName === fnName);\n if (route) {\n route.params.push(meta);\n route.params.sort((a, b) => a.index - b.index);\n }\n }\n}\n\n/** Attach a return schema to the route for `fnName` (called by the codegen\n * injection that reads the method's return type). If the route does not exist\n * yet, the schema is buffered (RETURN_BUFFER) and drained into the route by\n * `recordRoute` when the method decorator runs. */\nexport function recordReturn(target: object, fnName: string, schema: ZodTypeAny): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.returnSchema = schema;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, RETURN_BUFFER)) {\n carrier[RETURN_BUFFER] = {};\n }\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) returnBuffer[fnName] = schema;\n}\n\n/** Attach the inferred throw descriptors to the route for `fnName` (called by\n * the stager-injected IIFE that carries the throw analysis result — the\n * `recordReturn` twin). If the route does not exist yet, the descriptors are\n * buffered (THROWS_BUFFER) and drained into the route by `recordRoute` when the\n * method decorator runs. */\nexport function recordThrows(target: object, fnName: string, throws: ThrowDescriptor[]): void {\n const carrier = carrierOf(target);\n const routes = carrier[ROUTES];\n const route = routes?.find((r) => r.fnName === fnName);\n if (route) {\n route.throws = throws;\n return;\n }\n if (!Object.prototype.hasOwnProperty.call(carrier, THROWS_BUFFER)) {\n carrier[THROWS_BUFFER] = {};\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) throwsBuffer[fnName] = throws;\n}\n\n/** Read the route metadata for a controller class (the deploy/dispatch entry\n * point). Applies any buffered return schemas + throw descriptors (for the\n * recordReturn/recordThrows-runs-before orderings) and returns a defensive copy\n * so callers cannot mutate the registry.\n */\nexport function getRoutes(ctor: object): RouteMeta[] {\n const carrier = carrierOf(ctor);\n const routes = carrier[ROUTES] ?? [];\n const returnBuffer = carrier[RETURN_BUFFER];\n if (returnBuffer) {\n for (const route of routes) {\n const buffered = returnBuffer[route.fnName];\n if (buffered && route.returnSchema === undefined) {\n route.returnSchema = buffered;\n }\n }\n }\n const throwsBuffer = carrier[THROWS_BUFFER];\n if (throwsBuffer) {\n for (const route of routes) {\n const buffered = throwsBuffer[route.fnName];\n if (buffered && route.throws === undefined) {\n route.throws = buffered;\n }\n }\n }\n return routes.map((r) => ({\n ...r,\n params: r.params.slice(),\n ...(r.throws !== undefined ? { throws: r.throws.slice() } : {}),\n }));\n}\n\n// ── rooms ───────────────────────────────────────────────────────────────────\n\n/** Which lifecycle hook a method is bound to. */\nexport type RoomHook = \"authorize\" | \"first\" | \"join\" | \"leave\" | \"empty\";\n\nexport interface RoomMessageMeta {\n fnName: string;\n schema: ZodTypeAny;\n}\n\nexport interface RoomMeta {\n pattern: string;\n events: Record<string, ZodTypeAny>;\n graceMs: number;\n /** hook → the method name that implements it. */\n hooks: Partial<Record<RoomHook, string>>;\n /** inbound message name → its method and payload schema. */\n messages: Record<string, RoomMessageMeta>;\n}\n\ninterface RoomBuffer {\n hooks: Partial<Record<RoomHook, string>>;\n messages: Record<string, RoomMessageMeta>;\n}\n\n/** Get (creating if absent) the own hook buffer. Own — not inherited — so a\n * subclass never mutates its base's hooks. Member decorators fill this BEFORE\n * the class decorator runs; controller.ts:203 depends on the same ordering. */\nfunction ownRoomBuffer(carrier: RegistryCarrier): RoomBuffer {\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM_HOOKS)) {\n carrier[ROOM_HOOKS] = { hooks: {}, messages: {} };\n }\n return carrier[ROOM_HOOKS] as RoomBuffer;\n}\n\n/** Record a lifecycle hook. A second method for the same hook is refused: two\n * answers to \"who handles this\" cannot be resolved at dispatch, and silently\n * keeping one is how a hook stops running without anyone being told. */\nexport function recordRoomHook(target: object, hook: RoomHook, fnName: string): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.hooks[hook];\n if (existing !== undefined && existing !== fnName) {\n const label = `On${hook.charAt(0).toUpperCase()}${hook.slice(1)}`;\n throw new Error(\n `@${label} is declared twice in one room (${existing} and ${fnName}). ` +\n `A room has one of each hook.`,\n );\n }\n buffer.hooks[hook] = fnName;\n}\n\n/** Record an inbound message handler. */\nexport function recordRoomMessage(\n target: object,\n name: string,\n fnName: string,\n schema: ZodTypeAny,\n): void {\n const buffer = ownRoomBuffer(carrierOf(target));\n const existing = buffer.messages[name];\n if (existing !== undefined && existing.fnName !== fnName) {\n throw new Error(\n `@OnMessage(\"${name}\") is declared twice in one room (${existing.fnName} and ${fnName}).`,\n );\n }\n buffer.messages[name] = { fnName, schema };\n}\n\n/** Record the room itself (called by the class decorator), draining the buffer\n * the member decorators already filled. */\nexport function recordRoom(\n ctor: object,\n meta: Omit<RoomMeta, \"hooks\" | \"messages\">,\n): void {\n const carrier = carrierOf(ctor);\n const buffer = ownRoomBuffer(carrier);\n carrier[ROOM] = { ...meta, hooks: buffer.hooks, messages: buffer.messages };\n // AND into the shared class registry, the same slot @Controller pushes to.\n //\n // Without this line a room compiles, bundles and deploys, and is never called:\n // the bundler's entry exports `SDK.getRegisteredControllers()` and the runtime\n // reads its rooms out of THAT list (server.ts's `collectRooms`). A room that\n // only marks its own constructor is a room nobody can find — measured, on the\n // fixture, at the last gate before it would have worked.\n //\n // Rooms and controllers share one list because they are one thing to the\n // loader: classes a bundle declared. What each IS is decided by the marker it\n // carries, never by which list it arrived in.\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const REGISTRY = Symbol.for(\"palbase.backend.allControllers\");\n const all = (g[REGISTRY] ??= []);\n if (!all.includes(ctor)) all.push(ctor);\n}\n\n/** The room a class declares, or undefined. A class with no `@Room` is not a\n * room — the marker is the CONFIG's presence, never a name or a base class\n * (the rule upload.ts:13-16 states for uploads). */\nexport function getRoom(ctor: object): RoomMeta | undefined {\n const carrier = carrierOf(ctor);\n if (!Object.prototype.hasOwnProperty.call(carrier, ROOM)) return undefined;\n return carrier[ROOM] as RoomMeta;\n}\n","// `@Controller(basePath, options?)` — the class decorator that marks a class as\n// a Palbase backend controller. It stamps a non-enumerable `__palbase`\n// discriminant + the resolved controller metadata onto the class so the\n// deploy/dispatch pipeline (and `isController`/`resolveController`) can detect\n// and read it without `reflect-metadata`.\nimport type { AuthSpec } from \"../endpoint.js\";\nimport { getRoutes } from \"./registry.js\";\n\n/** The controller metadata stamped onto a `@Controller`-decorated class. The\n * default export of a `controllers/*.controller.ts` file resolves to this via\n * {@link resolveController}. */\nexport interface ControllerMeta {\n /** Discriminant the runtime + tooling read. */\n readonly __palbase: \"controller\";\n /** The base path every route in this controller mounts under (e.g. \"/todos\"). */\n basePath: string;\n /** Controller-level default auth, applied to routes that don't set their own\n * (`@Get(\"/x\", { auth })` overrides this). `undefined` ⇒ the application\n * default ({@link defineDefaultAuth}), and secure-by-default below that —\n * see {@link resolveEffectiveAuth} for the whole cascade. */\n defaultAuth?: AuthSpec;\n}\n\n/** Options accepted by `@Controller`. */\nexport interface ControllerOptions {\n /** Default auth for ALL routes in this controller (route-level overrides;\n * omitting it falls through to the application default declared with\n * {@link defineDefaultAuth}). */\n auth?: AuthSpec;\n}\n\n/** Symbol the controller metadata is stamped under. Symbol-keyed (not a string\n * property) so it never collides with an authored member and stays off the\n * structural surface. */\nexport const CONTROLLER_META: unique symbol = Symbol.for(\"palbase.backend.controllerMeta\");\n\n/**\n * Every class `@Controller` has decorated, in decoration order.\n *\n * This is what lets a controller file need no export at all: importing the file\n * runs the decorator, the decorator records the class here, and the runtime\n * reads the list. Without it the only handle on a class is its export name, so\n * every controller had to be exported AND named in a generated entry — the\n * ceremony NestJS still charges (`export class` PLUS\n * `@Module({controllers:[…]})`).\n *\n * Keyed on a well-known Symbol against globalThis rather than held in a module\n * variable, because a deployed bundle inlines its own copy of this package: two\n * copies would keep two lists, and the runtime would read the empty one. The\n * same hazard `runtimeHooks` exists for, closed the same way — one shared slot.\n */\nconst REGISTRY: unique symbol = Symbol.for(\"palbase.backend.allControllers\") as never;\n\nfunction registry(): unknown[] {\n const g = globalThis as unknown as Record<symbol, unknown[] | undefined>;\n const existing = g[REGISTRY];\n if (existing) return existing;\n const fresh: unknown[] = [];\n g[REGISTRY] = fresh;\n return fresh;\n}\n\n/**\n * The controller classes this process has loaded, in decoration order.\n *\n * Decoration order is import order, which the bundler fixes by sorting the\n * files it emits imports for — so two builds of one tree produce the same\n * route table, and route precedence is not a function of module-resolution\n * accidents.\n */\nexport function getRegisteredControllers(): readonly unknown[] {\n return registry().slice();\n}\n\n/** Empty the registry. For tests, which load controllers repeatedly. */\nexport function __resetRegisteredControllers(): void {\n registry().length = 0;\n}\n\n/**\n * The APPLICATION-level default auth.\n *\n * Held on globalThis under a well-known Symbol for exactly the reason\n * {@link REGISTRY} is: a deployed bundle inlines its own copy of this package,\n * and two copies keeping two defaults is how a security setting silently\n * becomes two different settings.\n */\nconst APP_DEFAULT_AUTH: unique symbol = Symbol.for(\"palbase.backend.appDefaultAuth\") as never;\n\nfunction appAuthSlot(): Record<symbol, AuthSpec | undefined> {\n return globalThis as unknown as Record<symbol, AuthSpec | undefined>;\n}\n\n/**\n * Declare the default auth for EVERY route in the application — the ring the\n * cascade consults when neither the route nor its controller says anything.\n *\n * The measured problem it removes: `auth: { verifiedEmail: true }` repeated by\n * hand on ten `@Controller`s. A security setting that must be repeated is a\n * security setting that will be forgotten — the eleventh controller opens the\n * door and nothing says so.\n *\n * Call it at MODULE SCOPE in a file the application imports (the controllers'\n * own barrel, or a module a controller imports). The cascade reads this slot\n * when the route table is built and when the spec is emitted — both of which\n * run after module loading — so declaration order does not matter, but being\n * imported at all does.\n *\n * @example\n * defineDefaultAuth({ verifiedEmail: true }); // every route, unless it says otherwise\n */\nexport function defineDefaultAuth(auth: AuthSpec): void {\n appAuthSlot()[APP_DEFAULT_AUTH] = auth;\n}\n\n/** The declared application default, or `undefined` when none was declared. */\nexport function getDefaultAuth(): AuthSpec | undefined {\n return appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/** Clear the application default. For tests, which declare it repeatedly. */\nexport function __resetDefaultAuth(): void {\n delete appAuthSlot()[APP_DEFAULT_AUTH];\n}\n\n/**\n * THE auth cascade: route → controller → application → `true`.\n *\n * One function, every caller — the route table (`engine/router.ts`) and the\n * spec emitter (`openapi/controllers.ts`) ASK for the answer instead of\n * spelling the chain themselves. Two hand-written copies of a cascade is how\n * the build-time answer and the runtime answer come to disagree about who may\n * call an endpoint, and the disagreement shows up as an open door.\n *\n * The terminal `true` is secure-by-default and is load-bearing: a route that\n * declared nothing, under a controller that declared nothing, in an\n * application that declared nothing, is CLOSED.\n */\nexport function resolveEffectiveAuth(\n routeAuth: AuthSpec | undefined,\n controllerAuth: AuthSpec | undefined,\n): AuthSpec {\n return routeAuth ?? controllerAuth ?? getDefaultAuth() ?? true;\n}\n\n/** A class carrying the stamped controller metadata + discriminant. */\ninterface ControllerCarrier {\n __palbase?: \"controller\";\n [CONTROLLER_META]?: ControllerMeta;\n}\n\n/** The one path segment the platform owns. The isolate matches\n * `^/webhooks/([^/]+)$` on the raw request path BEFORE controller dispatch, so\n * anything a controller resolves to under it answers `404 webhook_not_found`\n * and never runs. */\nconst RESERVED_FIRST_SEGMENT = \"webhooks\";\n\n/**\n * Throw if `path` resolves under the reserved segment. Segments are compared the\n * way the isolate compares them — `split(\"/\").filter(Boolean)` — NOT by string\n * prefix, because empty segments collapse there: `@Controller(\"/\")` +\n * `@Post(\"/webhooks/x\")` composes to `//webhooks/x`, which the isolate serves as\n * `/webhooks/x`. A prefix check reads that as safe; the segment check does not.\n * `/webhooksy` stays allowed for the same reason — it is a different segment.\n *\n * Every verb is refused, not just the POST the isolate currently intercepts: the\n * reservation is of the URL namespace, so a `@Get(\"/webhooks/x\")` that happens\n * to work today would be silently shadowed the moment the isolate's method gate\n * widens. Refusing at build is recoverable; discovering it as a 404 is not.\n */\nfunction assertNotReserved(path: string, subject: string): void {\n const [first] = path.split(\"/\").filter(Boolean);\n if (first === RESERVED_FIRST_SEGMENT) {\n throw new Error(\n `${subject} resolves under the reserved /${RESERVED_FIRST_SEGMENT} path — ` +\n \"inbound webhooks are served there and would shadow this route\",\n );\n }\n}\n\n/**\n * Mark a class as a Palbase backend controller. `basePath` is the mount path\n * for every route the class declares; `options.auth` sets the controller-level\n * default auth (a route's own `auth` overrides it; absent ⇒ secure-by-default).\n *\n * @example\n * \\@Controller(\"/todos\", { auth: false })\n * export class TodosController {\n * \\@Get(\"\") list(\\@QueryParams(ListTodosQuery) q: ListTodosQuery): TodoSchema[] { … }\n * }\n */\nexport function Controller(basePath: string, options: ControllerOptions = {}) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n // /webhooks/* belongs to the platform: the isolate matches the inbound\n // webhook route before controller dispatch, so a controller mounted here\n // would never receive a request. Silent shadowing is the failure mode this\n // whole change exists to remove, so refuse it at build.\n //\n // The COMPOSED path is what gets shadowed, not the base path. `@Controller(\"\")`\n // and `@Controller(\"/\")` both pass a base-path-only check while a\n // `@Post(\"/webhooks/stripe\")` inside them resolves to exactly the path the\n // isolate intercepts. Method decorators run BEFORE the class decorator (TS\n // evaluates members first), so every route this class declares is already in\n // the registry here — which is why the composed check can live at this one\n // seam instead of on the dispatch read path. The `@Controller(\"\") +\n // @Post(\"/webhooks/stripe\")` test is the lock on that ordering: if it ever\n // stopped holding, that test goes red.\n assertNotReserved(basePath, `@Controller(\"${basePath}\")`);\n for (const route of getRoutes(ctor)) {\n assertNotReserved(\n `${basePath}${route.subpath}`,\n `@${route.method}(\"${route.subpath}\") in @Controller(\"${basePath}\")`,\n );\n }\n\n const carrier = ctor as unknown as ControllerCarrier;\n const meta: ControllerMeta = {\n __palbase: \"controller\",\n basePath,\n ...(options.auth !== undefined ? { defaultAuth: options.auth } : {}),\n };\n // Non-enumerable so it doesn't leak onto instances / structural checks.\n Object.defineProperty(carrier, CONTROLLER_META, {\n value: meta,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // The bare `__palbase` discriminant is the cheap detection marker the\n // runtime/extractor checks; keep it readable but non-enumerable.\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"controller\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n // Record it, so importing the file is enough and exporting is optional.\n // Guarded against a double-decoration re-entering the same class twice.\n const all = registry();\n if (!all.includes(ctor)) all.push(ctor);\n return ctor;\n };\n}\n\n/** True when `value` is a `@Controller`-decorated class (cheap discriminant\n * check). Accepts the class constructor (the default export of a controller\n * file). */\nexport function isController(value: unknown): boolean {\n if (typeof value !== \"function\" && (typeof value !== \"object\" || value === null)) {\n return false;\n }\n const carrier = value as ControllerCarrier;\n return carrier.__palbase === \"controller\" && carrier[CONTROLLER_META] !== undefined;\n}\n\n/** Read the resolved controller metadata off a `@Controller`-decorated class.\n * Throws if the class was not decorated — callers should gate with\n * {@link isController} first (the loader does). */\nexport function resolveController(ctor: unknown): ControllerMeta {\n if (typeof ctor !== \"function\" && (typeof ctor !== \"object\" || ctor === null)) {\n throw new TypeError(\"resolveController: value is not a class\");\n }\n const meta = (ctor as ControllerCarrier)[CONTROLLER_META];\n if (!meta) {\n throw new TypeError(\n \"resolveController: class is not a @Controller — decorate it with `@Controller(path)` and list it in a module's `controllers`\",\n );\n }\n return meta;\n}\n\n/**\n * A class the runtime constructs takes NO constructor parameters.\n *\n * ONE writer, four callers (controller, hook, job, webhook) and the build's own\n * check. Four hand-written copies of this message is how the four come to\n * disagree about what is refused — and the disagreement is silent, because a\n * class that slips past one of them still ends up with `undefined` fields.\n *\n * Why it is refused rather than injected: there is no container. The parameter\n * would arrive `undefined`, the code would compile, deploy, and fail at the\n * first request that touches the field — the most expensive place to learn it.\n */\nexport function assertZeroArgConstructor(Ctrl: unknown, kind: string): void {\n const arity = (Ctrl as { length?: number }).length ?? 0;\n if (arity === 0) return;\n\n // This function's NAME is a promise: whatever reaches it will be constructed\n // with a zero-argument constructor. Letting a class with parameters through\n // would make the name a lie — worse than the rename FR-029 guards against.\n //\n // An earlier design made it \"declaration-aware\": pass when metadata matches\n // arity. Measured, that re-opens the exact silence this exists to close.\n // ANY decorator triggers metadata emission, not just `@Injectable`:\n //\n // @Job(...) class J { constructor(repo: unknown) {} }\n // → design:paramtypes = [Object] ← matches arity\n //\n // so J would pass, then be built with `new J()`, and `repo` would be\n // `undefined` at the first scheduled run. Four tests in this repo asserted\n // that refusal and all four went red; the tests were right.\n //\n // What changed instead is the MESSAGE, and who calls this. Callers holding a\n // container resolve from it and never come here (router.ts, job/hook/webhook);\n // this stays the guard for the container-less path, and keeps its promise.\n const name = (Ctrl as { name?: string }).name ?? \"<anonymous>\";\n throw new Error(\n `${kind} ${name} declares a constructor with ${arity} parameter(s), and this path ` +\n `builds it with a zero-argument constructor — every parameter would arrive as ` +\n `undefined. If you meant to inject them, add @Injectable() to ${name} and list it ` +\n `in a module's providers, so the container builds it instead.`,\n );\n}\n","// Method decorators: `@Get` / `@Post` / `@Put` / `@Patch` / `@Delete` /\n// `@Query` declare a route (verb + subpath + options) on a controller method. These are LEGACY\n// method decorators (`experimentalDecorators`), receiving\n// `(prototype, methodName, descriptor)`. They write into the per-class registry\n// (registry.ts). The success-response schema is NOT declared here: it is derived\n// from the method's RETURN TYPE by a codegen step and injected onto the route at\n// runtime via `recordReturn` (registry.ts).\nimport {\n recordRoute,\n type HttpMethodUpper,\n type RouteOptions,\n} from \"./registry.js\";\n\n/** A legacy method decorator.\n *\n * The third argument is typed `unknown`, not `PropertyDescriptor`, on purpose:\n * when the decorator is applied to a PARAMETER (`m(@Query(\"q\") q: string)`),\n * TypeScript calls it with the parameter INDEX there. The type would let the\n * runtime pretend that cannot happen; the runtime measures it instead. */\n// `descriptor` is OPTIONAL but stays a PropertyDescriptor: optional so a\n// property-position call (descriptor undefined) type-checks, narrow so a\n// parameter-position call (`m(@Query(\"q\") q)`, third argument a number) is\n// still TS1239 at compile time. `unknown` here would trade that compile-time\n// refusal for the runtime one below; keeping both is the point (W4 r2 I-3).\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol | undefined,\n descriptor?: PropertyDescriptor,\n) => void;\n\n/** Build a method decorator for one HTTP verb. The decorated method's name is\n * the route `fnName` — and it is PUBLIC API, not authoring sugar: the runtime\n * derives the operationId as `<controllerName>.<fnName>` (the dotted namespace\n * the SDKs expose as `pb.todos.list()`), so renaming this method renames every\n * client call. The flat verb+path id is only the fallback for routes with no\n * controller metadata. See openapi/discover.ts. */\nfunction makeMethodDecorator(method: HttpMethodUpper) {\n return function (subpath: string, options: RouteOptions = {}): MethodDecorator {\n // Runtime guard for stale pre-9.0.0 code: `@Query(zodSchema)` used to be\n // the query-string PARAM decorator. Applied against this SDK it would\n // silently record a garbage route (schema-as-subpath) and fail the deploy\n // with a baffling self-conflict — fail loud and name the migration instead.\n if (typeof subpath !== \"string\") {\n throw new Error(\n `@${method[0]}${method.slice(1).toLowerCase()}(subpath) expects a string subpath, got ${typeof subpath}.` +\n (method === \"QUERY\"\n ? \" If this is a zod schema on a method parameter: the query-string param decorator was renamed @QueryParams(schema) in @palbase/backend 9.0.0.\"\n : \"\"),\n );\n }\n return function (target, propertyKey, descriptor?: PropertyDescriptor) {\n const verb = `${method[0]}${method.slice(1).toLowerCase()}`;\n // POSITION guard, and it runs BEFORE `recordRoute`: `m(@Query(\"q\") q)`\n // passes the subpath guard above (the argument IS a string) and arrives\n // here as a parameter-decorator call — the third argument is the\n // parameter index, not a descriptor. Recording it would register a\n // route the author never wrote, named after the method, and the deploy\n // would fail later, elsewhere, on that route. Refuse here, by position,\n // and name the decorators that DO go on a parameter.\n if (typeof (descriptor as unknown) === \"number\") {\n throw new Error(\n `@${verb}(...) is a ROUTE decorator and was applied to parameter #${descriptor} of ${propertyKey === undefined ? \"the constructor\" : String(propertyKey)}; ` +\n \"for query-string params use @QueryParams(schema), for the body @Body(schema), for a path segment @Param(name)\",\n );\n }\n // CLASS position: `@Get(\"/x\") class C {}` arrives with no propertyKey\n // and would record a route literally named \"undefined\". AFTER the\n // parameter check: a constructor parameter (`constructor(@Get(\"/x\") x)`)\n // arrives as (C, undefined, 0) and deserves the parameter message.\n if (propertyKey === undefined) {\n throw new Error(`@${verb}(...) goes on a METHOD, not on a class; put it on the handler method inside @Controller`);\n }\n recordRoute(target, String(propertyKey), method, subpath, options);\n };\n };\n}\n\n/** `@Get(subpath, options?)` — declare a GET route. */\nexport const Get = makeMethodDecorator(\"GET\");\n/** `@Post(subpath, options?)` — declare a POST route. */\nexport const Post = makeMethodDecorator(\"POST\");\n/** `@Put(subpath, options?)` — declare a PUT route. */\nexport const Put = makeMethodDecorator(\"PUT\");\n/** `@Patch(subpath, options?)` — declare a PATCH route. */\nexport const Patch = makeMethodDecorator(\"PATCH\");\n/** `@Delete(subpath, options?)` — declare a DELETE route. */\nexport const Delete = makeMethodDecorator(\"DELETE\");\n/** `@Query(subpath, options?)` — declare an HTTP QUERY route (RFC 10008):\n * safe + idempotent like GET, body-carrying like POST. Input rides `@Body`. */\nexport const Query = makeMethodDecorator(\"QUERY\");\n","/**\n * The one rule for a declared surface name.\n *\n * A job's name is the row the scheduler holds it under; a webhook's name is the\n * path segment its endpoint is served at. Both used to be the FILE's name, which\n * made a public identity a property of where a class happened to sit — rename\n * the file and the scheduler starts a different job, or a sender's configured\n * URL stops resolving.\n *\n * Declaring it puts the identity beside the schedule and the secret, where a\n * reader is already looking. There is no default: a default would be a SECOND\n * source for the identity, and the whole design rests on there being one.\n */\nconst SHAPE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\nexport function assertSurfaceName(name: unknown, decorator: string, kind: string): void {\n if (typeof name !== \"string\" || name.trim() === \"\") {\n throw new Error(\n `${decorator} requires a \\`name\\` — it is this ${kind}'s identity, and it is ` +\n `declared rather than taken from the file name.`,\n );\n }\n if (!SHAPE.test(name)) {\n throw new Error(\n `${decorator} name \"${name}\" is not usable: it reaches a URL and a log line, so it ` +\n `must be lowercase letters, digits and dashes, starting and ending with one of those.`,\n );\n }\n}\n","// @Webhook / @On — the inbound-webhook half of the decorator surface.\n//\n// Mirrors decorators/controller.ts exactly: symbol-keyed, non-enumerable\n// metadata on the constructor plus a `__palbase` discriminant, read back by a\n// resolver. The resolver is the ONLY translation point — it returns the shape\n// the runtime already consumes, so the isolate's dispatch and the signature\n// engine's cross-binding golden are untouched by the authoring change.\nimport type { WebhookMeta, WebhookProvider } from \"../webhook.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\n/** A signature scheme spelled out, for a service with no preset. The presets\n * (`provider`) are named configurations of this same shape. */\nexport interface SignatureSpec {\n /** Header carrying the signature. */\n header: string;\n /** Stripped before comparison (e.g. `sha256=`). Omit when absent. */\n prefix?: string;\n algo: \"hmac-sha256\" | \"hmac-sha1\";\n encoding: \"hex\" | \"base64\";\n /** What the HMAC covers. Exactly two placeholders: `{body}` and `{ts}`.\n * Everything else is literal. `{ts}` requires `timestampHeader` and brings\n * the five-minute replay window with it. */\n signs: string;\n timestampHeader?: string;\n}\n\nexport interface WebhookOptions {\n /**\n * The path segment this webhook is served at: `/webhooks/<name>`.\n *\n * DECLARED, not derived. It used to be the file's name, which put a PUBLIC\n * URL — the one a sender is configured with — in the file system rather than\n * beside the provider and the secret, where a reader looks for it.\n */\n name: string;\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n /** Env-var REFERENCE for the signing secret — the platform never holds it. */\n secret: { env: string };\n}\n\nexport type WebhookEventHandler = (event: unknown, meta: WebhookMeta) => Promise<void>;\n\nexport interface ResolvedWebhook {\n provider?: WebhookProvider;\n signature?: SignatureSpec;\n secret: { env: string };\n events: Record<string, WebhookEventHandler>;\n}\n\nexport const WEBHOOK_META: unique symbol = Symbol.for(\"palbase.backend.webhookMeta\");\nexport const WEBHOOK_EVENTS: unique symbol = Symbol.for(\"palbase.backend.webhookEvents\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\ninterface WebhookCarrier {\n __palbase?: \"webhook\";\n [WEBHOOK_META]?: WebhookOptions;\n [WEBHOOK_EVENTS]?: EventEntry[];\n}\n\nfunction carrierOf(ctor: object): WebhookCarrier {\n return ctor as WebhookCarrier;\n}\n\n/** Mark a class as an inbound webhook. The mount name is the FILE name — there\n * is deliberately no `name` option, because the file name IS the public URL. */\nexport function Webhook(options: WebhookOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = carrierOf(ctor);\n Object.defineProperty(carrier, WEBHOOK_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"webhook\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/** Bind a method to one event name. Any string is valid: presets provide\n * autocomplete, never a constraint, because we do not carry provider catalogs. */\nexport function On(event: string) {\n return function (target: object, fnName: string | symbol): void {\n // Method decorators receive the PROTOTYPE; metadata belongs on the ctor.\n const carrier = carrierOf((target as { constructor: object }).constructor);\n const existing = carrier[WEBHOOK_EVENTS];\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, WEBHOOK_EVENTS, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Read a decorated class back as the resolved config the runtime consumes.\n * Every misuse throws HERE, at build time, rather than becoming a webhook that\n * answers 200 and does nothing.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every delivery. */\n/**\n * Everything a webhook DECLARES — provider or signature template, the secret's\n * env var, and the event names — validated, without constructing the class.\n *\n * Same split as jobs and hooks: reading a declaration should not build an\n * object. `getWebhookConfig` is what needs an instance, and it needs a\n * container to get one.\n */\nexport function getWebhookManifest(ctor: object): {\n name: string;\n provider: string | undefined;\n secretEnv: string;\n events: string[];\n} {\n const { meta, entries } = validateWebhook(ctor);\n return {\n name: meta.name,\n provider: meta.provider,\n secretEnv: meta.secret.env,\n events: entries.map((e) => e.event),\n };\n}\n\n/** The declaration half: every refusal, and no construction. */\nfunction validateWebhook(ctor: object): {\n meta: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_META]>;\n entries: NonNullable<ReturnType<typeof carrierOf>[typeof WEBHOOK_EVENTS]>;\n} {\n const carrier = carrierOf(ctor);\n const meta = carrier[WEBHOOK_META];\n const entries = carrier[WEBHOOK_EVENTS] ?? [];\n\n if (!meta) {\n throw new Error(\n `@On used on a class that is not decorated with @Webhook (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Webhook\", \"webhook\");\n if (!meta.provider && !meta.signature) {\n throw new Error(\n \"@Webhook requires either a `provider` preset or an explicit `signature` — \" +\n \"an endpoint with no verification would accept forged deliveries\",\n );\n }\n // EITHER, not both. The isolate picks `provider` when both are present and\n // never looks at `signature`, so a tenant that wrote both gets deliveries\n // verified against a scheme they did not choose — silently, and with no way to\n // tell from the outside which one ran. Ambiguity about WHICH signature check\n // guards an endpoint is not something to resolve by precedence.\n if (meta.provider && meta.signature) {\n throw new Error(\n \"@Webhook declares BOTH a `provider` preset and an explicit `signature` — \" +\n \"these are alternatives; keep the one that describes the sender, because only `provider` would be used\",\n );\n }\n if (meta.signature) {\n const sig = meta.signature;\n // Mirrors Go's NewTemplateVerifier (internal/webhook/verify.go). Both sides\n // reject the same specs; this one rejects at build, which is the only place\n // a tenant can still act on it.\n if (!sig.header) {\n throw new Error(\"@Webhook signature requires `header` — the header the signature arrives in\");\n }\n if (sig.algo !== \"hmac-sha256\" && sig.algo !== \"hmac-sha1\") {\n throw new Error(`@Webhook signature has an unsupported algo \"${sig.algo}\"`);\n }\n if (sig.encoding !== \"hex\" && sig.encoding !== \"base64\") {\n throw new Error(`@Webhook signature has an unsupported encoding \"${sig.encoding}\"`);\n }\n if (!sig.signs?.includes(\"{body}\")) {\n throw new Error(\"@Webhook signature `signs` must contain {body} — signing a constant is not a signature\");\n }\n if (sig.signs.includes(\"{ts}\") && !sig.timestampHeader) {\n throw new Error(\"@Webhook signature uses {ts} but declares no `timestampHeader` to read it from\");\n }\n }\n if (!meta.secret?.env) {\n throw new Error(\"@Webhook requires `secret: { env: \\\"VAR_NAME\\\" }`\");\n }\n if (entries.length === 0) {\n throw new Error(\"@Webhook requires at least one @On handler\");\n }\n return { meta, entries };\n}\n\nexport function getWebhookConfig(ctor: object, container: Container): ResolvedWebhook {\n const { meta, entries } = validateWebhook(ctor);\n\n const instance = container.get(ctor as never) as Record<string, WebhookEventHandler>;\n // Object.create(null), not {} — event names are free-form, so `@On(\"constructor\")`\n // and `@On(\"toString\")` are legal. A plain literal inherits those keys from\n // Object.prototype, and the duplicate check below would reject the FIRST and\n // only handler for them as a redeclaration.\n const events: Record<string, WebhookEventHandler> = Object.create(null) as Record<string, WebhookEventHandler>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(events, entry.event)) {\n throw new Error(`@On(\"${entry.event}\") declared twice on the same webhook`);\n }\n events[entry.event] = (event, metaArg) =>\n (instance[entry.fnName] as WebhookEventHandler).call(instance, event, metaArg);\n }\n\n return {\n ...(meta.provider ? { provider: meta.provider } : {}),\n ...(meta.signature ? { signature: meta.signature } : {}),\n secret: meta.secret,\n events,\n };\n}\n","// @Hook — the BLOCKING half of the internal-event surface.\n//\n// Two axes decide which decorator a handler wants. Where does the event come\n// from, and can the handler stop it?\n//\n// @Webhook + @On an OUTSIDE service (Stripe, GitHub…) — cannot block\n// @Hook an event this stack raised — CAN block: `throw` cancels it\n// @On an event this stack raised — listens only, a monitor\n//\n// The blocking power lives in the NAME `@Hook`, not in the method decorator's\n// shape, which is why `@On` keeps meaning \"listener\" in both worlds and needs\n// no change. `@Upload` is the same pattern already shipped: the storage module\n// calls the tenant's method, and a method that answers 4xx discards the object\n// and hands its exact status, body and content-type back to the client.\n//\n// Mirrors decorators/webhook.ts: symbol-keyed, non-enumerable metadata on the\n// constructor, read back by one resolver. The resolver is the only translation\n// point, so the runtime consumes a shape the authoring surface never leaks.\nimport type { HookMeta } from \"../hooks.js\";\nimport { WEBHOOK_EVENTS } from \"./webhook.js\";\nimport type { Container } from \"../container.js\";\n\n/** A hook handler. Returning quietly ALLOWS; throwing DENIES (blocking hooks). */\nexport type HookFn = (event: unknown, meta: HookMeta) => Promise<unknown>;\n\nexport interface ResolvedHookClass {\n /** `@Hook` handlers, by event. A throw here cancels the operation. */\n blocking: Record<string, HookFn>;\n /** `@On` handlers, by event. A throw here reaches nobody but the log. */\n listeners: Record<string, HookFn>;\n}\n\n/** A hook's refusal, with the reason the caller will see.\n *\n * Any thrown error denies — this class exists so the REASON travels as a\n * deliberate message rather than as whatever a stray TypeError happened to say.\n * The engine is fail-closed by design (an unreachable hook denies), so a hook\n * body should stay narrow: an accidental throw refuses a real user. */\nexport class Deny extends Error {\n constructor(reason: string) {\n super(reason);\n this.name = \"Deny\";\n }\n}\n\nexport const HOOK_BLOCKING: unique symbol = Symbol.for(\"palbase.backend.hookBlocking\");\n\ninterface EventEntry {\n event: string;\n fnName: string;\n}\n\n/** `@Hook(\"before.user.create\")` — a blocking handler for one stack event. */\nexport function Hook(event: string) {\n return function (target: object, fnName: string | symbol): void {\n const carrier = (target as { constructor: object }).constructor as Record<symbol, unknown>;\n const existing = carrier[HOOK_BLOCKING] as EventEntry[] | undefined;\n const entries: EventEntry[] = existing ? [...existing] : [];\n entries.push({ event, fnName: String(fnName) });\n Object.defineProperty(carrier, HOOK_BLOCKING, {\n value: entries,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n };\n}\n\n/** Binds one decorator's entries onto a single instance of the class.\n *\n * ONE instance for the whole class, built here rather than per call: a hook\n * that opens a client or reads a list in its constructor would otherwise pay\n * for it on every signup. */\nfunction bind(instance: Record<string, HookFn>, entries: EventEntry[], kind: string) {\n const out: Record<string, HookFn> = Object.create(null) as Record<string, HookFn>;\n for (const entry of entries) {\n if (Object.prototype.hasOwnProperty.call(out, entry.event)) {\n throw new Error(`${kind}(\"${entry.event}\") declared twice on the same hook class`);\n }\n // Resolved ONCE, here, so a decorator naming a method that does not exist\n // fails at build time with the name in the message — rather than at the\n // first signup, as \"instance[fnName] is not a function\".\n const fn = instance[entry.fnName];\n if (typeof fn !== \"function\") {\n throw new Error(`${kind}(\"${entry.event}\") names no method \"${entry.fnName}\" on the class`);\n }\n out[entry.event] = (event, meta) => fn.call(instance, event, meta);\n }\n return out;\n}\n\n/** Resolves a hook class into the two maps the runtime dispatches from.\n *\n * Every misuse throws HERE, at build time, rather than becoming a hook that is\n * silently never called — the failure mode this whole change exists to end.\n *\n * @throws when the class declares constructor parameters (FR-011) — nothing\n * here supplies them, so the field would be `undefined` on every event. */\nexport function getHookConfig(ctor: object, container: Container): ResolvedHookClass {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n\n const instance = container.get(ctor as never) as Record<string, HookFn>;\n return {\n blocking: bind(instance, blockingEntries, \"@Hook\"),\n listeners: bind(instance, listenerEntries, \"@On\"),\n };\n}\n\n/**\n * Which events a hook class declares, and which of them BLOCK.\n *\n * Metadata only — the class is not constructed. Deploy's `hooks.manifest.json`\n * needs exactly this and has no container to build with.\n */\nexport function getHookManifest(ctor: object): { blocking: string[]; listeners: string[] } {\n const carrier = ctor as Record<symbol, unknown>;\n const blockingEntries = (carrier[HOOK_BLOCKING] ?? []) as EventEntry[];\n const listenerEntries = (carrier[WEBHOOK_EVENTS] ?? []) as EventEntry[];\n if (blockingEntries.length === 0 && listenerEntries.length === 0) {\n throw new Error(\n `${(ctor as { name?: string }).name ?? \"a hook class\"} carries no handler — ` +\n \"a hook file must declare at least one @Hook (blocking) or @On (listener) method\",\n );\n }\n return {\n blocking: blockingEntries.map((e) => e.event),\n listeners: listenerEntries.map((e) => e.event),\n };\n}\n","// `@Upload` — the single-method direct-storage upload decorator, and its\n// `@UploadedObject` parameter companion + `UploadConfig`/`UploadedObject` types.\n//\n// Unlike `@Get`/`@Post`/… (where bytes flow THROUGH the br-pod), an `@Upload`\n// route never sees the file bytes: the client uploads DIRECTLY to storage via a\n// signed URL the br-pod mints in an authorize pre-flight. The decorated method\n// body is the COMPLETION handler — it runs once, after storage confirms the\n// object landed (via an HMAC-signed completion webhook), and returns the typed\n// result the client awaits. There is exactly one method: it is BOTH the\n// authorize gate (its uploadConfig drives the guard + signed-URL pinning) AND\n// the completion handler (its body).\n//\n// On the wire the authorize pre-flight is a POST; what marks a route as an\n// upload route through the whole pipeline (registry → flatten → openapi →\n// codegen) is the PRESENCE of `uploadConfig` on the route — never a special HTTP\n// verb. The `@Get`/`@Post`/… decorators never set it.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { PalbaseBucketName } from \"../stack.js\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Direct-storage upload settings for an `@Upload` route. The br-pod validates an\n * authorize request against these (size/type), then mints a signed upload URL\n * that PINS the limits so storage itself rejects an over-limit / wrong-type PUT\n * — the client cannot exceed what it declared.\n */\nexport interface UploadConfig {\n /**\n * Target bucket NAME — one the STACK holds.\n *\n * The union comes from the generated `palbase-stack.d.ts`, so a bucket the\n * stack does not carry is a compile error. It used to say \"MUST exist in\n * `config/storage.ts` defineStorage(...)\", and that invariant was carried by\n * this sentence plus a cross-check nothing called; it is carried by the type\n * now.\n *\n * The bucket is the SINGLE SOURCE OF TRUTH for the size limit + MIME allowlist:\n * `bucket({ fileSizeLimit, allowedMimeTypes })`. Storage enforces those at the\n * actual PUT (the only guard a client cannot skip), so `@Upload` deliberately\n * does NOT take its own `maxSize`/`allowedTypes` — duplicating them here would\n * let a route declare a tighter limit than its bucket that storage would not\n * enforce (a real bypass: declare 10 bytes at authorize, then PUT up to the\n * bucket ceiling straight at the signed URL). One bucket, one limit, enforced.\n */\n bucket: PalbaseBucketName;\n /**\n * SERVER-side object key template. The client NEVER chooses the path. Tokens:\n * `{userId}` (authenticated user id), `{uploadId}` (server-minted), and\n * `{filename}` (the client-declared filename, sanitized). e.g.\n * `\"{userId}/{uploadId}-{filename}\"`.\n */\n pathTemplate: string;\n}\n\n/**\n * The uploaded object, injected into an `@Upload` method body by\n * `@UploadedObject()` once storage confirms the upload. Bytes are NOT present\n * (they went straight to storage) — this is the metadata the completion handler\n * persists.\n */\nexport interface UploadedObject {\n /** Server-minted id correlating authorize ↔ completion (idempotency key). */\n uploadId: string;\n /** Final object key in the bucket (rendered from `pathTemplate`). */\n path: string;\n /** Bucket the object landed in. */\n bucket: string;\n /** Object size in bytes, as reported by storage. */\n size: number;\n /** Object MIME type, as reported by storage — detected from the BYTES, not\n * from the filename or from what the client claimed. */\n contentType: string;\n /** SHA-256 of the stored bytes, hex. The same value the object's ETag is\n * derived from, so a client that has it can tell whether it already holds\n * these bytes. */\n checksum: string;\n /** Pixel width, for an image. Absent otherwise — a PDF has no dimensions,\n * and reporting 0 would be a measurement rather than an absence. */\n width?: number;\n /** Pixel height, for an image. */\n height?: number;\n /**\n * A ~25-byte placeholder the client paints INSTANTLY while the real image\n * downloads — the thing that replaces a grey skeleton with something already\n * shaped like the picture. Absent for non-images.\n *\n * Persist it beside the object's path: it costs a column and saves a request\n * per picture on every gallery render.\n */\n thumbhash?: string;\n /**\n * The renditions the bucket declared, by name, as URLs ready to use.\n *\n * Present on the completion input so the handler that stores the row has\n * everything it needs in one place — asking for them afterwards would be a\n * second call per upload, and per picture on every read.\n */\n variants: Record<string, string>;\n}\n\n/**\n * `@Upload(subpath, config)` — declare a direct-storage upload route. The method\n * body is the completion handler; `config.uploadConfig` drives the authorize\n * guard + signed-URL pinning.\n *\n * @example\n * @Upload(\"/\", { bucket: \"docs\", pathTemplate: \"{userId}/{uploadId}-{filename}\" })\n * async upload(@UploadedObject() obj: UploadedObject, @User() user): Promise<DocResult> { ... }\n * // The size limit + MIME allowlist come from the \"docs\" bucket ON THE STACK\n * // — storage enforces them at the PUT.\n */\nexport function Upload(\n subpath: string,\n config: UploadConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...uploadConfig } = config;\n validateUploadConfigShape(uploadConfig);\n const options: RouteOptions = {\n uploadConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n // On the wire the authorize pre-flight is a POST; `uploadConfig` is what\n // marks this as an upload route downstream.\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@UploadedObject()` — inject the uploaded object (`: UploadedObject`) into an\n * `@Upload` method body (the completion input). Only valid on an `@Upload`\n * route; the bytes are NOT present (they went directly to storage), this is the\n * confirmed object's metadata.\n *\n * Co-located with the {@link UploadedObject} TYPE so a single exported name\n * `UploadedObject` carries BOTH the decorator value and the type annotation.\n */\nexport function UploadedObject(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind: \"uploadedObject\",\n });\n };\n}\n\n/**\n * Shape-validate an UploadConfig at decoration time (author-time failure beats a\n * silent deploy bug). Does NOT check that the bucket EXISTS — the generated\n * `palbase-stack.d.ts` union does that, and it does it at compile time rather\n * than at deploy.\n */\nexport function validateUploadConfigShape(c: UploadConfig): void {\n if (c === null || typeof c !== \"object\") {\n throw new Error(\"@Upload config must be an object { bucket, pathTemplate, ... }\");\n }\n // Read the bucket through a WIDENED view on purpose. Its declared type is\n // `PalbaseBucketName`, which is `never` until the project generates\n // `palbase-stack.d.ts` — and `never.length` does not typecheck. This function\n // is a RUNTIME guard against a shape the compiler never saw (a plain-JS\n // caller, a bundle boundary), so the value arriving here is genuinely unknown\n // and reading it as such is the honest signature, not a cast to dodge an error.\n const bucket: unknown = (c as { bucket?: unknown }).bucket;\n if (typeof bucket !== \"string\" || bucket.length === 0) {\n throw new Error(\"@Upload config.bucket must be a non-empty bucket name\");\n }\n if (typeof c.pathTemplate !== \"string\" || c.pathTemplate.length === 0) {\n throw new Error(\"@Upload config.pathTemplate must be a non-empty key template\");\n }\n}\n\n","// `@Sse` — the streaming-response decorator, and its `@SseOut` / `@Signal`\n// parameter companions.\n//\n// Unlike `@Get`/`@Post`/… (where the handler's RETURN VALUE is serialised to\n// JSON), an `@Sse` route's method body WRITES frames as it goes and its return\n// value is discarded. The response is `text/event-stream` and stays open until\n// the body returns or the client disconnects.\n//\n// On the wire an `@Sse` route is a POST — a stream is started by a request that\n// carries input. What marks it as a streaming route through the whole pipeline\n// (registry → flatten → openapi → codegen) is the PRESENCE of `sseConfig` on the\n// route, NEVER the verb: an ordinary `@Post` route is also POST, so the verb\n// cannot carry the distinction. This is the same rule `@Upload` states, for the\n// same reason.\n//\n// The problem this solves: a provider on the server (an AI client, a job queue,\n// any long-running producer) streams from a session; while a client is connected\n// the frames reach it, and when the client disconnects the provider must stop\n// being pulled. That last half is what `@Signal()` exists for.\nimport { recordRoute, recordParam } from \"./registry.js\";\nimport type { RouteOptions } from \"./registry.js\";\nimport type { ZodTypeAny } from \"zod\";\n\n/** A legacy method decorator (`experimentalDecorators`): `(prototype, name,\n * descriptor)`. */\ntype MethodDecorator = (\n target: object,\n propertyKey: string | symbol,\n descriptor: PropertyDescriptor,\n) => void;\n\n/** A legacy parameter decorator: `(prototype, name, paramIndex)`. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/**\n * Settings for an `@Sse` route.\n *\n * EMPTY in v1, and deliberately so: the pipeline keys off this object's\n * PRESENCE, not its contents (see the file header). Declaring the type now means\n * a later setting arrives as a field on an existing marker rather than as a\n * second marker nothing downstream reads.\n */\nexport interface SseConfig {\n /**\n * The shape of ONE frame — what a single `out.write(value)` carries.\n *\n * REQUIRED, not optional, and that is the whole point. An `@Sse` handler\n * returns `Promise<void>`, so the codegen-injected `recordReturn` has no type\n * to record and nothing downstream can infer what a frame is. A route without\n * this declares a stream whose element type is unknown, and every generated\n * client from that contract is opaque — which is precisely the failure\n * `x-palbase-sse` exists to prevent. Making it optional would have left that\n * failure one forgotten field away.\n *\n * Measured live on a real pushed stack (2026-08-29): the contract gate refused\n * the deploy with \"2 untyped response(s) — every generated client from it is\n * opaque\", naming both routes that omitted it.\n */\n frame: ZodTypeAny;\n}\n\n/**\n * The writer injected by `@SseOut()`. Each `write` emits ONE SSE `data:` frame\n * carrying `value` JSON-encoded.\n *\n * The FIRST `write` is load-bearing beyond its frame: it settles the request's\n * database transaction. A streaming response may run for minutes, and the\n * handler runs inside the request's transaction — holding one open for the life\n * of a stream exhausts the connection pool, a failure invisible to a unit test\n * that only dies under load. So the first frame is the point at which the\n * request phase is declared over, and database access after it is refused by\n * name rather than silently run against a settled transaction.\n *\n * The practical rule for a handler: do the database work BEFORE the first write.\n */\nexport interface SseWriter {\n write(value: unknown): void;\n}\n\n/**\n * `@Sse(subpath, config)` — declare a streaming route.\n *\n * @example\n * @Sse(\"/chat\", { frame: ChatFrame })\n * async chat(@Body() b: ChatInput, @SseOut() out: SseWriter, @Signal() signal: AbortSignal) {\n * const stream = await openai.chat.completions.create(\n * { model: \"gpt-5.6\", messages: b.messages, stream: true },\n * { signal },\n * );\n * for await (const chunk of stream) out.write(chunk);\n * }\n * // The client disconnects → `signal` aborts → the provider stops being pulled.\n * // The signal is a plain AbortSignal, so it goes wherever the provider takes\n * // one: `{ signal }` for the OpenAI and Anthropic SDKs, `abortSignal:` for the\n * // Vercel AI SDK, `fetch(url, { signal })` for a raw call.\n */\nexport function Sse(\n subpath = \"\",\n config: SseConfig & Pick<RouteOptions, \"auth\" | \"rateLimit\">,\n): MethodDecorator {\n const { auth, rateLimit, ...sseConfig } = config;\n const options: RouteOptions = {\n sseConfig,\n ...(auth !== undefined ? { auth } : {}),\n ...(rateLimit !== undefined ? { rateLimit } : {}),\n };\n return function (target, propertyKey) {\n recordRoute(target, String(propertyKey), \"POST\", subpath, options);\n };\n}\n\n/**\n * `@SseOut()` — inject the frame writer (`: SseWriter`) into an `@Sse` method\n * body. Only meaningful on an `@Sse` route.\n */\nexport function SseOut(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"sseOut\" });\n };\n}\n\n/**\n * `@Signal()` — inject the request's `AbortSignal`, which enters the aborted\n * state when the client disconnects.\n *\n * NOT derivable from `@Req()`: `PBRequest` carries only request-scoped data —\n * the typed input, route/query params, headers, the authenticated user, calling\n * client metadata, trace ids, and the declared error throwers — and no signal\n * (endpoint.ts:358-363).\n *\n * Measured 2026-08-29 on Bun: an infinite producer guarded by this signal\n * stopped four frames after the client was killed, and the handler's `finally`\n * ran. It is the same mechanism a NestJS handler reaches through\n * `req.on(\"close\")`.\n */\nexport function Signal(): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), { index: parameterIndex, kind: \"signal\" });\n };\n}\n","// @Room — the realtime surface a backend can actually MANAGE.\n//\n// palbase's realtime lets a backend TALK (broadcast, state.set, push.send) and\n// lets it INTERCEPT a client's publish (defineChannels' handler). What it never\n// let a backend do is SEE the connection: who joined, who left, whether anyone\n// is still watching. A room is that missing half, in the shape this SDK already\n// uses for HTTP — a class with decorated methods.\n//\n// The cost of the gap was concrete: nothing could tell a project that the last\n// device left, so an expensive upstream (an AI session, a market feed, a game\n// loop) kept running and kept billing with nobody reading it. `@OnFirst` and\n// `@OnEmpty` exist for exactly that pair of moments.\n//\n// WHAT A ROOM IS NOT: it does not know where the room id came from, what the\n// history is, or what `@OnFirst` starts. All three belong to the project. The\n// primitive is infrastructure; it carries messages both ways and reports who is\n// present.\n\nimport type { ZodTypeAny } from \"zod\";\nimport {\n recordRoom,\n recordRoomHook,\n recordRoomMessage,\n type RoomHook,\n} from \"./registry.js\";\n\nexport interface RoomOptions {\n /**\n * The events this room sends to its clients, by name.\n *\n * Declared rather than inferred, because a room emits from anywhere in the\n * class — there is no return type to read. The map is the room's public\n * surface: it becomes a Swift enum and a TypeScript union in the generated\n * clients, so a device gets `case .tick(n:)` instead of an opaque bag.\n *\n * Per-event rather than one blob because realtime is event-ADDRESSED all the\n * way down (`Realtime.broadcast(channel, EVENT, payload)`).\n */\n events: Record<string, ZodTypeAny>;\n\n /**\n * How long a room is held after its last sign of life, in milliseconds.\n *\n * Default 60_000, and the floor is not a matter of taste: the decision must\n * survive the SLOWEST client's heartbeat gap twice over, and the web SDK\n * beats every 25 s (palbe/src/realtime/connection.ts:133) against iOS's 2 s\n * (RealtimeConnection.swift:162). A shorter default would declare healthy web\n * clients dead between two beats.\n *\n * Raise it for an upstream that is expensive to restart; lower it (never\n * below ~50 s while web beats at 25 s) for one that is cheap.\n */\n graceMs?: number;\n}\n\n/** Twice the slowest client heartbeat, plus margin. See RoomOptions.graceMs. */\nconst DEFAULT_GRACE_MS = 60_000;\n\n/**\n * A room pattern IS a channel pattern, so it obeys the channel matcher's rules.\n *\n * Both ends of the wire split on `:` — Go's `matchPattern`\n * (internal/modules/rt/channels.go) and this SDK's `matchDeclared` — so a\n * pattern written with slashes matches NO live topic. It fails silently: the\n * room compiles, ships, and simply never fires. Refused here, by name, at the\n * only moment a human is looking.\n *\n * The duplicate-param rule is carried over for the reason channels.ts states:\n * `dm:{uid}:{uid}` against `dm:victim:attacker` lets the last segment win, and\n * an owner check then compares the attacker's id with itself and passes.\n */\nfunction assertPattern(pattern: string): void {\n if (pattern.includes(\"/\")) {\n throw new Error(\n `@Room(\"${pattern}\"): channel patterns are colon-separated, not slash-separated. ` +\n `Write \"${pattern.replace(/\\//g, \":\")}\" — a slash matches no live topic.`,\n );\n }\n const segments = pattern.split(\":\");\n if (segments.some((s) => s === \"\")) {\n throw new Error(`@Room(\"${pattern}\"): empty segment — every segment must be non-empty.`);\n }\n const seen = new Set<string>();\n for (const s of segments) {\n if (!s.startsWith(\"{\") || !s.endsWith(\"}\")) continue;\n const name = s.slice(1, -1);\n if (name === \"\") throw new Error(`@Room(\"${pattern}\"): \"{}\" names no parameter.`);\n if (seen.has(name)) {\n throw new Error(`@Room(\"${pattern}\"): parameter \"{${name}}\" appears twice.`);\n }\n seen.add(name);\n }\n}\n\n/**\n * Declare a class as a room.\n *\n * ```ts\n * @Room(\"chat:{roomId}\", { events: { message: Message } })\n * class ChatRoom {\n * @OnAuthorize() can({ user, params }) { … }\n * @OnFirst() open(ctx) { … } // the room filled\n * @OnEmpty() close(ctx) { … } // nobody is watching any more\n * @OnMessage(\"say\", Say) say(ctx) { … }\n * }\n * ```\n *\n * The pattern is the topic: `chat:{roomId}` addresses `chat:42`. A room is\n * marked by the PRESENCE of this config — never by a name, a base class or a\n * naming convention.\n */\nexport function Room(pattern: string, options: RoomOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n assertPattern(pattern);\n // Member decorators have already run (TypeScript evaluates members before\n // the class), so the hook buffer is complete here and `recordRoom` drains\n // it. controller.ts:203 documents and depends on the same ordering.\n recordRoom(ctor, {\n pattern,\n events: options.events,\n graceMs: options.graceMs ?? DEFAULT_GRACE_MS,\n });\n return ctor;\n };\n}\n\nfunction hookDecorator(hook: RoomHook): () => MethodDecorator {\n return () =>\n function (target: object, propertyKey: string | symbol): void {\n recordRoomHook(target, hook, String(propertyKey));\n };\n}\n\n/** Who may enter. Return a grant to admit, `null` to refuse. */\nexport const OnAuthorize = hookDecorator(\"authorize\");\n\n/**\n * The room is occupied and nobody owns it — start whatever the room needs.\n *\n * Deliberately a CONDITION rather than a 0→1 transition, and the difference is\n * load-bearing: a runtime restart, a deploy pointer swap (the previous release\n * is never torn down) and an owner that died all leave a full room with nobody\n * holding it. A transition would fire once and never again; a condition\n * recovers every time.\n *\n * Exactly one runtime in the cluster enters this hook for a given room, so\n * three devices never open three upstreams.\n */\nexport const OnFirst = hookDecorator(\"first\");\n\n/** A device arrived. Anything emitted here reaches ONLY that device. */\nexport const OnJoin = hookDecorator(\"join\");\n\n/** A device left. */\nexport const OnLeave = hookDecorator(\"leave\");\n\n/** Nobody is watching any more — stop whatever `@OnFirst` started. */\nexport const OnEmpty = hookDecorator(\"empty\");\n\n/**\n * A message from a client, validated against `schema` before the method runs.\n *\n * A payload that fails the schema never reaches the method: the client is told\n * why, and the room's code only ever sees the shape it declared.\n */\nexport function OnMessage(name: string, schema: ZodTypeAny): MethodDecorator {\n return function (target: object, propertyKey: string | symbol): void {\n recordRoomMessage(target, name, String(propertyKey), schema);\n };\n}\n","// Parameter decorators: `@Body` / `@QueryParams` / `@Param` / `@Headers` / `@User` /\n// `@OptionalUser` / `@Client` / `@RequestId` / `@TraceId` / `@Req`. Each records\n// `{ index, kind, schema?, name? }` into the per-class registry for the method\n// it decorates. These are LEGACY parameter decorators\n// (`experimentalDecorators`), receiving `(prototype, methodName, paramIndex)` —\n// esbuild/tsc preserve the param index at runtime (verified, design §0), which\n// is how dispatch injects positionally. No type reflection\n// (`emitDecoratorMetadata`) is used: validation comes from the zod schema, the\n// type annotation the developer writes is purely for autocomplete.\nimport type { ZodTypeAny } from \"zod\";\nimport { recordParam, type ParamKind } from \"./registry.js\";\n\n/** A legacy parameter decorator. */\ntype ParameterDecorator = (\n target: object,\n propertyKey: string | symbol,\n parameterIndex: number,\n) => void;\n\n/** Build a parameter decorator that records the given kind (+ optional schema /\n * name) at the decorated parameter's index. */\nfunction makeParamDecorator(\n kind: ParamKind,\n extra?: { schema?: ZodTypeAny; name?: string },\n): ParameterDecorator {\n return function (target, propertyKey, parameterIndex) {\n recordParam(target, String(propertyKey), {\n index: parameterIndex,\n kind,\n ...(extra?.schema !== undefined ? { schema: extra.schema } : {}),\n ...(extra?.name !== undefined ? { name: extra.name } : {}),\n });\n };\n}\n\n/** `@Body(schema)` — inject the request body, validated against `schema`. The\n * developer writes `: T` (= `z.infer<schema>`, same name) for autocomplete. */\nexport function Body(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"body\", { schema });\n}\n\n/** `@QueryParams(schema)` — inject the parsed query params, validated against\n * `schema`. */\nexport function QueryParams(schema: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"query\", { schema });\n}\n\n/** `@Headers(schema?)` — inject the request headers (lowercase keys). With a\n * schema, headers are validated + the codegen emits header parameters. */\nexport function Headers(schema?: ZodTypeAny): ParameterDecorator {\n return makeParamDecorator(\"headers\", schema !== undefined ? { schema } : undefined);\n}\n\n/** `@Param(\"id\")` — inject one matched path param by name. */\nexport function Param(name: string): ParameterDecorator {\n return makeParamDecorator(\"param\", { name });\n}\n\n/** `@User()` — inject the authenticated user (`: User`, non-null for an\n * effective-required route). The runtime resolves the effective auth. */\nexport function User(): ParameterDecorator {\n return makeParamDecorator(\"user\");\n}\n\n/** `@OptionalUser()` — inject the user as `User | null` (for routes whose\n * effective auth is `false` / `{ required: false }`). */\nexport function OptionalUser(): ParameterDecorator {\n return makeParamDecorator(\"optionalUser\");\n}\n\n/** `@Client()` — inject the parsed calling-client metadata (`: ClientInfo`). */\nexport function Client(): ParameterDecorator {\n return makeParamDecorator(\"client\");\n}\n\n/** `@RequestId()` — inject the per-request id (`: string`). */\nexport function RequestId(): ParameterDecorator {\n return makeParamDecorator(\"requestId\");\n}\n\n/** `@TraceId()` — inject the W3C trace id (`: string`). */\nexport function TraceId(): ParameterDecorator {\n return makeParamDecorator(\"traceId\");\n}\n\n/** `@Req()` — inject the raw request object (escape hatch, `: PBRequest`). */\nexport function Req(): ParameterDecorator {\n return makeParamDecorator(\"req\");\n}\n\n// NOTE: `@UploadedObject()` lives in decorators/upload.ts (co-located with the\n// `UploadedObject` TYPE) so a single exported name carries both the value (the\n// decorator) and the type — TS can only merge value+type under one export name\n// when both are declared in the SAME module.\n","import type { DBClient, Logger, CacheClient, PalbaseModuleClients } from \"./endpoint.js\";\nimport type { User } from \"./types.js\";\n\n/** Middleware context — subset of EndpointContext without input (not yet validated). */\nexport interface MiddlewareContext extends PalbaseModuleClients {\n params: Record<string, string>;\n query: Record<string, string>;\n headers: Record<string, string>;\n user: User | null;\n db: DBClient;\n env: Record<string, string>;\n log: Logger;\n cache: CacheClient;\n requestId: string;\n environmentId: string;\n}\n\n/** Middleware function signature — receives context and next function. */\nexport type MiddlewareHandler = (\n ctx: MiddlewareContext,\n next: () => Promise<void>,\n) => Promise<void>;\n\n/**\n * REMOVED IN BEHAVIOUR, KEPT IN NAME.\n *\n * There is no middleware pipeline in this runtime. No bundler reads a\n * `middleware/` directory, the engine never calls a handler defined here, and\n * measured on 2026-08-31 this function had no caller anywhere in the runtime or\n * the CLI. It returned its argument unchanged, so code written against it\n * compiled, deployed, and then never ran — with nothing reporting that.\n *\n * A silent shell is the worst version of a retired feature: it lets a user (or a\n * coding assistant, which is how this surfaced) ship a request logger, an auth\n * check or a rate limiter that simply does not exist in production. So the call\n * refuses, and says where the work belongs.\n *\n * The SYMBOL survives because removing a published export costs a major and\n * 25.0.1 had just shipped. Deleting it is a proposal for the next one; the types\n * below stay either way, so a file that only annotates with them still compiles.\n *\n * This is the shape the SDK already uses for a retired surface: `@Query(schema)`\n * on a parameter throws at decoration time with a message naming its\n * replacement.\n */\nexport function defineMiddleware(_fn: MiddlewareHandler): never {\n throw new Error(\n \"defineMiddleware() is not wired to anything: no bundler reads a `middleware/` \" +\n \"directory and the engine has no middleware pipeline, so a handler defined \" +\n \"here deploys and never runs. Put cross-cutting work in a service the \" +\n \"controllers call, and use route options for auth (`@Controller(path, { auth })`) \" +\n \"and rate limits (`@Get(path, { rateLimit })`).\",\n );\n}\n","// defineError — project-defined typed error classes + the module-global error\n// registry the OpenAPI spec twins join against.\n//\n// `defineError(code, status, dataSchema?)` returns an `HttpError` subclass whose\n// constructor is typed by the zod schema (`new TodoLocked({ retryAfter: 30 })`).\n// Each call self-registers `{ code, status, className, dataSchema }` in a\n// registry anchored on `globalThis` under `Symbol.for(...)` — mirroring the\n// ROUTES pattern — so the deploy bundle's registrations land on the single SDK\n// instance the extractor `require()`s. The registry is pre-seeded with the named\n// built-in classes (`NotFound`, `Conflict`, …) so throw inference can resolve\n// ad-hoc `throw new NotFound(...)` sites by their canonical wire codes.\n//\n// Duplicate code with a DIFFERENT shape (status OR converted data schema) is a\n// hard error at registration time (deploy fails loudly — error codes are\n// project-unique); structurally-identical re-registration is idempotent (each\n// controller BUNDLE carries its own copy of a shared models/errors.ts, so the\n// same defineError line legitimately runs once per bundle in one process).\nimport {\n OpenAPIRegistry,\n OpenApiGeneratorV31,\n extendZodWithOpenApi,\n} from \"@asteasolutions/zod-to-openapi\";\nimport { z, type ZodTypeAny } from \"zod\";\nimport { HttpError } from \"./errors.js\";\n\nextendZodWithOpenApi(z);\n\n/** One registered error: the wire code, HTTP status, the class name the\n * analyzer sees, the optional data payload schema, and whether it is one of the\n * pre-seeded built-in named classes. */\nexport interface RegisteredError {\n code: string;\n status: number;\n className: string;\n dataSchema?: ZodTypeAny;\n /** JSON.stringify of the converted JSON schema — equal digest ⇔ the spec\n * twins would emit an identical `data` schema for this error. */\n dataDigest?: string;\n builtin: boolean;\n}\n\n/** The cross-module-instance registry anchor (the pinned contract symbol). */\nconst ERROR_REGISTRY: unique symbol = Symbol.for(\"palbase.backend.errorRegistry\");\n\ninterface RegistryCarrier {\n [ERROR_REGISTRY]?: Map<string, RegisteredError>;\n}\n\n/** Get (creating + pre-seeding if absent) the project-global error registry,\n * keyed by wire code. Anchored on `globalThis` so every copy of the SDK in a\n * process shares the one registry. */\n/** The fixed data schemas the built-in named errors ship. Declared HERE (not in\n * errors.ts, which stays zod-free) because this is where the registry converts\n * them to JSON-schema for the spec — keying codegen's typed `error.data`. Only\n * the errors that semantically carry a payload have a schema; the rest are\n * data-less. `.int()` is preserved so the wire/codegen sees an integer. */\nconst BUILTIN_DATA_SCHEMAS: Record<string, ZodTypeAny> = {\n bad_request: z.object({\n fields: z.array(z.object({ field: z.string(), message: z.string() })),\n }),\n too_many_requests: z.object({ retryAfter: z.number().int() }),\n};\n\nexport function getErrorRegistry(): Map<string, RegisteredError> {\n const g = globalThis as RegistryCarrier;\n if (!g[ERROR_REGISTRY]) {\n const m = new Map<string, RegisteredError>();\n for (const [code, status, className] of [\n [\"bad_request\", 400, \"BadRequest\"],\n [\"unauthorized\", 401, \"Unauthorized\"],\n [\"forbidden\", 403, \"Forbidden\"],\n [\"not_found\", 404, \"NotFound\"],\n [\"conflict\", 409, \"Conflict\"],\n // The engine's own 23505 conversion (engine/db.ts) throws this, and an\n // author may too. Registered like every other built-in so the spec\n // emitter resolves it — an unregistered code is SKIPPED silently there\n // (openapi/convert.ts) and would degrade to the client's `.other` case.\n [\"unique_violation\", 409, \"UniqueViolation\"],\n [\"too_many_requests\", 429, \"TooManyRequests\"],\n ] as const) {\n const dataSchema = BUILTIN_DATA_SCHEMAS[code];\n m.set(code, {\n code,\n status,\n className,\n builtin: true,\n ...(dataSchema ? { dataSchema, dataDigest: digestOf(code, dataSchema) } : {}),\n });\n }\n g[ERROR_REGISTRY] = m;\n }\n return g[ERROR_REGISTRY];\n}\n\n/** Class returned for schema-bearing errors: ctor(data, message?). */\nexport interface DefinedErrorWithData<S extends ZodTypeAny> {\n new (data: z.input<S>, message?: string): HttpError;\n readonly code: string;\n readonly status: number;\n}\n\n/** Class returned for schema-less errors: ctor(message?). */\nexport interface DefinedError {\n new (message?: string): HttpError;\n readonly code: string;\n readonly status: number;\n}\n\n/**\n * Define a project error class. MUST be called with literal args (string\n * literal `code`, numeric literal `status`) at module top level — the deploy\n * stager's static analyzer reads those literals to resolve throw sites.\n *\n * @example\n * // models/todos/errors.ts\n * export const TodoLocked = defineError(\"todo_locked\", 409, z.object({ retryAfter: z.number() }));\n * // services/todo.service.ts\n * throw new TodoLocked({ retryAfter: 30 });\n */\nexport function defineError<S extends ZodTypeAny>(\n code: string,\n status: number,\n dataSchema: S,\n): DefinedErrorWithData<S>;\nexport function defineError(code: string, status: number): DefinedError;\nexport function defineError(code: string, status: number, dataSchema?: ZodTypeAny): unknown {\n if (!Number.isInteger(status) || status < 400 || status > 599) {\n throw new Error(\n `defineError: status for \"${code}\" must be a 4xx/5xx integer, got ${status} — ` +\n `error responses must not clobber success responses in the project spec.`,\n );\n }\n const registry = getErrorRegistry();\n const existing = registry.get(code);\n const className = defaultClassName(code);\n const dataDigest = dataSchema ? digestOf(code, dataSchema) : undefined;\n if (existing) {\n const sameShape =\n existing.status === status && !existing.builtin && existing.dataDigest === dataDigest;\n if (!sameShape) {\n throw new Error(\n `defineError: duplicate error code \"${code}\" with a different shape ` +\n `(existing: status ${existing.status}${existing.builtin ? \", built-in\" : \"\"}` +\n `${existing.status === status && !existing.builtin ? \", different data schema\" : \"\"}). ` +\n `Error codes are project-unique.`,\n );\n }\n }\n // Local factories so the class-constructor closures capture a NON-optional\n // schema binding (narrowing does not flow into closures created in a branch).\n const makeWithData = (schema: ZodTypeAny) =>\n class extends HttpError {\n static readonly code = code;\n static readonly status = status;\n constructor(data: unknown, message?: string) {\n super(status, code, message ?? humanize(code), schema.parse(data));\n this.name = className;\n }\n };\n const makeWithoutData = () =>\n class extends HttpError {\n static readonly code = code;\n static readonly status = status;\n constructor(message?: string) {\n super(status, code, message ?? humanize(code));\n this.name = className;\n }\n };\n const cls = dataSchema ? makeWithData(dataSchema) : makeWithoutData();\n Object.defineProperty(cls, \"name\", { value: className });\n registry.set(code, {\n code,\n status,\n className,\n builtin: false,\n ...(dataSchema ? { dataSchema } : {}),\n ...(dataDigest !== undefined ? { dataDigest } : {}),\n });\n return cls;\n}\n\n/** Convert a data schema through the SAME library the spec twins use and\n * return its JSON-schema digest (the duplicate-shape comparison key). Doubles\n * as the self-containment guard: a schema carrying `.openapi(refId)` metadata\n * (top-level or nested) converts to `$ref` pointers into components the\n * project spec never emits — a dangling ref every spec consumer would choke\n * on — so it is rejected here, at the definition site, with a fixable message. */\nfunction digestOf(code: string, dataSchema: ZodTypeAny): string {\n const TMP_REF = \"__PalbaseErrorDataDigest\";\n const tmpRegistry = new OpenAPIRegistry();\n // Wrap the schema as a property — exactly how the envelope embeds it — so a\n // TOP-LEVEL .openapi(refId) is not masked by the registration refId and\n // surfaces as the same $ref the real emission would produce.\n tmpRegistry.register(TMP_REF, z.object({ data: dataSchema }).openapi(TMP_REF));\n const generated = new OpenApiGeneratorV31(tmpRegistry.definitions).generateComponents();\n const out = generated.components?.schemas?.[TMP_REF];\n const digest = JSON.stringify(out ?? null);\n if (digest.includes('\"$ref\"')) {\n throw new Error(\n `defineError: dataSchema for \"${code}\" carries .openapi(refId) metadata — ` +\n `it would emit dangling $ref pointers in the project spec. ` +\n `Use a plain zod schema (z.object({...})) without .openapi(...).`,\n );\n }\n return digest;\n}\n\n/** \"todo_locked\" → \"TodoLocked\" (used as Error.name; the source class NAME the\n * analyzer sees is whatever the user assigned the const to — they should match\n * by convention, and the descriptor carries the analyzed const name anyway). */\nfunction defaultClassName(code: string): string {\n return code\n .split(\"_\")\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join(\"\");\n}\n\n/** \"todo_locked\" → \"Todo locked\" — the default human-readable message. */\nfunction humanize(code: string): string {\n const s = code.replace(/_/g, \" \");\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n","import { type Token } from \"./module.js\";\n\n/**\n * The slot injectable declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol for the same reason `DI_MODULES` is\n * (see `module.ts`): a tenant bundle inlines its OWN copy of `@palbase/backend`\n * and the engine that loads it carries another, so a module-local array would\n * have the decorators push into one and the container read the other.\n */\nexport const DI_INJECTABLES: unique symbol = Symbol.for(\n \"palbase.backend.diInjectables\",\n) as never;\n\n/**\n * The marker `@Injectable()` leaves ON the class.\n *\n * Two signals, because two questions are being asked and only one of them can be\n * answered by a list. \"WHICH classes were declared in this build\" needs an\n * enumeration and gets the claimable slot below. \"IS this class decorated\" needs\n * an answer that survives Bun's module cache: a rollback re-imports an artifact\n * whose body does not run again, so the slot comes back empty while the modules\n * still list the same classes. Reading the slot for that question refused a\n * correct app — measured in `engine.test.ts`, where the second `createApp` in\n * one process saw an emptied slot and called every provider undecorated.\n */\nexport const INJECTABLE: unique symbol = Symbol.for(\"palbase.backend.injectable\") as never;\n\n/** Does this class carry `@Injectable()`? Reads the class, not a registry. */\nexport const isInjectable = (c: unknown): boolean =>\n (c as Record<symbol, unknown> | null)?.[INJECTABLE] === true;\n\nfunction slot(): Token[] {\n const g = globalThis as unknown as Record<symbol, Token[] | undefined>;\n return (g[DI_INJECTABLES] ??= []);\n}\n\n/**\n * Marks a class the container can resolve.\n *\n * TWO JOBS, and the first one is why the decorator has to exist at all:\n * TypeScript under `emitDecoratorMetadata` emits `design:paramtypes` for\n * DECORATED classes only. Measured — an undecorated class with the same\n * constructor carries no metadata, and `Reflect.getMetadata` answers\n * `undefined`.\n *\n * The second is being COUNTABLE. Ownership, visibility and permission are still\n * read from a single `@Module` and never from this decorator — recording the\n * class here decides nothing. It only makes \"carries `@Injectable()` and\n * appears in no module\" a question the build can ask, which FR-010 requires it\n * to answer by name. The body was empty until 2026-09-02, and the consequence\n * was measured through the CLI: an `@Injectable()` service in no module built\n * clean, while this file's own comment claimed the build named it.\n */\nexport function Injectable(): ClassDecorator {\n return (target) => {\n (target as unknown as Record<symbol, unknown>)[INJECTABLE] = true;\n slot().push(target as unknown as Token);\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same claim semantics as `__claimModules`, and for the same reason: a\n * candidate bundle is imported into the SAME process as the live app it might\n * replace, so reading would let a candidate be judged against the live app's\n * classes and a discarded candidate would leave its own behind.\n */\nexport function __claimInjectables(): Token[] {\n return slot().splice(0);\n}\n","import type { Container, Token } from \"../container.js\";\n\n/**\n * Which of a container's classes are entry points of each kind.\n *\n * Discovery used to be a DIRECTORY: `jobs/*.ts` was the list of jobs, and\n * `@Job` recorded metadata but registered nothing. That made the file system a\n * second declaration — a class could carry `@Job`, sit outside `jobs/`, and\n * never run; or sit inside it, be listed in no module, and run anyway.\n *\n * Now a module lists it and the decorator says what it is. One declaration\n * answers ownership, and the metadata answers kind. These four predicates are\n * the only place that mapping lives.\n */\nconst JOB = Symbol.for(\"palbase.backend.jobMeta\");\nconst WEBHOOK = Symbol.for(\"palbase.backend.webhookMeta\");\nconst HOOK_BLOCKING = Symbol.for(\"palbase.backend.hookBlocking\");\nconst HOOK_LISTENERS = Symbol.for(\"palbase.backend.webhookEvents\");\nconst ROOM = Symbol.for(\"palbase.backend.room\");\nconst CONTROLLER = Symbol.for(\"palbase.backend.controllerMeta\");\n\nconst has = (c: unknown, s: symbol): boolean =>\n (c as Record<symbol, unknown>)[s] !== undefined;\n\n/**\n * Does this class carry one of the surface decorators?\n *\n * The container asks, because `providers` legitimately holds `@Job`, `@Hook`,\n * `@Webhook` and `@Room` classes alongside `@Injectable()` ones, and the rule it\n * enforces there — a provider must be DECORATED, so it is constructible and its\n * constructor's types were emitted — has to know that. The predicate lives here\n * because this file is the one place the marker symbols are named.\n */\nexport const isEntryPointClass = (c: unknown): boolean =>\n has(c, JOB) || has(c, WEBHOOK) || has(c, ROOM) || has(c, CONTROLLER) ||\n has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS);\n\nconst owned = (container: Container): Token[] => [...container.owned];\n\nexport const jobsOf = (container: Container): Token[] => owned(container).filter((c) => has(c, JOB));\n\nexport const webhooksOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, WEBHOOK));\n\n/**\n * A hook class carries handler entries and NO class-level marker, so it is\n * recognised by having handlers while being neither a webhook nor a controller.\n * `@On` is shared with `@Webhook`, which is why the webhook marker is what\n * separates them.\n */\nexport const hooksOf = (container: Container): Token[] =>\n owned(container).filter(\n (c) =>\n !has(c, WEBHOOK) &&\n !has(c, CONTROLLER) &&\n (has(c, HOOK_BLOCKING) || has(c, HOOK_LISTENERS)),\n );\n\nexport const roomsOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, ROOM));\n\nexport const controllersOf = (container: Container): Token[] =>\n owned(container).filter((c) => has(c, CONTROLLER));\n","/**\n * A class the container can resolve, named by its own constructor.\n *\n * There is NO separate token concept — no strings, no symbols, no `@Inject`.\n * An abstraction is an `abstract class`, which is still a runtime value and so\n * is still a token. `never[]` on the parameters makes a token something you can\n * NAME but not call: `Token` is an identity, not a factory.\n */\nexport type Token<T = unknown> = abstract new (...args: never[]) => T;\n\n/**\n * The four lists a module declares.\n *\n * `providers` is OWNERSHIP — a class belongs to exactly one module and this is\n * where that is said. `exports` is VISIBILITY — what other modules may reach.\n * `imports` is PERMISSION — whose exports this module may reach. `controllers`\n * are the entry points the module owns.\n *\n * Position in a list means nothing; ownership is read from this declaration and\n * from nowhere else — not from a directory, not from a file name, not from the\n * class's own decorator (spec FR-009).\n */\nexport interface ModuleDef {\n imports?: Token[];\n controllers?: Token[];\n providers?: Token[];\n exports?: Token[];\n}\n\n/**\n * The slot module declarations accumulate in.\n *\n * On `globalThis` under a well-known Symbol, for the same reason\n * `lifecycleHooks` is (runtime.ts:210): a tenant bundle inlines its OWN copy of\n * `@palbase/backend`, and the engine that loads it carries another. Two\n * module-local arrays would mean the engine reads the empty one — decorators\n * push into the bundle's copy, `createApp` claims from the engine's, and every\n * module silently disappears.\n */\nexport const DI_MODULES: unique symbol = Symbol.for(\"palbase.backend.diModules\") as never;\n\n/** One `@Module` declaration: the class that carried it, and what it declared. */\nexport interface ModuleEntry {\n mod: Token;\n def: ModuleDef;\n}\n\nfunction slot(): ModuleEntry[] {\n const g = globalThis as unknown as Record<symbol, ModuleEntry[] | undefined>;\n return (g[DI_MODULES] ??= []);\n}\n\n/**\n * Declares a module.\n *\n * There is no root module and nothing to mount it into: registration IS the\n * decorator running, which happens when the file is imported. A project with no\n * module file at all is not an error — it simply owns nothing, and every entry\n * point it declares is refused by name (FR-035) rather than quietly served.\n */\nexport function Module(def: ModuleDef): ClassDecorator {\n return (target) => {\n slot().push({ mod: target as unknown as Token, def });\n };\n}\n\n/**\n * TAKES the accumulated declarations — it does not read them.\n *\n * Same reason `__runStartHooks` splices (runtime.ts:297): a candidate bundle is\n * imported into the SAME process as the live app it might replace. Reading\n * would let the candidate build a container out of the live app's modules, and\n * a discarded candidate would leave its own behind for the next release to\n * adopt. Claiming makes each `createApp` see exactly the modules imported since\n * the last one, and a rollback leave nothing behind.\n */\nexport function __claimModules(): ModuleEntry[] {\n return slot().splice(0);\n}\n","import \"reflect-metadata\";\n\nimport { DECLARATION_REFUSAL } from \"./refusals.js\";\n\nimport { __claimInjectables, isInjectable } from \"./decorators/injectable.js\";\nimport { isEntryPointClass } from \"./decorators/kinds.js\";\nimport { __claimModules, type ModuleDef, type Token } from \"./decorators/module.js\";\n\n/**\n * `Token` is born in `decorators/module.ts` — the atom of a module's lists — and\n * re-exported here so a reader meets it on the container's surface too. ONE\n * definition: two would be two `abstract new (...)` signatures free to drift.\n */\nexport type { Token };\n\n/**\n * How a container refuses.\n *\n * Every refusal is one of these, and every one names the class involved. There\n * is deliberately no \"unknown\" member: a failure this list cannot classify is a\n * failure the error surface has not been taught to explain, and that is a defect\n * rather than a category.\n */\nexport type DiKind =\n | \"unresolvable dependency\"\n | \"private dependency\"\n | \"missing import\"\n | \"unowned class\"\n | \"dependency cycle\"\n | \"metadata missing\"\n | \"generic dependency\"\n | \"duplicate ownership\"\n | \"unknown export\"\n | \"unknown import\"\n | \"undeclared provider\";\n\n/**\n * A refusal carries four parts: what kind, the full resolution path, where\n * exactly, and what to do about it.\n *\n * The shape is borrowed on purpose — Angular's path, Awilix's failure kind, and\n * Nest's list of potential solutions — because each of the three answers a\n * question the other two leave open: what broke, where in the graph, and what\n * the author should type next.\n */\nexport class DiError extends Error {\n /**\n * EVERY `DiKind` IS A FACT ABOUT THE AUTHOR'S DECLARATIONS — an unresolvable\n * dependency, a cycle, a class no module owns. Not one of them is something\n * the environment could change, so restarting re-reads the same bytes and\n * fails identically. The cure is a new artifact, and the tag is how the\n * runtime learns that without matching on wording.\n */\n readonly [DECLARATION_REFUSAL] = true as const;\n\n constructor(\n readonly kind: DiKind,\n readonly path: string[],\n readonly at: string,\n detail: string,\n readonly fixes: string[],\n ) {\n super(\n `\\nKind: ${kind}\\n` +\n `Path: ${path.length > 0 ? path.join(\" -> \") : \"(none)\"}\\n` +\n `At: ${at}\\n` +\n `${detail}\\n\\n` +\n `Potential solutions:\\n${fixes.map((f) => ` - ${f}`).join(\"\\n\")}\\n`,\n );\n this.name = \"DiError\";\n }\n}\n\n/** How often a module appears in the OTHERS' `imports`. */\nexport interface ModulePressure {\n module: string;\n pct: number;\n /**\n * How many OTHER modules there were — the denominator.\n *\n * Without it the percentage cannot be read. Measured 2026-09-02: a project\n * with two modules, one importing the other, reports 100% — which is true and\n * says nothing, because \"all of the others\" is one module. A reader deciding\n * whether a module has become ambient needs to know whether 80% was four\n * modules or one.\n */\n of: number;\n}\n\nexport interface Container {\n get<T>(t: Token<T>): T;\n /** Every class a module claimed — the set an entry point must be in. */\n readonly owned: ReadonlySet<Token>;\n /**\n * Where `@Global()` pressure is accumulating.\n *\n * A module that appears in more than ~80% of the others' `imports` is one the\n * design is asking to be ambient. That is a JUDGEMENT — how much sharing is\n * too much depends on the domain — so this is reported as a number and never\n * enforced as a gate. Lives on the container rather than in a module-level\n * variable: the runtime builds a candidate's container beside the live app's,\n * and a shared variable would have one overwrite the other's report.\n */\n readonly pressure: readonly ModulePressure[];\n}\n\nconst nameOf = (c: unknown): string => (c as { name?: string } | null)?.name ?? String(c);\n\n/**\n * Values a transpiler emits when a parameter's type has no runtime class.\n *\n * `Object` is the sentinel — an interface, a type alias and a union all collapse\n * to it — and that it is DISTINGUISHABLE from a real class is what lets the\n * container refuse loudly instead of injecting something arbitrary. The\n * primitives are here for the same reason: they are runtime values, so a naive\n * check would happily try to `new` them.\n */\nconst UNRESOLVABLE = new Set<unknown>([\n Object,\n Function,\n String,\n Number,\n Boolean,\n Array,\n Symbol,\n Promise,\n Date,\n undefined,\n null,\n]);\n\n/** The subset worth naming separately: these say \"you passed DATA\" (FR-036). */\nconst DATA = new Set<unknown>([String, Number, Boolean, Date, Symbol]);\n\n/**\n * Does this class SAY what its constructor asks for?\n *\n * The one predicate for the metadata-against-arity cross-check.\n * `assertZeroArgConstructor` calls this rather than re-deriving it: two copies\n * of the rule are two rules, free to drift the moment one is edited.\n */\nexport function declaresDependencies(ctor: unknown): boolean {\n const arity = (ctor as { length?: number } | null)?.length ?? 0;\n if (arity === 0) return true;\n const meta = Reflect.getMetadata(\"design:paramtypes\", ctor as object) as unknown[] | undefined;\n return meta !== undefined && meta.length === arity;\n}\n\n/**\n * Validates the declared modules and returns a container over them.\n *\n * Validation runs in a fixed order, and the order is the point: each stage may\n * assume the previous one held, so a message never has to hedge. Ownership\n * before exports, exports before dependencies, dependencies before cycles,\n * cycles before construction.\n *\n * Stages 3-5 (dependencies and visibility, cycles, resolution) are added by the\n * tasks that follow; this file grows, it is not replaced.\n */\nexport function buildContainer(): Container {\n // CLAIMS the declarations rather than reading them — see `__claimModules`.\n const entries = __claimModules();\n // Claimed HERE even when the graph is about to be refused below, so a failed\n // build cannot leave a previous import's classes for the next one to inherit.\n const declared = __claimInjectables();\n\n // 0 · a project declares at least one module.\n //\n // There is no implicit module. An implicit one would be a SECOND way for a\n // class to become owned, and the whole design rests on there being one: read\n // the module, know the answer.\n if (entries.length === 0) {\n throw new DiError(\n \"unowned class\",\n [],\n \"project\",\n \"no module was declared — every project declares at least one @Module.\",\n [\n \"create `<domain>.module.ts` with @Module({ controllers: [...], providers: [...] })\",\n \"`palbase init` scaffolds one for you\",\n ],\n );\n }\n\n // 1 · ownership — a class belongs to at most one module.\n //\n // `providers` and `controllers` share ONE namespace: a class is owned or it is\n // not, and being listed as both would make \"which module owns it\" a question\n // with two answers.\n const declaredModules = new Set<Token>(entries.map((e) => e.mod));\n\n const owner = new Map<Token, string>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const c of [...(def.providers ?? []), ...(def.controllers ?? [])]) {\n const prev = owner.get(c);\n if (prev !== undefined) {\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(c)],\n `${prev} & ${m}`,\n `${nameOf(c)} is listed by two modules, so which one owns it has two answers.`,\n [\n `remove ${nameOf(c)} from ${prev}`,\n `or remove it from ${m}`,\n `if both modules need it, keep ONE owner and export it, then import that module`,\n ],\n );\n }\n owner.set(c, m);\n }\n }\n\n // 1a · every provider is a class the container can actually BUILD.\n //\n // Measured 02.09.2026: a module that listed an `abstract class` in its\n // `providers` got `new Clock()` — which succeeds in JavaScript and returns an\n // object missing every abstract member — injected into everything that asked\n // for it, and the failure surfaced mid-request as `c.now is not a function`.\n // FR-055 already refuses that shape when the abstraction is named as a\n // DEPENDENCY; this is the same defect coming in through the other door, and\n // the SDK's own test asserted the broken shape was legal.\n //\n // The signal is the decorator. An abstraction in this design is an UNDECORATED\n // `abstract class` (the scaffold's `NoteRepo`), and an implementation carries\n // `@Injectable()`; surfaces carry `@Job`/`@Hook`/`@Webhook`/`@Room`. So a\n // provider carrying none of them is either an abstraction listed in the wrong\n // place or a class somebody forgot to decorate — and the second is not benign\n // either: without a decorator TypeScript emits no `design:paramtypes`, so\n // every constructor parameter it asks for would arrive `undefined`.\n {\n for (const { mod, def } of entries) {\n for (const p of def.providers ?? []) {\n if (isInjectable(p) || isEntryPointClass(p)) continue;\n // A class whose constructor ASKS for something but carries no emitted\n // types is a different fault with a better message — `metadata missing`\n // in stage 3, which explains `emitDecoratorMetadata` and the bundler.\n // Leaving it to that stage keeps each refusal pointed at one cause. The\n // abstract seam this rule is for has a zero-argument constructor\n // (`abstract class NoteRepo { abstract findMany(…) }`), so it lands\n // here.\n if (!declaresDependencies(p)) continue;\n throw new DiError(\n \"undeclared provider\",\n [nameOf(mod), nameOf(p)],\n `${nameOf(mod)}.providers`,\n `${nameOf(p)} is listed in ${nameOf(mod)}.providers but carries no decorator, ` +\n `so the container cannot know it is constructible or what its constructor asks for.`,\n [\n `mark ${nameOf(p)} \\`@Injectable()\\` if it is a concrete class`,\n `if ${nameOf(p)} is an \\`abstract class\\`, list the class that \\`extends\\` it instead — ` +\n `name the abstraction as the DEPENDENCY and the container resolves it`,\n ],\n );\n }\n }\n }\n\n // 1b · every declared class is OWNED by a module (FR-010).\n //\n // `@Injectable()` decides nothing — ownership is read from a module and from\n // nowhere else — but it makes the class COUNTABLE, and this is the question\n // that needs counting: a service written, imported, and listed in no module.\n // It has no entry point, so `assertNoOrphanEntryPoints` never sees it; it has\n // no dependent, so the resolution stages never reach it. It simply does not\n // exist, silently, which is the one outcome this design refuses everywhere\n // else. Measured through the CLI on 2026-09-02: the build said \"build OK\".\n //\n // Not in `isolated()`: that builds a graph without consulting this file at\n // all, deliberately, because a unit test is not a second opinion about the\n // architecture.\n {\n const orphans = declared.filter((c) => !owner.has(c));\n if (orphans.length > 0) {\n const names = orphans.map(nameOf);\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} marked @Injectable() ` +\n `but listed in no module's providers, so nothing can reach ${orphans.length === 1 ? \"it\" : \"them\"}.`,\n [\n `add ${names.length === 1 ? names[0] : \"each of them\"} to a module's \\`providers\\``,\n \"or delete the class — one no module lists is never built\",\n ],\n );\n }\n }\n\n // 2 · exports — a module may only open up what it OWNS.\n //\n // Re-exporting someone else's class would be a hole in the boundary the\n // module system exists to draw: the owner's decision about who may reach it\n // would stop being the owner's.\n const exported = new Map<string, Set<Token>>();\n const importsOf = new Map<string, Set<string>>();\n for (const { mod, def } of entries) {\n const m = nameOf(mod);\n for (const e of def.exports ?? []) {\n if (owner.get(e) !== m) {\n const holder = owner.get(e);\n throw new DiError(\n \"unknown export\",\n [m],\n `${m}.exports`,\n holder === undefined\n ? `${m} exports ${nameOf(e)}, but no module owns it.`\n : `${m} exports ${nameOf(e)}, but ${holder} owns it — a module cannot re-export another's class.`,\n holder === undefined\n ? [`add ${nameOf(e)} to ${m}.providers`, `or remove it from ${m}.exports`]\n : [\n `remove ${nameOf(e)} from ${m}.exports`,\n `and have ${holder} export it instead, then add ${holder} to the importing module's imports`,\n ],\n );\n }\n }\n // An `imports` entry must BE a module. Measured before this check existed:\n // `@Module({ imports: [NotAModule] })` built cleanly and did nothing — the\n // name simply never matched an owner, so every dependency it was meant to\n // unlock kept being refused for a reason that pointed elsewhere.\n for (const i of def.imports ?? []) {\n // Self-import is expressible — legacy decorators run after the class\n // binding exists, so `@Module({ imports: [M] }) class M {}` compiles and\n // ran silently before this check. It grants a module access to its own\n // exports, which it already has, so it is always a typo for another name.\n if (i === mod) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports itself, which grants nothing it does not already have.`,\n [`remove ${m} from its own imports`, \"or name the module you meant instead\"],\n );\n }\n if (!declaredModules.has(i)) {\n throw new DiError(\n \"unknown import\",\n [m],\n `${m}.imports`,\n `${m} imports ${nameOf(i)}, which is not a module.`,\n [\n `add @Module({ ... }) to ${nameOf(i)}`,\n `or remove ${nameOf(i)} from ${m}.imports — to reach a class, import the module that OWNS it`,\n ],\n );\n }\n }\n\n exported.set(m, new Set(def.exports ?? []));\n importsOf.set(m, new Set((def.imports ?? []).map(nameOf)));\n }\n\n // 3 · dependencies — metadata against arity, then type validity, then module\n // visibility. In that order, because each answer makes the next question\n // meaningful.\n const deps = new Map<Token, Token[]>();\n\n /**\n * The owned classes that EXTEND `t`.\n *\n * `abstract` does not exist at runtime — JavaScript happily runs `new Clock()`\n * and returns an object missing every abstract member. Measured before this\n * existed: the container injected exactly that, the build was green, and the\n * failure surfaced mid-request as `c.now is not a function`.\n *\n * So an abstraction is resolved through its implementation, and the\n * relationship is read from the prototype chain — which is what `extends`\n * builds. That is a DECLARATION the class makes about itself, not an\n * inference from where its file sits.\n *\n * Only consulted for a token NOTHING owns. A class that IS owned is the\n * answer to its own name, so an unrelated `extends` elsewhere can never\n * change what an existing dependency resolves to.\n */\n const implementorsOf = (t: Token): Token[] =>\n [...owner.keys()].filter(\n (c) => c !== t && Object.prototype.isPrototypeOf.call(t as object, c as object),\n );\n\n // Is missing metadata GLOBAL or local? Decided BEFORE any per-class message,\n // because the two faults look identical one class at a time and lead to\n // opposite fixes: all of them missing means the build ran without\n // `emitDecoratorMetadata` (or without `reflect-metadata`, whose absence makes\n // the emitted helper a silent no-op); some of them missing means the author\n // forgot `@Injectable()` on those. Telling someone to decorate a class when\n // the flag is off sends them to edit a file that is not the problem.\n //\n // NOT a synthetic canary. An earlier design embedded a probe class in the SDK\n // and asked whether IT carried metadata — but the SDK is built with tsup, and\n // esbuild emits zero `__metadata` (measured), so that probe would report a\n // global fault on every healthy boot. The tenant's OWN classes are the only\n // honest sample of the tenant's build.\n const withArity = [...owner.keys()].filter(\n (c) => (c as unknown as { length: number }).length > 0,\n );\n const missingMeta = withArity.filter(\n (c) => Reflect.getMetadata(\"design:paramtypes\", c) === undefined,\n );\n // TWO is the smallest sample this inference is honest on. With ONE class,\n // \"all of them are missing\" is also what a single forgotten `@Injectable()`\n // looks like, and telling that author their build is broken sends them to the\n // wrong file. Below the threshold the per-class message runs, which names the\n // class and the decorator.\n if (withArity.length >= 2 && missingMeta.length === withArity.length) {\n throw new DiError(\n \"metadata missing\",\n withArity.map(nameOf),\n \"the whole build\",\n `no class carries constructor metadata — every one of the ${withArity.length} ` +\n `class(es) that asks for a dependency is missing it, so this is the build, ` +\n `not the classes.`,\n [\n \"set `emitDecoratorMetadata: true` in the project's tsconfig.json\",\n \"and import `reflect-metadata` before any decorated class evaluates — without it the emitted helper is a silent no-op\",\n \"if the build is fine, then none of these classes carries @Injectable()\",\n ],\n );\n }\n\n for (const [cls, m] of owner) {\n const arity = (cls as unknown as { length: number }).length;\n\n // ARITY IS THE GROUND TRUTH. It survives every transpile; metadata does not.\n // Measured: a decorated class with no constructor carries `undefined`\n // metadata and a decorated one with an empty constructor carries `[]` —\n // both ask for nothing, and only arity says so. Treating absent metadata as\n // a fault would refuse every dependency-free class that never wrote a\n // constructor, which is most of them.\n if (arity === 0) {\n deps.set(cls, []);\n continue;\n }\n\n // Asked through the shared predicate, so \"does this class say what it needs\"\n // has ONE definition — the same one `assertZeroArgConstructor` answers with.\n if (!declaresDependencies(cls)) {\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[] | undefined;\n throw new DiError(\n \"metadata missing\",\n [nameOf(cls)],\n `${nameOf(cls)} constructor`,\n `${nameOf(cls)} declares ${arity} parameter(s) but carries ` +\n `${meta === undefined ? \"no\" : String(meta.length)} metadata entries, ` +\n `so every parameter would arrive as undefined.`,\n [\n `add @Injectable() to ${nameOf(cls)} — metadata is emitted for DECORATED classes only`,\n \"or the build ran without emitDecoratorMetadata: check tsconfig.json\",\n ],\n );\n }\n\n const meta = Reflect.getMetadata(\"design:paramtypes\", cls) as unknown[];\n const list: Token[] = [];\n meta.forEach((t, i) => {\n const at = `${nameOf(cls)} constructor, parameter ${i}`;\n\n if (typeof t !== \"function\" || UNRESOLVABLE.has(t)) {\n throw new DiError(\n \"unresolvable dependency\",\n [nameOf(cls)],\n at,\n `parameter ${i} has no runtime class — an interface, a type alias, a ` +\n `union, or a data type. The container has nothing to construct.`,\n DATA.has(t)\n ? [\n \"an injectable's constructor takes dependencies, not data\",\n \"move the value to a method argument instead\",\n \"or make this a plain value class (no @Injectable, in no module) and `new` it yourself\",\n ]\n : [\n \"depend on a concrete class or an abstract class\",\n \"a TypeScript interface does not exist at runtime — there is nothing to inject\",\n ],\n );\n }\n\n const dep = t as Token;\n\n {\n let dm = owner.get(dep);\n if (dm === undefined) {\n // An ABSTRACTION, resolved to its one implementation (FR-055).\n //\n // Read from `extends`, not from a second syntax: `class SystemClock\n // extends Clock` is the class declaring \"I am a Clock\", and that is a\n // declaration — not an inference from where a file sits.\n const impls = implementorsOf(dep);\n if (impls.length === 1) {\n const impl = impls[0] as Token;\n list.push(impl);\n dm = owner.get(impl) as string;\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} and is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(impl)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(impl)],\n at,\n `${nameOf(impl)} implements ${nameOf(dep)} but is internal to ${dm}.`,\n [`add ${nameOf(impl)} to ${dm}.exports (and say why)`],\n );\n }\n }\n return;\n }\n if (impls.length > 1) {\n const names = impls.map(nameOf).sort();\n throw new DiError(\n \"duplicate ownership\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${names.join(\" and \")} both extend ${nameOf(dep)}, so which one ` +\n `${nameOf(cls)} should receive has two answers.`,\n [\n `keep ONE class extending ${nameOf(dep)} in this graph`,\n `or depend on ${names[0]} or ${names[1]} directly, by name`,\n ],\n );\n }\n throw new DiError(\n \"unowned class\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} belongs to no module, and nothing in this graph extends it — ` +\n `so there is nothing to construct. (An abstract class cannot be built: ` +\n `\\`abstract\\` is a type-level claim, and \\`new\\` on one returns an object ` +\n `missing every abstract member.)`,\n [\n `add ${nameOf(dep)} to a module's providers if it is concrete`,\n `or add a class that \\`extends ${nameOf(dep)}\\` to a module's providers`,\n ],\n );\n }\n if (dm !== m) {\n if (!importsOf.get(m)?.has(dm)) {\n throw new DiError(\n \"missing import\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is owned by ${dm}, which ${m} does not import.`,\n [`add ${dm} to ${m}.imports`],\n );\n }\n if (!exported.get(dm)?.has(dep)) {\n throw new DiError(\n \"private dependency\",\n [nameOf(cls), nameOf(dep)],\n at,\n `${nameOf(dep)} is internal to ${dm} — it is not exported.`,\n [\n `use one of ${dm}'s exported classes`,\n `or add ${nameOf(dep)} to ${dm}.exports (and say why it should be public)`,\n ],\n );\n }\n }\n }\n\n list.push(dep);\n });\n\n deps.set(cls, list);\n }\n\n // 4 · cycles — refused, with the path written out by name.\n //\n // There is NO `forwardRef`-style escape, and the reason is that the shape one\n // exists to rescue cannot be built: a real ESM cycle dies at import. Measured\n // in the spike — Bun throws `Cannot access 'CB' before initialization` before\n // the container is ever consulted. What CAN still be assembled is a cycle\n // inside one file, so the detector earns its place; what it never has to do is\n // offer a way to keep one.\n const state = new Map<Token, 0 | 1 | 2>();\n const stack: Token[] = [];\n const walk = (c: Token): void => {\n if (state.get(c) === 1) {\n // Slice from where this class first entered the stack, so the message is\n // the CYCLE and not the path that happened to reach it.\n const cyc = [...stack.slice(stack.indexOf(c)), c].map(nameOf);\n throw new DiError(\n \"dependency cycle\",\n cyc,\n `${cyc[0]} constructor`,\n `the dependency graph contains a cycle: ${cyc.join(\" -> \")}.`,\n [\n \"extract the shared part into a third class both can depend on\",\n \"or invert one direction — have the callee raise an event the caller listens for\",\n ],\n );\n }\n if (state.get(c) === 2) return;\n state.set(c, 1);\n stack.push(c);\n // A platform token needs no special case: it has no `deps` entry, so the\n // walk reaches it, finds nothing to follow, and marks it done. A guard here\n // would be an inert check — it was written, measured against a mutation, and\n // removed when removing it changed nothing.\n for (const d of deps.get(c) ?? []) walk(d);\n stack.pop();\n state.set(c, 2);\n };\n for (const c of owner.keys()) walk(c);\n\n // 5 · resolution — ONE lifetime, singleton.\n //\n // No `transient`, no `request`. Request scope already exists and it is an\n // AsyncLocalStorage, not an object lifetime: what varies per request is the\n // database handle and the claims, and the engine opens that scope around the\n // handler. Making the OBJECTS per-request would duplicate that mechanism and\n // then have to keep the two in agreement.\n //\n // The consequence is a rule about constructors: they stay synchronous and do\n // nothing but wiring. Real I/O belongs in `onStart`, where it can fail loudly\n // at boot instead of halfway through the first request.\n const cache = new Map<Token, unknown>();\n const make = (c: Token): unknown => {\n // A token this container never validated is NOT built. Measured before this\n // check existed: `get(Stranger)` found no `deps` entry, fell through to\n // `new Stranger()` with zero arguments, and returned it — so a class in no\n // module could still be constructed through the container's own front door,\n // which is the hole the module system exists to close (FR-053).\n //\n // There is no platform escape hatch here: platform services (Database, Log,\n // …) are AMBIENT — imported, not injected — because they are request-scoped\n // and a boot-time singleton holding one would capture the first request's\n // client forever (FR-005). Nothing supplies a platform map, so having one\n // would be an inert extension point.\n if (!owner.has(c)) {\n throw new DiError(\n \"unowned class\",\n [nameOf(c)],\n \"container.get\",\n `${nameOf(c)} belongs to no module, so this container never validated it ` +\n `and will not build it.`,\n [\n `add ${nameOf(c)} to a module's providers`,\n \"or, if it is a plain value class, construct it yourself with `new`\",\n ],\n );\n }\n const hit = cache.get(c);\n if (hit !== undefined) return hit;\n const args = (deps.get(c) ?? []).map(make);\n const inst = new (c as unknown as new (...a: unknown[]) => unknown)(...args);\n cache.set(c, inst);\n return inst;\n };\n\n return {\n get: <T,>(t: Token<T>): T => make(t) as T,\n owned: new Set(owner.keys()),\n pressure: computePressure(entries),\n };\n}\n\n/**\n * What fraction of the OTHER modules import each module.\n *\n * `total - 1` is the denominator because a module never imports itself, so the\n * most any module can reach is everyone else. Under two modules there is nothing\n * to compare and the answer is an empty list rather than a misleading 100%.\n */\nfunction computePressure(entries: { mod: Token; def: ModuleDef }[]): ModulePressure[] {\n // No `total < 2` guard, and none is needed: a single module cannot import\n // anything (there is no other module, and both self-import and non-module\n // imports are refused above), so `count` is empty and the division below never\n // runs. The guard was written, measured against a mutation, and removed when\n // removing it changed nothing — an inert check still draws a number.\n const total = entries.length;\n const count = new Map<string, number>();\n for (const { def } of entries) {\n for (const i of def.imports ?? []) {\n const n = nameOf(i);\n count.set(n, (count.get(n) ?? 0) + 1);\n }\n }\n return [...count]\n .map(([module, c]) => ({ module, pct: Math.round((c / (total - 1)) * 100), of: total - 1 }))\n .sort((a, b) => b.pct - a.pct);\n}\n\n/** Kept so the module surface is stable while stages 3-5 land. */\nexport type { ModuleDef };\n\n/**\n * Refuses an entry point that no module lists (FR-035).\n *\n * A decorated class registers itself — `@Controller` pushes into a globalThis\n * slot the moment its file is imported — so before this check a class listed in\n * no module still reached the route table, the dispatcher and the OpenAPI\n * document. It worked, which is the problem: nothing said the module system had\n * been bypassed.\n *\n * After this, a successful boot means the two sets are EQUAL: what decorated\n * itself and what a module claimed. That equality is what lets `src/openapi/`\n * stay untouched — it renders the list it is handed, and the list is now the\n * module's.\n */\nexport function assertNoOrphanEntryPoints(\n registered: readonly unknown[],\n owned: ReadonlySet<Token>,\n): void {\n const orphans = registered.filter((c) => !owned.has(c as Token));\n if (orphans.length === 0) return;\n const names = orphans.map((c) => (c as { name?: string }).name ?? \"<anonymous>\");\n throw new DiError(\n \"unowned class\",\n names,\n \"module declarations\",\n `${names.join(\", \")} ${orphans.length === 1 ? \"is\" : \"are\"} decorated as an entry ` +\n `point but listed in no module, so nothing decides whether it should be served.`,\n [\n \"add it to a module's `controllers` (for @Controller) or `providers` (for @Room/@Job/@Hook/@Webhook)\",\n \"an entry point no module lists is never mounted and never reaches the OpenAPI document\",\n ],\n );\n}\n","/** Non-service, per-invocation data for job handlers.\n * Services (Database, Log, …) are imported as singletons, not passed here. */\nexport interface JobMeta {\n /** Environment-scoped env vars. */\n env: Record<string, string>;\n /** The globally unique Environment runtime identifier. */\n environmentId: string;\n}\n\n/**\n * Cron expression validation.\n * Supports standard 5-field cron: minute hour day-of-month month day-of-week.\n * Each field allows: number, *, ranges (1-5), steps (star/2), lists (1,3,5).\n */\nexport function validateCronExpression(expression: string): string | null {\n const trimmed = expression.trim();\n if (trimmed === \"\") {\n return \"Cron expression is required\";\n }\n\n const parts = trimmed.split(/\\s+/);\n if (parts.length !== 5) {\n return `Invalid cron expression \"${trimmed}\": expected 5 fields (minute hour day month weekday), got ${parts.length}`;\n }\n\n const fieldNames = [\"minute\", \"hour\", \"day of month\", \"month\", \"day of week\"];\n const fieldRanges: [number, number][] = [\n [0, 59],\n [0, 23],\n [1, 31],\n [1, 12],\n [0, 7],\n ];\n\n for (let i = 0; i < 5; i++) {\n const field = parts[i]!;\n const name = fieldNames[i]!;\n const [min, max] = fieldRanges[i]!;\n\n const error = validateCronField(field, name, min, max);\n if (error !== null) {\n return error;\n }\n }\n\n return null;\n}\n\nfunction validateCronField(\n field: string,\n name: string,\n min: number,\n max: number,\n): string | null {\n // Split by comma for lists\n const listParts = field.split(\",\");\n for (const part of listParts) {\n // Check for step: */2, 1-5/2\n const stepParts = part.split(\"/\");\n if (stepParts.length > 2) {\n return `Invalid ${name} field: \"${field}\"`;\n }\n\n const base = stepParts[0]!;\n const step = stepParts[1];\n\n if (step !== undefined) {\n const stepNum = Number(step);\n if (!Number.isInteger(stepNum) || stepNum < 1) {\n return `Invalid step value in ${name} field: \"${field}\"`;\n }\n }\n\n if (base === \"*\") {\n continue;\n }\n\n // Check for range: 1-5\n if (base.includes(\"-\")) {\n const rangeParts = base.split(\"-\");\n if (rangeParts.length !== 2) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n const rangeStart = Number(rangeParts[0]);\n const rangeEnd = Number(rangeParts[1]);\n if (\n !Number.isInteger(rangeStart) ||\n !Number.isInteger(rangeEnd) ||\n rangeStart < min ||\n rangeEnd > max ||\n rangeStart > rangeEnd\n ) {\n return `Invalid range in ${name} field: \"${field}\"`;\n }\n continue;\n }\n\n // Single number\n const num = Number(base);\n if (!Number.isInteger(num) || num < min || num > max) {\n return `Invalid value in ${name} field: \"${field}\"`;\n }\n }\n\n return null;\n}\n","// @Job — the cron half of the decorator surface. Same metadata mechanism as\n// @Webhook/@Controller. The job's NAME is not here on purpose: it is the file\n// name, which is also what the Temporal schedule id is built from. Two names\n// with nothing reconciling them is what this replaces.\nimport type { JobMeta } from \"../job.js\";\nimport { validateCronExpression } from \"../job.js\";\nimport type { Container } from \"../container.js\";\nimport { assertSurfaceName } from \"./surface-name.js\";\n\nexport interface JobOptions {\n /**\n * The job's identity, and the name the scheduler holds its rows under.\n *\n * DECLARED, not derived. It used to be the file's name, which made the\n * identity a property of where the class sat — rename the file and the\n * scheduler starts a different job. Ownership and identity both come from a\n * declaration now, and this is where a reader looks for it.\n *\n * Lowercase, digits and dashes: it reaches a scheduler row and a log line.\n */\n name: string;\n /** Cron expression, five fields (e.g. \"0 3 * * *\"). */\n schedule: string;\n /** Execution timeout in seconds. Defaults to 30, ceiling 300 (sandbox limit). */\n timeout?: number;\n /**\n * How many times a FAILED run is retried before the run is recorded failed.\n * Defaults to 5, ceiling 10; 0 disables retrying entirely.\n *\n * Retries exist for the transient half of the failure space — the runtime\n * still waking, a network blip — not for a job that is wrong. A permanent\n * failure still lands in the run history, it just lands after the retries\n * are spent rather than instead of them.\n */\n retry?: number;\n}\n\nexport interface ResolvedJob {\n /** The declared identity — the scheduler's row name. */\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n handler: (meta: JobMeta) => Promise<void>;\n}\n\nconst DEFAULT_TIMEOUT_SECONDS = 30;\nconst MAX_TIMEOUT_SECONDS = 300;\nconst DEFAULT_RETRY = 5;\nconst MAX_RETRY = 10;\n\nexport const JOB_META: unique symbol = Symbol.for(\"palbase.backend.jobMeta\");\n\ninterface JobCarrier {\n __palbase?: \"job\";\n [JOB_META]?: JobOptions;\n}\n\nexport function Job(options: JobOptions) {\n return function <T extends abstract new (...args: never[]) => object>(ctor: T): T {\n const carrier = ctor as unknown as JobCarrier;\n Object.defineProperty(carrier, JOB_META, {\n value: options,\n enumerable: false,\n configurable: true,\n writable: false,\n });\n Object.defineProperty(carrier, \"__palbase\", {\n value: \"job\",\n enumerable: false,\n configurable: true,\n writable: false,\n });\n return ctor;\n };\n}\n\n/**\n * What a job DECLARES — schedule, timeout, retry. Reads metadata and nothing\n * else: the class is NOT constructed.\n *\n * Deploy's manifest script needs exactly this and no instance (stack_bundle.go\n * writes `jobs.manifest.json` from it, with no runtime and therefore no\n * container). Constructing a class to read a cron string was a side effect, and\n * it is the side effect that made the container look optional — which in turn\n * let a caller that never passes one compile quietly.\n */\nexport interface JobManifest {\n name: string;\n schedule: string;\n timeout: number;\n retry: number;\n}\n\nexport function getJobManifest(ctor: object): JobManifest {\n const meta = (ctor as JobCarrier)[JOB_META];\n if (!meta) {\n throw new Error(\n `getJobConfig on a class with no @Job decorator (${(ctor as { name?: string }).name ?? \"anonymous\"})`,\n );\n }\n assertSurfaceName(meta.name, \"@Job\", \"job\");\n if (!meta.schedule || meta.schedule.trim() === \"\") {\n throw new Error(\"@Job requires a `schedule` cron expression\");\n }\n const cronError = validateCronExpression(meta.schedule);\n if (cronError) {\n throw new Error(`@Job has an invalid cron schedule: ${cronError}`);\n }\n\n const timeout = meta.timeout ?? DEFAULT_TIMEOUT_SECONDS;\n if (!Number.isInteger(timeout) || timeout <= 0) {\n throw new Error(\"@Job `timeout` must be a positive whole number of seconds\");\n }\n if (timeout > MAX_TIMEOUT_SECONDS) {\n throw new Error(`@Job \\`timeout\\` exceeds the ${MAX_TIMEOUT_SECONDS}s sandbox ceiling`);\n }\n\n const retry = meta.retry ?? DEFAULT_RETRY;\n if (!Number.isInteger(retry) || retry < 0) {\n throw new Error(\"@Job `retry` must be a whole number of attempts, zero or more\");\n }\n if (retry > MAX_RETRY) {\n throw new Error(`@Job \\`retry\\` exceeds the ceiling of ${MAX_RETRY}`);\n }\n\n return { name: meta.name, schedule: meta.schedule, timeout, retry };\n}\n\n/**\n * The job, ready to run — manifest plus a bound `run`.\n *\n * `container` is REQUIRED. It used to be absent (the class was built with\n * `new`), and then briefly optional, which is worse: an optional parameter lets\n * a caller that forgot it compile, and the job would receive `undefined` for\n * every dependency at its first scheduled run, hours after deploy, in a process\n * nobody is watching. Required makes the two runtime call sites a TYPE error.\n */\nexport function getJobConfig(ctor: object, container: Container): ResolvedJob {\n const { name, schedule, timeout, retry } = getJobManifest(ctor);\n\n const instance = container.get(ctor as never) as { run?: (meta: JobMeta) => Promise<void> };\n if (typeof instance.run !== \"function\") {\n throw new Error(\"@Job class must declare an async run() method\");\n }\n const run = instance.run.bind(instance);\n\n return { name, schedule, timeout, retry, handler: run };\n}\n"],"mappings":"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","names":["TABLE_META","REF_BRAND","Symbol","for","brandRef","v","kind","Object","defineProperty","value","enumerable","brandOf","undefined","hasOwn","isColRef","v","brandOf","$col","isSqlFragment","v","brandOf","f","$sql","undefined","Array","isArray","text","values","TX_EXPR","Symbol","for","isNowExpr","isColumnExpr","e","fn","TxRefError","Error","message","name","TxPlanError","EXPR","Symbol","for","REF","ROW","ROWS","TRAPPED_PROPS","toPrimitive","trap","prop","what","hint","description","String","now","makeExpr","fn","increment","by","assertAmount","inc","decrement","dec","test","Number","isFinite","negative","trimStart","startsWith","other","makeExpr","expr","Proxy","EXPR","get","target","prop","TRAPPED_PROPS","includes","trap","undefined","makeRef","op","field","REF","t","makeRowHandle","ROW","refDescriptor","v","d","isRefDescriptor","rowOpIndex","exprOf","e","isRowsHandle","ROWS","encodeValue","value","column","allowColumnExpr","ref","brandRef","$ref","isNowExpr","$expr","fn","TxPlanError","assertNoNestedHandles","encodeFilterValue","Array","isArray","map","Date","isColRef","isSqlFragment","out","k","Object","entries","encodeFilterMap","key","keys","sort","item","values","encodeMap","SKIPPED_OP","TxRowsImpl","guarded","builder","opIndex","what","then","TxRefError","expectOne","error","declareGuard","expectNone","expectAtLeast","n","assertGuardCount","expectAtMost","kind","Error","attachGuard","Number","isInteger","String","MAX_OPS","MAX_ROWS","TxPlanBuilder","ops","slots","table","name","insert","encoded","length","push","put","options","onConflict","insertMany","rows","opts","row","assertUniformRows","action","updateWhere","where","set","encodedWhere","encodedSet","deleteWhere","select","limit","lock","index","slot","guard","body","errorForSlot","first","want","wantKey","join","i","got","materializeResult","results","rowOf","rowOp","isPlainObject","result","proto","getPrototypeOf","prototype","runTxPlan","transport","handle","returned","response","txPlan","err","translateRejection","rejection","error_code","retryBudget","value","n","Number","isInteger","Error","assertPlanRetry","options","retryBudget","retry","Error","defOf","column","_def","columnToJSON","def","out","type","nullable","primaryKey","defaultValue","undefined","defaultRandom","defaultNow","renamedFrom","ignored","owns","references","table","onDeleteAction","index","counter","enumName","enumValues","unique","dimensions","policyToJSON","policy","name","command","roles","using","withCheck","permissive","commonSearchFields","search","synonyms","Object","keys","length","fromEntries","entries","map","word","alts","validity","searchToJSON","vectorColumn","from","model","textCols","text","Array","isArray","columns","v","metric","embed","provider","apiKeyName","baseURL","staleness","mode","chunks","c","size","sizeChars","overlap","overlapChars","vector","legs","leg","memoryToJSON","m","into","subject","extract","tableToJSON","schemaName","schema","rls","policies","uniqueConstraints","u","raw","rawConstraints","r","up","checks","expr","indexes","i","ix","where","expression","sort","nulls","include","dropConstraints","foreignKeys","fk","j","refTable","refColumns","onUpdate","onDelete","match","freeze","f","when","guards","g","event","exists","message","detail","hint","backfills","b","sql","appendOnly","find","sj","memory","qualifiedTableKey","tableName","toSchemaJSON","schemas","tables","extensions","meta","seen","Set","has","Error","add","values","json","push","exposed","REQUEST_ALS","Symbol","for","__requestALS","g","globalThis","AsyncLocalStorage","runtime","__setRuntime","services","__runWithRuntime","fn","run","REQUIRED_SERVICES","refuseIncompleteBox","missing","filter","k","undefined","length","Error","join","__getRuntime","scoped","getStore","LIFECYCLE","declaredLifecycle","start","shutdown","onStart","name","hook","push","onShutdown","reason","err","message","String","drain","hooks","h","reverse","console","error","__runStartHooks","slot","splice","cause","drained","__resetLifecycleHooks","makeServiceProxy","key","handler","get","_target","prop","receiver","client","value","Reflect","bind","Proxy","makeTableProxy","ops","prefix","_t","insert","data","aggregate","q","insertMany","rows","opts","update","where","id","set","delete","findById","findUnique","select","with","page","findMany","put","onConflict","updateMany","returning","deleteMany","count","search","params","similar","recommend","facets","supersede","row","claim","unique","extra","rawDatabase","makeTypedSurface","raw","reco","$query","sql","query","$diagnostics","diagnostics","$insert","table","$update","$delete","$findById","$findUnique","$page","$findMany","$put","$updateMany","$deleteMany","$count","$search","$similar","$recommend","$facets","$claim","$lockRows","ids","lockRows","$lockRowsWhere","lockRowsWhere","$advisoryXactLock","advisoryXactLock","$aggregate","$insertMany","$supersede","base","Object","assign","$atomic","options","atomic","parent","tx","typed","invoke","refuse","ambient","asService","Database","$attempt","attempt","$transaction","assertPlanRetry","builder","TxPlanBuilder","runTxPlan","makeTxPlanHandle","$command","txPlan","plan","command","target","startsWith","qualifiedTableKey","makeTxTablesAccessor","tablesProxy","publicTables","$asService","Documents","makeBucketsAccessor","storage","bucket","rawStorage","Storage","buckets","Cache","Secrets","Auth","Log","Notifications","rawFlags","Flags","isEnabled","flagName","context","getVariant","getAll","defaultOrContext","maybeContext","setOverride","Realtime","PalbaseModuleError","Error","code","status","details","message","name","makeHttpClient","cfg","request","method","path","options","headers","apiKey","init","body","undefined","Uint8Array","FormData","Blob","JSON","stringify","signal","doFetch","fetchImpl","globalThis","fetch","response","baseUrl","err","data","error","contentType","get","parsed","includes","json","catch","startsWith","arrayBuffer","text","ok","error_description","statusText","RoleNotDefined","Error","role","message","name","refuse","error","code","PalbaseModuleError","rolesPath","userId","base","encodeURIComponent","undefined","buildAuthClient","http","assignRole","request","revokeRole","rolesOf","data","roles","SEGMENT_RE","validateSegment","segment","label","test","Error","source","buildDocumentRef","http","path","set","data","request","body","get","response","error","status","raw","exists","undefined","Boolean","id","segments","split","length","ref","update","delete","collection","name","buildCollectionRef","state","where","orderBy","snapshot","doc","querySnapshot","docs","empty","size","docChanges","map","type","add","resp","field","op","value","direction","limit","n","narrowed","queryBody","documents","w","o","MAX_BATCH","buildDocumentsClient","String","filter","s","forEach","i","join","batch","operations","PalbaseModuleError","FLAG_NAME_RE","assertFlagName","flagName","test","Error","source","flagEnabled","value","flagVariant","name","isContextObject","v","Array","isArray","buildFlagsClient","http","cfg","resolveUserId","context","userId","getCurrentUserId","undefined","mergedPath","uid","encodeURIComponent","fetchMerged","request","service","setOverrideForUser","key","body","setOverridesForUser","values","clearOverrideForUser","clearAllOverridesForUser","batchSetOverrides","operations","ops","map","op","raw","user_id","isEnabled","res","error","data","status","getVariant","get","defaultOrContext","maybeContext","defaultValue","hasDefault","resp","getAll","Object","keys","flag","enabled","variant","setOverride","message","asService","mapEnvelope","res","map","error","data","undefined","status","toEmailTemplate","wire","view","id","slug","locale","subject","htmlBody","html_body","variables","isDefault","is_default","createdAt","created_at","updatedAt","updated_at","text_body","textBody","toSmsTemplate","body","buildNotificationsClient","http","push","send","params","request","email","templateSlug","html","text","rest","template_slug","sms","whatsapp","userId","user_id","events","options","query","limit","encodeURIComponent","String","verifications","start","check","inbox","list","opts","URLSearchParams","cursor","set","is_read","category","include_archived","toString","unreadCount","markRead","markAllRead","archive","preferences","get","update","emailTemplates","resp","rows","create","input","delete","smsTemplates","templates","registerDevice","unregisterDevice","deviceId","mintToken","secret","now","Math","floor","Date","header","Buffer","from","JSON","stringify","alg","typ","toString","payload","iss","role","iat","exp","sig","createHmac","update","digest","buildRealtimeClient","cfg","url","baseUrl","stateUrl","writeState","topic","key","value","del","length","data","error","PalbaseModuleError","apiJwtSecret","token","err","Error","message","op","doFetch","fetchImpl","globalThis","fetch","response","method","headers","Authorization","body","ops","status","undefined","detail","text","catch","state","set","clear","broadcast","channel","event","messages","private","slice","BUCKET_NAME_RE","STORAGE_PATH_RE","STORAGE_TRAVERSAL_RE","validateStoragePath","p","test","Error","source","toFileObject","bucket","row","name","path","size","contentType","checksum","width","height","thumbhash","variants","mapResponse","res","map","error","data","undefined","status","buildBucketClient","http","bucketName","publicOrigin","objectPath","upload","file","options","headers","upsert","body","ArrayBuffer","Uint8Array","request","r","download","Accept","getPublicUrl","variant","encodeURIComponent","createSignedUrl","expiresIn","list","prefix","params","URLSearchParams","set","limit","String","query","toString","objects","remove","paths","removed","push","move","from","to","copy","buildStorageClient","replace","buildModuleClients","cfg","baseUrl","replace","apiKey","serviceRoleKey","http","makeHttpClient","fetchImpl","Auth","buildAuthClient","Documents","buildDocumentsClient","Storage","buildStorageClient","publicOrigin","Notifications","buildNotificationsClient","Flags","buildFlagsClient","getCurrentUserId","Realtime","buildRealtimeClient","apiJwtSecret","realtimeApiJwtSecret","TABLE_META","Symbol","for","REF_TARGET","ForeignKeyBuilder","_def","name","trim","Error","columns","refTable","refColumns","on","cols","map","c","e","expr","kind","references","table","length","Object","defineProperty","value","enumerable","configurable","onUpdate","action","onDelete","match","m","foreignKey","toForeignKeyDef","b","def","join","FreezeBuilder","when","pred","toFreezeDef","freeze","undefined","out","target","PolicyExprRef","expr","bin","op","other","kind","left","right","toExpr","eq","neq","gt","gte","lt","lte","isNull","negated","and","others","parts","map","o","or","not","v","value","exprCtx","_columns","depth","ownTable","alias","col","name","auth","uid","lit","p","part","existsIn","table","predicate","meta","TABLE_META","inner","Object","keys","columns","node","outer","defineProperty","REF_TARGET","enumerable","configurable","quote","replace","PolicyBuilder","_def","command","roles","using","withCheck","permissive","for","to","memberOf","membershipTable","foreignKey","options","Error","column","userColumn","as","mode","policy","assertCheckNode","CHECK_BIN_OPS","literalSQL","Number","isFinite","String","checkNodeSQL","undefined","length","joiner","join","check","trim","can","def","Array","isArray","policies","prototype","hasOwnProperty","call","rel","reservedCanRelation","names","filter","Buffer","byteLength","all","hint","n","z","array","enum","tableName","b","entries","referencesThunk","selfRefColumn","reverseAs","forward","owns","refAs","endsWith","slice","GuardBuilder","_def","name","trim","Error","on","event","when","pred","expr","exists","table","predicate","exprCtx","existsIn","refuse","message","opts","detail","undefined","hint","column","toGuardDef","guard","b","def","backfill","name","sql","trim","Error","IndexBuilder","_def","name","trim","Error","unique","on","cols","columns","map","c","e","expr","kind","onExpression","expression","where","desc","sort","asc","nulls","include","index","toPolicyDef","p","PolicyBuilder","TABLE_META","Symbol","for","defineTable","input","reserved","reservedCanRelation","JSON","stringify","policies","exprCtx","Object","keys","rls","length","owned","colName","b","entries","builder","clone","create","getPrototypeOf","defineProperty","value","enumerable","writable","def","primaryKey","undefined","raw","slice","declaredChecks","checks","declaredIndexes","indexes","i","declaredFKs","foreignKeys","toForeignKeyDef","declaredFreezes","freeze","toFreezeDef","fz","join","declaredGuards","guards","toGuardDef","g","column","backfills","seen","Set","has","add","sql","dropConstraints","appendOnly","ignored","search","s","from","vector","model","Array","isArray","text","String","legs","leg","memory","values","ownerTable","handle","declaringSchemaOf","WeakMap","resolveReferences","tables","schemaName","table","qualifyRefTargets","selfRefColumn","references","qualifiedTableKey","referencesThunk","target","owner","targetColumn","find","targetSchema","get","defineSchema","set","m","t","into","subject","factCol","factDef","type","extensions","exposed","qualifyRefTargets","table","where","qualify","holder","what","target","REF_TARGET","undefined","targetSchema","declaringSchemaOf","get","Error","name","qualified","qualifiedTableKey","refTable","fk","foreignKeys","fz","freeze","g","guards","exists","qualifyExistsNodes","node","kind","v","Object","values","Array","isArray","e","CHANNELS","Symbol","for","ownerOnly","kind","publicChannel","opts","publish","state","paramCount","pattern","split","filter","s","startsWith","endsWith","length","defineChannels","map","entries","entry","Object","Error","push","c","authorize","handler","def","carrier","globalThis","existing","sameDeclaration","e","join","wireRow","JSON","stringify","read","write","toString","a","b","every","x","i","PALBASE_EXTENSIONS","EXTENSION_DEPENDENCIES","earthdistance","isPalbaseExtension","name","includes","CODECS","number","fromDb","v","Number","toDb","isSafeInteger","Error","String","tsType","decimal","undefined","refuseOnVector","def","modifier","type","ColumnBuilder","_def","existingDef","nullable","primaryKey","notNull","default","value","defaultValue","defaultRandom","defaultNow","dbAssigned","renamedFrom","previous","ignored","references","target","opts","referencesThunk","as","refAs","reverseAs","onDelete","onDeleteAction","index","counter","selfReferences","column","selfRefColumn","action","unique","asNumber","withCodec","asDecimal","codec","method","transform","fns","uuid","text","integer","bigint","numeric","boolean","timestamp","jsonb","enumType","name","values","builder","enumName","enumValues","vector","dimensions","isInteger","b","ownedByUser","table","owns","userRef","installationRef","raw","name","up","openai","embedding","model","opts","provider","apiKeyName","dimensions","undefined","baseURL","chat","SQLSTATE","Object","freeze","serializationFailure","deadlockDetected","queryCancelled","commandGuardFailed","isTransactionRollbackState","state","HTTP_ERROR_BRAND","Symbol","for","HttpError","Error","status","error","errorDescription","data","HTTP_ERROR_BRAND","name","undefined","toJSON","requestId","result","error_description","request_id","PalError","code","description","NamedHttpError","defaultCode","message","defaultMessage","spaced","replace","charAt","toUpperCase","slice","toLowerCase","BadRequest","Unauthorized","Forbidden","NotFound","Conflict","UniqueViolation","is","e","constraint","isRetryable","retryable","isTransactionRollbackState","sqlstate","SerializationFailure","SQLSTATE","serializationFailure","DeadlockDetected","deadlockDetected","TooManyRequests","makeTypedTable","name","raw","insert","data","aggregate","q","insertMany","rows","opts","put","onConflict","update","where","id","set","delete","findUnique","select","findById","page","findMany","updateMany","returning","undefined","deleteMany","count","makeTypedDB","schema","tables","key","Object","keys","tableDef","qualifiedTableKey","result","diagnostics","command","fn","options","builder","TxPlanBuilder","planTables","fromEntries","entries","map","table","runTxPlan","txPlan","plan","transaction","col","name","brandRef","$col","withRetry","fn","opts","budget","retryBudget","retry","attempt","e","isRetryable","sqlFragment","strings","values","$sql","text","defineRepository","table","opts","tenantColumn","tenant","rowKey","key","scope","scopeRow","id","scopedPayload","values","Repository","list","findMany","where","find","rows","limit","insert","update","patch","row","updateScoped","NotFound","String","updateMany","set","delete","deleteMany","DECLARATION_REFUSAL","Symbol","for","DeclarationRefused","Error","message","name","isDeclarationRefused","e","liveNames","names","Set","sort","memberName","name","test","JSON","stringify","members","length","map","n","join","bucketMembers","buckets","normalized","b","variants","byName","Map","set","keys","rows","get","union","v","stackInterfaceBody","secrets","flags","roles","makeStackDts","uniqueKeysOf","table","columns","inlinePrimary","keys","name","value","Object","entries","col","_def","primaryKey","push","unique","primary","length","unshift","key","seen","Set","filter","size","some","hasOwn","Error","identity","JSON","stringify","sort","has","add","baseTsType","def","codec","undefined","CODECS","tsType","type","values","enumValues","length","map","v","JSON","stringify","join","unhandled","Error","String","pgBrand","sort","rowType","base","branded","nullable","optionalOnInsert","defaultRandom","defaultNow","defaultValue","forwardName","column","endsWith","slice","describeOrigin","o","direction","table","renameCall","owns","target","references","selfRefColumn","buildRelations","schemas","out","Map","taken","schema","t","Object","tables","key","qualifiedTableKey","name","set","claim","tableKey","origin","edge","names","get","held","DeclarationRefused","heldFix","originFix","remedy","push","childKey","has","col","builder","entries","columns","_def","targetKey","refAs","to","kind","via","reverse","reverseAs","tableBlock","relations","indent","cols","rowLines","hasCanColumn","prototype","hasOwnProperty","call","some","r","canNames","policies","filter","p","command","permissive","Buffer","byteLength","canDoc","canLine","insertLines","opt","relEntries","uniqueKeysOf","b","search","appendOnly","refuseFreeFormTransforms","transform","where","ENV_BLOCK_START","ENV_BLOCK_END","STACK_BLOCK_START","STACK_BLOCK_END","EMPTY_STACK_NAMES","secrets","flags","buckets","roles","makeEnvDts","publicSchema","find","s","others","publicBlocks","keys","body","schemaBlocks","inner","schemasBody","stackInterfaceBody","ROUTES","Symbol","for","PARAM_BUFFER","ROOM","ROOM_HOOKS","RETURN_BUFFER","THROWS_BUFFER","carrierOf","target","ctor","ownRoutes","carrier","Object","prototype","hasOwnProperty","call","ownParamBuffer","recordRoute","fnName","method","subpath","options","routes","buffer","params","slice","sort","a","b","index","route","returnBuffer","undefined","returnSchema","throwsBuffer","throws","push","recordParam","meta","find","r","recordThrows","target","fnName","throws","carrier","carrierOf","routes","ROUTES","route","find","r","Object","prototype","hasOwnProperty","call","THROWS_BUFFER","throwsBuffer","getRoutes","ctor","returnBuffer","RETURN_BUFFER","buffered","returnSchema","undefined","map","params","slice","ownRoomBuffer","ROOM_HOOKS","hooks","messages","recordRoomHook","hook","buffer","existing","label","charAt","toUpperCase","Error","recordRoomMessage","name","schema","recordRoom","meta","ROOM","g","globalThis","REGISTRY","Symbol","for","all","includes","push","CONTROLLER_META","Symbol","for","REGISTRY","registry","g","globalThis","existing","fresh","getRegisteredControllers","slice","__resetRegisteredControllers","length","APP_DEFAULT_AUTH","appAuthSlot","defineDefaultAuth","auth","getDefaultAuth","__resetDefaultAuth","resolveEffectiveAuth","routeAuth","controllerAuth","RESERVED_FIRST_SEGMENT","assertNotReserved","path","subject","first","split","filter","Boolean","Error","Controller","basePath","options","ctor","route","getRoutes","subpath","method","carrier","meta","__palbase","undefined","defaultAuth","Object","defineProperty","value","enumerable","configurable","writable","all","includes","push","assertZeroArgConstructor","Ctrl","kind","arity","length","name","Error","makeMethodDecorator","method","subpath","options","Error","slice","toLowerCase","target","propertyKey","descriptor","verb","undefined","String","recordRoute","Get","Post","Put","Patch","Delete","Query","SHAPE","assertSurfaceName","name","decorator","kind","trim","Error","test","WEBHOOK_META","Symbol","for","WEBHOOK_EVENTS","carrierOf","ctor","Webhook","options","carrier","Object","defineProperty","value","enumerable","configurable","writable","On","event","target","fnName","existing","entries","push","String","getWebhookManifest","meta","validateWebhook","name","provider","secretEnv","secret","env","events","map","e","Error","assertSurfaceName","signature","sig","header","algo","encoding","signs","includes","timestampHeader","length","getWebhookConfig","container","instance","get","create","entry","prototype","hasOwnProperty","call","metaArg","Deny","Error","reason","name","HOOK_BLOCKING","Symbol","for","Hook","event","target","fnName","carrier","existing","entries","push","String","Object","defineProperty","value","enumerable","configurable","writable","bind","instance","kind","out","create","entry","prototype","hasOwnProperty","call","fn","meta","getHookConfig","ctor","container","blockingEntries","listenerEntries","WEBHOOK_EVENTS","length","get","blocking","listeners","getHookManifest","map","e","Upload","subpath","config","auth","rateLimit","uploadConfig","validateUploadConfigShape","options","undefined","target","propertyKey","recordRoute","String","UploadedObject","parameterIndex","recordParam","index","kind","c","Error","bucket","length","pathTemplate","Sse","subpath","config","auth","rateLimit","sseConfig","options","undefined","target","propertyKey","recordRoute","String","SseOut","parameterIndex","recordParam","index","kind","Signal","DEFAULT_GRACE_MS","assertPattern","pattern","includes","Error","replace","segments","split","some","s","seen","Set","startsWith","endsWith","name","slice","has","add","Room","options","ctor","recordRoom","events","graceMs","hookDecorator","hook","target","propertyKey","recordRoomHook","String","OnAuthorize","OnFirst","OnJoin","OnLeave","OnEmpty","OnMessage","schema","recordRoomMessage","makeParamDecorator","kind","extra","target","propertyKey","parameterIndex","recordParam","String","index","schema","undefined","name","Body","QueryParams","Headers","Param","User","OptionalUser","Client","RequestId","TraceId","Req","defineMiddleware","_fn","Error","import_zod","extendZodWithOpenApi","z","ERROR_REGISTRY","Symbol","for","BUILTIN_DATA_SCHEMAS","bad_request","object","fields","array","field","string","message","too_many_requests","retryAfter","number","int","getErrorRegistry","g","globalThis","m","Map","code","status","className","dataSchema","set","builtin","dataDigest","digestOf","defineError","Number","isInteger","Error","registry","existing","get","defaultClassName","undefined","sameShape","makeWithData","schema","HttpError","data","humanize","parse","name","makeWithoutData","cls","Object","defineProperty","value","TMP_REF","tmpRegistry","OpenAPIRegistry","register","openapi","generated","OpenApiGeneratorV31","definitions","generateComponents","out","components","schemas","digest","JSON","stringify","includes","split","map","p","charAt","toUpperCase","slice","join","s","replace","DI_INJECTABLES","Symbol","for","INJECTABLE","isInjectable","c","slot","g","globalThis","Injectable","target","push","__claimInjectables","splice","JOB","Symbol","for","WEBHOOK","HOOK_BLOCKING","HOOK_LISTENERS","ROOM","CONTROLLER","has","c","s","undefined","isEntryPointClass","owned","container","jobsOf","filter","webhooksOf","hooksOf","roomsOf","controllersOf","DI_MODULES","Symbol","for","slot","g","globalThis","Module","def","target","push","mod","__claimModules","splice","DiError","Error","DECLARATION_REFUSAL","kind","path","at","detail","fixes","length","join","map","f","name","nameOf","c","String","UNRESOLVABLE","Set","Object","Function","Number","Boolean","Array","Symbol","Promise","Date","undefined","DATA","declaresDependencies","ctor","arity","meta","Reflect","getMetadata","buildContainer","entries","__claimModules","declared","__claimInjectables","declaredModules","e","mod","owner","Map","def","m","providers","controllers","prev","get","set","p","isInjectable","isEntryPointClass","orphans","filter","has","names","exported","importsOf","exports","holder","i","imports","deps","implementorsOf","t","keys","prototype","isPrototypeOf","call","withArity","missingMeta","cls","list","forEach","dep","dm","impls","impl","push","sort","state","stack","walk","cyc","slice","indexOf","d","pop","cache","make","hit","args","inst","owned","pressure","computePressure","total","count","n","module","pct","Math","round","of","a","b","assertNoOrphanEntryPoints","registered","validateCronExpression","expression","trimmed","trim","parts","split","length","fieldNames","fieldRanges","i","field","name","min","max","error","validateCronField","listParts","part","stepParts","base","step","undefined","stepNum","Number","isInteger","includes","rangeParts","rangeStart","rangeEnd","num","DEFAULT_TIMEOUT_SECONDS","MAX_TIMEOUT_SECONDS","DEFAULT_RETRY","MAX_RETRY","JOB_META","Symbol","for","Job","options","ctor","carrier","Object","defineProperty","value","enumerable","configurable","writable","getJobManifest","meta","Error","name","assertSurfaceName","schedule","trim","cronError","validateCronExpression","timeout","Number","isInteger","retry","getJobConfig","container","instance","get","run","bind","handler","import_zod"]}
|