@fitzzero/quickdraw-core 5.1.1 → 5.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +533 -180
- package/dist/{admin-DKwkIh5i.d.ts → admin-DWWrT1h6.d.ts} +2 -2
- package/dist/{adminSchemas-2DUA_hZ8.d.ts → adminSchemas-D4bFKsrb.d.ts} +6 -4
- package/dist/{auth-BhWqdyb-.d.ts → auth-DXiSJZaf.d.ts} +42 -16
- package/dist/{caller-CXTFswBO.d.ts → caller-BT-Mv4bD.d.ts} +117 -22
- package/dist/{chunk-RT6OILOI.js → chunk-4D2DOGAW.js} +2 -14
- package/dist/chunk-4D2DOGAW.js.map +1 -0
- package/dist/chunk-5CGO426C.js +15 -0
- package/dist/chunk-5CGO426C.js.map +1 -0
- package/dist/{chunk-RZTP4IEW.js → chunk-6K5BY47X.js} +4594 -3481
- package/dist/chunk-6K5BY47X.js.map +1 -0
- package/dist/{chunk-VSQBHPWH.js → chunk-753VJIUP.js} +13 -15
- package/dist/chunk-753VJIUP.js.map +1 -0
- package/dist/{chunk-ZIVPHYRG.js → chunk-7QCUX4TK.js} +4 -4
- package/dist/chunk-7QCUX4TK.js.map +1 -0
- package/dist/chunk-AK23XSWD.js +16 -0
- package/dist/chunk-AK23XSWD.js.map +1 -0
- package/dist/{chunk-SHEGLZEP.js → chunk-AONAFOYU.js} +14 -5
- package/dist/{chunk-SHEGLZEP.js.map → chunk-AONAFOYU.js.map} +1 -1
- package/dist/chunk-DKE6QO26.js +136 -0
- package/dist/chunk-DKE6QO26.js.map +1 -0
- package/dist/{chunk-H23KEFBA.js → chunk-DUBU3BB3.js} +30 -1
- package/dist/chunk-DUBU3BB3.js.map +1 -0
- package/dist/{chunk-CDKG4TFA.js → chunk-GKH3LJ7N.js} +1 -1
- package/dist/chunk-GKH3LJ7N.js.map +1 -0
- package/dist/{chunk-OECZPRPW.js → chunk-GSIPUNJL.js} +49 -9
- package/dist/chunk-GSIPUNJL.js.map +1 -0
- package/dist/{chunk-DD4SKCNO.js → chunk-LCC7HNFP.js} +12 -1
- package/dist/chunk-LCC7HNFP.js.map +1 -0
- package/dist/{chunk-2PWMUVC7.js → chunk-MBH6IDSM.js} +480 -12
- package/dist/chunk-MBH6IDSM.js.map +1 -0
- package/dist/{chunk-QCHKWIRS.js → chunk-NMXYENH4.js} +10 -10
- package/dist/{chunk-QCHKWIRS.js.map → chunk-NMXYENH4.js.map} +1 -1
- package/dist/chunk-NO4M6PO5.js +101 -0
- package/dist/chunk-NO4M6PO5.js.map +1 -0
- package/dist/{chunk-TBMKJ26R.js → chunk-NW6U45HX.js} +3 -1
- package/dist/chunk-NW6U45HX.js.map +1 -0
- package/dist/{chunk-REX5YPHX.js → chunk-RJ5I2VO3.js} +74 -19
- package/dist/chunk-RJ5I2VO3.js.map +1 -0
- package/dist/{chunk-QEKVYG5F.js → chunk-RL4VKLBX.js} +1 -1
- package/dist/{chunk-QEKVYG5F.js.map → chunk-RL4VKLBX.js.map} +1 -1
- package/dist/chunk-XH2IZVLT.js +62 -0
- package/dist/chunk-XH2IZVLT.js.map +1 -0
- package/dist/{chunk-4DIQHASK.js → chunk-Z5ILULF2.js} +26 -7
- package/dist/chunk-Z5ILULF2.js.map +1 -0
- package/dist/cli/quickdraw-docs.js +5 -3
- package/dist/cli/quickdraw-docs.js.map +1 -1
- package/dist/client/index.d.ts +30 -18
- package/dist/client/index.js +8 -6
- package/dist/client/index.js.map +1 -1
- package/dist/{clientTypes-Bc-G8n-U.d.ts → clientTypes-hWcPUVS9.d.ts} +3 -3
- package/dist/{connection-Cr1BU07W.d.ts → connection-CgijdGpT.d.ts} +8 -4
- package/dist/{createServer-CP9eDHZZ.d.ts → createServer-Cp-Wk500.d.ts} +36 -14
- package/dist/{createTestApp-UKVGEmOf.d.ts → createTestApp-BB_PkqQ7.d.ts} +16 -10
- package/dist/{envelope-Cp3YcVxC.d.ts → envelope-DzWyIXjj.d.ts} +18 -4
- package/dist/{http-Djj2Inuu.d.ts → http-DotQ5bj8.d.ts} +68 -17
- package/dist/index.d.ts +7 -7
- package/dist/index.js +37 -13
- package/dist/index.js.map +1 -1
- package/dist/{infer-Teo1xpsd.d.ts → infer-BmoZsL9a.d.ts} +43 -10
- package/dist/logger-Yz93KzdV.d.ts +30 -0
- package/dist/{metrics-BdBu5o8G.d.ts → metrics-DW80Exve.d.ts} +2 -2
- package/dist/origins-kvpxnVcW.d.ts +8 -0
- package/dist/prisma/index.d.ts +5 -5
- package/dist/prisma/index.js +130 -67
- package/dist/prisma/index.js.map +1 -1
- package/dist/{rateLimit-ZMIZJUZF.js → rateLimit-5RKBFLUR.js} +2 -2
- package/dist/server/auth/index.d.ts +82 -33
- package/dist/server/auth/index.js +273 -268
- package/dist/server/auth/index.js.map +1 -1
- package/dist/server/express/index.d.ts +9 -2
- package/dist/server/express/index.js +1 -1
- package/dist/server/index.d.ts +147 -67
- package/dist/server/index.js +520 -381
- package/dist/server/index.js.map +1 -1
- package/dist/server/mcp/index.d.ts +63 -17
- package/dist/server/mcp/index.js +256 -54
- package/dist/server/mcp/index.js.map +1 -1
- package/dist/server/otel.d.ts +3 -3
- package/dist/{sharing-DVa8W-yR.d.ts → sharing-UDLn1049.d.ts} +3 -3
- package/dist/testing/client.d.ts +14 -14
- package/dist/testing/client.js +9 -7
- package/dist/testing/client.js.map +1 -1
- package/dist/testing/index.d.ts +12 -12
- package/dist/testing/index.js +21 -12
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/mock.d.ts +5 -5
- package/dist/testing/mock.js +8 -6
- package/dist/{types-Cu0vmx7c.d.ts → types-CYliTP65.d.ts} +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-2PWMUVC7.js.map +0 -1
- package/dist/chunk-4DIQHASK.js.map +0 -1
- package/dist/chunk-CDKG4TFA.js.map +0 -1
- package/dist/chunk-DD4SKCNO.js.map +0 -1
- package/dist/chunk-H23KEFBA.js.map +0 -1
- package/dist/chunk-OECZPRPW.js.map +0 -1
- package/dist/chunk-REX5YPHX.js.map +0 -1
- package/dist/chunk-RT6OILOI.js.map +0 -1
- package/dist/chunk-RZTP4IEW.js.map +0 -1
- package/dist/chunk-TBMKJ26R.js.map +0 -1
- package/dist/chunk-VSQBHPWH.js.map +0 -1
- package/dist/chunk-YSWH776Y.js +0 -13
- package/dist/chunk-YSWH776Y.js.map +0 -1
- package/dist/chunk-ZIVPHYRG.js.map +0 -1
- package/dist/logger-BY28acW-.d.ts +0 -16
- /package/dist/{rateLimit-ZMIZJUZF.js.map → rateLimit-5RKBFLUR.js.map} +0 -0
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/access/rowless.ts","../../src/server/collections/define.ts","../../src/server/realtime/define.ts","../../src/server/serviceData.ts","../../src/server/buildService.ts","../../src/server/init.ts","../../src/server/access/policies/owner.ts","../../src/server/access/policies/jsonAcl.ts","../../src/server/access/policies/inherit.ts","../../src/server/access/policies/everyone.ts","../../src/server/kits/rowless.ts","../../src/server/kits/crud/access.ts","../../src/server/kits/columns.ts","../../src/server/kits/transactions.ts","../../src/server/kits/crud/runtime.ts","../../src/server/kits/guards.ts","../../src/server/kits/crud/update.ts","../../src/server/kits/crud/bulk.ts","../../src/server/kits/crud/create.ts","../../src/server/kits/crud/delete.ts","../../src/server/kits/crud/get.ts","../../src/server/kits/crud/getMany.ts","../../src/server/kits/crud/listQuery.ts","../../src/server/kits/crud/page.ts","../../src/server/kits/crud/list.ts","../../src/server/kits/crud/ordinal.ts","../../src/server/kits/crud/reorder.ts","../../src/server/kits/crud/methods.ts","../../src/server/kits/crud/handlers.ts","../../src/server/kits/search/filters.ts","../../src/server/kits/search/results.ts","../../src/server/kits/search/pages.ts","../../src/server/kits/search/run.ts","../../src/server/kits/search/handlers.ts","../../src/server/kits/sharing/aclList.ts","../../src/server/kits/sharing/policy.ts","../../src/server/kits/sharing/roles.ts","../../src/server/kits/sharing/runtime.ts","../../src/server/kits/sharing/admins.ts","../../src/server/kits/sharing/checks.ts","../../src/server/kits/sharing/context.ts","../../src/server/kits/sharing/acl.ts","../../src/server/kits/sharing/listMembers.ts","../../src/server/kits/sharing/members.ts","../../src/server/kits/sharing/methods.ts","../../src/server/kits/sharing/handlers.ts","../../src/server/kits/admin/meta.ts","../../src/server/kits/admin/runtime.ts","../../src/server/kits/admin/list.ts","../../src/server/kits/admin/live.ts","../../src/server/kits/admin/writes.ts","../../src/server/kits/admin/rows.ts","../../src/server/kits/admin/methods.ts","../../src/server/kits/admin/handlers.ts","../../src/server/redisPeers.ts","../../src/server/redis.ts","../../src/server/utils/env.ts","../../src/server/utils/encryption.ts"],"sourcesContent":["// The rowless check, run by `defineService`. On a service with an access\n// policy (RFC 0003 section 4.2), a method whose input has `id` reads or\n// writes the row that id names. A form that checks the caller's level on no\n// row, `\"public\"`, `\"authenticated\"` or `{ service: L }` with `L` below\n// `Admin`, hands that row to anyone the form admits, whoever's row it is:\n// 4.x's \"a Read method with no row id is open to every signed-in user\", in\n// 5.0's spelling. Such a method is refused when it is defined, naming the\n// two ways out: a form that asks the policy (`{ entry: L }`, or `{ service:\n// L, entry: L }` to keep the grant), or `rowless: true` on the method, which\n// says every caller the form admits may reach any row on purpose (public\n// profiles, lookups by an id that tells nothing).\n//\n// The input's keys come from its Standard JSON Schema (`inputKeys`): the\n// top-level keys of every object the input may be, so `id` in any branch of a\n// union counts, with values JSON Schema cannot write (a `Date`, a `Set`, a\n// `bigint`, a custom type) read as any value. Not checked: an input without\n// JSON Schema (a Zod 3 schema), which cannot say whether it holds an `id`; an\n// input that is no object (a bare string that is the id itself, an array, a\n// record); and a row named another way (`ids`, `taskId`, a nested\n// `where.id`). `custom` forms decide for themselves, and so do the kit\n// handlers that check the row whatever their form (`checksRowsItself`).\n\nimport { inputKeys } from \"../emit/projection\";\nimport { isKitHandler, isRowChecked, type ServiceMethod } from \"../service\";\nimport { isCustomAccess } from \"./forms\";\nimport type { AccessForm } from \"./types\";\n\n/** The forms that check the caller's level on no row: `\"public\"`, `\"authenticated\"`, `{ service: L }` below `Admin`. */\nfunction checksNoRow(form: AccessForm): boolean {\n if (form === \"public\" || form === \"authenticated\") {\n return true;\n }\n return (\n typeof form === \"object\" &&\n !isCustomAccess(form) &&\n form.entry === undefined &&\n form.scope === undefined &&\n form.service !== undefined &&\n form.service !== \"Admin\"\n );\n}\n\n/** A form that checks no row as code, and who it lets reach every row, for the message. */\nfunction described(form: AccessForm): { readonly code: string; readonly who: string } {\n if (form === \"public\") {\n return { code: '\"public\"', who: \"anyone, signed in or not,\" };\n }\n if (form === \"authenticated\") {\n return { code: '\"authenticated\"', who: \"every signed-in user\" };\n }\n const level = typeof form === \"object\" && !isCustomAccess(form) ? form.service : undefined;\n return {\n code: `{ service: \"${String(level)}\" }`,\n who: `everyone with a service-wide ${String(level)} grant`,\n };\n}\n\n/** The form to suggest instead: the policy's check at the method's level, keeping a named grant. */\nfunction suggestion(method: ServiceMethod): string {\n const { access } = method;\n if (typeof access === \"object\" && !isCustomAccess(access) && access.service !== undefined) {\n return `{ service: \"${access.service}\", entry: \"${access.service}\" }`;\n }\n return `{ entry: \"${method.kind === \"query\" ? \"Read\" : \"Moderate\"}\" }`;\n}\n\n/**\n * Why `method`, on a service with an access policy, must not be defined as\n * it is: its input has `id` and its form checks no row, and it did not say\n * `rowless: true`. `undefined` when it may.\n */\nexport function rowlessProblem(method: ServiceMethod): string | undefined {\n const { access, handler } = method;\n if (method.rowless || !checksNoRow(access) || isRowChecked(handler)) {\n return undefined;\n }\n if (inputKeys(method.input)?.includes(\"id\") !== true) {\n return undefined;\n }\n const optOut = isKitHandler(handler)\n ? `name it in the kit's rowless option (rowless: [\"${method.name}\"])`\n : \"set rowless: true on the method\";\n const form = described(access);\n return (\n `method \"${method.name}\" takes a row id (its input has id), but its access ${form.code} checks no row: ` +\n `on a service with an access policy, that lets ${form.who} reach any row by its id. ` +\n `Give it ${suggestion(method)} so the policy decides, or, if every caller its access admits may reach any row, ${optOut}`\n );\n}\n","// Collections as a service defines them (RFC 0003 section 7.1). The contract\n// declares what a collection is: its scope column or junction, its item\n// projection, its membership filter, its order, its page sizes and its index.\n// The service adds what a contract cannot carry, because access policies live\n// on the server: the contract whose rows the scope values are ids of\n// (`anchor`), or `scopeAccess: \"self\"` for a scope whose value is the\n// subscriber's own user id; and the `bulkThreshold` past which one flush's\n// changes to a scope go out as a single `reset`. Every collection of the\n// contract needs one or the other, so a scope nobody could authorize fails\n// when the service is defined rather than when a client subscribes. A\n// `\"self\"` scope is stripped at `Read` and may not declare a higher\n// `access`, since no level is checked to subscribe to it. The\n// index fields are checked here too, against the item projection only the\n// service compiles: a contract cannot see a schema's keys. No order column\n// may sit above the collection's `access` in the contract's `fields`, since\n// cursors carry order columns' values.\n//\n// 4.1 defined a collection with functions (`resolveScopeId`,\n// `checkScopeAccess`, `snapshot`, `toItem`;\n// 4.1 `src/server/collections.ts:36-72`), so the framework could not know\n// which writes move a row and read the whole row before every update.\n\nimport type { AccessLevel } from \"../../contract/access\";\nimport {\n DEFAULT_COLLECTION_LIMIT,\n DEFAULT_COLLECTION_MAX_LIMIT,\n type CollectionDef,\n type CollectionWhere,\n type OrderBy,\n} from \"../../contract/collections\";\nimport type { AnyContract } from \"../../contract/defineContract\";\nimport { meetsLevel } from \"../access/levels\";\nimport type { Projection } from \"../emit/projection\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\n/** How many changed rows of one scope a flush sends as deltas; past it, one `reset` instead. */\nexport const DEFAULT_BULK_THRESHOLD = 200;\n\n/** Where a collection's scope value comes from: a column of the row, or a junction table. */\nexport type CollectionScope =\n | { readonly kind: \"column\"; readonly column: string }\n | {\n readonly kind: \"via\";\n /** The junction model, as the client names it. */\n readonly model: string;\n /** The junction column holding the row's id. */\n readonly entry: string;\n /** The junction column holding the scope value. */\n readonly scope: string;\n /** A junction write sends its entry again to every scope that still holds it (`via`'s `refreshEntry`). */\n readonly refreshEntry: boolean;\n };\n\n/** One collection of a service: its contract declaration and the service's option, checked. */\nexport interface ServiceCollection {\n readonly name: string;\n readonly scope: CollectionScope;\n /** The item projection, compiled with the service's `project` option. */\n readonly item: Projection;\n /** The membership filter; empty when the collection declares none. */\n readonly where: CollectionWhere;\n readonly order: OrderBy;\n /** The page size of a snapshot that asks for none. */\n readonly limit: number;\n /** The largest page a snapshot may ask for. */\n readonly maxLimit: number;\n /** The level a subscriber needs on the scope's anchor row. */\n readonly access: AccessLevel;\n /** The contract of the rows scope values are ids of; `undefined` for a `\"self\"` scope. */\n readonly anchor: AnyContract | undefined;\n /** More changed rows than this for one scope in one flush go out as one `reset`. */\n readonly bulkThreshold: number;\n /**\n * The item fields every member's index row holds (RFC 0003 section 7.4),\n * in the order the contract declares them; `undefined` without an index.\n */\n readonly index: readonly string[] | undefined;\n}\n\nconst OPTION_KEYS: ReadonlySet<string> = new Set([\"anchor\", \"scopeAccess\", \"bulkThreshold\"]);\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isContract(value: unknown): value is AnyContract {\n return (\n isRecord(value) &&\n typeof value.name === \"string\" &&\n value.name.length > 0 &&\n Object.isFrozen(value)\n );\n}\n\ninterface CheckedOption {\n readonly anchor: AnyContract | undefined;\n readonly bulkThreshold: number;\n}\n\n/** One entry of the service's `collections` option, checked. */\nfunction checkOption(owner: string, option: unknown, fail: Fail): CheckedOption {\n if (!isRecord(option)) {\n fail(`${owner} must be { anchor: contract } or { scopeAccess: \"self\" }`);\n }\n const unknownKey = Object.keys(option).find((key) => !OPTION_KEYS.has(key));\n if (unknownKey !== undefined) {\n fail(\n `${owner} has an unknown option \"${unknownKey}\"; the options are anchor, scopeAccess and bulkThreshold`,\n );\n }\n const { anchor, scopeAccess, bulkThreshold = DEFAULT_BULK_THRESHOLD } = option;\n if ((anchor === undefined) === (scopeAccess === undefined)) {\n fail(\n `${owner} needs exactly one of anchor (the contract whose rows its scope values are ids of) and scopeAccess: \"self\"`,\n );\n }\n if (anchor !== undefined && !isContract(anchor)) {\n fail(`${owner}: anchor must be a contract from defineContract`);\n }\n if (scopeAccess !== undefined && scopeAccess !== \"self\") {\n fail(\n `${owner}: scopeAccess must be \"self\", for a scope whose value is the subscriber's user id`,\n );\n }\n if (\n typeof bulkThreshold !== \"number\" ||\n !Number.isSafeInteger(bulkThreshold) ||\n bulkThreshold < 1\n ) {\n fail(`${owner}: bulkThreshold must be a positive whole number`);\n }\n return { anchor: anchor as AnyContract | undefined, bulkThreshold };\n}\n\n/**\n * The collection's index fields, checked against its item (RFC 0003 sections\n * 2 and 7.4): each is a key of the item projection other than `id`, named\n * once, and one the collection's items carry, so not reserved by the\n * contract's `fields` for a level above the collection's `access`. An index\n * row holds what its item holds, nothing more. Every `order` column but `id`\n * is an index field, so a client can keep the index in order as deltas\n * arrive. `views` read index rows, so a collection with views needs an index.\n */\nfunction checkIndex(\n name: string,\n def: CollectionDef,\n item: Projection,\n access: AccessLevel,\n fail: Fail,\n): readonly string[] | undefined {\n const { index, views } = def;\n if (index === undefined) {\n if (views !== undefined) {\n fail(`collection \"${name}\" declares views but no index; views read index rows`);\n }\n return undefined;\n }\n if (!Array.isArray(index) || !index.every((field) => typeof field === \"string\")) {\n fail(`collection \"${name}\": index must be a list of item field names`);\n }\n const owner = `collection \"${name}\": index field`;\n const hidden = item.tiers.hidden(access);\n for (const [position, field] of index.entries()) {\n if (field === \"id\") {\n fail(`${owner} \"id\" is not needed; every index row starts with the member's id`);\n }\n if (!item.keys.includes(field)) {\n fail(\n `${owner} \"${field}\" is not a key of its item \"${item.name}\"; index fields are item fields`,\n );\n }\n if (hidden.has(field)) {\n fail(\n `${owner} \"${field}\" is reserved by the contract's fields for a level above the collection's access (${access}), so its items never carry it`,\n );\n }\n if (index.indexOf(field) !== position) {\n fail(`${owner} \"${field}\" is named twice`);\n }\n }\n checkIndexOrder(name, def.order, index, fail);\n return Object.freeze([...index]);\n}\n\n/**\n * No `order` column may be reserved by the contract's `fields` for a level\n * above the collection's `access`, index or not: a page's cursor carries\n * the last row's value of every order column, and the page's order tells\n * how the rows' values compare, so either would hand a subscriber the field.\n */\nfunction checkOrderTiers(\n name: string,\n order: OrderBy,\n fields: Readonly<Record<string, AccessLevel>>,\n access: AccessLevel,\n fail: Fail,\n): void {\n for (const [column] of order) {\n const required = Object.hasOwn(fields, column) ? fields[column] : undefined;\n if (required !== undefined && !meetsLevel(access, required)) {\n fail(\n `collection \"${name}\": order column \"${column}\" is reserved by the contract's fields for ${required}, above the collection's access (${access}); a page's cursor and order would tell its subscribers what it holds`,\n );\n }\n }\n}\n\n/** Every order column but `id` must be an index field: a client keeps the index in order by them. */\nfunction checkIndexOrder(name: string, order: OrderBy, index: readonly string[], fail: Fail): void {\n const missing = order.map(([column]) => column).find((c) => c !== \"id\" && !index.includes(c));\n if (missing !== undefined) {\n fail(\n `collection \"${name}\": order column \"${missing}\" is not an index field; a client keeps the index in order by it`,\n );\n }\n}\n\n/**\n * The level a collection's subscribers need on its anchor row, which its\n * items are also stripped at: its `access`, `Read` by default. A `\"self\"`\n * scope is authorized by the subscriber's own user id, never by a level, so\n * its items are stripped at `Read` and it may not declare more: a higher\n * `access` would hand every subscriber that level's fields of the rows in\n * their own scope.\n */\nfunction accessOf(\n name: string,\n def: CollectionDef,\n anchor: AnyContract | undefined,\n fail: Fail,\n): AccessLevel {\n if (anchor !== undefined) {\n return def.access ?? \"Read\";\n }\n if (def.access !== undefined && meetsLevel(def.access, \"Moderate\")) {\n fail(\n `collection \"${name}\" has scopeAccess \"self\", which is authorized by the subscriber's user id and not by a level, so its access may not be above Read (it declares ${def.access})`,\n );\n }\n return \"Read\";\n}\n\nfunction scopeOf(def: CollectionDef): CollectionScope {\n const { scope } = def;\n if (typeof scope === \"string\") {\n return Object.freeze({ kind: \"column\", column: scope });\n }\n return Object.freeze({\n kind: \"via\",\n model: scope.model,\n entry: scope.entry,\n scope: scope.scope,\n refreshEntry: scope.refreshEntry === true,\n });\n}\n\nfunction compileOne(\n [name, def]: readonly [string, CollectionDef],\n contract: Pick<AnyContract, \"fields\">,\n projections: ReadonlyMap<string, Projection>,\n option: unknown,\n fail: Fail,\n): ServiceCollection {\n if (option === undefined) {\n fail(\n `collection \"${name}\" needs its scope's access: collections: { ${name}: { anchor: contract } }, or { scopeAccess: \"self\" } for a scope that is the subscriber's user id`,\n );\n }\n const { anchor, bulkThreshold } = checkOption(`collections.${name}`, option, fail);\n const item = projections.get(def.item);\n if (item === undefined) {\n fail(`collection \"${name}\": item \"${def.item}\" is not a projection of the contract`);\n }\n const access = accessOf(name, def, anchor, fail);\n checkOrderTiers(name, def.order, contract.fields, access, fail);\n return Object.freeze({\n name,\n scope: scopeOf(def),\n item,\n where: Object.freeze({ ...def.where }),\n order: def.order,\n limit: def.limit ?? DEFAULT_COLLECTION_LIMIT,\n maxLimit: def.maxLimit ?? DEFAULT_COLLECTION_MAX_LIMIT,\n access,\n anchor,\n bulkThreshold,\n index: checkIndex(name, def, item, access, fail),\n });\n}\n\n/**\n * Compiles the contract's collections with the service's `collections`\n * option. Fails, through `fail`, for a collection without an entry, an entry\n * naming no collection, a malformed entry, and collections on a service\n * without a model.\n */\nexport function compileCollections(\n contract: AnyContract,\n projections: ReadonlyMap<string, Projection>,\n model: string | undefined,\n option: unknown,\n fail: Fail,\n): ReadonlyMap<string, ServiceCollection> {\n if (option !== undefined && !isRecord(option)) {\n fail(\n 'collections must map each collection of the contract to { anchor } or { scopeAccess: \"self\" }',\n );\n }\n const options = option ?? {};\n const unknownName = Object.keys(options).find(\n (name) => !Object.hasOwn(contract.collections, name),\n );\n if (unknownName !== undefined) {\n fail(`collections names \"${unknownName}\", which is not a collection of the contract`);\n }\n const declared = Object.entries(contract.collections);\n if (declared.length > 0 && model === undefined) {\n fail(\"collections need model: their items are rows of the service's model\");\n }\n const compiled = new Map<string, ServiceCollection>();\n for (const [name, def] of declared) {\n compiled.set(name, compileOne([name, def], contract, projections, options[name], fail));\n }\n return compiled;\n}\n","// The run-time half of `defineService`'s channels and streams (RFC 0003\n// section 12.5): one handler per channel of the contract, no more and no\n// fewer, with its access; each stream's access form as the access engine\n// decides it; and the service's own stream options (a seed computed when a\n// socket subscribes). The types make the same checks; these catch\n// JavaScript callers and casts when the service is defined.\n\nimport { isAccessLevel } from \"../../contract/access\";\nimport type { AnyContract } from \"../../contract/defineContract\";\nimport { reservedRoomPrefix } from \"../../contract/names\";\nimport {\n CHANNEL_DEFAULT_RATE,\n isScopedStream,\n type ChannelDef,\n type PayloadSelector,\n type RoomPrefix,\n type RoomSelector,\n type StreamAccess,\n type StreamDef,\n} from \"../../contract/realtime\";\nimport type { AccessForm } from \"../access/types\";\nimport type {\n AnyChannelHandler,\n AnyStreamSeed,\n ChannelAccess,\n CompiledSelector,\n ServiceChannel,\n ServiceStream,\n StreamRoomAccess,\n} from \"./types\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** A payload key, or a function of the payload, as a function that returns a non-empty string or nothing. */\nfunction compileSelector(selector: PayloadSelector): CompiledSelector {\n const read =\n typeof selector === \"function\"\n ? (selector as (payload: unknown) => unknown)\n : (payload: unknown) => (isRecord(payload) ? payload[selector] : undefined);\n return (payload) => {\n try {\n const value = read(payload);\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n } catch {\n // A selector that throws names nothing: the message is dropped.\n return undefined;\n }\n };\n}\n\n/**\n * The app room a message must come from: a fixed name (checked when the\n * contract was defined), or a function of the payload whose answer names no\n * room when it is not a string, is empty or is reserved (`qd:`, `user:`),\n * since a socket is never in such a room as an app room.\n */\nfunction compileRoom(room: Exclude<RoomSelector, RoomPrefix>): CompiledSelector {\n if (typeof room === \"string\") {\n return () => room;\n }\n const computed = compileSelector(room);\n return (payload) => {\n const name = computed(payload);\n return name === undefined || reservedRoomPrefix(name) !== undefined ? undefined : name;\n };\n}\n\nfunction compileRequires(def: ChannelDef): ServiceChannel[\"requires\"] {\n const { requires } = def;\n if (requires === undefined) {\n return undefined;\n }\n const { room } = requires;\n if (typeof room === \"object\") {\n return { kind: \"roomPrefix\", prefix: room.prefix };\n }\n if (room !== undefined) {\n return { kind: \"room\", select: compileRoom(room) };\n }\n if (requires.collection === undefined) {\n return { kind: \"entity\", select: compileSelector(requires.entity) };\n }\n return {\n kind: \"collection\",\n collection: requires.collection,\n select: compileSelector(requires.scope),\n };\n}\n\nfunction checkChannelAccess(owner: string, access: unknown, fail: Fail): ChannelAccess {\n if (access === undefined || access === \"authenticated\") {\n return \"authenticated\";\n }\n const keys = isRecord(access) ? Object.keys(access) : [];\n if (!isRecord(access) || keys.length !== 1 || !isAccessLevel(access.service)) {\n fail(`${owner}: access must be \"authenticated\" or { service: level }`);\n }\n return Object.freeze({ service: access.service });\n}\n\nfunction checkChannel(\n service: string,\n name: string,\n def: ChannelDef,\n entry: unknown,\n kinds: ReadonlySet<string> | undefined,\n fail: Fail,\n): ServiceChannel {\n const owner = `channel \"${name}\"`;\n const implementation = typeof entry === \"function\" ? { handler: entry } : entry;\n if (!isRecord(implementation) || typeof implementation.handler !== \"function\") {\n fail(`${owner} must be a handler function or { access, handler }`);\n }\n const unknownKey = Object.keys(implementation).find(\n (key) => ![\"access\", \"handler\"].includes(key),\n );\n if (unknownKey !== undefined) {\n fail(`${owner} has an unknown option \"${unknownKey}\"; the options are access, handler`);\n }\n const ratePerSecond = def.ratePerSecond ?? CHANNEL_DEFAULT_RATE;\n return Object.freeze({\n service,\n name,\n payload: def.payload,\n ratePerSecond,\n // At least one token, so a slow channel (0.2 a second) still lets a message through.\n burst: def.burst ?? Math.max(1, ratePerSecond * 2),\n requires: compileRequires(def),\n access: checkChannelAccess(owner, implementation.access, fail),\n kinds,\n handler: implementation.handler as AnyChannelHandler,\n });\n}\n\n/**\n * The channels of a service: `defineService`'s `channels` option checked\n * against the contract's channels, one implementation each, with the kinds\n * of principal the service admits (`undefined`: every kind) as a set.\n */\nexport function compileChannels(\n contract: AnyContract,\n value: unknown,\n kinds: readonly string[] | undefined,\n fail: Fail,\n): ReadonlyMap<string, ServiceChannel> {\n const declared = Object.entries(contract.channels);\n if (value === undefined && declared.length === 0) {\n return new Map();\n }\n if (!isRecord(value)) {\n fail(\"channels must be an object with one implementation per contract channel\");\n }\n const missing = declared.filter(([name]) => !Object.hasOwn(value, name)).map(([name]) => name);\n if (missing.length > 0) {\n fail(`channels has no implementation for ${missing.map((name) => `\"${name}\"`).join(\", \")}`);\n }\n const channels = new Map<string, ServiceChannel>();\n const admitted = kinds === undefined ? undefined : new Set(kinds);\n for (const [name, entry] of Object.entries(value)) {\n const def = Object.hasOwn(contract.channels, name) ? contract.channels[name] : undefined;\n if (def === undefined) {\n fail(`\"${name}\" is not a channel of the contract`);\n }\n channels.set(name, checkChannel(contract.name, name, def, entry, admitted, fail));\n }\n return channels;\n}\n\n/** A stream's access as the engine decides it: the scope is the row id an entry or scope form checks. */\nfunction engineForm(access: StreamAccess | undefined): AccessForm | undefined {\n if (access === undefined || typeof access === \"string\") {\n return access;\n }\n if (access.room !== undefined) {\n // The app room the subscriber's socket is in decides, not the engine.\n return undefined;\n }\n if (access.scope !== undefined) {\n return Object.freeze({ scope: access.scope, of: access.of, id: \"scope\" });\n }\n if (access.entry !== undefined) {\n const service = access.service === undefined ? {} : { service: access.service };\n return Object.freeze({ entry: access.entry, ...service, id: \"scope\" });\n }\n return Object.freeze({ service: access.service });\n}\n\n/** A stream's `access: { room }`, compiled; `undefined` for any other form. */\nfunction roomAccess(access: StreamAccess | undefined): StreamRoomAccess | undefined {\n if (typeof access !== \"object\" || access.room === undefined) {\n return undefined;\n }\n const { room } = access;\n if (typeof room === \"string\") {\n return Object.freeze({ kind: \"name\", room });\n }\n if (typeof room === \"object\") {\n return Object.freeze({ kind: \"prefix\", prefix: room.prefix });\n }\n const computed = compileRoom(room as (payload: never) => string | null | undefined);\n return Object.freeze({\n kind: \"computed\",\n select: (scope: string | undefined) => computed(scope),\n });\n}\n\n/** What a service declares that its streams' row-level access forms need. */\nexport interface StreamNeeds {\n readonly model: string | undefined;\n readonly hasPolicy: boolean;\n}\n\nconst STREAM_OPTION_KEYS = [\"seed\", \"validate\"];\n\n/** One stream's entry in `defineService`'s `streams`, checked: its seed function and when it validates. */\nfunction checkStreamOptions(\n name: string,\n def: StreamDef,\n entry: unknown,\n fail: Fail,\n): Pick<ServiceStream, \"computeSeed\" | \"validate\"> {\n const owner = `streams.${name}`;\n if (entry === undefined) {\n return { computeSeed: undefined, validate: \"always\" };\n }\n if (!isRecord(entry)) {\n fail(`${owner} must be an object: { seed?, validate? }`);\n }\n const unknownKey = Object.keys(entry).find((key) => !STREAM_OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(\n `${owner} has an unknown option \"${unknownKey}\"; the options are ${STREAM_OPTION_KEYS.join(\", \")}`,\n );\n }\n const { seed } = entry;\n if (seed !== undefined && typeof seed !== \"function\") {\n fail(`${owner}.seed must be a function of (scope, ctx) returning the seed's items`);\n }\n if (seed !== undefined && (def.seed ?? 0) > 0) {\n fail(\n `${owner}.seed computes the seed, but the contract's stream keeps the latest ${String(def.seed)} items as its seed; declare one of the two`,\n );\n }\n const { validate = \"always\" } = entry;\n if (validate !== \"always\" && validate !== \"development\") {\n fail(`${owner}.validate must be \"always\" or \"development\"`);\n }\n return { computeSeed: seed as AnyStreamSeed | undefined, validate };\n}\n\nfunction checkStream(\n name: string,\n def: StreamDef,\n needs: StreamNeeds,\n options: unknown,\n fail: Fail,\n): ServiceStream {\n const access = engineForm(def.access);\n if (typeof access === \"object\" && \"entry\" in access && !needs.hasPolicy) {\n fail(\n `stream \"${name}\" uses entry access, which needs the service's access policy: declare model and access`,\n );\n }\n if (typeof access === \"object\" && \"scope\" in access && needs.model === undefined) {\n fail(\n `stream \"${name}\" uses scope access, but the service declares no model; a service without a model may only use \"public\", \"authenticated\" or { service } access`,\n );\n }\n return Object.freeze({\n name,\n item: def.item,\n scoped: isScopedStream(def),\n seed: def.seed ?? 0,\n ...checkStreamOptions(name, def, options, fail),\n volatile: def.volatile === true,\n access,\n room: roomAccess(def.access),\n });\n}\n\n/**\n * The streams of a service, from its contract, with the access forms checked\n * against what it declares, and `defineService`'s `streams` option (a seed\n * function per stream) checked against the contract's streams.\n */\nexport function compileStreams(\n contract: AnyContract,\n needs: StreamNeeds,\n value: unknown,\n fail: Fail,\n): ReadonlyMap<string, ServiceStream> {\n if (value !== undefined && !isRecord(value)) {\n fail(\n \"streams must be an object of options per contract stream: { <stream>: { seed?, validate? } }\",\n );\n }\n const options = value ?? {};\n const unknownStream = Object.keys(options).find((name) => !Object.hasOwn(contract.streams, name));\n if (unknownStream !== undefined) {\n fail(`streams: \"${unknownStream}\" is not a stream of the contract`);\n }\n const streams = new Map<string, ServiceStream>();\n for (const [name, def] of Object.entries(contract.streams)) {\n const entry = Object.hasOwn(options, name) ? options[name] : undefined;\n streams.set(name, checkStream(name, def, needs, entry, fail));\n }\n return streams;\n}\n","// The run-time checks of `defineService`'s data options (RFC 0003 sections 3,\n// 4.1, 5.3, 6 and 11.3): the `model` the rows live in and its `access`\n// policy, the other models the service `writes`, the rows a write `affects`,\n// the `versionColumn` \"not modified\" answers read, who may watch the\n// service's change topic (`watchAccess`), and the kinds of principal it\n// admits (`kinds`, within the app's; each method's within the service's,\n// `access/kinds.ts`). The types make the same checks, kinds' narrowing\n// aside; these repeat them for JavaScript callers and casts.\n\nimport { isAccessLevel } from \"../contract/access\";\nimport type { AnyContract } from \"../contract/defineContract\";\nimport { narrowKinds } from \"./access/kinds\";\nimport { isAccessPolicy, type AnyAccessPolicy } from \"./access/policy\";\nimport type { WatchAccess } from \"./access/types\";\nimport type { AffectsLink } from \"./service\";\nimport { modelKey } from \"./storage\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\n/** The checked data options of a service definition. */\nexport interface ServiceData {\n readonly model: string | undefined;\n readonly access: AnyAccessPolicy | undefined;\n readonly writes: readonly string[];\n readonly affects: readonly AffectsLink[];\n readonly versionColumn: string | undefined;\n readonly watchAccess: WatchAccess | undefined;\n /** The kinds of principal the service admits: its own `kinds`, else the app's; `undefined` admits every kind. */\n readonly kinds: readonly string[] | undefined;\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isName(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\nfunction isContract(value: unknown): value is AnyContract {\n return isRecord(value) && isName(value.name) && Object.isFrozen(value);\n}\n\n/** The ids a link's value holds: a row id, a list of them, or nothing. */\nfunction idsIn(value: unknown): readonly string[] {\n if (isName(value)) {\n return [value];\n }\n return Array.isArray(value) ? value.filter(isName) : [];\n}\n\nfunction checkLink(index: number, entry: unknown, fail: Fail): AffectsLink {\n const owner = `affects[${index}]`;\n if (!isRecord(entry) || !isContract(entry.service)) {\n fail(`${owner} must be { service: contract, id }`);\n }\n const { id, columns } = entry;\n if (isName(id)) {\n if (columns !== undefined) {\n fail(`${owner}: columns belong to an id function; an id column is its own column`);\n }\n return Object.freeze({\n service: entry.service,\n columns: Object.freeze([id]),\n ids: (values: UnknownRecord) => idsIn(values[id]),\n });\n }\n const listed = Array.isArray(columns) && columns.length > 0 && columns.every(isName);\n if (typeof id !== \"function\" || !listed) {\n fail(\n `${owner}: id must be a column holding the affected row's id, or a function of the written row with the columns it reads in columns`,\n );\n }\n const read = id as (values: UnknownRecord) => unknown;\n return Object.freeze({\n service: entry.service,\n columns: Object.freeze([...(columns as readonly string[])]),\n ids: (values: UnknownRecord) => idsIn(read(values)),\n });\n}\n\nfunction checkAffects(value: unknown, model: string | undefined, fail: Fail): AffectsLink[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value)) {\n fail(\"affects must be a list of { service, id }\");\n }\n if (model === undefined) {\n fail(\"affects needs model: it reads the written rows of the service's model\");\n }\n return value.map((entry: unknown, index) => checkLink(index, entry, fail));\n}\n\nfunction checkWrites(value: unknown, fail: Fail): readonly string[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value) || !value.every(isName)) {\n fail('writes must be a list of model names, as the client names them (\"taskLabel\")');\n }\n return Object.freeze([...(value as readonly string[])]);\n}\n\n/** `watchAccess`: `\"public\"`, `\"authenticated\"` or `{ service: level }`; none keeps the service topic closed. */\nfunction checkWatchAccess(value: unknown, fail: Fail): WatchAccess | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === \"public\" || value === \"authenticated\") {\n return value;\n }\n if (!isRecord(value) || Object.keys(value).length !== 1 || !isAccessLevel(value.service)) {\n fail('watchAccess must be \"public\", \"authenticated\" or { service: level }');\n }\n return Object.freeze({ service: value.service });\n}\n\n/**\n * `initQuickdraw`'s `kinds`, checked: the kinds of principal every service\n * the instance defines admits, unless it narrows them.\n */\nexport function checkAppKinds(value: unknown): readonly string[] | undefined {\n return narrowKinds(value, undefined, (message) => {\n throw new TypeError(`initQuickdraw: ${message}`);\n });\n}\n\n/**\n * A method's own `kinds`, within its service's: the kinds it admits, its\n * service's when it declares none. A `\"public\"` method declares none, since a\n * caller of a kind it left out would call it signed out; it keeps the\n * service's list, which signed-in callers meet.\n */\nexport function checkMethodKinds(\n owner: string,\n entry: UnknownRecord,\n data: ServiceData,\n fail: Fail,\n): readonly string[] | undefined {\n if (entry.kinds !== undefined && entry.access === \"public\") {\n fail(\n `${owner} is \"public\", so kinds cannot narrow who may call it: a caller of a kind it left out would call it signed out. Leave kinds out, or give it a form that needs a principal`,\n );\n }\n return narrowKinds(entry.kinds, { kinds: data.kinds, by: \"its service\" }, (message) =>\n fail(`${owner}: ${message}`),\n );\n}\n\n/**\n * Checks a definition's `model`, `access`, `writes`, `affects`,\n * `versionColumn`, `watchAccess` and `kinds`, the last within `appKinds`, the\n * kinds of principal `initQuickdraw` admits.\n */\nexport function checkServiceData(\n definition: UnknownRecord,\n appKinds: readonly string[] | undefined,\n fail: Fail,\n): ServiceData {\n const { model, access, versionColumn } = definition;\n if (model !== undefined && !isName(model)) {\n fail('model must be the database model the rows live in, as the client names it (\"task\")');\n }\n if (access !== undefined && !isAccessPolicy(access)) {\n fail(\"access must be an access policy: owner, jsonAcl, members, inherit, anyOf or resolver\");\n }\n if (access !== undefined && model === undefined) {\n fail(\"access needs model: an access policy reads the rows of the service's model\");\n }\n if (versionColumn !== undefined && (!isName(versionColumn) || model === undefined)) {\n fail(\"versionColumn must be a column of the service's model, so it needs model\");\n }\n return {\n model,\n access,\n writes: checkWrites(definition.writes, fail),\n affects: Object.freeze(checkAffects(definition.affects, model, fail)),\n versionColumn,\n watchAccess: checkWatchAccess(definition.watchAccess, fail),\n kinds: narrowKinds(definition.kinds, { kinds: appKinds, by: \"initQuickdraw\" }, fail),\n };\n}\n\n/**\n * `watch: { service: [models] }` names models whose writes change the\n * service's topic: its `model` and those in its `writes` (finding F7.3).\n * Any other name could never match, so the query would never be told.\n */\nexport function checkWatchedModels(\n contract: AnyContract,\n name: string,\n models: unknown,\n data: ServiceData,\n fail: Fail,\n): void {\n const own = [data.model, ...data.writes].filter((model) => model !== undefined).map(modelKey);\n const listed = Array.isArray(models) ? models : [];\n const valid =\n listed.length > 0 &&\n listed.every((model) => typeof model === \"string\" && model !== \"\") &&\n new Set(listed.map((model) => modelKey(String(model)))).size === listed.length;\n if (!valid) {\n fail(\n `method \"${name}\": watch { service } lists the models of the service it watches: { service: [\"gameScore\"] }`,\n );\n }\n for (const model of listed as string[]) {\n if (!own.includes(modelKey(model))) {\n const known = own.length === 0 ? \"none\" : own.map((key) => `\"${key}\"`).join(\", \");\n fail(\n `method \"${name}\" watches the model \"${model}\", which ${contract.name} neither declares as its model nor lists in writes (its models: ${known})`,\n );\n }\n }\n}\n","// The run-time half of `defineService`: the checks the types already make,\n// repeated for JavaScript callers and casts, so a broken service fails when\n// it is defined rather than on its first call. It returns the frozen\n// service the registry and the dispatcher read. The runtime it is given,\n// what every service of one `initQuickdraw` keeps, is made here too, from\n// that call's options, checked.\n\nimport type { AnyContract } from \"../contract/defineContract\";\nimport { accessFormProblem, isCustomAccess } from \"./access/forms\";\nimport { rowlessProblem } from \"./access/rowless\";\nimport { compileCollections } from \"./collections/define\";\nimport { compileProjections, projectedOutput, type Projection } from \"./emit/projection\";\nimport { MAX_TIMEOUT_MS } from \"./pipeline/settings\";\nimport { outputSchemaOf, schemaOutputOf } from \"./pipeline/validation\";\nimport { compileChannels, compileStreams } from \"./realtime/define\";\nimport {\n handlerProblem,\n registerRuntime,\n type AnyHandler,\n type AnyService,\n type ServiceMethod,\n type ServiceRuntime,\n} from \"./service\";\nimport {\n checkAppKinds,\n checkMethodKinds,\n checkServiceData,\n checkWatchedModels,\n type ServiceData,\n} from \"./serviceData\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nconst DEFINITION_KEYS = new Set([\n \"model\",\n \"access\",\n \"writes\",\n \"affects\",\n \"project\",\n \"versionColumn\",\n \"collections\",\n \"watchAccess\",\n \"methods\",\n \"channels\",\n \"streams\",\n \"onRoomLeave\",\n \"adminBypass\",\n \"kinds\",\n]);\n\nconst METHOD_KEYS = new Set([\n \"access\",\n \"handler\",\n \"share\",\n \"ttlMs\",\n \"timeoutMs\",\n \"version\",\n \"rowless\",\n \"kinds\",\n]);\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction checkKeys(\n value: UnknownRecord,\n allowed: ReadonlySet<string>,\n owner: string,\n fail: Fail,\n): void {\n const unknownKey = Object.keys(value).find((key) => !allowed.has(key));\n if (unknownKey !== undefined) {\n fail(\n `${owner} has an unknown option \"${unknownKey}\"; the options are ${[...allowed].join(\", \")}`,\n );\n }\n}\n\nfunction isDuration(value: unknown, max: number): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 && value <= max;\n}\n\nfunction checkContract(contract: unknown): AnyContract {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n contract.name.length > 0 &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n throw new TypeError(\"defineService: the first argument must be a contract from defineContract\");\n }\n return contract as unknown as AnyContract;\n}\n\nfunction checkShare(owner: string, entry: UnknownRecord, fail: Fail): void {\n const { share, ttlMs } = entry;\n if (share !== undefined && share !== \"caller\" && share !== \"all\") {\n fail(`${owner}: share must be \"caller\" or \"all\"`);\n }\n if (share === \"all\" && isRecord(entry.access) && entry.access.kind === \"custom\") {\n fail(\n `${owner} has custom access, so it cannot share: \"all\"; its result may depend on who asks`,\n );\n }\n if (ttlMs !== undefined && (share === undefined || !isDuration(ttlMs, MAX_TIMEOUT_MS))) {\n fail(`${owner}: ttlMs needs share and must be a positive number of milliseconds`);\n }\n}\n\nfunction checkQueryOptions(\n owner: string,\n entry: UnknownRecord,\n kind: ServiceMethod[\"kind\"],\n fail: Fail,\n): void {\n const queryOnly = [entry.share, entry.ttlMs, entry.version].some((value) => value !== undefined);\n if (kind === \"mutation\" && queryOnly) {\n fail(`${owner} is a mutation; share, ttlMs and version are for queries`);\n }\n checkShare(owner, entry, fail);\n if (entry.version !== undefined && typeof entry.version !== \"function\") {\n fail(`${owner}: version must be a function of (input, ctx)`);\n }\n}\n\nfunction checkMethod(\n contract: AnyContract,\n projections: ReadonlyMap<string, Projection>,\n data: ServiceData,\n name: string,\n entry: unknown,\n fail: Fail,\n): ServiceMethod {\n const owner = `method \"${name}\"`;\n const def = contract.methods[name];\n if (def === undefined) {\n fail(`\"${name}\" is not a method of the contract`);\n }\n if (!isRecord(entry)) {\n fail(`${owner} must be { access, handler }`);\n }\n checkKeys(entry, METHOD_KEYS, owner, fail);\n const accessProblem = accessFormProblem(entry.access);\n if (accessProblem !== undefined) {\n fail(`${owner}: access ${accessProblem}`);\n }\n if (typeof entry.handler !== \"function\") {\n fail(`${owner} needs a handler function`);\n }\n if (entry.timeoutMs !== undefined && !isDuration(entry.timeoutMs, MAX_TIMEOUT_MS)) {\n fail(\n `${owner}: timeoutMs must be a positive number of milliseconds, at most ${MAX_TIMEOUT_MS}`,\n );\n }\n if (entry.rowless !== undefined && typeof entry.rowless !== \"boolean\") {\n fail(`${owner}: rowless must be true, or left out`);\n }\n checkQueryOptions(owner, entry, def.kind, fail);\n const kinds = checkMethodKinds(owner, entry, data, fail);\n const projection = projectedOutput(def.output, projections);\n return Object.freeze({\n name,\n kind: def.kind,\n input: def.input,\n output: outputSchemaOf(contract, def.output),\n projection,\n schemaOutput: projection === undefined ? schemaOutputOf(def.output) : undefined,\n access: entry.access as ServiceMethod[\"access\"],\n kinds,\n handler: entry.handler as AnyHandler,\n share: entry.share as ServiceMethod[\"share\"],\n ttlMs: entry.ttlMs as number | undefined,\n timeoutMs: entry.timeoutMs as number | undefined,\n version: entry.version as ServiceMethod[\"version\"],\n rowless: entry.rowless === true,\n });\n}\n\nfunction checkMethods(\n contract: AnyContract,\n projections: ReadonlyMap<string, Projection>,\n data: ServiceData,\n value: unknown,\n fail: Fail,\n): Record<string, ServiceMethod> {\n if (!isRecord(value)) {\n fail(\"methods must be an object with one implementation per contract method\");\n }\n const missing = Object.keys(contract.methods).filter((name) => !Object.hasOwn(value, name));\n if (missing.length > 0) {\n fail(`methods has no implementation for ${missing.map((name) => `\"${name}\"`).join(\", \")}`);\n }\n const methods: Record<string, ServiceMethod> = {};\n for (const [name, entry] of Object.entries(value)) {\n methods[name] = checkMethod(contract, projections, data, name, entry, fail);\n }\n return methods;\n}\n\n/**\n * A query's `watch` (RFC 0003 sections 2 and 11.3) names the topic of one\n * scope of one of the service's collections: the collection must be one the\n * service serves, and `scope` the function that finds the scope from the\n * input. `defineContract` checks the same; this catches a contract it never\n * saw. A watch of the service's topic needs `watchAccess`, and one narrowed\n * to models names the service's own (`checkWatchedModels`).\n */\nfunction checkWatches(\n contract: AnyContract,\n collections: ReadonlyMap<string, unknown>,\n data: ServiceData,\n fail: Fail,\n): void {\n for (const [name, def] of Object.entries(contract.methods)) {\n const watch: unknown = def.watch;\n if (watch === undefined) {\n continue;\n }\n if (def.kind !== \"query\") {\n fail(`method \"${name}\" is a mutation; only a query can watch`);\n }\n if (watch === \"service\" || (isRecord(watch) && Object.hasOwn(watch, \"service\"))) {\n if (data.watchAccess === undefined) {\n fail(\n `method \"${name}\" watches the service's topic, which is closed without watchAccess: declare who may watch it (\"public\", \"authenticated\" or { service: level })`,\n );\n }\n if (watch !== \"service\") {\n checkWatchedModels(contract, name, watch.service, data, fail);\n }\n continue;\n }\n if (!isRecord(watch) || typeof watch.scope !== \"function\") {\n fail(`method \"${name}\": watch needs a scope function, which finds the scope from the input`);\n }\n if (typeof watch.collection !== \"string\" || !collections.has(watch.collection)) {\n fail(\n `method \"${name}\" watches \"${String(watch.collection)}\", which is not a collection of ${contract.name}`,\n );\n }\n }\n}\n\n/**\n * The row-level access forms need what the service declares (RFC 0003\n * section 3): `entry` asks the service's own policy, and `scope` (another\n * service's policy) is for services that have a model. A service without a\n * model may only use `\"public\"`, `\"authenticated\"`, `{ service }` or `custom`.\n */\nfunction checkRowForms(\n methods: Readonly<Record<string, ServiceMethod>>,\n data: ServiceData,\n fail: Fail,\n): void {\n for (const method of Object.values(methods)) {\n const form = method.access;\n if (typeof form !== \"object\" || isCustomAccess(form)) {\n continue;\n }\n if (form.entry !== undefined && data.access === undefined) {\n fail(\n `method \"${method.name}\" uses entry access, which needs the service's access policy: declare model and access`,\n );\n }\n if (form.scope !== undefined && data.model === undefined) {\n fail(\n `method \"${method.name}\" uses scope access, but the service declares no model; a service without a model may only use \"public\", \"authenticated\", { service } or custom access`,\n );\n }\n }\n}\n\n/**\n * On a service with an access policy, a method whose input has `id` and\n * whose form checks no row is refused unless it says `rowless: true`\n * (`access/rowless.ts`). A service without a policy has no row check to\n * skip.\n */\nfunction checkRowless(\n methods: Readonly<Record<string, ServiceMethod>>,\n data: ServiceData,\n fail: Fail,\n): void {\n if (data.access === undefined) {\n return;\n }\n for (const method of Object.values(methods)) {\n const problem = rowlessProblem(method);\n if (problem !== undefined) {\n fail(problem);\n }\n }\n}\n\n/** The checks handlers carry for the service they run in (`checkWhenDefined`): a kit's need a model. */\nfunction checkHandlers(service: AnyService, fail: Fail): void {\n for (const method of Object.values(service.methods)) {\n const problem = handlerProblem(method.handler, service);\n if (problem !== undefined) {\n fail(`method \"${method.name}\": ${problem}`);\n }\n }\n}\n\n/**\n * The runtime every service of one `initQuickdraw` keeps, from that call's\n * options, checked: `context`, which adds the app's fields to every\n * handler's `ctx`, and `kinds`, the kinds of principal every service admits\n * unless it narrows them (RFC 0003 section 4.1). `adopt` makes a dispatcher\n * the instance's own.\n */\nexport function createRuntime(\n options: unknown,\n adopt: NonNullable<ServiceRuntime[\"adopt\"]>,\n): ServiceRuntime {\n if (options === undefined) {\n return Object.freeze({ extendContext: undefined, kinds: undefined, adopt });\n }\n if (typeof options !== \"object\" || options === null) {\n throw new TypeError(\"initQuickdraw: options must be an object\");\n }\n const { context, kinds } = options as { readonly context?: unknown; readonly kinds?: unknown };\n if (context !== undefined && typeof context !== \"function\") {\n throw new TypeError(\"initQuickdraw: context must be a function of the base context\");\n }\n return Object.freeze({\n extendContext: context as ServiceRuntime[\"extendContext\"],\n kinds: checkAppKinds(kinds),\n adopt,\n });\n}\n\n/** Checks a service definition and returns the frozen service, registered with `runtime`. */\nexport function buildService(\n runtime: ServiceRuntime,\n contract: unknown,\n definition: unknown,\n): AnyService {\n const checked = checkContract(contract);\n const fail: Fail = (message) => {\n throw new TypeError(`defineService(\"${checked.name}\"): ${message}`);\n };\n if (!isRecord(definition)) {\n fail(\"the definition must be an object\");\n }\n checkKeys(definition, DEFINITION_KEYS, \"the definition\", fail);\n const { adminBypass = true, onRoomLeave } = definition;\n if (typeof adminBypass !== \"boolean\") {\n fail(\"adminBypass must be a boolean\");\n }\n if (onRoomLeave !== undefined && typeof onRoomLeave !== \"function\") {\n fail(\"onRoomLeave must be a function of the leave and a run context\");\n }\n const data = checkServiceData(definition, runtime.kinds, fail);\n const projections = compileProjections(checked, definition.project, fail);\n const collections = compileCollections(\n checked,\n projections,\n data.model,\n definition.collections,\n fail,\n );\n checkWatches(checked, collections, data, fail);\n const methods = checkMethods(checked, projections, data, definition.methods, fail);\n checkRowForms(methods, data, fail);\n checkRowless(methods, data, fail);\n const service: AnyService = Object.freeze({\n name: checked.name,\n contract: checked,\n ...data,\n projections,\n collections,\n adminBypass,\n methods: Object.freeze(methods),\n channels: compileChannels(checked, definition.channels, data.kinds, fail),\n streams: compileStreams(\n checked,\n { model: data.model, hasPolicy: data.access !== undefined },\n definition.streams,\n fail,\n ),\n onRoomLeave: onRoomLeave as AnyService[\"onRoomLeave\"],\n });\n checkHandlers(service, fail);\n registerRuntime(service, runtime);\n return service;\n}\n","// `initQuickdraw`: the one place an app states its types (RFC 0003 section 3).\n//\n// export const qd = initQuickdraw<{ db: AppPrisma; principal: AppPrincipal }>();\n// export const taskService = qd.defineService(task, { methods: { ... } });\n//\n// Every service, handler argument and caller is typed from it. `context`\n// adds the app's own fields to every handler's `ctx`, once for the whole app;\n// it replaces 4.1's habit of overriding `defineMethod` per service.\n\nimport type { AnyContract } from \"../contract/defineContract\";\nimport { QuickdrawError } from \"../protocol/errors\";\nimport { buildService, createRuntime } from \"./buildService\";\nimport { callerGrantsOf, createCaller, type CallerFor } from \"./caller\";\nimport type { BaseContext, RunContext, RunOptions } from \"./context\";\nimport { createServer, type QuickdrawServer, type ServerOptions } from \"./createServer\";\nimport type { DefineService } from \"./defineService\";\nimport {\n createDispatcher,\n type Dispatcher,\n type DispatcherCollections,\n type DispatcherOptions,\n type Presence,\n type ServerRooms,\n type Service,\n type StreamHandle,\n} from \"./dispatcher\";\nimport type {\n ContextExtensionOf,\n McpContextOf,\n PrincipalKindOf,\n PrincipalOf,\n QuickdrawTypes,\n} from \"./types\";\nimport { runBeforeAnyDispatcher } from \"./uow/unitOfWork\";\n\n/**\n * Builds the app's fields of `ctx` from the framework's. It runs once per\n * call, before access is checked, so `custom` checks see the fields too.\n */\nexport type ContextFactory<T extends QuickdrawTypes> = (\n base: BaseContext<PrincipalOf<T> | null, McpContextOf<T>>,\n) => ContextExtensionOf<T>;\n\n/** Options of `initQuickdraw`. */\nexport interface InitOptions<T extends QuickdrawTypes> {\n /** Adds the app's fields to every handler's `ctx`. Required when the app's types declare `context`. */\n readonly context?: ContextFactory<T>;\n /**\n * The kinds of principal every service this instance defines admits\n * (RFC 0003 section 4.1), so a new service starts closed to the rest:\n * `kinds: [\"user\", \"agent\"]`. A service's `kinds`, and a method's, may\n * only narrow it. A principal of another kind, or without a `kind`, gets\n * `FORBIDDEN` before any access form or `Admin` grant is asked; an\n * anonymous caller is left to the form. Leave it out to admit every kind.\n */\n readonly kinds?: readonly PrincipalKindOf<T>[];\n}\n\n/** `initQuickdraw`'s arguments: the options are required when `T` declares `context`. */\nexport type InitArgs<T extends QuickdrawTypes> = T extends { readonly context: object }\n ? [options: InitOptions<T> & { readonly context: ContextFactory<T> }]\n : [options?: InitOptions<T>];\n\n/** What `initQuickdraw` returns. */\nexport interface Quickdraw<T extends QuickdrawTypes> {\n /**\n * Defines a service from its contract: one `{ access, handler }` per\n * contract method, no more and no fewer.\n */\n readonly defineService: DefineService<T>;\n /**\n * Creates a dispatcher for `services` and makes it the one `qd.caller`\n * calls through. The last dispatcher created wins.\n */\n createDispatcher<const S extends readonly Service<T>[]>(\n options: DispatcherOptions<S>,\n ): Dispatcher<S>;\n /**\n * An in-process caller acting as `principal` (`null` for anonymous),\n * through the dispatcher this instance created last:\n * `qd.caller(user).taskService.rename(input)`. Typed by the `contracts` of\n * the app's types; `dispatcher.caller` is typed by its own services.\n *\n * Through a server (`qd.createServer`, or `createTestApp`), a principal\n * that carries no `serviceAccess` gets the grants the server's\n * `auth.loadServiceAccess` loads, as a socket's handshake and an HTTP\n * call do: at the caller's first call, and again at the next call after\n * the server applied new grants to a user (`server.access.refresh`, a\n * tracked write to `auth.serviceAccessSource`). So an app's REST route\n * calls as the user's sockets would: `qd.caller(sessionOf(req).principal)`.\n * A principal that carries grants (even `{}`) keeps exactly those; a load\n * that fails rejects the call with `INTERNAL` and is tried again at the\n * next one.\n */\n caller(principal: PrincipalOf<T> | null): CallerFor<T>;\n /**\n * Runs `fn` inside a unit of work of the dispatcher this instance created\n * last, so the tracked writes of a job, script or webhook flush to its\n * sinks once `fn` settles, as a method's do (RFC 0003 section 5.1). Writes\n * made outside any unit of work still flush, on the next tick, with a\n * development warning. Inside a method or a transaction, `fn` joins it,\n * unless `{ detached: true }` gives it a unit of its own: background work\n * a handler starts and does not await (see {@link RunOptions}).\n * `fn` gets a {@link RunContext} (`{ touch, log, principal: null }`):\n * `ctx.touch` records the rows a raw SQL write changed.\n *\n * Before this instance created any dispatcher (a boot-time seed that runs\n * before `createServer`), `fn` still runs in a unit of work of its own:\n * its tracked writes raise no ambient warning and flush once it settles,\n * to the dispatcher the tracked client is attached to then, which before\n * any server is none, so they reach no one (no socket can be subscribed\n * yet; behind a cluster, other nodes' subscribers do not hear of them\n * either: write after `createServer` when they must). `ctx.touch` records\n * nothing there, and `ctx.log` is the console's.\n *\n * @example\n * await qd.run(() => db.task.updateMany({ where: { dueAt: { lt: now } }, data: { status: \"late\" } }));\n * await qd.run(async (ctx) => {\n * await db.$executeRaw`UPDATE \"Task\" SET \"status\" = 'late' WHERE \"id\" = ANY(${ids})`;\n * ctx.touch(\"task\", ids);\n * });\n */\n run<R>(fn: (ctx: RunContext) => R | PromiseLike<R>, options?: RunOptions): Promise<R>;\n /**\n * The collections of the dispatcher this instance created last (RFC 0003\n * section 7): `qd.collections.reset(contract, collection, scope)` sends one\n * scope a `reset`, for a change tracked writes cannot describe.\n */\n readonly collections: DispatcherCollections;\n /**\n * The handle of a stream (RFC 0003 section 12.5), for handlers, jobs and\n * timers: `qd.stream(task, \"logs\").push(taskId, line)` (`push(item)` for a\n * global stream; `pushMany(taskId, lines)` for several at once). Each push\n * goes through the dispatcher this instance created last, so a handle can\n * be made when a module loads; pushing before any dispatcher exists, or to\n * a stream it does not serve, throws.\n * Throws a `TypeError` at once for a stream the contract does not declare.\n */\n stream<C extends AnyContract, K extends keyof C[\"streams\"] & string>(\n contract: C,\n name: K,\n ): StreamHandle<C, K>;\n /**\n * Who is online and who is in a room (RFC 0003 section 12.5), through the\n * dispatcher this instance created last: the same as `ctx.presence`.\n */\n readonly presence: Presence;\n /**\n * App rooms from code that is not a handler (RFC 0003 section 12.5), through\n * the dispatcher this instance created last: a game loop's or a job's typed\n * room events (`qd.rooms.emit(room, contract, event, payload)`,\n * `emitToUser`), and `qd.rooms.leave(room, { userId })`, which takes every\n * socket of the user out of the room on every node. The same as the\n * socket-free half of `ctx.rooms`; using it before any dispatcher exists\n * throws.\n */\n readonly rooms: ServerRooms;\n /**\n * Serves `services` over Socket.IO and HTTP on the app's Express app and\n * HTTP server (see `createServer`), and makes the server's dispatcher the\n * one `qd.caller` calls through.\n */\n createServer<const S extends readonly Service<T>[]>(\n options: ServerOptions<S>,\n ): QuickdrawServer<S>;\n}\n\nconst NEEDS: Readonly<Record<string, string>> = Object.freeze({\n \"qd.collections.reset\": \"send through\",\n \"qd.stream\": \"push through\",\n \"qd.presence\": \"ask\",\n \"qd.rooms\": \"send through\",\n});\n\nfunction noDispatcher(member: string): never {\n throw new QuickdrawError(\n \"INTERNAL\",\n `${member} has no dispatcher to ${NEEDS[member] ?? \"call through\"}: create one with qd.createDispatcher (or qd.createServer) first`,\n );\n}\n\ntype Current = () => Dispatcher | undefined;\n\n/** `qd.stream`: a handle that pushes through the current dispatcher, resolving the stream once per dispatcher. */\nfunction streamOf(\n current: Current,\n contract: AnyContract,\n name: string,\n): StreamHandle<AnyContract, string> {\n const streams: unknown =\n typeof contract === \"object\" && contract !== null ? contract.streams : undefined;\n if (typeof streams !== \"object\" || streams === null || !Object.hasOwn(streams, name)) {\n throw new TypeError(\n `qd.stream: ${String(contract?.name)} declares no stream \"${String(name)}\"`,\n );\n }\n let resolved:\n | { readonly from: Dispatcher; readonly handle: StreamHandle<AnyContract, string> }\n | undefined;\n const handle = (): StreamHandle<AnyContract, string> => {\n const from = current() ?? noDispatcher(\"qd.stream\");\n if (resolved?.from !== from) {\n resolved = { from, handle: from.stream(contract, name) };\n }\n return resolved.handle;\n };\n return Object.freeze({\n push(...args: unknown[]): void {\n (handle().push as (...items: unknown[]) => void)(...args);\n },\n pushMany(...args: unknown[]): void {\n (handle().pushMany as (...items: unknown[]) => void)(...args);\n },\n }) as StreamHandle<AnyContract, string>;\n}\n\n/** `qd.presence`: presence through the current dispatcher. */\nfunction presenceOf(current: Current): Presence {\n const presence = (): Presence => (current() ?? noDispatcher(\"qd.presence\")).presence;\n return Object.freeze({\n isOnline: async (userId: string) => await presence().isOnline(userId),\n lastSeen: async (userId: string) => await presence().lastSeen(userId),\n count: async (room: string) => await presence().count(room),\n users: async (room: string) => await presence().users(room),\n });\n}\n\n/** `qd.rooms`: app rooms through the current dispatcher. */\nfunction roomsOf(current: Current): ServerRooms {\n const rooms = (): ServerRooms => (current() ?? noDispatcher(\"qd.rooms\")).rooms;\n return Object.freeze({\n emit: (...args: Parameters<ServerRooms[\"emit\"]>) => {\n rooms().emit(...args);\n },\n emitToUser: (...args: Parameters<ServerRooms[\"emitToUser\"]>) => {\n rooms().emitToUser(...args);\n },\n leave: async (room: string, target: Parameters<ServerRooms[\"leave\"]>[1]) =>\n await rooms().leave(room, target),\n size: (room: string) => rooms().size(room),\n }) as ServerRooms;\n}\n\n/**\n * Starts a quickdraw app. The type argument states the app's types once:\n * the database client handlers receive, the principal type, the fields\n * `context` adds to `ctx`, and the contracts that type `qd.caller`.\n *\n * @example\n * export const qd = initQuickdraw<{ db: AppPrisma; principal: AppPrincipal }>();\n */\nexport function initQuickdraw<T extends QuickdrawTypes = QuickdrawTypes>(\n ...args: InitArgs<T>\n): Quickdraw<T> {\n let current: Dispatcher | undefined;\n const runtime = createRuntime(args[0], (dispatcher) => {\n current = dispatcher as Dispatcher;\n });\n const qd: Quickdraw<T> = {\n defineService: ((contract: unknown, definition: unknown) =>\n buildService(runtime, contract, definition)) as DefineService<T>,\n createDispatcher(options) {\n const dispatcher = createDispatcher(options);\n current = dispatcher as Dispatcher;\n return dispatcher;\n },\n caller: (principal) =>\n createCaller(() => (current ?? noDispatcher(\"qd.caller\")).call, principal, {\n grants: () => callerGrantsOf(current),\n }) as CallerFor<T>,\n run: async (fn, options) =>\n current === undefined\n ? await runBeforeAnyDispatcher(fn, options)\n : await current.run(fn, options),\n collections: Object.freeze({\n reset: (contract, collection, scope) => {\n (current ?? noDispatcher(\"qd.collections.reset\")).collections.reset(\n contract,\n collection,\n scope,\n );\n },\n } satisfies DispatcherCollections),\n stream: <C extends AnyContract, K extends keyof C[\"streams\"] & string>(contract: C, name: K) =>\n streamOf(() => current, contract, name) as unknown as StreamHandle<C, K>,\n presence: presenceOf(() => current),\n rooms: roomsOf(() => current),\n createServer(options) {\n const server = createServer(options);\n current = server.dispatcher as Dispatcher;\n return server;\n },\n };\n return Object.freeze(qd);\n}\n","// `owner(field)` (RFC 0003 section 4.2): the user named in a column of the\n// row has `Admin` on it, and nobody else has anything.\n\nimport { checkName, definePolicy, levelsById, type AccessPolicy } from \"../policy\";\n\n/**\n * The user whose id is in `field` has `Admin` on the row; everyone else has\n * no level. One query reads `id` and `field` of every row asked about.\n *\n * @example\n * qd.defineService(project, { model: \"project\", access: owner(\"ownerId\"), methods });\n */\nexport function owner<const Field extends string>(field: Field): AccessPolicy<Field, never> {\n checkName(\"owner(field)\", \"field\", field);\n return definePolicy({\n kind: \"owner\",\n field,\n reads: { columns: [field], memberships: [], inherits: [], storage: true },\n async levelsFor(principal, ids, tools) {\n const rows = await tools.rows(ids);\n return levelsById(ids, (id) => (rows.get(id)?.[field] === principal.userId ? \"Admin\" : null));\n },\n accessWhere: (principal) => Promise.resolve({ [field]: principal.userId }),\n });\n}\n","// `jsonAcl(field, { owner? })` (RFC 0003 section 4.2): the level comes from a\n// JSON access list on the row, `[{ userId, level }]`, the shape 4.x apps\n// store (`ACL` on the root export), plus `Admin` for the owner column when\n// one is named. Ported from 4.1's `checkEntryACL`\n// (4.1 `src/server/BaseService.ts:526-547`), which read one row per check.\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport { levelsAtLeast, maxLevel } from \"../levels\";\nimport {\n checkName,\n definePolicy,\n levelsById,\n type AccessPolicy,\n type AnyAccessPolicy,\n type RowLevel,\n} from \"../policy\";\nimport type { StorageRow, StorageWhere } from \"../../storage\";\n\n/** Options of {@link jsonAcl}. */\nexport interface JsonAclOptions<Owner extends string = string> {\n /** A column holding the owner's user id; the owner has `Admin`. */\n readonly owner?: Owner;\n}\n\n/** The columns a `jsonAcl` policy reads: its access list, and its owner column when it names one. */\nexport interface JsonAclColumns {\n /** The column holding the `[{ userId, level }]` list. */\n readonly field: string;\n /** The column holding the owner's user id, or `undefined` without an owner. */\n readonly owner: string | undefined;\n}\n\nconst COLUMNS = new WeakMap<object, JsonAclColumns>();\n\n/**\n * The columns of a policy `jsonAcl` made, or `undefined` for any other\n * policy: what the sharing kit reads and writes.\n */\nexport function jsonAclColumnsOf(policy: AnyAccessPolicy): JsonAclColumns | undefined {\n return COLUMNS.get(policy);\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The highest level the access list grants `userId`. A value that is not a\n * list grants nothing; so does an entry that is not `{ userId, level }` with\n * a known level. Several entries for one user give the highest of them,\n * which is what `accessWhere` matches.\n */\nfunction aclLevel(acl: unknown, userId: string): RowLevel {\n if (!Array.isArray(acl)) {\n return null;\n }\n let level: RowLevel = null;\n for (const entry of acl) {\n if (isRecord(entry) && entry.userId === userId) {\n level = maxLevel(level, entry.level as AccessLevel);\n }\n }\n return level;\n}\n\n/**\n * The level comes from the JSON access list in `field`, `[{ userId, level }]`,\n * plus `Admin` for the user named in the `owner` column. One query reads both\n * columns of every row asked about. A malformed list, or an entry with an\n * unknown level, grants nothing.\n *\n * List filters match the list with JSON containment (Prisma's\n * `array_contains`, PostgreSQL's `@>`).\n *\n * @example\n * access: jsonAcl(\"acl\", { owner: \"ownerId\" }),\n */\nexport function jsonAcl<const Field extends string, const Owner extends string = never>(\n field: Field,\n options: JsonAclOptions<Owner> = {},\n): AccessPolicy<Field | Owner, never> {\n checkName(\"jsonAcl(field)\", \"field\", field);\n const ownerColumn = options.owner;\n if (ownerColumn !== undefined) {\n checkName(\"jsonAcl(field, { owner })\", \"owner\", ownerColumn);\n }\n const levelOf = (row: StorageRow | null | undefined, userId: string): RowLevel => {\n if (row === null || row === undefined) {\n return null;\n }\n const owned = ownerColumn !== undefined && row[ownerColumn] === userId ? \"Admin\" : null;\n return maxLevel(owned, aclLevel(row[field], userId));\n };\n const policy = definePolicy<AccessPolicy<Field | Owner, never>>({\n kind: \"jsonAcl\",\n field,\n owner: ownerColumn,\n reads: {\n columns: ownerColumn === undefined ? [field] : [field, ownerColumn],\n memberships: [],\n inherits: [],\n storage: true,\n },\n async levelsFor(principal, ids, tools) {\n const rows = await tools.rows(ids);\n return levelsById(ids, (id) => levelOf(rows.get(id), principal.userId));\n },\n accessWhere(principal, level) {\n const listed: StorageWhere[] = levelsAtLeast(level).map((granted) => ({\n [field]: { array_contains: [{ userId: principal.userId, level: granted }] },\n }));\n const owned = ownerColumn === undefined ? [] : [{ [ownerColumn]: principal.userId }];\n return Promise.resolve({ OR: [...owned, ...listed] });\n },\n });\n COLUMNS.set(policy, Object.freeze({ field, owner: ownerColumn }));\n return policy;\n}\n","// `inherit({ from, via })` (RFC 0003 section 4.2): a row's level is the\n// principal's level on its parent row in another service (a task inherits\n// from its project). The parent service must be served by the same\n// dispatcher and declare a policy of its own; `createDispatcher` checks both,\n// and refuses a cycle.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport { checkName, definePolicy, levelsById, type AccessPolicy } from \"../policy\";\n\n/** Options of {@link inherit}. */\nexport interface InheritOptions<Via extends string = string> {\n /** The parent service's contract. */\n readonly from: AnyContract;\n /** The column holding the parent row's id: `\"projectId\"`. */\n readonly via: Via;\n}\n\nfunction isContract(value: unknown): value is AnyContract {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { readonly name?: unknown }).name === \"string\" &&\n Object.isFrozen(value)\n );\n}\n\n/**\n * The level on the parent row, from the parent service's policy: one query\n * reads `via` of every row asked about, then one batched lookup asks the\n * parent's policy about the parents found. A row that does not exist, or has\n * no parent, has no level; its id is never taken for a parent id. Service\n * grants on the parent service do not count here, only its policy. A list's\n * filter names the parents the principal reaches (`{ via: { in: ids } }`),\n * or, when the parent's policy lets every row through, any row with a parent\n * (`{ via: { not: null } }`), without reading the parent table.\n *\n * @example\n * qd.defineService(task, { model: \"task\", access: inherit({ from: project, via: \"projectId\" }), methods });\n */\nexport function inherit<const Via extends string>(\n options: InheritOptions<Via>,\n): AccessPolicy<Via, never> {\n if (typeof options !== \"object\" || options === null || !isContract(options.from)) {\n throw new TypeError(\"inherit({ from, via }): from must be the parent service's contract\");\n }\n const { from } = options;\n const via = checkName(\"inherit({ via })\", \"via\", options.via);\n return definePolicy({\n kind: \"inherit\",\n from,\n via,\n reads: {\n columns: [via],\n memberships: [],\n inherits: [from],\n parents: [{ from, via }],\n storage: true,\n },\n async levelsFor(principal, ids, tools) {\n const rows = await tools.rows(ids);\n const parentOf = new Map<string, string>();\n for (const id of ids) {\n const parent = rows.get(id)?.[via];\n if (typeof parent === \"string\" && parent.length > 0) {\n parentOf.set(id, parent);\n }\n }\n const parents = await tools.levelsOf(from, principal, [...new Set(parentOf.values())]);\n return levelsById(ids, (id) => {\n const parent = parentOf.get(id);\n return parent === undefined ? null : (parents.get(parent) ?? null);\n });\n },\n async accessWhere(principal, level, tools) {\n // A parent whose every row passes (`everyone(level)`, alone or in `anyOf`): any row\n // that has a parent, without listing every parent id (the final review's E1).\n const parentFilter = await tools.whereOf(from, principal, level);\n if (parentFilter !== \"none\" && Object.keys(parentFilter).length === 0) {\n return { [via]: { not: null } };\n }\n const parents = await tools.idsWhere(from, principal, level);\n return parents.length === 0 ? \"none\" : { [via]: { in: parents } };\n },\n });\n}\n","// `everyone(level)` (finding F2.7 of the quickdraw-chat migration): every\n// signed-in user has `level` on every row of the service, for rows anyone\n// may read (public profiles, public posts). It reads nothing: a principal is\n// all it needs, so a row id that does not exist is allowed too and answers\n// `NOT_FOUND` where the row would be read (whether a row exists is no secret\n// when everyone may read every row). It covers every surface a policy does,\n// method calls on a row, entity subscriptions and list filters, where\n// `rowless: true` on a method covers that method alone. In `anyOf` it gives\n// the floor the other policies raise: `anyOf(owner(\"id\"), everyone(\"Read\"))`\n// is Admin on one's own row and Read on everyone else's.\n\nimport { isAccessLevel, type AccessLevel } from \"../../../contract/access\";\nimport { meetsLevel } from \"../levels\";\nimport { definePolicy, levelsById, type AccessPolicy } from \"../policy\";\n\n/**\n * Every signed-in user has `level` on every row. Anonymous callers have no\n * principal and so no level: a `\"public\"` method is what serves them.\n *\n * @example\n * // public profiles: everyone reads them, each user edits their own\n * qd.defineService(user, { model: \"user\", access: anyOf(owner(\"id\"), everyone(\"Read\")), methods });\n */\nexport function everyone(level: AccessLevel): AccessPolicy<never, never> {\n if (!isAccessLevel(level) || level === \"Public\") {\n throw new TypeError('everyone(level): level is \"Read\", \"Moderate\" or \"Admin\"');\n }\n return definePolicy({\n kind: \"everyone\",\n level,\n reads: { columns: [], memberships: [], inherits: [], storage: false },\n levelsFor: (_principal, ids) => Promise.resolve(levelsById(ids, () => level)),\n accessWhere: (_principal, wanted) => Promise.resolve(meetsLevel(level, wanted) ? {} : \"none\"),\n });\n}\n","// The kits' `rowless` option: the kit methods whose access form is their\n// whole check on purpose. Each one's implementation carries `rowless: true`,\n// which `defineService`'s rowless check reads (`../access/rowless.ts`): on a\n// service with an access policy, a kit method whose input has `id` (the\n// read/write kit's `get`, the admin kit's `adminGet`, the sharing kit's\n// access-list methods) under a form that checks no row is refused unless it\n// is named here.\n\nimport type { AccessForm } from \"../access/types\";\n\n/**\n * The kit methods `value` names, each one of the kit's `names`; an empty set\n * when it is left out. `fail` reports what is wrong with it.\n */\nexport function rowlessMethods(\n value: unknown,\n names: readonly string[],\n fail: (message: string) => never,\n): ReadonlySet<string> {\n if (value === undefined) {\n return new Set();\n }\n if (!Array.isArray(value) || !value.every((name) => typeof name === \"string\")) {\n fail(\"rowless must list the kit's methods whose access is their whole check\");\n }\n const unknownName = value.find((name) => !names.includes(name));\n if (unknownName !== undefined) {\n fail(`rowless names \"${String(unknownName)}\", which is not one of the kit's methods`);\n }\n return new Set(value);\n}\n\n/** One kit method's implementation: its form and handler, with `rowless: true` when `rowless` names it. */\nexport function kitEntry(\n name: string,\n form: AccessForm,\n handler: object,\n rowless: ReadonlySet<string>,\n): object {\n return Object.freeze(\n rowless.has(name) ? { access: form, handler, rowless: true } : { access: form, handler },\n );\n}\n","// Which rows a read/write kit method may touch (RFC 0003 sections 4.3 and\n// 12.1). The method's access form decides who may call it, as for every\n// method; a method on one row (`get`, `update`, `delete`, `reorder`) is\n// checked on that row by an `{ entry }` form. A method on many rows cannot\n// be: `list`, `getMany`, `bulkUpdate` and `bulkDelete` keep only the rows on\n// which the service's policy gives the caller the method's row level, from\n// the same policy that answers `get`, so a list never shows a row `get`\n// would refuse. A service-wide `Admin` grant (with `adminBypass`) reaches\n// every row, as everywhere.\n//\n// The row level is the form's own (`{ entry: L }` or `{ scope: L }`), or\n// else `Read` for reads and `Moderate` for writes. A `\"public\"` read's rows\n// are public; a write always needs the level, so an anonymous caller writes\n// nothing, and a write on one row needs it on that row whatever its form\n// (`checkRowWrite`). A service-wide grant at level L is a row level of L on\n// every row where the form names `service` (`grantRowLevel`): such a read is\n// unfiltered, its rows stripped at the grant. A service without a policy has\n// no row-level access: there the form is the whole check, so `defineService`\n// takes only `\"public\"` or `{ service }` for its methods on many rows\n// (`everyRowProblem`).\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { isCustomAccess } from \"../../access/forms\";\nimport { meetsLevel, serviceGrant } from \"../../access/levels\";\nimport type { AccessFilter, RowLevel } from \"../../access/policy\";\nimport type { AccessForm } from \"../../access/types\";\nimport type { AnyService } from \"../../service\";\nimport type { CrudCall } from \"./runtime\";\n\n/** The level a method's rows need: its form's entry level, else its scope level, else `fallback`. */\nexport function rowLevel(form: AccessForm, fallback: AccessLevel): AccessLevel {\n if (typeof form !== \"object\" || isCustomAccess(form)) {\n return fallback;\n }\n return form.entry ?? form.scope ?? fallback;\n}\n\n/** True when a method's rows are not checked against a policy: a public read, or no policy. */\nfunction unchecked(call: CrudCall, form: AccessForm, use: \"read\" | \"write\"): boolean {\n return call.runtime.service.access === undefined || (use === \"read\" && form === \"public\");\n}\n\n/** True for `\"public\"`, or `{ service: L }` alone: a form that names who may reach every row. */\nfunction reachesEveryRow(form: AccessForm): boolean {\n if (form === \"public\") {\n return true;\n }\n return (\n typeof form === \"object\" &&\n !isCustomAccess(form) &&\n form.service !== undefined &&\n form.entry === undefined &&\n form.scope === undefined\n );\n}\n\n/**\n * Why a kit method on many rows (`list`, `getMany`, `search`, the bulk\n * methods) cannot run on `service` under `form`; `undefined` when it can. A\n * service with a model but no row policy has nothing to keep rows by, so\n * such a method reaches every row, and its form must say so outright:\n * `\"public\"` or `{ service }`. `\"authenticated\"`, `custom` or a `scope`\n * form would hand every row to anyone who passes it.\n */\nexport function everyRowProblem(\n service: Pick<AnyService, \"name\" | \"access\">,\n method: string,\n form: AccessForm,\n): string | undefined {\n if (service.access !== undefined || reachesEveryRow(form)) {\n return undefined;\n }\n return `${method} reaches every row of ${service.name}, which declares no access policy to keep rows by: give it \"public\" or { service } access, or declare the service's access policy`;\n}\n\n/**\n * The caller's service-wide grant as their level on every row: a grant at\n * level L is a row level of L on every row where the form names `service`\n * and the grant meets it (a grant below `Admin` counts only where `service`\n * is named, RFC 0003 section 4.1). `undefined` otherwise.\n */\nexport function grantRowLevel(call: CrudCall, form: AccessForm): AccessLevel | undefined {\n const { principal } = call;\n if (principal === null || typeof form !== \"object\" || isCustomAccess(form)) {\n return undefined;\n }\n const grant = serviceGrant(principal, call.runtime.service.name);\n return form.service !== undefined && meetsLevel(grant, form.service) ? grant : undefined;\n}\n\n/** True when the caller's service-wide grant reaches every row at `level` (`grantRowLevel`). */\nfunction grantReaches(call: CrudCall, form: AccessForm, level: AccessLevel): boolean {\n return meetsLevel(grantRowLevel(call, form), level);\n}\n\n/**\n * The filter matching the rows the caller may see at `level`, `\"none\"` when\n * it may see none, or `undefined` when every row is visible.\n */\nexport async function rowsWhere(\n call: CrudCall,\n form: AccessForm,\n level: AccessLevel,\n): Promise<AccessFilter | undefined> {\n if (unchecked(call, form, \"read\") || grantReaches(call, form, level)) {\n return undefined;\n }\n if (call.principal === null) {\n return \"none\";\n }\n const { access, service } = call.runtime;\n return await access.accessWhere(service.name, call.principal, level);\n}\n\n/** True for a form whose own check covered row `input.id` at `level`: `{ entry }` alone, on `id`. */\nfunction entryCovers(form: AccessForm, level: AccessLevel): boolean {\n return (\n typeof form === \"object\" &&\n !isCustomAccess(form) &&\n form.service === undefined &&\n (form.id === undefined || form.id === \"id\") &&\n meetsLevel(form.entry, level)\n );\n}\n\n/**\n * `FORBIDDEN` unless the caller has the method's row level on row `id`: a\n * kit write on one row (`update`, `delete`, `reorder`) of a service with a\n * policy needs it whatever its form says, so `update: \"authenticated\"`\n * edits no row. The level is the form's `entry` (or `scope`) level, else\n * `Moderate`; a service-wide grant the form names counts on every row. One\n * lookup, unless the form's own `entry` check already covered the row.\n */\nexport async function checkRowWrite(call: CrudCall, form: AccessForm, id: string): Promise<void> {\n const { access, service } = call.runtime;\n const level = rowLevel(form, \"Moderate\");\n if (service.access === undefined || grantReaches(call, form, level) || entryCovers(form, level)) {\n return;\n }\n const levels =\n call.principal === null\n ? undefined\n : await access.levelsFor(service.name, call.principal, [id]);\n if (!meetsLevel(levels?.get(id), level)) {\n throw new QuickdrawError(\"FORBIDDEN\", \"Insufficient permissions\");\n }\n}\n\n/**\n * The ids among `ids` on which the caller has at least `level`, in order:\n * one batched lookup. `use` says whether the method reads or writes them.\n */\nexport async function allowedIds(\n call: CrudCall,\n form: AccessForm,\n ids: readonly string[],\n level: AccessLevel,\n use: \"read\" | \"write\",\n): Promise<string[]> {\n if (unchecked(call, form, use) || ids.length === 0 || grantReaches(call, form, level)) {\n return [...ids];\n }\n if (call.principal === null) {\n return [];\n }\n const { access, service } = call.runtime;\n const levels = await access.levelsFor(service.name, call.principal, ids);\n return ids.filter((id) => meetsLevel(levels.get(id), level));\n}\n\n/**\n * The level whose field tiers a list's items are stripped to. Like a\n * collection's items (RFC 0003 section 7.2), a page's items are stripped\n * once, at the level the page was filtered at, not per row: `Admin` for a\n * service-wide `Admin` grant, the grant for one the form names that reaches\n * every row (`grantRowLevel`), and no level for rows no policy checked.\n */\nexport function readerLevel(call: CrudCall, form: AccessForm, level: AccessLevel): RowLevel {\n const { service } = call.runtime;\n const grant = call.principal === null ? undefined : serviceGrant(call.principal, service.name);\n if (service.adminBypass && grant === \"Admin\") {\n return \"Admin\";\n }\n const granted = grantRowLevel(call, form);\n if (unchecked(call, form, \"read\")) {\n return granted ?? null;\n }\n return granted !== undefined && meetsLevel(granted, level) ? granted : level;\n}\n","// The columns a kit write may set (RFC 0003 sections 4.2, 4.4 and 12). A\n// write of the read/write kit (`update`, `bulkUpdate`) or of the admin kit\n// (`adminCreate`, `adminUpdate`) that names a column deciding who may reach\n// the row would hand its caller access the policy never gave them: a member\n// making themselves the owner, or a row moved into a project its mover\n// cannot open. So, unless the caller holds a service-wide `Admin` grant\n// (with `adminBypass`), which writes any column:\n//\n// - a column the service's policy reads (an owner column, an access list) is\n// read-only;\n// - a column that places the row under an anchor row (an `inherit` policy's\n// `via`, an anchored collection's scope column) may move it only into an\n// anchor row on which the caller's level, from that row's own policy (as\n// `inherit` and collection scopes count it, without grants on its\n// service), meets the method's row level. Setting it to null moves the row\n// out of every anchor, which needs nothing more.\n//\n// Statements: one engine call per anchor column the write sets (the anchor\n// policy's reads), none otherwise.\n\nimport type { AccessLevel } from \"../../contract/access\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport { meetsLevel, serviceGrant } from \"../access/levels\";\nimport type { KitRuntime } from \"../context\";\nimport type { AnyService } from \"../service\";\nimport type { Principal } from \"../types\";\n\n/** A column whose value is the id of an anchor row, and the service that row belongs to. */\ninterface AnchorColumn {\n readonly column: string;\n readonly anchor: string;\n}\n\n/** The columns of a service's rows that decide who may reach them. */\ninterface GuardedColumns {\n /** Read-only unless the caller holds a service-wide `Admin` grant. */\n readonly locked: ReadonlySet<string>;\n /** Writable into an anchor row the caller has the method's row level on. */\n readonly anchors: readonly AnchorColumn[];\n}\n\nfunction guardedColumns(service: AnyService): GuardedColumns {\n const reads = service.access?.reads;\n const anchors = new Map<string, AnchorColumn>();\n const add = (column: string, anchor: string): void => {\n anchors.set(`${column}\\u0000${anchor}`, { column, anchor });\n };\n for (const { from, via } of reads?.parents ?? []) {\n add(via, from.name);\n }\n for (const collection of service.collections.values()) {\n if (collection.anchor !== undefined && collection.scope.kind === \"column\") {\n add(collection.scope.column, collection.anchor.name);\n }\n }\n const moving = new Set([...anchors.values()].map(({ column }) => column));\n const locked = (reads?.columns ?? []).filter((column) => column !== \"id\" && !moving.has(column));\n return { locked: new Set(locked), anchors: [...anchors.values()] };\n}\n\nfunction forbidden(message: string): QuickdrawError {\n return new QuickdrawError(\"FORBIDDEN\", message);\n}\n\n/** True when the principal's service-wide `Admin` grant passes every check on the service. */\nfunction bypasses(service: AnyService, principal: Principal | null): boolean {\n return (\n principal !== null && service.adminBypass && serviceGrant(principal, service.name) === \"Admin\"\n );\n}\n\n/**\n * `FORBIDDEN` unless the caller may set every column `data` gives a value\n * (`undefined` is no value), in a write whose rows need `level`: no column\n * the policy reads, and each anchor column only to an anchor row the caller\n * has `level` on (or null).\n */\nexport async function checkWritableColumns(\n runtime: Pick<KitRuntime, \"service\" | \"access\">,\n principal: Principal | null,\n data: Readonly<Record<string, unknown>>,\n level: AccessLevel,\n): Promise<void> {\n const { service, access } = runtime;\n if (bypasses(service, principal)) {\n return;\n }\n const { locked, anchors } = guardedColumns(service);\n const named = new Set(Object.keys(data).filter((column) => data[column] !== undefined));\n const readOnly = [...named].find((column) => locked.has(column));\n if (readOnly !== undefined) {\n throw forbidden(\n `\"${readOnly}\" decides who may reach rows of ${service.name}: only a service-wide Admin may change it`,\n );\n }\n for (const { column, anchor } of anchors) {\n const target = data[column];\n if (!named.has(column) || target === null) {\n continue;\n }\n const valid = principal !== null && typeof target === \"string\" && target.length > 0;\n const resolved = valid\n ? await access.resolve(anchor, principal, [target], { grants: false })\n : undefined;\n if (resolved === undefined || !meetsLevel(resolved.levels.get(target as string), level)) {\n throw forbidden(\n `Moving a row of ${service.name} by \"${column}\" needs ${level} on the ${anchor} row it moves into`,\n );\n }\n }\n}\n","// The interactive transactions the kits write in (RFC 0003 sections 5.1 and\n// 12). A transaction's writes join the call's unit of work when it commits\n// and are dropped when it rolls back; the framework's own reads inside it\n// (access policies) go through its client.\n//\n// A kit change that reads rows and writes what it decided from them (a\n// sharing change, a `reorder`) runs SERIALIZABLE: PostgreSQL's default\n// isolation (READ COMMITTED) would let two changes that run at once both read\n// the old state, and the second write undo the first. Under SERIALIZABLE the\n// database fails one of them instead, which the kit answers `CONFLICT`, and\n// the caller may try again.\n\nimport { QuickdrawError } from \"../../protocol/errors\";\n\n/** How a kit's transaction runs. */\nexport interface KitTransaction {\n /** Who runs it, for the error when the client has no `$transaction`: \"The sharing kit's changes\". */\n readonly owner: string;\n /**\n * Run SERIALIZABLE, answering a transaction the database fails for a\n * concurrent one with `CONFLICT` and this message. Default isolation without it.\n */\n readonly conflict?: string;\n /** The transaction's time limit in milliseconds; the client's default (Prisma's is 5 s) without it. */\n readonly timeoutMs?: number;\n}\n\n/**\n * True for Prisma's report of a transaction the database failed for a\n * concurrent one: `P2034` when a statement fails (a concurrent update of the\n * row), and the driver adapter's own `TransactionWriteConflict` when the\n * commit does (PostgreSQL finds most serialization failures only then;\n * Prisma 7 passes that one through unmapped).\n */\nfunction isWriteConflict(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if (error.name === \"PrismaClientKnownRequestError\") {\n return (error as Error & { readonly code?: unknown }).code === \"P2034\";\n }\n const kind: unknown = (error.cause as { readonly kind?: unknown } | undefined)?.kind;\n return error.name === \"DriverAdapterError\" && kind === \"TransactionWriteConflict\";\n}\n\nfunction optionsOf(how: KitTransaction): object | undefined {\n const options = {\n ...(how.conflict === undefined ? {} : { isolationLevel: \"Serializable\" }),\n ...(how.timeoutMs === undefined ? {} : { timeout: how.timeoutMs }),\n };\n return Object.keys(options).length === 0 ? undefined : Object.freeze(options);\n}\n\n/** Runs `fn` in an interactive transaction of the database client, as `how` says. */\nexport async function inKitTransaction<T>(\n db: unknown,\n fn: (tx: unknown) => Promise<T>,\n how: KitTransaction,\n): Promise<T> {\n const client = db as { readonly $transaction?: unknown } | null;\n if (typeof client?.$transaction !== \"function\") {\n throw new QuickdrawError(\"INTERNAL\", `${how.owner} need a database client with $transaction`);\n }\n const run = client.$transaction as (\n callback: (tx: unknown) => Promise<T>,\n options?: object,\n ) => Promise<T>;\n const options = optionsOf(how);\n try {\n return options === undefined ? await run.call(client, fn) : await run.call(client, fn, options);\n } catch (error) {\n if (how.conflict === undefined || !isWriteConflict(error)) {\n throw error;\n }\n const conflict = new QuickdrawError(\"CONFLICT\", how.conflict);\n conflict.cause = error;\n throw conflict;\n }\n}\n","// What every handler of the read/write kit starts from (RFC 0003 section\n// 12.1): the service its method runs in, found through the call's `ctx`\n// (`kitRuntimeOf`), and the service's model on the dispatcher's tracked\n// database client. The kit reads and writes through that client, as a\n// hand-written handler does, so every write is tracked and its frames are\n// sent by the flush; the kit never sends one itself.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { kitRuntimeOf, type KitRuntime } from \"../../context\";\nimport type { Projection } from \"../../emit/projection\";\nimport { modelKey } from \"../../storage\";\nimport type { Principal } from \"../../types\";\nimport { inKitTransaction } from \"../transactions\";\n\n/** A row as the database client returns it. */\nexport type Row = Readonly<Record<string, unknown>>;\n\n/** The model methods the kit calls: a Prisma model delegate, structurally. */\nexport interface ModelDelegate {\n findUnique(args: object): Promise<Row | null>;\n findFirst(args: object): Promise<Row | null>;\n findMany(args: object): Promise<Row[]>;\n count(args: object): Promise<number>;\n create(args: object): Promise<Row>;\n update(args: object): Promise<Row>;\n delete(args: object): Promise<Row>;\n updateMany(args: object): Promise<{ readonly count: number }>;\n deleteMany(args: object): Promise<{ readonly count: number }>;\n aggregate(args: object): Promise<Row>;\n}\n\n/** What a kit handler is called with, whatever the app's own types. */\nexport interface KitHandlerArgs<Db = unknown> {\n readonly input: unknown;\n /** The call's `ctx`; a dispatcher's always carries its `signal`. */\n readonly ctx: { readonly principal: Principal | null; readonly signal?: AbortSignal };\n /** The app's database client. */\n readonly db: Db;\n}\n\n/**\n * A handler of a kit method. `Out` is what it resolves with: the row (or\n * rows, or page) its method's output names, which the framework projects as\n * for any handler. A kit that types it (the admin kit: its methods' output\n * types) lets an app wrap a handler and read what it returned with no cast;\n * one that leaves it `never` fits the method of any app's service. `Db` is\n * the app's database client type, as the app's callbacks (`prepare`,\n * `resolveUser`, `onChange`, `onWrite`) annotate their `db`, so a wrong\n * annotation is refused where the handlers are spread into\n * `qd.defineService`.\n */\nexport type KitHandler<Db = unknown, Out = never> = (args: KitHandlerArgs<Db>) => Promise<Out>;\n\n/** One call of a kit method: the service it runs in, its model's delegate, and the caller. */\nexport interface CrudCall {\n readonly runtime: KitRuntime;\n /** The model, named as the database client names it: `\"task\"`. */\n readonly model: string;\n readonly table: ModelDelegate;\n readonly principal: Principal | null;\n}\n\n/** The delegate of `model` on a database client (or a transaction's client). */\nexport function delegateOf(db: unknown, model: string): ModelDelegate {\n const name = modelKey(model);\n const isClient = (typeof db === \"object\" || typeof db === \"function\") && db !== null;\n const delegate: unknown = isClient ? Reflect.get(db, name) : undefined;\n const usable =\n typeof delegate === \"object\" &&\n delegate !== null &&\n typeof (delegate as { readonly findMany?: unknown }).findMany === \"function\";\n if (!usable) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit reads and writes through db.${name}, which the dispatcher's database client does not have`,\n );\n }\n return delegate as ModelDelegate;\n}\n\n/** The kit call `ctx` belongs to: its service and model, and the caller. */\nexport function crudCall(ctx: KitHandlerArgs[\"ctx\"], db: unknown): CrudCall {\n const runtime = kitRuntimeOf(ctx);\n const model = runtime?.service.model;\n if (runtime === undefined || model === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The read/write kit's handlers run through a dispatcher, in a service with a model\",\n );\n }\n return {\n runtime,\n model: modelKey(model),\n table: delegateOf(db, model),\n principal: ctx.principal,\n };\n}\n\n/**\n * Runs `fn` in an interactive transaction of the database client: its writes\n * join the call's unit of work when it commits, and are dropped when it\n * rolls back. Reads the framework makes inside it (access policies) go\n * through the transaction too.\n */\nexport async function inTransaction<T>(db: unknown, fn: (tx: unknown) => Promise<T>): Promise<T> {\n return await inKitTransaction(db, fn, { owner: \"The read/write kit's bulk methods\" });\n}\n\n/** A projection of the call's service, by name. */\nexport function projectionOf(call: CrudCall, name: string): Projection {\n const projection = call.runtime.service.projections.get(name);\n if (projection === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit asked ${call.runtime.service.name} for projection \"${name}\", which it does not have`,\n );\n }\n return projection;\n}\n\n/** The ids in `ids`, each once, in order. */\nexport function uniqueIds(ids: readonly string[]): string[] {\n return [...new Set(ids)];\n}\n","// Guards for handlers, the kits' own and hand-written ones (RFC 0003 section\n// 12). Four 4.1 apps copy a `services/shared/guards.ts` of these.\n\nimport { QuickdrawError } from \"../../protocol/errors\";\n\n/**\n * The row a read found, or `NOT_FOUND` with `message` when it found none.\n *\n * @example\n * const task = requireRow(await db.task.findUnique({ where: { id } }), \"No such task\");\n */\nexport function requireRow<Row>(row: Row | null | undefined, message = \"Not found\"): Row {\n if (row === null || row === undefined) {\n throw new QuickdrawError(\"NOT_FOUND\", message);\n }\n return row;\n}\n","// The read/write kit's `update` (RFC 0003 section 12.1): `db.<model>.update`\n// with the fields the call gives (the app's patch schema decides which). The\n// tracked client records the changed fields, so subscribers get a patch\n// (`p`) and collections a `patched` delta. A row that is not there is\n// `NOT_FOUND`, a unique violation `CONFLICT`. A call that changes nothing\n// reads the row instead of writing it. The caller needs the method's row\n// level on the row whatever the form (`checkRowWrite`), and a patch may not\n// set a column that decides access to the row, nor move it into an anchor\n// row the caller does not have that level on (`../columns.ts`).\n\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWritableColumns } from \"../columns\";\nimport { requireRow } from \"../guards\";\nimport { checkRowWrite, rowLevel } from \"./access\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** The fields a patch sets: its keys with a value, never `id`. */\nexport function patchData(patch: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(patch).filter(([key, value]) => key !== \"id\" && value !== undefined),\n );\n}\n\n/** The `update` handler. */\nexport function updateHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = crudCall(ctx, db);\n const { id, ...patch } = input as { readonly id: string } & Record<string, unknown>;\n const data = patchData(patch);\n const { select } = projectionOf(call, \"entity\");\n await checkRowWrite(call, form, id);\n await checkWritableColumns(call.runtime, call.principal, data, rowLevel(form, \"Moderate\"));\n if (Object.keys(data).length === 0) {\n return requireRow(\n await call.table.findUnique({ where: { id }, select }),\n `No such ${call.model}`,\n );\n }\n return await call.table.update({ where: { id }, data, select });\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `bulkUpdate` and `bulkDelete` (RFC 0003 section\n// 12.1): one `updateMany` or `deleteMany` over the ids the caller may write,\n// in one transaction with the policy lookup that picked them. Ids the caller\n// cannot write at the method's row level (`Moderate` unless the form names\n// another), and ids with no row, are skipped, even for a `\"public\"` method;\n// the result counts the rows changed. The tracked client records every row, and a flush touching more\n// rows of one collection scope than its `bulkThreshold` sends that scope one\n// `reset` instead of a delta per row. `bulkUpdate`'s data may not set a\n// column that decides access, nor move the rows into an anchor row the\n// caller lacks the row level on (`../columns.ts`).\n\nimport type { IdsInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWritableColumns } from \"../columns\";\nimport { allowedIds, rowLevel } from \"./access\";\nimport {\n crudCall,\n delegateOf,\n inTransaction,\n uniqueIds,\n type CrudCall,\n type KitHandler,\n type KitHandlerArgs,\n type ModelDelegate,\n} from \"./runtime\";\nimport { patchData } from \"./update\";\n\ninterface Counted {\n readonly count: number;\n}\n\n/** Runs `write` on the ids among `ids` the caller may write, inside one transaction. */\nasync function writeAllowed(\n call: CrudCall,\n db: unknown,\n form: AccessForm,\n ids: readonly string[],\n write: (table: ModelDelegate, allowed: readonly string[]) => Promise<Counted>,\n): Promise<Counted> {\n const unique = uniqueIds(ids);\n if (unique.length === 0) {\n return { count: 0 };\n }\n return await inTransaction(db, async (tx) => {\n const allowed = await allowedIds(call, form, unique, rowLevel(form, \"Moderate\"), \"write\");\n if (allowed.length === 0) {\n return { count: 0 };\n }\n const { count } = await write(delegateOf(tx, call.model), allowed);\n return { count };\n });\n}\n\n/** The `bulkUpdate` handler. */\nexport function bulkUpdateHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Counted> => {\n const call = crudCall(ctx, db);\n const { ids, data } = input as {\n readonly ids: readonly string[];\n readonly data: Readonly<Record<string, unknown>>;\n };\n const patch = patchData(data);\n if (Object.keys(patch).length === 0) {\n return { count: 0 };\n }\n await checkWritableColumns(call.runtime, call.principal, patch, rowLevel(form, \"Moderate\"));\n return await writeAllowed(call, db, form, ids, (table, allowed) =>\n table.updateMany({ where: { id: { in: [...allowed] } }, data: patch }),\n );\n };\n return handler as KitHandler;\n}\n\n/** The `bulkDelete` handler. */\nexport function bulkDeleteHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Counted> => {\n const call = crudCall(ctx, db);\n return await writeAllowed(call, db, form, (input as IdsInput).ids, (table, allowed) =>\n table.deleteMany({ where: { id: { in: [...allowed] } } }),\n );\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `create` (RFC 0003 section 12.1): `db.<model>.create`\n// with the caller's input, or what the service's `prepare` makes of it (an\n// owner or scope column from the principal, an ordinal from `nextOrdinal`).\n// The tracked client records the write, so the flush sends the new row to\n// its collections as `added`. A unique violation is `CONFLICT`.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { checked } from \"../../devWarnings\";\nimport type { MaybePromise, Principal } from \"../../types\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** `prepare(input, ctx, db)`: the data `create` writes, from the parsed input; `db` is the app's client. */\nexport type CrudPrepare<Input = never, Ctx = never, Db = unknown> = (\n input: Input,\n ctx: Ctx,\n db: Db,\n) => MaybePromise<Readonly<Record<string, unknown>>>;\n\n/** `prepare` as the handler calls it. */\nexport type AnyPrepare = (\n input: unknown,\n ctx: { readonly principal: Principal | null },\n db: unknown,\n) => MaybePromise<unknown>;\n\n/** The `create` handler. */\nexport function createHandler(prepare: AnyPrepare | undefined): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = crudCall(ctx, db);\n // The app's prepare is the app's code: its statements are checked.\n const data = prepare === undefined ? input : await checked(() => prepare(input, ctx, db));\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit's prepare for ${call.runtime.service.name} must return the new row's data`,\n );\n }\n const { select } = projectionOf(call, \"entity\");\n return await call.table.create({ data, select });\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `delete` (RFC 0003 section 12.1): `db.<model>.delete`.\n// The tracked client records it, so subscribers get `r` and collections a\n// `removed` delta. A row that is not there is `NOT_FOUND`. There is no soft\n// delete: no consumer app uses one.\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkRowWrite } from \"./access\";\nimport { crudCall, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** The `delete` handler: the caller needs the method's row level on the row whatever the form. */\nexport function deleteHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<null> => {\n const call = crudCall(ctx, db);\n const { id } = input as IdInput;\n await checkRowWrite(call, form, id);\n await call.table.delete({ where: { id }, select: { id: true } });\n return null;\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `get` (RFC 0003 section 12.1): one row by id, read\n// with its projection's select (one statement). Its access form decides who\n// may read the row; `{ entry: \"Read\" }` checks the row itself. A row that is\n// not there is `NOT_FOUND` (for a caller the form let through: an `entry`\n// check already refuses a missing row with `FORBIDDEN`).\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport { requireRow } from \"../guards\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** The `get` handler. */\nexport function getHandler(): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = crudCall(ctx, db);\n const { id } = input as IdInput;\n const { select } = projectionOf(call, \"entity\");\n return requireRow(\n await call.table.findUnique({ where: { id }, select }),\n `No such ${call.model}`,\n );\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `getMany` (RFC 0003 section 12.1): up to 200 rows by\n// id, in the order asked. The caller's level on every id comes from one\n// batched policy lookup (`levelsFor`), and the ids it does not reach at the\n// method's row level are left out, as are ids with no row: a caller learns\n// nothing about rows it may not read. The rows are then read in one\n// statement with the entity's select; the framework projects them.\n\nimport type { IdsInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AccessForm } from \"../../access/types\";\nimport { allowedIds, rowLevel } from \"./access\";\nimport {\n crudCall,\n projectionOf,\n uniqueIds,\n type KitHandler,\n type KitHandlerArgs,\n type Row,\n} from \"./runtime\";\n\n/** The `getMany` handler. */\nexport function getManyHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Row[]> => {\n const call = crudCall(ctx, db);\n const ids = uniqueIds((input as IdsInput).ids);\n const allowed = await allowedIds(call, form, ids, rowLevel(form, \"Read\"), \"read\");\n if (allowed.length === 0) {\n return [];\n }\n const { select } = projectionOf(call, \"entity\");\n const rows = await call.table.findMany({ where: { id: { in: allowed } }, select });\n const byId = new Map(rows.map((row) => [row.id, row]));\n return allowed.flatMap((id) => {\n const row = byId.get(id);\n return row === undefined ? [] : [row];\n });\n };\n return handler as KitHandler;\n}\n","// The order and the filter of a read/write kit `list` page (RFC 0003 section\n// 12.1), from the caller's parsed input: only declared fields reach here\n// (the contract's input schema refuses any other), and a filter is equality\n// on plain values, so nothing the caller sends becomes a query operator.\n//\n// Nor may a call name a field the caller does not receive (a field tier,\n// RFC 0003 section 6): whether a row passes an equality filter tells what\n// the field holds, and a sort puts the field's values in the page's cursor\n// and its order. Such a call is `FORBIDDEN`, and a default sort on such a\n// field falls back to `id`. The admin kit's `adminList` follows the same\n// rules.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport type { ListQuery } from \"../../../contract/kits/crudList\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { StorageWhere } from \"../../storage\";\n\n/** The fields a list call names: its filter's and its sort's. */\nexport function namedFields(query: Pick<ListQuery, \"filter\" | \"sort\">): string[] {\n return [...Object.keys(query.filter), ...(query.sort === undefined ? [] : [query.sort.field])];\n}\n\n/** `FORBIDDEN` when a call names one of the `hidden` fields of `service`: above the caller's level. */\nexport function checkVisible(\n service: string,\n hidden: ReadonlySet<string>,\n names: readonly string[],\n): void {\n const unseen = names.find((name) => hidden.has(name));\n if (unseen !== undefined) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `\"${unseen}\" is a field of ${service} above your access level`,\n );\n }\n}\n\n/** The declared sort fields a page may default to: none when the first is `hidden`, so the page sorts by `id`. */\nexport function defaultSorts(\n sortFields: readonly string[],\n hidden: ReadonlySet<string>,\n): readonly string[] {\n const [first] = sortFields;\n return first !== undefined && hidden.has(first) ? [] : sortFields;\n}\n\n/** The order of a page: the caller's sort, else the first declared sort field, else `id`; `id` last. */\nexport function listOrder(sortFields: readonly string[], sort: ListQuery[\"sort\"]): OrderBy {\n const field = sort?.field ?? sortFields[0];\n const direction = sort?.direction ?? \"asc\";\n if (field === undefined || field === \"id\") {\n return [[\"id\", direction]];\n }\n return [\n [field, direction],\n [\"id\", direction],\n ];\n}\n\n/** The caller's equality filter and the access filter, together. */\nexport function listWhere(\n filter: ListQuery[\"filter\"],\n access: StorageWhere | undefined,\n): StorageWhere {\n const equal = Object.fromEntries(\n Object.entries(filter).filter(([, value]) => value !== undefined),\n );\n const parts = [equal, access ?? {}].filter((part) => Object.keys(part).length > 0);\n return parts.length > 1 ? { AND: parts } : (parts[0] ?? {});\n}\n","// One page of rows by keyset cursor (RFC 0003 sections 7.3 and 12.1), for\n// the read/write kit's `list` and the kits built on it (search). It reuses\n// the collections' cursor (`collections/cursor.ts`): a cursor holds the last\n// row's value of each order column, `id` last, so the next page starts right\n// after that row however many rows are inserted or removed before it.\n//\n// A list can be sorted several ways, so its cursors also name the order they\n// were made for; a cursor from another order, or any string that is not a\n// cursor, is `VALIDATION`. So is a filter value or cursor value the\n// database refuses for its column's type.\n//\n// A page costs one statement, plus a second when the call counts the rows,\n// run beside the first. The first page of a sort on an optional column also\n// asks the storage adapter once per process whether it may hold null.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { afterCursor, decodeCursor, encodeCursor, orderByOf } from \"../../collections/cursor\";\nimport type { StorageAdapter, StorageWhere } from \"../../storage\";\nimport { unreadable } from \"../../transports/ack\";\nimport type { ModelDelegate, Row } from \"./runtime\";\n\n/** What one page reads. */\nexport interface PageRead {\n readonly table: ModelDelegate;\n /** The model, named as the client names it, for the storage adapter's `nullable`. */\n readonly model: string;\n readonly storage: StorageAdapter | undefined;\n /** The rows to page through: the caller's filter and the access filter. */\n readonly where: StorageWhere;\n /** Sort columns ending in `id`. */\n readonly order: OrderBy;\n readonly cursor: string | undefined;\n readonly limit: number;\n /** What each row is read with; it must include every order column. */\n readonly select: Readonly<Record<string, unknown>>;\n /** Count every row `where` matches, too. */\n readonly totalCount: boolean;\n /**\n * Whether `where` holds values the caller sent (a filter): a database\n * refusal of them, like one of the cursor's, is then `VALIDATION`.\n */\n readonly filtered: boolean;\n}\n\n/** One page of rows. */\nexport interface RowsPage {\n readonly rows: Row[];\n /** The cursor of the next page, or `null` on the last one. */\n readonly nextCursor: string | null;\n readonly totalCount?: number;\n}\n\nconst SIGNATURE = \"~order\";\n\nconst NOT_A_CURSOR = \"cursor is not a cursor of this list in this order\";\n\n/** The order a cursor was made for, as the cursor carries it. */\nfunction signatureOf(order: OrderBy): string {\n return order.map(([column, direction]) => `${column} ${direction}`).join(\",\");\n}\n\n/** `order` with the signature as a first, pseudo column. */\nfunction signed(order: OrderBy): OrderBy {\n return [[SIGNATURE, \"asc\"], ...order] as unknown as OrderBy;\n}\n\n/** The cursor of the page after `row`. */\nexport function cursorAfter(order: OrderBy, row: Row): string {\n return encodeCursor(signed(order), { ...row, [SIGNATURE]: signatureOf(order) });\n}\n\n/** The order column values a cursor holds, or `VALIDATION` for one that is not a cursor of `order`. */\nexport function cursorValues(order: OrderBy, cursor: string): readonly unknown[] {\n let values: readonly unknown[];\n try {\n values = decodeCursor(signed(order), cursor);\n } catch {\n throw unreadable(NOT_A_CURSOR, [\"cursor\"]);\n }\n if (values[0] !== signatureOf(order)) {\n throw unreadable(NOT_A_CURSOR, [\"cursor\"]);\n }\n return values.slice(1);\n}\n\n/**\n * The order columns that may hold null, as the storage adapter answers. A\n * cursor holding null for a column the adapter says cannot hold it is not a\n * cursor of this list.\n */\nasync function nullableColumns(\n read: PageRead,\n values: readonly unknown[] | undefined,\n): Promise<Set<string>> {\n const { storage, model, order } = read;\n const nullable = new Set<string>();\n for (const [index, [column]] of order.entries()) {\n const value = values?.[index];\n const known = column === \"id\" ? false : await storage?.nullable?.(model, column);\n if (value === null && known === false) {\n throw unreadable(NOT_A_CURSOR, [\"cursor\"]);\n }\n if (known === true || value === null) {\n nullable.add(column);\n }\n }\n return nullable;\n}\n\n/**\n * A database refusal of the caller's values (a filter or a cursor), as\n * `VALIDATION`; anything else unchanged. The admin kit's `adminList` too.\n */\nexport function refusal(error: unknown, read: Pick<PageRead, \"cursor\" | \"filtered\">): unknown {\n const isValidation = error instanceof Error && error.name === \"PrismaClientValidationError\";\n if (!isValidation || (read.cursor === undefined && !read.filtered)) {\n return error;\n }\n const refused = new QuickdrawError(\n \"VALIDATION\",\n \"The filter or the cursor does not fit its fields\",\n {\n issues: [\n {\n path: read.cursor === undefined ? [\"filter\"] : [],\n message: \"A filter or cursor value does not fit its field's type\",\n },\n ],\n },\n );\n refused.cause = error;\n return refused;\n}\n\n/** Reads one page: `limit` rows after the cursor, in `order`, the next cursor, and the count when asked. */\nexport async function readPage(read: PageRead): Promise<RowsPage> {\n const values = read.cursor === undefined ? undefined : cursorValues(read.order, read.cursor);\n const nullable = await nullableColumns(read, values);\n const where =\n values === undefined\n ? read.where\n : { AND: [read.where, afterCursor(read.order, values, nullable)] };\n let rows: Row[];\n let total: number | undefined;\n try {\n [rows, total] = await Promise.all([\n read.table.findMany({\n where,\n select: read.select,\n orderBy: orderByOf(read.order, nullable),\n take: read.limit + 1,\n }),\n read.totalCount ? read.table.count({ where: read.where }) : undefined,\n ]);\n } catch (error) {\n throw refusal(error, read);\n }\n const shown = rows.slice(0, read.limit);\n const last = shown.at(-1);\n return {\n rows: shown,\n nextCursor:\n rows.length > read.limit && last !== undefined ? cursorAfter(read.order, last) : null,\n ...(total === undefined ? {} : { totalCount: total }),\n };\n}\n","// The read/write kit's `list` (RFC 0003 section 12.1): one page of the rows\n// the caller may read, filtered and sorted by the fields the contract\n// declares, by keyset cursor (`page.ts`). The trap it exists to close: the\n// policy's `accessWhere` is part of every read, so a list never returns a row\n// `get` would refuse. Items are the declared projection's rows (its select,\n// its map, dates as ISO strings), stripped of the fields above the level\n// the page was filtered at; a filter or sort on such a field is `FORBIDDEN`\n// (`listQuery.ts`), since the rows it keeps and the cursor it makes would\n// tell what the field holds.\n//\n// Statements: the access filter's own reads (none for `owner` and `jsonAcl`\n// policies or a service-wide `Admin` grant), then one for the page, and one\n// more beside it when the call asks for `totalCount`.\n\nimport type { CrudSpec } from \"../../../contract/kits/crud\";\nimport type { ListPage, ListQuery } from \"../../../contract/kits/crudList\";\nimport type { AccessForm } from \"../../access/types\";\nimport { selectWith } from \"../../collections/items\";\nimport { projectRow, type Projection } from \"../../emit/projection\";\nimport { strip } from \"../../emit/tiers\";\nimport { readerLevel, rowLevel, rowsWhere } from \"./access\";\nimport { checkVisible, defaultSorts, listOrder, listWhere, namedFields } from \"./listQuery\";\nimport { readPage } from \"./page\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** What a `list` handler is made from. */\nexport interface ListContext {\n readonly spec: Extract<CrudSpec, { method: \"list\" }>;\n readonly form: AccessForm;\n /** The projection the items are: `\"entity\"` or one of the contract's. */\n readonly projection: string;\n}\n\n/** One row of a page as an item: projected, without the `hidden` fields. The search kit's too. */\nexport function pageItem(\n projection: Projection,\n row: object,\n hidden: ReadonlySet<string>,\n): unknown {\n const item = projectRow(projection, row);\n return typeof item === \"object\" && item !== null\n ? strip(item as Readonly<Record<string, unknown>>, hidden)\n : item;\n}\n\nfunction emptyPage(query: ListQuery): ListPage<never> {\n return { items: [], nextCursor: null, ...(query.totalCount ? { totalCount: 0 } : {}) };\n}\n\n/** The `list` handler. */\nexport function listHandler(context: ListContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ListPage<unknown>> => {\n const call = crudCall(ctx, db);\n const query = input as ListQuery;\n const level = rowLevel(context.form, \"Read\");\n const reader = readerLevel(call, context.form, level);\n const unseen = projectionOf(call, \"entity\").tiers.hidden(reader);\n checkVisible(call.runtime.service.name, unseen, namedFields(query));\n const access = await rowsWhere(call, context.form, level);\n if (access === \"none\") {\n return emptyPage(query);\n }\n const projection = projectionOf(call, context.projection);\n const order = listOrder(defaultSorts(context.spec.sort, unseen), query.sort);\n const page = await readPage({\n table: call.table,\n model: call.model,\n storage: call.runtime.storage,\n where: listWhere(query.filter, access),\n order,\n cursor: query.cursor,\n limit: query.limit,\n select: selectWith(\n projection.select,\n order.map(([column]) => column),\n ),\n totalCount: query.totalCount,\n filtered: Object.keys(query.filter).length > 0,\n });\n const hidden = projection.tiers.hidden(reader);\n return {\n items: page.rows.map((row) => pageItem(projection, row, hidden)),\n nextCursor: page.nextCursor,\n ...(page.totalCount === undefined ? {} : { totalCount: page.totalCount }),\n };\n };\n return handler as KitHandler;\n}\n","// Ordinals for the read/write kit's `reorder` (RFC 0003 section 12.1): rows\n// are kept apart by gaps of `ORDINAL_STEP`, so a row moves between two others\n// by taking the whole number halfway between them, and only that row is\n// written. When no whole number is left between them (about ten moves into\n// one gap), the ordered list is renumbered in steps. Whole numbers suit\n// `Int` and `Float` columns alike, and stay within a 32-bit integer.\n\nimport type { StorageWhere } from \"../../storage\";\nimport { delegateOf } from \"./runtime\";\n\n/** The gap between the ordinals of neighboring rows, after a renumbering and for `nextOrdinal`. */\nexport const ORDINAL_STEP = 1024;\n\nconst MIN_ORDINAL = -2_147_483_648;\nconst MAX_ORDINAL = 2_147_483_647;\n\n/** A number an ordinal column may hold: finite, and within a 32-bit integer. */\nexport function isOrdinal(value: unknown): value is number {\n return (\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n value >= MIN_ORDINAL &&\n value <= MAX_ORDINAL\n );\n}\n\n/**\n * A whole number strictly between `low` and `high`, a step below `high` when\n * there is no `low` (the start of the list), a step above `low` when there is\n * no `high` (its end); `undefined` when there is none left.\n */\nexport function ordinalBetween(\n low: number | undefined,\n high: number | undefined,\n): number | undefined {\n let value: number | undefined;\n if (low === undefined && high !== undefined) {\n value = Math.ceil(high) - ORDINAL_STEP;\n } else if (high === undefined && low !== undefined) {\n value = Math.floor(low) + ORDINAL_STEP;\n } else if (low !== undefined && high !== undefined) {\n const middle = Math.floor((low + high) / 2);\n value = middle > low && middle < high ? middle : undefined;\n }\n return isOrdinal(value) ? value : undefined;\n}\n\n/** Options of {@link nextOrdinal}. */\nexport interface NextOrdinalOptions {\n /** The ordinal column. Default `\"ordinal\"`. */\n readonly column?: string;\n}\n\n/**\n * The ordinal that puts a new row last among the rows `where` matches: a step\n * after the highest, or one step for an empty list. One statement. For a\n * create handler (or `crud.handlers`' `prepare`) of a model the kit's\n * `reorder` orders.\n *\n * @example\n * const ordinal = await nextOrdinal(db, \"task\", { projectId: input.projectId });\n * return db.task.create({ data: { ...input, ordinal } });\n */\nexport async function nextOrdinal(\n db: unknown,\n model: string,\n where: StorageWhere = {},\n options: NextOrdinalOptions = {},\n): Promise<number> {\n const column = options.column ?? \"ordinal\";\n if (typeof model !== \"string\" || model.length === 0 || column.length === 0) {\n throw new TypeError(\n \"nextOrdinal(db, model, where, { column? }): name the model and its column\",\n );\n }\n const result = await delegateOf(db, model).aggregate({ where, _max: { [column]: true } });\n const highest = (result._max as Readonly<Record<string, unknown>> | null | undefined)?.[column];\n return typeof highest === \"number\" && Number.isFinite(highest)\n ? Math.floor(highest) + ORDINAL_STEP\n : ORDINAL_STEP;\n}\n","// The read/write kit's `reorder` (RFC 0003 section 12.1): moves a row\n// between two others of the same ordered list (the rows sharing its\n// `within` columns), ascending by the declared column. `beforeId` is the row\n// that will come right before it and `afterId` the row right after; given\n// one, the kit finds the other. The moved row takes the whole number halfway\n// between its neighbors (`ordinal.ts`), so a move is one write; when no gap\n// is left, the list is renumbered first.\n//\n// A move reads its neighbors and writes from what it read, so it runs\n// SERIALIZABLE, as a sharing change does (`../transactions.ts`): two moves\n// into one gap at once would otherwise both take its midpoint. A conflict\n// the database reports is `CONFLICT`; the caller may try again.\n//\n// Statements, in one transaction: one read of the row and its neighbors,\n// one more to find the missing neighbor when only one is given, and the\n// write. When no gap is left, that transaction ends without writing; the\n// list's rows are counted, and a second transaction, given\n// `RENUMBER_BASE_MS` plus `RENUMBER_MS_PER_ROW` for each row (a client's\n// default limit, Prisma's 5 s, would fail a long list every time), reads the\n// rows again, renumbers (one read, and one write per row whose ordinal\n// changes) and moves. The renumbering's frames reach a collection scope as a\n// `reset` once they pass the scope's `bulkThreshold`.\n\nimport type { CrudSpec } from \"../../../contract/kits/crud\";\nimport type { ReorderInput } from \"../../../contract/kits/crudSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { StorageWhere } from \"../../storage\";\nimport type { AccessForm } from \"../../access/types\";\nimport { inKitTransaction } from \"../transactions\";\nimport { checkRowWrite } from \"./access\";\nimport { isOrdinal, ordinalBetween, ORDINAL_STEP } from \"./ordinal\";\nimport {\n crudCall,\n delegateOf,\n projectionOf,\n type CrudCall,\n type KitHandler,\n type KitHandlerArgs,\n type ModelDelegate,\n type Row,\n} from \"./runtime\";\n\ntype ReorderSpec = Extract<CrudSpec, { method: \"reorder\" }>;\n\n/** The rows a move names, read once. */\ninterface Named {\n readonly moved: Row;\n readonly before: Row | undefined;\n readonly after: Row | undefined;\n}\n\nfunction invalid(message: string, path: readonly string[]): QuickdrawError {\n return new QuickdrawError(\"VALIDATION\", message, { issues: [{ path: [...path], message }] });\n}\n\n/**\n * Reads the moved row and its named neighbors. A neighbor that is missing or\n * in another list is `NOT_FOUND` alike, so a move cannot tell whether a row\n * of another list exists.\n */\nasync function readNamed(\n table: ModelDelegate,\n spec: ReorderSpec,\n move: ReorderInput,\n model: string,\n): Promise<Named> {\n const select = Object.fromEntries([\"id\", spec.column, ...spec.within].map((key) => [key, true]));\n const ids = [move.id, move.beforeId, move.afterId].filter((id) => id !== undefined);\n const rows = await table.findMany({ where: { id: { in: ids } }, select });\n const byId = new Map(rows.map((row) => [row.id, row]));\n const moved = byId.get(move.id);\n if (moved === undefined) {\n throw new QuickdrawError(\"NOT_FOUND\", `No such ${model}`);\n }\n const neighbor = (id: string | undefined, key: string): Row | undefined => {\n const row = id === undefined ? undefined : byId.get(id);\n const listed =\n row !== undefined && spec.within.every((column) => row[column] === moved[column]);\n if (id !== undefined && !listed) {\n throw new QuickdrawError(\"NOT_FOUND\", `No such ${model} in this list as ${key}`);\n }\n return row;\n };\n return {\n moved,\n before: neighbor(move.beforeId, \"beforeId\"),\n after: neighbor(move.afterId, \"afterId\"),\n };\n}\n\n/** The rows of the moved row's list, the moved row left out. */\nfunction listOf(spec: ReorderSpec, moved: Row): StorageWhere {\n const scope = Object.fromEntries(spec.within.map((column) => [column, moved[column] ?? null]));\n return { AND: [scope, { id: { not: moved.id } }] };\n}\n\n/** The row right after (`\"next\"`) or right before (`\"previous\"`) `row` in the list. */\nasync function adjacent(\n table: ModelDelegate,\n spec: ReorderSpec,\n list: StorageWhere,\n row: Row,\n side: \"next\" | \"previous\",\n): Promise<Row | null> {\n const { column } = spec;\n const beyond = side === \"next\" ? \"gt\" : \"lt\";\n const direction = side === \"next\" ? \"asc\" : \"desc\";\n const value = row[column];\n return await table.findFirst({\n where: {\n AND: [\n list,\n { OR: [{ [column]: { [beyond]: value } }, { [column]: value, id: { [beyond]: row.id } }] },\n ],\n },\n orderBy: [{ [column]: direction }, { id: direction }],\n select: { id: true, [column]: true },\n });\n}\n\n/**\n * The ordinals the moved row goes between, `null` for an end of the list,\n * or `undefined` when a neighbor's ordinal is not a usable number.\n */\nasync function bounds(\n table: ModelDelegate,\n spec: ReorderSpec,\n named: Named,\n): Promise<[low: number | null, high: number | null] | undefined> {\n const { column } = spec;\n const { before, after } = named;\n const list = listOf(spec, named.moved);\n const low =\n before ?? (after === undefined ? null : await adjacent(table, spec, list, after, \"previous\"));\n const high =\n after ?? (before === undefined ? null : await adjacent(table, spec, list, before, \"next\"));\n const lowValue = low === null ? null : low[column];\n const highValue = high === null ? null : high[column];\n const usable = (value: unknown): boolean => value === null || isOrdinal(value);\n if (!usable(lowValue) || !usable(highValue)) {\n return undefined;\n }\n if (before !== undefined && after !== undefined && (lowValue as number) > (highValue as number)) {\n throw invalid(\"beforeId comes after afterId in the list\", [\"afterId\"]);\n }\n return [lowValue as number | null, highValue as number | null];\n}\n\n/** Renumbers the list in steps with the moved row in its new place; returns the moved row's ordinal. */\nasync function renumber(\n table: ModelDelegate,\n spec: ReorderSpec,\n named: Named,\n move: ReorderInput,\n): Promise<number> {\n const { column } = spec;\n const rows = await table.findMany({\n where: listOf(spec, named.moved),\n select: { id: true, [column]: true },\n orderBy: [{ [column]: \"asc\" }, { id: \"asc\" }],\n });\n const order = rows.map((row) => row.id);\n const at =\n move.beforeId === undefined\n ? Math.max(order.indexOf(move.afterId), 0)\n : order.indexOf(move.beforeId) + 1;\n order.splice(at, 0, move.id);\n const current = new Map(rows.map((row) => [row.id, row[column]]));\n let placed = ORDINAL_STEP;\n for (const [index, id] of order.entries()) {\n const value = (index + 1) * ORDINAL_STEP;\n if (id === move.id) {\n placed = value;\n } else if (current.get(id) !== value) {\n await table.update({ where: { id }, data: { [column]: value }, select: { id: true } });\n }\n }\n return placed;\n}\n\n/** A renumbering transaction's time limit: this much, plus `RENUMBER_MS_PER_ROW` for each row of the list. */\nexport const RENUMBER_BASE_MS = 5_000;\n\n/** The time a renumbering transaction is given for each row of the list it renumbers. */\nexport const RENUMBER_MS_PER_ROW = 10;\n\nconst OWNER = \"The read/write kit's reorder\";\n\nconst CONFLICT = \"Another change to this list ran at the same time; try again\";\n\n/** One move: the call, what it asks, and what the moved row is read back with. */\ninterface Move {\n readonly call: CrudCall;\n readonly spec: ReorderSpec;\n readonly move: ReorderInput;\n readonly select: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Moves the row inside `tx`: to the whole number between its new neighbors,\n * or, with `mayRenumber`, after renumbering its list. Without it, a move\n * with no gap left writes nothing and answers the list to renumber.\n */\nasync function moveIn(\n tx: unknown,\n { call, spec, move, select }: Move,\n mayRenumber: boolean,\n): Promise<{ readonly row: Row } | { readonly list: StorageWhere }> {\n const table = delegateOf(tx, call.model);\n const named = await readNamed(table, spec, move, call.model);\n const range = await bounds(table, spec, named);\n const between =\n range === undefined ? undefined : ordinalBetween(range[0] ?? undefined, range[1] ?? undefined);\n if (between === undefined && !mayRenumber) {\n return { list: listOf(spec, named.moved) };\n }\n const value = between ?? (await renumber(table, spec, named, move));\n return {\n row: await table.update({ where: { id: move.id }, data: { [spec.column]: value }, select }),\n };\n}\n\n/** The `reorder` handler: the caller needs the method's row level on the moved row whatever the form. */\nexport function reorderHandler(spec: ReorderSpec, form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Row> => {\n const call = crudCall(ctx, db);\n const move: Move = {\n call,\n spec,\n move: input as ReorderInput,\n select: projectionOf(call, \"entity\").select,\n };\n await checkRowWrite(call, form, move.move.id);\n const how = { owner: OWNER, conflict: CONFLICT };\n const first = await inKitTransaction(db, async (tx) => await moveIn(tx, move, false), how);\n if (\"row\" in first) {\n return first.row;\n }\n // No gap left: renumber, in a transaction given time for every row of the list.\n const rows = await call.table.count({ where: first.list });\n const timeoutMs = RENUMBER_BASE_MS + (rows + 1) * RENUMBER_MS_PER_ROW;\n const moved = await inKitTransaction(db, async (tx) => await moveIn(tx, move, true), {\n ...how,\n timeoutMs,\n });\n if (!(\"row\" in moved)) {\n throw new QuickdrawError(\"INTERNAL\", \"A renumbering reorder wrote no row\");\n }\n return moved.row;\n };\n return handler as KitHandler;\n}\n","// The handler of each read/write kit method (RFC 0003 section 12.1), from\n// what `crud.contract` made it for and the access form `crud.handlers`\n// gives it.\n\nimport { bulkDeleteHandler, bulkUpdateHandler } from \"./bulk\";\nimport { createHandler } from \"./create\";\nimport { deleteHandler } from \"./delete\";\nimport { getHandler } from \"./get\";\nimport { getManyHandler } from \"./getMany\";\nimport { listHandler } from \"./list\";\nimport { reorderHandler } from \"./reorder\";\nimport type { KitHandler } from \"./runtime\";\nimport type { MethodContext } from \"./types\";\nimport { updateHandler } from \"./update\";\n\n/** The handler of one kit method: a new function for each call, which `defineService` checks. */\nexport function handlerOf(context: MethodContext): KitHandler {\n const { spec, form } = context;\n switch (spec.method) {\n case \"get\":\n return getHandler();\n case \"getMany\":\n return getManyHandler(form);\n case \"list\":\n return listHandler({ spec, form, projection: context.projection });\n case \"create\":\n return createHandler(context.prepare);\n case \"update\":\n return updateHandler(form);\n case \"delete\":\n return deleteHandler(form);\n case \"reorder\":\n return reorderHandler(spec, form);\n case \"bulkUpdate\":\n return bulkUpdateHandler(form);\n default:\n return bulkDeleteHandler(form);\n }\n}\n","// `crud.handlers(contract, { access, prepare?, rowless? })` (RFC 0003 section 12.1):\n// the read/write kit's server half. It finds the methods `crud.contract` made\n// in the contract and returns an implementation of each, to spread into\n// `defineService`'s `methods`:\n//\n// export const taskService = qd.defineService(task, {\n// model: \"task\",\n// access: inherit({ from: project, via: \"projectId\" }),\n// methods: {\n// ...crud.handlers(task, {\n// access: {\n// get: { entry: \"Read\" },\n// list: \"authenticated\",\n// update: { entry: \"Moderate\" },\n// },\n// }),\n// rename: { access: { entry: \"Moderate\" }, handler: ... },\n// },\n// });\n//\n// Every kit method needs a form in `access`, and nothing else may be there.\n// The handlers find their service through the call (`kitRuntimeOf`), so the\n// service must declare its `model`; `defineService` checks that when the\n// service is defined, that a method on many rows of a service without an\n// access policy has `\"public\"` or `{ service }` access (`access.ts`), and,\n// on a service with one, that `get` under a form that checks no row\n// (`\"public\"`, `\"authenticated\"`, `{ service }` below `Admin`) is named in\n// `rowless`, which says every caller the form admits may read any row.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport { crud as contractHalf, crudSpecOf, type CrudSpec } from \"../../../contract/kits/crud\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWhenDefined, checksRowsItself, type AnyService } from \"../../service\";\nimport { kitEntry, rowlessMethods } from \"../rowless\";\nimport { everyRowProblem } from \"./access\";\nimport type { AnyPrepare } from \"./create\";\nimport { handlerOf } from \"./methods\";\nimport type { CrudAccess, CrudHandlersOptions, CrudImplementations } from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`crud.handlers: ${message}`);\n}\n\n/** The kit's methods in the contract, with what each was made for. */\nfunction kitMethods(contract: unknown): [string, CrudSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, CrudSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = crudSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n return found;\n}\n\n/** The access forms, one per kit method and nothing else. */\nfunction checkAccess(\n access: unknown,\n names: readonly string[],\n): Readonly<Record<string, AccessForm>> {\n if (!isRecord(access)) {\n fail(\"access must map each of the kit's methods to an access form\");\n }\n const missing = names.filter((name) => !Object.hasOwn(access, name));\n if (missing.length > 0) {\n fail(`access has no form for ${missing.map((name) => `\"${name}\"`).join(\", \")}`);\n }\n for (const [name, form] of Object.entries(access)) {\n if (!names.includes(name)) {\n fail(`access names \"${name}\", which is not a method crud.contract made`);\n }\n const problem = accessFormProblem(form);\n if (problem !== undefined) {\n fail(`access for \"${name}\" ${problem}`);\n }\n }\n return access as Readonly<Record<string, AccessForm>>;\n}\n\n/** The projection a `list`'s items are: the one whose schema `item` is, `\"entity\"` by default. */\nfunction itemProjection(\n contract: AnyContract,\n spec: Extract<CrudSpec, { method: \"list\" }>,\n): string {\n const { item } = spec;\n if (item === undefined || item === contract.entity) {\n return \"entity\";\n }\n const found = Object.entries(contract.projections).find(([, schema]) => schema === item);\n if (found === undefined) {\n fail(\n `list.item of ${contract.name} must be its entity schema or one of its projections' schemas`,\n );\n }\n return found[0];\n}\n\n/** `prepare`: a function, and only for a contract with the kit's `create`. */\nfunction checkPrepare(\n prepare: unknown,\n kit: readonly [string, CrudSpec][],\n): AnyPrepare | undefined {\n if (prepare === undefined) {\n return undefined;\n }\n if (typeof prepare !== \"function\" || !kit.some(([, spec]) => spec.method === \"create\")) {\n fail(\"prepare must be a function, for a contract with the kit's create\");\n }\n return prepare as AnyPrepare;\n}\n\n/** The kit's methods on many rows: on a service without a policy, they reach every row. */\nconst MANY_ROWS: ReadonlySet<CrudSpec[\"method\"]> = new Set([\n \"list\",\n \"getMany\",\n \"bulkUpdate\",\n \"bulkDelete\",\n]);\n\n/**\n * The kit's methods that check the caller's level on the row their `id`\n * names whatever their form (`checkRowWrite`), and `create`, whose `id` (when\n * its input has one) names a new row: `defineService`'s rowless check leaves\n * them alone. `get` reads the row its form lets the caller read, so a form\n * that checks no row needs `rowless`.\n */\nconst CHECKS_ROWS: ReadonlySet<CrudSpec[\"method\"]> = new Set([\n \"create\",\n \"update\",\n \"delete\",\n \"reorder\",\n]);\n\nconst OPTION_KEYS: readonly string[] = [\"access\", \"prepare\", \"rowless\"];\n\n/** Why a service cannot run the kit's method `name`, made for `contract` with `form`. */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n [name, spec]: readonly [string, CrudSpec],\n form: AccessForm,\n): string | undefined {\n if (service.contract !== contract) {\n return `its read/write kit handlers were made for another contract; pass ${service.name}'s own contract to crud.handlers`;\n }\n if (service.model === undefined) {\n return \"the read/write kit reads and writes the service's rows: declare its model\";\n }\n return MANY_ROWS.has(spec.method) ? everyRowProblem(service, name, form) : undefined;\n}\n\nfunction handlers<C extends AnyContract, const A extends CrudAccess<C>, Db = unknown>(\n contract: C,\n options: CrudHandlersOptions<C, A, Db>,\n): CrudImplementations<A, Db> {\n const kit = kitMethods(contract);\n if (!isRecord(options)) {\n fail(\"options must be { access, prepare?, rowless? }\");\n }\n const unknownKey = Object.keys(options).find((key) => !OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${OPTION_KEYS.join(\", \")}`);\n }\n const names = kit.map(([name]) => name);\n const access = checkAccess(options.access, names);\n const prepare = checkPrepare(options.prepare, kit);\n const rowless = rowlessMethods(options.rowless, names, fail);\n const entries: Record<string, object> = {};\n for (const [name, spec] of kit) {\n const form = access[name] as AccessForm;\n const projection = spec.method === \"list\" ? itemProjection(contract, spec) : \"entity\";\n const handler = handlerOf({ spec, form, projection, prepare });\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, [name, spec], form));\n if (CHECKS_ROWS.has(spec.method)) {\n checksRowsItself(handler);\n }\n entries[name] = kitEntry(name, form, handler, rowless);\n }\n return Object.freeze(entries) as CrudImplementations<A, Db>;\n}\n\n/**\n * The read/write kit: `crud.handlers(contract, { access, prepare?, rowless? })`\n * implements exactly the methods `crud.contract` made in `contract`, each\n * with the access form `access` gives it (and `rowless: true` for the\n * methods `rowless` names). `crud.contract` is here too, for server code; a\n * shared package imports it from the root export.\n */\nexport const crud = Object.freeze({ contract: contractHalf.contract, handlers });\n","// The parts of a search (RFC 0003 section 12.2): the condition that matches\n// the query, the scope's members, the order the results come in, and the\n// ids a strategy ranked. The handler (`run.ts`) puts them together with the\n// access filter.\n//\n// The default condition is a case-insensitive \"contains\" of the query in any\n// of the declared fields. Prisma passes LIKE's wildcards in a `contains`\n// value through to PostgreSQL, so `%`, `_` and the escape character `\\` in\n// the query are escaped: \"50%\" finds \"50%\", not \"500\". A field the caller's\n// level would not receive (a field tier, RFC 0003 section 6) is not searched\n// either, so whether a row matches never tells a caller what such a field\n// holds.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { allowedScopes } from \"../../collections/access\";\nimport type { ServiceCollection } from \"../../collections/define\";\nimport { checked } from \"../../devWarnings\";\nimport { membersWhere } from \"../../collections/snapshot\";\nimport type { FindManyArgs, StorageWhere } from \"../../storage\";\nimport { readerLevel } from \"../crud/access\";\nimport { delegateOf, projectionOf, uniqueIds } from \"../crud/runtime\";\nimport type { AnyStrategy, SearchRun } from \"./context\";\n\n/** The order of a search without a scope collection. */\nconst ID_ORDER: OrderBy = Object.freeze([Object.freeze([\"id\", \"asc\"] as const)]);\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** `parts` together: `{}` for none, the one part, or their `AND`. */\nexport function allOf(parts: readonly (StorageWhere | undefined)[]): StorageWhere {\n const kept = parts.filter(\n (part): part is StorageWhere => part !== undefined && Object.keys(part).length > 0,\n );\n return kept.length > 1 ? { AND: kept } : (kept[0] ?? {});\n}\n\n/** `q` as a LIKE pattern's literal text: its wildcards and escape character escaped. */\nexport function likeLiteral(q: string): string {\n return q.replace(/[\\\\%_]/g, \"\\\\$&\");\n}\n\n/** The default condition: `q` in any of `fields`, ignoring case. */\nexport function containsWhere(fields: readonly string[], q: string): StorageWhere {\n const contains = likeLiteral(q);\n return { OR: fields.map((field) => ({ [field]: { contains, mode: \"insensitive\" } })) };\n}\n\n/** The declared fields the caller's level receives, which the default condition looks in. */\nfunction searchedFields(run: SearchRun): readonly string[] {\n const { call, context, level } = run;\n const hidden = projectionOf(call, \"entity\").tiers.hidden(readerLevel(call, context.form, level));\n return context.spec.fields.filter((field) => !hidden.has(field));\n}\n\n/** The condition of the rows that match the query: the strategy's `where`, or the default; `\"none\"` when nothing can match. */\nexport async function textWhere(run: SearchRun): Promise<StorageWhere | \"none\"> {\n const where = run.context.strategy?.where;\n if (where === undefined) {\n const fields = searchedFields(run);\n return fields.length === 0 ? \"none\" : containsWhere(fields, run.query.q);\n }\n const filter: unknown = await checked(() => where(run.query.q, run.ctx));\n if (!isRecord(filter)) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The search strategy of ${run.call.runtime.service.name} must return a filter object from where`,\n );\n }\n return filter;\n}\n\n/** The collection a call keeps to: the search's scope collection, when the call passed a scope. */\nexport function scopedCollection(run: SearchRun): ServiceCollection | undefined {\n const { scope } = run.context.spec;\n if (scope === undefined || run.query.scope === undefined) {\n return undefined;\n }\n const collection = run.call.runtime.service.collections.get(scope);\n if (collection === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The search kit asked ${run.call.runtime.service.name} for collection \"${scope}\", which it does not have`,\n );\n }\n return collection;\n}\n\n/**\n * Refuses a call whose caller may not subscribe to its scope, decided as\n * `qd:col:sub` decides it (`allowedScopes`): `UNAUTHENTICATED` without a\n * principal, `FORBIDDEN` below the collection's `access` on the scope's\n * anchor (or for another user's `\"self\"` scope). A search's own access\n * filter keeps to rows, so without this a scope the caller cannot open\n * would still name the rows in it, and on a service without a row policy\n * show them.\n */\nasync function authorizeScope(\n run: SearchRun,\n collection: ServiceCollection,\n scope: string,\n): Promise<void> {\n const { principal, runtime } = run.call;\n if (principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n const rule = {\n service: runtime.service,\n anchor: collection.anchor?.name,\n access: collection.access,\n };\n const allowed = await allowedScopes(runtime.access, rule, principal, [scope]);\n if (!allowed.has(scope)) {\n throw new QuickdrawError(\"FORBIDDEN\", \"Insufficient permissions\");\n }\n}\n\n/**\n * The members of the call's scope, once the caller is allowed it: its column\n * and `where`, or the ids its `via` junction links to it (one read, through\n * the database client, of at most the collection's `maxLimit` links, the\n * first by the linked row's id: a search pages within those, and never reads\n * a large scope's every link per keystroke). `undefined` without a scope;\n * `\"none\"` for a scope without members.\n */\nexport async function scopeWhere(run: SearchRun): Promise<StorageWhere | \"none\" | undefined> {\n const collection = scopedCollection(run);\n if (collection === undefined || run.query.scope === undefined) {\n return undefined;\n }\n await authorizeScope(run, collection, run.query.scope);\n const reader = {\n findMany: (model: string, args?: FindManyArgs) =>\n delegateOf(run.db, model).findMany(args ?? {}),\n };\n return (await membersWhere(reader, collection, run.query.scope, collection.maxLimit)) ?? \"none\";\n}\n\n/** The order results come in: the scope collection's, else by id. No ranking. */\nexport function searchOrder(run: SearchRun): OrderBy {\n const { scope } = run.context.spec;\n const collection =\n scope === undefined ? undefined : run.call.runtime.service.collections.get(scope);\n return collection?.order ?? ID_ORDER;\n}\n\n/**\n * The ids the app's `ids` strategy ranks for the query, each once and at\n * most `limit`: the strategy is the app's code, so its statements are checked.\n */\nexport async function strategyIds(\n run: SearchRun,\n ids: NonNullable<AnyStrategy[\"ids\"]>,\n): Promise<string[]> {\n const found = await checked(() => ids(run.query.q, run.ctx, { limit: run.query.limit }));\n return rankedIds(run, found);\n}\n\n/** The ids a strategy ranked, each once and at most `limit`, or `INTERNAL` for anything else. */\nexport function rankedIds(run: SearchRun, ids: unknown): string[] {\n const valid = Array.isArray(ids) && ids.every((id) => typeof id === \"string\" && id.length > 0);\n if (!valid) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The search strategy of ${run.call.runtime.service.name} must return a list of row ids from ids`,\n );\n }\n return uniqueIds(ids as string[]).slice(0, run.query.limit);\n}\n","// The page a search answers with (RFC 0003 section 12.2). As for the\n// read/write kit's `list`, the items are the item projection's rows,\n// stripped once, at the level the page was read at (`readerLevel`). A search\n// kept to a scope also strips what the scope's collection strips, since its\n// results are that collection's items: when nothing else is missing from\n// them, they are exactly the items the collection's subscribers receive, and\n// the page carries the revision it was read at (`rev`), so a client can keep\n// them in the collection's cache.\n\nimport type { SearchPage } from \"../../../contract/kits/searchSchemas\";\nimport type { Projection } from \"../../emit/projection\";\nimport { readerLevel } from \"../crud/access\";\nimport { pageItem } from \"../crud/list\";\nimport type { Row } from \"../crud/runtime\";\nimport type { SearchRun } from \"./context\";\nimport { scopedCollection } from \"./filters\";\n\n/** A page with no results. */\nexport function emptyPage(): SearchPage<never> {\n return { items: [], nextCursor: null };\n}\n\n/** The fields a page's items go without, and whether they are the scope collection's items. */\nfunction strippingOf(\n run: SearchRun,\n projection: Projection,\n): { readonly hidden: ReadonlySet<string>; readonly collectionItems: boolean } {\n const { call, context, level } = run;\n const reader = projection.tiers.hidden(readerLevel(call, context.form, level));\n const collection = scopedCollection(run);\n if (collection === undefined) {\n return { hidden: reader, collectionItems: false };\n }\n const own = collection.item.tiers.hidden(collection.access);\n const hidden = new Set([...own, ...reader]);\n return { hidden, collectionItems: hidden.size === own.size };\n}\n\n/** The page of `rows`, in that order. */\nexport function resultsPage(\n run: SearchRun,\n projection: Projection,\n rows: readonly Row[],\n nextCursor: string | null,\n): SearchPage<unknown> {\n const { hidden, collectionItems } = strippingOf(run, projection);\n return {\n items: rows.map((row) => pageItem(projection, row, hidden)),\n nextCursor,\n ...(collectionItems ? { rev: run.rev } : {}),\n };\n}\n","// The two ways a search reads its page (RFC 0003 section 12.2).\n//\n// A call kept to a scope is first authorized for it as `qd:col:sub` would\n// be (`filters.ts`): a scope the caller may not open is refused, whatever\n// rows it holds.\n//\n// With a condition (the default \"contains\", or a strategy's `where`): one\n// keyset page (`../crud/page.ts`) of the rows that match it, that the\n// policy's `accessWhere` lets the caller read at the method's row level and,\n// in a scope, that are its members; in the scope collection's order, else by\n// id. Statements: the scope's authorization (the anchor's policy reads; none\n// with a service-wide `Admin` grant), the links of a `via` scope, the access\n// filter's own reads (none for `owner` and `jsonAcl` policies or a\n// service-wide `Admin` grant), then one for the page.\n//\n// With a strategy's `ids`: the rows of the ranked ids (and, in a scope, its\n// members), read in one statement, then only those the caller may read at\n// the row level (one batched `levelsFor`), in the strategy's order, as one\n// page. The ids come from outside the policy, so they are checked after they\n// are read, never trusted. A call whose caller cancelled while the strategy\n// looked up its ids stops before reading them.\n\nimport type { SearchPage } from \"../../../contract/kits/searchSchemas\";\nimport { selectWith } from \"../../collections/items\";\nimport { abortError } from \"../../pipeline/errors\";\nimport { unreadable } from \"../../transports/ack\";\nimport { allowedIds, rowsWhere } from \"../crud/access\";\nimport { readPage } from \"../crud/page\";\nimport { projectionOf, type Row } from \"../crud/runtime\";\nimport type { AnyStrategy, SearchRun } from \"./context\";\nimport { allOf, scopeWhere, searchOrder, strategyIds, textWhere } from \"./filters\";\nimport { emptyPage, resultsPage } from \"./results\";\n\n/** Stops a call that its caller cancelled, or that ran out of time, before it reads its rows. */\nfunction stopIfAborted(run: SearchRun): void {\n const { signal } = run.ctx;\n if (signal.aborted) {\n throw abortError(signal);\n }\n}\n\n/** One page of the rows a condition matches. */\nexport async function wherePage(run: SearchRun): Promise<SearchPage<unknown>> {\n const scope = await scopeWhere(run);\n const access = scope === \"none\" ? \"none\" : await rowsWhere(run.call, run.context.form, run.level);\n const text = access === \"none\" ? \"none\" : await textWhere(run);\n if (scope === \"none\" || access === \"none\" || text === \"none\") {\n return emptyPage();\n }\n stopIfAborted(run);\n const projection = projectionOf(run.call, run.context.projection);\n const order = searchOrder(run);\n const page = await readPage({\n table: run.call.table,\n model: run.call.model,\n storage: run.call.runtime.storage,\n where: allOf([text, access, scope]),\n order,\n cursor: run.query.cursor,\n limit: run.query.limit,\n select: selectWith(\n projection.select,\n order.map(([column]) => column),\n ),\n totalCount: false,\n filtered: run.query.scope !== undefined,\n });\n return resultsPage(run, projection, page.rows, page.nextCursor);\n}\n\n/** The page of the rows a strategy's `ids` ranked. */\nexport async function idsPage(\n run: SearchRun,\n ids: NonNullable<AnyStrategy[\"ids\"]>,\n): Promise<SearchPage<unknown>> {\n if (run.query.cursor !== undefined) {\n throw unreadable(\"cursor is not a cursor of this search, which answers in one page\", [\n \"cursor\",\n ]);\n }\n const scope = await scopeWhere(run);\n if (scope === \"none\") {\n return emptyPage();\n }\n const ranked = await strategyIds(run, ids);\n stopIfAborted(run);\n if (ranked.length === 0) {\n return emptyPage();\n }\n const projection = projectionOf(run.call, run.context.projection);\n const rows = await run.call.table.findMany({\n where: allOf([{ id: { in: ranked } }, scope]),\n select: selectWith(projection.select, []),\n });\n const found = new Map(rows.map((row) => [row.id, row]));\n const present = ranked.filter((id) => found.has(id));\n const allowed = await allowedIds(run.call, run.context.form, present, run.level, \"read\");\n return resultsPage(\n run,\n projection,\n allowed.map((id) => found.get(id) as Row),\n null,\n );\n}\n","// The search kit's handler (RFC 0003 section 12.2): a list with a text\n// condition. A query shorter than the method's `minLength`, once trimmed,\n// finds nothing and reads nothing. Otherwise the call takes the revision a\n// scoped page carries before it reads anything, and reads its page with the\n// strategy's `ids` (`idsPage`) or with a condition (`wherePage`).\n\nimport type { SearchPage, SearchQuery } from \"../../../contract/kits/searchSchemas\";\nimport { kitRuntimeOf } from \"../../context\";\nimport { currentRev } from \"../../rev\";\nimport { rowLevel } from \"../crud/access\";\nimport { crudCall, type KitHandler, type KitHandlerArgs } from \"../crud/runtime\";\nimport type { SearchContext, SearchRun } from \"./context\";\nimport { idsPage, wherePage } from \"./pages\";\nimport { emptyPage } from \"./results\";\nimport type { SearchStrategyContext } from \"./types\";\n\n/** The handler of one search method. */\nexport function searchHandler(context: SearchContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<SearchPage<unknown>> => {\n const query = input as SearchQuery;\n if (query.q.length < context.spec.minLength) {\n return emptyPage();\n }\n const run: SearchRun = {\n call: crudCall(ctx, db),\n context,\n query,\n ctx: ctx as SearchStrategyContext,\n db,\n level: rowLevel(context.form, \"Read\"),\n rev: await (kitRuntimeOf(ctx)?.claimRevision ?? currentRev)(),\n };\n const ids = context.strategy?.ids;\n return ids === undefined ? await wherePage(run) : await idsPage(run, ids);\n };\n return handler as KitHandler;\n}\n","// `search.handlers(contract, { access, strategy?, method? })` (RFC 0003\n// section 12.2): the search kit's server half. It finds the methods\n// `search.contract` made in the contract (usually one, `search`) and returns\n// their implementation, to spread into `defineService`'s `methods`; `method`\n// picks one, for a contract with several that need different access forms\n// or strategies:\n//\n// export const taskService = qd.defineService(task, {\n// model: \"task\",\n// access: inherit({ from: project, via: \"projectId\" }),\n// methods: {\n// ...search.handlers(task, { access: \"authenticated\" }),\n// },\n// });\n//\n// The method shares identical concurrent calls by one caller\n// (`share: \"caller\"`): a client typing sends the same search from several\n// places at once. The handler finds its service through the call\n// (`kitRuntimeOf`), so the service must declare its `model`; `defineService`\n// checks that when the service is defined, and that a search of a service\n// without an access policy, which reaches every row, has `\"public\"` or\n// `{ service }` access. A search kept to a scope returns\n// the scope collection's items, so its item must be that collection's item\n// projection: checked here, when the contract is known.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport {\n search as contractHalf,\n searchSpecOf,\n type SearchSpec,\n} from \"../../../contract/kits/search\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWhenDefined, type AnyService } from \"../../service\";\nimport { everyRowProblem } from \"../crud/access\";\nimport type { AnyStrategy } from \"./context\";\nimport { searchHandler } from \"./run\";\nimport type {\n SearchAccess,\n SearchContract,\n SearchHandlersOptions,\n SearchImplementations,\n SearchMethodsOf,\n} from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`search.handlers: ${message}`);\n}\n\n/** The search kit's methods in the contract, with what each was made for; at least one. */\nfunction kitMethods(contract: unknown): [string, SearchSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, SearchSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = searchSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n if (found.length === 0) {\n fail(`${String(contract.name)} has no method search.contract made`);\n }\n return found;\n}\n\n/** `strategy`: `{ where }` or `{ ids }`, a function either way. */\nfunction checkStrategy(strategy: unknown): AnyStrategy | undefined {\n if (strategy === undefined) {\n return undefined;\n }\n const valid =\n isRecord(strategy) &&\n Object.keys(strategy).every((key) => key === \"where\" || key === \"ids\") &&\n (strategy.where === undefined) !== (strategy.ids === undefined) &&\n [strategy.where, strategy.ids].every(\n (hook) => hook === undefined || typeof hook === \"function\",\n );\n if (!valid) {\n fail(\"strategy must be { where: (q, ctx) => filter } or { ids: (q, ctx, { limit }) => ids }\");\n }\n return strategy as AnyStrategy;\n}\n\nconst OPTION_KEYS: readonly string[] = [\"access\", \"strategy\", \"method\"];\n\n/** The options, checked: the access form, the strategy, and the methods to implement among `kit`. */\nfunction checkOptions(\n options: unknown,\n kit: readonly [string, SearchSpec][],\n): {\n readonly form: AccessForm;\n readonly strategy: AnyStrategy | undefined;\n readonly methods: readonly [string, SearchSpec][];\n} {\n if (!isRecord(options)) {\n fail(\"options must be { access, strategy?, method? }\");\n }\n const unknownKey = Object.keys(options).find((key) => !OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${OPTION_KEYS.join(\", \")}`);\n }\n const problem = accessFormProblem(options.access);\n if (problem !== undefined) {\n fail(`access ${problem}`);\n }\n const { method } = options;\n const methods = method === undefined ? kit : kit.filter(([name]) => name === method);\n if (methods.length === 0) {\n fail(`method \"${String(method)}\" is not a method search.contract made`);\n }\n return {\n form: options.access as AccessForm,\n strategy: checkStrategy(options.strategy),\n methods,\n };\n}\n\n/** The projection a search's results are: the one whose schema `item` is, `\"entity\"` by default. */\nfunction itemProjection(contract: AnyContract, name: string, spec: SearchSpec): string {\n if (contract.entity === undefined) {\n fail(`${contract.name} has no entity for ${name} to search`);\n }\n const { item } = spec;\n if (item === undefined || item === contract.entity) {\n return \"entity\";\n }\n const found = Object.entries(contract.projections).find(([, schema]) => schema === item);\n if (found === undefined) {\n fail(\n `the item of ${contract.name}.${name} must be its entity schema or one of its projections' schemas`,\n );\n }\n return found[0];\n}\n\n/** A scope collection of the contract, whose items the results are. */\nfunction checkScope(contract: AnyContract, name: string, spec: SearchSpec, item: string): void {\n const { scope } = spec;\n if (scope === undefined) {\n return;\n }\n const collection = Object.hasOwn(contract.collections, scope)\n ? contract.collections[scope]\n : undefined;\n if (collection === undefined) {\n fail(`${contract.name}.${name}'s scope \"${scope}\" is not a collection of ${contract.name}`);\n }\n if (collection.item !== item) {\n fail(\n `${contract.name}.${name}'s results are the items of its scope collection \"${scope}\", so its item must be \"${collection.item}\" (pass that projection's schema to search.contract as item), not \"${item}\"`,\n );\n }\n}\n\n/** Why a service cannot run the search method `name`, made for `contract` with `form`. */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n name: string,\n form: AccessForm,\n): string | undefined {\n if (service.contract !== contract) {\n return `its search kit handlers were made for another contract; pass ${service.name}'s own contract to search.handlers`;\n }\n if (service.model === undefined) {\n return \"the search kit reads the service's rows: declare its model\";\n }\n return everyRowProblem(service, name, form);\n}\n\nfunction handlers<\n C extends AnyContract,\n const A extends SearchAccess<C, M>,\n const M extends SearchMethodsOf<C> = SearchMethodsOf<C>,\n>(\n contract: C & NoInfer<SearchContract<C>>,\n options: SearchHandlersOptions<A, M>,\n): SearchImplementations<M, A> {\n const { form, strategy, methods } = checkOptions(options, kitMethods(contract));\n const entries: Record<string, object> = {};\n for (const [name, spec] of methods) {\n const projection = itemProjection(contract, name, spec);\n checkScope(contract, name, spec, projection);\n const handler = searchHandler({ spec, form, projection, strategy });\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, name, form));\n entries[name] = Object.freeze({ access: form, handler, share: \"caller\" });\n }\n return Object.freeze(entries) as SearchImplementations<M, A>;\n}\n\n/**\n * The search kit: `search.handlers(contract, { access, strategy?, method? })`\n * implements the methods `search.contract` made in `contract` (or the one\n * `method` names), with the access form `access` gives them.\n * `search.contract` is here too, for server code; a shared package imports\n * it from the root export.\n */\nexport const search = Object.freeze({ contract: contractHalf.contract, handlers });\n","// The JSON access list a `jsonAcl` policy reads, as the sharing kit reads and\n// rewrites it (RFC 0003 sections 4.2 and 12.3): `[{ userId, level }]`.\n//\n// - A column holding no list (`null`) is an empty list.\n// - A list the policy cannot fully read is malformed: not an array, or an\n// entry that is not an object with a non-empty `userId` and a known\n// `level`. The kit refuses to change a malformed list (`CONFLICT`) rather\n// than overwrite what the app stored there; the policy grants nothing from\n// it meanwhile.\n// - An entry may hold more keys than `userId` and `level` (an app's own\n// `addedAt`): the kit keeps them, and changes only the entries of the user\n// a call names.\n// - Several entries for one user count as their highest level, as the policy\n// reads them; a change to that user leaves one entry.\n\nimport { isAccessLevel, type ACE, type AccessLevel } from \"../../../contract/access\";\nimport { maxLevel } from \"../../access/levels\";\n\n/** One entry of a stored list, with whatever other keys the app keeps in it. */\nexport type StoredEntry = Readonly<Record<string, unknown>> & {\n readonly userId: string;\n readonly level: AccessLevel;\n};\n\nfunction isEntry(value: unknown): value is StoredEntry {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const { userId, level } = value as Readonly<Record<string, unknown>>;\n return typeof userId === \"string\" && userId.length > 0 && isAccessLevel(level);\n}\n\n/** The list a column holds, or `undefined` when it is malformed. */\nexport function parseList(value: unknown): readonly StoredEntry[] | undefined {\n if (value === null || value === undefined) {\n return [];\n }\n return Array.isArray(value) && value.every(isEntry) ? (value as StoredEntry[]) : undefined;\n}\n\n/** The level the list gives `userId`: the highest of their entries, or `null` without one. */\nexport function levelIn(entries: readonly StoredEntry[], userId: string): AccessLevel | null {\n return entries\n .filter((entry) => entry.userId === userId)\n .reduce<AccessLevel | null>((level, entry) => maxLevel(level, entry.level), null);\n}\n\n/** How many entries the list holds for `userId`. */\nexport function entriesOf(entries: readonly StoredEntry[], userId: string): number {\n return entries.filter((entry) => entry.userId === userId).length;\n}\n\n/**\n * The list as the kit reports it: one `{ userId, level }` per user, at the\n * level the list gives them, in the order each user first appears.\n */\nexport function sharesOf(entries: readonly StoredEntry[]): ACE[] {\n const levels = new Map<string, AccessLevel>();\n for (const entry of entries) {\n levels.set(entry.userId, maxLevel(levels.get(entry.userId), entry.level) ?? entry.level);\n }\n return [...levels].map(([userId, level]) => ({ userId, level }));\n}\n\n/**\n * The list with `userId` at `level`, or without them for `null`: their first\n * entry keeps its place and its other keys, their other entries go, and a\n * user without one gets a new entry at the end.\n */\nexport function withLevel(\n entries: readonly StoredEntry[],\n userId: string,\n level: AccessLevel | null,\n): StoredEntry[] {\n const kept: StoredEntry[] = [];\n let placed = false;\n for (const entry of entries) {\n if (entry.userId !== userId) {\n kept.push(entry);\n } else if (!placed && level !== null) {\n kept.push({ ...entry, level });\n placed = true;\n }\n }\n if (!placed && level !== null) {\n kept.push({ userId, level });\n }\n return kept;\n}\n\n/** True when someone has `Admin` on the row: the owner, or a user the list gives it. */\nexport function hasAdmin(entries: readonly StoredEntry[], owner: string | undefined): boolean {\n return owner !== undefined || entries.some((entry) => entry.level === \"Admin\");\n}\n","// Which access list or membership table the sharing kit changes (RFC 0003\n// sections 4.2 and 12.3): the one the service's own policy reads. A mode\n// `\"acl\"` method edits the list of the service's `jsonAcl` policy and a mode\n// `\"members\"` method the table of its `members` policy, alone or inside\n// `anyOf` (at any depth). The kit takes the column, model and role names\n// from that policy, never as options of its own, so the list it writes is\n// the one access is decided by. A service whose policy has none, or more\n// than one, cannot run the mode's methods: `defineService` refuses it.\n\nimport type { SharingMode } from \"../../../contract/kits/sharing\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { anyOfPolicies } from \"../../access/policies/anyOf\";\nimport { jsonAclColumnsOf, type JsonAclColumns } from \"../../access/policies/jsonAcl\";\nimport { membershipOf } from \"../../access/policies/members\";\nimport type { AnyAccessPolicy, MembershipRead } from \"../../access/policy\";\nimport type { AnyService } from \"../../service\";\n\n/** The policies `policy` is made of: itself, or each policy an `anyOf` combines, at any depth. */\nexport function policiesIn(policy: AnyAccessPolicy): readonly AnyAccessPolicy[] {\n const combined = anyOfPolicies(policy);\n return combined === undefined ? [policy] : combined.flatMap(policiesIn);\n}\n\n/** The distinct access lists the service's policy reads. */\nfunction listsOf(service: AnyService): JsonAclColumns[] {\n const policy = service.access;\n const found = policy === undefined ? [] : policiesIn(policy).map(jsonAclColumnsOf);\n return [...new Set(found)].filter((columns) => columns !== undefined);\n}\n\n/** The distinct membership tables the service's policy reads. */\nfunction tablesOf(service: AnyService): MembershipRead[] {\n const policy = service.access;\n const found = policy === undefined ? [] : policiesIn(policy).map(membershipOf);\n return [...new Set(found)].filter((read) => read !== undefined);\n}\n\nconst NEEDED: Readonly<Record<SharingMode, string>> = Object.freeze({\n acl: \"a jsonAcl(field) policy, whose access list they change\",\n members: \"a members({ model, entry, user, level }) policy, whose table they change\",\n});\n\n/** Why the service cannot run the sharing kit's methods of `mode`, or `undefined` when it can. */\nexport function policyProblem(service: AnyService, mode: SharingMode): string | undefined {\n const found = mode === \"acl\" ? listsOf(service) : tablesOf(service);\n if (found.length === 1) {\n return undefined;\n }\n const declared =\n service.access === undefined ? \"no access policy\" : `${service.access.kind}(...)`;\n if (found.length === 0) {\n return `the sharing kit's \"${mode}\" methods need ${NEEDED[mode]}, alone or inside anyOf; ${service.name} declares ${declared}`;\n }\n return `the sharing kit's \"${mode}\" methods need one ${mode === \"acl\" ? \"jsonAcl\" : \"members\"} policy to change, and ${service.name}'s has ${found.length}`;\n}\n\nfunction missing(service: AnyService, mode: SharingMode): never {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The sharing kit's \"${mode}\" methods run in ${service.name}, ${policyProblem(service, mode) ?? \"which they cannot use\"}`,\n );\n}\n\n/** The access list a mode `\"acl\"` method of the service changes. */\nexport function aclColumnsOf(service: AnyService): JsonAclColumns {\n const [columns, ...others] = listsOf(service);\n return columns !== undefined && others.length === 0 ? columns : missing(service, \"acl\");\n}\n\n/** The membership table a mode `\"members\"` method of the service changes. */\nexport function membershipTableOf(service: AnyService): MembershipRead {\n const [read, ...others] = tablesOf(service);\n return read !== undefined && others.length === 0 ? read : missing(service, \"members\");\n}\n","// The roles of the membership table a `members` policy reads (RFC 0003\n// section 4.2), as the sharing kit gives and reports them. With the policy's\n// `levels` (`{ owner: \"Admin\", editor: \"Moderate\", viewer: \"Read\" }`) the\n// roles are its keys; without it a stored role is a level name, and the kit\n// gives `Read`, `Moderate` or `Admin`. A role the policy cannot read is\n// refused (`VALIDATION`), since it would grant nothing. `invite` without a\n// role gives the lowest role that still lets the member read the row.\n\nimport { ACCESS_LEVELS, isAccessLevel, type AccessLevel } from \"../../../contract/access\";\nimport type { Member } from \"../../../contract/kits/sharingSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { maxLevel, meetsLevel } from \"../../access/levels\";\nimport type { MembershipRead } from \"../../access/policy\";\nimport type { Row } from \"../crud/runtime\";\n\n/** The level-named roles of a table without `levels`. */\nconst LEVEL_ROLES: readonly string[] = Object.freeze([\"Read\", \"Moderate\", \"Admin\"]);\n\n/** The roles a call may give. */\nexport function rolesOf(read: MembershipRead): readonly string[] {\n return read.levels === undefined ? LEVEL_ROLES : Object.keys(read.levels);\n}\n\n/** The level a stored role gives, as the policy reads it; `null` for a role it cannot read. */\nexport function levelOfRole(read: MembershipRead, role: unknown): AccessLevel | null {\n if (read.levels === undefined) {\n return isAccessLevel(role) ? role : null;\n }\n return typeof role === \"string\" && Object.hasOwn(read.levels, role)\n ? (read.levels[role] ?? null)\n : null;\n}\n\n/** The stored roles that give `Admin`. */\nexport function adminRolesOf(read: MembershipRead): string[] {\n return rolesOf(read).filter((role) => levelOfRole(read, role) === \"Admin\");\n}\n\n/** The role `invite` gives without one: the first role giving the lowest level from `Read` up. */\nfunction defaultRoleOf(read: MembershipRead): string | undefined {\n const rank = (role: string): number => ACCESS_LEVELS.indexOf(levelOfRole(read, role) ?? \"Public\");\n const readable = rolesOf(read).filter((role) => meetsLevel(levelOfRole(read, role), \"Read\"));\n return [...readable].sort((a, b) => rank(a) - rank(b))[0];\n}\n\nfunction invalidRole(message: string): QuickdrawError {\n return new QuickdrawError(\"VALIDATION\", message, { issues: [{ path: [\"role\"], message }] });\n}\n\n/** The role a call gives: `role`, or the default; `VALIDATION` for one the policy cannot read. */\nexport function checkRole(read: MembershipRead, role: string | undefined): string {\n const chosen = role ?? defaultRoleOf(read);\n if (chosen === undefined) {\n throw invalidRole(`Give a role: no role of ${read.model} lets a member read the row`);\n }\n const roles = rolesOf(read);\n if (!roles.includes(chosen)) {\n const known = roles.map((name) => `\"${name}\"`).join(\", \");\n throw invalidRole(`\"${chosen}\" is not a role of ${read.model}; the roles are ${known}`);\n }\n return chosen;\n}\n\nfunction textOf(value: unknown): string {\n return typeof value === \"string\" ? value : (JSON.stringify(value) ?? \"\");\n}\n\n/** A member as the kit returns it: their user id, their stored role, and the level it gives. */\nexport function memberOf(read: MembershipRead, userId: unknown, role: unknown): Member {\n return { userId: textOf(userId), role: textOf(role), level: levelOfRole(read, role) };\n}\n\n/** A member's role and level, from their rows: the row giving the highest level, as the policy reads it. */\nexport function currentRole(\n read: MembershipRead,\n rows: readonly Row[],\n): { readonly role: string; readonly level: AccessLevel | null } {\n let best: { role: string; level: AccessLevel | null } | undefined;\n for (const row of rows) {\n const level = levelOfRole(read, row[read.level]);\n if (best === undefined || (level !== null && maxLevel(best.level, level) !== best.level)) {\n best = { role: textOf(row[read.level]), level };\n }\n }\n return best ?? { role: \"\", level: null };\n}\n","// What every handler of the sharing kit starts from (RFC 0003 section 12.3):\n// the service its method runs in (found through the call's `ctx`, as the\n// read/write kit finds it), the caller, and the transaction a change runs\n// in. Every write goes through the dispatcher's tracked client, so the flush\n// evicts the access cache, revokes live subscriptions that lost access and\n// sends the `via` collection deltas; the kit sends nothing itself.\n//\n// A change reads the list or the members and writes them back in one\n// SERIALIZABLE transaction. PostgreSQL's default isolation (READ COMMITTED)\n// would let two changes that run at once both read the old list and the\n// second write drop the first (an unshare undone), or two Admin members each\n// see the other and both leave. Under SERIALIZABLE the database fails one of\n// them instead; the kit answers it `CONFLICT`, and the caller may try again.\n\nimport type { SharingChange, SharingOnChange } from \"./types\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { kitRuntimeOf, type KitRuntime } from \"../../context\";\nimport { checked } from \"../../devWarnings\";\nimport { modelKey } from \"../../storage\";\nimport type { Principal } from \"../../types\";\nimport type { KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport type { KitContext } from \"../crud/types\";\nimport { inKitTransaction } from \"../transactions\";\n\n/** One call of a sharing kit method: its service, the caller, and the database client. */\nexport interface SharingCall {\n readonly runtime: KitRuntime;\n /** The service's model, named as the client names it. */\n readonly model: string;\n readonly principal: Principal | null;\n /** The call's `ctx`, as `resolveUser` and `onChange` receive it. */\n readonly ctx: KitContext;\n /** The dispatcher's tracked database client. */\n readonly db: unknown;\n}\n\n/** The sharing kit call `ctx` belongs to. */\nexport function sharingCall(ctx: KitHandlerArgs[\"ctx\"], db: unknown): SharingCall {\n const runtime = kitRuntimeOf(ctx);\n const model = runtime?.service.model;\n if (runtime === undefined || model === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The sharing kit's handlers run through a dispatcher, in a service with a model\",\n );\n }\n return {\n runtime,\n model: modelKey(model),\n principal: ctx.principal,\n ctx: ctx as unknown as KitContext,\n db,\n };\n}\n\n/** The delegate of `model` on a database client or a transaction's client. */\nexport function tableOf(db: unknown, model: string): ModelDelegate {\n const name = modelKey(model);\n const isClient = (typeof db === \"object\" || typeof db === \"function\") && db !== null;\n const delegate: unknown = isClient ? Reflect.get(db, name) : undefined;\n const usable =\n typeof delegate === \"object\" &&\n delegate !== null &&\n typeof (delegate as { readonly findMany?: unknown }).findMany === \"function\";\n if (!usable) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The sharing kit reads and writes through db.${name}, which the dispatcher's database client does not have`,\n );\n }\n return delegate as ModelDelegate;\n}\n\n/**\n * Runs `fn` in a SERIALIZABLE interactive transaction of the database\n * client: its writes join the call's unit of work when it commits and are\n * dropped when it rolls back. A transaction the database fails for a\n * concurrent one is `CONFLICT`.\n */\nexport async function inSerializable<T>(db: unknown, fn: (tx: unknown) => Promise<T>): Promise<T> {\n return await inKitTransaction(db, fn, {\n owner: \"The sharing kit's changes\",\n conflict: \"Another change to this row's access ran at the same time; try again\",\n });\n}\n\n/** Tells the app's `onChange` about a change, inside its transaction (`tx`). */\nexport async function notifyChange(\n onChange: SharingOnChange | undefined,\n call: SharingCall,\n change: SharingChange,\n tx: unknown,\n): Promise<void> {\n if (onChange !== undefined) {\n await checked(() => onChange(Object.freeze(change), call.ctx, tx));\n }\n}\n","// Whether a row keeps an Admin through the service's other policies (RFC\n// 0003 sections 4.2 and 12.3). A change may not leave a row without an Admin\n// it had, and under `anyOf` an Admin can come from any of its policies: an\n// owner column (`owner`, or `jsonAcl`'s `owner`), an `Admin` entry of an\n// access list, or an `Admin` role in a membership table. So the owner of a\n// project whose policy is `anyOf(jsonAcl(\"acl\", { owner }), members(...))`\n// may remove its only Admin member: the row keeps the owner. The policy the\n// change edits counts its own Admins itself (`acl.ts`, `members.ts`); this\n// counts every other one. `inherit` and `resolver` policies are not counted:\n// their Admins are not the row's own.\n//\n// Statements, inside the change's transaction, and only when the edited\n// policy would be left without an Admin: one read of the row's owner and list\n// columns when the policy has any, then one per other membership table\n// unless the row named an Admin.\n\nimport { jsonAclColumnsOf, type JsonAclColumns } from \"../../access/policies/jsonAcl\";\nimport { membershipOf } from \"../../access/policies/members\";\nimport type { MembershipRead } from \"../../access/policy\";\nimport type { AnyService } from \"../../service\";\nimport { parseList } from \"./aclList\";\nimport { policiesIn } from \"./policy\";\nimport { adminRolesOf } from \"./roles\";\nimport { tableOf } from \"./runtime\";\n\n/** Where the service's other policies keep a row's Admins. */\ninterface AdminSources {\n /** Columns holding an owner's user id. */\n readonly owners: string[];\n /** Columns holding an access list. */\n readonly lists: string[];\n readonly tables: MembershipRead[];\n}\n\nfunction sourcesOf(service: AnyService, changing: JsonAclColumns | MembershipRead): AdminSources {\n const sources: AdminSources = { owners: [], lists: [], tables: [] };\n const policy = service.access;\n for (const one of policy === undefined ? [] : policiesIn(policy)) {\n const list = jsonAclColumnsOf(one);\n const table = membershipOf(one);\n if (list !== undefined && list !== changing) {\n sources.lists.push(list.field);\n sources.owners.push(...(list.owner === undefined ? [] : [list.owner]));\n } else if (table !== undefined && table !== changing) {\n sources.tables.push(table);\n } else if (one.kind === \"owner\") {\n sources.owners.push(...one.reads.columns);\n }\n }\n return sources;\n}\n\n/** True when the row's own columns name an Admin: an owner, or an `Admin` entry of a list. */\nasync function rowNamesAdmin(\n service: AnyService,\n tx: unknown,\n id: string,\n sources: AdminSources,\n): Promise<boolean> {\n const columns = [...sources.owners, ...sources.lists];\n if (columns.length === 0 || service.model === undefined) {\n return false;\n }\n const select = Object.fromEntries([[\"id\", true], ...columns.map((column) => [column, true])]);\n const row = await tableOf(tx, service.model).findUnique({ where: { id }, select });\n if (row === null) {\n return false;\n }\n const owned = sources.owners.some(\n (column) => typeof row[column] === \"string\" && row[column] !== \"\",\n );\n return (\n owned ||\n sources.lists.some((column) =>\n (parseList(row[column]) ?? []).some((entry) => entry.level === \"Admin\"),\n )\n );\n}\n\n/**\n * True when a policy of the service other than `changing` (the list or the\n * table the change edits) gives someone `Admin` on row `id`, read through\n * `tx`, the change's transaction.\n */\nexport async function adminElsewhere(\n service: AnyService,\n tx: unknown,\n id: string,\n changing: JsonAclColumns | MembershipRead,\n): Promise<boolean> {\n const sources = sourcesOf(service, changing);\n if (await rowNamesAdmin(service, tx, id, sources)) {\n return true;\n }\n const found = await Promise.all(\n sources.tables.map(async (table) => {\n const roles = adminRolesOf(table);\n return roles.length === 0\n ? null\n : await tableOf(tx, table.model).findFirst({\n where: { [table.entry]: id, [table.level]: { in: roles } },\n select: { id: true },\n });\n }),\n );\n return found.some((row) => row !== null);\n}\n","// The checks a sharing change makes inside its transaction (RFC 0003\n// sections 4 and 12.3): its caller, here, and whether the row keeps an Admin\n// (`admins.ts`, re-exported here). The pipeline authorized the call before\n// the transaction opened; a concurrent change (another Admin unsharing them)\n// may have lowered the caller's level since. So each change reads the\n// caller's own level on the row again as its first statement inside the\n// SERIALIZABLE transaction (the access engine's reads go through the\n// transaction's client there, and skip the cross-request cache), and:\n//\n// - refuses the change (`FORBIDDEN`) when that level no longer meets the\n// row-level half of the method's form (`{ entry: L }`; a `{ service: L }`\n// half passes on the caller's grant, which no row holds, and a form\n// without a row level, `\"authenticated\"` say, is not checked again);\n// - caps what the change gives: a caller never shares, sets or invites at a\n// level above their own on the row (`FORBIDDEN`), so a form lowered to\n// `{ entry: \"Moderate\" }` cannot hand out `Admin`.\n//\n// The caller's own level is the policy's (a service-wide `Admin` grant with\n// `adminBypass` gives `Admin`), or their service-wide grant when the form\n// names `service` and the grant is higher: a grant counts where the form\n// names it (RFC 0003 section 4.1).\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { isCustomAccess } from \"../../access/forms\";\nimport { maxLevel, meetsLevel, serviceGrant } from \"../../access/levels\";\nimport type { AccessForm } from \"../../access/types\";\nimport type { SharingCall } from \"./runtime\";\n\nexport { adminElsewhere } from \"./admins\";\n\n/** The levels of an object form's halves: its `service` and `entry` levels, when it names them. */\nfunction halvesOf(form: AccessForm): { service?: AccessLevel; entry?: AccessLevel } {\n return typeof form === \"object\" && !isCustomAccess(form)\n ? { service: form.service, entry: form.entry }\n : {};\n}\n\n/**\n * Reads the caller's own level on row `id` (call it inside the change's\n * transaction) and refuses the change unless it still meets the form's\n * row-level half; resolves with that level, to cap what the change gives.\n */\nexport async function checkCaller(\n call: SharingCall,\n form: AccessForm,\n id: string,\n): Promise<AccessLevel | null> {\n const { principal, runtime } = call;\n if (principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n const levels = await runtime.access.levelsFor(runtime.service.name, principal, [id]);\n const policy = levels.get(id) ?? null;\n const halves = halvesOf(form);\n const grant = serviceGrant(principal, runtime.service.name) ?? null;\n const granted = halves.service !== undefined && meetsLevel(grant, halves.service);\n if (halves.entry !== undefined && !granted && !meetsLevel(policy, halves.entry)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `Your access to this ${call.model} changed while the change ran; you no longer have ${halves.entry} on it`,\n );\n }\n return halves.service === undefined ? policy : maxLevel(policy, grant);\n}\n\n/** `FORBIDDEN` when a change would give `given` above the caller's own level on the row. */\nexport function capGrant(own: AccessLevel | null, given: AccessLevel | null, model: string): void {\n if (given !== null && !meetsLevel(own, given)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `You cannot give ${given} on this ${model}: it is above your own level on it (${own ?? \"none\"})`,\n );\n }\n}\n","// What every sharing kit handler is made from: the hooks `sharing.handlers`\n// was given, and its method's access form. And the user a by-name method means (`shareByName`,\n// `inviteByName`): the app's `resolveUser` finds them by the `name` or\n// `email` the call gave, before the change's transaction opens; no such user\n// is `NOT_FOUND`.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checked } from \"../../devWarnings\";\nimport type { SharingCall } from \"./runtime\";\nimport type { SharingOnChange, SharingResolveUser, SharingUserLookup } from \"./types\";\n\n/** The hooks a sharing kit handler calls, and the form its method runs under. */\nexport interface HandlerContext {\n readonly resolveUser: SharingResolveUser | undefined;\n readonly onChange: SharingOnChange | undefined;\n /** The method's access form: a change checks its caller against it again (`checks.ts`). */\n readonly form: AccessForm;\n}\n\n/** What a by-name call gave: a name, an email, or both. */\ninterface GivenLookup {\n readonly name: string | undefined;\n readonly email: string | undefined;\n}\n\n/** The user id `resolveUser` finds for the call's `name` or `email`; `NOT_FOUND` when it finds none. */\nexport async function resolveTarget(\n call: SharingCall,\n context: HandlerContext,\n given: GivenLookup,\n): Promise<string> {\n if (context.resolveUser === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The sharing kit's by-name methods need sharing.handlers' resolveUser\",\n );\n }\n const lookup: SharingUserLookup = Object.freeze({\n ...(given.name === undefined ? {} : { name: given.name }),\n ...(given.email === undefined ? {} : { email: given.email }),\n });\n const { resolveUser } = context;\n const found: unknown = await checked(() => resolveUser(lookup, call.ctx, call.db));\n if (found === null || found === undefined) {\n throw new QuickdrawError(\"NOT_FOUND\", \"No such user\");\n }\n if (typeof found !== \"string\" || found.length === 0) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"sharing.handlers' resolveUser must return a user id, or null when there is no such user\",\n );\n }\n return found;\n}\n","// The sharing kit's access list methods (RFC 0003 section 12.3, mode\n// `\"acl\"`): `share`, `shareByName`, `unshare`, `setLevel` and `listShares`,\n// on the list of the service's `jsonAcl` policy (`aclList.ts`). A change\n// reads the row's list (and owner) and writes it back with\n// `db.<model>.update` in one SERIALIZABLE transaction (`runtime.ts`); the\n// tracked write evicts the cached access of the row and revokes the live\n// subscriptions that lost it. A change:\n//\n// - first reads the caller's own level on the row again, inside the\n// transaction: `FORBIDDEN` when it no longer meets the method's form, or\n// when the change would give a level above it (`checks.ts`);\n// - never touches the owner's access, which the owner column gives:\n// `CONFLICT`;\n// - never leaves a row without an Admin it had (no owner column, the last\n// `Admin` entry unshared or lowered, and no Admin from another policy of\n// an `anyOf`, `admins.ts`): `CONFLICT`;\n// - refuses a malformed list (`CONFLICT`), leaving it as it is;\n// - writes nothing when the user already has exactly that level.\n//\n// `share` adds the user or replaces their level; `setLevel` and `unshare`\n// need the user in the list (`NOT_FOUND`). Each returns the list as\n// `listShares` does: `[{ userId, level }]`, one entry per user.\n//\n// Statements, inside the transaction: the caller's level (the policy's\n// reads; none with a service-wide `Admin` grant), one read of the row, then\n// (for a change) the tracked update, which reads the old access columns\n// first. `listShares` is one.\n\nimport type { ACE } from \"../../../contract/access\";\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type {\n ShareByNameQuery,\n ShareInput,\n ShareLevel,\n UnshareInput,\n} from \"../../../contract/kits/sharingSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { KitHandler, KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport {\n entriesOf,\n hasAdmin,\n levelIn,\n parseList,\n sharesOf,\n withLevel,\n type StoredEntry,\n} from \"./aclList\";\nimport { adminElsewhere, capGrant, checkCaller } from \"./checks\";\nimport { resolveTarget, type HandlerContext } from \"./context\";\nimport { aclColumnsOf } from \"./policy\";\nimport { inSerializable, notifyChange, sharingCall, tableOf, type SharingCall } from \"./runtime\";\n\n/** The access list a mode `\"acl\"` method changes: its column, and its owner column. */\ntype JsonAclColumns = ReturnType<typeof aclColumnsOf>;\n\n/** One change to a row's access list. */\ninterface AclChange {\n readonly kind: \"share\" | \"unshare\" | \"setLevel\";\n readonly id: string;\n readonly userId: string;\n /** The level to give the user, or `null` to take theirs away. */\n readonly level: ShareLevel | null;\n /** Whether the list must already hold the user (`setLevel`, `unshare`). */\n readonly listed: boolean;\n}\n\n/** The row's list and owner. */\ninterface Listed {\n readonly entries: readonly StoredEntry[];\n /** The owner's user id, when the policy names an owner column and the row holds one. */\n readonly owner: string | undefined;\n}\n\nasync function readList(\n table: ModelDelegate,\n columns: JsonAclColumns,\n id: string,\n model: string,\n): Promise<Listed> {\n const select = {\n id: true,\n [columns.field]: true,\n ...(columns.owner === undefined ? {} : { [columns.owner]: true }),\n };\n const row = await table.findUnique({ where: { id }, select });\n if (row === null) {\n throw new QuickdrawError(\"NOT_FOUND\", `No such ${model}`);\n }\n const entries = parseList(row[columns.field]);\n if (entries === undefined) {\n throw new QuickdrawError(\n \"CONFLICT\",\n `The access list in ${model}.${columns.field} is malformed, so the sharing kit leaves it as it is: it must be a list of { userId, level }`,\n );\n }\n const owner = columns.owner === undefined ? undefined : row[columns.owner];\n return { entries, owner: typeof owner === \"string\" && owner.length > 0 ? owner : undefined };\n}\n\n/** Why `change` may not be made to `listed`, as the error to throw; `undefined` when it may. */\nfunction refusal(listed: Listed, change: AclChange, model: string): QuickdrawError | undefined {\n if (listed.owner === change.userId) {\n return new QuickdrawError(\n \"CONFLICT\",\n `That user owns this ${model}: an owner's access cannot be shared, changed or taken away`,\n );\n }\n if (change.listed && levelIn(listed.entries, change.userId) === null) {\n return new QuickdrawError(\"NOT_FOUND\", `This ${model} is not shared with that user`);\n }\n return undefined;\n}\n\n/**\n * `CONFLICT` when `change` takes away the row's last Admin: the list (and its\n * owner) had one and would have none, and no other policy of the service\n * gives one (`admins.ts`), read through `tx`.\n */\nasync function checkLastAdmin(\n call: SharingCall,\n tx: unknown,\n listed: Listed,\n change: AclChange,\n): Promise<void> {\n const next = withLevel(listed.entries, change.userId, change.level);\n const losing = hasAdmin(listed.entries, listed.owner) && !hasAdmin(next, listed.owner);\n const { service } = call.runtime;\n if (losing && !(await adminElsewhere(service, tx, change.id, aclColumnsOf(service)))) {\n throw new QuickdrawError(\n \"CONFLICT\",\n `That user is the last Admin of this ${call.model}; give someone else Admin first`,\n );\n }\n}\n\n/** Makes `change` to the row's list, and returns the list as it is afterwards. */\nasync function changeList(\n call: SharingCall,\n context: HandlerContext,\n change: AclChange,\n): Promise<ACE[]> {\n const columns = aclColumnsOf(call.runtime.service);\n return await inSerializable(call.db, async (tx) => {\n capGrant(await checkCaller(call, context.form, change.id), change.level, call.model);\n const table = tableOf(tx, call.model);\n const listed = await readList(table, columns, change.id, call.model);\n const problem = refusal(listed, change, call.model);\n if (problem !== undefined) {\n throw problem;\n }\n await checkLastAdmin(call, tx, listed, change);\n const before = levelIn(listed.entries, change.userId);\n if (before === change.level && entriesOf(listed.entries, change.userId) === 1) {\n return sharesOf(listed.entries);\n }\n const next = withLevel(listed.entries, change.userId, change.level);\n await table.update({\n where: { id: change.id },\n data: { [columns.field]: next },\n select: { id: true },\n });\n const { kind, id, userId, level } = change;\n await notifyChange(context.onChange, call, { kind, id, userId, before, after: level }, tx);\n return sharesOf(next);\n });\n}\n\n/** The `share` handler: gives the user the level, whatever they had. */\nexport function shareHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, userId, level } = input as ShareInput;\n const change = { kind: \"share\", id, userId, level, listed: false } as const;\n return await changeList(sharingCall(ctx, db), context, change);\n };\n return handler as KitHandler;\n}\n\n/** The `shareByName` handler: `share`, for the user `resolveUser` finds. */\nexport function shareByNameHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, name, email, level } = input as ShareByNameQuery;\n const call = sharingCall(ctx, db);\n const userId = await resolveTarget(call, context, { name, email });\n return await changeList(call, context, { kind: \"share\", id, userId, level, listed: false });\n };\n return handler as KitHandler;\n}\n\n/** The `setLevel` handler: changes the level of a user the list holds. */\nexport function setLevelHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, userId, level } = input as ShareInput;\n const change = { kind: \"setLevel\", id, userId, level, listed: true } as const;\n return await changeList(sharingCall(ctx, db), context, change);\n };\n return handler as KitHandler;\n}\n\n/** The `unshare` handler: takes the user's entries out of the list. */\nexport function unshareHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, userId } = input as UnshareInput;\n const change = { kind: \"unshare\", id, userId, level: null, listed: true } as const;\n return await changeList(sharingCall(ctx, db), context, change);\n };\n return handler as KitHandler;\n}\n\n/** The `listShares` handler: the row's list, one entry per user. */\nexport function listSharesHandler(): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const call = sharingCall(ctx, db);\n const columns = aclColumnsOf(call.runtime.service);\n const table = tableOf(call.db, call.model);\n const { id } = input as IdInput;\n return sharesOf((await readList(table, columns, id, call.model)).entries);\n };\n return handler as KitHandler;\n}\n","// The sharing kit's `listMembers` (RFC 0003 section 12.3): one page of a\n// row's members from the table of the service's `members` policy, each as\n// `{ userId, role, level }`, by the read/write kit's keyset page\n// (`kits/crud/page.ts`). Members come in user id order (then the membership\n// row's id), so a page boundary stays put when members join or leave before\n// it; the kit knows no other column of the table to order by. One statement.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport type { ListMembersQuery, MembersPage } from \"../../../contract/kits/sharingSchemas\";\nimport { modelKey } from \"../../storage\";\nimport { readPage } from \"../crud/page\";\nimport type { KitHandler, KitHandlerArgs } from \"../crud/runtime\";\nimport { membershipTableOf } from \"./policy\";\nimport { memberOf } from \"./roles\";\nimport { sharingCall, tableOf } from \"./runtime\";\n\n/** The `listMembers` handler. */\nexport function listMembersHandler(): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<MembersPage> => {\n const call = sharingCall(ctx, db);\n const read = membershipTableOf(call.runtime.service);\n const query = input as ListMembersQuery;\n const order: OrderBy = [\n [read.user, \"asc\"],\n [\"id\", \"asc\"],\n ];\n const page = await readPage({\n table: tableOf(call.db, read.model),\n model: modelKey(read.model),\n storage: call.runtime.storage,\n where: { [read.entry]: query.entryId },\n order,\n cursor: query.cursor,\n limit: query.limit,\n select: { id: true, [read.user]: true, [read.level]: true },\n totalCount: false,\n filtered: false,\n });\n return {\n items: page.rows.map((row) => memberOf(read, row[read.user], row[read.level])),\n nextCursor: page.nextCursor,\n };\n };\n return handler as KitHandler;\n}\n","// The sharing kit's membership methods (RFC 0003 section 12.3, mode\n// `\"members\"`): `invite`, `inviteByName`, `remove`, `leave` and `setRole`,\n// on the table of the service's `members` policy. Each change creates,\n// updates or deletes membership rows through the tracked client, in one\n// SERIALIZABLE transaction (`runtime.ts`): the flush evicts the member's\n// cached level, revokes the live subscriptions they lost, and sends the\n// `via` collections over the table `added` or `removed`.\n//\n// - `invite` refuses a user who is a member already (`CONFLICT`; `setRole`\n// changes a role) and gives the lowest readable role when none is given.\n// An invitee the database does not know (a foreign key) is `NOT_FOUND`.\n// - `remove` and `setRole` need the user to be a member (`NOT_FOUND`);\n// `leave` is for members only (`FORBIDDEN` for anyone else).\n// - Each change but `leave` first reads the caller's own level on the row\n// again, inside the transaction: `FORBIDDEN` when it no longer meets the\n// method's form, or when `invite` or `setRole` would give a role whose\n// level is above it (`checks.ts`).\n// - The last Admin of a row cannot leave, be removed or lose Admin\n// (`CONFLICT`): whether someone else keeps Admin is read in the same\n// transaction as the change. Under `anyOf` every policy counts: another\n// Admin member, an owner column, an `Admin` entry of an access list\n// (`admins.ts`), so a project's owner may remove its only Admin member.\n//\n// Statements, inside the transaction: one read of the member's rows (of\n// whether they are one, for `invite`), one more for whether another member\n// has Admin when the change takes Admin away, and the write (a tracked\n// `create` or `delete` is one; `setRole`'s `updateMany` reads the old roles\n// first: two).\n\nimport type {\n InviteByNameQuery,\n InviteQuery,\n LeaveInput,\n Member,\n MemberInput,\n SetRoleInput,\n} from \"../../../contract/kits/sharingSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { MembershipRead } from \"../../access/policy\";\nimport type { KitHandler, KitHandlerArgs, ModelDelegate, Row } from \"../crud/runtime\";\nimport { adminElsewhere, capGrant, checkCaller } from \"./checks\";\nimport { resolveTarget, type HandlerContext } from \"./context\";\nimport { membershipTableOf } from \"./policy\";\nimport { adminRolesOf, checkRole, currentRole, levelOfRole, memberOf } from \"./roles\";\nimport { inSerializable, notifyChange, sharingCall, tableOf, type SharingCall } from \"./runtime\";\n\n/** Whom a membership change is about. */\ninterface Target {\n readonly entryId: string;\n readonly userId: string;\n}\n\nasync function rowsOf(table: ModelDelegate, read: MembershipRead, target: Target): Promise<Row[]> {\n return await table.findMany({\n where: { [read.entry]: target.entryId, [read.user]: target.userId },\n select: { id: true, [read.level]: true },\n });\n}\n\n/**\n * True when someone other than the target keeps `Admin` on the row: another\n * member of this table, or, under `anyOf`, an owner column, an access list\n * or another table (`admins.ts`), read through `tx`.\n */\nasync function anotherAdmin(\n call: SharingCall,\n tx: unknown,\n read: MembershipRead,\n target: Target,\n): Promise<boolean> {\n const roles = adminRolesOf(read);\n const found =\n roles.length === 0\n ? null\n : await tableOf(tx, read.model).findFirst({\n where: {\n [read.entry]: target.entryId,\n [read.user]: { not: target.userId },\n [read.level]: { in: roles },\n },\n select: { id: true },\n });\n return found !== null || (await adminElsewhere(call.runtime.service, tx, target.entryId, read));\n}\n\nfunction lastAdmin(model: string): QuickdrawError {\n return new QuickdrawError(\n \"CONFLICT\",\n `That user is the last Admin member of this ${model}; make another member Admin first`,\n );\n}\n\nfunction isForeignKeyFailure(error: unknown): boolean {\n return (\n error instanceof Error &&\n error.name === \"PrismaClientKnownRequestError\" &&\n (error as Error & { readonly code?: unknown }).code === \"P2003\"\n );\n}\n\n/** Makes the target a member with `role`. */\nasync function invite(\n call: SharingCall,\n context: HandlerContext,\n target: Target,\n role: string | undefined,\n): Promise<Member> {\n const read = membershipTableOf(call.runtime.service);\n const given = checkRole(read, role);\n return await inSerializable(call.db, async (tx) => {\n const own = await checkCaller(call, context.form, target.entryId);\n capGrant(own, levelOfRole(read, given), call.model);\n const table = tableOf(tx, read.model);\n if ((await rowsOf(table, read, target)).length > 0) {\n throw new QuickdrawError(\n \"CONFLICT\",\n `That user is a member of this ${call.model} already; setRole changes a member's role`,\n );\n }\n try {\n await table.create({\n data: { [read.entry]: target.entryId, [read.user]: target.userId, [read.level]: given },\n select: { id: true },\n });\n } catch (error) {\n if (!isForeignKeyFailure(error)) {\n throw error;\n }\n const missing = new QuickdrawError(\"NOT_FOUND\", `No such user, or no such ${call.model}`);\n missing.cause = error;\n throw missing;\n }\n const { entryId: id, userId } = target;\n const change = { kind: \"invite\", id, userId, before: null, after: given } as const;\n await notifyChange(context.onChange, call, change, tx);\n return memberOf(read, userId, given);\n });\n}\n\n/** Ends the target's membership: `remove` by an Admin, or `leave` by the member. */\nasync function end(\n call: SharingCall,\n context: HandlerContext,\n target: Target,\n kind: \"remove\" | \"leave\",\n): Promise<null> {\n const read = membershipTableOf(call.runtime.service);\n return await inSerializable(call.db, async (tx) => {\n if (kind === \"remove\") {\n await checkCaller(call, context.form, target.entryId);\n }\n const table = tableOf(tx, read.model);\n const rows = await rowsOf(table, read, target);\n if (rows.length === 0) {\n throw kind === \"leave\"\n ? new QuickdrawError(\"FORBIDDEN\", `You are not a member of this ${call.model}`)\n : new QuickdrawError(\"NOT_FOUND\", `That user is not a member of this ${call.model}`);\n }\n const current = currentRole(read, rows);\n if (current.level === \"Admin\" && !(await anotherAdmin(call, tx, read, target))) {\n throw lastAdmin(call.model);\n }\n const [only, ...more] = rows.map((row) => row.id);\n await (only !== undefined && more.length === 0\n ? table.delete({ where: { id: only }, select: { id: true } })\n : table.deleteMany({ where: { id: { in: [only, ...more] } } }));\n const change = { kind, id: target.entryId, userId: target.userId, after: null };\n await notifyChange(context.onChange, call, { ...change, before: current.role }, tx);\n return null;\n });\n}\n\n/** Gives the target member `role`. */\nasync function changeRole(\n call: SharingCall,\n context: HandlerContext,\n target: Target,\n role: string,\n): Promise<Member> {\n const read = membershipTableOf(call.runtime.service);\n checkRole(read, role);\n return await inSerializable(call.db, async (tx) => {\n const own = await checkCaller(call, context.form, target.entryId);\n capGrant(own, levelOfRole(read, role), call.model);\n const table = tableOf(tx, read.model);\n const rows = await rowsOf(table, read, target);\n if (rows.length === 0) {\n throw new QuickdrawError(\"NOT_FOUND\", `That user is not a member of this ${call.model}`);\n }\n const current = currentRole(read, rows);\n if (rows.length === 1 && current.role === role) {\n return memberOf(read, target.userId, role);\n }\n const demoted = current.level === \"Admin\" && levelOfRole(read, role) !== \"Admin\";\n if (demoted && !(await anotherAdmin(call, tx, read, target))) {\n throw lastAdmin(call.model);\n }\n await table.updateMany({\n where: { [read.entry]: target.entryId, [read.user]: target.userId },\n data: { [read.level]: role },\n });\n const { entryId: id, userId } = target;\n const change = { kind: \"setRole\", id, userId, before: current.role, after: role } as const;\n await notifyChange(context.onChange, call, change, tx);\n return memberOf(read, userId, role);\n });\n}\n\n/** The `invite` handler. */\nexport function inviteHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Member> => {\n const { entryId, userId, role } = input as InviteQuery;\n return await invite(sharingCall(ctx, db), context, { entryId, userId }, role);\n };\n return handler as KitHandler;\n}\n\n/** The `inviteByName` handler: `invite`, for the user `resolveUser` finds. */\nexport function inviteByNameHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Member> => {\n const { entryId, name, email, role } = input as InviteByNameQuery;\n const call = sharingCall(ctx, db);\n const userId = await resolveTarget(call, context, { name, email });\n return await invite(call, context, { entryId, userId }, role);\n };\n return handler as KitHandler;\n}\n\n/** The `remove` handler. */\nexport function removeHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<null> => {\n const { entryId, userId } = input as MemberInput;\n return await end(sharingCall(ctx, db), context, { entryId, userId }, \"remove\");\n };\n return handler as KitHandler;\n}\n\n/** The `leave` handler: the caller ends their own membership. */\nexport function leaveHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<null> => {\n const call = sharingCall(ctx, db);\n if (call.principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Sign in to leave\");\n }\n const { entryId } = input as LeaveInput;\n return await end(call, context, { entryId, userId: call.principal.userId }, \"leave\");\n };\n return handler as KitHandler;\n}\n\n/** The `setRole` handler. */\nexport function setRoleHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Member> => {\n const { entryId, userId, role } = input as SetRoleInput;\n return await changeRole(sharingCall(ctx, db), context, { entryId, userId }, role);\n };\n return handler as KitHandler;\n}\n","// The handler of each sharing kit method (RFC 0003 section 12.3), and the\n// access form each runs under unless `sharing.handlers` is given another: a\n// change needs `Admin` on the row, a list `Read`, and `leave` a signed-in\n// caller (the handler then checks they are a member). The forms name the row\n// by the input key each mode uses: `id`, or `entryId`.\n\nimport type { SharingMethodName } from \"../../../contract/kits/sharing\";\nimport type { AccessForm } from \"../../access/types\";\nimport type { KitHandler } from \"../crud/runtime\";\nimport {\n listSharesHandler,\n setLevelHandler,\n shareByNameHandler,\n shareHandler,\n unshareHandler,\n} from \"./acl\";\nimport type { HandlerContext } from \"./context\";\nimport { listMembersHandler } from \"./listMembers\";\nimport {\n inviteByNameHandler,\n inviteHandler,\n leaveHandler,\n removeHandler,\n setRoleHandler,\n} from \"./members\";\n\nconst ADMIN_ROW: AccessForm = Object.freeze({ entry: \"Admin\" });\nconst ADMIN_ENTRY: AccessForm = Object.freeze({ entry: \"Admin\", id: \"entryId\" });\nconst READ_ROW: AccessForm = Object.freeze({ entry: \"Read\" });\nconst READ_ENTRY: AccessForm = Object.freeze({ entry: \"Read\", id: \"entryId\" });\n\n/** The form each sharing kit method runs under when `access` gives none. */\nexport const DEFAULT_ACCESS: Readonly<Record<SharingMethodName, AccessForm>> = Object.freeze({\n share: ADMIN_ROW,\n shareByName: ADMIN_ROW,\n unshare: ADMIN_ROW,\n setLevel: ADMIN_ROW,\n listShares: READ_ROW,\n invite: ADMIN_ENTRY,\n inviteByName: ADMIN_ENTRY,\n remove: ADMIN_ENTRY,\n setRole: ADMIN_ENTRY,\n listMembers: READ_ENTRY,\n leave: \"authenticated\",\n});\n\nconst MAKERS: Readonly<Record<SharingMethodName, (context: HandlerContext) => KitHandler>> =\n Object.freeze({\n share: shareHandler,\n shareByName: shareByNameHandler,\n unshare: unshareHandler,\n setLevel: setLevelHandler,\n listShares: listSharesHandler,\n invite: inviteHandler,\n inviteByName: inviteByNameHandler,\n remove: removeHandler,\n leave: leaveHandler,\n setRole: setRoleHandler,\n listMembers: listMembersHandler,\n });\n\n/** The handler of one sharing kit method: a new function for each, which `defineService` checks. */\nexport function handlerOf(method: SharingMethodName, context: HandlerContext): KitHandler {\n return MAKERS[method](context);\n}\n","// `sharing.handlers(contract, { access?, resolveUser?, onChange?, rowless? })`\n// (RFC 0003 section 12.3): the sharing and membership kit's server half. It finds\n// the methods `sharing.contract` made in the contract and returns an\n// implementation of each, to spread into `defineService`'s `methods`:\n//\n// export const projectService = qd.defineService(project, {\n// model: \"project\",\n// access: anyOf(jsonAcl(\"acl\", { owner: \"ownerId\" }), members({ ... })),\n// methods: { ...sharing.handlers(project) },\n// });\n//\n// Each method runs under the kit's default form (a change needs `Admin` on\n// the row, a list `Read`, `leave` a signed-in member) unless `access` gives\n// another. The kit changes the access list or membership table the service's\n// own policy reads, so `defineService` refuses a service whose policy has\n// none for a mode the contract uses (`policy.ts`), or that has no model. An\n// access-list method (its input names the row as `id`) given a form that\n// checks no row (`\"authenticated\"`, say) must be named in `rowless`.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport {\n sharing as contractHalf,\n sharingSpecOf,\n type SharingMode,\n type SharingSpec,\n} from \"../../../contract/kits/sharing\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWhenDefined, type AnyService } from \"../../service\";\nimport { kitEntry, rowlessMethods } from \"../rowless\";\nimport type { HandlerContext } from \"./context\";\nimport { DEFAULT_ACCESS, handlerOf } from \"./methods\";\nimport { policyProblem } from \"./policy\";\nimport type {\n SharingAccess,\n SharingContract,\n SharingImplementations,\n SharingOptionsArgs,\n} from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\ntype Empty = Record<never, never>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`sharing.handlers: ${message}`);\n}\n\n/** The sharing kit's methods in the contract, with what each was made for; at least one. */\nfunction kitMethods(contract: unknown): [string, SharingSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, SharingSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = sharingSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n if (found.length === 0) {\n fail(`${String(contract.name)} has no method sharing.contract made`);\n }\n return found;\n}\n\n/** The forms `access` gives, each for one of the kit's methods. */\nfunction checkAccess(access: unknown, names: readonly string[]): UnknownRecord {\n if (access === undefined) {\n return {};\n }\n if (!isRecord(access)) {\n fail(\"access must map the kit's methods to access forms\");\n }\n for (const [name, form] of Object.entries(access)) {\n if (!names.includes(name)) {\n fail(`access names \"${name}\", which is not a method sharing.contract made`);\n }\n const problem = form === undefined ? undefined : accessFormProblem(form);\n if (problem !== undefined) {\n fail(`access for \"${name}\" ${problem}`);\n }\n }\n return access;\n}\n\n/** `resolveUser` and `onChange`: functions, and `resolveUser` exactly when a by-name method needs it. */\nfunction checkHooks(\n options: UnknownRecord,\n kit: readonly [string, SharingSpec][],\n): Omit<HandlerContext, \"form\"> {\n const { resolveUser, onChange } = options;\n const byName = kit.some(([, spec]) => [\"shareByName\", \"inviteByName\"].includes(spec.method));\n if (byName && typeof resolveUser !== \"function\") {\n fail(\"shareByName and inviteByName find their user with resolveUser: give it\");\n }\n if (!byName && resolveUser !== undefined) {\n fail(\"resolveUser is for shareByName and inviteByName, which the contract does not have\");\n }\n if (onChange !== undefined && typeof onChange !== \"function\") {\n fail(\"onChange must be a function of (change, ctx, db)\");\n }\n return {\n resolveUser: resolveUser as HandlerContext[\"resolveUser\"],\n onChange: onChange as HandlerContext[\"onChange\"],\n };\n}\n\nfunction checkOptions(options: unknown): UnknownRecord {\n if (options === undefined) {\n return {};\n }\n if (!isRecord(options)) {\n fail(\"options must be { access?, resolveUser?, onChange?, rowless? }\");\n }\n const allowed = [\"access\", \"resolveUser\", \"onChange\", \"rowless\"];\n const unknownKey = Object.keys(options).find((key) => !allowed.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${allowed.join(\", \")}`);\n }\n return options;\n}\n\n/** Why a service cannot run the sharing kit's handlers of `mode` made for `contract`. */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n mode: SharingMode,\n): string | undefined {\n if (service.contract !== contract) {\n return `its sharing kit handlers were made for another contract; pass ${service.name}'s own contract to sharing.handlers`;\n }\n if (service.model === undefined) {\n return \"the sharing kit changes who may see the service's rows: declare its model\";\n }\n return policyProblem(service, mode);\n}\n\nfunction handlers<C extends AnyContract, const A extends SharingAccess<C> = Empty, Db = unknown>(\n contract: C & NoInfer<SharingContract<C>>,\n ...rest: SharingOptionsArgs<C, A, Db>\n): SharingImplementations<C, A, Db> {\n const kit = kitMethods(contract);\n const options = checkOptions(rest[0]);\n const names = kit.map(([name]) => name);\n const access = checkAccess(options.access, names);\n const rowless = rowlessMethods(options.rowless, names, fail);\n const hooks = checkHooks(options, kit);\n const entries: Record<string, object> = {};\n for (const [name, spec] of kit) {\n const form = (access[name] as AccessForm | undefined) ?? DEFAULT_ACCESS[spec.method];\n const handler = handlerOf(spec.method, Object.freeze({ ...hooks, form }));\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, spec.mode));\n entries[name] = kitEntry(name, form, handler, rowless);\n }\n return Object.freeze(entries) as SharingImplementations<C, A, Db>;\n}\n\n/**\n * The sharing and membership kit: `sharing.handlers(contract, { access?,\n * resolveUser?, onChange?, rowless? })` implements the methods\n * `sharing.contract` made in `contract`. `sharing.contract` is here too, for server code; a shared\n * package imports it from the root export.\n */\nexport const sharing = Object.freeze({ contract: contractHalf.contract, handlers });\n","// What `adminMeta` answers (RFC 0003 section 12.4), worked out once when the\n// handlers are made: the entity's fields as the contract half read them from\n// its JSON Schema (`contract/kits/adminFields.ts`), configured for an admin\n// screen as 4.1's `zodToAdminFields` configured them\n// (4.1 `src/server/utils/zodToAdminFields.ts:138-265`):\n//\n// - hidden fields are left out: 4.1's `acl`, `serviceAccess` and\n// `service_access`, and those `hiddenFields` names; `grants: true` shows\n// and writes the entity's `serviceAccess` (or `service_access`) instead,\n// for callers with a service-wide `Admin` grant only (`runtime.ts`),\n// marked `kind: \"grants\"` so a screen with a grants editor of its own\n// finds it without its name (finding F5.5 of the quickdraw-chat\n// migration);\n// - `id`, `createdAt` and `updatedAt` come first with 4.1's fixed\n// configurations (\"ID\", \"Created At\", \"Updated At\"; `updatedAt` stays out\n// of the table), then the other fields in the schema's order;\n// - a label is the field's name in words (`assigneeId` is \"Assignee Id\");\n// - `id` and the timestamps are not editable; JSON fields stay out of the\n// table;\n// - `sortable` and `filterable` are the fields the contract declares for\n// `adminList`. 4.1 marked every field but JSON ones sortable, and sorted by\n// whatever a caller sent;\n// - `fieldOverrides` changes the rest, but cannot make `id` or a timestamp\n// editable; `showInForm: false` keeps a field out of a generic form;\n// - `editable` (finding R1.4 of the 5.0.0 review), or the list\n// `admin.contract` was given, names the only fields that are editable:\n// every other field is not, before the kit's writes are told which fields\n// they refuse, so `adminMeta`, a generic form and the writes agree. An\n// override may not say otherwise about a field it names or leaves out.\n//\n// It also says which fields the kit's writes refuse: the hidden ones and\n// those that are not editable.\n\nimport {\n ADMIN_FIELD_TYPES,\n ADMIN_NEVER_WRITABLE,\n type AdminEntityField,\n type AdminFieldConfig,\n type AdminServiceMeta,\n} from \"../../../contract/kits/adminFields\";\nimport type { AdminSpec } from \"../../../contract/kits/admin\";\n\n/** Fields 4.1 always hid from admin screens (4.1 `src/server/utils/zodToAdminFields.ts:12`). */\nexport const ADMIN_HIDDEN_FIELDS: readonly string[] = Object.freeze([\n \"acl\",\n \"serviceAccess\",\n \"service_access\",\n]);\n\n/**\n * The fields a user's service-wide grants live in. Hidden unless\n * `admin.handlers(contract, { grants: true })`; then shown and written, but\n * only to callers whose own service-wide grant on the service is `Admin`.\n */\nexport const ADMIN_GRANT_FIELDS: readonly string[] = Object.freeze([\n \"serviceAccess\",\n \"service_access\",\n]);\n\n/** The keys `fieldOverrides` may set. */\nconst OVERRIDE_KEYS: readonly string[] = Object.freeze([\n \"type\",\n \"label\",\n \"required\",\n \"editable\",\n \"showInTable\",\n \"showInForm\",\n \"enumValues\",\n \"relationService\",\n]);\n\n/** 4.1's configurations of the row's key and timestamps (`zodToAdminFields.ts:217-247`). */\nconst DEFAULT_FIELDS: Readonly<Record<string, Omit<AdminFieldConfig, \"sortable\" | \"filterable\">>> =\n Object.freeze({\n id: {\n name: \"id\",\n type: \"string\",\n label: \"ID\",\n required: true,\n editable: false,\n showInTable: true,\n },\n createdAt: {\n name: \"createdAt\",\n type: \"date\",\n label: \"Created At\",\n required: true,\n editable: false,\n showInTable: true,\n },\n updatedAt: {\n name: \"updatedAt\",\n type: \"date\",\n label: \"Updated At\",\n required: true,\n editable: false,\n showInTable: false,\n },\n });\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\n/** Fails the handlers being made, with a message. */\nexport type MetaFailure = (message: string) => never;\n\n/** What the handlers' options say about the entity's fields, checked. */\nexport interface MetaOptions {\n readonly displayName: unknown;\n readonly hiddenFields: unknown;\n readonly editable?: unknown;\n readonly fieldOverrides: unknown;\n readonly grants?: unknown;\n}\n\n/** `adminMeta`'s answer, and the fields the kit's reads and writes leave alone. */\nexport interface AdminFields {\n readonly meta: AdminServiceMeta;\n /** The fields the kit leaves out of every row and refuses to write. */\n readonly hidden: ReadonlySet<string>;\n /**\n * The fields shown but not written: `id`, the timestamps, those an\n * override made read-only, and those `editable` leaves out.\n */\n readonly readOnly: ReadonlySet<string>;\n /**\n * With `grants: true`, the grant fields the kit shows and writes: only for\n * callers whose service-wide grant on the service is `Admin`. Empty\n * otherwise (they are hidden).\n */\n readonly grants: ReadonlySet<string>;\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** A field's name in words: \"createdAt\" is \"Created At\", \"user_id\" is \"User Id\" (4.1's `toLabel`). */\nexport function labelOf(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (letter) => letter.toUpperCase());\n}\n\n/** A service's name for people: \"taskService\" is \"Tasks\" (4.1's `toDisplayName`). */\nexport function displayNameOf(serviceName: string): string {\n const words = serviceName\n .replace(/Service$/i, \"\")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/^./, (letter) => letter.toUpperCase());\n return `${words}s`;\n}\n\nfunction checkDisplayName(displayName: unknown, serviceName: string, fail: MetaFailure): string {\n if (displayName === undefined) {\n return displayNameOf(serviceName);\n }\n if (typeof displayName !== \"string\" || displayName.length === 0) {\n fail(\"displayName must be a non-empty string\");\n }\n return displayName;\n}\n\n/** The grant fields `grants: true` shows: those of the entity's fields that hold grants, at least one. */\nfunction checkGrants(\n grants: unknown,\n names: readonly string[],\n fail: MetaFailure,\n): ReadonlySet<string> {\n if (grants === undefined || grants === false) {\n return new Set();\n }\n if (grants !== true) {\n fail(\"grants must be true or false\");\n }\n const fields = ADMIN_GRANT_FIELDS.filter((name) => names.includes(name));\n if (fields.length === 0) {\n fail(\n `grants: the entity has no ${ADMIN_GRANT_FIELDS.join(\" or \")} field for the kit to show and write`,\n );\n }\n return new Set(fields);\n}\n\n/**\n * The fields hidden: 4.1's defaults but the grant fields `grants: true`\n * shows, and `hiddenFields`, which must name fields of the entity but `id`.\n */\nfunction checkHidden(\n hiddenFields: unknown,\n names: readonly string[],\n grants: ReadonlySet<string>,\n fail: MetaFailure,\n): ReadonlySet<string> {\n const defaults = ADMIN_HIDDEN_FIELDS.filter((name) => !grants.has(name));\n if (hiddenFields === undefined) {\n return new Set(defaults);\n }\n const valid =\n Array.isArray(hiddenFields) &&\n hiddenFields.every((name) => typeof name === \"string\") &&\n new Set(hiddenFields).size === hiddenFields.length;\n if (!valid) {\n fail(\"hiddenFields must be a list of distinct field names\");\n }\n for (const name of hiddenFields as string[]) {\n if (name === \"id\" || !names.includes(name)) {\n fail(`hiddenFields: \"${name}\" is not a field of the entity that can be hidden`);\n }\n if (grants.has(name)) {\n fail(\n `hiddenFields: \"${name}\" holds the grants that grants: true shows; leave one of them out`,\n );\n }\n }\n return new Set([...defaults, ...(hiddenFields as string[])]);\n}\n\nfunction overrideProblem(override: UnknownRecord): string | undefined {\n const unknownKey = Object.keys(override).find((key) => !OVERRIDE_KEYS.includes(key));\n if (unknownKey !== undefined) {\n return `has an unknown key \"${unknownKey}\"; the keys are ${OVERRIDE_KEYS.join(\", \")}`;\n }\n const { type, label, enumValues, relationService } = override;\n const flags = [\"required\", \"editable\", \"showInTable\", \"showInForm\"].filter(\n (key) => override[key] !== undefined && typeof override[key] !== \"boolean\",\n );\n if (flags.length > 0) {\n return `${flags.join(\", \")} must be true or false`;\n }\n const text = (value: unknown): boolean =>\n value === undefined || (typeof value === \"string\" && value.length > 0);\n const enumOk =\n enumValues === undefined ||\n (Array.isArray(enumValues) && enumValues.every((value) => typeof value === \"string\"));\n const typeOk = type === undefined || ADMIN_FIELD_TYPES.some((known) => known === type);\n return text(label) && text(relationService) && enumOk && typeOk\n ? undefined\n : \"has a type, label, enumValues or relationService of the wrong kind\";\n}\n\n/** The overrides, per field of the entity that is not hidden. */\nfunction checkOverrides(\n fieldOverrides: unknown,\n names: readonly string[],\n hidden: ReadonlySet<string>,\n fail: MetaFailure,\n): Readonly<Record<string, UnknownRecord>> {\n if (fieldOverrides === undefined) {\n return {};\n }\n if (!isRecord(fieldOverrides)) {\n fail(\"fieldOverrides must map field names to configuration changes\");\n }\n for (const [name, override] of Object.entries(fieldOverrides)) {\n if (!names.includes(name) || hidden.has(name)) {\n fail(`fieldOverrides: \"${name}\" is not a field of the entity the kit shows`);\n }\n const problem = isRecord(override) ? overrideProblem(override) : \"must be an object\";\n if (problem !== undefined) {\n fail(`fieldOverrides for \"${name}\" ${problem}`);\n }\n if ((override as UnknownRecord).editable === true && ADMIN_NEVER_WRITABLE.includes(name)) {\n fail(`fieldOverrides: \"${name}\" is never editable; the database sets it`);\n }\n }\n return fieldOverrides as Readonly<Record<string, UnknownRecord>>;\n}\n\nfunction quoted(names: readonly string[]): string {\n return names.map((name) => `\"${name}\"`).join(\", \");\n}\n\n/**\n * The fields `editable` names, or the list `admin.contract` was given\n * (`declared`) when it names none: each a field the kit shows, never `id` or\n * a timestamp. Given in both halves, the two must name the same fields.\n * `undefined` when neither half gives a list.\n */\nfunction checkEditable(\n editable: unknown,\n declared: readonly string[] | undefined,\n shown: (name: string) => boolean,\n fail: MetaFailure,\n): ReadonlySet<string> | undefined {\n const named = (label: string, list: readonly string[]): ReadonlySet<string> => {\n for (const name of list) {\n if (ADMIN_NEVER_WRITABLE.includes(name)) {\n fail(`${label}: \"${name}\" is never editable; the database sets it`);\n }\n if (!shown(name)) {\n fail(`${label}: \"${name}\" is not a field of the entity the kit shows`);\n }\n }\n return new Set(list);\n };\n if (editable === undefined) {\n return declared === undefined ? undefined : named(\"admin.contract's editable\", declared);\n }\n const valid =\n Array.isArray(editable) &&\n editable.every((name) => typeof name === \"string\") &&\n new Set(editable).size === editable.length;\n if (!valid) {\n fail(\"editable must be a list of distinct field names\");\n }\n const list = named(\"editable\", editable as string[]);\n if (\n declared !== undefined &&\n (declared.length !== list.size || !declared.every((name) => list.has(name)))\n ) {\n fail(\n `editable names ${quoted(editable as string[])}, but admin.contract was given ${quoted(declared)}: give both halves the same fields`,\n );\n }\n return list;\n}\n\n/** Refuses an override whose `editable` says otherwise than the `editable` list: two sources of truth. */\nfunction checkAgreement(\n overrides: Readonly<Record<string, UnknownRecord>>,\n editable: ReadonlySet<string> | undefined,\n fail: MetaFailure,\n): void {\n if (editable === undefined) {\n return;\n }\n for (const [name, override] of Object.entries(overrides)) {\n if (override.editable === true && !editable.has(name)) {\n fail(\n `fieldOverrides: \"${name}\" is editable: true, which editable leaves out; name it in editable instead`,\n );\n }\n if (override.editable === false && editable.has(name)) {\n fail(\n `fieldOverrides: \"${name}\" is editable: false, which editable names; leave it out of editable instead`,\n );\n }\n }\n}\n\n/** One field's configuration, before overrides; a grant field `grants: true` shows is marked. */\nfunction derived(\n field: AdminEntityField,\n grants: ReadonlySet<string>,\n): Omit<AdminFieldConfig, \"sortable\" | \"filterable\"> {\n const fixed = Object.hasOwn(DEFAULT_FIELDS, field.name) ? DEFAULT_FIELDS[field.name] : undefined;\n if (fixed !== undefined) {\n return fixed;\n }\n return {\n name: field.name,\n type: field.type,\n label: labelOf(field.name),\n required: field.required,\n editable: !ADMIN_NEVER_WRITABLE.includes(field.name),\n showInTable: field.type !== \"json\",\n ...(field.enumValues === undefined ? {} : { enumValues: field.enumValues }),\n ...(grants.has(field.name) ? { kind: \"grants\" as const } : {}),\n };\n}\n\n/** The fields in an admin screen's order: `id`, `createdAt` and `updatedAt` first. */\nfunction ordered(fields: readonly AdminEntityField[]): AdminEntityField[] {\n const first = Object.keys(DEFAULT_FIELDS).flatMap((name) =>\n fields.filter((field) => field.name === name),\n );\n return [...first, ...fields.filter((field) => !first.includes(field))];\n}\n\nfunction frozenConfig(config: AdminFieldConfig): AdminFieldConfig {\n const { enumValues } = config;\n return Object.freeze(\n enumValues === undefined ? config : { ...config, enumValues: Object.freeze([...enumValues]) },\n );\n}\n\n/**\n * `adminMeta`'s answer for a service, and the fields its reads and writes\n * leave alone, from what the contract half read of the entity (`spec`) and\n * the handlers' options. Fails through `fail` for options that name no field\n * of the entity, would make `id` or a timestamp editable, hide a field\n * `adminList` filters or sorts on (a filter on it would tell what it holds),\n * or give two answers to whether a field is editable.\n */\nexport function adminFieldsOf(\n serviceName: string,\n spec: Pick<AdminSpec, \"fields\" | \"filter\" | \"sort\"> & Partial<Pick<AdminSpec, \"editable\">>,\n options: MetaOptions,\n fail: MetaFailure,\n): AdminFields {\n const names = spec.fields.map((field) => field.name);\n const grants = checkGrants(options.grants, names, fail);\n const hidden = checkHidden(options.hiddenFields, names, grants, fail);\n const listed = [...spec.filter, ...spec.sort].find((name) => hidden.has(name));\n if (listed !== undefined) {\n fail(`\"${listed}\" is hidden, so adminList may not filter or sort on it`);\n }\n const overrides = checkOverrides(options.fieldOverrides, names, hidden, fail);\n const editable = checkEditable(\n options.editable,\n spec.editable,\n (name) => names.includes(name) && !hidden.has(name),\n fail,\n );\n checkAgreement(overrides, editable, fail);\n const fields = ordered(spec.fields)\n .filter((field) => !hidden.has(field.name))\n .map((field) =>\n frozenConfig({\n ...derived(field, grants),\n ...overrides[field.name],\n ...(editable === undefined ? {} : { editable: editable.has(field.name) }),\n sortable: spec.sort.includes(field.name),\n filterable: spec.filter.includes(field.name),\n }),\n );\n const meta: AdminServiceMeta = Object.freeze({\n serviceName,\n displayName: checkDisplayName(options.displayName, serviceName, fail),\n fields: Object.freeze(fields),\n });\n const readOnly = new Set(fields.filter((field) => !field.editable).map((field) => field.name));\n return Object.freeze({ meta, hidden, readOnly, grants });\n}\n","// What every handler of the admin kit starts from (RFC 0003 section 12.4):\n// the service its method runs in, found through the call's `ctx` as the other\n// kits find it, the model's delegate on the dispatcher's tracked database\n// client, and the fields the caller may see. Every write goes through that\n// client, so the flush sends its frames; the kit sends none itself.\n//\n// An admin method reaches every row of its service: no policy filters it,\n// since the default form needs a service-wide `Admin` grant, which reaches\n// every row anyway. What a row shows follows the same grant: a field above\n// the caller's service-wide level (a `fields` tier) is left out, as are the\n// fields the service hides from the kit. With the default form the grant is\n// `Admin`, which reaches every tier; a service that gives a method a lower\n// form shows that method's callers less, and refuses them a filter, a sort\n// or a write that names a field they cannot see (it would tell what the\n// field holds). The grant fields `grants: true` shows (`serviceAccess`) are\n// seen only by callers whose service-wide grant is `Admin`, whatever form\n// the method runs under: editing grants never comes with a lowered form.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { serviceGrant } from \"../../access/levels\";\nimport { kitRuntimeOf, type KitRuntime } from \"../../context\";\nimport type { Projection } from \"../../emit/projection\";\nimport { modelKey } from \"../../storage\";\nimport type { Principal } from \"../../types\";\nimport { pageItem } from \"../crud/list\";\nimport type { KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport type { AdminFields } from \"./meta\";\n\n/** One call of an admin method. */\nexport interface AdminCall {\n readonly runtime: KitRuntime;\n /** The service's model, named as the database client names it: `\"task\"`. */\n readonly model: string;\n readonly table: ModelDelegate;\n readonly principal: Principal | null;\n /** The entity projection: what a row is read with and sent as. */\n readonly projection: Projection;\n /** The fields above the caller's service-wide level: left out of rows, refused in filters, sorts and writes. */\n readonly unseen: ReadonlySet<string>;\n /** `unseen` and the fields the service hides from the kit: what no row of this call shows. */\n readonly omitted: ReadonlySet<string>;\n}\n\n/** The delegate of `model` on the dispatcher's database client (or a transaction's client). */\nexport function tableOf(db: unknown, model: string): ModelDelegate {\n const name = modelKey(model);\n const isClient = (typeof db === \"object\" || typeof db === \"function\") && db !== null;\n const delegate: unknown = isClient ? Reflect.get(db, name) : undefined;\n const usable =\n typeof delegate === \"object\" &&\n delegate !== null &&\n typeof (delegate as { readonly findMany?: unknown }).findMany === \"function\";\n if (!usable) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The admin kit reads and writes through db.${name}, which the dispatcher's database client does not have`,\n );\n }\n return delegate as ModelDelegate;\n}\n\n/** The admin kit call `ctx` belongs to. */\nexport function adminCall(ctx: KitHandlerArgs[\"ctx\"], db: unknown, fields: AdminFields): AdminCall {\n const runtime = kitRuntimeOf(ctx);\n const model = runtime?.service.model;\n const projection = runtime?.service.projections.get(\"entity\");\n if (runtime === undefined || model === undefined || projection === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The admin kit's handlers run through a dispatcher, in a service with a model and an entity\",\n );\n }\n const { principal } = ctx;\n const level = principal === null ? null : (serviceGrant(principal, runtime.service.name) ?? null);\n const tiered = projection.tiers.hidden(level);\n const unseen = level === \"Admin\" ? tiered : new Set([...tiered, ...fields.grants]);\n return {\n runtime,\n model: modelKey(model),\n table: tableOf(db, model),\n principal,\n projection,\n unseen,\n omitted: new Set([...unseen, ...fields.hidden]),\n };\n}\n\n/** A row as the call returns it: projected, without the fields it omits. */\nexport function rowOut(call: AdminCall, row: object): unknown {\n return pageItem(call.projection, row, call.omitted);\n}\n\nconst NOTHING_OMITTED: ReadonlySet<string> = Object.freeze(new Set<string>());\n\n/** A row as `onWrite` hears it: projected, every field (the hook is the server's own). */\nexport function rowWhole(call: AdminCall, row: object): unknown {\n return pageItem(call.projection, row, NOTHING_OMITTED);\n}\n\n/** `FORBIDDEN` when the call names a field above the caller's level. */\nexport function checkSeen(call: AdminCall, names: readonly string[]): void {\n const unseen = names.find((name) => call.unseen.has(name));\n if (unseen !== undefined) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `\"${unseen}\" is a field of ${call.runtime.service.name} above your access level`,\n );\n }\n}\n","// The admin kit's `adminList` (RFC 0003 section 12.4): one page of every row\n// of the service, by page number, with the total. The page arithmetic is\n// 4.1's (4.1 `src/server/BaseService.ts:1367-1388`): `skip` is\n// `(page - 1) * pageSize`, and `totalPages` is `ceil(total / pageSize)`; a\n// page past the last is empty. The rest is the read/write kit's list\n// machinery (`../crud/listQuery.ts`, `../crud/page.ts`): the filter is\n// equality on the declared fields and the sort a declared field, then `id`,\n// so the order is total and pages never overlap; a filter or sort on a field\n// above the caller's level is `FORBIDDEN`, and a default sort on one falls\n// back to `id` (its order would tell what the field holds). 4.1 passed the\n// caller's `where` and `orderBy` to the database as they came.\n//\n// Statements: two, run together: the page's rows and the count.\n\nimport type { AdminListQuery, AdminPage } from \"../../../contract/kits/adminSchemas\";\nimport { orderByOf } from \"../../collections/cursor\";\nimport { selectWith } from \"../../collections/items\";\nimport { defaultSorts, listOrder, listWhere, namedFields } from \"../crud/listQuery\";\nimport { refusal } from \"../crud/page\";\nimport type { KitHandler, KitHandlerArgs, Row } from \"../crud/runtime\";\nimport { adminCall, checkSeen, rowOut } from \"./runtime\";\nimport type { AdminContext } from \"./types\";\n\n/** Plain directions: an offset page needs no explicit place for nulls, only a total order. */\nconst NO_NULLABLE: ReadonlySet<string> = new Set();\n\n/** The `adminList` handler. */\nexport function adminListHandler(context: AdminContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<AdminPage<unknown>> => {\n const call = adminCall(ctx, db, context.fields);\n const query = input as AdminListQuery;\n checkSeen(call, namedFields(query));\n const order = listOrder(defaultSorts(context.spec.sort, call.unseen), query.sort);\n const where = listWhere(query.filter, undefined);\n const select = selectWith(\n call.projection.select,\n order.map(([column]) => column),\n );\n let rows: Row[];\n let total: number;\n try {\n [rows, total] = await Promise.all([\n call.table.findMany({\n where,\n select,\n orderBy: orderByOf(order, NO_NULLABLE),\n skip: (query.page - 1) * query.pageSize,\n take: query.pageSize,\n }),\n call.table.count({ where }),\n ]);\n } catch (error) {\n throw refusal(error, { cursor: undefined, filtered: Object.keys(query.filter).length > 0 });\n }\n return {\n items: rows.map((row) => rowOut(call, row)),\n total,\n page: query.page,\n pageSize: query.pageSize,\n totalPages: Math.ceil(total / query.pageSize),\n };\n };\n return handler as KitHandler;\n}\n","// The admin kit's methods on a row's subscribers (RFC 0003 sections 6 and\n// 12.4). A subscriber sits in the row's room for its access level\n// (`entityRoom(service, id, level)`), so `adminSubscribers` counts the\n// sockets in each of those rooms, reading nothing. 4.1 listed each socket and\n// user from a per-entity map (4.1 `src/server/BaseService.ts:1448-1464`),\n// which 5.0 does not keep. The counts are this process's: behind a cluster\n// adapter (Redis) another server's sockets are invisible here, and the reply\n// says so (`complete: false`).\n//\n// `adminReemit` records a touch of the row (`ctx.touch`), so the call's flush\n// reads it and sends it whole to every subscriber and collection, as after\n// any write; 4.1 emitted it by hand (`BaseService.ts:1470-1485`). A row that\n// is not there is `NOT_FOUND` (one statement).\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AdminSubscribers } from \"../../../contract/kits/adminSchemas\";\nimport { entityRoom } from \"../../../contract/names\";\nimport type { AnyContext } from \"../../context\";\nimport { SUBSCRIBER_LEVELS } from \"../../emit/tiers\";\nimport { requireRow } from \"../guards\";\nimport type { KitHandler, KitHandlerArgs } from \"../crud/runtime\";\nimport { adminCall, type AdminCall } from \"./runtime\";\nimport type { AdminContext } from \"./types\";\n\n/** The sockets subscribed to row `id`, per level. */\nfunction subscribersOf(call: AdminCall, id: string): AdminSubscribers {\n const { occupancy, service } = call.runtime;\n const counted = SUBSCRIBER_LEVELS.map(\n (level) => [level, occupancy?.sockets(entityRoom(service.name, id, level)) ?? 0] as const,\n );\n return {\n id,\n count: counted.reduce((sum, [, count]) => sum + count, 0),\n levels: Object.fromEntries(counted) as AdminSubscribers[\"levels\"],\n complete: occupancy?.complete() ?? true,\n };\n}\n\n/** The `adminSubscribers` handler. */\nexport function adminSubscribersHandler(context: AdminContext): KitHandler {\n const handler = ({ input, ctx, db }: KitHandlerArgs): Promise<AdminSubscribers> => {\n const call = adminCall(ctx, db, context.fields);\n return Promise.resolve(subscribersOf(call, (input as IdInput).id));\n };\n return handler as KitHandler;\n}\n\n/** The `adminReemit` handler. */\nexport function adminReemitHandler(context: AdminContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<AdminSubscribers> => {\n const call = adminCall(ctx, db, context.fields);\n const { id } = input as IdInput;\n requireRow(\n await call.table.findUnique({ where: { id }, select: { id: true } }),\n `No such ${call.model}`,\n );\n (ctx as Partial<Pick<AnyContext, \"touch\">>).touch?.(call.model, [id]);\n return subscribersOf(call, id);\n };\n return handler as KitHandler;\n}\n","// What the admin kit's writes may hold (RFC 0003 section 12.4): checked\n// before `adminCreate` and `adminUpdate` write, and the database's refusal\n// of a write's values, after. A write never sets a field the service hides,\n// one an override made read-only, `id` or a timestamp, nor a field above the\n// caller's level; and, as for every kit write, a column that decides access\n// to the row only with a service-wide `Admin` grant (`../columns.ts`).\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { checkWritableColumns } from \"../columns\";\nimport { rowLevel } from \"../crud/access\";\nimport { checkSeen, type AdminCall } from \"./runtime\";\nimport type { AdminContext } from \"./types\";\n\n/**\n * `VALIDATION` for a write that names a field the kit does not write (one the\n * service hides, `id`, a timestamp, or one an override made read-only), and\n * `FORBIDDEN` for one above the caller's level, or for a column that decides\n * access to the row unless the caller holds a service-wide `Admin` grant (a\n * lowered form must not let a member make themselves the owner; an anchor\n * column may move the row only into an anchor row the caller has the row\n * level on: `../columns.ts`).\n */\nexport async function checkWrite(\n call: AdminCall,\n context: AdminContext,\n data: Readonly<Record<string, unknown>>,\n): Promise<void> {\n const { hidden, readOnly } = context.fields;\n const names = Object.keys(data);\n const issues = names\n .filter((name) => hidden.has(name) || readOnly.has(name))\n .map((name) => ({\n path: [\"data\", name],\n message: hidden.has(name) ? `\"${name}\" is not a writable field` : `\"${name}\" is not editable`,\n }));\n if (issues.length > 0) {\n throw new QuickdrawError(\"VALIDATION\", \"The data names fields the admin kit does not write\", {\n issues,\n });\n }\n checkSeen(call, names);\n await checkWritableColumns(\n call.runtime,\n call.principal,\n data,\n rowLevel(context.form, \"Moderate\"),\n );\n}\n\n/** True for Prisma's report of a value its column cannot hold: the wrong kind, or out of range. */\nfunction isValueRefusal(error: unknown): error is Error {\n if (!(error instanceof Error)) {\n return false;\n }\n const { code } = error as Error & { readonly code?: unknown };\n return (\n error.name === \"PrismaClientValidationError\" ||\n (error.name === \"PrismaClientKnownRequestError\" && code === \"P2020\")\n );\n}\n\n/**\n * The database's refusal of a write's values (a value its column cannot\n * hold, a required column left out) as `VALIDATION`; anything else\n * unchanged. A foreign key that names no row stays `INTERNAL`, as for the\n * read/write kit.\n */\nexport function writeRefusal(error: unknown): unknown {\n if (!isValueRefusal(error)) {\n return error;\n }\n const message = \"The database refused the row's data\";\n const refused = new QuickdrawError(\"VALIDATION\", message, {\n issues: [\n {\n path: [\"data\"],\n message: \"A value does not fit its column, or a column the database requires was left out\",\n },\n ],\n });\n refused.cause = error;\n return refused;\n}\n","// The admin kit's methods on one row (RFC 0003 section 12.4): `adminGet`,\n// `adminCreate`, `adminUpdate` and `adminDelete`, through `db.<model>` on the\n// dispatcher's tracked client, as 4.1's went through `this.create` and\n// `this.update` (4.1 `src/server/BaseService.ts:1393-1417`). The tracked\n// client records each write, so the flush sends subscribers and collections\n// the same frames as any other write of the row: an admin edit shows live.\n//\n// Each reads one statement's worth: the row with the entity projection's\n// select. A row that is not there is `NOT_FOUND`, a unique violation\n// `CONFLICT`, and a value the database refuses `VALIDATION`. A write never\n// sets a field the service hides, one an override made read-only, `id` or a\n// timestamp (the contract half refuses the last two before the call runs).\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AdminCreateQuery, AdminUpdateQuery } from \"../../../contract/kits/adminSchemas\";\nimport { requireRow } from \"../guards\";\nimport type { KitHandler, KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport { kitRuntimeOf } from \"../../context\";\nimport { inKitTransaction } from \"../transactions\";\nimport { adminCall, rowOut, rowWhole, tableOf, type AdminCall } from \"./runtime\";\nimport type { AdminContext, AdminWrite } from \"./types\";\nimport { checkWrite, writeRefusal } from \"./writes\";\n\nasync function readRow(call: AdminCall, id: string): Promise<unknown> {\n const row = await call.table.findUnique({ where: { id }, select: call.projection.select });\n return rowOut(call, requireRow(row, `No such ${call.model}`));\n}\n\n/** One write, as a handler makes it: on `table`, reading the row before it when `before` is asked for. */\ntype Perform = (\n table: ModelDelegate,\n before: boolean,\n) => Promise<{\n readonly id: string;\n readonly before?: object | null;\n readonly after: object | null;\n readonly reply: unknown;\n}>;\n\n/**\n * Hands a committed write to `onCommitted`, in a detached unit of work of\n * the dispatcher the call runs in: the reply does not wait for it, and a\n * throw (or a rejection) is logged with the call's logger, never the\n * caller's.\n */\nfunction committed(context: AdminContext, args: KitHandlerArgs, write: AdminWrite): void {\n const { onCommitted } = context;\n if (onCommitted === undefined) {\n return;\n }\n const ctx = args.ctx as Parameters<typeof onCommitted>[1];\n const run = kitRuntimeOf(args.ctx)?.runDetached ?? ((fn: () => unknown) => Promise.resolve(fn()));\n const failed = (error: unknown): void => {\n ctx.log.error(\"The admin kit's onCommitted failed; the write stands\", {\n category: \"quickdraw.admin\",\n method: write.method,\n id: write.id,\n error: error instanceof Error ? error.message : String(error),\n });\n };\n try {\n run(() => onCommitted(write, ctx)).catch(failed);\n } catch (error) {\n failed(error);\n }\n}\n\n/**\n * Runs one write of `method`: alone without a hook, else in a transaction\n * with `onWrite` after it, which hears the row before (read in the\n * transaction) and after, every field; a throw undoes the write. Once it\n * committed, `onCommitted` hears the same (`committed`). The database's\n * refusal of the values is `VALIDATION` either way.\n */\nasync function written(\n context: AdminContext,\n call: AdminCall,\n args: KitHandlerArgs,\n method: AdminWrite[\"method\"],\n perform: Perform,\n): Promise<unknown> {\n const { onWrite, onCommitted } = context;\n const attempt = async (table: ModelDelegate, before: boolean) => {\n try {\n return await perform(table, before);\n } catch (error) {\n throw writeRefusal(error);\n }\n };\n if (onWrite === undefined && onCommitted === undefined) {\n return (await attempt(call.table, false)).reply;\n }\n let write: AdminWrite | undefined;\n const reply = await inKitTransaction(\n args.db,\n async (tx) => {\n const done = await attempt(tableOf(tx, call.model), method !== \"adminCreate\");\n const whole = (row: object | null | undefined) => (row ? rowWhole(call, row) : null);\n write = {\n method,\n id: done.id,\n ...(method === \"adminCreate\" ? {} : { before: whole(done.before) }),\n after: whole(done.after),\n };\n await onWrite?.(write, args.ctx as Parameters<typeof onWrite>[1], tx);\n return done.reply;\n },\n { owner: \"The admin kit's writes with onWrite or onCommitted\" },\n );\n if (write !== undefined) {\n committed(context, args, write);\n }\n return reply;\n}\n\n/** The `adminGet` handler. */\nexport function adminGetHandler(context: AdminContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(ctx, db, context.fields);\n return await readRow(call, (input as IdInput).id);\n };\n return handler as KitHandler;\n}\n\n/** The id of a row the kit wrote: it reads the entity projection, which always selects `id`. */\nfunction idOf(row: object): string {\n return String((row as { readonly id?: unknown }).id);\n}\n\n/** The `adminCreate` handler. */\nexport function adminCreateHandler(context: AdminContext): KitHandler {\n const handler = async (args: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(args.ctx, args.db, context.fields);\n const { data } = args.input as AdminCreateQuery;\n await checkWrite(call, context, data);\n return await written(context, call, args, \"adminCreate\", async (table) => {\n const after = await table.create({ data, select: call.projection.select });\n return { id: idOf(after), after, reply: rowOut(call, after) };\n });\n };\n return handler as KitHandler;\n}\n\n/** The `adminUpdate` handler. A call that changes nothing reads the row instead of writing it. */\nexport function adminUpdateHandler(context: AdminContext): KitHandler {\n const handler = async (args: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(args.ctx, args.db, context.fields);\n const { id, data } = args.input as AdminUpdateQuery;\n await checkWrite(call, context, data);\n if (Object.keys(data).length === 0) {\n return await readRow(call, id);\n }\n const { select } = call.projection;\n return await written(context, call, args, \"adminUpdate\", async (table, withBefore) => {\n const before = withBefore ? await table.findUnique({ where: { id }, select }) : undefined;\n const after = await table.update({ where: { id }, data, select });\n return { id, before, after, reply: rowOut(call, after) };\n });\n };\n return handler as KitHandler;\n}\n\n/** The `adminDelete` handler. */\nexport function adminDeleteHandler(context: AdminContext): KitHandler {\n const handler = async (args: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(args.ctx, args.db, context.fields);\n const { id } = args.input as IdInput;\n return await written(context, call, args, \"adminDelete\", async (table, withBefore) => {\n const select = withBefore ? call.projection.select : { id: true };\n const before = await table.delete({ where: { id }, select });\n return { id, ...(withBefore ? { before } : {}), after: null, reply: null };\n });\n };\n return handler as KitHandler;\n}\n","// The handler of each admin method (RFC 0003 section 12.4), and the form each\n// runs under unless `admin.handlers` is given another: a service-wide `Admin`\n// grant. 4.1 apps repeated a nine-key block of `\"Admin\"` levels for this\n// (4.1 `src/server/BaseService.ts:1167-1183`).\n\nimport type { AdminMethodName } from \"../../../contract/kits/admin\";\nimport type { KitHandler, KitHandlerArgs } from \"../crud/runtime\";\nimport { adminListHandler } from \"./list\";\nimport { adminReemitHandler, adminSubscribersHandler } from \"./live\";\nimport {\n adminCreateHandler,\n adminDeleteHandler,\n adminGetHandler,\n adminUpdateHandler,\n} from \"./rows\";\nimport type { AdminContext, AdminDefaultAccess } from \"./types\";\n\n/** The form every admin method runs under when `access` gives none. */\nexport const ADMIN_DEFAULT_ACCESS: AdminDefaultAccess = Object.freeze({ service: \"Admin\" });\n\nconst MAKERS: Readonly<\n Record<Exclude<AdminMethodName, \"adminMeta\">, (context: AdminContext) => KitHandler>\n> = Object.freeze({\n adminList: adminListHandler,\n adminGet: adminGetHandler,\n adminCreate: adminCreateHandler,\n adminUpdate: adminUpdateHandler,\n adminDelete: adminDeleteHandler,\n adminSubscribers: adminSubscribersHandler,\n adminReemit: adminReemitHandler,\n});\n\n/** `adminMeta`'s handler: the answer worked out when the handlers were made. */\nfunction adminMetaHandler(context: AdminContext): KitHandler {\n const { meta } = context.fields;\n const handler = (_args: KitHandlerArgs): Promise<typeof meta> => Promise.resolve(meta);\n return handler as KitHandler;\n}\n\n/** The handler of one admin method: a new function for each, which `defineService` checks. */\nexport function handlerOf(context: AdminContext): KitHandler {\n const { method } = context.spec;\n return method === \"adminMeta\" ? adminMetaHandler(context) : MAKERS[method](context);\n}\n","// `admin.handlers(contract, { access?, displayName?, hiddenFields?,\n// editable?, fieldOverrides?, rowless?, grants?, onWrite?, onCommitted? })`\n// (RFC 0003 section 12.4):\n// the admin kit's server half.\n// It finds the methods `admin.contract` made in the contract and returns an\n// implementation of each, to spread into `defineService`'s `methods`:\n//\n// export const taskService = qd.defineService(task, {\n// model: \"task\",\n// access: inherit({ from: project, via: \"projectId\" }),\n// methods: {\n// ...admin.handlers(task, { displayName: \"Tasks\", hiddenFields: [\"internalNotes\"] }),\n// rename: { access: { entry: \"Moderate\" }, handler: ... },\n// },\n// });\n//\n// Every method runs under `{ service: \"Admin\" }` unless `access` gives\n// another: the caller's service-wide grant must be `Admin`, and a row-level\n// `Admin` (the row's owner, say) is refused. That replaces the nine-key\n// access block 4.1 apps repeated for `installAdminMethods`. `adminMeta`'s\n// answer is worked out here, once (`meta.ts`). The handlers find their\n// service through the call, so `defineService` refuses a service without a\n// model, or one of another contract. On a service with an access policy, it\n// also refuses a method on one row (`adminGet`, `adminUpdate`,\n// `adminDelete`) given a form that checks no row below `Admin` (`{ service:\n// \"Moderate\" }`, `\"authenticated\"`) unless `rowless` names it, since such a\n// method reaches any row by its id.\n//\n// `grants: true` (a users service) shows and writes the entity's\n// `serviceAccess`, hidden by default, so an admin screen can edit grants\n// through `adminUpdate`; only a caller whose own service-wide grant is\n// `Admin` reads or writes it, whatever `access` says. The write goes through\n// the tracked client, so with `auth.serviceAccessSource` naming that column\n// the user's open sockets get the new grants on every node, as for any\n// grant change.\n//\n// `onWrite` runs in one transaction with each write, before it commits;\n// `onCommitted` (finding F6.5) once it has, in a detached unit of work, a\n// throw logged: what must wait until an edit is durable (a game applying an\n// edited definition) goes there (`rows.ts`).\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport { admin as contractHalf, adminSpecOf, type AdminSpec } from \"../../../contract/kits/admin\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWhenDefined, markGrantsEditor, type AnyService } from \"../../service\";\nimport { kitEntry, rowlessMethods } from \"../rowless\";\nimport { adminFieldsOf, type AdminFields } from \"./meta\";\nimport { ADMIN_DEFAULT_ACCESS, handlerOf } from \"./methods\";\nimport type {\n AdminAccess,\n AdminContract,\n AdminHandlersOptions,\n AdminImplementations,\n AdminOnCommitted,\n AdminOnWrite,\n} from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\ntype Empty = Record<never, never>;\n\nconst OPTION_KEYS: readonly string[] = [\n \"access\",\n \"displayName\",\n \"hiddenFields\",\n \"editable\",\n \"fieldOverrides\",\n \"rowless\",\n \"grants\",\n \"onWrite\",\n \"onCommitted\",\n];\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`admin.handlers: ${message}`);\n}\n\n/** The admin kit's methods in the contract, with what each was made for; at least one. */\nfunction kitMethods(contract: unknown): [string, AdminSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, AdminSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = adminSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n if (found.length === 0) {\n fail(`${String(contract.name)} has no method admin.contract made`);\n }\n if (found.some(([, spec]) => spec.entity !== contract.entity)) {\n fail(\n `admin.contract was given another schema than ${String(contract.name)}'s entity: pass the contract's entity schema`,\n );\n }\n return found;\n}\n\nfunction checkOptions(options: unknown): UnknownRecord {\n if (options === undefined) {\n return {};\n }\n if (!isRecord(options)) {\n fail(\n \"options must be { access?, displayName?, hiddenFields?, editable?, fieldOverrides?, rowless?, grants?, onWrite?, onCommitted? }\",\n );\n }\n const unknownKey = Object.keys(options).find((key) => !OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${OPTION_KEYS.join(\", \")}`);\n }\n return options;\n}\n\n/** The forms `access` gives, each for one of the kit's methods. */\nfunction checkAccess(access: unknown, names: readonly string[]): UnknownRecord {\n if (access === undefined) {\n return {};\n }\n if (!isRecord(access)) {\n fail(\"access must map the kit's methods to access forms\");\n }\n for (const [name, form] of Object.entries(access)) {\n if (!names.includes(name)) {\n fail(`access names \"${name}\", which is not a method admin.contract made`);\n }\n const problem = form === undefined ? undefined : accessFormProblem(form);\n if (problem !== undefined) {\n fail(`access for \"${name}\" ${problem}`);\n }\n }\n return access;\n}\n\n/** The `editable` list `admin.contract` was given for the kit's methods: at most one. */\nfunction contractEditable(\n contract: AnyContract,\n specs: readonly AdminSpec[],\n): readonly string[] | undefined {\n const lists = new Map<string, readonly string[]>();\n for (const { editable } of specs) {\n if (editable !== undefined) {\n lists.set([...editable].sort().join(\"\\u0000\"), editable);\n }\n }\n if (lists.size > 1) {\n fail(\n `admin.contract was given two editable lists for ${contract.name}: give its write methods one`,\n );\n }\n return [...lists.values()][0];\n}\n\n/** The kit's fields across its methods: every method's declared filter and sort fields. */\nfunction fieldsOf(\n contract: AnyContract,\n kit: readonly [string, AdminSpec][],\n options: UnknownRecord,\n): AdminFields {\n const specs = kit.map(([, spec]) => spec);\n const [first] = specs;\n const spec = {\n fields: first?.fields ?? [],\n filter: [...new Set(specs.flatMap((one) => one.filter))],\n sort: [...new Set(specs.flatMap((one) => one.sort))],\n editable: contractEditable(contract, specs),\n };\n return adminFieldsOf(\n contract.name,\n spec,\n {\n displayName: options.displayName,\n hiddenFields: options.hiddenFields,\n editable: options.editable,\n fieldOverrides: options.fieldOverrides,\n grants: options.grants,\n },\n fail,\n );\n}\n\n/** Why a service cannot run the admin kit's handlers made for `contract`. */\nfunction serviceProblem(service: AnyService, contract: AnyContract): string | undefined {\n if (service.contract !== contract) {\n return `its admin kit handlers were made for another contract; pass ${service.name}'s own contract to admin.handlers`;\n }\n return service.model === undefined\n ? \"the admin kit reads and writes the service's rows: declare its model\"\n : undefined;\n}\n\nfunction handlers<C extends AnyContract, const A extends AdminAccess<C> = Empty, Db = unknown>(\n contract: C & NoInfer<AdminContract<C>>,\n options?: AdminHandlersOptions<C, A, Db>,\n): AdminImplementations<C, A, Db> {\n const kit = kitMethods(contract);\n const checked = checkOptions(options);\n const names = kit.map(([name]) => name);\n const access = checkAccess(checked.access, names);\n const rowless = rowlessMethods(checked.rowless, names, fail);\n const fields = fieldsOf(contract, kit, checked);\n const { onWrite, onCommitted } = checked;\n if (onWrite !== undefined && typeof onWrite !== \"function\") {\n fail(\"onWrite must be a function of (write, ctx, db)\");\n }\n if (onCommitted !== undefined && typeof onCommitted !== \"function\") {\n fail(\"onCommitted must be a function of (write, ctx)\");\n }\n const hooks = {\n onWrite: onWrite as AdminOnWrite | undefined,\n onCommitted: onCommitted as AdminOnCommitted | undefined,\n };\n const entries: Record<string, object> = {};\n for (const [name, spec] of kit) {\n const form = (access[name] as AccessForm | undefined) ?? ADMIN_DEFAULT_ACCESS;\n const handler = handlerOf({ spec, fields, form, ...hooks });\n checkWhenDefined(handler, (service) => serviceProblem(service, contract));\n if (checked.grants === true) {\n // `createServer` warns when no `auth.serviceAccessSource` says where these grants live.\n markGrantsEditor(handler);\n }\n entries[name] = kitEntry(name, form, handler, rowless);\n }\n return Object.freeze(entries) as AdminImplementations<C, A, Db>;\n}\n\n/**\n * The admin kit: `admin.handlers(contract, { access?, displayName?,\n * hiddenFields?, editable?, fieldOverrides?, rowless?, grants? })` implements the\n * methods `admin.contract` made in `contract`, each open to a service-wide\n * `Admin` grant unless `access` gives another form. `admin.contract` is here\n * too, for server code; a shared package imports it from the root export.\n */\nexport const admin = Object.freeze({ contract: contractHalf.contract, handlers });\n","// Loads the Redis helper's optional peers, `@socket.io/redis-adapter` and\n// `redis`. A module of its own so a test can stand in for a missing peer: an\n// import that fails inside `vi.mock`'s factory reaches the caller wrapped in\n// vitest's own error, without the original's `code`.\n\n/** The two functions the Redis helper takes from its optional peers, untyped. */\nexport interface RedisPeers {\n readonly createAdapter: unknown;\n readonly createClient: unknown;\n}\n\n/** Imports both optional peers; rejects with the import error when either is missing. */\nexport async function loadRedisPeers(): Promise<RedisPeers> {\n // The build keeps both external because package.json declares them as peers.\n const [adapterModule, redisModule] = await Promise.all([\n import(\"@socket.io/redis-adapter\") as Promise<{ readonly createAdapter: unknown }>,\n import(\"redis\") as Promise<{ readonly createClient: unknown }>,\n ]);\n return { createAdapter: adapterModule.createAdapter, createClient: redisModule.createClient };\n}\n\n/**\n * True when `error` says a module could not be found. Node 24 and Bun throw\n * `ERR_MODULE_NOT_FOUND` from `import()` with the message \"Cannot find\n * package ...\", which 4.1 matched by message only and so logged as a failure\n * instead of a missing peer. The code is checked first; the 4.1 message checks\n * stay as a fallback for loaders that set no code.\n */\nexport function isModuleNotFound(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n const { code, message } = error as { readonly code?: unknown; readonly message?: unknown };\n if (code === \"ERR_MODULE_NOT_FOUND\" || code === \"MODULE_NOT_FOUND\") {\n return true;\n }\n return (\n typeof message === \"string\" &&\n (message.includes(\"Cannot find module\") || message.includes(\"MODULE_NOT_FOUND\"))\n );\n}\n","/**\n * Redis adapter utilities for horizontal scaling.\n *\n * This module provides optional Redis (or Valkey) integration for Socket.io\n * to enable running multiple server instances. Behind the adapter, the\n * server also takes its flush revisions from a shared counter on the same\n * client and keeps users' last-seen times there (`createServer`'s `cluster`\n * option; docs/deploying.md). When the subscribing connection comes back\n * after a drop, the node's clients are told to reconnect within 2 seconds,\n * so they catch up on what the node missed; a publish Valkey did not take\n * is logged rather than left unhandled (`cluster/adapterClients.ts`).\n *\n * @example\n * ```typescript\n * import { setupRedisAdapter } from '@fitzzero/quickdraw-core/server';\n *\n * const server = qd.createServer({ app, services, db });\n *\n * // Enable Redis for horizontal scaling\n * const redis = await setupRedisAdapter(server.io, {\n * host: process.env.REDIS_HOST ?? 'localhost',\n * port: parseInt(process.env.REDIS_PORT ?? '6379'),\n * });\n *\n * // On shutdown, once the server closed:\n * await server.close();\n * await redis.cleanup();\n * ```\n */\n\nimport type { Server as SocketIOServer } from \"socket.io\";\nimport type { Logger } from \"../contract/logger\";\nimport { consoleLogger } from \"../contract/logger\";\nimport { watchAdapterClients } from \"./cluster/adapterClients\";\nimport { isModuleNotFound, loadRedisPeers } from \"./redisPeers\";\nimport type { QuickdrawIo } from \"./transports/types\";\n\n/**\n * Redis adapter configuration options.\n */\nexport interface RedisAdapterOptions {\n /**\n * Redis host (default: 'localhost')\n */\n host?: string;\n\n /**\n * Redis port (default: 6379)\n */\n port?: number;\n\n /**\n * Redis password (optional)\n */\n password?: string;\n\n /**\n * Redis database number (default: 0)\n */\n db?: number;\n\n /**\n * Key prefix for Socket.io adapter (default: 'socket.io')\n */\n keyPrefix?: string;\n\n /**\n * Logger instance\n */\n logger?: Logger;\n}\n\n/**\n * Result of Redis adapter setup.\n */\nexport interface RedisAdapterResult {\n /**\n * Whether the adapter was successfully set up.\n */\n success: boolean;\n\n /**\n * Cleanup function to disconnect from Redis.\n */\n cleanup: () => Promise<void>;\n}\n\n// Type for dynamically loaded redis client\ninterface RedisClient {\n connect: () => Promise<void>;\n quit: () => Promise<void>;\n duplicate: () => RedisClient;\n on(event: \"error\" | \"ready\", listener: (error?: unknown) => void): unknown;\n}\n\n/**\n * Logs a client's errors at warn, once until it is ready again: a client\n * that lost its server reports every reconnect attempt, and one without an\n * `error` listener would make the adapter print a warning each time.\n */\nfunction reportErrors(client: RedisClient, logger: Logger, role: string): void {\n let reported = false;\n client.on(\"error\", (error) => {\n if (!reported) {\n reported = true;\n logger.warn(\"Redis adapter connection lost; it reconnects by itself\", {\n client: role,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n client.on(\"ready\", () => {\n reported = false;\n });\n}\n\n/**\n * Set up Redis adapter for Socket.io horizontal scaling.\n *\n * This function dynamically imports the @socket.io/redis-adapter package\n * to avoid requiring it as a hard dependency.\n *\n * @param io - Socket.io server instance\n * @param options - Redis configuration options\n * @returns Promise resolving to setup result\n *\n * @example\n * ```typescript\n * const { io } = createQuickdrawServer({ ... });\n *\n * const { success, cleanup } = await setupRedisAdapter(io, {\n * host: 'redis.example.com',\n * port: 6379,\n * password: process.env.REDIS_PASSWORD,\n * });\n *\n * if (success) {\n * console.log('Redis adapter enabled - horizontal scaling ready');\n * }\n *\n * // On shutdown:\n * await cleanup();\n * ```\n */\nexport async function setupRedisAdapter(\n io: SocketIOServer,\n options: RedisAdapterOptions = {},\n): Promise<RedisAdapterResult> {\n const logger =\n options.logger?.child({ service: \"RedisAdapter\" }) ??\n consoleLogger.child({ service: \"RedisAdapter\" });\n\n const { host = \"localhost\", port = 6379, password, db = 0, keyPrefix = \"socket.io\" } = options;\n\n try {\n // Dynamically import Redis packages - these are optional peer dependencies.\n const peers = await loadRedisPeers();\n\n const createAdapter = peers.createAdapter as (\n pubClient: RedisClient,\n subClient: RedisClient,\n opts?: { key?: string },\n ) => unknown;\n\n const createClient = peers.createClient as (opts: {\n socket: { host: string; port: number };\n password?: string;\n database?: number;\n }) => RedisClient;\n\n // Create Redis clients for pub/sub\n const pubClient = createClient({\n socket: { host, port },\n password,\n database: db,\n });\n\n const subClient = pubClient.duplicate();\n reportErrors(pubClient, logger, \"publish\");\n reportErrors(subClient, logger, \"subscribe\");\n\n // Connect both clients\n await Promise.all([pubClient.connect(), subClient.connect()]);\n\n // Set up the adapter\n io.adapter(\n createAdapter(pubClient, subClient, { key: keyPrefix }) as Parameters<typeof io.adapter>[0],\n );\n // When the subscription comes back, this node's clients catch up; a failed publish is logged.\n watchAdapterClients(io as unknown as QuickdrawIo, logger);\n\n logger.info(`Redis adapter connected to ${host}:${port}`);\n\n // Return cleanup function\n const cleanup = async () => {\n try {\n await Promise.all([pubClient.quit(), subClient.quit()]);\n logger.info(\"Redis adapter disconnected\");\n } catch (error) {\n logger.error(\"Error disconnecting Redis adapter\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n return { success: true, cleanup };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Check if it's a missing dependency error\n if (isModuleNotFound(error)) {\n logger.warn(\n \"Redis adapter packages not installed. Install @socket.io/redis-adapter and redis for horizontal scaling support.\",\n );\n } else {\n logger.error(\"Failed to set up Redis adapter\", { error: errorMessage });\n }\n\n return {\n success: false,\n cleanup: async () => {\n // No-op cleanup when setup failed\n },\n };\n }\n}\n\n/**\n * Check if Redis adapter packages are available.\n *\n * @returns Promise resolving to true if packages are installed\n */\nexport async function isRedisAdapterAvailable(): Promise<boolean> {\n try {\n await loadRedisPeers();\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Environment variable validation utilities.\n * Helps ensure required environment variables are set before the application starts.\n */\n\nexport interface ValidateEnvOptions {\n /**\n * List of required environment variable names.\n * Validation will fail if any of these are missing or empty.\n */\n required: string[];\n\n /**\n * Only enforce validation in production environment.\n * @default true\n */\n productionOnly?: boolean;\n\n /**\n * Custom error message prefix.\n * @default \"Missing required environment variables\"\n */\n errorPrefix?: string;\n}\n\nexport interface EnvValidationResult {\n success: boolean;\n missing: string[];\n message?: string;\n}\n\n/**\n * Validate that required environment variables are set.\n * Throws an error if any required variables are missing.\n *\n * @param options - Validation configuration\n * @throws {Error} If required environment variables are missing\n *\n * @example\n * ```typescript\n * // Validate required vars on startup\n * validateEnv({\n * required: ['JWT_SECRET', 'DATABASE_URL', 'CLIENT_URL'],\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Only validate in production\n * validateEnv({\n * required: ['JWT_SECRET', 'DATABASE_URL'],\n * productionOnly: true,\n * });\n * ```\n */\nexport function validateEnv(options: ValidateEnvOptions): void {\n const result = checkEnv(options);\n\n if (!result.success) {\n throw new Error(result.message);\n }\n}\n\n/**\n * Check environment variables without throwing.\n * Returns a result object with validation status and missing variables.\n *\n * @param options - Validation configuration\n * @returns Validation result with missing variables list\n *\n * @example\n * ```typescript\n * const result = checkEnv({ required: ['JWT_SECRET'] });\n * if (!result.success) {\n * console.warn('Missing env vars:', result.missing);\n * }\n * ```\n */\nexport function checkEnv(options: ValidateEnvOptions): EnvValidationResult {\n const {\n required,\n productionOnly = true,\n errorPrefix = \"Missing required environment variables\",\n } = options;\n\n // Skip validation in development if productionOnly is true\n if (productionOnly && process.env.NODE_ENV !== \"production\") {\n return { success: true, missing: [] };\n }\n\n const missing: string[] = [];\n\n for (const varName of required) {\n const value = process.env[varName];\n if (!value || value.trim() === \"\") {\n missing.push(varName);\n }\n }\n\n if (missing.length > 0) {\n return {\n success: false,\n missing,\n message: `${errorPrefix}: ${missing.join(\", \")}`,\n };\n }\n\n return { success: true, missing: [] };\n}\n\n/**\n * Get an environment variable or throw if it's missing.\n * Useful for individual variable access with validation.\n *\n * @param name - Environment variable name\n * @param defaultValue - Optional default value (if provided, won't throw)\n * @returns The environment variable value\n * @throws {Error} If variable is missing and no default provided\n *\n * @example\n * ```typescript\n * const jwtSecret = requireEnv('JWT_SECRET');\n * const port = requireEnv('PORT', '4000');\n * ```\n */\nexport function requireEnv(name: string, defaultValue?: string): string {\n const value = process.env[name];\n\n if (!value || value.trim() === \"\") {\n if (defaultValue !== undefined) {\n return defaultValue;\n }\n throw new Error(`Environment variable ${name} is required but not set`);\n }\n\n return value;\n}\n","/**\n * AES-256-GCM encryption helpers for at-rest secrets (e.g. stored OAuth tokens).\n *\n * Requires ENCRYPTION_KEY: a 64-character hex string (32 bytes).\n * Ciphertext format: \"iv:authTag:ciphertext\" (all hex).\n */\n\nimport { createCipheriv, createDecipheriv, randomBytes } from \"crypto\";\nimport { consoleLogger, type Logger } from \"../../contract/logger\";\n\nconst ALGORITHM = \"aes-256-gcm\";\nconst IV_LENGTH = 12;\nconst AUTH_TAG_LENGTH = 16;\n\nfunction getKey(): Buffer {\n const hex = process.env.ENCRYPTION_KEY;\n if (!hex || hex.length !== 64) {\n throw new Error(\n \"ENCRYPTION_KEY must be set as a 64-character hex string (32 bytes). Check your environment configuration.\",\n );\n }\n return Buffer.from(hex, \"hex\");\n}\n\nexport function encrypt(plaintext: string): string {\n const key = getKey();\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });\n const encrypted = Buffer.concat([cipher.update(plaintext, \"utf8\"), cipher.final()]);\n const authTag = cipher.getAuthTag();\n return `${iv.toString(\"hex\")}:${authTag.toString(\"hex\")}:${encrypted.toString(\"hex\")}`;\n}\n\nexport function decrypt(ciphertext: string): string {\n const key = getKey();\n const [ivHex, authTagHex, encryptedHex] = ciphertext.split(\":\");\n if (!ivHex || !authTagHex || !encryptedHex) {\n throw new Error(\"Invalid ciphertext format\");\n }\n const iv = Buffer.from(ivHex, \"hex\");\n const authTag = Buffer.from(authTagHex, \"hex\");\n const encrypted = Buffer.from(encryptedHex, \"hex\");\n const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });\n decipher.setAuthTag(authTag);\n return decipher.update(encrypted) + decipher.final(\"utf8\");\n}\n\n/**\n * Returns true when the value looks like AES-256-GCM ciphertext\n * (iv:authTag:data, all hex). Plaintext OAuth tokens (e.g. gho_xxx) will not match.\n */\nexport function isEncrypted(value: string): boolean {\n const parts = value.split(\":\");\n return parts.length === 3 && parts.every((p) => /^[0-9a-f]+$/.test(p));\n}\n\n/**\n * Decrypt if the value is in encrypted format, otherwise return as-is.\n * Allows graceful handling of pre-migration plaintext tokens.\n */\nexport function decryptIfEncrypted(value: string): string {\n return isEncrypted(value) ? decrypt(value) : value;\n}\n\n/** Safe wrapper that returns `null` instead of throwing on invalid/stale ciphertext. */\nexport function tryDecrypt(ciphertext: string, logger: Logger = consoleLogger): string | null {\n try {\n return decryptIfEncrypted(ciphertext);\n } catch {\n logger.warn(\"Failed to decrypt stored token — likely stale or re-keyed\");\n return null;\n }\n}\n"],"mappings":"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","names":["owner","fail","missing","isRecord","owner","fail","missing","isRecord","isContract","fail","owner","isRecord","owner","fail","missing","checked","isRecord","isContract","fail","isRecord","missing","OPTION_KEYS","crud","isRecord","emptyPage","emptyPage","emptyPage","isRecord","fail","kitMethods","OPTION_KEYS","itemProjection","serviceProblem","handlers","search","owner","owner","refusal","missing","handlerOf","isRecord","fail","kitMethods","checkAccess","checkOptions","serviceProblem","handlers","handlerOf","sharing","isRecord","fail","list","tableOf","tableOf","MAKERS","handlerOf","OPTION_KEYS","isRecord","fail","kitMethods","checkOptions","checkAccess","spec","serviceProblem","handlers","checked","handlerOf","admin","missing"]}
|
|
1
|
+
{"version":3,"sources":["../../src/server/realtime/define.ts","../../src/server/serviceData.ts","../../src/server/buildService.ts","../../src/server/init.ts","../../src/server/access/policies/owner.ts","../../src/server/access/policies/jsonAcl.ts","../../src/server/access/policies/inherit.ts","../../src/server/access/policies/everyone.ts","../../src/server/kits/rowless.ts","../../src/server/kits/crud/access.ts","../../src/server/kits/columns.ts","../../src/server/kits/transactions.ts","../../src/server/kits/crud/runtime.ts","../../src/server/kits/guards.ts","../../src/server/kits/crud/update.ts","../../src/server/kits/crud/bulk.ts","../../src/server/kits/crud/create.ts","../../src/server/kits/crud/delete.ts","../../src/server/kits/crud/get.ts","../../src/server/kits/crud/getMany.ts","../../src/server/kits/crud/listQuery.ts","../../src/server/kits/crud/page.ts","../../src/server/kits/crud/list.ts","../../src/server/kits/crud/ordinal.ts","../../src/server/kits/crud/reorder.ts","../../src/server/kits/crud/methods.ts","../../src/server/kits/crud/handlers.ts","../../src/server/kits/search/filters.ts","../../src/server/kits/search/results.ts","../../src/server/kits/search/pages.ts","../../src/server/kits/search/run.ts","../../src/server/kits/search/handlers.ts","../../src/server/kits/sharing/aclList.ts","../../src/server/kits/sharing/policy.ts","../../src/server/kits/sharing/roles.ts","../../src/server/kits/sharing/runtime.ts","../../src/server/kits/sharing/admins.ts","../../src/server/kits/sharing/checks.ts","../../src/server/kits/sharing/context.ts","../../src/server/kits/sharing/acl.ts","../../src/server/kits/sharing/listMembers.ts","../../src/server/kits/sharing/members.ts","../../src/server/kits/sharing/methods.ts","../../src/server/kits/sharing/handlers.ts","../../src/server/kits/admin/meta.ts","../../src/server/kits/admin/runtime.ts","../../src/server/kits/admin/list.ts","../../src/server/kits/admin/live.ts","../../src/server/kits/admin/writes.ts","../../src/server/kits/admin/rows.ts","../../src/server/kits/admin/methods.ts","../../src/server/kits/admin/handlers.ts","../../src/server/redisPeers.ts","../../src/server/redis.ts","../../src/server/utils/env.ts","../../src/server/utils/encryption.ts"],"sourcesContent":["// The run-time half of `defineService`'s channels and streams (RFC 0003\n// section 12.5): one handler per channel of the contract, no more and no\n// fewer, with its access; each stream's access form as the access engine\n// decides it; and the service's own stream options (a seed computed when a\n// socket subscribes). The types make the same checks; these catch\n// JavaScript callers and casts when the service is defined.\n\nimport { isAccessLevel } from \"../../contract/access\";\nimport type { AnyContract } from \"../../contract/defineContract\";\nimport { reservedRoomPrefix, socketIdShaped } from \"../../contract/names\";\nimport {\n CHANNEL_DEFAULT_RATE,\n isScopedStream,\n type ChannelDef,\n type PayloadSelector,\n type RoomPrefix,\n type RoomSelector,\n type StreamAccess,\n type StreamDef,\n} from \"../../contract/realtime\";\nimport type { AccessForm } from \"../access/types\";\nimport type {\n AnyChannelHandler,\n AnyStreamSeed,\n ChannelAccess,\n CompiledSelector,\n ServiceChannel,\n ServiceStream,\n StreamRoomAccess,\n} from \"./types\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** A payload key, or a function of the payload, as a function that returns a non-empty string or nothing. */\nfunction compileSelector(selector: PayloadSelector): CompiledSelector {\n const read =\n typeof selector === \"function\"\n ? (selector as (payload: unknown) => unknown)\n : (payload: unknown) => (isRecord(payload) ? payload[selector] : undefined);\n return (payload) => {\n try {\n const value = read(payload);\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n } catch {\n // A selector that throws names nothing: the message is dropped.\n return undefined;\n }\n };\n}\n\n/**\n * The app room a message must come from: a fixed name (checked when the\n * contract was defined), or a function of the payload whose answer names no\n * room when it is not a string, is empty, is reserved (`qd:`, `user:`) or\n * has the shape of a socket id, since `ctx.rooms.join` never puts a socket\n * in such a room.\n */\nfunction compileRoom(room: Exclude<RoomSelector, RoomPrefix>): CompiledSelector {\n if (typeof room === \"string\") {\n return () => room;\n }\n const computed = compileSelector(room);\n return (payload) => {\n const name = computed(payload);\n return name === undefined || reservedRoomPrefix(name) !== undefined || socketIdShaped(name)\n ? undefined\n : name;\n };\n}\n\nfunction compileRequires(def: ChannelDef): ServiceChannel[\"requires\"] {\n const { requires } = def;\n if (requires === undefined) {\n return undefined;\n }\n const { room } = requires;\n if (typeof room === \"object\") {\n return { kind: \"roomPrefix\", prefix: room.prefix };\n }\n if (room !== undefined) {\n return { kind: \"room\", select: compileRoom(room) };\n }\n if (requires.collection === undefined) {\n return { kind: \"entity\", select: compileSelector(requires.entity) };\n }\n return {\n kind: \"collection\",\n collection: requires.collection,\n select: compileSelector(requires.scope),\n };\n}\n\nfunction checkChannelAccess(owner: string, access: unknown, fail: Fail): ChannelAccess {\n if (access === undefined || access === \"authenticated\") {\n return \"authenticated\";\n }\n const keys = isRecord(access) ? Object.keys(access) : [];\n if (!isRecord(access) || keys.length !== 1 || !isAccessLevel(access.service)) {\n fail(`${owner}: access must be \"authenticated\" or { service: level }`);\n }\n return Object.freeze({ service: access.service });\n}\n\nfunction checkChannel(\n service: string,\n name: string,\n def: ChannelDef,\n entry: unknown,\n kinds: ReadonlySet<string> | undefined,\n fail: Fail,\n): ServiceChannel {\n const owner = `channel \"${name}\"`;\n const implementation = typeof entry === \"function\" ? { handler: entry } : entry;\n if (!isRecord(implementation) || typeof implementation.handler !== \"function\") {\n fail(`${owner} must be a handler function or { access, handler }`);\n }\n const unknownKey = Object.keys(implementation).find(\n (key) => ![\"access\", \"handler\"].includes(key),\n );\n if (unknownKey !== undefined) {\n fail(`${owner} has an unknown option \"${unknownKey}\"; the options are access, handler`);\n }\n const ratePerSecond = def.ratePerSecond ?? CHANNEL_DEFAULT_RATE;\n return Object.freeze({\n service,\n name,\n payload: def.payload,\n ratePerSecond,\n // At least one token, so a slow channel (0.2 a second) still lets a message through.\n burst: def.burst ?? Math.max(1, ratePerSecond * 2),\n requires: compileRequires(def),\n access: checkChannelAccess(owner, implementation.access, fail),\n accessDeclared: implementation.access !== undefined,\n kinds,\n handler: implementation.handler as AnyChannelHandler,\n });\n}\n\n/**\n * The channels of a service: `defineService`'s `channels` option checked\n * against the contract's channels, one implementation each, with the kinds\n * of principal the service admits (`undefined`: every kind) as a set.\n */\nexport function compileChannels(\n contract: AnyContract,\n value: unknown,\n kinds: readonly string[] | undefined,\n fail: Fail,\n): ReadonlyMap<string, ServiceChannel> {\n const declared = Object.entries(contract.channels);\n if (value === undefined && declared.length === 0) {\n return new Map();\n }\n if (!isRecord(value)) {\n fail(\"channels must be an object with one implementation per contract channel\");\n }\n const missing = declared.filter(([name]) => !Object.hasOwn(value, name)).map(([name]) => name);\n if (missing.length > 0) {\n fail(`channels has no implementation for ${missing.map((name) => `\"${name}\"`).join(\", \")}`);\n }\n const channels = new Map<string, ServiceChannel>();\n const admitted = kinds === undefined ? undefined : new Set(kinds);\n for (const [name, entry] of Object.entries(value)) {\n const def = Object.hasOwn(contract.channels, name) ? contract.channels[name] : undefined;\n if (def === undefined) {\n fail(`\"${name}\" is not a channel of the contract`);\n }\n channels.set(name, checkChannel(contract.name, name, def, entry, admitted, fail));\n }\n return channels;\n}\n\n/** A stream's access as the engine decides it: the scope is the row id an entry or scope form checks. */\nfunction engineForm(access: StreamAccess | undefined): AccessForm | undefined {\n if (access === undefined || typeof access === \"string\") {\n return access;\n }\n if (access.room !== undefined) {\n // The app room the subscriber's socket is in decides, not the engine.\n return undefined;\n }\n if (access.scope !== undefined) {\n return Object.freeze({ scope: access.scope, of: access.of, id: \"scope\" });\n }\n if (access.entry !== undefined) {\n const service = access.service === undefined ? {} : { service: access.service };\n return Object.freeze({ entry: access.entry, ...service, id: \"scope\" });\n }\n return Object.freeze({ service: access.service });\n}\n\n/** A stream's `access: { room }`, compiled; `undefined` for any other form. */\nfunction roomAccess(access: StreamAccess | undefined): StreamRoomAccess | undefined {\n if (typeof access !== \"object\" || access.room === undefined) {\n return undefined;\n }\n const { room } = access;\n if (typeof room === \"string\") {\n return Object.freeze({ kind: \"name\", room });\n }\n if (typeof room === \"object\") {\n return Object.freeze({ kind: \"prefix\", prefix: room.prefix });\n }\n const computed = compileRoom(room as (payload: never) => string | null | undefined);\n return Object.freeze({\n kind: \"computed\",\n select: (scope: string | undefined) => computed(scope),\n });\n}\n\n/** What a service declares that its streams' row-level access forms need. */\nexport interface StreamNeeds {\n readonly model: string | undefined;\n readonly hasPolicy: boolean;\n}\n\nconst STREAM_OPTION_KEYS = [\"seed\", \"validate\"];\n\n/** One stream's entry in `defineService`'s `streams`, checked: its seed function and when it validates. */\nfunction checkStreamOptions(\n name: string,\n def: StreamDef,\n entry: unknown,\n fail: Fail,\n): Pick<ServiceStream, \"computeSeed\" | \"validate\"> {\n const owner = `streams.${name}`;\n if (entry === undefined) {\n return { computeSeed: undefined, validate: \"always\" };\n }\n if (!isRecord(entry)) {\n fail(`${owner} must be an object: { seed?, validate? }`);\n }\n const unknownKey = Object.keys(entry).find((key) => !STREAM_OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(\n `${owner} has an unknown option \"${unknownKey}\"; the options are ${STREAM_OPTION_KEYS.join(\", \")}`,\n );\n }\n const { seed } = entry;\n if (seed !== undefined && typeof seed !== \"function\") {\n fail(`${owner}.seed must be a function of (scope, ctx) returning the seed's items`);\n }\n if (seed !== undefined && (def.seed ?? 0) > 0) {\n fail(\n `${owner}.seed computes the seed, but the contract's stream keeps the latest ${String(def.seed)} items as its seed; declare one of the two`,\n );\n }\n const { validate = \"always\" } = entry;\n if (validate !== \"always\" && validate !== \"development\") {\n fail(`${owner}.validate must be \"always\" or \"development\"`);\n }\n return { computeSeed: seed as AnyStreamSeed | undefined, validate };\n}\n\nfunction checkStream(\n name: string,\n def: StreamDef,\n needs: StreamNeeds,\n options: unknown,\n fail: Fail,\n): ServiceStream {\n const access = engineForm(def.access);\n if (typeof access === \"object\" && \"entry\" in access && !needs.hasPolicy) {\n fail(\n `stream \"${name}\" uses entry access, which needs the service's access policy: declare model and access`,\n );\n }\n if (typeof access === \"object\" && \"scope\" in access && needs.model === undefined) {\n fail(\n `stream \"${name}\" uses scope access, but the service declares no model; a service without a model may only use \"public\", \"authenticated\" or { service } access`,\n );\n }\n return Object.freeze({\n name,\n item: def.item,\n scoped: isScopedStream(def),\n seed: def.seed ?? 0,\n ...checkStreamOptions(name, def, options, fail),\n volatile: def.volatile === true,\n access,\n room: roomAccess(def.access),\n });\n}\n\n/**\n * The streams of a service, from its contract, with the access forms checked\n * against what it declares, and `defineService`'s `streams` option (a seed\n * function per stream) checked against the contract's streams.\n */\nexport function compileStreams(\n contract: AnyContract,\n needs: StreamNeeds,\n value: unknown,\n fail: Fail,\n): ReadonlyMap<string, ServiceStream> {\n if (value !== undefined && !isRecord(value)) {\n fail(\n \"streams must be an object of options per contract stream: { <stream>: { seed?, validate? } }\",\n );\n }\n const options = value ?? {};\n const unknownStream = Object.keys(options).find((name) => !Object.hasOwn(contract.streams, name));\n if (unknownStream !== undefined) {\n fail(`streams: \"${unknownStream}\" is not a stream of the contract`);\n }\n const streams = new Map<string, ServiceStream>();\n for (const [name, def] of Object.entries(contract.streams)) {\n const entry = Object.hasOwn(options, name) ? options[name] : undefined;\n streams.set(name, checkStream(name, def, needs, entry, fail));\n }\n return streams;\n}\n","// The run-time checks of `defineService`'s data options (RFC 0003 sections 3,\n// 4.1, 5.3, 6 and 11.3): the `model` the rows live in and its `access`\n// policy, the other models the service `writes`, the rows a write `affects`,\n// the `versionColumn` \"not modified\" answers read, who may watch the\n// service's change topic (`watchAccess`), and the kinds of principal it\n// admits (`kinds`, within the app's; each method's within the service's,\n// `access/kinds.ts`). The types make the same checks, kinds' narrowing\n// aside; these repeat them for JavaScript callers and casts.\n\nimport { isAccessLevel } from \"../contract/access\";\nimport type { AnyContract } from \"../contract/defineContract\";\nimport { claimsOption, type ClaimsCheck } from \"./access/claims\";\nimport { narrowKinds } from \"./access/kinds\";\nimport { isAccessPolicy, type AnyAccessPolicy } from \"./access/policy\";\nimport type { WatchAccess } from \"./access/types\";\nimport type { AffectsLink } from \"./service\";\nimport { modelKey } from \"./storage\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\n/** The checked data options of a service definition. */\nexport interface ServiceData {\n readonly model: string | undefined;\n readonly access: AnyAccessPolicy | undefined;\n readonly writes: readonly string[];\n readonly affects: readonly AffectsLink[];\n readonly versionColumn: string | undefined;\n readonly watchAccess: WatchAccess | undefined;\n /** The kinds of principal the service admits: its own `kinds`, else the app's; `undefined` admits every kind. */\n readonly kinds: readonly string[] | undefined;\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isName(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\nfunction isContract(value: unknown): value is AnyContract {\n return isRecord(value) && isName(value.name) && Object.isFrozen(value);\n}\n\n/** The ids a link's value holds: a row id, a list of them, or nothing. */\nfunction idsIn(value: unknown): readonly string[] {\n if (isName(value)) {\n return [value];\n }\n return Array.isArray(value) ? value.filter(isName) : [];\n}\n\nfunction checkLink(index: number, entry: unknown, fail: Fail): AffectsLink {\n const owner = `affects[${index}]`;\n if (!isRecord(entry) || !isContract(entry.service)) {\n fail(`${owner} must be { service: contract, id }`);\n }\n const { id, columns } = entry;\n if (isName(id)) {\n if (columns !== undefined) {\n fail(`${owner}: columns belong to an id function; an id column is its own column`);\n }\n return Object.freeze({\n service: entry.service,\n columns: Object.freeze([id]),\n ids: (values: UnknownRecord) => idsIn(values[id]),\n });\n }\n const listed = Array.isArray(columns) && columns.length > 0 && columns.every(isName);\n if (typeof id !== \"function\" || !listed) {\n fail(\n `${owner}: id must be a column holding the affected row's id, or a function of the written row with the columns it reads in columns`,\n );\n }\n const read = id as (values: UnknownRecord) => unknown;\n return Object.freeze({\n service: entry.service,\n columns: Object.freeze([...(columns as readonly string[])]),\n ids: (values: UnknownRecord) => idsIn(read(values)),\n });\n}\n\nfunction checkAffects(value: unknown, model: string | undefined, fail: Fail): AffectsLink[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value)) {\n fail(\"affects must be a list of { service, id }\");\n }\n if (model === undefined) {\n fail(\"affects needs model: it reads the written rows of the service's model\");\n }\n return value.map((entry: unknown, index) => checkLink(index, entry, fail));\n}\n\nfunction checkWrites(value: unknown, fail: Fail): readonly string[] {\n if (value === undefined) {\n return [];\n }\n if (!Array.isArray(value) || !value.every(isName)) {\n fail('writes must be a list of model names, as the client names them (\"taskLabel\")');\n }\n return Object.freeze([...(value as readonly string[])]);\n}\n\n/** `watchAccess`: `\"public\"`, `\"authenticated\"` or `{ service: level }`; none keeps the service topic closed. */\nfunction checkWatchAccess(value: unknown, fail: Fail): WatchAccess | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (value === \"public\" || value === \"authenticated\") {\n return value;\n }\n if (!isRecord(value) || Object.keys(value).length !== 1 || !isAccessLevel(value.service)) {\n fail('watchAccess must be \"public\", \"authenticated\" or { service: level }');\n }\n return Object.freeze({ service: value.service });\n}\n\n/**\n * `initQuickdraw`'s `kinds`, checked: the kinds of principal every service\n * the instance defines admits, unless it narrows them.\n */\nexport function checkAppKinds(value: unknown): readonly string[] | undefined {\n return narrowKinds(value, undefined, (message) => {\n throw new TypeError(`initQuickdraw: ${message}`);\n });\n}\n\n/**\n * A method's own `kinds`, within its service's: the kinds it admits, its\n * service's when it declares none. A `\"public\"` method declares none, since a\n * caller of a kind it left out would call it signed out; it keeps the\n * service's list, which signed-in callers meet.\n */\nexport function checkMethodKinds(\n owner: string,\n entry: UnknownRecord,\n data: ServiceData,\n fail: Fail,\n): readonly string[] | undefined {\n if (entry.kinds !== undefined && entry.access === \"public\") {\n fail(\n `${owner} is \"public\", so kinds cannot narrow who may call it: a caller of a kind it left out would call it signed out. Leave kinds out, or give it a form that needs a principal`,\n );\n }\n return narrowKinds(entry.kinds, { kinds: data.kinds, by: \"its service\" }, (message) =>\n fail(`${owner}: ${message}`),\n );\n}\n\n/**\n * A method's `claims` (`access/claims.ts`): a function, on a method whose\n * form needs a principal; `undefined` when it declares none.\n */\nexport function checkMethodClaims(\n owner: string,\n entry: UnknownRecord,\n fail: Fail,\n): ClaimsCheck | undefined {\n return claimsOption(owner, entry, fail);\n}\n\n/**\n * Checks a definition's `model`, `access`, `writes`, `affects`,\n * `versionColumn`, `watchAccess` and `kinds`, the last within `appKinds`, the\n * kinds of principal `initQuickdraw` admits.\n */\nexport function checkServiceData(\n definition: UnknownRecord,\n appKinds: readonly string[] | undefined,\n fail: Fail,\n): ServiceData {\n const { model, access, versionColumn } = definition;\n if (model !== undefined && !isName(model)) {\n fail('model must be the database model the rows live in, as the client names it (\"task\")');\n }\n if (access !== undefined && !isAccessPolicy(access)) {\n fail(\"access must be an access policy: owner, jsonAcl, members, inherit, anyOf or resolver\");\n }\n if (access !== undefined && model === undefined) {\n fail(\"access needs model: an access policy reads the rows of the service's model\");\n }\n if (versionColumn !== undefined && (!isName(versionColumn) || model === undefined)) {\n fail(\"versionColumn must be a column of the service's model, so it needs model\");\n }\n return {\n model,\n access,\n writes: checkWrites(definition.writes, fail),\n affects: Object.freeze(checkAffects(definition.affects, model, fail)),\n versionColumn,\n watchAccess: checkWatchAccess(definition.watchAccess, fail),\n kinds: narrowKinds(definition.kinds, { kinds: appKinds, by: \"initQuickdraw\" }, fail),\n };\n}\n\n/**\n * `watch: { service: [models] }` names models whose writes change the\n * service's topic: its `model` and those in its `writes` (finding F7.3).\n * Any other name could never match, so the query would never be told.\n */\nexport function checkWatchedModels(\n contract: AnyContract,\n name: string,\n models: unknown,\n data: ServiceData,\n fail: Fail,\n): void {\n const own = [data.model, ...data.writes].filter((model) => model !== undefined).map(modelKey);\n const listed = Array.isArray(models) ? models : [];\n const valid =\n listed.length > 0 &&\n listed.every((model) => typeof model === \"string\" && model !== \"\") &&\n new Set(listed.map((model) => modelKey(String(model)))).size === listed.length;\n if (!valid) {\n fail(\n `method \"${name}\": watch { service } lists the models of the service it watches: { service: [\"gameScore\"] }`,\n );\n }\n for (const model of listed as string[]) {\n if (!own.includes(modelKey(model))) {\n const known = own.length === 0 ? \"none\" : own.map((key) => `\"${key}\"`).join(\", \");\n fail(\n `method \"${name}\" watches the model \"${model}\", which ${contract.name} neither declares as its model nor lists in writes (its models: ${known})`,\n );\n }\n }\n}\n","// The run-time half of `defineService`: the checks the types already make,\n// repeated for JavaScript callers and casts, so a broken service fails when\n// it is defined rather than on its first call. It returns the frozen\n// service the registry and the dispatcher read. The runtime it is given,\n// what every service of one `initQuickdraw` keeps, is made here too, from\n// that call's options, checked.\n\nimport type { AnyContract } from \"../contract/defineContract\";\nimport { accessFormProblem, isCustomAccess } from \"./access/forms\";\nimport { rowlessProblem } from \"./access/rowless\";\nimport { compileCollections } from \"./collections/define\";\nimport { compileProjections, projectedOutput, type Projection } from \"./emit/projection\";\nimport { MAX_TIMEOUT_MS } from \"./pipeline/settings\";\nimport { outputSchemaOf, schemaOutputOf } from \"./pipeline/validation\";\nimport { compileChannels, compileStreams } from \"./realtime/define\";\nimport {\n handlerProblem,\n isCallerDependent,\n registerRuntime,\n type AnyHandler,\n type AnyService,\n type ServiceMethod,\n type ServiceRuntime,\n} from \"./service\";\nimport {\n checkAppKinds,\n checkMethodClaims,\n checkMethodKinds,\n checkServiceData,\n checkWatchedModels,\n type ServiceData,\n} from \"./serviceData\";\n\ntype Fail = (message: string) => never;\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nconst DEFINITION_KEYS = new Set([\n \"model\",\n \"access\",\n \"writes\",\n \"affects\",\n \"project\",\n \"versionColumn\",\n \"collections\",\n \"watchAccess\",\n \"methods\",\n \"channels\",\n \"streams\",\n \"onRoomLeave\",\n \"adminBypass\",\n \"kinds\",\n]);\n\nconst METHOD_KEYS = new Set([\n \"access\",\n \"handler\",\n \"share\",\n \"ttlMs\",\n \"timeoutMs\",\n \"version\",\n \"rowless\",\n \"kinds\",\n \"claims\",\n]);\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction checkKeys(\n value: UnknownRecord,\n allowed: ReadonlySet<string>,\n owner: string,\n fail: Fail,\n): void {\n const unknownKey = Object.keys(value).find((key) => !allowed.has(key));\n if (unknownKey !== undefined) {\n fail(\n `${owner} has an unknown option \"${unknownKey}\"; the options are ${[...allowed].join(\", \")}`,\n );\n }\n}\n\nfunction isDuration(value: unknown, max: number): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0 && value <= max;\n}\n\nfunction checkContract(contract: unknown): AnyContract {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n contract.name.length > 0 &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n throw new TypeError(\"defineService: the first argument must be a contract from defineContract\");\n }\n return contract as unknown as AnyContract;\n}\n\nfunction checkShare(owner: string, entry: UnknownRecord, fail: Fail): void {\n const { share, ttlMs } = entry;\n if (share !== undefined && share !== \"caller\" && share !== \"all\") {\n fail(`${owner}: share must be \"caller\" or \"all\"`);\n }\n if (share === \"all\" && isRecord(entry.access) && entry.access.kind === \"custom\") {\n fail(\n `${owner} has custom access, so it cannot share: \"all\"; its result may depend on who asks`,\n );\n }\n if (share === \"all\" && typeof entry.handler === \"function\" && isCallerDependent(entry.handler)) {\n fail(\n `${owner} is a kit method whose result depends on who asks, so it cannot share: \"all\"; share: \"caller\" runs one principal's identical calls once`,\n );\n }\n if (ttlMs !== undefined && (share === undefined || !isDuration(ttlMs, MAX_TIMEOUT_MS))) {\n fail(`${owner}: ttlMs needs share and must be a positive number of milliseconds`);\n }\n}\n\nfunction checkQueryOptions(\n owner: string,\n entry: UnknownRecord,\n kind: ServiceMethod[\"kind\"],\n fail: Fail,\n): void {\n const queryOnly = [entry.share, entry.ttlMs, entry.version].some((value) => value !== undefined);\n if (kind === \"mutation\" && queryOnly) {\n fail(`${owner} is a mutation; share, ttlMs and version are for queries`);\n }\n checkShare(owner, entry, fail);\n if (entry.version !== undefined && typeof entry.version !== \"function\") {\n fail(`${owner}: version must be a function of (input, ctx)`);\n }\n}\n\nfunction checkMethod(\n contract: AnyContract,\n projections: ReadonlyMap<string, Projection>,\n data: ServiceData,\n name: string,\n entry: unknown,\n fail: Fail,\n): ServiceMethod {\n const owner = `method \"${name}\"`;\n const def = contract.methods[name];\n if (def === undefined) {\n fail(`\"${name}\" is not a method of the contract`);\n }\n if (!isRecord(entry)) {\n fail(`${owner} must be { access, handler }`);\n }\n checkKeys(entry, METHOD_KEYS, owner, fail);\n const accessProblem = accessFormProblem(entry.access);\n if (accessProblem !== undefined) {\n fail(`${owner}: access ${accessProblem}`);\n }\n if (typeof entry.handler !== \"function\") {\n fail(`${owner} needs a handler function`);\n }\n if (entry.timeoutMs !== undefined && !isDuration(entry.timeoutMs, MAX_TIMEOUT_MS)) {\n fail(\n `${owner}: timeoutMs must be a positive number of milliseconds, at most ${MAX_TIMEOUT_MS}`,\n );\n }\n if (entry.rowless !== undefined && typeof entry.rowless !== \"boolean\") {\n fail(`${owner}: rowless must be true, or left out`);\n }\n checkQueryOptions(owner, entry, def.kind, fail);\n const kinds = checkMethodKinds(owner, entry, data, fail);\n const claims = checkMethodClaims(owner, entry, fail);\n const projection = projectedOutput(def.output, projections);\n return Object.freeze({\n name,\n kind: def.kind,\n input: def.input,\n output: outputSchemaOf(contract, def.output),\n projection,\n schemaOutput: projection === undefined ? schemaOutputOf(def.output) : undefined,\n access: entry.access as ServiceMethod[\"access\"],\n kinds,\n claims,\n handler: entry.handler as AnyHandler,\n share: entry.share as ServiceMethod[\"share\"],\n ttlMs: entry.ttlMs as number | undefined,\n timeoutMs: entry.timeoutMs as number | undefined,\n version: entry.version as ServiceMethod[\"version\"],\n rowless: entry.rowless === true,\n });\n}\n\nfunction checkMethods(\n contract: AnyContract,\n projections: ReadonlyMap<string, Projection>,\n data: ServiceData,\n value: unknown,\n fail: Fail,\n): Record<string, ServiceMethod> {\n if (!isRecord(value)) {\n fail(\"methods must be an object with one implementation per contract method\");\n }\n const missing = Object.keys(contract.methods).filter((name) => !Object.hasOwn(value, name));\n if (missing.length > 0) {\n fail(`methods has no implementation for ${missing.map((name) => `\"${name}\"`).join(\", \")}`);\n }\n const methods: Record<string, ServiceMethod> = {};\n for (const [name, entry] of Object.entries(value)) {\n methods[name] = checkMethod(contract, projections, data, name, entry, fail);\n }\n return methods;\n}\n\n/**\n * A query's `watch` (RFC 0003 sections 2 and 11.3) names the topic of one\n * scope of one of the service's collections: the collection must be one the\n * service serves, and `scope` the function that finds the scope from the\n * input. `defineContract` checks the same; this catches a contract it never\n * saw. A watch of the service's topic needs `watchAccess`, and one narrowed\n * to models names the service's own (`checkWatchedModels`).\n */\nfunction checkWatches(\n contract: AnyContract,\n collections: ReadonlyMap<string, unknown>,\n data: ServiceData,\n fail: Fail,\n): void {\n for (const [name, def] of Object.entries(contract.methods)) {\n const watch: unknown = def.watch;\n if (watch === undefined) {\n continue;\n }\n if (def.kind !== \"query\") {\n fail(`method \"${name}\" is a mutation; only a query can watch`);\n }\n if (watch === \"service\" || (isRecord(watch) && Object.hasOwn(watch, \"service\"))) {\n if (data.watchAccess === undefined) {\n fail(\n `method \"${name}\" watches the service's topic, which is closed without watchAccess: declare who may watch it (\"public\", \"authenticated\" or { service: level })`,\n );\n }\n if (watch !== \"service\") {\n checkWatchedModels(contract, name, watch.service, data, fail);\n }\n continue;\n }\n if (!isRecord(watch) || typeof watch.scope !== \"function\") {\n fail(`method \"${name}\": watch needs a scope function, which finds the scope from the input`);\n }\n if (typeof watch.collection !== \"string\" || !collections.has(watch.collection)) {\n fail(\n `method \"${name}\" watches \"${String(watch.collection)}\", which is not a collection of ${contract.name}`,\n );\n }\n }\n}\n\n/**\n * The row-level access forms need what the service declares (RFC 0003\n * section 3): `entry` asks the service's own policy, and `scope` (another\n * service's policy) is for services that have a model. A service without a\n * model may only use `\"public\"`, `\"authenticated\"`, `{ service }` or `custom`.\n */\nfunction checkRowForms(\n methods: Readonly<Record<string, ServiceMethod>>,\n data: ServiceData,\n fail: Fail,\n): void {\n for (const method of Object.values(methods)) {\n const form = method.access;\n if (typeof form !== \"object\" || isCustomAccess(form)) {\n continue;\n }\n if (form.entry !== undefined && data.access === undefined) {\n fail(\n `method \"${method.name}\" uses entry access, which needs the service's access policy: declare model and access`,\n );\n }\n if (form.scope !== undefined && data.model === undefined) {\n fail(\n `method \"${method.name}\" uses scope access, but the service declares no model; a service without a model may only use \"public\", \"authenticated\", { service } or custom access`,\n );\n }\n }\n}\n\n/**\n * On a service with an access policy, a method whose input has `id` and\n * whose form asks the policy nothing about the row that id names (an open\n * form, `custom`, `{ scope }`, or `{ entry }` on another key) is refused\n * unless it says `rowless: true` (`access/rowless.ts`). A service without a\n * policy has no row check to skip.\n */\nfunction checkRowless(\n contract: AnyContract,\n methods: Readonly<Record<string, ServiceMethod>>,\n data: ServiceData,\n fail: Fail,\n): void {\n if (data.access === undefined) {\n return;\n }\n for (const method of Object.values(methods)) {\n const problem = rowlessProblem(method, contract.name);\n if (problem !== undefined) {\n fail(problem);\n }\n }\n}\n\n/** The checks handlers carry for the service they run in (`checkWhenDefined`): a kit's need a model. */\nfunction checkHandlers(service: AnyService, fail: Fail): void {\n for (const method of Object.values(service.methods)) {\n const problem = handlerProblem(method.handler, service);\n if (problem !== undefined) {\n fail(`method \"${method.name}\": ${problem}`);\n }\n }\n}\n\n/**\n * The runtime every service of one `initQuickdraw` keeps, from that call's\n * options, checked: `context`, which adds the app's fields to every\n * handler's `ctx`, and `kinds`, the kinds of principal every service admits\n * unless it narrows them (RFC 0003 section 4.1). `adopt` makes a dispatcher\n * the instance's own.\n */\nexport function createRuntime(\n options: unknown,\n adopt: NonNullable<ServiceRuntime[\"adopt\"]>,\n): ServiceRuntime {\n if (options === undefined) {\n return Object.freeze({ extendContext: undefined, kinds: undefined, adopt });\n }\n if (typeof options !== \"object\" || options === null) {\n throw new TypeError(\"initQuickdraw: options must be an object\");\n }\n const { context, kinds } = options as { readonly context?: unknown; readonly kinds?: unknown };\n if (context !== undefined && typeof context !== \"function\") {\n throw new TypeError(\"initQuickdraw: context must be a function of the base context\");\n }\n return Object.freeze({\n extendContext: context as ServiceRuntime[\"extendContext\"],\n kinds: checkAppKinds(kinds),\n adopt,\n });\n}\n\n/** Checks a service definition and returns the frozen service, registered with `runtime`. */\nexport function buildService(\n runtime: ServiceRuntime,\n contract: unknown,\n definition: unknown,\n): AnyService {\n const checked = checkContract(contract);\n const fail: Fail = (message) => {\n throw new TypeError(`defineService(\"${checked.name}\"): ${message}`);\n };\n if (!isRecord(definition)) {\n fail(\"the definition must be an object\");\n }\n checkKeys(definition, DEFINITION_KEYS, \"the definition\", fail);\n const { adminBypass = true, onRoomLeave } = definition;\n if (typeof adminBypass !== \"boolean\") {\n fail(\"adminBypass must be a boolean\");\n }\n if (onRoomLeave !== undefined && typeof onRoomLeave !== \"function\") {\n fail(\"onRoomLeave must be a function of the leave and a run context\");\n }\n const data = checkServiceData(definition, runtime.kinds, fail);\n const projections = compileProjections(checked, definition.project, fail);\n const collections = compileCollections(\n checked,\n projections,\n data.model,\n definition.collections,\n fail,\n data.access,\n );\n checkWatches(checked, collections, data, fail);\n const methods = checkMethods(checked, projections, data, definition.methods, fail);\n checkRowForms(methods, data, fail);\n checkRowless(checked, methods, data, fail);\n const service: AnyService = Object.freeze({\n name: checked.name,\n contract: checked,\n ...data,\n projections,\n collections,\n adminBypass,\n methods: Object.freeze(methods),\n channels: compileChannels(checked, definition.channels, data.kinds, fail),\n streams: compileStreams(\n checked,\n { model: data.model, hasPolicy: data.access !== undefined },\n definition.streams,\n fail,\n ),\n onRoomLeave: onRoomLeave as AnyService[\"onRoomLeave\"],\n });\n checkHandlers(service, fail);\n registerRuntime(service, runtime);\n return service;\n}\n","// `initQuickdraw`: the one place an app states its types (RFC 0003 section 3).\n//\n// export const qd = initQuickdraw<{ db: AppPrisma; principal: AppPrincipal }>();\n// export const taskService = qd.defineService(task, { methods: { ... } });\n//\n// Every service, handler argument and caller is typed from it. `context`\n// adds the app's own fields to every handler's `ctx`, once for the whole app;\n// it replaces 4.1's habit of overriding `defineMethod` per service.\n\nimport type { AnyContract } from \"../contract/defineContract\";\nimport { QuickdrawError } from \"../protocol/errors\";\nimport { buildService, createRuntime } from \"./buildService\";\nimport { callerGrantsOf, createCaller, type CallerFor } from \"./caller\";\nimport type { BaseContext, RunContext, RunOptions } from \"./context\";\nimport { createServer, type QuickdrawServer, type ServerOptions } from \"./createServer\";\nimport type { DefineService } from \"./defineService\";\nimport {\n createDispatcher,\n type Dispatcher,\n type DispatcherCollections,\n type DispatcherOptions,\n type Presence,\n type ServerRooms,\n type Service,\n type StreamHandle,\n} from \"./dispatcher\";\nimport type {\n ContextExtensionOf,\n McpContextOf,\n PrincipalKindOf,\n PrincipalOf,\n QuickdrawTypes,\n} from \"./types\";\nimport { runBeforeAnyDispatcher } from \"./uow/unitOfWork\";\n\n/**\n * Builds the app's fields of `ctx` from the framework's. It runs once per\n * call, before access is checked, so `custom` checks see the fields too.\n */\nexport type ContextFactory<T extends QuickdrawTypes> = (\n base: BaseContext<PrincipalOf<T> | null, McpContextOf<T>>,\n) => ContextExtensionOf<T>;\n\n/** Options of `initQuickdraw`. */\nexport interface InitOptions<T extends QuickdrawTypes> {\n /** Adds the app's fields to every handler's `ctx`. Required when the app's types declare `context`. */\n readonly context?: ContextFactory<T>;\n /**\n * The kinds of principal every service this instance defines admits\n * (RFC 0003 section 4.1), so a new service starts closed to the rest:\n * `kinds: [\"user\", \"agent\"]`. A service's `kinds`, and a method's, may\n * only narrow it. A principal of another kind, or without a `kind`, gets\n * `FORBIDDEN` before any access form or `Admin` grant is asked; an\n * anonymous caller is left to the form. Leave it out to admit every kind.\n */\n readonly kinds?: readonly PrincipalKindOf<T>[];\n}\n\n/** `initQuickdraw`'s arguments: the options are required when `T` declares `context`. */\nexport type InitArgs<T extends QuickdrawTypes> = T extends { readonly context: object }\n ? [options: InitOptions<T> & { readonly context: ContextFactory<T> }]\n : [options?: InitOptions<T>];\n\n/** What `initQuickdraw` returns. */\nexport interface Quickdraw<T extends QuickdrawTypes> {\n /**\n * Defines a service from its contract: one `{ access, handler }` per\n * contract method, no more and no fewer.\n */\n readonly defineService: DefineService<T>;\n /**\n * Creates a dispatcher for `services` and makes it the one `qd.caller`\n * calls through. The last dispatcher created wins.\n */\n createDispatcher<const S extends readonly Service<T>[]>(\n options: DispatcherOptions<S>,\n ): Dispatcher<S>;\n /**\n * An in-process caller acting as `principal` (`null` for anonymous),\n * through the dispatcher this instance created last:\n * `qd.caller(user).taskService.rename(input)`. Typed by the `contracts` of\n * the app's types; `dispatcher.caller` is typed by its own services.\n *\n * Through a server (`qd.createServer`, or `createTestApp`), a principal\n * that carries no `serviceAccess` gets the grants the server's\n * `auth.loadServiceAccess` loads, as a socket's handshake and an HTTP\n * call do: at the caller's first call, and again at the next call after\n * the server applied new grants to a user (`server.access.refresh`, a\n * tracked write to `auth.serviceAccessSource`). So an app's REST route\n * calls as the user's sockets would: `qd.caller(sessionOf(req).principal)`.\n * A principal that carries grants (even `{}`) keeps exactly those; a load\n * that fails rejects the call with `INTERNAL` and is tried again at the\n * next one.\n */\n caller(principal: PrincipalOf<T> | null): CallerFor<T>;\n /**\n * Runs `fn` inside a unit of work of the dispatcher this instance created\n * last, so the tracked writes of a job, script or webhook flush to its\n * sinks once `fn` settles, as a method's do (RFC 0003 section 5.1). Writes\n * made outside any unit of work still flush, on the next tick, with a\n * development warning. Inside a method or a transaction, `fn` joins it,\n * unless `{ detached: true }` gives it a unit of its own: background work\n * a handler starts and does not await (see {@link RunOptions}).\n * `fn` gets a {@link RunContext} (`{ touch, log, principal: null }`):\n * `ctx.touch` records the rows a raw SQL write changed.\n *\n * Before this instance created any dispatcher (a boot-time seed that runs\n * before `createServer`), `fn` still runs in a unit of work of its own:\n * its tracked writes raise no ambient warning and flush once it settles,\n * to the dispatcher the tracked client is attached to then, which before\n * any server is none, so they reach no one (no socket can be subscribed\n * yet; behind a cluster, other nodes' subscribers do not hear of them\n * either: write after `createServer` when they must). `ctx.touch` records\n * nothing there, and `ctx.log` is the console's.\n *\n * @example\n * await qd.run(() => db.task.updateMany({ where: { dueAt: { lt: now } }, data: { status: \"late\" } }));\n * await qd.run(async (ctx) => {\n * await db.$executeRaw`UPDATE \"Task\" SET \"status\" = 'late' WHERE \"id\" = ANY(${ids})`;\n * ctx.touch(\"task\", ids);\n * });\n */\n run<R>(fn: (ctx: RunContext) => R | PromiseLike<R>, options?: RunOptions): Promise<R>;\n /**\n * The collections of the dispatcher this instance created last (RFC 0003\n * section 7): `qd.collections.reset(contract, collection, scope)` sends one\n * scope a `reset`, for a change tracked writes cannot describe.\n */\n readonly collections: DispatcherCollections;\n /**\n * The handle of a stream (RFC 0003 section 12.5), for handlers, jobs and\n * timers: `qd.stream(task, \"logs\").push(taskId, line)` (`push(item)` for a\n * global stream; `pushMany(taskId, lines)` for several at once). Each push\n * goes through the dispatcher this instance created last, so a handle can\n * be made when a module loads; pushing before any dispatcher exists, or to\n * a stream it does not serve, throws.\n * Throws a `TypeError` at once for a stream the contract does not declare.\n */\n stream<C extends AnyContract, K extends keyof C[\"streams\"] & string>(\n contract: C,\n name: K,\n ): StreamHandle<C, K>;\n /**\n * Who is online and who is in a room (RFC 0003 section 12.5), through the\n * dispatcher this instance created last: the same as `ctx.presence`.\n */\n readonly presence: Presence;\n /**\n * App rooms from code that is not a handler (RFC 0003 section 12.5), through\n * the dispatcher this instance created last: a game loop's or a job's typed\n * room events (`qd.rooms.emit(room, contract, event, payload)`,\n * `emitToUser`), and `qd.rooms.leave(room, { userId })`, which takes every\n * socket of the user out of the room on every node. The same as the\n * socket-free half of `ctx.rooms`; using it before any dispatcher exists\n * throws.\n */\n readonly rooms: ServerRooms;\n /**\n * Serves `services` over Socket.IO and HTTP on the app's Express app and\n * HTTP server (see `createServer`), and makes the server's dispatcher the\n * one `qd.caller` calls through.\n */\n createServer<const S extends readonly Service<T>[]>(\n options: ServerOptions<S>,\n ): QuickdrawServer<S>;\n}\n\nconst NEEDS: Readonly<Record<string, string>> = Object.freeze({\n \"qd.collections.reset\": \"send through\",\n \"qd.stream\": \"push through\",\n \"qd.presence\": \"ask\",\n \"qd.rooms\": \"send through\",\n});\n\nfunction noDispatcher(member: string): never {\n throw new QuickdrawError(\n \"INTERNAL\",\n `${member} has no dispatcher to ${NEEDS[member] ?? \"call through\"}: create one with qd.createDispatcher (or qd.createServer) first`,\n );\n}\n\ntype Current = () => Dispatcher | undefined;\n\n/** `qd.stream`: a handle that pushes through the current dispatcher, resolving the stream once per dispatcher. */\nfunction streamOf(\n current: Current,\n contract: AnyContract,\n name: string,\n): StreamHandle<AnyContract, string> {\n const streams: unknown =\n typeof contract === \"object\" && contract !== null ? contract.streams : undefined;\n if (typeof streams !== \"object\" || streams === null || !Object.hasOwn(streams, name)) {\n throw new TypeError(\n `qd.stream: ${String(contract?.name)} declares no stream \"${String(name)}\"`,\n );\n }\n let resolved:\n | { readonly from: Dispatcher; readonly handle: StreamHandle<AnyContract, string> }\n | undefined;\n const handle = (): StreamHandle<AnyContract, string> => {\n const from = current() ?? noDispatcher(\"qd.stream\");\n if (resolved?.from !== from) {\n resolved = { from, handle: from.stream(contract, name) };\n }\n return resolved.handle;\n };\n return Object.freeze({\n push(...args: unknown[]): void {\n (handle().push as (...items: unknown[]) => void)(...args);\n },\n pushMany(...args: unknown[]): void {\n (handle().pushMany as (...items: unknown[]) => void)(...args);\n },\n }) as StreamHandle<AnyContract, string>;\n}\n\n/** `qd.presence`: presence through the current dispatcher. */\nfunction presenceOf(current: Current): Presence {\n const presence = (): Presence => (current() ?? noDispatcher(\"qd.presence\")).presence;\n return Object.freeze({\n isOnline: async (userId: string) => await presence().isOnline(userId),\n lastSeen: async (userId: string) => await presence().lastSeen(userId),\n count: async (room: string) => await presence().count(room),\n users: async (room: string) => await presence().users(room),\n });\n}\n\n/** `qd.rooms`: app rooms through the current dispatcher. */\nfunction roomsOf(current: Current): ServerRooms {\n const rooms = (): ServerRooms => (current() ?? noDispatcher(\"qd.rooms\")).rooms;\n return Object.freeze({\n emit: (...args: Parameters<ServerRooms[\"emit\"]>) => {\n rooms().emit(...args);\n },\n emitToUser: (...args: Parameters<ServerRooms[\"emitToUser\"]>) => {\n rooms().emitToUser(...args);\n },\n leave: async (room: string, target: Parameters<ServerRooms[\"leave\"]>[1]) =>\n await rooms().leave(room, target),\n size: (room: string) => rooms().size(room),\n }) as ServerRooms;\n}\n\n/**\n * Starts a quickdraw app. The type argument states the app's types once:\n * the database client handlers receive, the principal type, the fields\n * `context` adds to `ctx`, and the contracts that type `qd.caller`.\n *\n * @example\n * export const qd = initQuickdraw<{ db: AppPrisma; principal: AppPrincipal }>();\n */\nexport function initQuickdraw<T extends QuickdrawTypes = QuickdrawTypes>(\n ...args: InitArgs<T>\n): Quickdraw<T> {\n let current: Dispatcher | undefined;\n const runtime = createRuntime(args[0], (dispatcher) => {\n current = dispatcher as Dispatcher;\n });\n const qd: Quickdraw<T> = {\n defineService: ((contract: unknown, definition: unknown) =>\n buildService(runtime, contract, definition)) as DefineService<T>,\n createDispatcher(options) {\n const dispatcher = createDispatcher(options);\n current = dispatcher as Dispatcher;\n return dispatcher;\n },\n caller: (principal) =>\n createCaller(() => (current ?? noDispatcher(\"qd.caller\")).call, principal, {\n grants: () => callerGrantsOf(current),\n }) as CallerFor<T>,\n run: async (fn, options) =>\n current === undefined\n ? await runBeforeAnyDispatcher(fn, options)\n : await current.run(fn, options),\n collections: Object.freeze({\n reset: (contract, collection, scope) => {\n (current ?? noDispatcher(\"qd.collections.reset\")).collections.reset(\n contract,\n collection,\n scope,\n );\n },\n } satisfies DispatcherCollections),\n stream: <C extends AnyContract, K extends keyof C[\"streams\"] & string>(contract: C, name: K) =>\n streamOf(() => current, contract, name) as unknown as StreamHandle<C, K>,\n presence: presenceOf(() => current),\n rooms: roomsOf(() => current),\n createServer(options) {\n const server = createServer(options);\n current = server.dispatcher as Dispatcher;\n return server;\n },\n };\n return Object.freeze(qd);\n}\n","// `owner(field)` (RFC 0003 section 4.2): the user named in a column of the\n// row has `Admin` on it, and nobody else has anything.\n\nimport { checkName, definePolicy, levelsById, type AccessPolicy } from \"../policy\";\n\n/**\n * The user whose id is in `field` has `Admin` on the row; everyone else has\n * no level. One query reads `id` and `field` of every row asked about.\n *\n * @example\n * qd.defineService(project, { model: \"project\", access: owner(\"ownerId\"), methods });\n */\nexport function owner<const Field extends string>(field: Field): AccessPolicy<Field, never> {\n checkName(\"owner(field)\", \"field\", field);\n return definePolicy({\n kind: \"owner\",\n field,\n reads: { columns: [field], memberships: [], inherits: [], storage: true },\n async levelsFor(principal, ids, tools) {\n const rows = await tools.rows(ids);\n return levelsById(ids, (id) => (rows.get(id)?.[field] === principal.userId ? \"Admin\" : null));\n },\n accessWhere: (principal) => Promise.resolve({ [field]: principal.userId }),\n });\n}\n","// `jsonAcl(field, { owner? })` (RFC 0003 section 4.2): the level comes from a\n// JSON access list on the row, `[{ userId, level }]`, the shape 4.x apps\n// store (`ACL` on the root export), plus `Admin` for the owner column when\n// one is named. Ported from 4.1's `checkEntryACL`\n// (4.1 `src/server/BaseService.ts:526-547`), which read one row per check.\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport { levelsAtLeast, maxLevel } from \"../levels\";\nimport {\n checkName,\n definePolicy,\n levelsById,\n type AccessPolicy,\n type AnyAccessPolicy,\n type RowLevel,\n} from \"../policy\";\nimport type { StorageRow, StorageWhere } from \"../../storage\";\n\n/** Options of {@link jsonAcl}. */\nexport interface JsonAclOptions<Owner extends string = string> {\n /** A column holding the owner's user id; the owner has `Admin`. */\n readonly owner?: Owner;\n}\n\n/** The columns a `jsonAcl` policy reads: its access list, and its owner column when it names one. */\nexport interface JsonAclColumns {\n /** The column holding the `[{ userId, level }]` list. */\n readonly field: string;\n /** The column holding the owner's user id, or `undefined` without an owner. */\n readonly owner: string | undefined;\n}\n\nconst COLUMNS = new WeakMap<object, JsonAclColumns>();\n\n/**\n * The columns of a policy `jsonAcl` made, or `undefined` for any other\n * policy: what the sharing kit reads and writes.\n */\nexport function jsonAclColumnsOf(policy: AnyAccessPolicy): JsonAclColumns | undefined {\n return COLUMNS.get(policy);\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * The highest level the access list grants `userId`. A value that is not a\n * list grants nothing; so does an entry that is not `{ userId, level }` with\n * a known level. Several entries for one user give the highest of them,\n * which is what `accessWhere` matches.\n */\nfunction aclLevel(acl: unknown, userId: string): RowLevel {\n if (!Array.isArray(acl)) {\n return null;\n }\n let level: RowLevel = null;\n for (const entry of acl) {\n if (isRecord(entry) && entry.userId === userId) {\n level = maxLevel(level, entry.level as AccessLevel);\n }\n }\n return level;\n}\n\n/**\n * The level comes from the JSON access list in `field`, `[{ userId, level }]`,\n * plus `Admin` for the user named in the `owner` column. One query reads both\n * columns of every row asked about. A malformed list, or an entry with an\n * unknown level, grants nothing.\n *\n * List filters match the list with JSON containment (Prisma's\n * `array_contains`, PostgreSQL's `@>`).\n *\n * @example\n * access: jsonAcl(\"acl\", { owner: \"ownerId\" }),\n */\nexport function jsonAcl<const Field extends string, const Owner extends string = never>(\n field: Field,\n options: JsonAclOptions<Owner> = {},\n): AccessPolicy<Field | Owner, never> {\n checkName(\"jsonAcl(field)\", \"field\", field);\n const ownerColumn = options.owner;\n if (ownerColumn !== undefined) {\n checkName(\"jsonAcl(field, { owner })\", \"owner\", ownerColumn);\n }\n const levelOf = (row: StorageRow | null | undefined, userId: string): RowLevel => {\n if (row === null || row === undefined) {\n return null;\n }\n const owned = ownerColumn !== undefined && row[ownerColumn] === userId ? \"Admin\" : null;\n return maxLevel(owned, aclLevel(row[field], userId));\n };\n const policy = definePolicy<AccessPolicy<Field | Owner, never>>({\n kind: \"jsonAcl\",\n field,\n owner: ownerColumn,\n reads: {\n columns: ownerColumn === undefined ? [field] : [field, ownerColumn],\n memberships: [],\n inherits: [],\n storage: true,\n },\n async levelsFor(principal, ids, tools) {\n const rows = await tools.rows(ids);\n return levelsById(ids, (id) => levelOf(rows.get(id), principal.userId));\n },\n accessWhere(principal, level) {\n const listed: StorageWhere[] = levelsAtLeast(level).map((granted) => ({\n [field]: { array_contains: [{ userId: principal.userId, level: granted }] },\n }));\n const owned = ownerColumn === undefined ? [] : [{ [ownerColumn]: principal.userId }];\n return Promise.resolve({ OR: [...owned, ...listed] });\n },\n });\n COLUMNS.set(policy, Object.freeze({ field, owner: ownerColumn }));\n return policy;\n}\n","// `inherit({ from, via })` (RFC 0003 section 4.2): a row's level is the\n// principal's level on its parent row in another service (a task inherits\n// from its project). The parent service must be served by the same\n// dispatcher and declare a policy of its own; `createDispatcher` checks both,\n// and refuses a cycle.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport { checkName, definePolicy, levelsById, type AccessPolicy } from \"../policy\";\n\n/** Options of {@link inherit}. */\nexport interface InheritOptions<Via extends string = string> {\n /** The parent service's contract. */\n readonly from: AnyContract;\n /** The column holding the parent row's id: `\"projectId\"`. */\n readonly via: Via;\n}\n\nfunction isContract(value: unknown): value is AnyContract {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as { readonly name?: unknown }).name === \"string\" &&\n Object.isFrozen(value)\n );\n}\n\n/**\n * The level on the parent row, from the parent service's policy: one query\n * reads `via` of every row asked about, then one batched lookup asks the\n * parent's policy about the parents found. A row that does not exist, or has\n * no parent, has no level; its id is never taken for a parent id. Service\n * grants on the parent service do not count here, only its policy. A list's\n * filter names the parents the principal reaches (`{ via: { in: ids } }`),\n * or, when the parent's policy lets every row through, any row with a parent\n * (`{ via: { not: null } }`), without reading the parent table.\n *\n * @example\n * qd.defineService(task, { model: \"task\", access: inherit({ from: project, via: \"projectId\" }), methods });\n */\nexport function inherit<const Via extends string>(\n options: InheritOptions<Via>,\n): AccessPolicy<Via, never> {\n if (typeof options !== \"object\" || options === null || !isContract(options.from)) {\n throw new TypeError(\"inherit({ from, via }): from must be the parent service's contract\");\n }\n const { from } = options;\n const via = checkName(\"inherit({ via })\", \"via\", options.via);\n return definePolicy({\n kind: \"inherit\",\n from,\n via,\n reads: {\n columns: [via],\n memberships: [],\n inherits: [from],\n parents: [{ from, via }],\n storage: true,\n },\n async levelsFor(principal, ids, tools) {\n const rows = await tools.rows(ids);\n const parentOf = new Map<string, string>();\n for (const id of ids) {\n const parent = rows.get(id)?.[via];\n if (typeof parent === \"string\" && parent.length > 0) {\n parentOf.set(id, parent);\n }\n }\n const parents = await tools.levelsOf(from, principal, [...new Set(parentOf.values())]);\n return levelsById(ids, (id) => {\n const parent = parentOf.get(id);\n return parent === undefined ? null : (parents.get(parent) ?? null);\n });\n },\n async accessWhere(principal, level, tools) {\n // A parent whose every row passes (`everyone(level)`, alone or in `anyOf`): any row\n // that has a parent, without listing every parent id (the final review's E1).\n const parentFilter = await tools.whereOf(from, principal, level);\n if (parentFilter !== \"none\" && Object.keys(parentFilter).length === 0) {\n return { [via]: { not: null } };\n }\n const parents = await tools.idsWhere(from, principal, level);\n return parents.length === 0 ? \"none\" : { [via]: { in: parents } };\n },\n });\n}\n","// `everyone(level)` (finding F2.7 of the quickdraw-chat migration): every\n// signed-in user has `level` on every row of the service, for rows anyone\n// may read (public profiles, public posts). It reads nothing: a principal is\n// all it needs, so a row id that does not exist is allowed too and answers\n// `NOT_FOUND` where the row would be read (whether a row exists is no secret\n// when everyone may read every row). It covers every surface a policy does,\n// method calls on a row, entity subscriptions and list filters, where\n// `rowless: true` on a method covers that method alone. In `anyOf` it gives\n// the floor the other policies raise: `anyOf(owner(\"id\"), everyone(\"Read\"))`\n// is Admin on one's own row and Read on everyone else's.\n\nimport { isAccessLevel, type AccessLevel } from \"../../../contract/access\";\nimport { meetsLevel } from \"../levels\";\nimport { definePolicy, levelsById, type AccessPolicy } from \"../policy\";\n\n/**\n * Every signed-in user has `level` on every row. Anonymous callers have no\n * principal and so no level: a `\"public\"` method is what serves them.\n *\n * @example\n * // public profiles: everyone reads them, each user edits their own\n * qd.defineService(user, { model: \"user\", access: anyOf(owner(\"id\"), everyone(\"Read\")), methods });\n */\nexport function everyone(level: AccessLevel): AccessPolicy<never, never> {\n if (!isAccessLevel(level) || level === \"Public\") {\n throw new TypeError('everyone(level): level is \"Read\", \"Moderate\" or \"Admin\"');\n }\n return definePolicy({\n kind: \"everyone\",\n level,\n reads: { columns: [], memberships: [], inherits: [], storage: false },\n levelsFor: (_principal, ids) => Promise.resolve(levelsById(ids, () => level)),\n accessWhere: (_principal, wanted) => Promise.resolve(meetsLevel(level, wanted) ? {} : \"none\"),\n });\n}\n","// The kits' `rowless` option: the kit methods whose access form is their\n// whole check on purpose. Each one's implementation carries `rowless: true`,\n// which `defineService`'s rowless check reads (`../access/rowless.ts`): on a\n// service with an access policy, a kit method whose input has `id` (the\n// read/write kit's `get`, the admin kit's `adminGet`, the sharing kit's\n// access-list methods) under a form that asks the policy nothing about the\n// row its `id` names (an open form, `custom`, `{ scope }`, or `{ entry }` on\n// another key) is refused unless it is named here.\n\nimport type { AccessForm } from \"../access/types\";\n\n/**\n * The kit methods `value` names, each one of the kit's `names`; an empty set\n * when it is left out. `fail` reports what is wrong with it.\n */\nexport function rowlessMethods(\n value: unknown,\n names: readonly string[],\n fail: (message: string) => never,\n): ReadonlySet<string> {\n if (value === undefined) {\n return new Set();\n }\n if (!Array.isArray(value) || !value.every((name) => typeof name === \"string\")) {\n fail(\"rowless must list the kit's methods whose access is their whole check\");\n }\n const unknownName = value.find((name) => !names.includes(name));\n if (unknownName !== undefined) {\n fail(`rowless names \"${String(unknownName)}\", which is not one of the kit's methods`);\n }\n return new Set(value);\n}\n\n/** One kit method's implementation: its form and handler, with `rowless: true` when `rowless` names it. */\nexport function kitEntry(\n name: string,\n form: AccessForm,\n handler: object,\n rowless: ReadonlySet<string>,\n): object {\n return Object.freeze(\n rowless.has(name) ? { access: form, handler, rowless: true } : { access: form, handler },\n );\n}\n","// Which rows a read/write kit method may touch (RFC 0003 sections 4.3 and\n// 12.1). The method's access form decides who may call it, as for every\n// method; a method on one row (`get`, `update`, `delete`, `reorder`) is\n// checked on that row by an `{ entry }` form. A method on many rows cannot\n// be: `list`, `getMany`, `bulkUpdate` and `bulkDelete` keep only the rows on\n// which the service's policy gives the caller the method's row level, from\n// the same policy that answers `get`, so a list never shows a row `get`\n// would refuse. A service-wide `Admin` grant (with `adminBypass`) reaches\n// every row, as everywhere.\n//\n// The row level is the form's own (`{ entry: L }` or `{ scope: L }`), or\n// else `Read` for reads and `Moderate` for writes; a bulk method's is its\n// single-row counterpart's (`delete`'s for `bulkDelete`, `update`'s for\n// `bulkUpdate`) before `Moderate`. A `\"public\"` read's rows\n// are public; a write always needs the level, so an anonymous caller writes\n// nothing, and a write on one row needs it on that row whatever its form\n// (`checkRowWrite`); `create` needs it on each anchor row its new row names\n// (`../columns.ts`). A service-wide grant at level L is a row level of L on\n// every row where the form names `service` (`grantRowLevel`): such a read is\n// unfiltered, its rows stripped at the grant. A service without a policy has\n// no row-level access: there the form is the whole check, so `defineService`\n// takes only `\"public\"` or `{ service }` for its methods on many rows\n// (`everyRowProblem`).\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { isCustomAccess } from \"../../access/forms\";\nimport { meetsLevel, serviceGrant } from \"../../access/levels\";\nimport type { AccessFilter, RowLevel } from \"../../access/policy\";\nimport type { AccessForm } from \"../../access/types\";\nimport type { AnyService } from \"../../service\";\nimport type { CrudCall } from \"./runtime\";\n\n/** The level a method's rows need: its form's entry level, else its scope level, else `fallback`. */\nexport function rowLevel(form: AccessForm, fallback: AccessLevel): AccessLevel {\n if (typeof form !== \"object\" || isCustomAccess(form)) {\n return fallback;\n }\n return form.entry ?? form.scope ?? fallback;\n}\n\n/**\n * The row level a bulk method needs when its own form names none: the\n * higher of `Moderate` and the row level of its single-row counterpart's\n * form (`delete`'s for `bulkDelete`, `update`'s for `bulkUpdate`), so it\n * never writes below 5.0's `Moderate`; `Moderate` without a counterpart, or\n * when the counterpart's form names no row level (`{ service: L }`,\n * `custom`): give both the same form then.\n */\nexport function bulkFallback(counterpart: AccessForm | undefined): AccessLevel {\n const level = counterpart === undefined ? \"Moderate\" : rowLevel(counterpart, \"Moderate\");\n return meetsLevel(level, \"Moderate\") ? level : \"Moderate\";\n}\n\n/** True when a method's rows are not checked against a policy: a public read, or no policy. */\nfunction unchecked(call: CrudCall, form: AccessForm, use: \"read\" | \"write\"): boolean {\n return call.runtime.service.access === undefined || (use === \"read\" && form === \"public\");\n}\n\n/** True for `\"public\"`, or `{ service: L }` alone: a form that names who may reach every row. */\nfunction reachesEveryRow(form: AccessForm): boolean {\n if (form === \"public\") {\n return true;\n }\n return (\n typeof form === \"object\" &&\n !isCustomAccess(form) &&\n form.service !== undefined &&\n form.entry === undefined &&\n form.scope === undefined\n );\n}\n\n/**\n * Why a kit method on many rows (`list`, `getMany`, `search`, the bulk\n * methods) cannot run on `service` under `form`; `undefined` when it can. A\n * service with a model but no row policy has nothing to keep rows by, so\n * such a method reaches every row, and its form must say so outright:\n * `\"public\"` or `{ service }`. `\"authenticated\"`, `custom` or a `scope`\n * form would hand every row to anyone who passes it.\n */\nexport function everyRowProblem(\n service: Pick<AnyService, \"name\" | \"access\">,\n method: string,\n form: AccessForm,\n): string | undefined {\n if (service.access !== undefined || reachesEveryRow(form)) {\n return undefined;\n }\n return `${method} reaches every row of ${service.name}, which declares no access policy to keep rows by: give it \"public\" or { service } access, or declare the service's access policy`;\n}\n\n/**\n * The caller's service-wide grant as their level on every row: a grant at\n * level L is a row level of L on every row where the form names `service`\n * and the grant meets it (a grant below `Admin` counts only where `service`\n * is named, RFC 0003 section 4.1). `undefined` otherwise.\n */\nexport function grantRowLevel(call: CrudCall, form: AccessForm): AccessLevel | undefined {\n const { principal } = call;\n if (principal === null || typeof form !== \"object\" || isCustomAccess(form)) {\n return undefined;\n }\n const grant = serviceGrant(principal, call.runtime.service.name);\n return form.service !== undefined && meetsLevel(grant, form.service) ? grant : undefined;\n}\n\n/** True when the caller's service-wide grant reaches every row at `level` (`grantRowLevel`). */\nfunction grantReaches(call: CrudCall, form: AccessForm, level: AccessLevel): boolean {\n return meetsLevel(grantRowLevel(call, form), level);\n}\n\n/**\n * The filter matching the rows the caller may see (`use` `\"read\"`) or\n * write (`\"write\"`, where a `\"public\"` form filters too) at `level`,\n * `\"none\"` when it may reach none, or `undefined` when it reaches every row.\n */\nexport async function rowsWhere(\n call: CrudCall,\n form: AccessForm,\n level: AccessLevel,\n use: \"read\" | \"write\" = \"read\",\n): Promise<AccessFilter | undefined> {\n if (unchecked(call, form, use) || grantReaches(call, form, level)) {\n return undefined;\n }\n if (call.principal === null) {\n return \"none\";\n }\n const { access, service } = call.runtime;\n return await access.accessWhere(service.name, call.principal, level);\n}\n\n/** True for a form whose own check covered row `input.id` at `level`: `{ entry }` alone, on `id`. */\nfunction entryCovers(form: AccessForm, level: AccessLevel): boolean {\n return (\n typeof form === \"object\" &&\n !isCustomAccess(form) &&\n form.service === undefined &&\n (form.id === undefined || form.id === \"id\") &&\n meetsLevel(form.entry, level)\n );\n}\n\n/**\n * `FORBIDDEN` unless the caller has the method's row level on row `id`: a\n * kit write on one row (`update`, `delete`, `reorder`) of a service with a\n * policy needs it whatever its form says, so `update: \"authenticated\"`\n * edits no row. The level is the form's `entry` (or `scope`) level, else\n * `Moderate`; a service-wide grant the form names counts on every row. One\n * lookup, unless the form's own `entry` check already covered the row.\n */\nexport async function checkRowWrite(call: CrudCall, form: AccessForm, id: string): Promise<void> {\n const { access, service } = call.runtime;\n const level = rowLevel(form, \"Moderate\");\n if (service.access === undefined || grantReaches(call, form, level) || entryCovers(form, level)) {\n return;\n }\n const levels =\n call.principal === null\n ? undefined\n : await access.levelsFor(service.name, call.principal, [id]);\n if (!meetsLevel(levels?.get(id), level)) {\n throw new QuickdrawError(\"FORBIDDEN\", \"Insufficient permissions\");\n }\n}\n\n/**\n * The ids among `ids` on which the caller has at least `level`, in order:\n * one batched lookup. `use` says whether the method reads or writes them.\n */\nexport async function allowedIds(\n call: CrudCall,\n form: AccessForm,\n ids: readonly string[],\n level: AccessLevel,\n use: \"read\" | \"write\",\n): Promise<string[]> {\n if (unchecked(call, form, use) || ids.length === 0 || grantReaches(call, form, level)) {\n return [...ids];\n }\n if (call.principal === null) {\n return [];\n }\n const { access, service } = call.runtime;\n const levels = await access.levelsFor(service.name, call.principal, ids);\n return ids.filter((id) => meetsLevel(levels.get(id), level));\n}\n\n/**\n * The level whose field tiers a list's items are stripped to. Like a\n * collection's items (RFC 0003 section 7.2), a page's items are stripped\n * once, at the level the page was filtered at, not per row: `Admin` for a\n * service-wide `Admin` grant, the grant for one the form names that reaches\n * every row (`grantRowLevel`), and no level for rows no policy checked.\n */\nexport function readerLevel(call: CrudCall, form: AccessForm, level: AccessLevel): RowLevel {\n const { service } = call.runtime;\n const grant = call.principal === null ? undefined : serviceGrant(call.principal, service.name);\n if (service.adminBypass && grant === \"Admin\") {\n return \"Admin\";\n }\n const granted = grantRowLevel(call, form);\n if (unchecked(call, form, \"read\")) {\n return granted ?? null;\n }\n return granted !== undefined && meetsLevel(granted, level) ? granted : level;\n}\n","// The values a kit write may hold (RFC 0003 sections 4.2, 4.4 and 12). A\n// write of the read/write kit (`create`, `update`, `bulkUpdate`) or of the\n// admin kit (`adminCreate`, `adminUpdate`) holds three kinds of risk, checked\n// here in this order:\n//\n// - Column values only (`checkColumnValues`): a key that is a relation of\n// the model (one a projection of the service selects with a nested\n// select) or a value that is a Prisma nested write (`{ connect }`, `{\n// update }`, a to-many `{ set: [...] }`) is `VALIDATION`, in every\n// environment and for every caller, a service-wide Admin included: nested\n// writes are not tracked, and they passed the name-only checks below\n// (`{ project: { update: { ownerId } } }` made a member the owner; the\n// 5.1 audit's CRUD-5, DATA-2 and ADMIN-1). A JSON value whose own key is a\n// relation operation holding rows is refused too; keep such data a level\n// deeper.\n// - Locked columns (`checkLockedColumns`): a column the service's policy\n// reads (an owner column, an access list) is read-only, and on `create`\n// comes only from the kit's `prepare`, even when an anchored collection\n// also scopes by it. Only an `inherit` policy's `via` columns leave the\n// locked set. A membership table's entry, user and level columns are\n// read-only on that table whichever bound policy reads them (`members`,\n// alone, in `anyOf` or a resolver's `reads`); they change through the\n// sharing kit. Before 5.1, a policy column that was also an anchored\n// collection's scope column was checked as an anchor move only\n// (`assigneeId` under `anyOf(owner(\"assigneeId\"), inherit(...))` beside\n// an `assigned` collection anchored on users made a member the row's\n// owner; the audit's CRUD-3), and crud on a membership table raised a\n// member's own role (CRUD-7).\n// - Anchor columns (`checkAnchorColumns`): a column that places the row\n// under an anchor row (an `inherit` policy's `via`, an anchored\n// collection's scope column) may name only an anchor row on which the\n// caller's level, from that row's own policy (as `inherit` and collection\n// scopes count it, without grants on its service), meets the method's row\n// level: a move on `update`, a parent on `create` (CRUD-1). Setting it to\n// null moves the row out of every anchor, which needs nothing more. An\n// anonymous caller names no anchor row.\n//\n// A caller with a service-wide `Admin` grant (with `adminBypass`) writes any\n// column, but never a relation or a nested write. `update`, `bulkUpdate`\n// and the admin writes run all three (`checkWritableColumns`); `create` runs\n// them apart: column values and locked columns on the caller's input before\n// `prepare`, column values and anchors on what it returns.\n//\n// Statements: one engine call per anchor column the write sets (the anchor\n// policy's reads), none otherwise.\n\nimport type { AccessLevel } from \"../../contract/access\";\nimport { findNestedWrites } from \"../../prisma/nested\";\nimport { QuickdrawError } from \"../../protocol/errors\";\nimport { meetsLevel, serviceGrant } from \"../access/levels\";\nimport type { KitRuntime } from \"../context\";\nimport type { AnyService } from \"../service\";\nimport { modelKey } from \"../storage\";\nimport type { Principal } from \"../types\";\n\n/** A column whose value is the id of an anchor row, and the service that row belongs to. */\ninterface AnchorColumn {\n readonly column: string;\n readonly anchor: string;\n}\n\n/** The columns of a service's rows that decide who may reach them. */\ninterface GuardedColumns {\n /** Read-only unless the caller holds a service-wide `Admin` grant. */\n readonly locked: ReadonlySet<string>;\n /** Writable into an anchor row the caller has the method's row level on. */\n readonly anchors: readonly AnchorColumn[];\n}\n\nfunction guardedColumns(service: AnyService): GuardedColumns {\n const reads = service.access?.reads;\n const anchors = new Map<string, AnchorColumn>();\n const add = (column: string, anchor: string): void => {\n anchors.set(`${column}\\u0000${anchor}`, { column, anchor });\n };\n for (const { from, via } of reads?.parents ?? []) {\n add(via, from.name);\n }\n for (const collection of service.collections.values()) {\n if (collection.anchor !== undefined && collection.scope.kind === \"column\") {\n add(collection.scope.column, collection.anchor.name);\n }\n }\n // Only an inherit parent's column moves the row; any other column the policy reads stays locked.\n const parents = new Set((reads?.parents ?? []).map(({ via }) => via));\n const locked = (reads?.columns ?? []).filter((column) => column !== \"id\" && !parents.has(column));\n return { locked: new Set(locked), anchors: [...anchors.values()] };\n}\n\nconst MEMBERSHIPS = new WeakMap<object, Map<string, ReadonlyMap<string, string>>>();\n\n/**\n * The columns of `model` that hold memberships a policy of `services` reads\n * (each membership's entry, user and level column), with the service whose\n * policy reads each. Found once per dispatcher's services and model.\n */\nexport function membershipColumnsOf(\n services: ReadonlyMap<string, AnyService>,\n model: string,\n): ReadonlyMap<string, string> {\n let byModel = MEMBERSHIPS.get(services);\n if (byModel === undefined) {\n byModel = new Map<string, ReadonlyMap<string, string>>();\n MEMBERSHIPS.set(services, byModel);\n }\n const key = modelKey(model);\n const kept = byModel.get(key);\n if (kept !== undefined) {\n return kept;\n }\n const columns = new Map<string, string>();\n for (const service of services.values()) {\n for (const read of service.access?.reads.memberships ?? []) {\n if (modelKey(read.model) !== key) {\n continue;\n }\n for (const column of [read.entry, read.user, read.level]) {\n if (!columns.has(column)) {\n columns.set(column, service.name);\n }\n }\n }\n }\n byModel.set(key, columns);\n return columns;\n}\n\nfunction forbidden(message: string): QuickdrawError {\n return new QuickdrawError(\"FORBIDDEN\", message);\n}\n\n/** True when the principal's service-wide `Admin` grant passes every check on the service. */\nfunction bypasses(service: AnyService, principal: Principal | null): boolean {\n return (\n principal !== null && service.adminBypass && serviceGrant(principal, service.name) === \"Admin\"\n );\n}\n\n/** Options of the column checks: `creating` words the refusals for `create`. */\ninterface ColumnCheckOptions {\n readonly creating?: boolean;\n}\n\n/** The columns `data` gives a value (`undefined` is no value). */\nfunction namedColumns(data: Readonly<Record<string, unknown>>): Set<string> {\n return new Set(Object.keys(data).filter((column) => data[column] !== undefined));\n}\n\n/** The membership column of the service's model `columns` names first, with the service that reads it. */\nfunction membershipNamed(\n runtime: Pick<KitRuntime, \"service\" | \"services\">,\n columns: readonly string[],\n): readonly [string, string] | undefined {\n const { service, services } = runtime;\n if (service.model === undefined) {\n return undefined;\n }\n const memberships = membershipColumnsOf(services, service.model);\n const column = columns.find((named) => memberships.has(named));\n return column === undefined ? undefined : [column, memberships.get(column) ?? service.name];\n}\n\n/**\n * `FORBIDDEN` when `data` gives a value to a column the service's policy\n * reads, or to a membership column of the service's model that any policy\n * of the dispatcher reads, unless the caller holds a service-wide `Admin`\n * grant.\n */\nexport function checkLockedColumns(\n runtime: Pick<KitRuntime, \"service\" | \"services\">,\n principal: Principal | null,\n data: Readonly<Record<string, unknown>>,\n options: ColumnCheckOptions = {},\n): void {\n const { service } = runtime;\n if (bypasses(service, principal)) {\n return;\n }\n const { locked } = guardedColumns(service);\n const named = [...namedColumns(data)];\n const readOnly = named.find((column) => locked.has(column));\n const creating = options.creating === true;\n if (readOnly !== undefined) {\n throw forbidden(\n creating\n ? `\"${readOnly}\" decides who may reach rows of ${service.name}: only a service-wide Admin may send it; set it in the kit's prepare`\n : `\"${readOnly}\" decides who may reach rows of ${service.name}: only a service-wide Admin may change it`,\n );\n }\n const membership = membershipNamed(runtime, named);\n if (membership !== undefined) {\n const [column, reader] = membership;\n throw forbidden(\n creating\n ? `\"${column}\" holds a membership in ${reader}'s policy: only a service-wide Admin may send it through a kit; add members with the sharing kit`\n : `\"${column}\" holds a membership in ${reader}'s policy: only a service-wide Admin may change it through a kit; change memberships with the sharing kit`,\n );\n }\n}\n\n/**\n * `FORBIDDEN` unless each anchor column `data` gives a value names an\n * anchor row the caller has `level` on (or is null), unless the caller\n * holds a service-wide `Admin` grant. An anonymous caller names none.\n */\nexport async function checkAnchorColumns(\n runtime: Pick<KitRuntime, \"service\" | \"access\">,\n principal: Principal | null,\n data: Readonly<Record<string, unknown>>,\n level: AccessLevel,\n options: ColumnCheckOptions = {},\n): Promise<void> {\n const { service, access } = runtime;\n if (bypasses(service, principal)) {\n return;\n }\n const { anchors } = guardedColumns(service);\n const named = namedColumns(data);\n for (const { column, anchor } of anchors) {\n const target = data[column];\n if (!named.has(column) || target === null) {\n continue;\n }\n const valid = principal !== null && typeof target === \"string\" && target.length > 0;\n const resolved = valid\n ? await access.resolve(anchor, principal, [target], { grants: false })\n : undefined;\n if (resolved === undefined || !meetsLevel(resolved.levels.get(target as string), level)) {\n throw forbidden(\n options.creating === true\n ? `Creating a row of ${service.name} with \"${column}\" needs ${level} on the ${anchor} row it names`\n : `Moving a row of ${service.name} by \"${column}\" needs ${level} on the ${anchor} row it moves into`,\n );\n }\n }\n}\n\n/** The relation keys of each service, by the service. */\nconst relations = new WeakMap<object, ReadonlySet<string>>();\n\n/**\n * The keys of a service's rows that are relations of its model, as far as\n * the service says: those any of its projections `select`s with an object\n * (`project: { select: { name: true } }`). A relation selected with `true`\n * is not known as one; its nested-write values still are.\n */\nexport function relationKeysOf(service: Pick<AnyService, \"projections\">): ReadonlySet<string> {\n let keys = relations.get(service);\n if (keys === undefined) {\n const found = new Set<string>();\n for (const projection of service.projections.values()) {\n for (const [key, value] of Object.entries(projection.select)) {\n if (typeof value === \"object\" && value !== null) {\n found.add(key);\n }\n }\n }\n keys = found;\n relations.set(service, keys);\n }\n return keys;\n}\n\n/** One reason a kit write's data is not column values. */\nexport interface ColumnValueIssue {\n readonly path: PropertyKey[];\n readonly message: string;\n}\n\nfunction isPlainObject(value: unknown): value is Readonly<Record<string, unknown>> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\n/**\n * Why `data` holds something other than column values: one issue per key\n * that is a relation of the service's model, or whose value is a nested\n * write (`findNestedWrites`), or a plain object holding a `set` list (which\n * disconnects every child of a to-many relation). Empty when it holds column\n * values only. `path` goes before each key (`[\"data\"]`).\n */\nexport function columnValueIssues(\n service: Pick<AnyService, \"name\" | \"projections\">,\n data: Readonly<Record<string, unknown>>,\n path: readonly PropertyKey[] = [],\n): ColumnValueIssue[] {\n const relationKeys = relationKeysOf(service);\n // A copy of its own keys: Prisma would walk the keys of any object it is given.\n const nested = new Map(\n findNestedWrites({ ...data }).map(({ field, operation }) => [field, operation]),\n );\n const issues: ColumnValueIssue[] = [];\n for (const [key, value] of Object.entries(data)) {\n if (value === undefined) {\n continue;\n }\n const operation =\n nested.get(key) ?? (isPlainObject(value) && Array.isArray(value.set) ? \"set\" : undefined);\n if (relationKeys.has(key)) {\n issues.push({\n path: [...path, key],\n message: `\"${key}\" is a relation of ${service.name}'s model: kits write column values only; set its foreign key column instead`,\n });\n } else if (operation !== undefined) {\n issues.push({\n path: [...path, key],\n message: `\"${key}\" holds a nested write ({ ${operation} }), which is not tracked: kits write column values only`,\n });\n }\n }\n return issues;\n}\n\n/**\n * `VALIDATION` unless `data` holds column values only (`columnValueIssues`),\n * whoever the caller: never bypassed, since a nested write is not tracked.\n */\nexport function checkColumnValues(\n service: Pick<AnyService, \"name\" | \"projections\">,\n data: Readonly<Record<string, unknown>>,\n path: readonly PropertyKey[] = [],\n): void {\n const issues = columnValueIssues(service, data, path);\n if (issues.length > 0) {\n throw new QuickdrawError(\n \"VALIDATION\",\n \"The data holds a relation or a nested write, which kits do not write\",\n { issues },\n );\n }\n}\n\n/**\n * The checks of a kit write on existing rows (`update`, `bulkUpdate`, the\n * admin writes): `VALIDATION` unless `data` holds column values only, then\n * `FORBIDDEN` unless the caller may set every column it gives a value, in a\n * write whose rows need `level`: no column the policy reads, and each\n * anchor column only to an anchor row the caller has `level` on (or null).\n * `path` goes before each key of an issue (`[\"data\"]`).\n */\nexport async function checkWritableColumns(\n runtime: Pick<KitRuntime, \"service\" | \"access\" | \"services\">,\n principal: Principal | null,\n data: Readonly<Record<string, unknown>>,\n level: AccessLevel,\n path: readonly PropertyKey[] = [],\n): Promise<void> {\n checkColumnValues(runtime.service, data, path);\n checkLockedColumns(runtime, principal, data);\n await checkAnchorColumns(runtime, principal, data, level);\n}\n","// The interactive transactions the kits write in (RFC 0003 sections 5.1 and\n// 12). A transaction's writes join the call's unit of work when it commits\n// and are dropped when it rolls back; the framework's own reads inside it\n// (access policies) go through its client.\n//\n// A kit change that reads rows and writes what it decided from them (a\n// sharing change, a `reorder`) runs SERIALIZABLE: PostgreSQL's default\n// isolation (READ COMMITTED) would let two changes that run at once both read\n// the old state, and the second write undo the first. Under SERIALIZABLE the\n// database fails one of them instead, which the kit answers `CONFLICT`, and\n// the caller may try again.\n\nimport { QuickdrawError } from \"../../protocol/errors\";\n\n/** How a kit's transaction runs. */\nexport interface KitTransaction {\n /** Who runs it, for the error when the client has no `$transaction`: \"The sharing kit's changes\". */\n readonly owner: string;\n /**\n * Run SERIALIZABLE, answering a transaction the database fails for a\n * concurrent one with `CONFLICT` and this message. Default isolation without it.\n */\n readonly conflict?: string;\n /** The transaction's time limit in milliseconds; the client's default (Prisma's is 5 s) without it. */\n readonly timeoutMs?: number;\n}\n\n/**\n * True for Prisma's report of a transaction the database failed for a\n * concurrent one: `P2034` when a statement fails (a concurrent update of the\n * row), and the driver adapter's own `TransactionWriteConflict` when the\n * commit does (PostgreSQL finds most serialization failures only then;\n * Prisma 7 passes that one through unmapped).\n */\nfunction isWriteConflict(error: unknown): boolean {\n if (!(error instanceof Error)) {\n return false;\n }\n if (error.name === \"PrismaClientKnownRequestError\") {\n return (error as Error & { readonly code?: unknown }).code === \"P2034\";\n }\n const kind: unknown = (error.cause as { readonly kind?: unknown } | undefined)?.kind;\n return error.name === \"DriverAdapterError\" && kind === \"TransactionWriteConflict\";\n}\n\nfunction optionsOf(how: KitTransaction): object | undefined {\n const options = {\n ...(how.conflict === undefined ? {} : { isolationLevel: \"Serializable\" }),\n ...(how.timeoutMs === undefined ? {} : { timeout: how.timeoutMs }),\n };\n return Object.keys(options).length === 0 ? undefined : Object.freeze(options);\n}\n\n/** Runs `fn` in an interactive transaction of the database client, as `how` says. */\nexport async function inKitTransaction<T>(\n db: unknown,\n fn: (tx: unknown) => Promise<T>,\n how: KitTransaction,\n): Promise<T> {\n const client = db as { readonly $transaction?: unknown } | null;\n if (typeof client?.$transaction !== \"function\") {\n throw new QuickdrawError(\"INTERNAL\", `${how.owner} need a database client with $transaction`);\n }\n const run = client.$transaction as (\n callback: (tx: unknown) => Promise<T>,\n options?: object,\n ) => Promise<T>;\n const options = optionsOf(how);\n try {\n return options === undefined ? await run.call(client, fn) : await run.call(client, fn, options);\n } catch (error) {\n if (how.conflict === undefined || !isWriteConflict(error)) {\n throw error;\n }\n const conflict = new QuickdrawError(\"CONFLICT\", how.conflict);\n conflict.cause = error;\n throw conflict;\n }\n}\n","// What every handler of the read/write kit starts from (RFC 0003 section\n// 12.1): the service its method runs in, found through the call's `ctx`\n// (`kitRuntimeOf`), and the service's model on the dispatcher's tracked\n// database client. The kit reads and writes through that client, as a\n// hand-written handler does, so every write is tracked and its frames are\n// sent by the flush; the kit never sends one itself.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { kitRuntimeOf, type KitRuntime } from \"../../context\";\nimport type { Projection } from \"../../emit/projection\";\nimport { modelKey } from \"../../storage\";\nimport type { Principal } from \"../../types\";\nimport { inKitTransaction } from \"../transactions\";\n\n/** A row as the database client returns it. */\nexport type Row = Readonly<Record<string, unknown>>;\n\n/** The model methods the kit calls: a Prisma model delegate, structurally. */\nexport interface ModelDelegate {\n findUnique(args: object): Promise<Row | null>;\n findFirst(args: object): Promise<Row | null>;\n findMany(args: object): Promise<Row[]>;\n count(args: object): Promise<number>;\n create(args: object): Promise<Row>;\n update(args: object): Promise<Row>;\n delete(args: object): Promise<Row>;\n updateMany(args: object): Promise<{ readonly count: number }>;\n deleteMany(args: object): Promise<{ readonly count: number }>;\n aggregate(args: object): Promise<Row>;\n}\n\n/** What a kit handler is called with, whatever the app's own types. */\nexport interface KitHandlerArgs<Db = unknown> {\n readonly input: unknown;\n /** The call's `ctx`; a dispatcher's always carries its `signal`. */\n readonly ctx: { readonly principal: Principal | null; readonly signal?: AbortSignal };\n /** The app's database client. */\n readonly db: Db;\n}\n\n/**\n * A handler of a kit method. `Out` is what it resolves with: the row (or\n * rows, or page) its method's output names, which the framework projects as\n * for any handler. A kit that types it (the admin kit: its methods' output\n * types) lets an app wrap a handler and read what it returned with no cast;\n * one that leaves it `never` fits the method of any app's service. `Db` is\n * the app's database client type, as the app's callbacks (`prepare`,\n * `resolveUser`, `onChange`, `onWrite`) annotate their `db`, so a wrong\n * annotation is refused where the handlers are spread into\n * `qd.defineService`.\n */\nexport type KitHandler<Db = unknown, Out = never> = (args: KitHandlerArgs<Db>) => Promise<Out>;\n\n/** One call of a kit method: the service it runs in, its model's delegate, and the caller. */\nexport interface CrudCall {\n readonly runtime: KitRuntime;\n /** The model, named as the database client names it: `\"task\"`. */\n readonly model: string;\n readonly table: ModelDelegate;\n readonly principal: Principal | null;\n}\n\n/** The delegate of `model` on a database client (or a transaction's client). */\nexport function delegateOf(db: unknown, model: string): ModelDelegate {\n const name = modelKey(model);\n const isClient = (typeof db === \"object\" || typeof db === \"function\") && db !== null;\n const delegate: unknown = isClient ? Reflect.get(db, name) : undefined;\n const usable =\n typeof delegate === \"object\" &&\n delegate !== null &&\n typeof (delegate as { readonly findMany?: unknown }).findMany === \"function\";\n if (!usable) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit reads and writes through db.${name}, which the dispatcher's database client does not have`,\n );\n }\n return delegate as ModelDelegate;\n}\n\n/** The kit call `ctx` belongs to: its service and model, and the caller. */\nexport function crudCall(ctx: KitHandlerArgs[\"ctx\"], db: unknown): CrudCall {\n const runtime = kitRuntimeOf(ctx);\n const model = runtime?.service.model;\n if (runtime === undefined || model === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The read/write kit's handlers run through a dispatcher, in a service with a model\",\n );\n }\n return {\n runtime,\n model: modelKey(model),\n table: delegateOf(db, model),\n principal: ctx.principal,\n };\n}\n\n/**\n * Runs `fn` in an interactive transaction of the database client: its writes\n * join the call's unit of work when it commits, and are dropped when it\n * rolls back. Reads the framework makes inside it (access policies) go\n * through the transaction too.\n */\nexport async function inTransaction<T>(db: unknown, fn: (tx: unknown) => Promise<T>): Promise<T> {\n return await inKitTransaction(db, fn, { owner: \"The read/write kit's bulk methods\" });\n}\n\n/** A projection of the call's service, by name. */\nexport function projectionOf(call: CrudCall, name: string): Projection {\n const projection = call.runtime.service.projections.get(name);\n if (projection === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit asked ${call.runtime.service.name} for projection \"${name}\", which it does not have`,\n );\n }\n return projection;\n}\n\n/** The ids in `ids`, each once, in order. */\nexport function uniqueIds(ids: readonly string[]): string[] {\n return [...new Set(ids)];\n}\n","// Guards for handlers, the kits' own and hand-written ones (RFC 0003 section\n// 12). Four 4.1 apps copy a `services/shared/guards.ts` of these.\n\nimport { QuickdrawError } from \"../../protocol/errors\";\n\n/**\n * The row a read found, or `NOT_FOUND` with `message` when it found none.\n *\n * @example\n * const task = requireRow(await db.task.findUnique({ where: { id } }), \"No such task\");\n */\nexport function requireRow<Row>(row: Row | null | undefined, message = \"Not found\"): Row {\n if (row === null || row === undefined) {\n throw new QuickdrawError(\"NOT_FOUND\", message);\n }\n return row;\n}\n","// The read/write kit's `update` (RFC 0003 section 12.1): `db.<model>.update`\n// with the fields the call gives (the app's patch schema decides which). The\n// tracked client records the changed fields, so subscribers get a patch\n// (`p`) and collections a `patched` delta. A row that is not there is\n// `NOT_FOUND`, a unique violation `CONFLICT`. A call that changes nothing\n// reads the row instead of writing it. The caller needs the method's row\n// level on the row whatever the form (`checkRowWrite`), and a patch holds\n// column values only (never a relation or a nested write), and may not set a\n// column that decides access to the row, nor move it into an anchor row the\n// caller does not have that level on (`../columns.ts`).\n\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWritableColumns } from \"../columns\";\nimport { requireRow } from \"../guards\";\nimport { checkRowWrite, rowLevel } from \"./access\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** The fields a patch sets: its keys with a value, never `id`. */\nexport function patchData(patch: Readonly<Record<string, unknown>>): Record<string, unknown> {\n return Object.fromEntries(\n Object.entries(patch).filter(([key, value]) => key !== \"id\" && value !== undefined),\n );\n}\n\n/** The `update` handler. */\nexport function updateHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = crudCall(ctx, db);\n const { id, ...patch } = input as { readonly id: string } & Record<string, unknown>;\n const data = patchData(patch);\n const { select } = projectionOf(call, \"entity\");\n await checkRowWrite(call, form, id);\n await checkWritableColumns(call.runtime, call.principal, data, rowLevel(form, \"Moderate\"));\n if (Object.keys(data).length === 0) {\n return requireRow(\n await call.table.findUnique({ where: { id }, select }),\n `No such ${call.model}`,\n );\n }\n return await call.table.update({ where: { id }, data, select });\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `bulkUpdate` and `bulkDelete` (RFC 0003 section\n// 12.1): one `updateMany` or `deleteMany` over the ids the caller may write,\n// in one transaction with the policy lookup that picked them. Ids the caller\n// cannot write at the method's row level, and ids with no row, are skipped,\n// even for a `\"public\"` method. The row level is the form's own, else the\n// higher of `Moderate` and the single-row counterpart's (`delete`'s for\n// `bulkDelete`, `update`'s for `bulkUpdate`; `bulkFallback`): a bulk delete\n// never deletes a row `delete`'s `{ entry: L }` would refuse (the 5.1\n// audit's CRUD-2). A counterpart whose form names no row level\n// (`{ service: L }`, `custom`) gives none: give both the same form;\n// the result counts the rows changed. The tracked client records every row, and a flush touching more\n// rows of one collection scope than its `bulkThreshold` sends that scope one\n// `reset` instead of a delta per row. `bulkUpdate`'s data holds column\n// values only (never a relation or a nested write), and may not set a column\n// that decides access, nor move the rows into an anchor row the caller lacks\n// the row level on (`../columns.ts`).\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport type { IdsInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWritableColumns } from \"../columns\";\nimport { allowedIds, rowLevel } from \"./access\";\nimport {\n crudCall,\n delegateOf,\n inTransaction,\n uniqueIds,\n type CrudCall,\n type KitHandler,\n type KitHandlerArgs,\n type ModelDelegate,\n} from \"./runtime\";\nimport { patchData } from \"./update\";\n\ninterface Counted {\n readonly count: number;\n}\n\n/** Runs `write` on the ids among `ids` the caller may write at `level`, inside one transaction. */\nasync function writeAllowed(\n call: CrudCall,\n db: unknown,\n [form, level]: readonly [AccessForm, AccessLevel],\n ids: readonly string[],\n write: (table: ModelDelegate, allowed: readonly string[]) => Promise<Counted>,\n): Promise<Counted> {\n const unique = uniqueIds(ids);\n if (unique.length === 0) {\n return { count: 0 };\n }\n return await inTransaction(db, async (tx) => {\n const allowed = await allowedIds(call, form, unique, level, \"write\");\n if (allowed.length === 0) {\n return { count: 0 };\n }\n const { count } = await write(delegateOf(tx, call.model), allowed);\n return { count };\n });\n}\n\n/** The `bulkUpdate` handler: its rows need the form's level, else `fallback` (`update`'s). */\nexport function bulkUpdateHandler(form: AccessForm, fallback: AccessLevel): KitHandler {\n const level = rowLevel(form, fallback);\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Counted> => {\n const call = crudCall(ctx, db);\n const { ids, data } = input as {\n readonly ids: readonly string[];\n readonly data: Readonly<Record<string, unknown>>;\n };\n const patch = patchData(data);\n if (Object.keys(patch).length === 0) {\n return { count: 0 };\n }\n await checkWritableColumns(call.runtime, call.principal, patch, level, [\"data\"]);\n return await writeAllowed(call, db, [form, level], ids, (table, allowed) =>\n table.updateMany({ where: { id: { in: [...allowed] } }, data: patch }),\n );\n };\n return handler as KitHandler;\n}\n\n/** The `bulkDelete` handler: its rows need the form's level, else `fallback` (`delete`'s). */\nexport function bulkDeleteHandler(form: AccessForm, fallback: AccessLevel): KitHandler {\n const level = rowLevel(form, fallback);\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Counted> => {\n const call = crudCall(ctx, db);\n return await writeAllowed(call, db, [form, level], (input as IdsInput).ids, (table, allowed) =>\n table.deleteMany({ where: { id: { in: [...allowed] } } }),\n );\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `create` (RFC 0003 section 12.1): `db.<model>.create`\n// with the caller's input, or what the service's `prepare` makes of it (an\n// owner or scope column from the principal, an ordinal from `nextOrdinal`).\n// The tracked client records the write, so the flush sends the new row to\n// its collections as `added`. A unique violation is `CONFLICT`.\n//\n// It checks no row of its own (its `id`, when its input has one, names the\n// new row), so it checks what it writes (`../columns.ts`; the 5.1 audit's\n// CRUD-1): the caller's input holds column values only, and no column the\n// policy reads (an owner or access-list column comes only from `prepare`),\n// before `prepare` runs; what `prepare` returns holds column values only,\n// and each anchor column it sets (an `inherit` parent, an anchored\n// collection's scope) names a row on which the caller has the method's row\n// level. A service-wide `Admin` passes the last two; an anonymous caller\n// names no anchor row.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checked } from \"../../devWarnings\";\nimport type { MaybePromise, Principal } from \"../../types\";\nimport {\n checkAnchorColumns,\n checkColumnValues,\n checkLockedColumns,\n columnValueIssues,\n} from \"../columns\";\nimport { rowLevel } from \"./access\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** `prepare(input, ctx, db)`: the data `create` writes, from the parsed input; `db` is the app's client. */\nexport type CrudPrepare<Input = never, Ctx = never, Db = unknown> = (\n input: Input,\n ctx: Ctx,\n db: Db,\n) => MaybePromise<Readonly<Record<string, unknown>>>;\n\n/** `prepare` as the handler calls it. */\nexport type AnyPrepare = (\n input: unknown,\n ctx: { readonly principal: Principal | null },\n db: unknown,\n) => MaybePromise<unknown>;\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** A plain object: what a write's data must be, so no key hides on a prototype. */\nfunction isPlainObject(value: unknown): value is Readonly<Record<string, unknown>> {\n if (!isRecord(value)) {\n return false;\n }\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\n/** The `create` handler, for a method whose access form is `form`. */\nexport function createHandler(form: AccessForm, prepare: AnyPrepare | undefined): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = crudCall(ctx, db);\n const { service } = call.runtime;\n // The caller's input: column values, and none the policy reads.\n const sent = isRecord(input) ? input : {};\n checkColumnValues(service, sent);\n checkLockedColumns(call.runtime, call.principal, sent, { creating: true });\n // The app's prepare is the app's code: its statements are checked.\n const data = prepare === undefined ? input : await checked(() => prepare(input, ctx, db));\n if (!isPlainObject(data)) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit's prepare for ${service.name} must return the new row's data`,\n );\n }\n const issues = columnValueIssues(service, data);\n if (issues.length > 0) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The read/write kit's prepare for ${service.name} must return column values: ${issues.map((issue) => issue.message).join(\"; \")}`,\n );\n }\n // What it writes: each parent it names, at the method's row level.\n await checkAnchorColumns(call.runtime, call.principal, data, rowLevel(form, \"Moderate\"), {\n creating: true,\n });\n const { select } = projectionOf(call, \"entity\");\n return await call.table.create({ data, select });\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `delete` (RFC 0003 section 12.1): `db.<model>.delete`.\n// The tracked client records it, so subscribers get `r` and collections a\n// `removed` delta. A row that is not there is `NOT_FOUND`. There is no soft\n// delete: no consumer app uses one.\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkRowWrite } from \"./access\";\nimport { crudCall, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** The `delete` handler: the caller needs the method's row level on the row whatever the form. */\nexport function deleteHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<null> => {\n const call = crudCall(ctx, db);\n const { id } = input as IdInput;\n await checkRowWrite(call, form, id);\n await call.table.delete({ where: { id }, select: { id: true } });\n return null;\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `get` (RFC 0003 section 12.1): one row by id, read\n// with its projection's select (one statement). Its access form decides who\n// may read the row; `{ entry: \"Read\" }` checks the row itself. A row that is\n// not there is `NOT_FOUND` (for a caller the form let through: an `entry`\n// check already refuses a missing row with `FORBIDDEN`).\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport { requireRow } from \"../guards\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** The `get` handler. */\nexport function getHandler(): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = crudCall(ctx, db);\n const { id } = input as IdInput;\n const { select } = projectionOf(call, \"entity\");\n return requireRow(\n await call.table.findUnique({ where: { id }, select }),\n `No such ${call.model}`,\n );\n };\n return handler as KitHandler;\n}\n","// The read/write kit's `getMany` (RFC 0003 section 12.1): up to 200 rows by\n// id, in the order asked. The caller's level on every id comes from one\n// batched policy lookup (`levelsFor`), and the ids it does not reach at the\n// method's row level are left out, as are ids with no row: a caller learns\n// nothing about rows it may not read. The rows are then read in one\n// statement with the entity's select; the framework projects them.\n\nimport type { IdsInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AccessForm } from \"../../access/types\";\nimport { allowedIds, rowLevel } from \"./access\";\nimport {\n crudCall,\n projectionOf,\n uniqueIds,\n type KitHandler,\n type KitHandlerArgs,\n type Row,\n} from \"./runtime\";\n\n/** The `getMany` handler. */\nexport function getManyHandler(form: AccessForm): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Row[]> => {\n const call = crudCall(ctx, db);\n const ids = uniqueIds((input as IdsInput).ids);\n const allowed = await allowedIds(call, form, ids, rowLevel(form, \"Read\"), \"read\");\n if (allowed.length === 0) {\n return [];\n }\n const { select } = projectionOf(call, \"entity\");\n const rows = await call.table.findMany({ where: { id: { in: allowed } }, select });\n const byId = new Map(rows.map((row) => [row.id, row]));\n return allowed.flatMap((id) => {\n const row = byId.get(id);\n return row === undefined ? [] : [row];\n });\n };\n return handler as KitHandler;\n}\n","// The order and the filter of a read/write kit `list` page (RFC 0003 section\n// 12.1), from the caller's parsed input: only declared fields reach here\n// (the contract's input schema refuses any other), and a filter is equality\n// on plain values, so nothing the caller sends becomes a query operator.\n//\n// Nor may a call name a field the caller does not receive (a field tier,\n// RFC 0003 section 6): whether a row passes an equality filter tells what\n// the field holds, and a sort puts the field's values in the page's cursor\n// and its order. Such a call is `FORBIDDEN`, and a default sort on such a\n// field falls back to `id`. The admin kit's `adminList` follows the same\n// rules.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport type { ListQuery } from \"../../../contract/kits/crudList\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { StorageWhere } from \"../../storage\";\n\n/** The fields a list call names: its filter's and its sort's. */\nexport function namedFields(query: Pick<ListQuery, \"filter\" | \"sort\">): string[] {\n return [...Object.keys(query.filter), ...(query.sort === undefined ? [] : [query.sort.field])];\n}\n\n/** `FORBIDDEN` when a call names one of the `hidden` fields of `service`: above the caller's level. */\nexport function checkVisible(\n service: string,\n hidden: ReadonlySet<string>,\n names: readonly string[],\n): void {\n const unseen = names.find((name) => hidden.has(name));\n if (unseen !== undefined) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `\"${unseen}\" is a field of ${service} above your access level`,\n );\n }\n}\n\n/** The declared sort fields a page may default to: none when the first is `hidden`, so the page sorts by `id`. */\nexport function defaultSorts(\n sortFields: readonly string[],\n hidden: ReadonlySet<string>,\n): readonly string[] {\n const [first] = sortFields;\n return first !== undefined && hidden.has(first) ? [] : sortFields;\n}\n\n/** The order of a page: the caller's sort, else the first declared sort field, else `id`; `id` last. */\nexport function listOrder(sortFields: readonly string[], sort: ListQuery[\"sort\"]): OrderBy {\n const field = sort?.field ?? sortFields[0];\n const direction = sort?.direction ?? \"asc\";\n if (field === undefined || field === \"id\") {\n return [[\"id\", direction]];\n }\n return [\n [field, direction],\n [\"id\", direction],\n ];\n}\n\n/** The caller's equality filter and the access filter, together. */\nexport function listWhere(\n filter: ListQuery[\"filter\"],\n access: StorageWhere | undefined,\n): StorageWhere {\n const equal = Object.fromEntries(\n Object.entries(filter).filter(([, value]) => value !== undefined),\n );\n const parts = [equal, access ?? {}].filter((part) => Object.keys(part).length > 0);\n return parts.length > 1 ? { AND: parts } : (parts[0] ?? {});\n}\n","// One page of rows by keyset cursor (RFC 0003 sections 7.3 and 12.1), for\n// the read/write kit's `list` and the kits built on it (search). It reuses\n// the collections' cursor (`collections/cursor.ts`): a cursor holds the last\n// row's value of each order column, `id` last, so the next page starts right\n// after that row however many rows are inserted or removed before it.\n//\n// A list can be sorted several ways, so its cursors also name the order they\n// were made for; a cursor from another order, or any string that is not a\n// cursor, is `VALIDATION`. So is a filter value or cursor value the\n// database refuses for its column's type.\n//\n// A page costs one statement, plus a second when the call counts the rows,\n// run beside the first. The first page of a sort on an optional column also\n// asks the storage adapter once per process whether it may hold null.\n//\n// A cursor longer than a cursor may be (`MAX_CURSOR_LENGTH`: a sort value\n// of thousands of characters) names its row instead of holding its values,\n// so paging goes on (the 5.1 audit's CRUD-8: such a cursor was refused).\n// The next page reads that row's order values first, inside the list's own\n// filter, so the row must still be one the caller may list: one more\n// statement, and `VALIDATION` once the row has left the list.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport { MAX_CURSOR_LENGTH } from \"../../../contract/kits/crudList\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { afterCursor, decodeCursor, encodeCursor, orderByOf } from \"../../collections/cursor\";\nimport type { StorageAdapter, StorageWhere } from \"../../storage\";\nimport { unreadable } from \"../../transports/ack\";\nimport type { ModelDelegate, Row } from \"./runtime\";\n\n/** What one page reads. */\nexport interface PageRead {\n readonly table: ModelDelegate;\n /** The model, named as the client names it, for the storage adapter's `nullable`. */\n readonly model: string;\n readonly storage: StorageAdapter | undefined;\n /** The rows to page through: the caller's filter and the access filter. */\n readonly where: StorageWhere;\n /** Sort columns ending in `id`. */\n readonly order: OrderBy;\n readonly cursor: string | undefined;\n readonly limit: number;\n /** What each row is read with; it must include every order column. */\n readonly select: Readonly<Record<string, unknown>>;\n /** Count every row `where` matches, too. */\n readonly totalCount: boolean;\n /**\n * Whether `where` holds values the caller sent (a filter): a database\n * refusal of them, like one of the cursor's, is then `VALIDATION`.\n */\n readonly filtered: boolean;\n}\n\n/** One page of rows. */\nexport interface RowsPage {\n readonly rows: Row[];\n /** The cursor of the next page, or `null` on the last one. */\n readonly nextCursor: string | null;\n readonly totalCount?: number;\n}\n\nconst SIGNATURE = \"~order\";\n\nconst NOT_A_CURSOR = \"cursor is not a cursor of this list in this order\";\n\n/** The order a cursor was made for, as the cursor carries it. */\nfunction signatureOf(order: OrderBy): string {\n return order.map(([column, direction]) => `${column} ${direction}`).join(\",\");\n}\n\n/** `order` with the signature as a first, pseudo column. */\nfunction signed(order: OrderBy): OrderBy {\n return [[SIGNATURE, \"asc\"], ...order] as unknown as OrderBy;\n}\n\n/** How a cursor that names its row is signed: this, then the order's signature. */\nconst ROW = \"row \";\n\n/** The shape of a cursor that names its row: its signature, then the row's id. */\nconst ROW_CURSOR = [\n [SIGNATURE, \"asc\"],\n [\"id\", \"asc\"],\n] as unknown as OrderBy;\n\n/**\n * The cursor of the page after `row`: its order values, or, when they would\n * make the cursor longer than `MAX_CURSOR_LENGTH`, its id.\n */\nexport function cursorAfter(order: OrderBy, row: Row): string {\n const cursor = encodeCursor(signed(order), { ...row, [SIGNATURE]: signatureOf(order) });\n return cursor.length <= MAX_CURSOR_LENGTH\n ? cursor\n : encodeCursor(ROW_CURSOR, { [SIGNATURE]: `${ROW}${signatureOf(order)}`, id: row.id });\n}\n\n/** What a cursor holds: the order values of the row before the page, or that row's id. */\ntype CursorHeld = { readonly values: readonly unknown[] } | { readonly row: string };\n\n/** What a cursor of `order` holds, or `VALIDATION` for one that is not a cursor of `order`. */\nexport function readCursor(order: OrderBy, cursor: string): CursorHeld {\n const signature = signatureOf(order);\n const decoded = (shape: OrderBy): readonly unknown[] | undefined => {\n try {\n return decodeCursor(shape, cursor);\n } catch {\n return undefined;\n }\n };\n const values = decoded(signed(order));\n if (values?.[0] === signature) {\n return { values: values.slice(1) };\n }\n const named = decoded(ROW_CURSOR);\n if (named?.[0] === `${ROW}${signature}` && typeof named[1] === \"string\") {\n return { row: named[1] };\n }\n throw unreadable(NOT_A_CURSOR, [\"cursor\"]);\n}\n\n/**\n * The order columns that may hold null, as the storage adapter answers. A\n * cursor holding null for a column the adapter says cannot hold it is not a\n * cursor of this list.\n */\nasync function nullableColumns(\n read: PageRead,\n values: readonly unknown[] | undefined,\n): Promise<Set<string>> {\n const { storage, model, order } = read;\n const nullable = new Set<string>();\n for (const [index, [column]] of order.entries()) {\n const value = values?.[index];\n const known = column === \"id\" ? false : await storage?.nullable?.(model, column);\n if (value === null && known === false) {\n throw unreadable(NOT_A_CURSOR, [\"cursor\"]);\n }\n if (known === true || value === null) {\n nullable.add(column);\n }\n }\n return nullable;\n}\n\n/**\n * A database refusal of the caller's values (a filter or a cursor), as\n * `VALIDATION`; anything else unchanged. The admin kit's `adminList` too.\n */\nexport function refusal(error: unknown, read: Pick<PageRead, \"cursor\" | \"filtered\">): unknown {\n const isValidation = error instanceof Error && error.name === \"PrismaClientValidationError\";\n if (!isValidation || (read.cursor === undefined && !read.filtered)) {\n return error;\n }\n const refused = new QuickdrawError(\n \"VALIDATION\",\n \"The filter or the cursor does not fit its fields\",\n {\n issues: [\n {\n path: read.cursor === undefined ? [\"filter\"] : [],\n message: \"A filter or cursor value does not fit its field's type\",\n },\n ],\n },\n );\n refused.cause = error;\n return refused;\n}\n\n/**\n * The order values a page starts after: the cursor's, or those of the row it\n * names, read inside the list's filter (`VALIDATION` once it has left).\n */\nasync function startValues(read: PageRead, cursor: string): Promise<readonly unknown[]> {\n const held = readCursor(read.order, cursor);\n if (\"values\" in held) {\n return held.values;\n }\n let row: Row | null;\n try {\n row = await read.table.findFirst({\n where: { AND: [read.where, { id: held.row }] },\n select: Object.fromEntries(read.order.map(([column]) => [column, true])),\n });\n } catch (error) {\n throw refusal(error, read);\n }\n if (row === null) {\n throw unreadable(NOT_A_CURSOR, [\"cursor\"]);\n }\n return read.order.map(([column]) => row[column]);\n}\n\n/** Reads one page: `limit` rows after the cursor, in `order`, the next cursor, and the count when asked. */\nexport async function readPage(read: PageRead): Promise<RowsPage> {\n const values = read.cursor === undefined ? undefined : await startValues(read, read.cursor);\n const nullable = await nullableColumns(read, values);\n const where =\n values === undefined\n ? read.where\n : { AND: [read.where, afterCursor(read.order, values, nullable)] };\n let rows: Row[];\n let total: number | undefined;\n try {\n [rows, total] = await Promise.all([\n read.table.findMany({\n where,\n select: read.select,\n orderBy: orderByOf(read.order, nullable),\n take: read.limit + 1,\n }),\n read.totalCount ? read.table.count({ where: read.where }) : undefined,\n ]);\n } catch (error) {\n throw refusal(error, read);\n }\n const shown = rows.slice(0, read.limit);\n const last = shown.at(-1);\n return {\n rows: shown,\n nextCursor:\n rows.length > read.limit && last !== undefined ? cursorAfter(read.order, last) : null,\n ...(total === undefined ? {} : { totalCount: total }),\n };\n}\n","// The read/write kit's `list` (RFC 0003 section 12.1): one page of the rows\n// the caller may read, filtered and sorted by the fields the contract\n// declares, by keyset cursor (`page.ts`). The trap it exists to close: the\n// policy's `accessWhere` is part of every read, so a list never returns a row\n// `get` would refuse. Items are the declared projection's rows (its select,\n// its map, dates as ISO strings), stripped of the fields above the level\n// the page was filtered at; a filter or sort on such a field is `FORBIDDEN`\n// (`listQuery.ts`), since the rows it keeps and the cursor it makes would\n// tell what the field holds.\n//\n// Statements: the access filter's own reads (none for `owner` and `jsonAcl`\n// policies or a service-wide `Admin` grant), then one for the page, and one\n// more beside it when the call asks for `totalCount`.\n\nimport type { CrudSpec } from \"../../../contract/kits/crud\";\nimport type { ListPage, ListQuery } from \"../../../contract/kits/crudList\";\nimport type { AccessForm } from \"../../access/types\";\nimport { selectWith } from \"../../collections/items\";\nimport { projectRow, type Projection } from \"../../emit/projection\";\nimport { strip } from \"../../emit/tiers\";\nimport { readerLevel, rowLevel, rowsWhere } from \"./access\";\nimport { checkVisible, defaultSorts, listOrder, listWhere, namedFields } from \"./listQuery\";\nimport { readPage } from \"./page\";\nimport { crudCall, projectionOf, type KitHandler, type KitHandlerArgs } from \"./runtime\";\n\n/** What a `list` handler is made from. */\nexport interface ListContext {\n readonly spec: Extract<CrudSpec, { method: \"list\" }>;\n readonly form: AccessForm;\n /** The projection the items are: `\"entity\"` or one of the contract's. */\n readonly projection: string;\n}\n\n/** One row of a page as an item: projected, without the `hidden` fields. The search kit's too. */\nexport function pageItem(\n projection: Projection,\n row: object,\n hidden: ReadonlySet<string>,\n): unknown {\n const item = projectRow(projection, row);\n return typeof item === \"object\" && item !== null\n ? strip(item as Readonly<Record<string, unknown>>, hidden)\n : item;\n}\n\nfunction emptyPage(query: ListQuery): ListPage<never> {\n return { items: [], nextCursor: null, ...(query.totalCount ? { totalCount: 0 } : {}) };\n}\n\n/** The `list` handler. */\nexport function listHandler(context: ListContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ListPage<unknown>> => {\n const call = crudCall(ctx, db);\n const query = input as ListQuery;\n const level = rowLevel(context.form, \"Read\");\n const reader = readerLevel(call, context.form, level);\n const unseen = projectionOf(call, \"entity\").tiers.hidden(reader);\n checkVisible(call.runtime.service.name, unseen, namedFields(query));\n const access = await rowsWhere(call, context.form, level);\n if (access === \"none\") {\n return emptyPage(query);\n }\n const projection = projectionOf(call, context.projection);\n const order = listOrder(defaultSorts(context.spec.sort, unseen), query.sort);\n const page = await readPage({\n table: call.table,\n model: call.model,\n storage: call.runtime.storage,\n where: listWhere(query.filter, access),\n order,\n cursor: query.cursor,\n limit: query.limit,\n select: selectWith(\n projection.select,\n order.map(([column]) => column),\n ),\n totalCount: query.totalCount,\n filtered: Object.keys(query.filter).length > 0,\n });\n const hidden = projection.tiers.hidden(reader);\n return {\n items: page.rows.map((row) => pageItem(projection, row, hidden)),\n nextCursor: page.nextCursor,\n ...(page.totalCount === undefined ? {} : { totalCount: page.totalCount }),\n };\n };\n return handler as KitHandler;\n}\n","// Ordinals for the read/write kit's `reorder` (RFC 0003 section 12.1): rows\n// are kept apart by gaps of `ORDINAL_STEP`, so a row moves between two others\n// by taking the whole number halfway between them, and only that row is\n// written. When no whole number is left between them (about ten moves into\n// one gap), the ordered list is renumbered in steps. Whole numbers suit\n// `Int` and `Float` columns alike, and stay within a 32-bit integer.\n\nimport type { StorageWhere } from \"../../storage\";\nimport { delegateOf } from \"./runtime\";\n\n/** The gap between the ordinals of neighboring rows, after a renumbering and for `nextOrdinal`. */\nexport const ORDINAL_STEP = 1024;\n\nconst MIN_ORDINAL = -2_147_483_648;\nconst MAX_ORDINAL = 2_147_483_647;\n\n/** A number an ordinal column may hold: finite, and within a 32-bit integer. */\nexport function isOrdinal(value: unknown): value is number {\n return (\n typeof value === \"number\" &&\n Number.isFinite(value) &&\n value >= MIN_ORDINAL &&\n value <= MAX_ORDINAL\n );\n}\n\n/**\n * A whole number strictly between `low` and `high`, a step below `high` when\n * there is no `low` (the start of the list), a step above `low` when there is\n * no `high` (its end); `undefined` when there is none left.\n */\nexport function ordinalBetween(\n low: number | undefined,\n high: number | undefined,\n): number | undefined {\n let value: number | undefined;\n if (low === undefined && high !== undefined) {\n value = Math.ceil(high) - ORDINAL_STEP;\n } else if (high === undefined && low !== undefined) {\n value = Math.floor(low) + ORDINAL_STEP;\n } else if (low !== undefined && high !== undefined) {\n const middle = Math.floor((low + high) / 2);\n value = middle > low && middle < high ? middle : undefined;\n }\n return isOrdinal(value) ? value : undefined;\n}\n\n/** Options of {@link nextOrdinal}. */\nexport interface NextOrdinalOptions {\n /** The ordinal column. Default `\"ordinal\"`. */\n readonly column?: string;\n}\n\n/**\n * The ordinal that puts a new row last among the rows `where` matches: a step\n * after the highest, or one step for an empty list. One statement. For a\n * create handler (or `crud.handlers`' `prepare`) of a model the kit's\n * `reorder` orders.\n *\n * @example\n * const ordinal = await nextOrdinal(db, \"task\", { projectId: input.projectId });\n * return db.task.create({ data: { ...input, ordinal } });\n */\nexport async function nextOrdinal(\n db: unknown,\n model: string,\n where: StorageWhere = {},\n options: NextOrdinalOptions = {},\n): Promise<number> {\n const column = options.column ?? \"ordinal\";\n if (typeof model !== \"string\" || model.length === 0 || column.length === 0) {\n throw new TypeError(\n \"nextOrdinal(db, model, where, { column? }): name the model and its column\",\n );\n }\n const result = await delegateOf(db, model).aggregate({ where, _max: { [column]: true } });\n const highest = (result._max as Readonly<Record<string, unknown>> | null | undefined)?.[column];\n return typeof highest === \"number\" && Number.isFinite(highest)\n ? Math.floor(highest) + ORDINAL_STEP\n : ORDINAL_STEP;\n}\n","// The read/write kit's `reorder` (RFC 0003 section 12.1): moves a row\n// between two others of the same ordered list (the rows sharing its\n// `within` columns), ascending by the declared column. `beforeId` is the row\n// that will come right before it and `afterId` the row right after; given\n// one, the kit finds the other. The moved row takes the whole number halfway\n// between its neighbors (`ordinal.ts`), so a move is one write; when no gap\n// is left, the list is renumbered first.\n//\n// A move reads its neighbors and writes from what it read, so it runs\n// SERIALIZABLE, as a sharing change does (`../transactions.ts`): two moves\n// into one gap at once would otherwise both take its midpoint. A conflict\n// the database reports is `CONFLICT`; the caller may try again.\n//\n// The moved row and the neighbors a move names need the method's row level\n// (one batched lookup): a neighbor below it is `NOT_FOUND`, as a missing\n// one or one of another list is. The list a move reads, counts and\n// renumbers is the rows sharing the moved row's `within` values that the\n// caller may write at that level, so a list with no `within` or a null one\n// is the caller's own and reaches no other tenant's row (the 5.1 audit's\n// CRUD-6: a caller named other tenants' rows as neighbors, read their\n// ordinals, and made renumbering write them). The rows a move names are\n// read through that same filter, so the neighbors and the list agree: a\n// moved row the filter leaves out is `FORBIDDEN`, and a policy whose filter\n// matches no row (a `resolver` without `where`) moves nothing below a\n// service-wide grant, as its lists show nothing.\n//\n// Statements: the lookup and the write filter's reads (none when the\n// caller's grant reaches every row), then, in one transaction: one read of\n// the row and its neighbors, one more to find the missing neighbor when only\n// one is given, and the write. When no gap is left, that transaction ends\n// without writing; the list's rows are counted, and a second transaction, given\n// `RENUMBER_BASE_MS` plus `RENUMBER_MS_PER_ROW` for each row (a client's\n// default limit, Prisma's 5 s, would fail a long list every time), reads the\n// rows again, renumbers (one read, and one write per row whose ordinal\n// changes) and moves. The renumbering's frames reach a collection scope as a\n// `reset` once they pass the scope's `bulkThreshold`.\n\nimport type { CrudSpec } from \"../../../contract/kits/crud\";\nimport type { ReorderInput } from \"../../../contract/kits/crudSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { AccessFilter } from \"../../access/policy\";\nimport type { StorageWhere } from \"../../storage\";\nimport type { AccessForm } from \"../../access/types\";\nimport { inKitTransaction } from \"../transactions\";\nimport { allowedIds, rowLevel, rowsWhere } from \"./access\";\nimport { isOrdinal, ordinalBetween, ORDINAL_STEP } from \"./ordinal\";\nimport {\n crudCall,\n delegateOf,\n projectionOf,\n type CrudCall,\n type KitHandler,\n type KitHandlerArgs,\n type ModelDelegate,\n type Row,\n uniqueIds,\n} from \"./runtime\";\n\ntype ReorderSpec = Extract<CrudSpec, { method: \"reorder\" }>;\n\n/** The rows a move names, read once. */\ninterface Named {\n readonly moved: Row;\n readonly before: Row | undefined;\n readonly after: Row | undefined;\n}\n\nfunction invalid(message: string, path: readonly string[]): QuickdrawError {\n return new QuickdrawError(\"VALIDATION\", message, { issues: [{ path: [...path], message }] });\n}\n\n/**\n * Reads the moved row and its named neighbors among the rows the caller may\n * write (`writable`, as `listOf` takes it). A neighbor that is missing, in\n * another list or not writable is `NOT_FOUND` alike, so a move cannot tell\n * whether a row of another list exists. A moved row the filter leaves out\n * is `FORBIDDEN`: the lookup let it through, so the policy's filter does not\n * match it, or access changed meanwhile. Unfiltered, a missing one is\n * `NOT_FOUND`.\n */\nasync function readNamed(\n table: ModelDelegate,\n [spec, writable]: readonly [ReorderSpec, AccessFilter | undefined],\n move: ReorderInput,\n model: string,\n): Promise<Named> {\n const select = Object.fromEntries([\"id\", spec.column, ...spec.within].map((key) => [key, true]));\n const ids = {\n id: { in: [move.id, move.beforeId, move.afterId].filter((id) => id !== undefined) },\n };\n const where = writable === undefined ? ids : { AND: [ids, writable] };\n const rows = writable === \"none\" ? [] : await table.findMany({ where, select });\n const byId = new Map(rows.map((row) => [row.id, row]));\n const moved = byId.get(move.id);\n if (moved === undefined) {\n throw writable === undefined\n ? new QuickdrawError(\"NOT_FOUND\", `No such ${model}`)\n : new QuickdrawError(\"FORBIDDEN\", \"Insufficient permissions\");\n }\n const neighbor = (id: string | undefined, key: string): Row | undefined => {\n const row = id === undefined ? undefined : byId.get(id);\n const listed =\n row !== undefined && spec.within.every((column) => row[column] === moved[column]);\n if (id !== undefined && !listed) {\n throw new QuickdrawError(\"NOT_FOUND\", `No such ${model} in this list as ${key}`);\n }\n return row;\n };\n return {\n moved,\n before: neighbor(move.beforeId, \"beforeId\"),\n after: neighbor(move.afterId, \"afterId\"),\n };\n}\n\n/**\n * The rows of the moved row's list, the moved row left out: those sharing\n * its `within` values that the caller may write (`writable`; `undefined`:\n * every row, `\"none\"`: none).\n */\nfunction listOf(spec: ReorderSpec, moved: Row, writable: AccessFilter | undefined): StorageWhere {\n const scope = Object.fromEntries(spec.within.map((column) => [column, moved[column] ?? null]));\n const mine = writable === undefined ? [] : [writable === \"none\" ? { id: { in: [] } } : writable];\n return { AND: [scope, { id: { not: moved.id } }, ...mine] };\n}\n\n/** The row right after (`\"next\"`) or right before (`\"previous\"`) `row` in the list. */\nasync function adjacent(\n table: ModelDelegate,\n spec: ReorderSpec,\n list: StorageWhere,\n row: Row,\n side: \"next\" | \"previous\",\n): Promise<Row | null> {\n const { column } = spec;\n const beyond = side === \"next\" ? \"gt\" : \"lt\";\n const direction = side === \"next\" ? \"asc\" : \"desc\";\n const value = row[column];\n return await table.findFirst({\n where: {\n AND: [\n list,\n { OR: [{ [column]: { [beyond]: value } }, { [column]: value, id: { [beyond]: row.id } }] },\n ],\n },\n orderBy: [{ [column]: direction }, { id: direction }],\n select: { id: true, [column]: true },\n });\n}\n\n/**\n * The ordinals the moved row goes between, `null` for an end of the list,\n * or `undefined` when a neighbor's ordinal is not a usable number.\n */\nasync function bounds(\n table: ModelDelegate,\n spec: ReorderSpec,\n named: Named,\n writable: AccessFilter | undefined,\n): Promise<[low: number | null, high: number | null] | undefined> {\n const { column } = spec;\n const { before, after } = named;\n const list = listOf(spec, named.moved, writable);\n const low =\n before ?? (after === undefined ? null : await adjacent(table, spec, list, after, \"previous\"));\n const high =\n after ?? (before === undefined ? null : await adjacent(table, spec, list, before, \"next\"));\n const lowValue = low === null ? null : low[column];\n const highValue = high === null ? null : high[column];\n const usable = (value: unknown): boolean => value === null || isOrdinal(value);\n if (!usable(lowValue) || !usable(highValue)) {\n return undefined;\n }\n if (before !== undefined && after !== undefined && (lowValue as number) > (highValue as number)) {\n throw invalid(\"beforeId comes after afterId in the list\", [\"afterId\"]);\n }\n return [lowValue as number | null, highValue as number | null];\n}\n\n/** Renumbers the list in steps with the moved row in its new place; returns the moved row's ordinal. */\nasync function renumber(\n table: ModelDelegate,\n [spec, writable]: readonly [ReorderSpec, AccessFilter | undefined],\n named: Named,\n move: ReorderInput,\n): Promise<number> {\n const { column } = spec;\n const rows = await table.findMany({\n where: listOf(spec, named.moved, writable),\n select: { id: true, [column]: true },\n orderBy: [{ [column]: \"asc\" }, { id: \"asc\" }],\n });\n const order = rows.map((row) => row.id);\n const neighbor = move.beforeId ?? move.afterId;\n if (neighbor !== undefined && !order.includes(neighbor)) {\n // Read through the same filter, in the same transaction, as the list: never guess its place.\n throw new QuickdrawError(\n \"INTERNAL\",\n \"A reorder's neighbor is missing from the list it renumbers\",\n );\n }\n const at =\n move.beforeId === undefined\n ? Math.max(order.indexOf(move.afterId), 0)\n : order.indexOf(move.beforeId) + 1;\n order.splice(at, 0, move.id);\n const current = new Map(rows.map((row) => [row.id, row[column]]));\n let placed = ORDINAL_STEP;\n for (const [index, id] of order.entries()) {\n const value = (index + 1) * ORDINAL_STEP;\n if (id === move.id) {\n placed = value;\n } else if (current.get(id) !== value) {\n await table.update({ where: { id }, data: { [column]: value }, select: { id: true } });\n }\n }\n return placed;\n}\n\n/** A renumbering transaction's time limit: this much, plus `RENUMBER_MS_PER_ROW` for each row of the list. */\nexport const RENUMBER_BASE_MS = 5_000;\n\n/** The time a renumbering transaction is given for each row of the list it renumbers. */\nexport const RENUMBER_MS_PER_ROW = 10;\n\nconst OWNER = \"The read/write kit's reorder\";\n\nconst CONFLICT = \"Another change to this list ran at the same time; try again\";\n\n/**\n * One move: the call, what it asks, the rows the caller may write, and what\n * the moved row is read back with.\n */\ninterface Move {\n readonly call: CrudCall;\n readonly spec: ReorderSpec;\n readonly move: ReorderInput;\n readonly writable: AccessFilter | undefined;\n readonly select: Readonly<Record<string, unknown>>;\n}\n\n/**\n * Moves the row inside `tx`: to the whole number between its new neighbors,\n * or, with `mayRenumber`, after renumbering its list. Without it, a move\n * with no gap left writes nothing and answers the list to renumber.\n */\nasync function moveIn(\n tx: unknown,\n { call, spec, move, writable, select }: Move,\n mayRenumber: boolean,\n): Promise<{ readonly row: Row } | { readonly list: StorageWhere }> {\n const table = delegateOf(tx, call.model);\n const named = await readNamed(table, [spec, writable], move, call.model);\n const range = await bounds(table, spec, named, writable);\n const between =\n range === undefined ? undefined : ordinalBetween(range[0] ?? undefined, range[1] ?? undefined);\n if (between === undefined && !mayRenumber) {\n return { list: listOf(spec, named.moved, writable) };\n }\n const value = between ?? (await renumber(table, [spec, writable], named, move));\n return {\n row: await table.update({ where: { id: move.id }, data: { [spec.column]: value }, select }),\n };\n}\n\n/**\n * `FORBIDDEN` unless the caller may write the moved row at `level`, and\n * `NOT_FOUND` for a named neighbor it may not, as for a missing one: one\n * batched lookup.\n */\nasync function checkNamed(\n call: CrudCall,\n [form, level]: readonly [AccessForm, ReturnType<typeof rowLevel>],\n move: ReorderInput,\n): Promise<void> {\n const named = [move.beforeId, move.afterId].filter((id) => id !== undefined);\n const ids = uniqueIds([move.id, ...named]);\n const writable = new Set(await allowedIds(call, form, ids, level, \"write\"));\n if (!writable.has(move.id)) {\n throw new QuickdrawError(\"FORBIDDEN\", \"Insufficient permissions\");\n }\n for (const [id, key] of [\n [move.beforeId, \"beforeId\"],\n [move.afterId, \"afterId\"],\n ] as const) {\n if (id !== undefined && !writable.has(id)) {\n throw new QuickdrawError(\"NOT_FOUND\", `No such ${call.model} in this list as ${key}`);\n }\n }\n}\n\n/**\n * The `reorder` handler: the caller needs the method's row level on the\n * moved row and on the neighbors it names, whatever the form, and the list\n * is the rows it may write.\n */\nexport function reorderHandler(spec: ReorderSpec, form: AccessForm): KitHandler {\n const level = rowLevel(form, \"Moderate\");\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Row> => {\n const call = crudCall(ctx, db);\n const asked = input as ReorderInput;\n await checkNamed(call, [form, level], asked);\n const move: Move = {\n call,\n spec,\n move: asked,\n writable: await rowsWhere(call, form, level, \"write\"),\n select: projectionOf(call, \"entity\").select,\n };\n const how = { owner: OWNER, conflict: CONFLICT };\n const first = await inKitTransaction(db, async (tx) => await moveIn(tx, move, false), how);\n if (\"row\" in first) {\n return first.row;\n }\n // No gap left: renumber, in a transaction given time for every row of the list.\n const rows = await call.table.count({ where: first.list });\n const timeoutMs = RENUMBER_BASE_MS + (rows + 1) * RENUMBER_MS_PER_ROW;\n const moved = await inKitTransaction(db, async (tx) => await moveIn(tx, move, true), {\n ...how,\n timeoutMs,\n });\n if (!(\"row\" in moved)) {\n throw new QuickdrawError(\"INTERNAL\", \"A renumbering reorder wrote no row\");\n }\n return moved.row;\n };\n return handler as KitHandler;\n}\n","// The handler of each read/write kit method (RFC 0003 section 12.1), from\n// what `crud.contract` made it for and the access form `crud.handlers`\n// gives it.\n\nimport { bulkDeleteHandler, bulkUpdateHandler } from \"./bulk\";\nimport { createHandler } from \"./create\";\nimport { deleteHandler } from \"./delete\";\nimport { getHandler } from \"./get\";\nimport { getManyHandler } from \"./getMany\";\nimport { listHandler } from \"./list\";\nimport { reorderHandler } from \"./reorder\";\nimport type { KitHandler } from \"./runtime\";\nimport type { MethodContext } from \"./types\";\nimport { updateHandler } from \"./update\";\n\n/** The handler of one kit method: a new function for each call, which `defineService` checks. */\nexport function handlerOf(context: MethodContext): KitHandler {\n const { spec, form } = context;\n switch (spec.method) {\n case \"get\":\n return getHandler();\n case \"getMany\":\n return getManyHandler(form);\n case \"list\":\n return listHandler({ spec, form, projection: context.projection });\n case \"create\":\n return createHandler(form, context.prepare);\n case \"update\":\n return updateHandler(form);\n case \"delete\":\n return deleteHandler(form);\n case \"reorder\":\n return reorderHandler(spec, form);\n case \"bulkUpdate\":\n return bulkUpdateHandler(form, context.bulkLevel);\n default:\n return bulkDeleteHandler(form, context.bulkLevel);\n }\n}\n","// `crud.handlers(contract, { access, prepare?, rowless? })` (RFC 0003 section 12.1):\n// the read/write kit's server half. It finds the methods `crud.contract` made\n// in the contract and returns an implementation of each, to spread into\n// `defineService`'s `methods`:\n//\n// export const taskService = qd.defineService(task, {\n// model: \"task\",\n// access: inherit({ from: project, via: \"projectId\" }),\n// methods: {\n// ...crud.handlers(task, {\n// access: {\n// get: { entry: \"Read\" },\n// list: \"authenticated\",\n// update: { entry: \"Moderate\" },\n// },\n// }),\n// rename: { access: { entry: \"Moderate\" }, handler: ... },\n// },\n// });\n//\n// Every kit method needs a form in `access`, and nothing else may be there.\n// The handlers find their service through the call (`kitRuntimeOf`), so the\n// service must declare its `model`; `defineService` checks that when the\n// service is defined, that a method on many rows of a service without an\n// access policy has `\"public\"` or `{ service }` access (`access.ts`), and,\n// on a service with one, that `get` under a form that asks the policy\n// nothing about the row its `id` names (`\"public\"`, `\"authenticated\"`,\n// `{ service }` below `Admin`, `custom`, `{ scope }`, `{ entry }` on another\n// key) is named in `rowless`, which says every caller the form admits may\n// read any row.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport { crud as contractHalf, crudSpecOf, type CrudSpec } from \"../../../contract/kits/crud\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport {\n checkWhenDefined,\n checksRowsItself,\n dependsOnCaller,\n type AnyService,\n} from \"../../service\";\nimport { kitEntry, rowlessMethods } from \"../rowless\";\nimport { bulkFallback, everyRowProblem } from \"./access\";\nimport type { AnyPrepare } from \"./create\";\nimport { handlerOf } from \"./methods\";\nimport type { CrudAccess, CrudHandlersOptions, CrudImplementations, MethodContext } from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`crud.handlers: ${message}`);\n}\n\n/** The kit's methods in the contract, with what each was made for. */\nfunction kitMethods(contract: unknown): [string, CrudSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, CrudSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = crudSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n return found;\n}\n\n/** The access forms, one per kit method and nothing else. */\nfunction checkAccess(\n access: unknown,\n names: readonly string[],\n): Readonly<Record<string, AccessForm>> {\n if (!isRecord(access)) {\n fail(\"access must map each of the kit's methods to an access form\");\n }\n const missing = names.filter((name) => !Object.hasOwn(access, name));\n if (missing.length > 0) {\n fail(`access has no form for ${missing.map((name) => `\"${name}\"`).join(\", \")}`);\n }\n for (const [name, form] of Object.entries(access)) {\n if (!names.includes(name)) {\n fail(`access names \"${name}\", which is not a method crud.contract made`);\n }\n const problem = accessFormProblem(form);\n if (problem !== undefined) {\n fail(`access for \"${name}\" ${problem}`);\n }\n }\n return access as Readonly<Record<string, AccessForm>>;\n}\n\n/** The projection a `list`'s items are: the one whose schema `item` is, `\"entity\"` by default. */\nfunction itemProjection(\n contract: AnyContract,\n spec: Extract<CrudSpec, { method: \"list\" }>,\n): string {\n const { item } = spec;\n if (item === undefined || item === contract.entity) {\n return \"entity\";\n }\n const found = Object.entries(contract.projections).find(([, schema]) => schema === item);\n if (found === undefined) {\n fail(\n `list.item of ${contract.name} must be its entity schema or one of its projections' schemas`,\n );\n }\n return found[0];\n}\n\n/** `prepare`: a function, and only for a contract with the kit's `create`. */\nfunction checkPrepare(\n prepare: unknown,\n kit: readonly [string, CrudSpec][],\n): AnyPrepare | undefined {\n if (prepare === undefined) {\n return undefined;\n }\n if (typeof prepare !== \"function\" || !kit.some(([, spec]) => spec.method === \"create\")) {\n fail(\"prepare must be a function, for a contract with the kit's create\");\n }\n return prepare as AnyPrepare;\n}\n\n/** The kit's methods on many rows: on a service without a policy, they reach every row. */\nconst MANY_ROWS: ReadonlySet<CrudSpec[\"method\"]> = new Set([\n \"list\",\n \"getMany\",\n \"bulkUpdate\",\n \"bulkDelete\",\n]);\n\n/**\n * The kit's methods that check the caller's level on the row their `id`\n * names whatever their form (`checkRowWrite`), and `create`, whose `id` (when\n * its input has one) names a new row and which checks the anchors it writes\n * instead (`create.ts`): `defineService`'s rowless check leaves them alone.\n * `get` reads the row its form lets the caller read, so a form that asks the\n * policy nothing about that row needs `rowless`.\n */\nconst CHECKS_ROWS: ReadonlySet<CrudSpec[\"method\"]> = new Set([\n \"create\",\n \"update\",\n \"delete\",\n \"reorder\",\n]);\n\n/**\n * The kit's methods whose result is the rows the caller's level reaches:\n * `defineService` refuses `share: \"all\"` on them (`dependsOnCaller`).\n */\nconst CALLER_DEPENDENT: ReadonlySet<CrudSpec[\"method\"]> = new Set([\"list\", \"getMany\"]);\n\n/** The single-row method whose row level each bulk method takes when its own form names none. */\nconst COUNTERPARTS = { bulkDelete: \"delete\", bulkUpdate: \"update\" } as const;\n\n/**\n * The row level `spec`'s method falls back to when its form names none: a\n * bulk method's counterpart's, when higher than `Moderate`\n * (`bulkFallback`; the 5.1 audit's CRUD-2: `bulkDelete` under\n * `\"authenticated\"` beside `delete: { entry: \"Admin\" }` deleted Admin-only\n * rows at `Moderate`), else `Moderate`.\n */\nfunction bulkLevelOf(\n kit: readonly (readonly [string, CrudSpec])[],\n access: Readonly<Record<string, unknown>>,\n spec: CrudSpec,\n): MethodContext[\"bulkLevel\"] {\n const counterpart =\n spec.method === \"bulkDelete\" || spec.method === \"bulkUpdate\"\n ? COUNTERPARTS[spec.method]\n : undefined;\n const found = kit.find(([, other]) => other.method === counterpart);\n return bulkFallback(found === undefined ? undefined : (access[found[0]] as AccessForm));\n}\n\nconst OPTION_KEYS: readonly string[] = [\"access\", \"prepare\", \"rowless\"];\n\n/** Why a service cannot run the kit's method `name`, made for `contract` with `form`. */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n [name, spec]: readonly [string, CrudSpec],\n form: AccessForm,\n): string | undefined {\n if (service.contract !== contract) {\n return `its read/write kit handlers were made for another contract; pass ${service.name}'s own contract to crud.handlers`;\n }\n if (service.model === undefined) {\n return \"the read/write kit reads and writes the service's rows: declare its model\";\n }\n return MANY_ROWS.has(spec.method) ? everyRowProblem(service, name, form) : undefined;\n}\n\nfunction handlers<C extends AnyContract, const A extends CrudAccess<C>, Db = unknown>(\n contract: C,\n options: CrudHandlersOptions<C, A, Db>,\n): CrudImplementations<A, Db> {\n const kit = kitMethods(contract);\n if (!isRecord(options)) {\n fail(\"options must be { access, prepare?, rowless? }\");\n }\n const unknownKey = Object.keys(options).find((key) => !OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${OPTION_KEYS.join(\", \")}`);\n }\n const names = kit.map(([name]) => name);\n const access = checkAccess(options.access, names);\n const prepare = checkPrepare(options.prepare, kit);\n const rowless = rowlessMethods(options.rowless, names, fail);\n const entries: Record<string, object> = {};\n for (const [name, spec] of kit) {\n const form = access[name] as AccessForm;\n const projection = spec.method === \"list\" ? itemProjection(contract, spec) : \"entity\";\n const bulkLevel = bulkLevelOf(kit, access, spec);\n const handler = handlerOf({ spec, form, projection, prepare, bulkLevel });\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, [name, spec], form));\n if (CHECKS_ROWS.has(spec.method)) {\n checksRowsItself(handler);\n }\n if (CALLER_DEPENDENT.has(spec.method)) {\n dependsOnCaller(handler);\n }\n entries[name] = kitEntry(name, form, handler, rowless);\n }\n return Object.freeze(entries) as CrudImplementations<A, Db>;\n}\n\n/**\n * The read/write kit: `crud.handlers(contract, { access, prepare?, rowless? })`\n * implements exactly the methods `crud.contract` made in `contract`, each\n * with the access form `access` gives it (and `rowless: true` for the\n * methods `rowless` names). `crud.contract` is here too, for server code; a\n * shared package imports it from the root export.\n */\nexport const crud = Object.freeze({ contract: contractHalf.contract, handlers });\n","// The parts of a search (RFC 0003 section 12.2): the condition that matches\n// the query, the scope's members, the order the results come in, and the\n// ids a strategy ranked. The handler (`run.ts`) puts them together with the\n// access filter.\n//\n// The default condition is a case-insensitive \"contains\" of the query in any\n// of the declared fields. Prisma passes LIKE's wildcards in a `contains`\n// value through to PostgreSQL, so `%`, `_` and the escape character `\\` in\n// the query are escaped: \"50%\" finds \"50%\", not \"500\". A field the caller's\n// level would not receive (a field tier, RFC 0003 section 6) is not searched\n// either, so whether a row matches never tells a caller what such a field\n// holds.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { allowedScopes } from \"../../collections/access\";\nimport type { ServiceCollection } from \"../../collections/define\";\nimport { checked } from \"../../devWarnings\";\nimport { membersWhere } from \"../../collections/snapshot\";\nimport type { FindManyArgs, StorageWhere } from \"../../storage\";\nimport { readerLevel } from \"../crud/access\";\nimport { delegateOf, projectionOf, uniqueIds } from \"../crud/runtime\";\nimport type { AnyStrategy, SearchRun } from \"./context\";\n\n/** The order of a search without a scope collection. */\nconst ID_ORDER: OrderBy = Object.freeze([Object.freeze([\"id\", \"asc\"] as const)]);\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** `parts` together: `{}` for none, the one part, or their `AND`. */\nexport function allOf(parts: readonly (StorageWhere | undefined)[]): StorageWhere {\n const kept = parts.filter(\n (part): part is StorageWhere => part !== undefined && Object.keys(part).length > 0,\n );\n return kept.length > 1 ? { AND: kept } : (kept[0] ?? {});\n}\n\n/** `q` as a LIKE pattern's literal text: its wildcards and escape character escaped. */\nexport function likeLiteral(q: string): string {\n return q.replace(/[\\\\%_]/g, \"\\\\$&\");\n}\n\n/** The default condition: `q` in any of `fields`, ignoring case. */\nexport function containsWhere(fields: readonly string[], q: string): StorageWhere {\n const contains = likeLiteral(q);\n return { OR: fields.map((field) => ({ [field]: { contains, mode: \"insensitive\" } })) };\n}\n\n/** The declared fields the caller's level receives, which the default condition looks in. */\nfunction searchedFields(run: SearchRun): readonly string[] {\n const { call, context, level } = run;\n const hidden = projectionOf(call, \"entity\").tiers.hidden(readerLevel(call, context.form, level));\n return context.spec.fields.filter((field) => !hidden.has(field));\n}\n\n/** The condition of the rows that match the query: the strategy's `where`, or the default; `\"none\"` when nothing can match. */\nexport async function textWhere(run: SearchRun): Promise<StorageWhere | \"none\"> {\n const where = run.context.strategy?.where;\n if (where === undefined) {\n const fields = searchedFields(run);\n return fields.length === 0 ? \"none\" : containsWhere(fields, run.query.q);\n }\n const filter: unknown = await checked(() => where(run.query.q, run.ctx));\n if (!isRecord(filter)) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The search strategy of ${run.call.runtime.service.name} must return a filter object from where`,\n );\n }\n return filter;\n}\n\n/** The collection a call keeps to: the search's scope collection, when the call passed a scope. */\nexport function scopedCollection(run: SearchRun): ServiceCollection | undefined {\n const { scope } = run.context.spec;\n if (scope === undefined || run.query.scope === undefined) {\n return undefined;\n }\n const collection = run.call.runtime.service.collections.get(scope);\n if (collection === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The search kit asked ${run.call.runtime.service.name} for collection \"${scope}\", which it does not have`,\n );\n }\n return collection;\n}\n\n/**\n * Refuses a call whose caller may not subscribe to its scope, decided as\n * `qd:col:sub` decides it (`allowedScopes`): `UNAUTHENTICATED` without a\n * principal, `FORBIDDEN` below the collection's `access` on the scope's\n * anchor (or for another user's `\"self\"` scope). A search's own access\n * filter keeps to rows, so without this a scope the caller cannot open\n * would still name the rows in it, and on a service without a row policy\n * show them.\n */\nasync function authorizeScope(\n run: SearchRun,\n collection: ServiceCollection,\n scope: string,\n): Promise<void> {\n const { principal, runtime } = run.call;\n if (principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n const rule = {\n service: runtime.service,\n anchor: collection.anchor?.name,\n access: collection.access,\n };\n const allowed = await allowedScopes(runtime.access, rule, principal, [scope]);\n if (!allowed.has(scope)) {\n throw new QuickdrawError(\"FORBIDDEN\", \"Insufficient permissions\");\n }\n}\n\n/**\n * The members of the call's scope, once the caller is allowed it: its column\n * and `where`, or the ids its `via` junction links to it (one read, through\n * the database client, of at most the collection's `maxLimit` links, the\n * first by the linked row's id: a search pages within those, and never reads\n * a large scope's every link per keystroke). `undefined` without a scope;\n * `\"none\"` for a scope without members.\n */\nexport async function scopeWhere(run: SearchRun): Promise<StorageWhere | \"none\" | undefined> {\n const collection = scopedCollection(run);\n if (collection === undefined || run.query.scope === undefined) {\n return undefined;\n }\n await authorizeScope(run, collection, run.query.scope);\n const reader = {\n findMany: (model: string, args?: FindManyArgs) =>\n delegateOf(run.db, model).findMany(args ?? {}),\n };\n return (await membersWhere(reader, collection, run.query.scope, collection.maxLimit)) ?? \"none\";\n}\n\n/**\n * The order results come in: the scope collection's for a call kept to a\n * scope, else by id. No ranking. An unscoped call is authorized for no\n * scope and its order columns were tier-checked against no collection, so\n * the collection's order (which may hold a column tiered at the\n * collection's access) would leak it through the order and `nextCursor`\n * (the 5.1 audit's CRUD-4).\n */\nexport function searchOrder(run: SearchRun): OrderBy {\n return scopedCollection(run)?.order ?? ID_ORDER;\n}\n\n/**\n * The ids the app's `ids` strategy ranks for the query, each once and at\n * most `limit`: the strategy is the app's code, so its statements are checked.\n */\nexport async function strategyIds(\n run: SearchRun,\n ids: NonNullable<AnyStrategy[\"ids\"]>,\n): Promise<string[]> {\n const found = await checked(() => ids(run.query.q, run.ctx, { limit: run.query.limit }));\n return rankedIds(run, found);\n}\n\n/** The ids a strategy ranked, each once and at most `limit`, or `INTERNAL` for anything else. */\nexport function rankedIds(run: SearchRun, ids: unknown): string[] {\n const valid = Array.isArray(ids) && ids.every((id) => typeof id === \"string\" && id.length > 0);\n if (!valid) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The search strategy of ${run.call.runtime.service.name} must return a list of row ids from ids`,\n );\n }\n return uniqueIds(ids as string[]).slice(0, run.query.limit);\n}\n","// The page a search answers with (RFC 0003 section 12.2). As for the\n// read/write kit's `list`, the items are the item projection's rows,\n// stripped once, at the level the page was read at (`readerLevel`). A search\n// kept to a scope also strips what the scope's collection strips, since its\n// results are that collection's items: when nothing else is missing from\n// them, they are exactly the items the collection's subscribers receive, and\n// the page carries the revision it was read at (`rev`), so a client can keep\n// them in the collection's cache.\n\nimport type { SearchPage } from \"../../../contract/kits/searchSchemas\";\nimport type { Projection } from \"../../emit/projection\";\nimport { readerLevel } from \"../crud/access\";\nimport { pageItem } from \"../crud/list\";\nimport type { Row } from \"../crud/runtime\";\nimport type { SearchRun } from \"./context\";\nimport { scopedCollection } from \"./filters\";\n\n/** A page with no results. */\nexport function emptyPage(): SearchPage<never> {\n return { items: [], nextCursor: null };\n}\n\n/** The fields a page's items go without, and whether they are the scope collection's items. */\nfunction strippingOf(\n run: SearchRun,\n projection: Projection,\n): { readonly hidden: ReadonlySet<string>; readonly collectionItems: boolean } {\n const { call, context, level } = run;\n const reader = projection.tiers.hidden(readerLevel(call, context.form, level));\n const collection = scopedCollection(run);\n if (collection === undefined) {\n return { hidden: reader, collectionItems: false };\n }\n const own = collection.item.tiers.hidden(collection.access);\n const hidden = new Set([...own, ...reader]);\n return { hidden, collectionItems: hidden.size === own.size };\n}\n\n/** The page of `rows`, in that order. */\nexport function resultsPage(\n run: SearchRun,\n projection: Projection,\n rows: readonly Row[],\n nextCursor: string | null,\n): SearchPage<unknown> {\n const { hidden, collectionItems } = strippingOf(run, projection);\n return {\n items: rows.map((row) => pageItem(projection, row, hidden)),\n nextCursor,\n ...(collectionItems ? { rev: run.rev } : {}),\n };\n}\n","// The two ways a search reads its page (RFC 0003 section 12.2).\n//\n// A call kept to a scope is first authorized for it as `qd:col:sub` would\n// be (`filters.ts`): a scope the caller may not open is refused, whatever\n// rows it holds.\n//\n// With a condition (the default \"contains\", or a strategy's `where`): one\n// keyset page (`../crud/page.ts`) of the rows that match it, that the\n// policy's `accessWhere` lets the caller read at the method's row level and,\n// in a scope, that are its members; a call with a scope comes in the scope\n// collection's order, one without by id. Statements: the scope's\n// authorization (the anchor's policy reads; none with a service-wide `Admin`\n// grant), the links of a `via` scope, the access filter's own reads (none\n// for `owner` and `jsonAcl` policies or a service-wide `Admin` grant), then\n// one for the page.\n//\n// With a strategy's `ids`: the rows of the ranked ids (and, in a scope, its\n// members), read in one statement, then only those the caller may read at\n// the row level (one batched `levelsFor`), in the strategy's order, as one\n// page. The ids come from outside the policy, so they are checked after they\n// are read, never trusted. A call whose caller cancelled while the strategy\n// looked up its ids stops before reading them.\n\nimport type { SearchPage } from \"../../../contract/kits/searchSchemas\";\nimport { selectWith } from \"../../collections/items\";\nimport { abortError } from \"../../pipeline/errors\";\nimport { unreadable } from \"../../transports/ack\";\nimport { allowedIds, rowsWhere } from \"../crud/access\";\nimport { readPage } from \"../crud/page\";\nimport { projectionOf, type Row } from \"../crud/runtime\";\nimport type { AnyStrategy, SearchRun } from \"./context\";\nimport { allOf, scopeWhere, searchOrder, strategyIds, textWhere } from \"./filters\";\nimport { emptyPage, resultsPage } from \"./results\";\n\n/** Stops a call that its caller cancelled, or that ran out of time, before it reads its rows. */\nfunction stopIfAborted(run: SearchRun): void {\n const { signal } = run.ctx;\n if (signal.aborted) {\n throw abortError(signal);\n }\n}\n\n/** One page of the rows a condition matches. */\nexport async function wherePage(run: SearchRun): Promise<SearchPage<unknown>> {\n const scope = await scopeWhere(run);\n const access = scope === \"none\" ? \"none\" : await rowsWhere(run.call, run.context.form, run.level);\n const text = access === \"none\" ? \"none\" : await textWhere(run);\n if (scope === \"none\" || access === \"none\" || text === \"none\") {\n return emptyPage();\n }\n stopIfAborted(run);\n const projection = projectionOf(run.call, run.context.projection);\n const order = searchOrder(run);\n const page = await readPage({\n table: run.call.table,\n model: run.call.model,\n storage: run.call.runtime.storage,\n where: allOf([text, access, scope]),\n order,\n cursor: run.query.cursor,\n limit: run.query.limit,\n select: selectWith(\n projection.select,\n order.map(([column]) => column),\n ),\n totalCount: false,\n filtered: run.query.scope !== undefined,\n });\n return resultsPage(run, projection, page.rows, page.nextCursor);\n}\n\n/** The page of the rows a strategy's `ids` ranked. */\nexport async function idsPage(\n run: SearchRun,\n ids: NonNullable<AnyStrategy[\"ids\"]>,\n): Promise<SearchPage<unknown>> {\n if (run.query.cursor !== undefined) {\n throw unreadable(\"cursor is not a cursor of this search, which answers in one page\", [\n \"cursor\",\n ]);\n }\n const scope = await scopeWhere(run);\n if (scope === \"none\") {\n return emptyPage();\n }\n const ranked = await strategyIds(run, ids);\n stopIfAborted(run);\n if (ranked.length === 0) {\n return emptyPage();\n }\n const projection = projectionOf(run.call, run.context.projection);\n const rows = await run.call.table.findMany({\n where: allOf([{ id: { in: ranked } }, scope]),\n select: selectWith(projection.select, []),\n });\n const found = new Map(rows.map((row) => [row.id, row]));\n const present = ranked.filter((id) => found.has(id));\n const allowed = await allowedIds(run.call, run.context.form, present, run.level, \"read\");\n return resultsPage(\n run,\n projection,\n allowed.map((id) => found.get(id) as Row),\n null,\n );\n}\n","// The search kit's handler (RFC 0003 section 12.2): a list with a text\n// condition. A query shorter than the method's `minLength`, once trimmed,\n// finds nothing and reads nothing. Otherwise the call takes the revision a\n// scoped page carries before it reads anything, and reads its page with the\n// strategy's `ids` (`idsPage`) or with a condition (`wherePage`).\n\nimport type { SearchPage, SearchQuery } from \"../../../contract/kits/searchSchemas\";\nimport { kitRuntimeOf } from \"../../context\";\nimport { currentRev } from \"../../rev\";\nimport { rowLevel } from \"../crud/access\";\nimport { crudCall, type KitHandler, type KitHandlerArgs } from \"../crud/runtime\";\nimport type { SearchContext, SearchRun } from \"./context\";\nimport { idsPage, wherePage } from \"./pages\";\nimport { emptyPage } from \"./results\";\nimport type { SearchStrategyContext } from \"./types\";\n\n/** The handler of one search method. */\nexport function searchHandler(context: SearchContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<SearchPage<unknown>> => {\n const query = input as SearchQuery;\n if (query.q.length < context.spec.minLength) {\n return emptyPage();\n }\n const run: SearchRun = {\n call: crudCall(ctx, db),\n context,\n query,\n ctx: ctx as SearchStrategyContext,\n db,\n level: rowLevel(context.form, \"Read\"),\n rev: await (kitRuntimeOf(ctx)?.claimRevision ?? currentRev)(),\n };\n const ids = context.strategy?.ids;\n return ids === undefined ? await wherePage(run) : await idsPage(run, ids);\n };\n return handler as KitHandler;\n}\n","// `search.handlers(contract, { access, strategy?, method? })` (RFC 0003\n// section 12.2): the search kit's server half. It finds the methods\n// `search.contract` made in the contract (usually one, `search`) and returns\n// their implementation, to spread into `defineService`'s `methods`; `method`\n// picks one, for a contract with several that need different access forms\n// or strategies:\n//\n// export const taskService = qd.defineService(task, {\n// model: \"task\",\n// access: inherit({ from: project, via: \"projectId\" }),\n// methods: {\n// ...search.handlers(task, { access: \"authenticated\" }),\n// },\n// });\n//\n// The method shares identical concurrent calls by one caller\n// (`share: \"caller\"`): a client typing sends the same search from several\n// places at once. The handler finds its service through the call\n// (`kitRuntimeOf`), so the service must declare its `model`; `defineService`\n// checks that when the service is defined, and that a search of a service\n// without an access policy, which reaches every row, has `\"public\"` or\n// `{ service }` access. A search kept to a scope returns\n// the scope collection's items, so its item must be that collection's item\n// projection: checked here, when the contract is known.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport {\n search as contractHalf,\n searchSpecOf,\n type SearchSpec,\n} from \"../../../contract/kits/search\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWhenDefined, dependsOnCaller, type AnyService } from \"../../service\";\nimport { everyRowProblem } from \"../crud/access\";\nimport type { AnyStrategy } from \"./context\";\nimport { searchHandler } from \"./run\";\nimport type {\n SearchAccess,\n SearchContract,\n SearchHandlersOptions,\n SearchImplementations,\n SearchMethodsOf,\n} from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`search.handlers: ${message}`);\n}\n\n/** The search kit's methods in the contract, with what each was made for; at least one. */\nfunction kitMethods(contract: unknown): [string, SearchSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, SearchSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = searchSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n if (found.length === 0) {\n fail(`${String(contract.name)} has no method search.contract made`);\n }\n return found;\n}\n\n/** `strategy`: `{ where }` or `{ ids }`, a function either way. */\nfunction checkStrategy(strategy: unknown): AnyStrategy | undefined {\n if (strategy === undefined) {\n return undefined;\n }\n const valid =\n isRecord(strategy) &&\n Object.keys(strategy).every((key) => key === \"where\" || key === \"ids\") &&\n (strategy.where === undefined) !== (strategy.ids === undefined) &&\n [strategy.where, strategy.ids].every(\n (hook) => hook === undefined || typeof hook === \"function\",\n );\n if (!valid) {\n fail(\"strategy must be { where: (q, ctx) => filter } or { ids: (q, ctx, { limit }) => ids }\");\n }\n return strategy as AnyStrategy;\n}\n\nconst OPTION_KEYS: readonly string[] = [\"access\", \"strategy\", \"method\"];\n\n/** The options, checked: the access form, the strategy, and the methods to implement among `kit`. */\nfunction checkOptions(\n options: unknown,\n kit: readonly [string, SearchSpec][],\n): {\n readonly form: AccessForm;\n readonly strategy: AnyStrategy | undefined;\n readonly methods: readonly [string, SearchSpec][];\n} {\n if (!isRecord(options)) {\n fail(\"options must be { access, strategy?, method? }\");\n }\n const unknownKey = Object.keys(options).find((key) => !OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${OPTION_KEYS.join(\", \")}`);\n }\n const problem = accessFormProblem(options.access);\n if (problem !== undefined) {\n fail(`access ${problem}`);\n }\n const { method } = options;\n const methods = method === undefined ? kit : kit.filter(([name]) => name === method);\n if (methods.length === 0) {\n fail(`method \"${String(method)}\" is not a method search.contract made`);\n }\n return {\n form: options.access as AccessForm,\n strategy: checkStrategy(options.strategy),\n methods,\n };\n}\n\n/** The projection a search's results are: the one whose schema `item` is, `\"entity\"` by default. */\nfunction itemProjection(contract: AnyContract, name: string, spec: SearchSpec): string {\n if (contract.entity === undefined) {\n fail(`${contract.name} has no entity for ${name} to search`);\n }\n const { item } = spec;\n if (item === undefined || item === contract.entity) {\n return \"entity\";\n }\n const found = Object.entries(contract.projections).find(([, schema]) => schema === item);\n if (found === undefined) {\n fail(\n `the item of ${contract.name}.${name} must be its entity schema or one of its projections' schemas`,\n );\n }\n return found[0];\n}\n\n/** A scope collection of the contract, whose items the results are. */\nfunction checkScope(contract: AnyContract, name: string, spec: SearchSpec, item: string): void {\n const { scope } = spec;\n if (scope === undefined) {\n return;\n }\n const collection = Object.hasOwn(contract.collections, scope)\n ? contract.collections[scope]\n : undefined;\n if (collection === undefined) {\n fail(`${contract.name}.${name}'s scope \"${scope}\" is not a collection of ${contract.name}`);\n }\n if (collection.item !== item) {\n fail(\n `${contract.name}.${name}'s results are the items of its scope collection \"${scope}\", so its item must be \"${collection.item}\" (pass that projection's schema to search.contract as item), not \"${item}\"`,\n );\n }\n}\n\n/** Why a service cannot run the search method `name`, made for `contract` with `form`. */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n name: string,\n form: AccessForm,\n): string | undefined {\n if (service.contract !== contract) {\n return `its search kit handlers were made for another contract; pass ${service.name}'s own contract to search.handlers`;\n }\n if (service.model === undefined) {\n return \"the search kit reads the service's rows: declare its model\";\n }\n return everyRowProblem(service, name, form);\n}\n\nfunction handlers<\n C extends AnyContract,\n const A extends SearchAccess<C, M>,\n const M extends SearchMethodsOf<C> = SearchMethodsOf<C>,\n>(\n contract: C & NoInfer<SearchContract<C>>,\n options: SearchHandlersOptions<A, M>,\n): SearchImplementations<M, A> {\n const { form, strategy, methods } = checkOptions(options, kitMethods(contract));\n const entries: Record<string, object> = {};\n for (const [name, spec] of methods) {\n const projection = itemProjection(contract, name, spec);\n checkScope(contract, name, spec, projection);\n const handler = searchHandler({ spec, form, projection, strategy });\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, name, form));\n // Its hits are the rows the caller's level reaches: never shared across principals.\n dependsOnCaller(handler);\n entries[name] = Object.freeze({ access: form, handler, share: \"caller\" });\n }\n return Object.freeze(entries) as SearchImplementations<M, A>;\n}\n\n/**\n * The search kit: `search.handlers(contract, { access, strategy?, method? })`\n * implements the methods `search.contract` made in `contract` (or the one\n * `method` names), with the access form `access` gives them.\n * `search.contract` is here too, for server code; a shared package imports\n * it from the root export.\n */\nexport const search = Object.freeze({ contract: contractHalf.contract, handlers });\n","// The JSON access list a `jsonAcl` policy reads, as the sharing kit reads and\n// rewrites it (RFC 0003 sections 4.2 and 12.3): `[{ userId, level }]`.\n//\n// - A column holding no list (`null`) is an empty list.\n// - A list the policy cannot fully read is malformed: not an array, or an\n// entry that is not an object with a non-empty `userId` and a known\n// `level`. The kit refuses to change a malformed list (`CONFLICT`) rather\n// than overwrite what the app stored there; the policy grants nothing from\n// it meanwhile.\n// - An entry may hold more keys than `userId` and `level` (an app's own\n// `addedAt`): the kit keeps them, and changes only the entries of the user\n// a call names.\n// - Several entries for one user count as their highest level, as the policy\n// reads them; a change to that user leaves one entry.\n\nimport { isAccessLevel, type ACE, type AccessLevel } from \"../../../contract/access\";\nimport { maxLevel } from \"../../access/levels\";\n\n/** One entry of a stored list, with whatever other keys the app keeps in it. */\nexport type StoredEntry = Readonly<Record<string, unknown>> & {\n readonly userId: string;\n readonly level: AccessLevel;\n};\n\nfunction isEntry(value: unknown): value is StoredEntry {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return false;\n }\n const { userId, level } = value as Readonly<Record<string, unknown>>;\n return typeof userId === \"string\" && userId.length > 0 && isAccessLevel(level);\n}\n\n/** The list a column holds, or `undefined` when it is malformed. */\nexport function parseList(value: unknown): readonly StoredEntry[] | undefined {\n if (value === null || value === undefined) {\n return [];\n }\n return Array.isArray(value) && value.every(isEntry) ? (value as StoredEntry[]) : undefined;\n}\n\n/** The level the list gives `userId`: the highest of their entries, or `null` without one. */\nexport function levelIn(entries: readonly StoredEntry[], userId: string): AccessLevel | null {\n return entries\n .filter((entry) => entry.userId === userId)\n .reduce<AccessLevel | null>((level, entry) => maxLevel(level, entry.level), null);\n}\n\n/** How many entries the list holds for `userId`. */\nexport function entriesOf(entries: readonly StoredEntry[], userId: string): number {\n return entries.filter((entry) => entry.userId === userId).length;\n}\n\n/**\n * The list as the kit reports it: one `{ userId, level }` per user, at the\n * level the list gives them, in the order each user first appears.\n */\nexport function sharesOf(entries: readonly StoredEntry[]): ACE[] {\n const levels = new Map<string, AccessLevel>();\n for (const entry of entries) {\n levels.set(entry.userId, maxLevel(levels.get(entry.userId), entry.level) ?? entry.level);\n }\n return [...levels].map(([userId, level]) => ({ userId, level }));\n}\n\n/**\n * The list with `userId` at `level`, or without them for `null`: their first\n * entry keeps its place and its other keys, their other entries go, and a\n * user without one gets a new entry at the end.\n */\nexport function withLevel(\n entries: readonly StoredEntry[],\n userId: string,\n level: AccessLevel | null,\n): StoredEntry[] {\n const kept: StoredEntry[] = [];\n let placed = false;\n for (const entry of entries) {\n if (entry.userId !== userId) {\n kept.push(entry);\n } else if (!placed && level !== null) {\n kept.push({ ...entry, level });\n placed = true;\n }\n }\n if (!placed && level !== null) {\n kept.push({ userId, level });\n }\n return kept;\n}\n\n/** True when someone has `Admin` on the row: the owner, or a user the list gives it. */\nexport function hasAdmin(entries: readonly StoredEntry[], owner: string | undefined): boolean {\n return owner !== undefined || entries.some((entry) => entry.level === \"Admin\");\n}\n","// Which access list or membership table the sharing kit changes (RFC 0003\n// sections 4.2 and 12.3): the one the service's own policy reads. A mode\n// `\"acl\"` method edits the list of the service's `jsonAcl` policy and a mode\n// `\"members\"` method the table of its `members` policy, alone or inside\n// `anyOf` (at any depth). The kit takes the column, model and role names\n// from that policy, never as options of its own, so the list it writes is\n// the one access is decided by. A service whose policy has none, or more\n// than one, cannot run the mode's methods: `defineService` refuses it.\n\nimport type { SharingMode } from \"../../../contract/kits/sharing\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { anyOfPolicies } from \"../../access/policies/anyOf\";\nimport { jsonAclColumnsOf, type JsonAclColumns } from \"../../access/policies/jsonAcl\";\nimport { membershipOf } from \"../../access/policies/members\";\nimport type { AnyAccessPolicy, MembershipRead } from \"../../access/policy\";\nimport type { AnyService } from \"../../service\";\n\n/** The policies `policy` is made of: itself, or each policy an `anyOf` combines, at any depth. */\nexport function policiesIn(policy: AnyAccessPolicy): readonly AnyAccessPolicy[] {\n const combined = anyOfPolicies(policy);\n return combined === undefined ? [policy] : combined.flatMap(policiesIn);\n}\n\n/** The distinct access lists the service's policy reads. */\nfunction listsOf(service: AnyService): JsonAclColumns[] {\n const policy = service.access;\n const found = policy === undefined ? [] : policiesIn(policy).map(jsonAclColumnsOf);\n return [...new Set(found)].filter((columns) => columns !== undefined);\n}\n\n/** The distinct membership tables the service's policy reads. */\nfunction tablesOf(service: AnyService): MembershipRead[] {\n const policy = service.access;\n const found = policy === undefined ? [] : policiesIn(policy).map(membershipOf);\n return [...new Set(found)].filter((read) => read !== undefined);\n}\n\nconst NEEDED: Readonly<Record<SharingMode, string>> = Object.freeze({\n acl: \"a jsonAcl(field) policy, whose access list they change\",\n members: \"a members({ model, entry, user, level }) policy, whose table they change\",\n});\n\n/** Why the service cannot run the sharing kit's methods of `mode`, or `undefined` when it can. */\nexport function policyProblem(service: AnyService, mode: SharingMode): string | undefined {\n const found = mode === \"acl\" ? listsOf(service) : tablesOf(service);\n if (found.length === 1) {\n return undefined;\n }\n const declared =\n service.access === undefined ? \"no access policy\" : `${service.access.kind}(...)`;\n if (found.length === 0) {\n return `the sharing kit's \"${mode}\" methods need ${NEEDED[mode]}, alone or inside anyOf; ${service.name} declares ${declared}`;\n }\n return `the sharing kit's \"${mode}\" methods need one ${mode === \"acl\" ? \"jsonAcl\" : \"members\"} policy to change, and ${service.name}'s has ${found.length}`;\n}\n\nfunction missing(service: AnyService, mode: SharingMode): never {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The sharing kit's \"${mode}\" methods run in ${service.name}, ${policyProblem(service, mode) ?? \"which they cannot use\"}`,\n );\n}\n\n/** The access list a mode `\"acl\"` method of the service changes. */\nexport function aclColumnsOf(service: AnyService): JsonAclColumns {\n const [columns, ...others] = listsOf(service);\n return columns !== undefined && others.length === 0 ? columns : missing(service, \"acl\");\n}\n\n/** The membership table a mode `\"members\"` method of the service changes. */\nexport function membershipTableOf(service: AnyService): MembershipRead {\n const [read, ...others] = tablesOf(service);\n return read !== undefined && others.length === 0 ? read : missing(service, \"members\");\n}\n","// The roles of the membership table a `members` policy reads (RFC 0003\n// section 4.2), as the sharing kit gives and reports them. With the policy's\n// `levels` (`{ owner: \"Admin\", editor: \"Moderate\", viewer: \"Read\" }`) the\n// roles are its keys; without it a stored role is a level name, and the kit\n// gives `Read`, `Moderate` or `Admin`. A role the policy cannot read is\n// refused (`VALIDATION`), since it would grant nothing. `invite` without a\n// role gives the lowest role that still lets the member read the row.\n\nimport { ACCESS_LEVELS, isAccessLevel, type AccessLevel } from \"../../../contract/access\";\nimport type { Member } from \"../../../contract/kits/sharingSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { maxLevel, meetsLevel } from \"../../access/levels\";\nimport type { MembershipRead } from \"../../access/policy\";\nimport type { Row } from \"../crud/runtime\";\n\n/** The level-named roles of a table without `levels`. */\nconst LEVEL_ROLES: readonly string[] = Object.freeze([\"Read\", \"Moderate\", \"Admin\"]);\n\n/** The roles a call may give. */\nexport function rolesOf(read: MembershipRead): readonly string[] {\n return read.levels === undefined ? LEVEL_ROLES : Object.keys(read.levels);\n}\n\n/** The level a stored role gives, as the policy reads it; `null` for a role it cannot read. */\nexport function levelOfRole(read: MembershipRead, role: unknown): AccessLevel | null {\n if (read.levels === undefined) {\n return isAccessLevel(role) ? role : null;\n }\n return typeof role === \"string\" && Object.hasOwn(read.levels, role)\n ? (read.levels[role] ?? null)\n : null;\n}\n\n/** The stored roles that give `Admin`. */\nexport function adminRolesOf(read: MembershipRead): string[] {\n return rolesOf(read).filter((role) => levelOfRole(read, role) === \"Admin\");\n}\n\n/** The role `invite` gives without one: the first role giving the lowest level from `Read` up. */\nfunction defaultRoleOf(read: MembershipRead): string | undefined {\n const rank = (role: string): number => ACCESS_LEVELS.indexOf(levelOfRole(read, role) ?? \"Public\");\n const readable = rolesOf(read).filter((role) => meetsLevel(levelOfRole(read, role), \"Read\"));\n return [...readable].sort((a, b) => rank(a) - rank(b))[0];\n}\n\nfunction invalidRole(message: string): QuickdrawError {\n return new QuickdrawError(\"VALIDATION\", message, { issues: [{ path: [\"role\"], message }] });\n}\n\n/** The role a call gives: `role`, or the default; `VALIDATION` for one the policy cannot read. */\nexport function checkRole(read: MembershipRead, role: string | undefined): string {\n const chosen = role ?? defaultRoleOf(read);\n if (chosen === undefined) {\n throw invalidRole(`Give a role: no role of ${read.model} lets a member read the row`);\n }\n const roles = rolesOf(read);\n if (!roles.includes(chosen)) {\n const known = roles.map((name) => `\"${name}\"`).join(\", \");\n throw invalidRole(`\"${chosen}\" is not a role of ${read.model}; the roles are ${known}`);\n }\n return chosen;\n}\n\nfunction textOf(value: unknown): string {\n return typeof value === \"string\" ? value : (JSON.stringify(value) ?? \"\");\n}\n\n/** A member as the kit returns it: their user id, their stored role, and the level it gives. */\nexport function memberOf(read: MembershipRead, userId: unknown, role: unknown): Member {\n return { userId: textOf(userId), role: textOf(role), level: levelOfRole(read, role) };\n}\n\n/** A member's role and level, from their rows: the row giving the highest level, as the policy reads it. */\nexport function currentRole(\n read: MembershipRead,\n rows: readonly Row[],\n): { readonly role: string; readonly level: AccessLevel | null } {\n let best: { role: string; level: AccessLevel | null } | undefined;\n for (const row of rows) {\n const level = levelOfRole(read, row[read.level]);\n if (best === undefined || (level !== null && maxLevel(best.level, level) !== best.level)) {\n best = { role: textOf(row[read.level]), level };\n }\n }\n return best ?? { role: \"\", level: null };\n}\n","// What every handler of the sharing kit starts from (RFC 0003 section 12.3):\n// the service its method runs in (found through the call's `ctx`, as the\n// read/write kit finds it), the caller, and the transaction a change runs\n// in. Every write goes through the dispatcher's tracked client, so the flush\n// evicts the access cache, revokes live subscriptions that lost access and\n// sends the `via` collection deltas; the kit sends nothing itself.\n//\n// A change reads the list or the members and writes them back in one\n// SERIALIZABLE transaction. PostgreSQL's default isolation (READ COMMITTED)\n// would let two changes that run at once both read the old list and the\n// second write drop the first (an unshare undone), or two Admin members each\n// see the other and both leave. Under SERIALIZABLE the database fails one of\n// them instead; the kit answers it `CONFLICT`, and the caller may try again.\n\nimport type { SharingChange, SharingOnChange } from \"./types\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { kitRuntimeOf, type KitRuntime } from \"../../context\";\nimport { checked } from \"../../devWarnings\";\nimport { modelKey } from \"../../storage\";\nimport type { Principal } from \"../../types\";\nimport type { KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport type { KitContext } from \"../crud/types\";\nimport { inKitTransaction } from \"../transactions\";\n\n/** One call of a sharing kit method: its service, the caller, and the database client. */\nexport interface SharingCall {\n readonly runtime: KitRuntime;\n /** The service's model, named as the client names it. */\n readonly model: string;\n readonly principal: Principal | null;\n /** The call's `ctx`, as `resolveUser` and `onChange` receive it. */\n readonly ctx: KitContext;\n /** The dispatcher's tracked database client. */\n readonly db: unknown;\n}\n\n/** The sharing kit call `ctx` belongs to. */\nexport function sharingCall(ctx: KitHandlerArgs[\"ctx\"], db: unknown): SharingCall {\n const runtime = kitRuntimeOf(ctx);\n const model = runtime?.service.model;\n if (runtime === undefined || model === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The sharing kit's handlers run through a dispatcher, in a service with a model\",\n );\n }\n return {\n runtime,\n model: modelKey(model),\n principal: ctx.principal,\n ctx: ctx as unknown as KitContext,\n db,\n };\n}\n\n/** The delegate of `model` on a database client or a transaction's client. */\nexport function tableOf(db: unknown, model: string): ModelDelegate {\n const name = modelKey(model);\n const isClient = (typeof db === \"object\" || typeof db === \"function\") && db !== null;\n const delegate: unknown = isClient ? Reflect.get(db, name) : undefined;\n const usable =\n typeof delegate === \"object\" &&\n delegate !== null &&\n typeof (delegate as { readonly findMany?: unknown }).findMany === \"function\";\n if (!usable) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The sharing kit reads and writes through db.${name}, which the dispatcher's database client does not have`,\n );\n }\n return delegate as ModelDelegate;\n}\n\n/**\n * Runs `fn` in a SERIALIZABLE interactive transaction of the database\n * client: its writes join the call's unit of work when it commits and are\n * dropped when it rolls back. A transaction the database fails for a\n * concurrent one is `CONFLICT`.\n */\nexport async function inSerializable<T>(db: unknown, fn: (tx: unknown) => Promise<T>): Promise<T> {\n return await inKitTransaction(db, fn, {\n owner: \"The sharing kit's changes\",\n conflict: \"Another change to this row's access ran at the same time; try again\",\n });\n}\n\n/** Tells the app's `onChange` about a change, inside its transaction (`tx`). */\nexport async function notifyChange(\n onChange: SharingOnChange | undefined,\n call: SharingCall,\n change: SharingChange,\n tx: unknown,\n): Promise<void> {\n if (onChange !== undefined) {\n await checked(() => onChange(Object.freeze(change), call.ctx, tx));\n }\n}\n","// Whether a row keeps an Admin through the service's other policies (RFC\n// 0003 sections 4.2 and 12.3). A change may not leave a row without an Admin\n// it had, and under `anyOf` an Admin can come from any of its policies: an\n// owner column (`owner`, or `jsonAcl`'s `owner`), an `Admin` entry of an\n// access list, or an `Admin` role in a membership table. So the owner of a\n// project whose policy is `anyOf(jsonAcl(\"acl\", { owner }), members(...))`\n// may remove its only Admin member: the row keeps the owner. The policy the\n// change edits counts its own Admins itself (`acl.ts`, `members.ts`); this\n// counts every other one. `inherit` and `resolver` policies are not counted:\n// their Admins are not the row's own.\n//\n// Statements, inside the change's transaction, and only when the edited\n// policy would be left without an Admin: one read of the row's owner and list\n// columns when the policy has any, then one per other membership table\n// unless the row named an Admin.\n\nimport { jsonAclColumnsOf, type JsonAclColumns } from \"../../access/policies/jsonAcl\";\nimport { membershipOf } from \"../../access/policies/members\";\nimport type { MembershipRead } from \"../../access/policy\";\nimport type { AnyService } from \"../../service\";\nimport { parseList } from \"./aclList\";\nimport { policiesIn } from \"./policy\";\nimport { adminRolesOf } from \"./roles\";\nimport { tableOf } from \"./runtime\";\n\n/** Where the service's other policies keep a row's Admins. */\ninterface AdminSources {\n /** Columns holding an owner's user id. */\n readonly owners: string[];\n /** Columns holding an access list. */\n readonly lists: string[];\n readonly tables: MembershipRead[];\n}\n\nfunction sourcesOf(service: AnyService, changing: JsonAclColumns | MembershipRead): AdminSources {\n const sources: AdminSources = { owners: [], lists: [], tables: [] };\n const policy = service.access;\n for (const one of policy === undefined ? [] : policiesIn(policy)) {\n const list = jsonAclColumnsOf(one);\n const table = membershipOf(one);\n if (list !== undefined && list !== changing) {\n sources.lists.push(list.field);\n sources.owners.push(...(list.owner === undefined ? [] : [list.owner]));\n } else if (table !== undefined && table !== changing) {\n sources.tables.push(table);\n } else if (one.kind === \"owner\") {\n sources.owners.push(...one.reads.columns);\n }\n }\n return sources;\n}\n\n/** True when the row's own columns name an Admin: an owner, or an `Admin` entry of a list. */\nasync function rowNamesAdmin(\n service: AnyService,\n tx: unknown,\n id: string,\n sources: AdminSources,\n): Promise<boolean> {\n const columns = [...sources.owners, ...sources.lists];\n if (columns.length === 0 || service.model === undefined) {\n return false;\n }\n const select = Object.fromEntries([[\"id\", true], ...columns.map((column) => [column, true])]);\n const row = await tableOf(tx, service.model).findUnique({ where: { id }, select });\n if (row === null) {\n return false;\n }\n const owned = sources.owners.some(\n (column) => typeof row[column] === \"string\" && row[column] !== \"\",\n );\n return (\n owned ||\n sources.lists.some((column) =>\n (parseList(row[column]) ?? []).some((entry) => entry.level === \"Admin\"),\n )\n );\n}\n\n/**\n * True when a policy of the service other than `changing` (the list or the\n * table the change edits) gives someone `Admin` on row `id`, read through\n * `tx`, the change's transaction.\n */\nexport async function adminElsewhere(\n service: AnyService,\n tx: unknown,\n id: string,\n changing: JsonAclColumns | MembershipRead,\n): Promise<boolean> {\n const sources = sourcesOf(service, changing);\n if (await rowNamesAdmin(service, tx, id, sources)) {\n return true;\n }\n const found = await Promise.all(\n sources.tables.map(async (table) => {\n const roles = adminRolesOf(table);\n return roles.length === 0\n ? null\n : await tableOf(tx, table.model).findFirst({\n where: { [table.entry]: id, [table.level]: { in: roles } },\n select: { id: true },\n });\n }),\n );\n return found.some((row) => row !== null);\n}\n","// The checks a sharing change makes inside its transaction (RFC 0003\n// sections 4 and 12.3): its caller, here, and whether the row keeps an Admin\n// (`admins.ts`, re-exported here). The pipeline authorized the call before\n// the transaction opened; a concurrent change (another Admin unsharing them)\n// may have lowered the caller's level since. So each change reads the\n// caller's own level on the row again as its first statement inside the\n// SERIALIZABLE transaction (the access engine's reads go through the\n// transaction's client there, and skip the cross-request cache), and:\n//\n// - refuses the change (`FORBIDDEN`) when that level no longer meets the\n// row-level half of the method's form (`{ entry: L }`; a `{ service: L }`\n// half passes on the caller's grant, which no row holds, and a form\n// without a row level, `\"authenticated\"` say, is not checked again);\n// - caps what the change gives: a caller never shares, sets or invites at a\n// level above their own on the row (`FORBIDDEN`), so a form lowered to\n// `{ entry: \"Moderate\" }` cannot hand out `Admin`;\n// - caps whom the change touches: a caller never replaces, lowers or takes\n// away the level of a user whose current level there is above their own\n// (`FORBIDDEN`; the 5.1 audit's SHARE-1). Equal passes, so one Admin\n// changes another. The current level is the one the list or table being\n// changed gives the user, which is all the change touches.\n//\n// The caller's own level is the policy's (a service-wide `Admin` grant with\n// `adminBypass` gives `Admin`), or their service-wide grant when the form\n// names `service` and the grant is higher: a grant counts where the form\n// names it (RFC 0003 section 4.1).\n\nimport type { AccessLevel } from \"../../../contract/access\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { isCustomAccess } from \"../../access/forms\";\nimport { maxLevel, meetsLevel, serviceGrant } from \"../../access/levels\";\nimport type { AccessForm } from \"../../access/types\";\nimport type { SharingCall } from \"./runtime\";\n\nexport { adminElsewhere } from \"./admins\";\n\n/** The levels of an object form's halves: its `service` and `entry` levels, when it names them. */\nfunction halvesOf(form: AccessForm): { service?: AccessLevel; entry?: AccessLevel } {\n return typeof form === \"object\" && !isCustomAccess(form)\n ? { service: form.service, entry: form.entry }\n : {};\n}\n\n/**\n * Reads the caller's own level on row `id` (call it inside the change's\n * transaction) and refuses the change unless it still meets the form's\n * row-level half; resolves with that level, to cap what the change gives.\n */\nexport async function checkCaller(\n call: SharingCall,\n form: AccessForm,\n id: string,\n): Promise<AccessLevel | null> {\n const { principal, runtime } = call;\n if (principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Authentication required\");\n }\n const levels = await runtime.access.levelsFor(runtime.service.name, principal, [id]);\n const policy = levels.get(id) ?? null;\n const halves = halvesOf(form);\n const grant = serviceGrant(principal, runtime.service.name) ?? null;\n const granted = halves.service !== undefined && meetsLevel(grant, halves.service);\n if (halves.entry !== undefined && !granted && !meetsLevel(policy, halves.entry)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `Your access to this ${call.model} changed while the change ran; you no longer have ${halves.entry} on it`,\n );\n }\n return halves.service === undefined ? policy : maxLevel(policy, grant);\n}\n\n/** `FORBIDDEN` when a change would give `given` above the caller's own level on the row. */\nexport function capGrant(own: AccessLevel | null, given: AccessLevel | null, model: string): void {\n if (given !== null && !meetsLevel(own, given)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `You cannot give ${given} on this ${model}: it is above your own level on it (${own ?? \"none\"})`,\n );\n }\n}\n\n/** `FORBIDDEN` when a change would replace, lower or take away `current`, a level above the caller's own on the row. */\nexport function capTarget(\n own: AccessLevel | null,\n current: AccessLevel | null,\n model: string,\n): void {\n if (current !== null && !meetsLevel(own, current)) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `That user has ${current} on this ${model}, above your own level on it (${own ?? \"none\"}); you cannot change or take away their access`,\n );\n }\n}\n","// What every sharing kit handler is made from: the hooks `sharing.handlers`\n// was given, and its method's access form. And the user a by-name method means (`shareByName`,\n// `inviteByName`): the app's `resolveUser` finds the one user the `name` or\n// `email` the call gave names, before the change's transaction opens; none,\n// or a name more than one user has (a resolver answers `null`), is\n// `NOT_FOUND`.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checked } from \"../../devWarnings\";\nimport type { SharingCall } from \"./runtime\";\nimport type { SharingOnChange, SharingResolveUser, SharingUserLookup } from \"./types\";\n\n/** The hooks a sharing kit handler calls, and the form its method runs under. */\nexport interface HandlerContext {\n readonly resolveUser: SharingResolveUser | undefined;\n readonly onChange: SharingOnChange | undefined;\n /** The method's access form: a change checks its caller against it again (`checks.ts`). */\n readonly form: AccessForm;\n}\n\n/** What a by-name call gave: a name, an email, or both. */\ninterface GivenLookup {\n readonly name: string | undefined;\n readonly email: string | undefined;\n}\n\n/** The one user id `resolveUser` finds for the call's `name` or `email`; `NOT_FOUND` when it finds none. */\nexport async function resolveTarget(\n call: SharingCall,\n context: HandlerContext,\n given: GivenLookup,\n): Promise<string> {\n if (context.resolveUser === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The sharing kit's by-name methods need sharing.handlers' resolveUser\",\n );\n }\n const lookup: SharingUserLookup = Object.freeze({\n ...(given.name === undefined ? {} : { name: given.name }),\n ...(given.email === undefined ? {} : { email: given.email }),\n });\n const { resolveUser } = context;\n const found: unknown = await checked(() => resolveUser(lookup, call.ctx, call.db));\n if (found === null || found === undefined) {\n throw new QuickdrawError(\"NOT_FOUND\", \"No such user\");\n }\n if (typeof found !== \"string\" || found.length === 0) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"sharing.handlers' resolveUser must return a user id, or null when there is no such user\",\n );\n }\n return found;\n}\n","// The sharing kit's access list methods (RFC 0003 section 12.3, mode\n// `\"acl\"`): `share`, `shareByName`, `unshare`, `setLevel` and `listShares`,\n// on the list of the service's `jsonAcl` policy (`aclList.ts`). A change\n// reads the row's list (and owner) and writes it back with\n// `db.<model>.update` in one SERIALIZABLE transaction (`runtime.ts`); the\n// tracked write evicts the cached access of the row and revokes the live\n// subscriptions that lost it. A change:\n//\n// - first reads the caller's own level on the row again, inside the\n// transaction: `FORBIDDEN` when it no longer meets the method's form,\n// when the change would give a level above it, or when the user's level\n// in the list is above it (`checks.ts`; equal passes);\n// - never touches the owner's access, which the owner column gives:\n// `CONFLICT`;\n// - never leaves a row without an Admin it had (no owner column, the last\n// `Admin` entry unshared or lowered, and no Admin from another policy of\n// an `anyOf`, `admins.ts`): `CONFLICT`;\n// - refuses a malformed list (`CONFLICT`), leaving it as it is;\n// - writes nothing when the user already has exactly that level.\n//\n// `share` adds the user or replaces their level, unless it is above the\n// caller's; `setLevel` and `unshare` need the user in the list\n// (`NOT_FOUND`). Each returns the list as `listShares` does:\n// `[{ userId, level }]`, one entry per user.\n//\n// Statements, inside the transaction: the caller's level (the policy's\n// reads; none with a service-wide `Admin` grant), one read of the row, then\n// (for a change) the tracked update, which reads the old access columns\n// first. `listShares` is one.\n\nimport type { ACE } from \"../../../contract/access\";\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type {\n ShareByNameQuery,\n ShareInput,\n ShareLevel,\n UnshareInput,\n} from \"../../../contract/kits/sharingSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { KitHandler, KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport {\n entriesOf,\n hasAdmin,\n levelIn,\n parseList,\n sharesOf,\n withLevel,\n type StoredEntry,\n} from \"./aclList\";\nimport { adminElsewhere, capGrant, capTarget, checkCaller } from \"./checks\";\nimport { resolveTarget, type HandlerContext } from \"./context\";\nimport { aclColumnsOf } from \"./policy\";\nimport { inSerializable, notifyChange, sharingCall, tableOf, type SharingCall } from \"./runtime\";\n\n/** The access list a mode `\"acl\"` method changes: its column, and its owner column. */\ntype JsonAclColumns = ReturnType<typeof aclColumnsOf>;\n\n/** One change to a row's access list. */\ninterface AclChange {\n readonly kind: \"share\" | \"unshare\" | \"setLevel\";\n readonly id: string;\n readonly userId: string;\n /** The level to give the user, or `null` to take theirs away. */\n readonly level: ShareLevel | null;\n /** Whether the list must already hold the user (`setLevel`, `unshare`). */\n readonly listed: boolean;\n}\n\n/** The row's list and owner. */\ninterface Listed {\n readonly entries: readonly StoredEntry[];\n /** The owner's user id, when the policy names an owner column and the row holds one. */\n readonly owner: string | undefined;\n}\n\nasync function readList(\n table: ModelDelegate,\n columns: JsonAclColumns,\n id: string,\n model: string,\n): Promise<Listed> {\n const select = {\n id: true,\n [columns.field]: true,\n ...(columns.owner === undefined ? {} : { [columns.owner]: true }),\n };\n const row = await table.findUnique({ where: { id }, select });\n if (row === null) {\n throw new QuickdrawError(\"NOT_FOUND\", `No such ${model}`);\n }\n const entries = parseList(row[columns.field]);\n if (entries === undefined) {\n throw new QuickdrawError(\n \"CONFLICT\",\n `The access list in ${model}.${columns.field} is malformed, so the sharing kit leaves it as it is: it must be a list of { userId, level }`,\n );\n }\n const owner = columns.owner === undefined ? undefined : row[columns.owner];\n return { entries, owner: typeof owner === \"string\" && owner.length > 0 ? owner : undefined };\n}\n\n/** Why `change` may not be made to `listed`, as the error to throw; `undefined` when it may. */\nfunction refusal(listed: Listed, change: AclChange, model: string): QuickdrawError | undefined {\n if (listed.owner === change.userId) {\n return new QuickdrawError(\n \"CONFLICT\",\n `That user owns this ${model}: an owner's access cannot be shared, changed or taken away`,\n );\n }\n if (change.listed && levelIn(listed.entries, change.userId) === null) {\n return new QuickdrawError(\"NOT_FOUND\", `This ${model} is not shared with that user`);\n }\n return undefined;\n}\n\n/**\n * `CONFLICT` when `change` takes away the row's last Admin: the list (and its\n * owner) had one and would have none, and no other policy of the service\n * gives one (`admins.ts`), read through `tx`.\n */\nasync function checkLastAdmin(\n call: SharingCall,\n tx: unknown,\n listed: Listed,\n change: AclChange,\n): Promise<void> {\n const next = withLevel(listed.entries, change.userId, change.level);\n const losing = hasAdmin(listed.entries, listed.owner) && !hasAdmin(next, listed.owner);\n const { service } = call.runtime;\n if (losing && !(await adminElsewhere(service, tx, change.id, aclColumnsOf(service)))) {\n throw new QuickdrawError(\n \"CONFLICT\",\n `That user is the last Admin of this ${call.model}; give someone else Admin first`,\n );\n }\n}\n\n/** Makes `change` to the row's list, and returns the list as it is afterwards. */\nasync function changeList(\n call: SharingCall,\n context: HandlerContext,\n change: AclChange,\n): Promise<ACE[]> {\n const columns = aclColumnsOf(call.runtime.service);\n return await inSerializable(call.db, async (tx) => {\n const own = await checkCaller(call, context.form, change.id);\n capGrant(own, change.level, call.model);\n const table = tableOf(tx, call.model);\n const listed = await readList(table, columns, change.id, call.model);\n const problem = refusal(listed, change, call.model);\n if (problem !== undefined) {\n throw problem;\n }\n const before = levelIn(listed.entries, change.userId);\n capTarget(own, before, call.model);\n await checkLastAdmin(call, tx, listed, change);\n if (before === change.level && entriesOf(listed.entries, change.userId) === 1) {\n return sharesOf(listed.entries);\n }\n const next = withLevel(listed.entries, change.userId, change.level);\n await table.update({\n where: { id: change.id },\n data: { [columns.field]: next },\n select: { id: true },\n });\n const { kind, id, userId, level } = change;\n await notifyChange(context.onChange, call, { kind, id, userId, before, after: level }, tx);\n return sharesOf(next);\n });\n}\n\n/** The `share` handler: gives the user the level, whatever they had. */\nexport function shareHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, userId, level } = input as ShareInput;\n const change = { kind: \"share\", id, userId, level, listed: false } as const;\n return await changeList(sharingCall(ctx, db), context, change);\n };\n return handler as KitHandler;\n}\n\n/** The `shareByName` handler: `share`, for the user `resolveUser` finds. */\nexport function shareByNameHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, name, email, level } = input as ShareByNameQuery;\n const call = sharingCall(ctx, db);\n const userId = await resolveTarget(call, context, { name, email });\n return await changeList(call, context, { kind: \"share\", id, userId, level, listed: false });\n };\n return handler as KitHandler;\n}\n\n/** The `setLevel` handler: changes the level of a user the list holds. */\nexport function setLevelHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, userId, level } = input as ShareInput;\n const change = { kind: \"setLevel\", id, userId, level, listed: true } as const;\n return await changeList(sharingCall(ctx, db), context, change);\n };\n return handler as KitHandler;\n}\n\n/** The `unshare` handler: takes the user's entries out of the list. */\nexport function unshareHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const { id, userId } = input as UnshareInput;\n const change = { kind: \"unshare\", id, userId, level: null, listed: true } as const;\n return await changeList(sharingCall(ctx, db), context, change);\n };\n return handler as KitHandler;\n}\n\n/** The `listShares` handler: the row's list, one entry per user. */\nexport function listSharesHandler(): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<ACE[]> => {\n const call = sharingCall(ctx, db);\n const columns = aclColumnsOf(call.runtime.service);\n const table = tableOf(call.db, call.model);\n const { id } = input as IdInput;\n return sharesOf((await readList(table, columns, id, call.model)).entries);\n };\n return handler as KitHandler;\n}\n","// The sharing kit's `listMembers` (RFC 0003 section 12.3): one page of a\n// row's members from the table of the service's `members` policy, each as\n// `{ userId, role, level }`, by the read/write kit's keyset page\n// (`kits/crud/page.ts`). Members come in user id order (then the membership\n// row's id), so a page boundary stays put when members join or leave before\n// it; the kit knows no other column of the table to order by. One statement.\n\nimport type { OrderBy } from \"../../../contract/collections\";\nimport type { ListMembersQuery, MembersPage } from \"../../../contract/kits/sharingSchemas\";\nimport { modelKey } from \"../../storage\";\nimport { readPage } from \"../crud/page\";\nimport type { KitHandler, KitHandlerArgs } from \"../crud/runtime\";\nimport { membershipTableOf } from \"./policy\";\nimport { memberOf } from \"./roles\";\nimport { sharingCall, tableOf } from \"./runtime\";\n\n/** The `listMembers` handler. */\nexport function listMembersHandler(): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<MembersPage> => {\n const call = sharingCall(ctx, db);\n const read = membershipTableOf(call.runtime.service);\n const query = input as ListMembersQuery;\n const order: OrderBy = [\n [read.user, \"asc\"],\n [\"id\", \"asc\"],\n ];\n const page = await readPage({\n table: tableOf(call.db, read.model),\n model: modelKey(read.model),\n storage: call.runtime.storage,\n where: { [read.entry]: query.entryId },\n order,\n cursor: query.cursor,\n limit: query.limit,\n select: { id: true, [read.user]: true, [read.level]: true },\n totalCount: false,\n filtered: false,\n });\n return {\n items: page.rows.map((row) => memberOf(read, row[read.user], row[read.level])),\n nextCursor: page.nextCursor,\n };\n };\n return handler as KitHandler;\n}\n","// The sharing kit's membership methods (RFC 0003 section 12.3, mode\n// `\"members\"`): `invite`, `inviteByName`, `remove`, `leave` and `setRole`,\n// on the table of the service's `members` policy. Each change creates,\n// updates or deletes membership rows through the tracked client, in one\n// SERIALIZABLE transaction (`runtime.ts`): the flush evicts the member's\n// cached level, revokes the live subscriptions they lost, and sends the\n// `via` collections over the table `added` or `removed`.\n//\n// - `invite` refuses a user who is a member already (`CONFLICT`; `setRole`\n// changes a role) and gives the lowest readable role when none is given.\n// An invitee the database does not know (a foreign key) is `NOT_FOUND`.\n// - `remove` and `setRole` need the user to be a member (`NOT_FOUND`);\n// `leave` is for members only (`FORBIDDEN` for anyone else).\n// - Each change but `leave` first reads the caller's own level on the row\n// again, inside the transaction: `FORBIDDEN` when it no longer meets the\n// method's form, when `invite` or `setRole` would give a role whose level\n// is above it, or when `remove` or `setRole` would touch a member whose\n// role's level is above it (`checks.ts`; equal passes).\n// - The last Admin of a row cannot leave, be removed or lose Admin\n// (`CONFLICT`): whether someone else keeps Admin is read in the same\n// transaction as the change. Under `anyOf` every policy counts: another\n// Admin member, an owner column, an `Admin` entry of an access list\n// (`admins.ts`), so a project's owner may remove its only Admin member.\n//\n// Statements, inside the transaction: one read of the member's rows (of\n// whether they are one, for `invite`), one more for whether another member\n// has Admin when the change takes Admin away, and the write (a tracked\n// `create` or `delete` is one; `setRole`'s `updateMany` reads the old roles\n// first: two).\n\nimport type {\n InviteByNameQuery,\n InviteQuery,\n LeaveInput,\n Member,\n MemberInput,\n SetRoleInput,\n} from \"../../../contract/kits/sharingSchemas\";\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport type { MembershipRead } from \"../../access/policy\";\nimport type { KitHandler, KitHandlerArgs, ModelDelegate, Row } from \"../crud/runtime\";\nimport { adminElsewhere, capGrant, capTarget, checkCaller } from \"./checks\";\nimport { resolveTarget, type HandlerContext } from \"./context\";\nimport { membershipTableOf } from \"./policy\";\nimport { adminRolesOf, checkRole, currentRole, levelOfRole, memberOf } from \"./roles\";\nimport { inSerializable, notifyChange, sharingCall, tableOf, type SharingCall } from \"./runtime\";\n\n/** Whom a membership change is about. */\ninterface Target {\n readonly entryId: string;\n readonly userId: string;\n}\n\nasync function rowsOf(table: ModelDelegate, read: MembershipRead, target: Target): Promise<Row[]> {\n return await table.findMany({\n where: { [read.entry]: target.entryId, [read.user]: target.userId },\n select: { id: true, [read.level]: true },\n });\n}\n\n/**\n * True when someone other than the target keeps `Admin` on the row: another\n * member of this table, or, under `anyOf`, an owner column, an access list\n * or another table (`admins.ts`), read through `tx`.\n */\nasync function anotherAdmin(\n call: SharingCall,\n tx: unknown,\n read: MembershipRead,\n target: Target,\n): Promise<boolean> {\n const roles = adminRolesOf(read);\n const found =\n roles.length === 0\n ? null\n : await tableOf(tx, read.model).findFirst({\n where: {\n [read.entry]: target.entryId,\n [read.user]: { not: target.userId },\n [read.level]: { in: roles },\n },\n select: { id: true },\n });\n return found !== null || (await adminElsewhere(call.runtime.service, tx, target.entryId, read));\n}\n\nfunction lastAdmin(model: string): QuickdrawError {\n return new QuickdrawError(\n \"CONFLICT\",\n `That user is the last Admin member of this ${model}; make another member Admin first`,\n );\n}\n\nfunction isForeignKeyFailure(error: unknown): boolean {\n return (\n error instanceof Error &&\n error.name === \"PrismaClientKnownRequestError\" &&\n (error as Error & { readonly code?: unknown }).code === \"P2003\"\n );\n}\n\n/** Makes the target a member with `role`. */\nasync function invite(\n call: SharingCall,\n context: HandlerContext,\n target: Target,\n role: string | undefined,\n): Promise<Member> {\n const read = membershipTableOf(call.runtime.service);\n const given = checkRole(read, role);\n return await inSerializable(call.db, async (tx) => {\n const own = await checkCaller(call, context.form, target.entryId);\n capGrant(own, levelOfRole(read, given), call.model);\n const table = tableOf(tx, read.model);\n if ((await rowsOf(table, read, target)).length > 0) {\n throw new QuickdrawError(\n \"CONFLICT\",\n `That user is a member of this ${call.model} already; setRole changes a member's role`,\n );\n }\n try {\n await table.create({\n data: { [read.entry]: target.entryId, [read.user]: target.userId, [read.level]: given },\n select: { id: true },\n });\n } catch (error) {\n if (!isForeignKeyFailure(error)) {\n throw error;\n }\n const missing = new QuickdrawError(\"NOT_FOUND\", `No such user, or no such ${call.model}`);\n missing.cause = error;\n throw missing;\n }\n const { entryId: id, userId } = target;\n const change = { kind: \"invite\", id, userId, before: null, after: given } as const;\n await notifyChange(context.onChange, call, change, tx);\n return memberOf(read, userId, given);\n });\n}\n\n/** Ends the target's membership: `remove` by an Admin, or `leave` by the member. */\nasync function end(\n call: SharingCall,\n context: HandlerContext,\n target: Target,\n kind: \"remove\" | \"leave\",\n): Promise<null> {\n const read = membershipTableOf(call.runtime.service);\n return await inSerializable(call.db, async (tx) => {\n const own =\n kind === \"remove\" ? await checkCaller(call, context.form, target.entryId) : undefined;\n const table = tableOf(tx, read.model);\n const rows = await rowsOf(table, read, target);\n if (rows.length === 0) {\n throw kind === \"leave\"\n ? new QuickdrawError(\"FORBIDDEN\", `You are not a member of this ${call.model}`)\n : new QuickdrawError(\"NOT_FOUND\", `That user is not a member of this ${call.model}`);\n }\n const current = currentRole(read, rows);\n if (own !== undefined) {\n capTarget(own, current.level, call.model);\n }\n if (current.level === \"Admin\" && !(await anotherAdmin(call, tx, read, target))) {\n throw lastAdmin(call.model);\n }\n const [only, ...more] = rows.map((row) => row.id);\n await (only !== undefined && more.length === 0\n ? table.delete({ where: { id: only }, select: { id: true } })\n : table.deleteMany({ where: { id: { in: [only, ...more] } } }));\n const change = { kind, id: target.entryId, userId: target.userId, after: null };\n await notifyChange(context.onChange, call, { ...change, before: current.role }, tx);\n return null;\n });\n}\n\n/** Gives the target member `role`. */\nasync function changeRole(\n call: SharingCall,\n context: HandlerContext,\n target: Target,\n role: string,\n): Promise<Member> {\n const read = membershipTableOf(call.runtime.service);\n checkRole(read, role);\n return await inSerializable(call.db, async (tx) => {\n const own = await checkCaller(call, context.form, target.entryId);\n capGrant(own, levelOfRole(read, role), call.model);\n const table = tableOf(tx, read.model);\n const rows = await rowsOf(table, read, target);\n if (rows.length === 0) {\n throw new QuickdrawError(\"NOT_FOUND\", `That user is not a member of this ${call.model}`);\n }\n const current = currentRole(read, rows);\n capTarget(own, current.level, call.model);\n if (rows.length === 1 && current.role === role) {\n return memberOf(read, target.userId, role);\n }\n const demoted = current.level === \"Admin\" && levelOfRole(read, role) !== \"Admin\";\n if (demoted && !(await anotherAdmin(call, tx, read, target))) {\n throw lastAdmin(call.model);\n }\n await table.updateMany({\n where: { [read.entry]: target.entryId, [read.user]: target.userId },\n data: { [read.level]: role },\n });\n const { entryId: id, userId } = target;\n const change = { kind: \"setRole\", id, userId, before: current.role, after: role } as const;\n await notifyChange(context.onChange, call, change, tx);\n return memberOf(read, userId, role);\n });\n}\n\n/** The `invite` handler. */\nexport function inviteHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Member> => {\n const { entryId, userId, role } = input as InviteQuery;\n return await invite(sharingCall(ctx, db), context, { entryId, userId }, role);\n };\n return handler as KitHandler;\n}\n\n/** The `inviteByName` handler: `invite`, for the user `resolveUser` finds. */\nexport function inviteByNameHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Member> => {\n const { entryId, name, email, role } = input as InviteByNameQuery;\n const call = sharingCall(ctx, db);\n const userId = await resolveTarget(call, context, { name, email });\n return await invite(call, context, { entryId, userId }, role);\n };\n return handler as KitHandler;\n}\n\n/** The `remove` handler. */\nexport function removeHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<null> => {\n const { entryId, userId } = input as MemberInput;\n return await end(sharingCall(ctx, db), context, { entryId, userId }, \"remove\");\n };\n return handler as KitHandler;\n}\n\n/** The `leave` handler: the caller ends their own membership. */\nexport function leaveHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<null> => {\n const call = sharingCall(ctx, db);\n if (call.principal === null) {\n throw new QuickdrawError(\"UNAUTHENTICATED\", \"Sign in to leave\");\n }\n const { entryId } = input as LeaveInput;\n return await end(call, context, { entryId, userId: call.principal.userId }, \"leave\");\n };\n return handler as KitHandler;\n}\n\n/** The `setRole` handler. */\nexport function setRoleHandler(context: HandlerContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<Member> => {\n const { entryId, userId, role } = input as SetRoleInput;\n return await changeRole(sharingCall(ctx, db), context, { entryId, userId }, role);\n };\n return handler as KitHandler;\n}\n","// The handler of each sharing kit method (RFC 0003 section 12.3), and the\n// access form each runs under unless `sharing.handlers` is given another: a\n// change needs `Admin` on the row, a list `Read`, and `leave` a signed-in\n// caller (the handler then checks they are a member). The forms name the row\n// by the input key each mode uses: `id`, or `entryId`.\n\nimport type { SharingMethodName } from \"../../../contract/kits/sharing\";\nimport type { AccessForm } from \"../../access/types\";\nimport type { KitHandler } from \"../crud/runtime\";\nimport {\n listSharesHandler,\n setLevelHandler,\n shareByNameHandler,\n shareHandler,\n unshareHandler,\n} from \"./acl\";\nimport type { HandlerContext } from \"./context\";\nimport { listMembersHandler } from \"./listMembers\";\nimport {\n inviteByNameHandler,\n inviteHandler,\n leaveHandler,\n removeHandler,\n setRoleHandler,\n} from \"./members\";\n\nconst ADMIN_ROW: AccessForm = Object.freeze({ entry: \"Admin\" });\nconst ADMIN_ENTRY: AccessForm = Object.freeze({ entry: \"Admin\", id: \"entryId\" });\nconst READ_ROW: AccessForm = Object.freeze({ entry: \"Read\" });\nconst READ_ENTRY: AccessForm = Object.freeze({ entry: \"Read\", id: \"entryId\" });\n\n/** The form each sharing kit method runs under when `access` gives none. */\nexport const DEFAULT_ACCESS: Readonly<Record<SharingMethodName, AccessForm>> = Object.freeze({\n share: ADMIN_ROW,\n shareByName: ADMIN_ROW,\n unshare: ADMIN_ROW,\n setLevel: ADMIN_ROW,\n listShares: READ_ROW,\n invite: ADMIN_ENTRY,\n inviteByName: ADMIN_ENTRY,\n remove: ADMIN_ENTRY,\n setRole: ADMIN_ENTRY,\n listMembers: READ_ENTRY,\n leave: \"authenticated\",\n});\n\nconst MAKERS: Readonly<Record<SharingMethodName, (context: HandlerContext) => KitHandler>> =\n Object.freeze({\n share: shareHandler,\n shareByName: shareByNameHandler,\n unshare: unshareHandler,\n setLevel: setLevelHandler,\n listShares: listSharesHandler,\n invite: inviteHandler,\n inviteByName: inviteByNameHandler,\n remove: removeHandler,\n leave: leaveHandler,\n setRole: setRoleHandler,\n listMembers: listMembersHandler,\n });\n\n/** The handler of one sharing kit method: a new function for each, which `defineService` checks. */\nexport function handlerOf(method: SharingMethodName, context: HandlerContext): KitHandler {\n return MAKERS[method](context);\n}\n","// `sharing.handlers(contract, { access?, resolveUser?, onChange?, rowless? })`\n// (RFC 0003 section 12.3): the sharing and membership kit's server half. It finds\n// the methods `sharing.contract` made in the contract and returns an\n// implementation of each, to spread into `defineService`'s `methods`:\n//\n// export const projectService = qd.defineService(project, {\n// model: \"project\",\n// access: anyOf(jsonAcl(\"acl\", { owner: \"ownerId\" }), members({ ... })),\n// methods: { ...sharing.handlers(project) },\n// });\n//\n// Each method runs under the kit's default form (a change needs `Admin` on\n// the row, a list `Read`, `leave` a signed-in member) unless `access` gives\n// another. The kit changes the access list or membership table the service's\n// own policy reads, so `defineService` refuses a service whose policy has\n// none for a mode the contract uses (`policy.ts`), or that has no model. An\n// access-list method (its input names the row as `id`) given a form that\n// asks the policy nothing about that row (`\"authenticated\"`, `custom`, say)\n// must be named in `rowless`.\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport {\n sharing as contractHalf,\n sharingSpecOf,\n type SharingMode,\n type SharingSpec,\n} from \"../../../contract/kits/sharing\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport { checkWhenDefined, dependsOnCaller, type AnyService } from \"../../service\";\nimport { kitEntry, rowlessMethods } from \"../rowless\";\nimport type { HandlerContext } from \"./context\";\nimport { DEFAULT_ACCESS, handlerOf } from \"./methods\";\nimport { policyProblem } from \"./policy\";\nimport type {\n SharingAccess,\n SharingContract,\n SharingImplementations,\n SharingOptionsArgs,\n} from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\ntype Empty = Record<never, never>;\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`sharing.handlers: ${message}`);\n}\n\n/** The sharing kit's methods in the contract, with what each was made for; at least one. */\nfunction kitMethods(contract: unknown): [string, SharingSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, SharingSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = sharingSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n if (found.length === 0) {\n fail(`${String(contract.name)} has no method sharing.contract made`);\n }\n return found;\n}\n\n/** The forms `access` gives, each for one of the kit's methods. */\nfunction checkAccess(access: unknown, names: readonly string[]): UnknownRecord {\n if (access === undefined) {\n return {};\n }\n if (!isRecord(access)) {\n fail(\"access must map the kit's methods to access forms\");\n }\n for (const [name, form] of Object.entries(access)) {\n if (!names.includes(name)) {\n fail(`access names \"${name}\", which is not a method sharing.contract made`);\n }\n const problem = form === undefined ? undefined : accessFormProblem(form);\n if (problem !== undefined) {\n fail(`access for \"${name}\" ${problem}`);\n }\n }\n return access;\n}\n\n/** `resolveUser` and `onChange`: functions, and `resolveUser` exactly when a by-name method needs it. */\nfunction checkHooks(\n options: UnknownRecord,\n kit: readonly [string, SharingSpec][],\n): Omit<HandlerContext, \"form\"> {\n const { resolveUser, onChange } = options;\n const byName = kit.some(([, spec]) => [\"shareByName\", \"inviteByName\"].includes(spec.method));\n if (byName && typeof resolveUser !== \"function\") {\n fail(\"shareByName and inviteByName find their user with resolveUser: give it\");\n }\n if (!byName && resolveUser !== undefined) {\n fail(\"resolveUser is for shareByName and inviteByName, which the contract does not have\");\n }\n if (onChange !== undefined && typeof onChange !== \"function\") {\n fail(\"onChange must be a function of (change, ctx, db)\");\n }\n return {\n resolveUser: resolveUser as HandlerContext[\"resolveUser\"],\n onChange: onChange as HandlerContext[\"onChange\"],\n };\n}\n\nfunction checkOptions(options: unknown): UnknownRecord {\n if (options === undefined) {\n return {};\n }\n if (!isRecord(options)) {\n fail(\"options must be { access?, resolveUser?, onChange?, rowless? }\");\n }\n const allowed = [\"access\", \"resolveUser\", \"onChange\", \"rowless\"];\n const unknownKey = Object.keys(options).find((key) => !allowed.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${allowed.join(\", \")}`);\n }\n return options;\n}\n\n/** Why a service cannot run the sharing kit's handlers of `mode` made for `contract`. */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n mode: SharingMode,\n): string | undefined {\n if (service.contract !== contract) {\n return `its sharing kit handlers were made for another contract; pass ${service.name}'s own contract to sharing.handlers`;\n }\n if (service.model === undefined) {\n return \"the sharing kit changes who may see the service's rows: declare its model\";\n }\n return policyProblem(service, mode);\n}\n\nfunction handlers<C extends AnyContract, const A extends SharingAccess<C> = Empty, Db = unknown>(\n contract: C & NoInfer<SharingContract<C>>,\n ...rest: SharingOptionsArgs<C, A, Db>\n): SharingImplementations<C, A, Db> {\n const kit = kitMethods(contract);\n const options = checkOptions(rest[0]);\n const names = kit.map(([name]) => name);\n const access = checkAccess(options.access, names);\n const rowless = rowlessMethods(options.rowless, names, fail);\n const hooks = checkHooks(options, kit);\n const entries: Record<string, object> = {};\n for (const [name, spec] of kit) {\n const form = (access[name] as AccessForm | undefined) ?? DEFAULT_ACCESS[spec.method];\n const handler = handlerOf(spec.method, Object.freeze({ ...hooks, form }));\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, spec.mode));\n if (spec.method === \"listShares\" || spec.method === \"listMembers\") {\n // Input-only today; marked so a run shared across principals never can leak a list.\n dependsOnCaller(handler);\n }\n entries[name] = kitEntry(name, form, handler, rowless);\n }\n return Object.freeze(entries) as SharingImplementations<C, A, Db>;\n}\n\n/**\n * The sharing and membership kit: `sharing.handlers(contract, { access?,\n * resolveUser?, onChange?, rowless? })` implements the methods\n * `sharing.contract` made in `contract`. `sharing.contract` is here too, for server code; a shared\n * package imports it from the root export.\n */\nexport const sharing = Object.freeze({ contract: contractHalf.contract, handlers });\n","// What `adminMeta` answers (RFC 0003 section 12.4), worked out once when the\n// handlers are made: the entity's fields as the contract half read them from\n// its JSON Schema (`contract/kits/adminFields.ts`), configured for an admin\n// screen as 4.1's `zodToAdminFields` configured them\n// (4.1 `src/server/utils/zodToAdminFields.ts:138-265`):\n//\n// - hidden fields are left out: 4.1's `acl`, `serviceAccess` and\n// `service_access`, the column `auth.serviceAccessSource` names on the\n// service's model whatever its name (`grantsColumn`; the 5.1 audit's\n// ADMIN-2), and those `hiddenFields` names; `grants: true` shows and\n// writes the entity's grants field instead (`serviceAccess`,\n// `service_access` or that column), for callers with a service-wide\n// `Admin` grant only (`runtime.ts`), marked `kind: \"grants\"` so a screen\n// with a grants editor of its own finds it without its name (finding F5.5\n// of the quickdraw-chat migration). The column is known only to the\n// server, so the handlers work their fields out once per column\n// (`handlers.ts`), and the dispatcher checks them when it is made;\n// - `id`, `createdAt` and `updatedAt` come first with 4.1's fixed\n// configurations (\"ID\", \"Created At\", \"Updated At\"; `updatedAt` stays out\n// of the table), then the other fields in the schema's order;\n// - a label is the field's name in words (`assigneeId` is \"Assignee Id\");\n// - `id` and the timestamps are not editable; JSON fields stay out of the\n// table;\n// - `sortable` and `filterable` are the fields the contract declares for\n// `adminList`. 4.1 marked every field but JSON ones sortable, and sorted by\n// whatever a caller sent;\n// - `fieldOverrides` changes the rest, but cannot make `id` or a timestamp\n// editable; `showInForm: false` keeps a field out of a generic form;\n// - `editable` (finding R1.4 of the 5.0.0 review), or the list\n// `admin.contract` was given, names the only fields that are editable:\n// every other field is not, before the kit's writes are told which fields\n// they refuse, so `adminMeta`, a generic form and the writes agree. An\n// override may not say otherwise about a field it names or leaves out.\n//\n// It also says which fields the kit's writes refuse: the hidden ones and\n// those that are not editable.\n\nimport {\n ADMIN_FIELD_TYPES,\n ADMIN_NEVER_WRITABLE,\n type AdminEntityField,\n type AdminFieldConfig,\n type AdminServiceMeta,\n} from \"../../../contract/kits/adminFields\";\nimport type { AdminSpec } from \"../../../contract/kits/admin\";\nimport { modelKey } from \"../../storage\";\n\n/** Fields 4.1 always hid from admin screens (4.1 `src/server/utils/zodToAdminFields.ts:12`). */\nexport const ADMIN_HIDDEN_FIELDS: readonly string[] = Object.freeze([\n \"acl\",\n \"serviceAccess\",\n \"service_access\",\n]);\n\n/**\n * The fields a user's service-wide grants live in, besides the column\n * `auth.serviceAccessSource` names on the service's model. Hidden unless\n * `admin.handlers(contract, { grants: true })`; then shown and written, but\n * only to callers whose own service-wide grant on the service is `Admin`.\n */\nexport const ADMIN_GRANT_FIELDS: readonly string[] = Object.freeze([\n \"serviceAccess\",\n \"service_access\",\n]);\n\n/** The keys `fieldOverrides` may set. */\nconst OVERRIDE_KEYS: readonly string[] = Object.freeze([\n \"type\",\n \"label\",\n \"required\",\n \"editable\",\n \"showInTable\",\n \"showInForm\",\n \"enumValues\",\n \"relationService\",\n]);\n\n/** 4.1's configurations of the row's key and timestamps (`zodToAdminFields.ts:217-247`). */\nconst DEFAULT_FIELDS: Readonly<Record<string, Omit<AdminFieldConfig, \"sortable\" | \"filterable\">>> =\n Object.freeze({\n id: {\n name: \"id\",\n type: \"string\",\n label: \"ID\",\n required: true,\n editable: false,\n showInTable: true,\n },\n createdAt: {\n name: \"createdAt\",\n type: \"date\",\n label: \"Created At\",\n required: true,\n editable: false,\n showInTable: true,\n },\n updatedAt: {\n name: \"updatedAt\",\n type: \"date\",\n label: \"Updated At\",\n required: true,\n editable: false,\n showInTable: false,\n },\n });\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\n/** Fails the handlers being made, with a message. */\nexport type MetaFailure = (message: string) => never;\n\n/** What the handlers' options say about the entity's fields, checked. */\nexport interface MetaOptions {\n readonly displayName: unknown;\n readonly hiddenFields: unknown;\n readonly editable?: unknown;\n readonly fieldOverrides: unknown;\n readonly grants?: unknown;\n /** The column `auth.serviceAccessSource` names on the service's model: a grants field whatever its name. */\n readonly grantsColumn?: string;\n}\n\n/** The names a grants field may have: `ADMIN_GRANT_FIELDS`, and the server's grants column. */\nfunction grantNamesOf(column: string | undefined): readonly string[] {\n return column === undefined || ADMIN_GRANT_FIELDS.includes(column)\n ? ADMIN_GRANT_FIELDS\n : [...ADMIN_GRANT_FIELDS, column];\n}\n\n/**\n * The column `auth.serviceAccessSource` (`source`) names when its model is\n * `model`, the service's: the admin kit's grants field there.\n */\nexport function grantsColumnFor(\n model: string | undefined,\n source: { readonly model: string; readonly column: string } | undefined,\n): string | undefined {\n const same = model !== undefined && source !== undefined;\n return same && modelKey(source.model) === modelKey(model) ? source.column : undefined;\n}\n\n/** `adminMeta`'s answer, and the fields the kit's reads and writes leave alone. */\nexport interface AdminFields {\n readonly meta: AdminServiceMeta;\n /** The fields the kit leaves out of every row and refuses to write. */\n readonly hidden: ReadonlySet<string>;\n /**\n * The fields shown but not written: `id`, the timestamps, those an\n * override made read-only, and those `editable` leaves out.\n */\n readonly readOnly: ReadonlySet<string>;\n /**\n * With `grants: true`, the grant fields the kit shows and writes: only for\n * callers whose service-wide grant on the service is `Admin`. Empty\n * otherwise (they are hidden).\n */\n readonly grants: ReadonlySet<string>;\n /**\n * The fields an `editable` list (either half) or a `fieldOverrides` entry\n * with `editable: true` names: none may be a relation of the service's\n * model, which `admin.handlers` checks once the service is defined.\n */\n readonly named: ReadonlySet<string>;\n}\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** A field's name in words: \"createdAt\" is \"Created At\", \"user_id\" is \"User Id\" (4.1's `toLabel`). */\nexport function labelOf(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (letter) => letter.toUpperCase());\n}\n\n/** A service's name for people: \"taskService\" is \"Tasks\" (4.1's `toDisplayName`). */\nexport function displayNameOf(serviceName: string): string {\n const words = serviceName\n .replace(/Service$/i, \"\")\n .replace(/([a-z])([A-Z])/g, \"$1 $2\")\n .replace(/^./, (letter) => letter.toUpperCase());\n return `${words}s`;\n}\n\nfunction checkDisplayName(displayName: unknown, serviceName: string, fail: MetaFailure): string {\n if (displayName === undefined) {\n return displayNameOf(serviceName);\n }\n if (typeof displayName !== \"string\" || displayName.length === 0) {\n fail(\"displayName must be a non-empty string\");\n }\n return displayName;\n}\n\n/**\n * The grant fields `grants: true` shows: those of the entity's fields named\n * `grantNames`, possibly none (the dispatcher refuses that, once it knows\n * the server's grants column: `handlers.ts`).\n */\nfunction checkGrants(\n grants: unknown,\n [names, grantNames]: readonly [readonly string[], readonly string[]],\n fail: MetaFailure,\n): ReadonlySet<string> {\n if (grants === undefined || grants === false) {\n return new Set();\n }\n if (grants !== true) {\n fail(\"grants must be true or false\");\n }\n return new Set(grantNames.filter((name) => names.includes(name)));\n}\n\n/**\n * The fields hidden: 4.1's defaults and the server's grants column but the\n * grant fields `grants: true` shows, and `hiddenFields`, which must name\n * fields of the entity but `id`.\n */\nfunction checkHidden(\n hiddenFields: unknown,\n [names, grantNames]: readonly [readonly string[], readonly string[]],\n grants: ReadonlySet<string>,\n fail: MetaFailure,\n): ReadonlySet<string> {\n const defaults = [...new Set([...ADMIN_HIDDEN_FIELDS, ...grantNames])].filter(\n (name) => !grants.has(name),\n );\n if (hiddenFields === undefined) {\n return new Set(defaults);\n }\n const valid =\n Array.isArray(hiddenFields) &&\n hiddenFields.every((name) => typeof name === \"string\") &&\n new Set(hiddenFields).size === hiddenFields.length;\n if (!valid) {\n fail(\"hiddenFields must be a list of distinct field names\");\n }\n for (const name of hiddenFields as string[]) {\n if (name === \"id\" || !names.includes(name)) {\n fail(`hiddenFields: \"${name}\" is not a field of the entity that can be hidden`);\n }\n if (grants.has(name)) {\n fail(\n `hiddenFields: \"${name}\" holds the grants that grants: true shows; leave one of them out`,\n );\n }\n }\n return new Set([...defaults, ...(hiddenFields as string[])]);\n}\n\nfunction overrideProblem(override: UnknownRecord): string | undefined {\n const unknownKey = Object.keys(override).find((key) => !OVERRIDE_KEYS.includes(key));\n if (unknownKey !== undefined) {\n return `has an unknown key \"${unknownKey}\"; the keys are ${OVERRIDE_KEYS.join(\", \")}`;\n }\n const { type, label, enumValues, relationService } = override;\n const flags = [\"required\", \"editable\", \"showInTable\", \"showInForm\"].filter(\n (key) => override[key] !== undefined && typeof override[key] !== \"boolean\",\n );\n if (flags.length > 0) {\n return `${flags.join(\", \")} must be true or false`;\n }\n const text = (value: unknown): boolean =>\n value === undefined || (typeof value === \"string\" && value.length > 0);\n const enumOk =\n enumValues === undefined ||\n (Array.isArray(enumValues) && enumValues.every((value) => typeof value === \"string\"));\n const typeOk = type === undefined || ADMIN_FIELD_TYPES.some((known) => known === type);\n return text(label) && text(relationService) && enumOk && typeOk\n ? undefined\n : \"has a type, label, enumValues or relationService of the wrong kind\";\n}\n\n/** The overrides, per field of the entity that is not hidden. */\nfunction checkOverrides(\n fieldOverrides: unknown,\n names: readonly string[],\n hidden: ReadonlySet<string>,\n fail: MetaFailure,\n): Readonly<Record<string, UnknownRecord>> {\n if (fieldOverrides === undefined) {\n return {};\n }\n if (!isRecord(fieldOverrides)) {\n fail(\"fieldOverrides must map field names to configuration changes\");\n }\n for (const [name, override] of Object.entries(fieldOverrides)) {\n if (!names.includes(name) || hidden.has(name)) {\n fail(`fieldOverrides: \"${name}\" is not a field of the entity the kit shows`);\n }\n const problem = isRecord(override) ? overrideProblem(override) : \"must be an object\";\n if (problem !== undefined) {\n fail(`fieldOverrides for \"${name}\" ${problem}`);\n }\n if ((override as UnknownRecord).editable === true && ADMIN_NEVER_WRITABLE.includes(name)) {\n fail(`fieldOverrides: \"${name}\" is never editable; the database sets it`);\n }\n }\n return fieldOverrides as Readonly<Record<string, UnknownRecord>>;\n}\n\nfunction quoted(names: readonly string[]): string {\n return names.map((name) => `\"${name}\"`).join(\", \");\n}\n\n/**\n * The fields `editable` names, or the list `admin.contract` was given\n * (`declared`) when it names none: each a field the kit shows, never `id` or\n * a timestamp. Given in both halves, the two must name the same fields.\n * `undefined` when neither half gives a list.\n */\nfunction checkEditable(\n editable: unknown,\n declared: readonly string[] | undefined,\n shown: (name: string) => boolean,\n fail: MetaFailure,\n): ReadonlySet<string> | undefined {\n const named = (label: string, list: readonly string[]): ReadonlySet<string> => {\n for (const name of list) {\n if (ADMIN_NEVER_WRITABLE.includes(name)) {\n fail(`${label}: \"${name}\" is never editable; the database sets it`);\n }\n if (!shown(name)) {\n fail(`${label}: \"${name}\" is not a field of the entity the kit shows`);\n }\n }\n return new Set(list);\n };\n if (editable === undefined) {\n return declared === undefined ? undefined : named(\"admin.contract's editable\", declared);\n }\n const valid =\n Array.isArray(editable) &&\n editable.every((name) => typeof name === \"string\") &&\n new Set(editable).size === editable.length;\n if (!valid) {\n fail(\"editable must be a list of distinct field names\");\n }\n const list = named(\"editable\", editable as string[]);\n if (\n declared !== undefined &&\n (declared.length !== list.size || !declared.every((name) => list.has(name)))\n ) {\n fail(\n `editable names ${quoted(editable as string[])}, but admin.contract was given ${quoted(declared)}: give both halves the same fields`,\n );\n }\n return list;\n}\n\n/** Refuses an override whose `editable` says otherwise than the `editable` list: two sources of truth. */\nfunction checkAgreement(\n overrides: Readonly<Record<string, UnknownRecord>>,\n editable: ReadonlySet<string> | undefined,\n fail: MetaFailure,\n): void {\n if (editable === undefined) {\n return;\n }\n for (const [name, override] of Object.entries(overrides)) {\n if (override.editable === true && !editable.has(name)) {\n fail(\n `fieldOverrides: \"${name}\" is editable: true, which editable leaves out; name it in editable instead`,\n );\n }\n if (override.editable === false && editable.has(name)) {\n fail(\n `fieldOverrides: \"${name}\" is editable: false, which editable names; leave it out of editable instead`,\n );\n }\n }\n}\n\n/** One field's configuration, before overrides; a grant field `grants: true` shows is marked. */\nfunction derived(\n field: AdminEntityField,\n grants: ReadonlySet<string>,\n): Omit<AdminFieldConfig, \"sortable\" | \"filterable\"> {\n const fixed = Object.hasOwn(DEFAULT_FIELDS, field.name) ? DEFAULT_FIELDS[field.name] : undefined;\n if (fixed !== undefined) {\n return fixed;\n }\n return {\n name: field.name,\n type: field.type,\n label: labelOf(field.name),\n required: field.required,\n editable: !ADMIN_NEVER_WRITABLE.includes(field.name),\n showInTable: field.type !== \"json\",\n ...(field.enumValues === undefined ? {} : { enumValues: field.enumValues }),\n ...(grants.has(field.name) ? { kind: \"grants\" as const } : {}),\n };\n}\n\n/** The fields in an admin screen's order: `id`, `createdAt` and `updatedAt` first. */\nfunction ordered(fields: readonly AdminEntityField[]): AdminEntityField[] {\n const first = Object.keys(DEFAULT_FIELDS).flatMap((name) =>\n fields.filter((field) => field.name === name),\n );\n return [...first, ...fields.filter((field) => !first.includes(field))];\n}\n\nfunction frozenConfig(config: AdminFieldConfig): AdminFieldConfig {\n const { enumValues } = config;\n return Object.freeze(\n enumValues === undefined ? config : { ...config, enumValues: Object.freeze([...enumValues]) },\n );\n}\n\n/**\n * `adminMeta`'s answer for a service, and the fields its reads and writes\n * leave alone, from what the contract half read of the entity (`spec`) and\n * the handlers' options. Fails through `fail` for options that name no field\n * of the entity, would make `id` or a timestamp editable, hide a field\n * `adminList` filters or sorts on (a filter on it would tell what it holds),\n * or give two answers to whether a field is editable.\n */\nexport function adminFieldsOf(\n serviceName: string,\n spec: Pick<AdminSpec, \"fields\" | \"filter\" | \"sort\"> & Partial<Pick<AdminSpec, \"editable\">>,\n options: MetaOptions,\n fail: MetaFailure,\n): AdminFields {\n const names = spec.fields.map((field) => field.name);\n const grantNames = grantNamesOf(options.grantsColumn);\n const grants = checkGrants(options.grants, [names, grantNames], fail);\n const hidden = checkHidden(options.hiddenFields, [names, grantNames], grants, fail);\n const listed = [...spec.filter, ...spec.sort].find((name) => hidden.has(name));\n if (listed !== undefined) {\n fail(`\"${listed}\" is hidden, so adminList may not filter or sort on it`);\n }\n const overrides = checkOverrides(options.fieldOverrides, names, hidden, fail);\n const editable = checkEditable(\n options.editable,\n spec.editable,\n (name) => names.includes(name) && !hidden.has(name),\n fail,\n );\n checkAgreement(overrides, editable, fail);\n const fields = ordered(spec.fields)\n .filter((field) => !hidden.has(field.name))\n .map((field) =>\n frozenConfig({\n ...derived(field, grants),\n ...overrides[field.name],\n ...(editable === undefined ? {} : { editable: editable.has(field.name) }),\n sortable: spec.sort.includes(field.name),\n filterable: spec.filter.includes(field.name),\n }),\n );\n const meta: AdminServiceMeta = Object.freeze({\n serviceName,\n displayName: checkDisplayName(options.displayName, serviceName, fail),\n fields: Object.freeze(fields),\n });\n const readOnly = new Set(fields.filter((field) => !field.editable).map((field) => field.name));\n const named = new Set([\n ...(editable ?? []),\n ...Object.entries(overrides)\n .filter(([, override]) => override.editable === true)\n .map(([name]) => name),\n ]);\n return Object.freeze({ meta, hidden, readOnly, grants, named });\n}\n\n/**\n * `meta` with the fields `readOnly` names shown as not editable: the\n * relations of the service's model, which the kit never writes. `meta`\n * itself when none of its fields is one.\n */\nexport function withReadOnlyFields(\n meta: AdminServiceMeta,\n readOnly: ReadonlySet<string>,\n): AdminServiceMeta {\n if (!meta.fields.some((field) => readOnly.has(field.name) && field.editable)) {\n return meta;\n }\n const fields = meta.fields.map((field) =>\n readOnly.has(field.name) && field.editable\n ? frozenConfig({ ...field, editable: false })\n : field,\n );\n return Object.freeze({ ...meta, fields: Object.freeze(fields) });\n}\n","// What every handler of the admin kit starts from (RFC 0003 section 12.4):\n// the service its method runs in, found through the call's `ctx` as the other\n// kits find it, the model's delegate on the dispatcher's tracked database\n// client, and the fields the caller may see. Every write goes through that\n// client, so the flush sends its frames; the kit sends none itself.\n//\n// An admin method reaches every row of its service: no policy filters it,\n// since the default form needs a service-wide `Admin` grant, which reaches\n// every row anyway. What a row shows follows the same grant: a field above\n// the caller's service-wide level (a `fields` tier) is left out, as are the\n// fields the service hides from the kit. With the default form the grant is\n// `Admin`, which reaches every tier; a service that gives a method a lower\n// form shows that method's callers less, and refuses them a filter, a sort\n// or a write that names a field they cannot see (it would tell what the\n// field holds). The grant fields `grants: true` shows (`serviceAccess`, or\n// the column `auth.serviceAccessSource` names on the service's model:\n// `grantsColumnOf`) are seen only by callers whose service-wide grant is\n// `Admin`, whatever form the method runs under: editing grants never comes\n// with a lowered form.\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { serviceGrant } from \"../../access/levels\";\nimport { kitRuntimeOf, type KitRuntime } from \"../../context\";\nimport type { Projection } from \"../../emit/projection\";\nimport { modelKey } from \"../../storage\";\nimport type { Principal } from \"../../types\";\nimport { pageItem } from \"../crud/list\";\nimport type { KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport { grantsColumnFor, type AdminFields } from \"./meta\";\n\n/** One call of an admin method. */\nexport interface AdminCall {\n readonly runtime: KitRuntime;\n /** The service's model, named as the database client names it: `\"task\"`. */\n readonly model: string;\n readonly table: ModelDelegate;\n readonly principal: Principal | null;\n /** The entity projection: what a row is read with and sent as. */\n readonly projection: Projection;\n /** The fields above the caller's service-wide level: left out of rows, refused in filters, sorts and writes. */\n readonly unseen: ReadonlySet<string>;\n /** `unseen` and the fields the service hides from the kit: what no row of this call shows. */\n readonly omitted: ReadonlySet<string>;\n /** The service's fields as the kit configures them for the server's grants column. */\n readonly fields: AdminFields;\n}\n\n/** The column `auth.serviceAccessSource` names on the service's model, or `undefined`: the kit's grants field there. */\nexport function grantsColumnOf(runtime: KitRuntime): string | undefined {\n return grantsColumnFor(runtime.service.model, runtime.grantsSource);\n}\n\n/** The delegate of `model` on the dispatcher's database client (or a transaction's client). */\nexport function tableOf(db: unknown, model: string): ModelDelegate {\n const name = modelKey(model);\n const isClient = (typeof db === \"object\" || typeof db === \"function\") && db !== null;\n const delegate: unknown = isClient ? Reflect.get(db, name) : undefined;\n const usable =\n typeof delegate === \"object\" &&\n delegate !== null &&\n typeof (delegate as { readonly findMany?: unknown }).findMany === \"function\";\n if (!usable) {\n throw new QuickdrawError(\n \"INTERNAL\",\n `The admin kit reads and writes through db.${name}, which the dispatcher's database client does not have`,\n );\n }\n return delegate as ModelDelegate;\n}\n\n/** The admin kit call `ctx` belongs to, with the fields `fieldsFor` gives the server's grants column. */\nexport function adminCall(\n ctx: KitHandlerArgs[\"ctx\"],\n db: unknown,\n fieldsFor: (grantsColumn: string | undefined) => AdminFields,\n): AdminCall {\n const runtime = kitRuntimeOf(ctx);\n const model = runtime?.service.model;\n const projection = runtime?.service.projections.get(\"entity\");\n if (runtime === undefined || model === undefined || projection === undefined) {\n throw new QuickdrawError(\n \"INTERNAL\",\n \"The admin kit's handlers run through a dispatcher, in a service with a model and an entity\",\n );\n }\n const fields = fieldsFor(grantsColumnOf(runtime));\n const { principal } = ctx;\n const level = principal === null ? null : (serviceGrant(principal, runtime.service.name) ?? null);\n const tiered = projection.tiers.hidden(level);\n const unseen = level === \"Admin\" ? tiered : new Set([...tiered, ...fields.grants]);\n return {\n runtime,\n model: modelKey(model),\n table: tableOf(db, model),\n principal,\n projection,\n unseen,\n omitted: new Set([...unseen, ...fields.hidden]),\n fields,\n };\n}\n\n/** A row as the call returns it: projected, without the fields it omits. */\nexport function rowOut(call: AdminCall, row: object): unknown {\n return pageItem(call.projection, row, call.omitted);\n}\n\nconst NOTHING_OMITTED: ReadonlySet<string> = Object.freeze(new Set<string>());\n\n/** A row as `onWrite` hears it: projected, every field (the hook is the server's own). */\nexport function rowWhole(call: AdminCall, row: object): unknown {\n return pageItem(call.projection, row, NOTHING_OMITTED);\n}\n\n/** `FORBIDDEN` when the call names a field above the caller's level. */\nexport function checkSeen(call: AdminCall, names: readonly string[]): void {\n const unseen = names.find((name) => call.unseen.has(name));\n if (unseen !== undefined) {\n throw new QuickdrawError(\n \"FORBIDDEN\",\n `\"${unseen}\" is a field of ${call.runtime.service.name} above your access level`,\n );\n }\n}\n","// The admin kit's `adminList` (RFC 0003 section 12.4): one page of every row\n// of the service, by page number, with the total. The page arithmetic is\n// 4.1's (4.1 `src/server/BaseService.ts:1367-1388`): `skip` is\n// `(page - 1) * pageSize`, and `totalPages` is `ceil(total / pageSize)`; a\n// page past the last is empty. The rest is the read/write kit's list\n// machinery (`../crud/listQuery.ts`, `../crud/page.ts`): the filter is\n// equality on the declared fields and the sort a declared field, then `id`,\n// so the order is total and pages never overlap; a filter or sort on a field\n// above the caller's level is `FORBIDDEN`, and a default sort on one falls\n// back to `id` (its order would tell what the field holds). 4.1 passed the\n// caller's `where` and `orderBy` to the database as they came.\n//\n// Statements: two, run together: the page's rows and the count.\n\nimport type { AdminListQuery, AdminPage } from \"../../../contract/kits/adminSchemas\";\nimport { orderByOf } from \"../../collections/cursor\";\nimport { selectWith } from \"../../collections/items\";\nimport { defaultSorts, listOrder, listWhere, namedFields } from \"../crud/listQuery\";\nimport { refusal } from \"../crud/page\";\nimport type { KitHandler, KitHandlerArgs, Row } from \"../crud/runtime\";\nimport { adminCall, checkSeen, rowOut } from \"./runtime\";\nimport type { AdminContext } from \"./types\";\n\n/** Plain directions: an offset page needs no explicit place for nulls, only a total order. */\nconst NO_NULLABLE: ReadonlySet<string> = new Set();\n\n/** The `adminList` handler. */\nexport function adminListHandler(context: AdminContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<AdminPage<unknown>> => {\n const call = adminCall(ctx, db, context.fieldsFor);\n const query = input as AdminListQuery;\n checkSeen(call, namedFields(query));\n const order = listOrder(defaultSorts(context.spec.sort, call.unseen), query.sort);\n const where = listWhere(query.filter, undefined);\n const select = selectWith(\n call.projection.select,\n order.map(([column]) => column),\n );\n let rows: Row[];\n let total: number;\n try {\n [rows, total] = await Promise.all([\n call.table.findMany({\n where,\n select,\n orderBy: orderByOf(order, NO_NULLABLE),\n skip: (query.page - 1) * query.pageSize,\n take: query.pageSize,\n }),\n call.table.count({ where }),\n ]);\n } catch (error) {\n throw refusal(error, { cursor: undefined, filtered: Object.keys(query.filter).length > 0 });\n }\n return {\n items: rows.map((row) => rowOut(call, row)),\n total,\n page: query.page,\n pageSize: query.pageSize,\n totalPages: Math.ceil(total / query.pageSize),\n };\n };\n return handler as KitHandler;\n}\n","// The admin kit's methods on a row's subscribers (RFC 0003 sections 6 and\n// 12.4). A subscriber sits in the row's room for its access level\n// (`entityRoom(service, id, level)`), so `adminSubscribers` counts the\n// sockets in each of those rooms, reading nothing. 4.1 listed each socket and\n// user from a per-entity map (4.1 `src/server/BaseService.ts:1448-1464`),\n// which 5.0 does not keep. The counts are this process's: behind a cluster\n// adapter (Redis) another server's sockets are invisible here, and the reply\n// says so (`complete: false`).\n//\n// `adminReemit` records a touch of the row (`ctx.touch`), so the call's flush\n// reads it and sends it whole to every subscriber and collection, as after\n// any write; 4.1 emitted it by hand (`BaseService.ts:1470-1485`). A row that\n// is not there is `NOT_FOUND` (one statement).\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AdminSubscribers } from \"../../../contract/kits/adminSchemas\";\nimport { entityRoom } from \"../../../contract/names\";\nimport type { AnyContext } from \"../../context\";\nimport { SUBSCRIBER_LEVELS } from \"../../emit/tiers\";\nimport { requireRow } from \"../guards\";\nimport type { KitHandler, KitHandlerArgs } from \"../crud/runtime\";\nimport { adminCall, type AdminCall } from \"./runtime\";\nimport type { AdminContext } from \"./types\";\n\n/** The sockets subscribed to row `id`, per level. */\nfunction subscribersOf(call: AdminCall, id: string): AdminSubscribers {\n const { occupancy, service } = call.runtime;\n const counted = SUBSCRIBER_LEVELS.map(\n (level) => [level, occupancy?.sockets(entityRoom(service.name, id, level)) ?? 0] as const,\n );\n return {\n id,\n count: counted.reduce((sum, [, count]) => sum + count, 0),\n levels: Object.fromEntries(counted) as AdminSubscribers[\"levels\"],\n complete: occupancy?.complete() ?? true,\n };\n}\n\n/** The `adminSubscribers` handler. */\nexport function adminSubscribersHandler(context: AdminContext): KitHandler {\n const handler = ({ input, ctx, db }: KitHandlerArgs): Promise<AdminSubscribers> => {\n const call = adminCall(ctx, db, context.fieldsFor);\n return Promise.resolve(subscribersOf(call, (input as IdInput).id));\n };\n return handler as KitHandler;\n}\n\n/** The `adminReemit` handler. */\nexport function adminReemitHandler(context: AdminContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<AdminSubscribers> => {\n const call = adminCall(ctx, db, context.fieldsFor);\n const { id } = input as IdInput;\n requireRow(\n await call.table.findUnique({ where: { id }, select: { id: true } }),\n `No such ${call.model}`,\n );\n (ctx as Partial<Pick<AnyContext, \"touch\">>).touch?.(call.model, [id]);\n return subscribersOf(call, id);\n };\n return handler as KitHandler;\n}\n","// What the admin kit's writes may hold (RFC 0003 section 12.4): checked\n// before `adminCreate` and `adminUpdate` write, and the database's refusal\n// of a write's values, after. A write never sets a field the service hides,\n// one an override made read-only, `id` or a timestamp, nor a field above the\n// caller's level; and, as for every kit write, it holds column values only\n// (never a relation or a nested write, whoever the caller), and sets a\n// column that decides access to the row only with a service-wide `Admin`\n// grant (`../columns.ts`).\n\nimport { QuickdrawError } from \"../../../protocol/errors\";\nimport { checkWritableColumns } from \"../columns\";\nimport { rowLevel } from \"../crud/access\";\nimport { checkSeen, type AdminCall } from \"./runtime\";\nimport type { AdminContext } from \"./types\";\n\n/**\n * `VALIDATION` for a write that names a field the kit does not write (one the\n * service hides, `id`, a timestamp, or one an override made read-only), or\n * that holds a relation of the model or a nested write, and `FORBIDDEN` for\n * one above the caller's level, or for a column that decides access to the\n * row unless the caller holds a service-wide `Admin` grant (a lowered form\n * must not let a member make themselves the owner; an anchor column may move\n * the row only into an anchor row the caller has the row level on:\n * `../columns.ts`).\n */\nexport async function checkWrite(\n call: AdminCall,\n context: AdminContext,\n data: Readonly<Record<string, unknown>>,\n): Promise<void> {\n const { hidden, readOnly } = call.fields;\n const names = Object.keys(data);\n const issues = names\n .filter((name) => hidden.has(name) || readOnly.has(name))\n .map((name) => ({\n path: [\"data\", name],\n message: hidden.has(name) ? `\"${name}\" is not a writable field` : `\"${name}\" is not editable`,\n }));\n if (issues.length > 0) {\n throw new QuickdrawError(\"VALIDATION\", \"The data names fields the admin kit does not write\", {\n issues,\n });\n }\n checkSeen(call, names);\n await checkWritableColumns(\n call.runtime,\n call.principal,\n data,\n rowLevel(context.form, \"Moderate\"),\n [\"data\"],\n );\n}\n\n/** True for Prisma's report of a value its column cannot hold: the wrong kind, or out of range. */\nfunction isValueRefusal(error: unknown): error is Error {\n if (!(error instanceof Error)) {\n return false;\n }\n const { code } = error as Error & { readonly code?: unknown };\n return (\n error.name === \"PrismaClientValidationError\" ||\n (error.name === \"PrismaClientKnownRequestError\" && code === \"P2020\")\n );\n}\n\n/**\n * The database's refusal of a write's values (a value its column cannot\n * hold, a required column left out) as `VALIDATION`; anything else\n * unchanged. A foreign key that names no row stays `INTERNAL`, as for the\n * read/write kit.\n */\nexport function writeRefusal(error: unknown): unknown {\n if (!isValueRefusal(error)) {\n return error;\n }\n const message = \"The database refused the row's data\";\n const refused = new QuickdrawError(\"VALIDATION\", message, {\n issues: [\n {\n path: [\"data\"],\n message: \"A value does not fit its column, or a column the database requires was left out\",\n },\n ],\n });\n refused.cause = error;\n return refused;\n}\n","// The admin kit's methods on one row (RFC 0003 section 12.4): `adminGet`,\n// `adminCreate`, `adminUpdate` and `adminDelete`, through `db.<model>` on the\n// dispatcher's tracked client, as 4.1's went through `this.create` and\n// `this.update` (4.1 `src/server/BaseService.ts:1393-1417`). The tracked\n// client records each write, so the flush sends subscribers and collections\n// the same frames as any other write of the row: an admin edit shows live.\n//\n// Each reads one statement's worth: the row with the entity projection's\n// select. A row that is not there is `NOT_FOUND`, a unique violation\n// `CONFLICT`, and a value the database refuses `VALIDATION`. A write never\n// sets a field the service hides, one an override made read-only, `id` or a\n// timestamp (the contract half refuses the last two before the call runs).\n\nimport type { IdInput } from \"../../../contract/kits/crudSchemas\";\nimport type { AdminCreateQuery, AdminUpdateQuery } from \"../../../contract/kits/adminSchemas\";\nimport { requireRow } from \"../guards\";\nimport type { KitHandler, KitHandlerArgs, ModelDelegate } from \"../crud/runtime\";\nimport { kitRuntimeOf } from \"../../context\";\nimport { inKitTransaction } from \"../transactions\";\nimport { adminCall, rowOut, rowWhole, tableOf, type AdminCall } from \"./runtime\";\nimport type { AdminContext, AdminWrite } from \"./types\";\nimport { checkWrite, writeRefusal } from \"./writes\";\nimport { errorText } from \"../../../contract/logger\";\n\nasync function readRow(call: AdminCall, id: string): Promise<unknown> {\n const row = await call.table.findUnique({ where: { id }, select: call.projection.select });\n return rowOut(call, requireRow(row, `No such ${call.model}`));\n}\n\n/** One write, as a handler makes it: on `table`, reading the row before it when `before` is asked for. */\ntype Perform = (\n table: ModelDelegate,\n before: boolean,\n) => Promise<{\n readonly id: string;\n readonly before?: object | null;\n readonly after: object | null;\n readonly reply: unknown;\n}>;\n\n/**\n * Hands a committed write to `onCommitted`, in a detached unit of work of\n * the dispatcher the call runs in: the reply does not wait for it, and a\n * throw (or a rejection) is logged with the call's logger, never the\n * caller's.\n */\nfunction committed(context: AdminContext, args: KitHandlerArgs, write: AdminWrite): void {\n const { onCommitted } = context;\n if (onCommitted === undefined) {\n return;\n }\n const ctx = args.ctx as Parameters<typeof onCommitted>[1];\n const run = kitRuntimeOf(args.ctx)?.runDetached ?? ((fn: () => unknown) => Promise.resolve(fn()));\n const failed = (error: unknown): void => {\n ctx.log.error(\"The admin kit's onCommitted failed; the write stands\", {\n category: \"quickdraw.admin\",\n method: write.method,\n id: write.id,\n error: errorText(error),\n });\n };\n try {\n run(() => onCommitted(write, ctx)).catch(failed);\n } catch (error) {\n failed(error);\n }\n}\n\n/**\n * Runs one write of `method`: alone without a hook, else in a transaction\n * with `onWrite` after it, which hears the row before (read in the\n * transaction) and after, every field; a throw undoes the write. Once it\n * committed, `onCommitted` hears the same (`committed`). The database's\n * refusal of the values is `VALIDATION` either way.\n */\nasync function written(\n context: AdminContext,\n call: AdminCall,\n args: KitHandlerArgs,\n method: AdminWrite[\"method\"],\n perform: Perform,\n): Promise<unknown> {\n const { onWrite, onCommitted } = context;\n const attempt = async (table: ModelDelegate, before: boolean) => {\n try {\n return await perform(table, before);\n } catch (error) {\n throw writeRefusal(error);\n }\n };\n if (onWrite === undefined && onCommitted === undefined) {\n return (await attempt(call.table, false)).reply;\n }\n let write: AdminWrite | undefined;\n const reply = await inKitTransaction(\n args.db,\n async (tx) => {\n const done = await attempt(tableOf(tx, call.model), method !== \"adminCreate\");\n const whole = (row: object | null | undefined) => (row ? rowWhole(call, row) : null);\n write = {\n method,\n id: done.id,\n ...(method === \"adminCreate\" ? {} : { before: whole(done.before) }),\n after: whole(done.after),\n };\n await onWrite?.(write, args.ctx as Parameters<typeof onWrite>[1], tx);\n return done.reply;\n },\n { owner: \"The admin kit's writes with onWrite or onCommitted\" },\n );\n if (write !== undefined) {\n committed(context, args, write);\n }\n return reply;\n}\n\n/** The `adminGet` handler. */\nexport function adminGetHandler(context: AdminContext): KitHandler {\n const handler = async ({ input, ctx, db }: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(ctx, db, context.fieldsFor);\n return await readRow(call, (input as IdInput).id);\n };\n return handler as KitHandler;\n}\n\n/** The id of a row the kit wrote: it reads the entity projection, which always selects `id`. */\nfunction idOf(row: object): string {\n return String((row as { readonly id?: unknown }).id);\n}\n\n/** The `adminCreate` handler. */\nexport function adminCreateHandler(context: AdminContext): KitHandler {\n const handler = async (args: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(args.ctx, args.db, context.fieldsFor);\n const { data } = args.input as AdminCreateQuery;\n await checkWrite(call, context, data);\n return await written(context, call, args, \"adminCreate\", async (table) => {\n const after = await table.create({ data, select: call.projection.select });\n return { id: idOf(after), after, reply: rowOut(call, after) };\n });\n };\n return handler as KitHandler;\n}\n\n/** The `adminUpdate` handler. A call that changes nothing reads the row instead of writing it. */\nexport function adminUpdateHandler(context: AdminContext): KitHandler {\n const handler = async (args: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(args.ctx, args.db, context.fieldsFor);\n const { id, data } = args.input as AdminUpdateQuery;\n await checkWrite(call, context, data);\n if (Object.keys(data).length === 0) {\n return await readRow(call, id);\n }\n const { select } = call.projection;\n return await written(context, call, args, \"adminUpdate\", async (table, withBefore) => {\n const before = withBefore ? await table.findUnique({ where: { id }, select }) : undefined;\n const after = await table.update({ where: { id }, data, select });\n return { id, before, after, reply: rowOut(call, after) };\n });\n };\n return handler as KitHandler;\n}\n\n/** The `adminDelete` handler. */\nexport function adminDeleteHandler(context: AdminContext): KitHandler {\n const handler = async (args: KitHandlerArgs): Promise<unknown> => {\n const call = adminCall(args.ctx, args.db, context.fieldsFor);\n const { id } = args.input as IdInput;\n return await written(context, call, args, \"adminDelete\", async (table, withBefore) => {\n const select = withBefore ? call.projection.select : { id: true };\n const before = await table.delete({ where: { id }, select });\n return { id, ...(withBefore ? { before } : {}), after: null, reply: null };\n });\n };\n return handler as KitHandler;\n}\n","// The handler of each admin method (RFC 0003 section 12.4), and the form each\n// runs under unless `admin.handlers` is given another: a service-wide `Admin`\n// grant. 4.1 apps repeated a nine-key block of `\"Admin\"` levels for this\n// (4.1 `src/server/BaseService.ts:1167-1183`).\n\nimport type { AdminMethodName } from \"../../../contract/kits/admin\";\nimport { kitRuntimeOf } from \"../../context\";\nimport { relationKeysOf } from \"../columns\";\nimport type { KitHandler, KitHandlerArgs } from \"../crud/runtime\";\nimport { adminListHandler } from \"./list\";\nimport { adminReemitHandler, adminSubscribersHandler } from \"./live\";\nimport { grantsColumnFor, withReadOnlyFields } from \"./meta\";\nimport {\n adminCreateHandler,\n adminDeleteHandler,\n adminGetHandler,\n adminUpdateHandler,\n} from \"./rows\";\nimport type { AdminContext, AdminDefaultAccess } from \"./types\";\n\n/** The form every admin method runs under when `access` gives none. */\nexport const ADMIN_DEFAULT_ACCESS: AdminDefaultAccess = Object.freeze({ service: \"Admin\" });\n\nconst MAKERS: Readonly<\n Record<Exclude<AdminMethodName, \"adminMeta\">, (context: AdminContext) => KitHandler>\n> = Object.freeze({\n adminList: adminListHandler,\n adminGet: adminGetHandler,\n adminCreate: adminCreateHandler,\n adminUpdate: adminUpdateHandler,\n adminDelete: adminDeleteHandler,\n adminSubscribers: adminSubscribersHandler,\n adminReemit: adminReemitHandler,\n});\n\ntype Meta = ReturnType<AdminContext[\"fieldsFor\"]>[\"meta\"];\n\n/**\n * `adminMeta`'s handler: the answer worked out for the server's grants\n * column on the service's model (`grantsColumnFor`), with the relations of\n * the service's model (which only the service knows, from its projections)\n * shown as not editable, once per service and column.\n */\nfunction adminMetaHandler(context: AdminContext): KitHandler {\n const byService = new WeakMap<object, Map<string, Meta>>();\n const handler = (args: KitHandlerArgs): Promise<Meta> => {\n const runtime = kitRuntimeOf(args.ctx);\n if (runtime === undefined) {\n return Promise.resolve(context.fieldsFor(undefined).meta);\n }\n const { service } = runtime;\n const column = grantsColumnFor(service.model, runtime.grantsSource);\n const answers = byService.get(service) ?? new Map<string, Meta>();\n byService.set(service, answers);\n let answer = answers.get(column ?? \"\");\n if (answer === undefined) {\n answer = withReadOnlyFields(context.fieldsFor(column).meta, relationKeysOf(service));\n answers.set(column ?? \"\", answer);\n }\n return Promise.resolve(answer);\n };\n return handler as KitHandler;\n}\n\n/** The handler of one admin method: a new function for each, which `defineService` checks. */\nexport function handlerOf(context: AdminContext): KitHandler {\n const { method } = context.spec;\n return method === \"adminMeta\" ? adminMetaHandler(context) : MAKERS[method](context);\n}\n","// `admin.handlers(contract, { access?, displayName?, hiddenFields?,\n// editable?, fieldOverrides?, rowless?, grants?, onWrite?, onCommitted? })`\n// (RFC 0003 section 12.4):\n// the admin kit's server half.\n// It finds the methods `admin.contract` made in the contract and returns an\n// implementation of each, to spread into `defineService`'s `methods`:\n//\n// export const taskService = qd.defineService(task, {\n// model: \"task\",\n// access: inherit({ from: project, via: \"projectId\" }),\n// methods: {\n// ...admin.handlers(task, { displayName: \"Tasks\", hiddenFields: [\"internalNotes\"] }),\n// rename: { access: { entry: \"Moderate\" }, handler: ... },\n// },\n// });\n//\n// Every method runs under `{ service: \"Admin\" }` unless `access` gives\n// another: the caller's service-wide grant must be `Admin`, and a row-level\n// `Admin` (the row's owner, say) is refused. That replaces the nine-key\n// access block 4.1 apps repeated for `installAdminMethods`. `adminMeta`'s\n// answer is worked out here, once (`meta.ts`). The handlers find their\n// service through the call, so `defineService` refuses a service without a\n// model, or one of another contract. On a service with an access policy, it\n// also refuses a method on one row (`adminGet`, `adminUpdate`,\n// `adminDelete`) given a form that checks no row below `Admin` (`{ service:\n// \"Moderate\" }`, `\"authenticated\"`) unless `rowless` names it, since such a\n// method reaches any row by its id.\n//\n// `grants: true` (a users service) shows and writes the entity's grants\n// field, hidden by default (`serviceAccess`, `service_access`, or the column\n// `auth.serviceAccessSource` names on the service's model, whatever its\n// name: the 5.1 audit's ADMIN-2), so an admin screen can edit grants through\n// `adminUpdate`; only a caller whose own service-wide grant is `Admin` reads\n// or writes it, whatever `access` says. The write goes through the tracked\n// client, so with `auth.serviceAccessSource` naming that column the user's\n// open sockets get the new grants on every node, as for any grant change.\n// Only the server knows that column, so the fields are worked out once per\n// column (`fieldsFor`), first without one here, so a bad option still fails\n// in `admin.handlers`; `createDispatcher` checks the server's column\n// (`checkWhenServed`), so a clash with it fails when the server is made,\n// never on a call, and so does `grants: true` on an entity without a grants\n// field.\n//\n// `onWrite` runs in one transaction with each write, before it commits;\n// `onCommitted` (finding F6.5) once it has, in a detached unit of work, a\n// throw logged: what must wait until an edit is durable (a game applying an\n// edited definition) goes there (`rows.ts`).\n\nimport type { AnyContract } from \"../../../contract/defineContract\";\nimport { admin as contractHalf, adminSpecOf, type AdminSpec } from \"../../../contract/kits/admin\";\nimport { accessFormProblem } from \"../../access/forms\";\nimport type { AccessForm } from \"../../access/types\";\nimport {\n checkWhenDefined,\n checkWhenServed,\n dependsOnCaller,\n markGrantsEditor,\n type AnyService,\n type ServedContext,\n} from \"../../service\";\nimport { relationKeysOf } from \"../columns\";\nimport { kitEntry, rowlessMethods } from \"../rowless\";\nimport { adminFieldsOf, grantsColumnFor, type AdminFields } from \"./meta\";\nimport { ADMIN_DEFAULT_ACCESS, handlerOf } from \"./methods\";\nimport type {\n AdminAccess,\n AdminContract,\n AdminHandlersOptions,\n AdminImplementations,\n AdminOnCommitted,\n AdminOnWrite,\n} from \"./types\";\n\ntype UnknownRecord = Readonly<Record<string, unknown>>;\n\ntype Empty = Record<never, never>;\n\nconst OPTION_KEYS: readonly string[] = [\n \"access\",\n \"displayName\",\n \"hiddenFields\",\n \"editable\",\n \"fieldOverrides\",\n \"rowless\",\n \"grants\",\n \"onWrite\",\n \"onCommitted\",\n];\n\nfunction isRecord(value: unknown): value is UnknownRecord {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction fail(message: string): never {\n throw new TypeError(`admin.handlers: ${message}`);\n}\n\n/** The admin kit's methods in the contract, with what each was made for; at least one. */\nfunction kitMethods(contract: unknown): [string, AdminSpec][] {\n const valid =\n isRecord(contract) &&\n typeof contract.name === \"string\" &&\n isRecord(contract.methods) &&\n Object.isFrozen(contract);\n if (!valid) {\n fail(\"the first argument must be a contract from defineContract\");\n }\n const found: [string, AdminSpec][] = [];\n for (const [name, def] of Object.entries(contract.methods as UnknownRecord)) {\n const spec = adminSpecOf(def);\n if (spec !== undefined) {\n found.push([name, spec]);\n }\n }\n if (found.length === 0) {\n fail(`${String(contract.name)} has no method admin.contract made`);\n }\n if (found.some(([, spec]) => spec.entity !== contract.entity)) {\n fail(\n `admin.contract was given another schema than ${String(contract.name)}'s entity: pass the contract's entity schema`,\n );\n }\n return found;\n}\n\nfunction checkOptions(options: unknown): UnknownRecord {\n if (options === undefined) {\n return {};\n }\n if (!isRecord(options)) {\n fail(\n \"options must be { access?, displayName?, hiddenFields?, editable?, fieldOverrides?, rowless?, grants?, onWrite?, onCommitted? }\",\n );\n }\n const unknownKey = Object.keys(options).find((key) => !OPTION_KEYS.includes(key));\n if (unknownKey !== undefined) {\n fail(`options has an unknown key \"${unknownKey}\"; the options are ${OPTION_KEYS.join(\", \")}`);\n }\n return options;\n}\n\n/** The forms `access` gives, each for one of the kit's methods. */\nfunction checkAccess(access: unknown, names: readonly string[]): UnknownRecord {\n if (access === undefined) {\n return {};\n }\n if (!isRecord(access)) {\n fail(\"access must map the kit's methods to access forms\");\n }\n for (const [name, form] of Object.entries(access)) {\n if (!names.includes(name)) {\n fail(`access names \"${name}\", which is not a method admin.contract made`);\n }\n const problem = form === undefined ? undefined : accessFormProblem(form);\n if (problem !== undefined) {\n fail(`access for \"${name}\" ${problem}`);\n }\n }\n return access;\n}\n\n/** The `editable` list `admin.contract` was given for the kit's methods: at most one. */\nfunction contractEditable(\n contract: AnyContract,\n specs: readonly AdminSpec[],\n): readonly string[] | undefined {\n const lists = new Map<string, readonly string[]>();\n for (const { editable } of specs) {\n if (editable !== undefined) {\n lists.set([...editable].sort().join(\"\\u0000\"), editable);\n }\n }\n if (lists.size > 1) {\n fail(\n `admin.contract was given two editable lists for ${contract.name}: give its write methods one`,\n );\n }\n return [...lists.values()][0];\n}\n\n/** The kit's fields across its methods (every method's declared filter and sort fields), for a grants column. */\nfunction fieldsOf(\n contract: AnyContract,\n kit: readonly [string, AdminSpec][],\n options: UnknownRecord,\n grantsColumn: string | undefined,\n): AdminFields {\n const specs = kit.map(([, spec]) => spec);\n const [first] = specs;\n const spec = {\n fields: first?.fields ?? [],\n filter: [...new Set(specs.flatMap((one) => one.filter))],\n sort: [...new Set(specs.flatMap((one) => one.sort))],\n editable: contractEditable(contract, specs),\n };\n return adminFieldsOf(\n contract.name,\n spec,\n {\n displayName: options.displayName,\n hiddenFields: options.hiddenFields,\n editable: options.editable,\n fieldOverrides: options.fieldOverrides,\n grants: options.grants,\n ...(grantsColumn === undefined ? {} : { grantsColumn }),\n },\n fail,\n );\n}\n\n/** The kit's fields per grants column, worked out once each; none for the column-less ones. */\nfunction fieldsByColumn(\n contract: AnyContract,\n kit: readonly [string, AdminSpec][],\n options: UnknownRecord,\n): (grantsColumn: string | undefined) => AdminFields {\n const byColumn = new Map<string, AdminFields>();\n return (grantsColumn) => {\n let fields = byColumn.get(grantsColumn ?? \"\");\n if (fields === undefined) {\n fields = fieldsOf(contract, kit, options, grantsColumn);\n byColumn.set(grantsColumn ?? \"\", fields);\n }\n return fields;\n };\n}\n\n/**\n * Why a server cannot serve the kit (`checkWhenServed`): an option that\n * clashes with its grants column on the service's model, or `grants: true`\n * on an entity with no grants field.\n */\nfunction servedProblemOf(\n fieldsFor: (grantsColumn: string | undefined) => AdminFields,\n grants: boolean,\n { service, grantsSource }: ServedContext,\n): string | undefined {\n const column = grantsColumnFor(service.model, grantsSource);\n let fields: AdminFields;\n try {\n fields = fieldsFor(column);\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n if (grants && fields.grants.size === 0) {\n const named =\n column === undefined\n ? `auth.serviceAccessSource names no column of model \"${service.model ?? \"\"}\"`\n : `the entity has no field \"${column}\", the column auth.serviceAccessSource names`;\n return `grants: true needs a grants field: the entity has no serviceAccess or service_access field, and ${named}`;\n }\n return undefined;\n}\n\n/**\n * Why a service cannot run the admin kit's handlers made for `contract`: a\n * service of another contract, one without a model, or one where `editable`\n * or a `fieldOverrides` entry makes a relation of the model editable (the\n * kit writes column values only).\n */\nfunction serviceProblem(\n service: AnyService,\n contract: AnyContract,\n fields: AdminFields,\n): string | undefined {\n if (service.contract !== contract) {\n return `its admin kit handlers were made for another contract; pass ${service.name}'s own contract to admin.handlers`;\n }\n if (service.model === undefined) {\n return \"the admin kit reads and writes the service's rows: declare its model\";\n }\n const relations = relationKeysOf(service);\n const relation = [...fields.named].find((name) => relations.has(name));\n return relation === undefined\n ? undefined\n : `\"${relation}\" is a relation of ${service.name}'s model (a projection selects it with a nested select): the admin kit writes column values only; leave it out of editable and fieldOverrides`;\n}\n\nfunction handlers<C extends AnyContract, const A extends AdminAccess<C> = Empty, Db = unknown>(\n contract: C & NoInfer<AdminContract<C>>,\n options?: AdminHandlersOptions<C, A, Db>,\n): AdminImplementations<C, A, Db> {\n const kit = kitMethods(contract);\n const checked = checkOptions(options);\n const names = kit.map(([name]) => name);\n const access = checkAccess(checked.access, names);\n const rowless = rowlessMethods(checked.rowless, names, fail);\n const fieldsFor = fieldsByColumn(contract, kit, checked);\n // Without a grants column now, so an option that names no field still fails here.\n const fields = fieldsFor(undefined);\n const { onWrite, onCommitted } = checked;\n if (onWrite !== undefined && typeof onWrite !== \"function\") {\n fail(\"onWrite must be a function of (write, ctx, db)\");\n }\n if (onCommitted !== undefined && typeof onCommitted !== \"function\") {\n fail(\"onCommitted must be a function of (write, ctx)\");\n }\n const hooks = {\n onWrite: onWrite as AdminOnWrite | undefined,\n onCommitted: onCommitted as AdminOnCommitted | undefined,\n };\n const entries: Record<string, object> = {};\n for (const [name, spec] of kit) {\n const form = (access[name] as AccessForm | undefined) ?? ADMIN_DEFAULT_ACCESS;\n const handler = handlerOf({ spec, fieldsFor, form, ...hooks });\n checkWhenDefined(handler, (service) => serviceProblem(service, contract, fields));\n checkWhenServed(handler, (served) =>\n servedProblemOf(fieldsFor, checked.grants === true, served),\n );\n if (checked.grants === true) {\n // `createServer` warns when no `auth.serviceAccessSource` says where these grants live.\n markGrantsEditor(handler);\n }\n if (spec.method === \"adminList\" || spec.method === \"adminGet\") {\n // Fields above the caller's grant are left out of their rows (`adminCall`).\n dependsOnCaller(handler);\n }\n entries[name] = kitEntry(name, form, handler, rowless);\n }\n return Object.freeze(entries) as AdminImplementations<C, A, Db>;\n}\n\n/**\n * The admin kit: `admin.handlers(contract, { access?, displayName?,\n * hiddenFields?, editable?, fieldOverrides?, rowless?, grants? })` implements the\n * methods `admin.contract` made in `contract`, each open to a service-wide\n * `Admin` grant unless `access` gives another form. `admin.contract` is here\n * too, for server code; a shared package imports it from the root export.\n */\nexport const admin = Object.freeze({ contract: contractHalf.contract, handlers });\n","// Loads the Redis helper's optional peers, `@socket.io/redis-adapter` and\n// `redis`. A module of its own so a test can stand in for a missing peer: an\n// import that fails inside `vi.mock`'s factory reaches the caller wrapped in\n// vitest's own error, without the original's `code`.\n\n/** The two functions the Redis helper takes from its optional peers, untyped. */\nexport interface RedisPeers {\n readonly createAdapter: unknown;\n readonly createClient: unknown;\n}\n\n/** Imports both optional peers; rejects with the import error when either is missing. */\nexport async function loadRedisPeers(): Promise<RedisPeers> {\n // The build keeps both external because package.json declares them as peers.\n const [adapterModule, redisModule] = await Promise.all([\n import(\"@socket.io/redis-adapter\") as Promise<{ readonly createAdapter: unknown }>,\n import(\"redis\") as Promise<{ readonly createClient: unknown }>,\n ]);\n return { createAdapter: adapterModule.createAdapter, createClient: redisModule.createClient };\n}\n\n/**\n * True when `error` says a module could not be found. Node 24 and Bun throw\n * `ERR_MODULE_NOT_FOUND` from `import()` with the message \"Cannot find\n * package ...\", which 4.1 matched by message only and so logged as a failure\n * instead of a missing peer. The code is checked first; the 4.1 message checks\n * stay as a fallback for loaders that set no code.\n */\nexport function isModuleNotFound(error: unknown): boolean {\n if (typeof error !== \"object\" || error === null) {\n return false;\n }\n const { code, message } = error as { readonly code?: unknown; readonly message?: unknown };\n if (code === \"ERR_MODULE_NOT_FOUND\" || code === \"MODULE_NOT_FOUND\") {\n return true;\n }\n return (\n typeof message === \"string\" &&\n (message.includes(\"Cannot find module\") || message.includes(\"MODULE_NOT_FOUND\"))\n );\n}\n","/**\n * Redis adapter utilities for horizontal scaling.\n *\n * This module provides optional Redis (or Valkey) integration for Socket.io\n * to enable running multiple server instances. Behind the adapter, the\n * server also takes its flush revisions from a shared counter on the same\n * client and keeps users' last-seen times there (`createServer`'s `cluster`\n * option; docs/deploying.md). When the subscribing connection comes back\n * after a drop, the node's clients are told to reconnect within 2 seconds,\n * so they catch up on what the node missed; a publish Valkey did not take\n * is logged rather than left unhandled (`cluster/adapterClients.ts`).\n *\n * @example\n * ```typescript\n * import { setupRedisAdapter } from '@fitzzero/quickdraw-core/server';\n *\n * const server = qd.createServer({ app, services, db });\n *\n * // Enable Redis for horizontal scaling\n * const redis = await setupRedisAdapter(server.io, {\n * host: process.env.REDIS_HOST ?? 'localhost',\n * port: parseInt(process.env.REDIS_PORT ?? '6379'),\n * });\n *\n * // On shutdown, once the server closed:\n * await server.close();\n * await redis.cleanup();\n * ```\n */\n\nimport type { Server as SocketIOServer } from \"socket.io\";\nimport type { Logger } from \"../contract/logger\";\nimport { consoleLogger } from \"../contract/logger\";\nimport { watchAdapterClients } from \"./cluster/adapterClients\";\nimport { deploymentOf } from \"./cluster/deployment\";\nimport { isModuleNotFound, loadRedisPeers } from \"./redisPeers\";\nimport type { QuickdrawIo } from \"./transports/types\";\n\n/**\n * Redis adapter configuration options.\n */\nexport interface RedisAdapterOptions {\n /**\n * Redis host (default: 'localhost')\n */\n host?: string;\n\n /**\n * Redis port (default: 6379)\n */\n port?: number;\n\n /**\n * Redis password (optional)\n */\n password?: string;\n\n /**\n * Redis database number (default: 0). It does not separate deployments:\n * pub/sub is shared across a server's databases, so two deployments on one\n * Valkey hear each other's events whatever their `db`; give each its own\n * Valkey, or its own `cluster.keyPrefix` (docs/deploying.md).\n */\n db?: number;\n\n /**\n * The adapter's key, which names its pub/sub channels. Default: the\n * server's `cluster.keyPrefix` (\"quickdraw\" without one), so deployments\n * with their own prefixes use their own channels. 5.1.0 and earlier used\n * \"socket.io\": pass `keyPrefix: \"socket.io\"` for the deploy that moves a\n * cluster from such nodes, so old and new nodes keep hearing each other.\n */\n keyPrefix?: string;\n\n /**\n * Logger instance\n */\n logger?: Logger;\n}\n\n/**\n * Result of Redis adapter setup.\n */\nexport interface RedisAdapterResult {\n /**\n * Whether the adapter was successfully set up.\n */\n success: boolean;\n\n /**\n * Cleanup function to disconnect from Redis.\n */\n cleanup: () => Promise<void>;\n}\n\n// Type for dynamically loaded redis client\ninterface RedisClient {\n connect: () => Promise<void>;\n quit: () => Promise<void>;\n duplicate: () => RedisClient;\n on(event: \"error\" | \"ready\", listener: (error?: unknown) => void): unknown;\n}\n\n/**\n * Logs a client's errors at warn, once until it is ready again: a client\n * that lost its server reports every reconnect attempt, and one without an\n * `error` listener would make the adapter print a warning each time.\n */\nfunction reportErrors(client: RedisClient, logger: Logger, role: string): void {\n let reported = false;\n client.on(\"error\", (error) => {\n if (!reported) {\n reported = true;\n logger.warn(\"Redis adapter connection lost; it reconnects by itself\", {\n client: role,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n client.on(\"ready\", () => {\n reported = false;\n });\n}\n\n/**\n * Set up Redis adapter for Socket.io horizontal scaling.\n *\n * This function dynamically imports the @socket.io/redis-adapter package\n * to avoid requiring it as a hard dependency.\n *\n * @param io - Socket.io server instance\n * @param options - Redis configuration options\n * @returns Promise resolving to setup result\n *\n * @example\n * ```typescript\n * const { io } = createQuickdrawServer({ ... });\n *\n * const { success, cleanup } = await setupRedisAdapter(io, {\n * host: 'redis.example.com',\n * port: 6379,\n * password: process.env.REDIS_PASSWORD,\n * });\n *\n * if (success) {\n * console.log('Redis adapter enabled - horizontal scaling ready');\n * }\n *\n * // On shutdown:\n * await cleanup();\n * ```\n */\nexport async function setupRedisAdapter(\n io: SocketIOServer,\n options: RedisAdapterOptions = {},\n): Promise<RedisAdapterResult> {\n const logger =\n options.logger?.child({ service: \"RedisAdapter\" }) ??\n consoleLogger.child({ service: \"RedisAdapter\" });\n\n const { host = \"localhost\", port = 6379, password, db = 0 } = options;\n const key = options.keyPrefix ?? deploymentOf(io);\n\n try {\n // Dynamically import Redis packages - these are optional peer dependencies.\n const peers = await loadRedisPeers();\n\n const createAdapter = peers.createAdapter as (\n pubClient: RedisClient,\n subClient: RedisClient,\n opts?: { key?: string },\n ) => unknown;\n\n const createClient = peers.createClient as (opts: {\n socket: { host: string; port: number };\n password?: string;\n database?: number;\n }) => RedisClient;\n\n // Create Redis clients for pub/sub\n const pubClient = createClient({\n socket: { host, port },\n password,\n database: db,\n });\n\n const subClient = pubClient.duplicate();\n reportErrors(pubClient, logger, \"publish\");\n reportErrors(subClient, logger, \"subscribe\");\n\n // Connect both clients\n await Promise.all([pubClient.connect(), subClient.connect()]);\n\n // Set up the adapter\n io.adapter(createAdapter(pubClient, subClient, { key }) as Parameters<typeof io.adapter>[0]);\n // When the subscription comes back, this node's clients catch up; a failed publish is logged.\n watchAdapterClients(io as unknown as QuickdrawIo, logger);\n\n logger.info(`Redis adapter connected to ${host}:${port}`);\n\n // Return cleanup function\n const cleanup = async () => {\n try {\n await Promise.all([pubClient.quit(), subClient.quit()]);\n logger.info(\"Redis adapter disconnected\");\n } catch (error) {\n logger.error(\"Error disconnecting Redis adapter\", {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n };\n\n return { success: true, cleanup };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Check if it's a missing dependency error\n if (isModuleNotFound(error)) {\n logger.warn(\n \"Redis adapter packages not installed. Install @socket.io/redis-adapter and redis for horizontal scaling support.\",\n );\n } else {\n logger.error(\"Failed to set up Redis adapter\", { error: errorMessage });\n }\n\n return {\n success: false,\n cleanup: async () => {\n // No-op cleanup when setup failed\n },\n };\n }\n}\n\n/**\n * Check if Redis adapter packages are available.\n *\n * @returns Promise resolving to true if packages are installed\n */\nexport async function isRedisAdapterAvailable(): Promise<boolean> {\n try {\n await loadRedisPeers();\n return true;\n } catch {\n return false;\n }\n}\n","/**\n * Environment variable validation utilities.\n * Helps ensure required environment variables are set before the application starts.\n */\n\nexport interface ValidateEnvOptions {\n /**\n * List of required environment variable names.\n * Validation will fail if any of these are missing or empty.\n */\n required: string[];\n\n /**\n * Only enforce validation in production environment.\n * @default true\n */\n productionOnly?: boolean;\n\n /**\n * Custom error message prefix.\n * @default \"Missing required environment variables\"\n */\n errorPrefix?: string;\n}\n\nexport interface EnvValidationResult {\n success: boolean;\n missing: string[];\n message?: string;\n}\n\n/**\n * Validate that required environment variables are set.\n * Throws an error if any required variables are missing.\n *\n * @param options - Validation configuration\n * @throws {Error} If required environment variables are missing\n *\n * @example\n * ```typescript\n * // Validate required vars on startup\n * validateEnv({\n * required: ['JWT_SECRET', 'DATABASE_URL', 'CLIENT_URL'],\n * });\n * ```\n *\n * @example\n * ```typescript\n * // Only validate in production\n * validateEnv({\n * required: ['JWT_SECRET', 'DATABASE_URL'],\n * productionOnly: true,\n * });\n * ```\n */\nexport function validateEnv(options: ValidateEnvOptions): void {\n const result = checkEnv(options);\n\n if (!result.success) {\n throw new Error(result.message);\n }\n}\n\n/**\n * Check environment variables without throwing.\n * Returns a result object with validation status and missing variables.\n *\n * @param options - Validation configuration\n * @returns Validation result with missing variables list\n *\n * @example\n * ```typescript\n * const result = checkEnv({ required: ['JWT_SECRET'] });\n * if (!result.success) {\n * console.warn('Missing env vars:', result.missing);\n * }\n * ```\n */\nexport function checkEnv(options: ValidateEnvOptions): EnvValidationResult {\n const {\n required,\n productionOnly = true,\n errorPrefix = \"Missing required environment variables\",\n } = options;\n\n // Skip validation in development if productionOnly is true\n if (productionOnly && process.env.NODE_ENV !== \"production\") {\n return { success: true, missing: [] };\n }\n\n const missing: string[] = [];\n\n for (const varName of required) {\n const value = process.env[varName];\n if (!value || value.trim() === \"\") {\n missing.push(varName);\n }\n }\n\n if (missing.length > 0) {\n return {\n success: false,\n missing,\n message: `${errorPrefix}: ${missing.join(\", \")}`,\n };\n }\n\n return { success: true, missing: [] };\n}\n\n/**\n * Get an environment variable or throw if it's missing.\n * Useful for individual variable access with validation.\n *\n * @param name - Environment variable name\n * @param defaultValue - Optional default value (if provided, won't throw)\n * @returns The environment variable value\n * @throws {Error} If variable is missing and no default provided\n *\n * @example\n * ```typescript\n * const jwtSecret = requireEnv('JWT_SECRET');\n * const port = requireEnv('PORT', '4000');\n * ```\n */\nexport function requireEnv(name: string, defaultValue?: string): string {\n const value = process.env[name];\n\n if (!value || value.trim() === \"\") {\n if (defaultValue !== undefined) {\n return defaultValue;\n }\n throw new Error(`Environment variable ${name} is required but not set`);\n }\n\n return value;\n}\n","/**\n * AES-256-GCM encryption helpers for at-rest secrets (e.g. stored OAuth tokens).\n *\n * Requires ENCRYPTION_KEY: a 64-character hex string (32 bytes).\n * Ciphertext format: \"iv:authTag:ciphertext\" (all hex).\n */\n\nimport { createCipheriv, createDecipheriv, randomBytes } from \"crypto\";\nimport { consoleLogger, type Logger } from \"../../contract/logger\";\n\nconst ALGORITHM = \"aes-256-gcm\";\nconst IV_LENGTH = 12;\nconst AUTH_TAG_LENGTH = 16;\n\nfunction getKey(): Buffer {\n const hex = process.env.ENCRYPTION_KEY;\n if (!hex || hex.length !== 64) {\n throw new Error(\n \"ENCRYPTION_KEY must be set as a 64-character hex string (32 bytes). Check your environment configuration.\",\n );\n }\n return Buffer.from(hex, \"hex\");\n}\n\nexport function encrypt(plaintext: string): string {\n const key = getKey();\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });\n const encrypted = Buffer.concat([cipher.update(plaintext, \"utf8\"), cipher.final()]);\n const authTag = cipher.getAuthTag();\n return `${iv.toString(\"hex\")}:${authTag.toString(\"hex\")}:${encrypted.toString(\"hex\")}`;\n}\n\nexport function decrypt(ciphertext: string): string {\n const key = getKey();\n const [ivHex, authTagHex, encryptedHex] = ciphertext.split(\":\");\n if (!ivHex || !authTagHex || !encryptedHex) {\n throw new Error(\"Invalid ciphertext format\");\n }\n const iv = Buffer.from(ivHex, \"hex\");\n const authTag = Buffer.from(authTagHex, \"hex\");\n const encrypted = Buffer.from(encryptedHex, \"hex\");\n const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });\n decipher.setAuthTag(authTag);\n return decipher.update(encrypted) + decipher.final(\"utf8\");\n}\n\n/**\n * Returns true when the value looks like AES-256-GCM ciphertext\n * (iv:authTag:data, all hex). Plaintext OAuth tokens (e.g. gho_xxx) will not match.\n */\nexport function isEncrypted(value: string): boolean {\n const parts = value.split(\":\");\n return parts.length === 3 && parts.every((p) => /^[0-9a-f]+$/.test(p));\n}\n\n/**\n * Decrypt if the value is in encrypted format, otherwise return as-is.\n * Allows graceful handling of pre-migration plaintext tokens.\n */\nexport function decryptIfEncrypted(value: string): string {\n return isEncrypted(value) ? decrypt(value) : value;\n}\n\n/** Safe wrapper that returns `null` instead of throwing on invalid/stale ciphertext. */\nexport function tryDecrypt(ciphertext: string, logger: Logger = consoleLogger): string | null {\n try {\n return decryptIfEncrypted(ciphertext);\n } catch {\n logger.warn(\"Failed to decrypt stored token — likely stale or re-keyed\");\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAS,SAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGA,SAAS,gBAAgB,UAA6C;AACpE,QAAM,OACJ,OAAO,aAAa,aACf,WACD,CAAC,YAAsB,SAAS,OAAO,IAAI,QAAQ,QAAQ,IAAI;AACrE,SAAO,CAAC,YAAY;AAClB,QAAI;AACF,YAAM,QAAQ,KAAK,OAAO;AAC1B,aAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AAAA,IACjE,QAAQ;AAEN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AASA,SAAS,YAAY,MAA2D;AAC9E,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,MAAM;AAAA,EACf;AACA,QAAM,WAAW,gBAAgB,IAAI;AACrC,SAAO,CAAC,YAAY;AAClB,UAAM,OAAO,SAAS,OAAO;AAC7B,WAAO,SAAS,UAAa,mBAAmB,IAAI,MAAM,UAAa,eAAe,IAAI,IACtF,SACA;AAAA,EACN;AACF;AAEA,SAAS,gBAAgB,KAA6C;AACpE,QAAM,EAAE,SAAS,IAAI;AACrB,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,EAAE,KAAK,IAAI;AACjB,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,EAAE,MAAM,cAAc,QAAQ,KAAK,OAAO;AAAA,EACnD;AACA,MAAI,SAAS,QAAW;AACtB,WAAO,EAAE,MAAM,QAAQ,QAAQ,YAAY,IAAI,EAAE;AAAA,EACnD;AACA,MAAI,SAAS,eAAe,QAAW;AACrC,WAAO,EAAE,MAAM,UAAU,QAAQ,gBAAgB,SAAS,MAAM,EAAE;AAAA,EACpE;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YAAY,SAAS;AAAA,IACrB,QAAQ,gBAAgB,SAAS,KAAK;AAAA,EACxC;AACF;AAEA,SAAS,mBAAmBA,QAAe,QAAiBC,OAA2B;AACrF,MAAI,WAAW,UAAa,WAAW,iBAAiB;AACtD,WAAO;AAAA,EACT;AACA,QAAM,OAAO,SAAS,MAAM,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC;AACvD,MAAI,CAAC,SAAS,MAAM,KAAK,KAAK,WAAW,KAAK,CAAC,cAAc,OAAO,OAAO,GAAG;AAC5E,IAAAA,MAAK,GAAGD,MAAK,wDAAwD;AAAA,EACvE;AACA,SAAO,OAAO,OAAO,EAAE,SAAS,OAAO,QAAQ,CAAC;AAClD;AAEA,SAAS,aACP,SACA,MACA,KACA,OACA,OACAC,OACgB;AAChB,QAAMD,SAAQ,YAAY,IAAI;AAC9B,QAAM,iBAAiB,OAAO,UAAU,aAAa,EAAE,SAAS,MAAM,IAAI;AAC1E,MAAI,CAAC,SAAS,cAAc,KAAK,OAAO,eAAe,YAAY,YAAY;AAC7E,IAAAC,MAAK,GAAGD,MAAK,oDAAoD;AAAA,EACnE;AACA,QAAM,aAAa,OAAO,KAAK,cAAc,EAAE;AAAA,IAC7C,CAAC,QAAQ,CAAC,CAAC,UAAU,SAAS,EAAE,SAAS,GAAG;AAAA,EAC9C;AACA,MAAI,eAAe,QAAW;AAC5B,IAAAC,MAAK,GAAGD,MAAK,2BAA2B,UAAU,oCAAoC;AAAA,EACxF;AACA,QAAM,gBAAgB,IAAI,iBAAiB;AAC3C,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA,SAAS,IAAI;AAAA,IACb;AAAA;AAAA,IAEA,OAAO,IAAI,SAAS,KAAK,IAAI,GAAG,gBAAgB,CAAC;AAAA,IACjD,UAAU,gBAAgB,GAAG;AAAA,IAC7B,QAAQ,mBAAmBA,QAAO,eAAe,QAAQC,KAAI;AAAA,IAC7D,gBAAgB,eAAe,WAAW;AAAA,IAC1C;AAAA,IACA,SAAS,eAAe;AAAA,EAC1B,CAAC;AACH;AAOO,SAAS,gBACd,UACA,OACA,OACAA,OACqC;AACrC,QAAM,WAAW,OAAO,QAAQ,SAAS,QAAQ;AACjD,MAAI,UAAU,UAAa,SAAS,WAAW,GAAG;AAChD,WAAO,oBAAI,IAAI;AAAA,EACjB;AACA,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,IAAAA,MAAK,yEAAyE;AAAA,EAChF;AACA,QAAMC,WAAU,SAAS,OAAO,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,OAAO,OAAO,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAC7F,MAAIA,SAAQ,SAAS,GAAG;AACtB,IAAAD,MAAK,sCAAsCC,SAAQ,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5F;AACA,QAAM,WAAW,oBAAI,IAA4B;AACjD,QAAM,WAAW,UAAU,SAAY,SAAY,IAAI,IAAI,KAAK;AAChE,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,UAAM,MAAM,OAAO,OAAO,SAAS,UAAU,IAAI,IAAI,SAAS,SAAS,IAAI,IAAI;AAC/E,QAAI,QAAQ,QAAW;AACrB,MAAAD,MAAK,IAAI,IAAI,oCAAoC;AAAA,IACnD;AACA,aAAS,IAAI,MAAM,aAAa,SAAS,MAAM,MAAM,KAAK,OAAO,UAAUA,KAAI,CAAC;AAAA,EAClF;AACA,SAAO;AACT;AAGA,SAAS,WAAW,QAA0D;AAC5E,MAAI,WAAW,UAAa,OAAO,WAAW,UAAU;AACtD,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,QAAW;AAE7B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,QAAW;AAC9B,WAAO,OAAO,OAAO,EAAE,OAAO,OAAO,OAAO,IAAI,OAAO,IAAI,IAAI,QAAQ,CAAC;AAAA,EAC1E;AACA,MAAI,OAAO,UAAU,QAAW;AAC9B,UAAM,UAAU,OAAO,YAAY,SAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;AAC9E,WAAO,OAAO,OAAO,EAAE,OAAO,OAAO,OAAO,GAAG,SAAS,IAAI,QAAQ,CAAC;AAAA,EACvE;AACA,SAAO,OAAO,OAAO,EAAE,SAAS,OAAO,QAAQ,CAAC;AAClD;AAGA,SAAS,WAAW,QAAgE;AAClF,MAAI,OAAO,WAAW,YAAY,OAAO,SAAS,QAAW;AAC3D,WAAO;AAAA,EACT;AACA,QAAM,EAAE,KAAK,IAAI;AACjB,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,OAAO,OAAO,EAAE,MAAM,QAAQ,KAAK,CAAC;AAAA,EAC7C;AACA,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,OAAO,OAAO,EAAE,MAAM,UAAU,QAAQ,KAAK,OAAO,CAAC;AAAA,EAC9D;AACA,QAAM,WAAW,YAAY,IAAqD;AAClF,SAAO,OAAO,OAAO;AAAA,IACnB,MAAM;AAAA,IACN,QAAQ,CAAC,UAA8B,SAAS,KAAK;AAAA,EACvD,CAAC;AACH;AAQA,IAAM,qBAAqB,CAAC,QAAQ,UAAU;AAG9C,SAAS,mBACP,MACA,KACA,OACAA,OACiD;AACjD,QAAMD,SAAQ,WAAW,IAAI;AAC7B,MAAI,UAAU,QAAW;AACvB,WAAO,EAAE,aAAa,QAAW,UAAU,SAAS;AAAA,EACtD;AACA,MAAI,CAAC,SAAS,KAAK,GAAG;AACpB,IAAAC,MAAK,GAAGD,MAAK,0CAA0C;AAAA,EACzD;AACA,QAAM,aAAa,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,mBAAmB,SAAS,GAAG,CAAC;AACrF,MAAI,eAAe,QAAW;AAC5B,IAAAC;AAAA,MACE,GAAGD,MAAK,2BAA2B,UAAU,sBAAsB,mBAAmB,KAAK,IAAI,CAAC;AAAA,IAClG;AAAA,EACF;AACA,QAAM,EAAE,KAAK,IAAI;AACjB,MAAI,SAAS,UAAa,OAAO,SAAS,YAAY;AACpD,IAAAC,MAAK,GAAGD,MAAK,qEAAqE;AAAA,EACpF;AACA,MAAI,SAAS,WAAc,IAAI,QAAQ,KAAK,GAAG;AAC7C,IAAAC;AAAA,MACE,GAAGD,MAAK,uEAAuE,OAAO,IAAI,IAAI,CAAC;AAAA,IACjG;AAAA,EACF;AACA,QAAM,EAAE,WAAW,SAAS,IAAI;AAChC,MAAI,aAAa,YAAY,aAAa,eAAe;AACvD,IAAAC,MAAK,GAAGD,MAAK,6CAA6C;AAAA,EAC5D;AACA,SAAO,EAAE,aAAa,MAAmC,SAAS;AACpE;AAEA,SAAS,YACP,MACA,KACA,OACA,SACAC,OACe;AACf,QAAM,SAAS,WAAW,IAAI,MAAM;AACpC,MAAI,OAAO,WAAW,YAAY,WAAW,UAAU,CAAC,MAAM,WAAW;AACvE,IAAAA;AAAA,MACE,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AACA,MAAI,OAAO,WAAW,YAAY,WAAW,UAAU,MAAM,UAAU,QAAW;AAChF,IAAAA;AAAA,MACE,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,MAAM,IAAI;AAAA,IACV,QAAQ,eAAe,GAAG;AAAA,IAC1B,MAAM,IAAI,QAAQ;AAAA,IAClB,GAAG,mBAAmB,MAAM,KAAK,SAASA,KAAI;AAAA,IAC9C,UAAU,IAAI,aAAa;AAAA,IAC3B;AAAA,IACA,MAAM,WAAW,IAAI,MAAM;AAAA,EAC7B,CAAC;AACH;AAOO,SAAS,eACd,UACA,OACA,OACAA,OACoC;AACpC,MAAI,UAAU,UAAa,CAAC,SAAS,KAAK,GAAG;AAC3C,IAAAA;AAAA,MACE;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,SAAS,CAAC;AAC1B,QAAM,gBAAgB,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,OAAO,SAAS,SAAS,IAAI,CAAC;AAChG,MAAI,kBAAkB,QAAW;AAC/B,IAAAA,MAAK,aAAa,aAAa,mCAAmC;AAAA,EACpE;AACA,QAAM,UAAU,oBAAI,IAA2B;AAC/C,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAO,GAAG;AAC1D,UAAM,QAAQ,OAAO,OAAO,SAAS,IAAI,IAAI,QAAQ,IAAI,IAAI;AAC7D,YAAQ,IAAI,MAAM,YAAY,MAAM,KAAK,OAAO,OAAOA,KAAI,CAAC;AAAA,EAC9D;AACA,SAAO;AACT;;;AC3RA,SAASE,UAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,OAAO,OAAiC;AAC/C,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS;AACrD;AAEA,SAAS,WAAW,OAAsC;AACxD,SAAOA,UAAS,KAAK,KAAK,OAAO,MAAM,IAAI,KAAK,OAAO,SAAS,KAAK;AACvE;AAGA,SAAS,MAAM,OAAmC;AAChD,MAAI,OAAO,KAAK,GAAG;AACjB,WAAO,CAAC,KAAK;AAAA,EACf;AACA,SAAO,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,MAAM,IAAI,CAAC;AACxD;AAEA,SAAS,UAAU,OAAe,OAAgBC,OAAyB;AACzE,QAAMC,SAAQ,WAAW,KAAK;AAC9B,MAAI,CAACF,UAAS,KAAK,KAAK,CAAC,WAAW,MAAM,OAAO,GAAG;AAClD,IAAAC,MAAK,GAAGC,MAAK,oCAAoC;AAAA,EACnD;AACA,QAAM,EAAE,IAAI,QAAQ,IAAI;AACxB,MAAI,OAAO,EAAE,GAAG;AACd,QAAI,YAAY,QAAW;AACzB,MAAAD,MAAK,GAAGC,MAAK,oEAAoE;AAAA,IACnF;AACA,WAAO,OAAO,OAAO;AAAA,MACnB,SAAS,MAAM;AAAA,MACf,SAAS,OAAO,OAAO,CAAC,EAAE,CAAC;AAAA,MAC3B,KAAK,CAAC,WAA0B,MAAM,OAAO,EAAE,CAAC;AAAA,IAClD,CAAC;AAAA,EACH;AACA,QAAM,SAAS,MAAM,QAAQ,OAAO,KAAK,QAAQ,SAAS,KAAK,QAAQ,MAAM,MAAM;AACnF,MAAI,OAAO,OAAO,cAAc,CAAC,QAAQ;AACvC,IAAAD;AAAA,MACE,GAAGC,MAAK;AAAA,IACV;AAAA,EACF;AACA,QAAM,OAAO;AACb,SAAO,OAAO,OAAO;AAAA,IACnB,SAAS,MAAM;AAAA,IACf,SAAS,OAAO,OAAO,CAAC,GAAI,OAA6B,CAAC;AAAA,IAC1D,KAAK,CAAC,WAA0B,MAAM,KAAK,MAAM,CAAC;AAAA,EACpD,CAAC;AACH;AAEA,SAAS,aAAa,OAAgB,OAA2BD,OAA2B;AAC1F,MAAI,UAAU,QAAW;AACvB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,IAAAA,MAAK,2CAA2C;AAAA,EAClD;AACA,MAAI,UAAU,QAAW;AACvB,IAAAA,MAAK,uEAAuE;AAAA,EAC9E;AACA,SAAO,MAAM,IAAI,CAAC,OAAgB,UAAU,UAAU,OAAO,OAAOA,KAAI,CAAC;AAC3E;AAEA,SAAS,YAAY,OAAgBA,OAA+B;AAClE,MAAI,UAAU,QAAW;AACvB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,MAAM,GAAG;AACjD,IAAAA,MAAK,8EAA8E;AAAA,EACrF;AACA,SAAO,OAAO,OAAO,CAAC,GAAI,KAA2B,CAAC;AACxD;AAGA,SAAS,iBAAiB,OAAgBA,OAAqC;AAC7E,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,MAAI,UAAU,YAAY,UAAU,iBAAiB;AACnD,WAAO;AAAA,EACT;AACA,MAAI,CAACD,UAAS,KAAK,KAAK,OAAO,KAAK,KAAK,EAAE,WAAW,KAAK,CAAC,cAAc,MAAM,OAAO,GAAG;AACxF,IAAAC,MAAK,qEAAqE;AAAA,EAC5E;AACA,SAAO,OAAO,OAAO,EAAE,SAAS,MAAM,QAAQ,CAAC;AACjD;AAMO,SAAS,cAAc,OAA+C;AAC3E,SAAO,YAAY,OAAO,QAAW,CAAC,YAAY;AAChD,UAAM,IAAI,UAAU,kBAAkB,OAAO,EAAE;AAAA,EACjD,CAAC;AACH;AAQO,SAAS,iBACdC,QACA,OACA,MACAD,OAC+B;AAC/B,MAAI,MAAM,UAAU,UAAa,MAAM,WAAW,UAAU;AAC1D,IAAAA;AAAA,MACE,GAAGC,MAAK;AAAA,IACV;AAAA,EACF;AACA,SAAO;AAAA,IAAY,MAAM;AAAA,IAAO,EAAE,OAAO,KAAK,OAAO,IAAI,cAAc;AAAA,IAAG,CAAC,YACzED,MAAK,GAAGC,MAAK,KAAK,OAAO,EAAE;AAAA,EAC7B;AACF;AAMO,SAAS,kBACdA,QACA,OACAD,OACyB;AACzB,SAAO,aAAaC,QAAO,OAAOD,KAAI;AACxC;AAOO,SAAS,iBACd,YACA,UACAA,OACa;AACb,QAAM,EAAE,OAAO,QAAQ,cAAc,IAAI;AACzC,MAAI,UAAU,UAAa,CAAC,OAAO,KAAK,GAAG;AACzC,IAAAA,MAAK,oFAAoF;AAAA,EAC3F;AACA,MAAI,WAAW,UAAa,CAAC,eAAe,MAAM,GAAG;AACnD,IAAAA,MAAK,sFAAsF;AAAA,EAC7F;AACA,MAAI,WAAW,UAAa,UAAU,QAAW;AAC/C,IAAAA,MAAK,4EAA4E;AAAA,EACnF;AACA,MAAI,kBAAkB,WAAc,CAAC,OAAO,aAAa,KAAK,UAAU,SAAY;AAClF,IAAAA,MAAK,0EAA0E;AAAA,EACjF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,YAAY,WAAW,QAAQA,KAAI;AAAA,IAC3C,SAAS,OAAO,OAAO,aAAa,WAAW,SAAS,OAAOA,KAAI,CAAC;AAAA,IACpE;AAAA,IACA,aAAa,iBAAiB,WAAW,aAAaA,KAAI;AAAA,IAC1D,OAAO,YAAY,WAAW,OAAO,EAAE,OAAO,UAAU,IAAI,gBAAgB,GAAGA,KAAI;AAAA,EACrF;AACF;AAOO,SAAS,mBACd,UACA,MACA,QACA,MACAA,OACM;AACN,QAAM,MAAM,CAAC,KAAK,OAAO,GAAG,KAAK,MAAM,EAAE,OAAO,CAAC,UAAU,UAAU,MAAS,EAAE,IAAI,QAAQ;AAC5F,QAAM,SAAS,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC;AACjD,QAAM,QACJ,OAAO,SAAS,KAChB,OAAO,MAAM,CAAC,UAAU,OAAO,UAAU,YAAY,UAAU,EAAE,KACjE,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,SAAS,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,OAAO;AAC1E,MAAI,CAAC,OAAO;AACV,IAAAA;AAAA,MACE,WAAW,IAAI;AAAA,IACjB;AAAA,EACF;AACA,aAAW,SAAS,QAAoB;AACtC,QAAI,CAAC,IAAI,SAAS,SAAS,KAAK,CAAC,GAAG;AAClC,YAAM,QAAQ,IAAI,WAAW,IAAI,SAAS,IAAI,IAAI,CAAC,QAAQ,IAAI,GAAG,GAAG,EAAE,KAAK,IAAI;AAChF,MAAAA;AAAA,QACE,WAAW,IAAI,wBAAwB,KAAK,YAAY,SAAS,IAAI,mEAAmE,KAAK;AAAA,MAC/I;AAAA,IACF;AAAA,EACF;AACF;;;ACjMA,IAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,cAAc,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAASE,UAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,UACP,OACA,SACAC,QACAC,OACM;AACN,QAAM,aAAa,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,IAAI,GAAG,CAAC;AACrE,MAAI,eAAe,QAAW;AAC5B,IAAAA;AAAA,MACE,GAAGD,MAAK,2BAA2B,UAAU,sBAAsB,CAAC,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IAC5F;AAAA,EACF;AACF;AAEA,SAAS,WAAW,OAAgB,KAA8B;AAChE,SAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ,KAAK,SAAS;AACtF;AAEA,SAAS,cAAc,UAAgC;AACrD,QAAM,QACJD,UAAS,QAAQ,KACjB,OAAO,SAAS,SAAS,YACzB,SAAS,KAAK,SAAS,KACvBA,UAAS,SAAS,OAAO,KACzB,OAAO,SAAS,QAAQ;AAC1B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,UAAU,0EAA0E;AAAA,EAChG;AACA,SAAO;AACT;AAEA,SAAS,WAAWC,QAAe,OAAsBC,OAAkB;AACzE,QAAM,EAAE,OAAO,MAAM,IAAI;AACzB,MAAI,UAAU,UAAa,UAAU,YAAY,UAAU,OAAO;AAChE,IAAAA,MAAK,GAAGD,MAAK,mCAAmC;AAAA,EAClD;AACA,MAAI,UAAU,SAASD,UAAS,MAAM,MAAM,KAAK,MAAM,OAAO,SAAS,UAAU;AAC/E,IAAAE;AAAA,MACE,GAAGD,MAAK;AAAA,IACV;AAAA,EACF;AACA,MAAI,UAAU,SAAS,OAAO,MAAM,YAAY,cAAc,kBAAkB,MAAM,OAAO,GAAG;AAC9F,IAAAC;AAAA,MACE,GAAGD,MAAK;AAAA,IACV;AAAA,EACF;AACA,MAAI,UAAU,WAAc,UAAU,UAAa,CAAC,WAAW,OAAO,cAAc,IAAI;AACtF,IAAAC,MAAK,GAAGD,MAAK,mEAAmE;AAAA,EAClF;AACF;AAEA,SAAS,kBACPA,QACA,OACA,MACAC,OACM;AACN,QAAM,YAAY,CAAC,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,EAAE,KAAK,CAAC,UAAU,UAAU,MAAS;AAC/F,MAAI,SAAS,cAAc,WAAW;AACpC,IAAAA,MAAK,GAAGD,MAAK,0DAA0D;AAAA,EACzE;AACA,aAAWA,QAAO,OAAOC,KAAI;AAC7B,MAAI,MAAM,YAAY,UAAa,OAAO,MAAM,YAAY,YAAY;AACtE,IAAAA,MAAK,GAAGD,MAAK,8CAA8C;AAAA,EAC7D;AACF;AAEA,SAAS,YACP,UACA,aACA,MACA,MACA,OACAC,OACe;AACf,QAAMD,SAAQ,WAAW,IAAI;AAC7B,QAAM,MAAM,SAAS,QAAQ,IAAI;AACjC,MAAI,QAAQ,QAAW;AACrB,IAAAC,MAAK,IAAI,IAAI,mCAAmC;AAAA,EAClD;AACA,MAAI,CAACF,UAAS,KAAK,GAAG;AACpB,IAAAE,MAAK,GAAGD,MAAK,8BAA8B;AAAA,EAC7C;AACA,YAAU,OAAO,aAAaA,QAAOC,KAAI;AACzC,QAAM,gBAAgB,kBAAkB,MAAM,MAAM;AACpD,MAAI,kBAAkB,QAAW;AAC/B,IAAAA,MAAK,GAAGD,MAAK,YAAY,aAAa,EAAE;AAAA,EAC1C;AACA,MAAI,OAAO,MAAM,YAAY,YAAY;AACvC,IAAAC,MAAK,GAAGD,MAAK,2BAA2B;AAAA,EAC1C;AACA,MAAI,MAAM,cAAc,UAAa,CAAC,WAAW,MAAM,WAAW,cAAc,GAAG;AACjF,IAAAC;AAAA,MACE,GAAGD,MAAK,kEAAkE,cAAc;AAAA,IAC1F;AAAA,EACF;AACA,MAAI,MAAM,YAAY,UAAa,OAAO,MAAM,YAAY,WAAW;AACrE,IAAAC,MAAK,GAAGD,MAAK,qCAAqC;AAAA,EACpD;AACA,oBAAkBA,QAAO,OAAO,IAAI,MAAMC,KAAI;AAC9C,QAAM,QAAQ,iBAAiBD,QAAO,OAAO,MAAMC,KAAI;AACvD,QAAM,SAAS,kBAAkBD,QAAO,OAAOC,KAAI;AACnD,QAAM,aAAa,gBAAgB,IAAI,QAAQ,WAAW;AAC1D,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA,MAAM,IAAI;AAAA,IACV,OAAO,IAAI;AAAA,IACX,QAAQ,eAAe,UAAU,IAAI,MAAM;AAAA,IAC3C;AAAA,IACA,cAAc,eAAe,SAAY,eAAe,IAAI,MAAM,IAAI;AAAA,IACtE,QAAQ,MAAM;AAAA,IACd;AAAA,IACA;AAAA,IACA,SAAS,MAAM;AAAA,IACf,OAAO,MAAM;AAAA,IACb,OAAO,MAAM;AAAA,IACb,WAAW,MAAM;AAAA,IACjB,SAAS,MAAM;AAAA,IACf,SAAS,MAAM,YAAY;AAAA,EAC7B,CAAC;AACH;AAEA,SAAS,aACP,UACA,aACA,MACA,OACAA,OAC+B;AAC/B,MAAI,CAACF,UAAS,KAAK,GAAG;AACpB,IAAAE,MAAK,uEAAuE;AAAA,EAC9E;AACA,QAAMC,WAAU,OAAO,KAAK,SAAS,OAAO,EAAE,OAAO,CAAC,SAAS,CAAC,OAAO,OAAO,OAAO,IAAI,CAAC;AAC1F,MAAIA,SAAQ,SAAS,GAAG;AACtB,IAAAD,MAAK,qCAAqCC,SAAQ,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC3F;AACA,QAAM,UAAyC,CAAC;AAChD,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,YAAQ,IAAI,IAAI,YAAY,UAAU,aAAa,MAAM,MAAM,OAAOD,KAAI;AAAA,EAC5E;AACA,SAAO;AACT;AAUA,SAAS,aACP,UACA,aACA,MACAA,OACM;AACN,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAO,GAAG;AAC1D,UAAM,QAAiB,IAAI;AAC3B,QAAI,UAAU,QAAW;AACvB;AAAA,IACF;AACA,QAAI,IAAI,SAAS,SAAS;AACxB,MAAAA,MAAK,WAAW,IAAI,yCAAyC;AAAA,IAC/D;AACA,QAAI,UAAU,aAAcF,UAAS,KAAK,KAAK,OAAO,OAAO,OAAO,SAAS,GAAI;AAC/E,UAAI,KAAK,gBAAgB,QAAW;AAClC,QAAAE;AAAA,UACE,WAAW,IAAI;AAAA,QACjB;AAAA,MACF;AACA,UAAI,UAAU,WAAW;AACvB,2BAAmB,UAAU,MAAM,MAAM,SAAS,MAAMA,KAAI;AAAA,MAC9D;AACA;AAAA,IACF;AACA,QAAI,CAACF,UAAS,KAAK,KAAK,OAAO,MAAM,UAAU,YAAY;AACzD,MAAAE,MAAK,WAAW,IAAI,uEAAuE;AAAA,IAC7F;AACA,QAAI,OAAO,MAAM,eAAe,YAAY,CAAC,YAAY,IAAI,MAAM,UAAU,GAAG;AAC9E,MAAAA;AAAA,QACE,WAAW,IAAI,cAAc,OAAO,MAAM,UAAU,CAAC,mCAAmC,SAAS,IAAI;AAAA,MACvG;AAAA,IACF;AAAA,EACF;AACF;AAQA,SAAS,cACP,SACA,MACAA,OACM;AACN,aAAW,UAAU,OAAO,OAAO,OAAO,GAAG;AAC3C,UAAM,OAAO,OAAO;AACpB,QAAI,OAAO,SAAS,YAAY,eAAe,IAAI,GAAG;AACpD;AAAA,IACF;AACA,QAAI,KAAK,UAAU,UAAa,KAAK,WAAW,QAAW;AACzD,MAAAA;AAAA,QACE,WAAW,OAAO,IAAI;AAAA,MACxB;AAAA,IACF;AACA,QAAI,KAAK,UAAU,UAAa,KAAK,UAAU,QAAW;AACxD,MAAAA;AAAA,QACE,WAAW,OAAO,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;AASA,SAAS,aACP,UACA,SACA,MACAA,OACM;AACN,MAAI,KAAK,WAAW,QAAW;AAC7B;AAAA,EACF;AACA,aAAW,UAAU,OAAO,OAAO,OAAO,GAAG;AAC3C,UAAM,UAAU,eAAe,QAAQ,SAAS,IAAI;AACpD,QAAI,YAAY,QAAW;AACzB,MAAAA,MAAK,OAAO;AAAA,IACd;AAAA,EACF;AACF;AAGA,SAAS,cAAc,SAAqBA,OAAkB;AAC5D,aAAW,UAAU,OAAO,OAAO,QAAQ,OAAO,GAAG;AACnD,UAAM,UAAU,eAAe,OAAO,SAAS,OAAO;AACtD,QAAI,YAAY,QAAW;AACzB,MAAAA,MAAK,WAAW,OAAO,IAAI,MAAM,OAAO,EAAE;AAAA,IAC5C;AAAA,EACF;AACF;AASO,SAAS,cACd,SACA,OACgB;AAChB,MAAI,YAAY,QAAW;AACzB,WAAO,OAAO,OAAO,EAAE,eAAe,QAAW,OAAO,QAAW,MAAM,CAAC;AAAA,EAC5E;AACA,MAAI,OAAO,YAAY,YAAY,YAAY,MAAM;AACnD,UAAM,IAAI,UAAU,0CAA0C;AAAA,EAChE;AACA,QAAM,EAAE,SAAS,MAAM,IAAI;AAC3B,MAAI,YAAY,UAAa,OAAO,YAAY,YAAY;AAC1D,UAAM,IAAI,UAAU,+DAA+D;AAAA,EACrF;AACA,SAAO,OAAO,OAAO;AAAA,IACnB,eAAe;AAAA,IACf,OAAO,cAAc,KAAK;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AAGO,SAAS,aACd,SACA,UACA,YACY;AACZ,QAAME,WAAU,cAAc,QAAQ;AACtC,QAAMF,QAAa,CAAC,YAAY;AAC9B,UAAM,IAAI,UAAU,kBAAkBE,SAAQ,IAAI,OAAO,OAAO,EAAE;AAAA,EACpE;AACA,MAAI,CAACJ,UAAS,UAAU,GAAG;AACzB,IAAAE,MAAK,kCAAkC;AAAA,EACzC;AACA,YAAU,YAAY,iBAAiB,kBAAkBA,KAAI;AAC7D,QAAM,EAAE,cAAc,MAAM,YAAY,IAAI;AAC5C,MAAI,OAAO,gBAAgB,WAAW;AACpC,IAAAA,MAAK,+BAA+B;AAAA,EACtC;AACA,MAAI,gBAAgB,UAAa,OAAO,gBAAgB,YAAY;AAClE,IAAAA,MAAK,+DAA+D;AAAA,EACtE;AACA,QAAM,OAAO,iBAAiB,YAAY,QAAQ,OAAOA,KAAI;AAC7D,QAAM,cAAc,mBAAmBE,UAAS,WAAW,SAASF,KAAI;AACxE,QAAM,cAAc;AAAA,IAClBE;AAAA,IACA;AAAA,IACA,KAAK;AAAA,IACL,WAAW;AAAA,IACXF;AAAA,IACA,KAAK;AAAA,EACP;AACA,eAAaE,UAAS,aAAa,MAAMF,KAAI;AAC7C,QAAM,UAAU,aAAaE,UAAS,aAAa,MAAM,WAAW,SAASF,KAAI;AACjF,gBAAc,SAAS,MAAMA,KAAI;AACjC,eAAaE,UAAS,SAAS,MAAMF,KAAI;AACzC,QAAM,UAAsB,OAAO,OAAO;AAAA,IACxC,MAAME,SAAQ;AAAA,IACd,UAAUA;AAAA,IACV,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,OAAO,OAAO,OAAO;AAAA,IAC9B,UAAU,gBAAgBA,UAAS,WAAW,UAAU,KAAK,OAAOF,KAAI;AAAA,IACxE,SAAS;AAAA,MACPE;AAAA,MACA,EAAE,OAAO,KAAK,OAAO,WAAW,KAAK,WAAW,OAAU;AAAA,MAC1D,WAAW;AAAA,MACXF;AAAA,IACF;AAAA,IACA;AAAA,EACF,CAAC;AACD,gBAAc,SAASA,KAAI;AAC3B,kBAAgB,SAAS,OAAO;AAChC,SAAO;AACT;;;AC5OA,IAAM,QAA0C,OAAO,OAAO;AAAA,EAC5D,wBAAwB;AAAA,EACxB,aAAa;AAAA,EACb,eAAe;AAAA,EACf,YAAY;AACd,CAAC;AAED,SAAS,aAAa,QAAuB;AAC3C,QAAM,IAAI;AAAA,IACR;AAAA,IACA,GAAG,MAAM,yBAAyB,MAAM,MAAM,KAAK,cAAc;AAAA,EACnE;AACF;AAKA,SAAS,SACP,SACA,UACA,MACmC;AACnC,QAAM,UACJ,OAAO,aAAa,YAAY,aAAa,OAAO,SAAS,UAAU;AACzE,MAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,CAAC,OAAO,OAAO,SAAS,IAAI,GAAG;AACpF,UAAM,IAAI;AAAA,MACR,cAAc,OAAO,UAAU,IAAI,CAAC,wBAAwB,OAAO,IAAI,CAAC;AAAA,IAC1E;AAAA,EACF;AACA,MAAI;AAGJ,QAAM,SAAS,MAAyC;AACtD,UAAM,OAAO,QAAQ,KAAK,aAAa,WAAW;AAClD,QAAI,UAAU,SAAS,MAAM;AAC3B,iBAAW,EAAE,MAAM,QAAQ,KAAK,OAAO,UAAU,IAAI,EAAE;AAAA,IACzD;AACA,WAAO,SAAS;AAAA,EAClB;AACA,SAAO,OAAO,OAAO;AAAA,IACnB,QAAQ,MAAuB;AAC7B,MAAC,OAAO,EAAE,KAAuC,GAAG,IAAI;AAAA,IAC1D;AAAA,IACA,YAAY,MAAuB;AACjC,MAAC,OAAO,EAAE,SAA2C,GAAG,IAAI;AAAA,IAC9D;AAAA,EACF,CAAC;AACH;AAGA,SAAS,WAAW,SAA4B;AAC9C,QAAM,WAAW,OAAiB,QAAQ,KAAK,aAAa,aAAa,GAAG;AAC5E,SAAO,OAAO,OAAO;AAAA,IACnB,UAAU,OAAO,WAAmB,MAAM,SAAS,EAAE,SAAS,MAAM;AAAA,IACpE,UAAU,OAAO,WAAmB,MAAM,SAAS,EAAE,SAAS,MAAM;AAAA,IACpE,OAAO,OAAO,SAAiB,MAAM,SAAS,EAAE,MAAM,IAAI;AAAA,IAC1D,OAAO,OAAO,SAAiB,MAAM,SAAS,EAAE,MAAM,IAAI;AAAA,EAC5D,CAAC;AACH;AAGA,SAAS,QAAQ,SAA+B;AAC9C,QAAM,QAAQ,OAAoB,QAAQ,KAAK,aAAa,UAAU,GAAG;AACzE,SAAO,OAAO,OAAO;AAAA,IACnB,MAAM,IAAI,SAA0C;AAClD,YAAM,EAAE,KAAK,GAAG,IAAI;AAAA,IACtB;AAAA,IACA,YAAY,IAAI,SAAgD;AAC9D,YAAM,EAAE,WAAW,GAAG,IAAI;AAAA,IAC5B;AAAA,IACA,OAAO,OAAO,MAAc,WAC1B,MAAM,MAAM,EAAE,MAAM,MAAM,MAAM;AAAA,IAClC,MAAM,CAAC,SAAiB,MAAM,EAAE,KAAK,IAAI;AAAA,EAC3C,CAAC;AACH;AAUO,SAAS,iBACX,MACW;AACd,MAAI;AACJ,QAAM,UAAU,cAAc,KAAK,CAAC,GAAG,CAAC,eAAe;AACrD,cAAU;AAAA,EACZ,CAAC;AACD,QAAM,KAAmB;AAAA,IACvB,gBAAgB,CAAC,UAAmB,eAClC,aAAa,SAAS,UAAU,UAAU;AAAA,IAC5C,iBAAiB,SAAS;AACxB,YAAM,aAAa,iBAAiB,OAAO;AAC3C,gBAAU;AACV,aAAO;AAAA,IACT;AAAA,IACA,QAAQ,CAAC,cACP,aAAa,OAAO,WAAW,aAAa,WAAW,GAAG,MAAM,WAAW;AAAA,MACzE,QAAQ,MAAM,eAAe,OAAO;AAAA,IACtC,CAAC;AAAA,IACH,KAAK,OAAO,IAAI,YACd,YAAY,SACR,MAAM,uBAAuB,IAAI,OAAO,IACxC,MAAM,QAAQ,IAAI,IAAI,OAAO;AAAA,IACnC,aAAa,OAAO,OAAO;AAAA,MACzB,OAAO,CAAC,UAAU,YAAY,UAAU;AACtC,SAAC,WAAW,aAAa,sBAAsB,GAAG,YAAY;AAAA,UAC5D;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAiC;AAAA,IACjC,QAAQ,CAA+D,UAAa,SAClF,SAAS,MAAM,SAAS,UAAU,IAAI;AAAA,IACxC,UAAU,WAAW,MAAM,OAAO;AAAA,IAClC,OAAO,QAAQ,MAAM,OAAO;AAAA,IAC5B,aAAa,SAAS;AACpB,YAAM,SAAS,aAAa,OAAO;AACnC,gBAAU,OAAO;AACjB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO,OAAO,OAAO,EAAE;AACzB;;;AC1RO,SAAS,MAAkC,OAA0C;AAC1F,YAAU,gBAAgB,SAAS,KAAK;AACxC,SAAO,aAAa;AAAA,IAClB,MAAM;AAAA,IACN;AAAA,IACA,OAAO,EAAE,SAAS,CAAC,KAAK,GAAG,aAAa,CAAC,GAAG,UAAU,CAAC,GAAG,SAAS,KAAK;AAAA,IACxE,MAAM,UAAU,WAAW,KAAK,OAAO;AACrC,YAAM,OAAO,MAAM,MAAM,KAAK,GAAG;AACjC,aAAO,WAAW,KAAK,CAAC,OAAQ,KAAK,IAAI,EAAE,IAAI,KAAK,MAAM,UAAU,SAAS,UAAU,IAAK;AAAA,IAC9F;AAAA,IACA,aAAa,CAAC,cAAc,QAAQ,QAAQ,EAAE,CAAC,KAAK,GAAG,UAAU,OAAO,CAAC;AAAA,EAC3E,CAAC;AACH;;;ACQA,IAAM,UAAU,oBAAI,QAAgC;AAM7C,SAAS,iBAAiB,QAAqD;AACpF,SAAO,QAAQ,IAAI,MAAM;AAC3B;AAEA,SAASG,UAAS,OAA4D;AAC5E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAQA,SAAS,SAAS,KAAc,QAA0B;AACxD,MAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACvB,WAAO;AAAA,EACT;AACA,MAAI,QAAkB;AACtB,aAAW,SAAS,KAAK;AACvB,QAAIA,UAAS,KAAK,KAAK,MAAM,WAAW,QAAQ;AAC9C,cAAQ,SAAS,OAAO,MAAM,KAAoB;AAAA,IACpD;AAAA,EACF;AACA,SAAO;AACT;AAcO,SAAS,QACd,OACA,UAAiC,CAAC,GACE;AACpC,YAAU,kBAAkB,SAAS,KAAK;AAC1C,QAAM,cAAc,QAAQ;AAC5B,MAAI,gBAAgB,QAAW;AAC7B,cAAU,6BAA6B,SAAS,WAAW;AAAA,EAC7D;AACA,QAAM,UAAU,CAAC,KAAoC,WAA6B;AAChF,QAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,aAAO;AAAA,IACT;AACA,UAAM,QAAQ,gBAAgB,UAAa,IAAI,WAAW,MAAM,SAAS,UAAU;AACnF,WAAO,SAAS,OAAO,SAAS,IAAI,KAAK,GAAG,MAAM,CAAC;AAAA,EACrD;AACA,QAAM,SAAS,aAAiD;AAAA,IAC9D,MAAM;AAAA,IACN;AAAA,IACA,OAAO;AAAA,IACP,OAAO;AAAA,MACL,SAAS,gBAAgB,SAAY,CAAC,KAAK,IAAI,CAAC,OAAO,WAAW;AAAA,MAClE,aAAa,CAAC;AAAA,MACd,UAAU,CAAC;AAAA,MACX,SAAS;AAAA,IACX;AAAA,IACA,MAAM,UAAU,WAAW,KAAK,OAAO;AACrC,YAAM,OAAO,MAAM,MAAM,KAAK,GAAG;AACjC,aAAO,WAAW,KAAK,CAAC,OAAO,QAAQ,KAAK,IAAI,EAAE,GAAG,UAAU,MAAM,CAAC;AAAA,IACxE;AAAA,IACA,YAAY,WAAW,OAAO;AAC5B,YAAM,SAAyB,cAAc,KAAK,EAAE,IAAI,CAAC,aAAa;AAAA,QACpE,CAAC,KAAK,GAAG,EAAE,gBAAgB,CAAC,EAAE,QAAQ,UAAU,QAAQ,OAAO,QAAQ,CAAC,EAAE;AAAA,MAC5E,EAAE;AACF,YAAM,QAAQ,gBAAgB,SAAY,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,GAAG,UAAU,OAAO,CAAC;AACnF,aAAO,QAAQ,QAAQ,EAAE,IAAI,CAAC,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC;AAAA,IACtD;AAAA,EACF,CAAC;AACD,UAAQ,IAAI,QAAQ,OAAO,OAAO,EAAE,OAAO,OAAO,YAAY,CAAC,CAAC;AAChE,SAAO;AACT;;;ACpGA,SAASC,YAAW,OAAsC;AACxD,SACE,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAAsC,SAAS,YACvD,OAAO,SAAS,KAAK;AAEzB;AAeO,SAAS,QACd,SAC0B;AAC1B,MAAI,OAAO,YAAY,YAAY,YAAY,QAAQ,CAACA,YAAW,QAAQ,IAAI,GAAG;AAChF,UAAM,IAAI,UAAU,oEAAoE;AAAA,EAC1F;AACA,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,MAAM,UAAU,oBAAoB,OAAO,QAAQ,GAAG;AAC5D,SAAO,aAAa;AAAA,IAClB,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,SAAS,CAAC,GAAG;AAAA,MACb,aAAa,CAAC;AAAA,MACd,UAAU,CAAC,IAAI;AAAA,MACf,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;AAAA,MACvB,SAAS;AAAA,IACX;AAAA,IACA,MAAM,UAAU,WAAW,KAAK,OAAO;AACrC,YAAM,OAAO,MAAM,MAAM,KAAK,GAAG;AACjC,YAAM,WAAW,oBAAI,IAAoB;AACzC,iBAAW,MAAM,KAAK;AACpB,cAAM,SAAS,KAAK,IAAI,EAAE,IAAI,GAAG;AACjC,YAAI,OAAO,WAAW,YAAY,OAAO,SAAS,GAAG;AACnD,mBAAS,IAAI,IAAI,MAAM;AAAA,QACzB;AAAA,MACF;AACA,YAAM,UAAU,MAAM,MAAM,SAAS,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,SAAS,OAAO,CAAC,CAAC,CAAC;AACrF,aAAO,WAAW,KAAK,CAAC,OAAO;AAC7B,cAAM,SAAS,SAAS,IAAI,EAAE;AAC9B,eAAO,WAAW,SAAY,OAAQ,QAAQ,IAAI,MAAM,KAAK;AAAA,MAC/D,CAAC;AAAA,IACH;AAAA,IACA,MAAM,YAAY,WAAW,OAAO,OAAO;AAGzC,YAAM,eAAe,MAAM,MAAM,QAAQ,MAAM,WAAW,KAAK;AAC/D,UAAI,iBAAiB,UAAU,OAAO,KAAK,YAAY,EAAE,WAAW,GAAG;AACrE,eAAO,EAAE,CAAC,GAAG,GAAG,EAAE,KAAK,KAAK,EAAE;AAAA,MAChC;AACA,YAAM,UAAU,MAAM,MAAM,SAAS,MAAM,WAAW,KAAK;AAC3D,aAAO,QAAQ,WAAW,IAAI,SAAS,EAAE,CAAC,GAAG,GAAG,EAAE,IAAI,QAAQ,EAAE;AAAA,IAClE;AAAA,EACF,CAAC;AACH;;;AC7DO,SAAS,SAAS,OAAgD;AACvE,MAAI,CAAC,cAAc,KAAK,KAAK,UAAU,UAAU;AAC/C,UAAM,IAAI,UAAU,yDAAyD;AAAA,EAC/E;AACA,SAAO,aAAa;AAAA,IAClB,MAAM;AAAA,IACN;AAAA,IACA,OAAO,EAAE,SAAS,CAAC,GAAG,aAAa,CAAC,GAAG,UAAU,CAAC,GAAG,SAAS,MAAM;AAAA,IACpE,WAAW,CAAC,YAAY,QAAQ,QAAQ,QAAQ,WAAW,KAAK,MAAM,KAAK,CAAC;AAAA,IAC5E,aAAa,CAAC,YAAY,WAAW,QAAQ,QAAQ,WAAW,OAAO,MAAM,IAAI,CAAC,IAAI,MAAM;AAAA,EAC9F,CAAC;AACH;;;ACnBO,SAAS,eACd,OACA,OACAC,OACqB;AACrB,MAAI,UAAU,QAAW;AACvB,WAAO,oBAAI,IAAI;AAAA,EACjB;AACA,MAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,CAAC,MAAM,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AAC7E,IAAAA,MAAK,uEAAuE;AAAA,EAC9E;AACA,QAAM,cAAc,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,SAAS,IAAI,CAAC;AAC9D,MAAI,gBAAgB,QAAW;AAC7B,IAAAA,MAAK,kBAAkB,OAAO,WAAW,CAAC,0CAA0C;AAAA,EACtF;AACA,SAAO,IAAI,IAAI,KAAK;AACtB;AAGO,SAAS,SACd,MACA,MACA,SACA,SACQ;AACR,SAAO,OAAO;AAAA,IACZ,QAAQ,IAAI,IAAI,IAAI,EAAE,QAAQ,MAAM,SAAS,SAAS,KAAK,IAAI,EAAE,QAAQ,MAAM,QAAQ;AAAA,EACzF;AACF;;;ACTO,SAAS,SAAS,MAAkB,UAAoC;AAC7E,MAAI,OAAO,SAAS,YAAY,eAAe,IAAI,GAAG;AACpD,WAAO;AAAA,EACT;AACA,SAAO,KAAK,SAAS,KAAK,SAAS;AACrC;AAUO,SAAS,aAAa,aAAkD;AAC7E,QAAM,QAAQ,gBAAgB,SAAY,aAAa,SAAS,aAAa,UAAU;AACvF,SAAO,WAAW,OAAO,UAAU,IAAI,QAAQ;AACjD;AAGA,SAAS,UAAU,MAAgB,MAAkB,KAAgC;AACnF,SAAO,KAAK,QAAQ,QAAQ,WAAW,UAAc,QAAQ,UAAU,SAAS;AAClF;AAGA,SAAS,gBAAgB,MAA2B;AAClD,MAAI,SAAS,UAAU;AACrB,WAAO;AAAA,EACT;AACA,SACE,OAAO,SAAS,YAChB,CAAC,eAAe,IAAI,KACpB,KAAK,YAAY,UACjB,KAAK,UAAU,UACf,KAAK,UAAU;AAEnB;AAUO,SAAS,gBACd,SACA,QACA,MACoB;AACpB,MAAI,QAAQ,WAAW,UAAa,gBAAgB,IAAI,GAAG;AACzD,WAAO;AAAA,EACT;AACA,SAAO,GAAG,MAAM,yBAAyB,QAAQ,IAAI;AACvD;AAQO,SAAS,cAAc,MAAgB,MAA2C;AACvF,QAAM,EAAE,UAAU,IAAI;AACtB,MAAI,cAAc,QAAQ,OAAO,SAAS,YAAY,eAAe,IAAI,GAAG;AAC1E,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,aAAa,WAAW,KAAK,QAAQ,QAAQ,IAAI;AAC/D,SAAO,KAAK,YAAY,UAAa,WAAW,OAAO,KAAK,OAAO,IAAI,QAAQ;AACjF;AAGA,SAAS,aAAa,MAAgB,MAAkB,OAA6B;AACnF,SAAO,WAAW,cAAc,MAAM,IAAI,GAAG,KAAK;AACpD;AAOA,eAAsB,UACpB,MACA,MACA,OACA,MAAwB,QACW;AACnC,MAAI,UAAU,MAAM,MAAM,GAAG,KAAK,aAAa,MAAM,MAAM,KAAK,GAAG;AACjE,WAAO;AAAA,EACT;AACA,MAAI,KAAK,cAAc,MAAM;AAC3B,WAAO;AAAA,EACT;AACA,QAAM,EAAE,QAAQ,QAAQ,IAAI,KAAK;AACjC,SAAO,MAAM,OAAO,YAAY,QAAQ,MAAM,KAAK,WAAW,KAAK;AACrE;AAGA,SAAS,YAAY,MAAkB,OAA6B;AAClE,SACE,OAAO,SAAS,YAChB,CAAC,eAAe,IAAI,KACpB,KAAK,YAAY,WAChB,KAAK,OAAO,UAAa,KAAK,OAAO,SACtC,WAAW,KAAK,OAAO,KAAK;AAEhC;AAUA,eAAsB,cAAc,MAAgB,MAAkB,IAA2B;AAC/F,QAAM,EAAE,QAAQ,QAAQ,IAAI,KAAK;AACjC,QAAM,QAAQ,SAAS,MAAM,UAAU;AACvC,MAAI,QAAQ,WAAW,UAAa,aAAa,MAAM,MAAM,KAAK,KAAK,YAAY,MAAM,KAAK,GAAG;AAC/F;AAAA,EACF;AACA,QAAM,SACJ,KAAK,cAAc,OACf,SACA,MAAM,OAAO,UAAU,QAAQ,MAAM,KAAK,WAAW,CAAC,EAAE,CAAC;AAC/D,MAAI,CAAC,WAAW,QAAQ,IAAI,EAAE,GAAG,KAAK,GAAG;AACvC,UAAM,IAAI,eAAe,aAAa,0BAA0B;AAAA,EAClE;AACF;AAMA,eAAsB,WACpB,MACA,MACA,KACA,OACA,KACmB;AACnB,MAAI,UAAU,MAAM,MAAM,GAAG,KAAK,IAAI,WAAW,KAAK,aAAa,MAAM,MAAM,KAAK,GAAG;AACrF,WAAO,CAAC,GAAG,GAAG;AAAA,EAChB;AACA,MAAI,KAAK,cAAc,MAAM;AAC3B,WAAO,CAAC;AAAA,EACV;AACA,QAAM,EAAE,QAAQ,QAAQ,IAAI,KAAK;AACjC,QAAM,SAAS,MAAM,OAAO,UAAU,QAAQ,MAAM,KAAK,WAAW,GAAG;AACvE,SAAO,IAAI,OAAO,CAAC,OAAO,WAAW,OAAO,IAAI,EAAE,GAAG,KAAK,CAAC;AAC7D;AASO,SAAS,YAAY,MAAgB,MAAkB,OAA8B;AAC1F,QAAM,EAAE,QAAQ,IAAI,KAAK;AACzB,QAAM,QAAQ,KAAK,cAAc,OAAO,SAAY,aAAa,KAAK,WAAW,QAAQ,IAAI;AAC7F,MAAI,QAAQ,eAAe,UAAU,SAAS;AAC5C,WAAO;AAAA,EACT;AACA,QAAM,UAAU,cAAc,MAAM,IAAI;AACxC,MAAI,UAAU,MAAM,MAAM,MAAM,GAAG;AACjC,WAAO,WAAW;AAAA,EACpB;AACA,SAAO,YAAY,UAAa,WAAW,SAAS,KAAK,IAAI,UAAU;AACzE;;;AC1IA,SAAS,eAAe,SAAqC;AAC3D,QAAM,QAAQ,QAAQ,QAAQ;AAC9B,QAAM,UAAU,oBAAI,IAA0B;AAC9C,QAAM,MAAM,CAAC,QAAgB,WAAyB;AACpD,YAAQ,IAAI,GAAG,MAAM,KAAS,MAAM,IAAI,EAAE,QAAQ,OAAO,CAAC;AAAA,EAC5D;AACA,aAAW,EAAE,MAAM,IAAI,KAAK,OAAO,WAAW,CAAC,GAAG;AAChD,QAAI,KAAK,KAAK,IAAI;AAAA,EACpB;AACA,aAAW,cAAc,QAAQ,YAAY,OAAO,GAAG;AACrD,QAAI,WAAW,WAAW,UAAa,WAAW,MAAM,SAAS,UAAU;AACzE,UAAI,WAAW,MAAM,QAAQ,WAAW,OAAO,IAAI;AAAA,IACrD;AAAA,EACF;AAEA,QAAM,UAAU,IAAI,KAAK,OAAO,WAAW,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,MAAM,GAAG,CAAC;AACpE,QAAM,UAAU,OAAO,WAAW,CAAC,GAAG,OAAO,CAAC,WAAW,WAAW,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC;AAChG,SAAO,EAAE,QAAQ,IAAI,IAAI,MAAM,GAAG,SAAS,CAAC,GAAG,QAAQ,OAAO,CAAC,EAAE;AACnE;AAEA,IAAM,cAAc,oBAAI,QAA0D;AAO3E,SAAS,oBACd,UACA,OAC6B;AAC7B,MAAI,UAAU,YAAY,IAAI,QAAQ;AACtC,MAAI,YAAY,QAAW;AACzB,cAAU,oBAAI,IAAyC;AACvD,gBAAY,IAAI,UAAU,OAAO;AAAA,EACnC;AACA,QAAM,MAAM,SAAS,KAAK;AAC1B,QAAM,OAAO,QAAQ,IAAI,GAAG;AAC5B,MAAI,SAAS,QAAW;AACtB,WAAO;AAAA,EACT;AACA,QAAM,UAAU,oBAAI,IAAoB;AACxC,aAAW,WAAW,SAAS,OAAO,GAAG;AACvC,eAAW,QAAQ,QAAQ,QAAQ,MAAM,eAAe,CAAC,GAAG;AAC1D,UAAI,SAAS,KAAK,KAAK,MAAM,KAAK;AAChC;AAAA,MACF;AACA,iBAAW,UAAU,CAAC,KAAK,OAAO,KAAK,MAAM,KAAK,KAAK,GAAG;AACxD,YAAI,CAAC,QAAQ,IAAI,MAAM,GAAG;AACxB,kBAAQ,IAAI,QAAQ,QAAQ,IAAI;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,UAAQ,IAAI,KAAK,OAAO;AACxB,SAAO;AACT;AAEA,SAAS,UAAU,SAAiC;AAClD,SAAO,IAAI,eAAe,aAAa,OAAO;AAChD;AAGA,SAAS,SAAS,SAAqB,WAAsC;AAC3E,SACE,cAAc,QAAQ,QAAQ,eAAe,aAAa,WAAW,QAAQ,IAAI,MAAM;AAE3F;AAQA,SAAS,aAAa,MAAsD;AAC1E,SAAO,IAAI,IAAI,OAAO,KAAK,IAAI,EAAE,OAAO,CAAC,WAAW,KAAK,MAAM,MAAM,MAAS,CAAC;AACjF;AAGA,SAAS,gBACP,SACA,SACuC;AACvC,QAAM,EAAE,SAAS,SAAS,IAAI;AAC9B,MAAI,QAAQ,UAAU,QAAW;AAC/B,WAAO;AAAA,EACT;AACA,QAAM,cAAc,oBAAoB,UAAU,QAAQ,KAAK;AAC/D,QAAM,SAAS,QAAQ,KAAK,CAAC,UAAU,YAAY,IAAI,KAAK,CAAC;AAC7D,SAAO,WAAW,SAAY,SAAY,CAAC,QAAQ,YAAY,IAAI,MAAM,KAAK,QAAQ,IAAI;AAC5F;AAQO,SAAS,mBACd,SACA,WACA,MACA,UAA8B,CAAC,GACzB;AACN,QAAM,EAAE,QAAQ,IAAI;AACpB,MAAI,SAAS,SAAS,SAAS,GAAG;AAChC;AAAA,EACF;AACA,QAAM,EAAE,OAAO,IAAI,eAAe,OAAO;AACzC,QAAM,QAAQ,CAAC,GAAG,aAAa,IAAI,CAAC;AACpC,QAAM,WAAW,MAAM,KAAK,CAAC,WAAW,OAAO,IAAI,MAAM,CAAC;AAC1D,QAAM,WAAW,QAAQ,aAAa;AACtC,MAAI,aAAa,QAAW;AAC1B,UAAM;AAAA,MACJ,WACI,IAAI,QAAQ,mCAAmC,QAAQ,IAAI,yEAC3D,IAAI,QAAQ,mCAAmC,QAAQ,IAAI;AAAA,IACjE;AAAA,EACF;AACA,QAAM,aAAa,gBAAgB,SAAS,KAAK;AACjD,MAAI,eAAe,QAAW;AAC5B,UAAM,CAAC,QAAQ,MAAM,IAAI;AACzB,UAAM;AAAA,MACJ,WACI,IAAI,MAAM,2BAA2B,MAAM,qGAC3C,IAAI,MAAM,2BAA2B,MAAM;AAAA,IACjD;AAAA,EACF;AACF;AAOA,eAAsB,mBACpB,SACA,WACA,MACA,OACA,UAA8B,CAAC,GAChB;AACf,QAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,MAAI,SAAS,SAAS,SAAS,GAAG;AAChC;AAAA,EACF;AACA,QAAM,EAAE,QAAQ,IAAI,eAAe,OAAO;AAC1C,QAAM,QAAQ,aAAa,IAAI;AAC/B,aAAW,EAAE,QAAQ,OAAO,KAAK,SAAS;AACxC,UAAM,SAAS,KAAK,MAAM;AAC1B,QAAI,CAAC,MAAM,IAAI,MAAM,KAAK,WAAW,MAAM;AACzC;AAAA,IACF;AACA,UAAM,QAAQ,cAAc,QAAQ,OAAO,WAAW,YAAY,OAAO,SAAS;AAClF,UAAM,WAAW,QACb,MAAM,OAAO,QAAQ,QAAQ,WAAW,CAAC,MAAM,GAAG,EAAE,QAAQ,MAAM,CAAC,IACnE;AACJ,QAAI,aAAa,UAAa,CAAC,WAAW,SAAS,OAAO,IAAI,MAAgB,GAAG,KAAK,GAAG;AACvF,YAAM;AAAA,QACJ,QAAQ,aAAa,OACjB,qBAAqB,QAAQ,IAAI,UAAU,MAAM,WAAW,KAAK,WAAW,MAAM,kBAClF,mBAAmB,QAAQ,IAAI,QAAQ,MAAM,WAAW,KAAK,WAAW,MAAM;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AACF;AAGA,IAAM,YAAY,oBAAI,QAAqC;AAQpD,SAAS,eAAe,SAA+D;AAC5F,MAAI,OAAO,UAAU,IAAI,OAAO;AAChC,MAAI,SAAS,QAAW;AACtB,UAAM,QAAQ,oBAAI,IAAY;AAC9B,eAAW,cAAc,QAAQ,YAAY,OAAO,GAAG;AACrD,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,WAAW,MAAM,GAAG;AAC5D,YAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,gBAAM,IAAI,GAAG;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,WAAO;AACP,cAAU,IAAI,SAAS,IAAI;AAAA,EAC7B;AACA,SAAO;AACT;AAQA,SAAS,cAAc,OAA4D;AACjF,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,WAAO;AAAA,EACT;AACA,QAAM,YAAqB,OAAO,eAAe,KAAK;AACtD,SAAO,cAAc,OAAO,aAAa,cAAc;AACzD;AASO,SAAS,kBACd,SACA,MACA,OAA+B,CAAC,GACZ;AACpB,QAAM,eAAe,eAAe,OAAO;AAE3C,QAAM,SAAS,IAAI;AAAA,IACjB,iBAAiB,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,OAAO,UAAU,MAAM,CAAC,OAAO,SAAS,CAAC;AAAA,EAChF;AACA,QAAM,SAA6B,CAAC;AACpC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,QAAI,UAAU,QAAW;AACvB;AAAA,IACF;AACA,UAAM,YACJ,OAAO,IAAI,GAAG,MAAM,cAAc,KAAK,KAAK,MAAM,QAAQ,MAAM,GAAG,IAAI,QAAQ;AACjF,QAAI,aAAa,IAAI,GAAG,GAAG;AACzB,aAAO,KAAK;AAAA,QACV,MAAM,CAAC,GAAG,MAAM,GAAG;AAAA,QACnB,SAAS,IAAI,GAAG,sBAAsB,QAAQ,IAAI;AAAA,MACpD,CAAC;AAAA,IACH,WAAW,cAAc,QAAW;AAClC,aAAO,KAAK;AAAA,QACV,MAAM,CAAC,GAAG,MAAM,GAAG;AAAA,QACnB,SAAS,IAAI,GAAG,6BAA6B,SAAS;AAAA,MACxD,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,kBACd,SACA,MACA,OAA+B,CAAC,GAC1B;AACN,QAAM,SAAS,kBAAkB,SAAS,MAAM,IAAI;AACpD,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,EAAE,OAAO;AAAA,IACX;AAAA,EACF;AACF;AAUA,eAAsB,qBACpB,SACA,WACA,MACA,OACA,OAA+B,CAAC,GACjB;AACf,oBAAkB,QAAQ,SAAS,MAAM,IAAI;AAC7C,qBAAmB,SAAS,WAAW,IAAI;AAC3C,QAAM,mBAAmB,SAAS,WAAW,MAAM,KAAK;AAC1D;;;AC/TA,SAAS,gBAAgB,OAAyB;AAChD,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS,iCAAiC;AAClD,WAAQ,MAA8C,SAAS;AAAA,EACjE;AACA,QAAM,OAAiB,MAAM,OAAmD;AAChF,SAAO,MAAM,SAAS,wBAAwB,SAAS;AACzD;AAEA,SAAS,UAAU,KAAyC;AAC1D,QAAM,UAAU;AAAA,IACd,GAAI,IAAI,aAAa,SAAY,CAAC,IAAI,EAAE,gBAAgB,eAAe;AAAA,IACvE,GAAI,IAAI,cAAc,SAAY,CAAC,IAAI,EAAE,SAAS,IAAI,UAAU;AAAA,EAClE;AACA,SAAO,OAAO,KAAK,OAAO,EAAE,WAAW,IAAI,SAAY,OAAO,OAAO,OAAO;AAC9E;AAGA,eAAsB,iBACpB,IACA,IACA,KACY;AACZ,QAAM,SAAS;AACf,MAAI,OAAO,QAAQ,iBAAiB,YAAY;AAC9C,UAAM,IAAI,eAAe,YAAY,GAAG,IAAI,KAAK,2CAA2C;AAAA,EAC9F;AACA,QAAM,MAAM,OAAO;AAInB,QAAM,UAAU,UAAU,GAAG;AAC7B,MAAI;AACF,WAAO,YAAY,SAAY,MAAM,IAAI,KAAK,QAAQ,EAAE,IAAI,MAAM,IAAI,KAAK,QAAQ,IAAI,OAAO;AAAA,EAChG,SAAS,OAAO;AACd,QAAI,IAAI,aAAa,UAAa,CAAC,gBAAgB,KAAK,GAAG;AACzD,YAAM;AAAA,IACR;AACA,UAAM,WAAW,IAAI,eAAe,YAAY,IAAI,QAAQ;AAC5D,aAAS,QAAQ;AACjB,UAAM;AAAA,EACR;AACF;;;ACfO,SAAS,WAAW,IAAa,OAA8B;AACpE,QAAM,OAAO,SAAS,KAAK;AAC3B,QAAM,YAAY,OAAO,OAAO,YAAY,OAAO,OAAO,eAAe,OAAO;AAChF,QAAM,WAAoB,WAAW,QAAQ,IAAI,IAAI,IAAI,IAAI;AAC7D,QAAM,SACJ,OAAO,aAAa,YACpB,aAAa,QACb,OAAQ,SAA6C,aAAa;AACpE,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,MACA,kDAAkD,IAAI;AAAA,IACxD;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,SAAS,KAA4B,IAAuB;AAC1E,QAAM,UAAU,aAAa,GAAG;AAChC,QAAM,QAAQ,SAAS,QAAQ;AAC/B,MAAI,YAAY,UAAa,UAAU,QAAW;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,SAAS,KAAK;AAAA,IACrB,OAAO,WAAW,IAAI,KAAK;AAAA,IAC3B,WAAW,IAAI;AAAA,EACjB;AACF;AAQA,eAAsB,cAAiB,IAAa,IAA6C;AAC/F,SAAO,MAAM,iBAAiB,IAAI,IAAI,EAAE,OAAO,oCAAoC,CAAC;AACtF;AAGO,SAAS,aAAa,MAAgB,MAA0B;AACrE,QAAM,aAAa,KAAK,QAAQ,QAAQ,YAAY,IAAI,IAAI;AAC5D,MAAI,eAAe,QAAW;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,MACA,4BAA4B,KAAK,QAAQ,QAAQ,IAAI,oBAAoB,IAAI;AAAA,IAC/E;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,UAAU,KAAkC;AAC1D,SAAO,CAAC,GAAG,IAAI,IAAI,GAAG,CAAC;AACzB;;;AChHO,SAAS,WAAgB,KAA6B,UAAU,aAAkB;AACvF,MAAI,QAAQ,QAAQ,QAAQ,QAAW;AACrC,UAAM,IAAI,eAAe,aAAa,OAAO;AAAA,EAC/C;AACA,SAAO;AACT;;;ACEO,SAAS,UAAU,OAAmE;AAC3F,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAK,EAAE,OAAO,CAAC,CAAC,KAAK,KAAK,MAAM,QAAQ,QAAQ,UAAU,MAAS;AAAA,EACpF;AACF;AAGO,SAAS,cAAc,MAA8B;AAC1D,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAwC;AAC9E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,EAAE,IAAI,GAAG,MAAM,IAAI;AACzB,UAAM,OAAO,UAAU,KAAK;AAC5B,UAAM,EAAE,OAAO,IAAI,aAAa,MAAM,QAAQ;AAC9C,UAAM,cAAc,MAAM,MAAM,EAAE;AAClC,UAAM,qBAAqB,KAAK,SAAS,KAAK,WAAW,MAAM,SAAS,MAAM,UAAU,CAAC;AACzF,QAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,aAAO;AAAA,QACL,MAAM,KAAK,MAAM,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;AAAA,QACrD,WAAW,KAAK,KAAK;AAAA,MACvB;AAAA,IACF;AACA,WAAO,MAAM,KAAK,MAAM,OAAO,EAAE,OAAO,EAAE,GAAG,GAAG,MAAM,OAAO,CAAC;AAAA,EAChE;AACA,SAAO;AACT;;;ACHA,eAAe,aACb,MACA,IACA,CAAC,MAAM,KAAK,GACZ,KACA,OACkB;AAClB,QAAM,SAAS,UAAU,GAAG;AAC5B,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,EAAE,OAAO,EAAE;AAAA,EACpB;AACA,SAAO,MAAM,cAAc,IAAI,OAAO,OAAO;AAC3C,UAAM,UAAU,MAAM,WAAW,MAAM,MAAM,QAAQ,OAAO,OAAO;AACnE,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,EAAE,OAAO,EAAE;AAAA,IACpB;AACA,UAAM,EAAE,MAAM,IAAI,MAAM,MAAM,WAAW,IAAI,KAAK,KAAK,GAAG,OAAO;AACjE,WAAO,EAAE,MAAM;AAAA,EACjB,CAAC;AACH;AAGO,SAAS,kBAAkB,MAAkB,UAAmC;AACrF,QAAM,QAAQ,SAAS,MAAM,QAAQ;AACrC,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAwC;AAC9E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,EAAE,KAAK,KAAK,IAAI;AAItB,UAAM,QAAQ,UAAU,IAAI;AAC5B,QAAI,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AACnC,aAAO,EAAE,OAAO,EAAE;AAAA,IACpB;AACA,UAAM,qBAAqB,KAAK,SAAS,KAAK,WAAW,OAAO,OAAO,CAAC,MAAM,CAAC;AAC/E,WAAO,MAAM;AAAA,MAAa;AAAA,MAAM;AAAA,MAAI,CAAC,MAAM,KAAK;AAAA,MAAG;AAAA,MAAK,CAAC,OAAO,YAC9D,MAAM,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,OAAO,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC;AAAA,IACvE;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,kBAAkB,MAAkB,UAAmC;AACrF,QAAM,QAAQ,SAAS,MAAM,QAAQ;AACrC,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAwC;AAC9E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,WAAO,MAAM;AAAA,MAAa;AAAA,MAAM;AAAA,MAAI,CAAC,MAAM,KAAK;AAAA,MAAI,MAAmB;AAAA,MAAK,CAAC,OAAO,YAClF,MAAM,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC;AAAA,IAC1D;AAAA,EACF;AACA,SAAO;AACT;;;AChDA,SAASC,UAAS,OAA4D;AAC5E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGA,SAASC,eAAc,OAA4D;AACjF,MAAI,CAACD,UAAS,KAAK,GAAG;AACpB,WAAO;AAAA,EACT;AACA,QAAM,YAAqB,OAAO,eAAe,KAAK;AACtD,SAAO,cAAc,OAAO,aAAa,cAAc;AACzD;AAGO,SAAS,cAAc,MAAkB,SAA6C;AAC3F,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAwC;AAC9E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,EAAE,QAAQ,IAAI,KAAK;AAEzB,UAAM,OAAOA,UAAS,KAAK,IAAI,QAAQ,CAAC;AACxC,sBAAkB,SAAS,IAAI;AAC/B,uBAAmB,KAAK,SAAS,KAAK,WAAW,MAAM,EAAE,UAAU,KAAK,CAAC;AAEzE,UAAM,OAAO,YAAY,SAAY,QAAQ,MAAM,QAAQ,MAAM,QAAQ,OAAO,KAAK,EAAE,CAAC;AACxF,QAAI,CAACC,eAAc,IAAI,GAAG;AACxB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oCAAoC,QAAQ,IAAI;AAAA,MAClD;AAAA,IACF;AACA,UAAM,SAAS,kBAAkB,SAAS,IAAI;AAC9C,QAAI,OAAO,SAAS,GAAG;AACrB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,oCAAoC,QAAQ,IAAI,+BAA+B,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MAChI;AAAA,IACF;AAEA,UAAM,mBAAmB,KAAK,SAAS,KAAK,WAAW,MAAM,SAAS,MAAM,UAAU,GAAG;AAAA,MACvF,UAAU;AAAA,IACZ,CAAC;AACD,UAAM,EAAE,OAAO,IAAI,aAAa,MAAM,QAAQ;AAC9C,WAAO,MAAM,KAAK,MAAM,OAAO,EAAE,MAAM,OAAO,CAAC;AAAA,EACjD;AACA,SAAO;AACT;;;AC7EO,SAAS,cAAc,MAA8B;AAC1D,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAqC;AAC3E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,EAAE,GAAG,IAAI;AACf,UAAM,cAAc,MAAM,MAAM,EAAE;AAClC,UAAM,KAAK,MAAM,OAAO,EAAE,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;AAC/D,WAAO;AAAA,EACT;AACA,SAAO;AACT;;;ACTO,SAAS,aAAyB;AACvC,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAwC;AAC9E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,EAAE,GAAG,IAAI;AACf,UAAM,EAAE,OAAO,IAAI,aAAa,MAAM,QAAQ;AAC9C,WAAO;AAAA,MACL,MAAM,KAAK,MAAM,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;AAAA,MACrD,WAAW,KAAK,KAAK;AAAA,IACvB;AAAA,EACF;AACA,SAAO;AACT;;;ACFO,SAAS,eAAe,MAA8B;AAC3D,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAsC;AAC5E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,MAAM,UAAW,MAAmB,GAAG;AAC7C,UAAM,UAAU,MAAM,WAAW,MAAM,MAAM,KAAK,SAAS,MAAM,MAAM,GAAG,MAAM;AAChF,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO,CAAC;AAAA,IACV;AACA,UAAM,EAAE,OAAO,IAAI,aAAa,MAAM,QAAQ;AAC9C,UAAM,OAAO,MAAM,KAAK,MAAM,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,QAAQ,EAAE,GAAG,OAAO,CAAC;AACjF,UAAM,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AACrD,WAAO,QAAQ,QAAQ,CAAC,OAAO;AAC7B,YAAM,MAAM,KAAK,IAAI,EAAE;AACvB,aAAO,QAAQ,SAAY,CAAC,IAAI,CAAC,GAAG;AAAA,IACtC,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACnBO,SAAS,YAAY,OAAqD;AAC/E,SAAO,CAAC,GAAG,OAAO,KAAK,MAAM,MAAM,GAAG,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,CAAC,MAAM,KAAK,KAAK,CAAE;AAC/F;AAGO,SAAS,aACd,SACA,QACA,OACM;AACN,QAAM,SAAS,MAAM,KAAK,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC;AACpD,MAAI,WAAW,QAAW;AACxB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,IAAI,MAAM,mBAAmB,OAAO;AAAA,IACtC;AAAA,EACF;AACF;AAGO,SAAS,aACd,YACA,QACmB;AACnB,QAAM,CAAC,KAAK,IAAI;AAChB,SAAO,UAAU,UAAa,OAAO,IAAI,KAAK,IAAI,CAAC,IAAI;AACzD;AAGO,SAAS,UAAU,YAA+B,MAAkC;AACzF,QAAM,QAAQ,MAAM,SAAS,WAAW,CAAC;AACzC,QAAM,YAAY,MAAM,aAAa;AACrC,MAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAO,CAAC,CAAC,MAAM,SAAS,CAAC;AAAA,EAC3B;AACA,SAAO;AAAA,IACL,CAAC,OAAO,SAAS;AAAA,IACjB,CAAC,MAAM,SAAS;AAAA,EAClB;AACF;AAGO,SAAS,UACd,QACA,QACc;AACd,QAAM,QAAQ,OAAO;AAAA,IACnB,OAAO,QAAQ,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,MAAS;AAAA,EAClE;AACA,QAAM,QAAQ,CAAC,OAAO,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,SAAS,OAAO,KAAK,IAAI,EAAE,SAAS,CAAC;AACjF,SAAO,MAAM,SAAS,IAAI,EAAE,KAAK,MAAM,IAAK,MAAM,CAAC,KAAK,CAAC;AAC3D;;;ACRA,IAAM,YAAY;AAElB,IAAM,eAAe;AAGrB,SAAS,YAAY,OAAwB;AAC3C,SAAO,MAAM,IAAI,CAAC,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM,IAAI,SAAS,EAAE,EAAE,KAAK,GAAG;AAC9E;AAGA,SAAS,OAAO,OAAyB;AACvC,SAAO,CAAC,CAAC,WAAW,KAAK,GAAG,GAAG,KAAK;AACtC;AAGA,IAAM,MAAM;AAGZ,IAAM,aAAa;AAAA,EACjB,CAAC,WAAW,KAAK;AAAA,EACjB,CAAC,MAAM,KAAK;AACd;AAMO,SAAS,YAAY,OAAgB,KAAkB;AAC5D,QAAM,SAAS,aAAa,OAAO,KAAK,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,YAAY,KAAK,EAAE,CAAC;AACtF,SAAO,OAAO,UAAU,oBACpB,SACA,aAAa,YAAY,EAAE,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,IAAI,IAAI,IAAI,GAAG,CAAC;AACzF;AAMO,SAAS,WAAW,OAAgB,QAA4B;AACrE,QAAM,YAAY,YAAY,KAAK;AACnC,QAAM,UAAU,CAAC,UAAmD;AAClE,QAAI;AACF,aAAO,aAAa,OAAO,MAAM;AAAA,IACnC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,SAAS,QAAQ,OAAO,KAAK,CAAC;AACpC,MAAI,SAAS,CAAC,MAAM,WAAW;AAC7B,WAAO,EAAE,QAAQ,OAAO,MAAM,CAAC,EAAE;AAAA,EACnC;AACA,QAAM,QAAQ,QAAQ,UAAU;AAChC,MAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,GAAG,SAAS,MAAM,OAAO,MAAM,CAAC,MAAM,UAAU;AACvE,WAAO,EAAE,KAAK,MAAM,CAAC,EAAE;AAAA,EACzB;AACA,QAAM,WAAW,cAAc,CAAC,QAAQ,CAAC;AAC3C;AAOA,eAAe,gBACb,MACA,QACsB;AACtB,QAAM,EAAE,SAAS,OAAO,MAAM,IAAI;AAClC,QAAM,WAAW,oBAAI,IAAY;AACjC,aAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,MAAM,QAAQ,GAAG;AAC/C,UAAM,QAAQ,SAAS,KAAK;AAC5B,UAAM,QAAQ,WAAW,OAAO,QAAQ,MAAM,SAAS,WAAW,OAAO,MAAM;AAC/E,QAAI,UAAU,QAAQ,UAAU,OAAO;AACrC,YAAM,WAAW,cAAc,CAAC,QAAQ,CAAC;AAAA,IAC3C;AACA,QAAI,UAAU,QAAQ,UAAU,MAAM;AACpC,eAAS,IAAI,MAAM;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,QAAQ,OAAgB,MAAsD;AAC5F,QAAM,eAAe,iBAAiB,SAAS,MAAM,SAAS;AAC9D,MAAI,CAAC,gBAAiB,KAAK,WAAW,UAAa,CAAC,KAAK,UAAW;AAClE,WAAO;AAAA,EACT;AACA,QAAM,UAAU,IAAI;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,MACE,QAAQ;AAAA,QACN;AAAA,UACE,MAAM,KAAK,WAAW,SAAY,CAAC,QAAQ,IAAI,CAAC;AAAA,UAChD,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,UAAQ,QAAQ;AAChB,SAAO;AACT;AAMA,eAAe,YAAY,MAAgB,QAA6C;AACtF,QAAM,OAAO,WAAW,KAAK,OAAO,MAAM;AAC1C,MAAI,YAAY,MAAM;AACpB,WAAO,KAAK;AAAA,EACd;AACA,MAAI;AACJ,MAAI;AACF,UAAM,MAAM,KAAK,MAAM,UAAU;AAAA,MAC/B,OAAO,EAAE,KAAK,CAAC,KAAK,OAAO,EAAE,IAAI,KAAK,IAAI,CAAC,EAAE;AAAA,MAC7C,QAAQ,OAAO,YAAY,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;AAAA,IACzE,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,QAAQ,OAAO,IAAI;AAAA,EAC3B;AACA,MAAI,QAAQ,MAAM;AAChB,UAAM,WAAW,cAAc,CAAC,QAAQ,CAAC;AAAA,EAC3C;AACA,SAAO,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,MAAM,IAAI,MAAM,CAAC;AACjD;AAGA,eAAsB,SAAS,MAAmC;AAChE,QAAM,SAAS,KAAK,WAAW,SAAY,SAAY,MAAM,YAAY,MAAM,KAAK,MAAM;AAC1F,QAAM,WAAW,MAAM,gBAAgB,MAAM,MAAM;AACnD,QAAM,QACJ,WAAW,SACP,KAAK,QACL,EAAE,KAAK,CAAC,KAAK,OAAO,YAAY,KAAK,OAAO,QAAQ,QAAQ,CAAC,EAAE;AACrE,MAAI;AACJ,MAAI;AACJ,MAAI;AACF,KAAC,MAAM,KAAK,IAAI,MAAM,QAAQ,IAAI;AAAA,MAChC,KAAK,MAAM,SAAS;AAAA,QAClB;AAAA,QACA,QAAQ,KAAK;AAAA,QACb,SAAS,UAAU,KAAK,OAAO,QAAQ;AAAA,QACvC,MAAM,KAAK,QAAQ;AAAA,MACrB,CAAC;AAAA,MACD,KAAK,aAAa,KAAK,MAAM,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,IAAI;AAAA,IAC9D,CAAC;AAAA,EACH,SAAS,OAAO;AACd,UAAM,QAAQ,OAAO,IAAI;AAAA,EAC3B;AACA,QAAM,QAAQ,KAAK,MAAM,GAAG,KAAK,KAAK;AACtC,QAAM,OAAO,MAAM,GAAG,EAAE;AACxB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,YACE,KAAK,SAAS,KAAK,SAAS,SAAS,SAAY,YAAY,KAAK,OAAO,IAAI,IAAI;AAAA,IACnF,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,YAAY,MAAM;AAAA,EACrD;AACF;;;AC7LO,SAAS,SACd,YACA,KACA,QACS;AACT,QAAM,OAAO,WAAW,YAAY,GAAG;AACvC,SAAO,OAAO,SAAS,YAAY,SAAS,OACxC,MAAM,MAA2C,MAAM,IACvD;AACN;AAEA,SAAS,UAAU,OAAmC;AACpD,SAAO,EAAE,OAAO,CAAC,GAAG,YAAY,MAAM,GAAI,MAAM,aAAa,EAAE,YAAY,EAAE,IAAI,CAAC,EAAG;AACvF;AAGO,SAAS,YAAY,SAAkC;AAC5D,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAkD;AACxF,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,QAAQ;AACd,UAAM,QAAQ,SAAS,QAAQ,MAAM,MAAM;AAC3C,UAAM,SAAS,YAAY,MAAM,QAAQ,MAAM,KAAK;AACpD,UAAM,SAAS,aAAa,MAAM,QAAQ,EAAE,MAAM,OAAO,MAAM;AAC/D,iBAAa,KAAK,QAAQ,QAAQ,MAAM,QAAQ,YAAY,KAAK,CAAC;AAClE,UAAM,SAAS,MAAM,UAAU,MAAM,QAAQ,MAAM,KAAK;AACxD,QAAI,WAAW,QAAQ;AACrB,aAAO,UAAU,KAAK;AAAA,IACxB;AACA,UAAM,aAAa,aAAa,MAAM,QAAQ,UAAU;AACxD,UAAM,QAAQ,UAAU,aAAa,QAAQ,KAAK,MAAM,MAAM,GAAG,MAAM,IAAI;AAC3E,UAAM,OAAO,MAAM,SAAS;AAAA,MAC1B,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,UAAU,MAAM,QAAQ,MAAM;AAAA,MACrC;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,OAAO,MAAM;AAAA,MACb,QAAQ;AAAA,QACN,WAAW;AAAA,QACX,MAAM,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM;AAAA,MAChC;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS;AAAA,IAC/C,CAAC;AACD,UAAM,SAAS,WAAW,MAAM,OAAO,MAAM;AAC7C,WAAO;AAAA,MACL,OAAO,KAAK,KAAK,IAAI,CAAC,QAAQ,SAAS,YAAY,KAAK,MAAM,CAAC;AAAA,MAC/D,YAAY,KAAK;AAAA,MACjB,GAAI,KAAK,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW;AAAA,IACzE;AAAA,EACF;AACA,SAAO;AACT;;;AC5EO,IAAM,eAAe;AAE5B,IAAM,cAAc;AACpB,IAAM,cAAc;AAGb,SAAS,UAAU,OAAiC;AACzD,SACE,OAAO,UAAU,YACjB,OAAO,SAAS,KAAK,KACrB,SAAS,eACT,SAAS;AAEb;AAOO,SAAS,eACd,KACA,MACoB;AACpB,MAAI;AACJ,MAAI,QAAQ,UAAa,SAAS,QAAW;AAC3C,YAAQ,KAAK,KAAK,IAAI,IAAI;AAAA,EAC5B,WAAW,SAAS,UAAa,QAAQ,QAAW;AAClD,YAAQ,KAAK,MAAM,GAAG,IAAI;AAAA,EAC5B,WAAW,QAAQ,UAAa,SAAS,QAAW;AAClD,UAAM,SAAS,KAAK,OAAO,MAAM,QAAQ,CAAC;AAC1C,YAAQ,SAAS,OAAO,SAAS,OAAO,SAAS;AAAA,EACnD;AACA,SAAO,UAAU,KAAK,IAAI,QAAQ;AACpC;AAkBA,eAAsB,YACpB,IACA,OACA,QAAsB,CAAC,GACvB,UAA8B,CAAC,GACd;AACjB,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,OAAO,WAAW,GAAG;AAC1E,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAAS,MAAM,WAAW,IAAI,KAAK,EAAE,UAAU,EAAE,OAAO,MAAM,EAAE,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;AACxF,QAAM,UAAW,OAAO,OAAgE,MAAM;AAC9F,SAAO,OAAO,YAAY,YAAY,OAAO,SAAS,OAAO,IACzD,KAAK,MAAM,OAAO,IAAI,eACtB;AACN;;;ACbA,SAAS,QAAQ,SAAiB,MAAyC;AACzE,SAAO,IAAI,eAAe,cAAc,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC7F;AAWA,eAAe,UACb,OACA,CAAC,MAAM,QAAQ,GACf,MACA,OACgB;AAChB,QAAM,SAAS,OAAO,YAAY,CAAC,MAAM,KAAK,QAAQ,GAAG,KAAK,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;AAC/F,QAAM,MAAM;AAAA,IACV,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK,UAAU,KAAK,OAAO,EAAE,OAAO,CAAC,OAAO,OAAO,MAAS,EAAE;AAAA,EACpF;AACA,QAAM,QAAQ,aAAa,SAAY,MAAM,EAAE,KAAK,CAAC,KAAK,QAAQ,EAAE;AACpE,QAAM,OAAO,aAAa,SAAS,CAAC,IAAI,MAAM,MAAM,SAAS,EAAE,OAAO,OAAO,CAAC;AAC9E,QAAM,OAAO,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AACrD,QAAM,QAAQ,KAAK,IAAI,KAAK,EAAE;AAC9B,MAAI,UAAU,QAAW;AACvB,UAAM,aAAa,SACf,IAAI,eAAe,aAAa,WAAW,KAAK,EAAE,IAClD,IAAI,eAAe,aAAa,0BAA0B;AAAA,EAChE;AACA,QAAM,WAAW,CAAC,IAAwB,QAAiC;AACzE,UAAM,MAAM,OAAO,SAAY,SAAY,KAAK,IAAI,EAAE;AACtD,UAAM,SACJ,QAAQ,UAAa,KAAK,OAAO,MAAM,CAAC,WAAW,IAAI,MAAM,MAAM,MAAM,MAAM,CAAC;AAClF,QAAI,OAAO,UAAa,CAAC,QAAQ;AAC/B,YAAM,IAAI,eAAe,aAAa,WAAW,KAAK,oBAAoB,GAAG,EAAE;AAAA,IACjF;AACA,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL;AAAA,IACA,QAAQ,SAAS,KAAK,UAAU,UAAU;AAAA,IAC1C,OAAO,SAAS,KAAK,SAAS,SAAS;AAAA,EACzC;AACF;AAOA,SAAS,OAAO,MAAmB,OAAY,UAAkD;AAC/F,QAAM,QAAQ,OAAO,YAAY,KAAK,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,MAAM,MAAM,KAAK,IAAI,CAAC,CAAC;AAC7F,QAAM,OAAO,aAAa,SAAY,CAAC,IAAI,CAAC,aAAa,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,QAAQ;AAC/F,SAAO,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,MAAM,GAAG,EAAE,GAAG,GAAG,IAAI,EAAE;AAC5D;AAGA,eAAe,SACb,OACA,MACA,MACA,KACA,MACqB;AACrB,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,SAAS,SAAS,OAAO;AACxC,QAAM,YAAY,SAAS,SAAS,QAAQ;AAC5C,QAAM,QAAQ,IAAI,MAAM;AACxB,SAAO,MAAM,MAAM,UAAU;AAAA,IAC3B,OAAO;AAAA,MACL,KAAK;AAAA,QACH;AAAA,QACA,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,GAAG,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,GAAG,OAAO,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC,EAAE;AAAA,MAC3F;AAAA,IACF;AAAA,IACA,SAAS,CAAC,EAAE,CAAC,MAAM,GAAG,UAAU,GAAG,EAAE,IAAI,UAAU,CAAC;AAAA,IACpD,QAAQ,EAAE,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;AAAA,EACrC,CAAC;AACH;AAMA,eAAe,OACb,OACA,MACA,OACA,UACgE;AAChE,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,QAAM,OAAO,OAAO,MAAM,MAAM,OAAO,QAAQ;AAC/C,QAAM,MACJ,WAAW,UAAU,SAAY,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,OAAO,UAAU;AAC7F,QAAM,OACJ,UAAU,WAAW,SAAY,OAAO,MAAM,SAAS,OAAO,MAAM,MAAM,QAAQ,MAAM;AAC1F,QAAM,WAAW,QAAQ,OAAO,OAAO,IAAI,MAAM;AACjD,QAAM,YAAY,SAAS,OAAO,OAAO,KAAK,MAAM;AACpD,QAAM,SAAS,CAAC,UAA4B,UAAU,QAAQ,UAAU,KAAK;AAC7E,MAAI,CAAC,OAAO,QAAQ,KAAK,CAAC,OAAO,SAAS,GAAG;AAC3C,WAAO;AAAA,EACT;AACA,MAAI,WAAW,UAAa,UAAU,UAAc,WAAuB,WAAsB;AAC/F,UAAM,QAAQ,4CAA4C,CAAC,SAAS,CAAC;AAAA,EACvE;AACA,SAAO,CAAC,UAA2B,SAA0B;AAC/D;AAGA,eAAe,SACb,OACA,CAAC,MAAM,QAAQ,GACf,OACA,MACiB;AACjB,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,OAAO,MAAM,MAAM,SAAS;AAAA,IAChC,OAAO,OAAO,MAAM,MAAM,OAAO,QAAQ;AAAA,IACzC,QAAQ,EAAE,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK;AAAA,IACnC,SAAS,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,EAAE,IAAI,MAAM,CAAC;AAAA,EAC9C,CAAC;AACD,QAAM,QAAQ,KAAK,IAAI,CAAC,QAAQ,IAAI,EAAE;AACtC,QAAM,WAAW,KAAK,YAAY,KAAK;AACvC,MAAI,aAAa,UAAa,CAAC,MAAM,SAAS,QAAQ,GAAG;AAEvD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,KACJ,KAAK,aAAa,SACd,KAAK,IAAI,MAAM,QAAQ,KAAK,OAAO,GAAG,CAAC,IACvC,MAAM,QAAQ,KAAK,QAAQ,IAAI;AACrC,QAAM,OAAO,IAAI,GAAG,KAAK,EAAE;AAC3B,QAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC;AAChE,MAAI,SAAS;AACb,aAAW,CAAC,OAAO,EAAE,KAAK,MAAM,QAAQ,GAAG;AACzC,UAAM,SAAS,QAAQ,KAAK;AAC5B,QAAI,OAAO,KAAK,IAAI;AAClB,eAAS;AAAA,IACX,WAAW,QAAQ,IAAI,EAAE,MAAM,OAAO;AACpC,YAAM,MAAM,OAAO,EAAE,OAAO,EAAE,GAAG,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;AAAA,IACvF;AAAA,EACF;AACA,SAAO;AACT;AAGO,IAAM,mBAAmB;AAGzB,IAAM,sBAAsB;AAEnC,IAAM,QAAQ;AAEd,IAAM,WAAW;AAmBjB,eAAe,OACb,IACA,EAAE,MAAM,MAAM,MAAM,UAAU,OAAO,GACrC,aACkE;AAClE,QAAM,QAAQ,WAAW,IAAI,KAAK,KAAK;AACvC,QAAM,QAAQ,MAAM,UAAU,OAAO,CAAC,MAAM,QAAQ,GAAG,MAAM,KAAK,KAAK;AACvE,QAAM,QAAQ,MAAM,OAAO,OAAO,MAAM,OAAO,QAAQ;AACvD,QAAM,UACJ,UAAU,SAAY,SAAY,eAAe,MAAM,CAAC,KAAK,QAAW,MAAM,CAAC,KAAK,MAAS;AAC/F,MAAI,YAAY,UAAa,CAAC,aAAa;AACzC,WAAO,EAAE,MAAM,OAAO,MAAM,MAAM,OAAO,QAAQ,EAAE;AAAA,EACrD;AACA,QAAM,QAAQ,WAAY,MAAM,SAAS,OAAO,CAAC,MAAM,QAAQ,GAAG,OAAO,IAAI;AAC7E,SAAO;AAAA,IACL,KAAK,MAAM,MAAM,OAAO,EAAE,OAAO,EAAE,IAAI,KAAK,GAAG,GAAG,MAAM,EAAE,CAAC,KAAK,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAAA,EAC5F;AACF;AAOA,eAAe,WACb,MACA,CAAC,MAAM,KAAK,GACZ,MACe;AACf,QAAM,QAAQ,CAAC,KAAK,UAAU,KAAK,OAAO,EAAE,OAAO,CAAC,OAAO,OAAO,MAAS;AAC3E,QAAM,MAAM,UAAU,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC;AACzC,QAAM,WAAW,IAAI,IAAI,MAAM,WAAW,MAAM,MAAM,KAAK,OAAO,OAAO,CAAC;AAC1E,MAAI,CAAC,SAAS,IAAI,KAAK,EAAE,GAAG;AAC1B,UAAM,IAAI,eAAe,aAAa,0BAA0B;AAAA,EAClE;AACA,aAAW,CAAC,IAAI,GAAG,KAAK;AAAA,IACtB,CAAC,KAAK,UAAU,UAAU;AAAA,IAC1B,CAAC,KAAK,SAAS,SAAS;AAAA,EAC1B,GAAY;AACV,QAAI,OAAO,UAAa,CAAC,SAAS,IAAI,EAAE,GAAG;AACzC,YAAM,IAAI,eAAe,aAAa,WAAW,KAAK,KAAK,oBAAoB,GAAG,EAAE;AAAA,IACtF;AAAA,EACF;AACF;AAOO,SAAS,eAAe,MAAmB,MAA8B;AAC9E,QAAM,QAAQ,SAAS,MAAM,UAAU;AACvC,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAoC;AAC1E,UAAM,OAAO,SAAS,KAAK,EAAE;AAC7B,UAAM,QAAQ;AACd,UAAM,WAAW,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK;AAC3C,UAAM,OAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN,UAAU,MAAM,UAAU,MAAM,MAAM,OAAO,OAAO;AAAA,MACpD,QAAQ,aAAa,MAAM,QAAQ,EAAE;AAAA,IACvC;AACA,UAAM,MAAM,EAAE,OAAO,OAAO,UAAU,SAAS;AAC/C,UAAM,QAAQ,MAAM,iBAAiB,IAAI,OAAO,OAAO,MAAM,OAAO,IAAI,MAAM,KAAK,GAAG,GAAG;AACzF,QAAI,SAAS,OAAO;AAClB,aAAO,MAAM;AAAA,IACf;AAEA,UAAM,OAAO,MAAM,KAAK,MAAM,MAAM,EAAE,OAAO,MAAM,KAAK,CAAC;AACzD,UAAM,YAAY,oBAAoB,OAAO,KAAK;AAClD,UAAM,QAAQ,MAAM,iBAAiB,IAAI,OAAO,OAAO,MAAM,OAAO,IAAI,MAAM,IAAI,GAAG;AAAA,MACnF,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AACD,QAAI,EAAE,SAAS,QAAQ;AACrB,YAAM,IAAI,eAAe,YAAY,oCAAoC;AAAA,IAC3E;AACA,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;;;ACvTO,SAAS,UAAU,SAAoC;AAC5D,QAAM,EAAE,MAAM,KAAK,IAAI;AACvB,UAAQ,KAAK,QAAQ;AAAA,IACnB,KAAK;AACH,aAAO,WAAW;AAAA,IACpB,KAAK;AACH,aAAO,eAAe,IAAI;AAAA,IAC5B,KAAK;AACH,aAAO,YAAY,EAAE,MAAM,MAAM,YAAY,QAAQ,WAAW,CAAC;AAAA,IACnE,KAAK;AACH,aAAO,cAAc,MAAM,QAAQ,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,cAAc,IAAI;AAAA,IAC3B,KAAK;AACH,aAAO,cAAc,IAAI;AAAA,IAC3B,KAAK;AACH,aAAO,eAAe,MAAM,IAAI;AAAA,IAClC,KAAK;AACH,aAAO,kBAAkB,MAAM,QAAQ,SAAS;AAAA,IAClD;AACE,aAAO,kBAAkB,MAAM,QAAQ,SAAS;AAAA,EACpD;AACF;;;ACWA,SAASC,UAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,KAAK,SAAwB;AACpC,QAAM,IAAI,UAAU,kBAAkB,OAAO,EAAE;AACjD;AAGA,SAAS,WAAW,UAAyC;AAC3D,QAAM,QACJA,UAAS,QAAQ,KACjB,OAAO,SAAS,SAAS,YACzBA,UAAS,SAAS,OAAO,KACzB,OAAO,SAAS,QAAQ;AAC1B,MAAI,CAAC,OAAO;AACV,SAAK,2DAA2D;AAAA,EAClE;AACA,QAAM,QAA8B,CAAC;AACrC,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAwB,GAAG;AAC3E,UAAM,OAAO,WAAW,GAAG;AAC3B,QAAI,SAAS,QAAW;AACtB,YAAM,KAAK,CAAC,MAAM,IAAI,CAAC;AAAA,IACzB;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,YACP,QACA,OACsC;AACtC,MAAI,CAACA,UAAS,MAAM,GAAG;AACrB,SAAK,6DAA6D;AAAA,EACpE;AACA,QAAMC,WAAU,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,OAAO,QAAQ,IAAI,CAAC;AACnE,MAAIA,SAAQ,SAAS,GAAG;AACtB,SAAK,0BAA0BA,SAAQ,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAChF;AACA,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,CAAC,MAAM,SAAS,IAAI,GAAG;AACzB,WAAK,iBAAiB,IAAI,6CAA6C;AAAA,IACzE;AACA,UAAM,UAAU,kBAAkB,IAAI;AACtC,QAAI,YAAY,QAAW;AACzB,WAAK,eAAe,IAAI,KAAK,OAAO,EAAE;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,eACP,UACA,MACQ;AACR,QAAM,EAAE,KAAK,IAAI;AACjB,MAAI,SAAS,UAAa,SAAS,SAAS,QAAQ;AAClD,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,QAAQ,SAAS,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,MAAM,WAAW,IAAI;AACvF,MAAI,UAAU,QAAW;AACvB;AAAA,MACE,gBAAgB,SAAS,IAAI;AAAA,IAC/B;AAAA,EACF;AACA,SAAO,MAAM,CAAC;AAChB;AAGA,SAAS,aACP,SACA,KACwB;AACxB,MAAI,YAAY,QAAW;AACzB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,YAAY,cAAc,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,WAAW,QAAQ,GAAG;AACtF,SAAK,kEAAkE;AAAA,EACzE;AACA,SAAO;AACT;AAGA,IAAM,YAA6C,oBAAI,IAAI;AAAA,EACzD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAUD,IAAM,cAA+C,oBAAI,IAAI;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAMD,IAAM,mBAAoD,oBAAI,IAAI,CAAC,QAAQ,SAAS,CAAC;AAGrF,IAAM,eAAe,EAAE,YAAY,UAAU,YAAY,SAAS;AASlE,SAAS,YACP,KACA,QACA,MAC4B;AAC5B,QAAM,cACJ,KAAK,WAAW,gBAAgB,KAAK,WAAW,eAC5C,aAAa,KAAK,MAAM,IACxB;AACN,QAAM,QAAQ,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,MAAM,MAAM,WAAW,WAAW;AAClE,SAAO,aAAa,UAAU,SAAY,SAAa,OAAO,MAAM,CAAC,CAAC,CAAgB;AACxF;AAEA,IAAM,cAAiC,CAAC,UAAU,WAAW,SAAS;AAGtE,SAAS,eACP,SACA,UACA,CAAC,MAAM,IAAI,GACX,MACoB;AACpB,MAAI,QAAQ,aAAa,UAAU;AACjC,WAAO,oEAAoE,QAAQ,IAAI;AAAA,EACzF;AACA,MAAI,QAAQ,UAAU,QAAW;AAC/B,WAAO;AAAA,EACT;AACA,SAAO,UAAU,IAAI,KAAK,MAAM,IAAI,gBAAgB,SAAS,MAAM,IAAI,IAAI;AAC7E;AAEA,SAAS,SACP,UACA,SAC4B;AAC5B,QAAM,MAAM,WAAW,QAAQ;AAC/B,MAAI,CAACD,UAAS,OAAO,GAAG;AACtB,SAAK,gDAAgD;AAAA,EACvD;AACA,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,YAAY,SAAS,GAAG,CAAC;AAChF,MAAI,eAAe,QAAW;AAC5B,SAAK,+BAA+B,UAAU,sBAAsB,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9F;AACA,QAAM,QAAQ,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACtC,QAAM,SAAS,YAAY,QAAQ,QAAQ,KAAK;AAChD,QAAM,UAAU,aAAa,QAAQ,SAAS,GAAG;AACjD,QAAM,UAAU,eAAe,QAAQ,SAAS,OAAO,IAAI;AAC3D,QAAM,UAAkC,CAAC;AACzC,aAAW,CAAC,MAAM,IAAI,KAAK,KAAK;AAC9B,UAAM,OAAO,OAAO,IAAI;AACxB,UAAM,aAAa,KAAK,WAAW,SAAS,eAAe,UAAU,IAAI,IAAI;AAC7E,UAAM,YAAY,YAAY,KAAK,QAAQ,IAAI;AAC/C,UAAM,UAAU,UAAU,EAAE,MAAM,MAAM,YAAY,SAAS,UAAU,CAAC;AACxE,qBAAiB,SAAS,CAAC,YAAY,eAAe,SAAS,UAAU,CAAC,MAAM,IAAI,GAAG,IAAI,CAAC;AAC5F,QAAI,YAAY,IAAI,KAAK,MAAM,GAAG;AAChC,uBAAiB,OAAO;AAAA,IAC1B;AACA,QAAI,iBAAiB,IAAI,KAAK,MAAM,GAAG;AACrC,sBAAgB,OAAO;AAAA,IACzB;AACA,YAAQ,IAAI,IAAI,SAAS,MAAM,MAAM,SAAS,OAAO;AAAA,EACvD;AACA,SAAO,OAAO,OAAO,OAAO;AAC9B;AASO,IAAME,QAAO,OAAO,OAAO,EAAE,UAAU,KAAa,UAAU,SAAS,CAAC;;;AC3N/E,IAAM,WAAoB,OAAO,OAAO,CAAC,OAAO,OAAO,CAAC,MAAM,KAAK,CAAU,CAAC,CAAC;AAE/E,SAASC,UAAS,OAA4D;AAC5E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGO,SAAS,MAAM,OAA4D;AAChF,QAAM,OAAO,MAAM;AAAA,IACjB,CAAC,SAA+B,SAAS,UAAa,OAAO,KAAK,IAAI,EAAE,SAAS;AAAA,EACnF;AACA,SAAO,KAAK,SAAS,IAAI,EAAE,KAAK,KAAK,IAAK,KAAK,CAAC,KAAK,CAAC;AACxD;AAGO,SAAS,YAAY,GAAmB;AAC7C,SAAO,EAAE,QAAQ,WAAW,MAAM;AACpC;AAGO,SAAS,cAAc,QAA2B,GAAyB;AAChF,QAAM,WAAW,YAAY,CAAC;AAC9B,SAAO,EAAE,IAAI,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,GAAG,EAAE,UAAU,MAAM,cAAc,EAAE,EAAE,EAAE;AACvF;AAGA,SAAS,eAAe,KAAmC;AACzD,QAAM,EAAE,MAAM,SAAS,MAAM,IAAI;AACjC,QAAM,SAAS,aAAa,MAAM,QAAQ,EAAE,MAAM,OAAO,YAAY,MAAM,QAAQ,MAAM,KAAK,CAAC;AAC/F,SAAO,QAAQ,KAAK,OAAO,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,KAAK,CAAC;AACjE;AAGA,eAAsB,UAAU,KAAgD;AAC9E,QAAM,QAAQ,IAAI,QAAQ,UAAU;AACpC,MAAI,UAAU,QAAW;AACvB,UAAM,SAAS,eAAe,GAAG;AACjC,WAAO,OAAO,WAAW,IAAI,SAAS,cAAc,QAAQ,IAAI,MAAM,CAAC;AAAA,EACzE;AACA,QAAM,SAAkB,MAAM,QAAQ,MAAM,MAAM,IAAI,MAAM,GAAG,IAAI,GAAG,CAAC;AACvE,MAAI,CAACA,UAAS,MAAM,GAAG;AACrB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,0BAA0B,IAAI,KAAK,QAAQ,QAAQ,IAAI;AAAA,IACzD;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,iBAAiB,KAA+C;AAC9E,QAAM,EAAE,MAAM,IAAI,IAAI,QAAQ;AAC9B,MAAI,UAAU,UAAa,IAAI,MAAM,UAAU,QAAW;AACxD,WAAO;AAAA,EACT;AACA,QAAM,aAAa,IAAI,KAAK,QAAQ,QAAQ,YAAY,IAAI,KAAK;AACjE,MAAI,eAAe,QAAW;AAC5B,UAAM,IAAI;AAAA,MACR;AAAA,MACA,wBAAwB,IAAI,KAAK,QAAQ,QAAQ,IAAI,oBAAoB,KAAK;AAAA,IAChF;AAAA,EACF;AACA,SAAO;AACT;AAWA,eAAe,eACb,KACA,YACA,OACe;AACf,QAAM,EAAE,WAAW,QAAQ,IAAI,IAAI;AACnC,MAAI,cAAc,MAAM;AACtB,UAAM,IAAI,eAAe,mBAAmB,yBAAyB;AAAA,EACvE;AACA,QAAM,OAAO;AAAA,IACX,SAAS,QAAQ;AAAA,IACjB,QAAQ,WAAW,QAAQ;AAAA,IAC3B,QAAQ,WAAW;AAAA,EACrB;AACA,QAAM,UAAU,MAAM,cAAc,QAAQ,QAAQ,MAAM,WAAW,CAAC,KAAK,CAAC;AAC5E,MAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,UAAM,IAAI,eAAe,aAAa,0BAA0B;AAAA,EAClE;AACF;AAUA,eAAsB,WAAW,KAA4D;AAC3F,QAAM,aAAa,iBAAiB,GAAG;AACvC,MAAI,eAAe,UAAa,IAAI,MAAM,UAAU,QAAW;AAC7D,WAAO;AAAA,EACT;AACA,QAAM,eAAe,KAAK,YAAY,IAAI,MAAM,KAAK;AACrD,QAAM,SAAS;AAAA,IACb,UAAU,CAAC,OAAe,SACxB,WAAW,IAAI,IAAI,KAAK,EAAE,SAAS,QAAQ,CAAC,CAAC;AAAA,EACjD;AACA,SAAQ,MAAM,aAAa,QAAQ,YAAY,IAAI,MAAM,OAAO,WAAW,QAAQ,KAAM;AAC3F;AAUO,SAAS,YAAY,KAAyB;AACnD,SAAO,iBAAiB,GAAG,GAAG,SAAS;AACzC;AAMA,eAAsB,YACpB,KACA,KACmB;AACnB,QAAM,QAAQ,MAAM,QAAQ,MAAM,IAAI,IAAI,MAAM,GAAG,IAAI,KAAK,EAAE,OAAO,IAAI,MAAM,MAAM,CAAC,CAAC;AACvF,SAAO,UAAU,KAAK,KAAK;AAC7B;AAGO,SAAS,UAAU,KAAgB,KAAwB;AAChE,QAAM,QAAQ,MAAM,QAAQ,GAAG,KAAK,IAAI,MAAM,CAAC,OAAO,OAAO,OAAO,YAAY,GAAG,SAAS,CAAC;AAC7F,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,MACA,0BAA0B,IAAI,KAAK,QAAQ,QAAQ,IAAI;AAAA,IACzD;AAAA,EACF;AACA,SAAO,UAAU,GAAe,EAAE,MAAM,GAAG,IAAI,MAAM,KAAK;AAC5D;;;AC5JO,SAASC,aAA+B;AAC7C,SAAO,EAAE,OAAO,CAAC,GAAG,YAAY,KAAK;AACvC;AAGA,SAAS,YACP,KACA,YAC6E;AAC7E,QAAM,EAAE,MAAM,SAAS,MAAM,IAAI;AACjC,QAAM,SAAS,WAAW,MAAM,OAAO,YAAY,MAAM,QAAQ,MAAM,KAAK,CAAC;AAC7E,QAAM,aAAa,iBAAiB,GAAG;AACvC,MAAI,eAAe,QAAW;AAC5B,WAAO,EAAE,QAAQ,QAAQ,iBAAiB,MAAM;AAAA,EAClD;AACA,QAAM,MAAM,WAAW,KAAK,MAAM,OAAO,WAAW,MAAM;AAC1D,QAAM,SAAS,oBAAI,IAAI,CAAC,GAAG,KAAK,GAAG,MAAM,CAAC;AAC1C,SAAO,EAAE,QAAQ,iBAAiB,OAAO,SAAS,IAAI,KAAK;AAC7D;AAGO,SAAS,YACd,KACA,YACA,MACA,YACqB;AACrB,QAAM,EAAE,QAAQ,gBAAgB,IAAI,YAAY,KAAK,UAAU;AAC/D,SAAO;AAAA,IACL,OAAO,KAAK,IAAI,CAAC,QAAQ,SAAS,YAAY,KAAK,MAAM,CAAC;AAAA,IAC1D;AAAA,IACA,GAAI,kBAAkB,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC;AAAA,EAC5C;AACF;;;AChBA,SAAS,cAAc,KAAsB;AAC3C,QAAM,EAAE,OAAO,IAAI,IAAI;AACvB,MAAI,OAAO,SAAS;AAClB,UAAM,WAAW,MAAM;AAAA,EACzB;AACF;AAGA,eAAsB,UAAU,KAA8C;AAC5E,QAAM,QAAQ,MAAM,WAAW,GAAG;AAClC,QAAM,SAAS,UAAU,SAAS,SAAS,MAAM,UAAU,IAAI,MAAM,IAAI,QAAQ,MAAM,IAAI,KAAK;AAChG,QAAM,OAAO,WAAW,SAAS,SAAS,MAAM,UAAU,GAAG;AAC7D,MAAI,UAAU,UAAU,WAAW,UAAU,SAAS,QAAQ;AAC5D,WAAOC,WAAU;AAAA,EACnB;AACA,gBAAc,GAAG;AACjB,QAAM,aAAa,aAAa,IAAI,MAAM,IAAI,QAAQ,UAAU;AAChE,QAAM,QAAQ,YAAY,GAAG;AAC7B,QAAM,OAAO,MAAM,SAAS;AAAA,IAC1B,OAAO,IAAI,KAAK;AAAA,IAChB,OAAO,IAAI,KAAK;AAAA,IAChB,SAAS,IAAI,KAAK,QAAQ;AAAA,IAC1B,OAAO,MAAM,CAAC,MAAM,QAAQ,KAAK,CAAC;AAAA,IAClC;AAAA,IACA,QAAQ,IAAI,MAAM;AAAA,IAClB,OAAO,IAAI,MAAM;AAAA,IACjB,QAAQ;AAAA,MACN,WAAW;AAAA,MACX,MAAM,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM;AAAA,IAChC;AAAA,IACA,YAAY;AAAA,IACZ,UAAU,IAAI,MAAM,UAAU;AAAA,EAChC,CAAC;AACD,SAAO,YAAY,KAAK,YAAY,KAAK,MAAM,KAAK,UAAU;AAChE;AAGA,eAAsB,QACpB,KACA,KAC8B;AAC9B,MAAI,IAAI,MAAM,WAAW,QAAW;AAClC,UAAM,WAAW,oEAAoE;AAAA,MACnF;AAAA,IACF,CAAC;AAAA,EACH;AACA,QAAM,QAAQ,MAAM,WAAW,GAAG;AAClC,MAAI,UAAU,QAAQ;AACpB,WAAOA,WAAU;AAAA,EACnB;AACA,QAAM,SAAS,MAAM,YAAY,KAAK,GAAG;AACzC,gBAAc,GAAG;AACjB,MAAI,OAAO,WAAW,GAAG;AACvB,WAAOA,WAAU;AAAA,EACnB;AACA,QAAM,aAAa,aAAa,IAAI,MAAM,IAAI,QAAQ,UAAU;AAChE,QAAM,OAAO,MAAM,IAAI,KAAK,MAAM,SAAS;AAAA,IACzC,OAAO,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,OAAO,EAAE,GAAG,KAAK,CAAC;AAAA,IAC5C,QAAQ,WAAW,WAAW,QAAQ,CAAC,CAAC;AAAA,EAC1C,CAAC;AACD,QAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;AACtD,QAAM,UAAU,OAAO,OAAO,CAAC,OAAO,MAAM,IAAI,EAAE,CAAC;AACnD,QAAM,UAAU,MAAM,WAAW,IAAI,MAAM,IAAI,QAAQ,MAAM,SAAS,IAAI,OAAO,MAAM;AACvF,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQ,IAAI,CAAC,OAAO,MAAM,IAAI,EAAE,CAAQ;AAAA,IACxC;AAAA,EACF;AACF;;;ACvFO,SAAS,cAAc,SAAoC;AAChE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAoD;AAC1F,UAAM,QAAQ;AACd,QAAI,MAAM,EAAE,SAAS,QAAQ,KAAK,WAAW;AAC3C,aAAOC,WAAU;AAAA,IACnB;AACA,UAAM,MAAiB;AAAA,MACrB,MAAM,SAAS,KAAK,EAAE;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,SAAS,QAAQ,MAAM,MAAM;AAAA,MACpC,KAAK,OAAO,aAAa,GAAG,GAAG,iBAAiB,YAAY;AAAA,IAC9D;AACA,UAAM,MAAM,QAAQ,UAAU;AAC9B,WAAO,QAAQ,SAAY,MAAM,UAAU,GAAG,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,EAC1E;AACA,SAAO;AACT;;;ACWA,SAASC,UAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAASC,MAAK,SAAwB;AACpC,QAAM,IAAI,UAAU,oBAAoB,OAAO,EAAE;AACnD;AAGA,SAASC,YAAW,UAA2C;AAC7D,QAAM,QACJF,UAAS,QAAQ,KACjB,OAAO,SAAS,SAAS,YACzBA,UAAS,SAAS,OAAO,KACzB,OAAO,SAAS,QAAQ;AAC1B,MAAI,CAAC,OAAO;AACV,IAAAC,MAAK,2DAA2D;AAAA,EAClE;AACA,QAAM,QAAgC,CAAC;AACvC,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAwB,GAAG;AAC3E,UAAM,OAAO,aAAa,GAAG;AAC7B,QAAI,SAAS,QAAW;AACtB,YAAM,KAAK,CAAC,MAAM,IAAI,CAAC;AAAA,IACzB;AAAA,EACF;AACA,MAAI,MAAM,WAAW,GAAG;AACtB,IAAAA,MAAK,GAAG,OAAO,SAAS,IAAI,CAAC,qCAAqC;AAAA,EACpE;AACA,SAAO;AACT;AAGA,SAAS,cAAc,UAA4C;AACjE,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,QACJD,UAAS,QAAQ,KACjB,OAAO,KAAK,QAAQ,EAAE,MAAM,CAAC,QAAQ,QAAQ,WAAW,QAAQ,KAAK,KACpE,SAAS,UAAU,YAAgB,SAAS,QAAQ,WACrD,CAAC,SAAS,OAAO,SAAS,GAAG,EAAE;AAAA,IAC7B,CAAC,SAAS,SAAS,UAAa,OAAO,SAAS;AAAA,EAClD;AACF,MAAI,CAAC,OAAO;AACV,IAAAC,MAAK,uFAAuF;AAAA,EAC9F;AACA,SAAO;AACT;AAEA,IAAME,eAAiC,CAAC,UAAU,YAAY,QAAQ;AAGtE,SAAS,aACP,SACA,KAKA;AACA,MAAI,CAACH,UAAS,OAAO,GAAG;AACtB,IAAAC,MAAK,gDAAgD;AAAA,EACvD;AACA,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,QAAQ,CAACE,aAAY,SAAS,GAAG,CAAC;AAChF,MAAI,eAAe,QAAW;AAC5B,IAAAF,MAAK,+BAA+B,UAAU,sBAAsBE,aAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9F;AACA,QAAM,UAAU,kBAAkB,QAAQ,MAAM;AAChD,MAAI,YAAY,QAAW;AACzB,IAAAF,MAAK,UAAU,OAAO,EAAE;AAAA,EAC1B;AACA,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,UAAU,WAAW,SAAY,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,MAAM,SAAS,MAAM;AACnF,MAAI,QAAQ,WAAW,GAAG;AACxB,IAAAA,MAAK,WAAW,OAAO,MAAM,CAAC,wCAAwC;AAAA,EACxE;AACA,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,UAAU,cAAc,QAAQ,QAAQ;AAAA,IACxC;AAAA,EACF;AACF;AAGA,SAASG,gBAAe,UAAuB,MAAc,MAA0B;AACrF,MAAI,SAAS,WAAW,QAAW;AACjC,IAAAH,MAAK,GAAG,SAAS,IAAI,sBAAsB,IAAI,YAAY;AAAA,EAC7D;AACA,QAAM,EAAE,KAAK,IAAI;AACjB,MAAI,SAAS,UAAa,SAAS,SAAS,QAAQ;AAClD,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,QAAQ,SAAS,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,MAAM,MAAM,WAAW,IAAI;AACvF,MAAI,UAAU,QAAW;AACvB,IAAAA;AAAA,MACE,eAAe,SAAS,IAAI,IAAI,IAAI;AAAA,IACtC;AAAA,EACF;AACA,SAAO,MAAM,CAAC;AAChB;AAGA,SAAS,WAAW,UAAuB,MAAc,MAAkB,MAAoB;AAC7F,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,UAAU,QAAW;AACvB;AAAA,EACF;AACA,QAAM,aAAa,OAAO,OAAO,SAAS,aAAa,KAAK,IACxD,SAAS,YAAY,KAAK,IAC1B;AACJ,MAAI,eAAe,QAAW;AAC5B,IAAAA,MAAK,GAAG,SAAS,IAAI,IAAI,IAAI,aAAa,KAAK,4BAA4B,SAAS,IAAI,EAAE;AAAA,EAC5F;AACA,MAAI,WAAW,SAAS,MAAM;AAC5B,IAAAA;AAAA,MACE,GAAG,SAAS,IAAI,IAAI,IAAI,qDAAqD,KAAK,2BAA2B,WAAW,IAAI,sEAAsE,IAAI;AAAA,IACxM;AAAA,EACF;AACF;AAGA,SAASI,gBACP,SACA,UACA,MACA,MACoB;AACpB,MAAI,QAAQ,aAAa,UAAU;AACjC,WAAO,gEAAgE,QAAQ,IAAI;AAAA,EACrF;AACA,MAAI,QAAQ,UAAU,QAAW;AAC/B,WAAO;AAAA,EACT;AACA,SAAO,gBAAgB,SAAS,MAAM,IAAI;AAC5C;AAEA,SAASC,UAKP,UACA,SAC6B;AAC7B,QAAM,EAAE,MAAM,UAAU,QAAQ,IAAI,aAAa,SAASJ,YAAW,QAAQ,CAAC;AAC9E,QAAM,UAAkC,CAAC;AACzC,aAAW,CAAC,MAAM,IAAI,KAAK,SAAS;AAClC,UAAM,aAAaE,gBAAe,UAAU,MAAM,IAAI;AACtD,eAAW,UAAU,MAAM,MAAM,UAAU;AAC3C,UAAM,UAAU,cAAc,EAAE,MAAM,MAAM,YAAY,SAAS,CAAC;AAClE,qBAAiB,SAAS,CAAC,YAAYC,gBAAe,SAAS,UAAU,MAAM,IAAI,CAAC;AAEpF,oBAAgB,OAAO;AACvB,YAAQ,IAAI,IAAI,OAAO,OAAO,EAAE,QAAQ,MAAM,SAAS,OAAO,SAAS,CAAC;AAAA,EAC1E;AACA,SAAO,OAAO,OAAO,OAAO;AAC9B;AASO,IAAME,UAAS,OAAO,OAAO,EAAE,UAAU,OAAa,UAAU,UAAAD,UAAS,CAAC;;;AC5LjF,SAAS,QAAQ,OAAsC;AACrD,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,WAAO;AAAA,EACT;AACA,QAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,SAAO,OAAO,WAAW,YAAY,OAAO,SAAS,KAAK,cAAc,KAAK;AAC/E;AAGO,SAAS,UAAU,OAAoD;AAC5E,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,WAAO,CAAC;AAAA,EACV;AACA,SAAO,MAAM,QAAQ,KAAK,KAAK,MAAM,MAAM,OAAO,IAAK,QAA0B;AACnF;AAGO,SAAS,QAAQ,SAAiC,QAAoC;AAC3F,SAAO,QACJ,OAAO,CAAC,UAAU,MAAM,WAAW,MAAM,EACzC,OAA2B,CAAC,OAAO,UAAU,SAAS,OAAO,MAAM,KAAK,GAAG,IAAI;AACpF;AAGO,SAAS,UAAU,SAAiC,QAAwB;AACjF,SAAO,QAAQ,OAAO,CAAC,UAAU,MAAM,WAAW,MAAM,EAAE;AAC5D;AAMO,SAAS,SAAS,SAAwC;AAC/D,QAAM,SAAS,oBAAI,IAAyB;AAC5C,aAAW,SAAS,SAAS;AAC3B,WAAO,IAAI,MAAM,QAAQ,SAAS,OAAO,IAAI,MAAM,MAAM,GAAG,MAAM,KAAK,KAAK,MAAM,KAAK;AAAA,EACzF;AACA,SAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,EAAE,QAAQ,MAAM,EAAE;AACjE;AAOO,SAAS,UACd,SACA,QACA,OACe;AACf,QAAM,OAAsB,CAAC;AAC7B,MAAI,SAAS;AACb,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,WAAW,QAAQ;AAC3B,WAAK,KAAK,KAAK;AAAA,IACjB,WAAW,CAAC,UAAU,UAAU,MAAM;AACpC,WAAK,KAAK,EAAE,GAAG,OAAO,MAAM,CAAC;AAC7B,eAAS;AAAA,IACX;AAAA,EACF;AACA,MAAI,CAAC,UAAU,UAAU,MAAM;AAC7B,SAAK,KAAK,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAGO,SAAS,SAAS,SAAiCE,QAAoC;AAC5F,SAAOA,WAAU,UAAa,QAAQ,KAAK,CAAC,UAAU,MAAM,UAAU,OAAO;AAC/E;;;AC3EO,SAAS,WAAW,QAAqD;AAC9E,QAAM,WAAW,cAAc,MAAM;AACrC,SAAO,aAAa,SAAY,CAAC,MAAM,IAAI,SAAS,QAAQ,UAAU;AACxE;AAGA,SAAS,QAAQ,SAAuC;AACtD,QAAM,SAAS,QAAQ;AACvB,QAAM,QAAQ,WAAW,SAAY,CAAC,IAAI,WAAW,MAAM,EAAE,IAAI,gBAAgB;AACjF,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,YAAY,MAAS;AACtE;AAGA,SAAS,SAAS,SAAuC;AACvD,QAAM,SAAS,QAAQ;AACvB,QAAM,QAAQ,WAAW,SAAY,CAAC,IAAI,WAAW,MAAM,EAAE,IAAI,YAAY;AAC7E,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AAChE;AAEA,IAAM,SAAgD,OAAO,OAAO;AAAA,EAClE,KAAK;AAAA,EACL,SAAS;AACX,CAAC;AAGM,SAAS,cAAc,SAAqB,MAAuC;AACxF,QAAM,QAAQ,SAAS,QAAQ,QAAQ,OAAO,IAAI,SAAS,OAAO;AAClE,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,EACT;AACA,QAAM,WACJ,QAAQ,WAAW,SAAY,qBAAqB,GAAG,QAAQ,OAAO,IAAI;AAC5E,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,sBAAsB,IAAI,kBAAkB,OAAO,IAAI,CAAC,4BAA4B,QAAQ,IAAI,aAAa,QAAQ;AAAA,EAC9H;AACA,SAAO,sBAAsB,IAAI,sBAAsB,SAAS,QAAQ,YAAY,SAAS,0BAA0B,QAAQ,IAAI,UAAU,MAAM,MAAM;AAC3J;AAEA,SAAS,QAAQ,SAAqB,MAA0B;AAC9D,QAAM,IAAI;AAAA,IACR;AAAA,IACA,sBAAsB,IAAI,oBAAoB,QAAQ,IAAI,KAAK,cAAc,SAAS,IAAI,KAAK,uBAAuB;AAAA,EACxH;AACF;AAGO,SAAS,aAAa,SAAqC;AAChE,QAAM,CAAC,SAAS,GAAG,MAAM,IAAI,QAAQ,OAAO;AAC5C,SAAO,YAAY,UAAa,OAAO,WAAW,IAAI,UAAU,QAAQ,SAAS,KAAK;AACxF;AAGO,SAAS,kBAAkB,SAAqC;AACrE,QAAM,CAAC,MAAM,GAAG,MAAM,IAAI,SAAS,OAAO;AAC1C,SAAO,SAAS,UAAa,OAAO,WAAW,IAAI,OAAO,QAAQ,SAAS,SAAS;AACtF;;;ACzDA,IAAM,cAAiC,OAAO,OAAO,CAAC,QAAQ,YAAY,OAAO,CAAC;AAG3E,SAAS,QAAQ,MAAyC;AAC/D,SAAO,KAAK,WAAW,SAAY,cAAc,OAAO,KAAK,KAAK,MAAM;AAC1E;AAGO,SAAS,YAAY,MAAsB,MAAmC;AACnF,MAAI,KAAK,WAAW,QAAW;AAC7B,WAAO,cAAc,IAAI,IAAI,OAAO;AAAA,EACtC;AACA,SAAO,OAAO,SAAS,YAAY,OAAO,OAAO,KAAK,QAAQ,IAAI,IAC7D,KAAK,OAAO,IAAI,KAAK,OACtB;AACN;AAGO,SAAS,aAAa,MAAgC;AAC3D,SAAO,QAAQ,IAAI,EAAE,OAAO,CAAC,SAAS,YAAY,MAAM,IAAI,MAAM,OAAO;AAC3E;AAGA,SAAS,cAAc,MAA0C;AAC/D,QAAM,OAAO,CAAC,SAAyB,cAAc,QAAQ,YAAY,MAAM,IAAI,KAAK,QAAQ;AAChG,QAAM,WAAW,QAAQ,IAAI,EAAE,OAAO,CAAC,SAAS,WAAW,YAAY,MAAM,IAAI,GAAG,MAAM,CAAC;AAC3F,SAAO,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC;AAC1D;AAEA,SAAS,YAAY,SAAiC;AACpD,SAAO,IAAI,eAAe,cAAc,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC5F;AAGO,SAAS,UAAU,MAAsB,MAAkC;AAChF,QAAM,SAAS,QAAQ,cAAc,IAAI;AACzC,MAAI,WAAW,QAAW;AACxB,UAAM,YAAY,2BAA2B,KAAK,KAAK,6BAA6B;AAAA,EACtF;AACA,QAAM,QAAQ,QAAQ,IAAI;AAC1B,MAAI,CAAC,MAAM,SAAS,MAAM,GAAG;AAC3B,UAAM,QAAQ,MAAM,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI;AACxD,UAAM,YAAY,IAAI,MAAM,sBAAsB,KAAK,KAAK,mBAAmB,KAAK,EAAE;AAAA,EACxF;AACA,SAAO;AACT;AAEA,SAAS,OAAO,OAAwB;AACtC,SAAO,OAAO,UAAU,WAAW,QAAS,KAAK,UAAU,KAAK,KAAK;AACvE;AAGO,SAAS,SAAS,MAAsB,QAAiB,MAAuB;AACrF,SAAO,EAAE,QAAQ,OAAO,MAAM,GAAG,MAAM,OAAO,IAAI,GAAG,OAAO,YAAY,MAAM,IAAI,EAAE;AACtF;AAGO,SAAS,YACd,MACA,MAC+D;AAC/D,MAAI;AACJ,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,YAAY,MAAM,IAAI,KAAK,KAAK,CAAC;AAC/C,QAAI,SAAS,UAAc,UAAU,QAAQ,SAAS,KAAK,OAAO,KAAK,MAAM,KAAK,OAAQ;AACxF,aAAO,EAAE,MAAM,OAAO,IAAI,KAAK,KAAK,CAAC,GAAG,MAAM;AAAA,IAChD;AAAA,EACF;AACA,SAAO,QAAQ,EAAE,MAAM,IAAI,OAAO,KAAK;AACzC;;;AChDO,SAAS,YAAY,KAA4B,IAA0B;AAChF,QAAM,UAAU,aAAa,GAAG;AAChC,QAAM,QAAQ,SAAS,QAAQ;AAC/B,MAAI,YAAY,UAAa,UAAU,QAAW;AAChD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,SAAS,KAAK;AAAA,IACrB,WAAW,IAAI;AAAA,IACf;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,QAAQ,IAAa,OAA8B;AACjE,QAAM,OAAO,SAAS,KAAK;AAC3B,QAAM,YAAY,OAAO,OAAO,YAAY,OAAO,OAAO,eAAe,OAAO;AAChF,QAAM,WAAoB,WAAW,QAAQ,IAAI,IAAI,IAAI,IAAI;AAC7D,QAAM,SACJ,OAAO,aAAa,YACpB,aAAa,QACb,OAAQ,SAA6C,aAAa;AACpE,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,MACA,+CAA+C,IAAI;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AACT;AAQA,eAAsB,eAAkB,IAAa,IAA6C;AAChG,SAAO,MAAM,iBAAiB,IAAI,IAAI;AAAA,IACpC,OAAO;AAAA,IACP,UAAU;AAAA,EACZ,CAAC;AACH;AAGA,eAAsB,aACpB,UACA,MACA,QACA,IACe;AACf,MAAI,aAAa,QAAW;AAC1B,UAAM,QAAQ,MAAM,SAAS,OAAO,OAAO,MAAM,GAAG,KAAK,KAAK,EAAE,CAAC;AAAA,EACnE;AACF;;;AC9DA,SAAS,UAAU,SAAqB,UAAyD;AAC/F,QAAM,UAAwB,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAClE,QAAM,SAAS,QAAQ;AACvB,aAAW,OAAO,WAAW,SAAY,CAAC,IAAI,WAAW,MAAM,GAAG;AAChE,UAAM,OAAO,iBAAiB,GAAG;AACjC,UAAM,QAAQ,aAAa,GAAG;AAC9B,QAAI,SAAS,UAAa,SAAS,UAAU;AAC3C,cAAQ,MAAM,KAAK,KAAK,KAAK;AAC7B,cAAQ,OAAO,KAAK,GAAI,KAAK,UAAU,SAAY,CAAC,IAAI,CAAC,KAAK,KAAK,CAAE;AAAA,IACvE,WAAW,UAAU,UAAa,UAAU,UAAU;AACpD,cAAQ,OAAO,KAAK,KAAK;AAAA,IAC3B,WAAW,IAAI,SAAS,SAAS;AAC/B,cAAQ,OAAO,KAAK,GAAG,IAAI,MAAM,OAAO;AAAA,IAC1C;AAAA,EACF;AACA,SAAO;AACT;AAGA,eAAe,cACb,SACA,IACA,IACA,SACkB;AAClB,QAAM,UAAU,CAAC,GAAG,QAAQ,QAAQ,GAAG,QAAQ,KAAK;AACpD,MAAI,QAAQ,WAAW,KAAK,QAAQ,UAAU,QAAW;AACvD,WAAO;AAAA,EACT;AACA,QAAM,SAAS,OAAO,YAAY,CAAC,CAAC,MAAM,IAAI,GAAG,GAAG,QAAQ,IAAI,CAAC,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;AAC5F,QAAM,MAAM,MAAM,QAAQ,IAAI,QAAQ,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;AACjF,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,QAAQ,OAAO;AAAA,IAC3B,CAAC,WAAW,OAAO,IAAI,MAAM,MAAM,YAAY,IAAI,MAAM,MAAM;AAAA,EACjE;AACA,SACE,SACA,QAAQ,MAAM;AAAA,IAAK,CAAC,YACjB,UAAU,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,UAAU,MAAM,UAAU,OAAO;AAAA,EACxE;AAEJ;AAOA,eAAsB,eACpB,SACA,IACA,IACA,UACkB;AAClB,QAAM,UAAU,UAAU,SAAS,QAAQ;AAC3C,MAAI,MAAM,cAAc,SAAS,IAAI,IAAI,OAAO,GAAG;AACjD,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,QAAQ;AAAA,IAC1B,QAAQ,OAAO,IAAI,OAAO,UAAU;AAClC,YAAM,QAAQ,aAAa,KAAK;AAChC,aAAO,MAAM,WAAW,IACpB,OACA,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,UAAU;AAAA,QACvC,OAAO,EAAE,CAAC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,KAAK,GAAG,EAAE,IAAI,MAAM,EAAE;AAAA,QACzD,QAAQ,EAAE,IAAI,KAAK;AAAA,MACrB,CAAC;AAAA,IACP,CAAC;AAAA,EACH;AACA,SAAO,MAAM,KAAK,CAAC,QAAQ,QAAQ,IAAI;AACzC;;;ACrEA,SAAS,SAAS,MAAkE;AAClF,SAAO,OAAO,SAAS,YAAY,CAAC,eAAe,IAAI,IACnD,EAAE,SAAS,KAAK,SAAS,OAAO,KAAK,MAAM,IAC3C,CAAC;AACP;AAOA,eAAsB,YACpB,MACA,MACA,IAC6B;AAC7B,QAAM,EAAE,WAAW,QAAQ,IAAI;AAC/B,MAAI,cAAc,MAAM;AACtB,UAAM,IAAI,eAAe,mBAAmB,yBAAyB;AAAA,EACvE;AACA,QAAM,SAAS,MAAM,QAAQ,OAAO,UAAU,QAAQ,QAAQ,MAAM,WAAW,CAAC,EAAE,CAAC;AACnF,QAAM,SAAS,OAAO,IAAI,EAAE,KAAK;AACjC,QAAM,SAAS,SAAS,IAAI;AAC5B,QAAM,QAAQ,aAAa,WAAW,QAAQ,QAAQ,IAAI,KAAK;AAC/D,QAAM,UAAU,OAAO,YAAY,UAAa,WAAW,OAAO,OAAO,OAAO;AAChF,MAAI,OAAO,UAAU,UAAa,CAAC,WAAW,CAAC,WAAW,QAAQ,OAAO,KAAK,GAAG;AAC/E,UAAM,IAAI;AAAA,MACR;AAAA,MACA,uBAAuB,KAAK,KAAK,qDAAqD,OAAO,KAAK;AAAA,IACpG;AAAA,EACF;AACA,SAAO,OAAO,YAAY,SAAY,SAAS,SAAS,QAAQ,KAAK;AACvE;AAGO,SAAS,SAAS,KAAyB,OAA2B,OAAqB;AAChG,MAAI,UAAU,QAAQ,CAAC,WAAW,KAAK,KAAK,GAAG;AAC7C,UAAM,IAAI;AAAA,MACR;AAAA,MACA,mBAAmB,KAAK,YAAY,KAAK,uCAAuC,OAAO,MAAM;AAAA,IAC/F;AAAA,EACF;AACF;AAGO,SAAS,UACd,KACA,SACA,OACM;AACN,MAAI,YAAY,QAAQ,CAAC,WAAW,KAAK,OAAO,GAAG;AACjD,UAAM,IAAI;AAAA,MACR;AAAA,MACA,iBAAiB,OAAO,YAAY,KAAK,iCAAiC,OAAO,MAAM;AAAA,IACzF;AAAA,EACF;AACF;;;ACjEA,eAAsB,cACpB,MACA,SACA,OACiB;AACjB,MAAI,QAAQ,gBAAgB,QAAW;AACrC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAA4B,OAAO,OAAO;AAAA,IAC9C,GAAI,MAAM,SAAS,SAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;AAAA,IACvD,GAAI,MAAM,UAAU,SAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;AAAA,EAC5D,CAAC;AACD,QAAM,EAAE,YAAY,IAAI;AACxB,QAAM,QAAiB,MAAM,QAAQ,MAAM,YAAY,QAAQ,KAAK,KAAK,KAAK,EAAE,CAAC;AACjF,MAAI,UAAU,QAAQ,UAAU,QAAW;AACzC,UAAM,IAAI,eAAe,aAAa,cAAc;AAAA,EACtD;AACA,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACoBA,eAAe,SACb,OACA,SACA,IACA,OACiB;AACjB,QAAM,SAAS;AAAA,IACb,IAAI;AAAA,IACJ,CAAC,QAAQ,KAAK,GAAG;AAAA,IACjB,GAAI,QAAQ,UAAU,SAAY,CAAC,IAAI,EAAE,CAAC,QAAQ,KAAK,GAAG,KAAK;AAAA,EACjE;AACA,QAAM,MAAM,MAAM,MAAM,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;AAC5D,MAAI,QAAQ,MAAM;AAChB,UAAM,IAAI,eAAe,aAAa,WAAW,KAAK,EAAE;AAAA,EAC1D;AACA,QAAM,UAAU,UAAU,IAAI,QAAQ,KAAK,CAAC;AAC5C,MAAI,YAAY,QAAW;AACzB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,sBAAsB,KAAK,IAAI,QAAQ,KAAK;AAAA,IAC9C;AAAA,EACF;AACA,QAAMC,SAAQ,QAAQ,UAAU,SAAY,SAAY,IAAI,QAAQ,KAAK;AACzE,SAAO,EAAE,SAAS,OAAO,OAAOA,WAAU,YAAYA,OAAM,SAAS,IAAIA,SAAQ,OAAU;AAC7F;AAGA,SAASC,SAAQ,QAAgB,QAAmB,OAA2C;AAC7F,MAAI,OAAO,UAAU,OAAO,QAAQ;AAClC,WAAO,IAAI;AAAA,MACT;AAAA,MACA,uBAAuB,KAAK;AAAA,IAC9B;AAAA,EACF;AACA,MAAI,OAAO,UAAU,QAAQ,OAAO,SAAS,OAAO,MAAM,MAAM,MAAM;AACpE,WAAO,IAAI,eAAe,aAAa,QAAQ,KAAK,+BAA+B;AAAA,EACrF;AACA,SAAO;AACT;AAOA,eAAe,eACb,MACA,IACA,QACA,QACe;AACf,QAAM,OAAO,UAAU,OAAO,SAAS,OAAO,QAAQ,OAAO,KAAK;AAClE,QAAM,SAAS,SAAS,OAAO,SAAS,OAAO,KAAK,KAAK,CAAC,SAAS,MAAM,OAAO,KAAK;AACrF,QAAM,EAAE,QAAQ,IAAI,KAAK;AACzB,MAAI,UAAU,CAAE,MAAM,eAAe,SAAS,IAAI,OAAO,IAAI,aAAa,OAAO,CAAC,GAAI;AACpF,UAAM,IAAI;AAAA,MACR;AAAA,MACA,uCAAuC,KAAK,KAAK;AAAA,IACnD;AAAA,EACF;AACF;AAGA,eAAe,WACb,MACA,SACA,QACgB;AAChB,QAAM,UAAU,aAAa,KAAK,QAAQ,OAAO;AACjD,SAAO,MAAM,eAAe,KAAK,IAAI,OAAO,OAAO;AACjD,UAAM,MAAM,MAAM,YAAY,MAAM,QAAQ,MAAM,OAAO,EAAE;AAC3D,aAAS,KAAK,OAAO,OAAO,KAAK,KAAK;AACtC,UAAM,QAAQ,QAAQ,IAAI,KAAK,KAAK;AACpC,UAAM,SAAS,MAAM,SAAS,OAAO,SAAS,OAAO,IAAI,KAAK,KAAK;AACnE,UAAM,UAAUA,SAAQ,QAAQ,QAAQ,KAAK,KAAK;AAClD,QAAI,YAAY,QAAW;AACzB,YAAM;AAAA,IACR;AACA,UAAM,SAAS,QAAQ,OAAO,SAAS,OAAO,MAAM;AACpD,cAAU,KAAK,QAAQ,KAAK,KAAK;AACjC,UAAM,eAAe,MAAM,IAAI,QAAQ,MAAM;AAC7C,QAAI,WAAW,OAAO,SAAS,UAAU,OAAO,SAAS,OAAO,MAAM,MAAM,GAAG;AAC7E,aAAO,SAAS,OAAO,OAAO;AAAA,IAChC;AACA,UAAM,OAAO,UAAU,OAAO,SAAS,OAAO,QAAQ,OAAO,KAAK;AAClE,UAAM,MAAM,OAAO;AAAA,MACjB,OAAO,EAAE,IAAI,OAAO,GAAG;AAAA,MACvB,MAAM,EAAE,CAAC,QAAQ,KAAK,GAAG,KAAK;AAAA,MAC9B,QAAQ,EAAE,IAAI,KAAK;AAAA,IACrB,CAAC;AACD,UAAM,EAAE,MAAM,IAAI,QAAQ,MAAM,IAAI;AACpC,UAAM,aAAa,QAAQ,UAAU,MAAM,EAAE,MAAM,IAAI,QAAQ,QAAQ,OAAO,MAAM,GAAG,EAAE;AACzF,WAAO,SAAS,IAAI;AAAA,EACtB,CAAC;AACH;AAGO,SAAS,aAAa,SAAqC;AAChE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAsC;AAC5E,UAAM,EAAE,IAAI,QAAQ,MAAM,IAAI;AAC9B,UAAM,SAAS,EAAE,MAAM,SAAS,IAAI,QAAQ,OAAO,QAAQ,MAAM;AACjE,WAAO,MAAM,WAAW,YAAY,KAAK,EAAE,GAAG,SAAS,MAAM;AAAA,EAC/D;AACA,SAAO;AACT;AAGO,SAAS,mBAAmB,SAAqC;AACtE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAsC;AAC5E,UAAM,EAAE,IAAI,MAAM,OAAO,MAAM,IAAI;AACnC,UAAM,OAAO,YAAY,KAAK,EAAE;AAChC,UAAM,SAAS,MAAM,cAAc,MAAM,SAAS,EAAE,MAAM,MAAM,CAAC;AACjE,WAAO,MAAM,WAAW,MAAM,SAAS,EAAE,MAAM,SAAS,IAAI,QAAQ,OAAO,QAAQ,MAAM,CAAC;AAAA,EAC5F;AACA,SAAO;AACT;AAGO,SAAS,gBAAgB,SAAqC;AACnE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAsC;AAC5E,UAAM,EAAE,IAAI,QAAQ,MAAM,IAAI;AAC9B,UAAM,SAAS,EAAE,MAAM,YAAY,IAAI,QAAQ,OAAO,QAAQ,KAAK;AACnE,WAAO,MAAM,WAAW,YAAY,KAAK,EAAE,GAAG,SAAS,MAAM;AAAA,EAC/D;AACA,SAAO;AACT;AAGO,SAAS,eAAe,SAAqC;AAClE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAsC;AAC5E,UAAM,EAAE,IAAI,OAAO,IAAI;AACvB,UAAM,SAAS,EAAE,MAAM,WAAW,IAAI,QAAQ,OAAO,MAAM,QAAQ,KAAK;AACxE,WAAO,MAAM,WAAW,YAAY,KAAK,EAAE,GAAG,SAAS,MAAM;AAAA,EAC/D;AACA,SAAO;AACT;AAGO,SAAS,oBAAgC;AAC9C,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAsC;AAC5E,UAAM,OAAO,YAAY,KAAK,EAAE;AAChC,UAAM,UAAU,aAAa,KAAK,QAAQ,OAAO;AACjD,UAAM,QAAQ,QAAQ,KAAK,IAAI,KAAK,KAAK;AACzC,UAAM,EAAE,GAAG,IAAI;AACf,WAAO,UAAU,MAAM,SAAS,OAAO,SAAS,IAAI,KAAK,KAAK,GAAG,OAAO;AAAA,EAC1E;AACA,SAAO;AACT;;;AC7MO,SAAS,qBAAiC;AAC/C,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAA4C;AAClF,UAAM,OAAO,YAAY,KAAK,EAAE;AAChC,UAAM,OAAO,kBAAkB,KAAK,QAAQ,OAAO;AACnD,UAAM,QAAQ;AACd,UAAM,QAAiB;AAAA,MACrB,CAAC,KAAK,MAAM,KAAK;AAAA,MACjB,CAAC,MAAM,KAAK;AAAA,IACd;AACA,UAAM,OAAO,MAAM,SAAS;AAAA,MAC1B,OAAO,QAAQ,KAAK,IAAI,KAAK,KAAK;AAAA,MAClC,OAAO,SAAS,KAAK,KAAK;AAAA,MAC1B,SAAS,KAAK,QAAQ;AAAA,MACtB,OAAO,EAAE,CAAC,KAAK,KAAK,GAAG,MAAM,QAAQ;AAAA,MACrC;AAAA,MACA,QAAQ,MAAM;AAAA,MACd,OAAO,MAAM;AAAA,MACb,QAAQ,EAAE,IAAI,MAAM,CAAC,KAAK,IAAI,GAAG,MAAM,CAAC,KAAK,KAAK,GAAG,KAAK;AAAA,MAC1D,YAAY;AAAA,MACZ,UAAU;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,MACL,OAAO,KAAK,KAAK,IAAI,CAAC,QAAQ,SAAS,MAAM,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC;AAAA,MAC7E,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AACA,SAAO;AACT;;;ACSA,eAAe,OAAO,OAAsB,MAAsB,QAAgC;AAChG,SAAO,MAAM,MAAM,SAAS;AAAA,IAC1B,OAAO,EAAE,CAAC,KAAK,KAAK,GAAG,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG,OAAO,OAAO;AAAA,IAClE,QAAQ,EAAE,IAAI,MAAM,CAAC,KAAK,KAAK,GAAG,KAAK;AAAA,EACzC,CAAC;AACH;AAOA,eAAe,aACb,MACA,IACA,MACA,QACkB;AAClB,QAAM,QAAQ,aAAa,IAAI;AAC/B,QAAM,QACJ,MAAM,WAAW,IACb,OACA,MAAM,QAAQ,IAAI,KAAK,KAAK,EAAE,UAAU;AAAA,IACtC,OAAO;AAAA,MACL,CAAC,KAAK,KAAK,GAAG,OAAO;AAAA,MACrB,CAAC,KAAK,IAAI,GAAG,EAAE,KAAK,OAAO,OAAO;AAAA,MAClC,CAAC,KAAK,KAAK,GAAG,EAAE,IAAI,MAAM;AAAA,IAC5B;AAAA,IACA,QAAQ,EAAE,IAAI,KAAK;AAAA,EACrB,CAAC;AACP,SAAO,UAAU,QAAS,MAAM,eAAe,KAAK,QAAQ,SAAS,IAAI,OAAO,SAAS,IAAI;AAC/F;AAEA,SAAS,UAAU,OAA+B;AAChD,SAAO,IAAI;AAAA,IACT;AAAA,IACA,8CAA8C,KAAK;AAAA,EACrD;AACF;AAEA,SAAS,oBAAoB,OAAyB;AACpD,SACE,iBAAiB,SACjB,MAAM,SAAS,mCACd,MAA8C,SAAS;AAE5D;AAGA,eAAe,OACb,MACA,SACA,QACA,MACiB;AACjB,QAAM,OAAO,kBAAkB,KAAK,QAAQ,OAAO;AACnD,QAAM,QAAQ,UAAU,MAAM,IAAI;AAClC,SAAO,MAAM,eAAe,KAAK,IAAI,OAAO,OAAO;AACjD,UAAM,MAAM,MAAM,YAAY,MAAM,QAAQ,MAAM,OAAO,OAAO;AAChE,aAAS,KAAK,YAAY,MAAM,KAAK,GAAG,KAAK,KAAK;AAClD,UAAM,QAAQ,QAAQ,IAAI,KAAK,KAAK;AACpC,SAAK,MAAM,OAAO,OAAO,MAAM,MAAM,GAAG,SAAS,GAAG;AAClD,YAAM,IAAI;AAAA,QACR;AAAA,QACA,iCAAiC,KAAK,KAAK;AAAA,MAC7C;AAAA,IACF;AACA,QAAI;AACF,YAAM,MAAM,OAAO;AAAA,QACjB,MAAM,EAAE,CAAC,KAAK,KAAK,GAAG,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG,OAAO,QAAQ,CAAC,KAAK,KAAK,GAAG,MAAM;AAAA,QACtF,QAAQ,EAAE,IAAI,KAAK;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,CAAC,oBAAoB,KAAK,GAAG;AAC/B,cAAM;AAAA,MACR;AACA,YAAMC,WAAU,IAAI,eAAe,aAAa,4BAA4B,KAAK,KAAK,EAAE;AACxF,MAAAA,SAAQ,QAAQ;AAChB,YAAMA;AAAA,IACR;AACA,UAAM,EAAE,SAAS,IAAI,OAAO,IAAI;AAChC,UAAM,SAAS,EAAE,MAAM,UAAU,IAAI,QAAQ,QAAQ,MAAM,OAAO,MAAM;AACxE,UAAM,aAAa,QAAQ,UAAU,MAAM,QAAQ,EAAE;AACrD,WAAO,SAAS,MAAM,QAAQ,KAAK;AAAA,EACrC,CAAC;AACH;AAGA,eAAe,IACb,MACA,SACA,QACA,MACe;AACf,QAAM,OAAO,kBAAkB,KAAK,QAAQ,OAAO;AACnD,SAAO,MAAM,eAAe,KAAK,IAAI,OAAO,OAAO;AACjD,UAAM,MACJ,SAAS,WAAW,MAAM,YAAY,MAAM,QAAQ,MAAM,OAAO,OAAO,IAAI;AAC9E,UAAM,QAAQ,QAAQ,IAAI,KAAK,KAAK;AACpC,UAAM,OAAO,MAAM,OAAO,OAAO,MAAM,MAAM;AAC7C,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,SAAS,UACX,IAAI,eAAe,aAAa,gCAAgC,KAAK,KAAK,EAAE,IAC5E,IAAI,eAAe,aAAa,qCAAqC,KAAK,KAAK,EAAE;AAAA,IACvF;AACA,UAAM,UAAU,YAAY,MAAM,IAAI;AACtC,QAAI,QAAQ,QAAW;AACrB,gBAAU,KAAK,QAAQ,OAAO,KAAK,KAAK;AAAA,IAC1C;AACA,QAAI,QAAQ,UAAU,WAAW,CAAE,MAAM,aAAa,MAAM,IAAI,MAAM,MAAM,GAAI;AAC9E,YAAM,UAAU,KAAK,KAAK;AAAA,IAC5B;AACA,UAAM,CAAC,MAAM,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,QAAQ,IAAI,EAAE;AAChD,WAAO,SAAS,UAAa,KAAK,WAAW,IACzC,MAAM,OAAO,EAAE,OAAO,EAAE,IAAI,KAAK,GAAG,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC,IAC1D,MAAM,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC;AAC/D,UAAM,SAAS,EAAE,MAAM,IAAI,OAAO,SAAS,QAAQ,OAAO,QAAQ,OAAO,KAAK;AAC9E,UAAM,aAAa,QAAQ,UAAU,MAAM,EAAE,GAAG,QAAQ,QAAQ,QAAQ,KAAK,GAAG,EAAE;AAClF,WAAO;AAAA,EACT,CAAC;AACH;AAGA,eAAe,WACb,MACA,SACA,QACA,MACiB;AACjB,QAAM,OAAO,kBAAkB,KAAK,QAAQ,OAAO;AACnD,YAAU,MAAM,IAAI;AACpB,SAAO,MAAM,eAAe,KAAK,IAAI,OAAO,OAAO;AACjD,UAAM,MAAM,MAAM,YAAY,MAAM,QAAQ,MAAM,OAAO,OAAO;AAChE,aAAS,KAAK,YAAY,MAAM,IAAI,GAAG,KAAK,KAAK;AACjD,UAAM,QAAQ,QAAQ,IAAI,KAAK,KAAK;AACpC,UAAM,OAAO,MAAM,OAAO,OAAO,MAAM,MAAM;AAC7C,QAAI,KAAK,WAAW,GAAG;AACrB,YAAM,IAAI,eAAe,aAAa,qCAAqC,KAAK,KAAK,EAAE;AAAA,IACzF;AACA,UAAM,UAAU,YAAY,MAAM,IAAI;AACtC,cAAU,KAAK,QAAQ,OAAO,KAAK,KAAK;AACxC,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,MAAM;AAC9C,aAAO,SAAS,MAAM,OAAO,QAAQ,IAAI;AAAA,IAC3C;AACA,UAAM,UAAU,QAAQ,UAAU,WAAW,YAAY,MAAM,IAAI,MAAM;AACzE,QAAI,WAAW,CAAE,MAAM,aAAa,MAAM,IAAI,MAAM,MAAM,GAAI;AAC5D,YAAM,UAAU,KAAK,KAAK;AAAA,IAC5B;AACA,UAAM,MAAM,WAAW;AAAA,MACrB,OAAO,EAAE,CAAC,KAAK,KAAK,GAAG,OAAO,SAAS,CAAC,KAAK,IAAI,GAAG,OAAO,OAAO;AAAA,MAClE,MAAM,EAAE,CAAC,KAAK,KAAK,GAAG,KAAK;AAAA,IAC7B,CAAC;AACD,UAAM,EAAE,SAAS,IAAI,OAAO,IAAI;AAChC,UAAM,SAAS,EAAE,MAAM,WAAW,IAAI,QAAQ,QAAQ,QAAQ,MAAM,OAAO,KAAK;AAChF,UAAM,aAAa,QAAQ,UAAU,MAAM,QAAQ,EAAE;AACrD,WAAO,SAAS,MAAM,QAAQ,IAAI;AAAA,EACpC,CAAC;AACH;AAGO,SAAS,cAAc,SAAqC;AACjE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAuC;AAC7E,UAAM,EAAE,SAAS,QAAQ,KAAK,IAAI;AAClC,WAAO,MAAM,OAAO,YAAY,KAAK,EAAE,GAAG,SAAS,EAAE,SAAS,OAAO,GAAG,IAAI;AAAA,EAC9E;AACA,SAAO;AACT;AAGO,SAAS,oBAAoB,SAAqC;AACvE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAuC;AAC7E,UAAM,EAAE,SAAS,MAAM,OAAO,KAAK,IAAI;AACvC,UAAM,OAAO,YAAY,KAAK,EAAE;AAChC,UAAM,SAAS,MAAM,cAAc,MAAM,SAAS,EAAE,MAAM,MAAM,CAAC;AACjE,WAAO,MAAM,OAAO,MAAM,SAAS,EAAE,SAAS,OAAO,GAAG,IAAI;AAAA,EAC9D;AACA,SAAO;AACT;AAGO,SAAS,cAAc,SAAqC;AACjE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAqC;AAC3E,UAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,WAAO,MAAM,IAAI,YAAY,KAAK,EAAE,GAAG,SAAS,EAAE,SAAS,OAAO,GAAG,QAAQ;AAAA,EAC/E;AACA,SAAO;AACT;AAGO,SAAS,aAAa,SAAqC;AAChE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAqC;AAC3E,UAAM,OAAO,YAAY,KAAK,EAAE;AAChC,QAAI,KAAK,cAAc,MAAM;AAC3B,YAAM,IAAI,eAAe,mBAAmB,kBAAkB;AAAA,IAChE;AACA,UAAM,EAAE,QAAQ,IAAI;AACpB,WAAO,MAAM,IAAI,MAAM,SAAS,EAAE,SAAS,QAAQ,KAAK,UAAU,OAAO,GAAG,OAAO;AAAA,EACrF;AACA,SAAO;AACT;AAGO,SAAS,eAAe,SAAqC;AAClE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAuC;AAC7E,UAAM,EAAE,SAAS,QAAQ,KAAK,IAAI;AAClC,WAAO,MAAM,WAAW,YAAY,KAAK,EAAE,GAAG,SAAS,EAAE,SAAS,OAAO,GAAG,IAAI;AAAA,EAClF;AACA,SAAO;AACT;;;AC3OA,IAAM,YAAwB,OAAO,OAAO,EAAE,OAAO,QAAQ,CAAC;AAC9D,IAAM,cAA0B,OAAO,OAAO,EAAE,OAAO,SAAS,IAAI,UAAU,CAAC;AAC/E,IAAM,WAAuB,OAAO,OAAO,EAAE,OAAO,OAAO,CAAC;AAC5D,IAAM,aAAyB,OAAO,OAAO,EAAE,OAAO,QAAQ,IAAI,UAAU,CAAC;AAGtE,IAAM,iBAAkE,OAAO,OAAO;AAAA,EAC3F,OAAO;AAAA,EACP,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,aAAa;AAAA,EACb,OAAO;AACT,CAAC;AAED,IAAM,SACJ,OAAO,OAAO;AAAA,EACZ,OAAO;AAAA,EACP,aAAa;AAAA,EACb,SAAS;AAAA,EACT,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,aAAa;AACf,CAAC;AAGI,SAASC,WAAU,QAA2B,SAAqC;AACxF,SAAO,OAAO,MAAM,EAAE,OAAO;AAC/B;;;ACnBA,SAASC,UAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAASC,MAAK,SAAwB;AACpC,QAAM,IAAI,UAAU,qBAAqB,OAAO,EAAE;AACpD;AAGA,SAASC,YAAW,UAA4C;AAC9D,QAAM,QACJF,UAAS,QAAQ,KACjB,OAAO,SAAS,SAAS,YACzBA,UAAS,SAAS,OAAO,KACzB,OAAO,SAAS,QAAQ;AAC1B,MAAI,CAAC,OAAO;AACV,IAAAC,MAAK,2DAA2D;AAAA,EAClE;AACA,QAAM,QAAiC,CAAC;AACxC,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAwB,GAAG;AAC3E,UAAM,OAAO,cAAc,GAAG;AAC9B,QAAI,SAAS,QAAW;AACtB,YAAM,KAAK,CAAC,MAAM,IAAI,CAAC;AAAA,IACzB;AAAA,EACF;AACA,MAAI,MAAM,WAAW,GAAG;AACtB,IAAAA,MAAK,GAAG,OAAO,SAAS,IAAI,CAAC,sCAAsC;AAAA,EACrE;AACA,SAAO;AACT;AAGA,SAASE,aAAY,QAAiB,OAAyC;AAC7E,MAAI,WAAW,QAAW;AACxB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAACH,UAAS,MAAM,GAAG;AACrB,IAAAC,MAAK,mDAAmD;AAAA,EAC1D;AACA,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,CAAC,MAAM,SAAS,IAAI,GAAG;AACzB,MAAAA,MAAK,iBAAiB,IAAI,gDAAgD;AAAA,IAC5E;AACA,UAAM,UAAU,SAAS,SAAY,SAAY,kBAAkB,IAAI;AACvE,QAAI,YAAY,QAAW;AACzB,MAAAA,MAAK,eAAe,IAAI,KAAK,OAAO,EAAE;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,WACP,SACA,KAC8B;AAC9B,QAAM,EAAE,aAAa,SAAS,IAAI;AAClC,QAAM,SAAS,IAAI,KAAK,CAAC,CAAC,EAAE,IAAI,MAAM,CAAC,eAAe,cAAc,EAAE,SAAS,KAAK,MAAM,CAAC;AAC3F,MAAI,UAAU,OAAO,gBAAgB,YAAY;AAC/C,IAAAA,MAAK,wEAAwE;AAAA,EAC/E;AACA,MAAI,CAAC,UAAU,gBAAgB,QAAW;AACxC,IAAAA,MAAK,mFAAmF;AAAA,EAC1F;AACA,MAAI,aAAa,UAAa,OAAO,aAAa,YAAY;AAC5D,IAAAA,MAAK,kDAAkD;AAAA,EACzD;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAASG,cAAa,SAAiC;AACrD,MAAI,YAAY,QAAW;AACzB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAACJ,UAAS,OAAO,GAAG;AACtB,IAAAC,MAAK,gEAAgE;AAAA,EACvE;AACA,QAAM,UAAU,CAAC,UAAU,eAAe,YAAY,SAAS;AAC/D,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,SAAS,GAAG,CAAC;AAC5E,MAAI,eAAe,QAAW;AAC5B,IAAAA,MAAK,+BAA+B,UAAU,sBAAsB,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,EAC1F;AACA,SAAO;AACT;AAGA,SAASI,gBACP,SACA,UACA,MACoB;AACpB,MAAI,QAAQ,aAAa,UAAU;AACjC,WAAO,iEAAiE,QAAQ,IAAI;AAAA,EACtF;AACA,MAAI,QAAQ,UAAU,QAAW;AAC/B,WAAO;AAAA,EACT;AACA,SAAO,cAAc,SAAS,IAAI;AACpC;AAEA,SAASC,UACP,aACG,MAC+B;AAClC,QAAM,MAAMJ,YAAW,QAAQ;AAC/B,QAAM,UAAUE,cAAa,KAAK,CAAC,CAAC;AACpC,QAAM,QAAQ,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACtC,QAAM,SAASD,aAAY,QAAQ,QAAQ,KAAK;AAChD,QAAM,UAAU,eAAe,QAAQ,SAAS,OAAOF,KAAI;AAC3D,QAAM,QAAQ,WAAW,SAAS,GAAG;AACrC,QAAM,UAAkC,CAAC;AACzC,aAAW,CAAC,MAAM,IAAI,KAAK,KAAK;AAC9B,UAAM,OAAQ,OAAO,IAAI,KAAgC,eAAe,KAAK,MAAM;AACnF,UAAM,UAAUM,WAAU,KAAK,QAAQ,OAAO,OAAO,EAAE,GAAG,OAAO,KAAK,CAAC,CAAC;AACxE,qBAAiB,SAAS,CAAC,YAAYF,gBAAe,SAAS,UAAU,KAAK,IAAI,CAAC;AACnF,QAAI,KAAK,WAAW,gBAAgB,KAAK,WAAW,eAAe;AAEjE,sBAAgB,OAAO;AAAA,IACzB;AACA,YAAQ,IAAI,IAAI,SAAS,MAAM,MAAM,SAAS,OAAO;AAAA,EACvD;AACA,SAAO,OAAO,OAAO,OAAO;AAC9B;AAQO,IAAMG,WAAU,OAAO,OAAO,EAAE,UAAU,QAAa,UAAU,UAAAF,UAAS,CAAC;;;AClI3E,IAAM,sBAAyC,OAAO,OAAO;AAAA,EAClE;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAQM,IAAM,qBAAwC,OAAO,OAAO;AAAA,EACjE;AAAA,EACA;AACF,CAAC;AAGD,IAAM,gBAAmC,OAAO,OAAO;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAGD,IAAM,iBACJ,OAAO,OAAO;AAAA,EACZ,IAAI;AAAA,IACF,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AAAA,EACA,WAAW;AAAA,IACT,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,aAAa;AAAA,EACf;AACF,CAAC;AAmBH,SAAS,aAAa,QAA+C;AACnE,SAAO,WAAW,UAAa,mBAAmB,SAAS,MAAM,IAC7D,qBACA,CAAC,GAAG,oBAAoB,MAAM;AACpC;AAMO,SAAS,gBACd,OACA,QACoB;AACpB,QAAM,OAAO,UAAU,UAAa,WAAW;AAC/C,SAAO,QAAQ,SAAS,OAAO,KAAK,MAAM,SAAS,KAAK,IAAI,OAAO,SAAS;AAC9E;AA0BA,SAASG,WAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAGO,SAAS,QAAQ,MAAsB;AAC5C,SAAO,KACJ,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,MAAM,GAAG,EACjB,QAAQ,SAAS,CAAC,WAAW,OAAO,YAAY,CAAC;AACtD;AAGO,SAAS,cAAc,aAA6B;AACzD,QAAM,QAAQ,YACX,QAAQ,aAAa,EAAE,EACvB,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,MAAM,CAAC,WAAW,OAAO,YAAY,CAAC;AACjD,SAAO,GAAG,KAAK;AACjB;AAEA,SAAS,iBAAiB,aAAsB,aAAqBC,OAA2B;AAC9F,MAAI,gBAAgB,QAAW;AAC7B,WAAO,cAAc,WAAW;AAAA,EAClC;AACA,MAAI,OAAO,gBAAgB,YAAY,YAAY,WAAW,GAAG;AAC/D,IAAAA,MAAK,wCAAwC;AAAA,EAC/C;AACA,SAAO;AACT;AAOA,SAAS,YACP,QACA,CAAC,OAAO,UAAU,GAClBA,OACqB;AACrB,MAAI,WAAW,UAAa,WAAW,OAAO;AAC5C,WAAO,oBAAI,IAAI;AAAA,EACjB;AACA,MAAI,WAAW,MAAM;AACnB,IAAAA,MAAK,8BAA8B;AAAA,EACrC;AACA,SAAO,IAAI,IAAI,WAAW,OAAO,CAAC,SAAS,MAAM,SAAS,IAAI,CAAC,CAAC;AAClE;AAOA,SAAS,YACP,cACA,CAAC,OAAO,UAAU,GAClB,QACAA,OACqB;AACrB,QAAM,WAAW,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,qBAAqB,GAAG,UAAU,CAAC,CAAC,EAAE;AAAA,IACrE,CAAC,SAAS,CAAC,OAAO,IAAI,IAAI;AAAA,EAC5B;AACA,MAAI,iBAAiB,QAAW;AAC9B,WAAO,IAAI,IAAI,QAAQ;AAAA,EACzB;AACA,QAAM,QACJ,MAAM,QAAQ,YAAY,KAC1B,aAAa,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,KACrD,IAAI,IAAI,YAAY,EAAE,SAAS,aAAa;AAC9C,MAAI,CAAC,OAAO;AACV,IAAAA,MAAK,qDAAqD;AAAA,EAC5D;AACA,aAAW,QAAQ,cAA0B;AAC3C,QAAI,SAAS,QAAQ,CAAC,MAAM,SAAS,IAAI,GAAG;AAC1C,MAAAA,MAAK,kBAAkB,IAAI,mDAAmD;AAAA,IAChF;AACA,QAAI,OAAO,IAAI,IAAI,GAAG;AACpB,MAAAA;AAAA,QACE,kBAAkB,IAAI;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACA,SAAO,oBAAI,IAAI,CAAC,GAAG,UAAU,GAAI,YAAyB,CAAC;AAC7D;AAEA,SAAS,gBAAgB,UAA6C;AACpE,QAAM,aAAa,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,cAAc,SAAS,GAAG,CAAC;AACnF,MAAI,eAAe,QAAW;AAC5B,WAAO,uBAAuB,UAAU,mBAAmB,cAAc,KAAK,IAAI,CAAC;AAAA,EACrF;AACA,QAAM,EAAE,MAAM,OAAO,YAAY,gBAAgB,IAAI;AACrD,QAAM,QAAQ,CAAC,YAAY,YAAY,eAAe,YAAY,EAAE;AAAA,IAClE,CAAC,QAAQ,SAAS,GAAG,MAAM,UAAa,OAAO,SAAS,GAAG,MAAM;AAAA,EACnE;AACA,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA,EAC5B;AACA,QAAM,OAAO,CAAC,UACZ,UAAU,UAAc,OAAO,UAAU,YAAY,MAAM,SAAS;AACtE,QAAM,SACJ,eAAe,UACd,MAAM,QAAQ,UAAU,KAAK,WAAW,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AACrF,QAAM,SAAS,SAAS,UAAa,kBAAkB,KAAK,CAAC,UAAU,UAAU,IAAI;AACrF,SAAO,KAAK,KAAK,KAAK,KAAK,eAAe,KAAK,UAAU,SACrD,SACA;AACN;AAGA,SAAS,eACP,gBACA,OACA,QACAA,OACyC;AACzC,MAAI,mBAAmB,QAAW;AAChC,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAACD,WAAS,cAAc,GAAG;AAC7B,IAAAC,MAAK,8DAA8D;AAAA,EACrE;AACA,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC7D,QAAI,CAAC,MAAM,SAAS,IAAI,KAAK,OAAO,IAAI,IAAI,GAAG;AAC7C,MAAAA,MAAK,oBAAoB,IAAI,8CAA8C;AAAA,IAC7E;AACA,UAAM,UAAUD,WAAS,QAAQ,IAAI,gBAAgB,QAAQ,IAAI;AACjE,QAAI,YAAY,QAAW;AACzB,MAAAC,MAAK,uBAAuB,IAAI,KAAK,OAAO,EAAE;AAAA,IAChD;AACA,QAAK,SAA2B,aAAa,QAAQ,qBAAqB,SAAS,IAAI,GAAG;AACxF,MAAAA,MAAK,oBAAoB,IAAI,2CAA2C;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,OAAO,OAAkC;AAChD,SAAO,MAAM,IAAI,CAAC,SAAS,IAAI,IAAI,GAAG,EAAE,KAAK,IAAI;AACnD;AAQA,SAAS,cACP,UACA,UACA,OACAA,OACiC;AACjC,QAAM,QAAQ,CAAC,OAAeC,UAAiD;AAC7E,eAAW,QAAQA,OAAM;AACvB,UAAI,qBAAqB,SAAS,IAAI,GAAG;AACvC,QAAAD,MAAK,GAAG,KAAK,MAAM,IAAI,2CAA2C;AAAA,MACpE;AACA,UAAI,CAAC,MAAM,IAAI,GAAG;AAChB,QAAAA,MAAK,GAAG,KAAK,MAAM,IAAI,8CAA8C;AAAA,MACvE;AAAA,IACF;AACA,WAAO,IAAI,IAAIC,KAAI;AAAA,EACrB;AACA,MAAI,aAAa,QAAW;AAC1B,WAAO,aAAa,SAAY,SAAY,MAAM,6BAA6B,QAAQ;AAAA,EACzF;AACA,QAAM,QACJ,MAAM,QAAQ,QAAQ,KACtB,SAAS,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,KACjD,IAAI,IAAI,QAAQ,EAAE,SAAS,SAAS;AACtC,MAAI,CAAC,OAAO;AACV,IAAAD,MAAK,iDAAiD;AAAA,EACxD;AACA,QAAM,OAAO,MAAM,YAAY,QAAoB;AACnD,MACE,aAAa,WACZ,SAAS,WAAW,KAAK,QAAQ,CAAC,SAAS,MAAM,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,IAC1E;AACA,IAAAA;AAAA,MACE,kBAAkB,OAAO,QAAoB,CAAC,kCAAkC,OAAO,QAAQ,CAAC;AAAA,IAClG;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,eACP,WACA,UACAA,OACM;AACN,MAAI,aAAa,QAAW;AAC1B;AAAA,EACF;AACA,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,SAAS,GAAG;AACxD,QAAI,SAAS,aAAa,QAAQ,CAAC,SAAS,IAAI,IAAI,GAAG;AACrD,MAAAA;AAAA,QACE,oBAAoB,IAAI;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,SAAS,aAAa,SAAS,SAAS,IAAI,IAAI,GAAG;AACrD,MAAAA;AAAA,QACE,oBAAoB,IAAI;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;AAGA,SAAS,QACP,OACA,QACmD;AACnD,QAAM,QAAQ,OAAO,OAAO,gBAAgB,MAAM,IAAI,IAAI,eAAe,MAAM,IAAI,IAAI;AACvF,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,MAAM,MAAM;AAAA,IACZ,MAAM,MAAM;AAAA,IACZ,OAAO,QAAQ,MAAM,IAAI;AAAA,IACzB,UAAU,MAAM;AAAA,IAChB,UAAU,CAAC,qBAAqB,SAAS,MAAM,IAAI;AAAA,IACnD,aAAa,MAAM,SAAS;AAAA,IAC5B,GAAI,MAAM,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,MAAM,WAAW;AAAA,IACzE,GAAI,OAAO,IAAI,MAAM,IAAI,IAAI,EAAE,MAAM,SAAkB,IAAI,CAAC;AAAA,EAC9D;AACF;AAGA,SAAS,QAAQ,QAAyD;AACxE,QAAM,QAAQ,OAAO,KAAK,cAAc,EAAE;AAAA,IAAQ,CAAC,SACjD,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,IAAI;AAAA,EAC9C;AACA,SAAO,CAAC,GAAG,OAAO,GAAG,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,SAAS,KAAK,CAAC,CAAC;AACvE;AAEA,SAAS,aAAa,QAA4C;AAChE,QAAM,EAAE,WAAW,IAAI;AACvB,SAAO,OAAO;AAAA,IACZ,eAAe,SAAY,SAAS,EAAE,GAAG,QAAQ,YAAY,OAAO,OAAO,CAAC,GAAG,UAAU,CAAC,EAAE;AAAA,EAC9F;AACF;AAUO,SAAS,cACd,aACA,MACA,SACAA,OACa;AACb,QAAM,QAAQ,KAAK,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI;AACnD,QAAM,aAAa,aAAa,QAAQ,YAAY;AACpD,QAAM,SAAS,YAAY,QAAQ,QAAQ,CAAC,OAAO,UAAU,GAAGA,KAAI;AACpE,QAAM,SAAS,YAAY,QAAQ,cAAc,CAAC,OAAO,UAAU,GAAG,QAAQA,KAAI;AAClF,QAAM,SAAS,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,IAAI,EAAE,KAAK,CAAC,SAAS,OAAO,IAAI,IAAI,CAAC;AAC7E,MAAI,WAAW,QAAW;AACxB,IAAAA,MAAK,IAAI,MAAM,wDAAwD;AAAA,EACzE;AACA,QAAM,YAAY,eAAe,QAAQ,gBAAgB,OAAO,QAAQA,KAAI;AAC5E,QAAM,WAAW;AAAA,IACf,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,CAAC,SAAS,MAAM,SAAS,IAAI,KAAK,CAAC,OAAO,IAAI,IAAI;AAAA,IAClDA;AAAA,EACF;AACA,iBAAe,WAAW,UAAUA,KAAI;AACxC,QAAM,SAAS,QAAQ,KAAK,MAAM,EAC/B,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,MAAM,IAAI,CAAC,EACzC;AAAA,IAAI,CAAC,UACJ,aAAa;AAAA,MACX,GAAG,QAAQ,OAAO,MAAM;AAAA,MACxB,GAAG,UAAU,MAAM,IAAI;AAAA,MACvB,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,UAAU,SAAS,IAAI,MAAM,IAAI,EAAE;AAAA,MACvE,UAAU,KAAK,KAAK,SAAS,MAAM,IAAI;AAAA,MACvC,YAAY,KAAK,OAAO,SAAS,MAAM,IAAI;AAAA,IAC7C,CAAC;AAAA,EACH;AACF,QAAM,OAAyB,OAAO,OAAO;AAAA,IAC3C;AAAA,IACA,aAAa,iBAAiB,QAAQ,aAAa,aAAaA,KAAI;AAAA,IACpE,QAAQ,OAAO,OAAO,MAAM;AAAA,EAC9B,CAAC;AACD,QAAM,WAAW,IAAI,IAAI,OAAO,OAAO,CAAC,UAAU,CAAC,MAAM,QAAQ,EAAE,IAAI,CAAC,UAAU,MAAM,IAAI,CAAC;AAC7F,QAAM,QAAQ,oBAAI,IAAI;AAAA,IACpB,GAAI,YAAY,CAAC;AAAA,IACjB,GAAG,OAAO,QAAQ,SAAS,EACxB,OAAO,CAAC,CAAC,EAAE,QAAQ,MAAM,SAAS,aAAa,IAAI,EACnD,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AAAA,EACzB,CAAC;AACD,SAAO,OAAO,OAAO,EAAE,MAAM,QAAQ,UAAU,QAAQ,MAAM,CAAC;AAChE;AAOO,SAAS,mBACd,MACA,UACkB;AAClB,MAAI,CAAC,KAAK,OAAO,KAAK,CAAC,UAAU,SAAS,IAAI,MAAM,IAAI,KAAK,MAAM,QAAQ,GAAG;AAC5E,WAAO;AAAA,EACT;AACA,QAAM,SAAS,KAAK,OAAO;AAAA,IAAI,CAAC,UAC9B,SAAS,IAAI,MAAM,IAAI,KAAK,MAAM,WAC9B,aAAa,EAAE,GAAG,OAAO,UAAU,MAAM,CAAC,IAC1C;AAAA,EACN;AACA,SAAO,OAAO,OAAO,EAAE,GAAG,MAAM,QAAQ,OAAO,OAAO,MAAM,EAAE,CAAC;AACjE;;;ACrbO,SAAS,eAAe,SAAyC;AACtE,SAAO,gBAAgB,QAAQ,QAAQ,OAAO,QAAQ,YAAY;AACpE;AAGO,SAASE,SAAQ,IAAa,OAA8B;AACjE,QAAM,OAAO,SAAS,KAAK;AAC3B,QAAM,YAAY,OAAO,OAAO,YAAY,OAAO,OAAO,eAAe,OAAO;AAChF,QAAM,WAAoB,WAAW,QAAQ,IAAI,IAAI,IAAI,IAAI;AAC7D,QAAM,SACJ,OAAO,aAAa,YACpB,aAAa,QACb,OAAQ,SAA6C,aAAa;AACpE,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,MACA,6CAA6C,IAAI;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,UACd,KACA,IACA,WACW;AACX,QAAM,UAAU,aAAa,GAAG;AAChC,QAAM,QAAQ,SAAS,QAAQ;AAC/B,QAAM,aAAa,SAAS,QAAQ,YAAY,IAAI,QAAQ;AAC5D,MAAI,YAAY,UAAa,UAAU,UAAa,eAAe,QAAW;AAC5E,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAAS,UAAU,eAAe,OAAO,CAAC;AAChD,QAAM,EAAE,UAAU,IAAI;AACtB,QAAM,QAAQ,cAAc,OAAO,OAAQ,aAAa,WAAW,QAAQ,QAAQ,IAAI,KAAK;AAC5F,QAAM,SAAS,WAAW,MAAM,OAAO,KAAK;AAC5C,QAAM,SAAS,UAAU,UAAU,SAAS,oBAAI,IAAI,CAAC,GAAG,QAAQ,GAAG,OAAO,MAAM,CAAC;AACjF,SAAO;AAAA,IACL;AAAA,IACA,OAAO,SAAS,KAAK;AAAA,IACrB,OAAOA,SAAQ,IAAI,KAAK;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,oBAAI,IAAI,CAAC,GAAG,QAAQ,GAAG,OAAO,MAAM,CAAC;AAAA,IAC9C;AAAA,EACF;AACF;AAGO,SAAS,OAAO,MAAiB,KAAsB;AAC5D,SAAO,SAAS,KAAK,YAAY,KAAK,KAAK,OAAO;AACpD;AAEA,IAAM,kBAAuC,OAAO,OAAO,oBAAI,IAAY,CAAC;AAGrE,SAAS,SAAS,MAAiB,KAAsB;AAC9D,SAAO,SAAS,KAAK,YAAY,KAAK,eAAe;AACvD;AAGO,SAAS,UAAU,MAAiB,OAAgC;AACzE,QAAM,SAAS,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,IAAI,IAAI,CAAC;AACzD,MAAI,WAAW,QAAW;AACxB,UAAM,IAAI;AAAA,MACR;AAAA,MACA,IAAI,MAAM,mBAAmB,KAAK,QAAQ,QAAQ,IAAI;AAAA,IACxD;AAAA,EACF;AACF;;;ACnGA,IAAM,cAAmC,oBAAI,IAAI;AAG1C,SAAS,iBAAiB,SAAmC;AAClE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAmD;AACzF,UAAM,OAAO,UAAU,KAAK,IAAI,QAAQ,SAAS;AACjD,UAAM,QAAQ;AACd,cAAU,MAAM,YAAY,KAAK,CAAC;AAClC,UAAM,QAAQ,UAAU,aAAa,QAAQ,KAAK,MAAM,KAAK,MAAM,GAAG,MAAM,IAAI;AAChF,UAAM,QAAQ,UAAU,MAAM,QAAQ,MAAS;AAC/C,UAAM,SAAS;AAAA,MACb,KAAK,WAAW;AAAA,MAChB,MAAM,IAAI,CAAC,CAAC,MAAM,MAAM,MAAM;AAAA,IAChC;AACA,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,OAAC,MAAM,KAAK,IAAI,MAAM,QAAQ,IAAI;AAAA,QAChC,KAAK,MAAM,SAAS;AAAA,UAClB;AAAA,UACA;AAAA,UACA,SAAS,UAAU,OAAO,WAAW;AAAA,UACrC,OAAO,MAAM,OAAO,KAAK,MAAM;AAAA,UAC/B,MAAM,MAAM;AAAA,QACd,CAAC;AAAA,QACD,KAAK,MAAM,MAAM,EAAE,MAAM,CAAC;AAAA,MAC5B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,YAAM,QAAQ,OAAO,EAAE,QAAQ,QAAW,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,EAAE,CAAC;AAAA,IAC5F;AACA,WAAO;AAAA,MACL,OAAO,KAAK,IAAI,CAAC,QAAQ,OAAO,MAAM,GAAG,CAAC;AAAA,MAC1C;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,YAAY,KAAK,KAAK,QAAQ,MAAM,QAAQ;AAAA,IAC9C;AAAA,EACF;AACA,SAAO;AACT;;;ACtCA,SAAS,cAAc,MAAiB,IAA8B;AACpE,QAAM,EAAE,WAAW,QAAQ,IAAI,KAAK;AACpC,QAAM,UAAU,kBAAkB;AAAA,IAChC,CAAC,UAAU,CAAC,OAAO,WAAW,QAAQ,WAAW,QAAQ,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC;AAAA,EACjF;AACA,SAAO;AAAA,IACL;AAAA,IACA,OAAO,QAAQ,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,MAAM,MAAM,OAAO,CAAC;AAAA,IACxD,QAAQ,OAAO,YAAY,OAAO;AAAA,IAClC,UAAU,WAAW,SAAS,KAAK;AAAA,EACrC;AACF;AAGO,SAAS,wBAAwB,SAAmC;AACzE,QAAM,UAAU,CAAC,EAAE,OAAO,KAAK,GAAG,MAAiD;AACjF,UAAM,OAAO,UAAU,KAAK,IAAI,QAAQ,SAAS;AACjD,WAAO,QAAQ,QAAQ,cAAc,MAAO,MAAkB,EAAE,CAAC;AAAA,EACnE;AACA,SAAO;AACT;AAGO,SAAS,mBAAmB,SAAmC;AACpE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAiD;AACvF,UAAM,OAAO,UAAU,KAAK,IAAI,QAAQ,SAAS;AACjD,UAAM,EAAE,GAAG,IAAI;AACf;AAAA,MACE,MAAM,KAAK,MAAM,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,IAAI,KAAK,EAAE,CAAC;AAAA,MACnE,WAAW,KAAK,KAAK;AAAA,IACvB;AACA,IAAC,IAA2C,QAAQ,KAAK,OAAO,CAAC,EAAE,CAAC;AACpE,WAAO,cAAc,MAAM,EAAE;AAAA,EAC/B;AACA,SAAO;AACT;;;ACnCA,eAAsB,WACpB,MACA,SACA,MACe;AACf,QAAM,EAAE,QAAQ,SAAS,IAAI,KAAK;AAClC,QAAM,QAAQ,OAAO,KAAK,IAAI;AAC9B,QAAM,SAAS,MACZ,OAAO,CAAC,SAAS,OAAO,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,EACvD,IAAI,CAAC,UAAU;AAAA,IACd,MAAM,CAAC,QAAQ,IAAI;AAAA,IACnB,SAAS,OAAO,IAAI,IAAI,IAAI,IAAI,IAAI,8BAA8B,IAAI,IAAI;AAAA,EAC5E,EAAE;AACJ,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,IAAI,eAAe,cAAc,sDAAsD;AAAA,MAC3F;AAAA,IACF,CAAC;AAAA,EACH;AACA,YAAU,MAAM,KAAK;AACrB,QAAM;AAAA,IACJ,KAAK;AAAA,IACL,KAAK;AAAA,IACL;AAAA,IACA,SAAS,QAAQ,MAAM,UAAU;AAAA,IACjC,CAAC,MAAM;AAAA,EACT;AACF;AAGA,SAAS,eAAe,OAAgC;AACtD,MAAI,EAAE,iBAAiB,QAAQ;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,EAAE,KAAK,IAAI;AACjB,SACE,MAAM,SAAS,iCACd,MAAM,SAAS,mCAAmC,SAAS;AAEhE;AAQO,SAAS,aAAa,OAAyB;AACpD,MAAI,CAAC,eAAe,KAAK,GAAG;AAC1B,WAAO;AAAA,EACT;AACA,QAAM,UAAU;AAChB,QAAM,UAAU,IAAI,eAAe,cAAc,SAAS;AAAA,IACxD,QAAQ;AAAA,MACN;AAAA,QACE,MAAM,CAAC,MAAM;AAAA,QACb,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AACD,UAAQ,QAAQ;AAChB,SAAO;AACT;;;AC9DA,eAAe,QAAQ,MAAiB,IAA8B;AACpE,QAAM,MAAM,MAAM,KAAK,MAAM,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,QAAQ,KAAK,WAAW,OAAO,CAAC;AACzF,SAAO,OAAO,MAAM,WAAW,KAAK,WAAW,KAAK,KAAK,EAAE,CAAC;AAC9D;AAmBA,SAAS,UAAU,SAAuB,MAAsB,OAAyB;AACvF,QAAM,EAAE,YAAY,IAAI;AACxB,MAAI,gBAAgB,QAAW;AAC7B;AAAA,EACF;AACA,QAAM,MAAM,KAAK;AACjB,QAAM,MAAM,aAAa,KAAK,GAAG,GAAG,gBAAgB,CAAC,OAAsB,QAAQ,QAAQ,GAAG,CAAC;AAC/F,QAAM,SAAS,CAAC,UAAyB;AACvC,QAAI,IAAI,MAAM,wDAAwD;AAAA,MACpE,UAAU;AAAA,MACV,QAAQ,MAAM;AAAA,MACd,IAAI,MAAM;AAAA,MACV,OAAO,UAAU,KAAK;AAAA,IACxB,CAAC;AAAA,EACH;AACA,MAAI;AACF,QAAI,MAAM,YAAY,OAAO,GAAG,CAAC,EAAE,MAAM,MAAM;AAAA,EACjD,SAAS,OAAO;AACd,WAAO,KAAK;AAAA,EACd;AACF;AASA,eAAe,QACb,SACA,MACA,MACA,QACA,SACkB;AAClB,QAAM,EAAE,SAAS,YAAY,IAAI;AACjC,QAAM,UAAU,OAAO,OAAsB,WAAoB;AAC/D,QAAI;AACF,aAAO,MAAM,QAAQ,OAAO,MAAM;AAAA,IACpC,SAAS,OAAO;AACd,YAAM,aAAa,KAAK;AAAA,IAC1B;AAAA,EACF;AACA,MAAI,YAAY,UAAa,gBAAgB,QAAW;AACtD,YAAQ,MAAM,QAAQ,KAAK,OAAO,KAAK,GAAG;AAAA,EAC5C;AACA,MAAI;AACJ,QAAM,QAAQ,MAAM;AAAA,IAClB,KAAK;AAAA,IACL,OAAO,OAAO;AACZ,YAAM,OAAO,MAAM,QAAQC,SAAQ,IAAI,KAAK,KAAK,GAAG,WAAW,aAAa;AAC5E,YAAM,QAAQ,CAAC,QAAoC,MAAM,SAAS,MAAM,GAAG,IAAI;AAC/E,cAAQ;AAAA,QACN;AAAA,QACA,IAAI,KAAK;AAAA,QACT,GAAI,WAAW,gBAAgB,CAAC,IAAI,EAAE,QAAQ,MAAM,KAAK,MAAM,EAAE;AAAA,QACjE,OAAO,MAAM,KAAK,KAAK;AAAA,MACzB;AACA,YAAM,UAAU,OAAO,KAAK,KAAsC,EAAE;AACpE,aAAO,KAAK;AAAA,IACd;AAAA,IACA,EAAE,OAAO,qDAAqD;AAAA,EAChE;AACA,MAAI,UAAU,QAAW;AACvB,cAAU,SAAS,MAAM,KAAK;AAAA,EAChC;AACA,SAAO;AACT;AAGO,SAAS,gBAAgB,SAAmC;AACjE,QAAM,UAAU,OAAO,EAAE,OAAO,KAAK,GAAG,MAAwC;AAC9E,UAAM,OAAO,UAAU,KAAK,IAAI,QAAQ,SAAS;AACjD,WAAO,MAAM,QAAQ,MAAO,MAAkB,EAAE;AAAA,EAClD;AACA,SAAO;AACT;AAGA,SAAS,KAAK,KAAqB;AACjC,SAAO,OAAQ,IAAkC,EAAE;AACrD;AAGO,SAAS,mBAAmB,SAAmC;AACpE,QAAM,UAAU,OAAO,SAA2C;AAChE,UAAM,OAAO,UAAU,KAAK,KAAK,KAAK,IAAI,QAAQ,SAAS;AAC3D,UAAM,EAAE,KAAK,IAAI,KAAK;AACtB,UAAM,WAAW,MAAM,SAAS,IAAI;AACpC,WAAO,MAAM,QAAQ,SAAS,MAAM,MAAM,eAAe,OAAO,UAAU;AACxE,YAAM,QAAQ,MAAM,MAAM,OAAO,EAAE,MAAM,QAAQ,KAAK,WAAW,OAAO,CAAC;AACzE,aAAO,EAAE,IAAI,KAAK,KAAK,GAAG,OAAO,OAAO,OAAO,MAAM,KAAK,EAAE;AAAA,IAC9D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAGO,SAAS,mBAAmB,SAAmC;AACpE,QAAM,UAAU,OAAO,SAA2C;AAChE,UAAM,OAAO,UAAU,KAAK,KAAK,KAAK,IAAI,QAAQ,SAAS;AAC3D,UAAM,EAAE,IAAI,KAAK,IAAI,KAAK;AAC1B,UAAM,WAAW,MAAM,SAAS,IAAI;AACpC,QAAI,OAAO,KAAK,IAAI,EAAE,WAAW,GAAG;AAClC,aAAO,MAAM,QAAQ,MAAM,EAAE;AAAA,IAC/B;AACA,UAAM,EAAE,OAAO,IAAI,KAAK;AACxB,WAAO,MAAM,QAAQ,SAAS,MAAM,MAAM,eAAe,OAAO,OAAO,eAAe;AACpF,YAAM,SAAS,aAAa,MAAM,MAAM,WAAW,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI;AAChF,YAAM,QAAQ,MAAM,MAAM,OAAO,EAAE,OAAO,EAAE,GAAG,GAAG,MAAM,OAAO,CAAC;AAChE,aAAO,EAAE,IAAI,QAAQ,OAAO,OAAO,OAAO,MAAM,KAAK,EAAE;AAAA,IACzD,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAGO,SAAS,mBAAmB,SAAmC;AACpE,QAAM,UAAU,OAAO,SAA2C;AAChE,UAAM,OAAO,UAAU,KAAK,KAAK,KAAK,IAAI,QAAQ,SAAS;AAC3D,UAAM,EAAE,GAAG,IAAI,KAAK;AACpB,WAAO,MAAM,QAAQ,SAAS,MAAM,MAAM,eAAe,OAAO,OAAO,eAAe;AACpF,YAAM,SAAS,aAAa,KAAK,WAAW,SAAS,EAAE,IAAI,KAAK;AAChE,YAAM,SAAS,MAAM,MAAM,OAAO,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC;AAC3D,aAAO,EAAE,IAAI,GAAI,aAAa,EAAE,OAAO,IAAI,CAAC,GAAI,OAAO,MAAM,OAAO,KAAK;AAAA,IAC3E,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;AC1JO,IAAM,uBAA2C,OAAO,OAAO,EAAE,SAAS,QAAQ,CAAC;AAE1F,IAAMC,UAEF,OAAO,OAAO;AAAA,EAChB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AAAA,EACb,aAAa;AAAA,EACb,kBAAkB;AAAA,EAClB,aAAa;AACf,CAAC;AAUD,SAAS,iBAAiB,SAAmC;AAC3D,QAAM,YAAY,oBAAI,QAAmC;AACzD,QAAM,UAAU,CAAC,SAAwC;AACvD,UAAM,UAAU,aAAa,KAAK,GAAG;AACrC,QAAI,YAAY,QAAW;AACzB,aAAO,QAAQ,QAAQ,QAAQ,UAAU,MAAS,EAAE,IAAI;AAAA,IAC1D;AACA,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,SAAS,gBAAgB,QAAQ,OAAO,QAAQ,YAAY;AAClE,UAAM,UAAU,UAAU,IAAI,OAAO,KAAK,oBAAI,IAAkB;AAChE,cAAU,IAAI,SAAS,OAAO;AAC9B,QAAI,SAAS,QAAQ,IAAI,UAAU,EAAE;AACrC,QAAI,WAAW,QAAW;AACxB,eAAS,mBAAmB,QAAQ,UAAU,MAAM,EAAE,MAAM,eAAe,OAAO,CAAC;AACnF,cAAQ,IAAI,UAAU,IAAI,MAAM;AAAA,IAClC;AACA,WAAO,QAAQ,QAAQ,MAAM;AAAA,EAC/B;AACA,SAAO;AACT;AAGO,SAASC,WAAU,SAAmC;AAC3D,QAAM,EAAE,OAAO,IAAI,QAAQ;AAC3B,SAAO,WAAW,cAAc,iBAAiB,OAAO,IAAID,QAAO,MAAM,EAAE,OAAO;AACpF;;;ACSA,IAAME,eAAiC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAASC,WAAS,OAAwC;AACxD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAASC,MAAK,SAAwB;AACpC,QAAM,IAAI,UAAU,mBAAmB,OAAO,EAAE;AAClD;AAGA,SAASC,YAAW,UAA0C;AAC5D,QAAM,QACJF,WAAS,QAAQ,KACjB,OAAO,SAAS,SAAS,YACzBA,WAAS,SAAS,OAAO,KACzB,OAAO,SAAS,QAAQ;AAC1B,MAAI,CAAC,OAAO;AACV,IAAAC,MAAK,2DAA2D;AAAA,EAClE;AACA,QAAM,QAA+B,CAAC;AACtC,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAwB,GAAG;AAC3E,UAAM,OAAO,YAAY,GAAG;AAC5B,QAAI,SAAS,QAAW;AACtB,YAAM,KAAK,CAAC,MAAM,IAAI,CAAC;AAAA,IACzB;AAAA,EACF;AACA,MAAI,MAAM,WAAW,GAAG;AACtB,IAAAA,MAAK,GAAG,OAAO,SAAS,IAAI,CAAC,oCAAoC;AAAA,EACnE;AACA,MAAI,MAAM,KAAK,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,WAAW,SAAS,MAAM,GAAG;AAC7D,IAAAA;AAAA,MACE,gDAAgD,OAAO,SAAS,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAASE,cAAa,SAAiC;AACrD,MAAI,YAAY,QAAW;AACzB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAACH,WAAS,OAAO,GAAG;AACtB,IAAAC;AAAA,MACE;AAAA,IACF;AAAA,EACF;AACA,QAAM,aAAa,OAAO,KAAK,OAAO,EAAE,KAAK,CAAC,QAAQ,CAACF,aAAY,SAAS,GAAG,CAAC;AAChF,MAAI,eAAe,QAAW;AAC5B,IAAAE,MAAK,+BAA+B,UAAU,sBAAsBF,aAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9F;AACA,SAAO;AACT;AAGA,SAASK,aAAY,QAAiB,OAAyC;AAC7E,MAAI,WAAW,QAAW;AACxB,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAACJ,WAAS,MAAM,GAAG;AACrB,IAAAC,MAAK,mDAAmD;AAAA,EAC1D;AACA,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,CAAC,MAAM,SAAS,IAAI,GAAG;AACzB,MAAAA,MAAK,iBAAiB,IAAI,8CAA8C;AAAA,IAC1E;AACA,UAAM,UAAU,SAAS,SAAY,SAAY,kBAAkB,IAAI;AACvE,QAAI,YAAY,QAAW;AACzB,MAAAA,MAAK,eAAe,IAAI,KAAK,OAAO,EAAE;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,iBACP,UACA,OAC+B;AAC/B,QAAM,QAAQ,oBAAI,IAA+B;AACjD,aAAW,EAAE,SAAS,KAAK,OAAO;AAChC,QAAI,aAAa,QAAW;AAC1B,YAAM,IAAI,CAAC,GAAG,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAQ,GAAG,QAAQ;AAAA,IACzD;AAAA,EACF;AACA,MAAI,MAAM,OAAO,GAAG;AAClB,IAAAA;AAAA,MACE,mDAAmD,SAAS,IAAI;AAAA,IAClE;AAAA,EACF;AACA,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC;AAC9B;AAGA,SAAS,SACP,UACA,KACA,SACA,cACa;AACb,QAAM,QAAQ,IAAI,IAAI,CAAC,CAAC,EAAEI,KAAI,MAAMA,KAAI;AACxC,QAAM,CAAC,KAAK,IAAI;AAChB,QAAM,OAAO;AAAA,IACX,QAAQ,OAAO,UAAU,CAAC;AAAA,IAC1B,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC,QAAQ,IAAI,MAAM,CAAC,CAAC;AAAA,IACvD,MAAM,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;AAAA,IACnD,UAAU,iBAAiB,UAAU,KAAK;AAAA,EAC5C;AACA,SAAO;AAAA,IACL,SAAS;AAAA,IACT;AAAA,IACA;AAAA,MACE,aAAa,QAAQ;AAAA,MACrB,cAAc,QAAQ;AAAA,MACtB,UAAU,QAAQ;AAAA,MAClB,gBAAgB,QAAQ;AAAA,MACxB,QAAQ,QAAQ;AAAA,MAChB,GAAI,iBAAiB,SAAY,CAAC,IAAI,EAAE,aAAa;AAAA,IACvD;AAAA,IACAJ;AAAA,EACF;AACF;AAGA,SAAS,eACP,UACA,KACA,SACmD;AACnD,QAAM,WAAW,oBAAI,IAAyB;AAC9C,SAAO,CAAC,iBAAiB;AACvB,QAAI,SAAS,SAAS,IAAI,gBAAgB,EAAE;AAC5C,QAAI,WAAW,QAAW;AACxB,eAAS,SAAS,UAAU,KAAK,SAAS,YAAY;AACtD,eAAS,IAAI,gBAAgB,IAAI,MAAM;AAAA,IACzC;AACA,WAAO;AAAA,EACT;AACF;AAOA,SAAS,gBACP,WACA,QACA,EAAE,SAAS,aAAa,GACJ;AACpB,QAAM,SAAS,gBAAgB,QAAQ,OAAO,YAAY;AAC1D,MAAI;AACJ,MAAI;AACF,aAAS,UAAU,MAAM;AAAA,EAC3B,SAAS,OAAO;AACd,WAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,EAC9D;AACA,MAAI,UAAU,OAAO,OAAO,SAAS,GAAG;AACtC,UAAM,QACJ,WAAW,SACP,sDAAsD,QAAQ,SAAS,EAAE,MACzE,4BAA4B,MAAM;AACxC,WAAO,mGAAmG,KAAK;AAAA,EACjH;AACA,SAAO;AACT;AAQA,SAASK,gBACP,SACA,UACA,QACoB;AACpB,MAAI,QAAQ,aAAa,UAAU;AACjC,WAAO,+DAA+D,QAAQ,IAAI;AAAA,EACpF;AACA,MAAI,QAAQ,UAAU,QAAW;AAC/B,WAAO;AAAA,EACT;AACA,QAAMC,aAAY,eAAe,OAAO;AACxC,QAAM,WAAW,CAAC,GAAG,OAAO,KAAK,EAAE,KAAK,CAAC,SAASA,WAAU,IAAI,IAAI,CAAC;AACrE,SAAO,aAAa,SAChB,SACA,IAAI,QAAQ,sBAAsB,QAAQ,IAAI;AACpD;AAEA,SAASC,UACP,UACA,SACgC;AAChC,QAAM,MAAMN,YAAW,QAAQ;AAC/B,QAAMO,WAAUN,cAAa,OAAO;AACpC,QAAM,QAAQ,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI;AACtC,QAAM,SAASC,aAAYK,SAAQ,QAAQ,KAAK;AAChD,QAAM,UAAU,eAAeA,SAAQ,SAAS,OAAOR,KAAI;AAC3D,QAAM,YAAY,eAAe,UAAU,KAAKQ,QAAO;AAEvD,QAAM,SAAS,UAAU,MAAS;AAClC,QAAM,EAAE,SAAS,YAAY,IAAIA;AACjC,MAAI,YAAY,UAAa,OAAO,YAAY,YAAY;AAC1D,IAAAR,MAAK,gDAAgD;AAAA,EACvD;AACA,MAAI,gBAAgB,UAAa,OAAO,gBAAgB,YAAY;AAClE,IAAAA,MAAK,gDAAgD;AAAA,EACvD;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAkC,CAAC;AACzC,aAAW,CAAC,MAAM,IAAI,KAAK,KAAK;AAC9B,UAAM,OAAQ,OAAO,IAAI,KAAgC;AACzD,UAAM,UAAUS,WAAU,EAAE,MAAM,WAAW,MAAM,GAAG,MAAM,CAAC;AAC7D,qBAAiB,SAAS,CAAC,YAAYJ,gBAAe,SAAS,UAAU,MAAM,CAAC;AAChF;AAAA,MAAgB;AAAA,MAAS,CAAC,WACxB,gBAAgB,WAAWG,SAAQ,WAAW,MAAM,MAAM;AAAA,IAC5D;AACA,QAAIA,SAAQ,WAAW,MAAM;AAE3B,uBAAiB,OAAO;AAAA,IAC1B;AACA,QAAI,KAAK,WAAW,eAAe,KAAK,WAAW,YAAY;AAE7D,sBAAgB,OAAO;AAAA,IACzB;AACA,YAAQ,IAAI,IAAI,SAAS,MAAM,MAAM,SAAS,OAAO;AAAA,EACvD;AACA,SAAO,OAAO,OAAO,OAAO;AAC9B;AASO,IAAME,SAAQ,OAAO,OAAO,EAAE,UAAU,MAAa,UAAU,UAAAH,UAAS,CAAC;;;AC7ThF,eAAsB,iBAAsC;AAE1D,QAAM,CAAC,eAAe,WAAW,IAAI,MAAM,QAAQ,IAAI;AAAA,IACrD,OAAO,0BAA0B;AAAA,IACjC,OAAO,OAAO;AAAA,EAChB,CAAC;AACD,SAAO,EAAE,eAAe,cAAc,eAAe,cAAc,YAAY,aAAa;AAC9F;AASO,SAAS,iBAAiB,OAAyB;AACxD,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,EACT;AACA,QAAM,EAAE,MAAM,QAAQ,IAAI;AAC1B,MAAI,SAAS,0BAA0B,SAAS,oBAAoB;AAClE,WAAO;AAAA,EACT;AACA,SACE,OAAO,YAAY,aAClB,QAAQ,SAAS,oBAAoB,KAAK,QAAQ,SAAS,kBAAkB;AAElF;;;ACoEA,SAAS,aAAa,QAAqB,QAAgB,MAAoB;AAC7E,MAAI,WAAW;AACf,SAAO,GAAG,SAAS,CAAC,UAAU;AAC5B,QAAI,CAAC,UAAU;AACb,iBAAW;AACX,aAAO,KAAK,0DAA0D;AAAA,QACpE,QAAQ;AAAA,QACR,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MAC9D,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AACD,SAAO,GAAG,SAAS,MAAM;AACvB,eAAW;AAAA,EACb,CAAC;AACH;AA8BA,eAAsB,kBACpB,IACA,UAA+B,CAAC,GACH;AAC7B,QAAM,SACJ,QAAQ,QAAQ,MAAM,EAAE,SAAS,eAAe,CAAC,KACjD,cAAc,MAAM,EAAE,SAAS,eAAe,CAAC;AAEjD,QAAM,EAAE,OAAO,aAAa,OAAO,MAAM,UAAU,KAAK,EAAE,IAAI;AAC9D,QAAM,MAAM,QAAQ,aAAa,aAAa,EAAE;AAEhD,MAAI;AAEF,UAAM,QAAQ,MAAM,eAAe;AAEnC,UAAM,gBAAgB,MAAM;AAM5B,UAAM,eAAe,MAAM;AAO3B,UAAM,YAAY,aAAa;AAAA,MAC7B,QAAQ,EAAE,MAAM,KAAK;AAAA,MACrB;AAAA,MACA,UAAU;AAAA,IACZ,CAAC;AAED,UAAM,YAAY,UAAU,UAAU;AACtC,iBAAa,WAAW,QAAQ,SAAS;AACzC,iBAAa,WAAW,QAAQ,WAAW;AAG3C,UAAM,QAAQ,IAAI,CAAC,UAAU,QAAQ,GAAG,UAAU,QAAQ,CAAC,CAAC;AAG5D,OAAG,QAAQ,cAAc,WAAW,WAAW,EAAE,IAAI,CAAC,CAAqC;AAE3F,wBAAoB,IAA8B,MAAM;AAExD,WAAO,KAAK,8BAA8B,IAAI,IAAI,IAAI,EAAE;AAGxD,UAAM,UAAU,YAAY;AAC1B,UAAI;AACF,cAAM,QAAQ,IAAI,CAAC,UAAU,KAAK,GAAG,UAAU,KAAK,CAAC,CAAC;AACtD,eAAO,KAAK,4BAA4B;AAAA,MAC1C,SAAS,OAAO;AACd,eAAO,MAAM,qCAAqC;AAAA,UAChD,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,QAC9D,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,MAAM,QAAQ;AAAA,EAClC,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAG1E,QAAI,iBAAiB,KAAK,GAAG;AAC3B,aAAO;AAAA,QACL;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO,MAAM,kCAAkC,EAAE,OAAO,aAAa,CAAC;AAAA,IACxE;AAEA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,YAAY;AAAA,MAErB;AAAA,IACF;AAAA,EACF;AACF;AAOA,eAAsB,0BAA4C;AAChE,MAAI;AACF,UAAM,eAAe;AACrB,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC/LO,SAAS,YAAY,SAAmC;AAC7D,QAAM,SAAS,SAAS,OAAO;AAE/B,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,IAAI,MAAM,OAAO,OAAO;AAAA,EAChC;AACF;AAiBO,SAAS,SAAS,SAAkD;AACzE,QAAM;AAAA,IACJ;AAAA,IACA,iBAAiB;AAAA,IACjB,cAAc;AAAA,EAChB,IAAI;AAGJ,MAAI,kBAAkB,QAAQ,IAAI,aAAa,cAAc;AAC3D,WAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE;AAAA,EACtC;AAEA,QAAMI,WAAoB,CAAC;AAE3B,aAAW,WAAW,UAAU;AAC9B,UAAM,QAAQ,QAAQ,IAAI,OAAO;AACjC,QAAI,CAAC,SAAS,MAAM,KAAK,MAAM,IAAI;AACjC,MAAAA,SAAQ,KAAK,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,MAAIA,SAAQ,SAAS,GAAG;AACtB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAAA;AAAA,MACA,SAAS,GAAG,WAAW,KAAKA,SAAQ,KAAK,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,MAAM,SAAS,CAAC,EAAE;AACtC;AAiBO,SAAS,WAAW,MAAc,cAA+B;AACtE,QAAM,QAAQ,QAAQ,IAAI,IAAI;AAE9B,MAAI,CAAC,SAAS,MAAM,KAAK,MAAM,IAAI;AACjC,QAAI,iBAAiB,QAAW;AAC9B,aAAO;AAAA,IACT;AACA,UAAM,IAAI,MAAM,wBAAwB,IAAI,0BAA0B;AAAA,EACxE;AAEA,SAAO;AACT;;;ACjIA,SAAS,gBAAgB,kBAAkB,mBAAmB;AAG9D,IAAM,YAAY;AAClB,IAAM,YAAY;AAClB,IAAM,kBAAkB;AAExB,SAAS,SAAiB;AACxB,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,OAAO,IAAI,WAAW,IAAI;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO,KAAK,KAAK,KAAK;AAC/B;AAEO,SAAS,QAAQ,WAA2B;AACjD,QAAM,MAAM,OAAO;AACnB,QAAM,KAAK,YAAY,SAAS;AAChC,QAAM,SAAS,eAAe,WAAW,KAAK,IAAI,EAAE,eAAe,gBAAgB,CAAC;AACpF,QAAM,YAAY,OAAO,OAAO,CAAC,OAAO,OAAO,WAAW,MAAM,GAAG,OAAO,MAAM,CAAC,CAAC;AAClF,QAAM,UAAU,OAAO,WAAW;AAClC,SAAO,GAAG,GAAG,SAAS,KAAK,CAAC,IAAI,QAAQ,SAAS,KAAK,CAAC,IAAI,UAAU,SAAS,KAAK,CAAC;AACtF;AAEO,SAAS,QAAQ,YAA4B;AAClD,QAAM,MAAM,OAAO;AACnB,QAAM,CAAC,OAAO,YAAY,YAAY,IAAI,WAAW,MAAM,GAAG;AAC9D,MAAI,CAAC,SAAS,CAAC,cAAc,CAAC,cAAc;AAC1C,UAAM,IAAI,MAAM,2BAA2B;AAAA,EAC7C;AACA,QAAM,KAAK,OAAO,KAAK,OAAO,KAAK;AACnC,QAAM,UAAU,OAAO,KAAK,YAAY,KAAK;AAC7C,QAAM,YAAY,OAAO,KAAK,cAAc,KAAK;AACjD,QAAM,WAAW,iBAAiB,WAAW,KAAK,IAAI,EAAE,eAAe,gBAAgB,CAAC;AACxF,WAAS,WAAW,OAAO;AAC3B,SAAO,SAAS,OAAO,SAAS,IAAI,SAAS,MAAM,MAAM;AAC3D;AAMO,SAAS,YAAY,OAAwB;AAClD,QAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,SAAO,MAAM,WAAW,KAAK,MAAM,MAAM,CAAC,MAAM,cAAc,KAAK,CAAC,CAAC;AACvE;AAMO,SAAS,mBAAmB,OAAuB;AACxD,SAAO,YAAY,KAAK,IAAI,QAAQ,KAAK,IAAI;AAC/C;AAGO,SAAS,WAAW,YAAoB,SAAiB,eAA8B;AAC5F,MAAI;AACF,WAAO,mBAAmB,UAAU;AAAA,EACtC,QAAQ;AACN,WAAO,KAAK,gEAA2D;AACvE,WAAO;AAAA,EACT;AACF;","names":["owner","fail","missing","isRecord","fail","owner","isRecord","owner","fail","missing","checked","isRecord","isContract","fail","isRecord","isPlainObject","isRecord","missing","crud","isRecord","emptyPage","emptyPage","emptyPage","isRecord","fail","kitMethods","OPTION_KEYS","itemProjection","serviceProblem","handlers","search","owner","owner","refusal","missing","handlerOf","isRecord","fail","kitMethods","checkAccess","checkOptions","serviceProblem","handlers","handlerOf","sharing","isRecord","fail","list","tableOf","tableOf","MAKERS","handlerOf","OPTION_KEYS","isRecord","fail","kitMethods","checkOptions","checkAccess","spec","serviceProblem","relations","handlers","checked","handlerOf","admin","missing"]}
|