@m1212e/rumble 0.26.1 → 0.26.4

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.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["GraphQLError","isTable","getTableColumns","getTableName","EmptyFilter","toMerged","or","relationsFilterToSQL","aliasedTable","sql","SpanNames","ATTR_GRAPHQL_OPERATION_NAME","ATTR_GRAPHQL_OPERATION_TYPE","ATTR_GRAPHQL_DOCUMENT","AttributeNames","trace","isSpanContextValid","SpanStatusCode","lazy","relationsFilterToSQL","debounce","relationsFilterToSQL","relationsFilterToSQL","makeDefaultName","capitalize","toCamelCase","lazy","is","PgEnumColumn","PgEnumObjectColumn","MySqlEnumColumn","MySqlEnumObjectColumn","isPgEnum","isTable","getTableName","capitalize","toCamelCase","capitalize","toCamelCase","is","PgColumn","generateFromSchema","lazy","count","getOperationAST","print","is","PgTable","MySqlTable","SQLiteTable","sql","cloneDeep","capitalize","is","One","PgColumn","createPubSub","sql","BasePlugin","isThenable","BasePlugin","DataLoader","createRequire","z","BaseEmailAddressResolver","GraphQLScalarType","Kind","GraphQLScalarType","Kind","parsePhoneNumberFromString","GraphQLScalarType","Kind","createOpenTelemetryWrapper","SchemaBuilder","DrizzlePlugin","SmartSubscriptionsPlugin","TracingPlugin","ValidationPlugin","is","PgTable","pgTableConfig","MySqlTable","mysqlTableConfig","SQLiteTable","sqliteTableConfig","isTable","getTableColumns","subscribeOptionsFromIterator","isRootField","wrapResolver","JSONResolver","DateResolver","DateTimeISOResolver","BigIntResolver","ByteResolver","LocaleResolver","trace","packagejson.version","lazy","GraphQLSchema","nativeCreateYoga","useDisableIntrospection","EnvelopArmorPlugin","defaultExecute","defaultSubscribe"],"sources":["../lib/types/rumbleError.ts","../lib/helpers/tableHelpers.ts","../lib/helpers/mergeFilters.ts","../lib/helpers/sanitizeFilterValue.ts","../lib/abilityBuilder/keys.ts","../lib/abilityBuilder/requestState.ts","../lib/abilityBuilder/columnMask.ts","../lib/helpers/sqlTypes/types.ts","../lib/helpers/sqlTypes/distinctValuesFromSQLType.ts","../lib/helpers/telemetry.ts","../lib/abilityBuilder/filterResponse.ts","../lib/abilityBuilder/queryFilter.ts","../lib/helpers/errorLogging.ts","../lib/abilityBuilder/telemetry.ts","../lib/abilityBuilder/tableAbilities.ts","../lib/abilityBuilder/inputGuard.ts","../lib/abilityBuilder/tableBuilder.ts","../lib/abilityBuilder/index.ts","../lib/helpers/asserts.ts","../lib/helpers/mapNullFieldsToUndefined.ts","../package.json","../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/helpers/objectTypeOptions.ts","../lib/helpers/registerPlugin.ts","../lib/columnMaskPlugin/maskTypes.ts","../lib/columnMaskPlugin/columnMaskPlugin.ts","../lib/helpers/abilityAwareClient.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 {\n type Column,\n getTableColumns,\n getTableName,\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","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 */\nexport function realWhere(where: unknown) {\n return where === EmptyFilter ? undefined : where;\n}\n\ntype Mode = \"AND\" | \"OR\";\n\nfunction mergeWhere(a: unknown, b: unknown, mode: Mode) {\n if (a && b) {\n return mode === \"OR\" ? { OR: [a, b] } : { AND: [a, b] };\n }\n // an OR with a missing side would widen to \"everything\", so no where at all\n return mode === \"OR\" ? undefined : (a ?? b);\n}\n\nfunction mergeColumns(\n a?: Record<string, unknown>,\n b?: Record<string, unknown>,\n) {\n if (!a && !b) return undefined;\n const result: Record<string, true> = {};\n for (const [key, value] of [\n ...Object.entries(a ?? {}),\n ...Object.entries(b ?? {}),\n ]) {\n if (value === true) result[key] = true;\n }\n return result;\n}\n\nfunction mergeRecords(a?: Record<string, any>, b?: Record<string, any>) {\n return a || b ? toMerged(a ?? {}, b ?? {}) : undefined;\n}\n\n/**\n * Combines two limit/offset style bounds. For OR the looser bound wins (and a\n * missing side means unbounded), for AND the stricter bound wins.\n */\nfunction mergeBound(\n a: number | undefined,\n b: number | undefined,\n mode: Mode,\n orPick: (a: number, b: number) => number,\n) {\n if (mode === \"OR\") {\n return a === undefined || b === undefined ? undefined : orPick(a, b);\n }\n return a || b ? Math.min(a ?? Infinity, b ?? Infinity) : undefined;\n}\n\nexport function mergeFilters<\n FilterA extends Record<string, any>,\n FilterB extends Record<string, any>,\n>(filterA?: Partial<FilterA>, filterB?: Partial<FilterB>, mode: Mode = \"AND\") {\n return {\n where: mergeWhere(\n realWhere(filterA?.where),\n realWhere(filterB?.where),\n mode,\n ),\n columns: mergeColumns(filterA?.columns, filterB?.columns),\n extras: mergeRecords(filterA?.extras, filterB?.extras),\n orderBy: mergeRecords(filterA?.orderBy, filterB?.orderBy),\n limit: mergeBound(filterA?.limit, filterB?.limit, mode, Math.max),\n offset: mergeBound(filterA?.offset, filterB?.offset, mode, Math.min),\n with: mergeRecords(filterA?.with, filterB?.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","// per row: the index of the action the row was loaded with\nexport const ACTION_FLAG_KEY = \"__rumble_action\";\n// per row and column group: 1 if the row matches one of the group's abilities\nexport const columnFlagKey = (group: number) => `__rumble_columns_${group}`;\n\nexport const columnMaskKey = Symbol.for(\"rumble:columnMask\");\n// per resolved filter: which rows expose a column, see `ColumnVisibility`\nexport const columnVisibilityKey = Symbol.for(\"rumble:columnVisibility\");\n// per request: the function checking client supplied where / orderBy against it\nexport const guardInputKey = Symbol.for(\"rumble:guardInput\");\nexport const resolvedFilterKey = Symbol.for(\"rumble:resolvedFilter\");\n\n// the masking state of a request, on its abilities\nexport const requestStateKey = Symbol.for(\"rumble:requestState\");\n","import type DataLoader from \"dataloader\";\nimport { requestStateKey } from \"./keys\";\n\n/**\n * The state of a single request, kept on its abilities instead of globally\n * or on the rows.\n */\nexport type RequestState<Action extends string> = {\n /** the rows masked in this request and whether their primary key is hidden */\n masked: WeakMap<object, boolean>;\n /** the columns hidden on the rows masked in this request */\n hidden: WeakMap<object, { cleared: string[]; primaryKey: boolean }>;\n /** per table the actions rows were masked with, reloads apply them */\n actions: Map<string, Set<Action>>;\n /** per runtime filter the loader batching its calls */\n filterLoaders: Map<object, DataLoader<any, any>>;\n};\n\nexport function createRequestState<\n Action extends string,\n>(): RequestState<Action> {\n return {\n // weak, a subscription's request lives as long as the subscription\n masked: new WeakMap(),\n hidden: new WeakMap(),\n actions: new Map(),\n filterLoaders: new Map(),\n };\n}\n\nexport function attachRequestState(\n abilities: object,\n state: RequestState<any>,\n) {\n // a symbol, so it can't collide with a table name\n Object.defineProperty(abilities, requestStateKey, { value: state });\n}\n\nexport function requestStateOf<Action extends string>(\n abilities: object | undefined,\n) {\n return (abilities as any)?.[requestStateKey] as\n | RequestState<Action>\n | undefined;\n}\n","import { aliasedTable, or, relationsFilterToSQL, sql } from \"drizzle-orm\";\nimport { realWhere } from \"../helpers/mergeFilters\";\nimport { sanitizeFilterValue } from \"../helpers/sanitizeFilterValue\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport {\n ACTION_FLAG_KEY,\n columnFlagKey,\n columnMaskKey,\n resolvedFilterKey,\n} from \"./keys\";\nimport { type RequestState, requestStateOf } from \"./requestState\";\nimport type { AbilitySettings, TableSchema } from \"./types\";\n\ntype HiddenColumns = {\n /** cleared on the row */\n cleared: string[];\n /** primary keys stay on the row, their fields hide them */\n primaryKey: boolean;\n};\n\nexport type ColumnMask = {\n guaranteed: Set<string>;\n conditional: Set<string>[];\n /** the extra flagging each conditional group */\n flags: string[];\n /** keyed by the matched groups, e.g. \"01\" */\n hiddenPerMatch: Map<string, HiddenColumns>;\n};\n\nfunction referencesRelation(\n filter: unknown,\n relations: Record<string, unknown>,\n): boolean {\n if (!filter || typeof filter !== \"object\") return false;\n return Object.entries(filter).some(([key, value]) => {\n if (key === \"AND\" || key === \"OR\") {\n return (value as unknown[]).some((v) => referencesRelation(v, relations));\n }\n if (key === \"NOT\") return referencesRelation(value, relations);\n return key in relations;\n });\n}\n\nfunction selectedColumns(\n columns: Record<string, boolean | undefined> | undefined,\n allColumns: string[],\n) {\n if (!columns) return new Set(allColumns);\n const entries = Object.entries(columns).filter(([, v]) => v !== undefined);\n if (entries.some(([, v]) => v)) {\n return new Set(entries.filter(([, v]) => v).map(([k]) => k));\n }\n if (entries.length === 0) return new Set<string>();\n return new Set(allColumns.filter((c) => columns[c] !== false));\n}\n\nfunction hiddenColumns(\n mask: ColumnMask,\n matched: string,\n allColumns: string[],\n primaryKey: string[],\n) {\n let hidden = mask.hiddenPerMatch.get(matched);\n if (!hidden) {\n const columns = allColumns.filter(\n (column) =>\n !mask.guaranteed.has(column) &&\n !mask.conditional.some(\n (columns, group) => matched[group] === \"1\" && columns.has(column),\n ),\n );\n hidden = {\n cleared: columns.filter((c) => !primaryKey.includes(c)),\n primaryKey: columns.some((c) => primaryKey.includes(c)),\n };\n mask.hiddenPerMatch.set(matched, hidden);\n }\n return hidden;\n}\n\nconst hasWhere = (where: unknown) =>\n !!where && Object.keys(where as object).length > 0;\n\ntype ColumnRule = { where: unknown; columns: Set<string> };\n\n/**\n * Which rows expose a column to the caller: all of them (`true`), none of\n * them (`false`) or those matching the returned where.\n */\nexport type ColumnVisibility = (column: string) => true | false | object;\n\n/** Columns every returned row is allowed to expose. */\nfunction guaranteedColumns(rules: ColumnRule[], allColumnNames: string[]) {\n // every returned row matches at least one ability\n const guaranteed = new Set<string>();\n for (const rule of rules) {\n if (hasWhere(rule.where)) continue;\n for (const column of rule.columns) guaranteed.add(column);\n }\n for (const column of allColumnNames) {\n if (rules.every((r) => r.columns.has(column))) {\n guaranteed.add(column);\n }\n }\n return guaranteed;\n}\n\n/**\n * Groups the conditional rules by the columns they grant on top of the\n * guaranteed ones. Each group gets its own flag.\n */\nfunction conditionalGroups(rules: ColumnRule[], guaranteed: Set<string>) {\n const groups = new Map<string, { columns: Set<string>; wheres: unknown[] }>();\n for (const rule of rules) {\n if (!hasWhere(rule.where)) continue;\n const additional = [...rule.columns]\n .filter((c) => !guaranteed.has(c))\n .sort();\n if (additional.length === 0) continue;\n const key = additional.join(\",\");\n const group = groups.get(key);\n if (group) {\n group.wheres.push(rule.where);\n } else {\n groups.set(key, {\n columns: new Set(additional),\n wheres: [rule.where],\n });\n }\n }\n return [...groups.values()];\n}\n\n/**\n * Creates the resolver which turns the abilities of a table into the columns\n * to select and, if columns depend on the matched ability, extras flagging\n * per row which abilities matched plus the mask to decode them.\n */\nexport function createColumnAccessResolver<\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends TableRelationNames<DB>,\n>({ db, actions }: AbilitySettings<DB, Action>, tableSchema: TableSchema) {\n const allColumnNames = Object.keys(tableSchema.columns);\n const primaryKeyNames = Object.keys(tableSchema.primaryKey);\n const primaryKeyName = primaryKeyNames[0]!;\n\n const toSQL = (table: any, wheres: unknown[]) =>\n or(\n ...wheres.map((where) =>\n relationsFilterToSQL(\n table,\n sanitizeFilterValue(where) as any,\n tableSchema.relations,\n db._.relations,\n ),\n ),\n );\n\n // Relational filters become subqueries. They are correlated to the row\n // (`exists (... where pk = row.pk and rule)`): an uncorrelated\n // `pk in (select pk ... where rule)` makes postgres evaluate every rule\n // against the whole table, once per flag and per nesting site, which turns\n // queries nesting a masked relation twice into multi-second ones.\n const uncorrelated = (table: any, wheres: unknown[], group: number) => {\n const inner = aliasedTable(tableSchema.table, `rumble_columns_${group}`);\n // a subquery renders with its own parentheses\n return sql`exists ${(db as any)\n .select({ pk: inner[primaryKeyName] })\n .from(inner)\n .where(\n sql`${inner[primaryKeyName]} = ${table[primaryKeyName]} and (${toSQL(inner, wheres)})`,\n )}`;\n };\n\n // An ability's columns only apply to the rows matched by its where. The\n // wheres are expected to restrict rows, see `restrictingWhere`.\n return function resolveColumnAccess(\n action: Action,\n filters: DrizzleQueryFunctionInput<DB, TableName>[],\n ) {\n const rules = filters.map((f) => ({\n where: realWhere(f?.where),\n columns: selectedColumns(f?.columns as any, allColumnNames),\n }));\n\n const guaranteed = guaranteedColumns(rules, allColumnNames);\n const groups = conditionalGroups(rules, guaranteed);\n\n // primary keys are always loaded, pothos reloads rows and subscriptions\n // by them. If not granted, the mask hides them from the client.\n const selected = new Set([\n ...primaryKeyNames,\n ...rules.flatMap((r) => [...r.columns]),\n ]);\n const columns =\n selected.size === allColumnNames.length\n ? undefined\n : Object.fromEntries([...selected].map((c) => [c, true]));\n\n // A mask (and action flag) is needed even without conditional groups:\n // rows loaded without the ability's columns (pothos reloads, custom\n // resolvers) are reduced to the guaranteed columns, and the action flag\n // records the action the row was loaded with, so that action's mask applies.\n if (guaranteed.size === allColumnNames.length) {\n return {\n columns,\n extras: undefined,\n mask: undefined,\n visibility: undefined,\n };\n }\n\n // A column is exposed by the rows matching any rule that grants it. Rules\n // without a where grant their columns to every row, those are guaranteed.\n const visibility: ColumnVisibility = (column) => {\n if (guaranteed.has(column)) return true;\n const wheres = rules\n .filter((rule) => rule.columns.has(column))\n .map((rule) => rule.where as object);\n if (wheres.length === 0) return false;\n return wheres.length === 1 ? wheres[0]! : { OR: wheres };\n };\n\n const mask: ColumnMask = {\n guaranteed,\n conditional: groups.map((g) => g.columns),\n flags: groups.map((_, group) => columnFlagKey(group)),\n hiddenPerMatch: new Map(),\n };\n const actionIndex = sql.raw(String(actions.indexOf(action)));\n // callbacks, so nested relation queries pass their aliased table\n const extras: Record<string, (table: any) => any> = {\n [ACTION_FLAG_KEY]: () => sql`${actionIndex}`,\n };\n groups.forEach(({ wheres }, group) => {\n const relational = wheres.some((w) =>\n referencesRelation(w, tableSchema.relations),\n );\n extras[mask.flags[group]!] = (table: any) => {\n const condition = relational\n ? uncorrelated(table, wheres, group)\n : toSQL(table, wheres);\n return sql`case when ${condition} then 1 else 0 end`;\n };\n });\n\n return { columns, extras, mask, visibility };\n };\n}\n\ntype Row = Record<PropertyKey, unknown>;\n\nconst isRow = (row: unknown): row is Row => !!row && typeof row === \"object\";\n\nfunction clearColumns(row: Row, columns: string[]) {\n for (let i = 0; i < columns.length; i++) {\n const column = columns[i]!;\n if (row[column] !== undefined) row[column] = undefined;\n }\n}\n\n// \"1\" per group the row matched, unflagged rows match none and only get the\n// guaranteed columns\nfunction matchedGroups(row: Row, flags: string[]) {\n let matched = \"\";\n for (let i = 0; i < flags.length; i++) {\n matched += Number(row[flags[i]!]) === 1 ? \"1\" : \"0\";\n }\n return matched;\n}\n\nfunction maskRow(row: Row, mask: ColumnMask, hidden: HiddenColumns) {\n // assign instead of delete to keep the row's hidden class\n if (row[ACTION_FLAG_KEY] !== undefined) row[ACTION_FLAG_KEY] = undefined;\n clearColumns(row, mask.flags);\n clearColumns(row, hidden.cleared);\n}\n\nexport type MaskColumnsInput<\n DB extends DrizzleInstance,\n Action extends string,\n> = {\n table: TableRelationNames<DB>;\n action: Action;\n abilities: Record<string, any>;\n entities: unknown[];\n};\n\n/**\n * Creates the function hiding the columns of queried rows which the ability\n * that matched the row does not grant.\n */\nexport function createColumnMasker<\n DB extends DrizzleInstance,\n Action extends string,\n>(\n { actions }: AbilitySettings<DB, Action>,\n tables: Map<\n TableRelationNames<DB>,\n { columns: string[]; primaryKey: string[] }\n >,\n) {\n const stateOf = (abilities: object) =>\n requestStateOf<Action>(abilities) as RequestState<Action>;\n\n const maskedActions = (\n abilities: object,\n table: TableRelationNames<DB>,\n ): Set<Action> => {\n const { actions } = stateOf(abilities);\n let used = actions.get(table);\n if (!used) {\n used = new Set();\n actions.set(table, used);\n }\n return used;\n };\n\n const primaryKeyHidden = (abilities: object, row: object) =>\n stateOf(abilities).masked.get(row) === true;\n\n const maskColumns = (\n { table, action, abilities, entities }: MaskColumnsInput<DB, Action>,\n start = 0,\n ): void | Promise<void> => {\n const tableAbilities = abilities[table];\n const { columns: columnNames, primaryKey } = tables.get(table)!;\n const state = stateOf(abilities);\n const used = maskedActions(abilities, table);\n\n for (let i = start; i < entities.length; i++) {\n const row = entities[i];\n if (!isRow(row) || state.masked.has(row)) continue;\n\n const flagged = row[ACTION_FLAG_KEY] != null;\n const rowAction = flagged\n ? actions[Number(row[ACTION_FLAG_KEY])]!\n : action;\n used.add(rowAction);\n\n const resolved = tableAbilities[resolvedFilterKey](rowAction);\n if (!resolved) {\n return tableAbilities\n .filter(rowAction)\n .then(() => maskColumns({ table, action, abilities, entities }, i));\n }\n\n const mask: ColumnMask | undefined = resolved[columnMaskKey];\n if (!mask) continue;\n\n const matched = matchedGroups(row, mask.flags);\n const hidden = hiddenColumns(mask, matched, columnNames, primaryKey);\n maskRow(row, mask, hidden);\n state.masked.set(row, hidden.primaryKey);\n state.hidden.set(row, hidden);\n }\n };\n\n /**\n * Whether masking hid any of the columns on the row. A hidden primary key\n * counts for the columns it consists of.\n */\n const columnsHidden = (\n abilities: object,\n row: object,\n columns: string[],\n primaryKey: string[],\n ) => {\n const hidden = stateOf(abilities).hidden.get(row);\n return (\n !!hidden &&\n columns.some(\n (column) =>\n hidden.cleared.includes(column) ||\n (hidden.primaryKey && primaryKey.includes(column)),\n )\n );\n };\n\n return { maskColumns, maskedActions, primaryKeyHidden, columnsHidden };\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 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`. */\nconst ATTR_VARIABLES_PREFIX: string = AttributeNames.VARIABLES;\n/** Log field holding all variables as one object (logs keep nesting, spans flatten). */\nconst 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 { relationsFilterToSQL, type SQL } from \"drizzle-orm\";\nimport { lazy } from \"../helpers/lazy\";\nimport { mergeFilters } from \"../helpers/mergeFilters\";\nimport { sanitizeFilterValue } from \"../helpers/sanitizeFilterValue\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport type { ColumnMask, ColumnVisibility } from \"./columnMask\";\nimport { columnMaskKey, columnVisibilityKey } from \"./keys\";\nimport type { AbilitySettings, TableSchema } from \"./types\";\n\ntype FindFirstConfig<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = NonNullable<Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]>;\n\ntype FindManyConfig<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = NonNullable<Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]>;\n\n/**\n * The query filters of an ability, as handed out by\n * `abilities.<table>.filter(...)`.\n *\n * `columns` and `extras` are set at runtime but left out of the types on\n * purpose: a visible, loosely typed extras makes drizzle infer `{}` as the row\n * type of findFirst/findMany, and the column flag is an internal detail anyway.\n */\nexport type AbilityFilter<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: async (_args, ctx) => (await ctx.abilities.users.filter(\"read\")).query.single,\n * }),\n * ```\n */\n query: {\n /**\n * For find first calls\n */\n single: Pick<FindFirstConfig<DB, TableName>, \"where\">;\n /**\n * For find many calls\n */\n many: Pick<FindManyConfig<DB, TableName>, \"where\" | \"limit\">;\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 (await ctx.abilities.users.filter(\"update\")).sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n readonly where: SQL | undefined;\n };\n};\n\n/**\n * What `abilities.<table>.filter(...)` resolves to.\n */\n// exported so the bundled declarations name it instead of inlining it\n// fallow-ignore-next-line unused-type\nexport type AbilityFilterResponse<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = AbilityFilter<DB, TableName> & {\n /**\n * Merges the current query filters with the provided filters for this call only\n */\n merge: (\n filters: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>,\n ) => AbilityFilter<DB, TableName>;\n};\n\n/**\n * The limit of a find many call. An injected merge limit wins unless the\n * ability limit is lower, otherwise the default limit caps the ability limit.\n */\nfunction resolveLimit(\n abilityLimit: number | undefined | null,\n mergedLimit: number | undefined,\n defaultLimit: number | undefined | null,\n) {\n if (\n mergedLimit !== undefined &&\n (!abilityLimit || abilityLimit > mergedLimit)\n ) {\n return mergedLimit;\n }\n\n if (\n defaultLimit &&\n (abilityLimit === undefined || (abilityLimit as number) > defaultLimit)\n ) {\n return defaultLimit;\n }\n\n // ensure that null is converted to undefined\n return abilityLimit ?? undefined;\n}\n\n/**\n * Creates the function packing resolved query filters into the object handed\n * out by `abilities.<table>.filter(...)`.\n */\nexport function createFilterResponder<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n>({ db, defaultLimit }: AbilitySettings<DB, any>, tableSchema: TableSchema) {\n const internalTransformer = (\n filters?: DrizzleQueryFunctionInput<DB, TableName>,\n mergedLimit?: number,\n ): AbilityFilter<DB, TableName> => {\n const where = filters?.where;\n const extras = filters?.extras;\n const columns = filters?.columns;\n\n const limit = lazy(() =>\n resolveLimit(\n filters?.limit as number | undefined | null,\n mergedLimit,\n defaultLimit,\n ),\n );\n\n const sqlTransformedWhere = lazy(() => {\n const casing = (db._ as any).session?.dialect?.casing;\n\n return where\n ? relationsFilterToSQL(\n tableSchema.foundRelation.table,\n sanitizeFilterValue(where) as any,\n tableSchema.relations,\n db._.relations,\n casing,\n )\n : undefined;\n });\n\n // Two shapes since we do not want to use delete for performance reasons\n // and an undefined columns field on a drizzle filter will prevent any\n // column from being selected at all\n const single = columns\n ? { extras, where: sanitizeFilterValue(where), columns }\n : { extras, where: sanitizeFilterValue(where) };\n const many = columns\n ? {\n extras,\n where: sanitizeFilterValue(where),\n columns,\n get limit() {\n return limit();\n },\n }\n : {\n extras,\n where: sanitizeFilterValue(where),\n get limit() {\n return limit();\n },\n };\n\n return {\n query: { single, many },\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n } as AbilityFilter<DB, TableName>;\n };\n\n /**\n * Packs the filters into a response object that can be applied for queries by the user\n */\n return function transformToResponse(\n queryFilters?: DrizzleQueryFunctionInput<DB, TableName>,\n columnMask?: ColumnMask,\n columnVisibility?: ColumnVisibility,\n ) {\n const ret = internalTransformer(queryFilters) as AbilityFilterResponse<\n DB,\n TableName\n >;\n\n ret.merge = (filters) =>\n internalTransformer(\n mergeFilters(ret.query.many, filters),\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 filters.limit as number | undefined,\n );\n (ret as any)[columnMaskKey] = columnMask;\n (ret as any)[columnVisibilityKey] = columnVisibility;\n\n return ret;\n };\n}\n","import type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleQueryFunctionInput,\n} from \"../types/drizzleInstanceType\";\n\n/**\n * Static, non changing query filter input type for a specific table\n */\nexport type 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 */\nexport type DynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> = (\n context: Context,\n) =>\n | StaticQueryFilter<DB, Table, Filter>\n | undefined\n | \"allow\"\n | Promise<StaticQueryFilter<DB, Table, Filter> | undefined | \"allow\">;\n\n/**\n * Combined query filter type for a specific table. May be static or dynamic.\n */\nexport type 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\n/**\n * The query filters registered per action. \"unrestricted\" when a bare allow()\n * granted the action without conditions.\n */\nexport type QueryFilterRegistry<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends keyof DrizzleQueryFunction<DB>,\n> = Map<\n Action,\n | QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[]\n | \"unrestricted\"\n>;\n\nexport function 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 typeof filter === \"function\";\n}\n\nexport function 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","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 type { AttributeValue, Span } from \"@opentelemetry/api\";\nimport { debounce } from \"es-toolkit\";\nimport { errorLogField } from \"../helpers/errorLogging\";\nimport {\n ATTR_ACTION,\n ATTR_TABLE,\n recordSpanError,\n SPAN_ABILITIES_PREPARE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"../helpers/telemetry\";\nimport type { RumbleLogger } from \"../types/rumbleInput\";\nimport type { AbilitySettings } from \"./types\";\n\nexport const 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\n/**\n * Runs the preparation of the abilities of one table and action, reporting\n * the attributes it collects to the span and the logger.\n */\nexport function traceAbilityPreparation<T>(\n { otel, log, telemetryConfig }: AbilitySettings<any, any>,\n tableName: string,\n action: string,\n assemble: (attributes: Record<string, AttributeValue>) => Promise<T>,\n): Promise<T> {\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 = async (span?: Span) => {\n const attributes: Record<string, AttributeValue> = {\n [ATTR_TABLE]: tableName,\n [ATTR_ACTION]: action,\n };\n\n try {\n const result = await assemble(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(SPAN_ABILITIES_PREPARE, async (span) => {\n try {\n return await run(span);\n } finally {\n span.end();\n }\n });\n }\n\n return run();\n}\n","import type { AttributeValue } from \"@opentelemetry/api\";\nimport { relationsFilterToSQL } from \"drizzle-orm\";\nimport { mergeFilters, realWhere } 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} from \"../helpers/telemetry\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\nimport { createColumnAccessResolver } from \"./columnMask\";\nimport { createFilterResponder } from \"./filterResponse\";\nimport { resolvedFilterKey } from \"./keys\";\nimport {\n type DynamicQueryFilter,\n isDynamicQueryFilter,\n isStaticQueryFilter,\n type QueryFilterRegistry,\n type StaticQueryFilter,\n} from \"./queryFilter\";\nimport { traceAbilityPreparation } from \"./telemetry\";\nimport type { AbilitySettings, TableSchema } from \"./types\";\n\n/**\n * filter() is async. Without type checking (plain JS, `any`) a forgotten await would\n * hand the promise itself to drizzle\n */\nfunction guardAgainstMissingAwait<T>(promise: Promise<T>): Promise<T> {\n for (const key of [\"query\", \"sql\", \"merge\"]) {\n Object.defineProperty(promise, key, {\n enumerable: true,\n get() {\n throw new RumbleError(\n `Tried to access \"${key}\" on the result of abilities.<table>.filter(...) which is a Promise. filter() is async, did you forget to await it?`,\n );\n },\n });\n }\n return promise;\n}\n\n/**\n * A filter no row can match, since it requires the primary key to equal two\n * distinct values at once.\n */\nexport function createBlockEverythingFilter(\n tableName: string,\n tableSchema: TableSchema,\n) {\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n throw new RumbleError(`No primary key found for entity ${tableName}`);\n }\n\n // relational where keys are ts names, not database names\n const [primaryKeyName, primaryKeyField] = Object.entries(\n tableSchema.primaryKey,\n )[0] as [string, any];\n const distinctValues = createDistinctValuesFromSQLType(\n primaryKeyField.getSQLType() as any,\n );\n\n return {\n where: {\n AND: [\n {\n [primaryKeyName]: distinctValues.value1,\n },\n {\n [primaryKeyName]: distinctValues.value2,\n },\n ],\n },\n };\n}\n\n/**\n * Creates the abilities of a single table, which resolve the registered\n * query filters for a request.\n */\nexport const createTableAbilities = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends TableRelationNames<DB>,\n>(\n settings: AbilitySettings<DB, Action>,\n tableName: TableName,\n queryFilters: QueryFilterRegistry<UserContext, DB, Action, TableName>,\n) => {\n const { db, actions } = settings;\n\n const tableSchema = tableHelper({\n db,\n table: tableName,\n });\n\n // A where compiling to no sql (e.g. `{ id: undefined }`) restricts nothing,\n // so its ability applies to every row. Dropped here, the row filter and the\n // column mask both treat it as such.\n const withRestrictingWhere = <Filter>(filter: Filter): Filter => {\n const where = realWhere((filter as { where?: unknown }).where);\n const restricts =\n !!where &&\n Object.keys(where).length > 0 &&\n relationsFilterToSQL(\n tableSchema.table,\n sanitizeFilterValue(where) as any,\n tableSchema.relations,\n db._.relations,\n ) !== undefined;\n return restricts || where === undefined\n ? filter\n : { ...filter, where: undefined };\n };\n\n // static filters are known upfront, so they are only checked once\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 [\n action,\n filters.filter(isStaticQueryFilter).map(withRestrictingWhere),\n ];\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 // we want a filter that excludes everything\n const blockEverythingFilter = createBlockEverythingFilter(\n String(tableName),\n tableSchema,\n );\n const resolveColumnAccess = createColumnAccessResolver<DB, Action, TableName>(\n settings,\n tableSchema,\n );\n const transformToResponse = createFilterResponder<DB, TableName>(\n settings,\n tableSchema,\n );\n\n const assembleAbilities = async (\n userContext: UserContext,\n action: Action,\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 settings.warnNothingRegistered(String(tableName), action);\n return transformToResponse(blockEverythingFilter);\n }\n\n // run all dynamic filters, they may be async so we start all of them first\n const rawResults = await Promise.all(\n dynamicQueryFilters[action].map((func) => func(userContext)),\n );\n\n // if one of the dynamic filters returns \"allow\", we want to allow everything\n if (rawResults.includes(\"allow\")) {\n attributes[ATTR_ABILITIES_STATUS] = \"unrestricted\";\n return transformToResponse();\n }\n\n // if nothing is returned, nothing is allowed by this filter\n const dynamicResults = (\n rawResults.filter(\n (r): r is Exclude<typeof r, undefined | \"allow\"> => r !== undefined,\n ) as DrizzleQueryFunctionInput<DB, TableName>[]\n ).map(withRestrictingWhere);\n\n attributes[ATTR_ABILITIES_DYNAMIC] = dynamicResults.length;\n attributes[ATTR_ABILITIES_STATIC] = simpleQueryFilters[action].length;\n\n const allQueryFilters = [...simpleQueryFilters[action], ...dynamicResults];\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 ) as Record<string, any>;\n\n const { columns, extras, mask, visibility } = resolveColumnAccess(\n action,\n allQueryFilters,\n );\n if (columns) {\n mergedFilters.columns = columns;\n } else {\n delete mergedFilters.columns;\n }\n if (extras) {\n mergedFilters.extras = {\n ...mergedFilters.extras,\n ...extras,\n };\n }\n\n attributes[ATTR_ABILITIES_STATUS] = \"applied\";\n return transformToResponse(mergedFilters as any, mask, visibility);\n };\n\n return {\n withContext: (userContext: UserContext) => {\n const prepare = (action: Action) =>\n traceAbilityPreparation(\n settings,\n String(tableName),\n action,\n (attributes) => assembleAbilities(userContext, action, attributes),\n );\n\n // abilities are resolved once per request and action, since\n // filter() is called by every field and the (possibly async)\n // callbacks may be expensive, e.g. calling an external service\n const cache = new Map<Action, ReturnType<typeof prepare>>();\n const resolved = new Map<Action, Awaited<ReturnType<typeof prepare>>>();\n\n const abilities = {\n filter: (action: Action) => {\n let prepared = cache.get(action);\n if (!prepared) {\n prepared = guardAgainstMissingAwait(prepare(action));\n cache.set(action, prepared);\n prepared.then(\n (result) => resolved.set(action, result),\n () => {},\n );\n }\n return prepared;\n },\n };\n // kept out of the type: declaration emit can't name the internal key\n (abilities as any)[resolvedFilterKey] = (action: Action) =>\n resolved.get(action);\n return abilities;\n },\n };\n};\n","import { relationsFilterToSQL, sql } from \"drizzle-orm\";\nimport { sanitizeFilterValue } from \"../helpers/sanitizeFilterValue\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport type { ColumnVisibility } from \"./columnMask\";\nimport { columnVisibilityKey, guardInputKey } from \"./keys\";\nimport { createBlockEverythingFilter } from \"./tableAbilities\";\n\ntype Where = Record<string, any>;\n\n/** The ts names of the columns a relation joins on, on either side. */\nexport function relationColumnKeys(\n db: DrizzleInstance,\n table: string,\n columns: unknown[] | undefined,\n) {\n const known = tableHelper({ db, table }).columns;\n return (columns ?? []).flatMap((column: any) => {\n const raw = column?._?.column ?? column;\n const key = Object.entries(known).find(\n ([name, candidate]) => candidate === raw || name === raw?.name,\n )?.[0];\n return key ? [key] : [];\n });\n}\n\nexport type GuardedInput = { where?: unknown; orderBy?: unknown };\n\ntype InputGuard = ReturnType<typeof createInputGuard>;\n\nconst isObject = (value: unknown): value is Where =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\n/**\n * Column masking hides values after the query ran, but a `where` or `orderBy`\n * argument is applied by the database on the real values: filtering for\n * `{ salary: { gt: 5000 } }` reveals which rows exceed it whether or not the\n * column may be read. This restricts such arguments to what the abilities\n * expose:\n *\n * - a column only matches on rows which expose it, for all other rows the\n * condition is false\n * - sorting by a column treats it as empty on rows which do not expose it\n * - a relation filter requires the columns the relation joins on to be\n * exposed, and is restricted to the rows the caller may read of the related\n * table, whose masked columns follow the same rules\n */\nexport function createInputGuard<DB extends DrizzleInstance>({\n db,\n abilities,\n readActionOf,\n}: {\n db: DB;\n abilities: Record<string, any>;\n readActionOf: (table: string) => string;\n}) {\n const visibilityOf = async (table: string, action: string) =>\n (await abilities[table].filter(action))[columnVisibilityKey] as\n | ColumnVisibility\n | undefined;\n\n const never = (table: string) =>\n createBlockEverythingFilter(table, tableHelper({ db, table })).where;\n\n /** The conditions under which the given columns are exposed. */\n const exposed = async (table: string, action: string, keys: string[]) => {\n const visibility = await visibilityOf(table, action);\n if (!visibility) return [];\n const conditions: unknown[] = [];\n for (const key of keys) {\n const condition = visibility(key);\n if (condition === true) continue;\n conditions.push(condition === false ? never(table) : condition);\n }\n return conditions;\n };\n\n /** The filter of a relation: the related rows the caller may read, exposing what it joins on. */\n const guardRelation = async (\n table: string,\n action: string,\n key: string,\n value: unknown,\n guarded: Where,\n conditions: unknown[],\n ) => {\n const relation = tableHelper({ db, table }).relations[key] as any;\n const target = relation.targetTableName as string;\n const targetAction = readActionOf(target);\n const targetKeys = relationColumnKeys(db, target, relation.targetColumns);\n\n conditions.push(\n ...(await exposed(\n table,\n action,\n relationColumnKeys(db, table, relation.sourceColumns),\n )),\n );\n\n const readable = (await abilities[target].filter(targetAction)).query.many\n .where;\n const related = [\n ...(readable ? [readable] : []),\n ...(await exposed(target, targetAction, targetKeys)),\n ];\n const inner = isObject(value)\n ? ((await guardWhere(target, targetAction, value)) as Where)\n : {};\n\n if (related.length === 0) {\n guarded[key] = isObject(value) ? inner : value;\n } else if (value === false) {\n // \"has no related rows\" means none of the ones the caller can see\n conditions.push({ NOT: { [key]: { AND: related } } });\n } else {\n guarded[key] = { ...inner, AND: [...(inner.AND ?? []), ...related] };\n }\n };\n\n // the operands of AND / OR (a list) and NOT (a single filter)\n const guardLogic = (table: string, action: string, value: unknown) =>\n Array.isArray(value)\n ? Promise.all(value.map((v) => guardWhere(table, action, v)))\n : guardWhere(table, action, value);\n\n /** A single entry of a where: a logical operator, a relation or a column. */\n const guardEntry = async (\n table: string,\n action: string,\n [key, value]: [string, unknown],\n guarded: Where,\n conditions: unknown[],\n ) => {\n const schema = tableHelper({ db, table });\n if (key === \"AND\" || key === \"OR\" || key === \"NOT\") {\n guarded[key] = await guardLogic(table, action, value);\n } else if (key in schema.relations) {\n await guardRelation(table, action, key, value, guarded, conditions);\n } else {\n guarded[key] = value;\n if (key in schema.columns) {\n conditions.push(...(await exposed(table, action, [key])));\n }\n }\n };\n\n const guardWhere = async (\n table: string,\n action: string,\n where: unknown,\n ): Promise<unknown> => {\n if (!isObject(where)) return where;\n const guarded: Where = {};\n const conditions: unknown[] = [];\n\n for (const entry of Object.entries(where)) {\n await guardEntry(table, action, entry, guarded, conditions);\n }\n\n if (conditions.length === 0) return guarded;\n return { ...guarded, AND: [...(guarded.AND ?? []), ...conditions] };\n };\n\n const guardOrderBy = async (\n table: string,\n action: string,\n orderBy: unknown,\n ): Promise<unknown> => {\n if (!isObject(orderBy)) return orderBy;\n const visibility = await visibilityOf(table, action);\n if (!visibility) return orderBy;\n const entries = Object.entries(orderBy).filter(\n ([, direction]) => direction,\n );\n if (entries.every(([key]) => visibility(key) === true)) return orderBy;\n\n const schema = tableHelper({ db, table });\n return (aliased: any, { asc, desc }: any) =>\n entries.map(([key, direction]) => {\n const condition = visibility(key);\n const column = aliased[key];\n const value =\n condition === true\n ? column\n : condition === false\n ? null\n : // the column only counts where it is exposed\n sql`case when ${relationsFilterToSQL(\n aliased,\n sanitizeFilterValue(condition) as any,\n schema.relations,\n db._.relations,\n )} then ${column} end`;\n return (direction === \"asc\" ? asc : desc)(value ?? sql`null`);\n });\n };\n\n return {\n input: async (table: string, action: string, input: GuardedInput) => ({\n ...input,\n where: await guardWhere(table, action, input.where),\n orderBy: await guardOrderBy(table, action, input.orderBy),\n }),\n exposed,\n };\n}\n\n/**\n * Restricts client supplied `where` and `orderBy` arguments to what the\n * abilities of the request let the caller read, see `createInputGuard`.\n */\nexport function guardFilterInput(\n abilities: object,\n table: string,\n action: string,\n input: GuardedInput,\n) {\n const guard = (abilities as any)[guardInputKey] as InputGuard | undefined;\n return guard ? guard.input(table, action, input) : Promise.resolve(input);\n}\n\n/**\n * The conditions a row of the related table has to meet to be reached through\n * a relation: the columns the relation joins on have to be exposed on it.\n */\nexport async function relationExposure(\n abilities: object,\n table: string,\n action: string,\n columns: string[],\n) {\n const guard = (abilities as any)[guardInputKey] as InputGuard | undefined;\n return guard ? guard.exposed(table, action, columns) : [];\n}\n","import type {\n Filter,\n FilterPrefetchCombo,\n Prefetch,\n} from \"../runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\nimport type { QueryFilter, QueryFilterRegistry } from \"./queryFilter\";\n\n/**\n * Creates the registration API (allow/filter) of a single table.\n */\nexport const createTableBuilder = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends TableRelationNames<DB>,\n>({\n actions,\n isBuilt,\n}: {\n actions: Action[];\n isBuilt: () => boolean;\n}) => {\n const queryFilters: QueryFilterRegistry<UserContext, DB, Action, TableName> =\n new Map();\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 // prefetch() is an optional step before by(), so both paths end in the\n // same registration, with the prefetched type flowing into the filter\n const registerFilter = <PrefetchReturnType = never>(\n actions: Action[],\n prefetch?: Prefetch<UserContext, PrefetchReturnType>,\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 PrefetchReturnType\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters\n .get(action)!\n .push(\n prefetch\n ? { filter: explicitFilter, prefetch }\n : { filter: explicitFilter },\n );\n }\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 (isBuilt()) {\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 ) => registerFilter<PrefetchReturnType>(actions, prefetch),\n ...registerFilter(actions),\n };\n },\n _: {\n runtimeFilters,\n queryFilters,\n },\n };\n};\n","import { tableHelper } from \"../helpers/tableHelpers\";\nimport type { TelemetryConfig } from \"../helpers/telemetry\";\nimport type { Filter } from \"../runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport { createColumnMasker, type MaskColumnsInput } from \"./columnMask\";\nimport { createInputGuard } from \"./inputGuard\";\nimport { guardInputKey } from \"./keys\";\nimport { attachRequestState, createRequestState } from \"./requestState\";\nimport { createTableAbilities } from \"./tableAbilities\";\nimport { createTableBuilder } from \"./tableBuilder\";\nimport { makeNothingRegisteredWarner } from \"./telemetry\";\nimport type { AbilitySettings } from \"./types\";\n\nexport type { ColumnMask } from \"./columnMask\";\nexport {\n guardFilterInput,\n relationColumnKeys,\n relationExposure,\n} from \"./inputGuard\";\nexport { columnMaskKey } from \"./keys\";\n\n//TODO: optimize this for v8\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\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 type TableNames = TableRelationNames<DB>;\n\n const log = loggerConfig?.enabled ? loggerConfig.logger : undefined;\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n const settings: AbilitySettings<DB, Action> = {\n db,\n // populated by rumble() when the user does not pass any\n actions: actions!,\n defaultLimit,\n otel,\n telemetryConfig,\n log,\n warnNothingRegistered: makeNothingRegisteredWarner(telemetryConfig, log),\n };\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 buildersPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createTableBuilder<UserContext, DB, Action, typeof tableName>({\n actions: settings.actions,\n isBuilt: () => hasBeenBuilt,\n }),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n typeof createTableBuilder<UserContext, DB, Action, key>\n >;\n };\n\n const { maskColumns, maskedActions, primaryKeyHidden, columnsHidden } =\n createColumnMasker(\n settings,\n new Map(\n tableRelationNames.map((tableName) => {\n const tableSchema = tableHelper({ db, table: tableName });\n return [\n tableName,\n {\n columns: Object.keys(tableSchema.columns),\n primaryKey: Object.keys(tableSchema.primaryKey),\n },\n ];\n }),\n ),\n );\n\n const readActionPerTable = new Map<TableNames, Action>();\n\n return {\n ...buildersPerTable,\n /**\n * @internal\n * @ignore\n */\n _: {\n maskColumns: (input: MaskColumnsInput<DB, Action>) => maskColumns(input),\n /** The actions rows of the table were masked with in this request. */\n maskedActions: (abilities: object, table: TableNames) =>\n maskedActions(abilities, table),\n /** Whether masking in this request hid the primary key of the row. */\n primaryKeyHidden: (abilities: object, row: object) =>\n primaryKeyHidden(abilities, row),\n /** Whether masking in this request hid one of the columns on the row. */\n columnsHidden: (\n abilities: object,\n row: object,\n columns: string[],\n primaryKey: string[],\n ) => columnsHidden(abilities, row, columns, primaryKey),\n registerReadAction(table: TableNames, action: Action) {\n readActionPerTable.set(table, action);\n },\n readActionOf(table: TableNames): Action {\n return readActionPerTable.get(table) ?? (\"read\" as Action);\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 abilitiesPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createTableAbilities<UserContext, DB, Action, typeof tableName>(\n settings,\n tableName,\n buildersPerTable[tableName]._.queryFilters,\n ),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n typeof createTableAbilities<UserContext, DB, Action, key>\n >;\n };\n\n hasBeenBuilt = true;\n\n return (ctx: UserContext) => {\n const state = createRequestState<Action>();\n const abilities = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n abilitiesPerTable[tableName].withContext(ctx),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n ReturnType<\n typeof createTableAbilities<UserContext, DB, Action, key>\n >[\"withContext\"]\n >;\n };\n attachRequestState(abilities, state);\n // kept out of the type, like the other internal keys\n Object.defineProperty(abilities, guardInputKey, {\n value: createInputGuard({\n db,\n abilities,\n readActionOf: (table) =>\n (readActionPerTable as unknown as Map<string, Action>).get(\n table,\n ) ?? (\"read\" as Action),\n }),\n });\n return abilities;\n };\n },\n },\n };\n};\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: (await 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 (await 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 (await 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 { 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\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 */\ntype 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 { guardFilterInput } from \"./abilityBuilder\";\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 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 // the client may only filter by what it may read\n const guarded = await guardFilterInput(\n ctx.abilities,\n String(table),\n listAction,\n { where: args.where },\n );\n if (args.where) args.where = guarded.where;\n\n return (db as any)\n .select({ count: count() })\n .from(tableSchema.table)\n .where(\n (await ctx.abilities[table].filter(listAction)).merge(\n mapNullFieldsToUndefined(args) as any,\n ).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\ntype AnyFieldBuilder = DrizzleObjectFieldBuilder<any, any, any, any>;\n\n// explicit so declaration emit doesn't have to name pothos' internal FieldRef\ntype PothosResponseFieldRef =\n | ReturnType<AnyFieldBuilder[\"exposeInt\"]>\n | ReturnType<AnyFieldBuilder[\"exposeIntList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeString\"]>\n | ReturnType<AnyFieldBuilder[\"exposeStringList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeBoolean\"]>\n | ReturnType<AnyFieldBuilder[\"exposeBooleanList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeFloat\"]>\n | ReturnType<AnyFieldBuilder[\"exposeFloatList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeID\"]>\n | ReturnType<AnyFieldBuilder[\"exposeIDList\"]>\n | ReturnType<AnyFieldBuilder[\"field\"]>;\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}): PothosResponseFieldRef {\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 { asc, desc, sql } from \"drizzle-orm\";\nimport { cloneDeep } from \"es-toolkit\";\nimport { type ColumnMask, columnMaskKey } from \"./abilityBuilder\";\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. The same goes for columns only some rows may expose.\n const columnMask: ColumnMask | undefined = abilities[columnMaskKey];\n // without a mask every column is guaranteed\n const columnsToSearch = (\n columnMask\n ? Object.entries(tableSchema.columns).filter(([key]) =>\n columnMask.guaranteed.has(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 =\n typeof args.orderBy === \"function\"\n ? args.orderBy\n : cloneDeep(args.orderBy);\n (args as any).orderBy = (table: any) => {\n // a function when the order was restricted to what the caller may read\n const argsOrderBySQL = sql.join(\n typeof originalOrderBy === \"function\"\n ? originalOrderBy(table, { asc, desc })\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 {\n type AbilityBuilderType,\n guardFilterInput,\n relationColumnKeys,\n relationExposure,\n} 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 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 abilityBuilder._.registerReadAction(table, readAction);\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 // rows are keyed by ts names, not database names\n const primaryKeyName = Object.keys(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 (!primaryKeyName) return;\n const primaryKeyValue = (element as any)[primaryKeyName];\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 maskColumns: ({ context, entities, action }) =>\n abilityBuilder._.maskColumns({\n table,\n action: (action as Action | undefined) ?? readAction,\n abilities: (context as any).abilities,\n entities,\n }),\n maskPrimaryKeys: {\n fields: Object.keys(tableSchema.primaryKey),\n isHidden: (context, row) =>\n abilityBuilder._.primaryKeyHidden((context as any).abilities, row),\n },\n maskRelations: {\n fields: Object.fromEntries(\n Object.entries(tableSchema.relations ?? {}).map(([key, relation]) => [\n key,\n {\n many: !is(relation, One),\n sourceColumns: relationColumnKeys(\n db,\n tableSchema.tsName,\n (relation as any).sourceColumns,\n ),\n },\n ]),\n ),\n isHidden: (context, row, columns) =>\n abilityBuilder._.columnsHidden(\n (context as any).abilities,\n row,\n columns,\n Object.keys(tableSchema.primaryKey),\n ),\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(\n // drizzle 1.0 rc.5+ wraps relation columns in a\n // RelationsBuilderColumn whose column sits at `_.column`\n (column) => ((column as any)._?.column ?? column).notNull,\n );\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: async (args: any, ctx: any) => {\n // transform null prototyped object\n args = JSON.parse(JSON.stringify(args));\n\n // the client may only filter and sort by what it may read\n const guarded = await guardFilterInput(\n ctx.abilities,\n relationSchema.tsName,\n readAction,\n { where: args.where, orderBy: args.orderBy },\n );\n if (args.where) args.where = guarded.where;\n if (args.orderBy) args.orderBy = guarded.orderBy;\n\n if (isMany) {\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema: relationSchema,\n abilities:\n await ctx.abilities[relationSchema.tsName].filter(\n readAction,\n ),\n });\n }\n\n // only the related rows exposing the columns the relation\n // joins on belong to the row\n const joined = await relationExposure(\n ctx.abilities,\n relationSchema.tsName,\n readAction,\n relationColumnKeys(\n db,\n relationSchema.tsName,\n (value as any).targetColumns,\n ),\n );\n\n const filter = (\n await ctx.abilities[relationSchema.tsName].filter(\n readAction,\n )\n ).merge({\n where: joined.length\n ? {\n AND: [...(args.where ? [args.where] : []), ...joined],\n }\n : 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 { guardFilterInput } from \"./abilityBuilder\";\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 primaryKeyName = Object.keys(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 maskColumnsAction: listAction,\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: async (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 // the client may only filter and sort by what it may read\n const guarded = await guardFilterInput(\n ctx.abilities,\n String(table),\n listAction,\n { where: args.where, orderBy: args.orderBy },\n );\n if (args.where) (args as any).where = guarded.where;\n if (args.orderBy) (args as any).orderBy = guarded.orderBy;\n\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities: await ctx.abilities[table].filter(listAction),\n });\n\n const mappedArgs = mapNullFieldsToUndefined(args);\n const filter = (\n await ctx.abilities[table].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 maskColumnsAction: readAction,\n description: `Get a single ${singularName} by ID`,\n args: {\n id: t.arg.id({ required: true }),\n },\n resolve: async (query, _root, args, ctx, _info) => {\n deepSetProto(args);\n\n const filter = (\n await (ctx.abilities as any)[table].filter(readAction)\n ).merge({ where: { [primaryKeyName]: args.id } }).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","import type {\n BuildCache,\n PothosOutputFieldConfig,\n SchemaTypes,\n} from \"@pothos/core\";\n\nexport function objectTypeOptionsOfField<Types extends SchemaTypes>(\n buildCache: BuildCache<Types>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n): Record<string, unknown> | undefined {\n const type = fieldConfig.type as any;\n const ref =\n type.kind === \"List\"\n ? type.type.kind === \"Object\"\n ? type.type.ref\n : undefined\n : type.kind === \"Object\"\n ? type.ref\n : undefined;\n if (!ref) return undefined;\n\n return buildCache.getTypeConfig(ref, \"Object\").pothosOptions as Record<\n string,\n unknown\n >;\n}\n","import SchemaBuilder, {\n type PluginConstructorMap,\n type SchemaTypes,\n} from \"@pothos/core\";\n\nconst registered = new Set<string>();\n\nexport function registerPluginOnce<\n Name extends keyof PluginConstructorMap<SchemaTypes>,\n>(name: Name, plugin: PluginConstructorMap<SchemaTypes>[Name]) {\n if (registered.has(name)) return;\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(name, plugin);\n registered.add(name);\n}\n","export type MaskColumns<Context> = (p: {\n context: Context;\n entities: unknown[];\n action?: string;\n}) => void | Promise<void>;\n\nexport const maskColumnsKey = \"maskColumns\";\n\nexport const maskColumnsActionKey = \"maskColumnsAction\";\n\n// masking keeps primary keys on the row, their fields return null instead\nexport type MaskPrimaryKeys<Context> = {\n fields: string[];\n isHidden: (context: Context, row: object) => boolean;\n};\n\nexport const maskPrimaryKeysKey = \"maskPrimaryKeys\";\n\n// A relation joins on columns of the row. If masking hid them, the related\n// rows are not the row's to see: the field returns null (or an empty list).\nexport type MaskRelations<Context> = {\n fields: Record<string, { many: boolean; sourceColumns: string[] }>;\n isHidden: (context: Context, row: object, columns: string[]) => boolean;\n};\n\nexport const maskRelationsKey = \"maskRelations\";\n\nexport const columnMaskPluginName = \"ColumnMaskPlugin\" as const;\n","import {\n BasePlugin,\n isThenable,\n type PothosOutputFieldConfig,\n type SchemaTypes,\n} from \"@pothos/core\";\nimport type { GraphQLFieldResolver } from \"graphql\";\nimport { objectTypeOptionsOfField } from \"../helpers/objectTypeOptions\";\nimport { registerPluginOnce } from \"../helpers/registerPlugin\";\nimport {\n columnMaskPluginName,\n type MaskColumns,\n type MaskPrimaryKeys,\n type MaskRelations,\n maskColumnsActionKey,\n maskColumnsKey,\n maskPrimaryKeysKey,\n maskRelationsKey,\n} from \"./maskTypes\";\n\nexport class ColumnMaskPlugin<\n Types extends SchemaTypes,\n> extends BasePlugin<Types> {\n // fallow-ignore-next-line unused-class-member\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n return this.maskResult(\n this.maskRelation(\n this.maskPrimaryKey(resolver, fieldConfig),\n fieldConfig,\n ),\n fieldConfig,\n );\n }\n\n // The rows of a relation are loaded by the database joining on the row's\n // columns, whether or not the caller may read them. If masking hid those\n // columns, the relation reveals what they would, so it resolves to nothing.\n private maskRelation(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const relations = (\n this.buildCache.getTypeConfig(fieldConfig.parentType).pothosOptions as {\n [maskRelationsKey]?: MaskRelations<Types[\"Context\"]>;\n }\n )[maskRelationsKey];\n const relation = relations?.fields[fieldConfig.name];\n if (!relations || !relation) return resolver;\n\n return (parent, args, context, info) =>\n relations.isHidden(context, parent as object, relation.sourceColumns)\n ? relation.many\n ? []\n : null\n : resolver(parent, args, context, info);\n }\n\n // Masking keeps primary keys on the row, the fields returning them hide them.\n // Pothos reloads rows by their primary key, e.g. a mutation returning\n // `db.update(users).returning()` selected as `{ id firstName }` where only\n // `firstName` is granted: pothos queries `where id in (row.id)` and matches\n // the result by `row.id`. Cleared on the row, that is `id in (undefined)`\n // and fails with \"Model users(undefined) not found\".\n private maskPrimaryKey(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const primaryKeys = (\n this.buildCache.getTypeConfig(fieldConfig.parentType).pothosOptions as {\n [maskPrimaryKeysKey]?: MaskPrimaryKeys<Types[\"Context\"]>;\n }\n )[maskPrimaryKeysKey];\n if (!primaryKeys?.fields.includes(fieldConfig.name)) return resolver;\n\n return (parent, args, context, info) =>\n primaryKeys.isHidden(context, parent as object)\n ? null\n : resolver(parent, args, context, info);\n }\n\n private maskResult(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const maskColumns = objectTypeOptionsOfField(\n this.buildCache,\n fieldConfig,\n )?.[maskColumnsKey] as MaskColumns<Types[\"Context\"]> | undefined;\n if (!maskColumns) return resolver;\n const action = (\n fieldConfig.pothosOptions as { [maskColumnsActionKey]?: string }\n )[maskColumnsActionKey];\n\n const mask = (value: unknown, context: Types[\"Context\"]): unknown => {\n if (value == null) return value;\n // graphql-js accepts lists of promises, the rows are masked once resolved\n if (Array.isArray(value) && value.some(isThenable)) {\n return Promise.all(value).then((rows) => mask(rows, context));\n }\n const pending = maskColumns({\n context,\n entities: Array.isArray(value) ? value : [value],\n action,\n });\n return pending ? pending.then(() => value) : value;\n };\n\n return (parent, args, context, info) => {\n const resolved = resolver(parent, args, context, info);\n return isThenable(resolved)\n ? resolved.then((value) => mask(value, context))\n : mask(resolved, context);\n };\n }\n}\n\nexport function registerColumnMaskPlugin() {\n registerPluginOnce(columnMaskPluginName, ColumnMaskPlugin);\n}\n","import type { AbilityBuilderType } from \"../abilityBuilder\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport { mergeFilters } from \"./mergeFilters\";\n\n// pothos reloads rows by primary key when a resolver returned them without\n// query(...). Those reloads are its only use of client.query, so the read\n// abilities are applied there: the ones the request masked rows of the table\n// with (e.g. a list action), or the table's read action if there are none.\nexport function createAbilityAwareClient<DB extends DrizzleInstance>({\n db,\n abilityBuilder,\n}: {\n db: DB;\n abilityBuilder: AbilityBuilderType<any, DB, any, any, any>;\n}) {\n return (context: { abilities: Record<string, any> }) => {\n const apis = new Map<string, unknown>();\n\n const query = new Proxy(db.query as Record<string, any>, {\n get(target, table, receiver) {\n const api = Reflect.get(target, table, receiver);\n if (typeof table !== \"string\" || !context.abilities?.[table]) {\n return api;\n }\n\n let wrapped = apis.get(table);\n if (!wrapped) {\n wrapped = Object.create(api, {\n findMany: {\n value: async (config: Record<string, any> = {}) => {\n const masked = abilityBuilder._.maskedActions(\n context.abilities,\n table as any,\n );\n const actions = masked.size\n ? [...masked]\n : [abilityBuilder._.readActionOf(table as any)];\n\n // one query per action, since each brings its own column flag.\n // A row found by several is matched by pothos once.\n const rowsPerAction = await Promise.all(\n actions.map(async (action) => {\n const ability = (\n await context.abilities[table].filter(action)\n ).query.many;\n const { where, extras } = mergeFilters(\n { where: config.where, extras: config.extras },\n { where: ability.where, extras: ability.extras },\n );\n\n const rows = await api.findMany({\n ...config,\n where,\n extras,\n });\n await abilityBuilder._.maskColumns({\n table: table as any,\n action,\n abilities: context.abilities,\n entities: rows,\n });\n return rows;\n }),\n );\n return rowsPerAction.flat();\n },\n },\n });\n apis.set(table, wrapped);\n }\n return wrapped;\n },\n });\n\n return new Proxy(db, {\n get(target, prop, receiver) {\n return prop === \"query\" ? query : Reflect.get(target, prop, receiver);\n },\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 {\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 { requestStateOf } from \"../abilityBuilder/requestState\";\nimport { errorLogField } from \"../helpers/errorLogging\";\nimport { objectTypeOptionsOfField } from \"../helpers/objectTypeOptions\";\nimport { registerPluginOnce } from \"../helpers/registerPlugin\";\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. The loaders are kept in the state of the request,\n // so they are gone once the request is done, no manual cleanup needed.\n private getLoader(\n context: Types[\"Context\"],\n filter: AnyFilterCombo,\n ): DataLoader<any, any> {\n // a context not created by rumble has no request state, it doesn't batch\n const loaders =\n requestStateOf((context as { abilities?: object }).abilities)\n ?.filterLoaders ?? new Map<object, DataLoader<any, any>>();\n\n let loader = loaders.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 loaders.set(filter, loader);\n }\n\n return loader;\n }\n\n // fallow-ignore-next-line unused-class-member\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 // fallow-ignore-next-line unused-class-member\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const filters = objectTypeOptionsOfField(this.buildCache, fieldConfig)?.[\n applyFiltersKey\n ] as ApplyFiltersField<Types[\"Context\"], any>;\n if (!filters) return resolver;\n // filters can still be registered after the schema is built\n const allFilters = Array.isArray(filters) ? filters : [filters];\n\n const applyFilters = async (\n parent: unknown,\n args: object,\n context: Types[\"Context\"],\n info: Parameters<typeof resolver>[3],\n ) => {\n const runFilters = async (span?: Span) => {\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 return (parent, args, context, info) =>\n allFilters.length === 0\n ? resolver(parent, args, context, info)\n : applyFilters(parent, args, context, info);\n }\n}\n\nexport function registerRuntimeFiltersPlugin() {\n registerPluginOnce(pluginName, RuntimeFiltersPlugin);\n}\n","import { createRequire } from \"node:module\";\nimport type * as LibAddress from \"lib-address\";\nimport { z } from \"zod\";\nimport type { AddressShape } from \"./address\";\n\nconst requireFromHere = createRequire(import.meta.url);\nconst libAddress: typeof LibAddress = requireFromHere(\"lib-address\");\n\nconst {\n AddressValidationError,\n CountryMissingError,\n InvalidStateError,\n InvalidZipError,\n isValidCountryCode,\n MissingFieldError,\n} = libAddress;\n\n//TODO: https://github.com/LancelotP/lib-address/issues/42\nconst validateAddress: typeof LibAddress.validateAddress =\n libAddress.validateAddress;\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, exactly\n * as the `EmailAddress` scalar does. Exported for values that do not arrive as GraphQL input,\n * such as OIDC claims.\n *\n * @throws RumbleErrorSafe if the value is not a valid email address\n */\nexport const normalizeEmailAddress = (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: normalizeEmailAddress,\n parseValue: normalizeEmailAddress,\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 normalizeEmailAddress(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// smart punctuation on phones and word processors swaps these in for ' and -\nconst APOSTROPHE_VARIANTS = /[\\u2018\\u2019\\u02BC\\u00B4\\u0060]/gu;\nconst HYPHEN_VARIANTS = /[\\u2010-\\u2015\\u2212]/gu;\n\n/**\n * Normalizes and validates a person's name, exactly as the `PersonName` scalar does. Exported\n * for values that do not arrive as GraphQL input, such as OIDC claims.\n *\n * @throws RumbleErrorSafe if the value is not a valid name\n */\nexport const normalizePersonName = (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(APOSTROPHE_VARIANTS, \"'\")\n .replace(HYPHEN_VARIANTS, \"-\")\n .replace(/\\p{Zs}+/gu, \" \")\n .trim()\n .replace(/ ?- ?/gu, \"-\")\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 (typographic apostrophe or dash variants, spaces around a hyphen, a doubled or stray leading/trailing hyphen/apostrophe) silently corrected rather than rejected.\",\n serialize: normalizePersonName,\n parseValue: normalizePersonName,\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 normalizePersonName(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. This is what the `PhoneNumber` scalar does with its input; exported for values\n * that do not arrive as GraphQL input. `.number` of the result is the E.164 form.\n *\n * @throws RumbleErrorSafe if the value is not a valid phone number\n */\nexport const parsePhoneNumber = (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 parsePhoneNumber(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: parsePhoneNumber,\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 parsePhoneNumber(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, is, isTable, type Table } from \"drizzle-orm\";\nimport {\n MySqlTable,\n getTableConfig as mysqlTableConfig,\n} from \"drizzle-orm/mysql-core\";\nimport { PgTable, getTableConfig as pgTableConfig } from \"drizzle-orm/pg-core\";\nimport {\n SQLiteTable,\n getTableConfig as sqliteTableConfig,\n} from \"drizzle-orm/sqlite-core\";\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 type { AbilityBuilderType } from \"./abilityBuilder\";\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 { registerColumnMaskPlugin } from \"./columnMaskPlugin/columnMaskPlugin\";\nimport { columnMaskPluginName } from \"./columnMaskPlugin/maskTypes\";\nimport type { ContextType } from \"./context\";\nimport { createAbilityAwareClient } from \"./helpers/abilityAwareClient\";\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 abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n pubsub: ReturnType<typeof createPubSub>;\n abilityBuilder: AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const createSpan =\n otel?.enabled && otel.tracer\n ? createOpenTelemetryWrapper(otel.tracer, otel.options)\n : undefined;\n\n registerRuntimeFiltersPlugin();\n registerColumnMaskPlugin();\n const schemaBuilder = new SchemaBuilder<{\n Context: ContextType<UserContext, DB, RequestEvent, Action, PothosConfig>;\n DrizzleRelations: DB[\"_\"][\"relations\"];\n AsyncSelections: true;\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 // must wrap the runtime filters, so filters see unmasked rows\n columnMaskPluginName,\n pluginName,\n DrizzlePlugin,\n SmartSubscriptionsPlugin,\n TracingPlugin,\n ValidationPlugin,\n ...(pothosConfig?.plugins ?? []),\n ],\n drizzle: {\n // plugin-drizzle >=0.19.1 checks the client structurally against the\n // relations of the generic DB, which TS can't resolve for an unresolved DB\n // @ts-expect-error\n client: createAbilityAwareClient({ db, abilityBuilder }),\n relations: db._.relations,\n getTableConfig(table) {\n if (is(table, PgTable)) return pgTableConfig(table) as any;\n if (is(table, MySqlTable)) return mysqlTableConfig(table) as any;\n if (is(table, SQLiteTable)) return sqliteTableConfig(table) as any;\n return {\n columns: isTable(table)\n ? Object.values(getTableColumns(table as Table))\n : [],\n primaryKeys: [],\n uniqueConstraints: [],\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, abilityBuilder });\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":"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ACX,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,iBAAiB;AAE3E;AAkBA,SAAS,wBACP,QACA,WACA,SACoB;CACpB,MAAM,gBAAA,GAAeC,QA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"}
1
+ {"version":3,"file":"index.cjs","names":["GraphQLError","isTable","getTableColumns","getTableName","EmptyFilter","toMerged","or","relationsFilterToSQL","aliasedTable","sql","SpanNames","ATTR_GRAPHQL_OPERATION_NAME","ATTR_GRAPHQL_OPERATION_TYPE","ATTR_GRAPHQL_DOCUMENT","AttributeNames","trace","isSpanContextValid","SpanStatusCode","once","relationsFilterToSQL","debounce","relationsFilterToSQL","relationsFilterToSQL","makeDefaultName","capitalize","toCamelCase","once","is","PgEnumColumn","PgEnumObjectColumn","MySqlEnumColumn","MySqlEnumObjectColumn","isPgEnum","isTable","getTableName","capitalize","toCamelCase","capitalize","toCamelCase","is","PgColumn","generateFromSchema","once","count","getOperationAST","print","is","PgTable","MySqlTable","SQLiteTable","sql","cloneDeep","capitalize","is","One","PgColumn","createPubSub","sql","BasePlugin","isThenable","BasePlugin","DataLoader","createRequire","z","BaseEmailAddressResolver","GraphQLScalarType","Kind","GraphQLScalarType","Kind","parsePhoneNumberFromString","GraphQLScalarType","Kind","createOpenTelemetryWrapper","SchemaBuilder","DrizzlePlugin","SmartSubscriptionsPlugin","TracingPlugin","ValidationPlugin","is","PgTable","pgTableConfig","MySqlTable","mysqlTableConfig","SQLiteTable","sqliteTableConfig","isTable","getTableColumns","subscribeOptionsFromIterator","isRootField","wrapResolver","JSONResolver","DateResolver","DateTimeISOResolver","BigIntResolver","ByteResolver","LocaleResolver","trace","packagejson.version","once","GraphQLSchema","nativeCreateYoga","useDisableIntrospection","EnvelopArmorPlugin","defaultExecute","defaultSubscribe"],"sources":["../lib/types/rumbleError.ts","../lib/helpers/tableHelpers.ts","../lib/helpers/mergeFilters.ts","../lib/helpers/sanitizeFilterValue.ts","../lib/abilityBuilder/keys.ts","../lib/abilityBuilder/requestState.ts","../lib/abilityBuilder/columnMask.ts","../lib/helpers/sqlTypes/types.ts","../lib/helpers/sqlTypes/distinctValuesFromSQLType.ts","../lib/helpers/telemetry.ts","../lib/abilityBuilder/filterResponse.ts","../lib/abilityBuilder/queryFilter.ts","../lib/helpers/errorLogging.ts","../lib/abilityBuilder/telemetry.ts","../lib/abilityBuilder/tableAbilities.ts","../lib/abilityBuilder/inputGuard.ts","../lib/abilityBuilder/tableBuilder.ts","../lib/abilityBuilder/index.ts","../lib/helpers/asserts.ts","../lib/helpers/mapNullFieldsToUndefined.ts","../package.json","../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/helpers/objectTypeOptions.ts","../lib/helpers/registerPlugin.ts","../lib/columnMaskPlugin/maskTypes.ts","../lib/columnMaskPlugin/columnMaskPlugin.ts","../lib/helpers/abilityAwareClient.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 {\n type Column,\n getTableColumns,\n getTableName,\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","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 */\nexport function realWhere(where: unknown) {\n return where === EmptyFilter ? undefined : where;\n}\n\ntype Mode = \"AND\" | \"OR\";\n\nfunction mergeWhere(a: unknown, b: unknown, mode: Mode) {\n if (a && b) {\n return mode === \"OR\" ? { OR: [a, b] } : { AND: [a, b] };\n }\n // an OR with a missing side would widen to \"everything\", so no where at all\n return mode === \"OR\" ? undefined : (a ?? b);\n}\n\nfunction mergeColumns(\n a?: Record<string, unknown>,\n b?: Record<string, unknown>,\n) {\n if (!a && !b) return undefined;\n const result: Record<string, true> = {};\n for (const [key, value] of [\n ...Object.entries(a ?? {}),\n ...Object.entries(b ?? {}),\n ]) {\n if (value === true) result[key] = true;\n }\n return result;\n}\n\nfunction mergeRecords(a?: Record<string, any>, b?: Record<string, any>) {\n return a || b ? toMerged(a ?? {}, b ?? {}) : undefined;\n}\n\n/**\n * Combines two limit/offset style bounds. For OR the looser bound wins (and a\n * missing side means unbounded), for AND the stricter bound wins.\n */\nfunction mergeBound(\n a: number | undefined,\n b: number | undefined,\n mode: Mode,\n orPick: (a: number, b: number) => number,\n) {\n if (mode === \"OR\") {\n return a === undefined || b === undefined ? undefined : orPick(a, b);\n }\n return a || b ? Math.min(a ?? Infinity, b ?? Infinity) : undefined;\n}\n\nexport function mergeFilters<\n FilterA extends Record<string, any>,\n FilterB extends Record<string, any>,\n>(filterA?: Partial<FilterA>, filterB?: Partial<FilterB>, mode: Mode = \"AND\") {\n return {\n where: mergeWhere(\n realWhere(filterA?.where),\n realWhere(filterB?.where),\n mode,\n ),\n columns: mergeColumns(filterA?.columns, filterB?.columns),\n extras: mergeRecords(filterA?.extras, filterB?.extras),\n orderBy: mergeRecords(filterA?.orderBy, filterB?.orderBy),\n limit: mergeBound(filterA?.limit, filterB?.limit, mode, Math.max),\n offset: mergeBound(filterA?.offset, filterB?.offset, mode, Math.min),\n with: mergeRecords(filterA?.with, filterB?.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","// per row: the index of the action the row was loaded with\nexport const ACTION_FLAG_KEY = \"__rumble_action\";\n// per row and column group: 1 if the row matches one of the group's abilities\nexport const columnFlagKey = (group: number) => `__rumble_columns_${group}`;\n\nexport const columnMaskKey = Symbol.for(\"rumble:columnMask\");\n// per resolved filter: which rows expose a column, see `ColumnVisibility`\nexport const columnVisibilityKey = Symbol.for(\"rumble:columnVisibility\");\n// per request: the function checking client supplied where / orderBy against it\nexport const guardInputKey = Symbol.for(\"rumble:guardInput\");\nexport const resolvedFilterKey = Symbol.for(\"rumble:resolvedFilter\");\n\n// the masking state of a request, on its abilities\nexport const requestStateKey = Symbol.for(\"rumble:requestState\");\n","import type DataLoader from \"dataloader\";\nimport { requestStateKey } from \"./keys\";\n\n/**\n * The state of a single request, kept on its abilities instead of globally\n * or on the rows.\n */\nexport type RequestState<Action extends string> = {\n /** the rows masked in this request and whether their primary key is hidden */\n masked: WeakMap<object, boolean>;\n /** the columns hidden on the rows masked in this request */\n hidden: WeakMap<object, { cleared: string[]; primaryKey: boolean }>;\n /** per table the actions rows were masked with, reloads apply them */\n actions: Map<string, Set<Action>>;\n /** per runtime filter the loader batching its calls */\n filterLoaders: Map<object, DataLoader<any, any>>;\n};\n\nexport function createRequestState<\n Action extends string,\n>(): RequestState<Action> {\n return {\n // weak, a subscription's request lives as long as the subscription\n masked: new WeakMap(),\n hidden: new WeakMap(),\n actions: new Map(),\n filterLoaders: new Map(),\n };\n}\n\nexport function attachRequestState(\n abilities: object,\n state: RequestState<any>,\n) {\n // a symbol, so it can't collide with a table name\n Object.defineProperty(abilities, requestStateKey, { value: state });\n}\n\nexport function requestStateOf<Action extends string>(\n abilities: object | undefined,\n) {\n return (abilities as any)?.[requestStateKey] as\n | RequestState<Action>\n | undefined;\n}\n","import { aliasedTable, or, relationsFilterToSQL, sql } from \"drizzle-orm\";\nimport { realWhere } from \"../helpers/mergeFilters\";\nimport { sanitizeFilterValue } from \"../helpers/sanitizeFilterValue\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport {\n ACTION_FLAG_KEY,\n columnFlagKey,\n columnMaskKey,\n resolvedFilterKey,\n} from \"./keys\";\nimport { type RequestState, requestStateOf } from \"./requestState\";\nimport type { AbilitySettings, TableSchema } from \"./types\";\n\ntype HiddenColumns = {\n /** cleared on the row */\n cleared: string[];\n /** primary keys stay on the row, their fields hide them */\n primaryKey: boolean;\n};\n\nexport type ColumnMask = {\n guaranteed: Set<string>;\n conditional: Set<string>[];\n /** the extra flagging each conditional group */\n flags: string[];\n /** keyed by the matched groups, e.g. \"01\" */\n hiddenPerMatch: Map<string, HiddenColumns>;\n};\n\nfunction referencesRelation(\n filter: unknown,\n relations: Record<string, unknown>,\n): boolean {\n if (!filter || typeof filter !== \"object\") return false;\n return Object.entries(filter).some(([key, value]) => {\n if (key === \"AND\" || key === \"OR\") {\n return (value as unknown[]).some((v) => referencesRelation(v, relations));\n }\n if (key === \"NOT\") return referencesRelation(value, relations);\n return key in relations;\n });\n}\n\nfunction selectedColumns(\n columns: Record<string, boolean | undefined> | undefined,\n allColumns: string[],\n) {\n if (!columns) return new Set(allColumns);\n const entries = Object.entries(columns).filter(([, v]) => v !== undefined);\n if (entries.some(([, v]) => v)) {\n return new Set(entries.filter(([, v]) => v).map(([k]) => k));\n }\n if (entries.length === 0) return new Set<string>();\n return new Set(allColumns.filter((c) => columns[c] !== false));\n}\n\nfunction hiddenColumns(\n mask: ColumnMask,\n matched: string,\n allColumns: string[],\n primaryKey: string[],\n) {\n let hidden = mask.hiddenPerMatch.get(matched);\n if (!hidden) {\n const columns = allColumns.filter(\n (column) =>\n !mask.guaranteed.has(column) &&\n !mask.conditional.some(\n (columns, group) => matched[group] === \"1\" && columns.has(column),\n ),\n );\n hidden = {\n cleared: columns.filter((c) => !primaryKey.includes(c)),\n primaryKey: columns.some((c) => primaryKey.includes(c)),\n };\n mask.hiddenPerMatch.set(matched, hidden);\n }\n return hidden;\n}\n\nconst hasWhere = (where: unknown) =>\n !!where && Object.keys(where as object).length > 0;\n\ntype ColumnRule = { where: unknown; columns: Set<string> };\n\n/**\n * Which rows expose a column to the caller: all of them (`true`), none of\n * them (`false`) or those matching the returned where.\n */\nexport type ColumnVisibility = (column: string) => true | false | object;\n\n/** Columns every returned row is allowed to expose. */\nfunction guaranteedColumns(rules: ColumnRule[], allColumnNames: string[]) {\n // every returned row matches at least one ability\n const guaranteed = new Set<string>();\n for (const rule of rules) {\n if (hasWhere(rule.where)) continue;\n for (const column of rule.columns) guaranteed.add(column);\n }\n for (const column of allColumnNames) {\n if (rules.every((r) => r.columns.has(column))) {\n guaranteed.add(column);\n }\n }\n return guaranteed;\n}\n\n/**\n * Groups the conditional rules by the columns they grant on top of the\n * guaranteed ones. Each group gets its own flag.\n */\nfunction conditionalGroups(rules: ColumnRule[], guaranteed: Set<string>) {\n const groups = new Map<string, { columns: Set<string>; wheres: unknown[] }>();\n for (const rule of rules) {\n if (!hasWhere(rule.where)) continue;\n const additional = [...rule.columns]\n .filter((c) => !guaranteed.has(c))\n .sort();\n if (additional.length === 0) continue;\n const key = additional.join(\",\");\n const group = groups.get(key);\n if (group) {\n group.wheres.push(rule.where);\n } else {\n groups.set(key, {\n columns: new Set(additional),\n wheres: [rule.where],\n });\n }\n }\n return [...groups.values()];\n}\n\n/**\n * Creates the resolver which turns the abilities of a table into the columns\n * to select and, if columns depend on the matched ability, extras flagging\n * per row which abilities matched plus the mask to decode them.\n */\nexport function createColumnAccessResolver<\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends TableRelationNames<DB>,\n>({ db, actions }: AbilitySettings<DB, Action>, tableSchema: TableSchema) {\n const allColumnNames = Object.keys(tableSchema.columns);\n const primaryKeyNames = Object.keys(tableSchema.primaryKey);\n const primaryKeyName = primaryKeyNames[0]!;\n\n const toSQL = (table: any, wheres: unknown[]) =>\n or(\n ...wheres.map((where) =>\n relationsFilterToSQL(\n table,\n sanitizeFilterValue(where) as any,\n tableSchema.relations,\n db._.relations,\n ),\n ),\n );\n\n // Relational filters become subqueries. They are correlated to the row\n // (`exists (... where pk = row.pk and rule)`): an uncorrelated\n // `pk in (select pk ... where rule)` makes postgres evaluate every rule\n // against the whole table, once per flag and per nesting site, which turns\n // queries nesting a masked relation twice into multi-second ones.\n const uncorrelated = (table: any, wheres: unknown[], group: number) => {\n const inner = aliasedTable(tableSchema.table, `rumble_columns_${group}`);\n // a subquery renders with its own parentheses\n return sql`exists ${(db as any)\n .select({ pk: inner[primaryKeyName] })\n .from(inner)\n .where(\n sql`${inner[primaryKeyName]} = ${table[primaryKeyName]} and (${toSQL(inner, wheres)})`,\n )}`;\n };\n\n // An ability's columns only apply to the rows matched by its where. The\n // wheres are expected to restrict rows, see `restrictingWhere`.\n return function resolveColumnAccess(\n action: Action,\n filters: DrizzleQueryFunctionInput<DB, TableName>[],\n ) {\n const rules = filters.map((f) => ({\n where: realWhere(f?.where),\n columns: selectedColumns(f?.columns as any, allColumnNames),\n }));\n\n const guaranteed = guaranteedColumns(rules, allColumnNames);\n const groups = conditionalGroups(rules, guaranteed);\n\n // primary keys are always loaded, pothos reloads rows and subscriptions\n // by them. If not granted, the mask hides them from the client.\n const selected = new Set([\n ...primaryKeyNames,\n ...rules.flatMap((r) => [...r.columns]),\n ]);\n const columns =\n selected.size === allColumnNames.length\n ? undefined\n : Object.fromEntries([...selected].map((c) => [c, true]));\n\n // A mask (and action flag) is needed even without conditional groups:\n // rows loaded without the ability's columns (pothos reloads, custom\n // resolvers) are reduced to the guaranteed columns, and the action flag\n // records the action the row was loaded with, so that action's mask applies.\n if (guaranteed.size === allColumnNames.length) {\n return {\n columns,\n extras: undefined,\n mask: undefined,\n visibility: undefined,\n };\n }\n\n // A column is exposed by the rows matching any rule that grants it. Rules\n // without a where grant their columns to every row, those are guaranteed.\n const visibility: ColumnVisibility = (column) => {\n if (guaranteed.has(column)) return true;\n const wheres = rules\n .filter((rule) => rule.columns.has(column))\n .map((rule) => rule.where as object);\n if (wheres.length === 0) return false;\n return wheres.length === 1 ? wheres[0]! : { OR: wheres };\n };\n\n const mask: ColumnMask = {\n guaranteed,\n conditional: groups.map((g) => g.columns),\n flags: groups.map((_, group) => columnFlagKey(group)),\n hiddenPerMatch: new Map(),\n };\n const actionIndex = sql.raw(String(actions.indexOf(action)));\n // callbacks, so nested relation queries pass their aliased table\n const extras: Record<string, (table: any) => any> = {\n [ACTION_FLAG_KEY]: () => sql`${actionIndex}`,\n };\n groups.forEach(({ wheres }, group) => {\n const relational = wheres.some((w) =>\n referencesRelation(w, tableSchema.relations),\n );\n extras[mask.flags[group]!] = (table: any) => {\n const condition = relational\n ? uncorrelated(table, wheres, group)\n : toSQL(table, wheres);\n return sql`case when ${condition} then 1 else 0 end`;\n };\n });\n\n return { columns, extras, mask, visibility };\n };\n}\n\ntype Row = Record<PropertyKey, unknown>;\n\nconst isRow = (row: unknown): row is Row => !!row && typeof row === \"object\";\n\nfunction clearColumns(row: Row, columns: string[]) {\n for (let i = 0; i < columns.length; i++) {\n const column = columns[i]!;\n if (row[column] !== undefined) row[column] = undefined;\n }\n}\n\n// \"1\" per group the row matched, unflagged rows match none and only get the\n// guaranteed columns\nfunction matchedGroups(row: Row, flags: string[]) {\n let matched = \"\";\n for (let i = 0; i < flags.length; i++) {\n matched += Number(row[flags[i]!]) === 1 ? \"1\" : \"0\";\n }\n return matched;\n}\n\nfunction maskRow(row: Row, mask: ColumnMask, hidden: HiddenColumns) {\n // assign instead of delete to keep the row's hidden class\n if (row[ACTION_FLAG_KEY] !== undefined) row[ACTION_FLAG_KEY] = undefined;\n clearColumns(row, mask.flags);\n clearColumns(row, hidden.cleared);\n}\n\nexport type MaskColumnsInput<\n DB extends DrizzleInstance,\n Action extends string,\n> = {\n table: TableRelationNames<DB>;\n action: Action;\n abilities: Record<string, any>;\n entities: unknown[];\n};\n\n/**\n * Creates the function hiding the columns of queried rows which the ability\n * that matched the row does not grant.\n */\nexport function createColumnMasker<\n DB extends DrizzleInstance,\n Action extends string,\n>(\n { actions }: AbilitySettings<DB, Action>,\n tables: Map<\n TableRelationNames<DB>,\n { columns: string[]; primaryKey: string[] }\n >,\n) {\n const stateOf = (abilities: object) =>\n requestStateOf<Action>(abilities) as RequestState<Action>;\n\n const maskedActions = (\n abilities: object,\n table: TableRelationNames<DB>,\n ): Set<Action> => {\n const { actions } = stateOf(abilities);\n let used = actions.get(table);\n if (!used) {\n used = new Set();\n actions.set(table, used);\n }\n return used;\n };\n\n const primaryKeyHidden = (abilities: object, row: object) =>\n stateOf(abilities).masked.get(row) === true;\n\n const maskColumns = (\n { table, action, abilities, entities }: MaskColumnsInput<DB, Action>,\n start = 0,\n ): void | Promise<void> => {\n const tableAbilities = abilities[table];\n const { columns: columnNames, primaryKey } = tables.get(table)!;\n const state = stateOf(abilities);\n const used = maskedActions(abilities, table);\n\n for (let i = start; i < entities.length; i++) {\n const row = entities[i];\n if (!isRow(row) || state.masked.has(row)) continue;\n\n const flagged = row[ACTION_FLAG_KEY] != null;\n const rowAction = flagged\n ? actions[Number(row[ACTION_FLAG_KEY])]!\n : action;\n used.add(rowAction);\n\n const resolved = tableAbilities[resolvedFilterKey](rowAction);\n if (!resolved) {\n return tableAbilities\n .filter(rowAction)\n .then(() => maskColumns({ table, action, abilities, entities }, i));\n }\n\n const mask: ColumnMask | undefined = resolved[columnMaskKey];\n if (!mask) continue;\n\n const matched = matchedGroups(row, mask.flags);\n const hidden = hiddenColumns(mask, matched, columnNames, primaryKey);\n maskRow(row, mask, hidden);\n state.masked.set(row, hidden.primaryKey);\n state.hidden.set(row, hidden);\n }\n };\n\n /**\n * Whether masking hid any of the columns on the row. A hidden primary key\n * counts for the columns it consists of.\n */\n const columnsHidden = (\n abilities: object,\n row: object,\n columns: string[],\n primaryKey: string[],\n ) => {\n const hidden = stateOf(abilities).hidden.get(row);\n return (\n !!hidden &&\n columns.some(\n (column) =>\n hidden.cleared.includes(column) ||\n (hidden.primaryKey && primaryKey.includes(column)),\n )\n );\n };\n\n return { maskColumns, maskedActions, primaryKeyHidden, columnsHidden };\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 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`. */\nconst ATTR_VARIABLES_PREFIX: string = AttributeNames.VARIABLES;\n/** Log field holding all variables as one object (logs keep nesting, spans flatten). */\nconst 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 { relationsFilterToSQL, type SQL } from \"drizzle-orm\";\nimport { once } from \"es-toolkit\";\nimport { mergeFilters } from \"../helpers/mergeFilters\";\nimport { sanitizeFilterValue } from \"../helpers/sanitizeFilterValue\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport type { ColumnMask, ColumnVisibility } from \"./columnMask\";\nimport { columnMaskKey, columnVisibilityKey } from \"./keys\";\nimport type { AbilitySettings, TableSchema } from \"./types\";\n\ntype FindFirstConfig<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = NonNullable<Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]>;\n\ntype FindManyConfig<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = NonNullable<Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]>;\n\n/**\n * The query filters of an ability, as handed out by\n * `abilities.<table>.filter(...)`.\n *\n * `columns` and `extras` are set at runtime but left out of the types on\n * purpose: a visible, loosely typed extras makes drizzle infer `{}` as the row\n * type of findFirst/findMany, and the column flag is an internal detail anyway.\n */\nexport type AbilityFilter<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: async (_args, ctx) => (await ctx.abilities.users.filter(\"read\")).query.single,\n * }),\n * ```\n */\n query: {\n /**\n * For find first calls\n */\n single: Pick<FindFirstConfig<DB, TableName>, \"where\">;\n /**\n * For find many calls\n */\n many: Pick<FindManyConfig<DB, TableName>, \"where\" | \"limit\">;\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 (await ctx.abilities.users.filter(\"update\")).sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n readonly where: SQL | undefined;\n };\n};\n\n/**\n * What `abilities.<table>.filter(...)` resolves to.\n */\n// exported so the bundled declarations name it instead of inlining it\n// fallow-ignore-next-line unused-type\nexport type AbilityFilterResponse<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n> = AbilityFilter<DB, TableName> & {\n /**\n * Merges the current query filters with the provided filters for this call only\n */\n merge: (\n filters: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>,\n ) => AbilityFilter<DB, TableName>;\n};\n\n/**\n * The limit of a find many call. An injected merge limit wins unless the\n * ability limit is lower, otherwise the default limit caps the ability limit.\n */\nfunction resolveLimit(\n abilityLimit: number | undefined | null,\n mergedLimit: number | undefined,\n defaultLimit: number | undefined | null,\n) {\n if (\n mergedLimit !== undefined &&\n (!abilityLimit || abilityLimit > mergedLimit)\n ) {\n return mergedLimit;\n }\n\n if (\n defaultLimit &&\n (abilityLimit === undefined || (abilityLimit as number) > defaultLimit)\n ) {\n return defaultLimit;\n }\n\n // ensure that null is converted to undefined\n return abilityLimit ?? undefined;\n}\n\n/**\n * Creates the function packing resolved query filters into the object handed\n * out by `abilities.<table>.filter(...)`.\n */\nexport function createFilterResponder<\n DB extends DrizzleInstance,\n TableName extends TableRelationNames<DB>,\n>({ db, defaultLimit }: AbilitySettings<DB, any>, tableSchema: TableSchema) {\n const internalTransformer = (\n filters?: DrizzleQueryFunctionInput<DB, TableName>,\n mergedLimit?: number,\n ): AbilityFilter<DB, TableName> => {\n const where = filters?.where;\n const extras = filters?.extras;\n const columns = filters?.columns;\n\n const limit = once(() =>\n resolveLimit(\n filters?.limit as number | undefined | null,\n mergedLimit,\n defaultLimit,\n ),\n );\n\n const sqlTransformedWhere = once(() => {\n const casing = (db._ as any).session?.dialect?.casing;\n\n return where\n ? relationsFilterToSQL(\n tableSchema.foundRelation.table,\n sanitizeFilterValue(where) as any,\n tableSchema.relations,\n db._.relations,\n casing,\n )\n : undefined;\n });\n\n // Two shapes since we do not want to use delete for performance reasons\n // and an undefined columns field on a drizzle filter will prevent any\n // column from being selected at all\n const single = columns\n ? { extras, where: sanitizeFilterValue(where), columns }\n : { extras, where: sanitizeFilterValue(where) };\n const many = columns\n ? {\n extras,\n where: sanitizeFilterValue(where),\n columns,\n get limit() {\n return limit();\n },\n }\n : {\n extras,\n where: sanitizeFilterValue(where),\n get limit() {\n return limit();\n },\n };\n\n return {\n query: { single, many },\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n } as AbilityFilter<DB, TableName>;\n };\n\n /**\n * Packs the filters into a response object that can be applied for queries by the user\n */\n return function transformToResponse(\n queryFilters?: DrizzleQueryFunctionInput<DB, TableName>,\n columnMask?: ColumnMask,\n columnVisibility?: ColumnVisibility,\n ) {\n const ret = internalTransformer(queryFilters) as AbilityFilterResponse<\n DB,\n TableName\n >;\n\n ret.merge = (filters) =>\n internalTransformer(\n mergeFilters(ret.query.many, filters),\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 filters.limit as number | undefined,\n );\n (ret as any)[columnMaskKey] = columnMask;\n (ret as any)[columnVisibilityKey] = columnVisibility;\n\n return ret;\n };\n}\n","import type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleQueryFunctionInput,\n} from \"../types/drizzleInstanceType\";\n\n/**\n * Static, non changing query filter input type for a specific table\n */\nexport type 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 */\nexport type DynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> = (\n context: Context,\n) =>\n | StaticQueryFilter<DB, Table, Filter>\n | undefined\n | \"allow\"\n | Promise<StaticQueryFilter<DB, Table, Filter> | undefined | \"allow\">;\n\n/**\n * Combined query filter type for a specific table. May be static or dynamic.\n */\nexport type 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\n/**\n * The query filters registered per action. \"unrestricted\" when a bare allow()\n * granted the action without conditions.\n */\nexport type QueryFilterRegistry<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends keyof DrizzleQueryFunction<DB>,\n> = Map<\n Action,\n | QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[]\n | \"unrestricted\"\n>;\n\nexport function 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 typeof filter === \"function\";\n}\n\nexport function 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","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 type { AttributeValue, Span } from \"@opentelemetry/api\";\nimport { debounce } from \"es-toolkit\";\nimport { errorLogField } from \"../helpers/errorLogging\";\nimport {\n ATTR_ACTION,\n ATTR_TABLE,\n recordSpanError,\n SPAN_ABILITIES_PREPARE,\n type TelemetryConfig,\n traceCorrelationFields,\n} from \"../helpers/telemetry\";\nimport type { RumbleLogger } from \"../types/rumbleInput\";\nimport type { AbilitySettings } from \"./types\";\n\nexport const 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\n/**\n * Runs the preparation of the abilities of one table and action, reporting\n * the attributes it collects to the span and the logger.\n */\nexport function traceAbilityPreparation<T>(\n { otel, log, telemetryConfig }: AbilitySettings<any, any>,\n tableName: string,\n action: string,\n assemble: (attributes: Record<string, AttributeValue>) => Promise<T>,\n): Promise<T> {\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 = async (span?: Span) => {\n const attributes: Record<string, AttributeValue> = {\n [ATTR_TABLE]: tableName,\n [ATTR_ACTION]: action,\n };\n\n try {\n const result = await assemble(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(SPAN_ABILITIES_PREPARE, async (span) => {\n try {\n return await run(span);\n } finally {\n span.end();\n }\n });\n }\n\n return run();\n}\n","import type { AttributeValue } from \"@opentelemetry/api\";\nimport { relationsFilterToSQL } from \"drizzle-orm\";\nimport { mergeFilters, realWhere } 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} from \"../helpers/telemetry\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\nimport { createColumnAccessResolver } from \"./columnMask\";\nimport { createFilterResponder } from \"./filterResponse\";\nimport { resolvedFilterKey } from \"./keys\";\nimport {\n type DynamicQueryFilter,\n isDynamicQueryFilter,\n isStaticQueryFilter,\n type QueryFilterRegistry,\n type StaticQueryFilter,\n} from \"./queryFilter\";\nimport { traceAbilityPreparation } from \"./telemetry\";\nimport type { AbilitySettings, TableSchema } from \"./types\";\n\n/**\n * filter() is async. Without type checking (plain JS, `any`) a forgotten await would\n * hand the promise itself to drizzle\n */\nfunction guardAgainstMissingAwait<T>(promise: Promise<T>): Promise<T> {\n for (const key of [\"query\", \"sql\", \"merge\"]) {\n Object.defineProperty(promise, key, {\n enumerable: true,\n get() {\n throw new RumbleError(\n `Tried to access \"${key}\" on the result of abilities.<table>.filter(...) which is a Promise. filter() is async, did you forget to await it?`,\n );\n },\n });\n }\n return promise;\n}\n\n/**\n * A filter no row can match, since it requires the primary key to equal two\n * distinct values at once.\n */\nexport function createBlockEverythingFilter(\n tableName: string,\n tableSchema: TableSchema,\n) {\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n throw new RumbleError(`No primary key found for entity ${tableName}`);\n }\n\n // relational where keys are ts names, not database names\n const [primaryKeyName, primaryKeyField] = Object.entries(\n tableSchema.primaryKey,\n )[0] as [string, any];\n const distinctValues = createDistinctValuesFromSQLType(\n primaryKeyField.getSQLType() as any,\n );\n\n return {\n where: {\n AND: [\n {\n [primaryKeyName]: distinctValues.value1,\n },\n {\n [primaryKeyName]: distinctValues.value2,\n },\n ],\n },\n };\n}\n\n/**\n * Creates the abilities of a single table, which resolve the registered\n * query filters for a request.\n */\nexport const createTableAbilities = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends TableRelationNames<DB>,\n>(\n settings: AbilitySettings<DB, Action>,\n tableName: TableName,\n queryFilters: QueryFilterRegistry<UserContext, DB, Action, TableName>,\n) => {\n const { db, actions } = settings;\n\n const tableSchema = tableHelper({\n db,\n table: tableName,\n });\n\n // A where compiling to no sql (e.g. `{ id: undefined }`) restricts nothing,\n // so its ability applies to every row. Dropped here, the row filter and the\n // column mask both treat it as such.\n const withRestrictingWhere = <Filter>(filter: Filter): Filter => {\n const where = realWhere((filter as { where?: unknown }).where);\n const restricts =\n !!where &&\n Object.keys(where).length > 0 &&\n relationsFilterToSQL(\n tableSchema.table,\n sanitizeFilterValue(where) as any,\n tableSchema.relations,\n db._.relations,\n ) !== undefined;\n return restricts || where === undefined\n ? filter\n : { ...filter, where: undefined };\n };\n\n // static filters are known upfront, so they are only checked once\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 [\n action,\n filters.filter(isStaticQueryFilter).map(withRestrictingWhere),\n ];\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 // we want a filter that excludes everything\n const blockEverythingFilter = createBlockEverythingFilter(\n String(tableName),\n tableSchema,\n );\n const resolveColumnAccess = createColumnAccessResolver<DB, Action, TableName>(\n settings,\n tableSchema,\n );\n const transformToResponse = createFilterResponder<DB, TableName>(\n settings,\n tableSchema,\n );\n\n const assembleAbilities = async (\n userContext: UserContext,\n action: Action,\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 settings.warnNothingRegistered(String(tableName), action);\n return transformToResponse(blockEverythingFilter);\n }\n\n // run all dynamic filters, they may be async so we start all of them first\n const rawResults = await Promise.all(\n dynamicQueryFilters[action].map((func) => func(userContext)),\n );\n\n // if one of the dynamic filters returns \"allow\", we want to allow everything\n if (rawResults.includes(\"allow\")) {\n attributes[ATTR_ABILITIES_STATUS] = \"unrestricted\";\n return transformToResponse();\n }\n\n // if nothing is returned, nothing is allowed by this filter\n const dynamicResults = (\n rawResults.filter(\n (r): r is Exclude<typeof r, undefined | \"allow\"> => r !== undefined,\n ) as DrizzleQueryFunctionInput<DB, TableName>[]\n ).map(withRestrictingWhere);\n\n attributes[ATTR_ABILITIES_DYNAMIC] = dynamicResults.length;\n attributes[ATTR_ABILITIES_STATIC] = simpleQueryFilters[action].length;\n\n const allQueryFilters = [...simpleQueryFilters[action], ...dynamicResults];\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 ) as Record<string, any>;\n\n const { columns, extras, mask, visibility } = resolveColumnAccess(\n action,\n allQueryFilters,\n );\n if (columns) {\n mergedFilters.columns = columns;\n } else {\n delete mergedFilters.columns;\n }\n if (extras) {\n mergedFilters.extras = {\n ...mergedFilters.extras,\n ...extras,\n };\n }\n\n attributes[ATTR_ABILITIES_STATUS] = \"applied\";\n return transformToResponse(mergedFilters as any, mask, visibility);\n };\n\n return {\n withContext: (userContext: UserContext) => {\n const prepare = (action: Action) =>\n traceAbilityPreparation(\n settings,\n String(tableName),\n action,\n (attributes) => assembleAbilities(userContext, action, attributes),\n );\n\n // abilities are resolved once per request and action, since\n // filter() is called by every field and the (possibly async)\n // callbacks may be expensive, e.g. calling an external service\n const cache = new Map<Action, ReturnType<typeof prepare>>();\n const resolved = new Map<Action, Awaited<ReturnType<typeof prepare>>>();\n\n const abilities = {\n filter: (action: Action) => {\n let prepared = cache.get(action);\n if (!prepared) {\n prepared = guardAgainstMissingAwait(prepare(action));\n cache.set(action, prepared);\n prepared.then(\n (result) => resolved.set(action, result),\n () => {},\n );\n }\n return prepared;\n },\n };\n // kept out of the type: declaration emit can't name the internal key\n (abilities as any)[resolvedFilterKey] = (action: Action) =>\n resolved.get(action);\n return abilities;\n },\n };\n};\n","import { relationsFilterToSQL, sql } from \"drizzle-orm\";\nimport { sanitizeFilterValue } from \"../helpers/sanitizeFilterValue\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport type { ColumnVisibility } from \"./columnMask\";\nimport { columnVisibilityKey, guardInputKey } from \"./keys\";\nimport { createBlockEverythingFilter } from \"./tableAbilities\";\n\ntype Where = Record<string, any>;\n\n/** The ts names of the columns a relation joins on, on either side. */\nexport function relationColumnKeys(\n db: DrizzleInstance,\n table: string,\n columns: unknown[] | undefined,\n) {\n const known = tableHelper({ db, table }).columns;\n return (columns ?? []).flatMap((column: any) => {\n const raw = column?._?.column ?? column;\n const key = Object.entries(known).find(\n ([name, candidate]) => candidate === raw || name === raw?.name,\n )?.[0];\n return key ? [key] : [];\n });\n}\n\nexport type GuardedInput = { where?: unknown; orderBy?: unknown };\n\ntype InputGuard = ReturnType<typeof createInputGuard>;\n\nconst isObject = (value: unknown): value is Where =>\n !!value && typeof value === \"object\" && !Array.isArray(value);\n\n/**\n * Column masking hides values after the query ran, but a `where` or `orderBy`\n * argument is applied by the database on the real values: filtering for\n * `{ salary: { gt: 5000 } }` reveals which rows exceed it whether or not the\n * column may be read. This restricts such arguments to what the abilities\n * expose:\n *\n * - a column only matches on rows which expose it, for all other rows the\n * condition is false\n * - sorting by a column treats it as empty on rows which do not expose it\n * - a relation filter requires the columns the relation joins on to be\n * exposed, and is restricted to the rows the caller may read of the related\n * table, whose masked columns follow the same rules\n */\nexport function createInputGuard<DB extends DrizzleInstance>({\n db,\n abilities,\n readActionOf,\n}: {\n db: DB;\n abilities: Record<string, any>;\n readActionOf: (table: string) => string;\n}) {\n const visibilityOf = async (table: string, action: string) =>\n (await abilities[table].filter(action))[columnVisibilityKey] as\n | ColumnVisibility\n | undefined;\n\n const never = (table: string) =>\n createBlockEverythingFilter(table, tableHelper({ db, table })).where;\n\n /** The conditions under which the given columns are exposed. */\n const exposed = async (table: string, action: string, keys: string[]) => {\n const visibility = await visibilityOf(table, action);\n if (!visibility) return [];\n const conditions: unknown[] = [];\n for (const key of keys) {\n const condition = visibility(key);\n if (condition === true) continue;\n conditions.push(condition === false ? never(table) : condition);\n }\n return conditions;\n };\n\n /** The filter of a relation: the related rows the caller may read, exposing what it joins on. */\n const guardRelation = async (\n table: string,\n action: string,\n key: string,\n value: unknown,\n guarded: Where,\n conditions: unknown[],\n ) => {\n const relation = tableHelper({ db, table }).relations[key] as any;\n const target = relation.targetTableName as string;\n const targetAction = readActionOf(target);\n const targetKeys = relationColumnKeys(db, target, relation.targetColumns);\n\n conditions.push(\n ...(await exposed(\n table,\n action,\n relationColumnKeys(db, table, relation.sourceColumns),\n )),\n );\n\n const readable = (await abilities[target].filter(targetAction)).query.many\n .where;\n const related = [\n ...(readable ? [readable] : []),\n ...(await exposed(target, targetAction, targetKeys)),\n ];\n const inner = isObject(value)\n ? ((await guardWhere(target, targetAction, value)) as Where)\n : {};\n\n if (related.length === 0) {\n guarded[key] = isObject(value) ? inner : value;\n } else if (value === false) {\n // \"has no related rows\" means none of the ones the caller can see\n conditions.push({ NOT: { [key]: { AND: related } } });\n } else {\n guarded[key] = { ...inner, AND: [...(inner.AND ?? []), ...related] };\n }\n };\n\n // the operands of AND / OR (a list) and NOT (a single filter)\n const guardLogic = (table: string, action: string, value: unknown) =>\n Array.isArray(value)\n ? Promise.all(value.map((v) => guardWhere(table, action, v)))\n : guardWhere(table, action, value);\n\n /** A single entry of a where: a logical operator, a relation or a column. */\n const guardEntry = async (\n table: string,\n action: string,\n [key, value]: [string, unknown],\n guarded: Where,\n conditions: unknown[],\n ) => {\n const schema = tableHelper({ db, table });\n if (key === \"AND\" || key === \"OR\" || key === \"NOT\") {\n guarded[key] = await guardLogic(table, action, value);\n } else if (key in schema.relations) {\n await guardRelation(table, action, key, value, guarded, conditions);\n } else {\n guarded[key] = value;\n if (key in schema.columns) {\n conditions.push(...(await exposed(table, action, [key])));\n }\n }\n };\n\n const guardWhere = async (\n table: string,\n action: string,\n where: unknown,\n ): Promise<unknown> => {\n if (!isObject(where)) return where;\n const guarded: Where = {};\n const conditions: unknown[] = [];\n\n for (const entry of Object.entries(where)) {\n await guardEntry(table, action, entry, guarded, conditions);\n }\n\n if (conditions.length === 0) return guarded;\n return { ...guarded, AND: [...(guarded.AND ?? []), ...conditions] };\n };\n\n const guardOrderBy = async (\n table: string,\n action: string,\n orderBy: unknown,\n ): Promise<unknown> => {\n if (!isObject(orderBy)) return orderBy;\n const visibility = await visibilityOf(table, action);\n if (!visibility) return orderBy;\n const entries = Object.entries(orderBy).filter(\n ([, direction]) => direction,\n );\n if (entries.every(([key]) => visibility(key) === true)) return orderBy;\n\n const schema = tableHelper({ db, table });\n return (aliased: any, { asc, desc }: any) =>\n entries.map(([key, direction]) => {\n const condition = visibility(key);\n const column = aliased[key];\n const value =\n condition === true\n ? column\n : condition === false\n ? null\n : // the column only counts where it is exposed\n sql`case when ${relationsFilterToSQL(\n aliased,\n sanitizeFilterValue(condition) as any,\n schema.relations,\n db._.relations,\n )} then ${column} end`;\n return (direction === \"asc\" ? asc : desc)(value ?? sql`null`);\n });\n };\n\n return {\n input: async (table: string, action: string, input: GuardedInput) => ({\n ...input,\n where: await guardWhere(table, action, input.where),\n orderBy: await guardOrderBy(table, action, input.orderBy),\n }),\n exposed,\n };\n}\n\n/**\n * Restricts client supplied `where` and `orderBy` arguments to what the\n * abilities of the request let the caller read, see `createInputGuard`.\n */\nexport function guardFilterInput(\n abilities: object,\n table: string,\n action: string,\n input: GuardedInput,\n) {\n const guard = (abilities as any)[guardInputKey] as InputGuard | undefined;\n return guard ? guard.input(table, action, input) : Promise.resolve(input);\n}\n\n/**\n * The conditions a row of the related table has to meet to be reached through\n * a relation: the columns the relation joins on have to be exposed on it.\n */\nexport async function relationExposure(\n abilities: object,\n table: string,\n action: string,\n columns: string[],\n) {\n const guard = (abilities as any)[guardInputKey] as InputGuard | undefined;\n return guard ? guard.exposed(table, action, columns) : [];\n}\n","import type {\n Filter,\n FilterPrefetchCombo,\n Prefetch,\n} from \"../runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunctionInput,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\nimport type { QueryFilter, QueryFilterRegistry } from \"./queryFilter\";\n\n/**\n * Creates the registration API (allow/filter) of a single table.\n */\nexport const createTableBuilder = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n Action extends string,\n TableName extends TableRelationNames<DB>,\n>({\n actions,\n isBuilt,\n}: {\n actions: Action[];\n isBuilt: () => boolean;\n}) => {\n const queryFilters: QueryFilterRegistry<UserContext, DB, Action, TableName> =\n new Map();\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 // prefetch() is an optional step before by(), so both paths end in the\n // same registration, with the prefetched type flowing into the filter\n const registerFilter = <PrefetchReturnType = never>(\n actions: Action[],\n prefetch?: Prefetch<UserContext, PrefetchReturnType>,\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 PrefetchReturnType\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters\n .get(action)!\n .push(\n prefetch\n ? { filter: explicitFilter, prefetch }\n : { filter: explicitFilter },\n );\n }\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 (isBuilt()) {\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 ) => registerFilter<PrefetchReturnType>(actions, prefetch),\n ...registerFilter(actions),\n };\n },\n _: {\n runtimeFilters,\n queryFilters,\n },\n };\n};\n","import { tableHelper } from \"../helpers/tableHelpers\";\nimport type { TelemetryConfig } from \"../helpers/telemetry\";\nimport type { Filter } from \"../runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleTableValueType,\n TableRelationNames,\n} from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport { createColumnMasker, type MaskColumnsInput } from \"./columnMask\";\nimport { createInputGuard } from \"./inputGuard\";\nimport { guardInputKey } from \"./keys\";\nimport { attachRequestState, createRequestState } from \"./requestState\";\nimport { createTableAbilities } from \"./tableAbilities\";\nimport { createTableBuilder } from \"./tableBuilder\";\nimport { makeNothingRegisteredWarner } from \"./telemetry\";\nimport type { AbilitySettings } from \"./types\";\n\nexport type { ColumnMask } from \"./columnMask\";\nexport {\n guardFilterInput,\n relationColumnKeys,\n relationExposure,\n} from \"./inputGuard\";\nexport { columnMaskKey } from \"./keys\";\n\n//TODO: optimize this for v8\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\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 type TableNames = TableRelationNames<DB>;\n\n const log = loggerConfig?.enabled ? loggerConfig.logger : undefined;\n const telemetryConfig: TelemetryConfig = { otel, logger: loggerConfig };\n const settings: AbilitySettings<DB, Action> = {\n db,\n // populated by rumble() when the user does not pass any\n actions: actions!,\n defaultLimit,\n otel,\n telemetryConfig,\n log,\n warnNothingRegistered: makeNothingRegisteredWarner(telemetryConfig, log),\n };\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 buildersPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createTableBuilder<UserContext, DB, Action, typeof tableName>({\n actions: settings.actions,\n isBuilt: () => hasBeenBuilt,\n }),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n typeof createTableBuilder<UserContext, DB, Action, key>\n >;\n };\n\n const { maskColumns, maskedActions, primaryKeyHidden, columnsHidden } =\n createColumnMasker(\n settings,\n new Map(\n tableRelationNames.map((tableName) => {\n const tableSchema = tableHelper({ db, table: tableName });\n return [\n tableName,\n {\n columns: Object.keys(tableSchema.columns),\n primaryKey: Object.keys(tableSchema.primaryKey),\n },\n ];\n }),\n ),\n );\n\n const readActionPerTable = new Map<TableNames, Action>();\n\n return {\n ...buildersPerTable,\n /**\n * @internal\n * @ignore\n */\n _: {\n maskColumns: (input: MaskColumnsInput<DB, Action>) => maskColumns(input),\n /** The actions rows of the table were masked with in this request. */\n maskedActions: (abilities: object, table: TableNames) =>\n maskedActions(abilities, table),\n /** Whether masking in this request hid the primary key of the row. */\n primaryKeyHidden: (abilities: object, row: object) =>\n primaryKeyHidden(abilities, row),\n /** Whether masking in this request hid one of the columns on the row. */\n columnsHidden: (\n abilities: object,\n row: object,\n columns: string[],\n primaryKey: string[],\n ) => columnsHidden(abilities, row, columns, primaryKey),\n registerReadAction(table: TableNames, action: Action) {\n readActionPerTable.set(table, action);\n },\n readActionOf(table: TableNames): Action {\n return readActionPerTable.get(table) ?? (\"read\" as Action);\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 abilitiesPerTable = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n createTableAbilities<UserContext, DB, Action, typeof tableName>(\n settings,\n tableName,\n buildersPerTable[tableName]._.queryFilters,\n ),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n typeof createTableAbilities<UserContext, DB, Action, key>\n >;\n };\n\n hasBeenBuilt = true;\n\n return (ctx: UserContext) => {\n const state = createRequestState<Action>();\n const abilities = Object.fromEntries(\n tableRelationNames.map((tableName) => [\n tableName,\n abilitiesPerTable[tableName].withContext(ctx),\n ]),\n ) as {\n [key in TableNames]: ReturnType<\n ReturnType<\n typeof createTableAbilities<UserContext, DB, Action, key>\n >[\"withContext\"]\n >;\n };\n attachRequestState(abilities, state);\n // kept out of the type, like the other internal keys\n Object.defineProperty(abilities, guardInputKey, {\n value: createInputGuard({\n db,\n abilities,\n readActionOf: (table) =>\n (readActionPerTable as unknown as Map<string, Action>).get(\n table,\n ) ?? (\"read\" as Action),\n }),\n });\n return abilities;\n };\n },\n },\n };\n};\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: (await 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 (await 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 (await 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 { toCamelCase } from \"drizzle-orm/casing\";\nimport { capitalize, once } from \"es-toolkit\";\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 = once(() =>\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\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 */\ntype 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 { once } from \"es-toolkit\";\nimport type { AbilityBuilderType } from \"./abilityBuilder\";\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 = once(() => 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 { guardFilterInput } from \"./abilityBuilder\";\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 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 // the client may only filter by what it may read\n const guarded = await guardFilterInput(\n ctx.abilities,\n String(table),\n listAction,\n { where: args.where },\n );\n if (args.where) args.where = guarded.where;\n\n return (db as any)\n .select({ count: count() })\n .from(tableSchema.table)\n .where(\n (await ctx.abilities[table].filter(listAction)).merge(\n mapNullFieldsToUndefined(args) as any,\n ).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\ntype AnyFieldBuilder = DrizzleObjectFieldBuilder<any, any, any, any>;\n\n// explicit so declaration emit doesn't have to name pothos' internal FieldRef\ntype PothosResponseFieldRef =\n | ReturnType<AnyFieldBuilder[\"exposeInt\"]>\n | ReturnType<AnyFieldBuilder[\"exposeIntList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeString\"]>\n | ReturnType<AnyFieldBuilder[\"exposeStringList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeBoolean\"]>\n | ReturnType<AnyFieldBuilder[\"exposeBooleanList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeFloat\"]>\n | ReturnType<AnyFieldBuilder[\"exposeFloatList\"]>\n | ReturnType<AnyFieldBuilder[\"exposeID\"]>\n | ReturnType<AnyFieldBuilder[\"exposeIDList\"]>\n | ReturnType<AnyFieldBuilder[\"field\"]>;\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}): PothosResponseFieldRef {\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 { asc, desc, sql } from \"drizzle-orm\";\nimport { cloneDeep } from \"es-toolkit\";\nimport { type ColumnMask, columnMaskKey } from \"./abilityBuilder\";\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. The same goes for columns only some rows may expose.\n const columnMask: ColumnMask | undefined = abilities[columnMaskKey];\n // without a mask every column is guaranteed\n const columnsToSearch = (\n columnMask\n ? Object.entries(tableSchema.columns).filter(([key]) =>\n columnMask.guaranteed.has(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 =\n typeof args.orderBy === \"function\"\n ? args.orderBy\n : cloneDeep(args.orderBy);\n (args as any).orderBy = (table: any) => {\n // a function when the order was restricted to what the caller may read\n const argsOrderBySQL = sql.join(\n typeof originalOrderBy === \"function\"\n ? originalOrderBy(table, { asc, desc })\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 {\n type AbilityBuilderType,\n guardFilterInput,\n relationColumnKeys,\n relationExposure,\n} 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 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 abilityBuilder._.registerReadAction(table, readAction);\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 // rows are keyed by ts names, not database names\n const primaryKeyName = Object.keys(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 (!primaryKeyName) return;\n const primaryKeyValue = (element as any)[primaryKeyName];\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 maskColumns: ({ context, entities, action }) =>\n abilityBuilder._.maskColumns({\n table,\n action: (action as Action | undefined) ?? readAction,\n abilities: (context as any).abilities,\n entities,\n }),\n maskPrimaryKeys: {\n fields: Object.keys(tableSchema.primaryKey),\n isHidden: (context, row) =>\n abilityBuilder._.primaryKeyHidden((context as any).abilities, row),\n },\n maskRelations: {\n fields: Object.fromEntries(\n Object.entries(tableSchema.relations ?? {}).map(([key, relation]) => [\n key,\n {\n many: !is(relation, One),\n sourceColumns: relationColumnKeys(\n db,\n tableSchema.tsName,\n (relation as any).sourceColumns,\n ),\n },\n ]),\n ),\n isHidden: (context, row, columns) =>\n abilityBuilder._.columnsHidden(\n (context as any).abilities,\n row,\n columns,\n Object.keys(tableSchema.primaryKey),\n ),\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(\n // drizzle 1.0 rc.5+ wraps relation columns in a\n // RelationsBuilderColumn whose column sits at `_.column`\n (column) => ((column as any)._?.column ?? column).notNull,\n );\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: async (args: any, ctx: any) => {\n // transform null prototyped object\n args = JSON.parse(JSON.stringify(args));\n\n // the client may only filter and sort by what it may read\n const guarded = await guardFilterInput(\n ctx.abilities,\n relationSchema.tsName,\n readAction,\n { where: args.where, orderBy: args.orderBy },\n );\n if (args.where) args.where = guarded.where;\n if (args.orderBy) args.orderBy = guarded.orderBy;\n\n if (isMany) {\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema: relationSchema,\n abilities:\n await ctx.abilities[relationSchema.tsName].filter(\n readAction,\n ),\n });\n }\n\n // only the related rows exposing the columns the relation\n // joins on belong to the row\n const joined = await relationExposure(\n ctx.abilities,\n relationSchema.tsName,\n readAction,\n relationColumnKeys(\n db,\n relationSchema.tsName,\n (value as any).targetColumns,\n ),\n );\n\n const filter = (\n await ctx.abilities[relationSchema.tsName].filter(\n readAction,\n )\n ).merge({\n where: joined.length\n ? {\n AND: [...(args.where ? [args.where] : []), ...joined],\n }\n : 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 { guardFilterInput } from \"./abilityBuilder\";\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 primaryKeyName = Object.keys(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 maskColumnsAction: listAction,\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: async (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 // the client may only filter and sort by what it may read\n const guarded = await guardFilterInput(\n ctx.abilities,\n String(table),\n listAction,\n { where: args.where, orderBy: args.orderBy },\n );\n if (args.where) (args as any).where = guarded.where;\n if (args.orderBy) (args as any).orderBy = guarded.orderBy;\n\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities: await ctx.abilities[table].filter(listAction),\n });\n\n const mappedArgs = mapNullFieldsToUndefined(args);\n const filter = (\n await ctx.abilities[table].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 maskColumnsAction: readAction,\n description: `Get a single ${singularName} by ID`,\n args: {\n id: t.arg.id({ required: true }),\n },\n resolve: async (query, _root, args, ctx, _info) => {\n deepSetProto(args);\n\n const filter = (\n await (ctx.abilities as any)[table].filter(readAction)\n ).merge({ where: { [primaryKeyName]: args.id } }).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","import type {\n BuildCache,\n PothosOutputFieldConfig,\n SchemaTypes,\n} from \"@pothos/core\";\n\nexport function objectTypeOptionsOfField<Types extends SchemaTypes>(\n buildCache: BuildCache<Types>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n): Record<string, unknown> | undefined {\n const type = fieldConfig.type as any;\n const ref =\n type.kind === \"List\"\n ? type.type.kind === \"Object\"\n ? type.type.ref\n : undefined\n : type.kind === \"Object\"\n ? type.ref\n : undefined;\n if (!ref) return undefined;\n\n return buildCache.getTypeConfig(ref, \"Object\").pothosOptions as Record<\n string,\n unknown\n >;\n}\n","import SchemaBuilder, {\n type PluginConstructorMap,\n type SchemaTypes,\n} from \"@pothos/core\";\n\nconst registered = new Set<string>();\n\nexport function registerPluginOnce<\n Name extends keyof PluginConstructorMap<SchemaTypes>,\n>(name: Name, plugin: PluginConstructorMap<SchemaTypes>[Name]) {\n if (registered.has(name)) return;\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(name, plugin);\n registered.add(name);\n}\n","export type MaskColumns<Context> = (p: {\n context: Context;\n entities: unknown[];\n action?: string;\n}) => void | Promise<void>;\n\nexport const maskColumnsKey = \"maskColumns\";\n\nexport const maskColumnsActionKey = \"maskColumnsAction\";\n\n// masking keeps primary keys on the row, their fields return null instead\nexport type MaskPrimaryKeys<Context> = {\n fields: string[];\n isHidden: (context: Context, row: object) => boolean;\n};\n\nexport const maskPrimaryKeysKey = \"maskPrimaryKeys\";\n\n// A relation joins on columns of the row. If masking hid them, the related\n// rows are not the row's to see: the field returns null (or an empty list).\nexport type MaskRelations<Context> = {\n fields: Record<string, { many: boolean; sourceColumns: string[] }>;\n isHidden: (context: Context, row: object, columns: string[]) => boolean;\n};\n\nexport const maskRelationsKey = \"maskRelations\";\n\nexport const columnMaskPluginName = \"ColumnMaskPlugin\" as const;\n","import {\n BasePlugin,\n isThenable,\n type PothosOutputFieldConfig,\n type SchemaTypes,\n} from \"@pothos/core\";\nimport type { GraphQLFieldResolver } from \"graphql\";\nimport { objectTypeOptionsOfField } from \"../helpers/objectTypeOptions\";\nimport { registerPluginOnce } from \"../helpers/registerPlugin\";\nimport {\n columnMaskPluginName,\n type MaskColumns,\n type MaskPrimaryKeys,\n type MaskRelations,\n maskColumnsActionKey,\n maskColumnsKey,\n maskPrimaryKeysKey,\n maskRelationsKey,\n} from \"./maskTypes\";\n\nexport class ColumnMaskPlugin<\n Types extends SchemaTypes,\n> extends BasePlugin<Types> {\n // fallow-ignore-next-line unused-class-member\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n return this.maskResult(\n this.maskRelation(\n this.maskPrimaryKey(resolver, fieldConfig),\n fieldConfig,\n ),\n fieldConfig,\n );\n }\n\n // The rows of a relation are loaded by the database joining on the row's\n // columns, whether or not the caller may read them. If masking hid those\n // columns, the relation reveals what they would, so it resolves to nothing.\n private maskRelation(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const relations = (\n this.buildCache.getTypeConfig(fieldConfig.parentType).pothosOptions as {\n [maskRelationsKey]?: MaskRelations<Types[\"Context\"]>;\n }\n )[maskRelationsKey];\n const relation = relations?.fields[fieldConfig.name];\n if (!relations || !relation) return resolver;\n\n return (parent, args, context, info) =>\n relations.isHidden(context, parent as object, relation.sourceColumns)\n ? relation.many\n ? []\n : null\n : resolver(parent, args, context, info);\n }\n\n // Masking keeps primary keys on the row, the fields returning them hide them.\n // Pothos reloads rows by their primary key, e.g. a mutation returning\n // `db.update(users).returning()` selected as `{ id firstName }` where only\n // `firstName` is granted: pothos queries `where id in (row.id)` and matches\n // the result by `row.id`. Cleared on the row, that is `id in (undefined)`\n // and fails with \"Model users(undefined) not found\".\n private maskPrimaryKey(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const primaryKeys = (\n this.buildCache.getTypeConfig(fieldConfig.parentType).pothosOptions as {\n [maskPrimaryKeysKey]?: MaskPrimaryKeys<Types[\"Context\"]>;\n }\n )[maskPrimaryKeysKey];\n if (!primaryKeys?.fields.includes(fieldConfig.name)) return resolver;\n\n return (parent, args, context, info) =>\n primaryKeys.isHidden(context, parent as object)\n ? null\n : resolver(parent, args, context, info);\n }\n\n private maskResult(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const maskColumns = objectTypeOptionsOfField(\n this.buildCache,\n fieldConfig,\n )?.[maskColumnsKey] as MaskColumns<Types[\"Context\"]> | undefined;\n if (!maskColumns) return resolver;\n const action = (\n fieldConfig.pothosOptions as { [maskColumnsActionKey]?: string }\n )[maskColumnsActionKey];\n\n const mask = (value: unknown, context: Types[\"Context\"]): unknown => {\n if (value == null) return value;\n // graphql-js accepts lists of promises, the rows are masked once resolved\n if (Array.isArray(value) && value.some(isThenable)) {\n return Promise.all(value).then((rows) => mask(rows, context));\n }\n const pending = maskColumns({\n context,\n entities: Array.isArray(value) ? value : [value],\n action,\n });\n return pending ? pending.then(() => value) : value;\n };\n\n return (parent, args, context, info) => {\n const resolved = resolver(parent, args, context, info);\n return isThenable(resolved)\n ? resolved.then((value) => mask(value, context))\n : mask(resolved, context);\n };\n }\n}\n\nexport function registerColumnMaskPlugin() {\n registerPluginOnce(columnMaskPluginName, ColumnMaskPlugin);\n}\n","import type { AbilityBuilderType } from \"../abilityBuilder\";\nimport type { DrizzleInstance } from \"../types/drizzleInstanceType\";\nimport { mergeFilters } from \"./mergeFilters\";\n\n// pothos reloads rows by primary key when a resolver returned them without\n// query(...). Those reloads are its only use of client.query, so the read\n// abilities are applied there: the ones the request masked rows of the table\n// with (e.g. a list action), or the table's read action if there are none.\nexport function createAbilityAwareClient<DB extends DrizzleInstance>({\n db,\n abilityBuilder,\n}: {\n db: DB;\n abilityBuilder: AbilityBuilderType<any, DB, any, any, any>;\n}) {\n return (context: { abilities: Record<string, any> }) => {\n const apis = new Map<string, unknown>();\n\n const query = new Proxy(db.query as Record<string, any>, {\n get(target, table, receiver) {\n const api = Reflect.get(target, table, receiver);\n if (typeof table !== \"string\" || !context.abilities?.[table]) {\n return api;\n }\n\n let wrapped = apis.get(table);\n if (!wrapped) {\n wrapped = Object.create(api, {\n findMany: {\n value: async (config: Record<string, any> = {}) => {\n const masked = abilityBuilder._.maskedActions(\n context.abilities,\n table as any,\n );\n const actions = masked.size\n ? [...masked]\n : [abilityBuilder._.readActionOf(table as any)];\n\n // one query per action, since each brings its own column flag.\n // A row found by several is matched by pothos once.\n const rowsPerAction = await Promise.all(\n actions.map(async (action) => {\n const ability = (\n await context.abilities[table].filter(action)\n ).query.many;\n const { where, extras } = mergeFilters(\n { where: config.where, extras: config.extras },\n { where: ability.where, extras: ability.extras },\n );\n\n const rows = await api.findMany({\n ...config,\n where,\n extras,\n });\n await abilityBuilder._.maskColumns({\n table: table as any,\n action,\n abilities: context.abilities,\n entities: rows,\n });\n return rows;\n }),\n );\n return rowsPerAction.flat();\n },\n },\n });\n apis.set(table, wrapped);\n }\n return wrapped;\n },\n });\n\n return new Proxy(db, {\n get(target, prop, receiver) {\n return prop === \"query\" ? query : Reflect.get(target, prop, receiver);\n },\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 {\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 { requestStateOf } from \"../abilityBuilder/requestState\";\nimport { errorLogField } from \"../helpers/errorLogging\";\nimport { objectTypeOptionsOfField } from \"../helpers/objectTypeOptions\";\nimport { registerPluginOnce } from \"../helpers/registerPlugin\";\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. The loaders are kept in the state of the request,\n // so they are gone once the request is done, no manual cleanup needed.\n private getLoader(\n context: Types[\"Context\"],\n filter: AnyFilterCombo,\n ): DataLoader<any, any> {\n // a context not created by rumble has no request state, it doesn't batch\n const loaders =\n requestStateOf((context as { abilities?: object }).abilities)\n ?.filterLoaders ?? new Map<object, DataLoader<any, any>>();\n\n let loader = loaders.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 loaders.set(filter, loader);\n }\n\n return loader;\n }\n\n // fallow-ignore-next-line unused-class-member\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 // fallow-ignore-next-line unused-class-member\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n const filters = objectTypeOptionsOfField(this.buildCache, fieldConfig)?.[\n applyFiltersKey\n ] as ApplyFiltersField<Types[\"Context\"], any>;\n if (!filters) return resolver;\n // filters can still be registered after the schema is built\n const allFilters = Array.isArray(filters) ? filters : [filters];\n\n const applyFilters = async (\n parent: unknown,\n args: object,\n context: Types[\"Context\"],\n info: Parameters<typeof resolver>[3],\n ) => {\n const runFilters = async (span?: Span) => {\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 return (parent, args, context, info) =>\n allFilters.length === 0\n ? resolver(parent, args, context, info)\n : applyFilters(parent, args, context, info);\n }\n}\n\nexport function registerRuntimeFiltersPlugin() {\n registerPluginOnce(pluginName, RuntimeFiltersPlugin);\n}\n","import { createRequire } from \"node:module\";\nimport type * as LibAddress from \"lib-address\";\nimport { z } from \"zod\";\nimport type { AddressShape } from \"./address\";\n\nconst requireFromHere = createRequire(import.meta.url);\nconst libAddress: typeof LibAddress = requireFromHere(\"lib-address\");\n\nconst {\n AddressValidationError,\n CountryMissingError,\n InvalidStateError,\n InvalidZipError,\n isValidCountryCode,\n MissingFieldError,\n} = libAddress;\n\n//TODO: https://github.com/LancelotP/lib-address/issues/42\nconst validateAddress: typeof LibAddress.validateAddress =\n libAddress.validateAddress;\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, exactly\n * as the `EmailAddress` scalar does. Exported for values that do not arrive as GraphQL input,\n * such as OIDC claims.\n *\n * @throws RumbleErrorSafe if the value is not a valid email address\n */\nexport const normalizeEmailAddress = (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: normalizeEmailAddress,\n parseValue: normalizeEmailAddress,\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 normalizeEmailAddress(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// smart punctuation on phones and word processors swaps these in for ' and -\nconst APOSTROPHE_VARIANTS = /[\\u2018\\u2019\\u02BC\\u00B4\\u0060]/gu;\nconst HYPHEN_VARIANTS = /[\\u2010-\\u2015\\u2212]/gu;\n\n/**\n * Normalizes and validates a person's name, exactly as the `PersonName` scalar does. Exported\n * for values that do not arrive as GraphQL input, such as OIDC claims.\n *\n * @throws RumbleErrorSafe if the value is not a valid name\n */\nexport const normalizePersonName = (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(APOSTROPHE_VARIANTS, \"'\")\n .replace(HYPHEN_VARIANTS, \"-\")\n .replace(/\\p{Zs}+/gu, \" \")\n .trim()\n .replace(/ ?- ?/gu, \"-\")\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 (typographic apostrophe or dash variants, spaces around a hyphen, a doubled or stray leading/trailing hyphen/apostrophe) silently corrected rather than rejected.\",\n serialize: normalizePersonName,\n parseValue: normalizePersonName,\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 normalizePersonName(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. This is what the `PhoneNumber` scalar does with its input; exported for values\n * that do not arrive as GraphQL input. `.number` of the result is the E.164 form.\n *\n * @throws RumbleErrorSafe if the value is not a valid phone number\n */\nexport const parsePhoneNumber = (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 parsePhoneNumber(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: parsePhoneNumber,\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 parsePhoneNumber(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, is, isTable, type Table } from \"drizzle-orm\";\nimport {\n MySqlTable,\n getTableConfig as mysqlTableConfig,\n} from \"drizzle-orm/mysql-core\";\nimport { PgTable, getTableConfig as pgTableConfig } from \"drizzle-orm/pg-core\";\nimport {\n SQLiteTable,\n getTableConfig as sqliteTableConfig,\n} from \"drizzle-orm/sqlite-core\";\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 type { AbilityBuilderType } from \"./abilityBuilder\";\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 { registerColumnMaskPlugin } from \"./columnMaskPlugin/columnMaskPlugin\";\nimport { columnMaskPluginName } from \"./columnMaskPlugin/maskTypes\";\nimport type { ContextType } from \"./context\";\nimport { createAbilityAwareClient } from \"./helpers/abilityAwareClient\";\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 abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n pubsub: ReturnType<typeof createPubSub>;\n abilityBuilder: AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >;\n}) => {\n const createSpan =\n otel?.enabled && otel.tracer\n ? createOpenTelemetryWrapper(otel.tracer, otel.options)\n : undefined;\n\n registerRuntimeFiltersPlugin();\n registerColumnMaskPlugin();\n const schemaBuilder = new SchemaBuilder<{\n Context: ContextType<UserContext, DB, RequestEvent, Action, PothosConfig>;\n DrizzleRelations: DB[\"_\"][\"relations\"];\n AsyncSelections: true;\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 // must wrap the runtime filters, so filters see unmasked rows\n columnMaskPluginName,\n pluginName,\n DrizzlePlugin,\n SmartSubscriptionsPlugin,\n TracingPlugin,\n ValidationPlugin,\n ...(pothosConfig?.plugins ?? []),\n ],\n drizzle: {\n // plugin-drizzle >=0.19.1 checks the client structurally against the\n // relations of the generic DB, which TS can't resolve for an unresolved DB\n // @ts-expect-error\n client: createAbilityAwareClient({ db, abilityBuilder }),\n relations: db._.relations,\n getTableConfig(table) {\n if (is(table, PgTable)) return pgTableConfig(table) as any;\n if (is(table, MySqlTable)) return mysqlTableConfig(table) as any;\n if (is(table, SQLiteTable)) return sqliteTableConfig(table) as any;\n return {\n columns: isTable(table)\n ? Object.values(getTableColumns(table as Table))\n : [],\n primaryKeys: [],\n uniqueConstraints: [],\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, once } 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 { 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, abilityBuilder });\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 = once(() => {\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 * Yoga's `cors` option, except that it defaults to `false` (no CORS headers at all)\n * rather than to Yoga's reflect-any-origin-with-credentials default. Pass the origins\n * that may call the API with their credentials when there are any, e.g.\n * `cors: { origin: [\"https://app.example.org\"], credentials: true }`.\n */\n cors?: YogaServerOptions<RequestEvent, any>[\"cors\"];\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 // Yoga's own default reflects any `Origin` with `Access-Control-Allow-Credentials: true`,\n // which lets every website run credentialed queries and mutations against a cookie\n // session. An API that is meant to be reached from other origins has to say which.\n cors: false,\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":"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a;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,iBAAiB;AAE3E;AAkBA,SAAS,wBAC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"}