@m1212e/rumble 0.23.21 → 0.23.22

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/out/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["EmptyFilter","makeDefaultName","normalize","BaseEmailAddressResolver","EmailAddressResolver","EmailAddressResolver","packagejson.version","createYoga","nativeCreateYoga"],"sources":["../lib/types/rumbleError.ts","../lib/helpers/asserts.ts","../lib/helpers/mapNullFieldsToUndefined.ts","../package.json","../lib/helpers/errorLogging.ts","../lib/helpers/mergeFilters.ts","../lib/helpers/sanitizeFilterValue.ts","../lib/helpers/sqlTypes/types.ts","../lib/helpers/sqlTypes/distinctValuesFromSQLType.ts","../lib/helpers/tableHelpers.ts","../lib/helpers/telemetry.ts","../lib/abilityBuilder.ts","../lib/args/orderArg.ts","../lib/enum.ts","../lib/helpers/sqlTypes/mapSQLTypeToTSType.ts","../lib/args/whereArg.ts","../lib/client/client.ts","../lib/context.ts","../lib/helpers/protoMapper.ts","../lib/countQuery.ts","../lib/helpers/sofaOpenAPIWebhookDocs.ts","../lib/helpers/tracing.ts","../lib/helpers/sqlTypes/mapDrizzleTypeToGraphQlType.ts","../lib/helpers/determineDialectFromSchema.ts","../lib/search.ts","../lib/object.ts","../lib/pubsub.ts","../lib/query.ts","../lib/args/whereArgsImplementer.ts","../lib/runtimeFiltersPlugin/filterTypes.ts","../lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts","../lib/scalars/addressValidation.ts","../lib/scalars/address.ts","../lib/scalars/emailAddress.ts","../lib/scalars/personName.ts","../lib/scalars/phoneNumber.ts","../lib/schemaBuilder.ts","../lib/rumble.ts"],"sourcesContent":["import { GraphQLError } from \"graphql\";\n/**\n * An error that gets raised by rumble whenever something does not go according to plan.\n * Mostly internals, configuration errors or other unexpected things.\n */\nexport class RumbleError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RumbleError\";\n }\n}\n\n/**\n * An error that gets raised by rumble whenever an error occurs in a resolver, containing\n * information safely exposeable to the user.\n * E.g. the assert helpers issue these.\n */\nexport class RumbleErrorSafe extends GraphQLError {}\n","import { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n * schemaBuilder.queryFields((t) => {\n return {\n findFirstUser: t.drizzleField({\n type: UserRef,\n resolve: (query, root, args, ctx, info) => {\n return (\n db.query.users\n .findFirst({\n ...query,\n where: ctx.abilities.users.filter(\"read\").single.where,\n })\n // note that we need to manually raise an error if the value is not found\n .then(assertFindFirstExists)\n );\n },\n }),\n };\n });\n * ```\n */\nexport const assertFindFirstExists = <T>(value: T | undefined): T => {\n if (!value) {\n throw new RumbleErrorSafe(\"Value not found but required (findFirst)\");\n }\n return value;\n};\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n schemaBuilder.mutationFields((t) => {\n return {\n updateUsername: t.drizzleField({\n type: UserRef,\n args: {\n userId: t.arg.int({ required: true }),\n newName: t.arg.string({ required: true }),\n },\n resolve: (query, root, args, ctx, info) => {\n return db\n .update(schema.users)\n .set({\n name: args.newName,\n })\n .where(\n and(\n eq(schema.users.id, args.userId),\n ctx.abilities.users.filter(\"update\").single.where\n )\n )\n .returning({ id: schema.users.id, name: schema.users.name })\n // note that we need to manually raise an error if the value is not found\n .then(assertFirstEntryExists);\n },\n }),\n };\n });\n * ```\n */\nexport const assertFirstEntryExists = <T>(value: T[]): T => {\n const v = value.at(0);\n if (!v)\n throw new RumbleErrorSafe(\"Value not found but required (firstEntry)\");\n return v;\n};\n","/**\n * Helper to map null fields to undefined\n * @param obj The object to map\n * @returns The mapped object with all fields of 'null' transformed to 'undefined'\n * \n * This becomes useful for update mutations where you do not want to pass null (unset value in db)\n * but undefined (do not touch value in db) in case of a value not beeing set in the args of said mutation\n * @example\n * ```ts\n * updateUser: t.drizzleField({\n type: User,\n args: {\n id: t.arg.string({ required: true }),\n email: t.arg.string(),\n lastName: t.arg.string(),\n firstName: t.arg.string(),\n },\n resolve: async (query, root, args, ctx, info) => {\n const mappedArgs = mapNullFieldsToUndefined(args);\n const user = await db.transaction(async (tx) => {\n const user = await tx\n .update(schema.user)\n .set({\n\n // email: args.email ?? undefined,\n // lastName: args.lastName ?? undefined,\n // firstName: args.firstName ?? undefined,\n\n // becomes this\n\n email: mappedArgs.email,\n lastName: mappedArgs.lastName,\n firstName: mappedArgs.firstName,\n })\n .returning()\n .then(assertFirstEntryExists);\n return user;\n });\n\n pubsub.updated(user.id);\n\n return db.query.user\n .findFirst(\n query(\n ctx.abilities.user.filter('read').merge(\n {\n where: { id: user.id },\n }\n 1).query.single,\n ),\n )\n .then(assertFindFirstExists);\n },\n }),\n * \n * \n * ```\n */\nexport function mapNullFieldsToUndefined<T extends object>(obj: T) {\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [\n key,\n value === null ? undefined : value,\n ]),\n ) as {\n [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>;\n };\n}\n","","import type { GraphQLError } from \"graphql\";\n\n/**\n * Shape of a single error entry in a log's `errors` array, following\n * OpenTelemetry's exception semantic conventions\n * (https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-logs/).\n */\nexport interface LoggedException {\n \"exception.type\": string;\n \"exception.message\": string;\n \"exception.stacktrace\"?: string;\n path?: ReadonlyArray<string | number>;\n extensions?: Record<string, unknown>;\n}\n\nfunction hasMessage(error: unknown): error is { message: unknown } {\n return typeof error === \"object\" && error !== null && \"message\" in error;\n}\n\nfunction toLoggedException(error: unknown): LoggedException {\n if (hasMessage(error)) {\n const gqlError = error as Partial<GraphQLError> & Error;\n return {\n \"exception.type\": gqlError.constructor?.name ?? gqlError.name ?? \"Error\",\n \"exception.message\": String(gqlError.message),\n ...(gqlError.stack ? { \"exception.stacktrace\": gqlError.stack } : {}),\n ...(gqlError.path ? { path: gqlError.path } : {}),\n ...(gqlError.extensions && Object.keys(gqlError.extensions).length > 0\n ? { extensions: gqlError.extensions }\n : {}),\n };\n }\n return {\n \"exception.type\": \"UnknownError\",\n \"exception.message\": String(error),\n };\n}\n\n/**\n * Every erroneous rumble log carries the same `errors` array shape,\n * whether it originates from a thrown exception (single-element array)\n * or a GraphQL `ExecutionResult.errors` list (multi-element array).\n */\nexport function errorsLogField(errors: readonly unknown[]): {\n errors: LoggedException[];\n} {\n return { errors: errors.map(toLoggedException) };\n}\n\nexport function errorLogField(error: unknown): { errors: LoggedException[] } {\n return errorsLogField([error]);\n}\n","import { toMerged } from \"es-toolkit\";\n\n// See the comment on `EmptyFilter` in `./sanitizeFilterValue.ts` for why this\n// is recreated locally instead of imported from drizzle-orm.\nconst EmptyFilter = Symbol.for(\"drizzle:EmptyFilter\");\n\n/**\n * Normalizes drizzle-orm's `EmptyFilter` sentinel to `undefined` so it's\n * treated as \"no filter\" rather than a real filter value to combine with\n * AND/OR — otherwise merging an unrestricted (EmptyFilter) base filter with\n * a real `where` would needlessly wrap it as `{ AND: [EmptyFilter, where] }`\n * instead of just `where`.\n */\nfunction realWhere(where: unknown) {\n return where === EmptyFilter ? undefined : where;\n}\n\nexport function mergeFilters<\n FilterA extends Record<string, any>,\n FilterB extends Record<string, any>,\n>(\n filterA?: Partial<FilterA>,\n filterB?: Partial<FilterB>,\n mode: \"AND\" | \"OR\" = \"AND\",\n) {\n const filterAWhere = realWhere(filterA?.where);\n const filterBWhere = realWhere(filterB?.where);\n\n const where =\n filterAWhere && filterBWhere\n ? mode === \"OR\"\n ? { OR: [filterAWhere, filterBWhere] }\n : { AND: [filterAWhere, filterBWhere] }\n : (filterAWhere ?? filterBWhere);\n\n const columns =\n filterA?.columns || filterB?.columns\n ? new Set(\n [\n Object.entries(filterA?.columns ?? {}),\n Object.entries(filterB?.columns ?? {}),\n ]\n .flat()\n .filter(([, v]) => v === true)\n .map(([k]) => k),\n )\n .entries()\n .reduce(\n (acc, [key]) => {\n acc[key] = true;\n return acc;\n },\n {} as Record<string, true>,\n )\n : undefined;\n\n const extras =\n filterA?.extras || filterB?.extras\n ? toMerged(filterA?.extras ?? {}, filterB?.extras ?? {})\n : undefined;\n\n const orderBy =\n filterA?.orderBy || filterB?.orderBy\n ? toMerged(filterA?.orderBy ?? {}, filterB?.orderBy ?? {})\n : undefined;\n\n const limit =\n mode === \"OR\"\n ? filterA?.limit === undefined || filterB?.limit === undefined\n ? undefined\n : Math.max(filterA.limit, filterB.limit)\n : filterA?.limit || filterB?.limit\n ? Math.min(filterA?.limit ?? Infinity, filterB?.limit ?? Infinity)\n : undefined;\n\n const offset =\n mode === \"OR\"\n ? filterA?.offset === undefined || filterB?.offset === undefined\n ? undefined\n : Math.min(filterA.offset, filterB.offset)\n : filterA?.offset || filterB?.offset\n ? Math.min(filterA?.offset ?? Infinity, filterB?.offset ?? Infinity)\n : undefined;\n\n const with_ =\n filterA?.with || filterB?.with\n ? toMerged(filterA?.with ?? {}, filterB?.with ?? {})\n : undefined;\n\n return {\n where,\n columns,\n extras,\n orderBy,\n limit,\n offset,\n with: with_,\n } as unknown as FilterA & FilterB;\n}\n","const EmptyFilter = Symbol.for(\"drizzle:EmptyFilter\");\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function sanitizeFilterValue(value: unknown): unknown {\n if (value === undefined || value === null) return EmptyFilter;\n if (Array.isArray(value)) return value.map(sanitizeFilterValue);\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [\n key,\n sanitizeFilterValue(entry),\n ]),\n );\n }\n return value;\n}\n","import { RumbleError } from \"../../types/rumbleError\";\n\n/**\n * Strips parameter suffixes like `(256)`, `(10,2)` and timezone modifiers\n * (`with time zone`, `without time zone`) from raw getSQLType() output so\n * every classifier works on the base type name only.\n */\nexport function normalizeSQLType(raw: string): string {\n return raw\n .replace(/\\s*with(?:out)?\\s+time\\s+zone/i, \"\")\n .replace(/\\s*\\([^)]*\\)/, \"\")\n .trim()\n .toLowerCase();\n}\n\nconst intLikeSQLTypeStrings = [\n \"serial\",\n \"int\",\n \"integer\",\n \"tinyint\",\n \"smallint\",\n \"mediumint\",\n \"int2\",\n \"int4\",\n \"smallserial\",\n] as const;\n\nexport function isIntLikeSQLTypeString(sqlType: string): boolean {\n return intLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst bigIntLikeSQLTypeStrings = [\n \"bigint\",\n \"bigserial\",\n \"int8\",\n \"bigint unsigned\",\n] as const;\n\nexport function isBigIntLikeSQLTypeString(sqlType: string): boolean {\n return bigIntLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst floatLikeSQLTypeStrings = [\n \"real\",\n \"decimal\",\n \"double\",\n \"float\",\n \"numeric\",\n \"double precision\",\n \"float4\",\n \"float8\",\n \"money\",\n] as const;\n\nexport function isFloatLikeSQLTypeString(sqlType: string): boolean {\n return floatLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst stringLikeSQLTypeStrings = [\n \"string\",\n \"text\",\n \"varchar\",\n \"char\",\n \"character varying\",\n \"character\",\n \"inet\",\n \"cidr\",\n \"macaddr\",\n \"macaddr8\",\n \"interval\",\n \"time\",\n \"year\",\n \"binary\",\n \"varbinary\",\n \"tinytext\",\n \"mediumtext\",\n \"longtext\",\n] as const;\n\nexport function isStringLikeSQLTypeString(sqlType: string): boolean {\n return stringLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst IDLikeSQLTypeStrings = [\"uuid\"] as const;\n\nexport function isIDLikeSQLTypeString(sqlType: string): boolean {\n return IDLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst booleanSQLTypeStrings = [\"boolean\", \"bool\"] as const;\n\nexport function isBooleanSQLTypeString(sqlType: string): boolean {\n return booleanSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateTimeLikeSQLTypeStrings = [\"timestamp\", \"datetime\"] as const;\n\nexport function isDateTimeLikeSQLTypeString(sqlType: string): boolean {\n return dateTimeLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateLikeSQLTypeStrings = [\"date\"] as const;\n\nexport function isDateLikeSQLTypeString(sqlType: string): boolean {\n return dateLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst jsonLikeSQLTypeStrings = [\"json\", \"jsonb\"] as const;\n\nexport function isJSONLikeSQLTypeString(sqlType: string): boolean {\n return jsonLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst jsonFallbackSQLTypeStrings = [\n \"point\",\n \"line\",\n \"lseg\",\n \"box\",\n \"path\",\n \"polygon\",\n \"circle\",\n \"geometry\",\n] as const;\n\nexport function isJSONFallbackSQLTypeString(sqlType: string): boolean {\n return (\n jsonFallbackSQLTypeStrings.includes(sqlType as any) ||\n sqlType.startsWith(\"geometry\")\n );\n}\n\nconst bytesSQLTypeStrings = [\"bytea\", \"blob\"] as const;\n\nexport function isBytesSQLTypeString(sqlType: string): boolean {\n return bytesSQLTypeStrings.includes(sqlType as any);\n}\n\n// PossibleSQLType is intentionally broad — classifiers receive normalized\n// strings and use runtime includes() checks.\nexport type PossibleSQLType = string & {};\n\nexport const UnknownTypeRumbleError = (\n sqlType: string,\n additionalInfo?: string,\n) =>\n new RumbleError(\n `RumbleError: Unknown SQL type '${sqlType}'. Please open an issue (https://github.com/m1212e/rumble/issues) so it can be added. (${additionalInfo})`,\n );\n","import {\n isBooleanSQLTypeString,\n isDateLikeSQLTypeString,\n isDateTimeLikeSQLTypeString,\n isFloatLikeSQLTypeString,\n isIDLikeSQLTypeString,\n isIntLikeSQLTypeString,\n isJSONLikeSQLTypeString,\n isStringLikeSQLTypeString,\n type PossibleSQLType,\n UnknownTypeRumbleError,\n} from \"./types\";\n\nexport function createDistinctValuesFromSQLType(sqlType: PossibleSQLType): {\n value1: any;\n value2: any;\n} {\n if (isIntLikeSQLTypeString(sqlType)) {\n return {\n value1: 1,\n value2: 2,\n };\n }\n\n if (isFloatLikeSQLTypeString(sqlType)) {\n return {\n value1: 1.1,\n value2: 2.2,\n };\n }\n\n if (isStringLikeSQLTypeString(sqlType)) {\n return {\n value1: \"a\",\n value2: \"b\",\n };\n }\n\n if (isIDLikeSQLTypeString(sqlType)) {\n return {\n value1: \"fba31870-5528-42d7-b27e-2e5ee657aea5\",\n value2: \"fc65db81-c2d1-483d-8a25-a30e2cf6e02d\",\n };\n }\n\n if (isBooleanSQLTypeString(sqlType)) {\n return {\n value1: true,\n value2: false,\n };\n }\n\n if (isDateTimeLikeSQLTypeString(sqlType)) {\n return {\n value1: new Date(2022, 1, 1),\n value2: new Date(2022, 1, 2),\n };\n }\n\n if (isDateLikeSQLTypeString(sqlType)) {\n return {\n value1: new Date(2022, 1, 1),\n value2: new Date(2022, 1, 2),\n };\n }\n\n if (isJSONLikeSQLTypeString(sqlType)) {\n return {\n value1: { a: 1 },\n value2: { b: 2 },\n };\n }\n\n throw UnknownTypeRumbleError(sqlType, \"Distinct\");\n}\n","import {\n type Column,\n getTableColumns,\n getTableName,\n is,\n isTable,\n type Many,\n type One,\n type Table,\n} from \"drizzle-orm\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\n\ntype RelationEntry = {\n /** TS-level key in db._.relations (i.e. the export name) */\n name: string;\n /** runtime DB table name as returned by getTableName(table) */\n dbName: string;\n /** the underlying drizzle Table object */\n table: any;\n /** columns map for the table */\n columns: Record<string, Column>;\n /** primary key columns, keyed by column ts-name */\n primaryKey: Record<string, Column>;\n /** named relations record (one/many) for this table */\n relations: Record<string, One<any, any> | Many<any>>;\n /**\n * Whether the underlying entity is a genuine drizzle Table (as opposed to a\n * View/MaterializedView)\n */\n isTable: boolean;\n /**\n * The raw entry from db._.relations — preserved for callers that previously\n * read `foundRelation` off tableHelper().\n */\n foundRelation: any;\n};\n\ntype TableIndex = {\n byTsName: Map<string, RelationEntry>;\n byDbName: Map<string, RelationEntry>;\n byTableRef: Map<any, RelationEntry>;\n};\n\nconst indexCache = new WeakMap<object, TableIndex>();\n\nfunction buildIndex<DB extends DrizzleInstance>(db: DB): TableIndex {\n const byTsName = new Map<string, RelationEntry>();\n const byDbName = new Map<string, RelationEntry>();\n const byTableRef = new Map<any, RelationEntry>();\n\n for (const [tsName, rawEntry] of Object.entries(db._.relations ?? {})) {\n const entry = rawEntry as any;\n const tableObj = entry.table;\n if (!tableObj) continue;\n\n const columns = (\n isTable(tableObj) ? getTableColumns(tableObj as Table) : {}\n ) as Record<string, Column>;\n\n const primaryKey = Object.fromEntries(\n Object.entries(columns).filter(([, col]) => (col as any).primary),\n ) as Record<string, Column>;\n\n const dbName = isTable(tableObj)\n ? (getTableName(tableObj as Table) as string)\n : ((entry.name as string) ?? tsName);\n\n const resolved: RelationEntry = {\n name: entry.name ?? tsName,\n dbName,\n table: tableObj,\n columns,\n primaryKey,\n relations: entry.relations ?? {},\n isTable: isTable(tableObj),\n foundRelation: entry,\n };\n\n byTsName.set(resolved.name, resolved);\n byDbName.set(resolved.dbName, resolved);\n byTableRef.set(tableObj, resolved);\n }\n\n return { byTsName, byDbName, byTableRef };\n}\n\nfunction getIndex<DB extends DrizzleInstance>(db: DB): TableIndex {\n let idx = indexCache.get(db as unknown as object);\n if (!idx) {\n idx = buildIndex(db);\n indexCache.set(db as unknown as object, idx);\n }\n return idx;\n}\n\nexport function tableHelper<\n DB extends DrizzleInstance,\n TableIdentifier extends\n | string\n | DB[\"_\"][\"relations\"][keyof DB[\"_\"][\"relations\"]],\n>({ db, table }: { db: DB; table: TableIdentifier }) {\n const idx = getIndex(db);\n\n let entry: RelationEntry | undefined;\n\n if (typeof table === \"string\") {\n // Lookup by TS-level relation name first (the common case), then by DB name.\n entry = idx.byTsName.get(table) ?? idx.byDbName.get(table);\n } else if (table && typeof table === \"object\") {\n const t = table as any;\n\n // Case 1: caller passed an entry from db._.relations directly:resolve by\n // table identity via its `.table` property.\n if (t.table) {\n entry = idx.byTableRef.get(t.table);\n if (!entry && t.name) {\n entry = idx.byTsName.get(t.name) ?? idx.byDbName.get(t.name);\n }\n }\n\n // Case 2: caller passed a raw Table object: resolve by identity.\n if (!entry) {\n entry = idx.byTableRef.get(t);\n }\n\n // Case 3: last resort lookup via the public getTableName() helper.\n if (!entry && isTable(t)) {\n const dbName = getTableName(t as Table) as string;\n entry = idx.byDbName.get(dbName);\n }\n }\n\n if (!entry) {\n throw new RumbleError(\n `Could not find schema for ${JSON.stringify(\n typeof table === \"string\" ? table : \"<table-object>\",\n )}`,\n );\n }\n\n return {\n columns: entry.columns,\n primaryKey: entry.primaryKey,\n relations: entry.relations,\n dbName: entry.dbName,\n tsName: entry.name,\n table: entry.table,\n isTable: entry.isTable,\n foundRelation: entry.foundRelation,\n };\n}\n\n/**\n * Looks up a relation entry by its TS-level name — i.e. the key in\n * db._.relations, which is also what `Relation.targetTableName` carries.\n * Prefer this for cross-relation navigation over re-resolving via the raw\n * `targetTable` object.\n */\nexport function tableHelperByTsName<DB extends DrizzleInstance>(\n db: DB,\n tsName: string,\n) {\n return tableHelper({ db, table: tsName });\n}\n\nexport { is };\n","import {\n type Attributes,\n type AttributeValue,\n isSpanContextValid,\n type Span,\n SpanStatusCode,\n type Tracer,\n trace,\n} from \"@opentelemetry/api\";\nimport {\n ATTR_GRAPHQL_DOCUMENT,\n ATTR_GRAPHQL_OPERATION_NAME,\n ATTR_GRAPHQL_OPERATION_TYPE,\n} from \"@opentelemetry/semantic-conventions/incubating\";\nimport { AttributeNames, SpanNames } from \"@pothos/tracing-opentelemetry\";\nimport type { RumbleInput, RumbleLogger } from \"../types/rumbleInput\";\n\n/**\n * Which entry point served the current GraphQL operation.\n *\n * Every operation span and log entry carries this as `rumble.transport` so the\n * GraphQL endpoint, the SOFA REST adapter and the WebSocket handler emit the\n * exact same telemetry shape and stay comparable in a single query.\n */\nexport type RumbleTransport = \"graphql\" | \"rest\" | \"ws\";\n\n/**\n * The slice of the rumble input that drives telemetry. Kept structural so every\n * helper in the library can take it without repeating rumble's generic signature.\n */\nexport type TelemetryConfig = Pick<\n RumbleInput<any, any, any, any, any>,\n \"otel\" | \"logger\"\n>;\n\n// ─── span names ──────────────────────────────────────────────────────────────\n// The GraphQL ones align with @pothos/tracing-opentelemetry so rumble's spans sit\n// in the same namespace as the resolver spans pothos emits.\n\nexport const SPAN_EXECUTE: string = SpanNames.EXECUTE;\n/** @pothos/tracing-opentelemetry's SpanNames enum has no subscribe member. */\nexport const SPAN_SUBSCRIBE = \"graphql.subscribe\";\nexport const SPAN_SUBSCRIBE_EVENT = \"graphql.subscribe.event\";\nexport const SPAN_ABILITIES_PREPARE = \"rumble.abilities.prepare\";\nexport const SPAN_FILTERS_APPLY = \"rumble.filters.apply\";\nexport const SPAN_FILTERS_RESOLVE = \"rumble.filters.resolve\";\n\n// ─── attribute and log field names ───────────────────────────────────────────\n// Span attributes and log fields deliberately share names, so the same key means\n// the same thing whether you are looking at a trace or at a log line. The GraphQL\n// ones come from OpenTelemetry's (still incubating) GraphQL semantic conventions\n// and happen to be exactly what pothos uses, so resolver and operation spans line\n// up without any translation.\n\nexport const ATTR_OPERATION_NAME: string = ATTR_GRAPHQL_OPERATION_NAME;\nexport const ATTR_OPERATION_TYPE: string = ATTR_GRAPHQL_OPERATION_TYPE;\nexport const ATTR_DOCUMENT: string = ATTR_GRAPHQL_DOCUMENT;\nexport const ATTR_FIELD_NAME: string = AttributeNames.FIELD_NAME;\n/** Prefix for per-variable span attributes, e.g. `graphql.variables.userId`. */\nexport const ATTR_VARIABLES_PREFIX: string = AttributeNames.VARIABLES;\n/** Log field holding all variables as one object (logs keep nesting, spans flatten). */\nexport const FIELD_VARIABLES = \"graphql.variables\";\nexport const ATTR_PARENT_TYPE = \"graphql.parent.type\";\nexport const ATTR_TRANSPORT = \"rumble.transport\";\nexport const ATTR_TABLE = \"rumble.table\";\nexport const ATTR_ACTION = \"rumble.action\";\nexport const ATTR_ABILITIES_STATUS = \"rumble.abilities.status\";\nexport const ATTR_ABILITIES_STATIC = \"rumble.abilities.static\";\nexport const ATTR_ABILITIES_DYNAMIC = \"rumble.abilities.dynamic\";\nexport const ATTR_ABILITIES_TOTAL = \"rumble.abilities.total\";\nexport const ATTR_FILTERS_TOTAL = \"rumble.filters.total\";\nexport const ATTR_FILTERS_ALLOWED = \"rumble.filters.allowed\";\nexport const ATTR_SUBSCRIPTION_EVENT_INDEX = \"rumble.subscription.event_index\";\nexport const FIELD_DURATION_MS = \"duration_ms\";\nexport const FIELD_EVENT_COUNT = \"event_count\";\n\n// ─── config accessors ────────────────────────────────────────────────────────\n\nexport function telemetryLogger(\n config: TelemetryConfig,\n): RumbleLogger | undefined {\n return config.logger?.enabled ? config.logger.logger : undefined;\n}\n\nexport function telemetryTracer(config: TelemetryConfig): Tracer | undefined {\n return config.otel?.enabled ? config.otel.tracer : undefined;\n}\n\n/**\n * Whether anything at all should be instrumented. When this is false, rumble\n * hands the untouched execute/subscribe functions back to the transports so a\n * user who wants neither traces nor logs pays no overhead.\n */\nexport function telemetryEnabled(config: TelemetryConfig): boolean {\n return Boolean(config.otel?.enabled || config.logger?.enabled);\n}\n\n// ─── log/trace correlation ───────────────────────────────────────────────────\n\n/**\n * `trace_id`/`span_id`/`trace_flags` for the given span, or for the currently\n * active one when no span is passed. Field names and the two-hex-digit flags\n * format follow the OpenTelemetry log data model, which is what log backends\n * (Loki, Tempo, Elastic) expect when linking a log line to its trace.\n *\n * Reading the *active* span means every rumble log site gets correlation for\n * free, without threading a child logger through the whole library.\n */\nexport function traceCorrelationFields(\n config: TelemetryConfig,\n span?: Span,\n): Record<string, string> {\n if (!config.otel?.enabled || config.logger?.injectTraceId === false) {\n return {};\n }\n\n const target = span ?? trace.getActiveSpan();\n if (!target) return {};\n\n const spanContext = target.spanContext();\n if (!isSpanContextValid(spanContext)) return {};\n\n return {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n trace_flags: spanContext.traceFlags.toString(16).padStart(2, \"0\"),\n };\n}\n\n// ─── errors on spans ─────────────────────────────────────────────────────────\n\nfunction toException(error: unknown) {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return error as { message: string };\n }\n return String(error);\n}\n\nfunction exceptionMessage(error: unknown): string | undefined {\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return error === undefined ? undefined : String(error);\n}\n\n/**\n * Records every error as an exception event and flips the span to ERROR, per\n * OpenTelemetry's exception conventions. Used for rumble's own spans as well as\n * the GraphQL operation spans so a failure looks identical wherever it happens.\n */\nexport function recordSpanErrors(\n span: Span | undefined,\n errors: readonly unknown[],\n): void {\n if (!span || errors.length === 0) return;\n\n for (const error of errors) {\n span.recordException(toException(error));\n }\n\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: exceptionMessage(errors[0]),\n });\n}\n\nexport function recordSpanError(span: Span | undefined, error: unknown): void {\n recordSpanErrors(span, [error]);\n}\n\n/**\n * Errors the operation wrapper has already reported.\n *\n * A transport can see the same failure twice: sofa, for instance, hands\n * `result.errors` to its error handler *after* execute has returned, so without\n * this the very same error would produce two log lines and two exception events,\n * which quietly doubles error counts in dashboards. A WeakSet keeps this free of\n * bookkeeping — entries disappear with the errors themselves.\n */\nconst reportedErrors = new WeakSet<object>();\n\nexport function markErrorsReported(errors: readonly unknown[]): void {\n for (const error of errors) {\n if (typeof error === \"object\" && error !== null) {\n reportedErrors.add(error);\n }\n }\n}\n\n/** True when every error was already reported by the operation wrapper. */\nexport function errorsAlreadyReported(errors: readonly unknown[]): boolean {\n if (errors.length === 0) return false;\n return errors.every(\n (error) =>\n typeof error === \"object\" && error !== null && reportedErrors.has(error),\n );\n}\n\n// ─── attribute values ────────────────────────────────────────────────────────\n\nfunction safeJsonStringify(value: unknown): string {\n try {\n return (\n JSON.stringify(value, (_key, inner) =>\n typeof inner === \"bigint\" ? inner.toString() : inner,\n ) ?? \"null\"\n );\n } catch {\n // circular structures, throwing getters, exotic objects\n return String(value);\n }\n}\n\nfunction isHomogeneousPrimitiveArray(value: unknown[]): boolean {\n let seen: \"string\" | \"number\" | \"boolean\" | undefined;\n for (const entry of value) {\n if (entry === null || entry === undefined) continue;\n const type = typeof entry;\n if (type !== \"string\" && type !== \"number\" && type !== \"boolean\") {\n return false;\n }\n if (seen && seen !== type) return false;\n seen = type;\n }\n return true;\n}\n\n/**\n * Coerces an arbitrary value into something the OpenTelemetry attribute type\n * allows: primitives pass through, homogeneous primitive arrays stay arrays\n * (mixed ones are invalid per spec) and everything else becomes JSON.\n *\n * Values are intentionally not truncated here — length limits belong to the SDK\n * (`OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT`) so they stay configurable per deployment.\n */\nexport function attributeValue(value: unknown): AttributeValue {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n return Number.isFinite(value) ? value : String(value);\n case \"boolean\":\n return value;\n case \"bigint\":\n return value.toString();\n case \"undefined\":\n return \"null\";\n default:\n break;\n }\n\n if (value === null) return \"null\";\n if (Array.isArray(value) && isHomogeneousPrimitiveArray(value)) {\n return value as AttributeValue;\n }\n return safeJsonStringify(value);\n}\n\n// ─── GraphQL variables ───────────────────────────────────────────────────────\n\n/**\n * `true` (default) captures all variables, `false` captures none, and a function\n * lets you redact or drop individual entries before they reach a span or a log.\n */\nexport type VariableInclusion =\n | boolean\n | ((\n variables: Record<string, unknown>,\n ) => Record<string, unknown> | undefined)\n | undefined;\n\nexport function resolveVariables(\n variables: Readonly<Record<string, unknown>> | null | undefined,\n include: VariableInclusion,\n): Record<string, unknown> | undefined {\n if (include === false || !variables) return undefined;\n\n const resolved =\n typeof include === \"function\" ? include({ ...variables }) : variables;\n\n if (!resolved || Object.keys(resolved).length === 0) return undefined;\n return resolved as Record<string, unknown>;\n}\n\n/** Variables flattened into `graphql.variables.<name>` span attributes. */\nexport function variableAttributes(\n variables: Readonly<Record<string, unknown>> | null | undefined,\n include: VariableInclusion,\n): Attributes {\n const resolved = resolveVariables(variables, include);\n if (!resolved) return {};\n\n const attributes: Attributes = {};\n for (const [key, value] of Object.entries(resolved)) {\n attributes[`${ATTR_VARIABLES_PREFIX}${key}`] = attributeValue(value);\n }\n return attributes;\n}\n\n/** Variables as a single nested `graphql.variables` log field. */\nexport function variableLogField(\n variables: Readonly<Record<string, unknown>> | null | undefined,\n include: VariableInclusion,\n): Record<string, unknown> {\n const resolved = resolveVariables(variables, include);\n return resolved ? { [FIELD_VARIABLES]: resolved } : {};\n}\n\n// ─── durations ───────────────────────────────────────────────────────────────\n\n/**\n * Monotonic clock reading. `Date.now()` can jump backwards when the wall clock is\n * adjusted (NTP), which would produce negative or inflated durations.\n */\nexport function startTimer(): number {\n return performance.now();\n}\n\nexport function durationMs(start: number): number {\n return Math.round((performance.now() - start) * 100) / 100;\n}\n","import type { AttributeValue, Span } from \"@opentelemetry/api\";\nimport { relationsFilterToSQL } from \"drizzle-orm\";\nimport { debounce } from \"es-toolkit\";\nimport { errorLogField } from \"./helpers/errorLogging\";\nimport { lazy } from \"./helpers/lazy\";\nimport { mergeFilters } from \"./helpers/mergeFilters\";\nimport { sanitizeFilterValue } from \"./helpers/sanitizeFilterValue\";\nimport { createDistinctValuesFromSQLType } from \"./helpers/sqlTypes/distinctValuesFromSQLType\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport {\n ATTR_ABILITIES_DYNAMIC,\n ATTR_ABILITIES_STATIC,\n ATTR_ABILITIES_STATUS,\n ATTR_ABILITIES_TOTAL,\n ATTR_ACTION,\n ATTR_TABLE,\n recordSpanError,\n SPAN_ABILITIES_PREPARE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport type {\n Filter,\n FilterPrefetchCombo,\n Prefetch,\n} from \"./runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleQueryFunctionInput,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n RumbleLogger,\n} from \"./types/rumbleInput\";\n\n//TODO: optimize this for v8 & refactor\n\nexport type AbilityBuilderType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\n/**\n * Static, non changing query filter input type for a specific table\n */\ntype StaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n> = Filter;\n\n/**\n * Dynamic, context based query filter input type for a specific table\n */\ntype DynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> = (\n context: Context,\n) => StaticQueryFilter<DB, Table, Filter> | undefined | \"allow\";\n\n/**\n * Combined query filter type for a specific table. May be static or dynamic.\n */\ntype QueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> =\n | StaticQueryFilter<DB, Table, Filter>\n | DynamicQueryFilter<DB, Table, Filter, Context>;\n\nfunction isDynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is DynamicQueryFilter<DB, Table, Filter, Context> {\n return (\n typeof filter === \"function\" && filter.constructor.name !== \"AsyncFunction\"\n );\n}\n\nfunction isStaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is StaticQueryFilter<DB, Table, Filter> {\n return typeof filter !== \"function\";\n}\n\nconst makeNothingRegisteredWarner = (\n config: TelemetryConfig,\n logger?: RumbleLogger,\n) =>\n debounce((model: string, action: string) => {\n const msg = `No abilities registered for ${model}/${action} — blocking everything. Register the ability or ignore this warning if intentional.`;\n if (logger) {\n logger.warn(\n {\n [ATTR_TABLE]: model,\n [ATTR_ACTION]: action,\n ...traceCorrelationFields(config),\n },\n msg,\n );\n } else {\n console.warn(msg);\n }\n }, 1000);\n\nexport const createAbilityBuilder = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n actions,\n defaultLimit,\n otel,\n logger: loggerConfig,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n const log = loggerConfig?.enabled ? loggerConfig.logger : undefined;\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n const nothingRegisteredWarningLogger = makeNothingRegisteredWarner(\n telemetryConfig,\n log,\n );\n type TableNames = TableRelationNames<DB>;\n\n // Views/materialized views can appear in db.query (if the caller's schema\n // includes them)\n const tableRelationNames = (\n Object.keys(db.query) as (keyof DrizzleQueryFunction<DB>)[]\n ).filter(\n (name) => tableHelper({ db, table: name as any }).isTable,\n ) as TableNames[];\n\n let hasBeenBuilt = false;\n\n const createBuilderForTable = <TableName extends TableNames>() => {\n const queryFilters = new Map<\n Action,\n | QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[]\n | \"unrestricted\"\n >();\n\n const runtimeFilters = new Map<\n Action,\n //TODO add a run all helper\n FilterPrefetchCombo<UserContext, any, any>[]\n >();\n\n // we want to init all possible runtime filters since we want to ensure\n // that the implementaiton helpers pass an object by reference when creating\n // the implementation, instead of a copy like it would be the case with undefined\n for (const action of actions!) {\n if (!runtimeFilters.has(action)) {\n runtimeFilters.set(action, []);\n }\n }\n\n return {\n /**\n * Allows to perform a specific action on a specific entity\n */\n allow: (action: Action | Action[]) => {\n if (hasBeenBuilt) {\n throw new RumbleError(\n \"You can't call allow() after the ability builder has been built. Please ensure that you register all abilities before accessing them.\",\n );\n }\n\n const actions = Array.isArray(action) ? action : [action];\n // Track which actions this specific allow() call initialized as \"unrestricted\",\n // so .when() can distinguish chained use (allow().when()) from a later separate call\n // that finds a pre-existing \"unrestricted\" from a prior bare allow().\n const setUnrestrictedByThisCall = new Set<(typeof actions)[number]>();\n for (const action of actions) {\n let filters = queryFilters.get(action);\n if (!filters) {\n filters = \"unrestricted\";\n queryFilters.set(action, filters);\n setUnrestrictedByThisCall.add(action);\n }\n }\n\n return {\n /**\n * Restricts the allowed actions to a filter\n * @example\n * ```ts\n * abilityBuilder.users.allow([\"read\", \"update\", \"delete\"]).when(({ userId }) => ({\n * where: {\n * id: userId,\n * },\n * }));\n * ```\n */\n when: (\n queryFilter: QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >,\n ) => {\n for (const action of actions) {\n if (queryFilters.get(action) === \"unrestricted\") {\n if (setUnrestrictedByThisCall.has(action)) {\n // Chained directly on this allow() call — override unrestricted with specific filter\n queryFilters.set(action, []);\n } else {\n // A previous separate bare allow() already set unrestricted\n // skip this filter\n continue;\n }\n }\n const filters = queryFilters.get(action)!;\n (filters as Exclude<typeof filters, \"unrestricted\">).push(\n queryFilter,\n );\n }\n },\n };\n },\n /**\n * Allows to register an application level filter to restrict some results\n * which were returned by a query\n */\n filter: (action: Action | Action[]) => {\n const actions = Array.isArray(action) ? action : [action];\n return {\n /**\n * Allows to register an application level prefetch to fetch some data\n * which could be useful for later filtering the results. The prefetch\n * function will be called with the user context but unlike the actual\n * filter function, it will not have access to the result of the query\n * and therefore can be run in parallel with underlying query resolver.\n * A typical use case is to fetch some data which is not directly\n * related to the query but to the context only. So e.g. fetching the\n * user's permissions from an external system and then later applying\n * the filter based on those permissions.\n */\n prefetch: <PrefetchReturnType>(\n prefetch: Prefetch<UserContext, PrefetchReturnType>,\n ) => {\n return {\n /**\n * The actual filter function to apply. Returns the allowed values\n */\n by: (\n explicitFilter: Filter<\n UserContext,\n DrizzleTableValueType<DB, TableName>,\n PrefetchReturnType\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters.get(action)!.push({\n filter: explicitFilter,\n prefetch: prefetch,\n });\n }\n },\n };\n },\n /**\n * The actual filter function to apply. Returns the allowed values\n */\n by: (\n explicitFilter: Filter<\n UserContext,\n DrizzleTableValueType<DB, TableName>\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters.get(action)!.push({\n filter: explicitFilter as Filter<UserContext, any, any>,\n });\n }\n },\n };\n },\n _: {\n runtimeFilters,\n queryFilters,\n },\n };\n };\n\n const buildersPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createBuilderForTable<typeof tableName>(),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createBuilderForTable<key>>;\n };\n\n return {\n ...buildersPerTable,\n /**\n * @internal\n * @ignore\n */\n _: {\n registeredFilters({\n action,\n table,\n }: {\n table: TableNames;\n action: Action;\n }) {\n return (buildersPerTable[table] as any)._.runtimeFilters.get(\n action,\n )! as Filter<UserContext, DrizzleTableValueType<DB, TableNames>>[];\n },\n build() {\n const createFilterForTable = <TableName extends TableNames>(\n tableName: TableName,\n ) => {\n const queryFilters = buildersPerTable[tableName]._.queryFilters;\n\n const simpleQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isStaticQueryFilter)];\n }),\n ) as {\n [key in Action]: StaticQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>\n >[];\n };\n\n const dynamicQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isDynamicQueryFilter)];\n }),\n ) as {\n [key in Action]: DynamicQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[];\n };\n\n const tableSchema = tableHelper({\n db,\n table: tableName,\n });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n throw new RumbleError(\n `No primary key found for entity ${String(tableName)}`,\n );\n }\n\n const primaryKeyField: any = Object.values(tableSchema.primaryKey)[0];\n // we want a filter that excludes everything\n const distinctValues = createDistinctValuesFromSQLType(\n primaryKeyField.getSQLType() as any,\n );\n\n const blockEverythingFilter = {\n where: {\n AND: [\n {\n [primaryKeyField.name]: distinctValues.value1,\n },\n {\n [primaryKeyField.name]: distinctValues.value2,\n },\n ],\n },\n };\n\n /**\n * Packs the filters into a response object that can be applied for queries by the user\n */\n function transformToResponse(\n queryFilters?: DrizzleQueryFunctionInput<DB, TableName>,\n ) {\n const internalTransformer = (\n filters?: DrizzleQueryFunctionInput<DB, TableName>,\n mergedLimit?: number,\n ) => {\n const limit = lazy(() => {\n if (\n // got a merge injection\n mergedLimit !== undefined\n ) {\n if (!filters?.limit) {\n // there is not ability limit\n return mergedLimit;\n }\n\n if ((filters.limit as number) > mergedLimit) {\n // there is an ability limit and it is higher that the injected merge limit\n return mergedLimit;\n }\n }\n\n let limit = filters?.limit as number | undefined;\n\n if (\n defaultLimit &&\n (limit === undefined || limit > defaultLimit)\n ) {\n limit = defaultLimit;\n }\n\n // ensure that null is converted to undefined\n return limit ?? undefined;\n });\n\n const sqlTransformedWhere = lazy(() => {\n const casing = (db._ as any).session?.dialect?.casing;\n\n return filters?.where\n ? relationsFilterToSQL(\n tableSchema.foundRelation.table,\n sanitizeFilterValue(filters.where) as any,\n tableSchema.relations,\n db._.relations,\n casing,\n )\n : undefined;\n });\n\n // we acutally need to define multiple return objects since we do not want to use delete for\n // performance reasons and an undefined columns field on a drizzle filter will prevent any\n // column from being selected at all\n if (filters?.columns) {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n columns: filters?.columns,\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"columns\" | \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n columns: filters?.columns,\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"columns\" | \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n } else {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n }\n };\n\n const ret = internalTransformer(queryFilters);\n\n /**\n * Merges the current query filters with the provided filters for this call only\n */\n function merge(\n p: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>,\n ) {\n const merged = mergeFilters(ret.query.many, p);\n return internalTransformer(\n merged,\n // in case the user wants to inject a limit, we need to ensure that it is applied\n // and not the potential default limit will be used\n // this is important for functions of the default query pagination implementation\n p.limit as number | undefined,\n );\n }\n\n (ret as any).merge = merge;\n\n return ret as typeof ret & {\n merge: typeof merge;\n };\n }\n\n return {\n withContext: (userContext: UserContext) => {\n return {\n filter: (action: Action) => {\n const assembleAbilities = (\n attributes: Record<string, AttributeValue>,\n ) => {\n const filters = queryFilters.get(action);\n\n // in case we have a wildcard ability, skip the rest and return no filters at all\n if (filters === \"unrestricted\") {\n attributes[ATTR_ABILITIES_STATUS] = \"unrestricted\";\n return transformToResponse();\n }\n\n // if nothing has been allowed, block everything\n if (!filters) {\n attributes[ATTR_ABILITIES_STATUS] = \"blocked_everything\";\n nothingRegisteredWarningLogger(String(tableName), action);\n return transformToResponse(blockEverythingFilter);\n }\n\n // run all dynamic filters\n const dynamicResults = new Array<\n DrizzleQueryFunctionInput<DB, TableName>\n >(dynamicQueryFilters[action].length);\n let filtersReturned = 0;\n for (\n let i = 0;\n i < dynamicQueryFilters[action].length;\n i++\n ) {\n const func = dynamicQueryFilters[action][i];\n const result = func(userContext);\n // if one of the dynamic filters returns \"allow\", we want to allow everything\n if (result === \"allow\") {\n attributes[ATTR_ABILITIES_STATUS] = \"unrestricted\";\n return transformToResponse();\n }\n // if nothing is returned, nothing is allowed by this filter\n if (result === undefined) continue;\n\n dynamicResults[filtersReturned++] = result;\n }\n dynamicResults.length = filtersReturned;\n\n attributes[ATTR_ABILITIES_DYNAMIC] = dynamicResults.length;\n attributes[ATTR_ABILITIES_STATIC] =\n simpleQueryFilters[action].length;\n\n const allQueryFilters = [\n ...simpleQueryFilters[action],\n ...dynamicResults,\n ];\n\n attributes[ATTR_ABILITIES_TOTAL] = allQueryFilters.length;\n\n // if we don't have any permitted filters then block everything\n if (allQueryFilters.length === 0) {\n attributes[ATTR_ABILITIES_STATUS] = \"blocked_everything\";\n\n return transformToResponse(blockEverythingFilter);\n }\n\n const mergedFilters =\n allQueryFilters.length === 1\n ? allQueryFilters[0]\n : allQueryFilters.reduce((a, b) => {\n return mergeFilters(a, b, \"OR\");\n });\n\n attributes[ATTR_ABILITIES_STATUS] = \"applied\";\n return transformToResponse(mergedFilters as any);\n };\n\n // one attribute set, fed to both sinks, so a trace and a log\n // line describing the same ability check cannot disagree\n const run = (span?: Span) => {\n const attributes: Record<string, AttributeValue> = {\n [ATTR_TABLE]: String(tableName),\n [ATTR_ACTION]: action,\n };\n\n try {\n const result = assembleAbilities(attributes);\n log?.debug(\n {\n ...attributes,\n ...traceCorrelationFields(telemetryConfig, span),\n },\n \"abilities prepared\",\n );\n return result;\n } catch (error) {\n recordSpanError(span, error);\n log?.error(\n {\n ...attributes,\n ...traceCorrelationFields(telemetryConfig, span),\n ...errorLogField(error),\n },\n \"abilities failed\",\n );\n throw error;\n } finally {\n span?.setAttributes(attributes);\n }\n };\n\n if (otel?.enabled && otel.tracer) {\n return otel.tracer.startActiveSpan(\n SPAN_ABILITIES_PREPARE,\n (span) => {\n try {\n return run(span);\n } finally {\n span.end();\n }\n },\n );\n }\n\n return run();\n },\n };\n },\n };\n };\n\n const abilitiesPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createFilterForTable(tableName),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createFilterForTable<key>>;\n };\n\n hasBeenBuilt = true;\n\n return (ctx: UserContext) => {\n return Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n abilitiesPerTable[tableName].withContext(ctx),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n ReturnType<typeof createFilterForTable<key>>[\"withContext\"]\n >;\n };\n };\n },\n },\n };\n};\n","import { toCamelCase } from \"drizzle-orm/casing\";\nimport { capitalize } from \"es-toolkit\";\nimport { lazy } from \"../helpers/lazy\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\n\nexport type OrderArgImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createOrderArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\nconst makeDefaultName = (dbName: string) =>\n `${capitalize(toCamelCase(dbName.toString()))}OrderInputArgument`;\n\nexport const createOrderArgImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const referenceStorage = new Map<string, any>();\n\n const sortingParameterEnumRef = lazy(() =>\n schemaBuilder.enumType(\"SortingParameter\", {\n values: [\"asc\", \"desc\"] as const,\n }),\n );\n\n const orderArgImplementer = <\n RefName extends string,\n TableName extends keyof DrizzleQueryFunction<DB>,\n >({\n table,\n refName,\n dbName,\n }: Partial<{\n table: TableName;\n refName: RefName | undefined;\n dbName: string;\n }> &\n (\n | {\n table: TableName;\n }\n | {\n dbName: string;\n }\n )) => {\n const tableSchema = tableHelper({\n db,\n table: dbName ?? table!,\n });\n\n const inputTypeName = refName ?? makeDefaultName(tableSchema.tsName);\n\n let ret: ReturnType<typeof implement> | undefined =\n referenceStorage.get(inputTypeName);\n if (ret) {\n return ret;\n }\n\n const implement = () => {\n return schemaBuilder.inputType(inputTypeName, {\n fields: (t) => {\n // Drizzle's relationsOrderToSQL treats every key as a column on the\n // current table, so exposing relation keys would generate invalid SQL.\n const fields = Object.entries(tableSchema.columns).reduce(\n (acc, [key]) => {\n // GraphQL reserves names starting with \"__\" for introspection.\n if (key.startsWith(\"__\")) return acc;\n\n acc[key] = t.field({\n type: sortingParameterEnumRef(),\n required: false,\n });\n\n return acc;\n },\n {} as Record<string, ReturnType<typeof t.field>>,\n );\n\n return fields;\n },\n });\n };\n\n ret = implement();\n referenceStorage.set(inputTypeName, ret);\n return ret;\n };\n\n return orderArgImplementer;\n};\n","import { type Column, getTableName, is, isTable } from \"drizzle-orm\";\nimport { toCamelCase } from \"drizzle-orm/casing\";\nimport { MySqlEnumColumn, MySqlEnumObjectColumn } from \"drizzle-orm/mysql-core\";\nimport {\n isPgEnum,\n type PgEnum,\n PgEnumColumn,\n type PgEnumObject,\n PgEnumObjectColumn,\n} from \"drizzle-orm/pg-core\";\nimport { capitalize } from \"es-toolkit\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\n/**\n * Checks if a column is a database enum column (Postgres or MySQL).\n */\nexport function isEnumSchema(\n schemaType: any,\n): schemaType is\n | PgEnumColumn<any>\n | PgEnumObjectColumn<any>\n | MySqlEnumColumn<any>\n | MySqlEnumObjectColumn<any> {\n return (\n is(schemaType, PgEnumColumn) ||\n is(schemaType, PgEnumObjectColumn) ||\n is(schemaType, MySqlEnumColumn) ||\n is(schemaType, MySqlEnumObjectColumn)\n );\n}\n\n// TODO make this compatible with other db drivers\ntype EnumTypes = PgEnum<any> | PgEnumObject<any>;\n\nexport type NonEnumFields<T> = {\n [K in keyof T as T[K] extends EnumTypes ? never : K]: T[K];\n};\n\n/**\n * Picks the keys of a schema object that are pgEnum definitions\n */\nexport type EnumFieldKeys<S> = keyof {\n [K in keyof S as S[K] extends EnumTypes ? K : never]: S[K];\n};\n\n/**\n * Fallback value tuple used whenever the concrete enum members cannot be\n * recovered from the drizzle types (e.g. an object-enum whose values were\n * widened to `string`, or a `tsName` that does not resolve against `Schema`).\n */\ntype UnknownEnumValues = readonly [string, ...string[]];\n\n/**\n * Extracts the literal value tuple carried by a drizzle enum definition.\n */\ntype EnumValuesOf<E> =\n E extends PgEnum<infer V>\n ? V\n : E extends PgEnumObject<infer O>\n ? ReadonlyArray<O[keyof O] & string>\n : UnknownEnumValues;\n\n/**\n * The GraphQL enum member union for a single `enum_(...)` call, resolved from\n * whichever of the three per-call generics the caller populated (`tsName` /\n * `enum` / `enumColumn`). The unused generics default to `never`, so\n * `[X] extends [never]` tells us which identification form was used.\n *\n * Anything we can't recover from the drizzle types (an object-enum widened to\n * `string`, or a `tsName` that doesn't resolve against `Schema`) falls back to\n * `string`, matching Pothos' own enum member type.\n */\ntype EnumMembers<Schema, TsName, EnumArg, EnumColumn> = [EnumColumn] extends [\n never,\n]\n ? [EnumArg] extends [never]\n ? [TsName] extends [never]\n ? string\n : TsName extends keyof Schema\n ? EnumValuesOf<Schema[TsName]>[number]\n : string\n : EnumValuesOf<EnumArg>[number]\n : EnumColumn extends { enumValues: infer CV extends UnknownEnumValues }\n ? CV[number]\n : string;\n\n/**\n * The strongly typed Pothos enum ref returned by a single `enum_(...)` call.\n *\n * Kept as a named, exported alias on purpose: the `.d.ts` emitter prints type\n * aliases by reference rather than expanding their bodies, so the (otherwise\n * very deep) `SchemaBuilder` / `EnumRef` types never get inlined into the\n * declaration output. Two details keep this printable without the emitter\n * recursing: referencing `SchemaBuilderType<...>` (a named alias) rather than\n * `typeof schemaBuilder` (a value), and inlining the member resolution so the\n * cyclic drizzle `Schema[TsName]` access never surfaces as its own symbol.\n */\nexport type EnumImplementationRef<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema,\n TsName,\n EnumArg,\n EnumColumn,\n> =\n SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n > extends PothosSchemaTypes.SchemaBuilder<infer Types>\n ? PothosSchemaTypes.EnumRef<\n Types,\n EnumMembers<Schema, TsName, EnumArg, EnumColumn>\n >\n : never;\n\nexport type EnumImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n AvailableEnums extends string,\n Schema extends Record<string, any> = Record<string, any>,\n> = ReturnType<\n typeof createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n AvailableEnums,\n Schema\n >\n>;\n\nexport const createEnumImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n AvailableEnums extends string,\n Schema extends Record<string, any> = Record<string, any>,\n>({\n schema,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const referenceStorage = new Map<string, any>();\n\n /**\n * Registers a Postgres enum as a GraphQL enum type.\n *\n * You can identify the enum in three ways:\n * - `tsName`: the exported TypeScript identifier from your schema module. This is the\n * most typesafe form, only valid enum keys autocomplete, typos are caught at compile time.\n * - `enum`: pass the pgEnum object directly.\n * - `enumColumn`: pass a column that uses the enum.\n *\n * Use `refName` to override the auto-generated GraphQL type name.\n */\n const enumImplementer = <\n TsName extends AvailableEnums = never,\n EnumArg extends PgEnum<any> | PgEnumObject<any> = never,\n EnumColumn extends Column = never,\n RefName extends string = string,\n >(\n args: {\n refName?: RefName;\n } & (\n | { tsName: TsName; enum?: never; enumColumn?: never }\n | { enum: EnumArg; tsName?: never; enumColumn?: never }\n | { enumColumn: EnumColumn; tsName?: never; enum?: never }\n ),\n ): EnumImplementationRef<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema,\n TsName,\n EnumArg,\n EnumColumn\n > => {\n const { refName } = args;\n const tsName = (args as { tsName?: string }).tsName;\n const enumObjectArg = (args as { enum?: PgEnum<any> | PgEnumObject<any> })\n .enum;\n const enumColumn = (args as { enumColumn?: Column }).enumColumn;\n\n let enumObject: PgEnum<any> | PgEnumObject<any> | undefined = enumObjectArg;\n\n if (tsName) {\n const candidate = (schema as Record<string, unknown>)[tsName];\n if (!candidate || !isPgEnum(candidate as any)) {\n throw new RumbleError(\n `Could not find a pgEnum exported as ${JSON.stringify(\n tsName,\n )} in the provided schema. ` +\n `Make sure the identifier exists and refers to a value created with \\`pgEnum(...)\\`.`,\n );\n }\n enumObject = candidate as PgEnum<any> | PgEnumObject<any>;\n }\n\n if (!enumObject && !enumColumn) {\n throw new RumbleError(\n `Could not determine enum structure! Pass one of 'tsName' (requires \\`schema\\` on rumble()), ` +\n `'enum' (the pgEnum object), or 'enumColumn' (a column that uses the enum).`,\n );\n }\n\n let enumSchemaName: string | undefined;\n let enumValues: any[] | undefined;\n\n if (enumObject) {\n enumSchemaName = enumObject.enumName;\n enumValues = enumObject.enumValues as unknown as any[];\n } else if (enumColumn) {\n // MySQL enum columns carry their values directly; there is no standalone\n // enum object. Derive a stable name from table + column name.\n if (\n is(enumColumn, MySqlEnumColumn) ||\n is(enumColumn, MySqlEnumObjectColumn)\n ) {\n enumValues = (enumColumn as any).enumValues as unknown as any[];\n const colTable = (enumColumn as any).table;\n const tableName =\n colTable && isTable(colTable) ? getTableName(colTable) : undefined;\n enumSchemaName = tableName\n ? `${tableName}_${enumColumn.name}`\n : enumColumn.name;\n } else {\n const pgEnum = (enumColumn as any).enum as\n | PgEnum<any>\n | PgEnumObject<any>\n | undefined;\n\n if (!pgEnum) {\n throw new RumbleError(\n `Could not find enum definition on column. Make sure the column is a pgEnum column.`,\n );\n }\n\n enumSchemaName = pgEnum.enumName;\n enumValues = enumColumn.enumValues as unknown as any[];\n }\n }\n\n if (!enumSchemaName || !enumValues) {\n throw new RumbleError(\"Could not determine enum structure!\");\n }\n\n const graphqlImplementationName =\n refName ?? `${capitalize(toCamelCase(enumSchemaName))}Enum`;\n\n // The runtime always produces a plain Pothos enum ref; the strong typing\n // lives entirely in the (explicit, named) return type, so we cast on the\n // way out. The named return alias is what keeps the `.d.ts` emitter from\n // recursing on the inlined SchemaBuilder/EnumRef types.\n type Ret = EnumImplementationRef<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema,\n TsName,\n EnumArg,\n EnumColumn\n >;\n\n const cached = referenceStorage.get(graphqlImplementationName);\n if (cached) {\n return cached as Ret;\n }\n\n const ret = schemaBuilder.enumType(graphqlImplementationName, {\n values: enumValues,\n });\n referenceStorage.set(graphqlImplementationName, ret);\n return ret as unknown as Ret;\n };\n\n return enumImplementer;\n};\n","import {\n isBigIntLikeSQLTypeString,\n isBooleanSQLTypeString,\n isBytesSQLTypeString,\n isDateLikeSQLTypeString,\n isDateTimeLikeSQLTypeString,\n isFloatLikeSQLTypeString,\n isIDLikeSQLTypeString,\n isIntLikeSQLTypeString,\n isJSONFallbackSQLTypeString,\n isJSONLikeSQLTypeString,\n isStringLikeSQLTypeString,\n normalizeSQLType,\n type PossibleSQLType,\n UnknownTypeRumbleError,\n} from \"./types\";\n\nexport type GraphQLTypeName =\n | \"Int\"\n | \"Float\"\n | \"String\"\n | \"ID\"\n | \"Boolean\"\n | \"DateTime\"\n | \"Date\"\n | \"JSON\"\n | \"BigInt\"\n | \"Bytes\";\n\nexport function mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n}: {\n sqlType: PossibleSQLType;\n fieldName?: string;\n}): GraphQLTypeName {\n // MySQL raw enum columns expose their values in the SQL type string.\n // Handle before normalization since normalization would strip the parens.\n if (/^enum\\(/.test(sqlType)) {\n return \"String\";\n }\n\n const normalized = normalizeSQLType(sqlType);\n\n let ret: GraphQLTypeName | undefined;\n\n if (isIntLikeSQLTypeString(normalized)) {\n ret = \"Int\";\n }\n\n if (isBigIntLikeSQLTypeString(normalized)) {\n ret = \"BigInt\";\n }\n\n if (isFloatLikeSQLTypeString(normalized)) {\n ret = \"Float\";\n }\n\n if (isStringLikeSQLTypeString(normalized)) {\n if (\n fieldName &&\n (fieldName.toLowerCase().endsWith(\"_id\") ||\n fieldName.toLowerCase().endsWith(\"id\"))\n ) {\n ret = \"ID\";\n } else {\n ret = \"String\";\n }\n }\n\n if (isIDLikeSQLTypeString(normalized)) {\n ret = \"ID\";\n }\n\n if (isBooleanSQLTypeString(normalized)) {\n ret = \"Boolean\";\n }\n\n if (isDateTimeLikeSQLTypeString(normalized)) {\n ret = \"DateTime\";\n }\n\n if (isDateLikeSQLTypeString(normalized)) {\n ret = \"Date\";\n }\n\n if (isJSONLikeSQLTypeString(normalized)) {\n ret = \"JSON\";\n }\n\n if (isJSONFallbackSQLTypeString(normalized)) {\n ret = \"JSON\";\n }\n\n if (isBytesSQLTypeString(normalized)) {\n ret = \"Bytes\";\n }\n\n if (ret !== undefined) {\n return ret;\n }\n\n throw UnknownTypeRumbleError(sqlType, \"SQL to GQL\");\n}\n","import { is } from \"drizzle-orm\";\nimport { toCamelCase } from \"drizzle-orm/casing\";\nimport { PgColumn } from \"drizzle-orm/pg-core\";\nimport { capitalize } from \"es-toolkit\";\nimport { type EnumImplementerType, isEnumSchema } from \"../enum\";\nimport { mapSQLTypeToGraphQLType } from \"../helpers/sqlTypes/mapSQLTypeToTSType\";\nimport type { PossibleSQLType } from \"../helpers/sqlTypes/types\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\n\n// TODO: in general, several of the filter methods should be more\n// restrictive in case of explicitly allowed columns\n// search, order and filter should be restricted to allowed cols\n// and should completely ignore other fields since one might be ably\n// to narrow down and guess the actual values behind forbidden columns by\n// using the provided args. This way one could guess, e.g. secrets which are forbidden by\n// the column abilitiy settings but will be respected in searches, etc.\n\nexport type WhereArgImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createWhereArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\nconst makeDefaultName = (dbName: string) =>\n `${capitalize(toCamelCase(dbName.toString()))}WhereInputArgument`;\n\nexport const createWhereArgImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n schemaBuilder,\n enumImplementer,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n enumImplementer: EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n any\n >;\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const referenceStorage = new Map<string, any>();\n const enumArrayWhereInputStorage = new Map<string, any>();\n const scalarArrayWhereInputStorage = new Map<string, any>();\n\n const scalarArrayWhereInputName = (gqlType: string) =>\n `${gqlType}ArrayWhereInputArgument`;\n\n const getScalarArrayWhereInput = (gqlType: string) => {\n const typeName = scalarArrayWhereInputName(gqlType);\n const existing = scalarArrayWhereInputStorage.get(typeName);\n if (existing) return existing;\n\n const ret = schemaBuilder.inputRef(typeName);\n scalarArrayWhereInputStorage.set(typeName, ret);\n\n ret.implement({\n fields: (t: any) => ({\n eq: t.field({ type: [gqlType], required: false }),\n ne: t.field({ type: [gqlType], required: false }),\n in: t.field({ type: [[gqlType]], required: false }),\n notIn: t.field({ type: [[gqlType]], required: false }),\n isNull: t.boolean({ required: false }),\n isNotNull: t.boolean({ required: false }),\n arrayOverlaps: t.field({ type: [gqlType], required: false }),\n arrayContained: t.field({ type: [gqlType], required: false }),\n arrayContains: t.field({ type: [gqlType], required: false }),\n AND: t.field({ type: [ret], required: false }),\n OR: t.field({ type: [ret], required: false }),\n NOT: t.field({ type: ret, required: false }),\n }),\n });\n\n return ret;\n };\n\n const getEnumArrayWhereInput = (enumImpl: any) => {\n const typeName = `${enumImpl.name}WhereInputArgument`;\n\n const existing = enumArrayWhereInputStorage.get(typeName);\n if (existing) {\n return existing;\n }\n\n const ret = schemaBuilder.inputRef(typeName);\n enumArrayWhereInputStorage.set(typeName, ret);\n\n ret.implement({\n fields: (t: any) => ({\n // the column holds an array, so eq/ne compare against a whole\n // array value and in/notIn against a list of array values\n eq: t.field({ type: [enumImpl], required: false }),\n ne: t.field({ type: [enumImpl], required: false }),\n in: t.field({ type: [[enumImpl]], required: false }),\n notIn: t.field({ type: [[enumImpl]], required: false }),\n isNull: t.boolean({ required: false }),\n isNotNull: t.boolean({ required: false }),\n arrayOverlaps: t.field({ type: [enumImpl], required: false }),\n arrayContained: t.field({ type: [enumImpl], required: false }),\n arrayContains: t.field({ type: [enumImpl], required: false }),\n AND: t.field({ type: [ret], required: false }),\n OR: t.field({ type: [ret], required: false }),\n NOT: t.field({ type: ret, required: false }),\n }),\n });\n\n return ret;\n };\n\n const whereArgImplementer = <\n TableName extends keyof DrizzleQueryFunction<DB>,\n RefName extends string,\n >({\n table,\n refName,\n dbName,\n }: Partial<{\n table: TableName;\n refName: RefName | undefined;\n dbName: string;\n }> &\n (\n | {\n table: TableName;\n }\n | {\n dbName: string;\n }\n )) => {\n const tableSchema = tableHelper({\n db,\n table: dbName ?? table!,\n });\n\n const inputTypeName = refName ?? makeDefaultName(tableSchema.tsName);\n\n const existing = referenceStorage.get(inputTypeName);\n if (existing) {\n return existing;\n }\n\n const ret = schemaBuilder.inputRef(inputTypeName);\n referenceStorage.set(inputTypeName, ret);\n\n ret.implement({\n fields: (t: any) => {\n const mapSQLTypeStringToInputPothosType = (\n sqlType: PossibleSQLType,\n fieldName: string,\n isArray: boolean,\n ) => {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n\n if (isArray) {\n return t.field({\n type: getScalarArrayWhereInput(gqlType),\n required: false,\n });\n }\n\n switch (gqlType) {\n case \"Int\":\n return t.field({\n type: \"IntWhereInputArgument\",\n required: false,\n });\n case \"BigInt\":\n return t.field({\n type: \"BigIntWhereInputArgument\",\n required: false,\n });\n case \"String\":\n return t.field({\n type: \"StringWhereInputArgument\",\n required: false,\n });\n case \"Boolean\":\n return t.field({\n type: \"BooleanWhereInputArgument\",\n required: false,\n });\n case \"Date\":\n return t.field({\n type: \"DateWhereInputArgument\",\n required: false,\n });\n case \"DateTime\":\n return t.field({\n type: \"DateTimeWhereInputArgument\",\n required: false,\n });\n case \"Float\":\n return t.field({\n type: \"FloatWhereInputArgument\",\n required: false,\n });\n case \"ID\":\n return t.field({\n type: \"IDWhereInputArgument\",\n required: false,\n });\n case \"JSON\":\n return t.field({\n type: \"JSONWhereInputArgument\",\n required: false,\n });\n case \"Bytes\":\n // No meaningful filter operators for byte columns — skip.\n return null;\n default:\n throw new RumbleError(\n `Unsupported argument type ${gqlType} for column ${sqlType}`,\n );\n }\n };\n const fields = Object.entries(tableSchema.columns).reduce(\n (acc, [key, value]) => {\n // GraphQL reserves names starting with \"__\" for introspection.\n if (key.startsWith(\"__\")) return acc;\n\n // Detect pg array columns via the `dimensions` runtime property.\n let isArray = false;\n if (is(value, PgColumn)) {\n const dims = (value as PgColumn & { dimensions?: number })\n .dimensions;\n if (dims && dims > 0) isArray = true;\n }\n\n if (isEnumSchema(value)) {\n const enumImpl = enumImplementer({\n enumColumn: value,\n });\n\n acc[key] = t.field({\n type: isArray ? getEnumArrayWhereInput(enumImpl) : enumImpl,\n required: false,\n });\n } else {\n const field = mapSQLTypeStringToInputPothosType(\n value.getSQLType() as PossibleSQLType,\n key,\n isArray,\n );\n if (field !== null) {\n acc[key] = field;\n }\n }\n\n return acc;\n },\n {} as Record<string, ReturnType<typeof t.field>>,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n // `targetTableName` is the publicly typed TS-key of the target\n // relation in db._.relations, prefer it over re-resolving via\n // the `targetTable` object.\n const targetTsName = (value as any).targetTableName as string;\n const relationSchema = tableHelper({\n db,\n table: targetTsName,\n });\n const referenceModel = whereArgImplementer({\n dbName: relationSchema.dbName,\n });\n\n acc[key] = t.field({\n type: referenceModel,\n required: false,\n });\n\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.columns,\n ReturnType<typeof mapSQLTypeStringToInputPothosType>\n >,\n );\n\n return {\n ...fields,\n ...relations,\n AND: t.field({ type: [ret], required: false }),\n OR: t.field({ type: [ret], required: false }),\n NOT: t.field({ type: ret, required: false }),\n };\n },\n });\n\n return ret;\n };\n\n return whereArgImplementer;\n};\n","import type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\nimport { generateFromSchema } from \"./generate/generate\";\n\nexport const clientCreatorImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n builtSchema,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n builtSchema: () => ReturnType<\n SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >[\"toSchema\"]\n >;\n}) => {\n const clientCreator = async ({\n apiUrl,\n outputPath,\n rumbleImportPath,\n useExternalUrqlClient,\n removeExisting,\n forceReactivity,\n autoIncludeIdField = false,\n }: {\n /**\n * Path to the output directory where the client files will be generated.\n */\n outputPath: string;\n /**\n * The base URL of the Rumble API.\n */\n apiUrl?: string;\n /**\n * The import path for the rumble library, defaults to \"@m1212e/rumble/client\".\n */\n rumbleImportPath?: string;\n /**\n * Set this to use an external urql client exported from a module.\n * If a string, uses the provided path to the urql client for importing the client.\n * If false, creates a new urql client with the provided apiUrl.\n */\n useExternalUrqlClient?: string;\n /**\n * Whether to remove existing generated files in the output directory before generating new ones.\n */\n removeExisting?: boolean;\n /**\n * Whether to force reactivity for generated queries and mutations. This will prevent the actual response fields of the awaited response from being populated\n * and requires you to subscribe to the response to access the data. Useful to prevent forgetting to subscribe to the response to utilize reactive data.\n */\n forceReactivity?: boolean;\n /**\n * Whether to automatically include the `id` field in generated queries and mutations.\n * This might be helpful to ensure that caching works correctly since all object will always be identifiable by their `id`.\n * Can be set to `true` to always include the `id` field, or to `false` to never include it.\n * Can also be set to a string to include a custom named field as Id field in case you have a different naming convention like `_id`.\n *\n * @default false\n */\n autoIncludeIdField?: boolean | string;\n }) => {\n if (process.env.NODE_ENV !== \"development\") {\n console.warn(\n `Running rumble client generation in non development mode. Are you sure this is correct? Called with arguments: ${JSON.stringify(\n {\n outputPath,\n apiUrl,\n rumbleImportPath,\n useExternalUrqlClient,\n removeExisting,\n },\n )}`,\n );\n }\n const schema = builtSchema();\n await generateFromSchema({\n schema,\n outputPath,\n rumbleImportPath,\n apiUrl,\n useExternalUrqlClient,\n removeExisting,\n forceReactivity,\n autoIncludeIdField,\n });\n };\n\n return clientCreator;\n};\n","import type { AbilityBuilderType } from \"./abilityBuilder\";\nimport { lazy } from \"./helpers/lazy\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\nexport type ContextFunctionType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createContextFunction<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\nexport type ContextType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = Awaited<\n ReturnType<\n ContextFunctionType<UserContext, DB, RequestEvent, Action, PothosConfig>\n >\n>;\n\nexport const createContextFunction = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n context: makeUserContext,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n abilityBuilder: AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const builtAbilityBuilder = lazy(() => abilityBuilder._.build());\n\n return async (req: RequestEvent) => {\n const userContext = makeUserContext\n ? await makeUserContext(req)\n : ({} as UserContext);\n\n return {\n ...userContext,\n abilities: builtAbilityBuilder()(userContext),\n };\n };\n};\n","export function deepSetProto(\n obj: any,\n proto = Object.prototype,\n seen = new WeakSet(),\n) {\n if (obj === null || typeof obj !== \"object\") return;\n if (seen.has(obj)) return;\n seen.add(obj);\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n deepSetProto(item, proto, seen);\n }\n return;\n }\n\n const currentProto = Object.getPrototypeOf(obj);\n if (currentProto !== Object.prototype && currentProto !== null) {\n return;\n }\n Object.setPrototypeOf(obj, proto);\n for (const key of Object.keys(obj)) {\n deepSetProto(obj[key], proto, seen);\n }\n}\n","import { count } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFirstEntryExists } from \"./helpers/asserts\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleErrorSafe } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\nexport const createCountQueryImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n>({\n db,\n schemaBuilder,\n whereArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig, Schema> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n whereArgImplementer: WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n makePubSubInstance: MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n return <TableName extends TableRelationNames<DB>>({\n table,\n listAction = \"read\" as Action,\n isAllowed,\n }: {\n /**\n * The table for which to implement the count query\n */\n table: TableName;\n /**\n * Which action should be used for listing many entities\n * @default \"read\"\n */\n listAction?: Action;\n /**\n * Optional function to check if the query is allowed\n */\n isAllowed?: (context: UserContext) => boolean | Promise<boolean>;\n }) => {\n const WhereArg = whereArgImplementer({\n table: table,\n });\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n const tableSchema = tableHelper({\n db,\n table,\n });\n\n return schemaBuilder.queryFields((t) => {\n return {\n [`${pluralize.plural(String(table))}Count`]: t.field({\n type: \"Int\",\n nullable: false,\n smartSubscription: true,\n description: `Count all ${pluralize.plural(String(table))}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: {\n where: t.arg({ type: WhereArg, required: false }),\n },\n resolve: async (_root, args, ctx, _info) => {\n if (isAllowed && !(await isAllowed(ctx))) {\n throw new RumbleErrorSafe(\"Not allowed to perform this action\");\n }\n\n deepSetProto(args);\n\n return (db as any)\n .select({ count: count() })\n .from(tableSchema.table)\n .where(\n ctx.abilities[table]\n .filter(listAction)\n .merge(mapNullFieldsToUndefined(args) as any).sql.where,\n )\n .then(assertFirstEntryExists)\n .then((r: any) => r.count);\n },\n }),\n };\n });\n };\n};\n","import type { useSofa } from \"@m1212e/sofa-api\";\n\nexport const sofaOpenAPIWebhookDocs: NonNullable<\n Parameters<typeof useSofa>[0][\"openAPI\"]\n> = {\n paths: {\n \"/webhook\": {\n post: {\n operationId: \"webhook_create\",\n description: \"Creates a webhook subscription.\",\n tags: [],\n parameters: [],\n requestBody: {\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookCreateBody\",\n },\n },\n },\n },\n responses: {\n \"200\": {\n description: \"\",\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookDetailResponse\",\n },\n },\n },\n },\n },\n },\n },\n \"/webhook/{id}\": {\n post: {\n operationId: \"webhook_update\",\n description: \"Updates a webhook subscription.\",\n parameters: [\n {\n name: \"id\",\n in: \"path\",\n description: \"The ID of the webhook to update\",\n required: true,\n schema: {\n type: \"string\",\n },\n } as any,\n ],\n requestBody: {\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookCreateBody\",\n },\n },\n },\n },\n responses: {\n \"200\": {\n description: \"\",\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookDetailResponse\",\n },\n },\n },\n },\n },\n },\n delete: {\n operationId: \"webhook_delete\",\n description: \"Removes a webhook subscription.\",\n tags: [],\n parameters: [\n {\n name: \"id\",\n in: \"path\",\n description: \"The ID of the webhook to delete\",\n required: true,\n schema: {\n type: \"string\",\n },\n } as any,\n ],\n responses: {\n \"200\": {\n description: \"\",\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookDetailResponse\",\n },\n },\n },\n },\n },\n },\n },\n },\n components: {\n schemas: {\n WebhookCreateBody: {\n type: \"object\",\n properties: {\n subscription: {\n description:\n \"The subscription to subscribe to. In many cases, these match the available query IDs without the '_query' suffix. E.g., 'users_query' -> 'users'. See the graphql schema for more details on what subscriptions are available.\",\n type: \"string\",\n },\n variables: {\n description: \"The variables to pass to the subscription.\",\n type: \"object\",\n },\n url: {\n description: \"The URL to send the webhook to.\",\n type: \"string\",\n },\n },\n },\n WebhookDetailResponse: {\n type: \"object\",\n properties: {\n id: {\n description:\n \"The ID of the webhook. Can be used as reference in update or delete calls.\",\n type: \"string\",\n },\n },\n },\n DateTime: {\n type: \"string\",\n format: \"date-time\",\n },\n Date: {\n type: \"string\",\n format: \"date\",\n },\n },\n },\n};\n","import type { Attributes, Span, SpanContext, Tracer } from \"@opentelemetry/api\";\nimport {\n execute as defaultExecute,\n subscribe as defaultSubscribe,\n type ExecutionArgs,\n type ExecutionResult,\n getOperationAST,\n print,\n} from \"graphql\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n RumbleLogger,\n} from \"../types/rumbleInput\";\nimport { errorLogField, errorsLogField } from \"./errorLogging\";\nimport {\n ATTR_DOCUMENT,\n ATTR_OPERATION_NAME,\n ATTR_OPERATION_TYPE,\n ATTR_SUBSCRIPTION_EVENT_INDEX,\n ATTR_TRANSPORT,\n durationMs,\n FIELD_DURATION_MS,\n FIELD_EVENT_COUNT,\n markErrorsReported,\n type RumbleTransport,\n recordSpanError,\n recordSpanErrors,\n SPAN_EXECUTE,\n SPAN_SUBSCRIBE,\n SPAN_SUBSCRIBE_EVENT,\n startTimer,\n type TelemetryConfig,\n telemetryEnabled,\n telemetryLogger,\n telemetryTracer,\n traceCorrelationFields,\n variableAttributes,\n variableLogField,\n} from \"./telemetry\";\n\nexport function isAsyncIterable(\n value: unknown,\n): value is AsyncIterable<unknown> {\n return (\n typeof value === \"object\" && value !== null && Symbol.asyncIterator in value\n );\n}\n\n/**\n * Everything the operation telemetry of a single execute/subscribe call needs.\n * Built once per operation so spans and logs cannot drift apart, and so the three\n * transports (GraphQL, SOFA REST, WebSocket) share one code path.\n */\ntype OperationTelemetry = {\n operationName: string;\n operationType?: string;\n /** Identical keys for spans and logs, minus the payload specific ones. */\n logFields: Record<string, unknown>;\n /** Only on the \"start\" entry, so variables are not repeated on every line. */\n variableLogFields: Record<string, unknown>;\n /** Lazy: printing the document and encoding variables is only worth it for otel. */\n attributes: () => Attributes;\n};\n\nfunction buildOperationTelemetry(\n config: TelemetryConfig,\n transport: RumbleTransport,\n options: ExecutionArgs,\n): OperationTelemetry {\n const operationAst = getOperationAST(options.document, options.operationName);\n const operationName =\n options.operationName ?? operationAst?.name?.value ?? \"anonymous\";\n const operationType = operationAst?.operation;\n\n const logFields = {\n [ATTR_OPERATION_NAME]: operationName,\n ...(operationType ? { [ATTR_OPERATION_TYPE]: operationType } : {}),\n [ATTR_TRANSPORT]: transport,\n };\n\n return {\n operationName,\n operationType,\n logFields,\n variableLogFields: variableLogField(\n options.variableValues,\n config.logger?.includeVariables,\n ),\n attributes: () => ({\n ...(logFields as Attributes),\n ...(config.otel?.includeDocument === false\n ? {}\n : { [ATTR_DOCUMENT]: print(options.document) }),\n ...variableAttributes(\n options.variableValues,\n config.otel?.includeVariables,\n ),\n }),\n };\n}\n\n/**\n * Wraps a subscription's event stream so delivered events are observable no\n * matter which transport consumes them.\n */\nexport async function* wrapSubscriptionIterator(\n iterator: AsyncIterable<ExecutionResult>,\n telemetry: {\n log?: RumbleLogger;\n tracer?: Tracer;\n setupSpanContext?: SpanContext;\n logFields: Record<string, unknown>;\n attributes: Attributes;\n },\n): AsyncGenerator<ExecutionResult> {\n const { log, tracer, setupSpanContext, logFields, attributes } = telemetry;\n\n const recordEventErrors = (\n eventCount: number,\n errors: readonly unknown[],\n ) => {\n if (!tracer) return;\n const span = tracer.startSpan(SPAN_SUBSCRIBE_EVENT, {\n root: true,\n links: setupSpanContext ? [{ context: setupSpanContext }] : undefined,\n attributes: {\n ...attributes,\n [ATTR_SUBSCRIPTION_EVENT_INDEX]: eventCount,\n },\n });\n recordSpanErrors(span, errors);\n span.end();\n };\n\n let eventCount = 0;\n try {\n for await (const event of iterator) {\n eventCount++;\n if (event.errors?.length) {\n log?.error(\n {\n ...logFields,\n [FIELD_EVENT_COUNT]: eventCount,\n ...errorsLogField(event.errors),\n },\n \"graphql subscription event error\",\n );\n recordEventErrors(eventCount, event.errors);\n }\n yield event;\n }\n log?.info(\n {\n ...logFields,\n [FIELD_EVENT_COUNT]: eventCount,\n },\n \"graphql subscription completed\",\n );\n } catch (error) {\n log?.error(\n {\n ...logFields,\n [FIELD_EVENT_COUNT]: eventCount,\n ...errorLogField(error),\n },\n \"graphql subscription threw\",\n );\n recordEventErrors(eventCount, [error]);\n throw error;\n }\n}\n\nexport function buildTracedExecute<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>(\n executeFn: (\n args: ExecutionArgs,\n ) => Promise<ExecutionResult> | ExecutionResult,\n rumbleInput: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>,\n transport: RumbleTransport,\n): (args: ExecutionArgs) => Promise<ExecutionResult> {\n if (!telemetryEnabled(rumbleInput)) {\n return executeFn as (args: ExecutionArgs) => Promise<ExecutionResult>;\n }\n\n return async (options: ExecutionArgs): Promise<ExecutionResult> => {\n const tracer = telemetryTracer(rumbleInput);\n let log = telemetryLogger(rumbleInput);\n const telemetry = buildOperationTelemetry(rumbleInput, transport, options);\n const start = startTimer();\n\n const run = async (span?: Span) => {\n log?.info(\n { ...telemetry.logFields, ...telemetry.variableLogFields },\n \"graphql execute start\",\n );\n\n try {\n const result = await executeFn(options);\n\n if (result && \"errors\" in result && result.errors?.length) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorsLogField(result.errors),\n },\n \"graphql execute completed with errors\",\n );\n recordSpanErrors(span, result.errors);\n markErrorsReported(result.errors);\n } else {\n log?.info(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n },\n \"graphql execute completed\",\n );\n }\n\n return result;\n } catch (error) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorLogField(error),\n },\n \"graphql execute threw\",\n );\n recordSpanError(span, error);\n markErrorsReported([error]);\n throw error;\n }\n };\n\n if (!tracer) return run();\n\n return tracer.startActiveSpan(\n SPAN_EXECUTE,\n { attributes: telemetry.attributes() },\n async (span: Span) => {\n if (log) {\n const correlation = traceCorrelationFields(rumbleInput, span);\n if (Object.keys(correlation).length > 0) {\n log = log.child(correlation);\n }\n }\n try {\n return await run(span);\n } finally {\n span.end();\n }\n },\n );\n };\n}\n\nexport function buildTracedSubscribe<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>(\n subscribeFn: (\n args: ExecutionArgs,\n ) =>\n | Promise<AsyncIterable<ExecutionResult> | ExecutionResult>\n | AsyncIterable<ExecutionResult>\n | ExecutionResult,\n rumbleInput: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>,\n transport: RumbleTransport,\n): (\n args: ExecutionArgs,\n) => Promise<AsyncIterable<ExecutionResult> | ExecutionResult> {\n if (!telemetryEnabled(rumbleInput)) {\n return subscribeFn as (\n args: ExecutionArgs,\n ) => Promise<AsyncIterable<ExecutionResult> | ExecutionResult>;\n }\n\n return async (\n options: ExecutionArgs,\n ): Promise<AsyncIterable<ExecutionResult> | ExecutionResult> => {\n const tracer = telemetryTracer(rumbleInput);\n let log = telemetryLogger(rumbleInput);\n const telemetry = buildOperationTelemetry(rumbleInput, transport, options);\n const start = startTimer();\n // Built once so the event spans carry the same attributes as the setup span.\n const attributes = tracer ? telemetry.attributes() : {};\n\n const doSubscribe = async (\n span?: Span,\n ): Promise<AsyncIterable<ExecutionResult> | ExecutionResult> => {\n log?.info(\n { ...telemetry.logFields, ...telemetry.variableLogFields },\n \"graphql subscribe start\",\n );\n\n try {\n const result = await subscribeFn(options);\n\n if (!isAsyncIterable(result)) {\n const execResult = result as ExecutionResult;\n if (execResult.errors?.length) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorsLogField(execResult.errors),\n },\n \"graphql subscribe completed with errors\",\n );\n recordSpanErrors(span, execResult.errors);\n markErrorsReported(execResult.errors);\n }\n return execResult;\n }\n\n log?.info(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n },\n \"graphql subscription established\",\n );\n\n return wrapSubscriptionIterator(\n result as AsyncIterable<ExecutionResult>,\n {\n log,\n tracer,\n setupSpanContext: span?.spanContext(),\n logFields: telemetry.logFields,\n attributes,\n },\n );\n } catch (error) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorLogField(error),\n },\n \"graphql subscribe threw\",\n );\n recordSpanError(span, error);\n markErrorsReported([error]);\n throw error;\n }\n };\n\n if (!tracer) return doSubscribe();\n\n return tracer.startActiveSpan(\n SPAN_SUBSCRIBE,\n { attributes },\n async (span: Span) => {\n if (log) {\n const correlation = traceCorrelationFields(rumbleInput, span);\n if (Object.keys(correlation).length > 0) {\n log = log.child(correlation);\n }\n }\n try {\n return await doSubscribe(span);\n } finally {\n // Ends after setup, not after the last event: a span kept open for the\n // lifetime of a subscription would never be exported in time.\n span.end();\n }\n },\n );\n };\n}\n\nexport { defaultExecute, defaultSubscribe };\n","import type { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { RumbleError } from \"../../types/rumbleError\";\nimport { mapSQLTypeToGraphQLType } from \"./mapSQLTypeToTSType\";\nimport type { PossibleSQLType } from \"./types\";\n\nexport function buildPothosResponseTypeFromGraphQLType<\n Builder extends DrizzleObjectFieldBuilder<any, any, any, any>,\n>({\n builder,\n sqlType,\n fieldName,\n nullable,\n isArray,\n}: {\n builder: Builder;\n sqlType: PossibleSQLType;\n fieldName: string;\n nullable: boolean;\n isArray: boolean;\n}) {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n switch (gqlType) {\n case \"Int\":\n return isArray\n ? builder.exposeIntList(fieldName, { nullable: nullable as any })\n : builder.exposeInt(fieldName, { nullable });\n case \"BigInt\":\n return builder.field({\n type: isArray ? [\"BigInt\"] : \"BigInt\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"String\":\n return isArray\n ? builder.exposeStringList(fieldName, { nullable: nullable as any })\n : builder.exposeString(fieldName, { nullable });\n case \"Boolean\":\n return isArray\n ? builder.exposeBooleanList(fieldName, { nullable: nullable as any })\n : builder.exposeBoolean(fieldName, { nullable });\n case \"Date\":\n return builder.field({\n type: isArray ? [\"Date\"] : \"Date\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"DateTime\":\n return builder.field({\n type: isArray ? [\"DateTime\"] : \"DateTime\",\n // Drizzle's timestamp({ mode: \"string\" }) returns a string; the\n // DateTimeISO scalar expects a Date object, so coerce when needed.\n resolve: (element: any) => {\n const v = element[fieldName];\n if (v == null) return v;\n return v instanceof Date ? v : new Date(v);\n },\n nullable,\n });\n case \"Float\":\n return isArray\n ? builder.exposeFloatList(fieldName, { nullable: nullable as any })\n : builder.exposeFloat(fieldName, { nullable });\n case \"ID\":\n return isArray\n ? builder.exposeIDList(fieldName, { nullable: nullable as any })\n : builder.exposeID(fieldName, { nullable });\n case \"JSON\":\n return builder.field({\n type: isArray ? [\"JSON\"] : \"JSON\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"Bytes\":\n return builder.field({\n type: \"Bytes\",\n resolve: (element: any) => {\n const v = element[fieldName];\n if (v == null) return v;\n return Buffer.isBuffer(v) ? v.toString(\"base64\") : String(v);\n },\n nullable,\n });\n default:\n throw new RumbleError(\n `Unsupported object type ${gqlType} for column ${fieldName}`,\n );\n }\n}\n","import { is } from \"drizzle-orm\";\nimport type { MySqlAsyncDatabase } from \"drizzle-orm/mysql-core\";\nimport { MySqlTable } from \"drizzle-orm/mysql-core\";\nimport type { PgAsyncDatabase } from \"drizzle-orm/pg-core\";\nimport { PgTable } from \"drizzle-orm/pg-core\";\nimport type { SQLiteAsyncDatabase } from \"drizzle-orm/sqlite-core\";\nimport { SQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\n\nexport type DBDialect = \"mysql\" | \"postgres\" | \"sqlite\";\n\nconst dialectCache = new WeakMap<object, DBDialect>();\n\nexport function determineDBDialectFromSchema<DB extends DrizzleInstance>(\n schema: DB[\"_\"][\"relations\"],\n): DBDialect {\n const cached = dialectCache.get(schema as unknown as object);\n if (cached) return cached;\n\n const found = new Set<DBDialect>();\n\n for (const table of Object.values(schema).map((t: any) => t.table)) {\n if (!table || typeof table !== \"object\") {\n continue;\n }\n\n // `is()` survives duplicate drizzle-orm copies in node_modules where\n // `instanceof` silently returns false against the \"wrong\" class identity.\n if (is(table, PgTable)) {\n found.add(\"postgres\");\n } else if (is(table, MySqlTable)) {\n found.add(\"mysql\");\n } else if (is(table, SQLiteTable)) {\n found.add(\"sqlite\");\n }\n }\n\n const dialects = Array.from(found);\n\n if (dialects.length === 1) {\n const only = dialects[0]!;\n dialectCache.set(schema as unknown as object, only);\n return only;\n }\n\n if (dialects.length === 0) {\n throw new Error(\"No tables found in schema, could not determine dialect\");\n }\n\n throw new Error(`Multiple dialects found in schema: ${dialects.join(\", \")}`);\n}\n\nexport function isPostgresDB<\n Narrowed extends PgAsyncDatabase<any, any> = PgAsyncDatabase<any, any>,\n>(db: any): db is Narrowed {\n return determineDBDialectFromSchema(db._.relations) === \"postgres\";\n}\n\nexport function isMySQLDB<\n Narrowed extends MySqlAsyncDatabase<any, any> = MySqlAsyncDatabase<any, any>,\n>(db: any): db is Narrowed {\n return determineDBDialectFromSchema(db._.relations) === \"mysql\";\n}\n\nexport function isSQLiteDB<\n Narrowed extends SQLiteAsyncDatabase<any, any, any> = SQLiteAsyncDatabase<\n any,\n any,\n any\n >,\n>(db: any): db is Narrowed {\n return determineDBDialectFromSchema(db._.relations) === \"sqlite\";\n}\n","import { sql } from \"drizzle-orm\";\nimport { cloneDeep } from \"es-toolkit\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\nimport { errorLogField } from \"./helpers/errorLogging\";\nimport {\n isIDLikeSQLTypeString,\n isStringLikeSQLTypeString,\n} from \"./helpers/sqlTypes/types\";\nimport type { tableHelper } from \"./helpers/tableHelpers\";\nimport type { RumbleInput } from \"./types/rumbleInput\";\n\nexport async function initSearchIfApplicable(\n input: RumbleInput<any, any, any, any, any, any>,\n) {\n const log = input.logger?.enabled ? input.logger.logger : undefined;\n\n if (!isPostgresDB(input.db)) {\n const msg =\n \"Database dialect is not compatible with search, skipping search initialization. Only PostgreSQL is supported.\";\n log ? log.info({}, msg) : console.info(msg);\n return;\n }\n\n try {\n await input.db.execute(sql`CREATE EXTENSION IF NOT EXISTS pg_trgm;`);\n } catch (error) {\n const msg =\n \"Failed to create pg_trgm extension. Search functionality may not work. Ensure the database user has CREATE privilege or the extension is pre-installed.\";\n log ? log.error(errorLogField(error), msg) : console.error(msg, error);\n return;\n }\n if (input.search?.threshold) {\n // make absolutely sure the threshold is a number\n const threshold = Number(input.search.threshold);\n\n if (threshold < 0 || threshold > 1) {\n throw new Error(`Search threshold must be between 0 and 1`);\n }\n\n const result = await input.db.execute(sql`SELECT current_database()`);\n const dbName = result.rows[0].current_database;\n\n try {\n await input.db.execute(\n sql.raw(\n `ALTER DATABASE ${dbName} SET pg_trgm.similarity_threshold = ${threshold};`,\n ),\n );\n } catch (error: any) {\n // XX000 = tuple concurrently updated: multiple workers racing to set the same\n // idempotent value at startup. Safe to ignore — one of them will win.\n if (error?.cause?.code !== \"XX000\" && error?.code !== \"XX000\")\n throw error;\n }\n }\n\n if (input.search?.cpu_operator_cost) {\n if (typeof input.search.cpu_operator_cost !== \"number\") {\n throw new Error(`CPU operator cost must be a number`);\n }\n\n if (input.search.cpu_operator_cost <= 0) {\n throw new Error(`CPU operator cost must be a positive number`);\n }\n }\n}\n\n/**\n * Performs adjustments to the query args to issue a full text search in case the\n * respective feature is enabled and a search term was provided.\n */\nexport function adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities,\n}: Pick<RumbleInput<any, any, any, any, any, any>, \"search\"> & {\n //TODO types\n args: any;\n tableSchema: ReturnType<typeof tableHelper>;\n //TODO types\n abilities: any;\n}) {\n if (search?.enabled && args.search && args.search.length > 0) {\n // this prevents columns beeing searched which are not accessible to the user\n // if the abilities defined the user not to be allowed to read something, we need\n // to prevent it from beeing included in the search since this could\n // leak information\n const columnsToSearch = (\n abilities.query.many.columns\n ? Object.entries(tableSchema.columns).filter(\n ([key]) => abilities.query.many.columns[key],\n )\n : Object.entries(tableSchema.columns)\n ).filter(\n ([_key, col]) =>\n isStringLikeSQLTypeString(col.getSQLType()) ||\n isIDLikeSQLTypeString(col.getSQLType()),\n );\n\n const searchParam = sql`${args.search}`;\n\n args.extras = {\n search_distance: (table: any) =>\n sql`${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`COALESCE((${table[key]}::TEXT <-> ${searchParam}), 1)`;\n }),\n sql.raw(\" + \"),\n )}`,\n };\n\n const originalOrderBy = cloneDeep(args.orderBy);\n (args as any).orderBy = (table: any) => {\n const argsOrderBySQL = sql.join(\n Object.entries(originalOrderBy ?? {}).map(([key, value]) => {\n // value is \"asc\" or \"desc\"\n if (value === \"asc\") {\n return sql`${table[key]} ASC`;\n } else if (value === \"desc\") {\n return sql`${table[key]} DESC`;\n } else {\n throw new Error(`Invalid value ${value} for orderBy`);\n }\n }),\n sql.raw(\", \"),\n );\n\n const searchSQL = sql`search_distance ASC`;\n\n const ret = originalOrderBy\n ? sql.join([argsOrderBySQL, searchSQL], sql.raw(\", \"))\n : searchSQL;\n\n return ret;\n };\n\n const originalWhere = cloneDeep(args.where);\n\n // this limits the search to the rows which at least match the threshold score\n (args as any).where = {\n AND: [\n originalWhere ?? {},\n {\n RAW: (table: any) =>\n sql`(${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`${table[key]} % ${searchParam}`;\n }),\n sql.raw(\" OR \"),\n )})`,\n },\n ],\n };\n }\n}\n","import type { FieldMap } from \"@pothos/core\";\nimport type { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { is, One } from \"drizzle-orm\";\nimport { PgColumn } from \"drizzle-orm/pg-core\";\nimport { capitalize } from \"es-toolkit\";\nimport pluralize from \"pluralize\";\nimport type { AbilityBuilderType } from \"./abilityBuilder\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { type EnumImplementerType, isEnumSchema } from \"./enum\";\nimport { buildPothosResponseTypeFromGraphQLType } from \"./helpers/sqlTypes/mapDrizzleTypeToGraphQlType\";\nimport type { PossibleSQLType } from \"./helpers/sqlTypes/types\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport {\n ATTR_TABLE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\n// TODO remove as many as any types as possible here\n\n//TODO this is a bit flaky, we should check if we can determine the config object more reliably\n//TODO maybe a plugin can place some marker field on these objects?\n// like this?\n// if (t instanceof DrizzleObjectOptions) {\n// return true;\n// }\n\nconst isProbablyAConfigObject = (t: any) => {\n if (typeof t !== \"object\") {\n return false;\n }\n\n if (\n Object.keys(t).some((k) =>\n [\n \"args\",\n \"nullable\",\n \"query\",\n \"subscribe\",\n \"description\",\n \"type\",\n \"resolve\",\n ].find((e) => e === k),\n )\n )\n return true;\n return false;\n};\n\nexport const createObjectImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n>({\n db,\n search,\n otel,\n logger: loggerConfig,\n schemaBuilder,\n makePubSubInstance,\n whereArgImplementer,\n orderArgImplementer,\n enumImplementer,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig, Schema> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n whereArgImplementer: WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n orderArgImplementer: OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n enumImplementer: EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n any\n >;\n makePubSubInstance: MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n abilityBuilder: AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n type SchemaBuilder = SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n /**\n * Schema construction warnings go through the configured logger when there is\n * one, so they end up in the same structured stream as everything else, and\n * fall back to the console otherwise.\n */\n const warn = (msg: string, fields: Record<string, unknown> = {}) => {\n const log = loggerConfig?.enabled ? loggerConfig.logger : undefined;\n if (log) {\n log.warn({ ...fields, ...traceCorrelationFields(telemetryConfig) }, msg);\n } else {\n console.warn(msg);\n }\n };\n return <TableName extends TableRelationNames<DB>, RefName extends string>({\n table,\n refName,\n readAction = \"read\" as Action,\n adjust,\n }: {\n /**\n * The table you want to be used as reference for the object creation.\n */\n table: TableName;\n /**\n * The name you want this object to have in your graphql schema.\n * Rumble will create a reasonable default if not specified.\n */\n refName?: RefName;\n /**\n * The action used for read access to the table.\n * Defaults to \"read\".\n */\n readAction?: Action;\n /**\n * A function which can be used to adjust the fields of the object.\n * You can extend the object by specifying fields that do not exist as\n * per your db schema, or overwrite existing fields with the same name.\n * In case you do overwrite, rumble will set proper nullability and\n * subscription properties if you do not specify them explicitly.\n */\n adjust?:\n | ((\n t: DrizzleObjectFieldBuilder<\n SchemaBuilder[\"$inferSchemaTypes\"],\n SchemaBuilder[\"$inferSchemaTypes\"][\"DrizzleRelations\"][TableName],\n DrizzleTableValueType<DB, TableName>\n >,\n ) => FieldMap)\n | undefined;\n }) => {\n const tableSchema = tableHelper({ db, table });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n warn(\n `Could not find primary key for ${String(table)}. Cannot register subscriptions!`,\n { [ATTR_TABLE]: String(table) },\n );\n }\n const primaryKey = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n return schemaBuilder.drizzleObject(table, {\n name: refName ?? capitalize(String(table)),\n subscribe: (subscriptions, element, _context) => {\n if (!primaryKey) return;\n const primaryKeyValue = (element as any)[primaryKey.name];\n if (!primaryKeyValue) {\n warn(\n `Could not find primary key value for element on ${String(table)}. Cannot register subscription!`,\n { [ATTR_TABLE]: String(table) },\n );\n return;\n }\n\n //TODO maybe register non specific update calls aswell?\n registerOnInstance({\n instance: subscriptions,\n action: \"updated\",\n primaryKeyValue: primaryKeyValue,\n });\n },\n applyFilters: abilityBuilder?._.registeredFilters({\n table,\n action: readAction,\n }),\n fields: (t) => {\n const columns = tableSchema.columns;\n\n // in case the user makes adjustments we want to store away which\n // pothos function was called with what config\n // this is mapped to the ref which later can be used to\n // reference these parameters while iterating over the fields\n // and checking against the userAdjustments object\n // this is necessary to e.g. merge nullability info from the database schema\n // or register subscriptions on relations\n const configMap = new Map<\n any,\n {\n creatorFunction: (...p: any[]) => any;\n params: any[];\n configObject: any;\n }\n >();\n // stores the results of the user adjustments\n // also stores all the used pothos functions and the configs\n // provided by the user so we can extend that if necessary\n const userAdjustments =\n adjust?.(\n new Proxy(t, {\n get: (target, prop, _receiver) => {\n if (\n // we only care for field/relation functions\n typeof (target as any)[prop] !== \"function\" ||\n prop === \"arg\" ||\n prop === \"builder\" ||\n prop === \"graphqlKind\" ||\n prop === \"kind\" ||\n prop === \"listRef\" ||\n prop === \"table\" ||\n prop === \"typename\" ||\n prop === \"variant\" ||\n prop.toString().startsWith(\"boolean\") ||\n prop.toString().startsWith(\"float\") ||\n prop.toString().startsWith(\"id\") ||\n prop.toString().startsWith(\"int\") ||\n prop.toString().startsWith(\"string\") ||\n prop.toString().startsWith(\"expose\")\n ) {\n return (target as any)[prop];\n }\n\n return (...params: any[]) => {\n const ref = (target as any)[prop](...params);\n const configObject = params.find(isProbablyAConfigObject);\n if (!configObject)\n throw new RumbleError(\n \"Expected config object to be passed to adjust field\",\n );\n\n configMap.set(ref, {\n params,\n creatorFunction: (target as any)[prop],\n configObject,\n });\n return ref;\n };\n },\n }) as any,\n ) ?? {};\n\n const fields = Object.entries(columns).reduce(\n (acc, [key, column]) => {\n // GraphQL reserves all names beginning with \"__\" for introspection.\n // Skip such columns silently — the user must expose them manually\n // via `adjust` if they truly need them.\n if (key.startsWith(\"__\")) {\n warn(\n `Skipping column \"${key}\" on table \"${tableSchema.tsName}\": names starting with \"__\" are reserved by GraphQL introspection. Use a custom adjust() call if you really need to expose this column.`,\n { [ATTR_TABLE]: tableSchema.tsName },\n );\n return acc;\n }\n\n // in case the user wants to overwrite a field\n // we want to merge with our stuff in case the user\n // did not specify it themselves\n if (userAdjustments[key]) {\n const { params, creatorFunction, configObject } = configMap.get(\n userAdjustments[key],\n )!;\n\n if (typeof configObject.nullable !== \"boolean\") {\n configObject.nullable = !column.notNull;\n }\n\n userAdjustments[key] = creatorFunction.bind(t)(...params);\n return acc;\n }\n\n // Array columns only exist on Postgres; `dimensions` is a runtime\n // property of PgColumn instances. Gate via is() so MySQL/SQLite\n // columns aren't probed for a field they don't have.\n let isArray = false;\n if (is(column, PgColumn)) {\n const dimensions = (column as PgColumn & { dimensions?: number })\n .dimensions;\n if (dimensions && dimensions > 0) {\n if (dimensions !== 1) {\n throw new RumbleError(\n \"Only one-dimensional arrays are supported for default object implementation\",\n );\n }\n isArray = true;\n }\n }\n\n if (isEnumSchema(column)) {\n const enumImpl = enumImplementer({\n enumColumn: column,\n });\n\n acc[key] = t.field({\n type: isArray ? [enumImpl] : enumImpl,\n resolve: (element) => (element as any)[key],\n nullable: !column.notNull,\n });\n } else {\n acc[key] = buildPothosResponseTypeFromGraphQLType({\n builder: t,\n sqlType: column.getSQLType() as PossibleSQLType,\n fieldName: key,\n nullable: !column.notNull,\n isArray,\n });\n }\n return acc;\n },\n {} as Record<\n keyof typeof columns,\n | ReturnType<typeof buildPothosResponseTypeFromGraphQLType>\n | ReturnType<typeof t.field>\n >,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n const targetTsName = (value as any).targetTableName as string;\n const relationSchema = tableHelper({\n db,\n table: targetTsName,\n });\n const WhereArg = whereArgImplementer({\n dbName: relationSchema.dbName,\n });\n const OrderArg = orderArgImplementer({\n dbName: relationSchema.dbName,\n });\n const relationTablePubSub = makePubSubInstance({\n table: relationSchema.tsName as any,\n });\n\n // many relations will return an empty array so we just don't set them nullable\n let nullable = false;\n let isMany = true;\n let filterSpecifier = \"many\";\n if (is(value, One)) {\n isMany = false;\n nullable =\n value.optional ||\n !value.sourceColumns.every((column) => column.notNull);\n filterSpecifier = \"single\";\n }\n\n const subscribe = (subscriptions: any, _element: any) => {\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n };\n\n // in case the user wants to overwrite a field\n // we want to merge with our stuff in case the user\n // did not specify it themselves\n if (userAdjustments[key]) {\n const { params, creatorFunction, configObject } = configMap.get(\n userAdjustments[key],\n )!;\n\n if (typeof configObject.nullable !== \"boolean\") {\n configObject.nullable = nullable;\n }\n\n if (typeof configObject.subscribe !== \"function\") {\n configObject.subscribe = subscribe;\n }\n\n userAdjustments[key] = creatorFunction.bind(t)(...params);\n return acc;\n }\n\n const args = {\n where: t.arg({ type: WhereArg, required: false }),\n orderBy: t.arg({ type: OrderArg, required: false }),\n ...(isMany\n ? {\n offset: t.arg.int({ required: false }),\n limit: t.arg.int({ required: false }),\n }\n : {}),\n search: t.arg.string({ required: false }),\n };\n\n if (!search?.enabled || !isMany) {\n delete (args as any).search;\n }\n\n (acc as any)[key] = t.relation(\n key as any,\n {\n args,\n subscribe,\n nullable,\n description: `Get the ${pluralize.plural(relationSchema.tsName)} related to this ${pluralize.singular(tableSchema.tsName)}`,\n query: (args: any, ctx: any) => {\n // transform null prototyped object\n args = JSON.parse(JSON.stringify(args));\n\n if (isMany) {\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema: relationSchema,\n abilities:\n ctx.abilities[relationSchema.tsName].filter(readAction),\n });\n }\n\n const filter = ctx.abilities[relationSchema.tsName]\n .filter(readAction)\n .merge({\n where: args.where,\n limit: args.limit,\n extras: args.extras,\n }).query[filterSpecifier];\n\n if (args.offset) {\n (filter as any).offset = args.offset;\n }\n\n if (args.orderBy) {\n (filter as any).orderBy = args.orderBy;\n }\n\n return filter;\n },\n } as any,\n ) as any;\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.relations,\n ReturnType<typeof buildPothosResponseTypeFromGraphQLType>\n >,\n );\n\n if (search?.enabled) {\n if (fields.search_distance) {\n throw new Error(\n \"Reserved field name 'search_distance' found on \" +\n tableSchema.tsName +\n \". If search is enabled, the 'search_distance' field is automatically added and cannot be defined manually.\",\n );\n }\n\n fields.search_distance = t.float({\n description:\n \"The search distance of the object. If a search is provided, this field will be populated with the search distance.\",\n nullable: true,\n resolve: (parent, _args, _ctx, _info) =>\n (parent as any).search_distance,\n });\n }\n\n return {\n ...fields,\n ...relations,\n ...userAdjustments,\n };\n },\n });\n };\n};\n","import { createPubSub } from \"graphql-yoga\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\ntype PubSubAction = \"created\" | \"removed\" | \"updated\";\n\nconst SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX = \"RUMBLE_SUBSCRIPTION_NOTIFICATION\";\nconst SUBSCRIPTION_NOTIFIER_REMOVED = \"REMOVED\";\nconst SUBSCRIPTION_NOTIFIER_UPDATED = \"UPDATED\";\nconst SUBSCRIPTION_NOTIFIER_CREATED = \"CREATED\";\n\nexport type MakePubSubInstanceType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>[\"makePubSubInstance\"];\n\nexport const createPubSubInstance = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n subscriptions,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n const pubsub = subscriptions\n ? createPubSub(...subscriptions)\n : createPubSub();\n\n const makePubSubInstance = <\n TableName extends keyof DrizzleQueryFunction<DB>,\n >({\n table,\n }: {\n table: TableName;\n }) => {\n type PrimaryKeyType = any;\n\n function makePubSubKey({\n action,\n tableName,\n primaryKeyValue,\n }: {\n tableName: string;\n action: PubSubAction;\n primaryKeyValue?: PrimaryKeyType;\n }) {\n let actionKey: string;\n\n switch (action) {\n case \"created\":\n actionKey = SUBSCRIPTION_NOTIFIER_CREATED;\n break;\n case \"removed\":\n actionKey = SUBSCRIPTION_NOTIFIER_REMOVED;\n break;\n case \"updated\":\n actionKey = SUBSCRIPTION_NOTIFIER_UPDATED;\n break;\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n\n return `${SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX}/${tableName}${\n primaryKeyValue ? `/${primaryKeyValue}` : \"\"\n }/${actionKey}`;\n }\n\n // TODO does caching these make sense?\n return {\n /**\n * Call this when you want to register a subscription on an instance to this table\n */\n registerOnInstance({\n instance,\n action,\n primaryKeyValue,\n }: {\n instance: { register: (id: string) => void };\n action: PubSubAction;\n primaryKeyValue?: string;\n }) {\n const key = makePubSubKey({\n tableName: table.toString(),\n action,\n primaryKeyValue,\n });\n instance.register(key);\n },\n /**\n * Call this when you created an entity of this table\n */\n created() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"created\",\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you removed one or more entities of this table\n */\n // removed(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n removed() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"removed\",\n //TODO would it make sense to use specific sub topics here?\n // primaryKeyValue,\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you updated one or more entities of this table\n */\n updated(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n const primaryKeys = Array.isArray(primaryKeyValue)\n ? primaryKeyValue\n : [primaryKeyValue];\n const keys = primaryKeys.map((primaryKeyValue) =>\n makePubSubKey({\n tableName: table.toString(),\n action: \"updated\",\n primaryKeyValue,\n }),\n );\n const uniqueKeys = Array.from(new Set(keys));\n for (const key of uniqueKeys) {\n pubsub.publish(key);\n }\n },\n };\n };\n\n return {\n pubsub,\n makePubSubInstance,\n };\n};\n","import { sql } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFindFirstExists } from \"./helpers/asserts\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport {\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\nexport const createQueryImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n>({\n db,\n schemaBuilder,\n search,\n otel,\n logger: loggerConfig,\n whereArgImplementer,\n orderArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig, Schema> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n whereArgImplementer: WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n orderArgImplementer: OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n makePubSubInstance: MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const registeredQueryFieldNames = new Set<string>();\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n\n return <TableName extends TableRelationNames<DB>>({\n table,\n readAction = \"read\" as Action,\n listAction = \"read\" as Action,\n findFirst,\n findMany,\n }: {\n /**\n * The table for which to implement the query\n */\n table: TableName;\n /**\n * Which action should be used for reading single entities\n * @default \"read\"\n */\n readAction?: Action;\n /**\n * Which action should be used for listing many entities\n * @default \"read\"\n */\n listAction?: Action;\n\n findMany?: (p: {\n tx: DB | Parameters<Parameters<DB[\"transaction\"]>[0]>[0];\n filter: Parameters<DrizzleQueryFunction<DB>[TableName][\"findMany\"]>[0];\n queryArgs: Parameters<DrizzleQueryFunction<DB>[TableName][\"findMany\"]>[0];\n }) => ReturnType<DrizzleQueryFunction<DB>[TableName][\"findMany\"]>;\n\n findFirst?: (p: {\n tx: DB;\n filter: Parameters<DrizzleQueryFunction<DB>[TableName][\"findFirst\"]>[0];\n queryArgs: Parameters<\n DrizzleQueryFunction<DB>[TableName][\"findFirst\"]\n >[0];\n }) => ReturnType<DrizzleQueryFunction<DB>[TableName][\"findFirst\"]>;\n }) => {\n const WhereArg = whereArgImplementer({\n table: table,\n });\n const OrderArg = orderArgImplementer({\n table: table,\n });\n const tableSchema = tableHelper({\n db,\n table,\n });\n const primaryKeyField = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n const pluralName = pluralize.plural(String(table));\n const singularName = pluralize.singular(String(table));\n for (const name of [pluralName, singularName]) {\n if (registeredQueryFieldNames.has(name)) {\n throw new RumbleError(\n `Duplicate query field \"${name}\": the table \"${String(table)}\" generates a ` +\n `query field that collides with one already registered. Use unique table names ` +\n `(or refNames) to avoid plural/singular collisions (e.g. \"post\" and \"posts\").`,\n );\n }\n registeredQueryFieldNames.add(name);\n }\n\n return schemaBuilder.queryFields((t) => {\n const manyArgs = {\n where: t.arg({ type: WhereArg, required: false }),\n orderBy: t.arg({ type: OrderArg, required: false }),\n limit: t.arg.int({ required: false }),\n offset: t.arg.int({ required: false }),\n search: t.arg.string({ required: false }),\n };\n\n if (!search?.enabled) {\n delete (manyArgs as any).search;\n }\n\n return {\n [pluralName]: t.drizzleField({\n type: [table],\n nullable: false,\n smartSubscription: true,\n description: `List all ${pluralName}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: manyArgs,\n resolve: (query, _root, args, ctx, _info) => {\n // args does not have Object.prototype as prototype, so we need to set it\n // otherwise some libraries (like drizzle-orm) might have issues with it\n deepSetProto(args);\n\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities: ctx.abilities[table].filter(listAction),\n });\n\n const mappedArgs = mapNullFieldsToUndefined(args);\n const filter = ctx.abilities[table]\n .filter(listAction)\n .merge(mappedArgs as any).query.many;\n\n if (mappedArgs.offset) {\n (filter as any).offset = mappedArgs.offset;\n }\n\n if (mappedArgs.orderBy) {\n (filter as any).orderBy = mappedArgs.orderBy;\n }\n\n const queryArgs = query(filter as any);\n\n if ((filter as any).columns) {\n queryArgs.columns = (filter as any).columns;\n }\n\n const run = findMany\n ? (tx: DB) => findMany({ tx, filter: filter as any, queryArgs })\n : (tx: any) => (tx.query as any)[table].findMany(queryArgs);\n\n if (\n search?.enabled &&\n args.search &&\n args.search.length > 0 &&\n search?.cpu_operator_cost\n ) {\n return db.transaction(async (tx: any) => {\n if (isPostgresDB(tx)) {\n await tx.execute(\n sql.raw(\n `SET cpu_operator_cost = ${search.cpu_operator_cost};`,\n ),\n );\n } else {\n const msg =\n \"Database dialect is not postgresql, cannot set cpu_operator_cost.\";\n const log = loggerConfig?.enabled\n ? loggerConfig.logger\n : undefined;\n log\n ? log.info(traceCorrelationFields(telemetryConfig), msg)\n : console.info(msg);\n }\n\n return run(tx);\n });\n }\n\n return run(db);\n },\n }),\n [singularName]: t.drizzleField({\n type: table,\n nullable: false,\n smartSubscription: true,\n description: `Get a single ${singularName} by ID`,\n args: {\n id: t.arg.id({ required: true }),\n },\n resolve: (query, _root, args, ctx, _info) => {\n deepSetProto(args);\n\n const filter = (ctx.abilities as any)[table]\n .filter(readAction)\n .merge({ where: { [primaryKeyField.name]: args.id } })\n .query.single;\n const queryArgs = query(filter);\n\n if (filter.columns) {\n queryArgs.columns = filter.columns;\n }\n\n return findFirst\n ? findFirst({ tx: db, filter: filter as any, queryArgs })\n : (db.query as any)[table]\n .findFirst(queryArgs)\n .then(assertFindFirstExists);\n },\n }),\n };\n });\n };\n};\n","export type NumberWhereInputArgument = {\n eq?: number;\n ne?: number;\n gt?: number;\n gte?: number;\n lt?: number;\n lte?: number;\n in?: number[];\n notIn?: number[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: number[];\n arrayContained?: number[];\n arrayContains?: number[];\n AND?: NumberWhereInputArgument[];\n OR?: NumberWhereInputArgument[];\n NOT?: NumberWhereInputArgument;\n};\n\nexport type StringWhereInputArgument = {\n eq?: string;\n ne?: string;\n gt?: string;\n gte?: string;\n lt?: string;\n lte?: string;\n in?: string[];\n notIn?: string[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: string[];\n arrayContained?: string[];\n arrayContains?: string[];\n AND?: StringWhereInputArgument[];\n OR?: StringWhereInputArgument[];\n NOT?: StringWhereInputArgument;\n};\n\nexport type DateWhereInputArgument = {\n eq?: Date;\n ne?: Date;\n gt?: Date;\n gte?: Date;\n lt?: Date;\n lte?: Date;\n in?: Date[];\n notIn?: Date[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: Date[];\n arrayContained?: Date[];\n arrayContains?: Date[];\n AND?: DateWhereInputArgument[];\n OR?: DateWhereInputArgument[];\n NOT?: DateWhereInputArgument;\n};\n\nexport type BooleanWhereInputArgument = {\n eq?: boolean;\n ne?: boolean;\n in?: boolean[];\n notIn?: boolean[];\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: boolean[];\n arrayContained?: boolean[];\n arrayContains?: boolean[];\n AND?: BooleanWhereInputArgument[];\n OR?: BooleanWhereInputArgument[];\n NOT?: BooleanWhereInputArgument;\n};\n\nexport type IDWhereInputArgument = {\n eq?: string;\n ne?: string;\n gt?: string;\n gte?: string;\n lt?: string;\n lte?: string;\n in?: string[];\n notIn?: string[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: string[];\n arrayContained?: string[];\n arrayContains?: string[];\n AND?: IDWhereInputArgument[];\n OR?: IDWhereInputArgument[];\n NOT?: IDWhereInputArgument;\n};\n\nexport type JSONWhereInputArgument = {\n eq?: unknown;\n ne?: unknown;\n in?: unknown[];\n notIn?: unknown[];\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: unknown[];\n arrayContained?: unknown[];\n arrayContains?: unknown[];\n AND?: JSONWhereInputArgument[];\n OR?: JSONWhereInputArgument[];\n NOT?: JSONWhereInputArgument;\n};\n\nexport type BigIntWhereInputArgument = {\n eq?: bigint | number;\n ne?: bigint | number;\n gt?: bigint | number;\n gte?: bigint | number;\n lt?: bigint | number;\n lte?: bigint | number;\n in?: (bigint | number)[];\n notIn?: (bigint | number)[];\n isNull?: boolean;\n isNotNull?: boolean;\n AND?: BigIntWhereInputArgument[];\n OR?: BigIntWhereInputArgument[];\n NOT?: BigIntWhereInputArgument;\n};\n\nexport type DateTimeWhereInputArgument = {\n eq?: Date;\n ne?: Date;\n gt?: Date;\n gte?: Date;\n lt?: Date;\n lte?: Date;\n in?: Date[];\n notIn?: Date[];\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: Date[];\n arrayContained?: Date[];\n arrayContains?: Date[];\n AND?: DateTimeWhereInputArgument[];\n OR?: DateTimeWhereInputArgument[];\n NOT?: DateTimeWhereInputArgument;\n};\n\n// TODO: Add proper type for schemaBuilder\n\nexport function implementDefaultWhereInputArgs(schemaBuilder: any) {\n const IntWhereInputArgument = schemaBuilder\n .inputRef(\"IntWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.int(),\n ne: t.int(),\n gt: t.int(),\n gte: t.int(),\n lt: t.int(),\n lte: t.int(),\n in: t.intList(),\n notIn: t.intList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.intList(),\n arrayContained: t.intList(),\n arrayContains: t.intList(),\n AND: t.field({\n type: [IntWhereInputArgument],\n }),\n OR: t.field({\n type: [IntWhereInputArgument],\n }),\n NOT: t.field({\n type: IntWhereInputArgument,\n }),\n }),\n });\n\n const FloatWhereInputArgument = schemaBuilder\n .inputRef(\"FloatWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.float(),\n ne: t.float(),\n gt: t.float(),\n gte: t.float(),\n lt: t.float(),\n lte: t.float(),\n in: t.floatList(),\n notIn: t.floatList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.floatList(),\n arrayContained: t.floatList(),\n arrayContains: t.floatList(),\n AND: t.field({\n type: [FloatWhereInputArgument],\n }),\n OR: t.field({\n type: [FloatWhereInputArgument],\n }),\n NOT: t.field({\n type: FloatWhereInputArgument,\n }),\n }),\n });\n\n const StringWhereInputArgument = schemaBuilder\n .inputRef(\"StringWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.string(),\n ne: t.string(),\n gt: t.string(),\n gte: t.string(),\n lt: t.string(),\n lte: t.string(),\n in: t.stringList(),\n notIn: t.stringList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.stringList(),\n arrayContained: t.stringList(),\n arrayContains: t.stringList(),\n AND: t.field({\n type: [StringWhereInputArgument],\n }),\n OR: t.field({\n type: [StringWhereInputArgument],\n }),\n NOT: t.field({\n type: StringWhereInputArgument,\n }),\n }),\n });\n\n const DateWhereInputArgument = schemaBuilder\n .inputRef(\"DateWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"Date\" }),\n ne: t.field({ type: \"Date\" }),\n gt: t.field({ type: \"Date\" }),\n gte: t.field({ type: \"Date\" }),\n lt: t.field({ type: \"Date\" }),\n lte: t.field({ type: \"Date\" }),\n in: t.field({ type: [\"Date\"] }),\n notIn: t.field({ type: [\"Date\"] }),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.field({ type: [\"Date\"] }),\n arrayContained: t.field({ type: [\"Date\"] }),\n arrayContains: t.field({ type: [\"Date\"] }),\n AND: t.field({\n type: [DateWhereInputArgument],\n }),\n OR: t.field({\n type: [DateWhereInputArgument],\n }),\n NOT: t.field({\n type: DateWhereInputArgument,\n }),\n }),\n });\n\n const BooleanWhereInputArgument = schemaBuilder\n .inputRef(\"BooleanWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.boolean(),\n ne: t.boolean(),\n in: t.booleanList(),\n notIn: t.booleanList(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.booleanList(),\n arrayContained: t.booleanList(),\n arrayContains: t.booleanList(),\n AND: t.field({\n type: [BooleanWhereInputArgument],\n }),\n OR: t.field({\n type: [BooleanWhereInputArgument],\n }),\n NOT: t.field({\n type: BooleanWhereInputArgument,\n }),\n }),\n });\n\n const IDWhereInputArgument = schemaBuilder\n .inputRef(\"IDWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.id(),\n ne: t.id(),\n gt: t.id(),\n gte: t.id(),\n lt: t.id(),\n lte: t.id(),\n in: t.idList(),\n notIn: t.idList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.idList(),\n arrayContained: t.idList(),\n arrayContains: t.idList(),\n AND: t.field({\n type: [IDWhereInputArgument],\n }),\n OR: t.field({\n type: [IDWhereInputArgument],\n }),\n NOT: t.field({\n type: IDWhereInputArgument,\n }),\n }),\n });\n\n const JSONWhereInputArgument = schemaBuilder\n .inputRef(\"JSONWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"JSON\", required: false }),\n ne: t.field({ type: \"JSON\", required: false }),\n in: t.field({ type: [\"JSON\"], required: false }),\n notIn: t.field({ type: [\"JSON\"], required: false }),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.field({ type: [\"JSON\"], required: false }),\n arrayContained: t.field({ type: [\"JSON\"], required: false }),\n arrayContains: t.field({ type: [\"JSON\"], required: false }),\n AND: t.field({\n type: [JSONWhereInputArgument],\n }),\n OR: t.field({\n type: [JSONWhereInputArgument],\n }),\n NOT: t.field({\n type: JSONWhereInputArgument,\n }),\n }),\n });\n\n const BigIntWhereInputArgument = schemaBuilder\n .inputRef(\"BigIntWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"BigInt\", required: false }),\n ne: t.field({ type: \"BigInt\", required: false }),\n gt: t.field({ type: \"BigInt\", required: false }),\n gte: t.field({ type: \"BigInt\", required: false }),\n lt: t.field({ type: \"BigInt\", required: false }),\n lte: t.field({ type: \"BigInt\", required: false }),\n in: t.field({ type: [\"BigInt\"], required: false }),\n notIn: t.field({ type: [\"BigInt\"], required: false }),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n AND: t.field({ type: [BigIntWhereInputArgument] }),\n OR: t.field({ type: [BigIntWhereInputArgument] }),\n NOT: t.field({ type: BigIntWhereInputArgument }),\n }),\n });\n\n const DateTimeWhereInputArgument = schemaBuilder\n .inputRef(\"DateTimeWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"DateTime\", required: false }),\n ne: t.field({ type: \"DateTime\", required: false }),\n gt: t.field({ type: \"DateTime\", required: false }),\n gte: t.field({ type: \"DateTime\", required: false }),\n lt: t.field({ type: \"DateTime\", required: false }),\n lte: t.field({ type: \"DateTime\", required: false }),\n in: t.field({ type: [\"DateTime\"], required: false }),\n notIn: t.field({ type: [\"DateTime\"], required: false }),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.field({ type: [\"DateTime\"], required: false }),\n arrayContained: t.field({ type: [\"DateTime\"], required: false }),\n arrayContains: t.field({ type: [\"DateTime\"], required: false }),\n AND: t.field({ type: [DateTimeWhereInputArgument] }),\n OR: t.field({ type: [DateTimeWhereInputArgument] }),\n NOT: t.field({ type: DateTimeWhereInputArgument }),\n }),\n });\n}\n","export type Prefetch<Context, ReturnType> = (params: {\n context: Context;\n}) => Promise<ReturnType>;\n\nexport type Filter<\n Context,\n FilteredEntityType,\n PrefetchReturnType = never,\n> = (p: {\n context: Context;\n entities: FilteredEntityType[];\n prefetched: PrefetchReturnType;\n}) => FilteredEntityType[] | Promise<FilteredEntityType[]>;\n\nexport type FilterPrefetchCombo<\n Context,\n FilteredEntityType,\n PrefetchReturnType = never,\n> = {\n filter: Filter<Context, FilteredEntityType, PrefetchReturnType>;\n prefetch?: Prefetch<Context, PrefetchReturnType>;\n};\n\nexport type ApplyFiltersField<Context, T> =\n | FilterPrefetchCombo<Context, T>\n | FilterPrefetchCombo<Context, T>[]\n | undefined;\n\nexport const pluginName = \"RuntimeFiltersPlugin\" as const;\n","import type { Span, Tracer } from \"@opentelemetry/api\";\nimport SchemaBuilder, {\n BasePlugin,\n type PothosOutputFieldConfig,\n type PothosTypeConfig,\n type SchemaTypes,\n} from \"@pothos/core\";\nimport DataLoader from \"dataloader\";\nimport type { GraphQLFieldResolver } from \"graphql\";\nimport { errorLogField } from \"../helpers/errorLogging\";\nimport {\n ATTR_FIELD_NAME,\n ATTR_FILTERS_ALLOWED,\n ATTR_FILTERS_TOTAL,\n recordSpanError,\n SPAN_FILTERS_APPLY,\n SPAN_FILTERS_RESOLVE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"../helpers/telemetry\";\nimport type { RumbleLogger } from \"../types/rumbleInput\";\nimport {\n type ApplyFiltersField,\n type FilterPrefetchCombo,\n pluginName,\n} from \"./filterTypes\";\n\nexport const applyFiltersKey = \"applyFilters\";\n\ntype AnyFilterCombo = FilterPrefetchCombo<any, any, any>;\n\nexport class RuntimeFiltersPlugin<\n Types extends SchemaTypes,\n> extends BasePlugin<Types> {\n private tracer?: Tracer;\n private tracerEnabled?: boolean;\n private logger?: RumbleLogger;\n private telemetryConfig: TelemetryConfig = {};\n\n // graphql-js resolves a relation field once per sibling in a list, concurrently,\n // so without this a filter like \"can read user\" would fire once per row instead\n // of once for the whole list. Keying loaders by context means they get garbage\n // collected once the request is done, no manual cleanup needed.\n private filterLoaders = new WeakMap<\n object,\n Map<AnyFilterCombo, DataLoader<any, any>>\n >();\n\n private getLoader(\n context: Types[\"Context\"],\n filter: AnyFilterCombo,\n ): DataLoader<any, any> {\n let perContext = this.filterLoaders.get(context as object);\n if (!perContext) {\n perContext = new Map();\n this.filterLoaders.set(context as object, perContext);\n }\n\n let loader = perContext.get(filter);\n if (!loader) {\n // not awaited here on purpose, so it runs alongside the resolver instead of after it\n const prefetchPromise = filter.prefetch\n ? filter.prefetch({ context })\n : undefined;\n\n loader = new DataLoader<any, any>(\n async (entities) => {\n const prefetched = prefetchPromise\n ? await prefetchPromise\n : undefined;\n const allowed = await filter.filter({\n context,\n entities: entities as any[],\n prefetched,\n } as any);\n const allowedSet = new Set(allowed);\n return entities.map((entity) =>\n allowedSet.has(entity) ? entity : null,\n );\n },\n // cache off on purpose, we only want the batching, filters should still\n // run fresh every time like before\n { cache: false },\n );\n perContext.set(filter, loader);\n }\n\n return loader;\n }\n\n override onTypeConfig(typeConfig: PothosTypeConfig) {\n this.tracer = this.builder.options.otel?.tracer;\n this.tracerEnabled = this.builder.options.otel?.enabled;\n this.logger = this.builder.options.logger?.enabled\n ? this.builder.options.logger.logger\n : undefined;\n this.telemetryConfig = {\n otel: this.builder.options.otel,\n logger: this.builder.options.logger,\n };\n return typeConfig;\n }\n\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n return async (parent, args, context, info) => {\n let filters: ApplyFiltersField<Types[\"Context\"], any> | undefined;\n const fieldType = fieldConfig?.type as any;\n\n if (fieldType.kind === \"List\") {\n filters =\n fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];\n } else if (fieldType.kind === \"Object\") {\n filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];\n }\n\n if (!filters || !Array.isArray(filters) || filters.length === 0) {\n // if no filter should be applied, just continue\n return resolver(parent, args, context, info);\n }\n\n const runFilters = async (span?: Span) => {\n const allFilters = Array.isArray(filters) ? filters : [filters];\n span?.setAttribute(ATTR_FILTERS_TOTAL, allFilters.length);\n\n const loaders = allFilters.map((filter) =>\n this.getLoader(context, filter as AnyFilterCombo),\n );\n\n let resolved: any;\n\n if (this.tracer && this.tracerEnabled) {\n resolved = await this.tracer.startActiveSpan(\n SPAN_FILTERS_RESOLVE,\n async (span) => {\n span.setAttribute(ATTR_FIELD_NAME, fieldConfig.name);\n try {\n return await resolver(parent, args, context, info);\n } catch (error) {\n recordSpanError(span, error);\n throw error;\n } finally {\n span.end();\n }\n },\n );\n } else {\n resolved = await resolver(parent, args, context, info);\n }\n\n const entities: any[] = Array.isArray(resolved) ? resolved : [resolved];\n\n // load() instead of loadMany() so a thrown filter still rejects here\n // instead of getting swallowed into an Error value\n const perFilterResults = await Promise.all(\n loaders.map((loader) =>\n Promise.all(entities.map((entity) => loader.load(entity))),\n ),\n );\n\n const allowed = entities.filter((_, index) =>\n perFilterResults.some((results) => results[index] != null),\n );\n\n span?.setAttribute(ATTR_FILTERS_ALLOWED, allowed.length);\n this.logger?.debug(\n {\n [ATTR_FIELD_NAME]: fieldConfig.name,\n [ATTR_FILTERS_TOTAL]: allFilters.length,\n [ATTR_FILTERS_ALLOWED]: allowed.length,\n ...traceCorrelationFields(this.telemetryConfig),\n },\n \"runtime filters applied\",\n );\n\n // if the original value was an array, return an array\n if (Array.isArray(resolved)) {\n return allowed;\n }\n\n // if the original value was a single value, return the first allowed\n // or null if not allowed\n return allowed[0] ?? null;\n };\n\n const logFilterError = (error: unknown) => {\n this.logger?.error(\n {\n [ATTR_FIELD_NAME]: fieldConfig.name,\n ...traceCorrelationFields(this.telemetryConfig),\n ...errorLogField(error),\n },\n \"runtime filter threw\",\n );\n };\n\n if (this.tracer && this.tracerEnabled) {\n return this.tracer.startActiveSpan(SPAN_FILTERS_APPLY, async (span) => {\n span.setAttribute(ATTR_FIELD_NAME, fieldConfig.name);\n try {\n return await runFilters(span);\n } catch (error) {\n logFilterError(error);\n recordSpanError(span, error);\n throw error;\n } finally {\n span.end();\n }\n });\n } else {\n try {\n return await runFilters();\n } catch (error) {\n logFilterError(error);\n throw error;\n }\n }\n };\n }\n}\n\nlet registered = false;\nexport function registerRuntimeFiltersPlugin() {\n if (!registered) {\n SchemaBuilder.registerPlugin(pluginName, RuntimeFiltersPlugin);\n registered = true;\n }\n}\n","import \"lib-address\";\nimport {\n AddressValidationError,\n CountryMissingError,\n InvalidStateError,\n InvalidZipError,\n isValidCountryCode,\n MissingFieldError,\n validateAddress,\n} from \"lib-address\";\nimport { z } from \"zod\";\nimport type { AddressShape } from \"./address\";\n\nconst FIELD_PATH_MAP: Partial<Record<string, keyof AddressShape>> = {\n addressLine1: \"streetAddress\",\n addressLine2: \"streetAddress\",\n addressLine3: \"streetAddress\",\n city: \"locality\",\n dependentLocality: \"locality\",\n state: \"region\",\n zip: \"postalCode\",\n sortingCode: \"postalCode\",\n};\n\n/**\n * Fixes the unambiguous, purely-cosmetic issues (stray surrounding whitespace, wrong case)\n * before validation runs, rather than rejecting a request over them. This runs as a Zod\n * `transform`, and `@pothos/plugin-validation` uses a transform's *output* as the field's\n * actual value — so the corrected value, not the original one, is what resolvers receive.\n *\n * `countryCode` and `postalCode` are uppercased since their canonical forms always are (ISO\n * 3166-1 codes, and postal codes in every country that mixes letters and digits, e.g. GB/CA/NL).\n * `region`/`locality` are only trimmed, not case-changed: unlike country/postal codes, a region\n * is sometimes a free-text place name rather than a code (lib-address's own subdivision lookup\n * is already case-insensitive, so case coercion there wouldn't fix anything a rejection-worthy\n * case wouldn't already pass).\n */\nconst normalizeAddress = (address: {\n streetAddress: string;\n locality?: string | null;\n region?: string | null;\n postalCode?: string | null;\n countryCode: string;\n}) => ({\n streetAddress:\n address.streetAddress\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\") || null,\n locality: address.locality?.trim() || null,\n region: address.region?.trim() || null,\n postalCode: address.postalCode?.trim().toUpperCase() || null,\n countryCode: address.countryCode.trim().toUpperCase(),\n});\n\nexport const addressValidationSchema = z\n .object({\n // Required (not nullable/optional), like countryCode below: checked against libaddressinput\n // data for all 252 countries, streetAddress is the one field required in literally all of\n // them. A whitespace-only value still reaches the normal per-country MissingFieldError path\n // below (it normalizes to null, same as omitting it), rather than needing its own check —\n // unlike countryCode, there's no chicken-and-egg problem here (checking it doesn't first\n // require knowing which country's rules apply).\n streetAddress: z.string(),\n locality: z.string().nullable().optional(),\n region: z.string().nullable().optional(),\n postalCode: z.string().nullable().optional(),\n // Required (not nullable/optional): without a country there is nothing to validate the\n // other fields' requiredness/format against, so a country-less \"address\" can't be verified.\n // Whitespace-only input is caught below, after trimming, rather than here — GraphQL's own\n // non-null check only guarantees a string was sent, not a meaningful one.\n countryCode: z.string(),\n })\n .transform(normalizeAddress)\n .superRefine((address, ctx) => {\n if (!address.countryCode) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"countryCode\"],\n message: \"countryCode is required.\",\n });\n return;\n }\n\n if (!isValidCountryCode(address.countryCode)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"countryCode\"],\n message: `Unknown country code: ${address.countryCode}`,\n });\n return;\n }\n\n const [addressLine1, addressLine2, addressLine3] = address.streetAddress\n ? address.streetAddress.split(\"\\n\")\n : [];\n\n try {\n validateAddress({\n country: address.countryCode,\n addressLine1,\n addressLine2,\n addressLine3,\n city: address.locality ?? undefined,\n // lib-address's own isValidCountrySubdivisionCode is case-insensitive, but\n // validateAddress's internal state check isn't — uppercase here (not in the value\n // returned to the client, since region is free text for some countries) to work\n // around that inconsistency rather than rejecting a validly-cased subdivision code.\n state: address.region?.toUpperCase() ?? undefined,\n zip: address.postalCode ?? undefined,\n });\n } catch (error) {\n if (error instanceof CountryMissingError) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"countryCode\"],\n message: error.message,\n });\n return;\n }\n\n if (!(error instanceof AddressValidationError)) {\n throw error;\n }\n\n for (const subError of error.errors) {\n if (subError instanceof MissingFieldError) {\n const path = FIELD_PATH_MAP[subError.field];\n if (!path) {\n // e.g. \"name\"/\"organization\" — out of scope for a pure location Address.\n continue;\n }\n ctx.addIssue({\n code: \"custom\",\n path: [path],\n message: `${path} is required for country ${address.countryCode}.`,\n });\n } else if (subError instanceof InvalidZipError) {\n // Also matches the InvalidZipSubRegionError subclass (postal code doesn't match\n // the expected format for the given state/region within the country).\n ctx.addIssue({\n code: \"custom\",\n path: [\"postalCode\"],\n message: `Invalid postal code for country ${address.countryCode}.`,\n });\n } else if (subError instanceof InvalidStateError) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"region\"],\n message: `Invalid region for country ${address.countryCode}.`,\n });\n }\n }\n }\n });\n","import { addressValidationSchema } from \"./addressValidation\";\n\n/**\n * The shape of a postal address, modeled after the OIDC `address` claim\n * (https://openid.net/specs/openid-connect-core-1_0.html#AddressClaim) and schema.org's\n * `PostalAddress`.\n */\nexport type AddressShape = {\n /** The street address, which may be multiple lines separated by newlines. */\n streetAddress?: string | null;\n /** City or town. */\n locality?: string | null;\n /** State, province, prefecture or region. */\n region?: string | null;\n /** Postal or zip code. */\n postalCode?: string | null;\n /** ISO 3166-1 alpha-2 country code. */\n countryCode?: string | null;\n};\n\n/**\n * AddressInput's shape differs from AddressShape in that `countryCode` and `streetAddress` are\n * required. `countryCode`: without a country there is nothing for the validator to check\n * requiredness/format/region against, so a country-less \"address\" can't be verified as valid\n * for anywhere. `streetAddress`: checked against every one of the 252 countries in\n * libaddressinput's dataset — it is the one field required in literally all of them (unlike\n * e.g. city, which 13 countries including Japan and Singapore don't require, or state/zip,\n * required in barely a sixth to a third of countries) — so it's safe to require unconditionally\n * rather than only per-country. The remaining fields stay optional since their requiredness\n * genuinely varies by country; that's enforced dynamically by `addressValidationSchema` instead\n * of statically here.\n */\nexport type AddressInputShape = Omit<\n AddressShape,\n \"countryCode\" | \"streetAddress\"\n> & {\n countryCode: string;\n streetAddress: string;\n};\n\n// TODO: Add proper type for schemaBuilder\nexport function implementDefaultAddressTypes(schemaBuilder: any) {\n const Address = schemaBuilder.objectRef(\"Address\").implement({\n description:\n \"A postal address, modeled after the OIDC `address` claim and schema.org's PostalAddress.\",\n fields: (t: any) => ({\n streetAddress: t.exposeString(\"streetAddress\", { nullable: true }),\n locality: t.exposeString(\"locality\", { nullable: true }),\n region: t.exposeString(\"region\", { nullable: true }),\n postalCode: t.exposeString(\"postalCode\", { nullable: true }),\n countryCode: t.exposeString(\"countryCode\", { nullable: true }),\n }),\n });\n\n const AddressInput = schemaBuilder.inputRef(\"AddressInput\").implement({\n description:\n \"Input counterpart of Address. countryCode and streetAddress are required — countryCode \" +\n \"because there is nothing to validate the other fields against without it, and \" +\n \"streetAddress because it's the one field required in every country. The remaining \" +\n \"fields are optional since their requiredness genuinely varies by country; validated as \" +\n \"a whole using Google's libaddressinput metadata (offline).\",\n validate: addressValidationSchema,\n fields: (t: any) => ({\n streetAddress: t.string({ required: true }),\n locality: t.string({ required: false }),\n region: t.string({ required: false }),\n postalCode: t.string({ required: false }),\n countryCode: t.string({ required: true }),\n }),\n });\n\n return { Address, AddressInput };\n}\n","import { GraphQLScalarType, Kind } from \"graphql\";\nimport { EmailAddressResolver as BaseEmailAddressResolver } from \"graphql-scalars\";\nimport { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n * Validates an email address using graphql-scalars' own format check, then lowercases it.\n */\nconst normalize = (value: unknown): string => {\n try {\n return (BaseEmailAddressResolver.parseValue(value) as string).toLowerCase();\n } catch (error) {\n throw new RumbleErrorSafe(\n error instanceof Error\n ? error.message\n : `Invalid email address: ${value}`,\n );\n }\n};\n\nexport const EmailAddressResolver = new GraphQLScalarType<string, string>({\n name: \"EmailAddress\",\n description: `${BaseEmailAddressResolver.description} Lowercased.`,\n specifiedByURL: BaseEmailAddressResolver.specifiedByURL,\n serialize: normalize,\n parseValue: normalize,\n parseLiteral(ast) {\n if (ast.kind !== Kind.STRING) {\n throw new RumbleErrorSafe(\n `Can only validate strings as email addresses but got a: ${ast.kind}`,\n );\n }\n return normalize(ast.value);\n },\n});\n","import { GraphQLScalarType, Kind } from \"graphql\";\nimport { RumbleErrorSafe } from \"../types/rumbleError\";\n\nconst MAX_LENGTH = 200;\n\nconst NAME_REGEX = /^[\\p{L}\\p{M}]+(?:(?:[ '-]|\\.\\x20?)[\\p{L}\\p{M}]+)*\\.?$/u;\n\n/**\n * Normalizes and validates a person's name.\n */\nconst normalize = (value: unknown): string => {\n if (typeof value !== \"string\") {\n throw new RumbleErrorSafe(`Name value is not a string: ${value}`);\n }\n\n const normalized = value\n .normalize(\"NFC\")\n .replace(/[\\p{Cc}\\p{Cf}]/gu, \"\")\n .replace(/\\p{Zs}+/gu, \" \")\n .trim()\n .replace(/([-'])\\1+/gu, \"$1\")\n .replace(/^[-']+|[-']+$/gu, \"\")\n .trim();\n\n if (normalized.length === 0) {\n throw new RumbleErrorSafe(\"Name must not be empty.\");\n }\n\n if (normalized.length > MAX_LENGTH) {\n throw new RumbleErrorSafe(\n `Name must not be longer than ${MAX_LENGTH} characters.`,\n );\n }\n\n if (!NAME_REGEX.test(normalized)) {\n throw new RumbleErrorSafe(\n `Invalid name: ${value}. Names may only contain letters and the separators space, apostrophe, hyphen and period, and may not start with or repeat a separator.`,\n );\n }\n\n return normalized;\n};\n\nexport const PersonNameResolver = new GraphQLScalarType<string, string>({\n name: \"PersonName\",\n description:\n \"A person's name. Unicode letters from any script are allowed, along with space, apostrophe, hyphen and period as separators between name parts. The value is Unicode NFC normalized, has invisible/control characters stripped, has its whitespace collapsed, and has unambiguous typos (a doubled or stray leading/trailing hyphen/apostrophe) silently corrected rather than rejected.\",\n serialize: normalize,\n parseValue: normalize,\n parseLiteral(ast) {\n if (ast.kind !== Kind.STRING) {\n throw new RumbleErrorSafe(\n `Can only validate strings as names but got a: ${ast.kind}`,\n );\n }\n return normalize(ast.value);\n },\n});\n","import { GraphQLScalarType, Kind } from \"graphql\";\nimport {\n type PhoneNumber,\n parsePhoneNumberFromString,\n} from \"libphonenumber-js\";\nimport { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n * Parses and validates a phone number using libphonenumber-js (Google's phone number metadata),\n * which checks real per-country validity (length, area code plausibility, ...) rather than just\n * the E.164 shape.\n */\nconst parse = (value: unknown): PhoneNumber => {\n if (typeof value !== \"string\") {\n throw new RumbleErrorSafe(`Phone number value is not a string: ${value}`);\n }\n\n const phoneNumber = parsePhoneNumberFromString(value);\n if (!phoneNumber?.isValid()) {\n throw new RumbleErrorSafe(\n `Invalid phone number: ${value}. Please provide a valid phone number including its country calling code, e.g. +4915123456789.`,\n );\n }\n\n return phoneNumber;\n};\n\n/**\n * Resolvers may either return an already-parsed PhoneNumber (e.g. one obtained via `parse`\n * above) or a raw string, which is parsed and validated the same way input values are.\n */\nconst serialize = (value: unknown): string => {\n if (\n value &&\n typeof value === \"object\" &&\n typeof (value as PhoneNumber).isValid === \"function\"\n ) {\n const phoneNumber = value as PhoneNumber;\n if (!phoneNumber.isValid()) {\n throw new RumbleErrorSafe(`Invalid phone number: ${phoneNumber.number}`);\n }\n return phoneNumber.number;\n }\n\n return parse(value).number;\n};\n\nexport const PhoneNumberResolver = new GraphQLScalarType<PhoneNumber, string>({\n name: \"PhoneNumber\",\n description:\n \"A phone number, validated using real per-country validity rules and represented as a parsed libphonenumber-js PhoneNumber. On the wire it is transported as the E.164 format (https://en.wikipedia.org/wiki/E.164), e.g. +4915123456789. The country calling code is required.\",\n serialize,\n parseValue: parse,\n parseLiteral(ast) {\n if (ast.kind !== Kind.STRING) {\n throw new RumbleErrorSafe(\n `Can only validate strings as phone numbers but got a: ${ast.kind}`,\n );\n }\n return parse(ast.value);\n },\n});\n","import SchemaBuilder from \"@pothos/core\";\nimport DrizzlePlugin from \"@pothos/plugin-drizzle\";\nimport SmartSubscriptionsPlugin, {\n subscribeOptionsFromIterator,\n} from \"@pothos/plugin-smart-subscriptions\";\nimport TracingPlugin, {\n isRootField,\n wrapResolver,\n} from \"@pothos/plugin-tracing\";\nimport ValidationPlugin from \"@pothos/plugin-validation\";\nimport { createOpenTelemetryWrapper } from \"@pothos/tracing-opentelemetry\";\nimport { getTableColumns, isTable, type Table } from \"drizzle-orm\";\nimport {\n BigIntResolver,\n ByteResolver,\n DateResolver,\n DateTimeISOResolver,\n JSONResolver,\n LocaleResolver,\n} from \"graphql-scalars\";\nimport type { createPubSub } from \"graphql-yoga\";\nimport type { PhoneNumber as LibPhoneNumber } from \"libphonenumber-js\";\nimport {\n type BigIntWhereInputArgument,\n type BooleanWhereInputArgument,\n type DateTimeWhereInputArgument,\n type DateWhereInputArgument,\n type IDWhereInputArgument,\n implementDefaultWhereInputArgs,\n type JSONWhereInputArgument,\n type NumberWhereInputArgument,\n type StringWhereInputArgument,\n} from \"./args/whereArgsImplementer\";\nimport type { ContextType } from \"./context\";\nimport { errorLogField } from \"./helpers/errorLogging\";\nimport {\n ATTR_FIELD_NAME,\n ATTR_PARENT_TYPE,\n FIELD_DURATION_MS,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport { pluginName } from \"./runtimeFiltersPlugin/filterTypes\";\nimport { registerRuntimeFiltersPlugin } from \"./runtimeFiltersPlugin/runtimeFiltersPlugin\";\nimport {\n type AddressInputShape,\n type AddressShape,\n implementDefaultAddressTypes,\n} from \"./scalars/address\";\nimport { EmailAddressResolver } from \"./scalars/emailAddress\";\nimport { PersonNameResolver } from \"./scalars/personName\";\nimport { PhoneNumberResolver } from \"./scalars/phoneNumber\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\nexport const createSchemaBuilder = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n pubsub,\n pothosConfig,\n otel,\n logger,\n validation,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n pubsub: ReturnType<typeof createPubSub>;\n}) => {\n const createSpan =\n otel?.enabled && otel.tracer\n ? createOpenTelemetryWrapper(otel.tracer, otel.options)\n : undefined;\n\n registerRuntimeFiltersPlugin();\n const schemaBuilder = new SchemaBuilder<{\n Context: ContextType<UserContext, DB, RequestEvent, Action, PothosConfig>;\n DrizzleRelations: DB[\"_\"][\"relations\"];\n Objects: {\n Address: AddressShape;\n };\n Scalars: {\n JSON: {\n Input: unknown;\n Output: unknown;\n };\n Date: {\n Input: Date;\n Output: Date;\n };\n DateTime: {\n Input: Date;\n Output: Date | string;\n };\n BigInt: {\n Input: bigint | number;\n Output: bigint | number | string;\n };\n Bytes: {\n Input: string;\n Output: string;\n };\n EmailAddress: {\n Input: string;\n Output: string;\n };\n PhoneNumber: {\n Input: LibPhoneNumber;\n Output: LibPhoneNumber | string;\n };\n Locale: {\n Input: string;\n Output: string;\n };\n PersonName: {\n Input: string;\n Output: string;\n };\n };\n Inputs: {\n IntWhereInputArgument: NumberWhereInputArgument;\n FloatWhereInputArgument: NumberWhereInputArgument;\n StringWhereInputArgument: StringWhereInputArgument;\n DateWhereInputArgument: DateWhereInputArgument;\n DateTimeWhereInputArgument: DateTimeWhereInputArgument;\n BigIntWhereInputArgument: BigIntWhereInputArgument;\n BooleanWhereInputArgument: BooleanWhereInputArgument;\n IDWhereInputArgument: IDWhereInputArgument;\n JSONWhereInputArgument: JSONWhereInputArgument;\n AddressInput: AddressInputShape;\n };\n DefaultFieldNullability: false;\n }>({\n ...pothosConfig,\n plugins: [\n pluginName,\n DrizzlePlugin,\n SmartSubscriptionsPlugin,\n TracingPlugin,\n ValidationPlugin,\n ...(pothosConfig?.plugins ?? []),\n ],\n drizzle: {\n client: db,\n relations: db._.relations,\n getTableConfig(table) {\n //TODO support composite primary keys\n const columns = isTable(table)\n ? Object.values(getTableColumns(table as Table))\n : [];\n return {\n columns,\n primaryKeys: columns.filter((v: any) => v.primary),\n } as any;\n },\n },\n smartSubscriptions: {\n ...subscribeOptionsFromIterator((name, _context) => {\n return pubsub.subscribe(name);\n }),\n },\n defaultFieldNullability: false,\n tracing: {\n default:\n otel?.enabled || logger?.enabled\n ? (config) => isRootField(config)\n : () => false,\n wrap: (resolver, options, config) => {\n let r = createSpan ? createSpan(resolver, options) : resolver;\n if (logger?.enabled) {\n const log = logger.logger;\n const telemetryConfig = { otel, logger };\n r = wrapResolver(r, (error, duration) => {\n const fields = {\n [ATTR_FIELD_NAME]: config.name,\n [ATTR_PARENT_TYPE]: config.parentType,\n [FIELD_DURATION_MS]: duration,\n // read from the active span, which at this point is the resolver\n // span pothos opened, so resolver logs correlate as precisely as\n // the operation level ones do\n ...traceCorrelationFields(telemetryConfig),\n };\n\n if (error) {\n log.error(\n { ...fields, ...errorLogField(error) },\n \"resolver failed\",\n );\n } else {\n log.debug(fields, \"resolver completed\");\n }\n });\n }\n return r;\n },\n },\n otel,\n logger,\n // `RumbleValidationConfig` is deliberately generic-unbound (extracted from the plugin's\n // own type, not hand-declared), so it doesn't line up with this builder's concrete\n // SchemaTypes — same category of mismatch `otel`/`logger`/`tracing` avoid by not\n // referencing Pothos generics at all.\n validation: validation as any,\n });\n\n schemaBuilder.addScalarType(\"JSON\", JSONResolver);\n schemaBuilder.addScalarType(\"Date\", DateResolver);\n schemaBuilder.addScalarType(\"DateTime\", DateTimeISOResolver);\n schemaBuilder.addScalarType(\"BigInt\", BigIntResolver);\n schemaBuilder.addScalarType(\"Bytes\", ByteResolver);\n schemaBuilder.addScalarType(\"EmailAddress\", EmailAddressResolver);\n schemaBuilder.addScalarType(\"PhoneNumber\", PhoneNumberResolver);\n schemaBuilder.addScalarType(\"Locale\", LocaleResolver);\n schemaBuilder.addScalarType(\"PersonName\", PersonNameResolver);\n implementDefaultWhereInputArgs(schemaBuilder);\n implementDefaultAddressTypes(schemaBuilder);\n\n schemaBuilder.queryType({});\n schemaBuilder.subscriptionType({});\n schemaBuilder.mutationType({});\n\n return { schemaBuilder };\n};\n","import { EnvelopArmorPlugin } from \"@escape.tech/graphql-armor\";\nimport { useDisableIntrospection } from \"@graphql-yoga/plugin-disable-introspection\";\nimport type { useSofa } from \"@m1212e/sofa-api\";\nimport { trace } from \"@opentelemetry/api\";\nimport { merge } from \"es-toolkit\";\nimport { GraphQLSchema } from \"graphql\";\nimport type { ServerOptions } from \"graphql-ws\";\nimport {\n createYoga as nativeCreateYoga,\n type Plugin,\n type YogaServerOptions,\n} from \"graphql-yoga\";\nimport packagejson from \"../package.json\";\nimport { createAbilityBuilder } from \"./abilityBuilder\";\nimport { createOrderArgImplementer } from \"./args/orderArg\";\nimport { createWhereArgImplementer } from \"./args/whereArg\";\nimport { clientCreatorImplementer } from \"./client/client\";\nimport { createContextFunction } from \"./context\";\nimport { createCountQueryImplementer } from \"./countQuery\";\nimport { createEnumImplementer, type EnumFieldKeys } from \"./enum\";\nimport { errorsLogField } from \"./helpers/errorLogging\";\nimport { lazy } from \"./helpers/lazy\";\nimport { sofaOpenAPIWebhookDocs } from \"./helpers/sofaOpenAPIWebhookDocs\";\nimport {\n ATTR_TRANSPORT,\n errorsAlreadyReported,\n recordSpanErrors,\n telemetryEnabled,\n telemetryLogger,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport {\n buildTracedExecute,\n buildTracedSubscribe,\n defaultExecute,\n defaultSubscribe,\n} from \"./helpers/tracing\";\nimport { createObjectImplementer } from \"./object\";\nimport { createPubSubInstance } from \"./pubsub\";\nimport { createQueryImplementer } from \"./query\";\nimport { createSchemaBuilder } from \"./schemaBuilder\";\nimport { initSearchIfApplicable } from \"./search\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\n/**\n * Mirrors sofa's own default error handler: it derives the HTTP status from\n * `extensions.http` and returns the errors as JSON. rumble only adds telemetry\n * around error handling, so a request that fails must still answer with the\n * status and body a plain sofa setup would have produced.\n */\nfunction sofaErrorResponse(errors: ReadonlyArray<any>): Response {\n let status: number | undefined;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json; charset=utf-8\",\n };\n\n for (const error of errors) {\n const http = error?.extensions?.http;\n if (!http) continue;\n\n if (http.status && (!status || http.status > status)) {\n status = http.status;\n }\n if (http.headers) {\n Object.assign(headers, http.headers);\n }\n // sofa strips this before serializing so the transport hint does not leak\n // into the response body\n delete error.extensions.http;\n }\n\n return Response.json(\n { errors },\n {\n status: status ?? 500,\n headers,\n },\n );\n}\n\nexport const rumble = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n Action extends string = \"read\" | \"update\" | \"delete\",\n>(\n rumbleInput: RumbleInput<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n > & {\n schema: Schema;\n },\n) => {\n if (!rumbleInput.db._.relations) {\n throw new RumbleError(`\nrumble could not find any relations in the provided drizzle instance.\nMake sure you import the relations and pass them to the drizzle instance:\n\nexport const db = drizzle(\n \"postgres://postgres:postgres@localhost:5432/postgres\",\n {\n relations, // <--- add this line\n },\n);\n\n`);\n }\n\n if (\n !rumbleInput.schema ||\n typeof rumbleInput.schema !== \"object\" ||\n Object.keys(rumbleInput.schema).length === 0\n ) {\n throw new RumbleError(`\nrumble requires the drizzle schema object to be passed when initializing.\nImport your schema module and pass it alongside \\`db\\`:\n\nimport * as schema from \"./db/schema\";\n\nexport const r = rumble({\n db,\n schema, // <--- add this line\n});\n\n`);\n }\n\n // to be able to iterate over the actions, we populate the actions array in case the user does not\n if (!rumbleInput.actions) {\n rumbleInput.actions = [\"read\", \"update\", \"delete\"] as Action[];\n }\n\n if (rumbleInput.defaultLimit === undefined) {\n rumbleInput.defaultLimit = 100;\n }\n\n if (rumbleInput.search?.enabled) {\n initSearchIfApplicable(rumbleInput);\n }\n\n if (rumbleInput.otel?.enabled && !rumbleInput.otel.tracer) {\n rumbleInput.otel.tracer = trace.getTracer(\n \"@m1212e/rumble\",\n packagejson.version,\n );\n }\n\n const abilityBuilder = createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >(rumbleInput);\n\n const context = createContextFunction<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n abilityBuilder,\n });\n\n const { makePubSubInstance, pubsub } = createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n });\n\n const { schemaBuilder } = createSchemaBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({ ...rumbleInput, pubsub });\n\n const enum_ = createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n EnumFieldKeys<Schema>,\n Schema\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const whereArg = createWhereArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n schemaBuilder,\n enumImplementer: enum_,\n });\n\n const orderArg = createOrderArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const object = createObjectImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema\n >({\n ...rumbleInput,\n schemaBuilder,\n makePubSubInstance,\n whereArgImplementer: whereArg,\n orderArgImplementer: orderArg,\n enumImplementer: enum_,\n abilityBuilder,\n });\n\n const query = createQueryImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema\n >({\n ...rumbleInput,\n schemaBuilder,\n whereArgImplementer: whereArg,\n orderArgImplementer: orderArg,\n makePubSubInstance,\n });\n\n const countQuery = createCountQueryImplementer({\n ...rumbleInput,\n schemaBuilder,\n whereArgImplementer: whereArg,\n makePubSubInstance,\n });\n\n const builtSchema = lazy(() => {\n let raw: ReturnType<typeof schemaBuilder.toSchema>;\n try {\n raw = schemaBuilder.toSchema();\n } catch (e: any) {\n const msg: string = e?.message ?? String(e);\n const unimplMatch = msg.match(\n /ObjectRef<(.+?)> has not been implemented/,\n );\n if (unimplMatch) {\n throw new RumbleError(\n `Could not build GraphQL schema: the table \"${unimplMatch[1]}\" is referenced ` +\n `in a relation but has not been registered. Call rumble.object({ table: \"${unimplMatch[1]}\" }) ` +\n `before building the schema.`,\n );\n }\n throw e;\n }\n\n const mutation = raw.getMutationType();\n const subscription = raw.getSubscriptionType();\n const emptyMutation =\n mutation && Object.keys(mutation.getFields()).length === 0;\n const emptySubscription =\n subscription && Object.keys(subscription.getFields()).length === 0;\n\n if (!emptyMutation && !emptySubscription) return raw;\n\n const config = raw.toConfig();\n const filteredTypes = config.types.filter((t) => {\n if (emptyMutation && t === mutation) return false;\n if (emptySubscription && t === subscription) return false;\n return true;\n });\n return new GraphQLSchema({\n ...config,\n mutation: emptyMutation ? undefined : config.mutation,\n subscription: emptySubscription ? undefined : config.subscription,\n types: filteredTypes,\n });\n });\n\n /**\n * Adapts the configured rumble logger to the logger interface yoga expects,\n * so yoga's own diagnostics end up in the same structured stream (with the\n * same `rumble.transport` and trace correlation fields) as rumble's entries.\n */\n const yogaLogging = () => {\n const log = telemetryLogger(rumbleInput);\n if (!log) return undefined;\n\n const emit =\n (level: \"debug\" | \"info\" | \"warn\" | \"error\") =>\n (...args: unknown[]) => {\n const messages = args.filter(\n (arg): arg is string => typeof arg === \"string\",\n );\n const rest = args.filter((arg) => typeof arg !== \"string\");\n const errors = rest.filter((entry) => entry instanceof Error);\n const details = rest.filter((entry) => !(entry instanceof Error));\n\n log[level](\n {\n [ATTR_TRANSPORT]: \"graphql\",\n ...traceCorrelationFields(rumbleInput),\n ...(errors.length > 0 ? errorsLogField(errors) : {}),\n ...(details.length > 0 ? { details } : {}),\n },\n messages.join(\" \") || \"yoga diagnostic\",\n );\n };\n\n return {\n debug: emit(\"debug\"),\n info: emit(\"info\"),\n warn: emit(\"warn\"),\n error: emit(\"error\"),\n };\n };\n\n const createYoga = (\n args?:\n | (Omit<YogaServerOptions<RequestEvent, any>, \"schema\" | \"context\"> & {\n /**\n * Determines if the API should disclose various things about its structure.\n * Defaults to `process.env.NODE_ENV === \"development\"`.\n * If enabled, the api will allow introspection requests, provide the graphiql\n * explorer and will not apply the additional envelop armor plugin.\n */\n enableApiDocs?: boolean;\n /**\n * Optional configuration passed to the auto-installed graphql-armor\n * EnvelopArmorPlugin. Only applied when `enableApiDocs` is false\n * (i.e. in production). Useful for relaxing the default depth/alias/\n * directive/token limits when the generated schema legitimately exceeds\n * them. See https://github.com/Escape-Technologies/graphql-armor for available options.\n *\n * @example\n * createYoga({ armorConfig: { maxDepth: { n: 20 } } })\n */\n armorConfig?: Parameters<typeof EnvelopArmorPlugin>[0];\n })\n | undefined,\n ) => {\n const enableApiDocs =\n args?.enableApiDocs ?? process?.env?.NODE_ENV === \"development\";\n\n return nativeCreateYoga<RequestEvent>({\n ...args,\n graphiql: enableApiDocs,\n schema: builtSchema(),\n context,\n // Yoga logs its own diagnostics (unexpected errors, warnings) to the\n // console by default. Routing them into the rumble logger keeps every log\n // line of a request in one structured, trace correlated stream.\n logging: args?.logging ?? yogaLogging() ?? true,\n plugins: [\n ...(args?.plugins ?? []),\n ...(enableApiDocs\n ? []\n : [useDisableIntrospection(), EnvelopArmorPlugin(args?.armorConfig)]),\n telemetryEnabled(rumbleInput)\n ? ({\n // TODO: add trace header per default in http response\n // TODO: Automatic Persisted Queries\n onExecute: ({ setExecuteFn, executeFn }) => {\n setExecuteFn(\n buildTracedExecute(\n executeFn,\n rumbleInput,\n \"graphql\",\n ) as typeof executeFn,\n );\n },\n onSubscribe: ({ setSubscribeFn, subscribeFn }) => {\n setSubscribeFn(\n buildTracedSubscribe(\n subscribeFn,\n rumbleInput,\n \"graphql\",\n ) as typeof subscribeFn,\n );\n },\n } as Plugin)\n : false,\n ].filter(Boolean),\n });\n };\n\n const createSofa = async (\n args: Omit<Parameters<typeof useSofa>[0], \"schema\" | \"context\">,\n ) => {\n const { useSofa: useSofaFn } = await import(\"@m1212e/sofa-api\");\n if (args.openAPI) {\n merge(args.openAPI, sofaOpenAPIWebhookDocs);\n }\n\n const userErrorHandler = args.errorHandler;\n\n return useSofaFn({\n ...args,\n schema: builtSchema(),\n context,\n execute: buildTracedExecute(\n args.execute ?? defaultExecute,\n rumbleInput,\n \"rest\",\n ) as any,\n subscribe: buildTracedSubscribe(\n args.subscribe ?? defaultSubscribe,\n rumbleInput,\n \"rest\",\n ) as any,\n errorHandler(errors) {\n if (!errorsAlreadyReported(errors)) {\n recordSpanErrors(trace.getActiveSpan(), errors);\n\n const log = telemetryLogger(rumbleInput);\n log?.error(\n {\n [ATTR_TRANSPORT]: \"rest\",\n ...traceCorrelationFields(rumbleInput),\n ...errorsLogField(errors),\n },\n \"rest request failed\",\n );\n }\n\n return (userErrorHandler?.(errors) ??\n sofaErrorResponse(errors)) as ReturnType<\n NonNullable<typeof userErrorHandler>\n >;\n },\n });\n };\n\n const createWs = <\n Options extends ServerOptions<any, any>,\n Rest extends unknown[],\n Return,\n >(\n implementation: (options: Options, ...rest: Rest) => Return,\n args: Omit<Options, \"schema\" | \"context\">,\n ...rest: Rest\n ): Return => {\n return implementation(\n {\n ...args,\n schema: builtSchema(),\n context,\n execute: buildTracedExecute(\n (args as any).execute ?? defaultExecute,\n rumbleInput,\n \"ws\",\n ) as any,\n subscribe: buildTracedSubscribe(\n (args as any).subscribe ?? defaultSubscribe,\n rumbleInput,\n \"ws\",\n ) as any,\n } as Options,\n ...rest,\n );\n };\n\n const clientCreator = clientCreatorImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n builtSchema,\n });\n\n return {\n /**\n * The ability builder. Use it to declare whats allowed for each entity in your DB.\n *\n * @example\n *\n * ```ts\n * // users can edit themselves\n abilityBuilder.users\n .allow([\"read\", \"update\", \"delete\"])\n .when(({ userId }) => ({ where: eq(schema.users.id, userId) }));\n\n // everyone can read posts\n abilityBuilder.posts.allow(\"read\");\n *\n * ```\n */\n abilityBuilder,\n /**\n * The pothos schema builder. See https://pothos-graphql.dev/docs/plugins/drizzle\n */\n schemaBuilder,\n /**\n * Creates the native yoga instance. Can be used to run an actual HTTP server.\n *\n * @example\n *\n * ```ts\n * import { createServer } from \"node:http\";\n * const server = createServer(createYoga());\n * server.listen(3000, () => {\n * console.info(\"Visit http://localhost:3000/graphql\");\n * });\n * ```\n * https://the-guild.dev/graphql/yoga-server/docs#server\n */\n createYoga,\n /**\n * Creates a sofa instance to offer a REST API.\n *\n * ```ts\n * import express from \"express\";\n *\n * const app = express();\n * const sofa = createSofa(...);\n *\n * app.use(\"/api\", useSofa({ schema }));\n * ```\n * https://the-guild.dev/graphql/sofa-api/docs#usage\n */\n createSofa,\n /**\n * Creates a WebSocket server handler for GraphQL subscriptions.\n * Pass the ws implementation function as the first argument and rumble will\n * inject the schema and context automatically.\n *\n * @example\n *\n * ```ts\n * // ws\n * import { useServer } from \"graphql-ws/use/ws\";\n * import { WebSocketServer } from \"ws\";\n * const wss = new WebSocketServer({ port: 4000 });\n * const disposable = createWs(useServer, { ... }, wss);\n *\n * // bun\n * import { makeHandler } from \"graphql-ws/use/bun\";\n * Bun.serve({ websocket: createWs(makeHandler, { ... }), ... });\n * ```\n */\n createWs,\n /**\n * A function for creating default objects for your schema\n */\n object,\n /**\n * A function for creating where args to filter entities\n */\n whereArg,\n /**\n * A function for creating order args to sort entities\n */\n orderArg,\n /**\n * A function for creating default READ queries.\n * Make sure the objects for the table you are creating the queries for are implemented\n */\n query,\n /**\n * A function for creating a pubsub instance for a table. Use this to publish or subscribe events\n */\n pubsub: makePubSubInstance,\n /**\n * A function to implement enums for graphql usage.\n * The other helpers use this helper internally so in most cases you do not have to\n * call this helper directly, unless you need the reference to an enum type\n */\n enum_,\n /**\n * Create a client to consume a rumble graphql api at the specified location.\n * Requires GraphQL, does not work with the SOFA REST API.\n */\n clientCreator,\n /**\n * A function for creating count queries for your tables\n */\n countQuery,\n /**\n * The generated GraphQL schema. You can use this for example to create a GraphQL server with a different library than Yoga or to generate types with codegen.\n * When calling this function, the schema will be built for the first time and cached for later usage. So you can call this function multiple times without performance issues.\n * After calling, you cannot adjust the schema via the schema builder\n */\n buildSchema: builtSchema,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,kBAAb,cAAqC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACenD,MAAa,yBAA4B,UAA4B;CACnE,IAAI,CAAC,OACH,MAAM,IAAI,gBAAgB,0CAA0C;CAEtE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,MAAa,0BAA6B,UAAkB;CAC1D,MAAM,IAAI,MAAM,GAAG,CAAC;CACpB,IAAI,CAAC,GACH,MAAM,IAAI,gBAAgB,2CAA2C;CACvE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzBA,SAAgB,yBAA2C,KAAQ;CACjE,OAAO,OAAO,YACZ,OAAO,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CACxC,KACA,UAAU,OAAO,KAAA,IAAY,KAC/B,CAAC,CACH;AAGF;;;;;;AEpDA,SAAS,WAAW,OAA+C;CACjE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa;AACrE;AAEA,SAAS,kBAAkB,OAAiC;CAC1D,IAAI,WAAW,KAAK,GAAG;EACrB,MAAM,WAAW;EACjB,OAAO;GACL,kBAAkB,SAAS,aAAa,QAAQ,SAAS,QAAQ;GACjE,qBAAqB,OAAO,SAAS,OAAO;GAC5C,GAAI,SAAS,QAAQ,EAAE,wBAAwB,SAAS,MAAM,IAAI,CAAC;GACnE,GAAI,SAAS,OAAO,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;GAC/C,GAAI,SAAS,cAAc,OAAO,KAAK,SAAS,UAAU,CAAC,CAAC,SAAS,IACjE,EAAE,YAAY,SAAS,WAAW,IAClC,CAAC;EACP;CACF;CACA,OAAO;EACL,kBAAkB;EAClB,qBAAqB,OAAO,KAAK;CACnC;AACF;;;;;;AAOA,SAAgB,eAAe,QAE7B;CACA,OAAO,EAAE,QAAQ,OAAO,IAAI,iBAAiB,EAAE;AACjD;AAEA,SAAgB,cAAc,OAA+C;CAC3E,OAAO,eAAe,CAAC,KAAK,CAAC;AAC/B;;;AC/CA,MAAMA,gBAAc,OAAO,IAAI,qBAAqB;;;;;;;;AASpD,SAAS,UAAU,OAAgB;CACjC,OAAO,UAAUA,gBAAc,KAAA,IAAY;AAC7C;AAEA,SAAgB,aAId,SACA,SACA,OAAqB,OACrB;CACA,MAAM,eAAe,UAAU,SAAS,KAAK;CAC7C,MAAM,eAAe,UAAU,SAAS,KAAK;CA+D7C,OAAO;EACL,OA7DA,gBAAgB,eACZ,SAAS,OACP,EAAE,IAAI,CAAC,cAAc,YAAY,EAAE,IACnC,EAAE,KAAK,CAAC,cAAc,YAAY,EAAE,IACrC,gBAAgB;EA0DrB,SAvDA,SAAS,WAAW,SAAS,UACzB,IAAI,IACF,CACE,OAAO,QAAQ,SAAS,WAAW,CAAC,CAAC,GACrC,OAAO,QAAQ,SAAS,WAAW,CAAC,CAAC,CACvC,CAAC,CACE,KAAK,CAAC,CACN,QAAQ,GAAG,OAAO,MAAM,IAAI,CAAC,CAC7B,KAAK,CAAC,OAAO,CAAC,CACnB,CAAC,CACE,QAAQ,CAAC,CACT,QACE,KAAK,CAAC,SAAS;GACd,IAAI,OAAO;GACX,OAAO;EACT,GACA,CAAC,CACH,IACF,KAAA;EAsCJ,QAnCA,SAAS,UAAU,SAAS,SACxB,SAAS,SAAS,UAAU,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC,IACrD,KAAA;EAkCJ,SA/BA,SAAS,WAAW,SAAS,UACzB,SAAS,SAAS,WAAW,CAAC,GAAG,SAAS,WAAW,CAAC,CAAC,IACvD,KAAA;EA8BJ,OA3BA,SAAS,OACL,SAAS,UAAU,KAAA,KAAa,SAAS,UAAU,KAAA,IACjD,KAAA,IACA,KAAK,IAAI,QAAQ,OAAO,QAAQ,KAAK,IACvC,SAAS,SAAS,SAAS,QACzB,KAAK,IAAI,SAAS,SAAS,UAAU,SAAS,SAAS,QAAQ,IAC/D,KAAA;EAsBN,QAnBA,SAAS,OACL,SAAS,WAAW,KAAA,KAAa,SAAS,WAAW,KAAA,IACnD,KAAA,IACA,KAAK,IAAI,QAAQ,QAAQ,QAAQ,MAAM,IACzC,SAAS,UAAU,SAAS,SAC1B,KAAK,IAAI,SAAS,UAAU,UAAU,SAAS,UAAU,QAAQ,IACjE,KAAA;EAcN,MAXA,SAAS,QAAQ,SAAS,OACtB,SAAS,SAAS,QAAQ,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,IACjD,KAAA;CAUN;AACF;;;AClGA,MAAM,cAAc,OAAO,IAAI,qBAAqB;AAEpD,SAAS,cAAc,OAAkD;CACvE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,QAAQ,OAAO,eAAe,KAAK;CACzC,OAAO,UAAU,OAAO,aAAa,UAAU;AACjD;AAEA,SAAgB,oBAAoB,OAAyB;CAC3D,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO;CAClD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,mBAAmB;CAC9D,IAAI,cAAc,KAAK,GACrB,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAC1C,KACA,oBAAoB,KAAK,CAC3B,CAAC,CACH;CAEF,OAAO;AACT;;;;;;;;ACbA,SAAgB,iBAAiB,KAAqB;CACpD,OAAO,IACJ,QAAQ,kCAAkC,EAAE,CAAC,CAC7C,QAAQ,gBAAgB,EAAE,CAAC,CAC3B,KAAK,CAAC,CACN,YAAY;AACjB;AAEA,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,uBAAuB,SAA0B;CAC/D,OAAO,sBAAsB,SAAS,OAAc;AACtD;AAEA,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;AACF;AAEA,SAAgB,0BAA0B,SAA0B;CAClE,OAAO,yBAAyB,SAAS,OAAc;AACzD;AAEA,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,yBAAyB,SAA0B;CACjE,OAAO,wBAAwB,SAAS,OAAc;AACxD;AAEA,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,0BAA0B,SAA0B;CAClE,OAAO,yBAAyB,SAAS,OAAc;AACzD;AAEA,MAAM,uBAAuB,CAAC,MAAM;AAEpC,SAAgB,sBAAsB,SAA0B;CAC9D,OAAO,qBAAqB,SAAS,OAAc;AACrD;AAEA,MAAM,wBAAwB,CAAC,WAAW,MAAM;AAEhD,SAAgB,uBAAuB,SAA0B;CAC/D,OAAO,sBAAsB,SAAS,OAAc;AACtD;AAEA,MAAM,6BAA6B,CAAC,aAAa,UAAU;AAE3D,SAAgB,4BAA4B,SAA0B;CACpE,OAAO,2BAA2B,SAAS,OAAc;AAC3D;AAEA,MAAM,yBAAyB,CAAC,MAAM;AAEtC,SAAgB,wBAAwB,SAA0B;CAChE,OAAO,uBAAuB,SAAS,OAAc;AACvD;AAEA,MAAM,yBAAyB,CAAC,QAAQ,OAAO;AAE/C,SAAgB,wBAAwB,SAA0B;CAChE,OAAO,uBAAuB,SAAS,OAAc;AACvD;AAEA,MAAM,6BAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,4BAA4B,SAA0B;CACpE,OACE,2BAA2B,SAAS,OAAc,KAClD,QAAQ,WAAW,UAAU;AAEjC;AAEA,MAAM,sBAAsB,CAAC,SAAS,MAAM;AAE5C,SAAgB,qBAAqB,SAA0B;CAC7D,OAAO,oBAAoB,SAAS,OAAc;AACpD;AAMA,MAAa,0BACX,SACA,mBAEA,IAAI,YACF,kCAAkC,QAAQ,yFAAyF,eAAe,EACpJ;;;ACtIF,SAAgB,gCAAgC,SAG9C;CACA,IAAI,uBAAuB,OAAO,GAChC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,yBAAyB,OAAO,GAClC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,0BAA0B,OAAO,GACnC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,sBAAsB,OAAO,GAC/B,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,uBAAuB,OAAO,GAChC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,4BAA4B,OAAO,GACrC,OAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;EAC3B,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;CAC7B;CAGF,IAAI,wBAAwB,OAAO,GACjC,OAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;EAC3B,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;CAC7B;CAGF,IAAI,wBAAwB,OAAO,GACjC,OAAO;EACL,QAAQ,EAAE,GAAG,EAAE;EACf,QAAQ,EAAE,GAAG,EAAE;CACjB;CAGF,MAAM,uBAAuB,SAAS,UAAU;AAClD;;;AC9BA,MAAM,6BAAa,IAAI,QAA4B;AAEnD,SAAS,WAAuC,IAAoB;CAClE,MAAM,2BAAW,IAAI,IAA2B;CAChD,MAAM,2BAAW,IAAI,IAA2B;CAChD,MAAM,6BAAa,IAAI,IAAwB;CAE/C,KAAK,MAAM,CAAC,QAAQ,aAAa,OAAO,QAAQ,GAAG,EAAE,aAAa,CAAC,CAAC,GAAG;EACrE,MAAM,QAAQ;EACd,MAAM,WAAW,MAAM;EACvB,IAAI,CAAC,UAAU;EAEf,MAAM,UACJ,QAAQ,QAAQ,IAAI,gBAAgB,QAAiB,IAAI,CAAC;EAG5D,MAAM,aAAa,OAAO,YACxB,OAAO,QAAQ,OAAO,CAAC,CAAC,QAAQ,GAAG,SAAU,IAAY,OAAO,CAClE;EAEA,MAAM,SAAS,QAAQ,QAAQ,IAC1B,aAAa,QAAiB,IAC7B,MAAM,QAAmB;EAE/B,MAAM,WAA0B;GAC9B,MAAM,MAAM,QAAQ;GACpB;GACA,OAAO;GACP;GACA;GACA,WAAW,MAAM,aAAa,CAAC;GAC/B,SAAS,QAAQ,QAAQ;GACzB,eAAe;EACjB;EAEA,SAAS,IAAI,SAAS,MAAM,QAAQ;EACpC,SAAS,IAAI,SAAS,QAAQ,QAAQ;EACtC,WAAW,IAAI,UAAU,QAAQ;CACnC;CAEA,OAAO;EAAE;EAAU;EAAU;CAAW;AAC1C;AAEA,SAAS,SAAqC,IAAoB;CAChE,IAAI,MAAM,WAAW,IAAI,EAAuB;CAChD,IAAI,CAAC,KAAK;EACR,MAAM,WAAW,EAAE;EACnB,WAAW,IAAI,IAAyB,GAAG;CAC7C;CACA,OAAO;AACT;AAEA,SAAgB,YAKd,EAAE,IAAI,SAA6C;CACnD,MAAM,MAAM,SAAS,EAAE;CAEvB,IAAI;CAEJ,IAAI,OAAO,UAAU,UAEnB,QAAQ,IAAI,SAAS,IAAI,KAAK,KAAK,IAAI,SAAS,IAAI,KAAK;MACpD,IAAI,SAAS,OAAO,UAAU,UAAU;EAC7C,MAAM,IAAI;EAIV,IAAI,EAAE,OAAO;GACX,QAAQ,IAAI,WAAW,IAAI,EAAE,KAAK;GAClC,IAAI,CAAC,SAAS,EAAE,MACd,QAAQ,IAAI,SAAS,IAAI,EAAE,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,IAAI;EAE/D;EAGA,IAAI,CAAC,OACH,QAAQ,IAAI,WAAW,IAAI,CAAC;EAI9B,IAAI,CAAC,SAAS,QAAQ,CAAC,GAAG;GACxB,MAAM,SAAS,aAAa,CAAU;GACtC,QAAQ,IAAI,SAAS,IAAI,MAAM;EACjC;CACF;CAEA,IAAI,CAAC,OACH,MAAM,IAAI,YACR,6BAA6B,KAAK,UAChC,OAAO,UAAU,WAAW,QAAQ,gBACtC,GACF;CAGF,OAAO;EACL,SAAS,MAAM;EACf,YAAY,MAAM;EAClB,WAAW,MAAM;EACjB,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,OAAO,MAAM;EACb,SAAS,MAAM;EACf,eAAe,MAAM;CACvB;AACF;;;AChHA,MAAa,eAAuB,UAAU;;AAE9C,MAAa,iBAAiB;AAC9B,MAAa,uBAAuB;AACpC,MAAa,yBAAyB;AACtC,MAAa,qBAAqB;AAClC,MAAa,uBAAuB;AASpC,MAAa,sBAA8B;AAC3C,MAAa,sBAA8B;AAC3C,MAAa,gBAAwB;AACrC,MAAa,kBAA0B,eAAe;;AAEtD,MAAa,wBAAgC,eAAe;;AAE5D,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAChC,MAAa,iBAAiB;AAC9B,MAAa,aAAa;AAC1B,MAAa,cAAc;AAC3B,MAAa,wBAAwB;AACrC,MAAa,wBAAwB;AACrC,MAAa,yBAAyB;AACtC,MAAa,uBAAuB;AACpC,MAAa,qBAAqB;AAClC,MAAa,uBAAuB;AACpC,MAAa,gCAAgC;AAC7C,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;AAIjC,SAAgB,gBACd,QAC0B;CAC1B,OAAO,OAAO,QAAQ,UAAU,OAAO,OAAO,SAAS,KAAA;AACzD;AAEA,SAAgB,gBAAgB,QAA6C;CAC3E,OAAO,OAAO,MAAM,UAAU,OAAO,KAAK,SAAS,KAAA;AACrD;;;;;;AAOA,SAAgB,iBAAiB,QAAkC;CACjE,OAAO,QAAQ,OAAO,MAAM,WAAW,OAAO,QAAQ,OAAO;AAC/D;;;;;;;;;;AAaA,SAAgB,uBACd,QACA,MACwB;CACxB,IAAI,CAAC,OAAO,MAAM,WAAW,OAAO,QAAQ,kBAAkB,OAC5D,OAAO,CAAC;CAGV,MAAM,SAAS,QAAQ,MAAM,cAAc;CAC3C,IAAI,CAAC,QAAQ,OAAO,CAAC;CAErB,MAAM,cAAc,OAAO,YAAY;CACvC,IAAI,CAAC,mBAAmB,WAAW,GAAG,OAAO,CAAC;CAE9C,OAAO;EACL,UAAU,YAAY;EACtB,SAAS,YAAY;EACrB,aAAa,YAAY,WAAW,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CAClE;AACF;AAIA,SAAS,YAAY,OAAgB;CACnC,IAAI,iBAAiB,OAAO,OAAO;CACnC,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAC9D,OAAO;CAET,OAAO,OAAO,KAAK;AACrB;AAEA,SAAS,iBAAiB,OAAoC;CAC5D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAC9D,OAAO,OAAQ,MAA+B,OAAO;CAEvD,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,OAAO,KAAK;AACvD;;;;;;AAOA,SAAgB,iBACd,MACA,QACM;CACN,IAAI,CAAC,QAAQ,OAAO,WAAW,GAAG;CAElC,KAAK,MAAM,SAAS,QAClB,KAAK,gBAAgB,YAAY,KAAK,CAAC;CAGzC,KAAK,UAAU;EACb,MAAM,eAAe;EACrB,SAAS,iBAAiB,OAAO,EAAE;CACrC,CAAC;AACH;AAEA,SAAgB,gBAAgB,MAAwB,OAAsB;CAC5E,iBAAiB,MAAM,CAAC,KAAK,CAAC;AAChC;;;;;;;;;;AAWA,MAAM,iCAAiB,IAAI,QAAgB;AAE3C,SAAgB,mBAAmB,QAAkC;CACnE,KAAK,MAAM,SAAS,QAClB,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,eAAe,IAAI,KAAK;AAG9B;;AAGA,SAAgB,sBAAsB,QAAqC;CACzE,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,OAAO,OAAO,OACX,UACC,OAAO,UAAU,YAAY,UAAU,QAAQ,eAAe,IAAI,KAAK,CAC3E;AACF;AAIA,SAAS,kBAAkB,OAAwB;CACjD,IAAI;EACF,OACE,KAAK,UAAU,QAAQ,MAAM,UAC3B,OAAO,UAAU,WAAW,MAAM,SAAS,IAAI,KACjD,KAAK;CAET,QAAQ;EAEN,OAAO,OAAO,KAAK;CACrB;AACF;AAEA,SAAS,4BAA4B,OAA2B;CAC9D,IAAI;CACJ,KAAK,MAAM,SAAS,OAAO;EACzB,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW;EAC3C,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,YAAY,SAAS,YAAY,SAAS,WACrD,OAAO;EAET,IAAI,QAAQ,SAAS,MAAM,OAAO;EAClC,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,eAAe,OAAgC;CAC7D,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK;EACtD,KAAK,WACH,OAAO;EACT,KAAK,UACH,OAAO,MAAM,SAAS;EACxB,KAAK,aACH,OAAO;EACT,SACE;CACJ;CAEA,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,MAAM,QAAQ,KAAK,KAAK,4BAA4B,KAAK,GAC3D,OAAO;CAET,OAAO,kBAAkB,KAAK;AAChC;AAeA,SAAgB,iBACd,WACA,SACqC;CACrC,IAAI,YAAY,SAAS,CAAC,WAAW,OAAO,KAAA;CAE5C,MAAM,WACJ,OAAO,YAAY,aAAa,QAAQ,EAAE,GAAG,UAAU,CAAC,IAAI;CAE9D,IAAI,CAAC,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,WAAW,GAAG,OAAO,KAAA;CAC5D,OAAO;AACT;;AAGA,SAAgB,mBACd,WACA,SACY;CACZ,MAAM,WAAW,iBAAiB,WAAW,OAAO;CACpD,IAAI,CAAC,UAAU,OAAO,CAAC;CAEvB,MAAM,aAAyB,CAAC;CAChC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,WAAW,GAAG,wBAAwB,SAAS,eAAe,KAAK;CAErE,OAAO;AACT;;AAGA,SAAgB,iBACd,WACA,SACyB;CACzB,MAAM,WAAW,iBAAiB,WAAW,OAAO;CACpD,OAAO,WAAW,GAAG,kBAAkB,SAAS,IAAI,CAAC;AACvD;;;;;AAQA,SAAgB,aAAqB;CACnC,OAAO,YAAY,IAAI;AACzB;AAEA,SAAgB,WAAW,OAAuB;CAChD,OAAO,KAAK,OAAO,YAAY,IAAI,IAAI,SAAS,GAAG,IAAI;AACzD;;;ACtOA,SAAS,qBAMP,QAC0D;CAC1D,OACE,OAAO,WAAW,cAAc,OAAO,YAAY,SAAS;AAEhE;AAEA,SAAS,oBAMP,QACgD;CAChD,OAAO,OAAO,WAAW;AAC3B;AAEA,MAAM,+BACJ,QACA,WAEA,UAAU,OAAe,WAAmB;CAC1C,MAAM,MAAM,+BAA+B,MAAM,GAAG,OAAO;CAC3D,IAAI,QACF,OAAO,KACL;GACG,aAAa;GACb,cAAc;EACf,GAAG,uBAAuB,MAAM;CAClC,GACA,GACF;MAEA,QAAQ,KAAK,GAAG;AAEpB,GAAG,GAAI;AAET,MAAa,wBAMX,EACA,IACA,SACA,cACA,MACA,QAAQ,mBAC8D;CACtE,MAAM,MAAM,cAAc,UAAU,aAAa,SAAS,KAAA;CAC1D,MAAM,kBAAmC;EAAE;EAAM,QAAQ;CAAa;CACtE,MAAM,iCAAiC,4BACrC,iBACA,GACF;CAKA,MAAM,qBACJ,OAAO,KAAK,GAAG,KAAK,CAAC,CACrB,QACC,SAAS,YAAY;EAAE;EAAI,OAAO;CAAY,CAAC,CAAC,CAAC,OACpD;CAEA,IAAI,eAAe;CAEnB,MAAM,8BAA4D;EAChE,MAAM,+BAAe,IAAI,IASvB;EAEF,MAAM,iCAAiB,IAAI,IAIzB;EAKF,KAAK,MAAM,UAAU,SACnB,IAAI,CAAC,eAAe,IAAI,MAAM,GAC5B,eAAe,IAAI,QAAQ,CAAC,CAAC;EAIjC,OAAO;;;;GAIL,QAAQ,WAA8B;IACpC,IAAI,cACF,MAAM,IAAI,YACR,uIACF;IAGF,MAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;IAIxD,MAAM,4CAA4B,IAAI,IAA8B;IACpE,KAAK,MAAM,UAAU,SAAS;KAC5B,IAAI,UAAU,aAAa,IAAI,MAAM;KACrC,IAAI,CAAC,SAAS;MACZ,UAAU;MACV,aAAa,IAAI,QAAQ,OAAO;MAChC,0BAA0B,IAAI,MAAM;KACtC;IACF;IAEA,OAAO;;;;;;;;;;;;AAYL,OACE,gBAMG;KACH,KAAK,MAAM,UAAU,SAAS;MAC5B,IAAI,aAAa,IAAI,MAAM,MAAM,gBAC/B,IAAI,0BAA0B,IAAI,MAAM,GAEtC,aAAa,IAAI,QAAQ,CAAC,CAAC;WAI3B;MAIJ,aAD6B,IAAI,MAC1B,CAAC,CAA6C,KACnD,WACF;KACF;IACF,EACF;GACF;;;;;GAKA,SAAS,WAA8B;IACrC,MAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;IACxD,OAAO;;;;;;;;;;;;KAYL,WACE,aACG;MACH,OAAO;;;;AAIL,KACE,mBAKG;OACH,KAAK,MAAM,UAAU,SAEnB,eAAe,IAAI,MAAM,CAAC,CAAE,KAAK;QAC/B,QAAQ;QACE;OACZ,CAAC;MAEL,EACF;KACF;;;;KAIA,KACE,mBAIG;MACH,KAAK,MAAM,UAAU,SAEnB,eAAe,IAAI,MAAM,CAAC,CAAE,KAAK,EAC/B,QAAQ,eACV,CAAC;KAEL;IACF;GACF;GACA,GAAG;IACD;IACA;GACF;EACF;CACF;CAEA,MAAM,mBAAmB,OAAO,YAC9B,mBAAmB,KAAK,cAAc,CACpC,WACA,sBAAwC,CAC1C,CAAC,CACH;CAIA,OAAO;EACL,GAAG;;;;;EAKH,GAAG;GACD,kBAAkB,EAChB,QACA,SAIC;IACD,OAAQ,iBAAiB,MAAM,CAAS,EAAE,eAAe,IACvD,MACF;GACF;GACA,QAAQ;IACN,MAAM,wBACJ,cACG;KACH,MAAM,eAAe,iBAAiB,UAAU,CAAC,EAAE;KAEnD,MAAM,qBAAqB,OAAO,YAChC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,MAAM;MAEvC,IAAI,CAAC,WAAW,YAAY,gBAAgB,OAAO,CAAC,QAAQ,CAAC,CAAC;MAE9D,OAAO,CAAC,QAAQ,QAAQ,OAAO,mBAAmB,CAAC;KACrD,CAAC,CACH;KAQA,MAAM,sBAAsB,OAAO,YACjC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,MAAM;MAEvC,IAAI,CAAC,WAAW,YAAY,gBAAgB,OAAO,CAAC,QAAQ,CAAC,CAAC;MAE9D,OAAO,CAAC,QAAQ,QAAQ,OAAO,oBAAoB,CAAC;KACtD,CAAC,CACH;KASA,MAAM,cAAc,YAAY;MAC9B;MACA,OAAO;KACT,CAAC;KAED,IAAI,OAAO,KAAK,YAAY,UAAU,CAAC,CAAC,WAAW,GACjD,MAAM,IAAI,YACR,mCAAmC,OAAO,SAAS,GACrD;KAGF,MAAM,kBAAuB,OAAO,OAAO,YAAY,UAAU,CAAC,CAAC;KAEnE,MAAM,iBAAiB,gCACrB,gBAAgB,WAAW,CAC7B;KAEA,MAAM,wBAAwB,EAC5B,OAAO,EACL,KAAK,CACH,GACG,gBAAgB,OAAO,eAAe,OACzC,GACA,GACG,gBAAgB,OAAO,eAAe,OACzC,CACF,EACF,EACF;;;;KAKA,SAAS,oBACP,cACA;MACA,MAAM,uBACJ,SACA,gBACG;OACH,MAAM,QAAQ,WAAW;QACvB,IAEE,gBAAgB,KAAA,GAChB;SACA,IAAI,CAAC,SAAS,OAEZ,OAAO;SAGT,IAAK,QAAQ,QAAmB,aAE9B,OAAO;QAEX;QAEA,IAAI,QAAQ,SAAS;QAErB,IACE,iBACC,UAAU,KAAA,KAAa,QAAQ,eAEhC,QAAQ;QAIV,OAAO,SAAS,KAAA;OAClB,CAAC;OAED,MAAM,sBAAsB,WAAW;QACrC,MAAM,SAAU,GAAG,EAAU,SAAS,SAAS;QAE/C,OAAO,SAAS,QACZ,qBACE,YAAY,cAAc,OAC1B,oBAAoB,QAAQ,KAAK,GACjC,YAAY,WACZ,GAAG,EAAE,WACL,MACF,IACA,KAAA;OACN,CAAC;OAKD,IAAI,SAAS,SACX,OAAO;;;;;;;;;;QAUL,OAAO;;;;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;UACzC,SAAS,SAAS;SACpB;;;;SAWA,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;UACzC,SAAS,SAAS;UAClB,IAAI,QAAQ;WACV,OAAO,MAAM;UACf;SACF;QAQF;;;;;;;;;;;;;;;;;;;;QAoBA,KAAK,EACH,IAAI,QAAQ;SACV,OAAO,oBAAoB;QAC7B,EACF;OACF;YAEA,OAAO;;;;;;;;;;QAUL,OAAO;;;;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;SAC3C;;;;SAWA,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;UACzC,IAAI,QAAQ;WACV,OAAO,MAAM;UACf;SACF;QAQF;;;;;;;;;;;;;;;;;;;;QAoBA,KAAK,EACH,IAAI,QAAQ;SACV,OAAO,oBAAoB;QAC7B,EACF;OACF;MAEJ;MAEA,MAAM,MAAM,oBAAoB,YAAY;;;;MAK5C,SAAS,MACP,GACA;OACA,MAAM,SAAS,aAAa,IAAI,MAAM,MAAM,CAAC;OAC7C,OAAO,oBACL,QAIA,EAAE,KACJ;MACF;MAEA,IAAa,QAAQ;MAErB,OAAO;KAGT;KAEA,OAAO,EACL,cAAc,gBAA6B;MACzC,OAAO,EACL,SAAS,WAAmB;OAC1B,MAAM,qBACJ,eACG;QACH,MAAM,UAAU,aAAa,IAAI,MAAM;QAGvC,IAAI,YAAY,gBAAgB;SAC9B,WAAW,yBAAyB;SACpC,OAAO,oBAAoB;QAC7B;QAGA,IAAI,CAAC,SAAS;SACZ,WAAW,yBAAyB;SACpC,+BAA+B,OAAO,SAAS,GAAG,MAAM;SACxD,OAAO,oBAAoB,qBAAqB;QAClD;QAGA,MAAM,iBAAiB,IAAI,MAEzB,oBAAoB,OAAO,CAAC,MAAM;QACpC,IAAI,kBAAkB;QACtB,KACE,IAAI,IAAI,GACR,IAAI,oBAAoB,OAAO,CAAC,QAChC,KACA;SACA,MAAM,OAAO,oBAAoB,OAAO,CAAC;SACzC,MAAM,SAAS,KAAK,WAAW;SAE/B,IAAI,WAAW,SAAS;UACtB,WAAW,yBAAyB;UACpC,OAAO,oBAAoB;SAC7B;SAEA,IAAI,WAAW,KAAA,GAAW;SAE1B,eAAe,qBAAqB;QACtC;QACA,eAAe,SAAS;QAExB,WAAW,0BAA0B,eAAe;QACpD,WAAW,yBACT,mBAAmB,OAAO,CAAC;QAE7B,MAAM,kBAAkB,CACtB,GAAG,mBAAmB,SACtB,GAAG,cACL;QAEA,WAAW,wBAAwB,gBAAgB;QAGnD,IAAI,gBAAgB,WAAW,GAAG;SAChC,WAAW,yBAAyB;SAEpC,OAAO,oBAAoB,qBAAqB;QAClD;QAEA,MAAM,gBACJ,gBAAgB,WAAW,IACvB,gBAAgB,KAChB,gBAAgB,QAAQ,GAAG,MAAM;SAC/B,OAAO,aAAa,GAAG,GAAG,IAAI;QAChC,CAAC;QAEP,WAAW,yBAAyB;QACpC,OAAO,oBAAoB,aAAoB;OACjD;OAIA,MAAM,OAAO,SAAgB;QAC3B,MAAM,aAA6C;UAChD,aAAa,OAAO,SAAS;UAC7B,cAAc;QACjB;QAEA,IAAI;SACF,MAAM,SAAS,kBAAkB,UAAU;SAC3C,KAAK,MACH;UACE,GAAG;UACH,GAAG,uBAAuB,iBAAiB,IAAI;SACjD,GACA,oBACF;SACA,OAAO;QACT,SAAS,OAAO;SACd,gBAAgB,MAAM,KAAK;SAC3B,KAAK,MACH;UACE,GAAG;UACH,GAAG,uBAAuB,iBAAiB,IAAI;UAC/C,GAAG,cAAc,KAAK;SACxB,GACA,kBACF;SACA,MAAM;QACR,UAAU;SACR,MAAM,cAAc,UAAU;QAChC;OACF;OAEA,IAAI,MAAM,WAAW,KAAK,QACxB,OAAO,KAAK,OAAO,gBACjB,yBACC,SAAS;QACR,IAAI;SACF,OAAO,IAAI,IAAI;QACjB,UAAU;SACR,KAAK,IAAI;QACX;OACF,CACF;OAGF,OAAO,IAAI;MACb,EACF;KACF,EACF;IACF;IAEA,MAAM,oBAAoB,OAAO,YAC/B,mBAAmB,KAAK,cAAc,CACpC,WACA,qBAAqB,SAAS,CAChC,CAAC,CACH;IAIA,eAAe;IAEf,QAAQ,QAAqB;KAC3B,OAAO,OAAO,YACZ,mBAAmB,KAAK,cAAc,CACpC,WACA,kBAAkB,UAAU,CAAC,YAAY,GAAG,CAC9C,CAAC,CACH;IAKF;GACF;EACF;CACF;AACF;;;ACjwBA,MAAMC,qBAAmB,WACvB,GAAG,WAAW,YAAY,OAAO,SAAS,CAAC,CAAC,EAAE;AAEhD,MAAa,6BAMX,EACA,IACA,oBASI;CACJ,MAAM,mCAAmB,IAAI,IAAiB;CAE9C,MAAM,0BAA0B,WAC9B,cAAc,SAAS,oBAAoB,EACzC,QAAQ,CAAC,OAAO,MAAM,EACxB,CAAC,CACH;CAEA,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;EACnB,CAAC;EAED,MAAM,gBAAgB,WAAWA,kBAAgB,YAAY,MAAM;EAEnE,IAAI,MACF,iBAAiB,IAAI,aAAa;EACpC,IAAI,KACF,OAAO;EAGT,MAAM,kBAAkB;GACtB,OAAO,cAAc,UAAU,eAAe,EAC5C,SAAS,MAAM;IAkBb,OAfe,OAAO,QAAQ,YAAY,OAAO,CAAC,CAAC,QAChD,KAAK,CAAC,SAAS;KAEd,IAAI,IAAI,WAAW,IAAI,GAAG,OAAO;KAEjC,IAAI,OAAO,EAAE,MAAM;MACjB,MAAM,wBAAwB;MAC9B,UAAU;KACZ,CAAC;KAED,OAAO;IACT,GACA,CAAC,CAGS;GACd,EACF,CAAC;EACH;EAEA,MAAM,UAAU;EAChB,iBAAiB,IAAI,eAAe,GAAG;EACvC,OAAO;CACT;CAEA,OAAO;AACT;;;;;;ACrGA,SAAgB,aACd,YAK6B;CAC7B,OACE,GAAG,YAAY,YAAY,KAC3B,GAAG,YAAY,kBAAkB,KACjC,GAAG,YAAY,eAAe,KAC9B,GAAG,YAAY,qBAAqB;AAExC;AAgHA,MAAa,yBAQX,EACA,QACA,oBASI;CACJ,MAAM,mCAAmB,IAAI,IAAiB;;;;;;;;;;;;CAa9C,MAAM,mBAMJ,SAiBG;EACH,MAAM,EAAE,YAAY;EACpB,MAAM,SAAU,KAA6B;EAC7C,MAAM,gBAAiB,KACpB;EACH,MAAM,aAAc,KAAiC;EAErD,IAAI,aAA0D;EAE9D,IAAI,QAAQ;GACV,MAAM,YAAa,OAAmC;GACtD,IAAI,CAAC,aAAa,CAAC,SAAS,SAAgB,GAC1C,MAAM,IAAI,YACR,uCAAuC,KAAK,UAC1C,MACF,EAAE,6GAEJ;GAEF,aAAa;EACf;EAEA,IAAI,CAAC,cAAc,CAAC,YAClB,MAAM,IAAI,YACR,sKAEF;EAGF,IAAI;EACJ,IAAI;EAEJ,IAAI,YAAY;GACd,iBAAiB,WAAW;GAC5B,aAAa,WAAW;EAC1B,OAAO,IAAI,YAGT,IACE,GAAG,YAAY,eAAe,KAC9B,GAAG,YAAY,qBAAqB,GACpC;GACA,aAAc,WAAmB;GACjC,MAAM,WAAY,WAAmB;GACrC,MAAM,YACJ,YAAY,QAAQ,QAAQ,IAAI,aAAa,QAAQ,IAAI,KAAA;GAC3D,iBAAiB,YACb,GAAG,UAAU,GAAG,WAAW,SAC3B,WAAW;EACjB,OAAO;GACL,MAAM,SAAU,WAAmB;GAKnC,IAAI,CAAC,QACH,MAAM,IAAI,YACR,oFACF;GAGF,iBAAiB,OAAO;GACxB,aAAa,WAAW;EAC1B;EAGF,IAAI,CAAC,kBAAkB,CAAC,YACtB,MAAM,IAAI,YAAY,qCAAqC;EAG7D,MAAM,4BACJ,WAAW,GAAG,WAAW,YAAY,cAAc,CAAC,EAAE;EAkBxD,MAAM,SAAS,iBAAiB,IAAI,yBAAyB;EAC7D,IAAI,QACF,OAAO;EAGT,MAAM,MAAM,cAAc,SAAS,2BAA2B,EAC5D,QAAQ,WACV,CAAC;EACD,iBAAiB,IAAI,2BAA2B,GAAG;EACnD,OAAO;CACT;CAEA,OAAO;AACT;;;ACpRA,SAAgB,wBAAwB,EACtC,SACA,aAIkB;CAGlB,IAAI,UAAU,KAAK,OAAO,GACxB,OAAO;CAGT,MAAM,aAAa,iBAAiB,OAAO;CAE3C,IAAI;CAEJ,IAAI,uBAAuB,UAAU,GACnC,MAAM;CAGR,IAAI,0BAA0B,UAAU,GACtC,MAAM;CAGR,IAAI,yBAAyB,UAAU,GACrC,MAAM;CAGR,IAAI,0BAA0B,UAAU,GACtC,IACE,cACC,UAAU,YAAY,CAAC,CAAC,SAAS,KAAK,KACrC,UAAU,YAAY,CAAC,CAAC,SAAS,IAAI,IAEvC,MAAM;MAEN,MAAM;CAIV,IAAI,sBAAsB,UAAU,GAClC,MAAM;CAGR,IAAI,uBAAuB,UAAU,GACnC,MAAM;CAGR,IAAI,4BAA4B,UAAU,GACxC,MAAM;CAGR,IAAI,wBAAwB,UAAU,GACpC,MAAM;CAGR,IAAI,wBAAwB,UAAU,GACpC,MAAM;CAGR,IAAI,4BAA4B,UAAU,GACxC,MAAM;CAGR,IAAI,qBAAqB,UAAU,GACjC,MAAM;CAGR,IAAI,QAAQ,KAAA,GACV,OAAO;CAGT,MAAM,uBAAuB,SAAS,YAAY;AACpD;;;AC5DA,MAAM,mBAAmB,WACvB,GAAG,WAAW,YAAY,OAAO,SAAS,CAAC,CAAC,EAAE;AAEhD,MAAa,6BAMX,EACA,IACA,eACA,sBAiBI;CACJ,MAAM,mCAAmB,IAAI,IAAiB;CAC9C,MAAM,6CAA6B,IAAI,IAAiB;CACxD,MAAM,+CAA+B,IAAI,IAAiB;CAE1D,MAAM,6BAA6B,YACjC,GAAG,QAAQ;CAEb,MAAM,4BAA4B,YAAoB;EACpD,MAAM,WAAW,0BAA0B,OAAO;EAClD,MAAM,WAAW,6BAA6B,IAAI,QAAQ;EAC1D,IAAI,UAAU,OAAO;EAErB,MAAM,MAAM,cAAc,SAAS,QAAQ;EAC3C,6BAA6B,IAAI,UAAU,GAAG;EAE9C,IAAI,UAAU,EACZ,SAAS,OAAY;GACnB,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAChD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAChD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,OAAO,CAAC;IAAG,UAAU;GAAM,CAAC;GAClD,OAAO,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,OAAO,CAAC;IAAG,UAAU;GAAM,CAAC;GACrD,QAAQ,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACrC,WAAW,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACxC,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAC3D,gBAAgB,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAC5D,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAC3D,KAAK,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC7C,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC5C,KAAK,EAAE,MAAM;IAAE,MAAM;IAAK,UAAU;GAAM,CAAC;EAC7C,GACF,CAAC;EAED,OAAO;CACT;CAEA,MAAM,0BAA0B,aAAkB;EAChD,MAAM,WAAW,GAAG,SAAS,KAAK;EAElC,MAAM,WAAW,2BAA2B,IAAI,QAAQ;EACxD,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,cAAc,SAAS,QAAQ;EAC3C,2BAA2B,IAAI,UAAU,GAAG;EAE5C,IAAI,UAAU,EACZ,SAAS,OAAY;GAGnB,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GACjD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GACjD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,QAAQ,CAAC;IAAG,UAAU;GAAM,CAAC;GACnD,OAAO,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,QAAQ,CAAC;IAAG,UAAU;GAAM,CAAC;GACtD,QAAQ,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACrC,WAAW,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACxC,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GAC5D,gBAAgB,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GAC7D,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GAC5D,KAAK,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC7C,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC5C,KAAK,EAAE,MAAM;IAAE,MAAM;IAAK,UAAU;GAAM,CAAC;EAC7C,GACF,CAAC;EAED,OAAO;CACT;CAEA,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;EACnB,CAAC;EAED,MAAM,gBAAgB,WAAW,gBAAgB,YAAY,MAAM;EAEnE,MAAM,WAAW,iBAAiB,IAAI,aAAa;EACnD,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,cAAc,SAAS,aAAa;EAChD,iBAAiB,IAAI,eAAe,GAAG;EAEvC,IAAI,UAAU,EACZ,SAAS,MAAW;GAClB,MAAM,qCACJ,SACA,WACA,YACG;IACH,MAAM,UAAU,wBAAwB;KACtC;KACA;IACF,CAAC;IAED,IAAI,SACF,OAAO,EAAE,MAAM;KACb,MAAM,yBAAyB,OAAO;KACtC,UAAU;IACZ,CAAC;IAGH,QAAQ,SAAR;KACE,KAAK,OACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,UACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,UACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,WACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,QACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,YACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,SACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,MACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,QACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,SAEH,OAAO;KACT,SACE,MAAM,IAAI,YACR,6BAA6B,QAAQ,cAAc,SACrD;IACJ;GACF;GACA,MAAM,SAAS,OAAO,QAAQ,YAAY,OAAO,CAAC,CAAC,QAChD,KAAK,CAAC,KAAK,WAAW;IAErB,IAAI,IAAI,WAAW,IAAI,GAAG,OAAO;IAGjC,IAAI,UAAU;IACd,IAAI,GAAG,OAAO,QAAQ,GAAG;KACvB,MAAM,OAAQ,MACX;KACH,IAAI,QAAQ,OAAO,GAAG,UAAU;IAClC;IAEA,IAAI,aAAa,KAAK,GAAG;KACvB,MAAM,WAAW,gBAAgB,EAC/B,YAAY,MACd,CAAC;KAED,IAAI,OAAO,EAAE,MAAM;MACjB,MAAM,UAAU,uBAAuB,QAAQ,IAAI;MACnD,UAAU;KACZ,CAAC;IACH,OAAO;KACL,MAAM,QAAQ,kCACZ,MAAM,WAAW,GACjB,KACA,OACF;KACA,IAAI,UAAU,MACZ,IAAI,OAAO;IAEf;IAEA,OAAO;GACT,GACA,CAAC,CACH;GAEA,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,CAAC,CAAC,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;IAIrB,MAAM,eAAgB,MAAc;IACpC,MAAM,iBAAiB,YAAY;KACjC;KACA,OAAO;IACT,CAAC;IACD,MAAM,iBAAiB,oBAAoB,EACzC,QAAQ,eAAe,OACzB,CAAC;IAED,IAAI,OAAO,EAAE,MAAM;KACjB,MAAM;KACN,UAAU;IACZ,CAAC;IAED,OAAO;GACT,GACA,CAAC,CAIH;GAEA,OAAO;IACL,GAAG;IACH,GAAG;IACH,KAAK,EAAE,MAAM;KAAE,MAAM,CAAC,GAAG;KAAG,UAAU;IAAM,CAAC;IAC7C,IAAI,EAAE,MAAM;KAAE,MAAM,CAAC,GAAG;KAAG,UAAU;IAAM,CAAC;IAC5C,KAAK,EAAE,MAAM;KAAE,MAAM;KAAK,UAAU;IAAM,CAAC;GAC7C;EACF,EACF,CAAC;EAED,OAAO;CACT;CAEA,OAAO;AACT;;;ACjUA,MAAa,4BAMX,EACA,kBAWI;CACJ,MAAM,gBAAgB,OAAO,EAC3B,QACA,YACA,kBACA,uBACA,gBACA,iBACA,qBAAqB,YAsCjB;EACJ,IAAI,QAAQ,IAAI,aAAa,eAC3B,QAAQ,KACN,kHAAkH,KAAK,UACrH;GACE;GACA;GACA;GACA;GACA;EACF,CACF,GACF;EAGF,MAAM,mBAAmB;GACvB,QAFa,YAER;GACL;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;CACH;CAEA,OAAO;AACT;;;AChEA,MAAa,yBAMX,EACA,SAAS,iBACT,qBASI;CACJ,MAAM,sBAAsB,WAAW,eAAe,EAAE,MAAM,CAAC;CAE/D,OAAO,OAAO,QAAsB;EAClC,MAAM,cAAc,kBAChB,MAAM,gBAAgB,GAAG,IACxB,CAAC;EAEN,OAAO;GACL,GAAG;GACH,WAAW,oBAAoB,CAAC,CAAC,WAAW;EAC9C;CACF;AACF;;;AClEA,SAAgB,aACd,KACA,QAAQ,OAAO,WACf,uBAAO,IAAI,QAAQ,GACnB;CACA,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;CAC7C,IAAI,KAAK,IAAI,GAAG,GAAG;CACnB,KAAK,IAAI,GAAG;CAEZ,IAAI,MAAM,QAAQ,GAAG,GAAG;EACtB,KAAK,MAAM,QAAQ,KACjB,aAAa,MAAM,OAAO,IAAI;EAEhC;CACF;CAEA,MAAM,eAAe,OAAO,eAAe,GAAG;CAC9C,IAAI,iBAAiB,OAAO,aAAa,iBAAiB,MACxD;CAEF,OAAO,eAAe,KAAK,KAAK;CAChC,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,aAAa,IAAI,MAAM,OAAO,IAAI;AAEtC;;;ACJA,MAAa,+BAOX,EACA,IACA,eACA,qBACA,yBAuBI;CACJ,QAAkD,EAChD,OACA,aAAa,QACb,gBAeI;EACJ,MAAM,WAAW,oBAAoB,EAC5B,MACT,CAAC;EACD,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,MAAM,CAAC;EAElE,MAAM,cAAc,YAAY;GAC9B;GACA;EACF,CAAC;EAED,OAAO,cAAc,aAAa,MAAM;GACtC,OAAO,GACJ,GAAG,UAAU,OAAO,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM;IACnD,MAAM;IACN,UAAU;IACV,mBAAmB;IACnB,aAAa,aAAa,UAAU,OAAO,OAAO,KAAK,CAAC;IACxD,YAAY,eAAe,OAAO,OAAO,MAAM,UAAU;KACvD,mBAAmB;MACjB,UAAU;MACV,QAAQ;KACV,CAAC;KACD,mBAAmB;MACjB,UAAU;MACV,QAAQ;KACV,CAAC;IACH;IACA,MAAM,EACJ,OAAO,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;IAAM,CAAC,EAClD;IACA,SAAS,OAAO,OAAO,MAAM,KAAK,UAAU;KAC1C,IAAI,aAAa,CAAE,MAAM,UAAU,GAAG,GACpC,MAAM,IAAI,gBAAgB,oCAAoC;KAGhE,aAAa,IAAI;KAEjB,OAAQ,GACL,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC,CAAC,CAC1B,KAAK,YAAY,KAAK,CAAC,CACvB,MACC,IAAI,UAAU,MAAM,CACjB,OAAO,UAAU,CAAC,CAClB,MAAM,yBAAyB,IAAI,CAAQ,CAAC,CAAC,IAAI,KACtD,CAAC,CACA,KAAK,sBAAsB,CAAC,CAC5B,MAAM,MAAW,EAAE,KAAK;IAC7B;GACF,CAAC,EACH;EACF,CAAC;CACH;AACF;;;AC5HA,MAAa,yBAET;CACF,OAAO;EACL,YAAY,EACV,MAAM;GACJ,aAAa;GACb,aAAa;GACb,MAAM,CAAC;GACP,YAAY,CAAC;GACb,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,yCACR,EACF,EACF,EACF;GACA,WAAW,EACT,OAAO;IACL,aAAa;IACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,6CACR,EACF,EACF;GACF,EACF;EACF,EACF;EACA,iBAAiB;GACf,MAAM;IACJ,aAAa;IACb,aAAa;IACb,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,SACR;IACF,CACF;IACA,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,yCACR,EACF,EACF,EACF;IACA,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,6CACR,EACF,EACF;IACF,EACF;GACF;GACA,QAAQ;IACN,aAAa;IACb,aAAa;IACb,MAAM,CAAC;IACP,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,SACR;IACF,CACF;IACA,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,6CACR,EACF,EACF;IACF,EACF;GACF;EACF;CACF;CACA,YAAY,EACV,SAAS;EACP,mBAAmB;GACjB,MAAM;GACN,YAAY;IACV,cAAc;KACZ,aACE;KACF,MAAM;IACR;IACA,WAAW;KACT,aAAa;KACb,MAAM;IACR;IACA,KAAK;KACH,aAAa;KACb,MAAM;IACR;GACF;EACF;EACA,uBAAuB;GACrB,MAAM;GACN,YAAY,EACV,IAAI;IACF,aACE;IACF,MAAM;GACR,EACF;EACF;EACA,UAAU;GACR,MAAM;GACN,QAAQ;EACV;EACA,MAAM;GACJ,MAAM;GACN,QAAQ;EACV;CACF,EACF;AACF;;;ACpGA,SAAgB,gBACd,OACiC;CACjC,OACE,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAO,iBAAi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"}
1
+ {"version":3,"file":"index.mjs","names":["EmptyFilter","makeDefaultName","normalize","BaseEmailAddressResolver","EmailAddressResolver","EmailAddressResolver","packagejson.version","createYoga","nativeCreateYoga"],"sources":["../lib/types/rumbleError.ts","../lib/helpers/asserts.ts","../lib/helpers/mapNullFieldsToUndefined.ts","../package.json","../lib/helpers/errorLogging.ts","../lib/helpers/mergeFilters.ts","../lib/helpers/sanitizeFilterValue.ts","../lib/helpers/sqlTypes/types.ts","../lib/helpers/sqlTypes/distinctValuesFromSQLType.ts","../lib/helpers/tableHelpers.ts","../lib/helpers/telemetry.ts","../lib/abilityBuilder.ts","../lib/args/orderArg.ts","../lib/enum.ts","../lib/helpers/sqlTypes/mapSQLTypeToTSType.ts","../lib/args/whereArg.ts","../lib/client/client.ts","../lib/context.ts","../lib/helpers/protoMapper.ts","../lib/countQuery.ts","../lib/helpers/sofaOpenAPIWebhookDocs.ts","../lib/helpers/tracing.ts","../lib/helpers/sqlTypes/mapDrizzleTypeToGraphQlType.ts","../lib/helpers/determineDialectFromSchema.ts","../lib/search.ts","../lib/object.ts","../lib/pubsub.ts","../lib/query.ts","../lib/args/whereArgsImplementer.ts","../lib/runtimeFiltersPlugin/filterTypes.ts","../lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts","../lib/scalars/addressValidation.ts","../lib/scalars/address.ts","../lib/scalars/emailAddress.ts","../lib/scalars/personName.ts","../lib/scalars/phoneNumber.ts","../lib/schemaBuilder.ts","../lib/rumble.ts"],"sourcesContent":["import { GraphQLError } from \"graphql\";\n/**\n * An error that gets raised by rumble whenever something does not go according to plan.\n * Mostly internals, configuration errors or other unexpected things.\n */\nexport class RumbleError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RumbleError\";\n }\n}\n\n/**\n * An error that gets raised by rumble whenever an error occurs in a resolver, containing\n * information safely exposeable to the user.\n * E.g. the assert helpers issue these.\n */\nexport class RumbleErrorSafe extends GraphQLError {}\n","import { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n * schemaBuilder.queryFields((t) => {\n return {\n findFirstUser: t.drizzleField({\n type: UserRef,\n resolve: (query, root, args, ctx, info) => {\n return (\n db.query.users\n .findFirst({\n ...query,\n where: ctx.abilities.users.filter(\"read\").single.where,\n })\n // note that we need to manually raise an error if the value is not found\n .then(assertFindFirstExists)\n );\n },\n }),\n };\n });\n * ```\n */\nexport const assertFindFirstExists = <T>(value: T | undefined): T => {\n if (!value) {\n throw new RumbleErrorSafe(\"Value not found but required (findFirst)\");\n }\n return value;\n};\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n schemaBuilder.mutationFields((t) => {\n return {\n updateUsername: t.drizzleField({\n type: UserRef,\n args: {\n userId: t.arg.int({ required: true }),\n newName: t.arg.string({ required: true }),\n },\n resolve: (query, root, args, ctx, info) => {\n return db\n .update(schema.users)\n .set({\n name: args.newName,\n })\n .where(\n and(\n eq(schema.users.id, args.userId),\n ctx.abilities.users.filter(\"update\").single.where\n )\n )\n .returning({ id: schema.users.id, name: schema.users.name })\n // note that we need to manually raise an error if the value is not found\n .then(assertFirstEntryExists);\n },\n }),\n };\n });\n * ```\n */\nexport const assertFirstEntryExists = <T>(value: T[]): T => {\n const v = value.at(0);\n if (!v)\n throw new RumbleErrorSafe(\"Value not found but required (firstEntry)\");\n return v;\n};\n","/**\n * Helper to map null fields to undefined\n * @param obj The object to map\n * @returns The mapped object with all fields of 'null' transformed to 'undefined'\n * \n * This becomes useful for update mutations where you do not want to pass null (unset value in db)\n * but undefined (do not touch value in db) in case of a value not beeing set in the args of said mutation\n * @example\n * ```ts\n * updateUser: t.drizzleField({\n type: User,\n args: {\n id: t.arg.string({ required: true }),\n email: t.arg.string(),\n lastName: t.arg.string(),\n firstName: t.arg.string(),\n },\n resolve: async (query, root, args, ctx, info) => {\n const mappedArgs = mapNullFieldsToUndefined(args);\n const user = await db.transaction(async (tx) => {\n const user = await tx\n .update(schema.user)\n .set({\n\n // email: args.email ?? undefined,\n // lastName: args.lastName ?? undefined,\n // firstName: args.firstName ?? undefined,\n\n // becomes this\n\n email: mappedArgs.email,\n lastName: mappedArgs.lastName,\n firstName: mappedArgs.firstName,\n })\n .returning()\n .then(assertFirstEntryExists);\n return user;\n });\n\n pubsub.updated(user.id);\n\n return db.query.user\n .findFirst(\n query(\n ctx.abilities.user.filter('read').merge(\n {\n where: { id: user.id },\n }\n 1).query.single,\n ),\n )\n .then(assertFindFirstExists);\n },\n }),\n * \n * \n * ```\n */\nexport function mapNullFieldsToUndefined<T extends object>(obj: T) {\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [\n key,\n value === null ? undefined : value,\n ]),\n ) as {\n [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>;\n };\n}\n","","import type { GraphQLError } from \"graphql\";\n\n/**\n * Shape of a single error entry in a log's `errors` array, following\n * OpenTelemetry's exception semantic conventions\n * (https://opentelemetry.io/docs/specs/semconv/exceptions/exceptions-logs/).\n */\nexport interface LoggedException {\n \"exception.type\": string;\n \"exception.message\": string;\n \"exception.stacktrace\"?: string;\n path?: ReadonlyArray<string | number>;\n extensions?: Record<string, unknown>;\n}\n\nfunction hasMessage(error: unknown): error is { message: unknown } {\n return typeof error === \"object\" && error !== null && \"message\" in error;\n}\n\nfunction toLoggedException(error: unknown): LoggedException {\n if (hasMessage(error)) {\n const gqlError = error as Partial<GraphQLError> & Error;\n return {\n \"exception.type\": gqlError.constructor?.name ?? gqlError.name ?? \"Error\",\n \"exception.message\": String(gqlError.message),\n ...(gqlError.stack ? { \"exception.stacktrace\": gqlError.stack } : {}),\n ...(gqlError.path ? { path: gqlError.path } : {}),\n ...(gqlError.extensions && Object.keys(gqlError.extensions).length > 0\n ? { extensions: gqlError.extensions }\n : {}),\n };\n }\n return {\n \"exception.type\": \"UnknownError\",\n \"exception.message\": String(error),\n };\n}\n\n/**\n * Every erroneous rumble log carries the same `errors` array shape,\n * whether it originates from a thrown exception (single-element array)\n * or a GraphQL `ExecutionResult.errors` list (multi-element array).\n */\nexport function errorsLogField(errors: readonly unknown[]): {\n errors: LoggedException[];\n} {\n return { errors: errors.map(toLoggedException) };\n}\n\nexport function errorLogField(error: unknown): { errors: LoggedException[] } {\n return errorsLogField([error]);\n}\n","import { toMerged } from \"es-toolkit\";\n\n// See the comment on `EmptyFilter` in `./sanitizeFilterValue.ts` for why this\n// is recreated locally instead of imported from drizzle-orm.\nconst EmptyFilter = Symbol.for(\"drizzle:EmptyFilter\");\n\n/**\n * Normalizes drizzle-orm's `EmptyFilter` sentinel to `undefined` so it's\n * treated as \"no filter\" rather than a real filter value to combine with\n * AND/OR — otherwise merging an unrestricted (EmptyFilter) base filter with\n * a real `where` would needlessly wrap it as `{ AND: [EmptyFilter, where] }`\n * instead of just `where`.\n */\nfunction realWhere(where: unknown) {\n return where === EmptyFilter ? undefined : where;\n}\n\nexport function mergeFilters<\n FilterA extends Record<string, any>,\n FilterB extends Record<string, any>,\n>(\n filterA?: Partial<FilterA>,\n filterB?: Partial<FilterB>,\n mode: \"AND\" | \"OR\" = \"AND\",\n) {\n const filterAWhere = realWhere(filterA?.where);\n const filterBWhere = realWhere(filterB?.where);\n\n const where =\n filterAWhere && filterBWhere\n ? mode === \"OR\"\n ? { OR: [filterAWhere, filterBWhere] }\n : { AND: [filterAWhere, filterBWhere] }\n : (filterAWhere ?? filterBWhere);\n\n const columns =\n filterA?.columns || filterB?.columns\n ? new Set(\n [\n Object.entries(filterA?.columns ?? {}),\n Object.entries(filterB?.columns ?? {}),\n ]\n .flat()\n .filter(([, v]) => v === true)\n .map(([k]) => k),\n )\n .entries()\n .reduce(\n (acc, [key]) => {\n acc[key] = true;\n return acc;\n },\n {} as Record<string, true>,\n )\n : undefined;\n\n const extras =\n filterA?.extras || filterB?.extras\n ? toMerged(filterA?.extras ?? {}, filterB?.extras ?? {})\n : undefined;\n\n const orderBy =\n filterA?.orderBy || filterB?.orderBy\n ? toMerged(filterA?.orderBy ?? {}, filterB?.orderBy ?? {})\n : undefined;\n\n const limit =\n mode === \"OR\"\n ? filterA?.limit === undefined || filterB?.limit === undefined\n ? undefined\n : Math.max(filterA.limit, filterB.limit)\n : filterA?.limit || filterB?.limit\n ? Math.min(filterA?.limit ?? Infinity, filterB?.limit ?? Infinity)\n : undefined;\n\n const offset =\n mode === \"OR\"\n ? filterA?.offset === undefined || filterB?.offset === undefined\n ? undefined\n : Math.min(filterA.offset, filterB.offset)\n : filterA?.offset || filterB?.offset\n ? Math.min(filterA?.offset ?? Infinity, filterB?.offset ?? Infinity)\n : undefined;\n\n const with_ =\n filterA?.with || filterB?.with\n ? toMerged(filterA?.with ?? {}, filterB?.with ?? {})\n : undefined;\n\n return {\n where,\n columns,\n extras,\n orderBy,\n limit,\n offset,\n with: with_,\n } as unknown as FilterA & FilterB;\n}\n","const EmptyFilter = Symbol.for(\"drizzle:EmptyFilter\");\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function sanitizeFilterValue(value: unknown): unknown {\n if (value === undefined || value === null) return EmptyFilter;\n if (Array.isArray(value)) return value.map(sanitizeFilterValue);\n if (isPlainObject(value)) {\n return Object.fromEntries(\n Object.entries(value).map(([key, entry]) => [\n key,\n sanitizeFilterValue(entry),\n ]),\n );\n }\n return value;\n}\n","import { RumbleError } from \"../../types/rumbleError\";\n\n/**\n * Strips parameter suffixes like `(256)`, `(10,2)` and timezone modifiers\n * (`with time zone`, `without time zone`) from raw getSQLType() output so\n * every classifier works on the base type name only.\n */\nexport function normalizeSQLType(raw: string): string {\n return raw\n .replace(/\\s*with(?:out)?\\s+time\\s+zone/i, \"\")\n .replace(/\\s*\\([^)]*\\)/, \"\")\n .trim()\n .toLowerCase();\n}\n\nconst intLikeSQLTypeStrings = [\n \"serial\",\n \"int\",\n \"integer\",\n \"tinyint\",\n \"smallint\",\n \"mediumint\",\n \"int2\",\n \"int4\",\n \"smallserial\",\n] as const;\n\nexport function isIntLikeSQLTypeString(sqlType: string): boolean {\n return intLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst bigIntLikeSQLTypeStrings = [\n \"bigint\",\n \"bigserial\",\n \"int8\",\n \"bigint unsigned\",\n] as const;\n\nexport function isBigIntLikeSQLTypeString(sqlType: string): boolean {\n return bigIntLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst floatLikeSQLTypeStrings = [\n \"real\",\n \"decimal\",\n \"double\",\n \"float\",\n \"numeric\",\n \"double precision\",\n \"float4\",\n \"float8\",\n \"money\",\n] as const;\n\nexport function isFloatLikeSQLTypeString(sqlType: string): boolean {\n return floatLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst stringLikeSQLTypeStrings = [\n \"string\",\n \"text\",\n \"varchar\",\n \"char\",\n \"character varying\",\n \"character\",\n \"inet\",\n \"cidr\",\n \"macaddr\",\n \"macaddr8\",\n \"interval\",\n \"time\",\n \"year\",\n \"binary\",\n \"varbinary\",\n \"tinytext\",\n \"mediumtext\",\n \"longtext\",\n] as const;\n\nexport function isStringLikeSQLTypeString(sqlType: string): boolean {\n return stringLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst IDLikeSQLTypeStrings = [\"uuid\"] as const;\n\nexport function isIDLikeSQLTypeString(sqlType: string): boolean {\n return IDLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst booleanSQLTypeStrings = [\"boolean\", \"bool\"] as const;\n\nexport function isBooleanSQLTypeString(sqlType: string): boolean {\n return booleanSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateTimeLikeSQLTypeStrings = [\"timestamp\", \"datetime\"] as const;\n\nexport function isDateTimeLikeSQLTypeString(sqlType: string): boolean {\n return dateTimeLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateLikeSQLTypeStrings = [\"date\"] as const;\n\nexport function isDateLikeSQLTypeString(sqlType: string): boolean {\n return dateLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst jsonLikeSQLTypeStrings = [\"json\", \"jsonb\"] as const;\n\nexport function isJSONLikeSQLTypeString(sqlType: string): boolean {\n return jsonLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst jsonFallbackSQLTypeStrings = [\n \"point\",\n \"line\",\n \"lseg\",\n \"box\",\n \"path\",\n \"polygon\",\n \"circle\",\n \"geometry\",\n] as const;\n\nexport function isJSONFallbackSQLTypeString(sqlType: string): boolean {\n return (\n jsonFallbackSQLTypeStrings.includes(sqlType as any) ||\n sqlType.startsWith(\"geometry\")\n );\n}\n\nconst bytesSQLTypeStrings = [\"bytea\", \"blob\"] as const;\n\nexport function isBytesSQLTypeString(sqlType: string): boolean {\n return bytesSQLTypeStrings.includes(sqlType as any);\n}\n\n// PossibleSQLType is intentionally broad — classifiers receive normalized\n// strings and use runtime includes() checks.\nexport type PossibleSQLType = string & {};\n\nexport const UnknownTypeRumbleError = (\n sqlType: string,\n additionalInfo?: string,\n) =>\n new RumbleError(\n `RumbleError: Unknown SQL type '${sqlType}'. Please open an issue (https://github.com/m1212e/rumble/issues) so it can be added. (${additionalInfo})`,\n );\n","import {\n isBooleanSQLTypeString,\n isDateLikeSQLTypeString,\n isDateTimeLikeSQLTypeString,\n isFloatLikeSQLTypeString,\n isIDLikeSQLTypeString,\n isIntLikeSQLTypeString,\n isJSONLikeSQLTypeString,\n isStringLikeSQLTypeString,\n type PossibleSQLType,\n UnknownTypeRumbleError,\n} from \"./types\";\n\nexport function createDistinctValuesFromSQLType(sqlType: PossibleSQLType): {\n value1: any;\n value2: any;\n} {\n if (isIntLikeSQLTypeString(sqlType)) {\n return {\n value1: 1,\n value2: 2,\n };\n }\n\n if (isFloatLikeSQLTypeString(sqlType)) {\n return {\n value1: 1.1,\n value2: 2.2,\n };\n }\n\n if (isStringLikeSQLTypeString(sqlType)) {\n return {\n value1: \"a\",\n value2: \"b\",\n };\n }\n\n if (isIDLikeSQLTypeString(sqlType)) {\n return {\n value1: \"fba31870-5528-42d7-b27e-2e5ee657aea5\",\n value2: \"fc65db81-c2d1-483d-8a25-a30e2cf6e02d\",\n };\n }\n\n if (isBooleanSQLTypeString(sqlType)) {\n return {\n value1: true,\n value2: false,\n };\n }\n\n if (isDateTimeLikeSQLTypeString(sqlType)) {\n return {\n value1: new Date(2022, 1, 1),\n value2: new Date(2022, 1, 2),\n };\n }\n\n if (isDateLikeSQLTypeString(sqlType)) {\n return {\n value1: new Date(2022, 1, 1),\n value2: new Date(2022, 1, 2),\n };\n }\n\n if (isJSONLikeSQLTypeString(sqlType)) {\n return {\n value1: { a: 1 },\n value2: { b: 2 },\n };\n }\n\n throw UnknownTypeRumbleError(sqlType, \"Distinct\");\n}\n","import {\n type Column,\n getTableColumns,\n getTableName,\n is,\n isTable,\n type Many,\n type One,\n type Table,\n} from \"drizzle-orm\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\n\ntype RelationEntry = {\n /** TS-level key in db._.relations (i.e. the export name) */\n name: string;\n /** runtime DB table name as returned by getTableName(table) */\n dbName: string;\n /** the underlying drizzle Table object */\n table: any;\n /** columns map for the table */\n columns: Record<string, Column>;\n /** primary key columns, keyed by column ts-name */\n primaryKey: Record<string, Column>;\n /** named relations record (one/many) for this table */\n relations: Record<string, One<any, any> | Many<any>>;\n /**\n * Whether the underlying entity is a genuine drizzle Table (as opposed to a\n * View/MaterializedView)\n */\n isTable: boolean;\n /**\n * The raw entry from db._.relations — preserved for callers that previously\n * read `foundRelation` off tableHelper().\n */\n foundRelation: any;\n};\n\ntype TableIndex = {\n byTsName: Map<string, RelationEntry>;\n byDbName: Map<string, RelationEntry>;\n byTableRef: Map<any, RelationEntry>;\n};\n\nconst indexCache = new WeakMap<object, TableIndex>();\n\nfunction buildIndex<DB extends DrizzleInstance>(db: DB): TableIndex {\n const byTsName = new Map<string, RelationEntry>();\n const byDbName = new Map<string, RelationEntry>();\n const byTableRef = new Map<any, RelationEntry>();\n\n for (const [tsName, rawEntry] of Object.entries(db._.relations ?? {})) {\n const entry = rawEntry as any;\n const tableObj = entry.table;\n if (!tableObj) continue;\n\n const columns = (\n isTable(tableObj) ? getTableColumns(tableObj as Table) : {}\n ) as Record<string, Column>;\n\n const primaryKey = Object.fromEntries(\n Object.entries(columns).filter(([, col]) => (col as any).primary),\n ) as Record<string, Column>;\n\n const dbName = isTable(tableObj)\n ? (getTableName(tableObj as Table) as string)\n : ((entry.name as string) ?? tsName);\n\n const resolved: RelationEntry = {\n name: entry.name ?? tsName,\n dbName,\n table: tableObj,\n columns,\n primaryKey,\n relations: entry.relations ?? {},\n isTable: isTable(tableObj),\n foundRelation: entry,\n };\n\n byTsName.set(resolved.name, resolved);\n byDbName.set(resolved.dbName, resolved);\n byTableRef.set(tableObj, resolved);\n }\n\n return { byTsName, byDbName, byTableRef };\n}\n\nfunction getIndex<DB extends DrizzleInstance>(db: DB): TableIndex {\n let idx = indexCache.get(db as unknown as object);\n if (!idx) {\n idx = buildIndex(db);\n indexCache.set(db as unknown as object, idx);\n }\n return idx;\n}\n\nexport function tableHelper<\n DB extends DrizzleInstance,\n TableIdentifier extends\n | string\n | DB[\"_\"][\"relations\"][keyof DB[\"_\"][\"relations\"]],\n>({ db, table }: { db: DB; table: TableIdentifier }) {\n const idx = getIndex(db);\n\n let entry: RelationEntry | undefined;\n\n if (typeof table === \"string\") {\n // Lookup by TS-level relation name first (the common case), then by DB name.\n entry = idx.byTsName.get(table) ?? idx.byDbName.get(table);\n } else if (table && typeof table === \"object\") {\n const t = table as any;\n\n // Case 1: caller passed an entry from db._.relations directly:resolve by\n // table identity via its `.table` property.\n if (t.table) {\n entry = idx.byTableRef.get(t.table);\n if (!entry && t.name) {\n entry = idx.byTsName.get(t.name) ?? idx.byDbName.get(t.name);\n }\n }\n\n // Case 2: caller passed a raw Table object: resolve by identity.\n if (!entry) {\n entry = idx.byTableRef.get(t);\n }\n\n // Case 3: last resort lookup via the public getTableName() helper.\n if (!entry && isTable(t)) {\n const dbName = getTableName(t as Table) as string;\n entry = idx.byDbName.get(dbName);\n }\n }\n\n if (!entry) {\n throw new RumbleError(\n `Could not find schema for ${JSON.stringify(\n typeof table === \"string\" ? table : \"<table-object>\",\n )}`,\n );\n }\n\n return {\n columns: entry.columns,\n primaryKey: entry.primaryKey,\n relations: entry.relations,\n dbName: entry.dbName,\n tsName: entry.name,\n table: entry.table,\n isTable: entry.isTable,\n foundRelation: entry.foundRelation,\n };\n}\n\n/**\n * Looks up a relation entry by its TS-level name — i.e. the key in\n * db._.relations, which is also what `Relation.targetTableName` carries.\n * Prefer this for cross-relation navigation over re-resolving via the raw\n * `targetTable` object.\n */\nexport function tableHelperByTsName<DB extends DrizzleInstance>(\n db: DB,\n tsName: string,\n) {\n return tableHelper({ db, table: tsName });\n}\n\nexport { is };\n","import {\n type Attributes,\n type AttributeValue,\n isSpanContextValid,\n type Span,\n SpanStatusCode,\n type Tracer,\n trace,\n} from \"@opentelemetry/api\";\nimport {\n ATTR_GRAPHQL_DOCUMENT,\n ATTR_GRAPHQL_OPERATION_NAME,\n ATTR_GRAPHQL_OPERATION_TYPE,\n} from \"@opentelemetry/semantic-conventions/incubating\";\nimport { AttributeNames, SpanNames } from \"@pothos/tracing-opentelemetry\";\nimport type { RumbleInput, RumbleLogger } from \"../types/rumbleInput\";\n\n/**\n * Which entry point served the current GraphQL operation.\n *\n * Every operation span and log entry carries this as `rumble.transport` so the\n * GraphQL endpoint, the SOFA REST adapter and the WebSocket handler emit the\n * exact same telemetry shape and stay comparable in a single query.\n */\nexport type RumbleTransport = \"graphql\" | \"rest\" | \"ws\";\n\n/**\n * The slice of the rumble input that drives telemetry. Kept structural so every\n * helper in the library can take it without repeating rumble's generic signature.\n */\nexport type TelemetryConfig = Pick<\n RumbleInput<any, any, any, any, any>,\n \"otel\" | \"logger\"\n>;\n\n// ─── span names ──────────────────────────────────────────────────────────────\n// The GraphQL ones align with @pothos/tracing-opentelemetry so rumble's spans sit\n// in the same namespace as the resolver spans pothos emits.\n\nexport const SPAN_EXECUTE: string = SpanNames.EXECUTE;\n/** @pothos/tracing-opentelemetry's SpanNames enum has no subscribe member. */\nexport const SPAN_SUBSCRIBE = \"graphql.subscribe\";\nexport const SPAN_SUBSCRIBE_EVENT = \"graphql.subscribe.event\";\nexport const SPAN_ABILITIES_PREPARE = \"rumble.abilities.prepare\";\nexport const SPAN_FILTERS_APPLY = \"rumble.filters.apply\";\nexport const SPAN_FILTERS_RESOLVE = \"rumble.filters.resolve\";\n\n// ─── attribute and log field names ───────────────────────────────────────────\n// Span attributes and log fields deliberately share names, so the same key means\n// the same thing whether you are looking at a trace or at a log line. The GraphQL\n// ones come from OpenTelemetry's (still incubating) GraphQL semantic conventions\n// and happen to be exactly what pothos uses, so resolver and operation spans line\n// up without any translation.\n\nexport const ATTR_OPERATION_NAME: string = ATTR_GRAPHQL_OPERATION_NAME;\nexport const ATTR_OPERATION_TYPE: string = ATTR_GRAPHQL_OPERATION_TYPE;\nexport const ATTR_DOCUMENT: string = ATTR_GRAPHQL_DOCUMENT;\nexport const ATTR_FIELD_NAME: string = AttributeNames.FIELD_NAME;\n/** Prefix for per-variable span attributes, e.g. `graphql.variables.userId`. */\nexport const ATTR_VARIABLES_PREFIX: string = AttributeNames.VARIABLES;\n/** Log field holding all variables as one object (logs keep nesting, spans flatten). */\nexport const FIELD_VARIABLES = \"graphql.variables\";\nexport const ATTR_PARENT_TYPE = \"graphql.parent.type\";\nexport const ATTR_TRANSPORT = \"rumble.transport\";\nexport const ATTR_TABLE = \"rumble.table\";\nexport const ATTR_ACTION = \"rumble.action\";\nexport const ATTR_ABILITIES_STATUS = \"rumble.abilities.status\";\nexport const ATTR_ABILITIES_STATIC = \"rumble.abilities.static\";\nexport const ATTR_ABILITIES_DYNAMIC = \"rumble.abilities.dynamic\";\nexport const ATTR_ABILITIES_TOTAL = \"rumble.abilities.total\";\nexport const ATTR_FILTERS_TOTAL = \"rumble.filters.total\";\nexport const ATTR_FILTERS_ALLOWED = \"rumble.filters.allowed\";\nexport const ATTR_SUBSCRIPTION_EVENT_INDEX = \"rumble.subscription.event_index\";\nexport const FIELD_DURATION_MS = \"duration_ms\";\nexport const FIELD_EVENT_COUNT = \"event_count\";\n\n// ─── config accessors ────────────────────────────────────────────────────────\n\nexport function telemetryLogger(\n config: TelemetryConfig,\n): RumbleLogger | undefined {\n return config.logger?.enabled ? config.logger.logger : undefined;\n}\n\nexport function telemetryTracer(config: TelemetryConfig): Tracer | undefined {\n return config.otel?.enabled ? config.otel.tracer : undefined;\n}\n\n/**\n * Whether anything at all should be instrumented. When this is false, rumble\n * hands the untouched execute/subscribe functions back to the transports so a\n * user who wants neither traces nor logs pays no overhead.\n */\nexport function telemetryEnabled(config: TelemetryConfig): boolean {\n return Boolean(config.otel?.enabled || config.logger?.enabled);\n}\n\n// ─── log/trace correlation ───────────────────────────────────────────────────\n\n/**\n * `trace_id`/`span_id`/`trace_flags` for the given span, or for the currently\n * active one when no span is passed. Field names and the two-hex-digit flags\n * format follow the OpenTelemetry log data model, which is what log backends\n * (Loki, Tempo, Elastic) expect when linking a log line to its trace.\n *\n * Reading the *active* span means every rumble log site gets correlation for\n * free, without threading a child logger through the whole library.\n */\nexport function traceCorrelationFields(\n config: TelemetryConfig,\n span?: Span,\n): Record<string, string> {\n if (!config.otel?.enabled || config.logger?.injectTraceId === false) {\n return {};\n }\n\n const target = span ?? trace.getActiveSpan();\n if (!target) return {};\n\n const spanContext = target.spanContext();\n if (!isSpanContextValid(spanContext)) return {};\n\n return {\n trace_id: spanContext.traceId,\n span_id: spanContext.spanId,\n trace_flags: spanContext.traceFlags.toString(16).padStart(2, \"0\"),\n };\n}\n\n// ─── errors on spans ─────────────────────────────────────────────────────────\n\nfunction toException(error: unknown) {\n if (error instanceof Error) return error;\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return error as { message: string };\n }\n return String(error);\n}\n\nfunction exceptionMessage(error: unknown): string | undefined {\n if (typeof error === \"object\" && error !== null && \"message\" in error) {\n return String((error as { message: unknown }).message);\n }\n return error === undefined ? undefined : String(error);\n}\n\n/**\n * Records every error as an exception event and flips the span to ERROR, per\n * OpenTelemetry's exception conventions. Used for rumble's own spans as well as\n * the GraphQL operation spans so a failure looks identical wherever it happens.\n */\nexport function recordSpanErrors(\n span: Span | undefined,\n errors: readonly unknown[],\n): void {\n if (!span || errors.length === 0) return;\n\n for (const error of errors) {\n span.recordException(toException(error));\n }\n\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: exceptionMessage(errors[0]),\n });\n}\n\nexport function recordSpanError(span: Span | undefined, error: unknown): void {\n recordSpanErrors(span, [error]);\n}\n\n/**\n * Errors the operation wrapper has already reported.\n *\n * A transport can see the same failure twice: sofa, for instance, hands\n * `result.errors` to its error handler *after* execute has returned, so without\n * this the very same error would produce two log lines and two exception events,\n * which quietly doubles error counts in dashboards. A WeakSet keeps this free of\n * bookkeeping — entries disappear with the errors themselves.\n */\nconst reportedErrors = new WeakSet<object>();\n\nexport function markErrorsReported(errors: readonly unknown[]): void {\n for (const error of errors) {\n if (typeof error === \"object\" && error !== null) {\n reportedErrors.add(error);\n }\n }\n}\n\n/** True when every error was already reported by the operation wrapper. */\nexport function errorsAlreadyReported(errors: readonly unknown[]): boolean {\n if (errors.length === 0) return false;\n return errors.every(\n (error) =>\n typeof error === \"object\" && error !== null && reportedErrors.has(error),\n );\n}\n\n// ─── attribute values ────────────────────────────────────────────────────────\n\nfunction safeJsonStringify(value: unknown): string {\n try {\n return (\n JSON.stringify(value, (_key, inner) =>\n typeof inner === \"bigint\" ? inner.toString() : inner,\n ) ?? \"null\"\n );\n } catch {\n // circular structures, throwing getters, exotic objects\n return String(value);\n }\n}\n\nfunction isHomogeneousPrimitiveArray(value: unknown[]): boolean {\n let seen: \"string\" | \"number\" | \"boolean\" | undefined;\n for (const entry of value) {\n if (entry === null || entry === undefined) continue;\n const type = typeof entry;\n if (type !== \"string\" && type !== \"number\" && type !== \"boolean\") {\n return false;\n }\n if (seen && seen !== type) return false;\n seen = type;\n }\n return true;\n}\n\n/**\n * Coerces an arbitrary value into something the OpenTelemetry attribute type\n * allows: primitives pass through, homogeneous primitive arrays stay arrays\n * (mixed ones are invalid per spec) and everything else becomes JSON.\n *\n * Values are intentionally not truncated here — length limits belong to the SDK\n * (`OTEL_ATTRIBUTE_VALUE_LENGTH_LIMIT`) so they stay configurable per deployment.\n */\nexport function attributeValue(value: unknown): AttributeValue {\n switch (typeof value) {\n case \"string\":\n return value;\n case \"number\":\n return Number.isFinite(value) ? value : String(value);\n case \"boolean\":\n return value;\n case \"bigint\":\n return value.toString();\n case \"undefined\":\n return \"null\";\n default:\n break;\n }\n\n if (value === null) return \"null\";\n if (Array.isArray(value) && isHomogeneousPrimitiveArray(value)) {\n return value as AttributeValue;\n }\n return safeJsonStringify(value);\n}\n\n// ─── GraphQL variables ───────────────────────────────────────────────────────\n\n/**\n * `true` (default) captures all variables, `false` captures none, and a function\n * lets you redact or drop individual entries before they reach a span or a log.\n */\nexport type VariableInclusion =\n | boolean\n | ((\n variables: Record<string, unknown>,\n ) => Record<string, unknown> | undefined)\n | undefined;\n\nexport function resolveVariables(\n variables: Readonly<Record<string, unknown>> | null | undefined,\n include: VariableInclusion,\n): Record<string, unknown> | undefined {\n if (include === false || !variables) return undefined;\n\n const resolved =\n typeof include === \"function\" ? include({ ...variables }) : variables;\n\n if (!resolved || Object.keys(resolved).length === 0) return undefined;\n return resolved as Record<string, unknown>;\n}\n\n/** Variables flattened into `graphql.variables.<name>` span attributes. */\nexport function variableAttributes(\n variables: Readonly<Record<string, unknown>> | null | undefined,\n include: VariableInclusion,\n): Attributes {\n const resolved = resolveVariables(variables, include);\n if (!resolved) return {};\n\n const attributes: Attributes = {};\n for (const [key, value] of Object.entries(resolved)) {\n attributes[`${ATTR_VARIABLES_PREFIX}${key}`] = attributeValue(value);\n }\n return attributes;\n}\n\n/** Variables as a single nested `graphql.variables` log field. */\nexport function variableLogField(\n variables: Readonly<Record<string, unknown>> | null | undefined,\n include: VariableInclusion,\n): Record<string, unknown> {\n const resolved = resolveVariables(variables, include);\n return resolved ? { [FIELD_VARIABLES]: resolved } : {};\n}\n\n// ─── durations ───────────────────────────────────────────────────────────────\n\n/**\n * Monotonic clock reading. `Date.now()` can jump backwards when the wall clock is\n * adjusted (NTP), which would produce negative or inflated durations.\n */\nexport function startTimer(): number {\n return performance.now();\n}\n\nexport function durationMs(start: number): number {\n return Math.round((performance.now() - start) * 100) / 100;\n}\n","import type { AttributeValue, Span } from \"@opentelemetry/api\";\nimport { relationsFilterToSQL } from \"drizzle-orm\";\nimport { debounce } from \"es-toolkit\";\nimport { errorLogField } from \"./helpers/errorLogging\";\nimport { lazy } from \"./helpers/lazy\";\nimport { mergeFilters } from \"./helpers/mergeFilters\";\nimport { sanitizeFilterValue } from \"./helpers/sanitizeFilterValue\";\nimport { createDistinctValuesFromSQLType } from \"./helpers/sqlTypes/distinctValuesFromSQLType\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport {\n ATTR_ABILITIES_DYNAMIC,\n ATTR_ABILITIES_STATIC,\n ATTR_ABILITIES_STATUS,\n ATTR_ABILITIES_TOTAL,\n ATTR_ACTION,\n ATTR_TABLE,\n recordSpanError,\n SPAN_ABILITIES_PREPARE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport type {\n Filter,\n FilterPrefetchCombo,\n Prefetch,\n} from \"./runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleQueryFunctionInput,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n RumbleLogger,\n} from \"./types/rumbleInput\";\n\n//TODO: optimize this for v8 & refactor\n\nexport type AbilityBuilderType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\n/**\n * Static, non changing query filter input type for a specific table\n */\ntype StaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n> = Filter;\n\n/**\n * Dynamic, context based query filter input type for a specific table\n */\ntype DynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> = (\n context: Context,\n) => StaticQueryFilter<DB, Table, Filter> | undefined | \"allow\";\n\n/**\n * Combined query filter type for a specific table. May be static or dynamic.\n */\ntype QueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> =\n | StaticQueryFilter<DB, Table, Filter>\n | DynamicQueryFilter<DB, Table, Filter, Context>;\n\nfunction isDynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is DynamicQueryFilter<DB, Table, Filter, Context> {\n return (\n typeof filter === \"function\" && filter.constructor.name !== \"AsyncFunction\"\n );\n}\n\nfunction isStaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is StaticQueryFilter<DB, Table, Filter> {\n return typeof filter !== \"function\";\n}\n\nconst makeNothingRegisteredWarner = (\n config: TelemetryConfig,\n logger?: RumbleLogger,\n) =>\n debounce((model: string, action: string) => {\n const msg = `No abilities registered for ${model}/${action} — blocking everything. Register the ability or ignore this warning if intentional.`;\n if (logger) {\n logger.warn(\n {\n [ATTR_TABLE]: model,\n [ATTR_ACTION]: action,\n ...traceCorrelationFields(config),\n },\n msg,\n );\n } else {\n console.warn(msg);\n }\n }, 1000);\n\nexport const createAbilityBuilder = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n actions,\n defaultLimit,\n otel,\n logger: loggerConfig,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n const log = loggerConfig?.enabled ? loggerConfig.logger : undefined;\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n const nothingRegisteredWarningLogger = makeNothingRegisteredWarner(\n telemetryConfig,\n log,\n );\n type TableNames = TableRelationNames<DB>;\n\n // Views/materialized views can appear in db.query (if the caller's schema\n // includes them)\n const tableRelationNames = (\n Object.keys(db.query) as (keyof DrizzleQueryFunction<DB>)[]\n ).filter(\n (name) => tableHelper({ db, table: name as any }).isTable,\n ) as TableNames[];\n\n let hasBeenBuilt = false;\n\n const createBuilderForTable = <TableName extends TableNames>() => {\n const queryFilters = new Map<\n Action,\n | QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[]\n | \"unrestricted\"\n >();\n\n const runtimeFilters = new Map<\n Action,\n //TODO add a run all helper\n FilterPrefetchCombo<UserContext, any, any>[]\n >();\n\n // we want to init all possible runtime filters since we want to ensure\n // that the implementaiton helpers pass an object by reference when creating\n // the implementation, instead of a copy like it would be the case with undefined\n for (const action of actions!) {\n if (!runtimeFilters.has(action)) {\n runtimeFilters.set(action, []);\n }\n }\n\n return {\n /**\n * Allows to perform a specific action on a specific entity\n */\n allow: (action: Action | Action[]) => {\n if (hasBeenBuilt) {\n throw new RumbleError(\n \"You can't call allow() after the ability builder has been built. Please ensure that you register all abilities before accessing them.\",\n );\n }\n\n const actions = Array.isArray(action) ? action : [action];\n // Track which actions this specific allow() call initialized as \"unrestricted\",\n // so .when() can distinguish chained use (allow().when()) from a later separate call\n // that finds a pre-existing \"unrestricted\" from a prior bare allow().\n const setUnrestrictedByThisCall = new Set<(typeof actions)[number]>();\n for (const action of actions) {\n let filters = queryFilters.get(action);\n if (!filters) {\n filters = \"unrestricted\";\n queryFilters.set(action, filters);\n setUnrestrictedByThisCall.add(action);\n }\n }\n\n return {\n /**\n * Restricts the allowed actions to a filter\n * @example\n * ```ts\n * abilityBuilder.users.allow([\"read\", \"update\", \"delete\"]).when(({ userId }) => ({\n * where: {\n * id: userId,\n * },\n * }));\n * ```\n */\n when: (\n queryFilter: QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >,\n ) => {\n for (const action of actions) {\n if (queryFilters.get(action) === \"unrestricted\") {\n if (setUnrestrictedByThisCall.has(action)) {\n // Chained directly on this allow() call — override unrestricted with specific filter\n queryFilters.set(action, []);\n } else {\n // A previous separate bare allow() already set unrestricted\n // skip this filter\n continue;\n }\n }\n const filters = queryFilters.get(action)!;\n (filters as Exclude<typeof filters, \"unrestricted\">).push(\n queryFilter,\n );\n }\n },\n };\n },\n /**\n * Allows to register an application level filter to restrict some results\n * which were returned by a query\n */\n filter: (action: Action | Action[]) => {\n const actions = Array.isArray(action) ? action : [action];\n return {\n /**\n * Allows to register an application level prefetch to fetch some data\n * which could be useful for later filtering the results. The prefetch\n * function will be called with the user context but unlike the actual\n * filter function, it will not have access to the result of the query\n * and therefore can be run in parallel with underlying query resolver.\n * A typical use case is to fetch some data which is not directly\n * related to the query but to the context only. So e.g. fetching the\n * user's permissions from an external system and then later applying\n * the filter based on those permissions.\n */\n prefetch: <PrefetchReturnType>(\n prefetch: Prefetch<UserContext, PrefetchReturnType>,\n ) => {\n return {\n /**\n * The actual filter function to apply. Returns the allowed values\n */\n by: (\n explicitFilter: Filter<\n UserContext,\n DrizzleTableValueType<DB, TableName>,\n PrefetchReturnType\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters.get(action)!.push({\n filter: explicitFilter,\n prefetch: prefetch,\n });\n }\n },\n };\n },\n /**\n * The actual filter function to apply. Returns the allowed values\n */\n by: (\n explicitFilter: Filter<\n UserContext,\n DrizzleTableValueType<DB, TableName>\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters.get(action)!.push({\n filter: explicitFilter as Filter<UserContext, any, any>,\n });\n }\n },\n };\n },\n _: {\n runtimeFilters,\n queryFilters,\n },\n };\n };\n\n const buildersPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createBuilderForTable<typeof tableName>(),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createBuilderForTable<key>>;\n };\n\n return {\n ...buildersPerTable,\n /**\n * @internal\n * @ignore\n */\n _: {\n registeredFilters({\n action,\n table,\n }: {\n table: TableNames;\n action: Action;\n }) {\n return (buildersPerTable[table] as any)._.runtimeFilters.get(\n action,\n )! as Filter<UserContext, DrizzleTableValueType<DB, TableNames>>[];\n },\n build() {\n const createFilterForTable = <TableName extends TableNames>(\n tableName: TableName,\n ) => {\n const queryFilters = buildersPerTable[tableName]._.queryFilters;\n\n const simpleQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isStaticQueryFilter)];\n }),\n ) as {\n [key in Action]: StaticQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>\n >[];\n };\n\n const dynamicQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isDynamicQueryFilter)];\n }),\n ) as {\n [key in Action]: DynamicQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[];\n };\n\n const tableSchema = tableHelper({\n db,\n table: tableName,\n });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n throw new RumbleError(\n `No primary key found for entity ${String(tableName)}`,\n );\n }\n\n const primaryKeyField: any = Object.values(tableSchema.primaryKey)[0];\n // we want a filter that excludes everything\n const distinctValues = createDistinctValuesFromSQLType(\n primaryKeyField.getSQLType() as any,\n );\n\n const blockEverythingFilter = {\n where: {\n AND: [\n {\n [primaryKeyField.name]: distinctValues.value1,\n },\n {\n [primaryKeyField.name]: distinctValues.value2,\n },\n ],\n },\n };\n\n /**\n * Packs the filters into a response object that can be applied for queries by the user\n */\n function transformToResponse(\n queryFilters?: DrizzleQueryFunctionInput<DB, TableName>,\n ) {\n const internalTransformer = (\n filters?: DrizzleQueryFunctionInput<DB, TableName>,\n mergedLimit?: number,\n ) => {\n const limit = lazy(() => {\n if (\n // got a merge injection\n mergedLimit !== undefined\n ) {\n if (!filters?.limit) {\n // there is not ability limit\n return mergedLimit;\n }\n\n if ((filters.limit as number) > mergedLimit) {\n // there is an ability limit and it is higher that the injected merge limit\n return mergedLimit;\n }\n }\n\n let limit = filters?.limit as number | undefined;\n\n if (\n defaultLimit &&\n (limit === undefined || limit > defaultLimit)\n ) {\n limit = defaultLimit;\n }\n\n // ensure that null is converted to undefined\n return limit ?? undefined;\n });\n\n const sqlTransformedWhere = lazy(() => {\n const casing = (db._ as any).session?.dialect?.casing;\n\n return filters?.where\n ? relationsFilterToSQL(\n tableSchema.foundRelation.table,\n sanitizeFilterValue(filters.where) as any,\n tableSchema.relations,\n db._.relations,\n casing,\n )\n : undefined;\n });\n\n // we acutally need to define multiple return objects since we do not want to use delete for\n // performance reasons and an undefined columns field on a drizzle filter will prevent any\n // column from being selected at all\n if (filters?.columns) {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n columns: filters?.columns,\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"columns\" | \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n columns: filters?.columns,\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"columns\" | \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n } else {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: sanitizeFilterValue(filters?.where),\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n }\n };\n\n const ret = internalTransformer(queryFilters);\n\n /**\n * Merges the current query filters with the provided filters for this call only\n */\n function merge(\n p: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>,\n ) {\n const merged = mergeFilters(ret.query.many, p);\n return internalTransformer(\n merged,\n // in case the user wants to inject a limit, we need to ensure that it is applied\n // and not the potential default limit will be used\n // this is important for functions of the default query pagination implementation\n p.limit as number | undefined,\n );\n }\n\n (ret as any).merge = merge;\n\n return ret as typeof ret & {\n merge: typeof merge;\n };\n }\n\n return {\n withContext: (userContext: UserContext) => {\n return {\n filter: (action: Action) => {\n const assembleAbilities = (\n attributes: Record<string, AttributeValue>,\n ) => {\n const filters = queryFilters.get(action);\n\n // in case we have a wildcard ability, skip the rest and return no filters at all\n if (filters === \"unrestricted\") {\n attributes[ATTR_ABILITIES_STATUS] = \"unrestricted\";\n return transformToResponse();\n }\n\n // if nothing has been allowed, block everything\n if (!filters) {\n attributes[ATTR_ABILITIES_STATUS] = \"blocked_everything\";\n nothingRegisteredWarningLogger(String(tableName), action);\n return transformToResponse(blockEverythingFilter);\n }\n\n // run all dynamic filters\n const dynamicResults = new Array<\n DrizzleQueryFunctionInput<DB, TableName>\n >(dynamicQueryFilters[action].length);\n let filtersReturned = 0;\n for (\n let i = 0;\n i < dynamicQueryFilters[action].length;\n i++\n ) {\n const func = dynamicQueryFilters[action][i];\n const result = func(userContext);\n // if one of the dynamic filters returns \"allow\", we want to allow everything\n if (result === \"allow\") {\n attributes[ATTR_ABILITIES_STATUS] = \"unrestricted\";\n return transformToResponse();\n }\n // if nothing is returned, nothing is allowed by this filter\n if (result === undefined) continue;\n\n dynamicResults[filtersReturned++] = result;\n }\n dynamicResults.length = filtersReturned;\n\n attributes[ATTR_ABILITIES_DYNAMIC] = dynamicResults.length;\n attributes[ATTR_ABILITIES_STATIC] =\n simpleQueryFilters[action].length;\n\n const allQueryFilters = [\n ...simpleQueryFilters[action],\n ...dynamicResults,\n ];\n\n attributes[ATTR_ABILITIES_TOTAL] = allQueryFilters.length;\n\n // if we don't have any permitted filters then block everything\n if (allQueryFilters.length === 0) {\n attributes[ATTR_ABILITIES_STATUS] = \"blocked_everything\";\n\n return transformToResponse(blockEverythingFilter);\n }\n\n const mergedFilters =\n allQueryFilters.length === 1\n ? allQueryFilters[0]\n : allQueryFilters.reduce((a, b) => {\n return mergeFilters(a, b, \"OR\");\n });\n\n attributes[ATTR_ABILITIES_STATUS] = \"applied\";\n return transformToResponse(mergedFilters as any);\n };\n\n // one attribute set, fed to both sinks, so a trace and a log\n // line describing the same ability check cannot disagree\n const run = (span?: Span) => {\n const attributes: Record<string, AttributeValue> = {\n [ATTR_TABLE]: String(tableName),\n [ATTR_ACTION]: action,\n };\n\n try {\n const result = assembleAbilities(attributes);\n log?.debug(\n {\n ...attributes,\n ...traceCorrelationFields(telemetryConfig, span),\n },\n \"abilities prepared\",\n );\n return result;\n } catch (error) {\n recordSpanError(span, error);\n log?.error(\n {\n ...attributes,\n ...traceCorrelationFields(telemetryConfig, span),\n ...errorLogField(error),\n },\n \"abilities failed\",\n );\n throw error;\n } finally {\n span?.setAttributes(attributes);\n }\n };\n\n if (otel?.enabled && otel.tracer) {\n return otel.tracer.startActiveSpan(\n SPAN_ABILITIES_PREPARE,\n (span) => {\n try {\n return run(span);\n } finally {\n span.end();\n }\n },\n );\n }\n\n return run();\n },\n };\n },\n };\n };\n\n const abilitiesPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createFilterForTable(tableName),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createFilterForTable<key>>;\n };\n\n hasBeenBuilt = true;\n\n return (ctx: UserContext) => {\n return Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n abilitiesPerTable[tableName].withContext(ctx),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n ReturnType<typeof createFilterForTable<key>>[\"withContext\"]\n >;\n };\n };\n },\n },\n };\n};\n","import { toCamelCase } from \"drizzle-orm/casing\";\nimport { capitalize } from \"es-toolkit\";\nimport { lazy } from \"../helpers/lazy\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\n\nexport type OrderArgImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createOrderArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\nconst makeDefaultName = (dbName: string) =>\n `${capitalize(toCamelCase(dbName.toString()))}OrderInputArgument`;\n\nexport const createOrderArgImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const referenceStorage = new Map<string, any>();\n\n const sortingParameterEnumRef = lazy(() =>\n schemaBuilder.enumType(\"SortingParameter\", {\n values: [\"asc\", \"desc\"] as const,\n }),\n );\n\n const orderArgImplementer = <\n RefName extends string,\n TableName extends keyof DrizzleQueryFunction<DB>,\n >({\n table,\n refName,\n dbName,\n }: Partial<{\n table: TableName;\n refName: RefName | undefined;\n dbName: string;\n }> &\n (\n | {\n table: TableName;\n }\n | {\n dbName: string;\n }\n )) => {\n const tableSchema = tableHelper({\n db,\n table: dbName ?? table!,\n });\n\n const inputTypeName = refName ?? makeDefaultName(tableSchema.tsName);\n\n let ret: ReturnType<typeof implement> | undefined =\n referenceStorage.get(inputTypeName);\n if (ret) {\n return ret;\n }\n\n const implement = () => {\n return schemaBuilder.inputType(inputTypeName, {\n fields: (t) => {\n // Drizzle's relationsOrderToSQL treats every key as a column on the\n // current table, so exposing relation keys would generate invalid SQL.\n const fields = Object.entries(tableSchema.columns).reduce(\n (acc, [key]) => {\n // GraphQL reserves names starting with \"__\" for introspection.\n if (key.startsWith(\"__\")) return acc;\n\n acc[key] = t.field({\n type: sortingParameterEnumRef(),\n required: false,\n });\n\n return acc;\n },\n {} as Record<string, ReturnType<typeof t.field>>,\n );\n\n return fields;\n },\n });\n };\n\n ret = implement();\n referenceStorage.set(inputTypeName, ret);\n return ret;\n };\n\n return orderArgImplementer;\n};\n","import { type Column, getTableName, is, isTable } from \"drizzle-orm\";\nimport { toCamelCase } from \"drizzle-orm/casing\";\nimport { MySqlEnumColumn, MySqlEnumObjectColumn } from \"drizzle-orm/mysql-core\";\nimport {\n isPgEnum,\n type PgEnum,\n PgEnumColumn,\n type PgEnumObject,\n PgEnumObjectColumn,\n} from \"drizzle-orm/pg-core\";\nimport { capitalize } from \"es-toolkit\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\n/**\n * Checks if a column is a database enum column (Postgres or MySQL).\n */\nexport function isEnumSchema(\n schemaType: any,\n): schemaType is\n | PgEnumColumn<any>\n | PgEnumObjectColumn<any>\n | MySqlEnumColumn<any>\n | MySqlEnumObjectColumn<any> {\n return (\n is(schemaType, PgEnumColumn) ||\n is(schemaType, PgEnumObjectColumn) ||\n is(schemaType, MySqlEnumColumn) ||\n is(schemaType, MySqlEnumObjectColumn)\n );\n}\n\n// TODO make this compatible with other db drivers\ntype EnumTypes = PgEnum<any> | PgEnumObject<any>;\n\nexport type NonEnumFields<T> = {\n [K in keyof T as T[K] extends EnumTypes ? never : K]: T[K];\n};\n\n/**\n * Picks the keys of a schema object that are pgEnum definitions\n */\nexport type EnumFieldKeys<S> = keyof {\n [K in keyof S as S[K] extends EnumTypes ? K : never]: S[K];\n};\n\n/**\n * Fallback value tuple used whenever the concrete enum members cannot be\n * recovered from the drizzle types (e.g. an object-enum whose values were\n * widened to `string`, or a `tsName` that does not resolve against `Schema`).\n */\ntype UnknownEnumValues = readonly [string, ...string[]];\n\n/**\n * Extracts the literal value tuple carried by a drizzle enum definition.\n */\ntype EnumValuesOf<E> =\n E extends PgEnum<infer V>\n ? V\n : E extends PgEnumObject<infer O>\n ? ReadonlyArray<O[keyof O] & string>\n : UnknownEnumValues;\n\n/**\n * The GraphQL enum member union for a single `enum_(...)` call, resolved from\n * whichever of the three per-call generics the caller populated (`tsName` /\n * `enum` / `enumColumn`). The unused generics default to `never`, so\n * `[X] extends [never]` tells us which identification form was used.\n *\n * Anything we can't recover from the drizzle types (an object-enum widened to\n * `string`, or a `tsName` that doesn't resolve against `Schema`) falls back to\n * `string`, matching Pothos' own enum member type.\n */\ntype EnumMembers<Schema, TsName, EnumArg, EnumColumn> = [EnumColumn] extends [\n never,\n]\n ? [EnumArg] extends [never]\n ? [TsName] extends [never]\n ? string\n : TsName extends keyof Schema\n ? EnumValuesOf<Schema[TsName]>[number]\n : string\n : EnumValuesOf<EnumArg>[number]\n : EnumColumn extends { enumValues: infer CV extends UnknownEnumValues }\n ? CV[number]\n : string;\n\n/**\n * The strongly typed Pothos enum ref returned by a single `enum_(...)` call.\n *\n * Kept as a named, exported alias on purpose: the `.d.ts` emitter prints type\n * aliases by reference rather than expanding their bodies, so the (otherwise\n * very deep) `SchemaBuilder` / `EnumRef` types never get inlined into the\n * declaration output. Two details keep this printable without the emitter\n * recursing: referencing `SchemaBuilderType<...>` (a named alias) rather than\n * `typeof schemaBuilder` (a value), and inlining the member resolution so the\n * cyclic drizzle `Schema[TsName]` access never surfaces as its own symbol.\n */\nexport type EnumImplementationRef<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema,\n TsName,\n EnumArg,\n EnumColumn,\n> =\n SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n > extends PothosSchemaTypes.SchemaBuilder<infer Types>\n ? PothosSchemaTypes.EnumRef<\n Types,\n EnumMembers<Schema, TsName, EnumArg, EnumColumn>\n >\n : never;\n\nexport type EnumImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n AvailableEnums extends string,\n Schema extends Record<string, any> = Record<string, any>,\n> = ReturnType<\n typeof createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n AvailableEnums,\n Schema\n >\n>;\n\nexport const createEnumImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n AvailableEnums extends string,\n Schema extends Record<string, any> = Record<string, any>,\n>({\n schema,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const referenceStorage = new Map<string, any>();\n\n /**\n * Registers a Postgres enum as a GraphQL enum type.\n *\n * You can identify the enum in three ways:\n * - `tsName`: the exported TypeScript identifier from your schema module. This is the\n * most typesafe form, only valid enum keys autocomplete, typos are caught at compile time.\n * - `enum`: pass the pgEnum object directly.\n * - `enumColumn`: pass a column that uses the enum.\n *\n * Use `refName` to override the auto-generated GraphQL type name.\n */\n const enumImplementer = <\n TsName extends AvailableEnums = never,\n EnumArg extends PgEnum<any> | PgEnumObject<any> = never,\n EnumColumn extends Column = never,\n RefName extends string = string,\n >(\n args: {\n refName?: RefName;\n } & (\n | { tsName: TsName; enum?: never; enumColumn?: never }\n | { enum: EnumArg; tsName?: never; enumColumn?: never }\n | { enumColumn: EnumColumn; tsName?: never; enum?: never }\n ),\n ): EnumImplementationRef<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema,\n TsName,\n EnumArg,\n EnumColumn\n > => {\n const { refName } = args;\n const tsName = (args as { tsName?: string }).tsName;\n const enumObjectArg = (args as { enum?: PgEnum<any> | PgEnumObject<any> })\n .enum;\n const enumColumn = (args as { enumColumn?: Column }).enumColumn;\n\n let enumObject: PgEnum<any> | PgEnumObject<any> | undefined = enumObjectArg;\n\n if (tsName) {\n const candidate = (schema as Record<string, unknown>)[tsName];\n if (!candidate || !isPgEnum(candidate as any)) {\n throw new RumbleError(\n `Could not find a pgEnum exported as ${JSON.stringify(\n tsName,\n )} in the provided schema. ` +\n `Make sure the identifier exists and refers to a value created with \\`pgEnum(...)\\`.`,\n );\n }\n enumObject = candidate as PgEnum<any> | PgEnumObject<any>;\n }\n\n if (!enumObject && !enumColumn) {\n throw new RumbleError(\n `Could not determine enum structure! Pass one of 'tsName' (requires \\`schema\\` on rumble()), ` +\n `'enum' (the pgEnum object), or 'enumColumn' (a column that uses the enum).`,\n );\n }\n\n let enumSchemaName: string | undefined;\n let enumValues: any[] | undefined;\n\n if (enumObject) {\n enumSchemaName = enumObject.enumName;\n enumValues = enumObject.enumValues as unknown as any[];\n } else if (enumColumn) {\n // MySQL enum columns carry their values directly; there is no standalone\n // enum object. Derive a stable name from table + column name.\n if (\n is(enumColumn, MySqlEnumColumn) ||\n is(enumColumn, MySqlEnumObjectColumn)\n ) {\n enumValues = (enumColumn as any).enumValues as unknown as any[];\n const colTable = (enumColumn as any).table;\n const tableName =\n colTable && isTable(colTable) ? getTableName(colTable) : undefined;\n enumSchemaName = tableName\n ? `${tableName}_${enumColumn.name}`\n : enumColumn.name;\n } else {\n const pgEnum = (enumColumn as any).enum as\n | PgEnum<any>\n | PgEnumObject<any>\n | undefined;\n\n if (!pgEnum) {\n throw new RumbleError(\n `Could not find enum definition on column. Make sure the column is a pgEnum column.`,\n );\n }\n\n enumSchemaName = pgEnum.enumName;\n enumValues = enumColumn.enumValues as unknown as any[];\n }\n }\n\n if (!enumSchemaName || !enumValues) {\n throw new RumbleError(\"Could not determine enum structure!\");\n }\n\n const graphqlImplementationName =\n refName ?? `${capitalize(toCamelCase(enumSchemaName))}Enum`;\n\n // The runtime always produces a plain Pothos enum ref; the strong typing\n // lives entirely in the (explicit, named) return type, so we cast on the\n // way out. The named return alias is what keeps the `.d.ts` emitter from\n // recursing on the inlined SchemaBuilder/EnumRef types.\n type Ret = EnumImplementationRef<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema,\n TsName,\n EnumArg,\n EnumColumn\n >;\n\n const cached = referenceStorage.get(graphqlImplementationName);\n if (cached) {\n return cached as Ret;\n }\n\n const ret = schemaBuilder.enumType(graphqlImplementationName, {\n values: enumValues,\n });\n referenceStorage.set(graphqlImplementationName, ret);\n return ret as unknown as Ret;\n };\n\n return enumImplementer;\n};\n","import {\n isBigIntLikeSQLTypeString,\n isBooleanSQLTypeString,\n isBytesSQLTypeString,\n isDateLikeSQLTypeString,\n isDateTimeLikeSQLTypeString,\n isFloatLikeSQLTypeString,\n isIDLikeSQLTypeString,\n isIntLikeSQLTypeString,\n isJSONFallbackSQLTypeString,\n isJSONLikeSQLTypeString,\n isStringLikeSQLTypeString,\n normalizeSQLType,\n type PossibleSQLType,\n UnknownTypeRumbleError,\n} from \"./types\";\n\nexport type GraphQLTypeName =\n | \"Int\"\n | \"Float\"\n | \"String\"\n | \"ID\"\n | \"Boolean\"\n | \"DateTime\"\n | \"Date\"\n | \"JSON\"\n | \"BigInt\"\n | \"Bytes\";\n\nexport function mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n}: {\n sqlType: PossibleSQLType;\n fieldName?: string;\n}): GraphQLTypeName {\n // MySQL raw enum columns expose their values in the SQL type string.\n // Handle before normalization since normalization would strip the parens.\n if (/^enum\\(/.test(sqlType)) {\n return \"String\";\n }\n\n const normalized = normalizeSQLType(sqlType);\n\n let ret: GraphQLTypeName | undefined;\n\n if (isIntLikeSQLTypeString(normalized)) {\n ret = \"Int\";\n }\n\n if (isBigIntLikeSQLTypeString(normalized)) {\n ret = \"BigInt\";\n }\n\n if (isFloatLikeSQLTypeString(normalized)) {\n ret = \"Float\";\n }\n\n if (isStringLikeSQLTypeString(normalized)) {\n if (\n fieldName &&\n (fieldName.toLowerCase().endsWith(\"_id\") ||\n fieldName.toLowerCase().endsWith(\"id\"))\n ) {\n ret = \"ID\";\n } else {\n ret = \"String\";\n }\n }\n\n if (isIDLikeSQLTypeString(normalized)) {\n ret = \"ID\";\n }\n\n if (isBooleanSQLTypeString(normalized)) {\n ret = \"Boolean\";\n }\n\n if (isDateTimeLikeSQLTypeString(normalized)) {\n ret = \"DateTime\";\n }\n\n if (isDateLikeSQLTypeString(normalized)) {\n ret = \"Date\";\n }\n\n if (isJSONLikeSQLTypeString(normalized)) {\n ret = \"JSON\";\n }\n\n if (isJSONFallbackSQLTypeString(normalized)) {\n ret = \"JSON\";\n }\n\n if (isBytesSQLTypeString(normalized)) {\n ret = \"Bytes\";\n }\n\n if (ret !== undefined) {\n return ret;\n }\n\n throw UnknownTypeRumbleError(sqlType, \"SQL to GQL\");\n}\n","import { is } from \"drizzle-orm\";\nimport { toCamelCase } from \"drizzle-orm/casing\";\nimport { PgColumn } from \"drizzle-orm/pg-core\";\nimport { capitalize } from \"es-toolkit\";\nimport { type EnumImplementerType, isEnumSchema } from \"../enum\";\nimport { mapSQLTypeToGraphQLType } from \"../helpers/sqlTypes/mapSQLTypeToTSType\";\nimport type { PossibleSQLType } from \"../helpers/sqlTypes/types\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\n\n// TODO: in general, several of the filter methods should be more\n// restrictive in case of explicitly allowed columns\n// search, order and filter should be restricted to allowed cols\n// and should completely ignore other fields since one might be ably\n// to narrow down and guess the actual values behind forbidden columns by\n// using the provided args. This way one could guess, e.g. secrets which are forbidden by\n// the column abilitiy settings but will be respected in searches, etc.\n\nexport type WhereArgImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createWhereArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\nconst makeDefaultName = (dbName: string) =>\n `${capitalize(toCamelCase(dbName.toString()))}WhereInputArgument`;\n\nexport const createWhereArgImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n schemaBuilder,\n enumImplementer,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n enumImplementer: EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n any\n >;\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const referenceStorage = new Map<string, any>();\n const enumArrayWhereInputStorage = new Map<string, any>();\n const scalarArrayWhereInputStorage = new Map<string, any>();\n\n const scalarArrayWhereInputName = (gqlType: string) =>\n `${gqlType}ArrayWhereInputArgument`;\n\n const getScalarArrayWhereInput = (gqlType: string) => {\n const typeName = scalarArrayWhereInputName(gqlType);\n const existing = scalarArrayWhereInputStorage.get(typeName);\n if (existing) return existing;\n\n const ret = schemaBuilder.inputRef(typeName);\n scalarArrayWhereInputStorage.set(typeName, ret);\n\n ret.implement({\n fields: (t: any) => ({\n eq: t.field({ type: [gqlType], required: false }),\n ne: t.field({ type: [gqlType], required: false }),\n in: t.field({ type: [[gqlType]], required: false }),\n notIn: t.field({ type: [[gqlType]], required: false }),\n isNull: t.boolean({ required: false }),\n isNotNull: t.boolean({ required: false }),\n arrayOverlaps: t.field({ type: [gqlType], required: false }),\n arrayContained: t.field({ type: [gqlType], required: false }),\n arrayContains: t.field({ type: [gqlType], required: false }),\n AND: t.field({ type: [ret], required: false }),\n OR: t.field({ type: [ret], required: false }),\n NOT: t.field({ type: ret, required: false }),\n }),\n });\n\n return ret;\n };\n\n const getEnumArrayWhereInput = (enumImpl: any) => {\n const typeName = `${enumImpl.name}WhereInputArgument`;\n\n const existing = enumArrayWhereInputStorage.get(typeName);\n if (existing) {\n return existing;\n }\n\n const ret = schemaBuilder.inputRef(typeName);\n enumArrayWhereInputStorage.set(typeName, ret);\n\n ret.implement({\n fields: (t: any) => ({\n // the column holds an array, so eq/ne compare against a whole\n // array value and in/notIn against a list of array values\n eq: t.field({ type: [enumImpl], required: false }),\n ne: t.field({ type: [enumImpl], required: false }),\n in: t.field({ type: [[enumImpl]], required: false }),\n notIn: t.field({ type: [[enumImpl]], required: false }),\n isNull: t.boolean({ required: false }),\n isNotNull: t.boolean({ required: false }),\n arrayOverlaps: t.field({ type: [enumImpl], required: false }),\n arrayContained: t.field({ type: [enumImpl], required: false }),\n arrayContains: t.field({ type: [enumImpl], required: false }),\n AND: t.field({ type: [ret], required: false }),\n OR: t.field({ type: [ret], required: false }),\n NOT: t.field({ type: ret, required: false }),\n }),\n });\n\n return ret;\n };\n\n const whereArgImplementer = <\n TableName extends keyof DrizzleQueryFunction<DB>,\n RefName extends string,\n >({\n table,\n refName,\n dbName,\n }: Partial<{\n table: TableName;\n refName: RefName | undefined;\n dbName: string;\n }> &\n (\n | {\n table: TableName;\n }\n | {\n dbName: string;\n }\n )) => {\n const tableSchema = tableHelper({\n db,\n table: dbName ?? table!,\n });\n\n const inputTypeName = refName ?? makeDefaultName(tableSchema.tsName);\n\n const existing = referenceStorage.get(inputTypeName);\n if (existing) {\n return existing;\n }\n\n const ret = schemaBuilder.inputRef(inputTypeName);\n referenceStorage.set(inputTypeName, ret);\n\n ret.implement({\n fields: (t: any) => {\n const mapSQLTypeStringToInputPothosType = (\n sqlType: PossibleSQLType,\n fieldName: string,\n isArray: boolean,\n ) => {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n\n if (isArray) {\n return t.field({\n type: getScalarArrayWhereInput(gqlType),\n required: false,\n });\n }\n\n switch (gqlType) {\n case \"Int\":\n return t.field({\n type: \"IntWhereInputArgument\",\n required: false,\n });\n case \"BigInt\":\n return t.field({\n type: \"BigIntWhereInputArgument\",\n required: false,\n });\n case \"String\":\n return t.field({\n type: \"StringWhereInputArgument\",\n required: false,\n });\n case \"Boolean\":\n return t.field({\n type: \"BooleanWhereInputArgument\",\n required: false,\n });\n case \"Date\":\n return t.field({\n type: \"DateWhereInputArgument\",\n required: false,\n });\n case \"DateTime\":\n return t.field({\n type: \"DateTimeWhereInputArgument\",\n required: false,\n });\n case \"Float\":\n return t.field({\n type: \"FloatWhereInputArgument\",\n required: false,\n });\n case \"ID\":\n return t.field({\n type: \"IDWhereInputArgument\",\n required: false,\n });\n case \"JSON\":\n return t.field({\n type: \"JSONWhereInputArgument\",\n required: false,\n });\n case \"Bytes\":\n // No meaningful filter operators for byte columns — skip.\n return null;\n default:\n throw new RumbleError(\n `Unsupported argument type ${gqlType} for column ${sqlType}`,\n );\n }\n };\n const fields = Object.entries(tableSchema.columns).reduce(\n (acc, [key, value]) => {\n // GraphQL reserves names starting with \"__\" for introspection.\n if (key.startsWith(\"__\")) return acc;\n\n // Detect pg array columns via the `dimensions` runtime property.\n let isArray = false;\n if (is(value, PgColumn)) {\n const dims = (value as PgColumn & { dimensions?: number })\n .dimensions;\n if (dims && dims > 0) isArray = true;\n }\n\n if (isEnumSchema(value)) {\n const enumImpl = enumImplementer({\n enumColumn: value,\n });\n\n acc[key] = t.field({\n type: isArray ? getEnumArrayWhereInput(enumImpl) : enumImpl,\n required: false,\n });\n } else {\n const field = mapSQLTypeStringToInputPothosType(\n value.getSQLType() as PossibleSQLType,\n key,\n isArray,\n );\n if (field !== null) {\n acc[key] = field;\n }\n }\n\n return acc;\n },\n {} as Record<string, ReturnType<typeof t.field>>,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n // `targetTableName` is the publicly typed TS-key of the target\n // relation in db._.relations, prefer it over re-resolving via\n // the `targetTable` object.\n const targetTsName = (value as any).targetTableName as string;\n const relationSchema = tableHelper({\n db,\n table: targetTsName,\n });\n const referenceModel = whereArgImplementer({\n dbName: relationSchema.dbName,\n });\n\n acc[key] = t.field({\n type: referenceModel,\n required: false,\n });\n\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.columns,\n ReturnType<typeof mapSQLTypeStringToInputPothosType>\n >,\n );\n\n return {\n ...fields,\n ...relations,\n AND: t.field({ type: [ret], required: false }),\n OR: t.field({ type: [ret], required: false }),\n NOT: t.field({ type: ret, required: false }),\n };\n },\n });\n\n return ret;\n };\n\n return whereArgImplementer;\n};\n","import type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\nimport { generateFromSchema } from \"./generate/generate\";\n\nexport const clientCreatorImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n builtSchema,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n builtSchema: () => ReturnType<\n SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >[\"toSchema\"]\n >;\n}) => {\n const clientCreator = async ({\n apiUrl,\n outputPath,\n rumbleImportPath,\n useExternalUrqlClient,\n removeExisting,\n forceReactivity,\n autoIncludeIdField = false,\n }: {\n /**\n * Path to the output directory where the client files will be generated.\n */\n outputPath: string;\n /**\n * The base URL of the Rumble API.\n */\n apiUrl?: string;\n /**\n * The import path for the rumble library, defaults to \"@m1212e/rumble/client\".\n */\n rumbleImportPath?: string;\n /**\n * Set this to use an external urql client exported from a module.\n * If a string, uses the provided path to the urql client for importing the client.\n * If false, creates a new urql client with the provided apiUrl.\n */\n useExternalUrqlClient?: string;\n /**\n * Whether to remove existing generated files in the output directory before generating new ones.\n */\n removeExisting?: boolean;\n /**\n * Whether to force reactivity for generated queries and mutations. This will prevent the actual response fields of the awaited response from being populated\n * and requires you to subscribe to the response to access the data. Useful to prevent forgetting to subscribe to the response to utilize reactive data.\n */\n forceReactivity?: boolean;\n /**\n * Whether to automatically include the `id` field in generated queries and mutations.\n * This might be helpful to ensure that caching works correctly since all object will always be identifiable by their `id`.\n * Can be set to `true` to always include the `id` field, or to `false` to never include it.\n * Can also be set to a string to include a custom named field as Id field in case you have a different naming convention like `_id`.\n *\n * @default false\n */\n autoIncludeIdField?: boolean | string;\n }) => {\n if (process.env.NODE_ENV !== \"development\") {\n console.warn(\n `Running rumble client generation in non development mode. Are you sure this is correct? Called with arguments: ${JSON.stringify(\n {\n outputPath,\n apiUrl,\n rumbleImportPath,\n useExternalUrqlClient,\n removeExisting,\n },\n )}`,\n );\n }\n const schema = builtSchema();\n await generateFromSchema({\n schema,\n outputPath,\n rumbleImportPath,\n apiUrl,\n useExternalUrqlClient,\n removeExisting,\n forceReactivity,\n autoIncludeIdField,\n });\n };\n\n return clientCreator;\n};\n","import type { AbilityBuilderType } from \"./abilityBuilder\";\nimport { lazy } from \"./helpers/lazy\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\nexport type ContextFunctionType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createContextFunction<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\nexport type ContextType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = Awaited<\n ReturnType<\n ContextFunctionType<UserContext, DB, RequestEvent, Action, PothosConfig>\n >\n>;\n\nexport const createContextFunction = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n context: makeUserContext,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n abilityBuilder: AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const builtAbilityBuilder = lazy(() => abilityBuilder._.build());\n\n return async (req: RequestEvent) => {\n const userContext = makeUserContext\n ? await makeUserContext(req)\n : ({} as UserContext);\n\n return {\n ...userContext,\n abilities: builtAbilityBuilder()(userContext),\n };\n };\n};\n","export function deepSetProto(\n obj: any,\n proto = Object.prototype,\n seen = new WeakSet(),\n) {\n if (obj === null || typeof obj !== \"object\") return;\n if (seen.has(obj)) return;\n seen.add(obj);\n\n if (Array.isArray(obj)) {\n for (const item of obj) {\n deepSetProto(item, proto, seen);\n }\n return;\n }\n\n const currentProto = Object.getPrototypeOf(obj);\n if (currentProto !== Object.prototype && currentProto !== null) {\n return;\n }\n Object.setPrototypeOf(obj, proto);\n for (const key of Object.keys(obj)) {\n deepSetProto(obj[key], proto, seen);\n }\n}\n","import { count } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFirstEntryExists } from \"./helpers/asserts\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleErrorSafe } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\nexport const createCountQueryImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n>({\n db,\n schemaBuilder,\n whereArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig, Schema> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n whereArgImplementer: WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n makePubSubInstance: MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n return <TableName extends TableRelationNames<DB>>({\n table,\n listAction = \"read\" as Action,\n isAllowed,\n }: {\n /**\n * The table for which to implement the count query\n */\n table: TableName;\n /**\n * Which action should be used for listing many entities\n * @default \"read\"\n */\n listAction?: Action;\n /**\n * Optional function to check if the query is allowed\n */\n isAllowed?: (context: UserContext) => boolean | Promise<boolean>;\n }) => {\n const WhereArg = whereArgImplementer({\n table: table,\n });\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n const tableSchema = tableHelper({\n db,\n table,\n });\n\n return schemaBuilder.queryFields((t) => {\n return {\n [`${pluralize.plural(String(table))}Count`]: t.field({\n type: \"Int\",\n nullable: false,\n smartSubscription: true,\n description: `Count all ${pluralize.plural(String(table))}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: {\n where: t.arg({ type: WhereArg, required: false }),\n },\n resolve: async (_root, args, ctx, _info) => {\n if (isAllowed && !(await isAllowed(ctx))) {\n throw new RumbleErrorSafe(\"Not allowed to perform this action\");\n }\n\n deepSetProto(args);\n\n return (db as any)\n .select({ count: count() })\n .from(tableSchema.table)\n .where(\n ctx.abilities[table]\n .filter(listAction)\n .merge(mapNullFieldsToUndefined(args) as any).sql.where,\n )\n .then(assertFirstEntryExists)\n .then((r: any) => r.count);\n },\n }),\n };\n });\n };\n};\n","import type { useSofa } from \"@m1212e/sofa-api\";\n\nexport const sofaOpenAPIWebhookDocs: NonNullable<\n Parameters<typeof useSofa>[0][\"openAPI\"]\n> = {\n paths: {\n \"/webhook\": {\n post: {\n operationId: \"webhook_create\",\n description: \"Creates a webhook subscription.\",\n tags: [],\n parameters: [],\n requestBody: {\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookCreateBody\",\n },\n },\n },\n },\n responses: {\n \"200\": {\n description: \"\",\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookDetailResponse\",\n },\n },\n },\n },\n },\n },\n },\n \"/webhook/{id}\": {\n post: {\n operationId: \"webhook_update\",\n description: \"Updates a webhook subscription.\",\n parameters: [\n {\n name: \"id\",\n in: \"path\",\n description: \"The ID of the webhook to update\",\n required: true,\n schema: {\n type: \"string\",\n },\n } as any,\n ],\n requestBody: {\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookCreateBody\",\n },\n },\n },\n },\n responses: {\n \"200\": {\n description: \"\",\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookDetailResponse\",\n },\n },\n },\n },\n },\n },\n delete: {\n operationId: \"webhook_delete\",\n description: \"Removes a webhook subscription.\",\n tags: [],\n parameters: [\n {\n name: \"id\",\n in: \"path\",\n description: \"The ID of the webhook to delete\",\n required: true,\n schema: {\n type: \"string\",\n },\n } as any,\n ],\n responses: {\n \"200\": {\n description: \"\",\n content: {\n \"application/json\": {\n schema: {\n $ref: \"#/components/schemas/WebhookDetailResponse\",\n },\n },\n },\n },\n },\n },\n },\n },\n components: {\n schemas: {\n WebhookCreateBody: {\n type: \"object\",\n properties: {\n subscription: {\n description:\n \"The subscription to subscribe to. In many cases, these match the available query IDs without the '_query' suffix. E.g., 'users_query' -> 'users'. See the graphql schema for more details on what subscriptions are available.\",\n type: \"string\",\n },\n variables: {\n description: \"The variables to pass to the subscription.\",\n type: \"object\",\n },\n url: {\n description: \"The URL to send the webhook to.\",\n type: \"string\",\n },\n },\n },\n WebhookDetailResponse: {\n type: \"object\",\n properties: {\n id: {\n description:\n \"The ID of the webhook. Can be used as reference in update or delete calls.\",\n type: \"string\",\n },\n },\n },\n DateTime: {\n type: \"string\",\n format: \"date-time\",\n },\n Date: {\n type: \"string\",\n format: \"date\",\n },\n },\n },\n};\n","import type { Attributes, Span, SpanContext, Tracer } from \"@opentelemetry/api\";\nimport {\n execute as defaultExecute,\n subscribe as defaultSubscribe,\n type ExecutionArgs,\n type ExecutionResult,\n getOperationAST,\n print,\n} from \"graphql\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n RumbleLogger,\n} from \"../types/rumbleInput\";\nimport { errorLogField, errorsLogField } from \"./errorLogging\";\nimport {\n ATTR_DOCUMENT,\n ATTR_OPERATION_NAME,\n ATTR_OPERATION_TYPE,\n ATTR_SUBSCRIPTION_EVENT_INDEX,\n ATTR_TRANSPORT,\n durationMs,\n FIELD_DURATION_MS,\n FIELD_EVENT_COUNT,\n markErrorsReported,\n type RumbleTransport,\n recordSpanError,\n recordSpanErrors,\n SPAN_EXECUTE,\n SPAN_SUBSCRIBE,\n SPAN_SUBSCRIBE_EVENT,\n startTimer,\n type TelemetryConfig,\n telemetryEnabled,\n telemetryLogger,\n telemetryTracer,\n traceCorrelationFields,\n variableAttributes,\n variableLogField,\n} from \"./telemetry\";\n\nexport function isAsyncIterable(\n value: unknown,\n): value is AsyncIterable<unknown> {\n return (\n typeof value === \"object\" && value !== null && Symbol.asyncIterator in value\n );\n}\n\n/**\n * Everything the operation telemetry of a single execute/subscribe call needs.\n * Built once per operation so spans and logs cannot drift apart, and so the three\n * transports (GraphQL, SOFA REST, WebSocket) share one code path.\n */\ntype OperationTelemetry = {\n operationName: string;\n operationType?: string;\n /** Identical keys for spans and logs, minus the payload specific ones. */\n logFields: Record<string, unknown>;\n /** Only on the \"start\" entry, so variables are not repeated on every line. */\n variableLogFields: Record<string, unknown>;\n /** Lazy: printing the document and encoding variables is only worth it for otel. */\n attributes: () => Attributes;\n};\n\nfunction buildOperationTelemetry(\n config: TelemetryConfig,\n transport: RumbleTransport,\n options: ExecutionArgs,\n): OperationTelemetry {\n const operationAst = getOperationAST(options.document, options.operationName);\n const operationName =\n options.operationName ?? operationAst?.name?.value ?? \"anonymous\";\n const operationType = operationAst?.operation;\n\n const logFields = {\n [ATTR_OPERATION_NAME]: operationName,\n ...(operationType ? { [ATTR_OPERATION_TYPE]: operationType } : {}),\n [ATTR_TRANSPORT]: transport,\n };\n\n return {\n operationName,\n operationType,\n logFields,\n variableLogFields: variableLogField(\n options.variableValues,\n config.logger?.includeVariables,\n ),\n attributes: () => ({\n ...(logFields as Attributes),\n ...(config.otel?.includeDocument === false\n ? {}\n : { [ATTR_DOCUMENT]: print(options.document) }),\n ...variableAttributes(\n options.variableValues,\n config.otel?.includeVariables,\n ),\n }),\n };\n}\n\n/**\n * Wraps a subscription's event stream so delivered events are observable no\n * matter which transport consumes them.\n */\nexport async function* wrapSubscriptionIterator(\n iterator: AsyncIterable<ExecutionResult>,\n telemetry: {\n log?: RumbleLogger;\n tracer?: Tracer;\n setupSpanContext?: SpanContext;\n logFields: Record<string, unknown>;\n attributes: Attributes;\n },\n): AsyncGenerator<ExecutionResult> {\n const { log, tracer, setupSpanContext, logFields, attributes } = telemetry;\n\n const recordEventErrors = (\n eventCount: number,\n errors: readonly unknown[],\n ) => {\n if (!tracer) return;\n const span = tracer.startSpan(SPAN_SUBSCRIBE_EVENT, {\n root: true,\n links: setupSpanContext ? [{ context: setupSpanContext }] : undefined,\n attributes: {\n ...attributes,\n [ATTR_SUBSCRIPTION_EVENT_INDEX]: eventCount,\n },\n });\n recordSpanErrors(span, errors);\n span.end();\n };\n\n let eventCount = 0;\n try {\n for await (const event of iterator) {\n eventCount++;\n if (event.errors?.length) {\n log?.error(\n {\n ...logFields,\n [FIELD_EVENT_COUNT]: eventCount,\n ...errorsLogField(event.errors),\n },\n \"graphql subscription event error\",\n );\n recordEventErrors(eventCount, event.errors);\n }\n yield event;\n }\n log?.info(\n {\n ...logFields,\n [FIELD_EVENT_COUNT]: eventCount,\n },\n \"graphql subscription completed\",\n );\n } catch (error) {\n log?.error(\n {\n ...logFields,\n [FIELD_EVENT_COUNT]: eventCount,\n ...errorLogField(error),\n },\n \"graphql subscription threw\",\n );\n recordEventErrors(eventCount, [error]);\n throw error;\n }\n}\n\nexport function buildTracedExecute<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>(\n executeFn: (\n args: ExecutionArgs,\n ) => Promise<ExecutionResult> | ExecutionResult,\n rumbleInput: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>,\n transport: RumbleTransport,\n): (args: ExecutionArgs) => Promise<ExecutionResult> {\n if (!telemetryEnabled(rumbleInput)) {\n return executeFn as (args: ExecutionArgs) => Promise<ExecutionResult>;\n }\n\n return async (options: ExecutionArgs): Promise<ExecutionResult> => {\n const tracer = telemetryTracer(rumbleInput);\n let log = telemetryLogger(rumbleInput);\n const telemetry = buildOperationTelemetry(rumbleInput, transport, options);\n const start = startTimer();\n\n const run = async (span?: Span) => {\n log?.info(\n { ...telemetry.logFields, ...telemetry.variableLogFields },\n \"graphql execute start\",\n );\n\n try {\n const result = await executeFn(options);\n\n if (result && \"errors\" in result && result.errors?.length) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorsLogField(result.errors),\n },\n \"graphql execute completed with errors\",\n );\n recordSpanErrors(span, result.errors);\n markErrorsReported(result.errors);\n } else {\n log?.info(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n },\n \"graphql execute completed\",\n );\n }\n\n return result;\n } catch (error) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorLogField(error),\n },\n \"graphql execute threw\",\n );\n recordSpanError(span, error);\n markErrorsReported([error]);\n throw error;\n }\n };\n\n if (!tracer) return run();\n\n return tracer.startActiveSpan(\n SPAN_EXECUTE,\n { attributes: telemetry.attributes() },\n async (span: Span) => {\n if (log) {\n const correlation = traceCorrelationFields(rumbleInput, span);\n if (Object.keys(correlation).length > 0) {\n log = log.child(correlation);\n }\n }\n try {\n return await run(span);\n } finally {\n span.end();\n }\n },\n );\n };\n}\n\nexport function buildTracedSubscribe<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>(\n subscribeFn: (\n args: ExecutionArgs,\n ) =>\n | Promise<AsyncIterable<ExecutionResult> | ExecutionResult>\n | AsyncIterable<ExecutionResult>\n | ExecutionResult,\n rumbleInput: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>,\n transport: RumbleTransport,\n): (\n args: ExecutionArgs,\n) => Promise<AsyncIterable<ExecutionResult> | ExecutionResult> {\n if (!telemetryEnabled(rumbleInput)) {\n return subscribeFn as (\n args: ExecutionArgs,\n ) => Promise<AsyncIterable<ExecutionResult> | ExecutionResult>;\n }\n\n return async (\n options: ExecutionArgs,\n ): Promise<AsyncIterable<ExecutionResult> | ExecutionResult> => {\n const tracer = telemetryTracer(rumbleInput);\n let log = telemetryLogger(rumbleInput);\n const telemetry = buildOperationTelemetry(rumbleInput, transport, options);\n const start = startTimer();\n // Built once so the event spans carry the same attributes as the setup span.\n const attributes = tracer ? telemetry.attributes() : {};\n\n const doSubscribe = async (\n span?: Span,\n ): Promise<AsyncIterable<ExecutionResult> | ExecutionResult> => {\n log?.info(\n { ...telemetry.logFields, ...telemetry.variableLogFields },\n \"graphql subscribe start\",\n );\n\n try {\n const result = await subscribeFn(options);\n\n if (!isAsyncIterable(result)) {\n const execResult = result as ExecutionResult;\n if (execResult.errors?.length) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorsLogField(execResult.errors),\n },\n \"graphql subscribe completed with errors\",\n );\n recordSpanErrors(span, execResult.errors);\n markErrorsReported(execResult.errors);\n }\n return execResult;\n }\n\n log?.info(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n },\n \"graphql subscription established\",\n );\n\n return wrapSubscriptionIterator(\n result as AsyncIterable<ExecutionResult>,\n {\n log,\n tracer,\n setupSpanContext: span?.spanContext(),\n logFields: telemetry.logFields,\n attributes,\n },\n );\n } catch (error) {\n log?.error(\n {\n ...telemetry.logFields,\n [FIELD_DURATION_MS]: durationMs(start),\n ...errorLogField(error),\n },\n \"graphql subscribe threw\",\n );\n recordSpanError(span, error);\n markErrorsReported([error]);\n throw error;\n }\n };\n\n if (!tracer) return doSubscribe();\n\n return tracer.startActiveSpan(\n SPAN_SUBSCRIBE,\n { attributes },\n async (span: Span) => {\n if (log) {\n const correlation = traceCorrelationFields(rumbleInput, span);\n if (Object.keys(correlation).length > 0) {\n log = log.child(correlation);\n }\n }\n try {\n return await doSubscribe(span);\n } finally {\n // Ends after setup, not after the last event: a span kept open for the\n // lifetime of a subscription would never be exported in time.\n span.end();\n }\n },\n );\n };\n}\n\nexport { defaultExecute, defaultSubscribe };\n","import type { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { RumbleError } from \"../../types/rumbleError\";\nimport { mapSQLTypeToGraphQLType } from \"./mapSQLTypeToTSType\";\nimport type { PossibleSQLType } from \"./types\";\n\nexport function buildPothosResponseTypeFromGraphQLType<\n Builder extends DrizzleObjectFieldBuilder<any, any, any, any>,\n>({\n builder,\n sqlType,\n fieldName,\n nullable,\n isArray,\n}: {\n builder: Builder;\n sqlType: PossibleSQLType;\n fieldName: string;\n nullable: boolean;\n isArray: boolean;\n}) {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n switch (gqlType) {\n case \"Int\":\n return isArray\n ? builder.exposeIntList(fieldName, { nullable: nullable as any })\n : builder.exposeInt(fieldName, { nullable });\n case \"BigInt\":\n return builder.field({\n type: isArray ? [\"BigInt\"] : \"BigInt\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"String\":\n return isArray\n ? builder.exposeStringList(fieldName, { nullable: nullable as any })\n : builder.exposeString(fieldName, { nullable });\n case \"Boolean\":\n return isArray\n ? builder.exposeBooleanList(fieldName, { nullable: nullable as any })\n : builder.exposeBoolean(fieldName, { nullable });\n case \"Date\":\n return builder.field({\n type: isArray ? [\"Date\"] : \"Date\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"DateTime\":\n return builder.field({\n type: isArray ? [\"DateTime\"] : \"DateTime\",\n // Drizzle's timestamp({ mode: \"string\" }) returns a string; the\n // DateTimeISO scalar expects a Date object, so coerce when needed.\n resolve: (element: any) => {\n const v = element[fieldName];\n if (v == null) return v;\n return v instanceof Date ? v : new Date(v);\n },\n nullable,\n });\n case \"Float\":\n return isArray\n ? builder.exposeFloatList(fieldName, { nullable: nullable as any })\n : builder.exposeFloat(fieldName, { nullable });\n case \"ID\":\n return isArray\n ? builder.exposeIDList(fieldName, { nullable: nullable as any })\n : builder.exposeID(fieldName, { nullable });\n case \"JSON\":\n return builder.field({\n type: isArray ? [\"JSON\"] : \"JSON\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"Bytes\":\n return builder.field({\n type: \"Bytes\",\n resolve: (element: any) => {\n const v = element[fieldName];\n if (v == null) return v;\n return Buffer.isBuffer(v) ? v.toString(\"base64\") : String(v);\n },\n nullable,\n });\n default:\n throw new RumbleError(\n `Unsupported object type ${gqlType} for column ${fieldName}`,\n );\n }\n}\n","import { is } from \"drizzle-orm\";\nimport type { MySqlAsyncDatabase } from \"drizzle-orm/mysql-core\";\nimport { MySqlTable } from \"drizzle-orm/mysql-core\";\nimport type { PgAsyncDatabase } from \"drizzle-orm/pg-core\";\nimport { PgTable } from \"drizzle-orm/pg-core\";\nimport type { SQLiteAsyncDatabase } from \"drizzle-orm/sqlite-core\";\nimport { SQLiteTable } from \"drizzle-orm/sqlite-core\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\n\nexport type DBDialect = \"mysql\" | \"postgres\" | \"sqlite\";\n\nconst dialectCache = new WeakMap<object, DBDialect>();\n\nexport function determineDBDialectFromSchema<DB extends DrizzleInstance>(\n schema: DB[\"_\"][\"relations\"],\n): DBDialect {\n const cached = dialectCache.get(schema as unknown as object);\n if (cached) return cached;\n\n const found = new Set<DBDialect>();\n\n for (const table of Object.values(schema).map((t: any) => t.table)) {\n if (!table || typeof table !== \"object\") {\n continue;\n }\n\n // `is()` survives duplicate drizzle-orm copies in node_modules where\n // `instanceof` silently returns false against the \"wrong\" class identity.\n if (is(table, PgTable)) {\n found.add(\"postgres\");\n } else if (is(table, MySqlTable)) {\n found.add(\"mysql\");\n } else if (is(table, SQLiteTable)) {\n found.add(\"sqlite\");\n }\n }\n\n const dialects = Array.from(found);\n\n if (dialects.length === 1) {\n const only = dialects[0]!;\n dialectCache.set(schema as unknown as object, only);\n return only;\n }\n\n if (dialects.length === 0) {\n throw new Error(\"No tables found in schema, could not determine dialect\");\n }\n\n throw new Error(`Multiple dialects found in schema: ${dialects.join(\", \")}`);\n}\n\nexport function isPostgresDB<\n Narrowed extends PgAsyncDatabase<any, any> = PgAsyncDatabase<any, any>,\n>(db: any): db is Narrowed {\n return determineDBDialectFromSchema(db._.relations) === \"postgres\";\n}\n\nexport function isMySQLDB<\n Narrowed extends MySqlAsyncDatabase<any, any> = MySqlAsyncDatabase<any, any>,\n>(db: any): db is Narrowed {\n return determineDBDialectFromSchema(db._.relations) === \"mysql\";\n}\n\nexport function isSQLiteDB<\n Narrowed extends SQLiteAsyncDatabase<any, any, any> = SQLiteAsyncDatabase<\n any,\n any,\n any\n >,\n>(db: any): db is Narrowed {\n return determineDBDialectFromSchema(db._.relations) === \"sqlite\";\n}\n","import { sql } from \"drizzle-orm\";\nimport { cloneDeep } from \"es-toolkit\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\nimport { errorLogField } from \"./helpers/errorLogging\";\nimport {\n isIDLikeSQLTypeString,\n isStringLikeSQLTypeString,\n} from \"./helpers/sqlTypes/types\";\nimport type { tableHelper } from \"./helpers/tableHelpers\";\nimport type { RumbleInput } from \"./types/rumbleInput\";\n\nexport async function initSearchIfApplicable(\n input: RumbleInput<any, any, any, any, any, any>,\n) {\n const log = input.logger?.enabled ? input.logger.logger : undefined;\n\n if (!isPostgresDB(input.db)) {\n const msg =\n \"Database dialect is not compatible with search, skipping search initialization. Only PostgreSQL is supported.\";\n log ? log.info({}, msg) : console.info(msg);\n return;\n }\n\n try {\n await input.db.execute(sql`CREATE EXTENSION IF NOT EXISTS pg_trgm;`);\n } catch (error) {\n const msg =\n \"Failed to create pg_trgm extension. Search functionality may not work. Ensure the database user has CREATE privilege or the extension is pre-installed.\";\n log ? log.error(errorLogField(error), msg) : console.error(msg, error);\n return;\n }\n if (input.search?.threshold) {\n // make absolutely sure the threshold is a number\n const threshold = Number(input.search.threshold);\n\n if (threshold < 0 || threshold > 1) {\n throw new Error(`Search threshold must be between 0 and 1`);\n }\n\n const result = await input.db.execute(sql`SELECT current_database()`);\n const dbName = result.rows[0].current_database;\n\n try {\n await input.db.execute(\n sql.raw(\n `ALTER DATABASE ${dbName} SET pg_trgm.similarity_threshold = ${threshold};`,\n ),\n );\n } catch (error: any) {\n // XX000 = tuple concurrently updated: multiple workers racing to set the same\n // idempotent value at startup. Safe to ignore — one of them will win.\n if (error?.cause?.code !== \"XX000\" && error?.code !== \"XX000\")\n throw error;\n }\n }\n\n if (input.search?.cpu_operator_cost) {\n if (typeof input.search.cpu_operator_cost !== \"number\") {\n throw new Error(`CPU operator cost must be a number`);\n }\n\n if (input.search.cpu_operator_cost <= 0) {\n throw new Error(`CPU operator cost must be a positive number`);\n }\n }\n}\n\n/**\n * Performs adjustments to the query args to issue a full text search in case the\n * respective feature is enabled and a search term was provided.\n */\nexport function adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities,\n}: Pick<RumbleInput<any, any, any, any, any, any>, \"search\"> & {\n //TODO types\n args: any;\n tableSchema: ReturnType<typeof tableHelper>;\n //TODO types\n abilities: any;\n}) {\n if (search?.enabled && args.search && args.search.length > 0) {\n // this prevents columns beeing searched which are not accessible to the user\n // if the abilities defined the user not to be allowed to read something, we need\n // to prevent it from beeing included in the search since this could\n // leak information\n const columnsToSearch = (\n abilities.query.many.columns\n ? Object.entries(tableSchema.columns).filter(\n ([key]) => abilities.query.many.columns[key],\n )\n : Object.entries(tableSchema.columns)\n ).filter(\n ([_key, col]) =>\n isStringLikeSQLTypeString(col.getSQLType()) ||\n isIDLikeSQLTypeString(col.getSQLType()),\n );\n\n const searchParam = sql`${args.search}`;\n\n args.extras = {\n search_distance: (table: any) =>\n sql`${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`COALESCE((${table[key]}::TEXT <-> ${searchParam}), 1)`;\n }),\n sql.raw(\" + \"),\n )}`,\n };\n\n const originalOrderBy = cloneDeep(args.orderBy);\n (args as any).orderBy = (table: any) => {\n const argsOrderBySQL = sql.join(\n Object.entries(originalOrderBy ?? {}).map(([key, value]) => {\n // value is \"asc\" or \"desc\"\n if (value === \"asc\") {\n return sql`${table[key]} ASC`;\n } else if (value === \"desc\") {\n return sql`${table[key]} DESC`;\n } else {\n throw new Error(`Invalid value ${value} for orderBy`);\n }\n }),\n sql.raw(\", \"),\n );\n\n const searchSQL = sql`search_distance ASC`;\n\n const ret = originalOrderBy\n ? sql.join([argsOrderBySQL, searchSQL], sql.raw(\", \"))\n : searchSQL;\n\n return ret;\n };\n\n const originalWhere = cloneDeep(args.where);\n\n // this limits the search to the rows which at least match the threshold score\n (args as any).where = {\n AND: [\n originalWhere ?? {},\n {\n RAW: (table: any) =>\n sql`(${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`${table[key]} % ${searchParam}`;\n }),\n sql.raw(\" OR \"),\n )})`,\n },\n ],\n };\n }\n}\n","import type { FieldMap } from \"@pothos/core\";\nimport type { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { is, One } from \"drizzle-orm\";\nimport { PgColumn } from \"drizzle-orm/pg-core\";\nimport { capitalize } from \"es-toolkit\";\nimport pluralize from \"pluralize\";\nimport type { AbilityBuilderType } from \"./abilityBuilder\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { type EnumImplementerType, isEnumSchema } from \"./enum\";\nimport { buildPothosResponseTypeFromGraphQLType } from \"./helpers/sqlTypes/mapDrizzleTypeToGraphQlType\";\nimport type { PossibleSQLType } from \"./helpers/sqlTypes/types\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport {\n ATTR_TABLE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\n// TODO remove as many as any types as possible here\n\n//TODO this is a bit flaky, we should check if we can determine the config object more reliably\n//TODO maybe a plugin can place some marker field on these objects?\n// like this?\n// if (t instanceof DrizzleObjectOptions) {\n// return true;\n// }\n\nconst isProbablyAConfigObject = (t: any) => {\n if (typeof t !== \"object\") {\n return false;\n }\n\n if (\n Object.keys(t).some((k) =>\n [\n \"args\",\n \"nullable\",\n \"query\",\n \"subscribe\",\n \"description\",\n \"type\",\n \"resolve\",\n ].find((e) => e === k),\n )\n )\n return true;\n return false;\n};\n\nexport const createObjectImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n>({\n db,\n search,\n otel,\n logger: loggerConfig,\n schemaBuilder,\n makePubSubInstance,\n whereArgImplementer,\n orderArgImplementer,\n enumImplementer,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig, Schema> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n whereArgImplementer: WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n orderArgImplementer: OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n enumImplementer: EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n any\n >;\n makePubSubInstance: MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n abilityBuilder: AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n type SchemaBuilder = SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n /**\n * Schema construction warnings go through the configured logger when there is\n * one, so they end up in the same structured stream as everything else, and\n * fall back to the console otherwise.\n */\n const warn = (msg: string, fields: Record<string, unknown> = {}) => {\n const log = loggerConfig?.enabled ? loggerConfig.logger : undefined;\n if (log) {\n log.warn({ ...fields, ...traceCorrelationFields(telemetryConfig) }, msg);\n } else {\n console.warn(msg);\n }\n };\n return <TableName extends TableRelationNames<DB>, RefName extends string>({\n table,\n refName,\n readAction = \"read\" as Action,\n adjust,\n }: {\n /**\n * The table you want to be used as reference for the object creation.\n */\n table: TableName;\n /**\n * The name you want this object to have in your graphql schema.\n * Rumble will create a reasonable default if not specified.\n */\n refName?: RefName;\n /**\n * The action used for read access to the table.\n * Defaults to \"read\".\n */\n readAction?: Action;\n /**\n * A function which can be used to adjust the fields of the object.\n * You can extend the object by specifying fields that do not exist as\n * per your db schema, or overwrite existing fields with the same name.\n * In case you do overwrite, rumble will set proper nullability and\n * subscription properties if you do not specify them explicitly.\n */\n adjust?:\n | ((\n t: DrizzleObjectFieldBuilder<\n SchemaBuilder[\"$inferSchemaTypes\"],\n SchemaBuilder[\"$inferSchemaTypes\"][\"DrizzleRelations\"][TableName],\n DrizzleTableValueType<DB, TableName>\n >,\n ) => FieldMap)\n | undefined;\n }) => {\n const tableSchema = tableHelper({ db, table });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n warn(\n `Could not find primary key for ${String(table)}. Cannot register subscriptions!`,\n { [ATTR_TABLE]: String(table) },\n );\n }\n const primaryKey = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n return schemaBuilder.drizzleObject(table, {\n name: refName ?? capitalize(String(table)),\n subscribe: (subscriptions, element, _context) => {\n if (!primaryKey) return;\n const primaryKeyValue = (element as any)[primaryKey.name];\n if (!primaryKeyValue) {\n warn(\n `Could not find primary key value for element on ${String(table)}. Cannot register subscription!`,\n { [ATTR_TABLE]: String(table) },\n );\n return;\n }\n\n //TODO maybe register non specific update calls aswell?\n registerOnInstance({\n instance: subscriptions,\n action: \"updated\",\n primaryKeyValue: primaryKeyValue,\n });\n },\n applyFilters: abilityBuilder?._.registeredFilters({\n table,\n action: readAction,\n }),\n fields: (t) => {\n const columns = tableSchema.columns;\n\n // in case the user makes adjustments we want to store away which\n // pothos function was called with what config\n // this is mapped to the ref which later can be used to\n // reference these parameters while iterating over the fields\n // and checking against the userAdjustments object\n // this is necessary to e.g. merge nullability info from the database schema\n // or register subscriptions on relations\n const configMap = new Map<\n any,\n {\n creatorFunction: (...p: any[]) => any;\n params: any[];\n configObject: any;\n }\n >();\n // stores the results of the user adjustments\n // also stores all the used pothos functions and the configs\n // provided by the user so we can extend that if necessary\n const userAdjustments =\n adjust?.(\n new Proxy(t, {\n get: (target, prop, _receiver) => {\n if (\n // we only care for field/relation functions\n typeof (target as any)[prop] !== \"function\" ||\n prop === \"arg\" ||\n prop === \"builder\" ||\n prop === \"graphqlKind\" ||\n prop === \"kind\" ||\n prop === \"listRef\" ||\n prop === \"table\" ||\n prop === \"typename\" ||\n prop === \"variant\" ||\n prop.toString().startsWith(\"boolean\") ||\n prop.toString().startsWith(\"float\") ||\n prop.toString().startsWith(\"id\") ||\n prop.toString().startsWith(\"int\") ||\n prop.toString().startsWith(\"string\") ||\n prop.toString().startsWith(\"expose\")\n ) {\n return (target as any)[prop];\n }\n\n return (...params: any[]) => {\n const ref = (target as any)[prop](...params);\n const configObject = params.find(isProbablyAConfigObject);\n if (!configObject)\n throw new RumbleError(\n \"Expected config object to be passed to adjust field\",\n );\n\n configMap.set(ref, {\n params,\n creatorFunction: (target as any)[prop],\n configObject,\n });\n return ref;\n };\n },\n }) as any,\n ) ?? {};\n\n const fields = Object.entries(columns).reduce(\n (acc, [key, column]) => {\n // GraphQL reserves all names beginning with \"__\" for introspection.\n // Skip such columns silently — the user must expose them manually\n // via `adjust` if they truly need them.\n if (key.startsWith(\"__\")) {\n warn(\n `Skipping column \"${key}\" on table \"${tableSchema.tsName}\": names starting with \"__\" are reserved by GraphQL introspection. Use a custom adjust() call if you really need to expose this column.`,\n { [ATTR_TABLE]: tableSchema.tsName },\n );\n return acc;\n }\n\n // in case the user wants to overwrite a field\n // we want to merge with our stuff in case the user\n // did not specify it themselves\n if (userAdjustments[key]) {\n const { params, creatorFunction, configObject } = configMap.get(\n userAdjustments[key],\n )!;\n\n if (typeof configObject.nullable !== \"boolean\") {\n configObject.nullable = !column.notNull;\n }\n\n userAdjustments[key] = creatorFunction.bind(t)(...params);\n return acc;\n }\n\n // Array columns only exist on Postgres; `dimensions` is a runtime\n // property of PgColumn instances. Gate via is() so MySQL/SQLite\n // columns aren't probed for a field they don't have.\n let isArray = false;\n if (is(column, PgColumn)) {\n const dimensions = (column as PgColumn & { dimensions?: number })\n .dimensions;\n if (dimensions && dimensions > 0) {\n if (dimensions !== 1) {\n throw new RumbleError(\n \"Only one-dimensional arrays are supported for default object implementation\",\n );\n }\n isArray = true;\n }\n }\n\n if (isEnumSchema(column)) {\n const enumImpl = enumImplementer({\n enumColumn: column,\n });\n\n acc[key] = t.field({\n type: isArray ? [enumImpl] : enumImpl,\n resolve: (element) => (element as any)[key],\n nullable: !column.notNull,\n });\n } else {\n acc[key] = buildPothosResponseTypeFromGraphQLType({\n builder: t,\n sqlType: column.getSQLType() as PossibleSQLType,\n fieldName: key,\n nullable: !column.notNull,\n isArray,\n });\n }\n return acc;\n },\n {} as Record<\n keyof typeof columns,\n | ReturnType<typeof buildPothosResponseTypeFromGraphQLType>\n | ReturnType<typeof t.field>\n >,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n const targetTsName = (value as any).targetTableName as string;\n const relationSchema = tableHelper({\n db,\n table: targetTsName,\n });\n const WhereArg = whereArgImplementer({\n dbName: relationSchema.dbName,\n });\n const OrderArg = orderArgImplementer({\n dbName: relationSchema.dbName,\n });\n const relationTablePubSub = makePubSubInstance({\n table: relationSchema.tsName as any,\n });\n\n // many relations will return an empty array so we just don't set them nullable\n let nullable = false;\n let isMany = true;\n let filterSpecifier = \"many\";\n if (is(value, One)) {\n isMany = false;\n nullable =\n value.optional ||\n !value.sourceColumns.every((column) => column.notNull);\n filterSpecifier = \"single\";\n }\n\n const subscribe = (subscriptions: any, _element: any) => {\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n };\n\n // in case the user wants to overwrite a field\n // we want to merge with our stuff in case the user\n // did not specify it themselves\n if (userAdjustments[key]) {\n const { params, creatorFunction, configObject } = configMap.get(\n userAdjustments[key],\n )!;\n\n if (typeof configObject.nullable !== \"boolean\") {\n configObject.nullable = nullable;\n }\n\n if (typeof configObject.subscribe !== \"function\") {\n configObject.subscribe = subscribe;\n }\n\n userAdjustments[key] = creatorFunction.bind(t)(...params);\n return acc;\n }\n\n const args = {\n where: t.arg({ type: WhereArg, required: false }),\n orderBy: t.arg({ type: OrderArg, required: false }),\n ...(isMany\n ? {\n offset: t.arg.int({ required: false }),\n limit: t.arg.int({ required: false }),\n }\n : {}),\n search: t.arg.string({ required: false }),\n };\n\n if (!search?.enabled || !isMany) {\n delete (args as any).search;\n }\n\n (acc as any)[key] = t.relation(\n key as any,\n {\n args,\n subscribe,\n nullable,\n description: `Get the ${pluralize.plural(relationSchema.tsName)} related to this ${pluralize.singular(tableSchema.tsName)}`,\n query: (args: any, ctx: any) => {\n // transform null prototyped object\n args = JSON.parse(JSON.stringify(args));\n\n if (isMany) {\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema: relationSchema,\n abilities:\n ctx.abilities[relationSchema.tsName].filter(readAction),\n });\n }\n\n const filter = ctx.abilities[relationSchema.tsName]\n .filter(readAction)\n .merge({\n where: args.where,\n limit: args.limit,\n extras: args.extras,\n }).query[filterSpecifier];\n\n if (args.offset) {\n (filter as any).offset = args.offset;\n }\n\n if (args.orderBy) {\n (filter as any).orderBy = args.orderBy;\n }\n\n return filter;\n },\n } as any,\n ) as any;\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.relations,\n ReturnType<typeof buildPothosResponseTypeFromGraphQLType>\n >,\n );\n\n if (search?.enabled) {\n if (fields.search_distance) {\n throw new Error(\n \"Reserved field name 'search_distance' found on \" +\n tableSchema.tsName +\n \". If search is enabled, the 'search_distance' field is automatically added and cannot be defined manually.\",\n );\n }\n\n fields.search_distance = t.float({\n description:\n \"The search distance of the object. If a search is provided, this field will be populated with the search distance.\",\n nullable: true,\n resolve: (parent, _args, _ctx, _info) =>\n (parent as any).search_distance,\n });\n }\n\n return {\n ...fields,\n ...relations,\n ...userAdjustments,\n };\n },\n });\n };\n};\n","import { createPubSub } from \"graphql-yoga\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\ntype PubSubAction = \"created\" | \"removed\" | \"updated\";\n\nconst SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX = \"RUMBLE_SUBSCRIPTION_NOTIFICATION\";\nconst SUBSCRIPTION_NOTIFIER_REMOVED = \"REMOVED\";\nconst SUBSCRIPTION_NOTIFIER_UPDATED = \"UPDATED\";\nconst SUBSCRIPTION_NOTIFIER_CREATED = \"CREATED\";\n\nexport type MakePubSubInstanceType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>[\"makePubSubInstance\"];\n\nexport const createPubSubInstance = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n subscriptions,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n const pubsub = subscriptions\n ? createPubSub(...subscriptions)\n : createPubSub();\n\n const makePubSubInstance = <\n TableName extends keyof DrizzleQueryFunction<DB>,\n >({\n table,\n }: {\n table: TableName;\n }) => {\n type PrimaryKeyType = any;\n\n function makePubSubKey({\n action,\n tableName,\n primaryKeyValue,\n }: {\n tableName: string;\n action: PubSubAction;\n primaryKeyValue?: PrimaryKeyType;\n }) {\n let actionKey: string;\n\n switch (action) {\n case \"created\":\n actionKey = SUBSCRIPTION_NOTIFIER_CREATED;\n break;\n case \"removed\":\n actionKey = SUBSCRIPTION_NOTIFIER_REMOVED;\n break;\n case \"updated\":\n actionKey = SUBSCRIPTION_NOTIFIER_UPDATED;\n break;\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n\n return `${SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX}/${tableName}${\n primaryKeyValue ? `/${primaryKeyValue}` : \"\"\n }/${actionKey}`;\n }\n\n // TODO does caching these make sense?\n return {\n /**\n * Call this when you want to register a subscription on an instance to this table\n */\n registerOnInstance({\n instance,\n action,\n primaryKeyValue,\n }: {\n instance: { register: (id: string) => void };\n action: PubSubAction;\n primaryKeyValue?: string;\n }) {\n const key = makePubSubKey({\n tableName: table.toString(),\n action,\n primaryKeyValue,\n });\n instance.register(key);\n },\n /**\n * Call this when you created an entity of this table\n */\n created() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"created\",\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you removed one or more entities of this table\n */\n // removed(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n removed() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"removed\",\n //TODO would it make sense to use specific sub topics here?\n // primaryKeyValue,\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you updated one or more entities of this table\n */\n updated(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n const primaryKeys = Array.isArray(primaryKeyValue)\n ? primaryKeyValue\n : [primaryKeyValue];\n const keys = primaryKeys.map((primaryKeyValue) =>\n makePubSubKey({\n tableName: table.toString(),\n action: \"updated\",\n primaryKeyValue,\n }),\n );\n const uniqueKeys = Array.from(new Set(keys));\n for (const key of uniqueKeys) {\n pubsub.publish(key);\n }\n },\n };\n };\n\n return {\n pubsub,\n makePubSubInstance,\n };\n};\n","import { sql } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFindFirstExists } from \"./helpers/asserts\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport {\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n TableRelationNames,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\nimport type { SchemaBuilderType } from \"./types/schemaBuilderType\";\n\nexport const createQueryImplementer = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n>({\n db,\n schemaBuilder,\n search,\n otel,\n logger: loggerConfig,\n whereArgImplementer,\n orderArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig, Schema> & {\n schemaBuilder: SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n whereArgImplementer: WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n orderArgImplementer: OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n makePubSubInstance: MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const registeredQueryFieldNames = new Set<string>();\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n\n return <TableName extends TableRelationNames<DB>>({\n table,\n readAction = \"read\" as Action,\n listAction = \"read\" as Action,\n findFirst,\n findMany,\n }: {\n /**\n * The table for which to implement the query\n */\n table: TableName;\n /**\n * Which action should be used for reading single entities\n * @default \"read\"\n */\n readAction?: Action;\n /**\n * Which action should be used for listing many entities\n * @default \"read\"\n */\n listAction?: Action;\n\n findMany?: (p: {\n tx: DB | Parameters<Parameters<DB[\"transaction\"]>[0]>[0];\n filter: Parameters<DrizzleQueryFunction<DB>[TableName][\"findMany\"]>[0];\n queryArgs: Parameters<DrizzleQueryFunction<DB>[TableName][\"findMany\"]>[0];\n }) => ReturnType<DrizzleQueryFunction<DB>[TableName][\"findMany\"]>;\n\n findFirst?: (p: {\n tx: DB;\n filter: Parameters<DrizzleQueryFunction<DB>[TableName][\"findFirst\"]>[0];\n queryArgs: Parameters<\n DrizzleQueryFunction<DB>[TableName][\"findFirst\"]\n >[0];\n }) => ReturnType<DrizzleQueryFunction<DB>[TableName][\"findFirst\"]>;\n }) => {\n const WhereArg = whereArgImplementer({\n table: table,\n });\n const OrderArg = orderArgImplementer({\n table: table,\n });\n const tableSchema = tableHelper({\n db,\n table,\n });\n const primaryKeyField = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n const pluralName = pluralize.plural(String(table));\n const singularName = pluralize.singular(String(table));\n for (const name of [pluralName, singularName]) {\n if (registeredQueryFieldNames.has(name)) {\n throw new RumbleError(\n `Duplicate query field \"${name}\": the table \"${String(table)}\" generates a ` +\n `query field that collides with one already registered. Use unique table names ` +\n `(or refNames) to avoid plural/singular collisions (e.g. \"post\" and \"posts\").`,\n );\n }\n registeredQueryFieldNames.add(name);\n }\n\n return schemaBuilder.queryFields((t) => {\n const manyArgs = {\n where: t.arg({ type: WhereArg, required: false }),\n orderBy: t.arg({ type: OrderArg, required: false }),\n limit: t.arg.int({ required: false }),\n offset: t.arg.int({ required: false }),\n search: t.arg.string({ required: false }),\n };\n\n if (!search?.enabled) {\n delete (manyArgs as any).search;\n }\n\n return {\n [pluralName]: t.drizzleField({\n type: [table],\n nullable: false,\n smartSubscription: true,\n description: `List all ${pluralName}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: manyArgs,\n resolve: (query, _root, args, ctx, _info) => {\n // args does not have Object.prototype as prototype, so we need to set it\n // otherwise some libraries (like drizzle-orm) might have issues with it\n deepSetProto(args);\n\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities: ctx.abilities[table].filter(listAction),\n });\n\n const mappedArgs = mapNullFieldsToUndefined(args);\n const filter = ctx.abilities[table]\n .filter(listAction)\n .merge(mappedArgs as any).query.many;\n\n if (mappedArgs.offset) {\n (filter as any).offset = mappedArgs.offset;\n }\n\n if (mappedArgs.orderBy) {\n (filter as any).orderBy = mappedArgs.orderBy;\n }\n\n const queryArgs = query(filter as any);\n\n if ((filter as any).columns) {\n queryArgs.columns = (filter as any).columns;\n }\n\n const run = findMany\n ? (tx: DB) => findMany({ tx, filter: filter as any, queryArgs })\n : (tx: any) => (tx.query as any)[table].findMany(queryArgs);\n\n if (\n search?.enabled &&\n args.search &&\n args.search.length > 0 &&\n search?.cpu_operator_cost\n ) {\n return db.transaction(async (tx: any) => {\n if (isPostgresDB(tx)) {\n await tx.execute(\n sql.raw(\n `SET cpu_operator_cost = ${search.cpu_operator_cost};`,\n ),\n );\n } else {\n const msg =\n \"Database dialect is not postgresql, cannot set cpu_operator_cost.\";\n const log = loggerConfig?.enabled\n ? loggerConfig.logger\n : undefined;\n log\n ? log.info(traceCorrelationFields(telemetryConfig), msg)\n : console.info(msg);\n }\n\n return run(tx);\n });\n }\n\n return run(db);\n },\n }),\n [singularName]: t.drizzleField({\n type: table,\n nullable: false,\n smartSubscription: true,\n description: `Get a single ${singularName} by ID`,\n args: {\n id: t.arg.id({ required: true }),\n },\n resolve: (query, _root, args, ctx, _info) => {\n deepSetProto(args);\n\n const filter = (ctx.abilities as any)[table]\n .filter(readAction)\n .merge({ where: { [primaryKeyField.name]: args.id } })\n .query.single;\n const queryArgs = query(filter);\n\n if (filter.columns) {\n queryArgs.columns = filter.columns;\n }\n\n return findFirst\n ? findFirst({ tx: db, filter: filter as any, queryArgs })\n : (db.query as any)[table]\n .findFirst(queryArgs)\n .then(assertFindFirstExists);\n },\n }),\n };\n });\n };\n};\n","export type NumberWhereInputArgument = {\n eq?: number;\n ne?: number;\n gt?: number;\n gte?: number;\n lt?: number;\n lte?: number;\n in?: number[];\n notIn?: number[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: number[];\n arrayContained?: number[];\n arrayContains?: number[];\n AND?: NumberWhereInputArgument[];\n OR?: NumberWhereInputArgument[];\n NOT?: NumberWhereInputArgument;\n};\n\nexport type StringWhereInputArgument = {\n eq?: string;\n ne?: string;\n gt?: string;\n gte?: string;\n lt?: string;\n lte?: string;\n in?: string[];\n notIn?: string[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: string[];\n arrayContained?: string[];\n arrayContains?: string[];\n AND?: StringWhereInputArgument[];\n OR?: StringWhereInputArgument[];\n NOT?: StringWhereInputArgument;\n};\n\nexport type DateWhereInputArgument = {\n eq?: Date;\n ne?: Date;\n gt?: Date;\n gte?: Date;\n lt?: Date;\n lte?: Date;\n in?: Date[];\n notIn?: Date[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: Date[];\n arrayContained?: Date[];\n arrayContains?: Date[];\n AND?: DateWhereInputArgument[];\n OR?: DateWhereInputArgument[];\n NOT?: DateWhereInputArgument;\n};\n\nexport type BooleanWhereInputArgument = {\n eq?: boolean;\n ne?: boolean;\n in?: boolean[];\n notIn?: boolean[];\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: boolean[];\n arrayContained?: boolean[];\n arrayContains?: boolean[];\n AND?: BooleanWhereInputArgument[];\n OR?: BooleanWhereInputArgument[];\n NOT?: BooleanWhereInputArgument;\n};\n\nexport type IDWhereInputArgument = {\n eq?: string;\n ne?: string;\n gt?: string;\n gte?: string;\n lt?: string;\n lte?: string;\n in?: string[];\n notIn?: string[];\n like?: string;\n ilike?: string;\n notLike?: string;\n notIlike?: string;\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: string[];\n arrayContained?: string[];\n arrayContains?: string[];\n AND?: IDWhereInputArgument[];\n OR?: IDWhereInputArgument[];\n NOT?: IDWhereInputArgument;\n};\n\nexport type JSONWhereInputArgument = {\n eq?: unknown;\n ne?: unknown;\n in?: unknown[];\n notIn?: unknown[];\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: unknown[];\n arrayContained?: unknown[];\n arrayContains?: unknown[];\n AND?: JSONWhereInputArgument[];\n OR?: JSONWhereInputArgument[];\n NOT?: JSONWhereInputArgument;\n};\n\nexport type BigIntWhereInputArgument = {\n eq?: bigint | number;\n ne?: bigint | number;\n gt?: bigint | number;\n gte?: bigint | number;\n lt?: bigint | number;\n lte?: bigint | number;\n in?: (bigint | number)[];\n notIn?: (bigint | number)[];\n isNull?: boolean;\n isNotNull?: boolean;\n AND?: BigIntWhereInputArgument[];\n OR?: BigIntWhereInputArgument[];\n NOT?: BigIntWhereInputArgument;\n};\n\nexport type DateTimeWhereInputArgument = {\n eq?: Date;\n ne?: Date;\n gt?: Date;\n gte?: Date;\n lt?: Date;\n lte?: Date;\n in?: Date[];\n notIn?: Date[];\n isNull?: boolean;\n isNotNull?: boolean;\n arrayOverlaps?: Date[];\n arrayContained?: Date[];\n arrayContains?: Date[];\n AND?: DateTimeWhereInputArgument[];\n OR?: DateTimeWhereInputArgument[];\n NOT?: DateTimeWhereInputArgument;\n};\n\n// TODO: Add proper type for schemaBuilder\n\nexport function implementDefaultWhereInputArgs(schemaBuilder: any) {\n const IntWhereInputArgument = schemaBuilder\n .inputRef(\"IntWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.int(),\n ne: t.int(),\n gt: t.int(),\n gte: t.int(),\n lt: t.int(),\n lte: t.int(),\n in: t.intList(),\n notIn: t.intList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.intList(),\n arrayContained: t.intList(),\n arrayContains: t.intList(),\n AND: t.field({\n type: [IntWhereInputArgument],\n }),\n OR: t.field({\n type: [IntWhereInputArgument],\n }),\n NOT: t.field({\n type: IntWhereInputArgument,\n }),\n }),\n });\n\n const FloatWhereInputArgument = schemaBuilder\n .inputRef(\"FloatWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.float(),\n ne: t.float(),\n gt: t.float(),\n gte: t.float(),\n lt: t.float(),\n lte: t.float(),\n in: t.floatList(),\n notIn: t.floatList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.floatList(),\n arrayContained: t.floatList(),\n arrayContains: t.floatList(),\n AND: t.field({\n type: [FloatWhereInputArgument],\n }),\n OR: t.field({\n type: [FloatWhereInputArgument],\n }),\n NOT: t.field({\n type: FloatWhereInputArgument,\n }),\n }),\n });\n\n const StringWhereInputArgument = schemaBuilder\n .inputRef(\"StringWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.string(),\n ne: t.string(),\n gt: t.string(),\n gte: t.string(),\n lt: t.string(),\n lte: t.string(),\n in: t.stringList(),\n notIn: t.stringList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.stringList(),\n arrayContained: t.stringList(),\n arrayContains: t.stringList(),\n AND: t.field({\n type: [StringWhereInputArgument],\n }),\n OR: t.field({\n type: [StringWhereInputArgument],\n }),\n NOT: t.field({\n type: StringWhereInputArgument,\n }),\n }),\n });\n\n const DateWhereInputArgument = schemaBuilder\n .inputRef(\"DateWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"Date\" }),\n ne: t.field({ type: \"Date\" }),\n gt: t.field({ type: \"Date\" }),\n gte: t.field({ type: \"Date\" }),\n lt: t.field({ type: \"Date\" }),\n lte: t.field({ type: \"Date\" }),\n in: t.field({ type: [\"Date\"] }),\n notIn: t.field({ type: [\"Date\"] }),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.field({ type: [\"Date\"] }),\n arrayContained: t.field({ type: [\"Date\"] }),\n arrayContains: t.field({ type: [\"Date\"] }),\n AND: t.field({\n type: [DateWhereInputArgument],\n }),\n OR: t.field({\n type: [DateWhereInputArgument],\n }),\n NOT: t.field({\n type: DateWhereInputArgument,\n }),\n }),\n });\n\n const BooleanWhereInputArgument = schemaBuilder\n .inputRef(\"BooleanWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.boolean(),\n ne: t.boolean(),\n in: t.booleanList(),\n notIn: t.booleanList(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.booleanList(),\n arrayContained: t.booleanList(),\n arrayContains: t.booleanList(),\n AND: t.field({\n type: [BooleanWhereInputArgument],\n }),\n OR: t.field({\n type: [BooleanWhereInputArgument],\n }),\n NOT: t.field({\n type: BooleanWhereInputArgument,\n }),\n }),\n });\n\n const IDWhereInputArgument = schemaBuilder\n .inputRef(\"IDWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.id(),\n ne: t.id(),\n gt: t.id(),\n gte: t.id(),\n lt: t.id(),\n lte: t.id(),\n in: t.idList(),\n notIn: t.idList(),\n like: t.string(),\n ilike: t.string(),\n notLike: t.string(),\n notIlike: t.string(),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.idList(),\n arrayContained: t.idList(),\n arrayContains: t.idList(),\n AND: t.field({\n type: [IDWhereInputArgument],\n }),\n OR: t.field({\n type: [IDWhereInputArgument],\n }),\n NOT: t.field({\n type: IDWhereInputArgument,\n }),\n }),\n });\n\n const JSONWhereInputArgument = schemaBuilder\n .inputRef(\"JSONWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"JSON\", required: false }),\n ne: t.field({ type: \"JSON\", required: false }),\n in: t.field({ type: [\"JSON\"], required: false }),\n notIn: t.field({ type: [\"JSON\"], required: false }),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.field({ type: [\"JSON\"], required: false }),\n arrayContained: t.field({ type: [\"JSON\"], required: false }),\n arrayContains: t.field({ type: [\"JSON\"], required: false }),\n AND: t.field({\n type: [JSONWhereInputArgument],\n }),\n OR: t.field({\n type: [JSONWhereInputArgument],\n }),\n NOT: t.field({\n type: JSONWhereInputArgument,\n }),\n }),\n });\n\n const BigIntWhereInputArgument = schemaBuilder\n .inputRef(\"BigIntWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"BigInt\", required: false }),\n ne: t.field({ type: \"BigInt\", required: false }),\n gt: t.field({ type: \"BigInt\", required: false }),\n gte: t.field({ type: \"BigInt\", required: false }),\n lt: t.field({ type: \"BigInt\", required: false }),\n lte: t.field({ type: \"BigInt\", required: false }),\n in: t.field({ type: [\"BigInt\"], required: false }),\n notIn: t.field({ type: [\"BigInt\"], required: false }),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n AND: t.field({ type: [BigIntWhereInputArgument] }),\n OR: t.field({ type: [BigIntWhereInputArgument] }),\n NOT: t.field({ type: BigIntWhereInputArgument }),\n }),\n });\n\n const DateTimeWhereInputArgument = schemaBuilder\n .inputRef(\"DateTimeWhereInputArgument\")\n .implement({\n fields: (t: any) => ({\n eq: t.field({ type: \"DateTime\", required: false }),\n ne: t.field({ type: \"DateTime\", required: false }),\n gt: t.field({ type: \"DateTime\", required: false }),\n gte: t.field({ type: \"DateTime\", required: false }),\n lt: t.field({ type: \"DateTime\", required: false }),\n lte: t.field({ type: \"DateTime\", required: false }),\n in: t.field({ type: [\"DateTime\"], required: false }),\n notIn: t.field({ type: [\"DateTime\"], required: false }),\n isNull: t.boolean(),\n isNotNull: t.boolean(),\n arrayOverlaps: t.field({ type: [\"DateTime\"], required: false }),\n arrayContained: t.field({ type: [\"DateTime\"], required: false }),\n arrayContains: t.field({ type: [\"DateTime\"], required: false }),\n AND: t.field({ type: [DateTimeWhereInputArgument] }),\n OR: t.field({ type: [DateTimeWhereInputArgument] }),\n NOT: t.field({ type: DateTimeWhereInputArgument }),\n }),\n });\n}\n","export type Prefetch<Context, ReturnType> = (params: {\n context: Context;\n}) => Promise<ReturnType>;\n\nexport type Filter<\n Context,\n FilteredEntityType,\n PrefetchReturnType = never,\n> = (p: {\n context: Context;\n entities: FilteredEntityType[];\n prefetched: PrefetchReturnType;\n}) => FilteredEntityType[] | Promise<FilteredEntityType[]>;\n\nexport type FilterPrefetchCombo<\n Context,\n FilteredEntityType,\n PrefetchReturnType = never,\n> = {\n filter: Filter<Context, FilteredEntityType, PrefetchReturnType>;\n prefetch?: Prefetch<Context, PrefetchReturnType>;\n};\n\nexport type ApplyFiltersField<Context, T> =\n | FilterPrefetchCombo<Context, T>\n | FilterPrefetchCombo<Context, T>[]\n | undefined;\n\nexport const pluginName = \"RuntimeFiltersPlugin\" as const;\n","import type { Span, Tracer } from \"@opentelemetry/api\";\nimport SchemaBuilder, {\n BasePlugin,\n type PothosOutputFieldConfig,\n type PothosTypeConfig,\n type SchemaTypes,\n} from \"@pothos/core\";\nimport DataLoader from \"dataloader\";\nimport type { GraphQLFieldResolver } from \"graphql\";\nimport { errorLogField } from \"../helpers/errorLogging\";\nimport {\n ATTR_FIELD_NAME,\n ATTR_FILTERS_ALLOWED,\n ATTR_FILTERS_TOTAL,\n recordSpanError,\n SPAN_FILTERS_APPLY,\n SPAN_FILTERS_RESOLVE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"../helpers/telemetry\";\nimport type { RumbleLogger } from \"../types/rumbleInput\";\nimport {\n type ApplyFiltersField,\n type FilterPrefetchCombo,\n pluginName,\n} from \"./filterTypes\";\n\nexport const applyFiltersKey = \"applyFilters\";\n\ntype AnyFilterCombo = FilterPrefetchCombo<any, any, any>;\n\nexport class RuntimeFiltersPlugin<\n Types extends SchemaTypes,\n> extends BasePlugin<Types> {\n private tracer?: Tracer;\n private tracerEnabled?: boolean;\n private logger?: RumbleLogger;\n private telemetryConfig: TelemetryConfig = {};\n\n // graphql-js resolves a relation field once per sibling in a list, concurrently,\n // so without this a filter like \"can read user\" would fire once per row instead\n // of once for the whole list. Keying loaders by context means they get garbage\n // collected once the request is done, no manual cleanup needed.\n private filterLoaders = new WeakMap<\n object,\n Map<AnyFilterCombo, DataLoader<any, any>>\n >();\n\n private getLoader(\n context: Types[\"Context\"],\n filter: AnyFilterCombo,\n ): DataLoader<any, any> {\n let perContext = this.filterLoaders.get(context as object);\n if (!perContext) {\n perContext = new Map();\n this.filterLoaders.set(context as object, perContext);\n }\n\n let loader = perContext.get(filter);\n if (!loader) {\n // not awaited here on purpose, so it runs alongside the resolver instead of after it\n const prefetchPromise = filter.prefetch\n ? filter.prefetch({ context })\n : undefined;\n\n loader = new DataLoader<any, any>(\n async (entities) => {\n const prefetched = prefetchPromise\n ? await prefetchPromise\n : undefined;\n const allowed = await filter.filter({\n context,\n entities: entities as any[],\n prefetched,\n } as any);\n const allowedSet = new Set(allowed);\n return entities.map((entity) =>\n allowedSet.has(entity) ? entity : null,\n );\n },\n // cache off on purpose, we only want the batching, filters should still\n // run fresh every time like before\n { cache: false },\n );\n perContext.set(filter, loader);\n }\n\n return loader;\n }\n\n override onTypeConfig(typeConfig: PothosTypeConfig) {\n this.tracer = this.builder.options.otel?.tracer;\n this.tracerEnabled = this.builder.options.otel?.enabled;\n this.logger = this.builder.options.logger?.enabled\n ? this.builder.options.logger.logger\n : undefined;\n this.telemetryConfig = {\n otel: this.builder.options.otel,\n logger: this.builder.options.logger,\n };\n return typeConfig;\n }\n\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n return async (parent, args, context, info) => {\n let filters: ApplyFiltersField<Types[\"Context\"], any> | undefined;\n const fieldType = fieldConfig?.type as any;\n\n if (fieldType.kind === \"List\") {\n filters =\n fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];\n } else if (fieldType.kind === \"Object\") {\n filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];\n }\n\n if (!filters || !Array.isArray(filters) || filters.length === 0) {\n // if no filter should be applied, just continue\n return resolver(parent, args, context, info);\n }\n\n const runFilters = async (span?: Span) => {\n const allFilters = Array.isArray(filters) ? filters : [filters];\n span?.setAttribute(ATTR_FILTERS_TOTAL, allFilters.length);\n\n const loaders = allFilters.map((filter) =>\n this.getLoader(context, filter as AnyFilterCombo),\n );\n\n let resolved: any;\n\n if (this.tracer && this.tracerEnabled) {\n resolved = await this.tracer.startActiveSpan(\n SPAN_FILTERS_RESOLVE,\n async (span) => {\n span.setAttribute(ATTR_FIELD_NAME, fieldConfig.name);\n try {\n return await resolver(parent, args, context, info);\n } catch (error) {\n recordSpanError(span, error);\n throw error;\n } finally {\n span.end();\n }\n },\n );\n } else {\n resolved = await resolver(parent, args, context, info);\n }\n\n const entities: any[] = Array.isArray(resolved) ? resolved : [resolved];\n\n // load() instead of loadMany() so a thrown filter still rejects here\n // instead of getting swallowed into an Error value\n const perFilterResults = await Promise.all(\n loaders.map((loader) =>\n Promise.all(entities.map((entity) => loader.load(entity))),\n ),\n );\n\n const allowed = entities.filter((_, index) =>\n perFilterResults.some((results) => results[index] != null),\n );\n\n span?.setAttribute(ATTR_FILTERS_ALLOWED, allowed.length);\n this.logger?.debug(\n {\n [ATTR_FIELD_NAME]: fieldConfig.name,\n [ATTR_FILTERS_TOTAL]: allFilters.length,\n [ATTR_FILTERS_ALLOWED]: allowed.length,\n ...traceCorrelationFields(this.telemetryConfig),\n },\n \"runtime filters applied\",\n );\n\n // if the original value was an array, return an array\n if (Array.isArray(resolved)) {\n return allowed;\n }\n\n // if the original value was a single value, return the first allowed\n // or null if not allowed\n return allowed[0] ?? null;\n };\n\n const logFilterError = (error: unknown) => {\n this.logger?.error(\n {\n [ATTR_FIELD_NAME]: fieldConfig.name,\n ...traceCorrelationFields(this.telemetryConfig),\n ...errorLogField(error),\n },\n \"runtime filter threw\",\n );\n };\n\n if (this.tracer && this.tracerEnabled) {\n return this.tracer.startActiveSpan(SPAN_FILTERS_APPLY, async (span) => {\n span.setAttribute(ATTR_FIELD_NAME, fieldConfig.name);\n try {\n return await runFilters(span);\n } catch (error) {\n logFilterError(error);\n recordSpanError(span, error);\n throw error;\n } finally {\n span.end();\n }\n });\n } else {\n try {\n return await runFilters();\n } catch (error) {\n logFilterError(error);\n throw error;\n }\n }\n };\n }\n}\n\nlet registered = false;\nexport function registerRuntimeFiltersPlugin() {\n if (!registered) {\n // Dev server restarts can re-evaluate this module (e.g. duplicate ESM/CJS\n // loads of @pothos/core), resetting the registered guard above and\n // causing pothos to throw on the second registerPlugin call. Reregistering\n // the same class is harmless, so allow it instead of crashing.\n SchemaBuilder.allowPluginReRegistration = true;\n SchemaBuilder.registerPlugin(pluginName, RuntimeFiltersPlugin);\n registered = true;\n }\n}\n","import \"lib-address\";\nimport {\n AddressValidationError,\n CountryMissingError,\n InvalidStateError,\n InvalidZipError,\n isValidCountryCode,\n MissingFieldError,\n validateAddress,\n} from \"lib-address\";\nimport { z } from \"zod\";\nimport type { AddressShape } from \"./address\";\n\nconst FIELD_PATH_MAP: Partial<Record<string, keyof AddressShape>> = {\n addressLine1: \"streetAddress\",\n addressLine2: \"streetAddress\",\n addressLine3: \"streetAddress\",\n city: \"locality\",\n dependentLocality: \"locality\",\n state: \"region\",\n zip: \"postalCode\",\n sortingCode: \"postalCode\",\n};\n\n/**\n * Fixes the unambiguous, purely-cosmetic issues (stray surrounding whitespace, wrong case)\n * before validation runs, rather than rejecting a request over them. This runs as a Zod\n * `transform`, and `@pothos/plugin-validation` uses a transform's *output* as the field's\n * actual value — so the corrected value, not the original one, is what resolvers receive.\n *\n * `countryCode` and `postalCode` are uppercased since their canonical forms always are (ISO\n * 3166-1 codes, and postal codes in every country that mixes letters and digits, e.g. GB/CA/NL).\n * `region`/`locality` are only trimmed, not case-changed: unlike country/postal codes, a region\n * is sometimes a free-text place name rather than a code (lib-address's own subdivision lookup\n * is already case-insensitive, so case coercion there wouldn't fix anything a rejection-worthy\n * case wouldn't already pass).\n */\nconst normalizeAddress = (address: {\n streetAddress: string;\n locality?: string | null;\n region?: string | null;\n postalCode?: string | null;\n countryCode: string;\n}) => ({\n streetAddress:\n address.streetAddress\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\") || null,\n locality: address.locality?.trim() || null,\n region: address.region?.trim() || null,\n postalCode: address.postalCode?.trim().toUpperCase() || null,\n countryCode: address.countryCode.trim().toUpperCase(),\n});\n\nexport const addressValidationSchema = z\n .object({\n // Required (not nullable/optional), like countryCode below: checked against libaddressinput\n // data for all 252 countries, streetAddress is the one field required in literally all of\n // them. A whitespace-only value still reaches the normal per-country MissingFieldError path\n // below (it normalizes to null, same as omitting it), rather than needing its own check —\n // unlike countryCode, there's no chicken-and-egg problem here (checking it doesn't first\n // require knowing which country's rules apply).\n streetAddress: z.string(),\n locality: z.string().nullable().optional(),\n region: z.string().nullable().optional(),\n postalCode: z.string().nullable().optional(),\n // Required (not nullable/optional): without a country there is nothing to validate the\n // other fields' requiredness/format against, so a country-less \"address\" can't be verified.\n // Whitespace-only input is caught below, after trimming, rather than here — GraphQL's own\n // non-null check only guarantees a string was sent, not a meaningful one.\n countryCode: z.string(),\n })\n .transform(normalizeAddress)\n .superRefine((address, ctx) => {\n if (!address.countryCode) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"countryCode\"],\n message: \"countryCode is required.\",\n });\n return;\n }\n\n if (!isValidCountryCode(address.countryCode)) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"countryCode\"],\n message: `Unknown country code: ${address.countryCode}`,\n });\n return;\n }\n\n const [addressLine1, addressLine2, addressLine3] = address.streetAddress\n ? address.streetAddress.split(\"\\n\")\n : [];\n\n try {\n validateAddress({\n country: address.countryCode,\n addressLine1,\n addressLine2,\n addressLine3,\n city: address.locality ?? undefined,\n // lib-address's own isValidCountrySubdivisionCode is case-insensitive, but\n // validateAddress's internal state check isn't — uppercase here (not in the value\n // returned to the client, since region is free text for some countries) to work\n // around that inconsistency rather than rejecting a validly-cased subdivision code.\n state: address.region?.toUpperCase() ?? undefined,\n zip: address.postalCode ?? undefined,\n });\n } catch (error) {\n if (error instanceof CountryMissingError) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"countryCode\"],\n message: error.message,\n });\n return;\n }\n\n if (!(error instanceof AddressValidationError)) {\n throw error;\n }\n\n for (const subError of error.errors) {\n if (subError instanceof MissingFieldError) {\n const path = FIELD_PATH_MAP[subError.field];\n if (!path) {\n // e.g. \"name\"/\"organization\" — out of scope for a pure location Address.\n continue;\n }\n ctx.addIssue({\n code: \"custom\",\n path: [path],\n message: `${path} is required for country ${address.countryCode}.`,\n });\n } else if (subError instanceof InvalidZipError) {\n // Also matches the InvalidZipSubRegionError subclass (postal code doesn't match\n // the expected format for the given state/region within the country).\n ctx.addIssue({\n code: \"custom\",\n path: [\"postalCode\"],\n message: `Invalid postal code for country ${address.countryCode}.`,\n });\n } else if (subError instanceof InvalidStateError) {\n ctx.addIssue({\n code: \"custom\",\n path: [\"region\"],\n message: `Invalid region for country ${address.countryCode}.`,\n });\n }\n }\n }\n });\n","import { addressValidationSchema } from \"./addressValidation\";\n\n/**\n * The shape of a postal address, modeled after the OIDC `address` claim\n * (https://openid.net/specs/openid-connect-core-1_0.html#AddressClaim) and schema.org's\n * `PostalAddress`.\n */\nexport type AddressShape = {\n /** The street address, which may be multiple lines separated by newlines. */\n streetAddress?: string | null;\n /** City or town. */\n locality?: string | null;\n /** State, province, prefecture or region. */\n region?: string | null;\n /** Postal or zip code. */\n postalCode?: string | null;\n /** ISO 3166-1 alpha-2 country code. */\n countryCode?: string | null;\n};\n\n/**\n * AddressInput's shape differs from AddressShape in that `countryCode` and `streetAddress` are\n * required. `countryCode`: without a country there is nothing for the validator to check\n * requiredness/format/region against, so a country-less \"address\" can't be verified as valid\n * for anywhere. `streetAddress`: checked against every one of the 252 countries in\n * libaddressinput's dataset — it is the one field required in literally all of them (unlike\n * e.g. city, which 13 countries including Japan and Singapore don't require, or state/zip,\n * required in barely a sixth to a third of countries) — so it's safe to require unconditionally\n * rather than only per-country. The remaining fields stay optional since their requiredness\n * genuinely varies by country; that's enforced dynamically by `addressValidationSchema` instead\n * of statically here.\n */\nexport type AddressInputShape = Omit<\n AddressShape,\n \"countryCode\" | \"streetAddress\"\n> & {\n countryCode: string;\n streetAddress: string;\n};\n\n// TODO: Add proper type for schemaBuilder\nexport function implementDefaultAddressTypes(schemaBuilder: any) {\n const Address = schemaBuilder.objectRef(\"Address\").implement({\n description:\n \"A postal address, modeled after the OIDC `address` claim and schema.org's PostalAddress.\",\n fields: (t: any) => ({\n streetAddress: t.exposeString(\"streetAddress\", { nullable: true }),\n locality: t.exposeString(\"locality\", { nullable: true }),\n region: t.exposeString(\"region\", { nullable: true }),\n postalCode: t.exposeString(\"postalCode\", { nullable: true }),\n countryCode: t.exposeString(\"countryCode\", { nullable: true }),\n }),\n });\n\n const AddressInput = schemaBuilder.inputRef(\"AddressInput\").implement({\n description:\n \"Input counterpart of Address. countryCode and streetAddress are required — countryCode \" +\n \"because there is nothing to validate the other fields against without it, and \" +\n \"streetAddress because it's the one field required in every country. The remaining \" +\n \"fields are optional since their requiredness genuinely varies by country; validated as \" +\n \"a whole using Google's libaddressinput metadata (offline).\",\n validate: addressValidationSchema,\n fields: (t: any) => ({\n streetAddress: t.string({ required: true }),\n locality: t.string({ required: false }),\n region: t.string({ required: false }),\n postalCode: t.string({ required: false }),\n countryCode: t.string({ required: true }),\n }),\n });\n\n return { Address, AddressInput };\n}\n","import { GraphQLScalarType, Kind } from \"graphql\";\nimport { EmailAddressResolver as BaseEmailAddressResolver } from \"graphql-scalars\";\nimport { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n * Validates an email address using graphql-scalars' own format check, then lowercases it.\n */\nconst normalize = (value: unknown): string => {\n try {\n return (BaseEmailAddressResolver.parseValue(value) as string).toLowerCase();\n } catch (error) {\n throw new RumbleErrorSafe(\n error instanceof Error\n ? error.message\n : `Invalid email address: ${value}`,\n );\n }\n};\n\nexport const EmailAddressResolver = new GraphQLScalarType<string, string>({\n name: \"EmailAddress\",\n description: `${BaseEmailAddressResolver.description} Lowercased.`,\n specifiedByURL: BaseEmailAddressResolver.specifiedByURL,\n serialize: normalize,\n parseValue: normalize,\n parseLiteral(ast) {\n if (ast.kind !== Kind.STRING) {\n throw new RumbleErrorSafe(\n `Can only validate strings as email addresses but got a: ${ast.kind}`,\n );\n }\n return normalize(ast.value);\n },\n});\n","import { GraphQLScalarType, Kind } from \"graphql\";\nimport { RumbleErrorSafe } from \"../types/rumbleError\";\n\nconst MAX_LENGTH = 200;\n\nconst NAME_REGEX = /^[\\p{L}\\p{M}]+(?:(?:[ '-]|\\.\\x20?)[\\p{L}\\p{M}]+)*\\.?$/u;\n\n/**\n * Normalizes and validates a person's name.\n */\nconst normalize = (value: unknown): string => {\n if (typeof value !== \"string\") {\n throw new RumbleErrorSafe(`Name value is not a string: ${value}`);\n }\n\n const normalized = value\n .normalize(\"NFC\")\n .replace(/[\\p{Cc}\\p{Cf}]/gu, \"\")\n .replace(/\\p{Zs}+/gu, \" \")\n .trim()\n .replace(/([-'])\\1+/gu, \"$1\")\n .replace(/^[-']+|[-']+$/gu, \"\")\n .trim();\n\n if (normalized.length === 0) {\n throw new RumbleErrorSafe(\"Name must not be empty.\");\n }\n\n if (normalized.length > MAX_LENGTH) {\n throw new RumbleErrorSafe(\n `Name must not be longer than ${MAX_LENGTH} characters.`,\n );\n }\n\n if (!NAME_REGEX.test(normalized)) {\n throw new RumbleErrorSafe(\n `Invalid name: ${value}. Names may only contain letters and the separators space, apostrophe, hyphen and period, and may not start with or repeat a separator.`,\n );\n }\n\n return normalized;\n};\n\nexport const PersonNameResolver = new GraphQLScalarType<string, string>({\n name: \"PersonName\",\n description:\n \"A person's name. Unicode letters from any script are allowed, along with space, apostrophe, hyphen and period as separators between name parts. The value is Unicode NFC normalized, has invisible/control characters stripped, has its whitespace collapsed, and has unambiguous typos (a doubled or stray leading/trailing hyphen/apostrophe) silently corrected rather than rejected.\",\n serialize: normalize,\n parseValue: normalize,\n parseLiteral(ast) {\n if (ast.kind !== Kind.STRING) {\n throw new RumbleErrorSafe(\n `Can only validate strings as names but got a: ${ast.kind}`,\n );\n }\n return normalize(ast.value);\n },\n});\n","import { GraphQLScalarType, Kind } from \"graphql\";\nimport {\n type PhoneNumber,\n parsePhoneNumberFromString,\n} from \"libphonenumber-js\";\nimport { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n * Parses and validates a phone number using libphonenumber-js (Google's phone number metadata),\n * which checks real per-country validity (length, area code plausibility, ...) rather than just\n * the E.164 shape.\n */\nconst parse = (value: unknown): PhoneNumber => {\n if (typeof value !== \"string\") {\n throw new RumbleErrorSafe(`Phone number value is not a string: ${value}`);\n }\n\n const phoneNumber = parsePhoneNumberFromString(value);\n if (!phoneNumber?.isValid()) {\n throw new RumbleErrorSafe(\n `Invalid phone number: ${value}. Please provide a valid phone number including its country calling code, e.g. +4915123456789.`,\n );\n }\n\n return phoneNumber;\n};\n\n/**\n * Resolvers may either return an already-parsed PhoneNumber (e.g. one obtained via `parse`\n * above) or a raw string, which is parsed and validated the same way input values are.\n */\nconst serialize = (value: unknown): string => {\n if (\n value &&\n typeof value === \"object\" &&\n typeof (value as PhoneNumber).isValid === \"function\"\n ) {\n const phoneNumber = value as PhoneNumber;\n if (!phoneNumber.isValid()) {\n throw new RumbleErrorSafe(`Invalid phone number: ${phoneNumber.number}`);\n }\n return phoneNumber.number;\n }\n\n return parse(value).number;\n};\n\nexport const PhoneNumberResolver = new GraphQLScalarType<PhoneNumber, string>({\n name: \"PhoneNumber\",\n description:\n \"A phone number, validated using real per-country validity rules and represented as a parsed libphonenumber-js PhoneNumber. On the wire it is transported as the E.164 format (https://en.wikipedia.org/wiki/E.164), e.g. +4915123456789. The country calling code is required.\",\n serialize,\n parseValue: parse,\n parseLiteral(ast) {\n if (ast.kind !== Kind.STRING) {\n throw new RumbleErrorSafe(\n `Can only validate strings as phone numbers but got a: ${ast.kind}`,\n );\n }\n return parse(ast.value);\n },\n});\n","import SchemaBuilder from \"@pothos/core\";\nimport DrizzlePlugin from \"@pothos/plugin-drizzle\";\nimport SmartSubscriptionsPlugin, {\n subscribeOptionsFromIterator,\n} from \"@pothos/plugin-smart-subscriptions\";\nimport TracingPlugin, {\n isRootField,\n wrapResolver,\n} from \"@pothos/plugin-tracing\";\nimport ValidationPlugin from \"@pothos/plugin-validation\";\nimport { createOpenTelemetryWrapper } from \"@pothos/tracing-opentelemetry\";\nimport { getTableColumns, isTable, type Table } from \"drizzle-orm\";\nimport {\n BigIntResolver,\n ByteResolver,\n DateResolver,\n DateTimeISOResolver,\n JSONResolver,\n LocaleResolver,\n} from \"graphql-scalars\";\nimport type { createPubSub } from \"graphql-yoga\";\nimport type { PhoneNumber as LibPhoneNumber } from \"libphonenumber-js\";\nimport {\n type BigIntWhereInputArgument,\n type BooleanWhereInputArgument,\n type DateTimeWhereInputArgument,\n type DateWhereInputArgument,\n type IDWhereInputArgument,\n implementDefaultWhereInputArgs,\n type JSONWhereInputArgument,\n type NumberWhereInputArgument,\n type StringWhereInputArgument,\n} from \"./args/whereArgsImplementer\";\nimport type { ContextType } from \"./context\";\nimport { errorLogField } from \"./helpers/errorLogging\";\nimport {\n ATTR_FIELD_NAME,\n ATTR_PARENT_TYPE,\n FIELD_DURATION_MS,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport { pluginName } from \"./runtimeFiltersPlugin/filterTypes\";\nimport { registerRuntimeFiltersPlugin } from \"./runtimeFiltersPlugin/runtimeFiltersPlugin\";\nimport {\n type AddressInputShape,\n type AddressShape,\n implementDefaultAddressTypes,\n} from \"./scalars/address\";\nimport { EmailAddressResolver } from \"./scalars/emailAddress\";\nimport { PersonNameResolver } from \"./scalars/personName\";\nimport { PhoneNumberResolver } from \"./scalars/phoneNumber\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\nexport const createSchemaBuilder = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n db,\n pubsub,\n pothosConfig,\n otel,\n logger,\n validation,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n pubsub: ReturnType<typeof createPubSub>;\n}) => {\n const createSpan =\n otel?.enabled && otel.tracer\n ? createOpenTelemetryWrapper(otel.tracer, otel.options)\n : undefined;\n\n registerRuntimeFiltersPlugin();\n const schemaBuilder = new SchemaBuilder<{\n Context: ContextType<UserContext, DB, RequestEvent, Action, PothosConfig>;\n DrizzleRelations: DB[\"_\"][\"relations\"];\n Objects: {\n Address: AddressShape;\n };\n Scalars: {\n JSON: {\n Input: unknown;\n Output: unknown;\n };\n Date: {\n Input: Date;\n Output: Date;\n };\n DateTime: {\n Input: Date;\n Output: Date | string;\n };\n BigInt: {\n Input: bigint | number;\n Output: bigint | number | string;\n };\n Bytes: {\n Input: string;\n Output: string;\n };\n EmailAddress: {\n Input: string;\n Output: string;\n };\n PhoneNumber: {\n Input: LibPhoneNumber;\n Output: LibPhoneNumber | string;\n };\n Locale: {\n Input: string;\n Output: string;\n };\n PersonName: {\n Input: string;\n Output: string;\n };\n };\n Inputs: {\n IntWhereInputArgument: NumberWhereInputArgument;\n FloatWhereInputArgument: NumberWhereInputArgument;\n StringWhereInputArgument: StringWhereInputArgument;\n DateWhereInputArgument: DateWhereInputArgument;\n DateTimeWhereInputArgument: DateTimeWhereInputArgument;\n BigIntWhereInputArgument: BigIntWhereInputArgument;\n BooleanWhereInputArgument: BooleanWhereInputArgument;\n IDWhereInputArgument: IDWhereInputArgument;\n JSONWhereInputArgument: JSONWhereInputArgument;\n AddressInput: AddressInputShape;\n };\n DefaultFieldNullability: false;\n }>({\n ...pothosConfig,\n plugins: [\n pluginName,\n DrizzlePlugin,\n SmartSubscriptionsPlugin,\n TracingPlugin,\n ValidationPlugin,\n ...(pothosConfig?.plugins ?? []),\n ],\n drizzle: {\n client: db,\n relations: db._.relations,\n getTableConfig(table) {\n //TODO support composite primary keys\n const columns = isTable(table)\n ? Object.values(getTableColumns(table as Table))\n : [];\n return {\n columns,\n primaryKeys: columns.filter((v: any) => v.primary),\n } as any;\n },\n },\n smartSubscriptions: {\n ...subscribeOptionsFromIterator((name, _context) => {\n return pubsub.subscribe(name);\n }),\n },\n defaultFieldNullability: false,\n tracing: {\n default:\n otel?.enabled || logger?.enabled\n ? (config) => isRootField(config)\n : () => false,\n wrap: (resolver, options, config) => {\n let r = createSpan ? createSpan(resolver, options) : resolver;\n if (logger?.enabled) {\n const log = logger.logger;\n const telemetryConfig = { otel, logger };\n r = wrapResolver(r, (error, duration) => {\n const fields = {\n [ATTR_FIELD_NAME]: config.name,\n [ATTR_PARENT_TYPE]: config.parentType,\n [FIELD_DURATION_MS]: duration,\n // read from the active span, which at this point is the resolver\n // span pothos opened, so resolver logs correlate as precisely as\n // the operation level ones do\n ...traceCorrelationFields(telemetryConfig),\n };\n\n if (error) {\n log.error(\n { ...fields, ...errorLogField(error) },\n \"resolver failed\",\n );\n } else {\n log.debug(fields, \"resolver completed\");\n }\n });\n }\n return r;\n },\n },\n otel,\n logger,\n // `RumbleValidationConfig` is deliberately generic-unbound (extracted from the plugin's\n // own type, not hand-declared), so it doesn't line up with this builder's concrete\n // SchemaTypes — same category of mismatch `otel`/`logger`/`tracing` avoid by not\n // referencing Pothos generics at all.\n validation: validation as any,\n });\n\n schemaBuilder.addScalarType(\"JSON\", JSONResolver);\n schemaBuilder.addScalarType(\"Date\", DateResolver);\n schemaBuilder.addScalarType(\"DateTime\", DateTimeISOResolver);\n schemaBuilder.addScalarType(\"BigInt\", BigIntResolver);\n schemaBuilder.addScalarType(\"Bytes\", ByteResolver);\n schemaBuilder.addScalarType(\"EmailAddress\", EmailAddressResolver);\n schemaBuilder.addScalarType(\"PhoneNumber\", PhoneNumberResolver);\n schemaBuilder.addScalarType(\"Locale\", LocaleResolver);\n schemaBuilder.addScalarType(\"PersonName\", PersonNameResolver);\n implementDefaultWhereInputArgs(schemaBuilder);\n implementDefaultAddressTypes(schemaBuilder);\n\n schemaBuilder.queryType({});\n schemaBuilder.subscriptionType({});\n schemaBuilder.mutationType({});\n\n return { schemaBuilder };\n};\n","import { EnvelopArmorPlugin } from \"@escape.tech/graphql-armor\";\nimport { useDisableIntrospection } from \"@graphql-yoga/plugin-disable-introspection\";\nimport type { useSofa } from \"@m1212e/sofa-api\";\nimport { trace } from \"@opentelemetry/api\";\nimport { merge } from \"es-toolkit\";\nimport { GraphQLSchema } from \"graphql\";\nimport type { ServerOptions } from \"graphql-ws\";\nimport {\n createYoga as nativeCreateYoga,\n type Plugin,\n type YogaServerOptions,\n} from \"graphql-yoga\";\nimport packagejson from \"../package.json\";\nimport { createAbilityBuilder } from \"./abilityBuilder\";\nimport { createOrderArgImplementer } from \"./args/orderArg\";\nimport { createWhereArgImplementer } from \"./args/whereArg\";\nimport { clientCreatorImplementer } from \"./client/client\";\nimport { createContextFunction } from \"./context\";\nimport { createCountQueryImplementer } from \"./countQuery\";\nimport { createEnumImplementer, type EnumFieldKeys } from \"./enum\";\nimport { errorsLogField } from \"./helpers/errorLogging\";\nimport { lazy } from \"./helpers/lazy\";\nimport { sofaOpenAPIWebhookDocs } from \"./helpers/sofaOpenAPIWebhookDocs\";\nimport {\n ATTR_TRANSPORT,\n errorsAlreadyReported,\n recordSpanErrors,\n telemetryEnabled,\n telemetryLogger,\n traceCorrelationFields,\n} from \"./helpers/telemetry\";\nimport {\n buildTracedExecute,\n buildTracedSubscribe,\n defaultExecute,\n defaultSubscribe,\n} from \"./helpers/tracing\";\nimport { createObjectImplementer } from \"./object\";\nimport { createPubSubInstance } from \"./pubsub\";\nimport { createQueryImplementer } from \"./query\";\nimport { createSchemaBuilder } from \"./schemaBuilder\";\nimport { initSearchIfApplicable } from \"./search\";\nimport type { DrizzleInstance } from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\n/**\n * Mirrors sofa's own default error handler: it derives the HTTP status from\n * `extensions.http` and returns the errors as JSON. rumble only adds telemetry\n * around error handling, so a request that fails must still answer with the\n * status and body a plain sofa setup would have produced.\n */\nfunction sofaErrorResponse(errors: ReadonlyArray<any>): Response {\n let status: number | undefined;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json; charset=utf-8\",\n };\n\n for (const error of errors) {\n const http = error?.extensions?.http;\n if (!http) continue;\n\n if (http.status && (!status || http.status > status)) {\n status = http.status;\n }\n if (http.headers) {\n Object.assign(headers, http.headers);\n }\n // sofa strips this before serializing so the transport hint does not leak\n // into the response body\n delete error.extensions.http;\n }\n\n return Response.json(\n { errors },\n {\n status: status ?? 500,\n headers,\n },\n );\n}\n\nexport const rumble = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n PothosConfig extends CustomRumblePothosConfig,\n Schema extends Record<string, any>,\n Action extends string = \"read\" | \"update\" | \"delete\",\n>(\n rumbleInput: RumbleInput<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n > & {\n schema: Schema;\n },\n) => {\n if (!rumbleInput.db._.relations) {\n throw new RumbleError(`\nrumble could not find any relations in the provided drizzle instance.\nMake sure you import the relations and pass them to the drizzle instance:\n\nexport const db = drizzle(\n \"postgres://postgres:postgres@localhost:5432/postgres\",\n {\n relations, // <--- add this line\n },\n);\n\n`);\n }\n\n if (\n !rumbleInput.schema ||\n typeof rumbleInput.schema !== \"object\" ||\n Object.keys(rumbleInput.schema).length === 0\n ) {\n throw new RumbleError(`\nrumble requires the drizzle schema object to be passed when initializing.\nImport your schema module and pass it alongside \\`db\\`:\n\nimport * as schema from \"./db/schema\";\n\nexport const r = rumble({\n db,\n schema, // <--- add this line\n});\n\n`);\n }\n\n // to be able to iterate over the actions, we populate the actions array in case the user does not\n if (!rumbleInput.actions) {\n rumbleInput.actions = [\"read\", \"update\", \"delete\"] as Action[];\n }\n\n if (rumbleInput.defaultLimit === undefined) {\n rumbleInput.defaultLimit = 100;\n }\n\n if (rumbleInput.search?.enabled) {\n initSearchIfApplicable(rumbleInput);\n }\n\n if (rumbleInput.otel?.enabled && !rumbleInput.otel.tracer) {\n rumbleInput.otel.tracer = trace.getTracer(\n \"@m1212e/rumble\",\n packagejson.version,\n );\n }\n\n const abilityBuilder = createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >(rumbleInput);\n\n const context = createContextFunction<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n abilityBuilder,\n });\n\n const { makePubSubInstance, pubsub } = createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n });\n\n const { schemaBuilder } = createSchemaBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({ ...rumbleInput, pubsub });\n\n const enum_ = createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n EnumFieldKeys<Schema>,\n Schema\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const whereArg = createWhereArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n schemaBuilder,\n enumImplementer: enum_,\n });\n\n const orderArg = createOrderArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const object = createObjectImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema\n >({\n ...rumbleInput,\n schemaBuilder,\n makePubSubInstance,\n whereArgImplementer: whereArg,\n orderArgImplementer: orderArg,\n enumImplementer: enum_,\n abilityBuilder,\n });\n\n const query = createQueryImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n Schema\n >({\n ...rumbleInput,\n schemaBuilder,\n whereArgImplementer: whereArg,\n orderArgImplementer: orderArg,\n makePubSubInstance,\n });\n\n const countQuery = createCountQueryImplementer({\n ...rumbleInput,\n schemaBuilder,\n whereArgImplementer: whereArg,\n makePubSubInstance,\n });\n\n const builtSchema = lazy(() => {\n let raw: ReturnType<typeof schemaBuilder.toSchema>;\n try {\n raw = schemaBuilder.toSchema();\n } catch (e: any) {\n const msg: string = e?.message ?? String(e);\n const unimplMatch = msg.match(\n /ObjectRef<(.+?)> has not been implemented/,\n );\n if (unimplMatch) {\n throw new RumbleError(\n `Could not build GraphQL schema: the table \"${unimplMatch[1]}\" is referenced ` +\n `in a relation but has not been registered. Call rumble.object({ table: \"${unimplMatch[1]}\" }) ` +\n `before building the schema.`,\n );\n }\n throw e;\n }\n\n const mutation = raw.getMutationType();\n const subscription = raw.getSubscriptionType();\n const emptyMutation =\n mutation && Object.keys(mutation.getFields()).length === 0;\n const emptySubscription =\n subscription && Object.keys(subscription.getFields()).length === 0;\n\n if (!emptyMutation && !emptySubscription) return raw;\n\n const config = raw.toConfig();\n const filteredTypes = config.types.filter((t) => {\n if (emptyMutation && t === mutation) return false;\n if (emptySubscription && t === subscription) return false;\n return true;\n });\n return new GraphQLSchema({\n ...config,\n mutation: emptyMutation ? undefined : config.mutation,\n subscription: emptySubscription ? undefined : config.subscription,\n types: filteredTypes,\n });\n });\n\n /**\n * Adapts the configured rumble logger to the logger interface yoga expects,\n * so yoga's own diagnostics end up in the same structured stream (with the\n * same `rumble.transport` and trace correlation fields) as rumble's entries.\n */\n const yogaLogging = () => {\n const log = telemetryLogger(rumbleInput);\n if (!log) return undefined;\n\n const emit =\n (level: \"debug\" | \"info\" | \"warn\" | \"error\") =>\n (...args: unknown[]) => {\n const messages = args.filter(\n (arg): arg is string => typeof arg === \"string\",\n );\n const rest = args.filter((arg) => typeof arg !== \"string\");\n const errors = rest.filter((entry) => entry instanceof Error);\n const details = rest.filter((entry) => !(entry instanceof Error));\n\n log[level](\n {\n [ATTR_TRANSPORT]: \"graphql\",\n ...traceCorrelationFields(rumbleInput),\n ...(errors.length > 0 ? errorsLogField(errors) : {}),\n ...(details.length > 0 ? { details } : {}),\n },\n messages.join(\" \") || \"yoga diagnostic\",\n );\n };\n\n return {\n debug: emit(\"debug\"),\n info: emit(\"info\"),\n warn: emit(\"warn\"),\n error: emit(\"error\"),\n };\n };\n\n const createYoga = (\n args?:\n | (Omit<YogaServerOptions<RequestEvent, any>, \"schema\" | \"context\"> & {\n /**\n * Determines if the API should disclose various things about its structure.\n * Defaults to `process.env.NODE_ENV === \"development\"`.\n * If enabled, the api will allow introspection requests, provide the graphiql\n * explorer and will not apply the additional envelop armor plugin.\n */\n enableApiDocs?: boolean;\n /**\n * Optional configuration passed to the auto-installed graphql-armor\n * EnvelopArmorPlugin. Only applied when `enableApiDocs` is false\n * (i.e. in production). Useful for relaxing the default depth/alias/\n * directive/token limits when the generated schema legitimately exceeds\n * them. See https://github.com/Escape-Technologies/graphql-armor for available options.\n *\n * @example\n * createYoga({ armorConfig: { maxDepth: { n: 20 } } })\n */\n armorConfig?: Parameters<typeof EnvelopArmorPlugin>[0];\n })\n | undefined,\n ) => {\n const enableApiDocs =\n args?.enableApiDocs ?? process?.env?.NODE_ENV === \"development\";\n\n return nativeCreateYoga<RequestEvent>({\n ...args,\n graphiql: enableApiDocs,\n schema: builtSchema(),\n context,\n // Yoga logs its own diagnostics (unexpected errors, warnings) to the\n // console by default. Routing them into the rumble logger keeps every log\n // line of a request in one structured, trace correlated stream.\n logging: args?.logging ?? yogaLogging() ?? true,\n plugins: [\n ...(args?.plugins ?? []),\n ...(enableApiDocs\n ? []\n : [useDisableIntrospection(), EnvelopArmorPlugin(args?.armorConfig)]),\n telemetryEnabled(rumbleInput)\n ? ({\n // TODO: add trace header per default in http response\n // TODO: Automatic Persisted Queries\n onExecute: ({ setExecuteFn, executeFn }) => {\n setExecuteFn(\n buildTracedExecute(\n executeFn,\n rumbleInput,\n \"graphql\",\n ) as typeof executeFn,\n );\n },\n onSubscribe: ({ setSubscribeFn, subscribeFn }) => {\n setSubscribeFn(\n buildTracedSubscribe(\n subscribeFn,\n rumbleInput,\n \"graphql\",\n ) as typeof subscribeFn,\n );\n },\n } as Plugin)\n : false,\n ].filter(Boolean),\n });\n };\n\n const createSofa = async (\n args: Omit<Parameters<typeof useSofa>[0], \"schema\" | \"context\">,\n ) => {\n const { useSofa: useSofaFn } = await import(\"@m1212e/sofa-api\");\n if (args.openAPI) {\n merge(args.openAPI, sofaOpenAPIWebhookDocs);\n }\n\n const userErrorHandler = args.errorHandler;\n\n return useSofaFn({\n ...args,\n schema: builtSchema(),\n context,\n execute: buildTracedExecute(\n args.execute ?? defaultExecute,\n rumbleInput,\n \"rest\",\n ) as any,\n subscribe: buildTracedSubscribe(\n args.subscribe ?? defaultSubscribe,\n rumbleInput,\n \"rest\",\n ) as any,\n errorHandler(errors) {\n if (!errorsAlreadyReported(errors)) {\n recordSpanErrors(trace.getActiveSpan(), errors);\n\n const log = telemetryLogger(rumbleInput);\n log?.error(\n {\n [ATTR_TRANSPORT]: \"rest\",\n ...traceCorrelationFields(rumbleInput),\n ...errorsLogField(errors),\n },\n \"rest request failed\",\n );\n }\n\n return (userErrorHandler?.(errors) ??\n sofaErrorResponse(errors)) as ReturnType<\n NonNullable<typeof userErrorHandler>\n >;\n },\n });\n };\n\n const createWs = <\n Options extends ServerOptions<any, any>,\n Rest extends unknown[],\n Return,\n >(\n implementation: (options: Options, ...rest: Rest) => Return,\n args: Omit<Options, \"schema\" | \"context\">,\n ...rest: Rest\n ): Return => {\n return implementation(\n {\n ...args,\n schema: builtSchema(),\n context,\n execute: buildTracedExecute(\n (args as any).execute ?? defaultExecute,\n rumbleInput,\n \"ws\",\n ) as any,\n subscribe: buildTracedSubscribe(\n (args as any).subscribe ?? defaultSubscribe,\n rumbleInput,\n \"ws\",\n ) as any,\n } as Options,\n ...rest,\n );\n };\n\n const clientCreator = clientCreatorImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n builtSchema,\n });\n\n return {\n /**\n * The ability builder. Use it to declare whats allowed for each entity in your DB.\n *\n * @example\n *\n * ```ts\n * // users can edit themselves\n abilityBuilder.users\n .allow([\"read\", \"update\", \"delete\"])\n .when(({ userId }) => ({ where: eq(schema.users.id, userId) }));\n\n // everyone can read posts\n abilityBuilder.posts.allow(\"read\");\n *\n * ```\n */\n abilityBuilder,\n /**\n * The pothos schema builder. See https://pothos-graphql.dev/docs/plugins/drizzle\n */\n schemaBuilder,\n /**\n * Creates the native yoga instance. Can be used to run an actual HTTP server.\n *\n * @example\n *\n * ```ts\n * import { createServer } from \"node:http\";\n * const server = createServer(createYoga());\n * server.listen(3000, () => {\n * console.info(\"Visit http://localhost:3000/graphql\");\n * });\n * ```\n * https://the-guild.dev/graphql/yoga-server/docs#server\n */\n createYoga,\n /**\n * Creates a sofa instance to offer a REST API.\n *\n * ```ts\n * import express from \"express\";\n *\n * const app = express();\n * const sofa = createSofa(...);\n *\n * app.use(\"/api\", useSofa({ schema }));\n * ```\n * https://the-guild.dev/graphql/sofa-api/docs#usage\n */\n createSofa,\n /**\n * Creates a WebSocket server handler for GraphQL subscriptions.\n * Pass the ws implementation function as the first argument and rumble will\n * inject the schema and context automatically.\n *\n * @example\n *\n * ```ts\n * // ws\n * import { useServer } from \"graphql-ws/use/ws\";\n * import { WebSocketServer } from \"ws\";\n * const wss = new WebSocketServer({ port: 4000 });\n * const disposable = createWs(useServer, { ... }, wss);\n *\n * // bun\n * import { makeHandler } from \"graphql-ws/use/bun\";\n * Bun.serve({ websocket: createWs(makeHandler, { ... }), ... });\n * ```\n */\n createWs,\n /**\n * A function for creating default objects for your schema\n */\n object,\n /**\n * A function for creating where args to filter entities\n */\n whereArg,\n /**\n * A function for creating order args to sort entities\n */\n orderArg,\n /**\n * A function for creating default READ queries.\n * Make sure the objects for the table you are creating the queries for are implemented\n */\n query,\n /**\n * A function for creating a pubsub instance for a table. Use this to publish or subscribe events\n */\n pubsub: makePubSubInstance,\n /**\n * A function to implement enums for graphql usage.\n * The other helpers use this helper internally so in most cases you do not have to\n * call this helper directly, unless you need the reference to an enum type\n */\n enum_,\n /**\n * Create a client to consume a rumble graphql api at the specified location.\n * Requires GraphQL, does not work with the SOFA REST API.\n */\n clientCreator,\n /**\n * A function for creating count queries for your tables\n */\n countQuery,\n /**\n * The generated GraphQL schema. You can use this for example to create a GraphQL server with a different library than Yoga or to generate types with codegen.\n * When calling this function, the schema will be built for the first time and cached for later usage. So you can call this function multiple times without performance issues.\n * After calling, you cannot adjust the schema via the schema builder\n */\n buildSchema: builtSchema,\n };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF;;;;;;AAOA,IAAa,kBAAb,cAAqC,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACenD,MAAa,yBAA4B,UAA4B;CACnE,IAAI,CAAC,OACH,MAAM,IAAI,gBAAgB,0CAA0C;CAEtE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,MAAa,0BAA6B,UAAkB;CAC1D,MAAM,IAAI,MAAM,GAAG,CAAC;CACpB,IAAI,CAAC,GACH,MAAM,IAAI,gBAAgB,2CAA2C;CACvE,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACzBA,SAAgB,yBAA2C,KAAQ;CACjE,OAAO,OAAO,YACZ,OAAO,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CACxC,KACA,UAAU,OAAO,KAAA,IAAY,KAC/B,CAAC,CACH;AAGF;;;;;;AEpDA,SAAS,WAAW,OAA+C;CACjE,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa;AACrE;AAEA,SAAS,kBAAkB,OAAiC;CAC1D,IAAI,WAAW,KAAK,GAAG;EACrB,MAAM,WAAW;EACjB,OAAO;GACL,kBAAkB,SAAS,aAAa,QAAQ,SAAS,QAAQ;GACjE,qBAAqB,OAAO,SAAS,OAAO;GAC5C,GAAI,SAAS,QAAQ,EAAE,wBAAwB,SAAS,MAAM,IAAI,CAAC;GACnE,GAAI,SAAS,OAAO,EAAE,MAAM,SAAS,KAAK,IAAI,CAAC;GAC/C,GAAI,SAAS,cAAc,OAAO,KAAK,SAAS,UAAU,CAAC,CAAC,SAAS,IACjE,EAAE,YAAY,SAAS,WAAW,IAClC,CAAC;EACP;CACF;CACA,OAAO;EACL,kBAAkB;EAClB,qBAAqB,OAAO,KAAK;CACnC;AACF;;;;;;AAOA,SAAgB,eAAe,QAE7B;CACA,OAAO,EAAE,QAAQ,OAAO,IAAI,iBAAiB,EAAE;AACjD;AAEA,SAAgB,cAAc,OAA+C;CAC3E,OAAO,eAAe,CAAC,KAAK,CAAC;AAC/B;;;AC/CA,MAAMA,gBAAc,OAAO,IAAI,qBAAqB;;;;;;;;AASpD,SAAS,UAAU,OAAgB;CACjC,OAAO,UAAUA,gBAAc,KAAA,IAAY;AAC7C;AAEA,SAAgB,aAId,SACA,SACA,OAAqB,OACrB;CACA,MAAM,eAAe,UAAU,SAAS,KAAK;CAC7C,MAAM,eAAe,UAAU,SAAS,KAAK;CA+D7C,OAAO;EACL,OA7DA,gBAAgB,eACZ,SAAS,OACP,EAAE,IAAI,CAAC,cAAc,YAAY,EAAE,IACnC,EAAE,KAAK,CAAC,cAAc,YAAY,EAAE,IACrC,gBAAgB;EA0DrB,SAvDA,SAAS,WAAW,SAAS,UACzB,IAAI,IACF,CACE,OAAO,QAAQ,SAAS,WAAW,CAAC,CAAC,GACrC,OAAO,QAAQ,SAAS,WAAW,CAAC,CAAC,CACvC,CAAC,CACE,KAAK,CAAC,CACN,QAAQ,GAAG,OAAO,MAAM,IAAI,CAAC,CAC7B,KAAK,CAAC,OAAO,CAAC,CACnB,CAAC,CACE,QAAQ,CAAC,CACT,QACE,KAAK,CAAC,SAAS;GACd,IAAI,OAAO;GACX,OAAO;EACT,GACA,CAAC,CACH,IACF,KAAA;EAsCJ,QAnCA,SAAS,UAAU,SAAS,SACxB,SAAS,SAAS,UAAU,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC,IACrD,KAAA;EAkCJ,SA/BA,SAAS,WAAW,SAAS,UACzB,SAAS,SAAS,WAAW,CAAC,GAAG,SAAS,WAAW,CAAC,CAAC,IACvD,KAAA;EA8BJ,OA3BA,SAAS,OACL,SAAS,UAAU,KAAA,KAAa,SAAS,UAAU,KAAA,IACjD,KAAA,IACA,KAAK,IAAI,QAAQ,OAAO,QAAQ,KAAK,IACvC,SAAS,SAAS,SAAS,QACzB,KAAK,IAAI,SAAS,SAAS,UAAU,SAAS,SAAS,QAAQ,IAC/D,KAAA;EAsBN,QAnBA,SAAS,OACL,SAAS,WAAW,KAAA,KAAa,SAAS,WAAW,KAAA,IACnD,KAAA,IACA,KAAK,IAAI,QAAQ,QAAQ,QAAQ,MAAM,IACzC,SAAS,UAAU,SAAS,SAC1B,KAAK,IAAI,SAAS,UAAU,UAAU,SAAS,UAAU,QAAQ,IACjE,KAAA;EAcN,MAXA,SAAS,QAAQ,SAAS,OACtB,SAAS,SAAS,QAAQ,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,IACjD,KAAA;CAUN;AACF;;;AClGA,MAAM,cAAc,OAAO,IAAI,qBAAqB;AAEpD,SAAS,cAAc,OAAkD;CACvE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,MAAM,QAAQ,OAAO,eAAe,KAAK;CACzC,OAAO,UAAU,OAAO,aAAa,UAAU;AACjD;AAEA,SAAgB,oBAAoB,OAAyB;CAC3D,IAAI,UAAU,KAAA,KAAa,UAAU,MAAM,OAAO;CAClD,IAAI,MAAM,QAAQ,KAAK,GAAG,OAAO,MAAM,IAAI,mBAAmB;CAC9D,IAAI,cAAc,KAAK,GACrB,OAAO,OAAO,YACZ,OAAO,QAAQ,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAC1C,KACA,oBAAoB,KAAK,CAC3B,CAAC,CACH;CAEF,OAAO;AACT;;;;;;;;ACbA,SAAgB,iBAAiB,KAAqB;CACpD,OAAO,IACJ,QAAQ,kCAAkC,EAAE,CAAC,CAC7C,QAAQ,gBAAgB,EAAE,CAAC,CAC3B,KAAK,CAAC,CACN,YAAY;AACjB;AAEA,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,uBAAuB,SAA0B;CAC/D,OAAO,sBAAsB,SAAS,OAAc;AACtD;AAEA,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;AACF;AAEA,SAAgB,0BAA0B,SAA0B;CAClE,OAAO,yBAAyB,SAAS,OAAc;AACzD;AAEA,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,yBAAyB,SAA0B;CACjE,OAAO,wBAAwB,SAAS,OAAc;AACxD;AAEA,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,0BAA0B,SAA0B;CAClE,OAAO,yBAAyB,SAAS,OAAc;AACzD;AAEA,MAAM,uBAAuB,CAAC,MAAM;AAEpC,SAAgB,sBAAsB,SAA0B;CAC9D,OAAO,qBAAqB,SAAS,OAAc;AACrD;AAEA,MAAM,wBAAwB,CAAC,WAAW,MAAM;AAEhD,SAAgB,uBAAuB,SAA0B;CAC/D,OAAO,sBAAsB,SAAS,OAAc;AACtD;AAEA,MAAM,6BAA6B,CAAC,aAAa,UAAU;AAE3D,SAAgB,4BAA4B,SAA0B;CACpE,OAAO,2BAA2B,SAAS,OAAc;AAC3D;AAEA,MAAM,yBAAyB,CAAC,MAAM;AAEtC,SAAgB,wBAAwB,SAA0B;CAChE,OAAO,uBAAuB,SAAS,OAAc;AACvD;AAEA,MAAM,yBAAyB,CAAC,QAAQ,OAAO;AAE/C,SAAgB,wBAAwB,SAA0B;CAChE,OAAO,uBAAuB,SAAS,OAAc;AACvD;AAEA,MAAM,6BAA6B;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAgB,4BAA4B,SAA0B;CACpE,OACE,2BAA2B,SAAS,OAAc,KAClD,QAAQ,WAAW,UAAU;AAEjC;AAEA,MAAM,sBAAsB,CAAC,SAAS,MAAM;AAE5C,SAAgB,qBAAqB,SAA0B;CAC7D,OAAO,oBAAoB,SAAS,OAAc;AACpD;AAMA,MAAa,0BACX,SACA,mBAEA,IAAI,YACF,kCAAkC,QAAQ,yFAAyF,eAAe,EACpJ;;;ACtIF,SAAgB,gCAAgC,SAG9C;CACA,IAAI,uBAAuB,OAAO,GAChC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,yBAAyB,OAAO,GAClC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,0BAA0B,OAAO,GACnC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,sBAAsB,OAAO,GAC/B,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,uBAAuB,OAAO,GAChC,OAAO;EACL,QAAQ;EACR,QAAQ;CACV;CAGF,IAAI,4BAA4B,OAAO,GACrC,OAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;EAC3B,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;CAC7B;CAGF,IAAI,wBAAwB,OAAO,GACjC,OAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;EAC3B,QAAQ,IAAI,KAAK,MAAM,GAAG,CAAC;CAC7B;CAGF,IAAI,wBAAwB,OAAO,GACjC,OAAO;EACL,QAAQ,EAAE,GAAG,EAAE;EACf,QAAQ,EAAE,GAAG,EAAE;CACjB;CAGF,MAAM,uBAAuB,SAAS,UAAU;AAClD;;;AC9BA,MAAM,6BAAa,IAAI,QAA4B;AAEnD,SAAS,WAAuC,IAAoB;CAClE,MAAM,2BAAW,IAAI,IAA2B;CAChD,MAAM,2BAAW,IAAI,IAA2B;CAChD,MAAM,6BAAa,IAAI,IAAwB;CAE/C,KAAK,MAAM,CAAC,QAAQ,aAAa,OAAO,QAAQ,GAAG,EAAE,aAAa,CAAC,CAAC,GAAG;EACrE,MAAM,QAAQ;EACd,MAAM,WAAW,MAAM;EACvB,IAAI,CAAC,UAAU;EAEf,MAAM,UACJ,QAAQ,QAAQ,IAAI,gBAAgB,QAAiB,IAAI,CAAC;EAG5D,MAAM,aAAa,OAAO,YACxB,OAAO,QAAQ,OAAO,CAAC,CAAC,QAAQ,GAAG,SAAU,IAAY,OAAO,CAClE;EAEA,MAAM,SAAS,QAAQ,QAAQ,IAC1B,aAAa,QAAiB,IAC7B,MAAM,QAAmB;EAE/B,MAAM,WAA0B;GAC9B,MAAM,MAAM,QAAQ;GACpB;GACA,OAAO;GACP;GACA;GACA,WAAW,MAAM,aAAa,CAAC;GAC/B,SAAS,QAAQ,QAAQ;GACzB,eAAe;EACjB;EAEA,SAAS,IAAI,SAAS,MAAM,QAAQ;EACpC,SAAS,IAAI,SAAS,QAAQ,QAAQ;EACtC,WAAW,IAAI,UAAU,QAAQ;CACnC;CAEA,OAAO;EAAE;EAAU;EAAU;CAAW;AAC1C;AAEA,SAAS,SAAqC,IAAoB;CAChE,IAAI,MAAM,WAAW,IAAI,EAAuB;CAChD,IAAI,CAAC,KAAK;EACR,MAAM,WAAW,EAAE;EACnB,WAAW,IAAI,IAAyB,GAAG;CAC7C;CACA,OAAO;AACT;AAEA,SAAgB,YAKd,EAAE,IAAI,SAA6C;CACnD,MAAM,MAAM,SAAS,EAAE;CAEvB,IAAI;CAEJ,IAAI,OAAO,UAAU,UAEnB,QAAQ,IAAI,SAAS,IAAI,KAAK,KAAK,IAAI,SAAS,IAAI,KAAK;MACpD,IAAI,SAAS,OAAO,UAAU,UAAU;EAC7C,MAAM,IAAI;EAIV,IAAI,EAAE,OAAO;GACX,QAAQ,IAAI,WAAW,IAAI,EAAE,KAAK;GAClC,IAAI,CAAC,SAAS,EAAE,MACd,QAAQ,IAAI,SAAS,IAAI,EAAE,IAAI,KAAK,IAAI,SAAS,IAAI,EAAE,IAAI;EAE/D;EAGA,IAAI,CAAC,OACH,QAAQ,IAAI,WAAW,IAAI,CAAC;EAI9B,IAAI,CAAC,SAAS,QAAQ,CAAC,GAAG;GACxB,MAAM,SAAS,aAAa,CAAU;GACtC,QAAQ,IAAI,SAAS,IAAI,MAAM;EACjC;CACF;CAEA,IAAI,CAAC,OACH,MAAM,IAAI,YACR,6BAA6B,KAAK,UAChC,OAAO,UAAU,WAAW,QAAQ,gBACtC,GACF;CAGF,OAAO;EACL,SAAS,MAAM;EACf,YAAY,MAAM;EAClB,WAAW,MAAM;EACjB,QAAQ,MAAM;EACd,QAAQ,MAAM;EACd,OAAO,MAAM;EACb,SAAS,MAAM;EACf,eAAe,MAAM;CACvB;AACF;;;AChHA,MAAa,eAAuB,UAAU;;AAE9C,MAAa,iBAAiB;AAC9B,MAAa,uBAAuB;AACpC,MAAa,yBAAyB;AACtC,MAAa,qBAAqB;AAClC,MAAa,uBAAuB;AASpC,MAAa,sBAA8B;AAC3C,MAAa,sBAA8B;AAC3C,MAAa,gBAAwB;AACrC,MAAa,kBAA0B,eAAe;;AAEtD,MAAa,wBAAgC,eAAe;;AAE5D,MAAa,kBAAkB;AAC/B,MAAa,mBAAmB;AAChC,MAAa,iBAAiB;AAC9B,MAAa,aAAa;AAC1B,MAAa,cAAc;AAC3B,MAAa,wBAAwB;AACrC,MAAa,wBAAwB;AACrC,MAAa,yBAAyB;AACtC,MAAa,uBAAuB;AACpC,MAAa,qBAAqB;AAClC,MAAa,uBAAuB;AACpC,MAAa,gCAAgC;AAC7C,MAAa,oBAAoB;AACjC,MAAa,oBAAoB;AAIjC,SAAgB,gBACd,QAC0B;CAC1B,OAAO,OAAO,QAAQ,UAAU,OAAO,OAAO,SAAS,KAAA;AACzD;AAEA,SAAgB,gBAAgB,QAA6C;CAC3E,OAAO,OAAO,MAAM,UAAU,OAAO,KAAK,SAAS,KAAA;AACrD;;;;;;AAOA,SAAgB,iBAAiB,QAAkC;CACjE,OAAO,QAAQ,OAAO,MAAM,WAAW,OAAO,QAAQ,OAAO;AAC/D;;;;;;;;;;AAaA,SAAgB,uBACd,QACA,MACwB;CACxB,IAAI,CAAC,OAAO,MAAM,WAAW,OAAO,QAAQ,kBAAkB,OAC5D,OAAO,CAAC;CAGV,MAAM,SAAS,QAAQ,MAAM,cAAc;CAC3C,IAAI,CAAC,QAAQ,OAAO,CAAC;CAErB,MAAM,cAAc,OAAO,YAAY;CACvC,IAAI,CAAC,mBAAmB,WAAW,GAAG,OAAO,CAAC;CAE9C,OAAO;EACL,UAAU,YAAY;EACtB,SAAS,YAAY;EACrB,aAAa,YAAY,WAAW,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG;CAClE;AACF;AAIA,SAAS,YAAY,OAAgB;CACnC,IAAI,iBAAiB,OAAO,OAAO;CACnC,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAC9D,OAAO;CAET,OAAO,OAAO,KAAK;AACrB;AAEA,SAAS,iBAAiB,OAAoC;CAC5D,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa,OAC9D,OAAO,OAAQ,MAA+B,OAAO;CAEvD,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,OAAO,KAAK;AACvD;;;;;;AAOA,SAAgB,iBACd,MACA,QACM;CACN,IAAI,CAAC,QAAQ,OAAO,WAAW,GAAG;CAElC,KAAK,MAAM,SAAS,QAClB,KAAK,gBAAgB,YAAY,KAAK,CAAC;CAGzC,KAAK,UAAU;EACb,MAAM,eAAe;EACrB,SAAS,iBAAiB,OAAO,EAAE;CACrC,CAAC;AACH;AAEA,SAAgB,gBAAgB,MAAwB,OAAsB;CAC5E,iBAAiB,MAAM,CAAC,KAAK,CAAC;AAChC;;;;;;;;;;AAWA,MAAM,iCAAiB,IAAI,QAAgB;AAE3C,SAAgB,mBAAmB,QAAkC;CACnE,KAAK,MAAM,SAAS,QAClB,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,eAAe,IAAI,KAAK;AAG9B;;AAGA,SAAgB,sBAAsB,QAAqC;CACzE,IAAI,OAAO,WAAW,GAAG,OAAO;CAChC,OAAO,OAAO,OACX,UACC,OAAO,UAAU,YAAY,UAAU,QAAQ,eAAe,IAAI,KAAK,CAC3E;AACF;AAIA,SAAS,kBAAkB,OAAwB;CACjD,IAAI;EACF,OACE,KAAK,UAAU,QAAQ,MAAM,UAC3B,OAAO,UAAU,WAAW,MAAM,SAAS,IAAI,KACjD,KAAK;CAET,QAAQ;EAEN,OAAO,OAAO,KAAK;CACrB;AACF;AAEA,SAAS,4BAA4B,OAA2B;CAC9D,IAAI;CACJ,KAAK,MAAM,SAAS,OAAO;EACzB,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW;EAC3C,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,YAAY,SAAS,YAAY,SAAS,WACrD,OAAO;EAET,IAAI,QAAQ,SAAS,MAAM,OAAO;EAClC,OAAO;CACT;CACA,OAAO;AACT;;;;;;;;;AAUA,SAAgB,eAAe,OAAgC;CAC7D,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO;EACT,KAAK,UACH,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK;EACtD,KAAK,WACH,OAAO;EACT,KAAK,UACH,OAAO,MAAM,SAAS;EACxB,KAAK,aACH,OAAO;EACT,SACE;CACJ;CAEA,IAAI,UAAU,MAAM,OAAO;CAC3B,IAAI,MAAM,QAAQ,KAAK,KAAK,4BAA4B,KAAK,GAC3D,OAAO;CAET,OAAO,kBAAkB,KAAK;AAChC;AAeA,SAAgB,iBACd,WACA,SACqC;CACrC,IAAI,YAAY,SAAS,CAAC,WAAW,OAAO,KAAA;CAE5C,MAAM,WACJ,OAAO,YAAY,aAAa,QAAQ,EAAE,GAAG,UAAU,CAAC,IAAI;CAE9D,IAAI,CAAC,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,WAAW,GAAG,OAAO,KAAA;CAC5D,OAAO;AACT;;AAGA,SAAgB,mBACd,WACA,SACY;CACZ,MAAM,WAAW,iBAAiB,WAAW,OAAO;CACpD,IAAI,CAAC,UAAU,OAAO,CAAC;CAEvB,MAAM,aAAyB,CAAC;CAChC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,GAChD,WAAW,GAAG,wBAAwB,SAAS,eAAe,KAAK;CAErE,OAAO;AACT;;AAGA,SAAgB,iBACd,WACA,SACyB;CACzB,MAAM,WAAW,iBAAiB,WAAW,OAAO;CACpD,OAAO,WAAW,GAAG,kBAAkB,SAAS,IAAI,CAAC;AACvD;;;;;AAQA,SAAgB,aAAqB;CACnC,OAAO,YAAY,IAAI;AACzB;AAEA,SAAgB,WAAW,OAAuB;CAChD,OAAO,KAAK,OAAO,YAAY,IAAI,IAAI,SAAS,GAAG,IAAI;AACzD;;;ACtOA,SAAS,qBAMP,QAC0D;CAC1D,OACE,OAAO,WAAW,cAAc,OAAO,YAAY,SAAS;AAEhE;AAEA,SAAS,oBAMP,QACgD;CAChD,OAAO,OAAO,WAAW;AAC3B;AAEA,MAAM,+BACJ,QACA,WAEA,UAAU,OAAe,WAAmB;CAC1C,MAAM,MAAM,+BAA+B,MAAM,GAAG,OAAO;CAC3D,IAAI,QACF,OAAO,KACL;GACG,aAAa;GACb,cAAc;EACf,GAAG,uBAAuB,MAAM;CAClC,GACA,GACF;MAEA,QAAQ,KAAK,GAAG;AAEpB,GAAG,GAAI;AAET,MAAa,wBAMX,EACA,IACA,SACA,cACA,MACA,QAAQ,mBAC8D;CACtE,MAAM,MAAM,cAAc,UAAU,aAAa,SAAS,KAAA;CAC1D,MAAM,kBAAmC;EAAE;EAAM,QAAQ;CAAa;CACtE,MAAM,iCAAiC,4BACrC,iBACA,GACF;CAKA,MAAM,qBACJ,OAAO,KAAK,GAAG,KAAK,CAAC,CACrB,QACC,SAAS,YAAY;EAAE;EAAI,OAAO;CAAY,CAAC,CAAC,CAAC,OACpD;CAEA,IAAI,eAAe;CAEnB,MAAM,8BAA4D;EAChE,MAAM,+BAAe,IAAI,IASvB;EAEF,MAAM,iCAAiB,IAAI,IAIzB;EAKF,KAAK,MAAM,UAAU,SACnB,IAAI,CAAC,eAAe,IAAI,MAAM,GAC5B,eAAe,IAAI,QAAQ,CAAC,CAAC;EAIjC,OAAO;;;;GAIL,QAAQ,WAA8B;IACpC,IAAI,cACF,MAAM,IAAI,YACR,uIACF;IAGF,MAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;IAIxD,MAAM,4CAA4B,IAAI,IAA8B;IACpE,KAAK,MAAM,UAAU,SAAS;KAC5B,IAAI,UAAU,aAAa,IAAI,MAAM;KACrC,IAAI,CAAC,SAAS;MACZ,UAAU;MACV,aAAa,IAAI,QAAQ,OAAO;MAChC,0BAA0B,IAAI,MAAM;KACtC;IACF;IAEA,OAAO;;;;;;;;;;;;AAYL,OACE,gBAMG;KACH,KAAK,MAAM,UAAU,SAAS;MAC5B,IAAI,aAAa,IAAI,MAAM,MAAM,gBAC/B,IAAI,0BAA0B,IAAI,MAAM,GAEtC,aAAa,IAAI,QAAQ,CAAC,CAAC;WAI3B;MAIJ,aAD6B,IAAI,MAC1B,CAAC,CAA6C,KACnD,WACF;KACF;IACF,EACF;GACF;;;;;GAKA,SAAS,WAA8B;IACrC,MAAM,UAAU,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;IACxD,OAAO;;;;;;;;;;;;KAYL,WACE,aACG;MACH,OAAO;;;;AAIL,KACE,mBAKG;OACH,KAAK,MAAM,UAAU,SAEnB,eAAe,IAAI,MAAM,CAAC,CAAE,KAAK;QAC/B,QAAQ;QACE;OACZ,CAAC;MAEL,EACF;KACF;;;;KAIA,KACE,mBAIG;MACH,KAAK,MAAM,UAAU,SAEnB,eAAe,IAAI,MAAM,CAAC,CAAE,KAAK,EAC/B,QAAQ,eACV,CAAC;KAEL;IACF;GACF;GACA,GAAG;IACD;IACA;GACF;EACF;CACF;CAEA,MAAM,mBAAmB,OAAO,YAC9B,mBAAmB,KAAK,cAAc,CACpC,WACA,sBAAwC,CAC1C,CAAC,CACH;CAIA,OAAO;EACL,GAAG;;;;;EAKH,GAAG;GACD,kBAAkB,EAChB,QACA,SAIC;IACD,OAAQ,iBAAiB,MAAM,CAAS,EAAE,eAAe,IACvD,MACF;GACF;GACA,QAAQ;IACN,MAAM,wBACJ,cACG;KACH,MAAM,eAAe,iBAAiB,UAAU,CAAC,EAAE;KAEnD,MAAM,qBAAqB,OAAO,YAChC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,MAAM;MAEvC,IAAI,CAAC,WAAW,YAAY,gBAAgB,OAAO,CAAC,QAAQ,CAAC,CAAC;MAE9D,OAAO,CAAC,QAAQ,QAAQ,OAAO,mBAAmB,CAAC;KACrD,CAAC,CACH;KAQA,MAAM,sBAAsB,OAAO,YACjC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,MAAM;MAEvC,IAAI,CAAC,WAAW,YAAY,gBAAgB,OAAO,CAAC,QAAQ,CAAC,CAAC;MAE9D,OAAO,CAAC,QAAQ,QAAQ,OAAO,oBAAoB,CAAC;KACtD,CAAC,CACH;KASA,MAAM,cAAc,YAAY;MAC9B;MACA,OAAO;KACT,CAAC;KAED,IAAI,OAAO,KAAK,YAAY,UAAU,CAAC,CAAC,WAAW,GACjD,MAAM,IAAI,YACR,mCAAmC,OAAO,SAAS,GACrD;KAGF,MAAM,kBAAuB,OAAO,OAAO,YAAY,UAAU,CAAC,CAAC;KAEnE,MAAM,iBAAiB,gCACrB,gBAAgB,WAAW,CAC7B;KAEA,MAAM,wBAAwB,EAC5B,OAAO,EACL,KAAK,CACH,GACG,gBAAgB,OAAO,eAAe,OACzC,GACA,GACG,gBAAgB,OAAO,eAAe,OACzC,CACF,EACF,EACF;;;;KAKA,SAAS,oBACP,cACA;MACA,MAAM,uBACJ,SACA,gBACG;OACH,MAAM,QAAQ,WAAW;QACvB,IAEE,gBAAgB,KAAA,GAChB;SACA,IAAI,CAAC,SAAS,OAEZ,OAAO;SAGT,IAAK,QAAQ,QAAmB,aAE9B,OAAO;QAEX;QAEA,IAAI,QAAQ,SAAS;QAErB,IACE,iBACC,UAAU,KAAA,KAAa,QAAQ,eAEhC,QAAQ;QAIV,OAAO,SAAS,KAAA;OAClB,CAAC;OAED,MAAM,sBAAsB,WAAW;QACrC,MAAM,SAAU,GAAG,EAAU,SAAS,SAAS;QAE/C,OAAO,SAAS,QACZ,qBACE,YAAY,cAAc,OAC1B,oBAAoB,QAAQ,KAAK,GACjC,YAAY,WACZ,GAAG,EAAE,WACL,MACF,IACA,KAAA;OACN,CAAC;OAKD,IAAI,SAAS,SACX,OAAO;;;;;;;;;;QAUL,OAAO;;;;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;UACzC,SAAS,SAAS;SACpB;;;;SAWA,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;UACzC,SAAS,SAAS;UAClB,IAAI,QAAQ;WACV,OAAO,MAAM;UACf;SACF;QAQF;;;;;;;;;;;;;;;;;;;;QAoBA,KAAK,EACH,IAAI,QAAQ;SACV,OAAO,oBAAoB;QAC7B,EACF;OACF;YAEA,OAAO;;;;;;;;;;QAUL,OAAO;;;;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;SAC3C;;;;SAWA,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,oBAAoB,SAAS,KAAK;UACzC,IAAI,QAAQ;WACV,OAAO,MAAM;UACf;SACF;QAQF;;;;;;;;;;;;;;;;;;;;QAoBA,KAAK,EACH,IAAI,QAAQ;SACV,OAAO,oBAAoB;QAC7B,EACF;OACF;MAEJ;MAEA,MAAM,MAAM,oBAAoB,YAAY;;;;MAK5C,SAAS,MACP,GACA;OACA,MAAM,SAAS,aAAa,IAAI,MAAM,MAAM,CAAC;OAC7C,OAAO,oBACL,QAIA,EAAE,KACJ;MACF;MAEA,IAAa,QAAQ;MAErB,OAAO;KAGT;KAEA,OAAO,EACL,cAAc,gBAA6B;MACzC,OAAO,EACL,SAAS,WAAmB;OAC1B,MAAM,qBACJ,eACG;QACH,MAAM,UAAU,aAAa,IAAI,MAAM;QAGvC,IAAI,YAAY,gBAAgB;SAC9B,WAAW,yBAAyB;SACpC,OAAO,oBAAoB;QAC7B;QAGA,IAAI,CAAC,SAAS;SACZ,WAAW,yBAAyB;SACpC,+BAA+B,OAAO,SAAS,GAAG,MAAM;SACxD,OAAO,oBAAoB,qBAAqB;QAClD;QAGA,MAAM,iBAAiB,IAAI,MAEzB,oBAAoB,OAAO,CAAC,MAAM;QACpC,IAAI,kBAAkB;QACtB,KACE,IAAI,IAAI,GACR,IAAI,oBAAoB,OAAO,CAAC,QAChC,KACA;SACA,MAAM,OAAO,oBAAoB,OAAO,CAAC;SACzC,MAAM,SAAS,KAAK,WAAW;SAE/B,IAAI,WAAW,SAAS;UACtB,WAAW,yBAAyB;UACpC,OAAO,oBAAoB;SAC7B;SAEA,IAAI,WAAW,KAAA,GAAW;SAE1B,eAAe,qBAAqB;QACtC;QACA,eAAe,SAAS;QAExB,WAAW,0BAA0B,eAAe;QACpD,WAAW,yBACT,mBAAmB,OAAO,CAAC;QAE7B,MAAM,kBAAkB,CACtB,GAAG,mBAAmB,SACtB,GAAG,cACL;QAEA,WAAW,wBAAwB,gBAAgB;QAGnD,IAAI,gBAAgB,WAAW,GAAG;SAChC,WAAW,yBAAyB;SAEpC,OAAO,oBAAoB,qBAAqB;QAClD;QAEA,MAAM,gBACJ,gBAAgB,WAAW,IACvB,gBAAgB,KAChB,gBAAgB,QAAQ,GAAG,MAAM;SAC/B,OAAO,aAAa,GAAG,GAAG,IAAI;QAChC,CAAC;QAEP,WAAW,yBAAyB;QACpC,OAAO,oBAAoB,aAAoB;OACjD;OAIA,MAAM,OAAO,SAAgB;QAC3B,MAAM,aAA6C;UAChD,aAAa,OAAO,SAAS;UAC7B,cAAc;QACjB;QAEA,IAAI;SACF,MAAM,SAAS,kBAAkB,UAAU;SAC3C,KAAK,MACH;UACE,GAAG;UACH,GAAG,uBAAuB,iBAAiB,IAAI;SACjD,GACA,oBACF;SACA,OAAO;QACT,SAAS,OAAO;SACd,gBAAgB,MAAM,KAAK;SAC3B,KAAK,MACH;UACE,GAAG;UACH,GAAG,uBAAuB,iBAAiB,IAAI;UAC/C,GAAG,cAAc,KAAK;SACxB,GACA,kBACF;SACA,MAAM;QACR,UAAU;SACR,MAAM,cAAc,UAAU;QAChC;OACF;OAEA,IAAI,MAAM,WAAW,KAAK,QACxB,OAAO,KAAK,OAAO,gBACjB,yBACC,SAAS;QACR,IAAI;SACF,OAAO,IAAI,IAAI;QACjB,UAAU;SACR,KAAK,IAAI;QACX;OACF,CACF;OAGF,OAAO,IAAI;MACb,EACF;KACF,EACF;IACF;IAEA,MAAM,oBAAoB,OAAO,YAC/B,mBAAmB,KAAK,cAAc,CACpC,WACA,qBAAqB,SAAS,CAChC,CAAC,CACH;IAIA,eAAe;IAEf,QAAQ,QAAqB;KAC3B,OAAO,OAAO,YACZ,mBAAmB,KAAK,cAAc,CACpC,WACA,kBAAkB,UAAU,CAAC,YAAY,GAAG,CAC9C,CAAC,CACH;IAKF;GACF;EACF;CACF;AACF;;;ACjwBA,MAAMC,qBAAmB,WACvB,GAAG,WAAW,YAAY,OAAO,SAAS,CAAC,CAAC,EAAE;AAEhD,MAAa,6BAMX,EACA,IACA,oBASI;CACJ,MAAM,mCAAmB,IAAI,IAAiB;CAE9C,MAAM,0BAA0B,WAC9B,cAAc,SAAS,oBAAoB,EACzC,QAAQ,CAAC,OAAO,MAAM,EACxB,CAAC,CACH;CAEA,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;EACnB,CAAC;EAED,MAAM,gBAAgB,WAAWA,kBAAgB,YAAY,MAAM;EAEnE,IAAI,MACF,iBAAiB,IAAI,aAAa;EACpC,IAAI,KACF,OAAO;EAGT,MAAM,kBAAkB;GACtB,OAAO,cAAc,UAAU,eAAe,EAC5C,SAAS,MAAM;IAkBb,OAfe,OAAO,QAAQ,YAAY,OAAO,CAAC,CAAC,QAChD,KAAK,CAAC,SAAS;KAEd,IAAI,IAAI,WAAW,IAAI,GAAG,OAAO;KAEjC,IAAI,OAAO,EAAE,MAAM;MACjB,MAAM,wBAAwB;MAC9B,UAAU;KACZ,CAAC;KAED,OAAO;IACT,GACA,CAAC,CAGS;GACd,EACF,CAAC;EACH;EAEA,MAAM,UAAU;EAChB,iBAAiB,IAAI,eAAe,GAAG;EACvC,OAAO;CACT;CAEA,OAAO;AACT;;;;;;ACrGA,SAAgB,aACd,YAK6B;CAC7B,OACE,GAAG,YAAY,YAAY,KAC3B,GAAG,YAAY,kBAAkB,KACjC,GAAG,YAAY,eAAe,KAC9B,GAAG,YAAY,qBAAqB;AAExC;AAgHA,MAAa,yBAQX,EACA,QACA,oBASI;CACJ,MAAM,mCAAmB,IAAI,IAAiB;;;;;;;;;;;;CAa9C,MAAM,mBAMJ,SAiBG;EACH,MAAM,EAAE,YAAY;EACpB,MAAM,SAAU,KAA6B;EAC7C,MAAM,gBAAiB,KACpB;EACH,MAAM,aAAc,KAAiC;EAErD,IAAI,aAA0D;EAE9D,IAAI,QAAQ;GACV,MAAM,YAAa,OAAmC;GACtD,IAAI,CAAC,aAAa,CAAC,SAAS,SAAgB,GAC1C,MAAM,IAAI,YACR,uCAAuC,KAAK,UAC1C,MACF,EAAE,6GAEJ;GAEF,aAAa;EACf;EAEA,IAAI,CAAC,cAAc,CAAC,YAClB,MAAM,IAAI,YACR,sKAEF;EAGF,IAAI;EACJ,IAAI;EAEJ,IAAI,YAAY;GACd,iBAAiB,WAAW;GAC5B,aAAa,WAAW;EAC1B,OAAO,IAAI,YAGT,IACE,GAAG,YAAY,eAAe,KAC9B,GAAG,YAAY,qBAAqB,GACpC;GACA,aAAc,WAAmB;GACjC,MAAM,WAAY,WAAmB;GACrC,MAAM,YACJ,YAAY,QAAQ,QAAQ,IAAI,aAAa,QAAQ,IAAI,KAAA;GAC3D,iBAAiB,YACb,GAAG,UAAU,GAAG,WAAW,SAC3B,WAAW;EACjB,OAAO;GACL,MAAM,SAAU,WAAmB;GAKnC,IAAI,CAAC,QACH,MAAM,IAAI,YACR,oFACF;GAGF,iBAAiB,OAAO;GACxB,aAAa,WAAW;EAC1B;EAGF,IAAI,CAAC,kBAAkB,CAAC,YACtB,MAAM,IAAI,YAAY,qCAAqC;EAG7D,MAAM,4BACJ,WAAW,GAAG,WAAW,YAAY,cAAc,CAAC,EAAE;EAkBxD,MAAM,SAAS,iBAAiB,IAAI,yBAAyB;EAC7D,IAAI,QACF,OAAO;EAGT,MAAM,MAAM,cAAc,SAAS,2BAA2B,EAC5D,QAAQ,WACV,CAAC;EACD,iBAAiB,IAAI,2BAA2B,GAAG;EACnD,OAAO;CACT;CAEA,OAAO;AACT;;;ACpRA,SAAgB,wBAAwB,EACtC,SACA,aAIkB;CAGlB,IAAI,UAAU,KAAK,OAAO,GACxB,OAAO;CAGT,MAAM,aAAa,iBAAiB,OAAO;CAE3C,IAAI;CAEJ,IAAI,uBAAuB,UAAU,GACnC,MAAM;CAGR,IAAI,0BAA0B,UAAU,GACtC,MAAM;CAGR,IAAI,yBAAyB,UAAU,GACrC,MAAM;CAGR,IAAI,0BAA0B,UAAU,GACtC,IACE,cACC,UAAU,YAAY,CAAC,CAAC,SAAS,KAAK,KACrC,UAAU,YAAY,CAAC,CAAC,SAAS,IAAI,IAEvC,MAAM;MAEN,MAAM;CAIV,IAAI,sBAAsB,UAAU,GAClC,MAAM;CAGR,IAAI,uBAAuB,UAAU,GACnC,MAAM;CAGR,IAAI,4BAA4B,UAAU,GACxC,MAAM;CAGR,IAAI,wBAAwB,UAAU,GACpC,MAAM;CAGR,IAAI,wBAAwB,UAAU,GACpC,MAAM;CAGR,IAAI,4BAA4B,UAAU,GACxC,MAAM;CAGR,IAAI,qBAAqB,UAAU,GACjC,MAAM;CAGR,IAAI,QAAQ,KAAA,GACV,OAAO;CAGT,MAAM,uBAAuB,SAAS,YAAY;AACpD;;;AC5DA,MAAM,mBAAmB,WACvB,GAAG,WAAW,YAAY,OAAO,SAAS,CAAC,CAAC,EAAE;AAEhD,MAAa,6BAMX,EACA,IACA,eACA,sBAiBI;CACJ,MAAM,mCAAmB,IAAI,IAAiB;CAC9C,MAAM,6CAA6B,IAAI,IAAiB;CACxD,MAAM,+CAA+B,IAAI,IAAiB;CAE1D,MAAM,6BAA6B,YACjC,GAAG,QAAQ;CAEb,MAAM,4BAA4B,YAAoB;EACpD,MAAM,WAAW,0BAA0B,OAAO;EAClD,MAAM,WAAW,6BAA6B,IAAI,QAAQ;EAC1D,IAAI,UAAU,OAAO;EAErB,MAAM,MAAM,cAAc,SAAS,QAAQ;EAC3C,6BAA6B,IAAI,UAAU,GAAG;EAE9C,IAAI,UAAU,EACZ,SAAS,OAAY;GACnB,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAChD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAChD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,OAAO,CAAC;IAAG,UAAU;GAAM,CAAC;GAClD,OAAO,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,OAAO,CAAC;IAAG,UAAU;GAAM,CAAC;GACrD,QAAQ,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACrC,WAAW,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACxC,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAC3D,gBAAgB,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAC5D,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,OAAO;IAAG,UAAU;GAAM,CAAC;GAC3D,KAAK,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC7C,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC5C,KAAK,EAAE,MAAM;IAAE,MAAM;IAAK,UAAU;GAAM,CAAC;EAC7C,GACF,CAAC;EAED,OAAO;CACT;CAEA,MAAM,0BAA0B,aAAkB;EAChD,MAAM,WAAW,GAAG,SAAS,KAAK;EAElC,MAAM,WAAW,2BAA2B,IAAI,QAAQ;EACxD,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,cAAc,SAAS,QAAQ;EAC3C,2BAA2B,IAAI,UAAU,GAAG;EAE5C,IAAI,UAAU,EACZ,SAAS,OAAY;GAGnB,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GACjD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GACjD,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,QAAQ,CAAC;IAAG,UAAU;GAAM,CAAC;GACnD,OAAO,EAAE,MAAM;IAAE,MAAM,CAAC,CAAC,QAAQ,CAAC;IAAG,UAAU;GAAM,CAAC;GACtD,QAAQ,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACrC,WAAW,EAAE,QAAQ,EAAE,UAAU,MAAM,CAAC;GACxC,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GAC5D,gBAAgB,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GAC7D,eAAe,EAAE,MAAM;IAAE,MAAM,CAAC,QAAQ;IAAG,UAAU;GAAM,CAAC;GAC5D,KAAK,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC7C,IAAI,EAAE,MAAM;IAAE,MAAM,CAAC,GAAG;IAAG,UAAU;GAAM,CAAC;GAC5C,KAAK,EAAE,MAAM;IAAE,MAAM;IAAK,UAAU;GAAM,CAAC;EAC7C,GACF,CAAC;EAED,OAAO;CACT;CAEA,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;EACnB,CAAC;EAED,MAAM,gBAAgB,WAAW,gBAAgB,YAAY,MAAM;EAEnE,MAAM,WAAW,iBAAiB,IAAI,aAAa;EACnD,IAAI,UACF,OAAO;EAGT,MAAM,MAAM,cAAc,SAAS,aAAa;EAChD,iBAAiB,IAAI,eAAe,GAAG;EAEvC,IAAI,UAAU,EACZ,SAAS,MAAW;GAClB,MAAM,qCACJ,SACA,WACA,YACG;IACH,MAAM,UAAU,wBAAwB;KACtC;KACA;IACF,CAAC;IAED,IAAI,SACF,OAAO,EAAE,MAAM;KACb,MAAM,yBAAyB,OAAO;KACtC,UAAU;IACZ,CAAC;IAGH,QAAQ,SAAR;KACE,KAAK,OACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,UACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,UACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,WACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,QACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,YACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,SACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,MACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,QACH,OAAO,EAAE,MAAM;MACb,MAAM;MACN,UAAU;KACZ,CAAC;KACH,KAAK,SAEH,OAAO;KACT,SACE,MAAM,IAAI,YACR,6BAA6B,QAAQ,cAAc,SACrD;IACJ;GACF;GACA,MAAM,SAAS,OAAO,QAAQ,YAAY,OAAO,CAAC,CAAC,QAChD,KAAK,CAAC,KAAK,WAAW;IAErB,IAAI,IAAI,WAAW,IAAI,GAAG,OAAO;IAGjC,IAAI,UAAU;IACd,IAAI,GAAG,OAAO,QAAQ,GAAG;KACvB,MAAM,OAAQ,MACX;KACH,IAAI,QAAQ,OAAO,GAAG,UAAU;IAClC;IAEA,IAAI,aAAa,KAAK,GAAG;KACvB,MAAM,WAAW,gBAAgB,EAC/B,YAAY,MACd,CAAC;KAED,IAAI,OAAO,EAAE,MAAM;MACjB,MAAM,UAAU,uBAAuB,QAAQ,IAAI;MACnD,UAAU;KACZ,CAAC;IACH,OAAO;KACL,MAAM,QAAQ,kCACZ,MAAM,WAAW,GACjB,KACA,OACF;KACA,IAAI,UAAU,MACZ,IAAI,OAAO;IAEf;IAEA,OAAO;GACT,GACA,CAAC,CACH;GAEA,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,CAAC,CAAC,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;IAIrB,MAAM,eAAgB,MAAc;IACpC,MAAM,iBAAiB,YAAY;KACjC;KACA,OAAO;IACT,CAAC;IACD,MAAM,iBAAiB,oBAAoB,EACzC,QAAQ,eAAe,OACzB,CAAC;IAED,IAAI,OAAO,EAAE,MAAM;KACjB,MAAM;KACN,UAAU;IACZ,CAAC;IAED,OAAO;GACT,GACA,CAAC,CAIH;GAEA,OAAO;IACL,GAAG;IACH,GAAG;IACH,KAAK,EAAE,MAAM;KAAE,MAAM,CAAC,GAAG;KAAG,UAAU;IAAM,CAAC;IAC7C,IAAI,EAAE,MAAM;KAAE,MAAM,CAAC,GAAG;KAAG,UAAU;IAAM,CAAC;IAC5C,KAAK,EAAE,MAAM;KAAE,MAAM;KAAK,UAAU;IAAM,CAAC;GAC7C;EACF,EACF,CAAC;EAED,OAAO;CACT;CAEA,OAAO;AACT;;;ACjUA,MAAa,4BAMX,EACA,kBAWI;CACJ,MAAM,gBAAgB,OAAO,EAC3B,QACA,YACA,kBACA,uBACA,gBACA,iBACA,qBAAqB,YAsCjB;EACJ,IAAI,QAAQ,IAAI,aAAa,eAC3B,QAAQ,KACN,kHAAkH,KAAK,UACrH;GACE;GACA;GACA;GACA;GACA;EACF,CACF,GACF;EAGF,MAAM,mBAAmB;GACvB,QAFa,YAER;GACL;GACA;GACA;GACA;GACA;GACA;GACA;EACF,CAAC;CACH;CAEA,OAAO;AACT;;;AChEA,MAAa,yBAMX,EACA,SAAS,iBACT,qBASI;CACJ,MAAM,sBAAsB,WAAW,eAAe,EAAE,MAAM,CAAC;CAE/D,OAAO,OAAO,QAAsB;EAClC,MAAM,cAAc,kBAChB,MAAM,gBAAgB,GAAG,IACxB,CAAC;EAEN,OAAO;GACL,GAAG;GACH,WAAW,oBAAoB,CAAC,CAAC,WAAW;EAC9C;CACF;AACF;;;AClEA,SAAgB,aACd,KACA,QAAQ,OAAO,WACf,uBAAO,IAAI,QAAQ,GACnB;CACA,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;CAC7C,IAAI,KAAK,IAAI,GAAG,GAAG;CACnB,KAAK,IAAI,GAAG;CAEZ,IAAI,MAAM,QAAQ,GAAG,GAAG;EACtB,KAAK,MAAM,QAAQ,KACjB,aAAa,MAAM,OAAO,IAAI;EAEhC;CACF;CAEA,MAAM,eAAe,OAAO,eAAe,GAAG;CAC9C,IAAI,iBAAiB,OAAO,aAAa,iBAAiB,MACxD;CAEF,OAAO,eAAe,KAAK,KAAK;CAChC,KAAK,MAAM,OAAO,OAAO,KAAK,GAAG,GAC/B,aAAa,IAAI,MAAM,OAAO,IAAI;AAEtC;;;ACJA,MAAa,+BAOX,EACA,IACA,eACA,qBACA,yBAuBI;CACJ,QAAkD,EAChD,OACA,aAAa,QACb,gBAeI;EACJ,MAAM,WAAW,oBAAoB,EAC5B,MACT,CAAC;EACD,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,MAAM,CAAC;EAElE,MAAM,cAAc,YAAY;GAC9B;GACA;EACF,CAAC;EAED,OAAO,cAAc,aAAa,MAAM;GACtC,OAAO,GACJ,GAAG,UAAU,OAAO,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,MAAM;IACnD,MAAM;IACN,UAAU;IACV,mBAAmB;IACnB,aAAa,aAAa,UAAU,OAAO,OAAO,KAAK,CAAC;IACxD,YAAY,eAAe,OAAO,OAAO,MAAM,UAAU;KACvD,mBAAmB;MACjB,UAAU;MACV,QAAQ;KACV,CAAC;KACD,mBAAmB;MACjB,UAAU;MACV,QAAQ;KACV,CAAC;IACH;IACA,MAAM,EACJ,OAAO,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;IAAM,CAAC,EAClD;IACA,SAAS,OAAO,OAAO,MAAM,KAAK,UAAU;KAC1C,IAAI,aAAa,CAAE,MAAM,UAAU,GAAG,GACpC,MAAM,IAAI,gBAAgB,oCAAoC;KAGhE,aAAa,IAAI;KAEjB,OAAQ,GACL,OAAO,EAAE,OAAO,MAAM,EAAE,CAAC,CAAC,CAC1B,KAAK,YAAY,KAAK,CAAC,CACvB,MACC,IAAI,UAAU,MAAM,CACjB,OAAO,UAAU,CAAC,CAClB,MAAM,yBAAyB,IAAI,CAAQ,CAAC,CAAC,IAAI,KACtD,CAAC,CACA,KAAK,sBAAsB,CAAC,CAC5B,MAAM,MAAW,EAAE,KAAK;IAC7B;GACF,CAAC,EACH;EACF,CAAC;CACH;AACF;;;AC5HA,MAAa,yBAET;CACF,OAAO;EACL,YAAY,EACV,MAAM;GACJ,aAAa;GACb,aAAa;GACb,MAAM,CAAC;GACP,YAAY,CAAC;GACb,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,yCACR,EACF,EACF,EACF;GACA,WAAW,EACT,OAAO;IACL,aAAa;IACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,6CACR,EACF,EACF;GACF,EACF;EACF,EACF;EACA,iBAAiB;GACf,MAAM;IACJ,aAAa;IACb,aAAa;IACb,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,SACR;IACF,CACF;IACA,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,yCACR,EACF,EACF,EACF;IACA,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,6CACR,EACF,EACF;IACF,EACF;GACF;GACA,QAAQ;IACN,aAAa;IACb,aAAa;IACb,MAAM,CAAC;IACP,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,SACR;IACF,CACF;IACA,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,6CACR,EACF,EACF;IACF,EACF;GACF;EACF;CACF;CACA,YAAY,EACV,SAAS;EACP,mBAAmB;GACjB,MAAM;GACN,YAAY;IACV,cAAc;KACZ,aACE;KACF,MAAM;IACR;IACA,WAAW;KACT,aAAa;KACb,MAAM;IACR;IACA,KAAK;KACH,aAAa;KACb,MAAM;IACR;GACF;EACF;EACA,uBAAuB;GACrB,MAAM;GACN,YAAY,EACV,IAAI;IACF,aACE;IACF,MAAM;GACR,EACF;EACF;EACA,UAAU;GACR,MAAM;GACN,QAAQ;EACV;EACA,MAAM;GACJ,MAAM;GACN,QAAQ;EACV;CACF,EACF;AACF;;;ACpGA,SAAgB,gBACd,OACiC;CACjC,OACE,OAAO,UAAU,YAAY,UAAU,QAAQ,OAAO,iBAAi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"}