@m1212e/rumble 0.16.21 → 0.16.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/index.cjs +30 -7
- package/out/index.cjs.map +1 -1
- package/out/index.d.cts.map +1 -1
- package/out/index.d.mts.map +1 -1
- package/out/index.mjs +30 -7
- package/out/index.mjs.map +1 -1
- package/package.json +1 -1
package/out/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["GraphQLError","lazy","makeDefaultName","lazy","PgEnumColumn","generateFromSchema","lazy","PgTable","MySqlTable","SQLiteTable","sql","One","sql","BasePlugin","SchemaBuilder","DrizzlePlugin","SmartSubscriptionsPlugin","TracingPlugin","JSONResolver","DateResolver","DateTimeISOResolver","trace","packagejson.version","lazy","SpanNames","AttributeNames","SpanStatusCode"],"sources":["../lib/types/rumbleError.ts","../lib/helpers/asserts.ts","../lib/helpers/mapNullFieldsToUndefined.ts","../package.json","../lib/helpers/mergeFilters.ts","../lib/helpers/sqlTypes/types.ts","../lib/helpers/sqlTypes/distinctValuesFromSQLType.ts","../lib/helpers/tableHelpers.ts","../lib/abilityBuilder.ts","../lib/args/orderArg.ts","../lib/enum.ts","../lib/helpers/sqlTypes/mapSQLTypeToTSType.ts","../lib/args/whereArg.ts","../lib/client/client.ts","../lib/context.ts","../lib/helpers/protoMapper.ts","../lib/countQuery.ts","../lib/helpers/sofaOpenAPIWebhookDocs.ts","../lib/helpers/sqlTypes/mapDrizzleTypeToGraphQlType.ts","../lib/helpers/determineDialectFromSchema.ts","../lib/search.ts","../lib/object.ts","../lib/pubsub.ts","../lib/query.ts","../lib/args/whereArgsImplementer.ts","../lib/runtimeFiltersPlugin/filterTypes.ts","../lib/helpers/applyFilters.ts","../lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts","../lib/schemaBuilder.ts","../lib/rumble.ts"],"sourcesContent":["import { GraphQLError } from \"graphql\";\n/**\n * An error that gets raised by rumble whenever something does not go according to plan.\n * Mostly internals, configuration errors or other unexpected things.\n */\nexport class RumbleError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RumbleError\";\n }\n}\n\n/**\n * An error that gets raised by rumble whenever an error occurs in a resolver, containing\n * information safely exposeable to the user.\n * E.g. the assert helpers issue these.\n */\nexport class RumbleErrorSafe extends GraphQLError {}\n","import { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n * schemaBuilder.queryFields((t) => {\n return {\n findFirstUser: t.drizzleField({\n type: UserRef,\n resolve: (query, root, args, ctx, info) => {\n return (\n db.query.users\n .findFirst({\n ...query,\n where: ctx.abilities.users.filter(\"read\").single.where,\n })\n // note that we need to manually raise an error if the value is not found\n .then(assertFindFirstExists)\n );\n },\n }),\n };\n });\n * ```\n */\nexport const assertFindFirstExists = <T>(value: T | undefined): T => {\n if (!value) {\n throw new RumbleErrorSafe(\"Value not found but required (findFirst)\");\n }\n return value;\n};\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n schemaBuilder.mutationFields((t) => {\n return {\n updateUsername: t.drizzleField({\n type: UserRef,\n args: {\n userId: t.arg.int({ required: true }),\n newName: t.arg.string({ required: true }),\n },\n resolve: (query, root, args, ctx, info) => {\n return db\n .update(schema.users)\n .set({\n name: args.newName,\n })\n .where(\n and(\n eq(schema.users.id, args.userId),\n ctx.abilities.users.filter(\"update\").single.where\n )\n )\n .returning({ id: schema.users.id, name: schema.users.name })\n // note that we need to manually raise an error if the value is not found\n .then(assertFirstEntryExists);\n },\n }),\n };\n });\n * ```\n */\nexport const assertFirstEntryExists = <T>(value: T[]): T => {\n const v = value.at(0);\n if (!v)\n throw new RumbleErrorSafe(\"Value not found but required (firstEntry)\");\n return v;\n};\n","/**\n * Helper to map null fields to undefined\n * @param obj The object to map\n * @returns The mapped object with all fields of 'null' transformed to 'undefined'\n * \n * This becomes useful for update mutations where you do not want to pass null (unset value in db)\n * but undefined (do not touch value in db) in case of a value not beeing set in the args of said mutation\n * @example\n * ```ts\n * updateUser: t.drizzleField({\n type: User,\n args: {\n id: t.arg.string({ required: true }),\n email: t.arg.string(),\n lastName: t.arg.string(),\n firstName: t.arg.string(),\n },\n resolve: async (query, root, args, ctx, info) => {\n const mappedArgs = mapNullFieldsToUndefined(args);\n const user = await db.transaction(async (tx) => {\n const user = await tx\n .update(schema.user)\n .set({\n\n // email: args.email ?? undefined,\n // lastName: args.lastName ?? undefined,\n // firstName: args.firstName ?? undefined,\n\n // becomes this\n\n email: mappedArgs.email,\n lastName: mappedArgs.lastName,\n firstName: mappedArgs.firstName,\n })\n .returning()\n .then(assertFirstEntryExists);\n return user;\n });\n\n pubsub.updated(user.id);\n\n return db.query.user\n .findFirst(\n query(\n ctx.abilities.user.filter('read').merge(\n {\n where: { id: user.id },\n }\n 1).query.single,\n ),\n )\n .then(assertFindFirstExists);\n },\n }),\n * \n * \n * ```\n */\nexport function mapNullFieldsToUndefined<T extends object>(obj: T) {\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [\n key,\n value === null ? undefined : value,\n ]),\n ) as {\n [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>;\n };\n}\n","","import { toMerged } from \"es-toolkit\";\n\nexport function mergeFilters<\n FilterA extends Record<string, any>,\n FilterB extends Record<string, any>,\n>(filterA?: Partial<FilterA>, filterB?: Partial<FilterB>) {\n const where =\n filterA?.where && filterB?.where\n ? { AND: [filterA?.where, filterB?.where] }\n : (filterA?.where ?? filterB?.where);\n\n const columns =\n filterA?.columns || filterB?.columns\n ? new Set(\n [\n Object.entries(filterA?.columns ?? {}),\n Object.entries(filterB?.columns ?? {}),\n ]\n .flat()\n .filter(([, v]) => v === true)\n .map(([k]) => k),\n )\n .entries()\n .reduce(\n (acc, [key]) => {\n acc[key] = true;\n return acc;\n },\n {} as Record<string, true>,\n )\n : undefined;\n\n const extras =\n filterA?.extras || filterB?.extras\n ? toMerged(filterA?.extras ?? {}, filterB?.extras ?? {})\n : undefined;\n\n const orderBy =\n filterA?.orderBy || filterB?.orderBy\n ? toMerged(filterA?.orderBy ?? {}, filterB?.orderBy ?? {})\n : undefined;\n\n const limit =\n filterA?.limit || filterB?.limit\n ? Math.min(filterA?.limit ?? Infinity, filterB?.limit ?? Infinity)\n : undefined;\n\n const offset =\n filterA?.offset || filterB?.offset\n ? Math.min(filterA?.offset ?? Infinity, filterB?.offset ?? Infinity)\n : undefined;\n\n const with_ =\n filterA?.with || filterB?.with\n ? toMerged(filterA?.with ?? {}, filterB?.with ?? {})\n : undefined;\n\n return {\n where,\n columns,\n extras,\n orderBy,\n limit,\n offset,\n with: with_,\n } as unknown as FilterA & FilterB;\n}\n","import { RumbleError } from \"../../types/rumbleError\";\n\nconst intLikeSQLTypeStrings = [\n \"serial\",\n \"int\",\n \"integer\",\n \"tinyint\",\n \"smallint\",\n \"mediumint\",\n] as const;\n\nexport function isIntLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof intLikeSQLTypeStrings)[number] {\n return intLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst floatLikeSQLTypeStrings = [\n \"real\",\n \"decimal\",\n \"double\",\n \"float\",\n \"numeric\",\n] as const;\n\nexport function isFloatLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof floatLikeSQLTypeStrings)[number] {\n return floatLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst stringLikeSQLTypeStrings = [\n \"string\",\n \"text\",\n \"varchar\",\n \"char\",\n \"text(256)\",\n] as const;\n\nexport function isStringLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof stringLikeSQLTypeStrings)[number] {\n return stringLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst IDLikeSQLTypeStrings = [\"uuid\"] as const;\n\nexport function isIDLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof IDLikeSQLTypeStrings)[number] {\n return IDLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst booleanSQLTypeStrings = [\"boolean\"] as const;\n\nexport function isBooleanSQLTypeString(\n sqlType: string,\n): sqlType is (typeof booleanSQLTypeStrings)[number] {\n return booleanSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateTimeLikeSQLTypeStrings = [\"timestamp\", \"datetime\"] as const;\n\nexport function isDateTimeLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof dateTimeLikeSQLTypeStrings)[number] {\n return dateTimeLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateLikeSQLTypeStrings = [\"date\"] as const;\n\nexport function isDateLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof dateLikeSQLTypeStrings)[number] {\n return dateLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst jsonLikeSQLTypeStrings = [\"json\", \"jsonb\"] as const;\n\nexport function isJSONLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof jsonLikeSQLTypeStrings)[number] {\n return jsonLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst possibleSQLTypesStrings = [\n ...intLikeSQLTypeStrings,\n ...floatLikeSQLTypeStrings,\n ...stringLikeSQLTypeStrings,\n ...IDLikeSQLTypeStrings,\n ...booleanSQLTypeStrings,\n ...dateTimeLikeSQLTypeStrings,\n ...dateLikeSQLTypeStrings,\n ...jsonLikeSQLTypeStrings,\n] as const;\n\nexport type PossibleSQLType = (typeof possibleSQLTypesStrings)[number];\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 type { Column, Many, One } from \"drizzle-orm\";\nimport type { drizzle } from \"drizzle-orm/node-postgres\";\nimport type {\n DrizzleInstance,\n DrizzleTableSchema,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\n\nconst drizzleNameSymbol = Symbol.for(\"drizzle:Name\");\nconst drizzleOriginalNameSymbol = Symbol.for(\"drizzle:OriginalName\");\nconst drizzleBaseNameSymbol = Symbol.for(\"drizzle:BaseName\");\n\nexport function tableHelper<\n DB extends DrizzleInstance,\n TableIdentifier extends\n | DrizzleTableSchema<DB>[\"tsName\"]\n | DrizzleTableSchema<DB>[\"dbName\"]\n | DrizzleTableSchema<DB>,\n>({ db, table }: { db: DB; table: TableIdentifier }) {\n if (typeof table !== \"string\") {\n table =\n table.tsName ||\n table.dbName ||\n table[drizzleNameSymbol] ||\n table[drizzleOriginalNameSymbol] ||\n table[drizzleBaseNameSymbol];\n }\n\n const foundRelation: any = Object.values(db._.relations!).find(\n (schema: any) =>\n schema.name === table ||\n schema.table[drizzleNameSymbol] === table ||\n schema.table[drizzleOriginalNameSymbol] === table ||\n schema.table[drizzleBaseNameSymbol] === table,\n );\n\n if (!foundRelation) {\n throw new RumbleError(`Could not find schema for ${JSON.stringify(table)}`);\n }\n\n const foundSchema = Object.values(\n (db as ReturnType<typeof drizzle<any, any, any>>)._.schema!,\n ).find(\n (schema) =>\n schema.dbName === foundRelation.table[drizzleOriginalNameSymbol],\n );\n\n if (!foundSchema) {\n throw new RumbleError(`Could not find schema for ${JSON.stringify(table)}`);\n }\n\n const fullSchema = db._.fullSchema?.[foundSchema.tsName!];\n\n if (!fullSchema) {\n throw new RumbleError(\n `Could not find full schema for ${JSON.stringify(table)}`,\n );\n }\n\n return {\n columns: foundSchema.columns as Record<string, Column>,\n primaryKey: foundSchema.primaryKey,\n relations: (foundRelation as any).relations as {\n [key: string]: One<any, any> | Many<any>;\n },\n dbName: foundSchema.dbName,\n tsName: foundSchema.tsName,\n foundSchema,\n foundRelation,\n fullSchema,\n };\n}\n","import type { Span } from \"@opentelemetry/api\";\nimport { relationsFilterToSQL } from \"drizzle-orm\";\nimport { debounce } from \"es-toolkit\";\nimport { lazy } from \"./helpers/lazy\";\nimport { mergeFilters } from \"./helpers/mergeFilters\";\nimport { createDistinctValuesFromSQLType } from \"./helpers/sqlTypes/distinctValuesFromSQLType\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { Filter } from \"./runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleQueryFunctionInput,\n DrizzleTableValueType,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\n//TODO: optimize this for v8 & refactor\n\nexport type AbilityBuilderType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\n/**\n * Static, non changing query filter input type for a specific table\n */\ntype StaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n> = Filter;\n\n/**\n * Dynamic, context based query filter input type for a specific table\n */\ntype DynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> = (\n context: Context,\n) => StaticQueryFilter<DB, Table, Filter> | undefined | \"allow\";\n\n/**\n * Combined query filter type for a specific table. May be static or dynamic.\n */\ntype QueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> =\n | StaticQueryFilter<DB, Table, Filter>\n | DynamicQueryFilter<DB, Table, Filter, Context>;\n\nfunction isDynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is DynamicQueryFilter<DB, Table, Filter, Context> {\n return (\n typeof filter === \"function\" && filter.constructor.name !== \"AsyncFunction\"\n );\n}\n\nfunction isStaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is StaticQueryFilter<DB, Table, Filter> {\n return typeof filter !== \"function\";\n}\n\nconst nothingRegisteredWarningLogger = debounce(\n (model: string, action: string) => {\n console.warn(`\nWarning! No abilities have been registered for\n\n ${model}/${action}\n\nbut has been accessed. This will block everything. If this is intended, you can ignore this warning. If not, please ensure that you register the ability in your ability builder.\n`);\n },\n 1000,\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}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n type TableNames = keyof DrizzleQueryFunction<DB>;\n\n let hasBeenBuilt = false;\n\n const createBuilderForTable = <TableName extends TableNames>() => {\n const queryFilters = new Map<\n Action,\n | QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[]\n | \"unrestricted\"\n >();\n\n const runtimeFilters = new Map<\n Action,\n //TODO add a run all helper\n Filter<UserContext, any>[]\n >();\n\n // we want to init all possible runtime filters since we want to ensure\n // that the implementaiton helpers pass an object by reference when creating\n // the implementation, instead of a copy like it would be the case with undefined\n for (const action of actions!) {\n if (!runtimeFilters.has(action)) {\n runtimeFilters.set(action, []);\n }\n }\n\n return {\n /**\n * Allows to perform a specific action on a specific entity\n */\n allow: (action: Action | Action[]) => {\n if (hasBeenBuilt) {\n throw new RumbleError(\n \"You can't call allow() after the ability builder has been built. Please ensure that you register all abilities before accessing them.\",\n );\n }\n\n const actions = Array.isArray(action) ? action : [action];\n for (const action of actions) {\n let filters = queryFilters.get(action);\n if (!filters) {\n filters = \"unrestricted\";\n queryFilters.set(action, filters);\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 queryFilters.set(action, []);\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 * The actual filter function to apply. Returns the allowed values\n */\n by: (\n explicitFilter: Filter<\n UserContext,\n DrizzleTableValueType<DB, TableName>\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters.get(action)!.push(explicitFilter);\n }\n },\n };\n },\n _: {\n runtimeFilters,\n queryFilters,\n },\n };\n };\n\n const buildersPerTable = Object.fromEntries(\n (Object.keys(db.query) as TableNames[]).map((tableName) => [\n tableName,\n createBuilderForTable<typeof tableName>(),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createBuilderForTable<key>>;\n };\n\n return {\n ...buildersPerTable,\n /**\n * @internal\n * @ignore\n */\n _: {\n registeredFilters({\n action,\n table,\n }: {\n table: TableNames;\n action: Action;\n }) {\n return (buildersPerTable[table] as any)._.runtimeFilters.get(\n action,\n )! as Filter<UserContext, DrizzleTableValueType<DB, TableNames>>[];\n },\n build() {\n const createFilterForTable = <TableName extends TableNames>(\n tableName: TableName,\n ) => {\n const queryFilters = buildersPerTable[tableName]._.queryFilters;\n\n const simpleQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isStaticQueryFilter)];\n }),\n ) as {\n [key in Action]: StaticQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>\n >[];\n };\n\n const dynamicQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isDynamicQueryFilter)];\n }),\n ) as {\n [key in Action]: DynamicQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[];\n };\n\n const tableSchema = tableHelper({\n db,\n table: tableName,\n });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n throw new RumbleError(\n `No primary key found for entity ${tableName.toString()}`,\n );\n }\n\n const primaryKeyField = Object.values(tableSchema.primaryKey)[0];\n // we want a filter that excludes everything\n const distinctValues = createDistinctValuesFromSQLType(\n primaryKeyField.getSQLType() as any,\n );\n\n const blockEverythingFilter = {\n where: {\n AND: [\n {\n [primaryKeyField.name]: distinctValues.value1,\n },\n {\n [primaryKeyField.name]: distinctValues.value2,\n },\n ],\n },\n };\n\n /**\n * Packs the filters into a response object that can be applied for queries by the user\n */\n function transformToResponse(\n queryFilters?: DrizzleQueryFunctionInput<DB, TableName>,\n ) {\n const internalTransformer = (\n filters?: DrizzleQueryFunctionInput<DB, TableName>,\n mergedLimit?: number,\n ) => {\n const limit = lazy(() => {\n if (\n // got a merge injection\n mergedLimit !== undefined\n ) {\n if (!filters?.limit) {\n // there is not ability limit\n return mergedLimit;\n }\n\n if ((filters.limit as number) > mergedLimit) {\n // there is an ability limit and it is higher that the injected merge limit\n return mergedLimit;\n }\n }\n\n let limit = filters?.limit as number | undefined;\n\n if (\n defaultLimit &&\n (limit === undefined || limit > defaultLimit)\n ) {\n limit = defaultLimit;\n }\n\n // ensure that null is converted to undefined\n return limit ?? undefined;\n });\n\n const sqlTransformedWhere = lazy(() => {\n return filters?.where\n ? relationsFilterToSQL(\n tableSchema.foundRelation.table,\n filters.where,\n )\n : undefined;\n });\n\n // we acutally need to define multiple return objects since we do not want to use delete for\n // performance reasons and an undefined columns field on a drizzle filter will prevent any\n // column from being selected at all\n if (filters?.columns) {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: filters?.where,\n columns: filters?.columns,\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"columns\" | \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: filters?.where,\n columns: filters?.columns,\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"columns\" | \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n } else {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: filters?.where,\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: filters?.where,\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n }\n };\n\n const ret = internalTransformer(queryFilters);\n\n /**\n * Merges the current query filters with the provided filters for this call only\n */\n function merge(\n p: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>,\n ) {\n const merged = mergeFilters(ret.query.many, p);\n return internalTransformer(\n merged,\n // in case the user wants to inject a limit, we need to ensure that it is applied\n // and not the potential default limit will be used\n // this is important for functions of the default query pagination implementation\n p.limit as number | undefined,\n );\n }\n\n (ret as any).merge = merge;\n\n return ret as typeof ret & {\n merge: typeof merge;\n };\n }\n\n return {\n withContext: (userContext: UserContext) => {\n return {\n filter: (action: Action) => {\n const assembleAbilities = (span?: Span) => {\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 span?.setAttribute(\"abilities.status\", \"unrestricted\");\n return transformToResponse();\n }\n\n // if nothing has been allowed, block everything\n if (!filters) {\n span?.setAttribute(\n \"abilities.status\",\n \"blocked_everything\",\n );\n nothingRegisteredWarningLogger(\n tableName.toString(),\n action,\n );\n return transformToResponse(blockEverythingFilter);\n }\n\n // run all dynamic filters\n const dynamicResults = new Array<\n DrizzleQueryFunctionInput<DB, TableName>\n >(dynamicQueryFilters[action].length);\n let filtersReturned = 0;\n for (\n let i = 0;\n i < dynamicQueryFilters[action].length;\n i++\n ) {\n const func = dynamicQueryFilters[action][i];\n const result = func(userContext);\n // if one of the dynamic filters returns \"allow\", we want to allow everything\n if (result === \"allow\") {\n return transformToResponse();\n }\n // if nothing is returned, nothing is allowed by this filter\n if (result === undefined) continue;\n\n dynamicResults[filtersReturned++] = result;\n }\n dynamicResults.length = filtersReturned;\n\n span?.setAttribute(\n \"abilities.dynamic\",\n dynamicResults.length,\n );\n span?.setAttribute(\n \"abilities.static\",\n simpleQueryFilters[action].length,\n );\n\n const allQueryFilters = [\n ...simpleQueryFilters[action],\n ...dynamicResults,\n ];\n\n span?.setAttribute(\n \"abilities.total\",\n allQueryFilters.length,\n );\n\n // if we don't have any permitted filters then block everything\n if (allQueryFilters.length === 0) {\n span?.setAttribute(\n \"abilities.status\",\n \"blocked_everything\",\n );\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);\n }, {});\n\n span?.setAttribute(\"abilities.status\", \"applied\");\n return transformToResponse(mergedFilters as any);\n };\n\n if (otel?.enabled && otel.tracer) {\n return otel.tracer.startActiveSpan(\n `prepare_query_abilities_${action}`,\n (span) => {\n try {\n return assembleAbilities(span);\n } finally {\n span.end();\n }\n },\n );\n } else {\n return assembleAbilities();\n }\n },\n };\n },\n };\n };\n\n const abilitiesPerTable = Object.fromEntries(\n (Object.keys(db.query) as TableNames[]).map((tableName) => [\n tableName,\n createFilterForTable(tableName),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createFilterForTable<key>>;\n };\n\n hasBeenBuilt = true;\n\n return (ctx: UserContext) => {\n return Object.fromEntries(\n (Object.keys(abilitiesPerTable) as TableNames[]).map(\n (tableName) => [\n tableName,\n abilitiesPerTable[tableName].withContext(ctx),\n ],\n ),\n ) as {\n [key in TableNames]: ReturnType<\n ReturnType<typeof createFilterForTable<key>>[\"withContext\"]\n >;\n };\n };\n },\n },\n };\n};\n","import { toCamelCase } from \"drizzle-orm/casing\";\nimport { capitalize } from \"es-toolkit\";\nimport { lazy } from \"../helpers/lazy\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\n\nexport type OrderArgImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createOrderArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n SchemaBuilderType<UserContext, DB, RequestEvent, Action, 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\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 const fields = Object.entries(tableSchema.columns).reduce(\n (acc, [key]) => {\n acc[key] = t.field({\n type: sortingParameterEnumRef(),\n required: false,\n });\n\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.columns,\n ReturnType<typeof t.field>\n >,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n const relationSchema = tableHelper({\n db,\n table: (value as any).targetTable,\n });\n const referenceModel = orderArgImplementer({\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 t.field>\n >,\n );\n\n return {\n ...fields,\n ...relations,\n };\n },\n });\n };\n\n ret = implement();\n referenceStorage.set(inputTypeName, ret);\n return ret;\n };\n\n return orderArgImplementer;\n};\n","import { toCamelCase } from \"drizzle-orm/casing\";\nimport type { drizzle } from \"drizzle-orm/node-postgres\";\nimport { type PgEnum, PgEnumColumn } 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//TODO check if the enum find logic can be made more solid after drizzle reaches 1.0\n\n/**\n * Checks if a schema type is an enum\n */\nexport function isEnumSchema(schemaType: any): schemaType is PgEnum<any> {\n // TODO make this compatible with other db drivers\n return schemaType instanceof PgEnumColumn;\n}\n\n// TODO make this compatible with other db drivers\ntype EnumTypes = PgEnum<any>;\n\ntype EnumFields<T> = {\n [K in keyof T as T[K] extends EnumTypes ? K : never]: T[K];\n};\n\nexport type NonEnumFields<T> = {\n [K in keyof T as T[K] extends EnumTypes ? never : K]: T[K];\n};\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> = ReturnType<\n typeof createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n SchemaBuilderType<UserContext, DB, RequestEvent, Action, PothosConfig>\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n}) => {\n const referenceStorage = new Map<string, any>();\n\n const enumImplementer = <\n ExplicitEnumVariableName extends keyof EnumFields<\n NonNullable<DB[\"_\"][\"fullSchema\"]>\n >,\n EnumColumn extends EnumTypes,\n RefName extends string,\n >({\n tsName,\n enumColumn,\n refName,\n }: Partial<{\n tsName: ExplicitEnumVariableName;\n enumColumn: EnumColumn;\n refName?: RefName | undefined;\n }> &\n (\n | {\n tsName: ExplicitEnumVariableName;\n }\n | {\n enumColumn: EnumColumn;\n }\n )) => {\n //TODO check if this can be done typesafe\n\n let enumSchemaName: string | undefined;\n let enumValues: any[] | undefined;\n\n if (tsName) {\n const schemaEnum = db._.fullSchema![tsName as string];\n\n enumSchemaName = tsName.toString();\n\n const enumCol = Object.values(\n (db as ReturnType<typeof drizzle<any, any, any>>)._.schema!,\n )\n .filter((s) => typeof s === \"object\")\n .map((s) => Object.values(s.columns))\n .flat(2)\n .filter(isEnumSchema)\n .find((e: any) => e.config.enum === schemaEnum);\n\n if (!enumCol) {\n throw new RumbleError(`Could not find applied enum column for ${tsName.toString()}.\nPlease ensure that you use the enum at least once as a column of a table!`);\n }\n\n enumValues = (enumCol as any).enumValues;\n } else if (enumColumn) {\n const entry = Object.entries(\n (db as ReturnType<typeof drizzle<any, any, any>>)._.fullSchema!,\n ).filter(([_, value]) => (enumColumn as any).config.enum === value)[0];\n\n if (!entry) {\n throw new RumbleError(\n `Could not find enum entry for ${(enumColumn as any).config.name}.`,\n );\n }\n enumSchemaName = entry[0];\n enumValues = enumColumn.enumValues;\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 let ret: ReturnType<typeof implement> | undefined = referenceStorage.get(\n graphqlImplementationName,\n );\n if (ret) {\n return ret;\n }\n\n const implement = () =>\n schemaBuilder.enumType(graphqlImplementationName, {\n values: enumValues,\n });\n\n ret = implement();\n referenceStorage.set(graphqlImplementationName, ret);\n return ret;\n };\n\n return enumImplementer;\n};\n","import type { DrizzleInstance } from \"../../types/drizzleInstanceType\";\nimport type { CustomRumblePothosConfig } from \"../../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../../types/schemaBuilderType\";\nimport {\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 mapSQLTypeToGraphQLType<\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({ sqlType, fieldName }: { sqlType: PossibleSQLType; fieldName?: string }) {\n type ReturnType = Parameters<\n Parameters<Parameters<SchemaBuilder[\"queryField\"]>[1]>[0][\"field\"]\n >[0][\"type\"];\n\n let ret: ReturnType | undefined;\n\n if (isIntLikeSQLTypeString(sqlType)) {\n ret = \"Int\";\n }\n\n if (isFloatLikeSQLTypeString(sqlType)) {\n ret = \"Float\";\n }\n\n if (isStringLikeSQLTypeString(sqlType)) {\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(sqlType)) {\n ret = \"ID\";\n }\n\n if (isBooleanSQLTypeString(sqlType)) {\n ret = \"Boolean\";\n }\n\n if (isDateTimeLikeSQLTypeString(sqlType)) {\n ret = \"DateTime\";\n }\n\n if (isDateLikeSQLTypeString(sqlType)) {\n ret = \"Date\";\n }\n\n if (isJSONLikeSQLTypeString(sqlType)) {\n ret = \"JSON\";\n }\n\n if (ret !== undefined) {\n return ret;\n }\n\n throw UnknownTypeRumbleError(sqlType, \"SQL to GQL\");\n}\n","import { toCamelCase } from \"drizzle-orm/casing\";\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 SchemaBuilderType<UserContext, DB, RequestEvent, Action, PothosConfig>,\n EnumImplementerType<UserContext, DB, RequestEvent, Action, 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n EnumImplementer extends EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n enumImplementer,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n enumImplementer: EnumImplementer;\n schemaBuilder: SchemaBuilder;\n}) => {\n const referenceStorage = new Map<string, any>();\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 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 const mapSQLTypeStringToInputPothosType = (\n sqlType: PossibleSQLType,\n fieldName: string,\n ) => {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n switch (gqlType) {\n case \"Int\":\n return t.field({ type: \"IntWhereInputArgument\" });\n case \"String\":\n return t.field({ type: \"StringWhereInputArgument\" });\n case \"Boolean\":\n return t.boolean({ required: false });\n case \"Date\":\n return t.field({\n type: \"DateWhereInputArgument\",\n });\n case \"DateTime\":\n return t.field({\n type: \"DateWhereInputArgument\",\n });\n case \"Float\":\n return t.field({\n type: \"FloatWhereInputArgument\",\n });\n case \"ID\":\n return t.id({ required: false });\n case \"JSON\":\n return t.field({\n type: \"JSON\",\n required: false,\n });\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 if (isEnumSchema(value)) {\n const enumImpl = enumImplementer({\n enumColumn: value,\n });\n\n acc[key] = t.field({\n type: enumImpl,\n required: false,\n });\n } else {\n acc[key] = mapSQLTypeStringToInputPothosType(\n value.getSQLType() as PossibleSQLType,\n key,\n );\n }\n\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.columns,\n ReturnType<typeof mapSQLTypeStringToInputPothosType>\n >,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n const relationSchema = tableHelper({\n db,\n table: (value as any).targetTable,\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 };\n },\n });\n };\n\n ret = implement();\n referenceStorage.set(inputTypeName, ret);\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n builtSchema,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n builtSchema: () => ReturnType<SchemaBuilder[\"toSchema\"]>;\n}) => {\n const clientCreator = async ({\n apiUrl,\n outputPath,\n rumbleImportPath,\n useExternalUrqlClient,\n removeExisting,\n forceReactivity,\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 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 from ${__filename} 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 });\n };\n\n return clientCreator;\n};\n","import type {\n AbilityBuilderType,\n createAbilityBuilder,\n} 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 AbilityBuilderType<UserContext, DB, RequestEvent, Action, 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 AbilityBuilder extends ReturnType<\n typeof createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n >,\n>({\n context: makeUserContext,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n abilityBuilder: AbilityBuilder;\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 Object.setPrototypeOf(obj, proto);\n for (const key of Object.keys(obj)) {\n deepSetProto(obj[key], proto, seen);\n }\n}\n","import { count } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFirstEntryExists } from \"./helpers/asserts\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n WhereArgImplementer extends WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n MakePubSubInstance extends MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n whereArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n whereArgImplementer: WhereArgImplementer;\n makePubSubInstance: MakePubSubInstance;\n}) => {\n return <TableName extends keyof DrizzleQueryFunction<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(table.toString())}Count`]: t.field({\n type: \"Int\",\n nullable: false,\n smartSubscription: true,\n description: `Count all ${pluralize.plural(table.toString())}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: {\n where: t.arg({ type: WhereArg, required: false }),\n },\n resolve: async (root, args, ctx, info) => {\n if (isAllowed && !(await isAllowed(ctx))) {\n throw new RumbleErrorSafe(\"Not allowed to perform this action\");\n }\n\n deepSetProto(args);\n\n return (db as any)\n .select({ count: count() })\n .from(tableSchema.fullSchema)\n .where(\n ctx.abilities[table]\n .filter(listAction)\n .merge(mapNullFieldsToUndefined(args) as any).sql.where,\n )\n .then(assertFirstEntryExists)\n .then((r: any) => r.count);\n },\n }),\n };\n });\n };\n};\n","import type { useSofa } from \"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 { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { RumbleError } from \"../../types/rumbleError\";\nimport { mapSQLTypeToGraphQLType } from \"./mapSQLTypeToTSType\";\nimport type { PossibleSQLType } from \"./types\";\n\nexport function buildPothosResponseTypeFromGraphQLType<\n Builder extends DrizzleObjectFieldBuilder<any, any, any, any>,\n>({\n builder,\n sqlType,\n fieldName,\n nullable,\n}: {\n builder: Builder;\n sqlType: PossibleSQLType;\n fieldName: string;\n nullable: boolean;\n}) {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n switch (gqlType) {\n case \"Int\":\n return builder.exposeInt(fieldName, { nullable });\n case \"String\":\n return builder.exposeString(fieldName, { nullable });\n case \"Boolean\":\n return builder.exposeBoolean(fieldName, { nullable });\n case \"Date\":\n return builder.field({\n type: \"Date\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"DateTime\":\n return builder.field({\n type: \"DateTime\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"Float\":\n return builder.exposeFloat(fieldName, { nullable });\n case \"ID\":\n return builder.exposeID(fieldName, { nullable });\n case \"JSON\":\n return builder.field({\n type: \"JSON\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n default:\n throw new RumbleError(\n `Unsupported object type ${gqlType} for column ${fieldName}`,\n );\n }\n}\n","import type { MySqlDatabase } 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 { BaseSQLiteDatabase } 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\nexport function determineDBDialectFromSchema<DB extends DrizzleInstance>(\n schema: DB[\"_\"][\"relations\"],\n) {\n const found = new Set<DBDialect>();\n\n for (const table of Object.values(schema).map((t: any) => t.table)) {\n if (typeof table !== \"object\") {\n continue;\n }\n\n if (table instanceof PgTable) {\n found.add(\"postgres\");\n } else if (table instanceof MySqlTable) {\n found.add(\"mysql\");\n } else if (table instanceof SQLiteTable) {\n found.add(\"sqlite\");\n }\n }\n\n const dialects = Array.from(found);\n\n if (dialects.length === 1) {\n return dialects[0];\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 const dialect = determineDBDialectFromSchema(db._.relations);\n\n return dialect === \"postgres\";\n}\n\nexport function isMySQLDB<\n Narrowed extends MySqlDatabase<any, any> = MySqlDatabase<any, any>,\n>(db: any): db is Narrowed {\n const dialect = determineDBDialectFromSchema(db._.relations);\n\n return dialect === \"mysql\";\n}\n\nexport function isSQLiteDB<\n Narrowed extends BaseSQLiteDatabase<any, any> = BaseSQLiteDatabase<any, any>,\n>(db: any): db is Narrowed {\n const dialect = determineDBDialectFromSchema(db._.relations);\n\n return dialect === \"sqlite\";\n}\n","import { sql } from \"drizzle-orm\";\nimport { cloneDeep } from \"es-toolkit\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\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>,\n) {\n if (!isPostgresDB(input.db)) {\n console.info(\n \"Database dialect is not compatible with search, skipping search initialization. Only PostgreSQL is supported.\",\n );\n return;\n }\n\n await input.db.execute(sql`CREATE EXTENSION IF NOT EXISTS pg_trgm;`);\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 await input.db.execute(\n sql.raw(\n `ALTER DATABASE ${dbName} SET pg_trgm.similarity_threshold = ${threshold};`,\n ),\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>, \"search\"> & {\n //TODO types\n args: any;\n tableSchema: ReturnType<typeof tableHelper>;\n //TODO types\n abilities: any;\n}) {\n if (search?.enabled && args.search && args.search.length > 0) {\n // this prevents columns beeing searched which are not accessible to the user\n // if the abilities defined the user not to be allowed to read something, we need\n // to prevent it from beeing included in the search since this could\n // leak information\n const columnsToSearch = (\n abilities.query.many.columns\n ? Object.entries(tableSchema.columns).filter(\n ([key]) => abilities.query.many.columns[key],\n )\n : Object.entries(tableSchema.columns)\n ).filter(\n ([key, col]) =>\n isStringLikeSQLTypeString(col.getSQLType()) ||\n isIDLikeSQLTypeString(col.getSQLType()),\n );\n\n const searchParam = sql`${args.search}`;\n\n args.extras = {\n search_distance: (table: any) =>\n sql`${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`COALESCE((${table[key]}::TEXT <-> ${searchParam}), 1)`;\n }),\n sql.raw(\" + \"),\n )}`,\n };\n\n const originalOrderBy = cloneDeep(args.orderBy);\n (args as any).orderBy = (table: any) => {\n const argsOrderBySQL = sql.join(\n Object.entries(originalOrderBy ?? {}).map(([key, value]) => {\n // value is \"asc\" or \"desc\"\n if (value === \"asc\") {\n return sql`${table[key]} ASC`;\n } else if (value === \"desc\") {\n return sql`${table[key]} DESC`;\n } else {\n throw new Error(`Invalid value ${value} for orderBy`);\n }\n }),\n sql.raw(\", \"),\n );\n\n const searchSQL = sql`search_distance ASC`;\n\n const ret = originalOrderBy\n ? sql.join([argsOrderBySQL, searchSQL], sql.raw(\", \"))\n : searchSQL;\n\n return ret;\n };\n\n const originalWhere = cloneDeep(args.where);\n\n // this limits the search to the rows which at least match the threshold score\n (args as any).where = {\n AND: [\n originalWhere ?? {},\n {\n RAW: (table: any) =>\n sql`(${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`${table[key]} % ${searchParam}`;\n }),\n sql.raw(\" OR \"),\n )})`,\n },\n ],\n };\n }\n}\n","import type { FieldMap } from \"@pothos/core\";\nimport type { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { One } from \"drizzle-orm\";\nimport { capitalize } from \"es-toolkit\";\nimport pluralize from \"pluralize\";\nimport type { AbilityBuilderType } from \"./abilityBuilder\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { type EnumImplementerType, isEnumSchema } from \"./enum\";\nimport { buildPothosResponseTypeFromGraphQLType } from \"./helpers/sqlTypes/mapDrizzleTypeToGraphQlType\";\nimport type { PossibleSQLType } from \"./helpers/sqlTypes/types\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleTableValueType,\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n WhereArgImplementer extends WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n OrderArgImplementer extends OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n EnumImplementer extends EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n MakePubSubInstance extends MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n AbilityBuilderInstance extends AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n search,\n schemaBuilder,\n makePubSubInstance,\n whereArgImplementer,\n orderArgImplementer,\n enumImplementer,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n whereArgImplementer: WhereArgImplementer;\n orderArgImplementer: OrderArgImplementer;\n enumImplementer: EnumImplementer;\n makePubSubInstance: MakePubSubInstance;\n abilityBuilder: AbilityBuilderInstance;\n}) => {\n return <\n TableName extends keyof DrizzleQueryFunction<DB>,\n RefName extends string,\n >({\n table,\n refName,\n readAction = \"read\" as Action,\n adjust,\n }: {\n /**\n * The table you want to be used as reference for the object creation.\n */\n table: TableName;\n /**\n * The name you want this object to have in your graphql schema.\n * Rumble will create a reasonable default if not specified.\n */\n refName?: RefName;\n /**\n * The action used for read access to the table.\n * Defaults to \"read\".\n */\n readAction?: Action;\n /**\n * A function which can be used to adjust the fields of the object.\n * You can extend the object by specifying fields that do not exist as\n * per your db schema, or overwrite existing fields with the same name.\n * In case you do overwrite, rumble will set proper nullability and\n * subscription properties if you do not specify them explicitly.\n */\n adjust?:\n | ((\n t: DrizzleObjectFieldBuilder<\n SchemaBuilder[\"$inferSchemaTypes\"],\n SchemaBuilder[\"$inferSchemaTypes\"][\"DrizzleRelations\"][TableName],\n DrizzleTableValueType<DB, TableName>\n >,\n ) => FieldMap)\n | undefined;\n }) => {\n const tableSchema = tableHelper({ db, table });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n console.warn(\n `Could not find primary key for ${table.toString()}. Cannot register subscriptions!`,\n );\n }\n const primaryKey = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n return schemaBuilder.drizzleObject(table, {\n name: refName ?? capitalize(table.toString()),\n subscribe: (subscriptions, element, _context) => {\n if (!primaryKey) return;\n const primaryKeyValue = (element as any)[primaryKey.name];\n if (!primaryKeyValue) {\n console.warn(\n `Could not find primary key value for ${JSON.stringify(\n element,\n )}. Cannot register subscription!`,\n );\n return;\n }\n\n //TODO maybe register non specific update calls aswell?\n registerOnInstance({\n instance: subscriptions,\n action: \"updated\",\n primaryKeyValue: primaryKeyValue,\n });\n },\n applyFilters: abilityBuilder?._.registeredFilters({\n table,\n action: readAction,\n }),\n fields: (t) => {\n const columns = tableSchema.columns;\n\n // in case the user makes adjustments we want to store away which\n // pothos function was called with what config\n // this is mapped to the ref which later can be used to\n // reference these parameters while iterating over the fields\n // and checking against the userAdjustments object\n // this is necessary to e.g. merge nullability info from the database schema\n // or register subscriptions on relations\n const configMap = new Map<\n any,\n {\n creatorFunction: (...p: any[]) => any;\n params: any[];\n configObject: any;\n }\n >();\n // stores the results of the user adjustments\n // also stores all the used pothos functions and the configs\n // provided by the user so we can extend that if necessary\n const userAdjustments =\n adjust?.(\n new Proxy(t, {\n get: (target, prop, receiver) => {\n if (\n // we only care for field/relation functions\n typeof (target as any)[prop] !== \"function\" ||\n prop === \"arg\" ||\n prop === \"builder\" ||\n prop === \"graphqlKind\" ||\n prop === \"kind\" ||\n prop === \"listRef\" ||\n prop === \"table\" ||\n prop === \"typename\" ||\n prop === \"variant\" ||\n prop.toString().startsWith(\"boolean\") ||\n prop.toString().startsWith(\"float\") ||\n prop.toString().startsWith(\"id\") ||\n prop.toString().startsWith(\"int\") ||\n prop.toString().startsWith(\"string\") ||\n prop.toString().startsWith(\"expose\")\n ) {\n return (target as any)[prop];\n }\n\n return (...params: any[]) => {\n const ref = (target as any)[prop](...params);\n const configObject = params.find(isProbablyAConfigObject);\n if (!configObject)\n throw new RumbleError(\n \"Expected config object to be passed to adjust field\",\n );\n\n configMap.set(ref, {\n params,\n creatorFunction: (target as any)[prop],\n configObject,\n });\n return ref;\n };\n },\n }) as any,\n ) ?? {};\n\n const fields = Object.entries(columns).reduce(\n (acc, [key, column]) => {\n // 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 if (isEnumSchema(column)) {\n const enumImpl = enumImplementer({\n enumColumn: column,\n });\n\n acc[key] = t.field({\n type: 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 });\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 relationSchema = tableHelper({\n db,\n table: (value as any).targetTable,\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 (value instanceof One) {\n isMany = false;\n nullable = !value.sourceColumns.every((column) => column.notNull);\n filterSpecifier = \"single\";\n }\n\n const subscribe = (subscriptions: any, _element: any) => {\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n };\n\n // in case the user wants to overwrite a field\n // we want to merge with our stuff in case the user\n // did not specify it themselves\n if (userAdjustments[key]) {\n const { params, creatorFunction, configObject } = configMap.get(\n userAdjustments[key],\n )!;\n\n if (typeof configObject.nullable !== \"boolean\") {\n configObject.nullable = nullable;\n }\n\n if (typeof configObject.subscribe !== \"function\") {\n configObject.subscribe = subscribe;\n }\n\n userAdjustments[key] = creatorFunction.bind(t)(...params);\n return acc;\n }\n\n const args = {\n where: t.arg({ type: WhereArg, required: false }),\n orderBy: t.arg({ type: OrderArg, required: false }),\n ...(isMany\n ? {\n offset: t.arg.int({ required: false }),\n limit: t.arg.int({ required: false }),\n }\n : {}),\n search: t.arg.string({ required: false }),\n };\n\n if (!search?.enabled || !isMany) {\n delete (args as any).search;\n }\n\n (acc as any)[key] = t.relation(\n key as any,\n {\n args,\n subscribe,\n nullable,\n description: `Get the ${pluralize.plural(relationSchema.tsName)} related to this ${pluralize.singular(tableSchema.tsName)}`,\n query: (args: any, ctx: any) => {\n // transform null prototyped object\n args = JSON.parse(JSON.stringify(args));\n\n if (isMany) {\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema: relationSchema,\n abilities:\n ctx.abilities[relationSchema.tsName].filter(readAction),\n });\n }\n\n const filter = ctx.abilities[relationSchema.tsName]\n .filter(readAction)\n .merge({\n where: args.where,\n limit: args.limit,\n extras: args.extras,\n }).query[filterSpecifier];\n\n if (args.offset) {\n (filter as any).offset = args.offset;\n }\n\n if (args.orderBy) {\n (filter as any).orderBy = args.orderBy;\n }\n\n return filter;\n },\n } as any,\n ) as any;\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.relations,\n ReturnType<typeof buildPothosResponseTypeFromGraphQLType>\n >,\n );\n\n if (search?.enabled) {\n if (fields.search_distance) {\n throw new Error(\n \"Reserved field name 'search_distance' found on \" +\n tableSchema.tsName +\n \". If search is enabled, the 'search_distance' field is automatically added and cannot be defined manually.\",\n );\n }\n\n fields.search_distance = t.float({\n description:\n \"The search distance of the object. If a search is provided, this field will be populated with the search distance.\",\n nullable: true,\n resolve: (parent, args, ctx, info) =>\n (parent as any).search_distance,\n });\n }\n\n return {\n ...fields,\n ...relations,\n ...userAdjustments,\n };\n },\n });\n };\n};\n","import { createPubSub } from \"graphql-yoga\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\ntype PubSubAction = \"created\" | \"removed\" | \"updated\";\n\nconst SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX = \"RUMBLE_SUBSCRIPTION_NOTIFICATION\";\nconst SUBSCRIPTION_NOTIFIER_REMOVED = \"REMOVED\";\nconst SUBSCRIPTION_NOTIFIER_UPDATED = \"UPDATED\";\nconst SUBSCRIPTION_NOTIFIER_CREATED = \"CREATED\";\n\nexport type MakePubSubInstanceType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>[\"makePubSubInstance\"];\n\nexport const createPubSubInstance = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n subscriptions,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n const pubsub = subscriptions\n ? createPubSub(...subscriptions)\n : createPubSub();\n\n const makePubSubInstance = <\n TableName extends keyof DrizzleQueryFunction<DB>,\n >({\n table,\n }: {\n table: TableName;\n }) => {\n type PrimaryKeyType = any;\n\n function makePubSubKey({\n action,\n tableName,\n primaryKeyValue,\n }: {\n tableName: string;\n action: PubSubAction;\n primaryKeyValue?: PrimaryKeyType;\n }) {\n let actionKey: string;\n\n switch (action) {\n case \"created\":\n actionKey = SUBSCRIPTION_NOTIFIER_CREATED;\n break;\n case \"removed\":\n actionKey = SUBSCRIPTION_NOTIFIER_REMOVED;\n break;\n case \"updated\":\n actionKey = SUBSCRIPTION_NOTIFIER_UPDATED;\n break;\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n\n return `${SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX}/${tableName}${\n primaryKeyValue ? `/${primaryKeyValue}` : \"\"\n }/${actionKey}`;\n }\n\n // TODO does caching these make sense?\n return {\n /**\n * Call this when you want to register a subscription on an instance to this table\n */\n registerOnInstance({\n instance,\n action,\n primaryKeyValue,\n }: {\n instance: { register: (id: string) => void };\n action: PubSubAction;\n primaryKeyValue?: string;\n }) {\n const key = makePubSubKey({\n tableName: table.toString(),\n action,\n primaryKeyValue,\n });\n instance.register(key);\n },\n /**\n * Call this when you created an entity of this table\n */\n created() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"created\",\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you removed one or more entities of this table\n */\n // removed(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n removed() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"removed\",\n //TODO would it make sense to use specific sub topics here?\n // primaryKeyValue,\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you updated one or more entities of this table\n */\n updated(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n const primaryKeys = Array.isArray(primaryKeyValue)\n ? primaryKeyValue\n : [primaryKeyValue];\n const keys = primaryKeys.map((primaryKeyValue) =>\n makePubSubKey({\n tableName: table.toString(),\n action: \"updated\",\n primaryKeyValue,\n }),\n );\n const uniqueKeys = Array.from(new Set(keys));\n for (const key of uniqueKeys) {\n pubsub.publish(key);\n }\n },\n };\n };\n\n return {\n pubsub,\n makePubSubInstance,\n };\n};\n","import { sql } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFindFirstExists } from \"./helpers/asserts\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\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 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n WhereArgImplementer extends WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n OrderArgImplementer extends OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n MakePubSubInstance extends MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n search,\n whereArgImplementer,\n orderArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n whereArgImplementer: WhereArgImplementer;\n orderArgImplementer: OrderArgImplementer;\n makePubSubInstance: MakePubSubInstance;\n}) => {\n return <TableName extends keyof DrizzleQueryFunction<DB>>({\n table,\n readAction = \"read\" as Action,\n listAction = \"read\" as Action,\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 const WhereArg = whereArgImplementer({\n table: table,\n });\n const OrderArg = orderArgImplementer({\n table: table,\n });\n const tableSchema = tableHelper({\n db,\n table,\n });\n const primaryKeyField = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n 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 [pluralize.plural(table.toString())]: t.drizzleField({\n type: [table],\n nullable: false,\n smartSubscription: true,\n description: `List all ${pluralize.plural(table.toString())}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: manyArgs,\n resolve: (query, _root, args, ctx, _info) => {\n // args does not have Object.prototype as prototype, so we need to set it\n // otherwise some libraries (like drizzle-orm) might have issues with it\n deepSetProto(args);\n\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities: ctx.abilities[table].filter(listAction),\n });\n\n const mappedArgs = mapNullFieldsToUndefined(args);\n const filter = ctx.abilities[table]\n .filter(listAction)\n .merge(mappedArgs as any).query.many;\n\n if (mappedArgs.offset) {\n (filter as any).offset = mappedArgs.offset;\n }\n\n if (mappedArgs.orderBy) {\n (filter as any).orderBy = mappedArgs.orderBy;\n }\n\n const queryInstance = query(filter as any);\n\n if ((filter as any).columns) {\n queryInstance.columns = (filter as any).columns;\n }\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) => {\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 console.info(\n \"Database dialect is not postgresql, cannot set cpu_operator_cost.\",\n );\n }\n return (tx.query as any)[table].findMany(queryInstance);\n });\n }\n\n return (db.query as any)[table].findMany(queryInstance);\n },\n }),\n [pluralize.singular(table.toString())]: t.drizzleField({\n type: table,\n nullable: false,\n smartSubscription: true,\n description: `Get a single ${pluralize.singular(table.toString())} by ID`,\n args: {\n id: t.arg.id({ required: true }),\n },\n resolve: (query, _root, args, ctx, _info) => {\n deepSetProto(args);\n\n const filter = (ctx.abilities as any)[table]\n .filter(readAction)\n .merge({ where: { [primaryKeyField.name]: args.id } })\n .query.single;\n const q = query(filter);\n\n if (filter.columns) {\n q.columns = filter.columns;\n }\n\n return (db.query as any)[table]\n .findFirst(q)\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\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","export type Filter<Context, T> = (p: {\n context: Context;\n entities: T[];\n}) => T[] | Promise<T[]>;\n\nexport type ApplyFiltersField<Context, T> =\n | Filter<Context, T>\n | Filter<Context, T>[]\n | undefined;\n\nexport const pluginName = \"RuntimeFiltersPlugin\" as const;\n","import type { Filter } from \"../runtimeFiltersPlugin/filterTypes\";\n\n/**\n * A helper to apply a list of filters to a given list of entities.\n * \n * @example\n * \n * ```ts\n * const filtered = await applyFilters({\n filters: abilityBuilder.registeredFilters.posts.update,\n entities: entitiesToFilter,\n context: ctx,\n });\n * ```\n */\nexport const applyFilters = async <Context, T, H extends T>({\n filters,\n entities,\n context,\n}: {\n entities: T[];\n filters: Filter<Context, H>[];\n context: Context;\n}) => {\n return Array.from(\n (\n await Promise.all(\n filters.map((f) =>\n f({\n context,\n entities: entities as H[],\n }),\n ),\n )\n ).reduce((acc, val) => {\n for (const element of val) {\n acc.add(element);\n }\n return acc;\n // since multiple helpers might return the same entity we use a set to deduplicate\n }, new Set<T>()),\n );\n};\n","import type { Span, Tracer } from \"@opentelemetry/api\";\nimport SchemaBuilder, {\n BasePlugin,\n type PothosOutputFieldConfig,\n type PothosTypeConfig,\n type SchemaTypes,\n} from \"@pothos/core\";\nimport type { GraphQLFieldResolver } from \"graphql\";\nimport { applyFilters } from \"../helpers/applyFilters\";\nimport { type ApplyFiltersField, pluginName } from \"./filterTypes\";\n\nexport const applyFiltersKey = \"applyFilters\";\n\nexport class RuntimeFiltersPlugin<\n Types extends SchemaTypes,\n> extends BasePlugin<Types> {\n private tracer?: Tracer;\n private tracerEnabled?: boolean;\n\n override onTypeConfig(typeConfig: PothosTypeConfig) {\n this.tracer = this.builder.options.otel?.tracer;\n this.tracerEnabled = this.builder.options.otel?.enabled;\n return typeConfig;\n }\n\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n return async (parent, args, context, info) => {\n //TODO: https://github.com/hayes/pothos/discussions/1431#discussioncomment-12974130\n let filters: ApplyFiltersField<Types[\"Context\"], any> | undefined;\n const fieldType = fieldConfig?.type as any;\n\n if (fieldType.kind === \"List\") {\n filters =\n fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];\n } else if (fieldType.kind === \"Object\") {\n filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];\n }\n\n if (!filters || !Array.isArray(filters) || filters.length === 0) {\n // if no filter should be applied, just continue\n return resolver(parent, args, context, info);\n }\n\n const runFilters = async (span?: Span) => {\n const resolved = await resolver(parent, args, context, info);\n const allResolvedValues = Array.isArray(resolved)\n ? resolved\n : [resolved];\n const allFilters = Array.isArray(filters) ? filters : [filters];\n span?.setAttribute(\"filters.total\", allFilters.length);\n\n const allowed = await applyFilters({\n filters: allFilters,\n entities: allResolvedValues,\n context,\n });\n span?.setAttribute(\"filters.allowed\", allowed.length);\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 if (this.tracer && this.tracerEnabled) {\n return this.tracer.startActiveSpan(\n `apply_filters_${fieldConfig.name}`,\n async (span) => {\n try {\n return await runFilters(span);\n } finally {\n span.end();\n }\n },\n );\n } else {\n return runFilters();\n }\n };\n }\n}\n\nlet registered = false;\nexport function registerRuntimeFiltersPlugin() {\n if (!registered) {\n SchemaBuilder.registerPlugin(pluginName, RuntimeFiltersPlugin);\n registered = true;\n }\n}\n","import SchemaBuilder from \"@pothos/core\";\nimport DrizzlePlugin from \"@pothos/plugin-drizzle\";\nimport SmartSubscriptionsPlugin, {\n subscribeOptionsFromIterator,\n} from \"@pothos/plugin-smart-subscriptions\";\nimport TracingPlugin, { isRootField } from \"@pothos/plugin-tracing\";\nimport { createOpenTelemetryWrapper } from \"@pothos/tracing-opentelemetry\";\nimport {\n DateResolver,\n DateTimeISOResolver,\n JSONResolver,\n} from \"graphql-scalars\";\nimport type { createPubSub } from \"graphql-yoga\";\nimport {\n type DateWhereInputArgument,\n implementDefaultWhereInputArgs,\n type NumberWhereInputArgument,\n type StringWhereInputArgument,\n} from \"./args/whereArgsImplementer\";\nimport type { ContextType } from \"./context\";\nimport { pluginName } from \"./runtimeFiltersPlugin/filterTypes\";\nimport { registerRuntimeFiltersPlugin } from \"./runtimeFiltersPlugin/runtimeFiltersPlugin\";\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 disableDefaultObjects,\n pubsub,\n pothosConfig,\n otel,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n pubsub: ReturnType<typeof createPubSub>;\n}) => {\n const createSpan =\n otel?.enabled && otel.tracer\n ? createOpenTelemetryWrapper(otel.tracer, otel.options)\n : undefined;\n\n registerRuntimeFiltersPlugin();\n const schemaBuilder = new SchemaBuilder<{\n Context: ContextType<UserContext, DB, RequestEvent, Action, PothosConfig>;\n DrizzleRelations: DB[\"_\"][\"relations\"];\n 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;\n };\n };\n Inputs: {\n IntWhereInputArgument: NumberWhereInputArgument;\n FloatWhereInputArgument: NumberWhereInputArgument;\n StringWhereInputArgument: StringWhereInputArgument;\n DateWhereInputArgument: DateWhereInputArgument;\n };\n DefaultFieldNullability: false;\n }>({\n ...pothosConfig,\n plugins: [\n pluginName,\n DrizzlePlugin,\n SmartSubscriptionsPlugin,\n TracingPlugin,\n ...(pothosConfig?.plugins ?? []),\n ],\n drizzle: {\n client: db,\n relations: db._.relations,\n getTableConfig(table) {\n //TODO support composite primary keys\n return {\n columns: Object.values((table as any)[Symbol.for(\"drizzle:Columns\")]),\n primaryKeys: Object.values(\n (table as any)[Symbol.for(\"drizzle:Columns\")],\n ).filter((v: any) => v.primary),\n } as any;\n },\n },\n smartSubscriptions: {\n ...subscribeOptionsFromIterator((name, _context) => {\n return pubsub.subscribe(name);\n }),\n },\n defaultFieldNullability: false,\n tracing: {\n default: otel?.enabled ? (config) => isRootField(config) : () => false,\n wrap: createSpan\n ? (resolver, options) => createSpan(resolver, options)\n : (resolver) => resolver,\n },\n otel,\n });\n\n schemaBuilder.addScalarType(\"JSON\", JSONResolver);\n schemaBuilder.addScalarType(\"Date\", DateResolver);\n schemaBuilder.addScalarType(\"DateTime\", DateTimeISOResolver);\n implementDefaultWhereInputArgs(schemaBuilder);\n\n if (!disableDefaultObjects?.query) {\n schemaBuilder.queryType({});\n }\n\n if (!disableDefaultObjects?.subscription) {\n schemaBuilder.subscriptionType({});\n }\n\n if (!disableDefaultObjects?.mutation) {\n schemaBuilder.mutationType({});\n }\n\n return { schemaBuilder };\n};\n","import { EnvelopArmorPlugin } from \"@escape.tech/graphql-armor\";\nimport { useDisableIntrospection } from \"@graphql-yoga/plugin-disable-introspection\";\nimport { SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport { AttributeNames, SpanNames } from \"@pothos/tracing-opentelemetry\";\nimport { merge } from \"es-toolkit\";\nimport {\n createYoga as nativeCreateYoga,\n type Plugin,\n type YogaServerOptions,\n} from \"graphql-yoga\";\nimport { useSofa } from \"sofa-api\";\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 } from \"./enum\";\nimport { lazy } from \"./helpers/lazy\";\nimport { sofaOpenAPIWebhookDocs } from \"./helpers/sofaOpenAPIWebhookDocs\";\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\nexport const rumble = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n PothosConfig extends CustomRumblePothosConfig,\n Action extends string = \"read\" | \"update\" | \"delete\",\n>(\n rumbleInput: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>,\n) => {\n if (!rumbleInput.db._.schema) {\n throw new RumbleError(`\nrumble could not find any schema in the provided drizzle instance.\nMake sure you import the schema and pass it to the drizzle instance:\n\nexport const db = drizzle(\n \"postgres://postgres:postgres@localhost:5432/postgres\",\n {\n relations,\n schema, // <--- add this line\n },\n);\n\n`);\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 schema,\n },\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 typeof abilityBuilder\n >({\n ...rumbleInput,\n abilityBuilder,\n });\n\n const { makePubSubInstance, pubsub } = createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n });\n\n const { schemaBuilder } = createSchemaBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({ ...rumbleInput, pubsub });\n\n const enum_ = createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const whereArg = createWhereArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder,\n typeof enum_\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 typeof schemaBuilder\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const object = createObjectImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder,\n typeof whereArg,\n typeof orderArg,\n typeof enum_,\n typeof makePubSubInstance,\n typeof abilityBuilder\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 typeof schemaBuilder,\n typeof whereArg,\n typeof orderArg,\n typeof makePubSubInstance\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(() => schemaBuilder.toSchema());\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 | undefined,\n ) => {\n const enableApiDocs =\n args?.enableApiDocs ?? process?.env?.NODE_ENV === \"development\";\n\n return nativeCreateYoga<RequestEvent>({\n ...args,\n graphiql: enableApiDocs,\n plugins: [\n ...(args?.plugins ?? []),\n ...(enableApiDocs\n ? []\n : [useDisableIntrospection(), EnvelopArmorPlugin()]),\n rumbleInput.otel?.enabled\n ? ({\n onExecute: ({ setExecuteFn, executeFn }) => {\n setExecuteFn((options) =>\n rumbleInput.otel!.tracer!.startActiveSpan(\n SpanNames.EXECUTE,\n {\n attributes: {\n [AttributeNames.OPERATION_NAME]:\n options.operationName ?? \"anonymous\",\n // TODO\n // [AttributeNames.SOURCE]: print(options.document),\n },\n },\n async (span) => {\n try {\n const result = await executeFn(options);\n\n return result;\n } catch (error) {\n if (error instanceof Error) {\n span.recordException(error);\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n },\n ),\n );\n },\n } as Plugin)\n : false,\n ].filter(Boolean),\n schema: builtSchema(),\n context,\n });\n };\n\n const createSofa = (\n args: Omit<Parameters<typeof useSofa>[0], \"schema\" | \"context\">,\n ) => {\n if (args.openAPI) {\n merge(args.openAPI, sofaOpenAPIWebhookDocs);\n }\n return useSofa({\n ...args,\n schema: builtSchema(),\n context,\n });\n };\n\n const clientCreator = clientCreatorImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder\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 * 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};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;AAShB,IAAa,kBAAb,cAAqCA,qBAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACelD,MAAa,yBAA4B,UAA4B;AACnE,KAAI,CAAC,MACH,OAAM,IAAI,gBAAgB,2CAA2C;AAEvE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CT,MAAa,0BAA6B,UAAkB;CAC1D,MAAM,IAAI,MAAM,GAAG,EAAE;AACrB,KAAI,CAAC,EACH,OAAM,IAAI,gBAAgB,4CAA4C;AACxE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBT,SAAgB,yBAA2C,KAAQ;AACjE,QAAO,OAAO,YACZ,OAAO,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,WAAW,CACxC,KACA,UAAU,OAAO,SAAY,MAC9B,CAAC,CACH;;;;;;;;;AE9DH,SAAgB,aAGd,SAA4B,SAA4B;AAoDxD,QAAO;EACL,OAnDA,SAAS,SAAS,SAAS,QACvB,EAAE,KAAK,CAAC,SAAS,OAAO,SAAS,MAAM,EAAE,GACxC,SAAS,SAAS,SAAS;EAkDhC,SA/CA,SAAS,WAAW,SAAS,UACzB,IAAI,IACF,CACE,OAAO,QAAQ,SAAS,WAAW,EAAE,CAAC,EACtC,OAAO,QAAQ,SAAS,WAAW,EAAE,CAAC,CACvC,CACE,MAAM,CACN,QAAQ,GAAG,OAAO,MAAM,KAAK,CAC7B,KAAK,CAAC,OAAO,EAAE,CACnB,CACE,SAAS,CACT,QACE,KAAK,CAAC,SAAS;AACd,OAAI,OAAO;AACX,UAAO;KAET,EAAE,CACH,GACH;EA8BJ,QA3BA,SAAS,UAAU,SAAS,kCACf,SAAS,UAAU,EAAE,EAAE,SAAS,UAAU,EAAE,CAAC,GACtD;EA0BJ,SAvBA,SAAS,WAAW,SAAS,mCAChB,SAAS,WAAW,EAAE,EAAE,SAAS,WAAW,EAAE,CAAC,GACxD;EAsBJ,OAnBA,SAAS,SAAS,SAAS,QACvB,KAAK,IAAI,SAAS,SAAS,UAAU,SAAS,SAAS,SAAS,GAChE;EAkBJ,QAfA,SAAS,UAAU,SAAS,SACxB,KAAK,IAAI,SAAS,UAAU,UAAU,SAAS,UAAU,SAAS,GAClE;EAcJ,MAXA,SAAS,QAAQ,SAAS,gCACb,SAAS,QAAQ,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,GAClD;EAUL;;;;;AC/DH,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,uBACd,SACmD;AACnD,QAAO,sBAAsB,SAAS,QAAe;;AAGvD,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,yBACd,SACqD;AACrD,QAAO,wBAAwB,SAAS,QAAe;;AAGzD,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,0BACd,SACsD;AACtD,QAAO,yBAAyB,SAAS,QAAe;;AAG1D,MAAM,uBAAuB,CAAC,OAAO;AAErC,SAAgB,sBACd,SACkD;AAClD,QAAO,qBAAqB,SAAS,QAAe;;AAGtD,MAAM,wBAAwB,CAAC,UAAU;AAEzC,SAAgB,uBACd,SACmD;AACnD,QAAO,sBAAsB,SAAS,QAAe;;AAGvD,MAAM,6BAA6B,CAAC,aAAa,WAAW;AAE5D,SAAgB,4BACd,SACwD;AACxD,QAAO,2BAA2B,SAAS,QAAe;;AAG5D,MAAM,yBAAyB,CAAC,OAAO;AAEvC,SAAgB,wBACd,SACoD;AACpD,QAAO,uBAAuB,SAAS,QAAe;;AAGxD,MAAM,yBAAyB,CAAC,QAAQ,QAAQ;AAEhD,SAAgB,wBACd,SACoD;AACpD,QAAO,uBAAuB,SAAS,QAAe;;AAGxB;CAC9B,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAID,MAAa,0BACX,SACA,mBAEA,IAAI,YACF,kCAAkC,QAAQ,yFAAyF,eAAe,GACnJ;;;;AC3FH,SAAgB,gCAAgC,SAG9C;AACA,KAAI,uBAAuB,QAAQ,CACjC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,yBAAyB,QAAQ,CACnC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,0BAA0B,QAAQ,CACpC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,sBAAsB,QAAQ,CAChC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,uBAAuB,QAAQ,CACjC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,4BAA4B,QAAQ,CACtC,QAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC5B,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC7B;AAGH,KAAI,wBAAwB,QAAQ,CAClC,QAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC5B,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC7B;AAGH,KAAI,wBAAwB,QAAQ,CAClC,QAAO;EACL,QAAQ,EAAE,GAAG,GAAG;EAChB,QAAQ,EAAE,GAAG,GAAG;EACjB;AAGH,OAAM,uBAAuB,SAAS,WAAW;;;;;ACjEnD,MAAM,oBAAoB,OAAO,IAAI,eAAe;AACpD,MAAM,4BAA4B,OAAO,IAAI,uBAAuB;AACpE,MAAM,wBAAwB,OAAO,IAAI,mBAAmB;AAE5D,SAAgB,YAMd,EAAE,IAAI,SAA6C;AACnD,KAAI,OAAO,UAAU,SACnB,SACE,MAAM,UACN,MAAM,UACN,MAAM,sBACN,MAAM,8BACN,MAAM;CAGV,MAAM,gBAAqB,OAAO,OAAO,GAAG,EAAE,UAAW,CAAC,MACvD,WACC,OAAO,SAAS,SAChB,OAAO,MAAM,uBAAuB,SACpC,OAAO,MAAM,+BAA+B,SAC5C,OAAO,MAAM,2BAA2B,MAC3C;AAED,KAAI,CAAC,cACH,OAAM,IAAI,YAAY,6BAA6B,KAAK,UAAU,MAAM,GAAG;CAG7E,MAAM,cAAc,OAAO,OACxB,GAAiD,EAAE,OACrD,CAAC,MACC,WACC,OAAO,WAAW,cAAc,MAAM,2BACzC;AAED,KAAI,CAAC,YACH,OAAM,IAAI,YAAY,6BAA6B,KAAK,UAAU,MAAM,GAAG;CAG7E,MAAM,aAAa,GAAG,EAAE,aAAa,YAAY;AAEjD,KAAI,CAAC,WACH,OAAM,IAAI,YACR,kCAAkC,KAAK,UAAU,MAAM,GACxD;AAGH,QAAO;EACL,SAAS,YAAY;EACrB,YAAY,YAAY;EACxB,WAAY,cAAsB;EAGlC,QAAQ,YAAY;EACpB,QAAQ,YAAY;EACpB;EACA;EACA;EACD;;;;;ACCH,SAAS,qBAMP,QAC0D;AAC1D,QACE,OAAO,WAAW,cAAc,OAAO,YAAY,SAAS;;AAIhE,SAAS,oBAMP,QACgD;AAChD,QAAO,OAAO,WAAW;;AAG3B,MAAM,2DACH,OAAe,WAAmB;AACjC,SAAQ,KAAK;;;MAGX,MAAM,GAAG,OAAO;;;EAGpB;GAEA,IACD;AAED,MAAa,wBAMX,EACA,IACA,SACA,cACA,WACsE;CAGtE,IAAI,eAAe;CAEnB,MAAM,8BAA4D;EAChE,MAAM,+BAAe,IAAI,KAStB;EAEH,MAAM,iCAAiB,IAAI,KAIxB;AAKH,OAAK,MAAM,UAAU,QACnB,KAAI,CAAC,eAAe,IAAI,OAAO,CAC7B,gBAAe,IAAI,QAAQ,EAAE,CAAC;AAIlC,SAAO;GAIL,QAAQ,WAA8B;AACpC,QAAI,aACF,OAAM,IAAI,YACR,wIACD;IAGH,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO;AACzD,SAAK,MAAM,UAAU,SAAS;KAC5B,IAAI,UAAU,aAAa,IAAI,OAAO;AACtC,SAAI,CAAC,SAAS;AACZ,gBAAU;AACV,mBAAa,IAAI,QAAQ,QAAQ;;;AAIrC,WAAO,EAYL,OACE,gBAMG;AACH,UAAK,MAAM,UAAU,SAAS;AAC5B,UAAI,aAAa,IAAI,OAAO,KAAK,eAC/B,cAAa,IAAI,QAAQ,EAAE,CAAC;AAG9B,MADgB,aAAa,IAAI,OAAO,CACa,KACnD,YACD;;OAGN;;GAMH,SAAS,WAA8B;IACrC,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO;AACzD,WAAO,EAIL,KACE,mBAIG;AACH,UAAK,MAAM,UAAU,QAEnB,gBAAe,IAAI,OAAO,CAAE,KAAK,eAAe;OAGrD;;GAEH,GAAG;IACD;IACA;IACD;GACF;;CAGH,MAAM,mBAAmB,OAAO,YAC7B,OAAO,KAAK,GAAG,MAAM,CAAkB,KAAK,cAAc,CACzD,WACA,uBAAyC,CAC1C,CAAC,CACH;AAID,QAAO;EACL,GAAG;EAKH,GAAG;GACD,kBAAkB,EAChB,QACA,SAIC;AACD,WAAQ,iBAAiB,OAAe,EAAE,eAAe,IACvD,OACD;;GAEH,QAAQ;IACN,MAAM,wBACJ,cACG;KACH,MAAM,eAAe,iBAAiB,WAAW,EAAE;KAEnD,MAAM,qBAAqB,OAAO,YAChC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,OAAO;AAExC,UAAI,CAAC,WAAW,YAAY,eAAgB,QAAO,CAAC,QAAQ,EAAE,CAAC;AAE/D,aAAO,CAAC,QAAQ,QAAQ,OAAO,oBAAoB,CAAC;OACpD,CACH;KAQD,MAAM,sBAAsB,OAAO,YACjC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,OAAO;AAExC,UAAI,CAAC,WAAW,YAAY,eAAgB,QAAO,CAAC,QAAQ,EAAE,CAAC;AAE/D,aAAO,CAAC,QAAQ,QAAQ,OAAO,qBAAqB,CAAC;OACrD,CACH;KASD,MAAM,cAAc,YAAY;MAC9B;MACA,OAAO;MACR,CAAC;AAEF,SAAI,OAAO,KAAK,YAAY,WAAW,CAAC,WAAW,EACjD,OAAM,IAAI,YACR,mCAAmC,UAAU,UAAU,GACxD;KAGH,MAAM,kBAAkB,OAAO,OAAO,YAAY,WAAW,CAAC;KAE9D,MAAM,iBAAiB,gCACrB,gBAAgB,YAAY,CAC7B;KAED,MAAM,wBAAwB,EAC5B,OAAO,EACL,KAAK,CACH,GACG,gBAAgB,OAAO,eAAe,QACxC,EACD,GACG,gBAAgB,OAAO,eAAe,QACxC,CACF,EACF,EACF;;;;KAKD,SAAS,oBACP,cACA;MACA,MAAM,uBACJ,SACA,gBACG;OACH,MAAM,QAAQC,wBAAW;AACvB,YAEE,gBAAgB,QAChB;AACA,aAAI,CAAC,SAAS,MAEZ,QAAO;AAGT,aAAK,QAAQ,QAAmB,YAE9B,QAAO;;QAIX,IAAI,QAAQ,SAAS;AAErB,YACE,iBACC,UAAU,UAAa,QAAQ,cAEhC,SAAQ;AAIV,eAAO,SAAS;SAChB;OAEF,MAAM,sBAAsBA,wBAAW;AACrC,eAAO,SAAS,8CAEV,YAAY,cAAc,OAC1B,QAAQ,MACT,GACD;SACJ;AAKF,WAAI,SAAS,QACX,QAAO;QAUL,OAAO;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,SAAS;UAChB,SAAS,SAAS;UACnB;SAWD,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,SAAS;UAChB,SAAS,SAAS;UAClB,IAAI,QAAQ;AACV,kBAAO,OAAO;;UAEjB;SAQF;QAoBD,KAAK,EACH,IAAI,QAAQ;AACV,gBAAO,qBAAqB;WAE/B;QACF;WAED,QAAO;QAUL,OAAO;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,SAAS;UACjB;SAWD,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,SAAS;UAChB,IAAI,QAAQ;AACV,kBAAO,OAAO;;UAEjB;SAQF;QAoBD,KAAK,EACH,IAAI,QAAQ;AACV,gBAAO,qBAAqB;WAE/B;QACF;;MAIL,MAAM,MAAM,oBAAoB,aAAa;;;;MAK7C,SAAS,MACP,GACA;AAEA,cAAO,oBADQ,aAAa,IAAI,MAAM,MAAM,EAAE,EAM5C,EAAE,MACH;;AAGH,MAAC,IAAY,QAAQ;AAErB,aAAO;;AAKT,YAAO,EACL,cAAc,gBAA6B;AACzC,aAAO,EACL,SAAS,WAAmB;OAC1B,MAAM,qBAAqB,SAAgB;QACzC,MAAM,UAAU,aAAa,IAAI,OAAO;AAGxC,YAAI,YAAY,gBAAgB;AAC9B,eAAM,aAAa,oBAAoB,eAAe;AACtD,gBAAO,qBAAqB;;AAI9B,YAAI,CAAC,SAAS;AACZ,eAAM,aACJ,oBACA,qBACD;AACD,wCACE,UAAU,UAAU,EACpB,OACD;AACD,gBAAO,oBAAoB,sBAAsB;;QAInD,MAAM,iBAAiB,IAAI,MAEzB,oBAAoB,QAAQ,OAAO;QACrC,IAAI,kBAAkB;AACtB,aACE,IAAI,IAAI,GACR,IAAI,oBAAoB,QAAQ,QAChC,KACA;SACA,MAAM,OAAO,oBAAoB,QAAQ;SACzC,MAAM,SAAS,KAAK,YAAY;AAEhC,aAAI,WAAW,QACb,QAAO,qBAAqB;AAG9B,aAAI,WAAW,OAAW;AAE1B,wBAAe,qBAAqB;;AAEtC,uBAAe,SAAS;AAExB,cAAM,aACJ,qBACA,eAAe,OAChB;AACD,cAAM,aACJ,oBACA,mBAAmB,QAAQ,OAC5B;QAED,MAAM,kBAAkB,CACtB,GAAG,mBAAmB,SACtB,GAAG,eACJ;AAED,cAAM,aACJ,mBACA,gBAAgB,OACjB;AAGD,YAAI,gBAAgB,WAAW,GAAG;AAChC,eAAM,aACJ,oBACA,qBACD;AAED,gBAAO,oBAAoB,sBAAsB;;QAGnD,MAAM,gBACJ,gBAAgB,WAAW,IACvB,gBAAgB,KAChB,gBAAgB,QAAQ,GAAG,MAAM;AAC/B,gBAAO,aAAa,GAAG,EAAE;WACxB,EAAE,CAAC;AAEZ,cAAM,aAAa,oBAAoB,UAAU;AACjD,eAAO,oBAAoB,cAAqB;;AAGlD,WAAI,MAAM,WAAW,KAAK,OACxB,QAAO,KAAK,OAAO,gBACjB,2BAA2B,WAC1B,SAAS;AACR,YAAI;AACF,gBAAO,kBAAkB,KAAK;kBACtB;AACR,cAAK,KAAK;;SAGf;WAED,QAAO,mBAAmB;SAG/B;QAEJ;;IAGH,MAAM,oBAAoB,OAAO,YAC9B,OAAO,KAAK,GAAG,MAAM,CAAkB,KAAK,cAAc,CACzD,WACA,qBAAqB,UAAU,CAChC,CAAC,CACH;AAID,mBAAe;AAEf,YAAQ,QAAqB;AAC3B,YAAO,OAAO,YACX,OAAO,KAAK,kBAAkB,CAAkB,KAC9C,cAAc,CACb,WACA,kBAAkB,WAAW,YAAY,IAAI,CAC9C,CACF,CACF;;;GAON;EACF;;;;;AC7oBH,MAAMC,qBAAmB,WACvB,kEAA0B,OAAO,UAAU,CAAC,CAAC,CAAC;AAEhD,MAAa,6BAaX,EACA,IACA,oBAGI;CACJ,MAAM,mCAAmB,IAAI,KAAkB;CAE/C,MAAM,0BAA0BC,wBAC9B,cAAc,SAAS,oBAAoB,EACzC,QAAQ,CAAC,OAAO,OAAO,EACxB,CAAC,CACH;CAED,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;GAClB,CAAC;EAEF,MAAM,gBAAgB,WAAWD,kBAAgB,YAAY,OAAO;EAEpE,IAAI,MACF,iBAAiB,IAAI,cAAc;AACrC,MAAI,IACF,QAAO;EAGT,MAAM,kBAAkB;AACtB,UAAO,cAAc,UAAU,eAAe,EAC5C,SAAS,MAAM;IACb,MAAM,SAAS,OAAO,QAAQ,YAAY,QAAQ,CAAC,QAChD,KAAK,CAAC,SAAS;AACd,SAAI,OAAO,EAAE,MAAM;MACjB,MAAM,yBAAyB;MAC/B,UAAU;MACX,CAAC;AAEF,YAAO;OAET,EAAE,CAIH;IAED,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,EAAE,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;KAKrB,MAAM,iBAAiB,oBAAoB,EACzC,QALqB,YAAY;MACjC;MACA,OAAQ,MAAc;MACvB,CAAC,CAEuB,QACxB,CAAC;AAEF,SAAI,OAAO,EAAE,MAAM;MACjB,MAAM;MACN,UAAU;MACX,CAAC;AAEF,YAAO;OAET,EAAE,CAIH;AAED,WAAO;KACL,GAAG;KACH,GAAG;KACJ;MAEJ,CAAC;;AAGJ,QAAM,WAAW;AACjB,mBAAiB,IAAI,eAAe,IAAI;AACxC,SAAO;;AAGT,QAAO;;;;;;;;ACnIT,SAAgB,aAAa,YAA4C;AAEvE,QAAO,sBAAsBE;;AA+B/B,MAAa,yBAaX,EACA,IACA,oBAGI;CACJ,MAAM,mCAAmB,IAAI,KAAkB;CAE/C,MAAM,mBAMJ,EACA,QACA,YACA,cAaM;EAGN,IAAI;EACJ,IAAI;AAEJ,MAAI,QAAQ;GACV,MAAM,aAAa,GAAG,EAAE,WAAY;AAEpC,oBAAiB,OAAO,UAAU;GAElC,MAAM,UAAU,OAAO,OACpB,GAAiD,EAAE,OACrD,CACE,QAAQ,MAAM,OAAO,MAAM,SAAS,CACpC,KAAK,MAAM,OAAO,OAAO,EAAE,QAAQ,CAAC,CACpC,KAAK,EAAE,CACP,OAAO,aAAa,CACpB,MAAM,MAAW,EAAE,OAAO,SAAS,WAAW;AAEjD,OAAI,CAAC,QACH,OAAM,IAAI,YAAY,0CAA0C,OAAO,UAAU,CAAC;2EACf;AAGrE,gBAAc,QAAgB;aACrB,YAAY;GACrB,MAAM,QAAQ,OAAO,QAClB,GAAiD,EAAE,WACrD,CAAC,QAAQ,CAAC,GAAG,WAAY,WAAmB,OAAO,SAAS,MAAM,CAAC;AAEpE,OAAI,CAAC,MACH,OAAM,IAAI,YACR,iCAAkC,WAAmB,OAAO,KAAK,GAClE;AAEH,oBAAiB,MAAM;AACvB,gBAAa,WAAW;;AAG1B,MAAI,CAAC,kBAAkB,CAAC,WACtB,OAAM,IAAI,YAAY,sCAAsC;EAG9D,MAAM,4BACJ,WAAW,kEAA0B,eAAe,CAAC,CAAC;EAExD,IAAI,MAAgD,iBAAiB,IACnE,0BACD;AACD,MAAI,IACF,QAAO;EAGT,MAAM,kBACJ,cAAc,SAAS,2BAA2B,EAChD,QAAQ,YACT,CAAC;AAEJ,QAAM,WAAW;AACjB,mBAAiB,IAAI,2BAA2B,IAAI;AACpD,SAAO;;AAGT,QAAO;;;;;AC7IT,SAAgB,wBAad,EAAE,SAAS,aAA+D;CAK1E,IAAI;AAEJ,KAAI,uBAAuB,QAAQ,CACjC,OAAM;AAGR,KAAI,yBAAyB,QAAQ,CACnC,OAAM;AAGR,KAAI,0BAA0B,QAAQ,CACpC,KACE,cACC,UAAU,aAAa,CAAC,SAAS,MAAM,IACtC,UAAU,aAAa,CAAC,SAAS,KAAK,EAExC,OAAM;KAEN,OAAM;AAIV,KAAI,sBAAsB,QAAQ,CAChC,OAAM;AAGR,KAAI,uBAAuB,QAAQ,CACjC,OAAM;AAGR,KAAI,4BAA4B,QAAQ,CACtC,OAAM;AAGR,KAAI,wBAAwB,QAAQ,CAClC,OAAM;AAGR,KAAI,wBAAwB,QAAQ,CAClC,OAAM;AAGR,KAAI,QAAQ,OACV,QAAO;AAGT,OAAM,uBAAuB,SAAS,aAAa;;;;;ACrCrD,MAAM,mBAAmB,WACvB,kEAA0B,OAAO,UAAU,CAAC,CAAC,CAAC;AAEhD,MAAa,6BAoBX,EACA,IACA,eACA,sBAII;CACJ,MAAM,mCAAmB,IAAI,KAAkB;CAE/C,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;GAClB,CAAC;EAEF,MAAM,gBAAgB,WAAW,gBAAgB,YAAY,OAAO;EAEpE,IAAI,MACF,iBAAiB,IAAI,cAAc;AACrC,MAAI,IACF,QAAO;EAGT,MAAM,kBAAkB;AACtB,UAAO,cAAc,UAAU,eAAe,EAC5C,SAAS,MAAM;IACb,MAAM,qCACJ,SACA,cACG;KACH,MAAM,UAAU,wBAAwB;MACtC;MACA;MACD,CAAC;AACF,aAAQ,SAAR;MACE,KAAK,MACH,QAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;MACnD,KAAK,SACH,QAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;MACtD,KAAK,UACH,QAAO,EAAE,QAAQ,EAAE,UAAU,OAAO,CAAC;MACvC,KAAK,OACH,QAAO,EAAE,MAAM,EACb,MAAM,0BACP,CAAC;MACJ,KAAK,WACH,QAAO,EAAE,MAAM,EACb,MAAM,0BACP,CAAC;MACJ,KAAK,QACH,QAAO,EAAE,MAAM,EACb,MAAM,2BACP,CAAC;MACJ,KAAK,KACH,QAAO,EAAE,GAAG,EAAE,UAAU,OAAO,CAAC;MAClC,KAAK,OACH,QAAO,EAAE,MAAM;OACb,MAAM;OACN,UAAU;OACX,CAAC;MACJ,QACE,OAAM,IAAI,YACR,6BAA6B,QAAQ,cAAc,UACpD;;;IAGP,MAAM,SAAS,OAAO,QAAQ,YAAY,QAAQ,CAAC,QAChD,KAAK,CAAC,KAAK,WAAW;AACrB,SAAI,aAAa,MAAM,EAAE;MACvB,MAAM,WAAW,gBAAgB,EAC/B,YAAY,OACb,CAAC;AAEF,UAAI,OAAO,EAAE,MAAM;OACjB,MAAM;OACN,UAAU;OACX,CAAC;WAEF,KAAI,OAAO,kCACT,MAAM,YAAY,EAClB,IACD;AAGH,YAAO;OAET,EAAE,CAIH;IAED,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,EAAE,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;KAKrB,MAAM,iBAAiB,oBAAoB,EACzC,QALqB,YAAY;MACjC;MACA,OAAQ,MAAc;MACvB,CAAC,CAEuB,QACxB,CAAC;AAEF,SAAI,OAAO,EAAE,MAAM;MACjB,MAAM;MACN,UAAU;MACX,CAAC;AAEF,YAAO;OAET,EAAE,CAIH;AAED,WAAO;KACL,GAAG;KACH,GAAG;KACJ;MAEJ,CAAC;;AAGJ,QAAM,WAAW;AACjB,mBAAiB,IAAI,eAAe,IAAI;AACxC,SAAO;;AAGT,QAAO;;;;;AC9MT,MAAa,4BAaX,EACA,kBAGI;CACJ,MAAM,gBAAgB,OAAO,EAC3B,QACA,YACA,kBACA,uBACA,gBACA,sBA6BI;AACJ,MAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,KACN,uGAAuG,WAAW,mBAAmB,KAAK,UACxI;GACE;GACA;GACA;GACA;GACA;GACD,CACF,GACF;AAGH,QAAMC,oCAAmB;GACvB,QAFa,aAAa;GAG1B;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;;AAGJ,QAAO;;;;;AC/CT,MAAa,yBAeX,EACA,SAAS,iBACT,qBAGI;CACJ,MAAM,sBAAsBC,wBAAW,eAAe,EAAE,OAAO,CAAC;AAEhE,QAAO,OAAO,QAAsB;EAClC,MAAM,cAAc,kBAChB,MAAM,gBAAgB,IAAI,GACzB,EAAE;AAEP,SAAO;GACL,GAAG;GACH,WAAW,qBAAqB,CAAC,YAAY;GAC9C;;;;;;ACvEL,SAAgB,aACd,KACA,QAAQ,OAAO,WACf,uBAAO,IAAI,SAAS,EACpB;AACA,KAAI,QAAQ,QAAQ,OAAO,QAAQ,SAAU;AAC7C,KAAI,KAAK,IAAI,IAAI,CAAE;AACnB,MAAK,IAAI,IAAI;AACb,QAAO,eAAe,KAAK,MAAM;AACjC,MAAK,MAAM,OAAO,OAAO,KAAK,IAAI,CAChC,cAAa,IAAI,MAAM,OAAO,KAAK;;;;;ACSvC,MAAa,+BA2BX,EACA,IACA,eACA,qBACA,yBAKI;AACJ,SAA0D,EACxD,OACA,aAAa,QACb,gBAeI;EACJ,MAAM,WAAW,oBAAoB,EAC5B,OACR,CAAC;EACF,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,OAAO,CAAC;EAEnE,MAAM,cAAc,YAAY;GAC9B;GACA;GACD,CAAC;AAEF,SAAO,cAAc,aAAa,MAAM;AACtC,UAAO,GACJ,GAAG,kBAAU,OAAO,MAAM,UAAU,CAAC,CAAC,SAAS,EAAE,MAAM;IACtD,MAAM;IACN,UAAU;IACV,mBAAmB;IACnB,aAAa,aAAa,kBAAU,OAAO,MAAM,UAAU,CAAC;IAC5D,YAAY,eAAe,OAAO,OAAO,MAAM,UAAU;AACvD,wBAAmB;MACjB,UAAU;MACV,QAAQ;MACT,CAAC;AACF,wBAAmB;MACjB,UAAU;MACV,QAAQ;MACT,CAAC;;IAEJ,MAAM,EACJ,OAAO,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;KAAO,CAAC,EAClD;IACD,SAAS,OAAO,MAAM,MAAM,KAAK,SAAS;AACxC,SAAI,aAAa,CAAE,MAAM,UAAU,IAAI,CACrC,OAAM,IAAI,gBAAgB,qCAAqC;AAGjE,kBAAa,KAAK;AAElB,YAAQ,GACL,OAAO,EAAE,+BAAc,EAAE,CAAC,CAC1B,KAAK,YAAY,WAAW,CAC5B,MACC,IAAI,UAAU,OACX,OAAO,WAAW,CAClB,MAAM,yBAAyB,KAAK,CAAQ,CAAC,IAAI,MACrD,CACA,KAAK,uBAAuB,CAC5B,MAAM,MAAW,EAAE,MAAM;;IAE/B,CAAC,EACH;IACD;;;;;;AC3HN,MAAa,yBAET;CACF,OAAO;EACL,YAAY,EACV,MAAM;GACJ,aAAa;GACb,aAAa;GACb,MAAM,EAAE;GACR,YAAY,EAAE;GACd,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,0CACP,EACF,EACF,EACF;GACD,WAAW,EACT,OAAO;IACL,aAAa;IACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,8CACP,EACF,EACF;IACF,EACF;GACF,EACF;EACD,iBAAiB;GACf,MAAM;IACJ,aAAa;IACb,aAAa;IACb,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,UACP;KACF,CACF;IACD,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,0CACP,EACF,EACF,EACF;IACD,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,8CACP,EACF,EACF;KACF,EACF;IACF;GACD,QAAQ;IACN,aAAa;IACb,aAAa;IACb,MAAM,EAAE;IACR,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,UACP;KACF,CACF;IACD,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,8CACP,EACF,EACF;KACF,EACF;IACF;GACF;EACF;CACD,YAAY,EACV,SAAS;EACP,mBAAmB;GACjB,MAAM;GACN,YAAY;IACV,cAAc;KACZ,aACE;KACF,MAAM;KACP;IACD,WAAW;KACT,aAAa;KACb,MAAM;KACP;IACD,KAAK;KACH,aAAa;KACb,MAAM;KACP;IACF;GACF;EACD,uBAAuB;GACrB,MAAM;GACN,YAAY,EACV,IAAI;IACF,aACE;IACF,MAAM;IACP,EACF;GACF;EACD,UAAU;GACR,MAAM;GACN,QAAQ;GACT;EACD,MAAM;GACJ,MAAM;GACN,QAAQ;GACT;EACF,EACF;CACF;;;;ACzID,SAAgB,uCAEd,EACA,SACA,SACA,WACA,YAMC;CACD,MAAM,UAAU,wBAAwB;EACtC;EACA;EACD,CAAC;AACF,SAAQ,SAAR;EACE,KAAK,MACH,QAAO,QAAQ,UAAU,WAAW,EAAE,UAAU,CAAC;EACnD,KAAK,SACH,QAAO,QAAQ,aAAa,WAAW,EAAE,UAAU,CAAC;EACtD,KAAK,UACH,QAAO,QAAQ,cAAc,WAAW,EAAE,UAAU,CAAC;EACvD,KAAK,OACH,QAAO,QAAQ,MAAM;GACnB,MAAM;GACN,UAAU,YAAiB,QAAQ;GACnC;GACD,CAAC;EACJ,KAAK,WACH,QAAO,QAAQ,MAAM;GACnB,MAAM;GACN,UAAU,YAAiB,QAAQ;GACnC;GACD,CAAC;EACJ,KAAK,QACH,QAAO,QAAQ,YAAY,WAAW,EAAE,UAAU,CAAC;EACrD,KAAK,KACH,QAAO,QAAQ,SAAS,WAAW,EAAE,UAAU,CAAC;EAClD,KAAK,OACH,QAAO,QAAQ,MAAM;GACnB,MAAM;GACN,UAAU,YAAiB,QAAQ;GACnC;GACD,CAAC;EACJ,QACE,OAAM,IAAI,YACR,2BAA2B,QAAQ,cAAc,YAClD;;;;;;AC5CP,SAAgB,6BACd,QACA;CACA,MAAM,wBAAQ,IAAI,KAAgB;AAElC,MAAK,MAAM,SAAS,OAAO,OAAO,OAAO,CAAC,KAAK,MAAW,EAAE,MAAM,EAAE;AAClE,MAAI,OAAO,UAAU,SACnB;AAGF,MAAI,iBAAiBC,4BACnB,OAAM,IAAI,WAAW;WACZ,iBAAiBC,kCAC1B,OAAM,IAAI,QAAQ;WACT,iBAAiBC,oCAC1B,OAAM,IAAI,SAAS;;CAIvB,MAAM,WAAW,MAAM,KAAK,MAAM;AAElC,KAAI,SAAS,WAAW,EACtB,QAAO,SAAS;AAGlB,KAAI,SAAS,WAAW,EACtB,OAAM,IAAI,MAAM,yDAAyD;AAG3E,OAAM,IAAI,MAAM,sCAAsC,SAAS,KAAK,KAAK,GAAG;;AAG9E,SAAgB,aAEd,IAAyB;AAGzB,QAFgB,6BAA6B,GAAG,EAAE,UAAU,KAEzC;;;;;ACrCrB,eAAsB,uBACpB,OACA;AACA,KAAI,CAAC,aAAa,MAAM,GAAG,EAAE;AAC3B,UAAQ,KACN,gHACD;AACD;;AAGF,OAAM,MAAM,GAAG,QAAQ,eAAG,0CAA0C;AACpE,KAAI,MAAM,QAAQ,WAAW;EAE3B,MAAM,YAAY,OAAO,MAAM,OAAO,UAAU;AAEhD,MAAI,YAAY,KAAK,YAAY,EAC/B,OAAM,IAAI,MAAM,2CAA2C;EAI7D,MAAM,UADS,MAAM,MAAM,GAAG,QAAQ,eAAG,4BAA4B,EAC/C,KAAK,GAAG;AAE9B,QAAM,MAAM,GAAG,QACbC,gBAAI,IACF,kBAAkB,OAAO,sCAAsC,UAAU,GAC1E,CACF;;AAGH,KAAI,MAAM,QAAQ,mBAAmB;AACnC,MAAI,OAAO,MAAM,OAAO,sBAAsB,SAC5C,OAAM,IAAI,MAAM,qCAAqC;AAGvD,MAAI,MAAM,OAAO,qBAAqB,EACpC,OAAM,IAAI,MAAM,8CAA8C;;;;;;;AASpE,SAAgB,yBAAyB,EACvC,QACA,MACA,aACA,aAOC;AACD,KAAI,QAAQ,WAAW,KAAK,UAAU,KAAK,OAAO,SAAS,GAAG;EAK5D,MAAM,mBACJ,UAAU,MAAM,KAAK,UACjB,OAAO,QAAQ,YAAY,QAAQ,CAAC,QACjC,CAAC,SAAS,UAAU,MAAM,KAAK,QAAQ,KACzC,GACD,OAAO,QAAQ,YAAY,QAAQ,EACvC,QACC,CAAC,KAAK,SACL,0BAA0B,IAAI,YAAY,CAAC,IAC3C,sBAAsB,IAAI,YAAY,CAAC,CAC1C;EAED,MAAM,cAAc,eAAG,GAAG,KAAK;AAE/B,OAAK,SAAS,EACZ,kBAAkB,UAChB,eAAG,GAAGA,gBAAI,KACR,gBAAgB,KAAK,CAAC,SAAS;AAC7B,UAAO,eAAG,aAAa,MAAM,KAAK,aAAa,YAAY;IAC3D,EACFA,gBAAI,IAAI,MAAM,CACf,IACJ;EAED,MAAM,4CAA4B,KAAK,QAAQ;AAC/C,EAAC,KAAa,WAAW,UAAe;GACtC,MAAM,iBAAiBA,gBAAI,KACzB,OAAO,QAAQ,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;AAE1D,QAAI,UAAU,MACZ,QAAO,eAAG,GAAG,MAAM,KAAK;aACf,UAAU,OACnB,QAAO,eAAG,GAAG,MAAM,KAAK;QAExB,OAAM,IAAI,MAAM,iBAAiB,MAAM,cAAc;KAEvD,EACFA,gBAAI,IAAI,KAAK,CACd;GAED,MAAM,YAAY,eAAG;AAMrB,UAJY,kBACRA,gBAAI,KAAK,CAAC,gBAAgB,UAAU,EAAEA,gBAAI,IAAI,KAAK,CAAC,GACpD;;AAQN,EAAC,KAAa,QAAQ,EACpB,KAAK,2BAJyB,KAAK,MAAM,IAKtB,EAAE,EACnB,EACE,MAAM,UACJ,eAAG,IAAIA,gBAAI,KACT,gBAAgB,KAAK,CAAC,SAAS;AAC7B,UAAO,eAAG,GAAG,MAAM,KAAK,KAAK;IAC7B,EACFA,gBAAI,IAAI,OAAO,CAChB,CAAC,IACL,CACF,EACF;;;;;;ACrGL,MAAM,2BAA2B,MAAW;AAC1C,KAAI,OAAO,MAAM,SACf,QAAO;AAGT,KACE,OAAO,KAAK,EAAE,CAAC,MAAM,MACnB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,MAAM,MAAM,MAAM,EAAE,CACvB,CAED,QAAO;AACT,QAAO;;AAGT,MAAa,2BAgDX,EACA,IACA,QACA,eACA,oBACA,qBACA,qBACA,iBACA,qBAQI;AACJ,SAGE,EACA,OACA,SACA,aAAa,QACb,aAgCI;EACJ,MAAM,cAAc,YAAY;GAAE;GAAI;GAAO,CAAC;AAE9C,MAAI,OAAO,KAAK,YAAY,WAAW,CAAC,WAAW,EACjD,SAAQ,KACN,kCAAkC,MAAM,UAAU,CAAC,kCACpD;EAEH,MAAM,aAAa,OAAO,OAAO,YAAY,WAAW,CAAC;EAEzD,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,OAAO,CAAC;AAEnE,SAAO,cAAc,cAAc,OAAO;GACxC,MAAM,sCAAsB,MAAM,UAAU,CAAC;GAC7C,YAAY,eAAe,SAAS,aAAa;AAC/C,QAAI,CAAC,WAAY;IACjB,MAAM,kBAAmB,QAAgB,WAAW;AACpD,QAAI,CAAC,iBAAiB;AACpB,aAAQ,KACN,wCAAwC,KAAK,UAC3C,QACD,CAAC,iCACH;AACD;;AAIF,uBAAmB;KACjB,UAAU;KACV,QAAQ;KACS;KAClB,CAAC;;GAEJ,cAAc,gBAAgB,EAAE,kBAAkB;IAChD;IACA,QAAQ;IACT,CAAC;GACF,SAAS,MAAM;IACb,MAAM,UAAU,YAAY;IAS5B,MAAM,4BAAY,IAAI,KAOnB;IAIH,MAAM,kBACJ,SACE,IAAI,MAAM,GAAG,EACX,MAAM,QAAQ,MAAM,aAAa;AAC/B,SAEE,OAAQ,OAAe,UAAU,cACjC,SAAS,SACT,SAAS,aACT,SAAS,iBACT,SAAS,UACT,SAAS,aACT,SAAS,WACT,SAAS,cACT,SAAS,aACT,KAAK,UAAU,CAAC,WAAW,UAAU,IACrC,KAAK,UAAU,CAAC,WAAW,QAAQ,IACnC,KAAK,UAAU,CAAC,WAAW,KAAK,IAChC,KAAK,UAAU,CAAC,WAAW,MAAM,IACjC,KAAK,UAAU,CAAC,WAAW,SAAS,IACpC,KAAK,UAAU,CAAC,WAAW,SAAS,CAEpC,QAAQ,OAAe;AAGzB,aAAQ,GAAG,WAAkB;MAC3B,MAAM,MAAO,OAAe,MAAM,GAAG,OAAO;MAC5C,MAAM,eAAe,OAAO,KAAK,wBAAwB;AACzD,UAAI,CAAC,aACH,OAAM,IAAI,YACR,sDACD;AAEH,gBAAU,IAAI,KAAK;OACjB;OACA,iBAAkB,OAAe;OACjC;OACD,CAAC;AACF,aAAO;;OAGZ,CAAC,CACH,IAAI,EAAE;IAET,MAAM,SAAS,OAAO,QAAQ,QAAQ,CAAC,QACpC,KAAK,CAAC,KAAK,YAAY;AAItB,SAAI,gBAAgB,MAAM;MACxB,MAAM,EAAE,QAAQ,iBAAiB,iBAAiB,UAAU,IAC1D,gBAAgB,KACjB;AAED,UAAI,OAAO,aAAa,aAAa,UACnC,cAAa,WAAW,CAAC,OAAO;AAGlC,sBAAgB,OAAO,gBAAgB,KAAK,EAAE,CAAC,GAAG,OAAO;AACzD,aAAO;;AAGT,SAAI,aAAa,OAAO,EAAE;MACxB,MAAM,WAAW,gBAAgB,EAC/B,YAAY,QACb,CAAC;AAEF,UAAI,OAAO,EAAE,MAAM;OACjB,MAAM;OACN,UAAU,YAAa,QAAgB;OACvC,UAAU,CAAC,OAAO;OACnB,CAAC;WAEF,KAAI,OAAO,uCAAuC;MAChD,SAAS;MACT,SAAS,OAAO,YAAY;MAC5B,WAAW;MACX,UAAU,CAAC,OAAO;MACnB,CAAC;AAEJ,YAAO;OAET,EAAE,CAKH;IAED,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,EAAE,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;KACrB,MAAM,iBAAiB,YAAY;MACjC;MACA,OAAQ,MAAc;MACvB,CAAC;KACF,MAAM,WAAW,oBAAoB,EACnC,QAAQ,eAAe,QACxB,CAAC;KACF,MAAM,WAAW,oBAAoB,EACnC,QAAQ,eAAe,QACxB,CAAC;KACF,MAAM,sBAAsB,mBAAmB,EAC7C,OAAO,eAAe,QACvB,CAAC;KAGF,IAAI,WAAW;KACf,IAAI,SAAS;KACb,IAAI,kBAAkB;AACtB,SAAI,iBAAiBC,iBAAK;AACxB,eAAS;AACT,iBAAW,CAAC,MAAM,cAAc,OAAO,WAAW,OAAO,QAAQ;AACjE,wBAAkB;;KAGpB,MAAM,aAAa,eAAoB,aAAkB;AACvD,0BAAoB,mBAAmB;OACrC,UAAU;OACV,QAAQ;OACT,CAAC;AACF,0BAAoB,mBAAmB;OACrC,UAAU;OACV,QAAQ;OACT,CAAC;;AAMJ,SAAI,gBAAgB,MAAM;MACxB,MAAM,EAAE,QAAQ,iBAAiB,iBAAiB,UAAU,IAC1D,gBAAgB,KACjB;AAED,UAAI,OAAO,aAAa,aAAa,UACnC,cAAa,WAAW;AAG1B,UAAI,OAAO,aAAa,cAAc,WACpC,cAAa,YAAY;AAG3B,sBAAgB,OAAO,gBAAgB,KAAK,EAAE,CAAC,GAAG,OAAO;AACzD,aAAO;;KAGT,MAAM,OAAO;MACX,OAAO,EAAE,IAAI;OAAE,MAAM;OAAU,UAAU;OAAO,CAAC;MACjD,SAAS,EAAE,IAAI;OAAE,MAAM;OAAU,UAAU;OAAO,CAAC;MACnD,GAAI,SACA;OACE,QAAQ,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;OACtC,OAAO,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;OACtC,GACD,EAAE;MACN,QAAQ,EAAE,IAAI,OAAO,EAAE,UAAU,OAAO,CAAC;MAC1C;AAED,SAAI,CAAC,QAAQ,WAAW,CAAC,OACvB,QAAQ,KAAa;AAGvB,KAAC,IAAY,OAAO,EAAE,SACpB,KACA;MACE;MACA;MACA;MACA,aAAa,WAAW,kBAAU,OAAO,eAAe,OAAO,CAAC,mBAAmB,kBAAU,SAAS,YAAY,OAAO;MACzH,QAAQ,MAAW,QAAa;AAE9B,cAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AAEvC,WAAI,OACF,0BAAyB;QACvB;QACA;QACA,aAAa;QACb,WACE,IAAI,UAAU,eAAe,QAAQ,OAAO,WAAW;QAC1D,CAAC;OAGJ,MAAM,SAAS,IAAI,UAAU,eAAe,QACzC,OAAO,WAAW,CAClB,MAAM;QACL,OAAO,KAAK;QACZ,OAAO,KAAK;QACZ,QAAQ,KAAK;QACd,CAAC,CAAC,MAAM;AAEX,WAAI,KAAK,OACP,CAAC,OAAe,SAAS,KAAK;AAGhC,WAAI,KAAK,QACP,CAAC,OAAe,UAAU,KAAK;AAGjC,cAAO;;MAEV,CACF;AACD,YAAO;OAET,EAAE,CAIH;AAED,QAAI,QAAQ,SAAS;AACnB,SAAI,OAAO,gBACT,OAAM,IAAI,MACR,oDACE,YAAY,SACZ,6GACH;AAGH,YAAO,kBAAkB,EAAE,MAAM;MAC/B,aACE;MACF,UAAU;MACV,UAAU,QAAQ,MAAM,KAAK,SAC1B,OAAe;MACnB,CAAC;;AAGJ,WAAO;KACL,GAAG;KACH,GAAG;KACH,GAAG;KACJ;;GAEJ,CAAC;;;;;;AC1bN,MAAM,sCAAsC;AAC5C,MAAM,gCAAgC;AACtC,MAAM,gCAAgC;AACtC,MAAM,gCAAgC;AAkBtC,MAAa,wBAMX,EACA,oBACsE;CACtE,MAAM,SAAS,+CACE,GAAG,cAAc,mCAChB;CAElB,MAAM,sBAEJ,EACA,YAGI;EAGJ,SAAS,cAAc,EACrB,QACA,WACA,mBAKC;GACD,IAAI;AAEJ,WAAQ,QAAR;IACE,KAAK;AACH,iBAAY;AACZ;IACF,KAAK;AACH,iBAAY;AACZ;IACF,KAAK;AACH,iBAAY;AACZ;IACF,QACE,OAAM,IAAI,MAAM,mBAAmB,SAAS;;AAGhD,UAAO,GAAG,oCAAoC,GAAG,YAC/C,kBAAkB,IAAI,oBAAoB,GAC3C,GAAG;;AAIN,SAAO;GAIL,mBAAmB,EACjB,UACA,QACA,mBAKC;IACD,MAAM,MAAM,cAAc;KACxB,WAAW,MAAM,UAAU;KAC3B;KACA;KACD,CAAC;AACF,aAAS,SAAS,IAAI;;GAKxB,UAAU;IACR,MAAM,MAAM,cAAc;KACxB,WAAW,MAAM,UAAU;KAC3B,QAAQ;KACT,CAAC;AACF,WAAO,OAAO,QAAQ,IAAI;;GAM5B,UAAU;IACR,MAAM,MAAM,cAAc;KACxB,WAAW,MAAM,UAAU;KAC3B,QAAQ;KAGT,CAAC;AACF,WAAO,OAAO,QAAQ,IAAI;;GAK5B,QAAQ,iBAAqD;IAI3D,MAAM,QAHc,MAAM,QAAQ,gBAAgB,GAC9C,kBACA,CAAC,gBAAgB,EACI,KAAK,oBAC5B,cAAc;KACZ,WAAW,MAAM,UAAU;KAC3B,QAAQ;KACR;KACD,CAAC,CACH;IACD,MAAM,aAAa,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC;AAC5C,SAAK,MAAM,OAAO,WAChB,QAAO,QAAQ,IAAI;;GAGxB;;AAGH,QAAO;EACL;EACA;EACD;;;;;ACrIH,MAAa,0BAkCX,EACA,IACA,eACA,QACA,qBACA,qBACA,yBAMI;AACJ,SAA0D,EACxD,OACA,aAAa,QACb,aAAa,aAgBT;EACJ,MAAM,WAAW,oBAAoB,EAC5B,OACR,CAAC;EACF,MAAM,WAAW,oBAAoB,EAC5B,OACR,CAAC;EACF,MAAM,cAAc,YAAY;GAC9B;GACA;GACD,CAAC;EACF,MAAM,kBAAkB,OAAO,OAAO,YAAY,WAAW,CAAC;EAE9D,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,OAAO,CAAC;AAEnE,SAAO,cAAc,aAAa,MAAM;GACtC,MAAM,WAAW;IACf,OAAO,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;KAAO,CAAC;IACjD,SAAS,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;KAAO,CAAC;IACnD,OAAO,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;IACrC,QAAQ,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;IACtC,QAAQ,EAAE,IAAI,OAAO,EAAE,UAAU,OAAO,CAAC;IAC1C;AAED,OAAI,CAAC,QAAQ,QACX,QAAQ,SAAiB;AAG3B,UAAO;KACJ,kBAAU,OAAO,MAAM,UAAU,CAAC,GAAG,EAAE,aAAa;KACnD,MAAM,CAAC,MAAM;KACb,UAAU;KACV,mBAAmB;KACnB,aAAa,YAAY,kBAAU,OAAO,MAAM,UAAU,CAAC;KAC3D,YAAY,eAAe,OAAO,OAAO,MAAM,UAAU;AACvD,yBAAmB;OACjB,UAAU;OACV,QAAQ;OACT,CAAC;AACF,yBAAmB;OACjB,UAAU;OACV,QAAQ;OACT,CAAC;;KAEJ,MAAM;KACN,UAAU,OAAO,OAAO,MAAM,KAAK,UAAU;AAG3C,mBAAa,KAAK;AAElB,+BAAyB;OACvB;OACA;OACA;OACA,WAAW,IAAI,UAAU,OAAO,OAAO,WAAW;OACnD,CAAC;MAEF,MAAM,aAAa,yBAAyB,KAAK;MACjD,MAAM,SAAS,IAAI,UAAU,OAC1B,OAAO,WAAW,CAClB,MAAM,WAAkB,CAAC,MAAM;AAElC,UAAI,WAAW,OACb,CAAC,OAAe,SAAS,WAAW;AAGtC,UAAI,WAAW,QACb,CAAC,OAAe,UAAU,WAAW;MAGvC,MAAM,gBAAgB,MAAM,OAAc;AAE1C,UAAK,OAAe,QAClB,eAAc,UAAW,OAAe;AAG1C,UACE,QAAQ,WACR,KAAK,UACL,KAAK,OAAO,SAAS,KACrB,QAAQ,kBAER,QAAO,GAAG,YAAY,OAAO,OAAO;AAClC,WAAI,aAAa,GAAG,CAClB,OAAM,GAAG,QACPC,gBAAI,IACF,2BAA2B,OAAO,kBAAkB,GACrD,CACF;WAED,SAAQ,KACN,oEACD;AAEH,cAAQ,GAAG,MAAc,OAAO,SAAS,cAAc;QACvD;AAGJ,aAAQ,GAAG,MAAc,OAAO,SAAS,cAAc;;KAE1D,CAAC;KACD,kBAAU,SAAS,MAAM,UAAU,CAAC,GAAG,EAAE,aAAa;KACrD,MAAM;KACN,UAAU;KACV,mBAAmB;KACnB,aAAa,gBAAgB,kBAAU,SAAS,MAAM,UAAU,CAAC,CAAC;KAClE,MAAM,EACJ,IAAI,EAAE,IAAI,GAAG,EAAE,UAAU,MAAM,CAAC,EACjC;KACD,UAAU,OAAO,OAAO,MAAM,KAAK,UAAU;AAC3C,mBAAa,KAAK;MAElB,MAAM,SAAU,IAAI,UAAkB,OACnC,OAAO,WAAW,CAClB,MAAM,EAAE,OAAO,GAAG,gBAAgB,OAAO,KAAK,IAAI,EAAE,CAAC,CACrD,MAAM;MACT,MAAM,IAAI,MAAM,OAAO;AAEvB,UAAI,OAAO,QACT,GAAE,UAAU,OAAO;AAGrB,aAAQ,GAAG,MAAc,OACtB,UAAU,EAAE,CACZ,KAAK,sBAAsB;;KAEjC,CAAC;IACH;IACD;;;;;;AChJN,SAAgB,+BAA+B,eAAoB;CACjE,MAAM,wBAAwB,cAC3B,SAAS,wBAAwB,CACjC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,KAAK;EACX,IAAI,EAAE,KAAK;EACX,IAAI,EAAE,KAAK;EACX,KAAK,EAAE,KAAK;EACZ,IAAI,EAAE,KAAK;EACX,KAAK,EAAE,KAAK;EACZ,IAAI,EAAE,SAAS;EACf,OAAO,EAAE,SAAS;EAClB,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,SAAS;EAC1B,gBAAgB,EAAE,SAAS;EAC3B,eAAe,EAAE,SAAS;EAC1B,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,sBAAsB,EAC9B,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,sBAAsB,EAC9B,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,uBACP,CAAC;EACH,GACF,CAAC;CAEJ,MAAM,0BAA0B,cAC7B,SAAS,0BAA0B,CACnC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,OAAO;EACb,IAAI,EAAE,OAAO;EACb,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,OAAO;EACd,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,OAAO;EACd,IAAI,EAAE,WAAW;EACjB,OAAO,EAAE,WAAW;EACpB,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,WAAW;EAC5B,gBAAgB,EAAE,WAAW;EAC7B,eAAe,EAAE,WAAW;EAC5B,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,wBAAwB,EAChC,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,wBAAwB,EAChC,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,yBACP,CAAC;EACH,GACF,CAAC;CAEJ,MAAM,2BAA2B,cAC9B,SAAS,2BAA2B,CACpC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,QAAQ;EACd,IAAI,EAAE,QAAQ;EACd,IAAI,EAAE,QAAQ;EACd,KAAK,EAAE,QAAQ;EACf,IAAI,EAAE,QAAQ;EACd,KAAK,EAAE,QAAQ;EACf,IAAI,EAAE,YAAY;EAClB,OAAO,EAAE,YAAY;EACrB,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,YAAY;EAC7B,gBAAgB,EAAE,YAAY;EAC9B,eAAe,EAAE,YAAY;EAC7B,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,yBAAyB,EACjC,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,yBAAyB,EACjC,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,0BACP,CAAC;EACH,GACF,CAAC;CAEJ,MAAM,yBAAyB,cAC5B,SAAS,yBAAyB,CAClC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC9B,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC9B,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAClC,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC1C,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC3C,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC1C,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,uBAAuB,EAC/B,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,uBAAuB,EAC/B,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,wBACP,CAAC;EACH,GACF,CAAC;;;;;AChMN,MAAa,aAAa;;;;;;;;;;;;;;;;;ACK1B,MAAa,eAAe,OAAgC,EAC1D,SACA,UACA,cAKI;AACJ,QAAO,MAAM,MAET,MAAM,QAAQ,IACZ,QAAQ,KAAK,MACX,EAAE;EACA;EACU;EACX,CAAC,CACH,CACF,EACD,QAAQ,KAAK,QAAQ;AACrB,OAAK,MAAM,WAAW,IACpB,KAAI,IAAI,QAAQ;AAElB,SAAO;oBAEN,IAAI,KAAQ,CAAC,CACjB;;;;;AC9BH,MAAa,kBAAkB;AAE/B,IAAa,uBAAb,cAEUC,wBAAkB;CAC1B,AAAQ;CACR,AAAQ;CAER,AAAS,aAAa,YAA8B;AAClD,OAAK,SAAS,KAAK,QAAQ,QAAQ,MAAM;AACzC,OAAK,gBAAgB,KAAK,QAAQ,QAAQ,MAAM;AAChD,SAAO;;CAGT,AAAS,YACP,UACA,aACyD;AACzD,SAAO,OAAO,QAAQ,MAAM,SAAS,SAAS;GAE5C,IAAI;GACJ,MAAM,YAAY,aAAa;AAE/B,OAAI,UAAU,SAAS,OACrB,WACE,UAAU,MAAM,IAAI,cAAc,cAAc;YACzC,UAAU,SAAS,SAC5B,WAAU,UAAU,IAAI,cAAc,cAAc;AAGtD,OAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,QAAQ,IAAI,QAAQ,WAAW,EAE5D,QAAO,SAAS,QAAQ,MAAM,SAAS,KAAK;GAG9C,MAAM,aAAa,OAAO,SAAgB;IACxC,MAAM,WAAW,MAAM,SAAS,QAAQ,MAAM,SAAS,KAAK;IAC5D,MAAM,oBAAoB,MAAM,QAAQ,SAAS,GAC7C,WACA,CAAC,SAAS;IACd,MAAM,aAAa,MAAM,QAAQ,QAAQ,GAAG,UAAU,CAAC,QAAQ;AAC/D,UAAM,aAAa,iBAAiB,WAAW,OAAO;IAEtD,MAAM,UAAU,MAAM,aAAa;KACjC,SAAS;KACT,UAAU;KACV;KACD,CAAC;AACF,UAAM,aAAa,mBAAmB,QAAQ,OAAO;AAGrD,QAAI,MAAM,QAAQ,SAAS,CACzB,QAAO;AAKT,WAAO,QAAQ,MAAM;;AAGvB,OAAI,KAAK,UAAU,KAAK,cACtB,QAAO,KAAK,OAAO,gBACjB,iBAAiB,YAAY,QAC7B,OAAO,SAAS;AACd,QAAI;AACF,YAAO,MAAM,WAAW,KAAK;cACrB;AACR,UAAK,KAAK;;KAGf;OAED,QAAO,YAAY;;;;AAM3B,IAAI,aAAa;AACjB,SAAgB,+BAA+B;AAC7C,KAAI,CAAC,YAAY;AACf,uBAAc,eAAe,YAAY,qBAAqB;AAC9D,eAAa;;;;;;ACjEjB,MAAa,uBAMX,EACA,IACA,uBACA,QACA,cACA,WAGI;CACJ,MAAM,aACJ,MAAM,WAAW,KAAK,uEACS,KAAK,QAAQ,KAAK,QAAQ,GACrD;AAEN,+BAA8B;CAC9B,MAAM,gBAAgB,IAAIC,qBAwBvB;EACD,GAAG;EACH,SAAS;GACP;GACAC;GACAC;GACAC;GACA,GAAI,cAAc,WAAW,EAAE;GAChC;EACD,SAAS;GACP,QAAQ;GACR,WAAW,GAAG,EAAE;GAChB,eAAe,OAAO;AAEpB,WAAO;KACL,SAAS,OAAO,OAAQ,MAAc,OAAO,IAAI,kBAAkB,EAAE;KACrE,aAAa,OAAO,OACjB,MAAc,OAAO,IAAI,kBAAkB,EAC7C,CAAC,QAAQ,MAAW,EAAE,QAAQ;KAChC;;GAEJ;EACD,oBAAoB,EAClB,yEAAiC,MAAM,aAAa;AAClD,UAAO,OAAO,UAAU,KAAK;IAC7B,EACH;EACD,yBAAyB;EACzB,SAAS;GACP,SAAS,MAAM,WAAW,mDAAuB,OAAO,SAAS;GACjE,MAAM,cACD,UAAU,YAAY,WAAW,UAAU,QAAQ,IACnD,aAAa;GACnB;EACD;EACD,CAAC;AAEF,eAAc,cAAc,QAAQC,6BAAa;AACjD,eAAc,cAAc,QAAQC,6BAAa;AACjD,eAAc,cAAc,YAAYC,oCAAoB;AAC5D,gCAA+B,cAAc;AAE7C,KAAI,CAAC,uBAAuB,MAC1B,eAAc,UAAU,EAAE,CAAC;AAG7B,KAAI,CAAC,uBAAuB,aAC1B,eAAc,iBAAiB,EAAE,CAAC;AAGpC,KAAI,CAAC,uBAAuB,SAC1B,eAAc,aAAa,EAAE,CAAC;AAGhC,QAAO,EAAE,eAAe;;;;;AC9F1B,MAAa,UAOX,gBACG;AACH,KAAI,CAAC,YAAY,GAAG,EAAE,OACpB,OAAM,IAAI,YAAY;;;;;;;;;;;;EAYxB;AAGA,KAAI,CAAC,YAAY,GAAG,EAAE,UACpB,OAAM,IAAI,YAAY;;;;;;;;;;;;EAYxB;AAIA,KAAI,CAAC,YAAY,QACf,aAAY,UAAU;EAAC;EAAQ;EAAU;EAAS;AAGpD,KAAI,YAAY,iBAAiB,OAC/B,aAAY,eAAe;AAG7B,KAAI,YAAY,QAAQ,QACtB,wBAAuB,YAAY;AAGrC,KAAI,YAAY,MAAM,WAAW,CAAC,YAAY,KAAK,OACjD,aAAY,KAAK,SAASC,yBAAM,UAC9B,kBACAC,QACD;CAGH,MAAM,iBAAiB,qBAMrB,YAAY;CAEd,MAAM,UAAU,sBAOd;EACA,GAAG;EACH;EACD,CAAC;CAEF,MAAM,EAAE,oBAAoB,WAAW,qBAMrC,EACA,GAAG,aACJ,CAAC;CAEF,MAAM,EAAE,kBAAkB,oBAMxB;EAAE,GAAG;EAAa;EAAQ,CAAC;CAE7B,MAAM,QAAQ,sBAOZ;EACA,GAAG;EACH;EACD,CAAC;CAEF,MAAM,WAAW,0BAQf;EACA,GAAG;EACH;EACA,iBAAiB;EAClB,CAAC;CAEF,MAAM,WAAW,0BAOf;EACA,GAAG;EACH;EACD,CAAC;CAEF,MAAM,SAAS,wBAYb;EACA,GAAG;EACH;EACA;EACA,qBAAqB;EACrB,qBAAqB;EACrB,iBAAiB;EACjB;EACD,CAAC;CAEF,MAAM,QAAQ,uBAUZ;EACA,GAAG;EACH;EACA,qBAAqB;EACrB,qBAAqB;EACrB;EACD,CAAC;CAEF,MAAM,aAAa,4BAA4B;EAC7C,GAAG;EACH;EACA,qBAAqB;EACrB;EACD,CAAC;CAEF,MAAM,cAAcC,wBAAW,cAAc,UAAU,CAAC;CAExD,MAAM,cACJ,SAWG;EACH,MAAM,gBACJ,MAAM,iBAAiB,SAAS,KAAK,aAAa;AAEpD,sCAAsC;GACpC,GAAG;GACH,UAAU;GACV,SAAS;IACP,GAAI,MAAM,WAAW,EAAE;IACvB,GAAI,gBACA,EAAE,GACF,0EAA0B,sDAAsB,CAAC;IACrD,YAAY,MAAM,UACb,EACC,YAAY,EAAE,cAAc,gBAAgB;AAC1C,mBAAc,YACZ,YAAY,KAAM,OAAQ,gBACxBC,wCAAU,SACV,EACE,YAAY,GACTC,6CAAe,iBACd,QAAQ,iBAAiB,aAG5B,EACF,EACD,OAAO,SAAS;AACd,UAAI;AAGF,cAFe,MAAM,UAAU,QAAQ;eAGhC,OAAO;AACd,WAAI,iBAAiB,MACnB,MAAK,gBAAgB,MAAM;AAE7B,YAAK,UAAU,EAAE,MAAMC,kCAAe,OAAO,CAAC;AAC9C,aAAM;gBACE;AACR,YAAK,KAAK;;OAGf,CACF;OAEJ,GACD;IACL,CAAC,OAAO,QAAQ;GACjB,QAAQ,aAAa;GACrB;GACD,CAAC;;CAGJ,MAAM,cACJ,SACG;AACH,MAAI,KAAK,QACP,uBAAM,KAAK,SAAS,uBAAuB;AAE7C,+BAAe;GACb,GAAG;GACH,QAAQ,aAAa;GACrB;GACD,CAAC;;AAeJ,QAAO;EAiBL;EAIA;EAeA;EAcA;EAIA;EAIA;EAIA;EAKA;EAIA,QAAQ;EAMR;EAKA,eA9FoB,yBAOpB;GACA,GAAG;GACH;GACD,CAAC;EAwFA;EACD"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["GraphQLError","lazy","makeDefaultName","lazy","PgEnumColumn","generateFromSchema","lazy","PgTable","MySqlTable","SQLiteTable","sql","One","sql","BasePlugin","SchemaBuilder","DrizzlePlugin","SmartSubscriptionsPlugin","TracingPlugin","JSONResolver","DateResolver","DateTimeISOResolver","trace","packagejson.version","lazy","SpanNames","AttributeNames","SpanStatusCode"],"sources":["../lib/types/rumbleError.ts","../lib/helpers/asserts.ts","../lib/helpers/mapNullFieldsToUndefined.ts","../package.json","../lib/helpers/mergeFilters.ts","../lib/helpers/sqlTypes/types.ts","../lib/helpers/sqlTypes/distinctValuesFromSQLType.ts","../lib/helpers/tableHelpers.ts","../lib/abilityBuilder.ts","../lib/args/orderArg.ts","../lib/enum.ts","../lib/helpers/sqlTypes/mapSQLTypeToTSType.ts","../lib/args/whereArg.ts","../lib/client/client.ts","../lib/context.ts","../lib/helpers/protoMapper.ts","../lib/countQuery.ts","../lib/helpers/sofaOpenAPIWebhookDocs.ts","../lib/helpers/sqlTypes/mapDrizzleTypeToGraphQlType.ts","../lib/helpers/determineDialectFromSchema.ts","../lib/search.ts","../lib/object.ts","../lib/pubsub.ts","../lib/query.ts","../lib/args/whereArgsImplementer.ts","../lib/runtimeFiltersPlugin/filterTypes.ts","../lib/helpers/applyFilters.ts","../lib/runtimeFiltersPlugin/runtimeFiltersPlugin.ts","../lib/schemaBuilder.ts","../lib/rumble.ts"],"sourcesContent":["import { GraphQLError } from \"graphql\";\n/**\n * An error that gets raised by rumble whenever something does not go according to plan.\n * Mostly internals, configuration errors or other unexpected things.\n */\nexport class RumbleError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"RumbleError\";\n }\n}\n\n/**\n * An error that gets raised by rumble whenever an error occurs in a resolver, containing\n * information safely exposeable to the user.\n * E.g. the assert helpers issue these.\n */\nexport class RumbleErrorSafe extends GraphQLError {}\n","import { RumbleErrorSafe } from \"../types/rumbleError\";\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n * schemaBuilder.queryFields((t) => {\n return {\n findFirstUser: t.drizzleField({\n type: UserRef,\n resolve: (query, root, args, ctx, info) => {\n return (\n db.query.users\n .findFirst({\n ...query,\n where: ctx.abilities.users.filter(\"read\").single.where,\n })\n // note that we need to manually raise an error if the value is not found\n .then(assertFindFirstExists)\n );\n },\n }),\n };\n });\n * ```\n */\nexport const assertFindFirstExists = <T>(value: T | undefined): T => {\n if (!value) {\n throw new RumbleErrorSafe(\"Value not found but required (findFirst)\");\n }\n return value;\n};\n\n/**\n *\n * Helper function to map a drizzle findFirst query result,\n * which may be optional, to a correct drizzle type.\n *\n * @throws RumbleError\n *\n * @example\n *\n * ```ts\n schemaBuilder.mutationFields((t) => {\n return {\n updateUsername: t.drizzleField({\n type: UserRef,\n args: {\n userId: t.arg.int({ required: true }),\n newName: t.arg.string({ required: true }),\n },\n resolve: (query, root, args, ctx, info) => {\n return db\n .update(schema.users)\n .set({\n name: args.newName,\n })\n .where(\n and(\n eq(schema.users.id, args.userId),\n ctx.abilities.users.filter(\"update\").single.where\n )\n )\n .returning({ id: schema.users.id, name: schema.users.name })\n // note that we need to manually raise an error if the value is not found\n .then(assertFirstEntryExists);\n },\n }),\n };\n });\n * ```\n */\nexport const assertFirstEntryExists = <T>(value: T[]): T => {\n const v = value.at(0);\n if (!v)\n throw new RumbleErrorSafe(\"Value not found but required (firstEntry)\");\n return v;\n};\n","/**\n * Helper to map null fields to undefined\n * @param obj The object to map\n * @returns The mapped object with all fields of 'null' transformed to 'undefined'\n * \n * This becomes useful for update mutations where you do not want to pass null (unset value in db)\n * but undefined (do not touch value in db) in case of a value not beeing set in the args of said mutation\n * @example\n * ```ts\n * updateUser: t.drizzleField({\n type: User,\n args: {\n id: t.arg.string({ required: true }),\n email: t.arg.string(),\n lastName: t.arg.string(),\n firstName: t.arg.string(),\n },\n resolve: async (query, root, args, ctx, info) => {\n const mappedArgs = mapNullFieldsToUndefined(args);\n const user = await db.transaction(async (tx) => {\n const user = await tx\n .update(schema.user)\n .set({\n\n // email: args.email ?? undefined,\n // lastName: args.lastName ?? undefined,\n // firstName: args.firstName ?? undefined,\n\n // becomes this\n\n email: mappedArgs.email,\n lastName: mappedArgs.lastName,\n firstName: mappedArgs.firstName,\n })\n .returning()\n .then(assertFirstEntryExists);\n return user;\n });\n\n pubsub.updated(user.id);\n\n return db.query.user\n .findFirst(\n query(\n ctx.abilities.user.filter('read').merge(\n {\n where: { id: user.id },\n }\n 1).query.single,\n ),\n )\n .then(assertFindFirstExists);\n },\n }),\n * \n * \n * ```\n */\nexport function mapNullFieldsToUndefined<T extends object>(obj: T) {\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) => [\n key,\n value === null ? undefined : value,\n ]),\n ) as {\n [K in keyof T]: T[K] extends null ? undefined : Exclude<T[K], null>;\n };\n}\n","","import { toMerged } from \"es-toolkit\";\n\nexport function mergeFilters<\n FilterA extends Record<string, any>,\n FilterB extends Record<string, any>,\n>(filterA?: Partial<FilterA>, filterB?: Partial<FilterB>) {\n const where =\n filterA?.where && filterB?.where\n ? { AND: [filterA?.where, filterB?.where] }\n : (filterA?.where ?? filterB?.where);\n\n const columns =\n filterA?.columns || filterB?.columns\n ? new Set(\n [\n Object.entries(filterA?.columns ?? {}),\n Object.entries(filterB?.columns ?? {}),\n ]\n .flat()\n .filter(([, v]) => v === true)\n .map(([k]) => k),\n )\n .entries()\n .reduce(\n (acc, [key]) => {\n acc[key] = true;\n return acc;\n },\n {} as Record<string, true>,\n )\n : undefined;\n\n const extras =\n filterA?.extras || filterB?.extras\n ? toMerged(filterA?.extras ?? {}, filterB?.extras ?? {})\n : undefined;\n\n const orderBy =\n filterA?.orderBy || filterB?.orderBy\n ? toMerged(filterA?.orderBy ?? {}, filterB?.orderBy ?? {})\n : undefined;\n\n const limit =\n filterA?.limit || filterB?.limit\n ? Math.min(filterA?.limit ?? Infinity, filterB?.limit ?? Infinity)\n : undefined;\n\n const offset =\n filterA?.offset || filterB?.offset\n ? Math.min(filterA?.offset ?? Infinity, filterB?.offset ?? Infinity)\n : undefined;\n\n const with_ =\n filterA?.with || filterB?.with\n ? toMerged(filterA?.with ?? {}, filterB?.with ?? {})\n : undefined;\n\n return {\n where,\n columns,\n extras,\n orderBy,\n limit,\n offset,\n with: with_,\n } as unknown as FilterA & FilterB;\n}\n","import { RumbleError } from \"../../types/rumbleError\";\n\nconst intLikeSQLTypeStrings = [\n \"serial\",\n \"int\",\n \"integer\",\n \"tinyint\",\n \"smallint\",\n \"mediumint\",\n] as const;\n\nexport function isIntLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof intLikeSQLTypeStrings)[number] {\n return intLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst floatLikeSQLTypeStrings = [\n \"real\",\n \"decimal\",\n \"double\",\n \"float\",\n \"numeric\",\n] as const;\n\nexport function isFloatLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof floatLikeSQLTypeStrings)[number] {\n return floatLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst stringLikeSQLTypeStrings = [\n \"string\",\n \"text\",\n \"varchar\",\n \"char\",\n \"text(256)\",\n] as const;\n\nexport function isStringLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof stringLikeSQLTypeStrings)[number] {\n return stringLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst IDLikeSQLTypeStrings = [\"uuid\"] as const;\n\nexport function isIDLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof IDLikeSQLTypeStrings)[number] {\n return IDLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst booleanSQLTypeStrings = [\"boolean\"] as const;\n\nexport function isBooleanSQLTypeString(\n sqlType: string,\n): sqlType is (typeof booleanSQLTypeStrings)[number] {\n return booleanSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateTimeLikeSQLTypeStrings = [\"timestamp\", \"datetime\"] as const;\n\nexport function isDateTimeLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof dateTimeLikeSQLTypeStrings)[number] {\n return dateTimeLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst dateLikeSQLTypeStrings = [\"date\"] as const;\n\nexport function isDateLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof dateLikeSQLTypeStrings)[number] {\n return dateLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst jsonLikeSQLTypeStrings = [\"json\", \"jsonb\"] as const;\n\nexport function isJSONLikeSQLTypeString(\n sqlType: string,\n): sqlType is (typeof jsonLikeSQLTypeStrings)[number] {\n return jsonLikeSQLTypeStrings.includes(sqlType as any);\n}\n\nconst possibleSQLTypesStrings = [\n ...intLikeSQLTypeStrings,\n ...floatLikeSQLTypeStrings,\n ...stringLikeSQLTypeStrings,\n ...IDLikeSQLTypeStrings,\n ...booleanSQLTypeStrings,\n ...dateTimeLikeSQLTypeStrings,\n ...dateLikeSQLTypeStrings,\n ...jsonLikeSQLTypeStrings,\n] as const;\n\nexport type PossibleSQLType = (typeof possibleSQLTypesStrings)[number];\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 type { Column, Many, One } from \"drizzle-orm\";\nimport type { drizzle } from \"drizzle-orm/node-postgres\";\nimport type {\n DrizzleInstance,\n DrizzleTableSchema,\n} from \"../types/drizzleInstanceType\";\nimport { RumbleError } from \"../types/rumbleError\";\n\nconst drizzleNameSymbol = Symbol.for(\"drizzle:Name\");\nconst drizzleOriginalNameSymbol = Symbol.for(\"drizzle:OriginalName\");\nconst drizzleBaseNameSymbol = Symbol.for(\"drizzle:BaseName\");\n\nexport function tableHelper<\n DB extends DrizzleInstance,\n TableIdentifier extends\n | DrizzleTableSchema<DB>[\"tsName\"]\n | DrizzleTableSchema<DB>[\"dbName\"]\n | DrizzleTableSchema<DB>,\n>({ db, table }: { db: DB; table: TableIdentifier }) {\n if (typeof table !== \"string\") {\n table =\n table.tsName ||\n table.dbName ||\n table[drizzleNameSymbol] ||\n table[drizzleOriginalNameSymbol] ||\n table[drizzleBaseNameSymbol];\n }\n\n const foundRelation: any = Object.values(db._.relations!).find(\n (schema: any) =>\n schema.name === table ||\n schema.table[drizzleNameSymbol] === table ||\n schema.table[drizzleOriginalNameSymbol] === table ||\n schema.table[drizzleBaseNameSymbol] === table,\n );\n\n if (!foundRelation) {\n throw new RumbleError(`Could not find schema for ${JSON.stringify(table)}`);\n }\n\n const foundSchema = Object.values(\n (db as ReturnType<typeof drizzle<any, any, any>>)._.schema!,\n ).find(\n (schema) =>\n schema.dbName === foundRelation.table[drizzleOriginalNameSymbol],\n );\n\n if (!foundSchema) {\n throw new RumbleError(`Could not find schema for ${JSON.stringify(table)}`);\n }\n\n const fullSchema = db._.fullSchema?.[foundSchema.tsName!];\n\n if (!fullSchema) {\n throw new RumbleError(\n `Could not find full schema for ${JSON.stringify(table)}`,\n );\n }\n\n return {\n columns: foundSchema.columns as Record<string, Column>,\n primaryKey: foundSchema.primaryKey,\n relations: (foundRelation as any).relations as {\n [key: string]: One<any, any> | Many<any>;\n },\n dbName: foundSchema.dbName,\n tsName: foundSchema.tsName,\n foundSchema,\n foundRelation,\n fullSchema,\n };\n}\n","import type { Span } from \"@opentelemetry/api\";\nimport { relationsFilterToSQL } from \"drizzle-orm\";\nimport { debounce } from \"es-toolkit\";\nimport { lazy } from \"./helpers/lazy\";\nimport { mergeFilters } from \"./helpers/mergeFilters\";\nimport { createDistinctValuesFromSQLType } from \"./helpers/sqlTypes/distinctValuesFromSQLType\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { Filter } from \"./runtimeFiltersPlugin/filterTypes\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleQueryFunctionInput,\n DrizzleTableValueType,\n} from \"./types/drizzleInstanceType\";\nimport { RumbleError } from \"./types/rumbleError\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\n//TODO: optimize this for v8 & refactor\n\nexport type AbilityBuilderType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>;\n\n/**\n * Static, non changing query filter input type for a specific table\n */\ntype StaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n> = Filter;\n\n/**\n * Dynamic, context based query filter input type for a specific table\n */\ntype DynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> = (\n context: Context,\n) => StaticQueryFilter<DB, Table, Filter> | undefined | \"allow\";\n\n/**\n * Combined query filter type for a specific table. May be static or dynamic.\n */\ntype QueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n> =\n | StaticQueryFilter<DB, Table, Filter>\n | DynamicQueryFilter<DB, Table, Filter, Context>;\n\nfunction isDynamicQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is DynamicQueryFilter<DB, Table, Filter, Context> {\n return (\n typeof filter === \"function\" && filter.constructor.name !== \"AsyncFunction\"\n );\n}\n\nfunction isStaticQueryFilter<\n DB extends DrizzleInstance,\n Table extends keyof DrizzleQueryFunction<DB>,\n Filter extends DrizzleQueryFunctionInput<DB, Table>,\n Context,\n>(\n filter: QueryFilter<DB, Table, Filter, Context>,\n): filter is StaticQueryFilter<DB, Table, Filter> {\n return typeof filter !== \"function\";\n}\n\nconst nothingRegisteredWarningLogger = debounce(\n (model: string, action: string) => {\n console.warn(`\nWarning! No abilities have been registered for\n\n ${model}/${action}\n\nbut has been accessed. This will block everything. If this is intended, you can ignore this warning. If not, please ensure that you register the ability in your ability builder.\n`);\n },\n 1000,\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}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n type TableNames = keyof DrizzleQueryFunction<DB>;\n\n let hasBeenBuilt = false;\n\n const createBuilderForTable = <TableName extends TableNames>() => {\n const queryFilters = new Map<\n Action,\n | QueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[]\n | \"unrestricted\"\n >();\n\n const runtimeFilters = new Map<\n Action,\n //TODO add a run all helper\n Filter<UserContext, any>[]\n >();\n\n // we want to init all possible runtime filters since we want to ensure\n // that the implementaiton helpers pass an object by reference when creating\n // the implementation, instead of a copy like it would be the case with undefined\n for (const action of actions!) {\n if (!runtimeFilters.has(action)) {\n runtimeFilters.set(action, []);\n }\n }\n\n return {\n /**\n * Allows to perform a specific action on a specific entity\n */\n allow: (action: Action | Action[]) => {\n if (hasBeenBuilt) {\n throw new RumbleError(\n \"You can't call allow() after the ability builder has been built. Please ensure that you register all abilities before accessing them.\",\n );\n }\n\n const actions = Array.isArray(action) ? action : [action];\n for (const action of actions) {\n let filters = queryFilters.get(action);\n if (!filters) {\n filters = \"unrestricted\";\n queryFilters.set(action, filters);\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 queryFilters.set(action, []);\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 * The actual filter function to apply. Returns the allowed values\n */\n by: (\n explicitFilter: Filter<\n UserContext,\n DrizzleTableValueType<DB, TableName>\n >,\n ) => {\n for (const action of actions) {\n // we initialized all possible actions when creating the builder\n runtimeFilters.get(action)!.push(explicitFilter);\n }\n },\n };\n },\n _: {\n runtimeFilters,\n queryFilters,\n },\n };\n };\n\n const buildersPerTable = Object.fromEntries(\n (Object.keys(db.query) as TableNames[]).map((tableName) => [\n tableName,\n createBuilderForTable<typeof tableName>(),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createBuilderForTable<key>>;\n };\n\n return {\n ...buildersPerTable,\n /**\n * @internal\n * @ignore\n */\n _: {\n registeredFilters({\n action,\n table,\n }: {\n table: TableNames;\n action: Action;\n }) {\n return (buildersPerTable[table] as any)._.runtimeFilters.get(\n action,\n )! as Filter<UserContext, DrizzleTableValueType<DB, TableNames>>[];\n },\n build() {\n const createFilterForTable = <TableName extends TableNames>(\n tableName: TableName,\n ) => {\n const queryFilters = buildersPerTable[tableName]._.queryFilters;\n\n const simpleQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isStaticQueryFilter)];\n }),\n ) as {\n [key in Action]: StaticQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>\n >[];\n };\n\n const dynamicQueryFilters = Object.fromEntries(\n actions!.map((action) => {\n const filters = queryFilters.get(action);\n\n if (!filters || filters === \"unrestricted\") return [action, []];\n\n return [action, filters.filter(isDynamicQueryFilter)];\n }),\n ) as {\n [key in Action]: DynamicQueryFilter<\n DB,\n TableName,\n DrizzleQueryFunctionInput<DB, TableName>,\n UserContext\n >[];\n };\n\n const tableSchema = tableHelper({\n db,\n table: tableName,\n });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n throw new RumbleError(\n `No primary key found for entity ${tableName.toString()}`,\n );\n }\n\n const primaryKeyField = Object.values(tableSchema.primaryKey)[0];\n // we want a filter that excludes everything\n const distinctValues = createDistinctValuesFromSQLType(\n primaryKeyField.getSQLType() as any,\n );\n\n const blockEverythingFilter = {\n where: {\n AND: [\n {\n [primaryKeyField.name]: distinctValues.value1,\n },\n {\n [primaryKeyField.name]: distinctValues.value2,\n },\n ],\n },\n };\n\n /**\n * Packs the filters into a response object that can be applied for queries by the user\n */\n function transformToResponse(\n queryFilters?: DrizzleQueryFunctionInput<DB, TableName>,\n ) {\n const internalTransformer = (\n filters?: DrizzleQueryFunctionInput<DB, TableName>,\n mergedLimit?: number,\n ) => {\n const limit = lazy(() => {\n if (\n // got a merge injection\n mergedLimit !== undefined\n ) {\n if (!filters?.limit) {\n // there is not ability limit\n return mergedLimit;\n }\n\n if ((filters.limit as number) > mergedLimit) {\n // there is an ability limit and it is higher that the injected merge limit\n return mergedLimit;\n }\n }\n\n let limit = filters?.limit as number | undefined;\n\n if (\n defaultLimit &&\n (limit === undefined || limit > defaultLimit)\n ) {\n limit = defaultLimit;\n }\n\n // ensure that null is converted to undefined\n return limit ?? undefined;\n });\n\n const sqlTransformedWhere = lazy(() => {\n return filters?.where\n ? relationsFilterToSQL(\n tableSchema.foundRelation.table,\n filters.where,\n )\n : undefined;\n });\n\n // we acutally need to define multiple return objects since we do not want to use delete for\n // performance reasons and an undefined columns field on a drizzle filter will prevent any\n // column from being selected at all\n if (filters?.columns) {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: filters?.where,\n columns: filters?.columns,\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"columns\" | \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: filters?.where,\n columns: filters?.columns,\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"columns\" | \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n } else {\n return {\n /**\n * Query filters for the drizzle query API.\n * @example\n * ```ts\n * author: t.relation(\"author\", {\n * query: (_args, ctx) => ctx.abilities.users.filter(\"read\").query.single,\n * }),\n * ´´´\n */\n query: {\n /**\n * For find first calls\n */\n single: {\n extras: filters?.extras,\n where: filters?.where,\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findFirst\"]>[0]\n >\n >,\n \"where\"\n >,\n /**\n * For find many calls\n */\n many: {\n extras: filters?.extras,\n where: filters?.where,\n get limit() {\n return limit();\n },\n } as Pick<\n NonNullable<\n NonNullable<\n Parameters<DB[\"query\"][TableName][\"findMany\"]>[0]\n >\n >,\n \"where\" | \"limit\"\n >,\n },\n /**\n * Query filters for the drizzle SQL API as used in e.g. updates.\n * @example\n *\n * ```ts\n * await db\n *\t.update(schema.users)\n *\t.set({\n *\t name: args.newName,\n * \t})\n *\t.where(\n *\t and(\n *\t eq(schema.users.id, args.userId),\n *\t ctx.abilities.users.filter(\"update\").sql.where,\n *\t ),\n *\t);\n * ```\n *\n */\n sql: {\n get where() {\n return sqlTransformedWhere();\n },\n },\n };\n }\n };\n\n const ret = internalTransformer(queryFilters);\n\n /**\n * Merges the current query filters with the provided filters for this call only\n */\n function merge(\n p: NonNullable<DrizzleQueryFunctionInput<DB, TableName>>,\n ) {\n const merged = mergeFilters(ret.query.many, p);\n return internalTransformer(\n merged,\n // in case the user wants to inject a limit, we need to ensure that it is applied\n // and not the potential default limit will be used\n // this is important for functions of the default query pagination implementation\n p.limit as number | undefined,\n );\n }\n\n (ret as any).merge = merge;\n\n return ret as typeof ret & {\n merge: typeof merge;\n };\n }\n\n return {\n withContext: (userContext: UserContext) => {\n return {\n filter: (action: Action) => {\n const assembleAbilities = (span?: Span) => {\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 span?.setAttribute(\"abilities.status\", \"unrestricted\");\n return transformToResponse();\n }\n\n // if nothing has been allowed, block everything\n if (!filters) {\n span?.setAttribute(\n \"abilities.status\",\n \"blocked_everything\",\n );\n nothingRegisteredWarningLogger(\n tableName.toString(),\n action,\n );\n return transformToResponse(blockEverythingFilter);\n }\n\n // run all dynamic filters\n const dynamicResults = new Array<\n DrizzleQueryFunctionInput<DB, TableName>\n >(dynamicQueryFilters[action].length);\n let filtersReturned = 0;\n for (\n let i = 0;\n i < dynamicQueryFilters[action].length;\n i++\n ) {\n const func = dynamicQueryFilters[action][i];\n const result = func(userContext);\n // if one of the dynamic filters returns \"allow\", we want to allow everything\n if (result === \"allow\") {\n return transformToResponse();\n }\n // if nothing is returned, nothing is allowed by this filter\n if (result === undefined) continue;\n\n dynamicResults[filtersReturned++] = result;\n }\n dynamicResults.length = filtersReturned;\n\n span?.setAttribute(\n \"abilities.dynamic\",\n dynamicResults.length,\n );\n span?.setAttribute(\n \"abilities.static\",\n simpleQueryFilters[action].length,\n );\n\n const allQueryFilters = [\n ...simpleQueryFilters[action],\n ...dynamicResults,\n ];\n\n span?.setAttribute(\n \"abilities.total\",\n allQueryFilters.length,\n );\n\n // if we don't have any permitted filters then block everything\n if (allQueryFilters.length === 0) {\n span?.setAttribute(\n \"abilities.status\",\n \"blocked_everything\",\n );\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);\n }, {});\n\n span?.setAttribute(\"abilities.status\", \"applied\");\n return transformToResponse(mergedFilters as any);\n };\n\n if (otel?.enabled && otel.tracer) {\n return otel.tracer.startActiveSpan(\n `prepare_query_abilities_${action}`,\n (span) => {\n try {\n return assembleAbilities(span);\n } finally {\n span.end();\n }\n },\n );\n } else {\n return assembleAbilities();\n }\n },\n };\n },\n };\n };\n\n const abilitiesPerTable = Object.fromEntries(\n (Object.keys(db.query) as TableNames[]).map((tableName) => [\n tableName,\n createFilterForTable(tableName),\n ]),\n ) as {\n [key in TableNames]: ReturnType<typeof createFilterForTable<key>>;\n };\n\n hasBeenBuilt = true;\n\n return (ctx: UserContext) => {\n return Object.fromEntries(\n (Object.keys(abilitiesPerTable) as TableNames[]).map(\n (tableName) => [\n tableName,\n abilitiesPerTable[tableName].withContext(ctx),\n ],\n ),\n ) as {\n [key in TableNames]: ReturnType<\n ReturnType<typeof createFilterForTable<key>>[\"withContext\"]\n >;\n };\n };\n },\n },\n };\n};\n","import { toCamelCase } from \"drizzle-orm/casing\";\nimport { capitalize } from \"es-toolkit\";\nimport { lazy } from \"../helpers/lazy\";\nimport { tableHelper } from \"../helpers/tableHelpers\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"../types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../types/schemaBuilderType\";\n\nexport type OrderArgImplementerType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createOrderArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n SchemaBuilderType<UserContext, DB, RequestEvent, Action, 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\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 const fields = Object.entries(tableSchema.columns).reduce(\n (acc, [key]) => {\n acc[key] = t.field({\n type: sortingParameterEnumRef(),\n required: false,\n });\n\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.columns,\n ReturnType<typeof t.field>\n >,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n const relationSchema = tableHelper({\n db,\n table: (value as any).targetTable,\n });\n const referenceModel = orderArgImplementer({\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 t.field>\n >,\n );\n\n return {\n ...fields,\n ...relations,\n };\n },\n });\n };\n\n ret = implement();\n referenceStorage.set(inputTypeName, ret);\n return ret;\n };\n\n return orderArgImplementer;\n};\n","import { toCamelCase } from \"drizzle-orm/casing\";\nimport type { drizzle } from \"drizzle-orm/node-postgres\";\nimport { type PgEnum, PgEnumColumn } 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//TODO check if the enum find logic can be made more solid after drizzle reaches 1.0\n\n/**\n * Checks if a schema type is an enum\n */\nexport function isEnumSchema(schemaType: any): schemaType is PgEnum<any> {\n // TODO make this compatible with other db drivers\n return schemaType instanceof PgEnumColumn;\n}\n\n// TODO make this compatible with other db drivers\ntype EnumTypes = PgEnum<any>;\n\ntype EnumFields<T> = {\n [K in keyof T as T[K] extends EnumTypes ? K : never]: T[K];\n};\n\nexport type NonEnumFields<T> = {\n [K in keyof T as T[K] extends EnumTypes ? never : K]: T[K];\n};\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> = ReturnType<\n typeof createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n SchemaBuilderType<UserContext, DB, RequestEvent, Action, PothosConfig>\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n}) => {\n const referenceStorage = new Map<string, any>();\n\n const enumImplementer = <\n ExplicitEnumVariableName extends keyof EnumFields<\n NonNullable<DB[\"_\"][\"fullSchema\"]>\n >,\n EnumColumn extends EnumTypes,\n RefName extends string,\n >({\n tsName,\n enumColumn,\n refName,\n }: Partial<{\n tsName: ExplicitEnumVariableName;\n enumColumn: EnumColumn;\n refName?: RefName | undefined;\n }> &\n (\n | {\n tsName: ExplicitEnumVariableName;\n }\n | {\n enumColumn: EnumColumn;\n }\n )) => {\n //TODO check if this can be done typesafe\n\n let enumSchemaName: string | undefined;\n let enumValues: any[] | undefined;\n\n if (tsName) {\n const schemaEnum = db._.fullSchema![tsName as string];\n\n enumSchemaName = tsName.toString();\n\n const enumCol = Object.values(\n (db as ReturnType<typeof drizzle<any, any, any>>)._.schema!,\n )\n .filter((s) => typeof s === \"object\")\n .map((s) => Object.values(s.columns))\n .flat(2)\n .filter(isEnumSchema)\n .find((e: any) => e.config.enum === schemaEnum);\n\n if (!enumCol) {\n throw new RumbleError(`Could not find applied enum column for ${tsName.toString()}.\nPlease ensure that you use the enum at least once as a column of a table!`);\n }\n\n enumValues = (enumCol as any).enumValues;\n } else if (enumColumn) {\n const entry = Object.entries(\n (db as ReturnType<typeof drizzle<any, any, any>>)._.fullSchema!,\n ).filter(([_, value]) => (enumColumn as any).config.enum === value)[0];\n\n if (!entry) {\n throw new RumbleError(\n `Could not find enum entry for ${(enumColumn as any).config.name}.`,\n );\n }\n enumSchemaName = entry[0];\n enumValues = enumColumn.enumValues;\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 let ret: ReturnType<typeof implement> | undefined = referenceStorage.get(\n graphqlImplementationName,\n );\n if (ret) {\n return ret;\n }\n\n const implement = () =>\n schemaBuilder.enumType(graphqlImplementationName, {\n values: enumValues,\n });\n\n ret = implement();\n referenceStorage.set(graphqlImplementationName, ret);\n return ret;\n };\n\n return enumImplementer;\n};\n","import type { DrizzleInstance } from \"../../types/drizzleInstanceType\";\nimport type { CustomRumblePothosConfig } from \"../../types/rumbleInput\";\nimport type { SchemaBuilderType } from \"../../types/schemaBuilderType\";\nimport {\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 mapSQLTypeToGraphQLType<\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({ sqlType, fieldName }: { sqlType: PossibleSQLType; fieldName?: string }) {\n type ReturnType = Parameters<\n Parameters<Parameters<SchemaBuilder[\"queryField\"]>[1]>[0][\"field\"]\n >[0][\"type\"];\n\n let ret: ReturnType | undefined;\n\n if (isIntLikeSQLTypeString(sqlType)) {\n ret = \"Int\";\n }\n\n if (isFloatLikeSQLTypeString(sqlType)) {\n ret = \"Float\";\n }\n\n if (isStringLikeSQLTypeString(sqlType)) {\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(sqlType)) {\n ret = \"ID\";\n }\n\n if (isBooleanSQLTypeString(sqlType)) {\n ret = \"Boolean\";\n }\n\n if (isDateTimeLikeSQLTypeString(sqlType)) {\n ret = \"DateTime\";\n }\n\n if (isDateLikeSQLTypeString(sqlType)) {\n ret = \"Date\";\n }\n\n if (isJSONLikeSQLTypeString(sqlType)) {\n ret = \"JSON\";\n }\n\n if (ret !== undefined) {\n return ret;\n }\n\n throw UnknownTypeRumbleError(sqlType, \"SQL to GQL\");\n}\n","import { toCamelCase } from \"drizzle-orm/casing\";\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 SchemaBuilderType<UserContext, DB, RequestEvent, Action, PothosConfig>,\n EnumImplementerType<UserContext, DB, RequestEvent, Action, 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n EnumImplementer extends EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n enumImplementer,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n enumImplementer: EnumImplementer;\n schemaBuilder: SchemaBuilder;\n}) => {\n const referenceStorage = new Map<string, any>();\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 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 const mapSQLTypeStringToInputPothosType = (\n sqlType: PossibleSQLType,\n fieldName: string,\n ) => {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n switch (gqlType) {\n case \"Int\":\n return t.field({ type: \"IntWhereInputArgument\" });\n case \"String\":\n return t.field({ type: \"StringWhereInputArgument\" });\n case \"Boolean\":\n return t.boolean({ required: false });\n case \"Date\":\n return t.field({\n type: \"DateWhereInputArgument\",\n });\n case \"DateTime\":\n return t.field({\n type: \"DateWhereInputArgument\",\n });\n case \"Float\":\n return t.field({\n type: \"FloatWhereInputArgument\",\n });\n case \"ID\":\n return t.id({ required: false });\n case \"JSON\":\n return t.field({\n type: \"JSON\",\n required: false,\n });\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 if (isEnumSchema(value)) {\n const enumImpl = enumImplementer({\n enumColumn: value,\n });\n\n acc[key] = t.field({\n type: enumImpl,\n required: false,\n });\n } else {\n acc[key] = mapSQLTypeStringToInputPothosType(\n value.getSQLType() as PossibleSQLType,\n key,\n );\n }\n\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.columns,\n ReturnType<typeof mapSQLTypeStringToInputPothosType>\n >,\n );\n\n const relations = Object.entries(tableSchema.relations ?? {}).reduce(\n (acc, [key, value]) => {\n const relationSchema = tableHelper({\n db,\n table: (value as any).targetTable,\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 };\n },\n });\n };\n\n ret = implement();\n referenceStorage.set(inputTypeName, ret);\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n builtSchema,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n builtSchema: () => ReturnType<SchemaBuilder[\"toSchema\"]>;\n}) => {\n const clientCreator = async ({\n apiUrl,\n outputPath,\n rumbleImportPath,\n useExternalUrqlClient,\n removeExisting,\n forceReactivity,\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 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 from ${__filename} 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 });\n };\n\n return clientCreator;\n};\n","import type {\n AbilityBuilderType,\n createAbilityBuilder,\n} 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 AbilityBuilderType<UserContext, DB, RequestEvent, Action, 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 AbilityBuilder extends ReturnType<\n typeof createAbilityBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n >,\n>({\n context: makeUserContext,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n abilityBuilder: AbilityBuilder;\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 Object.setPrototypeOf(obj, proto);\n for (const key of Object.keys(obj)) {\n deepSetProto(obj[key], proto, seen);\n }\n}\n","import { count } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFirstEntryExists } from \"./helpers/asserts\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n WhereArgImplementer extends WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n MakePubSubInstance extends MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n whereArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n whereArgImplementer: WhereArgImplementer;\n makePubSubInstance: MakePubSubInstance;\n}) => {\n return <TableName extends keyof DrizzleQueryFunction<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(table.toString())}Count`]: t.field({\n type: \"Int\",\n nullable: false,\n smartSubscription: true,\n description: `Count all ${pluralize.plural(table.toString())}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: {\n where: t.arg({ type: WhereArg, required: false }),\n },\n resolve: async (root, args, ctx, info) => {\n if (isAllowed && !(await isAllowed(ctx))) {\n throw new RumbleErrorSafe(\"Not allowed to perform this action\");\n }\n\n deepSetProto(args);\n\n return (db as any)\n .select({ count: count() })\n .from(tableSchema.fullSchema)\n .where(\n ctx.abilities[table]\n .filter(listAction)\n .merge(mapNullFieldsToUndefined(args) as any).sql.where,\n )\n .then(assertFirstEntryExists)\n .then((r: any) => r.count);\n },\n }),\n };\n });\n };\n};\n","import type { useSofa } from \"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 { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { RumbleError } from \"../../types/rumbleError\";\nimport { mapSQLTypeToGraphQLType } from \"./mapSQLTypeToTSType\";\nimport type { PossibleSQLType } from \"./types\";\n\nexport function buildPothosResponseTypeFromGraphQLType<\n Builder extends DrizzleObjectFieldBuilder<any, any, any, any>,\n>({\n builder,\n sqlType,\n fieldName,\n nullable,\n}: {\n builder: Builder;\n sqlType: PossibleSQLType;\n fieldName: string;\n nullable: boolean;\n}) {\n const gqlType = mapSQLTypeToGraphQLType({\n sqlType,\n fieldName,\n });\n switch (gqlType) {\n case \"Int\":\n return builder.exposeInt(fieldName, { nullable });\n case \"String\":\n return builder.exposeString(fieldName, { nullable });\n case \"Boolean\":\n return builder.exposeBoolean(fieldName, { nullable });\n case \"Date\":\n return builder.field({\n type: \"Date\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"DateTime\":\n return builder.field({\n type: \"DateTime\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n case \"Float\":\n return builder.exposeFloat(fieldName, { nullable });\n case \"ID\":\n return builder.exposeID(fieldName, { nullable });\n case \"JSON\":\n return builder.field({\n type: \"JSON\",\n resolve: (element: any) => element[fieldName],\n nullable,\n });\n default:\n throw new RumbleError(\n `Unsupported object type ${gqlType} for column ${fieldName}`,\n );\n }\n}\n","import type { MySqlDatabase } 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 { BaseSQLiteDatabase } 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\nexport function determineDBDialectFromSchema<DB extends DrizzleInstance>(\n schema: DB[\"_\"][\"relations\"],\n) {\n const found = new Set<DBDialect>();\n\n for (const table of Object.values(schema).map((t: any) => t.table)) {\n if (typeof table !== \"object\") {\n continue;\n }\n\n if (table instanceof PgTable) {\n found.add(\"postgres\");\n } else if (table instanceof MySqlTable) {\n found.add(\"mysql\");\n } else if (table instanceof SQLiteTable) {\n found.add(\"sqlite\");\n }\n }\n\n const dialects = Array.from(found);\n\n if (dialects.length === 1) {\n return dialects[0];\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 const dialect = determineDBDialectFromSchema(db._.relations);\n\n return dialect === \"postgres\";\n}\n\nexport function isMySQLDB<\n Narrowed extends MySqlDatabase<any, any> = MySqlDatabase<any, any>,\n>(db: any): db is Narrowed {\n const dialect = determineDBDialectFromSchema(db._.relations);\n\n return dialect === \"mysql\";\n}\n\nexport function isSQLiteDB<\n Narrowed extends BaseSQLiteDatabase<any, any> = BaseSQLiteDatabase<any, any>,\n>(db: any): db is Narrowed {\n const dialect = determineDBDialectFromSchema(db._.relations);\n\n return dialect === \"sqlite\";\n}\n","import { sql } from \"drizzle-orm\";\nimport { cloneDeep } from \"es-toolkit\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\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>,\n) {\n if (!isPostgresDB(input.db)) {\n console.info(\n \"Database dialect is not compatible with search, skipping search initialization. Only PostgreSQL is supported.\",\n );\n return;\n }\n\n await input.db.execute(sql`CREATE EXTENSION IF NOT EXISTS pg_trgm;`);\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 await input.db.execute(\n sql.raw(\n `ALTER DATABASE ${dbName} SET pg_trgm.similarity_threshold = ${threshold};`,\n ),\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>, \"search\"> & {\n //TODO types\n args: any;\n tableSchema: ReturnType<typeof tableHelper>;\n //TODO types\n abilities: any;\n}) {\n if (search?.enabled && args.search && args.search.length > 0) {\n // this prevents columns beeing searched which are not accessible to the user\n // if the abilities defined the user not to be allowed to read something, we need\n // to prevent it from beeing included in the search since this could\n // leak information\n const columnsToSearch = (\n abilities.query.many.columns\n ? Object.entries(tableSchema.columns).filter(\n ([key]) => abilities.query.many.columns[key],\n )\n : Object.entries(tableSchema.columns)\n ).filter(\n ([key, col]) =>\n isStringLikeSQLTypeString(col.getSQLType()) ||\n isIDLikeSQLTypeString(col.getSQLType()),\n );\n\n const searchParam = sql`${args.search}`;\n\n args.extras = {\n search_distance: (table: any) =>\n sql`${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`COALESCE((${table[key]}::TEXT <-> ${searchParam}), 1)`;\n }),\n sql.raw(\" + \"),\n )}`,\n };\n\n const originalOrderBy = cloneDeep(args.orderBy);\n (args as any).orderBy = (table: any) => {\n const argsOrderBySQL = sql.join(\n Object.entries(originalOrderBy ?? {}).map(([key, value]) => {\n // value is \"asc\" or \"desc\"\n if (value === \"asc\") {\n return sql`${table[key]} ASC`;\n } else if (value === \"desc\") {\n return sql`${table[key]} DESC`;\n } else {\n throw new Error(`Invalid value ${value} for orderBy`);\n }\n }),\n sql.raw(\", \"),\n );\n\n const searchSQL = sql`search_distance ASC`;\n\n const ret = originalOrderBy\n ? sql.join([argsOrderBySQL, searchSQL], sql.raw(\", \"))\n : searchSQL;\n\n return ret;\n };\n\n const originalWhere = cloneDeep(args.where);\n\n // this limits the search to the rows which at least match the threshold score\n (args as any).where = {\n AND: [\n originalWhere ?? {},\n {\n RAW: (table: any) =>\n sql`(${sql.join(\n columnsToSearch.map(([key]) => {\n return sql`${table[key]} % ${searchParam}`;\n }),\n sql.raw(\" OR \"),\n )})`,\n },\n ],\n };\n }\n}\n","import type { FieldMap } from \"@pothos/core\";\nimport type { DrizzleObjectFieldBuilder } from \"@pothos/plugin-drizzle\";\nimport { One } from \"drizzle-orm\";\nimport { capitalize } from \"es-toolkit\";\nimport pluralize from \"pluralize\";\nimport type { AbilityBuilderType } from \"./abilityBuilder\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { type EnumImplementerType, isEnumSchema } from \"./enum\";\nimport { buildPothosResponseTypeFromGraphQLType } from \"./helpers/sqlTypes/mapDrizzleTypeToGraphQlType\";\nimport type { PossibleSQLType } from \"./helpers/sqlTypes/types\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n DrizzleTableValueType,\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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n WhereArgImplementer extends WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n OrderArgImplementer extends OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n EnumImplementer extends EnumImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n MakePubSubInstance extends MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n AbilityBuilderInstance extends AbilityBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n search,\n schemaBuilder,\n makePubSubInstance,\n whereArgImplementer,\n orderArgImplementer,\n enumImplementer,\n abilityBuilder,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n whereArgImplementer: WhereArgImplementer;\n orderArgImplementer: OrderArgImplementer;\n enumImplementer: EnumImplementer;\n makePubSubInstance: MakePubSubInstance;\n abilityBuilder: AbilityBuilderInstance;\n}) => {\n return <\n TableName extends keyof DrizzleQueryFunction<DB>,\n RefName extends string,\n >({\n table,\n refName,\n readAction = \"read\" as Action,\n adjust,\n }: {\n /**\n * The table you want to be used as reference for the object creation.\n */\n table: TableName;\n /**\n * The name you want this object to have in your graphql schema.\n * Rumble will create a reasonable default if not specified.\n */\n refName?: RefName;\n /**\n * The action used for read access to the table.\n * Defaults to \"read\".\n */\n readAction?: Action;\n /**\n * A function which can be used to adjust the fields of the object.\n * You can extend the object by specifying fields that do not exist as\n * per your db schema, or overwrite existing fields with the same name.\n * In case you do overwrite, rumble will set proper nullability and\n * subscription properties if you do not specify them explicitly.\n */\n adjust?:\n | ((\n t: DrizzleObjectFieldBuilder<\n SchemaBuilder[\"$inferSchemaTypes\"],\n SchemaBuilder[\"$inferSchemaTypes\"][\"DrizzleRelations\"][TableName],\n DrizzleTableValueType<DB, TableName>\n >,\n ) => FieldMap)\n | undefined;\n }) => {\n const tableSchema = tableHelper({ db, table });\n\n if (Object.keys(tableSchema.primaryKey).length === 0) {\n console.warn(\n `Could not find primary key for ${table.toString()}. Cannot register subscriptions!`,\n );\n }\n const primaryKey = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n return schemaBuilder.drizzleObject(table, {\n name: refName ?? capitalize(table.toString()),\n subscribe: (subscriptions, element, _context) => {\n if (!primaryKey) return;\n const primaryKeyValue = (element as any)[primaryKey.name];\n if (!primaryKeyValue) {\n console.warn(\n `Could not find primary key value for ${JSON.stringify(\n element,\n )}. Cannot register subscription!`,\n );\n return;\n }\n\n //TODO maybe register non specific update calls aswell?\n registerOnInstance({\n instance: subscriptions,\n action: \"updated\",\n primaryKeyValue: primaryKeyValue,\n });\n },\n applyFilters: abilityBuilder?._.registeredFilters({\n table,\n action: readAction,\n }),\n fields: (t) => {\n const columns = tableSchema.columns;\n\n // in case the user makes adjustments we want to store away which\n // pothos function was called with what config\n // this is mapped to the ref which later can be used to\n // reference these parameters while iterating over the fields\n // and checking against the userAdjustments object\n // this is necessary to e.g. merge nullability info from the database schema\n // or register subscriptions on relations\n const configMap = new Map<\n any,\n {\n creatorFunction: (...p: any[]) => any;\n params: any[];\n configObject: any;\n }\n >();\n // stores the results of the user adjustments\n // also stores all the used pothos functions and the configs\n // provided by the user so we can extend that if necessary\n const userAdjustments =\n adjust?.(\n new Proxy(t, {\n get: (target, prop, receiver) => {\n if (\n // we only care for field/relation functions\n typeof (target as any)[prop] !== \"function\" ||\n prop === \"arg\" ||\n prop === \"builder\" ||\n prop === \"graphqlKind\" ||\n prop === \"kind\" ||\n prop === \"listRef\" ||\n prop === \"table\" ||\n prop === \"typename\" ||\n prop === \"variant\" ||\n prop.toString().startsWith(\"boolean\") ||\n prop.toString().startsWith(\"float\") ||\n prop.toString().startsWith(\"id\") ||\n prop.toString().startsWith(\"int\") ||\n prop.toString().startsWith(\"string\") ||\n prop.toString().startsWith(\"expose\")\n ) {\n return (target as any)[prop];\n }\n\n return (...params: any[]) => {\n const ref = (target as any)[prop](...params);\n const configObject = params.find(isProbablyAConfigObject);\n if (!configObject)\n throw new RumbleError(\n \"Expected config object to be passed to adjust field\",\n );\n\n configMap.set(ref, {\n params,\n creatorFunction: (target as any)[prop],\n configObject,\n });\n return ref;\n };\n },\n }) as any,\n ) ?? {};\n\n const fields = Object.entries(columns).reduce(\n (acc, [key, column]) => {\n // 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 if (isEnumSchema(column)) {\n const enumImpl = enumImplementer({\n enumColumn: column,\n });\n\n acc[key] = t.field({\n type: 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 });\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 relationSchema = tableHelper({\n db,\n table: (value as any).targetTable,\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 (value instanceof One) {\n isMany = false;\n nullable = !value.sourceColumns.every((column) => column.notNull);\n filterSpecifier = \"single\";\n }\n\n const subscribe = (subscriptions: any, _element: any) => {\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n relationTablePubSub.registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n };\n\n // in case the user wants to overwrite a field\n // we want to merge with our stuff in case the user\n // did not specify it themselves\n if (userAdjustments[key]) {\n const { params, creatorFunction, configObject } = configMap.get(\n userAdjustments[key],\n )!;\n\n if (typeof configObject.nullable !== \"boolean\") {\n configObject.nullable = nullable;\n }\n\n if (typeof configObject.subscribe !== \"function\") {\n configObject.subscribe = subscribe;\n }\n\n userAdjustments[key] = creatorFunction.bind(t)(...params);\n return acc;\n }\n\n const args = {\n where: t.arg({ type: WhereArg, required: false }),\n orderBy: t.arg({ type: OrderArg, required: false }),\n ...(isMany\n ? {\n offset: t.arg.int({ required: false }),\n limit: t.arg.int({ required: false }),\n }\n : {}),\n search: t.arg.string({ required: false }),\n };\n\n if (!search?.enabled || !isMany) {\n delete (args as any).search;\n }\n\n (acc as any)[key] = t.relation(\n key as any,\n {\n args,\n subscribe,\n nullable,\n description: `Get the ${pluralize.plural(relationSchema.tsName)} related to this ${pluralize.singular(tableSchema.tsName)}`,\n query: (args: any, ctx: any) => {\n // transform null prototyped object\n args = JSON.parse(JSON.stringify(args));\n\n if (isMany) {\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema: relationSchema,\n abilities:\n ctx.abilities[relationSchema.tsName].filter(readAction),\n });\n }\n\n const filter = ctx.abilities[relationSchema.tsName]\n .filter(readAction)\n .merge({\n where: args.where,\n limit: args.limit,\n extras: args.extras,\n }).query[filterSpecifier];\n\n if (args.offset) {\n (filter as any).offset = args.offset;\n }\n\n if (args.orderBy) {\n (filter as any).orderBy = args.orderBy;\n }\n\n return filter;\n },\n } as any,\n ) as any;\n return acc;\n },\n {} as Record<\n keyof typeof tableSchema.relations,\n ReturnType<typeof buildPothosResponseTypeFromGraphQLType>\n >,\n );\n\n if (search?.enabled) {\n if (fields.search_distance) {\n throw new Error(\n \"Reserved field name 'search_distance' found on \" +\n tableSchema.tsName +\n \". If search is enabled, the 'search_distance' field is automatically added and cannot be defined manually.\",\n );\n }\n\n fields.search_distance = t.float({\n description:\n \"The search distance of the object. If a search is provided, this field will be populated with the search distance.\",\n nullable: true,\n resolve: (parent, args, ctx, info) =>\n (parent as any).search_distance,\n });\n }\n\n return {\n ...fields,\n ...relations,\n ...userAdjustments,\n };\n },\n });\n };\n};\n","import { createPubSub } from \"graphql-yoga\";\nimport type {\n DrizzleInstance,\n DrizzleQueryFunction,\n} from \"./types/drizzleInstanceType\";\nimport type {\n CustomRumblePothosConfig,\n RumbleInput,\n} from \"./types/rumbleInput\";\n\ntype PubSubAction = \"created\" | \"removed\" | \"updated\";\n\nconst SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX = \"RUMBLE_SUBSCRIPTION_NOTIFICATION\";\nconst SUBSCRIPTION_NOTIFIER_REMOVED = \"REMOVED\";\nconst SUBSCRIPTION_NOTIFIER_UPDATED = \"UPDATED\";\nconst SUBSCRIPTION_NOTIFIER_CREATED = \"CREATED\";\n\nexport type MakePubSubInstanceType<\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n> = ReturnType<\n typeof createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >\n>[\"makePubSubInstance\"];\n\nexport const createPubSubInstance = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n Action extends string,\n PothosConfig extends CustomRumblePothosConfig,\n>({\n subscriptions,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>) => {\n const pubsub = subscriptions\n ? createPubSub(...subscriptions)\n : createPubSub();\n\n const makePubSubInstance = <\n TableName extends keyof DrizzleQueryFunction<DB>,\n >({\n table,\n }: {\n table: TableName;\n }) => {\n type PrimaryKeyType = any;\n\n function makePubSubKey({\n action,\n tableName,\n primaryKeyValue,\n }: {\n tableName: string;\n action: PubSubAction;\n primaryKeyValue?: PrimaryKeyType;\n }) {\n let actionKey: string;\n\n switch (action) {\n case \"created\":\n actionKey = SUBSCRIPTION_NOTIFIER_CREATED;\n break;\n case \"removed\":\n actionKey = SUBSCRIPTION_NOTIFIER_REMOVED;\n break;\n case \"updated\":\n actionKey = SUBSCRIPTION_NOTIFIER_UPDATED;\n break;\n default:\n throw new Error(`Unknown action: ${action}`);\n }\n\n return `${SUBSCRIPTION_NOTIFIER_RUMBLE_PREFIX}/${tableName}${\n primaryKeyValue ? `/${primaryKeyValue}` : \"\"\n }/${actionKey}`;\n }\n\n // TODO does caching these make sense?\n return {\n /**\n * Call this when you want to register a subscription on an instance to this table\n */\n registerOnInstance({\n instance,\n action,\n primaryKeyValue,\n }: {\n instance: { register: (id: string) => void };\n action: PubSubAction;\n primaryKeyValue?: string;\n }) {\n const key = makePubSubKey({\n tableName: table.toString(),\n action,\n primaryKeyValue,\n });\n instance.register(key);\n },\n /**\n * Call this when you created an entity of this table\n */\n created() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"created\",\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you removed one or more entities of this table\n */\n // removed(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n removed() {\n const key = makePubSubKey({\n tableName: table.toString(),\n action: \"removed\",\n //TODO would it make sense to use specific sub topics here?\n // primaryKeyValue,\n });\n return pubsub.publish(key);\n },\n /**\n * Call this when you updated one or more entities of this table\n */\n updated(primaryKeyValue?: PrimaryKeyType | PrimaryKeyType[]) {\n const primaryKeys = Array.isArray(primaryKeyValue)\n ? primaryKeyValue\n : [primaryKeyValue];\n const keys = primaryKeys.map((primaryKeyValue) =>\n makePubSubKey({\n tableName: table.toString(),\n action: \"updated\",\n primaryKeyValue,\n }),\n );\n const uniqueKeys = Array.from(new Set(keys));\n for (const key of uniqueKeys) {\n pubsub.publish(key);\n }\n },\n };\n };\n\n return {\n pubsub,\n makePubSubInstance,\n };\n};\n","import { sql } from \"drizzle-orm\";\nimport pluralize from \"pluralize\";\nimport type { OrderArgImplementerType } from \"./args/orderArg\";\nimport type { WhereArgImplementerType } from \"./args/whereArg\";\nimport { assertFindFirstExists } from \"./helpers/asserts\";\nimport { isPostgresDB } from \"./helpers/determineDialectFromSchema\";\nimport { mapNullFieldsToUndefined } from \"./helpers/mapNullFieldsToUndefined\";\nimport { deepSetProto } from \"./helpers/protoMapper\";\nimport { tableHelper } from \"./helpers/tableHelpers\";\nimport type { MakePubSubInstanceType } from \"./pubsub\";\nimport { adjustQueryArgsForSearch } from \"./search\";\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 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 SchemaBuilder extends SchemaBuilderType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n WhereArgImplementer extends WhereArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n OrderArgImplementer extends OrderArgImplementerType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n MakePubSubInstance extends MakePubSubInstanceType<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >,\n>({\n db,\n schemaBuilder,\n search,\n whereArgImplementer,\n orderArgImplementer,\n makePubSubInstance,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n schemaBuilder: SchemaBuilder;\n whereArgImplementer: WhereArgImplementer;\n orderArgImplementer: OrderArgImplementer;\n makePubSubInstance: MakePubSubInstance;\n}) => {\n return <TableName extends keyof DrizzleQueryFunction<DB>>({\n table,\n readAction = \"read\" as Action,\n listAction = \"read\" as Action,\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 const WhereArg = whereArgImplementer({\n table: table,\n });\n const OrderArg = orderArgImplementer({\n table: table,\n });\n const tableSchema = tableHelper({\n db,\n table,\n });\n const primaryKeyField = Object.values(tableSchema.primaryKey)[0];\n\n const { registerOnInstance } = makePubSubInstance({ table: table });\n\n 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 [pluralize.plural(table.toString())]: t.drizzleField({\n type: [table],\n nullable: false,\n smartSubscription: true,\n description: `List all ${pluralize.plural(table.toString())}`,\n subscribe: (subscriptions, _root, _args, _ctx, _info) => {\n registerOnInstance({\n instance: subscriptions,\n action: \"created\",\n });\n registerOnInstance({\n instance: subscriptions,\n action: \"removed\",\n });\n },\n args: manyArgs,\n resolve: (query, _root, args, ctx, _info) => {\n // args does not have Object.prototype as prototype, so we need to set it\n // otherwise some libraries (like drizzle-orm) might have issues with it\n deepSetProto(args);\n\n adjustQueryArgsForSearch({\n search,\n args,\n tableSchema,\n abilities: ctx.abilities[table].filter(listAction),\n });\n\n const mappedArgs = mapNullFieldsToUndefined(args);\n const filter = ctx.abilities[table]\n .filter(listAction)\n .merge(mappedArgs as any).query.many;\n\n if (mappedArgs.offset) {\n (filter as any).offset = mappedArgs.offset;\n }\n\n if (mappedArgs.orderBy) {\n (filter as any).orderBy = mappedArgs.orderBy;\n }\n\n const queryInstance = query(filter as any);\n\n if ((filter as any).columns) {\n queryInstance.columns = (filter as any).columns;\n }\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) => {\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 console.info(\n \"Database dialect is not postgresql, cannot set cpu_operator_cost.\",\n );\n }\n return (tx.query as any)[table].findMany(queryInstance);\n });\n }\n\n return (db.query as any)[table].findMany(queryInstance);\n },\n }),\n [pluralize.singular(table.toString())]: t.drizzleField({\n type: table,\n nullable: false,\n smartSubscription: true,\n description: `Get a single ${pluralize.singular(table.toString())} by ID`,\n args: {\n id: t.arg.id({ required: true }),\n },\n resolve: (query, _root, args, ctx, _info) => {\n deepSetProto(args);\n\n const filter = (ctx.abilities as any)[table]\n .filter(readAction)\n .merge({ where: { [primaryKeyField.name]: args.id } })\n .query.single;\n const q = query(filter);\n\n if (filter.columns) {\n q.columns = filter.columns;\n }\n\n return (db.query as any)[table]\n .findFirst(q)\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\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","export type Filter<Context, T> = (p: {\n context: Context;\n entities: T[];\n}) => T[] | Promise<T[]>;\n\nexport type ApplyFiltersField<Context, T> =\n | Filter<Context, T>\n | Filter<Context, T>[]\n | undefined;\n\nexport const pluginName = \"RuntimeFiltersPlugin\" as const;\n","import type { Filter } from \"../runtimeFiltersPlugin/filterTypes\";\n\n/**\n * A helper to apply a list of filters to a given list of entities.\n * \n * @example\n * \n * ```ts\n * const filtered = await applyFilters({\n filters: abilityBuilder.registeredFilters.posts.update,\n entities: entitiesToFilter,\n context: ctx,\n });\n * ```\n */\nexport const applyFilters = async <Context, T, H extends T>({\n filters,\n entities,\n context,\n}: {\n entities: T[];\n filters: Filter<Context, H>[];\n context: Context;\n}) => {\n return Array.from(\n (\n await Promise.all(\n filters.map((f) =>\n f({\n context,\n entities: entities as H[],\n }),\n ),\n )\n ).reduce((acc, val) => {\n for (const element of val) {\n acc.add(element);\n }\n return acc;\n // since multiple helpers might return the same entity we use a set to deduplicate\n }, new Set<T>()),\n );\n};\n","import type { Span, Tracer } from \"@opentelemetry/api\";\nimport SchemaBuilder, {\n BasePlugin,\n type PothosOutputFieldConfig,\n type PothosTypeConfig,\n type SchemaTypes,\n} from \"@pothos/core\";\nimport type { GraphQLFieldResolver } from \"graphql\";\nimport { applyFilters } from \"../helpers/applyFilters\";\nimport { type ApplyFiltersField, pluginName } from \"./filterTypes\";\n\nexport const applyFiltersKey = \"applyFilters\";\n\nexport class RuntimeFiltersPlugin<\n Types extends SchemaTypes,\n> extends BasePlugin<Types> {\n private tracer?: Tracer;\n private tracerEnabled?: boolean;\n\n override onTypeConfig(typeConfig: PothosTypeConfig) {\n this.tracer = this.builder.options.otel?.tracer;\n this.tracerEnabled = this.builder.options.otel?.enabled;\n return typeConfig;\n }\n\n override wrapResolve(\n resolver: GraphQLFieldResolver<unknown, Types[\"Context\"], object>,\n fieldConfig: PothosOutputFieldConfig<Types>,\n ): GraphQLFieldResolver<unknown, Types[\"Context\"], object> {\n return async (parent, args, context, info) => {\n //TODO: https://github.com/hayes/pothos/discussions/1431#discussioncomment-12974130\n let filters: ApplyFiltersField<Types[\"Context\"], any> | undefined;\n const fieldType = fieldConfig?.type as any;\n\n if (fieldType.kind === \"List\") {\n filters =\n fieldType.type?.ref.currentConfig.pothosOptions[applyFiltersKey];\n } else if (fieldType.kind === \"Object\") {\n filters = fieldType.ref.currentConfig.pothosOptions[applyFiltersKey];\n }\n\n if (!filters || !Array.isArray(filters) || filters.length === 0) {\n // if no filter should be applied, just continue\n return resolver(parent, args, context, info);\n }\n\n const runFilters = async (span?: Span) => {\n const resolved = await resolver(parent, args, context, info);\n const allResolvedValues = Array.isArray(resolved)\n ? resolved\n : [resolved];\n const allFilters = Array.isArray(filters) ? filters : [filters];\n span?.setAttribute(\"filters.total\", allFilters.length);\n\n const allowed = await applyFilters({\n filters: allFilters,\n entities: allResolvedValues,\n context,\n });\n span?.setAttribute(\"filters.allowed\", allowed.length);\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 if (this.tracer && this.tracerEnabled) {\n return this.tracer.startActiveSpan(\n `apply_filters_${fieldConfig.name}`,\n async (span) => {\n try {\n return await runFilters(span);\n } finally {\n span.end();\n }\n },\n );\n } else {\n return runFilters();\n }\n };\n }\n}\n\nlet registered = false;\nexport function registerRuntimeFiltersPlugin() {\n if (!registered) {\n SchemaBuilder.registerPlugin(pluginName, RuntimeFiltersPlugin);\n registered = true;\n }\n}\n","import SchemaBuilder from \"@pothos/core\";\nimport DrizzlePlugin from \"@pothos/plugin-drizzle\";\nimport SmartSubscriptionsPlugin, {\n subscribeOptionsFromIterator,\n} from \"@pothos/plugin-smart-subscriptions\";\nimport TracingPlugin, { isRootField } from \"@pothos/plugin-tracing\";\nimport { createOpenTelemetryWrapper } from \"@pothos/tracing-opentelemetry\";\nimport {\n DateResolver,\n DateTimeISOResolver,\n JSONResolver,\n} from \"graphql-scalars\";\nimport type { createPubSub } from \"graphql-yoga\";\nimport {\n type DateWhereInputArgument,\n implementDefaultWhereInputArgs,\n type NumberWhereInputArgument,\n type StringWhereInputArgument,\n} from \"./args/whereArgsImplementer\";\nimport type { ContextType } from \"./context\";\nimport { pluginName } from \"./runtimeFiltersPlugin/filterTypes\";\nimport { registerRuntimeFiltersPlugin } from \"./runtimeFiltersPlugin/runtimeFiltersPlugin\";\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 disableDefaultObjects,\n pubsub,\n pothosConfig,\n otel,\n}: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig> & {\n pubsub: ReturnType<typeof createPubSub>;\n}) => {\n const createSpan =\n otel?.enabled && otel.tracer\n ? createOpenTelemetryWrapper(otel.tracer, otel.options)\n : undefined;\n\n registerRuntimeFiltersPlugin();\n const schemaBuilder = new SchemaBuilder<{\n Context: ContextType<UserContext, DB, RequestEvent, Action, PothosConfig>;\n DrizzleRelations: DB[\"_\"][\"relations\"];\n 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;\n };\n };\n Inputs: {\n IntWhereInputArgument: NumberWhereInputArgument;\n FloatWhereInputArgument: NumberWhereInputArgument;\n StringWhereInputArgument: StringWhereInputArgument;\n DateWhereInputArgument: DateWhereInputArgument;\n };\n DefaultFieldNullability: false;\n }>({\n ...pothosConfig,\n plugins: [\n pluginName,\n DrizzlePlugin,\n SmartSubscriptionsPlugin,\n TracingPlugin,\n ...(pothosConfig?.plugins ?? []),\n ],\n drizzle: {\n client: db,\n relations: db._.relations,\n getTableConfig(table) {\n //TODO support composite primary keys\n return {\n columns: Object.values((table as any)[Symbol.for(\"drizzle:Columns\")]),\n primaryKeys: Object.values(\n (table as any)[Symbol.for(\"drizzle:Columns\")],\n ).filter((v: any) => v.primary),\n } as any;\n },\n },\n smartSubscriptions: {\n ...subscribeOptionsFromIterator((name, _context) => {\n return pubsub.subscribe(name);\n }),\n },\n defaultFieldNullability: false,\n tracing: {\n default: otel?.enabled ? (config) => isRootField(config) : () => false,\n wrap: createSpan\n ? (resolver, options) => createSpan(resolver, options)\n : (resolver) => resolver,\n },\n otel,\n });\n\n schemaBuilder.addScalarType(\"JSON\", JSONResolver);\n schemaBuilder.addScalarType(\"Date\", DateResolver);\n schemaBuilder.addScalarType(\"DateTime\", DateTimeISOResolver);\n implementDefaultWhereInputArgs(schemaBuilder);\n\n if (!disableDefaultObjects?.query) {\n schemaBuilder.queryType({});\n }\n\n if (!disableDefaultObjects?.subscription) {\n schemaBuilder.subscriptionType({});\n }\n\n if (!disableDefaultObjects?.mutation) {\n schemaBuilder.mutationType({});\n }\n\n return { schemaBuilder };\n};\n","import { EnvelopArmorPlugin } from \"@escape.tech/graphql-armor\";\nimport { useDisableIntrospection } from \"@graphql-yoga/plugin-disable-introspection\";\nimport { SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport { AttributeNames, SpanNames } from \"@pothos/tracing-opentelemetry\";\nimport { merge } from \"es-toolkit\";\nimport {\n createYoga as nativeCreateYoga,\n type Plugin,\n type YogaServerOptions,\n} from \"graphql-yoga\";\nimport { useSofa } from \"sofa-api\";\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 } from \"./enum\";\nimport { lazy } from \"./helpers/lazy\";\nimport { sofaOpenAPIWebhookDocs } from \"./helpers/sofaOpenAPIWebhookDocs\";\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\nexport const rumble = <\n UserContext extends Record<string, any>,\n DB extends DrizzleInstance,\n RequestEvent extends Record<string, any>,\n PothosConfig extends CustomRumblePothosConfig,\n Action extends string = \"read\" | \"update\" | \"delete\",\n>(\n rumbleInput: RumbleInput<UserContext, DB, RequestEvent, Action, PothosConfig>,\n) => {\n if (!rumbleInput.db._.schema) {\n throw new RumbleError(`\nrumble could not find any schema in the provided drizzle instance.\nMake sure you import the schema and pass it to the drizzle instance:\n\nexport const db = drizzle(\n \"postgres://postgres:postgres@localhost:5432/postgres\",\n {\n relations,\n schema, // <--- add this line\n },\n);\n\n`);\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 schema,\n },\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 typeof abilityBuilder\n >({\n ...rumbleInput,\n abilityBuilder,\n });\n\n const { makePubSubInstance, pubsub } = createPubSubInstance<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({\n ...rumbleInput,\n });\n\n const { schemaBuilder } = createSchemaBuilder<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig\n >({ ...rumbleInput, pubsub });\n\n const enum_ = createEnumImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const whereArg = createWhereArgImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder,\n typeof enum_\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 typeof schemaBuilder\n >({\n ...rumbleInput,\n schemaBuilder,\n });\n\n const object = createObjectImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder,\n typeof whereArg,\n typeof orderArg,\n typeof enum_,\n typeof makePubSubInstance,\n typeof abilityBuilder\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 typeof schemaBuilder,\n typeof whereArg,\n typeof orderArg,\n typeof makePubSubInstance\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(() => schemaBuilder.toSchema());\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 | 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 plugins: [\n ...(args?.plugins ?? []),\n ...(enableApiDocs\n ? []\n : [useDisableIntrospection(), EnvelopArmorPlugin()]),\n rumbleInput.otel?.enabled\n ? ({\n onExecute: ({ setExecuteFn, executeFn }) => {\n setExecuteFn((options) =>\n rumbleInput.otel!.tracer!.startActiveSpan(\n SpanNames.EXECUTE,\n {\n attributes: {\n [AttributeNames.OPERATION_NAME]:\n options.operationName ?? \"anonymous\",\n [AttributeNames.SOURCE]: options.document,\n },\n },\n async (span) => {\n try {\n const result = await executeFn(options);\n\n if (\n result &&\n \"errors\" in result &&\n result.errors?.length\n ) {\n for (const error of result.errors) {\n span.recordException(error);\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n }\n\n return result;\n } catch (error) {\n if (error instanceof Error) {\n span.recordException(error);\n }\n span.setStatus({ code: SpanStatusCode.ERROR });\n throw error;\n } finally {\n span.end();\n }\n },\n ),\n );\n },\n } as Plugin)\n : false,\n ].filter(Boolean),\n });\n };\n\n const createSofa = (\n args: Omit<Parameters<typeof useSofa>[0], \"schema\" | \"context\">,\n ) => {\n if (args.openAPI) {\n merge(args.openAPI, sofaOpenAPIWebhookDocs);\n }\n if (args.errorHandler) {\n const originalHandler = args.errorHandler;\n args.errorHandler = (errors) => {\n const span = trace.getActiveSpan();\n\n for (const error of errors) {\n span?.recordException(error);\n }\n span?.setStatus({ code: SpanStatusCode.ERROR });\n return originalHandler(errors);\n };\n }\n return useSofa({\n ...args,\n schema: builtSchema(),\n context,\n errorHandler(errors) {\n const span = trace.getActiveSpan();\n\n for (const error of errors) {\n span?.recordException(error);\n }\n span?.setStatus({ code: SpanStatusCode.ERROR });\n\n return new Response(errors[0].message, {\n status: 500,\n }) as any;\n },\n });\n };\n\n const clientCreator = clientCreatorImplementer<\n UserContext,\n DB,\n RequestEvent,\n Action,\n PothosConfig,\n typeof schemaBuilder\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 * 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};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAa,cAAb,cAAiC,MAAM;CACrC,YAAY,SAAiB;AAC3B,QAAM,QAAQ;AACd,OAAK,OAAO;;;;;;;;AAShB,IAAa,kBAAb,cAAqCA,qBAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACelD,MAAa,yBAA4B,UAA4B;AACnE,KAAI,CAAC,MACH,OAAM,IAAI,gBAAgB,2CAA2C;AAEvE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CT,MAAa,0BAA6B,UAAkB;CAC1D,MAAM,IAAI,MAAM,GAAG,EAAE;AACrB,KAAI,CAAC,EACH,OAAM,IAAI,gBAAgB,4CAA4C;AACxE,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBT,SAAgB,yBAA2C,KAAQ;AACjE,QAAO,OAAO,YACZ,OAAO,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,WAAW,CACxC,KACA,UAAU,OAAO,SAAY,MAC9B,CAAC,CACH;;;;;;;;;AE9DH,SAAgB,aAGd,SAA4B,SAA4B;AAoDxD,QAAO;EACL,OAnDA,SAAS,SAAS,SAAS,QACvB,EAAE,KAAK,CAAC,SAAS,OAAO,SAAS,MAAM,EAAE,GACxC,SAAS,SAAS,SAAS;EAkDhC,SA/CA,SAAS,WAAW,SAAS,UACzB,IAAI,IACF,CACE,OAAO,QAAQ,SAAS,WAAW,EAAE,CAAC,EACtC,OAAO,QAAQ,SAAS,WAAW,EAAE,CAAC,CACvC,CACE,MAAM,CACN,QAAQ,GAAG,OAAO,MAAM,KAAK,CAC7B,KAAK,CAAC,OAAO,EAAE,CACnB,CACE,SAAS,CACT,QACE,KAAK,CAAC,SAAS;AACd,OAAI,OAAO;AACX,UAAO;KAET,EAAE,CACH,GACH;EA8BJ,QA3BA,SAAS,UAAU,SAAS,kCACf,SAAS,UAAU,EAAE,EAAE,SAAS,UAAU,EAAE,CAAC,GACtD;EA0BJ,SAvBA,SAAS,WAAW,SAAS,mCAChB,SAAS,WAAW,EAAE,EAAE,SAAS,WAAW,EAAE,CAAC,GACxD;EAsBJ,OAnBA,SAAS,SAAS,SAAS,QACvB,KAAK,IAAI,SAAS,SAAS,UAAU,SAAS,SAAS,SAAS,GAChE;EAkBJ,QAfA,SAAS,UAAU,SAAS,SACxB,KAAK,IAAI,SAAS,UAAU,UAAU,SAAS,UAAU,SAAS,GAClE;EAcJ,MAXA,SAAS,QAAQ,SAAS,gCACb,SAAS,QAAQ,EAAE,EAAE,SAAS,QAAQ,EAAE,CAAC,GAClD;EAUL;;;;;AC/DH,MAAM,wBAAwB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,uBACd,SACmD;AACnD,QAAO,sBAAsB,SAAS,QAAe;;AAGvD,MAAM,0BAA0B;CAC9B;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,yBACd,SACqD;AACrD,QAAO,wBAAwB,SAAS,QAAe;;AAGzD,MAAM,2BAA2B;CAC/B;CACA;CACA;CACA;CACA;CACD;AAED,SAAgB,0BACd,SACsD;AACtD,QAAO,yBAAyB,SAAS,QAAe;;AAG1D,MAAM,uBAAuB,CAAC,OAAO;AAErC,SAAgB,sBACd,SACkD;AAClD,QAAO,qBAAqB,SAAS,QAAe;;AAGtD,MAAM,wBAAwB,CAAC,UAAU;AAEzC,SAAgB,uBACd,SACmD;AACnD,QAAO,sBAAsB,SAAS,QAAe;;AAGvD,MAAM,6BAA6B,CAAC,aAAa,WAAW;AAE5D,SAAgB,4BACd,SACwD;AACxD,QAAO,2BAA2B,SAAS,QAAe;;AAG5D,MAAM,yBAAyB,CAAC,OAAO;AAEvC,SAAgB,wBACd,SACoD;AACpD,QAAO,uBAAuB,SAAS,QAAe;;AAGxD,MAAM,yBAAyB,CAAC,QAAQ,QAAQ;AAEhD,SAAgB,wBACd,SACoD;AACpD,QAAO,uBAAuB,SAAS,QAAe;;AAGxB;CAC9B,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACJ;AAID,MAAa,0BACX,SACA,mBAEA,IAAI,YACF,kCAAkC,QAAQ,yFAAyF,eAAe,GACnJ;;;;AC3FH,SAAgB,gCAAgC,SAG9C;AACA,KAAI,uBAAuB,QAAQ,CACjC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,yBAAyB,QAAQ,CACnC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,0BAA0B,QAAQ,CACpC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,sBAAsB,QAAQ,CAChC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,uBAAuB,QAAQ,CACjC,QAAO;EACL,QAAQ;EACR,QAAQ;EACT;AAGH,KAAI,4BAA4B,QAAQ,CACtC,QAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC5B,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC7B;AAGH,KAAI,wBAAwB,QAAQ,CAClC,QAAO;EACL,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC5B,QAAQ,IAAI,KAAK,MAAM,GAAG,EAAE;EAC7B;AAGH,KAAI,wBAAwB,QAAQ,CAClC,QAAO;EACL,QAAQ,EAAE,GAAG,GAAG;EAChB,QAAQ,EAAE,GAAG,GAAG;EACjB;AAGH,OAAM,uBAAuB,SAAS,WAAW;;;;;ACjEnD,MAAM,oBAAoB,OAAO,IAAI,eAAe;AACpD,MAAM,4BAA4B,OAAO,IAAI,uBAAuB;AACpE,MAAM,wBAAwB,OAAO,IAAI,mBAAmB;AAE5D,SAAgB,YAMd,EAAE,IAAI,SAA6C;AACnD,KAAI,OAAO,UAAU,SACnB,SACE,MAAM,UACN,MAAM,UACN,MAAM,sBACN,MAAM,8BACN,MAAM;CAGV,MAAM,gBAAqB,OAAO,OAAO,GAAG,EAAE,UAAW,CAAC,MACvD,WACC,OAAO,SAAS,SAChB,OAAO,MAAM,uBAAuB,SACpC,OAAO,MAAM,+BAA+B,SAC5C,OAAO,MAAM,2BAA2B,MAC3C;AAED,KAAI,CAAC,cACH,OAAM,IAAI,YAAY,6BAA6B,KAAK,UAAU,MAAM,GAAG;CAG7E,MAAM,cAAc,OAAO,OACxB,GAAiD,EAAE,OACrD,CAAC,MACC,WACC,OAAO,WAAW,cAAc,MAAM,2BACzC;AAED,KAAI,CAAC,YACH,OAAM,IAAI,YAAY,6BAA6B,KAAK,UAAU,MAAM,GAAG;CAG7E,MAAM,aAAa,GAAG,EAAE,aAAa,YAAY;AAEjD,KAAI,CAAC,WACH,OAAM,IAAI,YACR,kCAAkC,KAAK,UAAU,MAAM,GACxD;AAGH,QAAO;EACL,SAAS,YAAY;EACrB,YAAY,YAAY;EACxB,WAAY,cAAsB;EAGlC,QAAQ,YAAY;EACpB,QAAQ,YAAY;EACpB;EACA;EACA;EACD;;;;;ACCH,SAAS,qBAMP,QAC0D;AAC1D,QACE,OAAO,WAAW,cAAc,OAAO,YAAY,SAAS;;AAIhE,SAAS,oBAMP,QACgD;AAChD,QAAO,OAAO,WAAW;;AAG3B,MAAM,2DACH,OAAe,WAAmB;AACjC,SAAQ,KAAK;;;MAGX,MAAM,GAAG,OAAO;;;EAGpB;GAEA,IACD;AAED,MAAa,wBAMX,EACA,IACA,SACA,cACA,WACsE;CAGtE,IAAI,eAAe;CAEnB,MAAM,8BAA4D;EAChE,MAAM,+BAAe,IAAI,KAStB;EAEH,MAAM,iCAAiB,IAAI,KAIxB;AAKH,OAAK,MAAM,UAAU,QACnB,KAAI,CAAC,eAAe,IAAI,OAAO,CAC7B,gBAAe,IAAI,QAAQ,EAAE,CAAC;AAIlC,SAAO;GAIL,QAAQ,WAA8B;AACpC,QAAI,aACF,OAAM,IAAI,YACR,wIACD;IAGH,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO;AACzD,SAAK,MAAM,UAAU,SAAS;KAC5B,IAAI,UAAU,aAAa,IAAI,OAAO;AACtC,SAAI,CAAC,SAAS;AACZ,gBAAU;AACV,mBAAa,IAAI,QAAQ,QAAQ;;;AAIrC,WAAO,EAYL,OACE,gBAMG;AACH,UAAK,MAAM,UAAU,SAAS;AAC5B,UAAI,aAAa,IAAI,OAAO,KAAK,eAC/B,cAAa,IAAI,QAAQ,EAAE,CAAC;AAG9B,MADgB,aAAa,IAAI,OAAO,CACa,KACnD,YACD;;OAGN;;GAMH,SAAS,WAA8B;IACrC,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO;AACzD,WAAO,EAIL,KACE,mBAIG;AACH,UAAK,MAAM,UAAU,QAEnB,gBAAe,IAAI,OAAO,CAAE,KAAK,eAAe;OAGrD;;GAEH,GAAG;IACD;IACA;IACD;GACF;;CAGH,MAAM,mBAAmB,OAAO,YAC7B,OAAO,KAAK,GAAG,MAAM,CAAkB,KAAK,cAAc,CACzD,WACA,uBAAyC,CAC1C,CAAC,CACH;AAID,QAAO;EACL,GAAG;EAKH,GAAG;GACD,kBAAkB,EAChB,QACA,SAIC;AACD,WAAQ,iBAAiB,OAAe,EAAE,eAAe,IACvD,OACD;;GAEH,QAAQ;IACN,MAAM,wBACJ,cACG;KACH,MAAM,eAAe,iBAAiB,WAAW,EAAE;KAEnD,MAAM,qBAAqB,OAAO,YAChC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,OAAO;AAExC,UAAI,CAAC,WAAW,YAAY,eAAgB,QAAO,CAAC,QAAQ,EAAE,CAAC;AAE/D,aAAO,CAAC,QAAQ,QAAQ,OAAO,oBAAoB,CAAC;OACpD,CACH;KAQD,MAAM,sBAAsB,OAAO,YACjC,QAAS,KAAK,WAAW;MACvB,MAAM,UAAU,aAAa,IAAI,OAAO;AAExC,UAAI,CAAC,WAAW,YAAY,eAAgB,QAAO,CAAC,QAAQ,EAAE,CAAC;AAE/D,aAAO,CAAC,QAAQ,QAAQ,OAAO,qBAAqB,CAAC;OACrD,CACH;KASD,MAAM,cAAc,YAAY;MAC9B;MACA,OAAO;MACR,CAAC;AAEF,SAAI,OAAO,KAAK,YAAY,WAAW,CAAC,WAAW,EACjD,OAAM,IAAI,YACR,mCAAmC,UAAU,UAAU,GACxD;KAGH,MAAM,kBAAkB,OAAO,OAAO,YAAY,WAAW,CAAC;KAE9D,MAAM,iBAAiB,gCACrB,gBAAgB,YAAY,CAC7B;KAED,MAAM,wBAAwB,EAC5B,OAAO,EACL,KAAK,CACH,GACG,gBAAgB,OAAO,eAAe,QACxC,EACD,GACG,gBAAgB,OAAO,eAAe,QACxC,CACF,EACF,EACF;;;;KAKD,SAAS,oBACP,cACA;MACA,MAAM,uBACJ,SACA,gBACG;OACH,MAAM,QAAQC,wBAAW;AACvB,YAEE,gBAAgB,QAChB;AACA,aAAI,CAAC,SAAS,MAEZ,QAAO;AAGT,aAAK,QAAQ,QAAmB,YAE9B,QAAO;;QAIX,IAAI,QAAQ,SAAS;AAErB,YACE,iBACC,UAAU,UAAa,QAAQ,cAEhC,SAAQ;AAIV,eAAO,SAAS;SAChB;OAEF,MAAM,sBAAsBA,wBAAW;AACrC,eAAO,SAAS,8CAEV,YAAY,cAAc,OAC1B,QAAQ,MACT,GACD;SACJ;AAKF,WAAI,SAAS,QACX,QAAO;QAUL,OAAO;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,SAAS;UAChB,SAAS,SAAS;UACnB;SAWD,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,SAAS;UAChB,SAAS,SAAS;UAClB,IAAI,QAAQ;AACV,kBAAO,OAAO;;UAEjB;SAQF;QAoBD,KAAK,EACH,IAAI,QAAQ;AACV,gBAAO,qBAAqB;WAE/B;QACF;WAED,QAAO;QAUL,OAAO;SAIL,QAAQ;UACN,QAAQ,SAAS;UACjB,OAAO,SAAS;UACjB;SAWD,MAAM;UACJ,QAAQ,SAAS;UACjB,OAAO,SAAS;UAChB,IAAI,QAAQ;AACV,kBAAO,OAAO;;UAEjB;SAQF;QAoBD,KAAK,EACH,IAAI,QAAQ;AACV,gBAAO,qBAAqB;WAE/B;QACF;;MAIL,MAAM,MAAM,oBAAoB,aAAa;;;;MAK7C,SAAS,MACP,GACA;AAEA,cAAO,oBADQ,aAAa,IAAI,MAAM,MAAM,EAAE,EAM5C,EAAE,MACH;;AAGH,MAAC,IAAY,QAAQ;AAErB,aAAO;;AAKT,YAAO,EACL,cAAc,gBAA6B;AACzC,aAAO,EACL,SAAS,WAAmB;OAC1B,MAAM,qBAAqB,SAAgB;QACzC,MAAM,UAAU,aAAa,IAAI,OAAO;AAGxC,YAAI,YAAY,gBAAgB;AAC9B,eAAM,aAAa,oBAAoB,eAAe;AACtD,gBAAO,qBAAqB;;AAI9B,YAAI,CAAC,SAAS;AACZ,eAAM,aACJ,oBACA,qBACD;AACD,wCACE,UAAU,UAAU,EACpB,OACD;AACD,gBAAO,oBAAoB,sBAAsB;;QAInD,MAAM,iBAAiB,IAAI,MAEzB,oBAAoB,QAAQ,OAAO;QACrC,IAAI,kBAAkB;AACtB,aACE,IAAI,IAAI,GACR,IAAI,oBAAoB,QAAQ,QAChC,KACA;SACA,MAAM,OAAO,oBAAoB,QAAQ;SACzC,MAAM,SAAS,KAAK,YAAY;AAEhC,aAAI,WAAW,QACb,QAAO,qBAAqB;AAG9B,aAAI,WAAW,OAAW;AAE1B,wBAAe,qBAAqB;;AAEtC,uBAAe,SAAS;AAExB,cAAM,aACJ,qBACA,eAAe,OAChB;AACD,cAAM,aACJ,oBACA,mBAAmB,QAAQ,OAC5B;QAED,MAAM,kBAAkB,CACtB,GAAG,mBAAmB,SACtB,GAAG,eACJ;AAED,cAAM,aACJ,mBACA,gBAAgB,OACjB;AAGD,YAAI,gBAAgB,WAAW,GAAG;AAChC,eAAM,aACJ,oBACA,qBACD;AAED,gBAAO,oBAAoB,sBAAsB;;QAGnD,MAAM,gBACJ,gBAAgB,WAAW,IACvB,gBAAgB,KAChB,gBAAgB,QAAQ,GAAG,MAAM;AAC/B,gBAAO,aAAa,GAAG,EAAE;WACxB,EAAE,CAAC;AAEZ,cAAM,aAAa,oBAAoB,UAAU;AACjD,eAAO,oBAAoB,cAAqB;;AAGlD,WAAI,MAAM,WAAW,KAAK,OACxB,QAAO,KAAK,OAAO,gBACjB,2BAA2B,WAC1B,SAAS;AACR,YAAI;AACF,gBAAO,kBAAkB,KAAK;kBACtB;AACR,cAAK,KAAK;;SAGf;WAED,QAAO,mBAAmB;SAG/B;QAEJ;;IAGH,MAAM,oBAAoB,OAAO,YAC9B,OAAO,KAAK,GAAG,MAAM,CAAkB,KAAK,cAAc,CACzD,WACA,qBAAqB,UAAU,CAChC,CAAC,CACH;AAID,mBAAe;AAEf,YAAQ,QAAqB;AAC3B,YAAO,OAAO,YACX,OAAO,KAAK,kBAAkB,CAAkB,KAC9C,cAAc,CACb,WACA,kBAAkB,WAAW,YAAY,IAAI,CAC9C,CACF,CACF;;;GAON;EACF;;;;;AC7oBH,MAAMC,qBAAmB,WACvB,kEAA0B,OAAO,UAAU,CAAC,CAAC,CAAC;AAEhD,MAAa,6BAaX,EACA,IACA,oBAGI;CACJ,MAAM,mCAAmB,IAAI,KAAkB;CAE/C,MAAM,0BAA0BC,wBAC9B,cAAc,SAAS,oBAAoB,EACzC,QAAQ,CAAC,OAAO,OAAO,EACxB,CAAC,CACH;CAED,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;GAClB,CAAC;EAEF,MAAM,gBAAgB,WAAWD,kBAAgB,YAAY,OAAO;EAEpE,IAAI,MACF,iBAAiB,IAAI,cAAc;AACrC,MAAI,IACF,QAAO;EAGT,MAAM,kBAAkB;AACtB,UAAO,cAAc,UAAU,eAAe,EAC5C,SAAS,MAAM;IACb,MAAM,SAAS,OAAO,QAAQ,YAAY,QAAQ,CAAC,QAChD,KAAK,CAAC,SAAS;AACd,SAAI,OAAO,EAAE,MAAM;MACjB,MAAM,yBAAyB;MAC/B,UAAU;MACX,CAAC;AAEF,YAAO;OAET,EAAE,CAIH;IAED,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,EAAE,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;KAKrB,MAAM,iBAAiB,oBAAoB,EACzC,QALqB,YAAY;MACjC;MACA,OAAQ,MAAc;MACvB,CAAC,CAEuB,QACxB,CAAC;AAEF,SAAI,OAAO,EAAE,MAAM;MACjB,MAAM;MACN,UAAU;MACX,CAAC;AAEF,YAAO;OAET,EAAE,CAIH;AAED,WAAO;KACL,GAAG;KACH,GAAG;KACJ;MAEJ,CAAC;;AAGJ,QAAM,WAAW;AACjB,mBAAiB,IAAI,eAAe,IAAI;AACxC,SAAO;;AAGT,QAAO;;;;;;;;ACnIT,SAAgB,aAAa,YAA4C;AAEvE,QAAO,sBAAsBE;;AA+B/B,MAAa,yBAaX,EACA,IACA,oBAGI;CACJ,MAAM,mCAAmB,IAAI,KAAkB;CAE/C,MAAM,mBAMJ,EACA,QACA,YACA,cAaM;EAGN,IAAI;EACJ,IAAI;AAEJ,MAAI,QAAQ;GACV,MAAM,aAAa,GAAG,EAAE,WAAY;AAEpC,oBAAiB,OAAO,UAAU;GAElC,MAAM,UAAU,OAAO,OACpB,GAAiD,EAAE,OACrD,CACE,QAAQ,MAAM,OAAO,MAAM,SAAS,CACpC,KAAK,MAAM,OAAO,OAAO,EAAE,QAAQ,CAAC,CACpC,KAAK,EAAE,CACP,OAAO,aAAa,CACpB,MAAM,MAAW,EAAE,OAAO,SAAS,WAAW;AAEjD,OAAI,CAAC,QACH,OAAM,IAAI,YAAY,0CAA0C,OAAO,UAAU,CAAC;2EACf;AAGrE,gBAAc,QAAgB;aACrB,YAAY;GACrB,MAAM,QAAQ,OAAO,QAClB,GAAiD,EAAE,WACrD,CAAC,QAAQ,CAAC,GAAG,WAAY,WAAmB,OAAO,SAAS,MAAM,CAAC;AAEpE,OAAI,CAAC,MACH,OAAM,IAAI,YACR,iCAAkC,WAAmB,OAAO,KAAK,GAClE;AAEH,oBAAiB,MAAM;AACvB,gBAAa,WAAW;;AAG1B,MAAI,CAAC,kBAAkB,CAAC,WACtB,OAAM,IAAI,YAAY,sCAAsC;EAG9D,MAAM,4BACJ,WAAW,kEAA0B,eAAe,CAAC,CAAC;EAExD,IAAI,MAAgD,iBAAiB,IACnE,0BACD;AACD,MAAI,IACF,QAAO;EAGT,MAAM,kBACJ,cAAc,SAAS,2BAA2B,EAChD,QAAQ,YACT,CAAC;AAEJ,QAAM,WAAW;AACjB,mBAAiB,IAAI,2BAA2B,IAAI;AACpD,SAAO;;AAGT,QAAO;;;;;AC7IT,SAAgB,wBAad,EAAE,SAAS,aAA+D;CAK1E,IAAI;AAEJ,KAAI,uBAAuB,QAAQ,CACjC,OAAM;AAGR,KAAI,yBAAyB,QAAQ,CACnC,OAAM;AAGR,KAAI,0BAA0B,QAAQ,CACpC,KACE,cACC,UAAU,aAAa,CAAC,SAAS,MAAM,IACtC,UAAU,aAAa,CAAC,SAAS,KAAK,EAExC,OAAM;KAEN,OAAM;AAIV,KAAI,sBAAsB,QAAQ,CAChC,OAAM;AAGR,KAAI,uBAAuB,QAAQ,CACjC,OAAM;AAGR,KAAI,4BAA4B,QAAQ,CACtC,OAAM;AAGR,KAAI,wBAAwB,QAAQ,CAClC,OAAM;AAGR,KAAI,wBAAwB,QAAQ,CAClC,OAAM;AAGR,KAAI,QAAQ,OACV,QAAO;AAGT,OAAM,uBAAuB,SAAS,aAAa;;;;;ACrCrD,MAAM,mBAAmB,WACvB,kEAA0B,OAAO,UAAU,CAAC,CAAC,CAAC;AAEhD,MAAa,6BAoBX,EACA,IACA,eACA,sBAII;CACJ,MAAM,mCAAmB,IAAI,KAAkB;CAE/C,MAAM,uBAGJ,EACA,OACA,SACA,aAaM;EACN,MAAM,cAAc,YAAY;GAC9B;GACA,OAAO,UAAU;GAClB,CAAC;EAEF,MAAM,gBAAgB,WAAW,gBAAgB,YAAY,OAAO;EAEpE,IAAI,MACF,iBAAiB,IAAI,cAAc;AACrC,MAAI,IACF,QAAO;EAGT,MAAM,kBAAkB;AACtB,UAAO,cAAc,UAAU,eAAe,EAC5C,SAAS,MAAM;IACb,MAAM,qCACJ,SACA,cACG;KACH,MAAM,UAAU,wBAAwB;MACtC;MACA;MACD,CAAC;AACF,aAAQ,SAAR;MACE,KAAK,MACH,QAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;MACnD,KAAK,SACH,QAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;MACtD,KAAK,UACH,QAAO,EAAE,QAAQ,EAAE,UAAU,OAAO,CAAC;MACvC,KAAK,OACH,QAAO,EAAE,MAAM,EACb,MAAM,0BACP,CAAC;MACJ,KAAK,WACH,QAAO,EAAE,MAAM,EACb,MAAM,0BACP,CAAC;MACJ,KAAK,QACH,QAAO,EAAE,MAAM,EACb,MAAM,2BACP,CAAC;MACJ,KAAK,KACH,QAAO,EAAE,GAAG,EAAE,UAAU,OAAO,CAAC;MAClC,KAAK,OACH,QAAO,EAAE,MAAM;OACb,MAAM;OACN,UAAU;OACX,CAAC;MACJ,QACE,OAAM,IAAI,YACR,6BAA6B,QAAQ,cAAc,UACpD;;;IAGP,MAAM,SAAS,OAAO,QAAQ,YAAY,QAAQ,CAAC,QAChD,KAAK,CAAC,KAAK,WAAW;AACrB,SAAI,aAAa,MAAM,EAAE;MACvB,MAAM,WAAW,gBAAgB,EAC/B,YAAY,OACb,CAAC;AAEF,UAAI,OAAO,EAAE,MAAM;OACjB,MAAM;OACN,UAAU;OACX,CAAC;WAEF,KAAI,OAAO,kCACT,MAAM,YAAY,EAClB,IACD;AAGH,YAAO;OAET,EAAE,CAIH;IAED,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,EAAE,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;KAKrB,MAAM,iBAAiB,oBAAoB,EACzC,QALqB,YAAY;MACjC;MACA,OAAQ,MAAc;MACvB,CAAC,CAEuB,QACxB,CAAC;AAEF,SAAI,OAAO,EAAE,MAAM;MACjB,MAAM;MACN,UAAU;MACX,CAAC;AAEF,YAAO;OAET,EAAE,CAIH;AAED,WAAO;KACL,GAAG;KACH,GAAG;KACJ;MAEJ,CAAC;;AAGJ,QAAM,WAAW;AACjB,mBAAiB,IAAI,eAAe,IAAI;AACxC,SAAO;;AAGT,QAAO;;;;;AC9MT,MAAa,4BAaX,EACA,kBAGI;CACJ,MAAM,gBAAgB,OAAO,EAC3B,QACA,YACA,kBACA,uBACA,gBACA,sBA6BI;AACJ,MAAI,QAAQ,IAAI,aAAa,cAC3B,SAAQ,KACN,uGAAuG,WAAW,mBAAmB,KAAK,UACxI;GACE;GACA;GACA;GACA;GACA;GACD,CACF,GACF;AAGH,QAAMC,oCAAmB;GACvB,QAFa,aAAa;GAG1B;GACA;GACA;GACA;GACA;GACA;GACD,CAAC;;AAGJ,QAAO;;;;;AC/CT,MAAa,yBAeX,EACA,SAAS,iBACT,qBAGI;CACJ,MAAM,sBAAsBC,wBAAW,eAAe,EAAE,OAAO,CAAC;AAEhE,QAAO,OAAO,QAAsB;EAClC,MAAM,cAAc,kBAChB,MAAM,gBAAgB,IAAI,GACzB,EAAE;AAEP,SAAO;GACL,GAAG;GACH,WAAW,qBAAqB,CAAC,YAAY;GAC9C;;;;;;ACvEL,SAAgB,aACd,KACA,QAAQ,OAAO,WACf,uBAAO,IAAI,SAAS,EACpB;AACA,KAAI,QAAQ,QAAQ,OAAO,QAAQ,SAAU;AAC7C,KAAI,KAAK,IAAI,IAAI,CAAE;AACnB,MAAK,IAAI,IAAI;AACb,QAAO,eAAe,KAAK,MAAM;AACjC,MAAK,MAAM,OAAO,OAAO,KAAK,IAAI,CAChC,cAAa,IAAI,MAAM,OAAO,KAAK;;;;;ACSvC,MAAa,+BA2BX,EACA,IACA,eACA,qBACA,yBAKI;AACJ,SAA0D,EACxD,OACA,aAAa,QACb,gBAeI;EACJ,MAAM,WAAW,oBAAoB,EAC5B,OACR,CAAC;EACF,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,OAAO,CAAC;EAEnE,MAAM,cAAc,YAAY;GAC9B;GACA;GACD,CAAC;AAEF,SAAO,cAAc,aAAa,MAAM;AACtC,UAAO,GACJ,GAAG,kBAAU,OAAO,MAAM,UAAU,CAAC,CAAC,SAAS,EAAE,MAAM;IACtD,MAAM;IACN,UAAU;IACV,mBAAmB;IACnB,aAAa,aAAa,kBAAU,OAAO,MAAM,UAAU,CAAC;IAC5D,YAAY,eAAe,OAAO,OAAO,MAAM,UAAU;AACvD,wBAAmB;MACjB,UAAU;MACV,QAAQ;MACT,CAAC;AACF,wBAAmB;MACjB,UAAU;MACV,QAAQ;MACT,CAAC;;IAEJ,MAAM,EACJ,OAAO,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;KAAO,CAAC,EAClD;IACD,SAAS,OAAO,MAAM,MAAM,KAAK,SAAS;AACxC,SAAI,aAAa,CAAE,MAAM,UAAU,IAAI,CACrC,OAAM,IAAI,gBAAgB,qCAAqC;AAGjE,kBAAa,KAAK;AAElB,YAAQ,GACL,OAAO,EAAE,+BAAc,EAAE,CAAC,CAC1B,KAAK,YAAY,WAAW,CAC5B,MACC,IAAI,UAAU,OACX,OAAO,WAAW,CAClB,MAAM,yBAAyB,KAAK,CAAQ,CAAC,IAAI,MACrD,CACA,KAAK,uBAAuB,CAC5B,MAAM,MAAW,EAAE,MAAM;;IAE/B,CAAC,EACH;IACD;;;;;;AC3HN,MAAa,yBAET;CACF,OAAO;EACL,YAAY,EACV,MAAM;GACJ,aAAa;GACb,aAAa;GACb,MAAM,EAAE;GACR,YAAY,EAAE;GACd,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,0CACP,EACF,EACF,EACF;GACD,WAAW,EACT,OAAO;IACL,aAAa;IACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,8CACP,EACF,EACF;IACF,EACF;GACF,EACF;EACD,iBAAiB;GACf,MAAM;IACJ,aAAa;IACb,aAAa;IACb,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,UACP;KACF,CACF;IACD,aAAa,EACX,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,0CACP,EACF,EACF,EACF;IACD,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,8CACP,EACF,EACF;KACF,EACF;IACF;GACD,QAAQ;IACN,aAAa;IACb,aAAa;IACb,MAAM,EAAE;IACR,YAAY,CACV;KACE,MAAM;KACN,IAAI;KACJ,aAAa;KACb,UAAU;KACV,QAAQ,EACN,MAAM,UACP;KACF,CACF;IACD,WAAW,EACT,OAAO;KACL,aAAa;KACb,SAAS,EACP,oBAAoB,EAClB,QAAQ,EACN,MAAM,8CACP,EACF,EACF;KACF,EACF;IACF;GACF;EACF;CACD,YAAY,EACV,SAAS;EACP,mBAAmB;GACjB,MAAM;GACN,YAAY;IACV,cAAc;KACZ,aACE;KACF,MAAM;KACP;IACD,WAAW;KACT,aAAa;KACb,MAAM;KACP;IACD,KAAK;KACH,aAAa;KACb,MAAM;KACP;IACF;GACF;EACD,uBAAuB;GACrB,MAAM;GACN,YAAY,EACV,IAAI;IACF,aACE;IACF,MAAM;IACP,EACF;GACF;EACD,UAAU;GACR,MAAM;GACN,QAAQ;GACT;EACD,MAAM;GACJ,MAAM;GACN,QAAQ;GACT;EACF,EACF;CACF;;;;ACzID,SAAgB,uCAEd,EACA,SACA,SACA,WACA,YAMC;CACD,MAAM,UAAU,wBAAwB;EACtC;EACA;EACD,CAAC;AACF,SAAQ,SAAR;EACE,KAAK,MACH,QAAO,QAAQ,UAAU,WAAW,EAAE,UAAU,CAAC;EACnD,KAAK,SACH,QAAO,QAAQ,aAAa,WAAW,EAAE,UAAU,CAAC;EACtD,KAAK,UACH,QAAO,QAAQ,cAAc,WAAW,EAAE,UAAU,CAAC;EACvD,KAAK,OACH,QAAO,QAAQ,MAAM;GACnB,MAAM;GACN,UAAU,YAAiB,QAAQ;GACnC;GACD,CAAC;EACJ,KAAK,WACH,QAAO,QAAQ,MAAM;GACnB,MAAM;GACN,UAAU,YAAiB,QAAQ;GACnC;GACD,CAAC;EACJ,KAAK,QACH,QAAO,QAAQ,YAAY,WAAW,EAAE,UAAU,CAAC;EACrD,KAAK,KACH,QAAO,QAAQ,SAAS,WAAW,EAAE,UAAU,CAAC;EAClD,KAAK,OACH,QAAO,QAAQ,MAAM;GACnB,MAAM;GACN,UAAU,YAAiB,QAAQ;GACnC;GACD,CAAC;EACJ,QACE,OAAM,IAAI,YACR,2BAA2B,QAAQ,cAAc,YAClD;;;;;;AC5CP,SAAgB,6BACd,QACA;CACA,MAAM,wBAAQ,IAAI,KAAgB;AAElC,MAAK,MAAM,SAAS,OAAO,OAAO,OAAO,CAAC,KAAK,MAAW,EAAE,MAAM,EAAE;AAClE,MAAI,OAAO,UAAU,SACnB;AAGF,MAAI,iBAAiBC,4BACnB,OAAM,IAAI,WAAW;WACZ,iBAAiBC,kCAC1B,OAAM,IAAI,QAAQ;WACT,iBAAiBC,oCAC1B,OAAM,IAAI,SAAS;;CAIvB,MAAM,WAAW,MAAM,KAAK,MAAM;AAElC,KAAI,SAAS,WAAW,EACtB,QAAO,SAAS;AAGlB,KAAI,SAAS,WAAW,EACtB,OAAM,IAAI,MAAM,yDAAyD;AAG3E,OAAM,IAAI,MAAM,sCAAsC,SAAS,KAAK,KAAK,GAAG;;AAG9E,SAAgB,aAEd,IAAyB;AAGzB,QAFgB,6BAA6B,GAAG,EAAE,UAAU,KAEzC;;;;;ACrCrB,eAAsB,uBACpB,OACA;AACA,KAAI,CAAC,aAAa,MAAM,GAAG,EAAE;AAC3B,UAAQ,KACN,gHACD;AACD;;AAGF,OAAM,MAAM,GAAG,QAAQ,eAAG,0CAA0C;AACpE,KAAI,MAAM,QAAQ,WAAW;EAE3B,MAAM,YAAY,OAAO,MAAM,OAAO,UAAU;AAEhD,MAAI,YAAY,KAAK,YAAY,EAC/B,OAAM,IAAI,MAAM,2CAA2C;EAI7D,MAAM,UADS,MAAM,MAAM,GAAG,QAAQ,eAAG,4BAA4B,EAC/C,KAAK,GAAG;AAE9B,QAAM,MAAM,GAAG,QACbC,gBAAI,IACF,kBAAkB,OAAO,sCAAsC,UAAU,GAC1E,CACF;;AAGH,KAAI,MAAM,QAAQ,mBAAmB;AACnC,MAAI,OAAO,MAAM,OAAO,sBAAsB,SAC5C,OAAM,IAAI,MAAM,qCAAqC;AAGvD,MAAI,MAAM,OAAO,qBAAqB,EACpC,OAAM,IAAI,MAAM,8CAA8C;;;;;;;AASpE,SAAgB,yBAAyB,EACvC,QACA,MACA,aACA,aAOC;AACD,KAAI,QAAQ,WAAW,KAAK,UAAU,KAAK,OAAO,SAAS,GAAG;EAK5D,MAAM,mBACJ,UAAU,MAAM,KAAK,UACjB,OAAO,QAAQ,YAAY,QAAQ,CAAC,QACjC,CAAC,SAAS,UAAU,MAAM,KAAK,QAAQ,KACzC,GACD,OAAO,QAAQ,YAAY,QAAQ,EACvC,QACC,CAAC,KAAK,SACL,0BAA0B,IAAI,YAAY,CAAC,IAC3C,sBAAsB,IAAI,YAAY,CAAC,CAC1C;EAED,MAAM,cAAc,eAAG,GAAG,KAAK;AAE/B,OAAK,SAAS,EACZ,kBAAkB,UAChB,eAAG,GAAGA,gBAAI,KACR,gBAAgB,KAAK,CAAC,SAAS;AAC7B,UAAO,eAAG,aAAa,MAAM,KAAK,aAAa,YAAY;IAC3D,EACFA,gBAAI,IAAI,MAAM,CACf,IACJ;EAED,MAAM,4CAA4B,KAAK,QAAQ;AAC/C,EAAC,KAAa,WAAW,UAAe;GACtC,MAAM,iBAAiBA,gBAAI,KACzB,OAAO,QAAQ,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;AAE1D,QAAI,UAAU,MACZ,QAAO,eAAG,GAAG,MAAM,KAAK;aACf,UAAU,OACnB,QAAO,eAAG,GAAG,MAAM,KAAK;QAExB,OAAM,IAAI,MAAM,iBAAiB,MAAM,cAAc;KAEvD,EACFA,gBAAI,IAAI,KAAK,CACd;GAED,MAAM,YAAY,eAAG;AAMrB,UAJY,kBACRA,gBAAI,KAAK,CAAC,gBAAgB,UAAU,EAAEA,gBAAI,IAAI,KAAK,CAAC,GACpD;;AAQN,EAAC,KAAa,QAAQ,EACpB,KAAK,2BAJyB,KAAK,MAAM,IAKtB,EAAE,EACnB,EACE,MAAM,UACJ,eAAG,IAAIA,gBAAI,KACT,gBAAgB,KAAK,CAAC,SAAS;AAC7B,UAAO,eAAG,GAAG,MAAM,KAAK,KAAK;IAC7B,EACFA,gBAAI,IAAI,OAAO,CAChB,CAAC,IACL,CACF,EACF;;;;;;ACrGL,MAAM,2BAA2B,MAAW;AAC1C,KAAI,OAAO,MAAM,SACf,QAAO;AAGT,KACE,OAAO,KAAK,EAAE,CAAC,MAAM,MACnB;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,MAAM,MAAM,MAAM,EAAE,CACvB,CAED,QAAO;AACT,QAAO;;AAGT,MAAa,2BAgDX,EACA,IACA,QACA,eACA,oBACA,qBACA,qBACA,iBACA,qBAQI;AACJ,SAGE,EACA,OACA,SACA,aAAa,QACb,aAgCI;EACJ,MAAM,cAAc,YAAY;GAAE;GAAI;GAAO,CAAC;AAE9C,MAAI,OAAO,KAAK,YAAY,WAAW,CAAC,WAAW,EACjD,SAAQ,KACN,kCAAkC,MAAM,UAAU,CAAC,kCACpD;EAEH,MAAM,aAAa,OAAO,OAAO,YAAY,WAAW,CAAC;EAEzD,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,OAAO,CAAC;AAEnE,SAAO,cAAc,cAAc,OAAO;GACxC,MAAM,sCAAsB,MAAM,UAAU,CAAC;GAC7C,YAAY,eAAe,SAAS,aAAa;AAC/C,QAAI,CAAC,WAAY;IACjB,MAAM,kBAAmB,QAAgB,WAAW;AACpD,QAAI,CAAC,iBAAiB;AACpB,aAAQ,KACN,wCAAwC,KAAK,UAC3C,QACD,CAAC,iCACH;AACD;;AAIF,uBAAmB;KACjB,UAAU;KACV,QAAQ;KACS;KAClB,CAAC;;GAEJ,cAAc,gBAAgB,EAAE,kBAAkB;IAChD;IACA,QAAQ;IACT,CAAC;GACF,SAAS,MAAM;IACb,MAAM,UAAU,YAAY;IAS5B,MAAM,4BAAY,IAAI,KAOnB;IAIH,MAAM,kBACJ,SACE,IAAI,MAAM,GAAG,EACX,MAAM,QAAQ,MAAM,aAAa;AAC/B,SAEE,OAAQ,OAAe,UAAU,cACjC,SAAS,SACT,SAAS,aACT,SAAS,iBACT,SAAS,UACT,SAAS,aACT,SAAS,WACT,SAAS,cACT,SAAS,aACT,KAAK,UAAU,CAAC,WAAW,UAAU,IACrC,KAAK,UAAU,CAAC,WAAW,QAAQ,IACnC,KAAK,UAAU,CAAC,WAAW,KAAK,IAChC,KAAK,UAAU,CAAC,WAAW,MAAM,IACjC,KAAK,UAAU,CAAC,WAAW,SAAS,IACpC,KAAK,UAAU,CAAC,WAAW,SAAS,CAEpC,QAAQ,OAAe;AAGzB,aAAQ,GAAG,WAAkB;MAC3B,MAAM,MAAO,OAAe,MAAM,GAAG,OAAO;MAC5C,MAAM,eAAe,OAAO,KAAK,wBAAwB;AACzD,UAAI,CAAC,aACH,OAAM,IAAI,YACR,sDACD;AAEH,gBAAU,IAAI,KAAK;OACjB;OACA,iBAAkB,OAAe;OACjC;OACD,CAAC;AACF,aAAO;;OAGZ,CAAC,CACH,IAAI,EAAE;IAET,MAAM,SAAS,OAAO,QAAQ,QAAQ,CAAC,QACpC,KAAK,CAAC,KAAK,YAAY;AAItB,SAAI,gBAAgB,MAAM;MACxB,MAAM,EAAE,QAAQ,iBAAiB,iBAAiB,UAAU,IAC1D,gBAAgB,KACjB;AAED,UAAI,OAAO,aAAa,aAAa,UACnC,cAAa,WAAW,CAAC,OAAO;AAGlC,sBAAgB,OAAO,gBAAgB,KAAK,EAAE,CAAC,GAAG,OAAO;AACzD,aAAO;;AAGT,SAAI,aAAa,OAAO,EAAE;MACxB,MAAM,WAAW,gBAAgB,EAC/B,YAAY,QACb,CAAC;AAEF,UAAI,OAAO,EAAE,MAAM;OACjB,MAAM;OACN,UAAU,YAAa,QAAgB;OACvC,UAAU,CAAC,OAAO;OACnB,CAAC;WAEF,KAAI,OAAO,uCAAuC;MAChD,SAAS;MACT,SAAS,OAAO,YAAY;MAC5B,WAAW;MACX,UAAU,CAAC,OAAO;MACnB,CAAC;AAEJ,YAAO;OAET,EAAE,CAKH;IAED,MAAM,YAAY,OAAO,QAAQ,YAAY,aAAa,EAAE,CAAC,CAAC,QAC3D,KAAK,CAAC,KAAK,WAAW;KACrB,MAAM,iBAAiB,YAAY;MACjC;MACA,OAAQ,MAAc;MACvB,CAAC;KACF,MAAM,WAAW,oBAAoB,EACnC,QAAQ,eAAe,QACxB,CAAC;KACF,MAAM,WAAW,oBAAoB,EACnC,QAAQ,eAAe,QACxB,CAAC;KACF,MAAM,sBAAsB,mBAAmB,EAC7C,OAAO,eAAe,QACvB,CAAC;KAGF,IAAI,WAAW;KACf,IAAI,SAAS;KACb,IAAI,kBAAkB;AACtB,SAAI,iBAAiBC,iBAAK;AACxB,eAAS;AACT,iBAAW,CAAC,MAAM,cAAc,OAAO,WAAW,OAAO,QAAQ;AACjE,wBAAkB;;KAGpB,MAAM,aAAa,eAAoB,aAAkB;AACvD,0BAAoB,mBAAmB;OACrC,UAAU;OACV,QAAQ;OACT,CAAC;AACF,0BAAoB,mBAAmB;OACrC,UAAU;OACV,QAAQ;OACT,CAAC;;AAMJ,SAAI,gBAAgB,MAAM;MACxB,MAAM,EAAE,QAAQ,iBAAiB,iBAAiB,UAAU,IAC1D,gBAAgB,KACjB;AAED,UAAI,OAAO,aAAa,aAAa,UACnC,cAAa,WAAW;AAG1B,UAAI,OAAO,aAAa,cAAc,WACpC,cAAa,YAAY;AAG3B,sBAAgB,OAAO,gBAAgB,KAAK,EAAE,CAAC,GAAG,OAAO;AACzD,aAAO;;KAGT,MAAM,OAAO;MACX,OAAO,EAAE,IAAI;OAAE,MAAM;OAAU,UAAU;OAAO,CAAC;MACjD,SAAS,EAAE,IAAI;OAAE,MAAM;OAAU,UAAU;OAAO,CAAC;MACnD,GAAI,SACA;OACE,QAAQ,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;OACtC,OAAO,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;OACtC,GACD,EAAE;MACN,QAAQ,EAAE,IAAI,OAAO,EAAE,UAAU,OAAO,CAAC;MAC1C;AAED,SAAI,CAAC,QAAQ,WAAW,CAAC,OACvB,QAAQ,KAAa;AAGvB,KAAC,IAAY,OAAO,EAAE,SACpB,KACA;MACE;MACA;MACA;MACA,aAAa,WAAW,kBAAU,OAAO,eAAe,OAAO,CAAC,mBAAmB,kBAAU,SAAS,YAAY,OAAO;MACzH,QAAQ,MAAW,QAAa;AAE9B,cAAO,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;AAEvC,WAAI,OACF,0BAAyB;QACvB;QACA;QACA,aAAa;QACb,WACE,IAAI,UAAU,eAAe,QAAQ,OAAO,WAAW;QAC1D,CAAC;OAGJ,MAAM,SAAS,IAAI,UAAU,eAAe,QACzC,OAAO,WAAW,CAClB,MAAM;QACL,OAAO,KAAK;QACZ,OAAO,KAAK;QACZ,QAAQ,KAAK;QACd,CAAC,CAAC,MAAM;AAEX,WAAI,KAAK,OACP,CAAC,OAAe,SAAS,KAAK;AAGhC,WAAI,KAAK,QACP,CAAC,OAAe,UAAU,KAAK;AAGjC,cAAO;;MAEV,CACF;AACD,YAAO;OAET,EAAE,CAIH;AAED,QAAI,QAAQ,SAAS;AACnB,SAAI,OAAO,gBACT,OAAM,IAAI,MACR,oDACE,YAAY,SACZ,6GACH;AAGH,YAAO,kBAAkB,EAAE,MAAM;MAC/B,aACE;MACF,UAAU;MACV,UAAU,QAAQ,MAAM,KAAK,SAC1B,OAAe;MACnB,CAAC;;AAGJ,WAAO;KACL,GAAG;KACH,GAAG;KACH,GAAG;KACJ;;GAEJ,CAAC;;;;;;AC1bN,MAAM,sCAAsC;AAC5C,MAAM,gCAAgC;AACtC,MAAM,gCAAgC;AACtC,MAAM,gCAAgC;AAkBtC,MAAa,wBAMX,EACA,oBACsE;CACtE,MAAM,SAAS,+CACE,GAAG,cAAc,mCAChB;CAElB,MAAM,sBAEJ,EACA,YAGI;EAGJ,SAAS,cAAc,EACrB,QACA,WACA,mBAKC;GACD,IAAI;AAEJ,WAAQ,QAAR;IACE,KAAK;AACH,iBAAY;AACZ;IACF,KAAK;AACH,iBAAY;AACZ;IACF,KAAK;AACH,iBAAY;AACZ;IACF,QACE,OAAM,IAAI,MAAM,mBAAmB,SAAS;;AAGhD,UAAO,GAAG,oCAAoC,GAAG,YAC/C,kBAAkB,IAAI,oBAAoB,GAC3C,GAAG;;AAIN,SAAO;GAIL,mBAAmB,EACjB,UACA,QACA,mBAKC;IACD,MAAM,MAAM,cAAc;KACxB,WAAW,MAAM,UAAU;KAC3B;KACA;KACD,CAAC;AACF,aAAS,SAAS,IAAI;;GAKxB,UAAU;IACR,MAAM,MAAM,cAAc;KACxB,WAAW,MAAM,UAAU;KAC3B,QAAQ;KACT,CAAC;AACF,WAAO,OAAO,QAAQ,IAAI;;GAM5B,UAAU;IACR,MAAM,MAAM,cAAc;KACxB,WAAW,MAAM,UAAU;KAC3B,QAAQ;KAGT,CAAC;AACF,WAAO,OAAO,QAAQ,IAAI;;GAK5B,QAAQ,iBAAqD;IAI3D,MAAM,QAHc,MAAM,QAAQ,gBAAgB,GAC9C,kBACA,CAAC,gBAAgB,EACI,KAAK,oBAC5B,cAAc;KACZ,WAAW,MAAM,UAAU;KAC3B,QAAQ;KACR;KACD,CAAC,CACH;IACD,MAAM,aAAa,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC;AAC5C,SAAK,MAAM,OAAO,WAChB,QAAO,QAAQ,IAAI;;GAGxB;;AAGH,QAAO;EACL;EACA;EACD;;;;;ACrIH,MAAa,0BAkCX,EACA,IACA,eACA,QACA,qBACA,qBACA,yBAMI;AACJ,SAA0D,EACxD,OACA,aAAa,QACb,aAAa,aAgBT;EACJ,MAAM,WAAW,oBAAoB,EAC5B,OACR,CAAC;EACF,MAAM,WAAW,oBAAoB,EAC5B,OACR,CAAC;EACF,MAAM,cAAc,YAAY;GAC9B;GACA;GACD,CAAC;EACF,MAAM,kBAAkB,OAAO,OAAO,YAAY,WAAW,CAAC;EAE9D,MAAM,EAAE,uBAAuB,mBAAmB,EAAS,OAAO,CAAC;AAEnE,SAAO,cAAc,aAAa,MAAM;GACtC,MAAM,WAAW;IACf,OAAO,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;KAAO,CAAC;IACjD,SAAS,EAAE,IAAI;KAAE,MAAM;KAAU,UAAU;KAAO,CAAC;IACnD,OAAO,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;IACrC,QAAQ,EAAE,IAAI,IAAI,EAAE,UAAU,OAAO,CAAC;IACtC,QAAQ,EAAE,IAAI,OAAO,EAAE,UAAU,OAAO,CAAC;IAC1C;AAED,OAAI,CAAC,QAAQ,QACX,QAAQ,SAAiB;AAG3B,UAAO;KACJ,kBAAU,OAAO,MAAM,UAAU,CAAC,GAAG,EAAE,aAAa;KACnD,MAAM,CAAC,MAAM;KACb,UAAU;KACV,mBAAmB;KACnB,aAAa,YAAY,kBAAU,OAAO,MAAM,UAAU,CAAC;KAC3D,YAAY,eAAe,OAAO,OAAO,MAAM,UAAU;AACvD,yBAAmB;OACjB,UAAU;OACV,QAAQ;OACT,CAAC;AACF,yBAAmB;OACjB,UAAU;OACV,QAAQ;OACT,CAAC;;KAEJ,MAAM;KACN,UAAU,OAAO,OAAO,MAAM,KAAK,UAAU;AAG3C,mBAAa,KAAK;AAElB,+BAAyB;OACvB;OACA;OACA;OACA,WAAW,IAAI,UAAU,OAAO,OAAO,WAAW;OACnD,CAAC;MAEF,MAAM,aAAa,yBAAyB,KAAK;MACjD,MAAM,SAAS,IAAI,UAAU,OAC1B,OAAO,WAAW,CAClB,MAAM,WAAkB,CAAC,MAAM;AAElC,UAAI,WAAW,OACb,CAAC,OAAe,SAAS,WAAW;AAGtC,UAAI,WAAW,QACb,CAAC,OAAe,UAAU,WAAW;MAGvC,MAAM,gBAAgB,MAAM,OAAc;AAE1C,UAAK,OAAe,QAClB,eAAc,UAAW,OAAe;AAG1C,UACE,QAAQ,WACR,KAAK,UACL,KAAK,OAAO,SAAS,KACrB,QAAQ,kBAER,QAAO,GAAG,YAAY,OAAO,OAAO;AAClC,WAAI,aAAa,GAAG,CAClB,OAAM,GAAG,QACPC,gBAAI,IACF,2BAA2B,OAAO,kBAAkB,GACrD,CACF;WAED,SAAQ,KACN,oEACD;AAEH,cAAQ,GAAG,MAAc,OAAO,SAAS,cAAc;QACvD;AAGJ,aAAQ,GAAG,MAAc,OAAO,SAAS,cAAc;;KAE1D,CAAC;KACD,kBAAU,SAAS,MAAM,UAAU,CAAC,GAAG,EAAE,aAAa;KACrD,MAAM;KACN,UAAU;KACV,mBAAmB;KACnB,aAAa,gBAAgB,kBAAU,SAAS,MAAM,UAAU,CAAC,CAAC;KAClE,MAAM,EACJ,IAAI,EAAE,IAAI,GAAG,EAAE,UAAU,MAAM,CAAC,EACjC;KACD,UAAU,OAAO,OAAO,MAAM,KAAK,UAAU;AAC3C,mBAAa,KAAK;MAElB,MAAM,SAAU,IAAI,UAAkB,OACnC,OAAO,WAAW,CAClB,MAAM,EAAE,OAAO,GAAG,gBAAgB,OAAO,KAAK,IAAI,EAAE,CAAC,CACrD,MAAM;MACT,MAAM,IAAI,MAAM,OAAO;AAEvB,UAAI,OAAO,QACT,GAAE,UAAU,OAAO;AAGrB,aAAQ,GAAG,MAAc,OACtB,UAAU,EAAE,CACZ,KAAK,sBAAsB;;KAEjC,CAAC;IACH;IACD;;;;;;AChJN,SAAgB,+BAA+B,eAAoB;CACjE,MAAM,wBAAwB,cAC3B,SAAS,wBAAwB,CACjC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,KAAK;EACX,IAAI,EAAE,KAAK;EACX,IAAI,EAAE,KAAK;EACX,KAAK,EAAE,KAAK;EACZ,IAAI,EAAE,KAAK;EACX,KAAK,EAAE,KAAK;EACZ,IAAI,EAAE,SAAS;EACf,OAAO,EAAE,SAAS;EAClB,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,SAAS;EAC1B,gBAAgB,EAAE,SAAS;EAC3B,eAAe,EAAE,SAAS;EAC1B,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,sBAAsB,EAC9B,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,sBAAsB,EAC9B,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,uBACP,CAAC;EACH,GACF,CAAC;CAEJ,MAAM,0BAA0B,cAC7B,SAAS,0BAA0B,CACnC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,OAAO;EACb,IAAI,EAAE,OAAO;EACb,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,OAAO;EACd,IAAI,EAAE,OAAO;EACb,KAAK,EAAE,OAAO;EACd,IAAI,EAAE,WAAW;EACjB,OAAO,EAAE,WAAW;EACpB,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,WAAW;EAC5B,gBAAgB,EAAE,WAAW;EAC7B,eAAe,EAAE,WAAW;EAC5B,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,wBAAwB,EAChC,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,wBAAwB,EAChC,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,yBACP,CAAC;EACH,GACF,CAAC;CAEJ,MAAM,2BAA2B,cAC9B,SAAS,2BAA2B,CACpC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,QAAQ;EACd,IAAI,EAAE,QAAQ;EACd,IAAI,EAAE,QAAQ;EACd,KAAK,EAAE,QAAQ;EACf,IAAI,EAAE,QAAQ;EACd,KAAK,EAAE,QAAQ;EACf,IAAI,EAAE,YAAY;EAClB,OAAO,EAAE,YAAY;EACrB,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,YAAY;EAC7B,gBAAgB,EAAE,YAAY;EAC9B,eAAe,EAAE,YAAY;EAC7B,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,yBAAyB,EACjC,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,yBAAyB,EACjC,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,0BACP,CAAC;EACH,GACF,CAAC;CAEJ,MAAM,yBAAyB,cAC5B,SAAS,yBAAyB,CAClC,UAAU,EACT,SAAS,OAAY;EACnB,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC9B,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC7B,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;EAC9B,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAClC,MAAM,EAAE,QAAQ;EAChB,OAAO,EAAE,QAAQ;EACjB,SAAS,EAAE,QAAQ;EACnB,UAAU,EAAE,QAAQ;EACpB,QAAQ,EAAE,SAAS;EACnB,WAAW,EAAE,SAAS;EACtB,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC1C,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC3C,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;EAC1C,KAAK,EAAE,MAAM,EACX,MAAM,CAAC,uBAAuB,EAC/B,CAAC;EACF,IAAI,EAAE,MAAM,EACV,MAAM,CAAC,uBAAuB,EAC/B,CAAC;EACF,KAAK,EAAE,MAAM,EACX,MAAM,wBACP,CAAC;EACH,GACF,CAAC;;;;;AChMN,MAAa,aAAa;;;;;;;;;;;;;;;;;ACK1B,MAAa,eAAe,OAAgC,EAC1D,SACA,UACA,cAKI;AACJ,QAAO,MAAM,MAET,MAAM,QAAQ,IACZ,QAAQ,KAAK,MACX,EAAE;EACA;EACU;EACX,CAAC,CACH,CACF,EACD,QAAQ,KAAK,QAAQ;AACrB,OAAK,MAAM,WAAW,IACpB,KAAI,IAAI,QAAQ;AAElB,SAAO;oBAEN,IAAI,KAAQ,CAAC,CACjB;;;;;AC9BH,MAAa,kBAAkB;AAE/B,IAAa,uBAAb,cAEUC,wBAAkB;CAC1B,AAAQ;CACR,AAAQ;CAER,AAAS,aAAa,YAA8B;AAClD,OAAK,SAAS,KAAK,QAAQ,QAAQ,MAAM;AACzC,OAAK,gBAAgB,KAAK,QAAQ,QAAQ,MAAM;AAChD,SAAO;;CAGT,AAAS,YACP,UACA,aACyD;AACzD,SAAO,OAAO,QAAQ,MAAM,SAAS,SAAS;GAE5C,IAAI;GACJ,MAAM,YAAY,aAAa;AAE/B,OAAI,UAAU,SAAS,OACrB,WACE,UAAU,MAAM,IAAI,cAAc,cAAc;YACzC,UAAU,SAAS,SAC5B,WAAU,UAAU,IAAI,cAAc,cAAc;AAGtD,OAAI,CAAC,WAAW,CAAC,MAAM,QAAQ,QAAQ,IAAI,QAAQ,WAAW,EAE5D,QAAO,SAAS,QAAQ,MAAM,SAAS,KAAK;GAG9C,MAAM,aAAa,OAAO,SAAgB;IACxC,MAAM,WAAW,MAAM,SAAS,QAAQ,MAAM,SAAS,KAAK;IAC5D,MAAM,oBAAoB,MAAM,QAAQ,SAAS,GAC7C,WACA,CAAC,SAAS;IACd,MAAM,aAAa,MAAM,QAAQ,QAAQ,GAAG,UAAU,CAAC,QAAQ;AAC/D,UAAM,aAAa,iBAAiB,WAAW,OAAO;IAEtD,MAAM,UAAU,MAAM,aAAa;KACjC,SAAS;KACT,UAAU;KACV;KACD,CAAC;AACF,UAAM,aAAa,mBAAmB,QAAQ,OAAO;AAGrD,QAAI,MAAM,QAAQ,SAAS,CACzB,QAAO;AAKT,WAAO,QAAQ,MAAM;;AAGvB,OAAI,KAAK,UAAU,KAAK,cACtB,QAAO,KAAK,OAAO,gBACjB,iBAAiB,YAAY,QAC7B,OAAO,SAAS;AACd,QAAI;AACF,YAAO,MAAM,WAAW,KAAK;cACrB;AACR,UAAK,KAAK;;KAGf;OAED,QAAO,YAAY;;;;AAM3B,IAAI,aAAa;AACjB,SAAgB,+BAA+B;AAC7C,KAAI,CAAC,YAAY;AACf,uBAAc,eAAe,YAAY,qBAAqB;AAC9D,eAAa;;;;;;ACjEjB,MAAa,uBAMX,EACA,IACA,uBACA,QACA,cACA,WAGI;CACJ,MAAM,aACJ,MAAM,WAAW,KAAK,uEACS,KAAK,QAAQ,KAAK,QAAQ,GACrD;AAEN,+BAA8B;CAC9B,MAAM,gBAAgB,IAAIC,qBAwBvB;EACD,GAAG;EACH,SAAS;GACP;GACAC;GACAC;GACAC;GACA,GAAI,cAAc,WAAW,EAAE;GAChC;EACD,SAAS;GACP,QAAQ;GACR,WAAW,GAAG,EAAE;GAChB,eAAe,OAAO;AAEpB,WAAO;KACL,SAAS,OAAO,OAAQ,MAAc,OAAO,IAAI,kBAAkB,EAAE;KACrE,aAAa,OAAO,OACjB,MAAc,OAAO,IAAI,kBAAkB,EAC7C,CAAC,QAAQ,MAAW,EAAE,QAAQ;KAChC;;GAEJ;EACD,oBAAoB,EAClB,yEAAiC,MAAM,aAAa;AAClD,UAAO,OAAO,UAAU,KAAK;IAC7B,EACH;EACD,yBAAyB;EACzB,SAAS;GACP,SAAS,MAAM,WAAW,mDAAuB,OAAO,SAAS;GACjE,MAAM,cACD,UAAU,YAAY,WAAW,UAAU,QAAQ,IACnD,aAAa;GACnB;EACD;EACD,CAAC;AAEF,eAAc,cAAc,QAAQC,6BAAa;AACjD,eAAc,cAAc,QAAQC,6BAAa;AACjD,eAAc,cAAc,YAAYC,oCAAoB;AAC5D,gCAA+B,cAAc;AAE7C,KAAI,CAAC,uBAAuB,MAC1B,eAAc,UAAU,EAAE,CAAC;AAG7B,KAAI,CAAC,uBAAuB,aAC1B,eAAc,iBAAiB,EAAE,CAAC;AAGpC,KAAI,CAAC,uBAAuB,SAC1B,eAAc,aAAa,EAAE,CAAC;AAGhC,QAAO,EAAE,eAAe;;;;;AC9F1B,MAAa,UAOX,gBACG;AACH,KAAI,CAAC,YAAY,GAAG,EAAE,OACpB,OAAM,IAAI,YAAY;;;;;;;;;;;;EAYxB;AAGA,KAAI,CAAC,YAAY,GAAG,EAAE,UACpB,OAAM,IAAI,YAAY;;;;;;;;;;;;EAYxB;AAIA,KAAI,CAAC,YAAY,QACf,aAAY,UAAU;EAAC;EAAQ;EAAU;EAAS;AAGpD,KAAI,YAAY,iBAAiB,OAC/B,aAAY,eAAe;AAG7B,KAAI,YAAY,QAAQ,QACtB,wBAAuB,YAAY;AAGrC,KAAI,YAAY,MAAM,WAAW,CAAC,YAAY,KAAK,OACjD,aAAY,KAAK,SAASC,yBAAM,UAC9B,kBACAC,QACD;CAGH,MAAM,iBAAiB,qBAMrB,YAAY;CAEd,MAAM,UAAU,sBAOd;EACA,GAAG;EACH;EACD,CAAC;CAEF,MAAM,EAAE,oBAAoB,WAAW,qBAMrC,EACA,GAAG,aACJ,CAAC;CAEF,MAAM,EAAE,kBAAkB,oBAMxB;EAAE,GAAG;EAAa;EAAQ,CAAC;CAE7B,MAAM,QAAQ,sBAOZ;EACA,GAAG;EACH;EACD,CAAC;CAEF,MAAM,WAAW,0BAQf;EACA,GAAG;EACH;EACA,iBAAiB;EAClB,CAAC;CAEF,MAAM,WAAW,0BAOf;EACA,GAAG;EACH;EACD,CAAC;CAEF,MAAM,SAAS,wBAYb;EACA,GAAG;EACH;EACA;EACA,qBAAqB;EACrB,qBAAqB;EACrB,iBAAiB;EACjB;EACD,CAAC;CAEF,MAAM,QAAQ,uBAUZ;EACA,GAAG;EACH;EACA,qBAAqB;EACrB,qBAAqB;EACrB;EACD,CAAC;CAEF,MAAM,aAAa,4BAA4B;EAC7C,GAAG;EACH;EACA,qBAAqB;EACrB;EACD,CAAC;CAEF,MAAM,cAAcC,wBAAW,cAAc,UAAU,CAAC;CAExD,MAAM,cACJ,SAWG;EACH,MAAM,gBACJ,MAAM,iBAAiB,SAAS,KAAK,aAAa;AAEpD,sCAAsC;GACpC,GAAG;GACH,UAAU;GACV,QAAQ,aAAa;GACrB;GACA,SAAS;IACP,GAAI,MAAM,WAAW,EAAE;IACvB,GAAI,gBACA,EAAE,GACF,0EAA0B,sDAAsB,CAAC;IACrD,YAAY,MAAM,UACb,EACC,YAAY,EAAE,cAAc,gBAAgB;AAC1C,mBAAc,YACZ,YAAY,KAAM,OAAQ,gBACxBC,wCAAU,SACV,EACE,YAAY;OACTC,6CAAe,iBACd,QAAQ,iBAAiB;OAC1BA,6CAAe,SAAS,QAAQ;MAClC,EACF,EACD,OAAO,SAAS;AACd,UAAI;OACF,MAAM,SAAS,MAAM,UAAU,QAAQ;AAEvC,WACE,UACA,YAAY,UACZ,OAAO,QAAQ,QACf;AACA,aAAK,MAAM,SAAS,OAAO,OACzB,MAAK,gBAAgB,MAAM;AAE7B,aAAK,UAAU,EAAE,MAAMC,kCAAe,OAAO,CAAC;;AAGhD,cAAO;eACA,OAAO;AACd,WAAI,iBAAiB,MACnB,MAAK,gBAAgB,MAAM;AAE7B,YAAK,UAAU,EAAE,MAAMA,kCAAe,OAAO,CAAC;AAC9C,aAAM;gBACE;AACR,YAAK,KAAK;;OAGf,CACF;OAEJ,GACD;IACL,CAAC,OAAO,QAAQ;GAClB,CAAC;;CAGJ,MAAM,cACJ,SACG;AACH,MAAI,KAAK,QACP,uBAAM,KAAK,SAAS,uBAAuB;AAE7C,MAAI,KAAK,cAAc;GACrB,MAAM,kBAAkB,KAAK;AAC7B,QAAK,gBAAgB,WAAW;IAC9B,MAAM,OAAOL,yBAAM,eAAe;AAElC,SAAK,MAAM,SAAS,OAClB,OAAM,gBAAgB,MAAM;AAE9B,UAAM,UAAU,EAAE,MAAMK,kCAAe,OAAO,CAAC;AAC/C,WAAO,gBAAgB,OAAO;;;AAGlC,+BAAe;GACb,GAAG;GACH,QAAQ,aAAa;GACrB;GACA,aAAa,QAAQ;IACnB,MAAM,OAAOL,yBAAM,eAAe;AAElC,SAAK,MAAM,SAAS,OAClB,OAAM,gBAAgB,MAAM;AAE9B,UAAM,UAAU,EAAE,MAAMK,kCAAe,OAAO,CAAC;AAE/C,WAAO,IAAI,SAAS,OAAO,GAAG,SAAS,EACrC,QAAQ,KACT,CAAC;;GAEL,CAAC;;AAeJ,QAAO;EAiBL;EAIA;EAeA;EAcA;EAIA;EAIA;EAIA;EAKA;EAIA,QAAQ;EAMR;EAKA,eA9FoB,yBAOpB;GACA,GAAG;GACH;GACD,CAAC;EAwFA;EACD"}
|