@nxgt/mongo 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -26
- package/dist/collection/context.d.ts +64 -0
- package/dist/collection/context.d.ts.map +1 -0
- package/dist/collection/documents.d.ts +21 -0
- package/dist/collection/documents.d.ts.map +1 -0
- package/dist/collection/filters.d.ts +15 -0
- package/dist/collection/filters.d.ts.map +1 -0
- package/dist/collection/get-collection.d.ts +26 -0
- package/dist/collection/get-collection.d.ts.map +1 -0
- package/dist/collection/paginate.d.ts +6 -0
- package/dist/collection/paginate.d.ts.map +1 -0
- package/dist/collection/reads.d.ts +19 -0
- package/dist/collection/reads.d.ts.map +1 -0
- package/dist/collection/types.d.ts +270 -0
- package/dist/collection/types.d.ts.map +1 -0
- package/dist/collection/writes.d.ts +12 -0
- package/dist/collection/writes.d.ts.map +1 -0
- package/dist/definition/define-collection.d.ts +2 -2
- package/dist/definition/fields.d.ts +5 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +664 -589
- package/dist/index.js.map +17 -11
- package/dist/transaction/with-transaction.d.ts +4 -4
- package/package.json +1 -1
- package/dist/repository/create-repository.d.ts +0 -21
- package/dist/repository/create-repository.d.ts.map +0 -1
- package/dist/repository/types.d.ts +0 -147
- package/dist/repository/types.d.ts.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/definition/
|
|
3
|
+
"sources": ["../src/definition/json-schema.ts", "../src/errors/data-error.ts", "../src/errors/to-data-error.ts", "../src/sync/index-diff.ts", "../src/sync/validator-diff.ts", "../src/sync/sync-collection.ts", "../src/definition/define-collection.ts", "../src/pagination/page.ts", "../src/collection/context.ts", "../src/pagination/cursor.ts", "../src/collection/filters.ts", "../src/collection/documents.ts", "../src/collection/reads.ts", "../src/collection/paginate.ts", "../src/collection/writes.ts", "../src/collection/get-collection.ts", "../src/definition/fields.ts", "../src/definition/object-id.ts", "../src/transaction/with-transaction.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { IndexDescription, IndexDirection, ObjectId } from 'mongodb';\nimport type { z } from 'zod';\n\n/** What MongoDB does with a document that fails the validator. */\nexport type ValidationAction = 'error' | 'warn';\n\n/**\n * Which documents the validator applies to. `off` writes no validator at all;\n * `moderate` exempts documents that were already invalid from updates.\n */\nexport type ValidationLevel = 'off' | 'moderate' | 'strict';\n\nexport interface ValidationConfig {\n\t/** Default `'strict'`. */\n\tlevel?: ValidationLevel;\n\t/** Default `'error'`. `'warn'` logs and lets the write through. */\n\taction?: ValidationAction;\n}\n\n/**\n * What an index may be keyed on: a field of the documents, which an editor\n * completes, or a path into one — `{ 'address.city': 1 }` is how MongoDB\n * indexes a nested field, and there is no way to check the tail of a path\n * against a schema without rejecting the paths Mongo allows.\n */\nexport type IndexKey<Doc> =\n\t| {\n\t\t\t[Field in\n\t\t\t\t| (keyof Doc & string)\n\t\t\t\t| `${keyof Doc & string}.${string}`]?: IndexDirection;\n\t }\n\t// The driver takes a `Map` too, and an index read back off the server comes\n\t// as one: refusing it here would refuse a definition built from a live one.\n\t| Map<string, IndexDirection>;\n\n/**\n * An index, keyed on the schema's own fields. Everything else — `unique`,\n * `name`, `collation`, `partialFilterExpression`, the TTL — is the driver's\n * `IndexDescription`, unchanged.\n */\nexport interface CollectionIndex<Doc> extends Omit<IndexDescription, 'key'> {\n\tkey: IndexKey<Doc>;\n}\n\n/** What `defineCollection` takes. */\nexport interface CollectionConfig<Schema extends z.ZodObject> {\n\t/** The collection's name on the server. */\n\tname: string;\n\t/**\n\t * The documents, as they are stored: `z.output` is what a read gives back,\n\t * `z.input` what a write takes. It must have an `_id`.\n\t */\n\tschema: Schema;\n\t/** The indexes `sync` creates, keyed on the schema's fields. */\n\tindexes?: readonly CollectionIndex<z.output<Schema>>[];\n\t/** The `$jsonSchema` validator `sync` writes from the schema. */\n\tvalidation?: ValidationConfig;\n}\n\n/** A collection, as `defineCollection` returns it: frozen, with its defaults. */\nexport interface CollectionDefinition<\n\tSchema extends z.ZodObject = z.ZodObject,\n> {\n\treadonly name: string;\n\treadonly schema: Schema;\n\t/** As the driver takes them: `sync` hands these straight to MongoDB. */\n\treadonly indexes: readonly IndexDescription[];\n\treadonly validation: Required<ValidationConfig>;\n}\n\n/** Any definition, whatever its documents. */\nexport type AnyCollectionDefinition = CollectionDefinition<any>;\n\n/** The documents of a definition, as they are read back. */\nexport type DocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.output<Schema>\n\t\t: never\n\t: never;\n\n/**\n * A document as a repository gives it back: the stored document, plus `id`.\n *\n * `id` is `_id` as a string, computed rather than stored — the collection\n * holds `_id` alone. It is enumerable, so `JSON.stringify` and a spread carry\n * it, which is what makes a document ready to return from an API; it is not\n * part of `DocumentOf`, so a filter or a patch cannot be keyed on it, because\n * the server would match nothing.\n */\nexport type ReadDocumentOf<Def> = DocumentOf<Def> & { readonly id: string };\n\n/** What a write takes: the documents before their defaults are filled. */\nexport type NewDocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.input<Schema>\n\t\t: never\n\t: never;\n\n/** The type of `_id`. */\nexport type IdOf<Def> =\n\tDocumentOf<Def> extends { _id: infer Id } ? Id : ObjectId;\n\n/** A field of the documents, as a top-level key. */\nexport type FieldOf<Def> = keyof DocumentOf<Def> & string;\n\n/**\n * Defines a collection: its name, the Zod schema of its documents, its\n * indexes, and how its validator is applied.\n *\n * The schema is the one source: it types every read and write, and `sync`\n * derives the collection's `$jsonSchema` validator from it.\n *\n * ```ts\n * export const users = defineCollection({\n * \tname: 'users',\n * \tschema: z.object({\n * \t\t_id: id(),\n * \t\temail: z.email(),\n * \t\t...timestamps(),\n * \t\t...softDelete(),\n * \t}),\n * \tindexes: [{ key: { email: 1 }, unique: true, name: 'users_email_unique' }],\n * });\n * ```\n */\nexport function defineCollection<Schema extends z.ZodObject>(\n\tconfig: CollectionConfig<Schema>,\n): CollectionDefinition<Schema> {\n\tif (!('_id' in config.schema.shape)) {\n\t\tthrow new TypeError(\n\t\t\t`defineCollection: \"${config.name}\"'s schema has no _id. Add ` +\n\t\t\t\t'`_id: id()`, which fills a new ObjectId on create, or declare the ' +\n\t\t\t\t'key your documents use.',\n\t\t);\n\t}\n\treturn Object.freeze({\n\t\t...config,\n\t\tindexes: Object.freeze([...(config.indexes ?? [])]),\n\t\tvalidation: Object.freeze({\n\t\t\tlevel: config.validation?.level ?? 'strict',\n\t\t\taction: config.validation?.action ?? 'error',\n\t\t}),\n\t}) as CollectionDefinition<Schema>;\n}\n\n/** Which of the fields the repository knows about a definition's schema has. */\nexport function stampsOf(definition: AnyCollectionDefinition): {\n\tcreatedAt: boolean;\n\tupdatedAt: boolean;\n\tdeletedAt: boolean;\n\tversion: boolean;\n\tcreatedBy: boolean;\n\tupdatedBy: boolean;\n\tdeletedBy: boolean;\n} {\n\tconst shape = definition.schema.shape as Record<string, unknown>;\n\tconst has = (name: string) => name in shape;\n\treturn {\n\t\tcreatedAt: has('createdAt'),\n\t\tupdatedAt: has('updatedAt'),\n\t\tdeletedAt: has('deletedAt'),\n\t\tversion: has('version'),\n\t\tcreatedBy: has('createdBy'),\n\t\tupdatedBy: has('updatedBy'),\n\t\tdeletedBy: has('deletedBy'),\n\t};\n}\n",
|
|
6
|
-
"import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { isObjectId } from './object-id';\n\n/**\n * An `ObjectId`, declared to MongoDB as `bsonType: 'objectId'`. JSON Schema\n * has no type for one, so the metadata is how the validator learns of it.\n */\nexport function objectId() {\n\treturn z\n\t\t.custom<ObjectId>(isObjectId, { error: 'must be an ObjectId' })\n\t\t.meta({ bsonType: 'objectId' });\n}\n\n/**\n * `_id`, filled with a new `ObjectId` when a document is created: optional to\n * write, always there once read.\n */\nexport function id() {\n\treturn objectId().default(() => new ObjectId());\n}\n\n/**\n * `createdAt` and `updatedAt`, filled on create. A repository sets `updatedAt`\n * on every update.\n */\nexport function timestamps() {\n\treturn {\n\t\tcreatedAt: z.date().default(() => new Date()),\n\t\tupdatedAt: z.date().default(() => new Date()),\n\t};\n}\n\n/**\n * `deletedAt`, `null` while the document is live. A repository on a collection\n * with it soft-deletes, and leaves deleted documents out of every read.\n */\nexport function softDelete() {\n\treturn { deletedAt: z.date().nullable().default(null) };\n}\n\n/**\n * `version`, raised by one on every update. A repository with it takes\n * `expectedVersion` and throws `OptimisticLockError` when it no longer\n * matches.\n */\nexport function optimisticLock() {\n\treturn { version: z.int().nonnegative().default(0) };\n}\n\n/**\n * `createdBy`, `updatedBy` and `deletedBy`, stamped from the actor a\n * repository was given with `as(actor)`. The actor's own type is the schema\n * passed in, an `ObjectId` by default.\n */\nexport function actors<Actor extends z.ZodType = ReturnType<typeof objectId>>(\n\tactor: Actor = objectId() as unknown as Actor,\n) {\n\treturn {\n\t\tcreatedBy: actor.nullable().default(null),\n\t\tupdatedBy: actor.nullable().default(null),\n\t\tdeletedBy: actor.nullable().default(null),\n\t};\n}\n\n/** The fields the repository gives a meaning to, by name. */\nexport const STAMP_FIELDS = {\n\tid: '_id',\n\tcreatedAt: 'createdAt',\n\tupdatedAt: 'updatedAt',\n\tdeletedAt: 'deletedAt',\n\tversion: 'version',\n\tcreatedBy: 'createdBy',\n\tupdatedBy: 'updatedBy',\n\tdeletedBy: 'deletedBy',\n} as const;\n",
|
|
7
|
-
"import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { InvalidIdError } from '../errors/data-error';\n\n/** The 24 hex characters an `ObjectId` is written as. */\nconst HEX_24 = /^[0-9a-fA-F]{24}$/;\n\n/**\n * An `ObjectId`, read by its BSON tag rather than with `instanceof`, which\n * answers `false` across two copies of the driver in one tree.\n */\nexport function isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n/** Is this the 24-character hex string an `ObjectId` is written as? */\nexport function isObjectIdString(value: unknown): value is string {\n\treturn typeof value === 'string' && HEX_24.test(value);\n}\n\n/** An `ObjectId`, or a string that stands for one. */\nexport function isValidObjectId(value: unknown): boolean {\n\treturn isObjectId(value) || isObjectIdString(value);\n}\n\n/**\n * The `ObjectId` this value stands for, or `undefined`. Never throws.\n *\n * Prefer it to `new ObjectId(value)`, which **invents a fresh id** when it is\n * given `null` or `undefined` — a missing route parameter then reads as a\n * perfectly valid id that matches nothing.\n */\nexport function tryObjectId(value: unknown): ObjectId | undefined {\n\tif (isObjectId(value)) return value;\n\tif (isObjectIdString(value)) return ObjectId.createFromHexString(value);\n\treturn undefined;\n}\n\nfunction describe(value: unknown): string {\n\tif (value === null) return 'null';\n\tif (value === undefined) return 'undefined';\n\tif (typeof value === 'string') return `the string ${JSON.stringify(value)}`;\n\treturn `a ${typeof value}`;\n}\n\n/**\n * The `ObjectId` this value stands for. Throws `InvalidIdError` for anything\n * else, `null` and `undefined` included.\n *\n * ```ts\n * const user = await users.getById(toObjectId(request.params.id));\n * ```\n */\nexport function toObjectId(value: unknown, field = '_id'): ObjectId {\n\tconst made = tryObjectId(value);\n\tif (made) return made;\n\tthrow new InvalidIdError(\n\t\t`${field}: expected an ObjectId or its 24-character hex string, got ${describe(value)}`,\n\t\t{ id: value, keys: [field] },\n\t);\n}\n\n/**\n * The same, for a list — a `$in` filter built from query parameters.\n *\n * ```ts\n * await users.findMany({ filter: { _id: { $in: toObjectIds(ids) } } });\n * ```\n */\nexport function toObjectIds(\n\tvalues: Iterable<unknown>,\n\tfield = '_id',\n): ObjectId[] {\n\treturn [...values].map((value) => toObjectId(value, field));\n}\n\n/**\n * A Zod schema for an id that arrives from outside: it takes an `ObjectId` or\n * its hex string and gives back an `ObjectId`.\n *\n * It belongs in the schema of a route's parameters, **not** in a collection's:\n * a field that parses one type into another has no honest `$jsonSchema`, and\n * what a collection stores is `objectId()`.\n *\n * ```ts\n * const params = z.object({ id: objectIdParam() });\n * const { id } = params.parse(request.params); // ObjectId\n * ```\n */\nexport function objectIdParam() {\n\treturn z\n\t\t.custom<ObjectId | string>(isValidObjectId, {\n\t\t\terror: 'must be an ObjectId or its 24-character hex string',\n\t\t})\n\t\t.transform((value) => toObjectId(value));\n}\n",
|
|
8
|
-
"/** What went wrong, as a string a caller can switch on. */\nexport type DataErrorCode =\n\t| 'DATABASE'\n\t| 'NOT_FOUND'\n\t| 'CONFLICT'\n\t| 'VALIDATION'\n\t| 'OPTIMISTIC_LOCK'\n\t| 'INVALID_CURSOR'\n\t| 'INVALID_ID';\n\n/** One reason a document failed the collection's `$jsonSchema` validator. */\nexport interface ValidationIssue {\n\t/** The dotted path of the field, empty for the document itself. */\n\tpath: string;\n\t/** The rule it broke: `bsonType`, `required`, `minimum`… */\n\treason: string;\n\t/** What the schema asked for, as MongoDB reports it. */\n\tspecifiedAs?: unknown;\n\t/** The value that was refused, when the server names it. */\n\tconsideredValue?: unknown;\n\t/** Its BSON type, when the server names it: `string`, `int`, `double`… */\n\tconsideredType?: string;\n\t/** The schema's `description` for the field, when it has one. */\n\tdescription?: string;\n}\n\nexport interface DataErrorOptions {\n\tcollection?: string | undefined;\n\t/** The `_id` a method by id was given. */\n\tid?: unknown;\n\t/** MongoDB's numeric error code: 11000, 121, 26… */\n\tserverCode?: number | undefined;\n\t/** MongoDB's `codeName`, which write errors do not carry. */\n\tserverCodeName?: string | undefined;\n\t/** The index a conflict names, when the server names one. */\n\tindex?: string | undefined;\n\t/** The fields the error is about: an index's keys, or a validator's paths. */\n\tkeys?: string[];\n\t/** Those fields' values, when the server gives them. */\n\tvalues?: Record<string, unknown> | undefined;\n\tissues?: ValidationIssue[];\n\texpectedVersion?: number | undefined;\n\tactualVersion?: number | undefined;\n\tcause?: unknown;\n}\n\n/**\n * What this package throws. Every method turns a driver error into one of\n * these, so an application catches `ConflictError` instead of reading `11000`\n * off an error whose shape changes with the operation that produced it.\n *\n * A driver error that is none of them reaches the caller as it is.\n */\nexport class DataError extends Error {\n\toverride name = 'DataError';\n\treadonly code: DataErrorCode = 'DATABASE';\n\treadonly collection: string | undefined;\n\treadonly id: unknown;\n\treadonly serverCode: number | undefined;\n\treadonly serverCodeName: string | undefined;\n\treadonly index: string | undefined;\n\treadonly keys: string[];\n\treadonly values: Record<string, unknown> | undefined;\n\treadonly issues: ValidationIssue[];\n\treadonly expectedVersion: number | undefined;\n\treadonly actualVersion: number | undefined;\n\n\tconstructor(message = 'Database error', options: DataErrorOptions = {}) {\n\t\tsuper(\n\t\t\tmessage,\n\t\t\toptions.cause === undefined ? undefined : { cause: options.cause },\n\t\t);\n\t\tthis.collection = options.collection;\n\t\tthis.id = options.id;\n\t\tthis.serverCode = options.serverCode;\n\t\tthis.serverCodeName = options.serverCodeName;\n\t\tthis.index = options.index;\n\t\tthis.keys = options.keys ?? [];\n\t\tthis.values = options.values;\n\t\tthis.issues = options.issues ?? [];\n\t\tthis.expectedVersion = options.expectedVersion;\n\t\tthis.actualVersion = options.actualVersion;\n\t}\n}\n\n/** No document matched, where one was required. */\nexport class NotFoundError extends DataError {\n\toverride name = 'NotFoundError';\n\toverride readonly code = 'NOT_FOUND' as const;\n\n\tconstructor(message = 'Not found', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A unique index refused the write: MongoDB's `E11000`. */\nexport class ConflictError extends DataError {\n\toverride name = 'ConflictError';\n\toverride readonly code = 'CONFLICT' as const;\n\n\tconstructor(message = 'Duplicate key', options: DataErrorOptions = {}) {\n\t\tsuper(message, { serverCode: 11000, ...options });\n\t}\n}\n\n/** The collection's `$jsonSchema` validator refused the document: code 121. */\nexport class ValidationError extends DataError {\n\toverride name = 'ValidationError';\n\toverride readonly code = 'VALIDATION' as const;\n\n\tconstructor(\n\t\tmessage = 'Document failed validation',\n\t\toptions: DataErrorOptions = {},\n\t) {\n\t\tsuper(message, { serverCode: 121, ...options });\n\t}\n}\n\n/**\n * The document changed since it was read: its `version` is no longer the one\n * the update expected, and nothing was written.\n */\nexport class OptimisticLockError extends DataError {\n\toverride name = 'OptimisticLockError';\n\toverride readonly code = 'OPTIMISTIC_LOCK' as const;\n\n\tconstructor(message = 'Version conflict', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/**\n * A value that is not an `ObjectId` and not the string of one.\n *\n * It is a `DataError` rather than a `TypeError` because it is usually data,\n * not a mistake in the code: an id off a URL or a form reaches `toObjectId`,\n * and a handler wants to answer 400 or 404 rather than crash.\n */\nexport class InvalidIdError extends DataError {\n\toverride name = 'InvalidIdError';\n\toverride readonly code = 'INVALID_ID' as const;\n\n\tconstructor(message = 'Invalid id', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A cursor this package did not write, or one for another ordering. */\nexport class InvalidCursorError extends DataError {\n\toverride name = 'InvalidCursorError';\n\toverride readonly code = 'INVALID_CURSOR' as const;\n\n\tconstructor(message = 'Invalid cursor', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n",
|
|
9
5
|
"import { z } from 'zod';\n\n/**\n * Every keyword MongoDB's `$jsonSchema` knows. It **rejects** a document that\n * uses any other, rather than ignoring it, so anything not in here is dropped\n * on the way out.\n */\nexport const MONGO_JSON_SCHEMA_KEYWORDS: ReadonlySet<string> = new Set([\n\t'additionalItems',\n\t'additionalProperties',\n\t'allOf',\n\t'anyOf',\n\t'bsonType',\n\t'dependencies',\n\t'description',\n\t'enum',\n\t'exclusiveMaximum',\n\t'exclusiveMinimum',\n\t'items',\n\t'maxItems',\n\t'maxLength',\n\t'maxProperties',\n\t'maximum',\n\t'minItems',\n\t'minLength',\n\t'minProperties',\n\t'minimum',\n\t'multipleOf',\n\t'not',\n\t'oneOf',\n\t'pattern',\n\t'patternProperties',\n\t'properties',\n\t'required',\n\t'title',\n\t'type',\n\t'uniqueItems',\n]);\n\n/** Keywords whose value is a map of names to schemas, not a schema. */\nconst SCHEMA_MAPS = new Set([\n\t'properties',\n\t'patternProperties',\n\t'dependencies',\n]);\n\ntype Node = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Node {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * A JavaScript number reaches BSON as an `int` when it is a whole number that\n * fits in 32 bits, and as a `double` otherwise — never as a `long`, unless the\n * caller wrapped it. `type: \"integer\"`, which MongoDB has no equivalent for,\n * therefore becomes the three types a whole number can arrive as, with\n * `multipleOf: 1` to refuse a fractional double.\n */\nconst INTEGER_BSON_TYPES = ['int', 'long', 'double'];\n\nfunction convertIntegerType(node: Node): void {\n\tconst type = node.type;\n\tif (type === 'integer') {\n\t\tdelete node.type;\n\t\tnode.bsonType = [...INTEGER_BSON_TYPES];\n\t\tnode.multipleOf ??= 1;\n\t\treturn;\n\t}\n\tif (Array.isArray(type) && type.includes('integer')) {\n\t\tdelete node.type;\n\t\tnode.bsonType = [\n\t\t\t...type.filter((one) => one !== 'integer'),\n\t\t\t...INTEGER_BSON_TYPES,\n\t\t];\n\t\tnode.multipleOf ??= 1;\n\t}\n}\n\nfunction refName(ref: string): string {\n\treturn ref.replace(/^#\\/(definitions|\\$defs)\\//, '');\n}\n\nfunction inline(value: unknown, defs: Node, stack: string[]): unknown {\n\tif (Array.isArray(value)) {\n\t\treturn value.map((one) => inline(one, defs, stack));\n\t}\n\tif (!isRecord(value)) return value;\n\n\tif (typeof value.$ref === 'string') {\n\t\tconst name = refName(value.$ref);\n\t\tif (stack.includes(name)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`toMongoJsonSchema: \"${name}\" refers to itself. MongoDB's $jsonSchema ` +\n\t\t\t\t\t'has no $ref, so a recursive schema cannot be a validator. Give the ' +\n\t\t\t\t\t'collection no validator, or model the field as an object with no ' +\n\t\t\t\t\t'schema of its own.',\n\t\t\t);\n\t\t}\n\t\tconst target = defs[name];\n\t\tif (!isRecord(target)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`toMongoJsonSchema: cannot resolve ${value.$ref}, which zod emitted`,\n\t\t\t);\n\t\t}\n\t\tconst { $ref: _ref, ...siblings } = value;\n\t\treturn {\n\t\t\t...(inline(target, defs, [...stack, name]) as Node),\n\t\t\t...(inline(siblings, defs, stack) as Node),\n\t\t};\n\t}\n\n\tconst out: Node = {};\n\tfor (const [key, inner] of Object.entries(value)) {\n\t\tif (!MONGO_JSON_SCHEMA_KEYWORDS.has(key)) continue;\n\t\tif (SCHEMA_MAPS.has(key) && isRecord(inner)) {\n\t\t\tconst mapped: Node = {};\n\t\t\tfor (const [name, schema] of Object.entries(inner)) {\n\t\t\t\tmapped[name] = inline(schema, defs, stack);\n\t\t\t}\n\t\t\tout[key] = mapped;\n\t\t\tcontinue;\n\t\t}\n\t\tout[key] = inline(inner, defs, stack);\n\t}\n\tconvertIntegerType(out);\n\treturn out;\n}\n\n/**\n * A Zod schema as a MongoDB `$jsonSchema`, ready for a collection's validator.\n *\n * `z.toJSONSchema` alone is not one: MongoDB rejects `$schema`, `$ref`,\n * `definitions`, `default`, `format` and `id`, has no `integer` type, and\n * treats a keyword it does not know as an error rather than ignoring it. This\n * resolves every `$ref` by inlining it, keeps only the keywords MongoDB\n * knows, and maps `integer`.\n *\n * `Date` and `ObjectId` have no JSON Schema type: they are declared with\n * `bsonType`, which `date()` and `objectId()` already carry in their metadata.\n * Any schema can do the same with `.meta({ bsonType: 'decimal' })`.\n *\n * ```ts\n * toMongoJsonSchema(z.object({ _id: objectId(), email: z.string() }));\n * // { type: 'object', properties: { … }, required: ['_id', 'email'], … }\n * ```\n */\nexport function toMongoJsonSchema(schema: z.ZodType): Record<string, unknown> {\n\tconst json = z.toJSONSchema(schema, {\n\t\ttarget: 'draft-4',\n\t\tio: 'output',\n\t\t// A `Date` is unrepresentable in JSON Schema; the override below gives\n\t\t// it a bsonType instead, and `{}` is what it starts from.\n\t\tunrepresentable: 'any',\n\t\toverride: (ctx) => {\n\t\t\tconst type = (ctx.zodSchema as { _zod: { def: { type: string } } })._zod\n\t\t\t\t.def.type;\n\t\t\tif (type === 'date' && ctx.jsonSchema.bsonType === undefined) {\n\t\t\t\tctx.jsonSchema.bsonType = 'date';\n\t\t\t}\n\t\t},\n\t}) as Node;\n\n\tconst definitions = isRecord(json.definitions)\n\t\t? json.definitions\n\t\t: isRecord(json.$defs)\n\t\t\t? json.$defs\n\t\t\t: {};\n\treturn inline(json, definitions, []) as Record<string, unknown>;\n}\n",
|
|
6
|
+
"/** What went wrong, as a string a caller can switch on. */\nexport type DataErrorCode =\n\t| 'DATABASE'\n\t| 'NOT_FOUND'\n\t| 'CONFLICT'\n\t| 'VALIDATION'\n\t| 'OPTIMISTIC_LOCK'\n\t| 'INVALID_CURSOR'\n\t| 'INVALID_ID';\n\n/** One reason a document failed the collection's `$jsonSchema` validator. */\nexport interface ValidationIssue {\n\t/** The dotted path of the field, empty for the document itself. */\n\tpath: string;\n\t/** The rule it broke: `bsonType`, `required`, `minimum`… */\n\treason: string;\n\t/** What the schema asked for, as MongoDB reports it. */\n\tspecifiedAs?: unknown;\n\t/** The value that was refused, when the server names it. */\n\tconsideredValue?: unknown;\n\t/** Its BSON type, when the server names it: `string`, `int`, `double`… */\n\tconsideredType?: string;\n\t/** The schema's `description` for the field, when it has one. */\n\tdescription?: string;\n}\n\nexport interface DataErrorOptions {\n\tcollection?: string | undefined;\n\t/** The `_id` a method by id was given. */\n\tid?: unknown;\n\t/** MongoDB's numeric error code: 11000, 121, 26… */\n\tserverCode?: number | undefined;\n\t/** MongoDB's `codeName`, which write errors do not carry. */\n\tserverCodeName?: string | undefined;\n\t/** The index a conflict names, when the server names one. */\n\tindex?: string | undefined;\n\t/** The fields the error is about: an index's keys, or a validator's paths. */\n\tkeys?: string[];\n\t/** Those fields' values, when the server gives them. */\n\tvalues?: Record<string, unknown> | undefined;\n\tissues?: ValidationIssue[];\n\texpectedVersion?: number | undefined;\n\tactualVersion?: number | undefined;\n\tcause?: unknown;\n}\n\n/**\n * What this package throws. Every method turns a driver error into one of\n * these, so an application catches `ConflictError` instead of reading `11000`\n * off an error whose shape changes with the operation that produced it.\n *\n * A driver error that is none of them reaches the caller as it is.\n */\nexport class DataError extends Error {\n\toverride name = 'DataError';\n\treadonly code: DataErrorCode = 'DATABASE';\n\treadonly collection: string | undefined;\n\treadonly id: unknown;\n\treadonly serverCode: number | undefined;\n\treadonly serverCodeName: string | undefined;\n\treadonly index: string | undefined;\n\treadonly keys: string[];\n\treadonly values: Record<string, unknown> | undefined;\n\treadonly issues: ValidationIssue[];\n\treadonly expectedVersion: number | undefined;\n\treadonly actualVersion: number | undefined;\n\n\tconstructor(message = 'Database error', options: DataErrorOptions = {}) {\n\t\tsuper(\n\t\t\tmessage,\n\t\t\toptions.cause === undefined ? undefined : { cause: options.cause },\n\t\t);\n\t\tthis.collection = options.collection;\n\t\tthis.id = options.id;\n\t\tthis.serverCode = options.serverCode;\n\t\tthis.serverCodeName = options.serverCodeName;\n\t\tthis.index = options.index;\n\t\tthis.keys = options.keys ?? [];\n\t\tthis.values = options.values;\n\t\tthis.issues = options.issues ?? [];\n\t\tthis.expectedVersion = options.expectedVersion;\n\t\tthis.actualVersion = options.actualVersion;\n\t}\n}\n\n/** No document matched, where one was required. */\nexport class NotFoundError extends DataError {\n\toverride name = 'NotFoundError';\n\toverride readonly code = 'NOT_FOUND' as const;\n\n\tconstructor(message = 'Not found', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A unique index refused the write: MongoDB's `E11000`. */\nexport class ConflictError extends DataError {\n\toverride name = 'ConflictError';\n\toverride readonly code = 'CONFLICT' as const;\n\n\tconstructor(message = 'Duplicate key', options: DataErrorOptions = {}) {\n\t\tsuper(message, { serverCode: 11000, ...options });\n\t}\n}\n\n/** The collection's `$jsonSchema` validator refused the document: code 121. */\nexport class ValidationError extends DataError {\n\toverride name = 'ValidationError';\n\toverride readonly code = 'VALIDATION' as const;\n\n\tconstructor(\n\t\tmessage = 'Document failed validation',\n\t\toptions: DataErrorOptions = {},\n\t) {\n\t\tsuper(message, { serverCode: 121, ...options });\n\t}\n}\n\n/**\n * The document changed since it was read: its `version` is no longer the one\n * the update expected, and nothing was written.\n */\nexport class OptimisticLockError extends DataError {\n\toverride name = 'OptimisticLockError';\n\toverride readonly code = 'OPTIMISTIC_LOCK' as const;\n\n\tconstructor(message = 'Version conflict', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/**\n * A value that is not an `ObjectId` and not the string of one.\n *\n * It is a `DataError` rather than a `TypeError` because it is usually data,\n * not a mistake in the code: an id off a URL or a form reaches `toObjectId`,\n * and a handler wants to answer 400 or 404 rather than crash.\n */\nexport class InvalidIdError extends DataError {\n\toverride name = 'InvalidIdError';\n\toverride readonly code = 'INVALID_ID' as const;\n\n\tconstructor(message = 'Invalid id', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n\n/** A cursor this package did not write, or one for another ordering. */\nexport class InvalidCursorError extends DataError {\n\toverride name = 'InvalidCursorError';\n\toverride readonly code = 'INVALID_CURSOR' as const;\n\n\tconstructor(message = 'Invalid cursor', options: DataErrorOptions = {}) {\n\t\tsuper(message, options);\n\t}\n}\n",
|
|
10
7
|
"import {\n\tConflictError,\n\tDataError,\n\ttype DataErrorOptions,\n\tValidationError,\n\ttype ValidationIssue,\n} from './data-error';\n\ntype Record_ = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Record_ {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction asArray(value: unknown): unknown[] {\n\tif (Array.isArray(value)) return value;\n\treturn value === undefined || value === null ? [] : [value];\n}\n\nfunction text(value: unknown): string | undefined {\n\treturn typeof value === 'string' ? value : undefined;\n}\n\n/**\n * The index a duplicate key names. The message is the only place it is:\n * `E11000 duplicate key error collection: db.users index: users_email_unique\n * dup key: { email: \"a@b.c\" }`.\n */\nfunction indexFromMessage(message: string | undefined): string | undefined {\n\treturn message?.match(/index:\\s*(\\S+)\\s+dup key/)?.[1];\n}\n\n/**\n * The keys of a duplicate key. `keyPattern` carries them for a single write;\n * a bulk write carries neither it nor `keyValue`, and the message is all there\n * is: `dup key: { email: \"a@b.c\", tenant: 1 }`.\n */\nfunction keysOfDuplicate(error: Record_): {\n\tkeys: string[];\n\tvalues: Record_ | undefined;\n} {\n\tconst pattern = error.keyPattern;\n\tif (isRecord(pattern)) {\n\t\tconst values = isRecord(error.keyValue) ? error.keyValue : undefined;\n\t\treturn { keys: Object.keys(pattern), values };\n\t}\n\tconst inMessage = text(error.errmsg)?.match(/dup key:\\s*\\{([^}]*)\\}/)?.[1];\n\tif (!inMessage) return { keys: [], values: undefined };\n\tconst keys = [...inMessage.matchAll(/([\\w.$]+)\\s*:/g)].map(\n\t\t(match) => match[1] as string,\n\t);\n\treturn { keys, values: undefined };\n}\n\n/** The first write error of a bulk result, which may be one object or a list. */\nfunction firstWriteError(error: Record_): Record_ | undefined {\n\tfor (const write of asArray(error.writeErrors)) {\n\t\t// The driver wraps each one; its fields sit on `err` there.\n\t\tconst inner = isRecord(write) && isRecord(write.err) ? write.err : write;\n\t\tif (isRecord(inner)) return inner;\n\t}\n\treturn undefined;\n}\n\n/**\n * The issues of a `$jsonSchema` failure, from `errInfo.details`. The server\n * nests them: `schemaRulesNotSatisfied` holds `propertiesNotSatisfied`, whose\n * `details` hold either leaf rules or another level of properties.\n */\nfunction issuesOf(details: unknown, path: string[] = []): ValidationIssue[] {\n\tconst issues: ValidationIssue[] = [];\n\tfor (const rule of asArray(details)) {\n\t\tif (!isRecord(rule)) continue;\n\n\t\tif (rule.propertiesNotSatisfied !== undefined) {\n\t\t\tfor (const property of asArray(rule.propertiesNotSatisfied)) {\n\t\t\t\tif (!isRecord(property)) continue;\n\t\t\t\tconst name = text(property.propertyName) ?? '';\n\t\t\t\tconst nested = issuesOf(property.details, [...path, name]);\n\t\t\t\tconst description = text(property.description);\n\t\t\t\tissues.push(\n\t\t\t\t\t...(description === undefined\n\t\t\t\t\t\t? nested\n\t\t\t\t\t\t: nested.map((issue) => ({ description, ...issue }))),\n\t\t\t\t);\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (rule.missingProperties !== undefined) {\n\t\t\tfor (const missing of asArray(rule.missingProperties)) {\n\t\t\t\tissues.push({\n\t\t\t\t\tpath: [...path, String(missing)].join('.'),\n\t\t\t\t\treason: 'required',\n\t\t\t\t\tspecifiedAs: rule.specifiedAs,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (rule.schemaRulesNotSatisfied !== undefined) {\n\t\t\tissues.push(...issuesOf(rule.schemaRulesNotSatisfied, path));\n\t\t\tcontinue;\n\t\t}\n\n\t\tissues.push({\n\t\t\tpath: path.join('.'),\n\t\t\treason: text(rule.reason) ?? text(rule.operatorName) ?? 'invalid',\n\t\t\t...(rule.specifiedAs === undefined\n\t\t\t\t? {}\n\t\t\t\t: { specifiedAs: rule.specifiedAs }),\n\t\t\t...(rule.consideredValue === undefined\n\t\t\t\t? {}\n\t\t\t\t: { consideredValue: rule.consideredValue }),\n\t\t\t...(text(rule.consideredType) === undefined\n\t\t\t\t? {}\n\t\t\t\t: { consideredType: text(rule.consideredType) }),\n\t\t});\n\t}\n\treturn issues;\n}\n\n/**\n * A MongoDB error as one of this package's, or the error itself when it is\n * none of them.\n *\n * It reads the error's fields rather than its class: a duplicate key arrives\n * as a `MongoServerError` with `keyPattern` from `insertOne`, and as a\n * `MongoBulkWriteError` whose `writeErrors` carry neither `keyPattern` nor\n * `keyValue` from `insertMany` and `bulkWrite`. Both become a `ConflictError`\n * with the same fields. Reading fields also survives two copies of the driver\n * in one tree, where `instanceof` does not.\n */\nexport function toDataError(\n\terror: unknown,\n\tcontext: { collection?: string | undefined } = {},\n): unknown {\n\tif (error instanceof DataError) return error;\n\tif (!isRecord(error)) return error;\n\n\t// A bulk write carries the detail on its write errors, and only a message\n\t// at the top; a single write carries everything at the top.\n\tconst source = firstWriteError(error) ?? error;\n\tconst code =\n\t\ttypeof source.code === 'number'\n\t\t\t? source.code\n\t\t\t: typeof error.code === 'number'\n\t\t\t\t? error.code\n\t\t\t\t: undefined;\n\tif (typeof code !== 'number') return error;\n\n\tconst message =\n\t\ttext(source.errmsg) ??\n\t\ttext(source.message) ??\n\t\ttext((error as { message?: unknown }).message) ??\n\t\t'';\n\tconst common: DataErrorOptions = {\n\t\tcollection: context.collection,\n\t\tserverCode: code,\n\t\tserverCodeName: text(error.codeName) ?? text(source.codeName),\n\t\tcause: error,\n\t};\n\n\tif (code === 11000) {\n\t\tconst { keys, values } = keysOfDuplicate(source);\n\t\tconst index = indexFromMessage(message);\n\t\tconst named =\n\t\t\tkeys.length > 0 ? keys.join(', ') : (index ?? 'a unique index');\n\t\treturn new ConflictError(\n\t\t\t`Duplicate key on ${named}${\n\t\t\t\tcontext.collection ? ` in \"${context.collection}\"` : ''\n\t\t\t}`,\n\t\t\t{ ...common, index, keys, values },\n\t\t);\n\t}\n\n\tif (code === 121) {\n\t\tconst errInfo = isRecord(source.errInfo) ? source.errInfo : undefined;\n\t\tconst issues = issuesOf(errInfo?.details);\n\t\treturn new ValidationError(\n\t\t\t`Document failed validation${\n\t\t\t\tcontext.collection ? ` in \"${context.collection}\"` : ''\n\t\t\t}${issues.length > 0 ? `: ${issues.map((i) => `${i.path} ${i.reason}`).join(', ')}` : ''}`,\n\t\t\t{ ...common, issues, keys: issues.map((issue) => issue.path) },\n\t\t);\n\t}\n\n\treturn new DataError(message || `MongoDB error ${code}`, common);\n}\n",
|
|
11
|
-
"import { ObjectId } from 'mongodb';\nimport { InvalidCursorError } from '../errors/data-error';\n\n/** What a cursor holds: the ordering values of the last document of a page. */\nexport interface CursorPayload {\n\t/** The ordering it was written for: `<field>:<asc|desc>`. */\n\treadonly key: string;\n\treadonly values: readonly unknown[];\n}\n\n/** An `ObjectId`, read without `instanceof`: two copies of the driver. */\nfunction isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n// JSON has no Date, no bigint and no ObjectId, and a cursor must give back the\n// very value it was written from: a Date compares with a date field, an\n// ObjectId with `_id`. `JSON.stringify` has already called `toJSON` by the time\n// the replacer runs, so the raw value is read off `this`.\nfunction replacer(this: Record<string, unknown>, key: string, value: unknown) {\n\tconst raw = this[key];\n\tif (raw instanceof Date) return { $date: raw.toISOString() };\n\tif (typeof raw === 'bigint') return { $bigint: raw.toString() };\n\tif (isObjectId(raw)) return { $oid: raw.toHexString() };\n\treturn value;\n}\n\nfunction reviver(_key: string, value: unknown): unknown {\n\tif (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst keys = Object.keys(value);\n\t\tif (keys.length === 1) {\n\t\t\tconst tagged = value as {\n\t\t\t\t$date?: unknown;\n\t\t\t\t$bigint?: unknown;\n\t\t\t\t$oid?: unknown;\n\t\t\t};\n\t\t\tif (typeof tagged.$date === 'string') return new Date(tagged.$date);\n\t\t\tif (typeof tagged.$bigint === 'string') return BigInt(tagged.$bigint);\n\t\t\tif (typeof tagged.$oid === 'string') return new ObjectId(tagged.$oid);\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction toBase64Url(text: string): string {\n\tlet binary = '';\n\tfor (const byte of new TextEncoder().encode(text)) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary)\n\t\t.replace(/\\+/g, '-')\n\t\t.replace(/\\//g, '_')\n\t\t.replace(/=+$/, '');\n}\n\nfunction fromBase64Url(text: string): string {\n\tconst base64 = text.replace(/-/g, '+').replace(/_/g, '/');\n\tconst binary = atob(base64 + '='.repeat((4 - (base64.length % 4)) % 4));\n\treturn new TextDecoder().decode(\n\t\tUint8Array.from(binary, (char) => char.charCodeAt(0)),\n\t);\n}\n\n/**\n * Writes an opaque, URL-safe cursor. `Date`, `bigint` and `ObjectId` values\n * survive the round trip. It is encoded, not signed: a client can read it,\n * and forge one.\n */\nexport function encodeCursor(payload: CursorPayload): string {\n\treturn toBase64Url(JSON.stringify([payload.key, payload.values], replacer));\n}\n\n/**\n * Reads a cursor `encodeCursor` wrote. Throws `InvalidCursorError` for\n * anything else, and for a cursor written for another ordering when\n * `expectedKey` is given.\n */\nexport function decodeCursor(\n\tcursor: string,\n\texpectedKey?: string,\n): CursorPayload {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fromBase64Url(cursor), reviver);\n\t} catch (cause) {\n\t\tthrow new InvalidCursorError('Invalid cursor: it cannot be decoded', {\n\t\t\tcause,\n\t\t});\n\t}\n\tif (\n\t\t!Array.isArray(parsed) ||\n\t\tparsed.length !== 2 ||\n\t\ttypeof parsed[0] !== 'string' ||\n\t\t!Array.isArray(parsed[1])\n\t) {\n\t\tthrow new InvalidCursorError('Invalid cursor: unexpected shape');\n\t}\n\tconst [key, values] = parsed as [string, unknown[]];\n\tif (expectedKey !== undefined && key !== expectedKey) {\n\t\tthrow new InvalidCursorError(\n\t\t\t`Invalid cursor: it was written for the ordering ${key}, not ${expectedKey}`,\n\t\t);\n\t}\n\treturn { key, values };\n}\n",
|
|
12
|
-
"/** One page of an offset pagination. */\nexport interface Page<T> {\n\titems: T[];\n\t/** Every document that matches, across all pages. */\n\ttotal: number;\n\t/** 1-based. */\n\tpage: number;\n\tpageSize: number;\n\t/** `Math.ceil(total / pageSize)`: 0 when nothing matches. */\n\tpageCount: number;\n}\n\n/** One page of a cursor pagination. */\nexport interface CursorPage<T> {\n\titems: T[];\n\t/** Pass it as `after` for the next page; `null` on the last one. */\n\tnextCursor: string | null;\n}\n\nexport interface PageOptions {\n\t/** 1-based. Default `1`. */\n\tpage?: number;\n\t/** Default `20`, at most `maxPageSize`. */\n\tpageSize?: number;\n}\n\nexport interface PageWindow {\n\tpage: number;\n\tpageSize: number;\n\tlimit: number;\n\tskip: number;\n}\n\nexport const DEFAULT_PAGE_SIZE = 20;\nexport const DEFAULT_MAX_PAGE_SIZE = 100;\n\nfunction positiveInteger(name: string, value: number): number {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new RangeError(\n\t\t\t`${name} must be an integer of at least 1, not ${value}`,\n\t\t);\n\t}\n\treturn value;\n}\n\n/**\n * Checks `page` and `pageSize` and turns them into a `limit` and a `skip`.\n * A `pageSize` above `maxPageSize` is lowered to it; one that is not a\n * positive integer throws a `RangeError`.\n */\nexport function pageWindow(\n\toptions: PageOptions = {},\n\tmaxPageSize = DEFAULT_MAX_PAGE_SIZE,\n): PageWindow {\n\tconst page = positiveInteger('page', options.page ?? 1);\n\tconst pageSize = Math.min(\n\t\tpositiveInteger('pageSize', options.pageSize ?? DEFAULT_PAGE_SIZE),\n\t\tmaxPageSize,\n\t);\n\treturn { page, pageSize, limit: pageSize, skip: (page - 1) * pageSize };\n}\n\n/** Assembles a `Page` from its documents and the total. */\nexport function toPage<T>(\n\titems: T[],\n\ttotal: number,\n\twindow: PageWindow,\n): Page<T> {\n\treturn {\n\t\titems,\n\t\ttotal,\n\t\tpage: window.page,\n\t\tpageSize: window.pageSize,\n\t\tpageCount: Math.ceil(total / window.pageSize),\n\t};\n}\n\n/** Checks a cursor page's `limit`, as `pageWindow` checks a `pageSize`. */\nexport function cursorLimit(\n\tlimit: number | undefined,\n\tmaxPageSize = DEFAULT_MAX_PAGE_SIZE,\n): number {\n\treturn Math.min(\n\t\tpositiveInteger('limit', limit ?? DEFAULT_PAGE_SIZE),\n\t\tmaxPageSize,\n\t);\n}\n",
|
|
13
8
|
"import type { IndexDescription, IndexDescriptionInfo } from 'mongodb';\n\n/**\n * What MongoDB fills a collation in with. It reads an index's collation back\n * canonical — every field, plus the ICU `version` — so a wanted collation is\n * compared against its own defaults, and `version` is left out: it changes\n * with the server's ICU, and recreating every index over it would be absurd.\n */\nconst COLLATION_DEFAULTS: Record<string, unknown> = {\n\tcaseLevel: false,\n\tcaseFirst: 'off',\n\tstrength: 3,\n\tnumericOrdering: false,\n\talternate: 'non-ignorable',\n\tmaxVariable: 'punct',\n\tnormalization: false,\n\tbackwards: false,\n};\n\n/**\n * Options the server does not read back when they are false, but does when\n * they were sent explicitly. Compared against the default either way.\n */\nconst OPTION_DEFAULTS: Record<string, unknown> = {\n\tunique: false,\n\tsparse: false,\n\thidden: false,\n\tbackground: false,\n};\n\n/** Never part of an index's identity: the server's own bookkeeping. */\nconst IGNORED = new Set(['v', 'ns', 'key', 'name']);\n\ntype Fields = Record<string, unknown>;\n\nfunction keyOf(index: IndexDescription | IndexDescriptionInfo): Fields {\n\tconst key = index.key;\n\treturn key instanceof Map ? Object.fromEntries(key) : { ...key };\n}\n\n/**\n * The name MongoDB gives an index that names none: every field and direction,\n * joined by `_`.\n */\nexport function indexNameOf(key: Fields): string {\n\treturn Object.entries(key)\n\t\t.map(([field, direction]) => `${field}_${String(direction)}`)\n\t\t.join('_');\n}\n\nfunction canonicalCollation(value: unknown): unknown {\n\tif (typeof value !== 'object' || value === null) return value;\n\tconst collation = value as Fields;\n\tconst out: Fields = {};\n\tfor (const [field, fallback] of Object.entries(COLLATION_DEFAULTS)) {\n\t\tout[field] = collation[field] ?? fallback;\n\t}\n\tout.locale = collation.locale;\n\t// `version` is the server's ICU version, never something to sync on.\n\treturn out;\n}\n\n/** An index reduced to what makes two of them the same. */\nexport interface NormalizedIndex {\n\tname: string;\n\t/** In order: a compound index on `{a, b}` is not one on `{b, a}`. */\n\tkey: Fields;\n\toptions: Fields;\n}\n\nexport function normalizeIndex(\n\tindex: IndexDescription | IndexDescriptionInfo,\n): NormalizedIndex {\n\tconst key = keyOf(index);\n\tconst options: Fields = {};\n\tfor (const [name, value] of Object.entries(index)) {\n\t\tif (IGNORED.has(name) || value === undefined) continue;\n\t\tif (name === 'collation') {\n\t\t\toptions.collation = canonicalCollation(value);\n\t\t\tcontinue;\n\t\t}\n\t\tif (OPTION_DEFAULTS[name] === value) continue;\n\t\toptions[name] = value;\n\t}\n\treturn { name: index.name ?? indexNameOf(key), key, options };\n}\n\nfunction canonical(value: unknown): string {\n\treturn JSON.stringify(value, (_name, inner) =>\n\t\tinner && typeof inner === 'object' && !Array.isArray(inner)\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(inner).sort(([a], [b]) => (a < b ? -1 : 1)),\n\t\t\t\t)\n\t\t\t: inner,\n\t);\n}\n\n/** Are two indexes the same index, with the same options? */\nexport function indexMatches(\n\twanted: IndexDescription,\n\tlive: IndexDescriptionInfo,\n): boolean {\n\tconst a = normalizeIndex(wanted);\n\tconst b = normalizeIndex(live);\n\treturn (\n\t\t// The key's order counts, so it is compared as it was written.\n\t\tJSON.stringify(Object.entries(a.key)) ===\n\t\t\tJSON.stringify(Object.entries(b.key)) &&\n\t\tcanonical(a.options) === canonical(b.options)\n\t);\n}\n\nexport interface IndexDiff {\n\t/** Not on the server yet. */\n\tcreate: IndexDescription[];\n\t/**\n\t * There under this name, with other options: MongoDB refuses to change\n\t * one, so it is dropped and created again.\n\t */\n\trecreate: IndexDescription[];\n\t/** Already as the definition wants it. */\n\tunchanged: string[];\n\t/** On the server and in no definition. `_id_` is never one. */\n\textra: string[];\n}\n\n/**\n * What an index sync has to do. Indexes are matched by name, which is what\n * MongoDB keys them on: the same name with other options is error 86, and the\n * same key under another name is error 85.\n */\nexport function diffIndexes(\n\twanted: readonly IndexDescription[],\n\tlive: readonly IndexDescriptionInfo[],\n): IndexDiff {\n\tconst byName = new Map(\n\t\tlive.map((index) => [normalizeIndex(index).name, index]),\n\t);\n\tconst diff: IndexDiff = {\n\t\tcreate: [],\n\t\trecreate: [],\n\t\tunchanged: [],\n\t\textra: [],\n\t};\n\tconst named = new Set<string>();\n\n\tfor (const index of wanted) {\n\t\tconst name = normalizeIndex(index).name;\n\t\tnamed.add(name);\n\t\tconst existing = byName.get(name);\n\t\tif (!existing) diff.create.push({ ...index, name });\n\t\telse if (indexMatches(index, existing)) diff.unchanged.push(name);\n\t\telse diff.recreate.push({ ...index, name });\n\t}\n\n\tfor (const name of byName.keys()) {\n\t\t// The `_id_` index is created with the collection and cannot be dropped.\n\t\tif (name !== '_id_' && !named.has(name)) diff.extra.push(name);\n\t}\n\treturn diff;\n}\n",
|
|
14
9
|
"import type {\n\tValidationAction,\n\tValidationLevel,\n} from '../definition/define-collection';\n\n/** A collection's validation, as `listCollections` reports it in `options`. */\nexport interface LiveValidation {\n\tvalidator?: Record<string, unknown>;\n\tvalidationLevel?: string;\n\tvalidationAction?: string;\n}\n\n/** The validation a definition asks for. `validator` is absent for `off`. */\nexport interface WantedValidation {\n\tvalidator: Record<string, unknown> | undefined;\n\tlevel: ValidationLevel;\n\taction: ValidationAction;\n}\n\nfunction canonical(value: unknown): string {\n\treturn JSON.stringify(value ?? null, (_name, inner) =>\n\t\tinner && typeof inner === 'object' && !Array.isArray(inner)\n\t\t\t? Object.fromEntries(\n\t\t\t\t\tObject.entries(inner).sort(([a], [b]) => (a < b ? -1 : 1)),\n\t\t\t\t)\n\t\t\t: inner,\n\t);\n}\n\n/** Has a collection a validator at all? An empty one is no validator. */\nexport function hasValidator(live: LiveValidation): boolean {\n\treturn live.validator !== undefined && Object.keys(live.validator).length > 0;\n}\n\n/**\n * Does the collection already validate the way the definition says?\n *\n * MongoDB reads a `$jsonSchema` back exactly as it was sent, so the two are\n * compared whole. What it does not read back is a validator that was removed:\n * `collMod` with `validator: {}` leaves **no `validator` key at all**, while\n * `validationLevel` and `validationAction` stay behind. And a collection\n * created without one reports `options: {}`, where the level is `strict` and\n * the action `error` by default.\n */\nexport function validationMatches(\n\twanted: WantedValidation,\n\tlive: LiveValidation,\n): boolean {\n\tif (wanted.validator === undefined) return !hasValidator(live);\n\tif (!hasValidator(live)) return false;\n\treturn (\n\t\tcanonical(live.validator) === canonical(wanted.validator) &&\n\t\t(live.validationLevel ?? 'strict') === wanted.level &&\n\t\t(live.validationAction ?? 'error') === wanted.action\n\t);\n}\n",
|
|
15
10
|
"import type {\n\tClientSession,\n\tDb,\n\tDocument,\n\tIndexDescription,\n\tIndexDescriptionInfo,\n} from 'mongodb';\nimport type { AnyCollectionDefinition } from '../definition/define-collection';\nimport { toMongoJsonSchema } from '../definition/json-schema';\nimport { DataError } from '../errors/data-error';\nimport { toDataError } from '../errors/to-data-error';\nimport { diffIndexes, normalizeIndex } from './index-diff';\nimport {\n\thasValidator,\n\ttype LiveValidation,\n\tvalidationMatches,\n\ttype WantedValidation,\n} from './validator-diff';\n\nexport interface SyncOptions {\n\t/**\n\t * Compare and report, but send nothing: no collection is created, no\n\t * validator written, no index touched. For a check in CI, or a look before\n\t * a deploy.\n\t */\n\tdryRun?: boolean;\n\t/**\n\t * Drop the indexes the server has and no definition names. Off by default:\n\t * an index someone added on purpose is not this package's to remove.\n\t * `_id_` is never dropped, and cannot be.\n\t */\n\tdropUnknownIndexes?: boolean;\n\t/**\n\t * A session for the reads. MongoDB does not allow `collMod` or an index\n\t * build inside a transaction, so do not pass one that is in a transaction.\n\t */\n\tsession?: ClientSession;\n}\n\n/** What `sync` found and did to one collection. */\nexport interface SyncReport {\n\tname: string;\n\t/** The collection did not exist, and was created. */\n\tcreated: boolean;\n\t/** What the `$jsonSchema` validator needed. */\n\tvalidator: 'unchanged' | 'created' | 'updated' | 'removed';\n\tindexes: {\n\t\tcreated: string[];\n\t\t/** There with other options: MongoDB cannot change one, so it is dropped and built again. */\n\t\trecreated: string[];\n\t\tdropped: string[];\n\t\tunchanged: string[];\n\t};\n\tdryRun: boolean;\n}\n\nfunction serverCode(error: unknown): number | undefined {\n\tconst code = (error as { code?: unknown } | null)?.code;\n\treturn typeof code === 'number' ? code : undefined;\n}\n\nasync function collectionOptions(\n\tdb: Db,\n\tname: string,\n\tsession: ClientSession | undefined,\n): Promise<LiveValidation | undefined> {\n\t// `nameOnly: false` is what types the answer as the whole entry: without\n\t// it the driver's overload gives back a name and a type alone.\n\tconst [info] = await db\n\t\t.listCollections(\n\t\t\t{ name },\n\t\t\t{ ...(session ? { session } : {}), nameOnly: false },\n\t\t)\n\t\t.toArray();\n\treturn info ? ((info.options ?? {}) as LiveValidation) : undefined;\n}\n\n/** The indexes of a collection, or none when it does not exist yet. */\nasync function liveIndexes(\n\tdb: Db,\n\tname: string,\n\tsession: ClientSession | undefined,\n): Promise<IndexDescriptionInfo[]> {\n\ttry {\n\t\treturn await db.collection(name).indexes({ session });\n\t} catch (error) {\n\t\t// NamespaceNotFound: nothing is there, so nothing is indexed.\n\t\tif (serverCode(error) === 26) return [];\n\t\tthrow error;\n\t}\n}\n\nfunction validationFor(definition: AnyCollectionDefinition): WantedValidation {\n\tconst { level, action } = definition.validation;\n\treturn {\n\t\tvalidator:\n\t\t\tlevel === 'off'\n\t\t\t\t? undefined\n\t\t\t\t: { $jsonSchema: toMongoJsonSchema(definition.schema) },\n\t\tlevel,\n\t\taction,\n\t};\n}\n\nfunction creationOptions(wanted: WantedValidation): Document {\n\treturn wanted.validator === undefined\n\t\t? {}\n\t\t: {\n\t\t\t\tvalidator: wanted.validator,\n\t\t\t\tvalidationLevel: wanted.level,\n\t\t\t\tvalidationAction: wanted.action,\n\t\t\t};\n}\n\nasync function writeValidation(\n\tdb: Db,\n\tname: string,\n\twanted: WantedValidation,\n\tsession: ClientSession | undefined,\n): Promise<void> {\n\ttry {\n\t\tawait db.command(\n\t\t\t{\n\t\t\t\tcollMod: name,\n\t\t\t\t// An empty validator is how one is removed: the key then goes\n\t\t\t\t// away entirely, and the level and the action stay behind.\n\t\t\t\tvalidator: wanted.validator ?? {},\n\t\t\t\t...(wanted.validator === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { validationLevel: wanted.level, validationAction: wanted.action }),\n\t\t\t},\n\t\t\tsession ? { session } : undefined,\n\t\t);\n\t} catch (error) {\n\t\tif (serverCode(error) === 13) {\n\t\t\tthrow new DataError(\n\t\t\t\t`sync: not allowed to run collMod on \"${name}\". Writing a validator ` +\n\t\t\t\t\t'needs the `collMod` action, which `readWrite` does not grant and ' +\n\t\t\t\t\t'`dbAdmin` does: sync with a role that has it, not with the ' +\n\t\t\t\t\t'application’s own user.',\n\t\t\t\t{ collection: name, serverCode: 13, cause: error },\n\t\t\t);\n\t\t}\n\t\tthrow toDataError(error, { collection: name });\n\t}\n}\n\n/**\n * Brings one collection in line with its definition, and says what it changed:\n *\n * 1. creates the collection, with its validator, when it is missing;\n * 2. writes the validator with `collMod` when it differs from the definition's;\n * 3. creates the indexes that are missing, and rebuilds those whose options\n * changed — MongoDB refuses to alter an index in place.\n *\n * Run it twice and the second run sends nothing.\n *\n * ```ts\n * const report = await syncCollection(db, users);\n * // { created: true, validator: 'created', indexes: { created: ['users_email_unique'], … } }\n * ```\n *\n * It is a deployment step, not a request-time one: `collMod` needs the\n * `dbAdmin` role, and neither it nor an index build may run in a transaction.\n */\nexport async function syncCollection(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: SyncOptions = {},\n): Promise<SyncReport> {\n\tconst { name } = definition;\n\tconst dryRun = options.dryRun ?? false;\n\tconst session = options.session;\n\tconst wanted = validationFor(definition);\n\n\tlet live = await collectionOptions(db, name, session);\n\tlet created = false;\n\tlet validator: SyncReport['validator'] = 'unchanged';\n\n\tif (!live) {\n\t\tcreated = true;\n\t\tif (wanted.validator !== undefined) validator = 'created';\n\t\tif (!dryRun) {\n\t\t\ttry {\n\t\t\t\tawait db.createCollection(name, {\n\t\t\t\t\t...creationOptions(wanted),\n\t\t\t\t\t...(session ? { session } : {}),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\t// NamespaceExists: another sync created it between the lookup and\n\t\t\t\t// the creation. Go on with theirs, which is compared below.\n\t\t\t\tif (serverCode(error) !== 48) {\n\t\t\t\t\tthrow toDataError(error, { collection: name });\n\t\t\t\t}\n\t\t\t\tcreated = false;\n\t\t\t\tvalidator = 'unchanged';\n\t\t\t\tlive = await collectionOptions(db, name, session);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (live && !validationMatches(wanted, live)) {\n\t\tvalidator =\n\t\t\twanted.validator === undefined\n\t\t\t\t? 'removed'\n\t\t\t\t: hasValidator(live)\n\t\t\t\t\t? 'updated'\n\t\t\t\t\t: 'created';\n\t\tif (!dryRun) await writeValidation(db, name, wanted, session);\n\t}\n\n\tconst existing =\n\t\tdryRun && created ? [] : await liveIndexes(db, name, session);\n\tconst diff = diffIndexes(definition.indexes, existing);\n\tconst dropped = options.dropUnknownIndexes ? diff.extra : [];\n\tconst build: IndexDescription[] = [...diff.create, ...diff.recreate];\n\n\tif (!dryRun) {\n\t\tconst collection = db.collection(name);\n\t\tfor (const index of [\n\t\t\t...diff.recreate.map((i) => normalizeIndex(i).name),\n\t\t\t...dropped,\n\t\t]) {\n\t\t\tawait collection.dropIndex(index, session ? { session } : undefined);\n\t\t}\n\t\tif (build.length > 0) {\n\t\t\ttry {\n\t\t\t\tawait collection.createIndexes(\n\t\t\t\t\tbuild,\n\t\t\t\t\tsession ? { session } : undefined,\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tthrow toDataError(error, { collection: name });\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tname,\n\t\tcreated,\n\t\tvalidator,\n\t\tindexes: {\n\t\t\tcreated: diff.create.map((index) => normalizeIndex(index).name),\n\t\t\trecreated: diff.recreate.map((index) => normalizeIndex(index).name),\n\t\t\tdropped,\n\t\t\tunchanged: diff.unchanged,\n\t\t},\n\t\tdryRun,\n\t};\n}\n\n/**\n * `syncCollection` for each definition, one after the other, in the order\n * given. The first that throws stops the rest.\n */\nexport async function syncCollections(\n\tdb: Db,\n\tdefinitions: readonly AnyCollectionDefinition[],\n\toptions: SyncOptions = {},\n): Promise<SyncReport[]> {\n\tconst reports: SyncReport[] = [];\n\tfor (const definition of definitions) {\n\t\treports.push(await syncCollection(db, definition, options));\n\t}\n\treturn reports;\n}\n",
|
|
16
|
-
"import type { ClientSession, Db, Document } from 'mongodb';\nimport type { z } from 'zod';\nimport {\n\ttype AnyCollectionDefinition,\n\ttype CollectionDefinition,\n\tstampsOf,\n} from '../definition/define-collection';\nimport {\n\tDataError,\n\tNotFoundError,\n\tOptimisticLockError,\n} from '../errors/data-error';\nimport { toDataError } from '../errors/to-data-error';\nimport { decodeCursor, encodeCursor } from '../pagination/cursor';\nimport {\n\ttype CursorPage,\n\tcursorLimit,\n\tDEFAULT_MAX_PAGE_SIZE,\n\ttype Page,\n\tpageWindow,\n\ttoPage,\n} from '../pagination/page';\nimport { type SyncOptions, syncCollection } from '../sync/sync-collection';\nimport type { OrderDirection, Repository, RepositoryOptions } from './types';\n\ntype Fields = Record<string, unknown>;\n\nfunction isRecord(value: unknown): value is Fields {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Does this patch speak in MongoDB's operators rather than in fields? */\nfunction isUpdateFilter(patch: Fields): boolean {\n\treturn Object.keys(patch).some((key) => key.startsWith('$'));\n}\n\n/** `a` and `b`, without letting one's `$or` swallow the other's. */\nfunction mergeFilters(a: Fields | undefined, b: Fields | undefined): Fields {\n\tconst left = a && Object.keys(a).length > 0 ? a : undefined;\n\tconst right = b && Object.keys(b).length > 0 ? b : undefined;\n\tif (!left) return right ?? {};\n\tif (!right) return left;\n\treturn { $and: [left, right] };\n}\n\n/**\n * A repository over one collection: typed reads and writes by `_id` or by\n * filter, pagination, soft delete, optimistic locking, audit stamps, and\n * MongoDB errors turned into this package's.\n *\n * ```ts\n * const users = createRepository(db, usersCollection);\n * const ada = await users.create({ email: 'ada@example.com' });\n * await users.update(ada._id, { name: 'Ada' }, { expectedVersion: ada.version });\n * ```\n *\n * Every operation runs in the repository's session, which `with(session)`\n * sets: MongoDB has no ambient session, so a write inside a transaction that\n * was not given one is not part of it and is not rolled back.\n */\nexport function createRepository<Schema extends z.ZodObject>(\n\tdb: Db,\n\tdefinition: CollectionDefinition<Schema>,\n\toptions: RepositoryOptions = {},\n): Repository<CollectionDefinition<Schema>> {\n\treturn build(db, definition, options) as unknown as Repository<\n\t\tCollectionDefinition<Schema>\n\t>;\n}\n\nfunction build(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: RepositoryOptions,\n) {\n\tconst name = definition.name;\n\t// The driver types a collection by its documents; this body works on any\n\t// collection, and the public type above is what callers see.\n\tconst collection = db.collection<any>(name);\n\tconst shape = definition.schema.shape as Record<string, z.ZodType>;\n\t// A schema may declare an `id` field of its own; then it is that field's,\n\t// and the repository neither computes it nor drops it.\n\tconst hasOwnId = 'id' in shape;\n\tconst stamps = stampsOf(definition);\n\tconst session = options.session;\n\tconst actor = options.actor;\n\tconst maxPageSize = options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE;\n\tconst parses = (options.validate ?? 'parse') === 'parse';\n\tconst softDeletes = options.softDelete ?? stamps.deletedAt;\n\tconst touches = options.touchUpdatedAt ?? stamps.updatedAt;\n\tconst locks = options.optimisticLock ?? stamps.version;\n\n\tif (options.softDelete === true && !stamps.deletedAt) {\n\t\tthrow new TypeError(\n\t\t\t`createRepository: softDelete needs a \"deletedAt\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\tif (options.optimisticLock === true && !stamps.version) {\n\t\tthrow new TypeError(\n\t\t\t`createRepository: optimisticLock needs a \"version\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\n\tconst run = async <T>(fn: () => Promise<T>): Promise<T> => {\n\t\ttry {\n\t\t\treturn await fn();\n\t\t} catch (error) {\n\t\t\tthrow toDataError(error, { collection: name });\n\t\t}\n\t};\n\n\tconst sessionOption = session ? { session } : {};\n\n\t/** The filter that leaves soft-deleted documents out. */\n\tconst live = (withDeleted?: boolean): Fields | undefined =>\n\t\tsoftDeletes && !withDeleted ? { deletedAt: null } : undefined;\n\n\tconst scoped = (filter: unknown, withDeleted?: boolean): Fields =>\n\t\tmergeFilters(isRecord(filter) ? filter : undefined, live(withDeleted));\n\n\t/**\n\t * `id` on a document the repository gives back: `_id` as a string, computed\n\t * rather than stored — the collection holds `_id` alone.\n\t *\n\t * It is enumerable, so `JSON.stringify` and a spread carry it and a handler\n\t * can return the document as it is. `toDocument` drops it again on a write,\n\t * and it is no part of `DocumentOf`, so nothing can filter on it: the server\n\t * would match nothing.\n\t */\n\tconst withId = <T>(document: T): T => {\n\t\tif (\n\t\t\thasOwnId ||\n\t\t\t!isRecord(document) ||\n\t\t\tdocument._id === undefined ||\n\t\t\tObject.hasOwn(document, 'id')\n\t\t) {\n\t\t\treturn document;\n\t\t}\n\t\tObject.defineProperty(document, 'id', {\n\t\t\tget: () => String((document as Fields)._id),\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\t\t});\n\t\treturn document;\n\t};\n\n\tconst notFound = (id: unknown) =>\n\t\tnew NotFoundError(`No document in \"${name}\" with _id ${String(id)}`, {\n\t\t\tcollection: name,\n\t\t\tid,\n\t\t});\n\n\tconst requireFilter = (method: string, filter: unknown): void => {\n\t\tif (!isRecord(filter) || Object.keys(filter).length === 0) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`${method} needs a filter. Pass \\`{ _id: { $exists: true } }\\` to target every document of \"${name}\".`,\n\t\t\t);\n\t\t}\n\t};\n\n\t/** The document to insert: checked against the schema, defaults filled. */\n\tconst toDocument = (values: unknown): Fields => {\n\t\tconst stamped: Fields = { ...(values as Fields) };\n\t\t// A document that was read carries `id`, which is this repository's view\n\t\t// of `_id` and not a field: writing it back would be refused by the\n\t\t// validator, which allows no property the schema does not declare.\n\t\t// Parsing strips it too, but `validate: 'off'` does not parse.\n\t\tif (!hasOwnId) delete stamped.id;\n\t\tif (actor !== undefined) {\n\t\t\tif (stamps.createdBy && stamped.createdBy === undefined) {\n\t\t\t\tstamped.createdBy = actor;\n\t\t\t}\n\t\t\tif (stamps.updatedBy && stamped.updatedBy === undefined) {\n\t\t\t\tstamped.updatedBy = actor;\n\t\t\t}\n\t\t}\n\t\treturn parses ? (definition.schema.parse(stamped) as Fields) : stamped;\n\t};\n\n\t/**\n\t * The update to send: a patch of fields becomes `$set`, checked field by\n\t * field against the schema, with the stamps this repository keeps. A patch\n\t * that already speaks in operators is sent as it is, with the stamps added.\n\t */\n\tconst toUpdate = (patch: unknown): Fields => {\n\t\tif (!isRecord(patch)) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`update: expected the document's fields or MongoDB's operators, not ${String(patch)}`,\n\t\t\t);\n\t\t}\n\t\tconst update: Fields = isUpdateFilter(patch) ? { ...patch } : {};\n\t\tconst set: Fields = isRecord(update.$set) ? { ...update.$set } : {};\n\n\t\tif (!isUpdateFilter(patch)) {\n\t\t\tfor (const [field, value] of Object.entries(patch)) {\n\t\t\t\tif (value === undefined) continue;\n\t\t\t\tconst schema = shape[field];\n\t\t\t\tif (!schema) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`update: \"${name}\" has no field \"${field}\" in its schema`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tset[field] = parses ? schema.parse(value) : value;\n\t\t\t}\n\t\t}\n\n\t\tif (touches && set.updatedAt === undefined) set.updatedAt = new Date();\n\t\tif (\n\t\t\tactor !== undefined &&\n\t\t\tstamps.updatedBy &&\n\t\t\tset.updatedBy === undefined\n\t\t) {\n\t\t\tset.updatedBy = actor;\n\t\t}\n\t\tif (Object.keys(set).length > 0) update.$set = set;\n\n\t\tif (locks) {\n\t\t\tconst inc = isRecord(update.$inc) ? { ...update.$inc } : {};\n\t\t\tinc.version = (inc.version as number | undefined) ?? 1;\n\t\t\tupdate.$inc = inc;\n\t\t}\n\t\treturn update;\n\t};\n\n\tconst findOne = async (filter: Fields, projection?: unknown) =>\n\t\trun(async () => {\n\t\t\tconst found = await collection.findOne(filter, {\n\t\t\t\t...sessionOption,\n\t\t\t\t...(projection ? { projection } : {}),\n\t\t\t});\n\t\t\treturn found === null ? null : withId(found as Fields);\n\t\t});\n\n\tasync function findById(id: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\tconst found = await findOne(scoped({ _id: id }, opts.withDeleted));\n\t\treturn found ?? undefined;\n\t}\n\n\tasync function getById(id: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\tconst found = await findById(id, opts);\n\t\tif (!found) throw notFound(id);\n\t\treturn found;\n\t}\n\n\tasync function findMany(opts: Fields = {}): Promise<Fields[]> {\n\t\treturn run(async () => {\n\t\t\tlet cursor = collection.find(\n\t\t\t\tscoped(opts.filter, opts.withDeleted as boolean | undefined),\n\t\t\t\t{\n\t\t\t\t\t...sessionOption,\n\t\t\t\t\t...(opts.projection ? { projection: opts.projection } : {}),\n\t\t\t\t},\n\t\t\t);\n\t\t\tif (opts.sort !== undefined) cursor = cursor.sort(opts.sort as never);\n\t\t\tif (opts.skip !== undefined) cursor = cursor.skip(opts.skip as number);\n\t\t\tif (opts.limit !== undefined) cursor = cursor.limit(opts.limit as number);\n\t\t\tconst found = await cursor.toArray();\n\t\t\treturn found.map((document) => withId(document as Fields));\n\t\t});\n\t}\n\n\tasync function countDocuments(\n\t\tfilter?: unknown,\n\t\topts: { withDeleted?: boolean } = {},\n\t) {\n\t\treturn run(async () =>\n\t\t\tcollection.countDocuments(scoped(filter, opts.withDeleted), {\n\t\t\t\t...sessionOption,\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * `findOneAndUpdate` answers `null` for a document that is not there, one\n\t * that is soft-deleted, and one whose version moved. Only a second read\n\t * tells them apart.\n\t */\n\tasync function updatedOrThrow(\n\t\tid: unknown,\n\t\tfilter: Fields,\n\t\tupdate: Fields,\n\t\texpectedVersion: number | undefined,\n\t): Promise<Fields> {\n\t\tconst updated = await run(async () =>\n\t\t\tcollection.findOneAndUpdate(filter, update, {\n\t\t\t\t...sessionOption,\n\t\t\t\treturnDocument: 'after',\n\t\t\t}),\n\t\t);\n\t\tif (updated) return withId(updated as Fields);\n\n\t\tif (expectedVersion !== undefined) {\n\t\t\tconst current = await findOne({ _id: id });\n\t\t\tif (current) {\n\t\t\t\tthrow new OptimisticLockError(\n\t\t\t\t\t`Document ${String(id)} of \"${name}\" is at version ${String(\n\t\t\t\t\t\tcurrent.version,\n\t\t\t\t\t)}, not ${expectedVersion}: it changed since it was read`,\n\t\t\t\t\t{\n\t\t\t\t\t\tcollection: name,\n\t\t\t\t\t\tid,\n\t\t\t\t\t\texpectedVersion,\n\t\t\t\t\t\tactualVersion:\n\t\t\t\t\t\t\ttypeof current.version === 'number' ? current.version : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tthrow notFound(id);\n\t}\n\n\tasync function hardDelete(id: unknown): Promise<Fields> {\n\t\tconst deleted = await run(async () =>\n\t\t\tcollection.findOneAndDelete({ _id: id }, { ...sessionOption }),\n\t\t);\n\t\tif (!deleted) throw notFound(id);\n\t\treturn withId(deleted as Fields);\n\t}\n\n\tasync function hardDeleteMany(filter: unknown): Promise<number> {\n\t\trequireFilter('hardDeleteMany', filter);\n\t\treturn run(async () => {\n\t\t\tconst result = await collection.deleteMany(filter as Fields, {\n\t\t\t\t...sessionOption,\n\t\t\t});\n\t\t\treturn result.deletedCount;\n\t\t});\n\t}\n\n\tconst repository = {\n\t\tdefinition,\n\t\tdb,\n\t\tcollection,\n\t\tsession,\n\n\t\twith: (other: ClientSession | undefined) =>\n\t\t\tbuild(db, definition, { ...options, session: other }),\n\t\tas: (who: unknown) => build(db, definition, { ...options, actor: who }),\n\t\tsync: (syncOptions: SyncOptions = {}) =>\n\t\t\tsyncCollection(db, definition, { ...sessionOption, ...syncOptions }),\n\n\t\tfindById,\n\t\tgetById,\n\n\t\tasync findFirst(filter?: unknown, opts: Fields = {}) {\n\t\t\tconst [first] = await findMany({ ...opts, filter, limit: 1 });\n\t\t\treturn first;\n\t\t},\n\n\t\tfindMany,\n\n\t\tasync create(values: unknown) {\n\t\t\tconst document = toDocument(values);\n\t\t\treturn run(async () => {\n\t\t\t\tawait collection.insertOne(document as Document, { ...sessionOption });\n\t\t\t\treturn withId(document);\n\t\t\t});\n\t\t},\n\n\t\tasync createMany(values: readonly unknown[]) {\n\t\t\tif (values.length === 0) return [];\n\t\t\tconst documents = values.map(toDocument);\n\t\t\treturn run(async () => {\n\t\t\t\tawait collection.insertMany(documents as Document[], {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn documents.map((document) => withId(document));\n\t\t\t});\n\t\t},\n\n\t\tasync update(id: unknown, patch: unknown, opts: Fields = {}) {\n\t\t\tconst expectedVersion = opts.expectedVersion as number | undefined;\n\t\t\tif (expectedVersion !== undefined && !locks) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`update: expectedVersion needs a \"version\" field, and \"${name}\" has none`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst update = toUpdate(patch);\n\t\t\tconst filter = mergeFilters(\n\t\t\t\t{\n\t\t\t\t\t_id: id,\n\t\t\t\t\t...(expectedVersion === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { version: expectedVersion }),\n\t\t\t\t},\n\t\t\t\tlive(),\n\t\t\t);\n\t\t\treturn updatedOrThrow(id, filter, update, expectedVersion);\n\t\t},\n\n\t\tasync updateMany(filter: unknown, patch: unknown) {\n\t\t\trequireFilter('updateMany', filter);\n\t\t\tconst update = toUpdate(patch);\n\t\t\treturn run(async () => {\n\t\t\t\tconst result = await collection.updateMany(scoped(filter), update, {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn result.modifiedCount;\n\t\t\t});\n\t\t},\n\n\t\tasync delete(id: unknown) {\n\t\t\tif (!softDeletes) return hardDelete(id);\n\t\t\tconst set: Fields = { deletedAt: new Date() };\n\t\t\tif (actor !== undefined && stamps.deletedBy) set.deletedBy = actor;\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn updatedOrThrow(\n\t\t\t\tid,\n\t\t\t\tmergeFilters({ _id: id }, live()),\n\t\t\t\tupdate,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t},\n\n\t\tasync deleteMany(filter: unknown) {\n\t\t\trequireFilter('deleteMany', filter);\n\t\t\tif (!softDeletes) return hardDeleteMany(filter);\n\t\t\tconst set: Fields = { deletedAt: new Date() };\n\t\t\tif (actor !== undefined && stamps.deletedBy) set.deletedBy = actor;\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn run(async () => {\n\t\t\t\tconst result = await collection.updateMany(scoped(filter), update, {\n\t\t\t\t\t...sessionOption,\n\t\t\t\t});\n\t\t\t\treturn result.modifiedCount;\n\t\t\t});\n\t\t},\n\n\t\thardDelete,\n\t\thardDeleteMany,\n\n\t\tasync restore(id: unknown) {\n\t\t\tif (!stamps.deletedAt) {\n\t\t\t\tthrow new TypeError(`restore: \"${name}\" has no soft delete`);\n\t\t\t}\n\t\t\tconst set: Fields = { deletedAt: null };\n\t\t\tif (stamps.deletedBy) set.deletedBy = null;\n\t\t\tif (touches) set.updatedAt = new Date();\n\t\t\tconst update: Fields = { $set: set };\n\t\t\tif (locks) update.$inc = { version: 1 };\n\t\t\treturn updatedOrThrow(id, { _id: id }, update, undefined);\n\t\t},\n\n\t\tcount: countDocuments,\n\n\t\tasync exists(filter: unknown, opts: { withDeleted?: boolean } = {}) {\n\t\t\tconst found = await findOne(scoped(filter, opts.withDeleted), { _id: 1 });\n\t\t\treturn found !== null && found !== undefined;\n\t\t},\n\n\t\tasync paginate(opts: Fields = {}): Promise<Page<Fields>> {\n\t\t\tconst window = pageWindow(opts, maxPageSize);\n\t\t\tconst [items, total] = await Promise.all([\n\t\t\t\tfindMany({\n\t\t\t\t\tfilter: opts.filter,\n\t\t\t\t\tsort: opts.sort ?? { _id: 1 },\n\t\t\t\t\tlimit: window.limit,\n\t\t\t\t\tskip: window.skip,\n\t\t\t\t\twithDeleted: opts.withDeleted,\n\t\t\t\t}),\n\t\t\t\tcountDocuments(opts.filter, {\n\t\t\t\t\twithDeleted: opts.withDeleted as boolean | undefined,\n\t\t\t\t}),\n\t\t\t]);\n\t\t\treturn toPage(items, total, window);\n\t\t},\n\n\t\tasync paginateByCursor(opts: Fields = {}): Promise<CursorPage<Fields>> {\n\t\t\tconst sortField = (opts.orderBy as string | undefined) ?? '_id';\n\t\t\tif (!shape[sortField] && sortField !== '_id') {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`paginateByCursor: \"${name}\" has no field \"${sortField}\" in its schema`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst direction = (opts.direction as OrderDirection | undefined) ?? 'asc';\n\t\t\tconst fields = sortField === '_id' ? ['_id'] : [sortField, '_id'];\n\t\t\tconst cursorKey = `${sortField}:${direction}`;\n\t\t\tconst limit = cursorLimit(opts.limit as number | undefined, maxPageSize);\n\t\t\tconst past = direction === 'asc' ? '$gt' : '$lt';\n\n\t\t\tlet after: Fields | undefined;\n\t\t\tif (opts.after) {\n\t\t\t\tconst { values } = decodeCursor(opts.after as string, cursorKey);\n\t\t\t\tif (values.length !== fields.length) {\n\t\t\t\t\tthrow new DataError(\n\t\t\t\t\t\t`Invalid cursor: expected ${fields.length} value(s), got ${values.length}`,\n\t\t\t\t\t\t{ collection: name },\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\t// `a > x OR (a = x AND b > y)`, the keyset of the ordering.\n\t\t\t\tafter = {\n\t\t\t\t\t$or: fields.map((field, index) => ({\n\t\t\t\t\t\t...Object.fromEntries(\n\t\t\t\t\t\t\tfields\n\t\t\t\t\t\t\t\t.slice(0, index)\n\t\t\t\t\t\t\t\t.map((previous, i) => [previous, values[i]]),\n\t\t\t\t\t\t),\n\t\t\t\t\t\t[field]: { [past]: values[index] },\n\t\t\t\t\t})),\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst sort = Object.fromEntries(\n\t\t\t\tfields.map((field) => [field, direction === 'asc' ? 1 : -1]),\n\t\t\t);\n\t\t\tconst documents = await findMany({\n\t\t\t\tfilter: mergeFilters(\n\t\t\t\t\tisRecord(opts.filter) ? opts.filter : undefined,\n\t\t\t\t\tafter,\n\t\t\t\t),\n\t\t\t\tsort,\n\t\t\t\tlimit: limit + 1,\n\t\t\t\twithDeleted: opts.withDeleted,\n\t\t\t});\n\n\t\t\tconst items = documents.slice(0, limit);\n\t\t\tconst last = items.at(-1);\n\t\t\tif (documents.length <= limit || !last) {\n\t\t\t\treturn { items, nextCursor: null };\n\t\t\t}\n\n\t\t\tconst values = fields.map((field) => {\n\t\t\t\tconst value = last[field];\n\t\t\t\tif (value === null || value === undefined) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t`paginateByCursor: \"${field}\" is null in a document of \"${name}\". ` +\n\t\t\t\t\t\t\t'Page along a field every document has.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn value;\n\t\t\t});\n\t\t\treturn { items, nextCursor: encodeCursor({ key: cursorKey, values }) };\n\t\t},\n\t};\n\n\treturn repository;\n}\n",
|
|
17
|
-
"
|
|
11
|
+
"import type { IndexDescription, IndexDirection, ObjectId } from 'mongodb';\nimport type { z } from 'zod';\n\n/** What MongoDB does with a document that fails the validator. */\nexport type ValidationAction = 'error' | 'warn';\n\n/**\n * Which documents the validator applies to. `off` writes no validator at all;\n * `moderate` exempts documents that were already invalid from updates.\n */\nexport type ValidationLevel = 'off' | 'moderate' | 'strict';\n\nexport interface ValidationConfig {\n\t/** Default `'strict'`. */\n\tlevel?: ValidationLevel;\n\t/** Default `'error'`. `'warn'` logs and lets the write through. */\n\taction?: ValidationAction;\n}\n\n/**\n * What an index may be keyed on: a field of the documents, which an editor\n * completes, or a path into one — `{ 'address.city': 1 }` is how MongoDB\n * indexes a nested field, and there is no way to check the tail of a path\n * against a schema without rejecting the paths Mongo allows.\n */\nexport type IndexKey<Doc> =\n\t| {\n\t\t\t[Field in\n\t\t\t\t| (keyof Doc & string)\n\t\t\t\t| `${keyof Doc & string}.${string}`]?: IndexDirection;\n\t }\n\t// The driver takes a `Map` too, and an index read back off the server comes\n\t// as one: refusing it here would refuse a definition built from a live one.\n\t| Map<string, IndexDirection>;\n\n/**\n * An index, keyed on the schema's own fields. Everything else — `unique`,\n * `name`, `collation`, `partialFilterExpression`, the TTL — is the driver's\n * `IndexDescription`, unchanged.\n */\nexport interface CollectionIndex<Doc> extends Omit<IndexDescription, 'key'> {\n\tkey: IndexKey<Doc>;\n}\n\n/** What `defineCollection` takes. */\nexport interface CollectionConfig<Schema extends z.ZodObject> {\n\t/** The collection's name on the server. */\n\tname: string;\n\t/**\n\t * The documents, as they are stored: `z.output` is what a read gives back,\n\t * `z.input` what a write takes. It must have an `_id`.\n\t */\n\tschema: Schema;\n\t/** The indexes `sync` creates, keyed on the schema's fields. */\n\tindexes?: readonly CollectionIndex<z.output<Schema>>[];\n\t/** The `$jsonSchema` validator `sync` writes from the schema. */\n\tvalidation?: ValidationConfig;\n}\n\n/** A collection, as `defineCollection` returns it: frozen, with its defaults. */\nexport interface CollectionDefinition<\n\tSchema extends z.ZodObject = z.ZodObject,\n> {\n\treadonly name: string;\n\treadonly schema: Schema;\n\t/** As the driver takes them: `sync` hands these straight to MongoDB. */\n\treadonly indexes: readonly IndexDescription[];\n\treadonly validation: Required<ValidationConfig>;\n}\n\n/** Any definition, whatever its documents. */\nexport type AnyCollectionDefinition = CollectionDefinition<any>;\n\n/** The documents of a definition, as they are read back. */\nexport type DocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.output<Schema>\n\t\t: never\n\t: never;\n\n/**\n * A document as a collection gives it back: the stored document, plus `id`.\n *\n * `id` is `_id` as a string, computed rather than stored — the collection\n * holds `_id` alone. It is enumerable, so `JSON.stringify` and a spread carry\n * it, which is what makes a document ready to return from an API; it is not\n * part of `DocumentOf`, so a filter or a patch cannot be keyed on it, because\n * the server would match nothing.\n */\nexport type ReadDocumentOf<Def> = DocumentOf<Def> & { readonly id: string };\n\n/** What a write takes: the documents before their defaults are filled. */\nexport type NewDocumentOf<Def> = Def extends { schema: infer Schema }\n\t? Schema extends z.ZodType\n\t\t? z.input<Schema>\n\t\t: never\n\t: never;\n\n/** The type of `_id`. */\nexport type IdOf<Def> =\n\tDocumentOf<Def> extends { _id: infer Id } ? Id : ObjectId;\n\n/** A field of the documents, as a top-level key. */\nexport type FieldOf<Def> = keyof DocumentOf<Def> & string;\n\n/**\n * Defines a collection: its name, the Zod schema of its documents, its\n * indexes, and how its validator is applied.\n *\n * The schema is the one source: it types every read and write, and `sync`\n * derives the collection's `$jsonSchema` validator from it.\n *\n * ```ts\n * export const users = defineCollection({\n * \tname: 'users',\n * \tschema: z.object({\n * \t\t_id: id(),\n * \t\temail: z.email(),\n * \t\t...timestamps(),\n * \t\t...softDelete(),\n * \t}),\n * \tindexes: [{ key: { email: 1 }, unique: true, name: 'users_email_unique' }],\n * });\n * ```\n */\nexport function defineCollection<Schema extends z.ZodObject>(\n\tconfig: CollectionConfig<Schema>,\n): CollectionDefinition<Schema> {\n\tif (!('_id' in config.schema.shape)) {\n\t\tthrow new TypeError(\n\t\t\t`defineCollection: \"${config.name}\"'s schema has no _id. Add ` +\n\t\t\t\t'`_id: id()`, which fills a new ObjectId on create, or declare the ' +\n\t\t\t\t'key your documents use.',\n\t\t);\n\t}\n\treturn Object.freeze({\n\t\t...config,\n\t\tindexes: Object.freeze([...(config.indexes ?? [])]),\n\t\tvalidation: Object.freeze({\n\t\t\tlevel: config.validation?.level ?? 'strict',\n\t\t\taction: config.validation?.action ?? 'error',\n\t\t}),\n\t}) as CollectionDefinition<Schema>;\n}\n\n/** Which of the fields the collection knows about a definition's schema has. */\nexport function stampsOf(definition: AnyCollectionDefinition): {\n\tcreatedAt: boolean;\n\tupdatedAt: boolean;\n\tdeletedAt: boolean;\n\tversion: boolean;\n\tcreatedBy: boolean;\n\tupdatedBy: boolean;\n\tdeletedBy: boolean;\n} {\n\tconst shape = definition.schema.shape as Record<string, unknown>;\n\tconst has = (name: string) => name in shape;\n\treturn {\n\t\tcreatedAt: has('createdAt'),\n\t\tupdatedAt: has('updatedAt'),\n\t\tdeletedAt: has('deletedAt'),\n\t\tversion: has('version'),\n\t\tcreatedBy: has('createdBy'),\n\t\tupdatedBy: has('updatedBy'),\n\t\tdeletedBy: has('deletedBy'),\n\t};\n}\n",
|
|
12
|
+
"/** One page of an offset pagination. */\nexport interface Page<T> {\n\titems: T[];\n\t/** Every document that matches, across all pages. */\n\ttotal: number;\n\t/** 1-based. */\n\tpage: number;\n\tpageSize: number;\n\t/** `Math.ceil(total / pageSize)`: 0 when nothing matches. */\n\tpageCount: number;\n}\n\n/** One page of a cursor pagination. */\nexport interface CursorPage<T> {\n\titems: T[];\n\t/** Pass it as `after` for the next page; `null` on the last one. */\n\tnextCursor: string | null;\n}\n\nexport interface PageOptions {\n\t/** 1-based. Default `1`. */\n\tpage?: number;\n\t/** Default `20`, at most `maxPageSize`. */\n\tpageSize?: number;\n}\n\nexport interface PageWindow {\n\tpage: number;\n\tpageSize: number;\n\tlimit: number;\n\tskip: number;\n}\n\nexport const DEFAULT_PAGE_SIZE = 20;\nexport const DEFAULT_MAX_PAGE_SIZE = 100;\n\nfunction positiveInteger(name: string, value: number): number {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new RangeError(\n\t\t\t`${name} must be an integer of at least 1, not ${value}`,\n\t\t);\n\t}\n\treturn value;\n}\n\n/**\n * Checks `page` and `pageSize` and turns them into a `limit` and a `skip`.\n * A `pageSize` above `maxPageSize` is lowered to it; one that is not a\n * positive integer throws a `RangeError`.\n */\nexport function pageWindow(\n\toptions: PageOptions = {},\n\tmaxPageSize = DEFAULT_MAX_PAGE_SIZE,\n): PageWindow {\n\tconst page = positiveInteger('page', options.page ?? 1);\n\tconst pageSize = Math.min(\n\t\tpositiveInteger('pageSize', options.pageSize ?? DEFAULT_PAGE_SIZE),\n\t\tmaxPageSize,\n\t);\n\treturn { page, pageSize, limit: pageSize, skip: (page - 1) * pageSize };\n}\n\n/** Assembles a `Page` from its documents and the total. */\nexport function toPage<T>(\n\titems: T[],\n\ttotal: number,\n\twindow: PageWindow,\n): Page<T> {\n\treturn {\n\t\titems,\n\t\ttotal,\n\t\tpage: window.page,\n\t\tpageSize: window.pageSize,\n\t\tpageCount: Math.ceil(total / window.pageSize),\n\t};\n}\n\n/** Checks a cursor page's `limit`, as `pageWindow` checks a `pageSize`. */\nexport function cursorLimit(\n\tlimit: number | undefined,\n\tmaxPageSize = DEFAULT_MAX_PAGE_SIZE,\n): number {\n\treturn Math.min(\n\t\tpositiveInteger('limit', limit ?? DEFAULT_PAGE_SIZE),\n\t\tmaxPageSize,\n\t);\n}\n",
|
|
13
|
+
"import type {\n\tClientSession,\n\tDb,\n\tCollection as DriverCollection,\n} from 'mongodb';\nimport type { z } from 'zod';\nimport {\n\ttype AnyCollectionDefinition,\n\tstampsOf,\n} from '../definition/define-collection';\nimport { NotFoundError } from '../errors/data-error';\nimport { toDataError } from '../errors/to-data-error';\nimport { DEFAULT_MAX_PAGE_SIZE } from '../pagination/page';\nimport type { CollectionOptions } from './types';\n\n/** Which of the fields the collection knows about a schema has. */\ntype Stamps = ReturnType<typeof stampsOf>;\n\n/**\n * What every method of a collection works from, resolved once: the\n * definition, the driver's collection, and the options once they have been\n * read against the schema.\n *\n * It holds **data only**. The operations are plain functions that take it as\n * their first argument, in `filters.ts`, `documents.ts`, `reads.ts`,\n * `writes.ts` and `paginate.ts` — a context of closures would only be the\n * factory this package split up, one size down.\n *\n * `withSession` and `as` build another one, cheaply: they are the same\n * collection with a single option changed.\n */\nexport interface CollectionContext {\n\treadonly definition: AnyCollectionDefinition;\n\treadonly db: Db;\n\t/**\n\t * The driver's collection, typed loosely on purpose: this layer works on\n\t * any documents, and the public type is what callers see.\n\t */\n\treadonly collection: DriverCollection<any>;\n\treadonly name: string;\n\treadonly shape: Record<string, z.ZodType>;\n\treadonly stamps: Stamps;\n\t/** Who is writing, stamped into the `*By` fields. */\n\treadonly actor: unknown;\n\treadonly session: ClientSession | undefined;\n\t/** `{ session }` when there is one, to spread into the driver's options. */\n\treadonly sessionOption: { session?: ClientSession };\n\treadonly maxPageSize: number;\n\t/**\n\t * Whether the schema declares an `id` field of its own. Then `id` is that\n\t * field's, and this package neither computes it nor drops it.\n\t */\n\treadonly hasOwnId: boolean;\n\t/** Whether a write is checked against the schema, which fills its defaults. */\n\treadonly parses: boolean;\n\t/** Whether `delete` writes `deletedAt` rather than removing the document. */\n\treadonly softDeletes: boolean;\n\t/** Whether an update that does not set `updatedAt` gets it set. */\n\treadonly touches: boolean;\n\t/** Whether an update raises `version`. */\n\treadonly locks: boolean;\n}\n\n/**\n * Resolves a collection's options against its schema, and refuses the two\n * that cannot be honoured: a soft delete without `deletedAt`, and an\n * optimistic lock without `version`.\n */\nexport function createContext(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: CollectionOptions<never>,\n): CollectionContext {\n\tconst name = definition.name;\n\tconst shape = definition.schema.shape as Record<string, z.ZodType>;\n\tconst stamps = stampsOf(definition);\n\tconst session = options.session;\n\n\tif (options.softDelete === true && !stamps.deletedAt) {\n\t\tthrow new TypeError(\n\t\t\t`getCollection: softDelete needs a \"deletedAt\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\tif (options.optimisticLock === true && !stamps.version) {\n\t\tthrow new TypeError(\n\t\t\t`getCollection: optimisticLock needs a \"version\" field, and \"${name}\" has none`,\n\t\t);\n\t}\n\n\treturn {\n\t\tdefinition,\n\t\tdb,\n\t\tcollection: db.collection<any>(name),\n\t\tname,\n\t\tshape,\n\t\tstamps,\n\t\tactor: options.actor as unknown,\n\t\tsession,\n\t\tsessionOption: session ? { session } : {},\n\t\tmaxPageSize: options.maxPageSize ?? DEFAULT_MAX_PAGE_SIZE,\n\t\thasOwnId: 'id' in shape,\n\t\tparses: (options.validate ?? 'parse') === 'parse',\n\t\tsoftDeletes: options.softDelete ?? stamps.deletedAt,\n\t\ttouches: options.touchUpdatedAt ?? stamps.updatedAt,\n\t\tlocks: options.optimisticLock ?? stamps.version,\n\t};\n}\n\n/** Runs an operation, turning a MongoDB error into a `DataError`. */\nexport async function run<T>(\n\tctx: CollectionContext,\n\tfn: () => Promise<T>,\n): Promise<T> {\n\ttry {\n\t\treturn await fn();\n\t} catch (error) {\n\t\tthrow toDataError(error, { collection: ctx.name });\n\t}\n}\n\nexport function notFound(ctx: CollectionContext, id: unknown): NotFoundError {\n\treturn new NotFoundError(\n\t\t`No document in \"${ctx.name}\" with _id ${String(id)}`,\n\t\t{ collection: ctx.name, id },\n\t);\n}\n",
|
|
14
|
+
"import { ObjectId } from 'mongodb';\nimport { InvalidCursorError } from '../errors/data-error';\n\n/** What a cursor holds: the ordering values of the last document of a page. */\nexport interface CursorPayload {\n\t/** The ordering it was written for: `<field>:<asc|desc>`. */\n\treadonly key: string;\n\treadonly values: readonly unknown[];\n}\n\n/** An `ObjectId`, read without `instanceof`: two copies of the driver. */\nfunction isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n// JSON has no Date, no bigint and no ObjectId, and a cursor must give back the\n// very value it was written from: a Date compares with a date field, an\n// ObjectId with `_id`. `JSON.stringify` has already called `toJSON` by the time\n// the replacer runs, so the raw value is read off `this`.\nfunction replacer(this: Record<string, unknown>, key: string, value: unknown) {\n\tconst raw = this[key];\n\tif (raw instanceof Date) return { $date: raw.toISOString() };\n\tif (typeof raw === 'bigint') return { $bigint: raw.toString() };\n\tif (isObjectId(raw)) return { $oid: raw.toHexString() };\n\treturn value;\n}\n\nfunction reviver(_key: string, value: unknown): unknown {\n\tif (value && typeof value === 'object' && !Array.isArray(value)) {\n\t\tconst keys = Object.keys(value);\n\t\tif (keys.length === 1) {\n\t\t\tconst tagged = value as {\n\t\t\t\t$date?: unknown;\n\t\t\t\t$bigint?: unknown;\n\t\t\t\t$oid?: unknown;\n\t\t\t};\n\t\t\tif (typeof tagged.$date === 'string') return new Date(tagged.$date);\n\t\t\tif (typeof tagged.$bigint === 'string') return BigInt(tagged.$bigint);\n\t\t\tif (typeof tagged.$oid === 'string') return new ObjectId(tagged.$oid);\n\t\t}\n\t}\n\treturn value;\n}\n\nfunction toBase64Url(text: string): string {\n\tlet binary = '';\n\tfor (const byte of new TextEncoder().encode(text)) {\n\t\tbinary += String.fromCharCode(byte);\n\t}\n\treturn btoa(binary)\n\t\t.replace(/\\+/g, '-')\n\t\t.replace(/\\//g, '_')\n\t\t.replace(/=+$/, '');\n}\n\nfunction fromBase64Url(text: string): string {\n\tconst base64 = text.replace(/-/g, '+').replace(/_/g, '/');\n\tconst binary = atob(base64 + '='.repeat((4 - (base64.length % 4)) % 4));\n\treturn new TextDecoder().decode(\n\t\tUint8Array.from(binary, (char) => char.charCodeAt(0)),\n\t);\n}\n\n/**\n * Writes an opaque, URL-safe cursor. `Date`, `bigint` and `ObjectId` values\n * survive the round trip. It is encoded, not signed: a client can read it,\n * and forge one.\n */\nexport function encodeCursor(payload: CursorPayload): string {\n\treturn toBase64Url(JSON.stringify([payload.key, payload.values], replacer));\n}\n\n/**\n * Reads a cursor `encodeCursor` wrote. Throws `InvalidCursorError` for\n * anything else, and for a cursor written for another ordering when\n * `expectedKey` is given.\n */\nexport function decodeCursor(\n\tcursor: string,\n\texpectedKey?: string,\n): CursorPayload {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(fromBase64Url(cursor), reviver);\n\t} catch (cause) {\n\t\tthrow new InvalidCursorError('Invalid cursor: it cannot be decoded', {\n\t\t\tcause,\n\t\t});\n\t}\n\tif (\n\t\t!Array.isArray(parsed) ||\n\t\tparsed.length !== 2 ||\n\t\ttypeof parsed[0] !== 'string' ||\n\t\t!Array.isArray(parsed[1])\n\t) {\n\t\tthrow new InvalidCursorError('Invalid cursor: unexpected shape');\n\t}\n\tconst [key, values] = parsed as [string, unknown[]];\n\tif (expectedKey !== undefined && key !== expectedKey) {\n\t\tthrow new InvalidCursorError(\n\t\t\t`Invalid cursor: it was written for the ordering ${key}, not ${expectedKey}`,\n\t\t);\n\t}\n\treturn { key, values };\n}\n",
|
|
15
|
+
"import type { CollectionContext } from './context';\n\n/** A document as this package handles one internally: keys it cannot know. */\nexport type Fields = Record<string, unknown>;\n\nexport function isRecord(value: unknown): value is Fields {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Does this patch speak in MongoDB's operators rather than in fields? */\nexport function isUpdateFilter(patch: Fields): boolean {\n\treturn Object.keys(patch).some((key) => key.startsWith('$'));\n}\n\n/** `a` and `b`, without letting one's `$or` swallow the other's. */\nexport function mergeFilters(\n\ta: Fields | undefined,\n\tb: Fields | undefined,\n): Fields {\n\tconst left = a && Object.keys(a).length > 0 ? a : undefined;\n\tconst right = b && Object.keys(b).length > 0 ? b : undefined;\n\tif (!left) return right ?? {};\n\tif (!right) return left;\n\treturn { $and: [left, right] };\n}\n\n/** The filter that leaves soft-deleted documents out. */\nexport function live(\n\tctx: CollectionContext,\n\twithDeleted?: boolean,\n): Fields | undefined {\n\treturn ctx.softDeletes && !withDeleted ? { deletedAt: null } : undefined;\n}\n\n/** A caller's filter, narrowed to the documents this collection shows. */\nexport function scoped(\n\tctx: CollectionContext,\n\tfilter: unknown,\n\twithDeleted?: boolean,\n): Fields {\n\treturn mergeFilters(\n\t\tisRecord(filter) ? filter : undefined,\n\t\tlive(ctx, withDeleted),\n\t);\n}\n\n/** Refuses a call that would otherwise run on the whole collection. */\nexport function requireFilter(\n\tctx: CollectionContext,\n\tmethod: string,\n\tfilter: unknown,\n): void {\n\tif (!isRecord(filter) || Object.keys(filter).length === 0) {\n\t\tthrow new TypeError(\n\t\t\t`${method} needs a filter. Pass \\`{ _id: { $exists: true } }\\` to target every document of \"${ctx.name}\".`,\n\t\t);\n\t}\n}\n",
|
|
16
|
+
"import type { CollectionContext } from './context';\nimport { type Fields, isRecord, isUpdateFilter } from './filters';\n\n/**\n * `id` on a document a collection gives back: `_id` as a string, computed\n * rather than stored — the collection holds `_id` alone.\n *\n * It is enumerable, so `JSON.stringify` and a spread carry it and a handler\n * can return the document as it is. `toDocument` drops it again on a write,\n * and it is no part of `DocumentOf`, so nothing can filter on it: the server\n * would match nothing.\n */\nexport function withId<T>(ctx: CollectionContext, document: T): T {\n\tif (\n\t\tctx.hasOwnId ||\n\t\t!isRecord(document) ||\n\t\tdocument._id === undefined ||\n\t\tObject.hasOwn(document, 'id')\n\t) {\n\t\treturn document;\n\t}\n\tObject.defineProperty(document, 'id', {\n\t\tget: () => String((document as Fields)._id),\n\t\tenumerable: true,\n\t\tconfigurable: true,\n\t});\n\treturn document;\n}\n\n/** The document to insert: checked against the schema, defaults filled. */\nexport function toDocument(ctx: CollectionContext, values: unknown): Fields {\n\tconst stamped: Fields = { ...(values as Fields) };\n\t// A document that was read carries `id`, which is this collection's view\n\t// of `_id` and not a field: writing it back would be refused by the\n\t// validator, which allows no property the schema does not declare.\n\t// Parsing strips it too, but `validate: 'off'` does not parse.\n\tif (!ctx.hasOwnId) delete stamped.id;\n\tif (ctx.actor !== undefined) {\n\t\tif (ctx.stamps.createdBy && stamped.createdBy === undefined) {\n\t\t\tstamped.createdBy = ctx.actor;\n\t\t}\n\t\tif (ctx.stamps.updatedBy && stamped.updatedBy === undefined) {\n\t\t\tstamped.updatedBy = ctx.actor;\n\t\t}\n\t}\n\treturn ctx.parses\n\t\t? (ctx.definition.schema.parse(stamped) as Fields)\n\t\t: stamped;\n}\n\n/** The fields of a patch, checked one by one against the schema. */\nfunction setFromFields(ctx: CollectionContext, patch: Fields): Fields {\n\tconst set: Fields = {};\n\tfor (const [field, value] of Object.entries(patch)) {\n\t\tif (value === undefined) continue;\n\t\tconst schema = ctx.shape[field];\n\t\tif (!schema) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`update: \"${ctx.name}\" has no field \"${field}\" in its schema`,\n\t\t\t);\n\t\t}\n\t\tset[field] = ctx.parses ? schema.parse(value) : value;\n\t}\n\treturn set;\n}\n\n/**\n * The update to send: a patch of fields becomes `$set`, checked field by\n * field against the schema, with the stamps this collection keeps. A patch\n * that already speaks in operators is sent as it is, with the stamps added.\n */\nexport function toUpdate(ctx: CollectionContext, patch: unknown): Fields {\n\tif (!isRecord(patch)) {\n\t\tthrow new TypeError(\n\t\t\t`update: expected the document's fields or MongoDB's operators, not ${String(patch)}`,\n\t\t);\n\t}\n\tconst operators = isUpdateFilter(patch);\n\tconst update: Fields = operators ? { ...patch } : {};\n\tconst set: Fields = {\n\t\t...(isRecord(update.$set) ? update.$set : {}),\n\t\t...(operators ? {} : setFromFields(ctx, patch)),\n\t};\n\n\tif (ctx.touches && set.updatedAt === undefined) set.updatedAt = new Date();\n\tif (\n\t\tctx.actor !== undefined &&\n\t\tctx.stamps.updatedBy &&\n\t\tset.updatedBy === undefined\n\t) {\n\t\tset.updatedBy = ctx.actor;\n\t}\n\tif (Object.keys(set).length > 0) update.$set = set;\n\n\tif (ctx.locks) {\n\t\tconst inc = isRecord(update.$inc) ? { ...update.$inc } : {};\n\t\tinc.version = (inc.version as number | undefined) ?? 1;\n\t\tupdate.$inc = inc;\n\t}\n\treturn update;\n}\n",
|
|
17
|
+
"import { type CollectionContext, notFound, run } from './context';\nimport { withId } from './documents';\nimport { type Fields, scoped } from './filters';\n\n/** One document, straight from the driver, carrying its computed `id`. */\nexport function findOne(\n\tctx: CollectionContext,\n\tfilter: Fields,\n\tprojection?: unknown,\n): Promise<Fields | null> {\n\treturn run(ctx, async () => {\n\t\tconst found = await ctx.collection.findOne(filter, {\n\t\t\t...ctx.sessionOption,\n\t\t\t...(projection ? { projection } : {}),\n\t\t});\n\t\treturn found === null ? null : withId(ctx, found as Fields);\n\t});\n}\n\nexport async function findById(\n\tctx: CollectionContext,\n\tid: unknown,\n\topts: { withDeleted?: boolean } = {},\n): Promise<Fields | undefined> {\n\tconst found = await findOne(ctx, scoped(ctx, { _id: id }, opts.withDeleted));\n\treturn found ?? undefined;\n}\n\nexport async function getById(\n\tctx: CollectionContext,\n\tid: unknown,\n\topts: { withDeleted?: boolean } = {},\n): Promise<Fields> {\n\tconst found = await findById(ctx, id, opts);\n\tif (!found) throw notFound(ctx, id);\n\treturn found;\n}\n\nexport async function findMany(\n\tctx: CollectionContext,\n\topts: Fields = {},\n): Promise<Fields[]> {\n\treturn run(ctx, async () => {\n\t\tlet cursor = ctx.collection.find(\n\t\t\tscoped(ctx, opts.filter, opts.withDeleted as boolean | undefined),\n\t\t\t{\n\t\t\t\t...ctx.sessionOption,\n\t\t\t\t...(opts.projection ? { projection: opts.projection } : {}),\n\t\t\t},\n\t\t);\n\t\tif (opts.sort !== undefined) cursor = cursor.sort(opts.sort as never);\n\t\tif (opts.skip !== undefined) cursor = cursor.skip(opts.skip as number);\n\t\tif (opts.limit !== undefined) cursor = cursor.limit(opts.limit as number);\n\t\tconst found = await cursor.toArray();\n\t\treturn found.map((document) => withId(ctx, document as Fields));\n\t});\n}\n\nexport async function findFirst(\n\tctx: CollectionContext,\n\tfilter?: unknown,\n\topts: Fields = {},\n): Promise<Fields | undefined> {\n\tconst [first] = await findMany(ctx, { ...opts, filter, limit: 1 });\n\treturn first;\n}\n\nexport async function countDocuments(\n\tctx: CollectionContext,\n\tfilter?: unknown,\n\topts: { withDeleted?: boolean } = {},\n): Promise<number> {\n\treturn run(ctx, async () =>\n\t\tctx.collection.countDocuments(scoped(ctx, filter, opts.withDeleted), {\n\t\t\t...ctx.sessionOption,\n\t\t}),\n\t);\n}\n\nexport async function exists(\n\tctx: CollectionContext,\n\tfilter: unknown,\n\topts: { withDeleted?: boolean } = {},\n): Promise<boolean> {\n\tconst found = await findOne(ctx, scoped(ctx, filter, opts.withDeleted), {\n\t\t_id: 1,\n\t});\n\treturn found !== null && found !== undefined;\n}\n",
|
|
18
|
+
"import { DataError } from '../errors/data-error';\nimport { decodeCursor, encodeCursor } from '../pagination/cursor';\nimport {\n\ttype CursorPage,\n\tcursorLimit,\n\ttype Page,\n\tpageWindow,\n\ttoPage,\n} from '../pagination/page';\nimport type { CollectionContext } from './context';\nimport { type Fields, isRecord, mergeFilters } from './filters';\nimport { countDocuments, findMany } from './reads';\nimport type { OrderDirection } from './types';\n\nexport async function paginate(\n\tctx: CollectionContext,\n\topts: Fields = {},\n): Promise<Page<Fields>> {\n\tconst window = pageWindow(opts, ctx.maxPageSize);\n\tconst [items, total] = await Promise.all([\n\t\tfindMany(ctx, {\n\t\t\tfilter: opts.filter,\n\t\t\tsort: opts.sort ?? { _id: 1 },\n\t\t\tlimit: window.limit,\n\t\t\tskip: window.skip,\n\t\t\twithDeleted: opts.withDeleted,\n\t\t}),\n\t\tcountDocuments(ctx, opts.filter, {\n\t\t\twithDeleted: opts.withDeleted as boolean | undefined,\n\t\t}),\n\t]);\n\treturn toPage(items, total, window);\n}\n\nexport async function paginateByCursor(\n\tctx: CollectionContext,\n\topts: Fields = {},\n): Promise<CursorPage<Fields>> {\n\tconst sortField = (opts.orderBy as string | undefined) ?? '_id';\n\tif (!ctx.shape[sortField] && sortField !== '_id') {\n\t\tthrow new TypeError(\n\t\t\t`paginateByCursor: \"${ctx.name}\" has no field \"${sortField}\" in its schema`,\n\t\t);\n\t}\n\tconst direction = (opts.direction as OrderDirection | undefined) ?? 'asc';\n\tconst fields = sortField === '_id' ? ['_id'] : [sortField, '_id'];\n\tconst cursorKey = `${sortField}:${direction}`;\n\tconst limit = cursorLimit(opts.limit as number | undefined, ctx.maxPageSize);\n\tconst past = direction === 'asc' ? '$gt' : '$lt';\n\n\tlet after: Fields | undefined;\n\tif (opts.after) {\n\t\tconst { values } = decodeCursor(opts.after as string, cursorKey);\n\t\tif (values.length !== fields.length) {\n\t\t\tthrow new DataError(\n\t\t\t\t`Invalid cursor: expected ${fields.length} value(s), got ${values.length}`,\n\t\t\t\t{ collection: ctx.name },\n\t\t\t);\n\t\t}\n\t\t// `a > x OR (a = x AND b > y)`, the keyset of the ordering.\n\t\tafter = {\n\t\t\t$or: fields.map((field, index) => ({\n\t\t\t\t...Object.fromEntries(\n\t\t\t\t\tfields.slice(0, index).map((previous, i) => [previous, values[i]]),\n\t\t\t\t),\n\t\t\t\t[field]: { [past]: values[index] },\n\t\t\t})),\n\t\t};\n\t}\n\n\tconst sort = Object.fromEntries(\n\t\tfields.map((field) => [field, direction === 'asc' ? 1 : -1]),\n\t);\n\tconst documents = await findMany(ctx, {\n\t\tfilter: mergeFilters(\n\t\t\tisRecord(opts.filter) ? opts.filter : undefined,\n\t\t\tafter,\n\t\t),\n\t\tsort,\n\t\tlimit: limit + 1,\n\t\twithDeleted: opts.withDeleted,\n\t});\n\n\tconst items = documents.slice(0, limit);\n\tconst last = items.at(-1);\n\tif (documents.length <= limit || !last) {\n\t\treturn { items, nextCursor: null };\n\t}\n\n\tconst values = fields.map((field) => {\n\t\tconst value = last[field];\n\t\tif (value === null || value === undefined) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`paginateByCursor: \"${field}\" is null in a document of \"${ctx.name}\". ` +\n\t\t\t\t\t'Page along a field every document has.',\n\t\t\t);\n\t\t}\n\t\treturn value;\n\t});\n\treturn { items, nextCursor: encodeCursor({ key: cursorKey, values }) };\n}\n",
|
|
19
|
+
"import type { Document } from 'mongodb';\nimport { OptimisticLockError } from '../errors/data-error';\nimport { type CollectionContext, notFound, run } from './context';\nimport { toDocument, toUpdate, withId } from './documents';\nimport {\n\ttype Fields,\n\tlive,\n\tmergeFilters,\n\trequireFilter,\n\tscoped,\n} from './filters';\nimport { findOne } from './reads';\n\n/**\n * `findOneAndUpdate` answers `null` for a document that is not there, one\n * that is soft-deleted, and one whose version moved. Only a second read\n * tells them apart.\n */\nasync function updatedOrThrow(\n\tctx: CollectionContext,\n\tid: unknown,\n\tfilter: Fields,\n\tupdate: Fields,\n\texpectedVersion: number | undefined,\n): Promise<Fields> {\n\tconst updated = await run(ctx, async () =>\n\t\tctx.collection.findOneAndUpdate(filter, update, {\n\t\t\t...ctx.sessionOption,\n\t\t\treturnDocument: 'after',\n\t\t}),\n\t);\n\tif (updated) return withId(ctx, updated as Fields);\n\n\tif (expectedVersion !== undefined) {\n\t\tconst current = await findOne(ctx, { _id: id });\n\t\tif (current) {\n\t\t\tthrow new OptimisticLockError(\n\t\t\t\t`Document ${String(id)} of \"${ctx.name}\" is at version ${String(\n\t\t\t\t\tcurrent.version,\n\t\t\t\t)}, not ${expectedVersion}: it changed since it was read`,\n\t\t\t\t{\n\t\t\t\t\tcollection: ctx.name,\n\t\t\t\t\tid,\n\t\t\t\t\texpectedVersion,\n\t\t\t\t\tactualVersion:\n\t\t\t\t\t\ttypeof current.version === 'number' ? current.version : undefined,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\tthrow notFound(ctx, id);\n}\n\n/** What a soft delete writes: the stamps, and the lock if there is one. */\nfunction softDeleteUpdate(ctx: CollectionContext): Fields {\n\tconst set: Fields = { deletedAt: new Date() };\n\tif (ctx.actor !== undefined && ctx.stamps.deletedBy) {\n\t\tset.deletedBy = ctx.actor;\n\t}\n\tconst update: Fields = { $set: set };\n\tif (ctx.locks) update.$inc = { version: 1 };\n\treturn update;\n}\n\nexport async function create(\n\tctx: CollectionContext,\n\tvalues: unknown,\n): Promise<Fields> {\n\tconst document = toDocument(ctx, values);\n\treturn run(ctx, async () => {\n\t\tawait ctx.collection.insertOne(document as Document, {\n\t\t\t...ctx.sessionOption,\n\t\t});\n\t\treturn withId(ctx, document);\n\t});\n}\n\nexport async function createMany(\n\tctx: CollectionContext,\n\tvalues: readonly unknown[],\n): Promise<Fields[]> {\n\tif (values.length === 0) return [];\n\tconst documents = values.map((value) => toDocument(ctx, value));\n\treturn run(ctx, async () => {\n\t\tawait ctx.collection.insertMany(documents as Document[], {\n\t\t\t...ctx.sessionOption,\n\t\t});\n\t\treturn documents.map((document) => withId(ctx, document));\n\t});\n}\n\nexport async function update(\n\tctx: CollectionContext,\n\tid: unknown,\n\tpatch: unknown,\n\topts: Fields = {},\n): Promise<Fields> {\n\tconst expectedVersion = opts.expectedVersion as number | undefined;\n\tif (expectedVersion !== undefined && !ctx.locks) {\n\t\tthrow new TypeError(\n\t\t\t`update: expectedVersion needs a \"version\" field, and \"${ctx.name}\" has none`,\n\t\t);\n\t}\n\tconst patched = toUpdate(ctx, patch);\n\tconst filter = mergeFilters(\n\t\t{\n\t\t\t_id: id,\n\t\t\t...(expectedVersion === undefined ? {} : { version: expectedVersion }),\n\t\t},\n\t\tlive(ctx),\n\t);\n\treturn updatedOrThrow(ctx, id, filter, patched, expectedVersion);\n}\n\nexport async function updateMany(\n\tctx: CollectionContext,\n\tfilter: unknown,\n\tpatch: unknown,\n): Promise<number> {\n\trequireFilter(ctx, 'updateMany', filter);\n\tconst patched = toUpdate(ctx, patch);\n\treturn run(ctx, async () => {\n\t\tconst result = await ctx.collection.updateMany(\n\t\t\tscoped(ctx, filter),\n\t\t\tpatched,\n\t\t\t{ ...ctx.sessionOption },\n\t\t);\n\t\treturn result.modifiedCount;\n\t});\n}\n\nexport async function hardDelete(\n\tctx: CollectionContext,\n\tid: unknown,\n): Promise<Fields> {\n\tconst deleted = await run(ctx, async () =>\n\t\tctx.collection.findOneAndDelete({ _id: id }, { ...ctx.sessionOption }),\n\t);\n\tif (!deleted) throw notFound(ctx, id);\n\treturn withId(ctx, deleted as Fields);\n}\n\nexport async function hardDeleteMany(\n\tctx: CollectionContext,\n\tfilter: unknown,\n): Promise<number> {\n\trequireFilter(ctx, 'hardDeleteMany', filter);\n\treturn run(ctx, async () => {\n\t\tconst result = await ctx.collection.deleteMany(filter as Fields, {\n\t\t\t...ctx.sessionOption,\n\t\t});\n\t\treturn result.deletedCount;\n\t});\n}\n\nexport async function deleteOne(\n\tctx: CollectionContext,\n\tid: unknown,\n): Promise<Fields> {\n\tif (!ctx.softDeletes) return hardDelete(ctx, id);\n\treturn updatedOrThrow(\n\t\tctx,\n\t\tid,\n\t\tmergeFilters({ _id: id }, live(ctx)),\n\t\tsoftDeleteUpdate(ctx),\n\t\tundefined,\n\t);\n}\n\nexport async function deleteMany(\n\tctx: CollectionContext,\n\tfilter: unknown,\n): Promise<number> {\n\trequireFilter(ctx, 'deleteMany', filter);\n\tif (!ctx.softDeletes) return hardDeleteMany(ctx, filter);\n\treturn run(ctx, async () => {\n\t\tconst result = await ctx.collection.updateMany(\n\t\t\tscoped(ctx, filter),\n\t\t\tsoftDeleteUpdate(ctx),\n\t\t\t{ ...ctx.sessionOption },\n\t\t);\n\t\treturn result.modifiedCount;\n\t});\n}\n\nexport async function restore(\n\tctx: CollectionContext,\n\tid: unknown,\n): Promise<Fields> {\n\tif (!ctx.stamps.deletedAt) {\n\t\tthrow new TypeError(`restore: \"${ctx.name}\" has no soft delete`);\n\t}\n\tconst set: Fields = { deletedAt: null };\n\tif (ctx.stamps.deletedBy) set.deletedBy = null;\n\tif (ctx.touches) set.updatedAt = new Date();\n\tconst update: Fields = { $set: set };\n\tif (ctx.locks) update.$inc = { version: 1 };\n\treturn updatedOrThrow(ctx, id, { _id: id }, update, undefined);\n}\n",
|
|
20
|
+
"import type { ClientSession, Db, MongoClient } from 'mongodb';\nimport type { z } from 'zod';\nimport type {\n\tAnyCollectionDefinition,\n\tCollectionDefinition,\n} from '../definition/define-collection';\nimport { type SyncOptions, syncCollection } from '../sync/sync-collection';\nimport { type CollectionContext, createContext } from './context';\nimport type { Fields } from './filters';\nimport { paginate, paginateByCursor } from './paginate';\nimport {\n\tcountDocuments,\n\texists,\n\tfindById,\n\tfindFirst,\n\tfindMany,\n\tgetById,\n} from './reads';\nimport type { CollectionOptions, TypedCollection } from './types';\nimport {\n\tcreate,\n\tcreateMany,\n\tdeleteMany,\n\tdeleteOne,\n\thardDelete,\n\thardDeleteMany,\n\trestore,\n\tupdate,\n\tupdateMany,\n} from './writes';\n\n/** What a collection can be reached through: a database, or a client. */\nexport type CollectionSource = Db | MongoClient;\n\n/**\n * A `Db`, from either. A client is told from a database by its `db` method,\n * not by `instanceof`, which answers `false` across two copies of the driver.\n */\nfunction databaseOf(source: CollectionSource, name: string | undefined): Db {\n\tconst client = source as MongoClient;\n\tif (typeof client.db === 'function') return client.db(name);\n\tconst db = source as Db;\n\tif (name !== undefined && db.databaseName !== name) {\n\t\tthrow new TypeError(\n\t\t\t`getCollection: given a Db for \"${db.databaseName}\", and a db option of ` +\n\t\t\t\t`\"${name}\". Pass the client, or the database you mean.`,\n\t\t);\n\t}\n\treturn db;\n}\n\n/**\n * A collection: this package's methods and the driver's own, on one object.\n *\n * ```ts\n * const users = getCollection(db, usersDefinition);\n *\n * const ada = await users.create({ email: 'ada@example.com' });\n * await users.update(ada._id, { name: 'Ada' }, { expectedVersion: ada.version });\n * await users.aggregate([{ $group: { _id: '$teamId', n: { $sum: 1 } } }]);\n * ```\n *\n * It takes a `Db`, or a `MongoClient` — then the database is the URI's, or the\n * one named in `{ db }`.\n *\n * Every operation runs in the collection's session, which `withSession` sets:\n * MongoDB has no ambient session, so a write inside a transaction that was not\n * given one is not part of it and is not rolled back.\n */\nexport function getCollection<Schema extends z.ZodObject>(\n\tsource: CollectionSource,\n\tdefinition: CollectionDefinition<Schema>,\n\toptions: CollectionOptions<CollectionDefinition<Schema>> = {},\n): TypedCollection<CollectionDefinition<Schema>> {\n\tconst db = databaseOf(source, options.db);\n\treturn build(db, definition, options as CollectionOptions<never>);\n}\n\n/**\n * This package's methods, bound to a context. Each one lives in `reads`,\n * `writes` or `paginate`; this is only the surface they are reached by.\n */\nfunction apiOf(ctx: CollectionContext, rebuild: Rebuild) {\n\treturn {\n\t\tdefinition: ctx.definition,\n\t\tdb: ctx.db,\n\t\traw: ctx.collection,\n\t\tsession: ctx.session,\n\n\t\twithSession: (other: ClientSession | undefined) =>\n\t\t\trebuild({ session: other }),\n\t\tas: (who: unknown) => rebuild({ actor: who as never }),\n\t\tsync: (syncOptions: SyncOptions = {}) =>\n\t\t\tsyncCollection(ctx.db, ctx.definition, {\n\t\t\t\t...ctx.sessionOption,\n\t\t\t\t...syncOptions,\n\t\t\t}),\n\n\t\tfindById: (id: unknown, opts?: { withDeleted?: boolean }) =>\n\t\t\tfindById(ctx, id, opts),\n\t\tgetById: (id: unknown, opts?: { withDeleted?: boolean }) =>\n\t\t\tgetById(ctx, id, opts),\n\t\tfindFirst: (filter?: unknown, opts?: Fields) =>\n\t\t\tfindFirst(ctx, filter, opts),\n\t\tfindMany: (opts?: Fields) => findMany(ctx, opts),\n\n\t\tcreate: (values: unknown) => create(ctx, values),\n\t\tcreateMany: (values: readonly unknown[]) => createMany(ctx, values),\n\t\tupdate: (id: unknown, patch: unknown, opts?: Fields) =>\n\t\t\tupdate(ctx, id, patch, opts),\n\t\tupdateMany: (filter: unknown, patch: unknown) =>\n\t\t\tupdateMany(ctx, filter, patch),\n\n\t\tdelete: (id: unknown) => deleteOne(ctx, id),\n\t\tdeleteMany: (filter: unknown) => deleteMany(ctx, filter),\n\t\thardDelete: (id: unknown) => hardDelete(ctx, id),\n\t\thardDeleteMany: (filter: unknown) => hardDeleteMany(ctx, filter),\n\t\trestore: (id: unknown) => restore(ctx, id),\n\n\t\tcount: (filter?: unknown, opts?: { withDeleted?: boolean }) =>\n\t\t\tcountDocuments(ctx, filter, opts),\n\t\texists: (filter: unknown, opts?: { withDeleted?: boolean }) =>\n\t\t\texists(ctx, filter, opts),\n\t\tpaginate: (opts?: Fields) => paginate(ctx, opts),\n\t\tpaginateByCursor: (opts?: Fields) => paginateByCursor(ctx, opts),\n\t};\n}\n\n/**\n * The same collection with one option changed, as `withSession` and `as`\n * give it back. It answers `unknown` because the collection this package\n * hands out is typed by the cast at the end of `build`, not by `apiOf`.\n */\ntype Rebuild = (changed: Partial<CollectionOptions<never>>) => unknown;\n\nfunction build<Def>(\n\tdb: Db,\n\tdefinition: AnyCollectionDefinition,\n\toptions: CollectionOptions<never>,\n): TypedCollection<Def> {\n\tconst ctx = createContext(db, definition, options);\n\tconst rebuild: Rebuild = (changed) =>\n\t\tbuild(db, definition, { ...options, ...changed });\n\tconst api = apiOf(ctx, rebuild);\n\tconst collection = ctx.collection;\n\n\t/**\n\t * This package's methods first, the driver's collection behind them. A\n\t * name both define — `count`, `updateMany`, `deleteMany` — is this\n\t * package's; the driver's is on `raw`.\n\t *\n\t * A proxy rather than a copy, so that a method the driver gains is on the\n\t * collection without this package being republished.\n\t */\n\treturn new Proxy(api, {\n\t\tget(target, key, receiver) {\n\t\t\tif (Reflect.has(target, key)) return Reflect.get(target, key, receiver);\n\t\t\tconst value = (collection as unknown as Fields)[key as string];\n\t\t\treturn typeof value === 'function' ? value.bind(collection) : value;\n\t\t},\n\t\thas(target, key) {\n\t\t\treturn Reflect.has(target, key) || key in (collection as object);\n\t\t},\n\t}) as unknown as TypedCollection<Def>;\n}\n",
|
|
21
|
+
"import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { isObjectId } from './object-id';\n\n/**\n * An `ObjectId`, declared to MongoDB as `bsonType: 'objectId'`. JSON Schema\n * has no type for one, so the metadata is how the validator learns of it.\n */\nexport function objectId() {\n\treturn z\n\t\t.custom<ObjectId>(isObjectId, { error: 'must be an ObjectId' })\n\t\t.meta({ bsonType: 'objectId' });\n}\n\n/**\n * `_id`, filled with a new `ObjectId` when a document is created: optional to\n * write, always there once read.\n */\nexport function id() {\n\treturn objectId().default(() => new ObjectId());\n}\n\n/**\n * `createdAt` and `updatedAt`, filled on create. A collection sets `updatedAt`\n * on every update.\n */\nexport function timestamps() {\n\treturn {\n\t\tcreatedAt: z.date().default(() => new Date()),\n\t\tupdatedAt: z.date().default(() => new Date()),\n\t};\n}\n\n/**\n * `deletedAt`, `null` while the document is live. A collection on a collection\n * with it soft-deletes, and leaves deleted documents out of every read.\n */\nexport function softDelete() {\n\treturn { deletedAt: z.date().nullable().default(null) };\n}\n\n/**\n * `version`, raised by one on every update. A collection with it takes\n * `expectedVersion` and throws `OptimisticLockError` when it no longer\n * matches.\n */\nexport function optimisticLock() {\n\treturn { version: z.int().nonnegative().default(0) };\n}\n\n/**\n * `createdBy`, `updatedBy` and `deletedBy`, stamped from the actor a\n * collection was given with `as(actor)`. The actor's own type is the schema\n * passed in, an `ObjectId` by default.\n */\nexport function actors<Actor extends z.ZodType = ReturnType<typeof objectId>>(\n\tactor: Actor = objectId() as unknown as Actor,\n) {\n\treturn {\n\t\tcreatedBy: actor.nullable().default(null),\n\t\tupdatedBy: actor.nullable().default(null),\n\t\tdeletedBy: actor.nullable().default(null),\n\t};\n}\n\n/** The fields the collection gives a meaning to, by name. */\nexport const STAMP_FIELDS = {\n\tid: '_id',\n\tcreatedAt: 'createdAt',\n\tupdatedAt: 'updatedAt',\n\tdeletedAt: 'deletedAt',\n\tversion: 'version',\n\tcreatedBy: 'createdBy',\n\tupdatedBy: 'updatedBy',\n\tdeletedBy: 'deletedBy',\n} as const;\n",
|
|
22
|
+
"import { ObjectId } from 'mongodb';\nimport { z } from 'zod';\nimport { InvalidIdError } from '../errors/data-error';\n\n/** The 24 hex characters an `ObjectId` is written as. */\nconst HEX_24 = /^[0-9a-fA-F]{24}$/;\n\n/**\n * An `ObjectId`, read by its BSON tag rather than with `instanceof`, which\n * answers `false` across two copies of the driver in one tree.\n */\nexport function isObjectId(value: unknown): value is ObjectId {\n\treturn (\n\t\ttypeof value === 'object' &&\n\t\tvalue !== null &&\n\t\t(value as { _bsontype?: unknown })._bsontype === 'ObjectId'\n\t);\n}\n\n/** Is this the 24-character hex string an `ObjectId` is written as? */\nexport function isObjectIdString(value: unknown): value is string {\n\treturn typeof value === 'string' && HEX_24.test(value);\n}\n\n/** An `ObjectId`, or a string that stands for one. */\nexport function isValidObjectId(value: unknown): boolean {\n\treturn isObjectId(value) || isObjectIdString(value);\n}\n\n/**\n * The `ObjectId` this value stands for, or `undefined`. Never throws.\n *\n * Prefer it to `new ObjectId(value)`, which **invents a fresh id** when it is\n * given `null` or `undefined` — a missing route parameter then reads as a\n * perfectly valid id that matches nothing.\n */\nexport function tryObjectId(value: unknown): ObjectId | undefined {\n\tif (isObjectId(value)) return value;\n\tif (isObjectIdString(value)) return ObjectId.createFromHexString(value);\n\treturn undefined;\n}\n\nfunction describe(value: unknown): string {\n\tif (value === null) return 'null';\n\tif (value === undefined) return 'undefined';\n\tif (typeof value === 'string') return `the string ${JSON.stringify(value)}`;\n\treturn `a ${typeof value}`;\n}\n\n/**\n * The `ObjectId` this value stands for. Throws `InvalidIdError` for anything\n * else, `null` and `undefined` included.\n *\n * ```ts\n * const user = await users.getById(toObjectId(request.params.id));\n * ```\n */\nexport function toObjectId(value: unknown, field = '_id'): ObjectId {\n\tconst made = tryObjectId(value);\n\tif (made) return made;\n\tthrow new InvalidIdError(\n\t\t`${field}: expected an ObjectId or its 24-character hex string, got ${describe(value)}`,\n\t\t{ id: value, keys: [field] },\n\t);\n}\n\n/**\n * The same, for a list — a `$in` filter built from query parameters.\n *\n * ```ts\n * await users.findMany({ filter: { _id: { $in: toObjectIds(ids) } } });\n * ```\n */\nexport function toObjectIds(\n\tvalues: Iterable<unknown>,\n\tfield = '_id',\n): ObjectId[] {\n\treturn [...values].map((value) => toObjectId(value, field));\n}\n\n/**\n * A Zod schema for an id that arrives from outside: it takes an `ObjectId` or\n * its hex string and gives back an `ObjectId`.\n *\n * It belongs in the schema of a route's parameters, **not** in a collection's:\n * a field that parses one type into another has no honest `$jsonSchema`, and\n * what a collection stores is `objectId()`.\n *\n * ```ts\n * const params = z.object({ id: objectIdParam() });\n * const { id } = params.parse(request.params); // ObjectId\n * ```\n */\nexport function objectIdParam() {\n\treturn z\n\t\t.custom<ObjectId | string>(isValidObjectId, {\n\t\t\terror: 'must be an ObjectId or its 24-character hex string',\n\t\t})\n\t\t.transform((value) => toObjectId(value));\n}\n",
|
|
23
|
+
"import type { ClientSession, MongoClient, TransactionOptions } from 'mongodb';\nimport { toDataError } from '../errors/to-data-error';\n\n/** What a transaction can be started from: a client, or a session. */\nexport type TransactionHost = MongoClient | ClientSession;\n\n/** A session, read without `instanceof`: two copies of the driver. */\nfunction isSession(host: TransactionHost): host is ClientSession {\n\treturn typeof (host as ClientSession).inTransaction === 'function';\n}\n\n/**\n * Runs `fn` in a transaction: committed when it resolves, aborted when it\n * throws, and a MongoDB error turned into a `DataError` on the way out. The\n * session is the argument, and **every operation inside has to be given it**:\n * MongoDB has no ambient session, so an operation without one runs outside the\n * transaction and is not rolled back. `collection.withSession(session)` is how\n * a collection takes it.\n *\n * ```ts\n * await withTransaction(client, async (session) => {\n * \tconst team = await teams.withSession(session).create({ name: 'Core' });\n * \tawait users.withSession(session).update(userId, { teamId: team._id });\n * });\n * ```\n *\n * Given a session that is already in a transaction, it **joins** it: `fn` runs\n * with that session and nothing is committed until the outer one commits.\n * MongoDB has no savepoints, so an inner failure cannot be rolled back on its\n * own, and starting a second transaction on one session throws\n * `MongoTransactionError`.\n *\n * Two things the driver does that are easy to be surprised by:\n *\n * - it **retries `fn`** from the start on a `TransientTransactionError`, and\n * the commit alone on an `UnknownTransactionCommitResult`, until 120 seconds\n * have passed. `fn` must therefore be safe to run twice.\n * - `session.abortTransaction()` inside `fn` ends the transaction without\n * throwing: `withTransaction` then resolves.\n */\nexport async function withTransaction<T>(\n\thost: TransactionHost,\n\tfn: (session: ClientSession) => Promise<T>,\n\toptions?: TransactionOptions,\n): Promise<T> {\n\ttry {\n\t\tif (isSession(host)) {\n\t\t\tif (host.inTransaction()) {\n\t\t\t\tif (options) {\n\t\t\t\t\tthrow new TypeError(\n\t\t\t\t\t\t'withTransaction: this session is already in a transaction, which ' +\n\t\t\t\t\t\t\t'this call joins. MongoDB has no savepoints, so the read ' +\n\t\t\t\t\t\t\t'concern, the write concern and the read preference are the ' +\n\t\t\t\t\t\t\t'outer transaction’s.',\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn await fn(host);\n\t\t\t}\n\t\t\treturn await host.withTransaction(fn, options);\n\t\t}\n\n\t\tconst session = host.startSession();\n\t\ttry {\n\t\t\treturn await session.withTransaction(fn, options);\n\t\t} finally {\n\t\t\tawait session.endSession();\n\t\t}\n\t} catch (error) {\n\t\tthrow toDataError(error);\n\t}\n}\n"
|
|
18
24
|
],
|
|
19
|
-
"mappings": ";AA6HO,SAAS,gBAA4C,CAC3D,QAC+B;AAAA,EAC/B,IAAI,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IACpC,MAAM,IAAI,UACT,sBAAsB,OAAO,oCAC5B,uEACA,yBACF;AAAA,EACD;AAAA,EACA,OAAO,OAAO,OAAO;AAAA,OACjB;AAAA,IACH,SAAS,OAAO,OAAO,CAAC,GAAI,OAAO,WAAW,CAAC,CAAE,CAAC;AAAA,IAClD,YAAY,OAAO,OAAO;AAAA,MACzB,OAAO,OAAO,YAAY,SAAS;AAAA,MACnC,QAAQ,OAAO,YAAY,UAAU;AAAA,IACtC,CAAC;AAAA,EACF,CAAC;AAAA;AAIK,SAAS,QAAQ,CAAC,YAQvB;AAAA,EACD,MAAM,QAAQ,WAAW,OAAO;AAAA,EAChC,MAAM,MAAM,CAAC,UAAiB,QAAQ;AAAA,EACtC,OAAO;AAAA,IACN,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,IAC1B,SAAS,IAAI,SAAS;AAAA,IACtB,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,EAC3B;AAAA;;ACrKD,qBAAS;AACT,cAAS;;;ACDT;AACA;;;ACoDO,MAAM,kBAAkB,MAAM;AAAA,EAcpC,WAAW,CAAC,UAAU,kBAAkB,UAA4B,CAAC,GAAG;AAAA,IACvE,MACC,SACA,QAAQ,UAAU,YAAY,YAAY,EAAE,OAAO,QAAQ,MAAM,CAClE;AAAA,IAjBQ,YAAO;AAAA,IACP,YAAsB;AAAA,IAiB9B,KAAK,aAAa,QAAQ;AAAA,IAC1B,KAAK,KAAK,QAAQ;AAAA,IAClB,KAAK,aAAa,QAAQ;AAAA,IAC1B,KAAK,iBAAiB,QAAQ;AAAA,IAC9B,KAAK,QAAQ,QAAQ;AAAA,IACrB,KAAK,OAAO,QAAQ,QAAQ,CAAC;AAAA,IAC7B,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,SAAS,QAAQ,UAAU,CAAC;AAAA,IACjC,KAAK,kBAAkB,QAAQ;AAAA,IAC/B,KAAK,gBAAgB,QAAQ;AAAA;AAE/B;AAAA;AAGO,MAAM,sBAAsB,UAAU;AAAA,EAI5C,WAAW,CAAC,UAAU,aAAa,UAA4B,CAAC,GAAG;AAAA,IAClE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AAGO,MAAM,sBAAsB,UAAU;AAAA,EAI5C,WAAW,CAAC,UAAU,iBAAiB,UAA4B,CAAC,GAAG;AAAA,IACtE,MAAM,SAAS,EAAE,YAAY,UAAU,QAAQ,CAAC;AAAA,IAJxC,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AAGO,MAAM,wBAAwB,UAAU;AAAA,EAI9C,WAAW,CACV,UAAU,8BACV,UAA4B,CAAC,GAC5B;AAAA,IACD,MAAM,SAAS,EAAE,YAAY,QAAQ,QAAQ,CAAC;AAAA,IAPtC,YAAO;AAAA,IACE,YAAO;AAAA;AAQ1B;AAAA;AAMO,MAAM,4BAA4B,UAAU;AAAA,EAIlD,WAAW,CAAC,UAAU,oBAAoB,UAA4B,CAAC,GAAG;AAAA,IACzE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AASO,MAAM,uBAAuB,UAAU;AAAA,EAI7C,WAAW,CAAC,UAAU,cAAc,UAA4B,CAAC,GAAG;AAAA,IACnE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AAGO,MAAM,2BAA2B,UAAU;AAAA,EAIjD,WAAW,CAAC,UAAU,kBAAkB,UAA4B,CAAC,GAAG;AAAA,IACvE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;;;ADtJA,IAAM,SAAS;AAMR,SAAS,UAAU,CAAC,OAAmC;AAAA,EAC7D,OACC,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,cAAc;AAAA;AAK5C,SAAS,gBAAgB,CAAC,OAAiC;AAAA,EACjE,OAAO,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK;AAAA;AAI/C,SAAS,eAAe,CAAC,OAAyB;AAAA,EACxD,OAAO,WAAW,KAAK,KAAK,iBAAiB,KAAK;AAAA;AAU5C,SAAS,WAAW,CAAC,OAAsC;AAAA,EACjE,IAAI,WAAW,KAAK;AAAA,IAAG,OAAO;AAAA,EAC9B,IAAI,iBAAiB,KAAK;AAAA,IAAG,OAAO,SAAS,oBAAoB,KAAK;AAAA,EACtE;AAAA;AAGD,SAAS,QAAQ,CAAC,OAAwB;AAAA,EACzC,IAAI,UAAU;AAAA,IAAM,OAAO;AAAA,EAC3B,IAAI,UAAU;AAAA,IAAW,OAAO;AAAA,EAChC,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,cAAc,KAAK,UAAU,KAAK;AAAA,EACxE,OAAO,KAAK,OAAO;AAAA;AAWb,SAAS,UAAU,CAAC,OAAgB,QAAQ,OAAiB;AAAA,EACnE,MAAM,OAAO,YAAY,KAAK;AAAA,EAC9B,IAAI;AAAA,IAAM,OAAO;AAAA,EACjB,MAAM,IAAI,eACT,GAAG,mEAAmE,SAAS,KAAK,KACpF,EAAE,IAAI,OAAO,MAAM,CAAC,KAAK,EAAE,CAC5B;AAAA;AAUM,SAAS,WAAW,CAC1B,QACA,QAAQ,OACK;AAAA,EACb,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,OAAO,KAAK,CAAC;AAAA;AAgBpD,SAAS,aAAa,GAAG;AAAA,EAC/B,OAAO,EACL,OAA0B,iBAAiB;AAAA,IAC3C,OAAO;AAAA,EACR,CAAC,EACA,UAAU,CAAC,UAAU,WAAW,KAAK,CAAC;AAAA;;;AD1FlC,SAAS,QAAQ,GAAG;AAAA,EAC1B,OAAO,GACL,OAAiB,YAAY,EAAE,OAAO,sBAAsB,CAAC,EAC7D,KAAK,EAAE,UAAU,WAAW,CAAC;AAAA;AAOzB,SAAS,EAAE,GAAG;AAAA,EACpB,OAAO,SAAS,EAAE,QAAQ,MAAM,IAAI,SAAU;AAAA;AAOxC,SAAS,UAAU,GAAG;AAAA,EAC5B,OAAO;AAAA,IACN,WAAW,GAAE,KAAK,EAAE,QAAQ,MAAM,IAAI,IAAM;AAAA,IAC5C,WAAW,GAAE,KAAK,EAAE,QAAQ,MAAM,IAAI,IAAM;AAAA,EAC7C;AAAA;AAOM,SAAS,UAAU,GAAG;AAAA,EAC5B,OAAO,EAAE,WAAW,GAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE;AAAA;AAQhD,SAAS,cAAc,GAAG;AAAA,EAChC,OAAO,EAAE,SAAS,GAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;AAAA;AAQ7C,SAAS,MAA6D,CAC5E,QAAe,SAAS,GACvB;AAAA,EACD,OAAO;AAAA,IACN,WAAW,MAAM,SAAS,EAAE,QAAQ,IAAI;AAAA,IACxC,WAAW,MAAM,SAAS,EAAE,QAAQ,IAAI;AAAA,IACxC,WAAW,MAAM,SAAS,EAAE,QAAQ,IAAI;AAAA,EACzC;AAAA;AAIM,IAAM,eAAe;AAAA,EAC3B,IAAI;AAAA,EACJ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AACZ;;AG3EA,cAAS;AAOF,IAAM,6BAAkD,IAAI,IAAI;AAAA,EACtE;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;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;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAGD,IAAM,cAAc,IAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAID,SAAS,QAAQ,CAAC,OAA+B;AAAA,EAChD,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAU3E,IAAM,qBAAqB,CAAC,OAAO,QAAQ,QAAQ;AAEnD,SAAS,kBAAkB,CAAC,MAAkB;AAAA,EAC7C,MAAM,OAAO,KAAK;AAAA,EAClB,IAAI,SAAS,WAAW;AAAA,IACvB,OAAO,KAAK;AAAA,IACZ,KAAK,WAAW,CAAC,GAAG,kBAAkB;AAAA,IACtC,KAAK,eAAe;AAAA,IACpB;AAAA,EACD;AAAA,EACA,IAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,SAAS,GAAG;AAAA,IACpD,OAAO,KAAK;AAAA,IACZ,KAAK,WAAW;AAAA,MACf,GAAG,KAAK,OAAO,CAAC,QAAQ,QAAQ,SAAS;AAAA,MACzC,GAAG;AAAA,IACJ;AAAA,IACA,KAAK,eAAe;AAAA,EACrB;AAAA;AAGD,SAAS,OAAO,CAAC,KAAqB;AAAA,EACrC,OAAO,IAAI,QAAQ,8BAA8B,EAAE;AAAA;AAGpD,SAAS,MAAM,CAAC,OAAgB,MAAY,OAA0B;AAAA,EACrE,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACzB,OAAO,MAAM,IAAI,CAAC,QAAQ,OAAO,KAAK,MAAM,KAAK,CAAC;AAAA,EACnD;AAAA,EACA,IAAI,CAAC,SAAS,KAAK;AAAA,IAAG,OAAO;AAAA,EAE7B,IAAI,OAAO,MAAM,SAAS,UAAU;AAAA,IACnC,MAAM,OAAO,QAAQ,MAAM,IAAI;AAAA,IAC/B,IAAI,MAAM,SAAS,IAAI,GAAG;AAAA,MACzB,MAAM,IAAI,UACT,uBAAuB,mDACtB,wEACA,sEACA,oBACF;AAAA,IACD;AAAA,IACA,MAAM,SAAS,KAAK;AAAA,IACpB,IAAI,CAAC,SAAS,MAAM,GAAG;AAAA,MACtB,MAAM,IAAI,UACT,qCAAqC,MAAM,yBAC5C;AAAA,IACD;AAAA,IACA,QAAQ,MAAM,SAAS,aAAa;AAAA,IACpC,OAAO;AAAA,SACF,OAAO,QAAQ,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC;AAAA,SACrC,OAAO,UAAU,MAAM,KAAK;AAAA,IACjC;AAAA,EACD;AAAA,EAEA,MAAM,MAAY,CAAC;AAAA,EACnB,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IACjD,IAAI,CAAC,2BAA2B,IAAI,GAAG;AAAA,MAAG;AAAA,IAC1C,IAAI,YAAY,IAAI,GAAG,KAAK,SAAS,KAAK,GAAG;AAAA,MAC5C,MAAM,SAAe,CAAC;AAAA,MACtB,YAAY,MAAM,WAAW,OAAO,QAAQ,KAAK,GAAG;AAAA,QACnD,OAAO,QAAQ,OAAO,QAAQ,MAAM,KAAK;AAAA,MAC1C;AAAA,MACA,IAAI,OAAO;AAAA,MACX;AAAA,IACD;AAAA,IACA,IAAI,OAAO,OAAO,OAAO,MAAM,KAAK;AAAA,EACrC;AAAA,EACA,mBAAmB,GAAG;AAAA,EACtB,OAAO;AAAA;AAqBD,SAAS,iBAAiB,CAAC,QAA4C;AAAA,EAC7E,MAAM,OAAO,GAAE,aAAa,QAAQ;AAAA,IACnC,QAAQ;AAAA,IACR,IAAI;AAAA,IAGJ,iBAAiB;AAAA,IACjB,UAAU,CAAC,QAAQ;AAAA,MAClB,MAAM,OAAQ,IAAI,UAAkD,KAClE,IAAI;AAAA,MACN,IAAI,SAAS,UAAU,IAAI,WAAW,aAAa,WAAW;AAAA,QAC7D,IAAI,WAAW,WAAW;AAAA,MAC3B;AAAA;AAAA,EAEF,CAAC;AAAA,EAED,MAAM,cAAc,SAAS,KAAK,WAAW,IAC1C,KAAK,cACL,SAAS,KAAK,KAAK,IAClB,KAAK,QACL,CAAC;AAAA,EACL,OAAO,OAAO,MAAM,aAAa,CAAC,CAAC;AAAA;;AC9JpC,SAAS,SAAQ,CAAC,OAAkC;AAAA,EACnD,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAG3E,SAAS,OAAO,CAAC,OAA2B;AAAA,EAC3C,IAAI,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EACjC,OAAO,UAAU,aAAa,UAAU,OAAO,CAAC,IAAI,CAAC,KAAK;AAAA;AAG3D,SAAS,IAAI,CAAC,OAAoC;AAAA,EACjD,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA;AAQ5C,SAAS,gBAAgB,CAAC,SAAiD;AAAA,EAC1E,OAAO,SAAS,MAAM,0BAA0B,IAAI;AAAA;AAQrD,SAAS,eAAe,CAAC,OAGvB;AAAA,EACD,MAAM,UAAU,MAAM;AAAA,EACtB,IAAI,UAAS,OAAO,GAAG;AAAA,IACtB,MAAM,SAAS,UAAS,MAAM,QAAQ,IAAI,MAAM,WAAW;AAAA,IAC3D,OAAO,EAAE,MAAM,OAAO,KAAK,OAAO,GAAG,OAAO;AAAA,EAC7C;AAAA,EACA,MAAM,YAAY,KAAK,MAAM,MAAM,GAAG,MAAM,wBAAwB,IAAI;AAAA,EACxE,IAAI,CAAC;AAAA,IAAW,OAAO,EAAE,MAAM,CAAC,GAAG,QAAQ,UAAU;AAAA,EACrD,MAAM,OAAO,CAAC,GAAG,UAAU,SAAS,gBAAgB,CAAC,EAAE,IACtD,CAAC,UAAU,MAAM,EAClB;AAAA,EACA,OAAO,EAAE,MAAM,QAAQ,UAAU;AAAA;AAIlC,SAAS,eAAe,CAAC,OAAqC;AAAA,EAC7D,WAAW,SAAS,QAAQ,MAAM,WAAW,GAAG;AAAA,IAE/C,MAAM,QAAQ,UAAS,KAAK,KAAK,UAAS,MAAM,GAAG,IAAI,MAAM,MAAM;AAAA,IACnE,IAAI,UAAS,KAAK;AAAA,MAAG,OAAO;AAAA,EAC7B;AAAA,EACA;AAAA;AAQD,SAAS,QAAQ,CAAC,SAAkB,OAAiB,CAAC,GAAsB;AAAA,EAC3E,MAAM,SAA4B,CAAC;AAAA,EACnC,WAAW,QAAQ,QAAQ,OAAO,GAAG;AAAA,IACpC,IAAI,CAAC,UAAS,IAAI;AAAA,MAAG;AAAA,IAErB,IAAI,KAAK,2BAA2B,WAAW;AAAA,MAC9C,WAAW,YAAY,QAAQ,KAAK,sBAAsB,GAAG;AAAA,QAC5D,IAAI,CAAC,UAAS,QAAQ;AAAA,UAAG;AAAA,QACzB,MAAM,OAAO,KAAK,SAAS,YAAY,KAAK;AAAA,QAC5C,MAAM,SAAS,SAAS,SAAS,SAAS,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,QACzD,MAAM,cAAc,KAAK,SAAS,WAAW;AAAA,QAC7C,OAAO,KACN,GAAI,gBAAgB,YACjB,SACA,OAAO,IAAI,CAAC,WAAW,EAAE,gBAAgB,MAAM,EAAE,CACrD;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,IAEA,IAAI,KAAK,sBAAsB,WAAW;AAAA,MACzC,WAAW,WAAW,QAAQ,KAAK,iBAAiB,GAAG;AAAA,QACtD,OAAO,KAAK;AAAA,UACX,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO,CAAC,EAAE,KAAK,GAAG;AAAA,UACzC,QAAQ;AAAA,UACR,aAAa,KAAK;AAAA,QACnB,CAAC;AAAA,MACF;AAAA,MACA;AAAA,IACD;AAAA,IAEA,IAAI,KAAK,4BAA4B,WAAW;AAAA,MAC/C,OAAO,KAAK,GAAG,SAAS,KAAK,yBAAyB,IAAI,CAAC;AAAA,MAC3D;AAAA,IACD;AAAA,IAEA,OAAO,KAAK;AAAA,MACX,MAAM,KAAK,KAAK,GAAG;AAAA,MACnB,QAAQ,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,YAAY,KAAK;AAAA,SACpD,KAAK,gBAAgB,YACtB,CAAC,IACD,EAAE,aAAa,KAAK,YAAY;AAAA,SAC/B,KAAK,oBAAoB,YAC1B,CAAC,IACD,EAAE,iBAAiB,KAAK,gBAAgB;AAAA,SACvC,KAAK,KAAK,cAAc,MAAM,YAC/B,CAAC,IACD,EAAE,gBAAgB,KAAK,KAAK,cAAc,EAAE;AAAA,IAChD,CAAC;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAcD,SAAS,WAAW,CAC1B,OACA,UAA+C,CAAC,GACtC;AAAA,EACV,IAAI,iBAAiB;AAAA,IAAW,OAAO;AAAA,EACvC,IAAI,CAAC,UAAS,KAAK;AAAA,IAAG,OAAO;AAAA,EAI7B,MAAM,SAAS,gBAAgB,KAAK,KAAK;AAAA,EACzC,MAAM,OACL,OAAO,OAAO,SAAS,WACpB,OAAO,OACP,OAAO,MAAM,SAAS,WACrB,MAAM,OACN;AAAA,EACL,IAAI,OAAO,SAAS;AAAA,IAAU,OAAO;AAAA,EAErC,MAAM,UACL,KAAK,OAAO,MAAM,KAClB,KAAK,OAAO,OAAO,KACnB,KAAM,MAAgC,OAAO,KAC7C;AAAA,EACD,MAAM,SAA2B;AAAA,IAChC,YAAY,QAAQ;AAAA,IACpB,YAAY;AAAA,IACZ,gBAAgB,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,QAAQ;AAAA,IAC5D,OAAO;AAAA,EACR;AAAA,EAEA,IAAI,SAAS,OAAO;AAAA,IACnB,QAAQ,MAAM,WAAW,gBAAgB,MAAM;AAAA,IAC/C,MAAM,QAAQ,iBAAiB,OAAO;AAAA,IACtC,MAAM,QACL,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAK,SAAS;AAAA,IAC/C,OAAO,IAAI,cACV,oBAAoB,QACnB,QAAQ,aAAa,QAAQ,QAAQ,gBAAgB,MAEtD,KAAK,QAAQ,OAAO,MAAM,OAAO,CAClC;AAAA,EACD;AAAA,EAEA,IAAI,SAAS,KAAK;AAAA,IACjB,MAAM,UAAU,UAAS,OAAO,OAAO,IAAI,OAAO,UAAU;AAAA,IAC5D,MAAM,SAAS,SAAS,SAAS,OAAO;AAAA,IACxC,OAAO,IAAI,gBACV,6BACC,QAAQ,aAAa,QAAQ,QAAQ,gBAAgB,KACnD,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,MAAM,MACtF,KAAK,QAAQ,QAAQ,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI,EAAE,CAC9D;AAAA,EACD;AAAA,EAEA,OAAO,IAAI,UAAU,WAAW,iBAAiB,QAAQ,MAAM;AAAA;;AC3LhE,qBAAS;AAWT,SAAS,WAAU,CAAC,OAAmC;AAAA,EACtD,OACC,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,cAAc;AAAA;AAQnD,SAAS,QAAQ,CAAgC,KAAa,OAAgB;AAAA,EAC7E,MAAM,MAAM,KAAK;AAAA,EACjB,IAAI,eAAe;AAAA,IAAM,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE;AAAA,EAC3D,IAAI,OAAO,QAAQ;AAAA,IAAU,OAAO,EAAE,SAAS,IAAI,SAAS,EAAE;AAAA,EAC9D,IAAI,YAAW,GAAG;AAAA,IAAG,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE;AAAA,EACtD,OAAO;AAAA;AAGR,SAAS,OAAO,CAAC,MAAc,OAAyB;AAAA,EACvD,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAAA,IAChE,MAAM,OAAO,OAAO,KAAK,KAAK;AAAA,IAC9B,IAAI,KAAK,WAAW,GAAG;AAAA,MACtB,MAAM,SAAS;AAAA,MAKf,IAAI,OAAO,OAAO,UAAU;AAAA,QAAU,OAAO,IAAI,KAAK,OAAO,KAAK;AAAA,MAClE,IAAI,OAAO,OAAO,YAAY;AAAA,QAAU,OAAO,OAAO,OAAO,OAAO;AAAA,MACpE,IAAI,OAAO,OAAO,SAAS;AAAA,QAAU,OAAO,IAAI,UAAS,OAAO,IAAI;AAAA,IACrE;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAGR,SAAS,WAAW,CAAC,MAAsB;AAAA,EAC1C,IAAI,SAAS;AAAA,EACb,WAAW,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,GAAG;AAAA,IAClD,UAAU,OAAO,aAAa,IAAI;AAAA,EACnC;AAAA,EACA,OAAO,KAAK,MAAM,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AAAA;AAGpB,SAAS,aAAa,CAAC,MAAsB;AAAA,EAC5C,MAAM,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAAA,EACxD,MAAM,SAAS,KAAK,SAAS,IAAI,QAAQ,IAAK,OAAO,SAAS,KAAM,CAAC,CAAC;AAAA,EACtE,OAAO,IAAI,YAAY,EAAE,OACxB,WAAW,KAAK,QAAQ,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CACrD;AAAA;AAQM,SAAS,YAAY,CAAC,SAAgC;AAAA,EAC5D,OAAO,YAAY,KAAK,UAAU,CAAC,QAAQ,KAAK,QAAQ,MAAM,GAAG,QAAQ,CAAC;AAAA;AAQpE,SAAS,YAAY,CAC3B,QACA,aACgB;AAAA,EAChB,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,SAAS,KAAK,MAAM,cAAc,MAAM,GAAG,OAAO;AAAA,IACjD,OAAO,OAAO;AAAA,IACf,MAAM,IAAI,mBAAmB,wCAAwC;AAAA,MACpE;AAAA,IACD,CAAC;AAAA;AAAA,EAEF,IACC,CAAC,MAAM,QAAQ,MAAM,KACrB,OAAO,WAAW,KAClB,OAAO,OAAO,OAAO,YACrB,CAAC,MAAM,QAAQ,OAAO,EAAE,GACvB;AAAA,IACD,MAAM,IAAI,mBAAmB,kCAAkC;AAAA,EAChE;AAAA,EACA,OAAO,KAAK,UAAU;AAAA,EACtB,IAAI,gBAAgB,aAAa,QAAQ,aAAa;AAAA,IACrD,MAAM,IAAI,mBACT,mDAAmD,YAAY,aAChE;AAAA,EACD;AAAA,EACA,OAAO,EAAE,KAAK,OAAO;AAAA;;AC1Ef,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAErC,SAAS,eAAe,CAAC,MAAc,OAAuB;AAAA,EAC7D,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AAAA,IAC1C,MAAM,IAAI,WACT,GAAG,8CAA8C,OAClD;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAQD,SAAS,UAAU,CACzB,UAAuB,CAAC,GACxB,cAAc,uBACD;AAAA,EACb,MAAM,OAAO,gBAAgB,QAAQ,QAAQ,QAAQ,CAAC;AAAA,EACtD,MAAM,WAAW,KAAK,IACrB,gBAAgB,YAAY,QAAQ,YAAY,iBAAiB,GACjE,WACD;AAAA,EACA,OAAO,EAAE,MAAM,UAAU,OAAO,UAAU,OAAO,OAAO,KAAK,SAAS;AAAA;AAIhE,SAAS,MAAS,CACxB,OACA,OACA,QACU;AAAA,EACV,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,WAAW,KAAK,KAAK,QAAQ,OAAO,QAAQ;AAAA,EAC7C;AAAA;AAIM,SAAS,WAAW,CAC1B,OACA,cAAc,uBACL;AAAA,EACT,OAAO,KAAK,IACX,gBAAgB,SAAS,SAAS,iBAAiB,GACnD,WACD;AAAA;;AC7ED,IAAM,qBAA8C;AAAA,EACnD,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,eAAe;AAAA,EACf,WAAW;AACZ;AAMA,IAAM,kBAA2C;AAAA,EAChD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AACb;AAGA,IAAM,UAAU,IAAI,IAAI,CAAC,KAAK,MAAM,OAAO,MAAM,CAAC;AAIlD,SAAS,KAAK,CAAC,OAAwD;AAAA,EACtE,MAAM,MAAM,MAAM;AAAA,EAClB,OAAO,eAAe,MAAM,OAAO,YAAY,GAAG,IAAI,KAAK,IAAI;AAAA;AAOzD,SAAS,WAAW,CAAC,KAAqB;AAAA,EAChD,OAAO,OAAO,QAAQ,GAAG,EACvB,IAAI,EAAE,OAAO,eAAe,GAAG,SAAS,OAAO,SAAS,GAAG,EAC3D,KAAK,GAAG;AAAA;AAGX,SAAS,kBAAkB,CAAC,OAAyB;AAAA,EACpD,IAAI,OAAO,UAAU,YAAY,UAAU;AAAA,IAAM,OAAO;AAAA,EACxD,MAAM,YAAY;AAAA,EAClB,MAAM,MAAc,CAAC;AAAA,EACrB,YAAY,OAAO,aAAa,OAAO,QAAQ,kBAAkB,GAAG;AAAA,IACnE,IAAI,SAAS,UAAU,UAAU;AAAA,EAClC;AAAA,EACA,IAAI,SAAS,UAAU;AAAA,EAEvB,OAAO;AAAA;AAWD,SAAS,cAAc,CAC7B,OACkB;AAAA,EAClB,MAAM,MAAM,MAAM,KAAK;AAAA,EACvB,MAAM,UAAkB,CAAC;AAAA,EACzB,YAAY,MAAM,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAClD,IAAI,QAAQ,IAAI,IAAI,KAAK,UAAU;AAAA,MAAW;AAAA,IAC9C,IAAI,SAAS,aAAa;AAAA,MACzB,QAAQ,YAAY,mBAAmB,KAAK;AAAA,MAC5C;AAAA,IACD;AAAA,IACA,IAAI,gBAAgB,UAAU;AAAA,MAAO;AAAA,IACrC,QAAQ,QAAQ;AAAA,EACjB;AAAA,EACA,OAAO,EAAE,MAAM,MAAM,QAAQ,YAAY,GAAG,GAAG,KAAK,QAAQ;AAAA;AAG7D,SAAS,SAAS,CAAC,OAAwB;AAAA,EAC1C,OAAO,KAAK,UAAU,OAAO,CAAC,OAAO,UACpC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACvD,OAAO,YACP,OAAO,QAAQ,KAAK,EAAE,KAAK,EAAE,KAAK,OAAQ,IAAI,IAAI,KAAK,CAAE,CAC1D,IACC,KACJ;AAAA;AAIM,SAAS,YAAY,CAC3B,QACA,MACU;AAAA,EACV,MAAM,IAAI,eAAe,MAAM;AAAA,EAC/B,MAAM,IAAI,eAAe,IAAI;AAAA,EAC7B,OAEC,KAAK,UAAU,OAAO,QAAQ,EAAE,GAAG,CAAC,MACnC,KAAK,UAAU,OAAO,QAAQ,EAAE,GAAG,CAAC,KACrC,UAAU,EAAE,OAAO,MAAM,UAAU,EAAE,OAAO;AAAA;AAuBvC,SAAS,WAAW,CAC1B,QACA,MACY;AAAA,EACZ,MAAM,SAAS,IAAI,IAClB,KAAK,IAAI,CAAC,UAAU,CAAC,eAAe,KAAK,EAAE,MAAM,KAAK,CAAC,CACxD;AAAA,EACA,MAAM,OAAkB;AAAA,IACvB,QAAQ,CAAC;AAAA,IACT,UAAU,CAAC;AAAA,IACX,WAAW,CAAC;AAAA,IACZ,OAAO,CAAC;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,IAAI;AAAA,EAElB,WAAW,SAAS,QAAQ;AAAA,IAC3B,MAAM,OAAO,eAAe,KAAK,EAAE;AAAA,IACnC,MAAM,IAAI,IAAI;AAAA,IACd,MAAM,WAAW,OAAO,IAAI,IAAI;AAAA,IAChC,IAAI,CAAC;AAAA,MAAU,KAAK,OAAO,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,IAC7C,SAAI,aAAa,OAAO,QAAQ;AAAA,MAAG,KAAK,UAAU,KAAK,IAAI;AAAA,IAC3D;AAAA,WAAK,SAAS,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,EAC3C;AAAA,EAEA,WAAW,QAAQ,OAAO,KAAK,GAAG;AAAA,IAEjC,IAAI,SAAS,UAAU,CAAC,MAAM,IAAI,IAAI;AAAA,MAAG,KAAK,MAAM,KAAK,IAAI;AAAA,EAC9D;AAAA,EACA,OAAO;AAAA;;;AC5IR,SAAS,UAAS,CAAC,OAAwB;AAAA,EAC1C,OAAO,KAAK,UAAU,SAAS,MAAM,CAAC,OAAO,UAC5C,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACvD,OAAO,YACP,OAAO,QAAQ,KAAK,EAAE,KAAK,EAAE,KAAK,OAAQ,IAAI,IAAI,KAAK,CAAE,CAC1D,IACC,KACJ;AAAA;AAIM,SAAS,YAAY,CAAC,MAA+B;AAAA,EAC3D,OAAO,KAAK,cAAc,aAAa,OAAO,KAAK,KAAK,SAAS,EAAE,SAAS;AAAA;AAatE,SAAS,iBAAiB,CAChC,QACA,MACU;AAAA,EACV,IAAI,OAAO,cAAc;AAAA,IAAW,OAAO,CAAC,aAAa,IAAI;AAAA,EAC7D,IAAI,CAAC,aAAa,IAAI;AAAA,IAAG,OAAO;AAAA,EAChC,OACC,WAAU,KAAK,SAAS,MAAM,WAAU,OAAO,SAAS,MACvD,KAAK,mBAAmB,cAAc,OAAO,UAC7C,KAAK,oBAAoB,aAAa,OAAO;AAAA;;;ACGhD,SAAS,UAAU,CAAC,OAAoC;AAAA,EACvD,MAAM,OAAQ,OAAqC;AAAA,EACnD,OAAO,OAAO,SAAS,WAAW,OAAO;AAAA;AAG1C,eAAe,iBAAiB,CAC/B,IACA,MACA,SACsC;AAAA,EAGtC,OAAO,QAAQ,MAAM,GACnB,gBACA,EAAE,KAAK,GACP,KAAM,UAAU,EAAE,QAAQ,IAAI,CAAC,GAAI,UAAU,MAAM,CACpD,EACC,QAAQ;AAAA,EACV,OAAO,OAAS,KAAK,WAAW,CAAC,IAAwB;AAAA;AAI1D,eAAe,WAAW,CACzB,IACA,MACA,SACkC;AAAA,EAClC,IAAI;AAAA,IACH,OAAO,MAAM,GAAG,WAAW,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,IACnD,OAAO,OAAO;AAAA,IAEf,IAAI,WAAW,KAAK,MAAM;AAAA,MAAI,OAAO,CAAC;AAAA,IACtC,MAAM;AAAA;AAAA;AAIR,SAAS,aAAa,CAAC,YAAuD;AAAA,EAC7E,QAAQ,OAAO,WAAW,WAAW;AAAA,EACrC,OAAO;AAAA,IACN,WACC,UAAU,QACP,YACA,EAAE,aAAa,kBAAkB,WAAW,MAAM,EAAE;AAAA,IACxD;AAAA,IACA;AAAA,EACD;AAAA;AAGD,SAAS,eAAe,CAAC,QAAoC;AAAA,EAC5D,OAAO,OAAO,cAAc,YACzB,CAAC,IACD;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,iBAAiB,OAAO;AAAA,IACxB,kBAAkB,OAAO;AAAA,EAC1B;AAAA;AAGH,eAAe,eAAe,CAC7B,IACA,MACA,QACA,SACgB;AAAA,EAChB,IAAI;AAAA,IACH,MAAM,GAAG,QACR;AAAA,MACC,SAAS;AAAA,MAGT,WAAW,OAAO,aAAa,CAAC;AAAA,SAC5B,OAAO,cAAc,YACtB,CAAC,IACD,EAAE,iBAAiB,OAAO,OAAO,kBAAkB,OAAO,OAAO;AAAA,IACrE,GACA,UAAU,EAAE,QAAQ,IAAI,SACzB;AAAA,IACC,OAAO,OAAO;AAAA,IACf,IAAI,WAAW,KAAK,MAAM,IAAI;AAAA,MAC7B,MAAM,IAAI,UACT,wCAAwC,gCACvC,sEACA,gEACA,2BACD,EAAE,YAAY,MAAM,YAAY,IAAI,OAAO,MAAM,CAClD;AAAA,IACD;AAAA,IACA,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA;AAAA;AAsB/C,eAAsB,cAAc,CACnC,IACA,YACA,UAAuB,CAAC,GACF;AAAA,EACtB,QAAQ,SAAS;AAAA,EACjB,MAAM,SAAS,QAAQ,UAAU;AAAA,EACjC,MAAM,UAAU,QAAQ;AAAA,EACxB,MAAM,SAAS,cAAc,UAAU;AAAA,EAEvC,IAAI,OAAO,MAAM,kBAAkB,IAAI,MAAM,OAAO;AAAA,EACpD,IAAI,UAAU;AAAA,EACd,IAAI,YAAqC;AAAA,EAEzC,IAAI,CAAC,MAAM;AAAA,IACV,UAAU;AAAA,IACV,IAAI,OAAO,cAAc;AAAA,MAAW,YAAY;AAAA,IAChD,IAAI,CAAC,QAAQ;AAAA,MACZ,IAAI;AAAA,QACH,MAAM,GAAG,iBAAiB,MAAM;AAAA,aAC5B,gBAAgB,MAAM;AAAA,aACrB,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC9B,CAAC;AAAA,QACA,OAAO,OAAO;AAAA,QAGf,IAAI,WAAW,KAAK,MAAM,IAAI;AAAA,UAC7B,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA,QAC9C;AAAA,QACA,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,OAAO,MAAM,kBAAkB,IAAI,MAAM,OAAO;AAAA;AAAA,IAElD;AAAA,EACD;AAAA,EAEA,IAAI,QAAQ,CAAC,kBAAkB,QAAQ,IAAI,GAAG;AAAA,IAC7C,YACC,OAAO,cAAc,YAClB,YACA,aAAa,IAAI,IAChB,YACA;AAAA,IACL,IAAI,CAAC;AAAA,MAAQ,MAAM,gBAAgB,IAAI,MAAM,QAAQ,OAAO;AAAA,EAC7D;AAAA,EAEA,MAAM,WACL,UAAU,UAAU,CAAC,IAAI,MAAM,YAAY,IAAI,MAAM,OAAO;AAAA,EAC7D,MAAM,OAAO,YAAY,WAAW,SAAS,QAAQ;AAAA,EACrD,MAAM,UAAU,QAAQ,qBAAqB,KAAK,QAAQ,CAAC;AAAA,EAC3D,MAAM,QAA4B,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,QAAQ;AAAA,EAEnE,IAAI,CAAC,QAAQ;AAAA,IACZ,MAAM,aAAa,GAAG,WAAW,IAAI;AAAA,IACrC,WAAW,SAAS;AAAA,MACnB,GAAG,KAAK,SAAS,IAAI,CAAC,MAAM,eAAe,CAAC,EAAE,IAAI;AAAA,MAClD,GAAG;AAAA,IACJ,GAAG;AAAA,MACF,MAAM,WAAW,UAAU,OAAO,UAAU,EAAE,QAAQ,IAAI,SAAS;AAAA,IACpE;AAAA,IACA,IAAI,MAAM,SAAS,GAAG;AAAA,MACrB,IAAI;AAAA,QACH,MAAM,WAAW,cAChB,OACA,UAAU,EAAE,QAAQ,IAAI,SACzB;AAAA,QACC,OAAO,OAAO;AAAA,QACf,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA;AAAA,IAE/C;AAAA,EACD;AAAA,EAEA,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACR,SAAS,KAAK,OAAO,IAAI,CAAC,UAAU,eAAe,KAAK,EAAE,IAAI;AAAA,MAC9D,WAAW,KAAK,SAAS,IAAI,CAAC,UAAU,eAAe,KAAK,EAAE,IAAI;AAAA,MAClE;AAAA,MACA,WAAW,KAAK;AAAA,IACjB;AAAA,IACA;AAAA,EACD;AAAA;AAOD,eAAsB,eAAe,CACpC,IACA,aACA,UAAuB,CAAC,GACA;AAAA,EACxB,MAAM,UAAwB,CAAC;AAAA,EAC/B,WAAW,cAAc,aAAa;AAAA,IACrC,QAAQ,KAAK,MAAM,eAAe,IAAI,YAAY,OAAO,CAAC;AAAA,EAC3D;AAAA,EACA,OAAO;AAAA;;;AC7OR,SAAS,SAAQ,CAAC,OAAiC;AAAA,EAClD,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAI3E,SAAS,cAAc,CAAC,OAAwB;AAAA,EAC/C,OAAO,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,WAAW,GAAG,CAAC;AAAA;AAI5D,SAAS,YAAY,CAAC,GAAuB,GAA+B;AAAA,EAC3E,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC,EAAE,SAAS,IAAI,IAAI;AAAA,EAClD,MAAM,QAAQ,KAAK,OAAO,KAAK,CAAC,EAAE,SAAS,IAAI,IAAI;AAAA,EACnD,IAAI,CAAC;AAAA,IAAM,OAAO,SAAS,CAAC;AAAA,EAC5B,IAAI,CAAC;AAAA,IAAO,OAAO;AAAA,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,EAAE;AAAA;AAkBvB,SAAS,gBAA4C,CAC3D,IACA,YACA,UAA6B,CAAC,GACa;AAAA,EAC3C,OAAO,MAAM,IAAI,YAAY,OAAO;AAAA;AAKrC,SAAS,KAAK,CACb,IACA,YACA,SACC;AAAA,EACD,MAAM,OAAO,WAAW;AAAA,EAGxB,MAAM,aAAa,GAAG,WAAgB,IAAI;AAAA,EAC1C,MAAM,QAAQ,WAAW,OAAO;AAAA,EAGhC,MAAM,WAAW,QAAQ;AAAA,EACzB,MAAM,SAAS,SAAS,UAAU;AAAA,EAClC,MAAM,UAAU,QAAQ;AAAA,EACxB,MAAM,QAAQ,QAAQ;AAAA,EACtB,MAAM,cAAc,QAAQ,eAAe;AAAA,EAC3C,MAAM,UAAU,QAAQ,YAAY,aAAa;AAAA,EACjD,MAAM,cAAc,QAAQ,cAAc,OAAO;AAAA,EACjD,MAAM,UAAU,QAAQ,kBAAkB,OAAO;AAAA,EACjD,MAAM,QAAQ,QAAQ,kBAAkB,OAAO;AAAA,EAE/C,IAAI,QAAQ,eAAe,QAAQ,CAAC,OAAO,WAAW;AAAA,IACrD,MAAM,IAAI,UACT,gEAAgE,gBACjE;AAAA,EACD;AAAA,EACA,IAAI,QAAQ,mBAAmB,QAAQ,CAAC,OAAO,SAAS;AAAA,IACvD,MAAM,IAAI,UACT,kEAAkE,gBACnE;AAAA,EACD;AAAA,EAEA,MAAM,MAAM,OAAU,OAAqC;AAAA,IAC1D,IAAI;AAAA,MACH,OAAO,MAAM,GAAG;AAAA,MACf,OAAO,OAAO;AAAA,MACf,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA;AAAA;AAAA,EAI/C,MAAM,gBAAgB,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAG/C,MAAM,OAAO,CAAC,gBACb,eAAe,CAAC,cAAc,EAAE,WAAW,KAAK,IAAI;AAAA,EAErD,MAAM,SAAS,CAAC,QAAiB,gBAChC,aAAa,UAAS,MAAM,IAAI,SAAS,WAAW,KAAK,WAAW,CAAC;AAAA,EAWtE,MAAM,SAAS,CAAI,aAAmB;AAAA,IACrC,IACC,YACA,CAAC,UAAS,QAAQ,KAClB,SAAS,QAAQ,aACjB,OAAO,OAAO,UAAU,IAAI,GAC3B;AAAA,MACD,OAAO;AAAA,IACR;AAAA,IACA,OAAO,eAAe,UAAU,MAAM;AAAA,MACrC,KAAK,MAAM,OAAQ,SAAoB,GAAG;AAAA,MAC1C,YAAY;AAAA,MACZ,cAAc;AAAA,IACf,CAAC;AAAA,IACD,OAAO;AAAA;AAAA,EAGR,MAAM,WAAW,CAAC,OACjB,IAAI,cAAc,mBAAmB,kBAAkB,OAAO,EAAE,KAAK;AAAA,IACpE,YAAY;AAAA,IACZ;AAAA,EACD,CAAC;AAAA,EAEF,MAAM,gBAAgB,CAAC,QAAgB,WAA0B;AAAA,IAChE,IAAI,CAAC,UAAS,MAAM,KAAK,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AAAA,MAC1D,MAAM,IAAI,UACT,GAAG,2FAA2F,QAC/F;AAAA,IACD;AAAA;AAAA,EAID,MAAM,aAAa,CAAC,WAA4B;AAAA,IAC/C,MAAM,UAAkB,KAAM,OAAkB;AAAA,IAKhD,IAAI,CAAC;AAAA,MAAU,OAAO,QAAQ;AAAA,IAC9B,IAAI,UAAU,WAAW;AAAA,MACxB,IAAI,OAAO,aAAa,QAAQ,cAAc,WAAW;AAAA,QACxD,QAAQ,YAAY;AAAA,MACrB;AAAA,MACA,IAAI,OAAO,aAAa,QAAQ,cAAc,WAAW;AAAA,QACxD,QAAQ,YAAY;AAAA,MACrB;AAAA,IACD;AAAA,IACA,OAAO,SAAU,WAAW,OAAO,MAAM,OAAO,IAAe;AAAA;AAAA,EAQhE,MAAM,WAAW,CAAC,UAA2B;AAAA,IAC5C,IAAI,CAAC,UAAS,KAAK,GAAG;AAAA,MACrB,MAAM,IAAI,UACT,sEAAsE,OAAO,KAAK,GACnF;AAAA,IACD;AAAA,IACA,MAAM,SAAiB,eAAe,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;AAAA,IAC/D,MAAM,MAAc,UAAS,OAAO,IAAI,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,IAElE,IAAI,CAAC,eAAe,KAAK,GAAG;AAAA,MAC3B,YAAY,OAAO,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,QACnD,IAAI,UAAU;AAAA,UAAW;AAAA,QACzB,MAAM,SAAS,MAAM;AAAA,QACrB,IAAI,CAAC,QAAQ;AAAA,UACZ,MAAM,IAAI,UACT,YAAY,uBAAuB,sBACpC;AAAA,QACD;AAAA,QACA,IAAI,SAAS,SAAS,OAAO,MAAM,KAAK,IAAI;AAAA,MAC7C;AAAA,IACD;AAAA,IAEA,IAAI,WAAW,IAAI,cAAc;AAAA,MAAW,IAAI,YAAY,IAAI;AAAA,IAChE,IACC,UAAU,aACV,OAAO,aACP,IAAI,cAAc,WACjB;AAAA,MACD,IAAI,YAAY;AAAA,IACjB;AAAA,IACA,IAAI,OAAO,KAAK,GAAG,EAAE,SAAS;AAAA,MAAG,OAAO,OAAO;AAAA,IAE/C,IAAI,OAAO;AAAA,MACV,MAAM,MAAM,UAAS,OAAO,IAAI,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,MAC1D,IAAI,UAAW,IAAI,WAAkC;AAAA,MACrD,OAAO,OAAO;AAAA,IACf;AAAA,IACA,OAAO;AAAA;AAAA,EAGR,MAAM,UAAU,OAAO,QAAgB,eACtC,IAAI,YAAY;AAAA,IACf,MAAM,QAAQ,MAAM,WAAW,QAAQ,QAAQ;AAAA,SAC3C;AAAA,SACC,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACpC,CAAC;AAAA,IACD,OAAO,UAAU,OAAO,OAAO,OAAO,KAAe;AAAA,GACrD;AAAA,EAEF,eAAe,QAAQ,CAAC,IAAa,OAAkC,CAAC,GAAG;AAAA,IAC1E,MAAM,QAAQ,MAAM,QAAQ,OAAO,EAAE,KAAK,GAAG,GAAG,KAAK,WAAW,CAAC;AAAA,IACjE,OAAO,SAAS;AAAA;AAAA,EAGjB,eAAe,OAAO,CAAC,IAAa,OAAkC,CAAC,GAAG;AAAA,IACzE,MAAM,QAAQ,MAAM,SAAS,IAAI,IAAI;AAAA,IACrC,IAAI,CAAC;AAAA,MAAO,MAAM,SAAS,EAAE;AAAA,IAC7B,OAAO;AAAA;AAAA,EAGR,eAAe,QAAQ,CAAC,OAAe,CAAC,GAAsB;AAAA,IAC7D,OAAO,IAAI,YAAY;AAAA,MACtB,IAAI,SAAS,WAAW,KACvB,OAAO,KAAK,QAAQ,KAAK,WAAkC,GAC3D;AAAA,WACI;AAAA,WACC,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,MAC1D,CACD;AAAA,MACA,IAAI,KAAK,SAAS;AAAA,QAAW,SAAS,OAAO,KAAK,KAAK,IAAa;AAAA,MACpE,IAAI,KAAK,SAAS;AAAA,QAAW,SAAS,OAAO,KAAK,KAAK,IAAc;AAAA,MACrE,IAAI,KAAK,UAAU;AAAA,QAAW,SAAS,OAAO,MAAM,KAAK,KAAe;AAAA,MACxE,MAAM,QAAQ,MAAM,OAAO,QAAQ;AAAA,MACnC,OAAO,MAAM,IAAI,CAAC,aAAa,OAAO,QAAkB,CAAC;AAAA,KACzD;AAAA;AAAA,EAGF,eAAe,cAAc,CAC5B,QACA,OAAkC,CAAC,GAClC;AAAA,IACD,OAAO,IAAI,YACV,WAAW,eAAe,OAAO,QAAQ,KAAK,WAAW,GAAG;AAAA,SACxD;AAAA,IACJ,CAAC,CACF;AAAA;AAAA,EAQD,eAAe,cAAc,CAC5B,IACA,QACA,QACA,iBACkB;AAAA,IAClB,MAAM,UAAU,MAAM,IAAI,YACzB,WAAW,iBAAiB,QAAQ,QAAQ;AAAA,SACxC;AAAA,MACH,gBAAgB;AAAA,IACjB,CAAC,CACF;AAAA,IACA,IAAI;AAAA,MAAS,OAAO,OAAO,OAAiB;AAAA,IAE5C,IAAI,oBAAoB,WAAW;AAAA,MAClC,MAAM,UAAU,MAAM,QAAQ,EAAE,KAAK,GAAG,CAAC;AAAA,MACzC,IAAI,SAAS;AAAA,QACZ,MAAM,IAAI,oBACT,YAAY,OAAO,EAAE,SAAS,uBAAuB,OACpD,QAAQ,OACT,UAAU,iDACV;AAAA,UACC,YAAY;AAAA,UACZ;AAAA,UACA;AAAA,UACA,eACC,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAAA,QAC1D,CACD;AAAA,MACD;AAAA,IACD;AAAA,IACA,MAAM,SAAS,EAAE;AAAA;AAAA,EAGlB,eAAe,UAAU,CAAC,IAA8B;AAAA,IACvD,MAAM,UAAU,MAAM,IAAI,YACzB,WAAW,iBAAiB,EAAE,KAAK,GAAG,GAAG,KAAK,cAAc,CAAC,CAC9D;AAAA,IACA,IAAI,CAAC;AAAA,MAAS,MAAM,SAAS,EAAE;AAAA,IAC/B,OAAO,OAAO,OAAiB;AAAA;AAAA,EAGhC,eAAe,cAAc,CAAC,QAAkC;AAAA,IAC/D,cAAc,kBAAkB,MAAM;AAAA,IACtC,OAAO,IAAI,YAAY;AAAA,MACtB,MAAM,SAAS,MAAM,WAAW,WAAW,QAAkB;AAAA,WACzD;AAAA,MACJ,CAAC;AAAA,MACD,OAAO,OAAO;AAAA,KACd;AAAA;AAAA,EAGF,MAAM,aAAa;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA,MAAM,CAAC,UACN,MAAM,IAAI,YAAY,KAAK,SAAS,SAAS,MAAM,CAAC;AAAA,IACrD,IAAI,CAAC,QAAiB,MAAM,IAAI,YAAY,KAAK,SAAS,OAAO,IAAI,CAAC;AAAA,IACtE,MAAM,CAAC,cAA2B,CAAC,MAClC,eAAe,IAAI,YAAY,KAAK,kBAAkB,YAAY,CAAC;AAAA,IAEpE;AAAA,IACA;AAAA,SAEM,UAAS,CAAC,QAAkB,OAAe,CAAC,GAAG;AAAA,MACpD,OAAO,SAAS,MAAM,SAAS,KAAK,MAAM,QAAQ,OAAO,EAAE,CAAC;AAAA,MAC5D,OAAO;AAAA;AAAA,IAGR;AAAA,SAEM,OAAM,CAAC,QAAiB;AAAA,MAC7B,MAAM,WAAW,WAAW,MAAM;AAAA,MAClC,OAAO,IAAI,YAAY;AAAA,QACtB,MAAM,WAAW,UAAU,UAAsB,KAAK,cAAc,CAAC;AAAA,QACrE,OAAO,OAAO,QAAQ;AAAA,OACtB;AAAA;AAAA,SAGI,WAAU,CAAC,QAA4B;AAAA,MAC5C,IAAI,OAAO,WAAW;AAAA,QAAG,OAAO,CAAC;AAAA,MACjC,MAAM,YAAY,OAAO,IAAI,UAAU;AAAA,MACvC,OAAO,IAAI,YAAY;AAAA,QACtB,MAAM,WAAW,WAAW,WAAyB;AAAA,aACjD;AAAA,QACJ,CAAC;AAAA,QACD,OAAO,UAAU,IAAI,CAAC,aAAa,OAAO,QAAQ,CAAC;AAAA,OACnD;AAAA;AAAA,SAGI,OAAM,CAAC,IAAa,OAAgB,OAAe,CAAC,GAAG;AAAA,MAC5D,MAAM,kBAAkB,KAAK;AAAA,MAC7B,IAAI,oBAAoB,aAAa,CAAC,OAAO;AAAA,QAC5C,MAAM,IAAI,UACT,yDAAyD,gBAC1D;AAAA,MACD;AAAA,MACA,MAAM,SAAS,SAAS,KAAK;AAAA,MAC7B,MAAM,SAAS,aACd;AAAA,QACC,KAAK;AAAA,WACD,oBAAoB,YACrB,CAAC,IACD,EAAE,SAAS,gBAAgB;AAAA,MAC/B,GACA,KAAK,CACN;AAAA,MACA,OAAO,eAAe,IAAI,QAAQ,QAAQ,eAAe;AAAA;AAAA,SAGpD,WAAU,CAAC,QAAiB,OAAgB;AAAA,MACjD,cAAc,cAAc,MAAM;AAAA,MAClC,MAAM,SAAS,SAAS,KAAK;AAAA,MAC7B,OAAO,IAAI,YAAY;AAAA,QACtB,MAAM,SAAS,MAAM,WAAW,WAAW,OAAO,MAAM,GAAG,QAAQ;AAAA,aAC/D;AAAA,QACJ,CAAC;AAAA,QACD,OAAO,OAAO;AAAA,OACd;AAAA;AAAA,SAGI,OAAM,CAAC,IAAa;AAAA,MACzB,IAAI,CAAC;AAAA,QAAa,OAAO,WAAW,EAAE;AAAA,MACtC,MAAM,MAAc,EAAE,WAAW,IAAI,KAAO;AAAA,MAC5C,IAAI,UAAU,aAAa,OAAO;AAAA,QAAW,IAAI,YAAY;AAAA,MAC7D,MAAM,SAAiB,EAAE,MAAM,IAAI;AAAA,MACnC,IAAI;AAAA,QAAO,OAAO,OAAO,EAAE,SAAS,EAAE;AAAA,MACtC,OAAO,eACN,IACA,aAAa,EAAE,KAAK,GAAG,GAAG,KAAK,CAAC,GAChC,QACA,SACD;AAAA;AAAA,SAGK,WAAU,CAAC,QAAiB;AAAA,MACjC,cAAc,cAAc,MAAM;AAAA,MAClC,IAAI,CAAC;AAAA,QAAa,OAAO,eAAe,MAAM;AAAA,MAC9C,MAAM,MAAc,EAAE,WAAW,IAAI,KAAO;AAAA,MAC5C,IAAI,UAAU,aAAa,OAAO;AAAA,QAAW,IAAI,YAAY;AAAA,MAC7D,MAAM,SAAiB,EAAE,MAAM,IAAI;AAAA,MACnC,IAAI;AAAA,QAAO,OAAO,OAAO,EAAE,SAAS,EAAE;AAAA,MACtC,OAAO,IAAI,YAAY;AAAA,QACtB,MAAM,SAAS,MAAM,WAAW,WAAW,OAAO,MAAM,GAAG,QAAQ;AAAA,aAC/D;AAAA,QACJ,CAAC;AAAA,QACD,OAAO,OAAO;AAAA,OACd;AAAA;AAAA,IAGF;AAAA,IACA;AAAA,SAEM,QAAO,CAAC,IAAa;AAAA,MAC1B,IAAI,CAAC,OAAO,WAAW;AAAA,QACtB,MAAM,IAAI,UAAU,aAAa,0BAA0B;AAAA,MAC5D;AAAA,MACA,MAAM,MAAc,EAAE,WAAW,KAAK;AAAA,MACtC,IAAI,OAAO;AAAA,QAAW,IAAI,YAAY;AAAA,MACtC,IAAI;AAAA,QAAS,IAAI,YAAY,IAAI;AAAA,MACjC,MAAM,SAAiB,EAAE,MAAM,IAAI;AAAA,MACnC,IAAI;AAAA,QAAO,OAAO,OAAO,EAAE,SAAS,EAAE;AAAA,MACtC,OAAO,eAAe,IAAI,EAAE,KAAK,GAAG,GAAG,QAAQ,SAAS;AAAA;AAAA,IAGzD,OAAO;AAAA,SAED,OAAM,CAAC,QAAiB,OAAkC,CAAC,GAAG;AAAA,MACnE,MAAM,QAAQ,MAAM,QAAQ,OAAO,QAAQ,KAAK,WAAW,GAAG,EAAE,KAAK,EAAE,CAAC;AAAA,MACxE,OAAO,UAAU,QAAQ,UAAU;AAAA;AAAA,SAG9B,SAAQ,CAAC,OAAe,CAAC,GAA0B;AAAA,MACxD,MAAM,SAAS,WAAW,MAAM,WAAW;AAAA,MAC3C,OAAO,OAAO,SAAS,MAAM,QAAQ,IAAI;AAAA,QACxC,SAAS;AAAA,UACR,QAAQ,KAAK;AAAA,UACb,MAAM,KAAK,QAAQ,EAAE,KAAK,EAAE;AAAA,UAC5B,OAAO,OAAO;AAAA,UACd,MAAM,OAAO;AAAA,UACb,aAAa,KAAK;AAAA,QACnB,CAAC;AAAA,QACD,eAAe,KAAK,QAAQ;AAAA,UAC3B,aAAa,KAAK;AAAA,QACnB,CAAC;AAAA,MACF,CAAC;AAAA,MACD,OAAO,OAAO,OAAO,OAAO,MAAM;AAAA;AAAA,SAG7B,iBAAgB,CAAC,OAAe,CAAC,GAAgC;AAAA,MACtE,MAAM,YAAa,KAAK,WAAkC;AAAA,MAC1D,IAAI,CAAC,MAAM,cAAc,cAAc,OAAO;AAAA,QAC7C,MAAM,IAAI,UACT,sBAAsB,uBAAuB,0BAC9C;AAAA,MACD;AAAA,MACA,MAAM,YAAa,KAAK,aAA4C;AAAA,MACpE,MAAM,SAAS,cAAc,QAAQ,CAAC,KAAK,IAAI,CAAC,WAAW,KAAK;AAAA,MAChE,MAAM,YAAY,GAAG,aAAa;AAAA,MAClC,MAAM,QAAQ,YAAY,KAAK,OAA6B,WAAW;AAAA,MACvE,MAAM,OAAO,cAAc,QAAQ,QAAQ;AAAA,MAE3C,IAAI;AAAA,MACJ,IAAI,KAAK,OAAO;AAAA,QACf,QAAQ,WAAW,aAAa,KAAK,OAAiB,SAAS;AAAA,QAC/D,IAAI,OAAO,WAAW,OAAO,QAAQ;AAAA,UACpC,MAAM,IAAI,UACT,4BAA4B,OAAO,wBAAwB,OAAO,UAClE,EAAE,YAAY,KAAK,CACpB;AAAA,QACD;AAAA,QAEA,QAAQ;AAAA,UACP,KAAK,OAAO,IAAI,CAAC,OAAO,WAAW;AAAA,eAC/B,OAAO,YACT,OACE,MAAM,GAAG,KAAK,EACd,IAAI,CAAC,UAAU,MAAM,CAAC,UAAU,OAAO,EAAE,CAAC,CAC7C;AAAA,aACC,QAAQ,GAAG,OAAO,OAAO,OAAO;AAAA,UAClC,EAAE;AAAA,QACH;AAAA,MACD;AAAA,MAEA,MAAM,OAAO,OAAO,YACnB,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,cAAc,QAAQ,IAAI,EAAE,CAAC,CAC5D;AAAA,MACA,MAAM,YAAY,MAAM,SAAS;AAAA,QAChC,QAAQ,aACP,UAAS,KAAK,MAAM,IAAI,KAAK,SAAS,WACtC,KACD;AAAA,QACA;AAAA,QACA,OAAO,QAAQ;AAAA,QACf,aAAa,KAAK;AAAA,MACnB,CAAC;AAAA,MAED,MAAM,QAAQ,UAAU,MAAM,GAAG,KAAK;AAAA,MACtC,MAAM,OAAO,MAAM,GAAG,EAAE;AAAA,MACxB,IAAI,UAAU,UAAU,SAAS,CAAC,MAAM;AAAA,QACvC,OAAO,EAAE,OAAO,YAAY,KAAK;AAAA,MAClC;AAAA,MAEA,MAAM,SAAS,OAAO,IAAI,CAAC,UAAU;AAAA,QACpC,MAAM,QAAQ,KAAK;AAAA,QACnB,IAAI,UAAU,QAAQ,UAAU,WAAW;AAAA,UAC1C,MAAM,IAAI,UACT,sBAAsB,oCAAoC,YACzD,wCACF;AAAA,QACD;AAAA,QACA,OAAO;AAAA,OACP;AAAA,MACD,OAAO,EAAE,OAAO,YAAY,aAAa,EAAE,KAAK,WAAW,OAAO,CAAC,EAAE;AAAA;AAAA,EAEvE;AAAA,EAEA,OAAO;AAAA;;AClhBR,SAAS,SAAS,CAAC,MAA8C;AAAA,EAChE,OAAO,OAAQ,KAAuB,kBAAkB;AAAA;AAgCzD,eAAsB,eAAkB,CACvC,MACA,IACA,SACa;AAAA,EACb,IAAI;AAAA,IACH,IAAI,UAAU,IAAI,GAAG;AAAA,MACpB,IAAI,KAAK,cAAc,GAAG;AAAA,QACzB,IAAI,SAAS;AAAA,UACZ,MAAM,IAAI,UACT,sEACC,6DACA,gEACA,sBACF;AAAA,QACD;AAAA,QACA,OAAO,MAAM,GAAG,IAAI;AAAA,MACrB;AAAA,MACA,OAAO,MAAM,KAAK,gBAAgB,IAAI,OAAO;AAAA,IAC9C;AAAA,IAEA,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI;AAAA,MACH,OAAO,MAAM,QAAQ,gBAAgB,IAAI,OAAO;AAAA,cAC/C;AAAA,MACD,MAAM,QAAQ,WAAW;AAAA;AAAA,IAEzB,OAAO,OAAO;AAAA,IACf,MAAM,YAAY,KAAK;AAAA;AAAA;",
|
|
20
|
-
"debugId": "
|
|
25
|
+
"mappings": ";AAAA;AAOO,IAAM,6BAAkD,IAAI,IAAI;AAAA,EACtE;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;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;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAGD,IAAM,cAAc,IAAI,IAAI;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAID,SAAS,QAAQ,CAAC,OAA+B;AAAA,EAChD,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAU3E,IAAM,qBAAqB,CAAC,OAAO,QAAQ,QAAQ;AAEnD,SAAS,kBAAkB,CAAC,MAAkB;AAAA,EAC7C,MAAM,OAAO,KAAK;AAAA,EAClB,IAAI,SAAS,WAAW;AAAA,IACvB,OAAO,KAAK;AAAA,IACZ,KAAK,WAAW,CAAC,GAAG,kBAAkB;AAAA,IACtC,KAAK,eAAe;AAAA,IACpB;AAAA,EACD;AAAA,EACA,IAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,SAAS,GAAG;AAAA,IACpD,OAAO,KAAK;AAAA,IACZ,KAAK,WAAW;AAAA,MACf,GAAG,KAAK,OAAO,CAAC,QAAQ,QAAQ,SAAS;AAAA,MACzC,GAAG;AAAA,IACJ;AAAA,IACA,KAAK,eAAe;AAAA,EACrB;AAAA;AAGD,SAAS,OAAO,CAAC,KAAqB;AAAA,EACrC,OAAO,IAAI,QAAQ,8BAA8B,EAAE;AAAA;AAGpD,SAAS,MAAM,CAAC,OAAgB,MAAY,OAA0B;AAAA,EACrE,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACzB,OAAO,MAAM,IAAI,CAAC,QAAQ,OAAO,KAAK,MAAM,KAAK,CAAC;AAAA,EACnD;AAAA,EACA,IAAI,CAAC,SAAS,KAAK;AAAA,IAAG,OAAO;AAAA,EAE7B,IAAI,OAAO,MAAM,SAAS,UAAU;AAAA,IACnC,MAAM,OAAO,QAAQ,MAAM,IAAI;AAAA,IAC/B,IAAI,MAAM,SAAS,IAAI,GAAG;AAAA,MACzB,MAAM,IAAI,UACT,uBAAuB,mDACtB,wEACA,sEACA,oBACF;AAAA,IACD;AAAA,IACA,MAAM,SAAS,KAAK;AAAA,IACpB,IAAI,CAAC,SAAS,MAAM,GAAG;AAAA,MACtB,MAAM,IAAI,UACT,qCAAqC,MAAM,yBAC5C;AAAA,IACD;AAAA,IACA,QAAQ,MAAM,SAAS,aAAa;AAAA,IACpC,OAAO;AAAA,SACF,OAAO,QAAQ,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC;AAAA,SACrC,OAAO,UAAU,MAAM,KAAK;AAAA,IACjC;AAAA,EACD;AAAA,EAEA,MAAM,MAAY,CAAC;AAAA,EACnB,YAAY,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IACjD,IAAI,CAAC,2BAA2B,IAAI,GAAG;AAAA,MAAG;AAAA,IAC1C,IAAI,YAAY,IAAI,GAAG,KAAK,SAAS,KAAK,GAAG;AAAA,MAC5C,MAAM,SAAe,CAAC;AAAA,MACtB,YAAY,MAAM,WAAW,OAAO,QAAQ,KAAK,GAAG;AAAA,QACnD,OAAO,QAAQ,OAAO,QAAQ,MAAM,KAAK;AAAA,MAC1C;AAAA,MACA,IAAI,OAAO;AAAA,MACX;AAAA,IACD;AAAA,IACA,IAAI,OAAO,OAAO,OAAO,MAAM,KAAK;AAAA,EACrC;AAAA,EACA,mBAAmB,GAAG;AAAA,EACtB,OAAO;AAAA;AAqBD,SAAS,iBAAiB,CAAC,QAA4C;AAAA,EAC7E,MAAM,OAAO,EAAE,aAAa,QAAQ;AAAA,IACnC,QAAQ;AAAA,IACR,IAAI;AAAA,IAGJ,iBAAiB;AAAA,IACjB,UAAU,CAAC,QAAQ;AAAA,MAClB,MAAM,OAAQ,IAAI,UAAkD,KAClE,IAAI;AAAA,MACN,IAAI,SAAS,UAAU,IAAI,WAAW,aAAa,WAAW;AAAA,QAC7D,IAAI,WAAW,WAAW;AAAA,MAC3B;AAAA;AAAA,EAEF,CAAC;AAAA,EAED,MAAM,cAAc,SAAS,KAAK,WAAW,IAC1C,KAAK,cACL,SAAS,KAAK,KAAK,IAClB,KAAK,QACL,CAAC;AAAA,EACL,OAAO,OAAO,MAAM,aAAa,CAAC,CAAC;AAAA;;;ACnH7B,MAAM,kBAAkB,MAAM;AAAA,EAcpC,WAAW,CAAC,UAAU,kBAAkB,UAA4B,CAAC,GAAG;AAAA,IACvE,MACC,SACA,QAAQ,UAAU,YAAY,YAAY,EAAE,OAAO,QAAQ,MAAM,CAClE;AAAA,IAjBQ,YAAO;AAAA,IACP,YAAsB;AAAA,IAiB9B,KAAK,aAAa,QAAQ;AAAA,IAC1B,KAAK,KAAK,QAAQ;AAAA,IAClB,KAAK,aAAa,QAAQ;AAAA,IAC1B,KAAK,iBAAiB,QAAQ;AAAA,IAC9B,KAAK,QAAQ,QAAQ;AAAA,IACrB,KAAK,OAAO,QAAQ,QAAQ,CAAC;AAAA,IAC7B,KAAK,SAAS,QAAQ;AAAA,IACtB,KAAK,SAAS,QAAQ,UAAU,CAAC;AAAA,IACjC,KAAK,kBAAkB,QAAQ;AAAA,IAC/B,KAAK,gBAAgB,QAAQ;AAAA;AAE/B;AAAA;AAGO,MAAM,sBAAsB,UAAU;AAAA,EAI5C,WAAW,CAAC,UAAU,aAAa,UAA4B,CAAC,GAAG;AAAA,IAClE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AAGO,MAAM,sBAAsB,UAAU;AAAA,EAI5C,WAAW,CAAC,UAAU,iBAAiB,UAA4B,CAAC,GAAG;AAAA,IACtE,MAAM,SAAS,EAAE,YAAY,UAAU,QAAQ,CAAC;AAAA,IAJxC,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AAGO,MAAM,wBAAwB,UAAU;AAAA,EAI9C,WAAW,CACV,UAAU,8BACV,UAA4B,CAAC,GAC5B;AAAA,IACD,MAAM,SAAS,EAAE,YAAY,QAAQ,QAAQ,CAAC;AAAA,IAPtC,YAAO;AAAA,IACE,YAAO;AAAA;AAQ1B;AAAA;AAMO,MAAM,4BAA4B,UAAU;AAAA,EAIlD,WAAW,CAAC,UAAU,oBAAoB,UAA4B,CAAC,GAAG;AAAA,IACzE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AASO,MAAM,uBAAuB,UAAU;AAAA,EAI7C,WAAW,CAAC,UAAU,cAAc,UAA4B,CAAC,GAAG;AAAA,IACnE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;AAAA;AAGO,MAAM,2BAA2B,UAAU;AAAA,EAIjD,WAAW,CAAC,UAAU,kBAAkB,UAA4B,CAAC,GAAG;AAAA,IACvE,MAAM,SAAS,OAAO;AAAA,IAJd,YAAO;AAAA,IACE,YAAO;AAAA;AAK1B;;;ACjJA,SAAS,SAAQ,CAAC,OAAkC;AAAA,EACnD,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAG3E,SAAS,OAAO,CAAC,OAA2B;AAAA,EAC3C,IAAI,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EACjC,OAAO,UAAU,aAAa,UAAU,OAAO,CAAC,IAAI,CAAC,KAAK;AAAA;AAG3D,SAAS,IAAI,CAAC,OAAoC;AAAA,EACjD,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA;AAQ5C,SAAS,gBAAgB,CAAC,SAAiD;AAAA,EAC1E,OAAO,SAAS,MAAM,0BAA0B,IAAI;AAAA;AAQrD,SAAS,eAAe,CAAC,OAGvB;AAAA,EACD,MAAM,UAAU,MAAM;AAAA,EACtB,IAAI,UAAS,OAAO,GAAG;AAAA,IACtB,MAAM,SAAS,UAAS,MAAM,QAAQ,IAAI,MAAM,WAAW;AAAA,IAC3D,OAAO,EAAE,MAAM,OAAO,KAAK,OAAO,GAAG,OAAO;AAAA,EAC7C;AAAA,EACA,MAAM,YAAY,KAAK,MAAM,MAAM,GAAG,MAAM,wBAAwB,IAAI;AAAA,EACxE,IAAI,CAAC;AAAA,IAAW,OAAO,EAAE,MAAM,CAAC,GAAG,QAAQ,UAAU;AAAA,EACrD,MAAM,OAAO,CAAC,GAAG,UAAU,SAAS,gBAAgB,CAAC,EAAE,IACtD,CAAC,UAAU,MAAM,EAClB;AAAA,EACA,OAAO,EAAE,MAAM,QAAQ,UAAU;AAAA;AAIlC,SAAS,eAAe,CAAC,OAAqC;AAAA,EAC7D,WAAW,SAAS,QAAQ,MAAM,WAAW,GAAG;AAAA,IAE/C,MAAM,QAAQ,UAAS,KAAK,KAAK,UAAS,MAAM,GAAG,IAAI,MAAM,MAAM;AAAA,IACnE,IAAI,UAAS,KAAK;AAAA,MAAG,OAAO;AAAA,EAC7B;AAAA,EACA;AAAA;AAQD,SAAS,QAAQ,CAAC,SAAkB,OAAiB,CAAC,GAAsB;AAAA,EAC3E,MAAM,SAA4B,CAAC;AAAA,EACnC,WAAW,QAAQ,QAAQ,OAAO,GAAG;AAAA,IACpC,IAAI,CAAC,UAAS,IAAI;AAAA,MAAG;AAAA,IAErB,IAAI,KAAK,2BAA2B,WAAW;AAAA,MAC9C,WAAW,YAAY,QAAQ,KAAK,sBAAsB,GAAG;AAAA,QAC5D,IAAI,CAAC,UAAS,QAAQ;AAAA,UAAG;AAAA,QACzB,MAAM,OAAO,KAAK,SAAS,YAAY,KAAK;AAAA,QAC5C,MAAM,SAAS,SAAS,SAAS,SAAS,CAAC,GAAG,MAAM,IAAI,CAAC;AAAA,QACzD,MAAM,cAAc,KAAK,SAAS,WAAW;AAAA,QAC7C,OAAO,KACN,GAAI,gBAAgB,YACjB,SACA,OAAO,IAAI,CAAC,WAAW,EAAE,gBAAgB,MAAM,EAAE,CACrD;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,IAEA,IAAI,KAAK,sBAAsB,WAAW;AAAA,MACzC,WAAW,WAAW,QAAQ,KAAK,iBAAiB,GAAG;AAAA,QACtD,OAAO,KAAK;AAAA,UACX,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO,CAAC,EAAE,KAAK,GAAG;AAAA,UACzC,QAAQ;AAAA,UACR,aAAa,KAAK;AAAA,QACnB,CAAC;AAAA,MACF;AAAA,MACA;AAAA,IACD;AAAA,IAEA,IAAI,KAAK,4BAA4B,WAAW;AAAA,MAC/C,OAAO,KAAK,GAAG,SAAS,KAAK,yBAAyB,IAAI,CAAC;AAAA,MAC3D;AAAA,IACD;AAAA,IAEA,OAAO,KAAK;AAAA,MACX,MAAM,KAAK,KAAK,GAAG;AAAA,MACnB,QAAQ,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,YAAY,KAAK;AAAA,SACpD,KAAK,gBAAgB,YACtB,CAAC,IACD,EAAE,aAAa,KAAK,YAAY;AAAA,SAC/B,KAAK,oBAAoB,YAC1B,CAAC,IACD,EAAE,iBAAiB,KAAK,gBAAgB;AAAA,SACvC,KAAK,KAAK,cAAc,MAAM,YAC/B,CAAC,IACD,EAAE,gBAAgB,KAAK,KAAK,cAAc,EAAE;AAAA,IAChD,CAAC;AAAA,EACF;AAAA,EACA,OAAO;AAAA;AAcD,SAAS,WAAW,CAC1B,OACA,UAA+C,CAAC,GACtC;AAAA,EACV,IAAI,iBAAiB;AAAA,IAAW,OAAO;AAAA,EACvC,IAAI,CAAC,UAAS,KAAK;AAAA,IAAG,OAAO;AAAA,EAI7B,MAAM,SAAS,gBAAgB,KAAK,KAAK;AAAA,EACzC,MAAM,OACL,OAAO,OAAO,SAAS,WACpB,OAAO,OACP,OAAO,MAAM,SAAS,WACrB,MAAM,OACN;AAAA,EACL,IAAI,OAAO,SAAS;AAAA,IAAU,OAAO;AAAA,EAErC,MAAM,UACL,KAAK,OAAO,MAAM,KAClB,KAAK,OAAO,OAAO,KACnB,KAAM,MAAgC,OAAO,KAC7C;AAAA,EACD,MAAM,SAA2B;AAAA,IAChC,YAAY,QAAQ;AAAA,IACpB,YAAY;AAAA,IACZ,gBAAgB,KAAK,MAAM,QAAQ,KAAK,KAAK,OAAO,QAAQ;AAAA,IAC5D,OAAO;AAAA,EACR;AAAA,EAEA,IAAI,SAAS,OAAO;AAAA,IACnB,QAAQ,MAAM,WAAW,gBAAgB,MAAM;AAAA,IAC/C,MAAM,QAAQ,iBAAiB,OAAO;AAAA,IACtC,MAAM,QACL,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAK,SAAS;AAAA,IAC/C,OAAO,IAAI,cACV,oBAAoB,QACnB,QAAQ,aAAa,QAAQ,QAAQ,gBAAgB,MAEtD,KAAK,QAAQ,OAAO,MAAM,OAAO,CAClC;AAAA,EACD;AAAA,EAEA,IAAI,SAAS,KAAK;AAAA,IACjB,MAAM,UAAU,UAAS,OAAO,OAAO,IAAI,OAAO,UAAU;AAAA,IAC5D,MAAM,SAAS,SAAS,SAAS,OAAO;AAAA,IACxC,OAAO,IAAI,gBACV,6BACC,QAAQ,aAAa,QAAQ,QAAQ,gBAAgB,KACnD,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,MAAM,MACtF,KAAK,QAAQ,QAAQ,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,IAAI,EAAE,CAC9D;AAAA,EACD;AAAA,EAEA,OAAO,IAAI,UAAU,WAAW,iBAAiB,QAAQ,MAAM;AAAA;;;ACnLhE,IAAM,qBAA8C;AAAA,EACnD,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,aAAa;AAAA,EACb,eAAe;AAAA,EACf,WAAW;AACZ;AAMA,IAAM,kBAA2C;AAAA,EAChD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AACb;AAGA,IAAM,UAAU,IAAI,IAAI,CAAC,KAAK,MAAM,OAAO,MAAM,CAAC;AAIlD,SAAS,KAAK,CAAC,OAAwD;AAAA,EACtE,MAAM,MAAM,MAAM;AAAA,EAClB,OAAO,eAAe,MAAM,OAAO,YAAY,GAAG,IAAI,KAAK,IAAI;AAAA;AAOzD,SAAS,WAAW,CAAC,KAAqB;AAAA,EAChD,OAAO,OAAO,QAAQ,GAAG,EACvB,IAAI,EAAE,OAAO,eAAe,GAAG,SAAS,OAAO,SAAS,GAAG,EAC3D,KAAK,GAAG;AAAA;AAGX,SAAS,kBAAkB,CAAC,OAAyB;AAAA,EACpD,IAAI,OAAO,UAAU,YAAY,UAAU;AAAA,IAAM,OAAO;AAAA,EACxD,MAAM,YAAY;AAAA,EAClB,MAAM,MAAc,CAAC;AAAA,EACrB,YAAY,OAAO,aAAa,OAAO,QAAQ,kBAAkB,GAAG;AAAA,IACnE,IAAI,SAAS,UAAU,UAAU;AAAA,EAClC;AAAA,EACA,IAAI,SAAS,UAAU;AAAA,EAEvB,OAAO;AAAA;AAWD,SAAS,cAAc,CAC7B,OACkB;AAAA,EAClB,MAAM,MAAM,MAAM,KAAK;AAAA,EACvB,MAAM,UAAkB,CAAC;AAAA,EACzB,YAAY,MAAM,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IAClD,IAAI,QAAQ,IAAI,IAAI,KAAK,UAAU;AAAA,MAAW;AAAA,IAC9C,IAAI,SAAS,aAAa;AAAA,MACzB,QAAQ,YAAY,mBAAmB,KAAK;AAAA,MAC5C;AAAA,IACD;AAAA,IACA,IAAI,gBAAgB,UAAU;AAAA,MAAO;AAAA,IACrC,QAAQ,QAAQ;AAAA,EACjB;AAAA,EACA,OAAO,EAAE,MAAM,MAAM,QAAQ,YAAY,GAAG,GAAG,KAAK,QAAQ;AAAA;AAG7D,SAAS,SAAS,CAAC,OAAwB;AAAA,EAC1C,OAAO,KAAK,UAAU,OAAO,CAAC,OAAO,UACpC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACvD,OAAO,YACP,OAAO,QAAQ,KAAK,EAAE,KAAK,EAAE,KAAK,OAAQ,IAAI,IAAI,KAAK,CAAE,CAC1D,IACC,KACJ;AAAA;AAIM,SAAS,YAAY,CAC3B,QACA,MACU;AAAA,EACV,MAAM,IAAI,eAAe,MAAM;AAAA,EAC/B,MAAM,IAAI,eAAe,IAAI;AAAA,EAC7B,OAEC,KAAK,UAAU,OAAO,QAAQ,EAAE,GAAG,CAAC,MACnC,KAAK,UAAU,OAAO,QAAQ,EAAE,GAAG,CAAC,KACrC,UAAU,EAAE,OAAO,MAAM,UAAU,EAAE,OAAO;AAAA;AAuBvC,SAAS,WAAW,CAC1B,QACA,MACY;AAAA,EACZ,MAAM,SAAS,IAAI,IAClB,KAAK,IAAI,CAAC,UAAU,CAAC,eAAe,KAAK,EAAE,MAAM,KAAK,CAAC,CACxD;AAAA,EACA,MAAM,OAAkB;AAAA,IACvB,QAAQ,CAAC;AAAA,IACT,UAAU,CAAC;AAAA,IACX,WAAW,CAAC;AAAA,IACZ,OAAO,CAAC;AAAA,EACT;AAAA,EACA,MAAM,QAAQ,IAAI;AAAA,EAElB,WAAW,SAAS,QAAQ;AAAA,IAC3B,MAAM,OAAO,eAAe,KAAK,EAAE;AAAA,IACnC,MAAM,IAAI,IAAI;AAAA,IACd,MAAM,WAAW,OAAO,IAAI,IAAI;AAAA,IAChC,IAAI,CAAC;AAAA,MAAU,KAAK,OAAO,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,IAC7C,SAAI,aAAa,OAAO,QAAQ;AAAA,MAAG,KAAK,UAAU,KAAK,IAAI;AAAA,IAC3D;AAAA,WAAK,SAAS,KAAK,KAAK,OAAO,KAAK,CAAC;AAAA,EAC3C;AAAA,EAEA,WAAW,QAAQ,OAAO,KAAK,GAAG;AAAA,IAEjC,IAAI,SAAS,UAAU,CAAC,MAAM,IAAI,IAAI;AAAA,MAAG,KAAK,MAAM,KAAK,IAAI;AAAA,EAC9D;AAAA,EACA,OAAO;AAAA;;;AC5IR,SAAS,UAAS,CAAC,OAAwB;AAAA,EAC1C,OAAO,KAAK,UAAU,SAAS,MAAM,CAAC,OAAO,UAC5C,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACvD,OAAO,YACP,OAAO,QAAQ,KAAK,EAAE,KAAK,EAAE,KAAK,OAAQ,IAAI,IAAI,KAAK,CAAE,CAC1D,IACC,KACJ;AAAA;AAIM,SAAS,YAAY,CAAC,MAA+B;AAAA,EAC3D,OAAO,KAAK,cAAc,aAAa,OAAO,KAAK,KAAK,SAAS,EAAE,SAAS;AAAA;AAatE,SAAS,iBAAiB,CAChC,QACA,MACU;AAAA,EACV,IAAI,OAAO,cAAc;AAAA,IAAW,OAAO,CAAC,aAAa,IAAI;AAAA,EAC7D,IAAI,CAAC,aAAa,IAAI;AAAA,IAAG,OAAO;AAAA,EAChC,OACC,WAAU,KAAK,SAAS,MAAM,WAAU,OAAO,SAAS,MACvD,KAAK,mBAAmB,cAAc,OAAO,UAC7C,KAAK,oBAAoB,aAAa,OAAO;AAAA;;;ACGhD,SAAS,UAAU,CAAC,OAAoC;AAAA,EACvD,MAAM,OAAQ,OAAqC;AAAA,EACnD,OAAO,OAAO,SAAS,WAAW,OAAO;AAAA;AAG1C,eAAe,iBAAiB,CAC/B,IACA,MACA,SACsC;AAAA,EAGtC,OAAO,QAAQ,MAAM,GACnB,gBACA,EAAE,KAAK,GACP,KAAM,UAAU,EAAE,QAAQ,IAAI,CAAC,GAAI,UAAU,MAAM,CACpD,EACC,QAAQ;AAAA,EACV,OAAO,OAAS,KAAK,WAAW,CAAC,IAAwB;AAAA;AAI1D,eAAe,WAAW,CACzB,IACA,MACA,SACkC;AAAA,EAClC,IAAI;AAAA,IACH,OAAO,MAAM,GAAG,WAAW,IAAI,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAAA,IACnD,OAAO,OAAO;AAAA,IAEf,IAAI,WAAW,KAAK,MAAM;AAAA,MAAI,OAAO,CAAC;AAAA,IACtC,MAAM;AAAA;AAAA;AAIR,SAAS,aAAa,CAAC,YAAuD;AAAA,EAC7E,QAAQ,OAAO,WAAW,WAAW;AAAA,EACrC,OAAO;AAAA,IACN,WACC,UAAU,QACP,YACA,EAAE,aAAa,kBAAkB,WAAW,MAAM,EAAE;AAAA,IACxD;AAAA,IACA;AAAA,EACD;AAAA;AAGD,SAAS,eAAe,CAAC,QAAoC;AAAA,EAC5D,OAAO,OAAO,cAAc,YACzB,CAAC,IACD;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,iBAAiB,OAAO;AAAA,IACxB,kBAAkB,OAAO;AAAA,EAC1B;AAAA;AAGH,eAAe,eAAe,CAC7B,IACA,MACA,QACA,SACgB;AAAA,EAChB,IAAI;AAAA,IACH,MAAM,GAAG,QACR;AAAA,MACC,SAAS;AAAA,MAGT,WAAW,OAAO,aAAa,CAAC;AAAA,SAC5B,OAAO,cAAc,YACtB,CAAC,IACD,EAAE,iBAAiB,OAAO,OAAO,kBAAkB,OAAO,OAAO;AAAA,IACrE,GACA,UAAU,EAAE,QAAQ,IAAI,SACzB;AAAA,IACC,OAAO,OAAO;AAAA,IACf,IAAI,WAAW,KAAK,MAAM,IAAI;AAAA,MAC7B,MAAM,IAAI,UACT,wCAAwC,gCACvC,sEACA,gEACA,2BACD,EAAE,YAAY,MAAM,YAAY,IAAI,OAAO,MAAM,CAClD;AAAA,IACD;AAAA,IACA,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA;AAAA;AAsB/C,eAAsB,cAAc,CACnC,IACA,YACA,UAAuB,CAAC,GACF;AAAA,EACtB,QAAQ,SAAS;AAAA,EACjB,MAAM,SAAS,QAAQ,UAAU;AAAA,EACjC,MAAM,UAAU,QAAQ;AAAA,EACxB,MAAM,SAAS,cAAc,UAAU;AAAA,EAEvC,IAAI,OAAO,MAAM,kBAAkB,IAAI,MAAM,OAAO;AAAA,EACpD,IAAI,UAAU;AAAA,EACd,IAAI,YAAqC;AAAA,EAEzC,IAAI,CAAC,MAAM;AAAA,IACV,UAAU;AAAA,IACV,IAAI,OAAO,cAAc;AAAA,MAAW,YAAY;AAAA,IAChD,IAAI,CAAC,QAAQ;AAAA,MACZ,IAAI;AAAA,QACH,MAAM,GAAG,iBAAiB,MAAM;AAAA,aAC5B,gBAAgB,MAAM;AAAA,aACrB,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,QAC9B,CAAC;AAAA,QACA,OAAO,OAAO;AAAA,QAGf,IAAI,WAAW,KAAK,MAAM,IAAI;AAAA,UAC7B,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA,QAC9C;AAAA,QACA,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,OAAO,MAAM,kBAAkB,IAAI,MAAM,OAAO;AAAA;AAAA,IAElD;AAAA,EACD;AAAA,EAEA,IAAI,QAAQ,CAAC,kBAAkB,QAAQ,IAAI,GAAG;AAAA,IAC7C,YACC,OAAO,cAAc,YAClB,YACA,aAAa,IAAI,IAChB,YACA;AAAA,IACL,IAAI,CAAC;AAAA,MAAQ,MAAM,gBAAgB,IAAI,MAAM,QAAQ,OAAO;AAAA,EAC7D;AAAA,EAEA,MAAM,WACL,UAAU,UAAU,CAAC,IAAI,MAAM,YAAY,IAAI,MAAM,OAAO;AAAA,EAC7D,MAAM,OAAO,YAAY,WAAW,SAAS,QAAQ;AAAA,EACrD,MAAM,UAAU,QAAQ,qBAAqB,KAAK,QAAQ,CAAC;AAAA,EAC3D,MAAM,QAA4B,CAAC,GAAG,KAAK,QAAQ,GAAG,KAAK,QAAQ;AAAA,EAEnE,IAAI,CAAC,QAAQ;AAAA,IACZ,MAAM,aAAa,GAAG,WAAW,IAAI;AAAA,IACrC,WAAW,SAAS;AAAA,MACnB,GAAG,KAAK,SAAS,IAAI,CAAC,MAAM,eAAe,CAAC,EAAE,IAAI;AAAA,MAClD,GAAG;AAAA,IACJ,GAAG;AAAA,MACF,MAAM,WAAW,UAAU,OAAO,UAAU,EAAE,QAAQ,IAAI,SAAS;AAAA,IACpE;AAAA,IACA,IAAI,MAAM,SAAS,GAAG;AAAA,MACrB,IAAI;AAAA,QACH,MAAM,WAAW,cAChB,OACA,UAAU,EAAE,QAAQ,IAAI,SACzB;AAAA,QACC,OAAO,OAAO;AAAA,QACf,MAAM,YAAY,OAAO,EAAE,YAAY,KAAK,CAAC;AAAA;AAAA,IAE/C;AAAA,EACD;AAAA,EAEA,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACR,SAAS,KAAK,OAAO,IAAI,CAAC,UAAU,eAAe,KAAK,EAAE,IAAI;AAAA,MAC9D,WAAW,KAAK,SAAS,IAAI,CAAC,UAAU,eAAe,KAAK,EAAE,IAAI;AAAA,MAClE;AAAA,MACA,WAAW,KAAK;AAAA,IACjB;AAAA,IACA;AAAA,EACD;AAAA;AAOD,eAAsB,eAAe,CACpC,IACA,aACA,UAAuB,CAAC,GACA;AAAA,EACxB,MAAM,UAAwB,CAAC;AAAA,EAC/B,WAAW,cAAc,aAAa;AAAA,IACrC,QAAQ,KAAK,MAAM,eAAe,IAAI,YAAY,OAAO,CAAC;AAAA,EAC3D;AAAA,EACA,OAAO;AAAA;;;AC3ID,SAAS,gBAA4C,CAC3D,QAC+B;AAAA,EAC/B,IAAI,EAAE,SAAS,OAAO,OAAO,QAAQ;AAAA,IACpC,MAAM,IAAI,UACT,sBAAsB,OAAO,oCAC5B,uEACA,yBACF;AAAA,EACD;AAAA,EACA,OAAO,OAAO,OAAO;AAAA,OACjB;AAAA,IACH,SAAS,OAAO,OAAO,CAAC,GAAI,OAAO,WAAW,CAAC,CAAE,CAAC;AAAA,IAClD,YAAY,OAAO,OAAO;AAAA,MACzB,OAAO,OAAO,YAAY,SAAS;AAAA,MACnC,QAAQ,OAAO,YAAY,UAAU;AAAA,IACtC,CAAC;AAAA,EACF,CAAC;AAAA;AAIK,SAAS,QAAQ,CAAC,YAQvB;AAAA,EACD,MAAM,QAAQ,WAAW,OAAO;AAAA,EAChC,MAAM,MAAM,CAAC,UAAiB,QAAQ;AAAA,EACtC,OAAO;AAAA,IACN,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,IAC1B,SAAS,IAAI,SAAS;AAAA,IACtB,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,IAC1B,WAAW,IAAI,WAAW;AAAA,EAC3B;AAAA;;;ACpIM,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAErC,SAAS,eAAe,CAAC,MAAc,OAAuB;AAAA,EAC7D,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,GAAG;AAAA,IAC1C,MAAM,IAAI,WACT,GAAG,8CAA8C,OAClD;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAQD,SAAS,UAAU,CACzB,UAAuB,CAAC,GACxB,cAAc,uBACD;AAAA,EACb,MAAM,OAAO,gBAAgB,QAAQ,QAAQ,QAAQ,CAAC;AAAA,EACtD,MAAM,WAAW,KAAK,IACrB,gBAAgB,YAAY,QAAQ,YAAY,iBAAiB,GACjE,WACD;AAAA,EACA,OAAO,EAAE,MAAM,UAAU,OAAO,UAAU,OAAO,OAAO,KAAK,SAAS;AAAA;AAIhE,SAAS,MAAS,CACxB,OACA,OACA,QACU;AAAA,EACV,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,MAAM,OAAO;AAAA,IACb,UAAU,OAAO;AAAA,IACjB,WAAW,KAAK,KAAK,QAAQ,OAAO,QAAQ;AAAA,EAC7C;AAAA;AAIM,SAAS,WAAW,CAC1B,OACA,cAAc,uBACL;AAAA,EACT,OAAO,KAAK,IACX,gBAAgB,SAAS,SAAS,iBAAiB,GACnD,WACD;AAAA;;;ACjBM,SAAS,aAAa,CAC5B,IACA,YACA,SACoB;AAAA,EACpB,MAAM,OAAO,WAAW;AAAA,EACxB,MAAM,QAAQ,WAAW,OAAO;AAAA,EAChC,MAAM,SAAS,SAAS,UAAU;AAAA,EAClC,MAAM,UAAU,QAAQ;AAAA,EAExB,IAAI,QAAQ,eAAe,QAAQ,CAAC,OAAO,WAAW;AAAA,IACrD,MAAM,IAAI,UACT,6DAA6D,gBAC9D;AAAA,EACD;AAAA,EACA,IAAI,QAAQ,mBAAmB,QAAQ,CAAC,OAAO,SAAS;AAAA,IACvD,MAAM,IAAI,UACT,+DAA+D,gBAChE;AAAA,EACD;AAAA,EAEA,OAAO;AAAA,IACN;AAAA,IACA;AAAA,IACA,YAAY,GAAG,WAAgB,IAAI;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AAAA,IACf;AAAA,IACA,eAAe,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxC,aAAa,QAAQ,eAAe;AAAA,IACpC,UAAU,QAAQ;AAAA,IAClB,SAAS,QAAQ,YAAY,aAAa;AAAA,IAC1C,aAAa,QAAQ,cAAc,OAAO;AAAA,IAC1C,SAAS,QAAQ,kBAAkB,OAAO;AAAA,IAC1C,OAAO,QAAQ,kBAAkB,OAAO;AAAA,EACzC;AAAA;AAID,eAAsB,GAAM,CAC3B,KACA,IACa;AAAA,EACb,IAAI;AAAA,IACH,OAAO,MAAM,GAAG;AAAA,IACf,OAAO,OAAO;AAAA,IACf,MAAM,YAAY,OAAO,EAAE,YAAY,IAAI,KAAK,CAAC;AAAA;AAAA;AAI5C,SAAS,QAAQ,CAAC,KAAwB,IAA4B;AAAA,EAC5E,OAAO,IAAI,cACV,mBAAmB,IAAI,kBAAkB,OAAO,EAAE,KAClD,EAAE,YAAY,IAAI,MAAM,GAAG,CAC5B;AAAA;;;AC5HD;AAWA,SAAS,UAAU,CAAC,OAAmC;AAAA,EACtD,OACC,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,cAAc;AAAA;AAQnD,SAAS,QAAQ,CAAgC,KAAa,OAAgB;AAAA,EAC7E,MAAM,MAAM,KAAK;AAAA,EACjB,IAAI,eAAe;AAAA,IAAM,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE;AAAA,EAC3D,IAAI,OAAO,QAAQ;AAAA,IAAU,OAAO,EAAE,SAAS,IAAI,SAAS,EAAE;AAAA,EAC9D,IAAI,WAAW,GAAG;AAAA,IAAG,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE;AAAA,EACtD,OAAO;AAAA;AAGR,SAAS,OAAO,CAAC,MAAc,OAAyB;AAAA,EACvD,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAAA,IAChE,MAAM,OAAO,OAAO,KAAK,KAAK;AAAA,IAC9B,IAAI,KAAK,WAAW,GAAG;AAAA,MACtB,MAAM,SAAS;AAAA,MAKf,IAAI,OAAO,OAAO,UAAU;AAAA,QAAU,OAAO,IAAI,KAAK,OAAO,KAAK;AAAA,MAClE,IAAI,OAAO,OAAO,YAAY;AAAA,QAAU,OAAO,OAAO,OAAO,OAAO;AAAA,MACpE,IAAI,OAAO,OAAO,SAAS;AAAA,QAAU,OAAO,IAAI,SAAS,OAAO,IAAI;AAAA,IACrE;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAGR,SAAS,WAAW,CAAC,MAAsB;AAAA,EAC1C,IAAI,SAAS;AAAA,EACb,WAAW,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI,GAAG;AAAA,IAClD,UAAU,OAAO,aAAa,IAAI;AAAA,EACnC;AAAA,EACA,OAAO,KAAK,MAAM,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,EAAE;AAAA;AAGpB,SAAS,aAAa,CAAC,MAAsB;AAAA,EAC5C,MAAM,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AAAA,EACxD,MAAM,SAAS,KAAK,SAAS,IAAI,QAAQ,IAAK,OAAO,SAAS,KAAM,CAAC,CAAC;AAAA,EACtE,OAAO,IAAI,YAAY,EAAE,OACxB,WAAW,KAAK,QAAQ,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CACrD;AAAA;AAQM,SAAS,YAAY,CAAC,SAAgC;AAAA,EAC5D,OAAO,YAAY,KAAK,UAAU,CAAC,QAAQ,KAAK,QAAQ,MAAM,GAAG,QAAQ,CAAC;AAAA;AAQpE,SAAS,YAAY,CAC3B,QACA,aACgB;AAAA,EAChB,IAAI;AAAA,EACJ,IAAI;AAAA,IACH,SAAS,KAAK,MAAM,cAAc,MAAM,GAAG,OAAO;AAAA,IACjD,OAAO,OAAO;AAAA,IACf,MAAM,IAAI,mBAAmB,wCAAwC;AAAA,MACpE;AAAA,IACD,CAAC;AAAA;AAAA,EAEF,IACC,CAAC,MAAM,QAAQ,MAAM,KACrB,OAAO,WAAW,KAClB,OAAO,OAAO,OAAO,YACrB,CAAC,MAAM,QAAQ,OAAO,EAAE,GACvB;AAAA,IACD,MAAM,IAAI,mBAAmB,kCAAkC;AAAA,EAChE;AAAA,EACA,OAAO,KAAK,UAAU;AAAA,EACtB,IAAI,gBAAgB,aAAa,QAAQ,aAAa;AAAA,IACrD,MAAM,IAAI,mBACT,mDAAmD,YAAY,aAChE;AAAA,EACD;AAAA,EACA,OAAO,EAAE,KAAK,OAAO;AAAA;;;ACtGf,SAAS,SAAQ,CAAC,OAAiC;AAAA,EACzD,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAAA;AAIpE,SAAS,cAAc,CAAC,OAAwB;AAAA,EACtD,OAAO,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,WAAW,GAAG,CAAC;AAAA;AAIrD,SAAS,YAAY,CAC3B,GACA,GACS;AAAA,EACT,MAAM,OAAO,KAAK,OAAO,KAAK,CAAC,EAAE,SAAS,IAAI,IAAI;AAAA,EAClD,MAAM,QAAQ,KAAK,OAAO,KAAK,CAAC,EAAE,SAAS,IAAI,IAAI;AAAA,EACnD,IAAI,CAAC;AAAA,IAAM,OAAO,SAAS,CAAC;AAAA,EAC5B,IAAI,CAAC;AAAA,IAAO,OAAO;AAAA,EACnB,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,EAAE;AAAA;AAIvB,SAAS,IAAI,CACnB,KACA,aACqB;AAAA,EACrB,OAAO,IAAI,eAAe,CAAC,cAAc,EAAE,WAAW,KAAK,IAAI;AAAA;AAIzD,SAAS,MAAM,CACrB,KACA,QACA,aACS;AAAA,EACT,OAAO,aACN,UAAS,MAAM,IAAI,SAAS,WAC5B,KAAK,KAAK,WAAW,CACtB;AAAA;AAIM,SAAS,aAAa,CAC5B,KACA,QACA,QACO;AAAA,EACP,IAAI,CAAC,UAAS,MAAM,KAAK,OAAO,KAAK,MAAM,EAAE,WAAW,GAAG;AAAA,IAC1D,MAAM,IAAI,UACT,GAAG,2FAA2F,IAAI,QACnG;AAAA,EACD;AAAA;;;AC5CM,SAAS,MAAS,CAAC,KAAwB,UAAgB;AAAA,EACjE,IACC,IAAI,YACJ,CAAC,UAAS,QAAQ,KAClB,SAAS,QAAQ,aACjB,OAAO,OAAO,UAAU,IAAI,GAC3B;AAAA,IACD,OAAO;AAAA,EACR;AAAA,EACA,OAAO,eAAe,UAAU,MAAM;AAAA,IACrC,KAAK,MAAM,OAAQ,SAAoB,GAAG;AAAA,IAC1C,YAAY;AAAA,IACZ,cAAc;AAAA,EACf,CAAC;AAAA,EACD,OAAO;AAAA;AAID,SAAS,UAAU,CAAC,KAAwB,QAAyB;AAAA,EAC3E,MAAM,UAAkB,KAAM,OAAkB;AAAA,EAKhD,IAAI,CAAC,IAAI;AAAA,IAAU,OAAO,QAAQ;AAAA,EAClC,IAAI,IAAI,UAAU,WAAW;AAAA,IAC5B,IAAI,IAAI,OAAO,aAAa,QAAQ,cAAc,WAAW;AAAA,MAC5D,QAAQ,YAAY,IAAI;AAAA,IACzB;AAAA,IACA,IAAI,IAAI,OAAO,aAAa,QAAQ,cAAc,WAAW;AAAA,MAC5D,QAAQ,YAAY,IAAI;AAAA,IACzB;AAAA,EACD;AAAA,EACA,OAAO,IAAI,SACP,IAAI,WAAW,OAAO,MAAM,OAAO,IACpC;AAAA;AAIJ,SAAS,aAAa,CAAC,KAAwB,OAAuB;AAAA,EACrE,MAAM,MAAc,CAAC;AAAA,EACrB,YAAY,OAAO,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IACnD,IAAI,UAAU;AAAA,MAAW;AAAA,IACzB,MAAM,SAAS,IAAI,MAAM;AAAA,IACzB,IAAI,CAAC,QAAQ;AAAA,MACZ,MAAM,IAAI,UACT,YAAY,IAAI,uBAAuB,sBACxC;AAAA,IACD;AAAA,IACA,IAAI,SAAS,IAAI,SAAS,OAAO,MAAM,KAAK,IAAI;AAAA,EACjD;AAAA,EACA,OAAO;AAAA;AAQD,SAAS,QAAQ,CAAC,KAAwB,OAAwB;AAAA,EACxE,IAAI,CAAC,UAAS,KAAK,GAAG;AAAA,IACrB,MAAM,IAAI,UACT,sEAAsE,OAAO,KAAK,GACnF;AAAA,EACD;AAAA,EACA,MAAM,YAAY,eAAe,KAAK;AAAA,EACtC,MAAM,SAAiB,YAAY,KAAK,MAAM,IAAI,CAAC;AAAA,EACnD,MAAM,MAAc;AAAA,OACf,UAAS,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC;AAAA,OACvC,YAAY,CAAC,IAAI,cAAc,KAAK,KAAK;AAAA,EAC9C;AAAA,EAEA,IAAI,IAAI,WAAW,IAAI,cAAc;AAAA,IAAW,IAAI,YAAY,IAAI;AAAA,EACpE,IACC,IAAI,UAAU,aACd,IAAI,OAAO,aACX,IAAI,cAAc,WACjB;AAAA,IACD,IAAI,YAAY,IAAI;AAAA,EACrB;AAAA,EACA,IAAI,OAAO,KAAK,GAAG,EAAE,SAAS;AAAA,IAAG,OAAO,OAAO;AAAA,EAE/C,IAAI,IAAI,OAAO;AAAA,IACd,MAAM,MAAM,UAAS,OAAO,IAAI,IAAI,KAAK,OAAO,KAAK,IAAI,CAAC;AAAA,IAC1D,IAAI,UAAW,IAAI,WAAkC;AAAA,IACrD,OAAO,OAAO;AAAA,EACf;AAAA,EACA,OAAO;AAAA;;;AC9FD,SAAS,OAAO,CACtB,KACA,QACA,YACyB;AAAA,EACzB,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,MAAM,QAAQ,MAAM,IAAI,WAAW,QAAQ,QAAQ;AAAA,SAC/C,IAAI;AAAA,SACH,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACpC,CAAC;AAAA,IACD,OAAO,UAAU,OAAO,OAAO,OAAO,KAAK,KAAe;AAAA,GAC1D;AAAA;AAGF,eAAsB,QAAQ,CAC7B,KACA,IACA,OAAkC,CAAC,GACL;AAAA,EAC9B,MAAM,QAAQ,MAAM,QAAQ,KAAK,OAAO,KAAK,EAAE,KAAK,GAAG,GAAG,KAAK,WAAW,CAAC;AAAA,EAC3E,OAAO,SAAS;AAAA;AAGjB,eAAsB,OAAO,CAC5B,KACA,IACA,OAAkC,CAAC,GACjB;AAAA,EAClB,MAAM,QAAQ,MAAM,SAAS,KAAK,IAAI,IAAI;AAAA,EAC1C,IAAI,CAAC;AAAA,IAAO,MAAM,SAAS,KAAK,EAAE;AAAA,EAClC,OAAO;AAAA;AAGR,eAAsB,QAAQ,CAC7B,KACA,OAAe,CAAC,GACI;AAAA,EACpB,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,IAAI,SAAS,IAAI,WAAW,KAC3B,OAAO,KAAK,KAAK,QAAQ,KAAK,WAAkC,GAChE;AAAA,SACI,IAAI;AAAA,SACH,KAAK,aAAa,EAAE,YAAY,KAAK,WAAW,IAAI,CAAC;AAAA,IAC1D,CACD;AAAA,IACA,IAAI,KAAK,SAAS;AAAA,MAAW,SAAS,OAAO,KAAK,KAAK,IAAa;AAAA,IACpE,IAAI,KAAK,SAAS;AAAA,MAAW,SAAS,OAAO,KAAK,KAAK,IAAc;AAAA,IACrE,IAAI,KAAK,UAAU;AAAA,MAAW,SAAS,OAAO,MAAM,KAAK,KAAe;AAAA,IACxE,MAAM,QAAQ,MAAM,OAAO,QAAQ;AAAA,IACnC,OAAO,MAAM,IAAI,CAAC,aAAa,OAAO,KAAK,QAAkB,CAAC;AAAA,GAC9D;AAAA;AAGF,eAAsB,SAAS,CAC9B,KACA,QACA,OAAe,CAAC,GACc;AAAA,EAC9B,OAAO,SAAS,MAAM,SAAS,KAAK,KAAK,MAAM,QAAQ,OAAO,EAAE,CAAC;AAAA,EACjE,OAAO;AAAA;AAGR,eAAsB,cAAc,CACnC,KACA,QACA,OAAkC,CAAC,GACjB;AAAA,EAClB,OAAO,IAAI,KAAK,YACf,IAAI,WAAW,eAAe,OAAO,KAAK,QAAQ,KAAK,WAAW,GAAG;AAAA,OACjE,IAAI;AAAA,EACR,CAAC,CACF;AAAA;AAGD,eAAsB,MAAM,CAC3B,KACA,QACA,OAAkC,CAAC,GAChB;AAAA,EACnB,MAAM,QAAQ,MAAM,QAAQ,KAAK,OAAO,KAAK,QAAQ,KAAK,WAAW,GAAG;AAAA,IACvE,KAAK;AAAA,EACN,CAAC;AAAA,EACD,OAAO,UAAU,QAAQ,UAAU;AAAA;;;ACzEpC,eAAsB,QAAQ,CAC7B,KACA,OAAe,CAAC,GACQ;AAAA,EACxB,MAAM,SAAS,WAAW,MAAM,IAAI,WAAW;AAAA,EAC/C,OAAO,OAAO,SAAS,MAAM,QAAQ,IAAI;AAAA,IACxC,SAAS,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,MAAM,KAAK,QAAQ,EAAE,KAAK,EAAE;AAAA,MAC5B,OAAO,OAAO;AAAA,MACd,MAAM,OAAO;AAAA,MACb,aAAa,KAAK;AAAA,IACnB,CAAC;AAAA,IACD,eAAe,KAAK,KAAK,QAAQ;AAAA,MAChC,aAAa,KAAK;AAAA,IACnB,CAAC;AAAA,EACF,CAAC;AAAA,EACD,OAAO,OAAO,OAAO,OAAO,MAAM;AAAA;AAGnC,eAAsB,gBAAgB,CACrC,KACA,OAAe,CAAC,GACc;AAAA,EAC9B,MAAM,YAAa,KAAK,WAAkC;AAAA,EAC1D,IAAI,CAAC,IAAI,MAAM,cAAc,cAAc,OAAO;AAAA,IACjD,MAAM,IAAI,UACT,sBAAsB,IAAI,uBAAuB,0BAClD;AAAA,EACD;AAAA,EACA,MAAM,YAAa,KAAK,aAA4C;AAAA,EACpE,MAAM,SAAS,cAAc,QAAQ,CAAC,KAAK,IAAI,CAAC,WAAW,KAAK;AAAA,EAChE,MAAM,YAAY,GAAG,aAAa;AAAA,EAClC,MAAM,QAAQ,YAAY,KAAK,OAA6B,IAAI,WAAW;AAAA,EAC3E,MAAM,OAAO,cAAc,QAAQ,QAAQ;AAAA,EAE3C,IAAI;AAAA,EACJ,IAAI,KAAK,OAAO;AAAA,IACf,QAAQ,WAAW,aAAa,KAAK,OAAiB,SAAS;AAAA,IAC/D,IAAI,OAAO,WAAW,OAAO,QAAQ;AAAA,MACpC,MAAM,IAAI,UACT,4BAA4B,OAAO,wBAAwB,OAAO,UAClE,EAAE,YAAY,IAAI,KAAK,CACxB;AAAA,IACD;AAAA,IAEA,QAAQ;AAAA,MACP,KAAK,OAAO,IAAI,CAAC,OAAO,WAAW;AAAA,WAC/B,OAAO,YACT,OAAO,MAAM,GAAG,KAAK,EAAE,IAAI,CAAC,UAAU,MAAM,CAAC,UAAU,OAAO,EAAE,CAAC,CAClE;AAAA,SACC,QAAQ,GAAG,OAAO,OAAO,OAAO;AAAA,MAClC,EAAE;AAAA,IACH;AAAA,EACD;AAAA,EAEA,MAAM,OAAO,OAAO,YACnB,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,cAAc,QAAQ,IAAI,EAAE,CAAC,CAC5D;AAAA,EACA,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,IACrC,QAAQ,aACP,UAAS,KAAK,MAAM,IAAI,KAAK,SAAS,WACtC,KACD;AAAA,IACA;AAAA,IACA,OAAO,QAAQ;AAAA,IACf,aAAa,KAAK;AAAA,EACnB,CAAC;AAAA,EAED,MAAM,QAAQ,UAAU,MAAM,GAAG,KAAK;AAAA,EACtC,MAAM,OAAO,MAAM,GAAG,EAAE;AAAA,EACxB,IAAI,UAAU,UAAU,SAAS,CAAC,MAAM;AAAA,IACvC,OAAO,EAAE,OAAO,YAAY,KAAK;AAAA,EAClC;AAAA,EAEA,MAAM,SAAS,OAAO,IAAI,CAAC,UAAU;AAAA,IACpC,MAAM,QAAQ,KAAK;AAAA,IACnB,IAAI,UAAU,QAAQ,UAAU,WAAW;AAAA,MAC1C,MAAM,IAAI,UACT,sBAAsB,oCAAoC,IAAI,YAC7D,wCACF;AAAA,IACD;AAAA,IACA,OAAO;AAAA,GACP;AAAA,EACD,OAAO,EAAE,OAAO,YAAY,aAAa,EAAE,KAAK,WAAW,OAAO,CAAC,EAAE;AAAA;;;ACjFtE,eAAe,cAAc,CAC5B,KACA,IACA,QACA,QACA,iBACkB;AAAA,EAClB,MAAM,UAAU,MAAM,IAAI,KAAK,YAC9B,IAAI,WAAW,iBAAiB,QAAQ,QAAQ;AAAA,OAC5C,IAAI;AAAA,IACP,gBAAgB;AAAA,EACjB,CAAC,CACF;AAAA,EACA,IAAI;AAAA,IAAS,OAAO,OAAO,KAAK,OAAiB;AAAA,EAEjD,IAAI,oBAAoB,WAAW;AAAA,IAClC,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,IAC9C,IAAI,SAAS;AAAA,MACZ,MAAM,IAAI,oBACT,YAAY,OAAO,EAAE,SAAS,IAAI,uBAAuB,OACxD,QAAQ,OACT,UAAU,iDACV;AAAA,QACC,YAAY,IAAI;AAAA,QAChB;AAAA,QACA;AAAA,QACA,eACC,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAAA,MAC1D,CACD;AAAA,IACD;AAAA,EACD;AAAA,EACA,MAAM,SAAS,KAAK,EAAE;AAAA;AAIvB,SAAS,gBAAgB,CAAC,KAAgC;AAAA,EACzD,MAAM,MAAc,EAAE,WAAW,IAAI,KAAO;AAAA,EAC5C,IAAI,IAAI,UAAU,aAAa,IAAI,OAAO,WAAW;AAAA,IACpD,IAAI,YAAY,IAAI;AAAA,EACrB;AAAA,EACA,MAAM,SAAiB,EAAE,MAAM,IAAI;AAAA,EACnC,IAAI,IAAI;AAAA,IAAO,OAAO,OAAO,EAAE,SAAS,EAAE;AAAA,EAC1C,OAAO;AAAA;AAGR,eAAsB,MAAM,CAC3B,KACA,QACkB;AAAA,EAClB,MAAM,WAAW,WAAW,KAAK,MAAM;AAAA,EACvC,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,MAAM,IAAI,WAAW,UAAU,UAAsB;AAAA,SACjD,IAAI;AAAA,IACR,CAAC;AAAA,IACD,OAAO,OAAO,KAAK,QAAQ;AAAA,GAC3B;AAAA;AAGF,eAAsB,UAAU,CAC/B,KACA,QACoB;AAAA,EACpB,IAAI,OAAO,WAAW;AAAA,IAAG,OAAO,CAAC;AAAA,EACjC,MAAM,YAAY,OAAO,IAAI,CAAC,UAAU,WAAW,KAAK,KAAK,CAAC;AAAA,EAC9D,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,MAAM,IAAI,WAAW,WAAW,WAAyB;AAAA,SACrD,IAAI;AAAA,IACR,CAAC;AAAA,IACD,OAAO,UAAU,IAAI,CAAC,aAAa,OAAO,KAAK,QAAQ,CAAC;AAAA,GACxD;AAAA;AAGF,eAAsB,MAAM,CAC3B,KACA,IACA,OACA,OAAe,CAAC,GACE;AAAA,EAClB,MAAM,kBAAkB,KAAK;AAAA,EAC7B,IAAI,oBAAoB,aAAa,CAAC,IAAI,OAAO;AAAA,IAChD,MAAM,IAAI,UACT,yDAAyD,IAAI,gBAC9D;AAAA,EACD;AAAA,EACA,MAAM,UAAU,SAAS,KAAK,KAAK;AAAA,EACnC,MAAM,SAAS,aACd;AAAA,IACC,KAAK;AAAA,OACD,oBAAoB,YAAY,CAAC,IAAI,EAAE,SAAS,gBAAgB;AAAA,EACrE,GACA,KAAK,GAAG,CACT;AAAA,EACA,OAAO,eAAe,KAAK,IAAI,QAAQ,SAAS,eAAe;AAAA;AAGhE,eAAsB,UAAU,CAC/B,KACA,QACA,OACkB;AAAA,EAClB,cAAc,KAAK,cAAc,MAAM;AAAA,EACvC,MAAM,UAAU,SAAS,KAAK,KAAK;AAAA,EACnC,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,MAAM,SAAS,MAAM,IAAI,WAAW,WACnC,OAAO,KAAK,MAAM,GAClB,SACA,KAAK,IAAI,cAAc,CACxB;AAAA,IACA,OAAO,OAAO;AAAA,GACd;AAAA;AAGF,eAAsB,UAAU,CAC/B,KACA,IACkB;AAAA,EAClB,MAAM,UAAU,MAAM,IAAI,KAAK,YAC9B,IAAI,WAAW,iBAAiB,EAAE,KAAK,GAAG,GAAG,KAAK,IAAI,cAAc,CAAC,CACtE;AAAA,EACA,IAAI,CAAC;AAAA,IAAS,MAAM,SAAS,KAAK,EAAE;AAAA,EACpC,OAAO,OAAO,KAAK,OAAiB;AAAA;AAGrC,eAAsB,cAAc,CACnC,KACA,QACkB;AAAA,EAClB,cAAc,KAAK,kBAAkB,MAAM;AAAA,EAC3C,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,MAAM,SAAS,MAAM,IAAI,WAAW,WAAW,QAAkB;AAAA,SAC7D,IAAI;AAAA,IACR,CAAC;AAAA,IACD,OAAO,OAAO;AAAA,GACd;AAAA;AAGF,eAAsB,SAAS,CAC9B,KACA,IACkB;AAAA,EAClB,IAAI,CAAC,IAAI;AAAA,IAAa,OAAO,WAAW,KAAK,EAAE;AAAA,EAC/C,OAAO,eACN,KACA,IACA,aAAa,EAAE,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC,GACnC,iBAAiB,GAAG,GACpB,SACD;AAAA;AAGD,eAAsB,UAAU,CAC/B,KACA,QACkB;AAAA,EAClB,cAAc,KAAK,cAAc,MAAM;AAAA,EACvC,IAAI,CAAC,IAAI;AAAA,IAAa,OAAO,eAAe,KAAK,MAAM;AAAA,EACvD,OAAO,IAAI,KAAK,YAAY;AAAA,IAC3B,MAAM,SAAS,MAAM,IAAI,WAAW,WACnC,OAAO,KAAK,MAAM,GAClB,iBAAiB,GAAG,GACpB,KAAK,IAAI,cAAc,CACxB;AAAA,IACA,OAAO,OAAO;AAAA,GACd;AAAA;AAGF,eAAsB,OAAO,CAC5B,KACA,IACkB;AAAA,EAClB,IAAI,CAAC,IAAI,OAAO,WAAW;AAAA,IAC1B,MAAM,IAAI,UAAU,aAAa,IAAI,0BAA0B;AAAA,EAChE;AAAA,EACA,MAAM,MAAc,EAAE,WAAW,KAAK;AAAA,EACtC,IAAI,IAAI,OAAO;AAAA,IAAW,IAAI,YAAY;AAAA,EAC1C,IAAI,IAAI;AAAA,IAAS,IAAI,YAAY,IAAI;AAAA,EACrC,MAAM,SAAiB,EAAE,MAAM,IAAI;AAAA,EACnC,IAAI,IAAI;AAAA,IAAO,OAAO,OAAO,EAAE,SAAS,EAAE;AAAA,EAC1C,OAAO,eAAe,KAAK,IAAI,EAAE,KAAK,GAAG,GAAG,QAAQ,SAAS;AAAA;;;AC/J9D,SAAS,UAAU,CAAC,QAA0B,MAA8B;AAAA,EAC3E,MAAM,SAAS;AAAA,EACf,IAAI,OAAO,OAAO,OAAO;AAAA,IAAY,OAAO,OAAO,GAAG,IAAI;AAAA,EAC1D,MAAM,KAAK;AAAA,EACX,IAAI,SAAS,aAAa,GAAG,iBAAiB,MAAM;AAAA,IACnD,MAAM,IAAI,UACT,kCAAkC,GAAG,uCACpC,IAAI,mDACN;AAAA,EACD;AAAA,EACA,OAAO;AAAA;AAqBD,SAAS,aAAyC,CACxD,QACA,YACA,UAA2D,CAAC,GACZ;AAAA,EAChD,MAAM,KAAK,WAAW,QAAQ,QAAQ,EAAE;AAAA,EACxC,OAAO,MAAM,IAAI,YAAY,OAAmC;AAAA;AAOjE,SAAS,KAAK,CAAC,KAAwB,SAAkB;AAAA,EACxD,OAAO;AAAA,IACN,YAAY,IAAI;AAAA,IAChB,IAAI,IAAI;AAAA,IACR,KAAK,IAAI;AAAA,IACT,SAAS,IAAI;AAAA,IAEb,aAAa,CAAC,UACb,QAAQ,EAAE,SAAS,MAAM,CAAC;AAAA,IAC3B,IAAI,CAAC,QAAiB,QAAQ,EAAE,OAAO,IAAa,CAAC;AAAA,IACrD,MAAM,CAAC,cAA2B,CAAC,MAClC,eAAe,IAAI,IAAI,IAAI,YAAY;AAAA,SACnC,IAAI;AAAA,SACJ;AAAA,IACJ,CAAC;AAAA,IAEF,UAAU,CAAC,IAAa,SACvB,SAAS,KAAK,IAAI,IAAI;AAAA,IACvB,SAAS,CAAC,IAAa,SACtB,QAAQ,KAAK,IAAI,IAAI;AAAA,IACtB,WAAW,CAAC,QAAkB,SAC7B,UAAU,KAAK,QAAQ,IAAI;AAAA,IAC5B,UAAU,CAAC,SAAkB,SAAS,KAAK,IAAI;AAAA,IAE/C,QAAQ,CAAC,WAAoB,OAAO,KAAK,MAAM;AAAA,IAC/C,YAAY,CAAC,WAA+B,WAAW,KAAK,MAAM;AAAA,IAClE,QAAQ,CAAC,IAAa,OAAgB,SACrC,OAAO,KAAK,IAAI,OAAO,IAAI;AAAA,IAC5B,YAAY,CAAC,QAAiB,UAC7B,WAAW,KAAK,QAAQ,KAAK;AAAA,IAE9B,QAAQ,CAAC,OAAgB,UAAU,KAAK,EAAE;AAAA,IAC1C,YAAY,CAAC,WAAoB,WAAW,KAAK,MAAM;AAAA,IACvD,YAAY,CAAC,OAAgB,WAAW,KAAK,EAAE;AAAA,IAC/C,gBAAgB,CAAC,WAAoB,eAAe,KAAK,MAAM;AAAA,IAC/D,SAAS,CAAC,OAAgB,QAAQ,KAAK,EAAE;AAAA,IAEzC,OAAO,CAAC,QAAkB,SACzB,eAAe,KAAK,QAAQ,IAAI;AAAA,IACjC,QAAQ,CAAC,QAAiB,SACzB,OAAO,KAAK,QAAQ,IAAI;AAAA,IACzB,UAAU,CAAC,SAAkB,SAAS,KAAK,IAAI;AAAA,IAC/C,kBAAkB,CAAC,SAAkB,iBAAiB,KAAK,IAAI;AAAA,EAChE;AAAA;AAUD,SAAS,KAAU,CAClB,IACA,YACA,SACuB;AAAA,EACvB,MAAM,MAAM,cAAc,IAAI,YAAY,OAAO;AAAA,EACjD,MAAM,UAAmB,CAAC,YACzB,MAAM,IAAI,YAAY,KAAK,YAAY,QAAQ,CAAC;AAAA,EACjD,MAAM,MAAM,MAAM,KAAK,OAAO;AAAA,EAC9B,MAAM,aAAa,IAAI;AAAA,EAUvB,OAAO,IAAI,MAAM,KAAK;AAAA,IACrB,GAAG,CAAC,QAAQ,KAAK,UAAU;AAAA,MAC1B,IAAI,QAAQ,IAAI,QAAQ,GAAG;AAAA,QAAG,OAAO,QAAQ,IAAI,QAAQ,KAAK,QAAQ;AAAA,MACtE,MAAM,QAAS,WAAiC;AAAA,MAChD,OAAO,OAAO,UAAU,aAAa,MAAM,KAAK,UAAU,IAAI;AAAA;AAAA,IAE/D,GAAG,CAAC,QAAQ,KAAK;AAAA,MAChB,OAAO,QAAQ,IAAI,QAAQ,GAAG,KAAK,OAAQ;AAAA;AAAA,EAE7C,CAAC;AAAA;;ACnKF,qBAAS;AACT,cAAS;;;ACDT,qBAAS;AACT,cAAS;AAIT,IAAM,SAAS;AAMR,SAAS,WAAU,CAAC,OAAmC;AAAA,EAC7D,OACC,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,cAAc;AAAA;AAK5C,SAAS,gBAAgB,CAAC,OAAiC;AAAA,EACjE,OAAO,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK;AAAA;AAI/C,SAAS,eAAe,CAAC,OAAyB;AAAA,EACxD,OAAO,YAAW,KAAK,KAAK,iBAAiB,KAAK;AAAA;AAU5C,SAAS,WAAW,CAAC,OAAsC;AAAA,EACjE,IAAI,YAAW,KAAK;AAAA,IAAG,OAAO;AAAA,EAC9B,IAAI,iBAAiB,KAAK;AAAA,IAAG,OAAO,UAAS,oBAAoB,KAAK;AAAA,EACtE;AAAA;AAGD,SAAS,QAAQ,CAAC,OAAwB;AAAA,EACzC,IAAI,UAAU;AAAA,IAAM,OAAO;AAAA,EAC3B,IAAI,UAAU;AAAA,IAAW,OAAO;AAAA,EAChC,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,cAAc,KAAK,UAAU,KAAK;AAAA,EACxE,OAAO,KAAK,OAAO;AAAA;AAWb,SAAS,UAAU,CAAC,OAAgB,QAAQ,OAAiB;AAAA,EACnE,MAAM,OAAO,YAAY,KAAK;AAAA,EAC9B,IAAI;AAAA,IAAM,OAAO;AAAA,EACjB,MAAM,IAAI,eACT,GAAG,mEAAmE,SAAS,KAAK,KACpF,EAAE,IAAI,OAAO,MAAM,CAAC,KAAK,EAAE,CAC5B;AAAA;AAUM,SAAS,WAAW,CAC1B,QACA,QAAQ,OACK;AAAA,EACb,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,UAAU,WAAW,OAAO,KAAK,CAAC;AAAA;AAgBpD,SAAS,aAAa,GAAG;AAAA,EAC/B,OAAO,GACL,OAA0B,iBAAiB;AAAA,IAC3C,OAAO;AAAA,EACR,CAAC,EACA,UAAU,CAAC,UAAU,WAAW,KAAK,CAAC;AAAA;;;AD1FlC,SAAS,QAAQ,GAAG;AAAA,EAC1B,OAAO,GACL,OAAiB,aAAY,EAAE,OAAO,sBAAsB,CAAC,EAC7D,KAAK,EAAE,UAAU,WAAW,CAAC;AAAA;AAOzB,SAAS,EAAE,GAAG;AAAA,EACpB,OAAO,SAAS,EAAE,QAAQ,MAAM,IAAI,SAAU;AAAA;AAOxC,SAAS,UAAU,GAAG;AAAA,EAC5B,OAAO;AAAA,IACN,WAAW,GAAE,KAAK,EAAE,QAAQ,MAAM,IAAI,IAAM;AAAA,IAC5C,WAAW,GAAE,KAAK,EAAE,QAAQ,MAAM,IAAI,IAAM;AAAA,EAC7C;AAAA;AAOM,SAAS,UAAU,GAAG;AAAA,EAC5B,OAAO,EAAE,WAAW,GAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE;AAAA;AAQhD,SAAS,cAAc,GAAG;AAAA,EAChC,OAAO,EAAE,SAAS,GAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;AAAA;AAQ7C,SAAS,MAA6D,CAC5E,QAAe,SAAS,GACvB;AAAA,EACD,OAAO;AAAA,IACN,WAAW,MAAM,SAAS,EAAE,QAAQ,IAAI;AAAA,IACxC,WAAW,MAAM,SAAS,EAAE,QAAQ,IAAI;AAAA,IACxC,WAAW,MAAM,SAAS,EAAE,QAAQ,IAAI;AAAA,EACzC;AAAA;AAIM,IAAM,eAAe;AAAA,EAC3B,IAAI;AAAA,EACJ,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AACZ;;AEpEA,SAAS,SAAS,CAAC,MAA8C;AAAA,EAChE,OAAO,OAAQ,KAAuB,kBAAkB;AAAA;AAgCzD,eAAsB,eAAkB,CACvC,MACA,IACA,SACa;AAAA,EACb,IAAI;AAAA,IACH,IAAI,UAAU,IAAI,GAAG;AAAA,MACpB,IAAI,KAAK,cAAc,GAAG;AAAA,QACzB,IAAI,SAAS;AAAA,UACZ,MAAM,IAAI,UACT,sEACC,6DACA,gEACA,sBACF;AAAA,QACD;AAAA,QACA,OAAO,MAAM,GAAG,IAAI;AAAA,MACrB;AAAA,MACA,OAAO,MAAM,KAAK,gBAAgB,IAAI,OAAO;AAAA,IAC9C;AAAA,IAEA,MAAM,UAAU,KAAK,aAAa;AAAA,IAClC,IAAI;AAAA,MACH,OAAO,MAAM,QAAQ,gBAAgB,IAAI,OAAO;AAAA,cAC/C;AAAA,MACD,MAAM,QAAQ,WAAW;AAAA;AAAA,IAEzB,OAAO,OAAO;AAAA,IACf,MAAM,YAAY,KAAK;AAAA;AAAA;",
|
|
26
|
+
"debugId": "AC287DF6F57068F864756E2164756E21",
|
|
21
27
|
"names": []
|
|
22
28
|
}
|
|
@@ -6,13 +6,13 @@ export type TransactionHost = MongoClient | ClientSession;
|
|
|
6
6
|
* throws, and a MongoDB error turned into a `DataError` on the way out. The
|
|
7
7
|
* session is the argument, and **every operation inside has to be given it**:
|
|
8
8
|
* MongoDB has no ambient session, so an operation without one runs outside the
|
|
9
|
-
* transaction and is not rolled back. `
|
|
10
|
-
*
|
|
9
|
+
* transaction and is not rolled back. `collection.withSession(session)` is how
|
|
10
|
+
* a collection takes it.
|
|
11
11
|
*
|
|
12
12
|
* ```ts
|
|
13
13
|
* await withTransaction(client, async (session) => {
|
|
14
|
-
* const team = await teams.
|
|
15
|
-
* await users.
|
|
14
|
+
* const team = await teams.withSession(session).create({ name: 'Core' });
|
|
15
|
+
* await users.withSession(session).update(userId, { teamId: team._id });
|
|
16
16
|
* });
|
|
17
17
|
* ```
|
|
18
18
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxgt/mongo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A typed MongoDB collection from a Zod schema: its indexes and $jsonSchema validator synced idempotently, a typed repository with pagination, transactions, optimistic locking, soft delete and its own errors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { Db } from 'mongodb';
|
|
2
|
-
import type { z } from 'zod';
|
|
3
|
-
import { type CollectionDefinition } from '../definition/define-collection';
|
|
4
|
-
import type { Repository, RepositoryOptions } from './types';
|
|
5
|
-
/**
|
|
6
|
-
* A repository over one collection: typed reads and writes by `_id` or by
|
|
7
|
-
* filter, pagination, soft delete, optimistic locking, audit stamps, and
|
|
8
|
-
* MongoDB errors turned into this package's.
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* const users = createRepository(db, usersCollection);
|
|
12
|
-
* const ada = await users.create({ email: 'ada@example.com' });
|
|
13
|
-
* await users.update(ada._id, { name: 'Ada' }, { expectedVersion: ada.version });
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* Every operation runs in the repository's session, which `with(session)`
|
|
17
|
-
* sets: MongoDB has no ambient session, so a write inside a transaction that
|
|
18
|
-
* was not given one is not part of it and is not rolled back.
|
|
19
|
-
*/
|
|
20
|
-
export declare function createRepository<Schema extends z.ZodObject>(db: Db, definition: CollectionDefinition<Schema>, options?: RepositoryOptions): Repository<CollectionDefinition<Schema>>;
|
|
21
|
-
//# sourceMappingURL=create-repository.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-repository.d.ts","sourceRoot":"","sources":["../../src/repository/create-repository.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,EAAE,EAAY,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAEN,KAAK,oBAAoB,EAEzB,MAAM,iCAAiC,CAAC;AAiBzC,OAAO,KAAK,EAAkB,UAAU,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAsB7E;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,SAAS,CAAC,CAAC,SAAS,EAC1D,EAAE,EAAE,EAAE,EACN,UAAU,EAAE,oBAAoB,CAAC,MAAM,CAAC,EACxC,OAAO,GAAE,iBAAsB,GAC7B,UAAU,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAI1C"}
|