convex-verify 1.1.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +148 -80
  2. package/dist/core/index.d.mts +14 -55
  3. package/dist/core/index.d.ts +14 -55
  4. package/dist/core/index.js +492 -92
  5. package/dist/core/index.js.map +1 -1
  6. package/dist/core/index.mjs +491 -92
  7. package/dist/core/index.mjs.map +1 -1
  8. package/dist/index.d.mts +9 -6
  9. package/dist/index.d.ts +9 -6
  10. package/dist/index.js +378 -271
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +378 -267
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/types-B8ZkLuJ2.d.mts +141 -0
  15. package/dist/types-B8ZkLuJ2.d.ts +141 -0
  16. package/dist/utils/index.d.mts +3 -2
  17. package/dist/utils/index.d.ts +3 -2
  18. package/dist/utils/index.js +1 -1
  19. package/dist/utils/index.js.map +1 -1
  20. package/dist/utils/index.mjs +1 -1
  21. package/dist/utils/index.mjs.map +1 -1
  22. package/dist/verifyConfig-CTrtqMr_.d.ts +94 -0
  23. package/dist/verifyConfig-Kn3Ikj00.d.mts +94 -0
  24. package/package.json +1 -16
  25. package/dist/configs/index.d.mts +0 -51
  26. package/dist/configs/index.d.ts +0 -51
  27. package/dist/configs/index.js +0 -38
  28. package/dist/configs/index.js.map +0 -1
  29. package/dist/configs/index.mjs +0 -11
  30. package/dist/configs/index.mjs.map +0 -1
  31. package/dist/plugin-BOb1Kw1A.d.ts +0 -47
  32. package/dist/plugin-DlsboiCF.d.mts +0 -47
  33. package/dist/plugins/index.d.mts +0 -85
  34. package/dist/plugins/index.d.ts +0 -85
  35. package/dist/plugins/index.js +0 -312
  36. package/dist/plugins/index.js.map +0 -1
  37. package/dist/plugins/index.mjs +0 -284
  38. package/dist/plugins/index.mjs.map +0 -1
  39. package/dist/transforms/index.d.mts +0 -38
  40. package/dist/transforms/index.d.ts +0 -38
  41. package/dist/transforms/index.js +0 -46
  42. package/dist/transforms/index.js.map +0 -1
  43. package/dist/transforms/index.mjs +0 -19
  44. package/dist/transforms/index.mjs.map +0 -1
  45. package/dist/types-DvJMYubf.d.mts +0 -151
  46. package/dist/types-DvJMYubf.d.ts +0 -151
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/plugin.ts","../src/core/verifyConfig.ts","../src/core/types.ts","../src/transforms/defaultValuesConfig.ts","../src/configs/protectedColumnsConfig.ts","../src/plugins/uniqueRowConfig.ts","../src/utils/helpers.ts","../src/plugins/uniqueColumnConfig.ts"],"sourcesContent":["// =============================================================================\n// Core\n// =============================================================================\n\nexport { verifyConfig } from './core';\nexport { createExtension, isExtension, runExtensions } from './core';\nexport type {\n\tExtensionContext,\n\tExtensionInput,\n\tExtensionInputForSchema,\n\tExtension,\n\tExtensionRecord,\n\tSchemaExtension,\n} from './core';\nexport type {\n\t// Utility types\n\tPrettify,\n\tMakeOptional,\n\t// OnFail types\n\tOnFailArgs,\n\tOnFailCallback,\n\t// VerifyConfig types\n\tVerifyConfigInput,\n\t// Type extraction helpers\n\tExtractDefaultValuesConfig,\n\tOptionalKeysForTable,\n\tHasKey,\n\tExtractProtectedColumnsConfig,\n\tProtectedKeysForTable,\n} from './core';\n\n// =============================================================================\n// Transforms\n// =============================================================================\n\nexport { defaultValuesConfig } from './transforms';\nexport type { DefaultValuesConfigData } from './transforms';\n\n// =============================================================================\n// Configs\n// =============================================================================\n\nexport { protectedColumnsConfig } from './configs';\nexport type { ProtectedColumnsConfigData } from './configs';\n\n// =============================================================================\n// Built-in Extensions\n// =============================================================================\n\nexport { uniqueRowConfig, uniqueColumnConfig } from './plugins';\nexport type {\n\tUniqueRowConfigData,\n\tUniqueRowConfigEntry,\n\tUniqueRowConfigOptions,\n\tUniqueColumnConfigData,\n\tUniqueColumnConfigEntry,\n\tUniqueColumnConfigOptions,\n} from './plugins';\n\n// =============================================================================\n// Utils\n// =============================================================================\n\nexport { getTableIndexes, constructColumnData, constructIndexData } from './utils';\nexport { normalizeIndexConfigEntry } from './utils';\nexport type { NormalizedIndexConfig, IndexConfigBaseOptions, IndexConfigEntry } from './utils';\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericMutationCtx,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from \"convex/server\";\nimport { GenericId } from \"convex/values\";\n\nimport { DMGeneric, OnFailCallback } from \"./types\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\ntype MutationCtx<DM extends DMGeneric = DMGeneric> = Omit<GenericMutationCtx<DM>, never>;\n\nexport type InsertExtensionContext<\n\tTN extends string = string,\n\tDM extends DMGeneric = DMGeneric,\n\tS extends SchemaDefinition<GenericSchema, boolean> = SchemaDefinition<GenericSchema, boolean>,\n> = {\n\tctx: MutationCtx<DM>;\n\ttableName: TN;\n\toperation: \"insert\";\n\tonFail?: OnFailCallback<any>;\n\tschema: S;\n\tpatchId?: undefined;\n};\n\nexport type PatchExtensionContext<\n\tTN extends string = string,\n\tDM extends DMGeneric = DMGeneric,\n\tS extends SchemaDefinition<GenericSchema, boolean> = SchemaDefinition<GenericSchema, boolean>,\n> = {\n\tctx: MutationCtx<DM>;\n\ttableName: TN;\n\toperation: \"patch\";\n\tpatchId: GenericId<TN>;\n\tonFail?: OnFailCallback<any>;\n\tschema: S;\n};\n\nexport type ExtensionContext<\n\tTN extends string = string,\n\tDM extends DMGeneric = DMGeneric,\n\tS extends SchemaDefinition<GenericSchema, boolean> = SchemaDefinition<GenericSchema, boolean>,\n> = InsertExtensionContext<TN, DM, S> | PatchExtensionContext<TN, DM, S>;\n\nexport type ExtensionInput<\n\tTData = unknown,\n\tTContext = ExtensionContext,\n> = TContext & {\n\tdata: TData;\n};\n\ntype ExtensionInputBase = {\n\tdata: unknown;\n};\n\ntype DataModelForSchema<S extends SchemaDefinition<GenericSchema, boolean>> =\n\tDataModelFromSchemaDefinition<S>;\n\nexport type ExtensionInputForSchema<S extends SchemaDefinition<GenericSchema, boolean>> = {\n\t[TN in TableNamesInDataModel<DataModelForSchema<S>>]:\n\t\t| ExtensionInput<\n\t\t\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>,\n\t\t\t\tInsertExtensionContext<TN, DataModelForSchema<S>, S>\n\t\t >\n\t\t| ExtensionInput<\n\t\t\t\tPartial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>,\n\t\t\t\tPatchExtensionContext<TN, DataModelForSchema<S>, S>\n\t\t >;\n}[TableNamesInDataModel<DataModelForSchema<S>>];\n\nexport type ExtensionVerify<TInput extends ExtensionInputBase = ExtensionInput> = (\n\tinput: TInput,\n) => MaybePromise<TInput[\"data\"]>;\n\nexport type ExtensionRecord<\n\tTType extends string = string,\n\tTConfig = unknown,\n\tTInput extends ExtensionInputBase = ExtensionInput,\n> = {\n\treadonly _type: TType;\n\treadonly config?: TConfig;\n\tverify(input: TInput): MaybePromise<TInput[\"data\"]>;\n};\n\nexport type Extension<TInput extends ExtensionInputBase = ExtensionInput> = ExtensionRecord<\n\t\"extension\",\n\tundefined,\n\tTInput\n>;\n\nexport type SchemaExtension<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tTType extends string = string,\n\tTConfig = unknown,\n> = ExtensionRecord<TType, TConfig, ExtensionInputForSchema<S>>;\n\nexport function createExtension<const S extends SchemaDefinition<GenericSchema, boolean>>(\n\tverify: ExtensionVerify<ExtensionInputForSchema<S>>,\n): Extension<ExtensionInputForSchema<S>>;\nexport function createExtension(verify: ExtensionVerify): Extension;\nexport function createExtension(\n\tverify: (input: any) => MaybePromise<any>,\n): Extension {\n\treturn {\n\t\t_type: \"extension\",\n\t\tverify(input) {\n\t\t\treturn verify(input);\n\t\t},\n\t};\n}\n\nexport function isExtension(value: unknown): value is ExtensionRecord {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"verify\" in value &&\n\t\ttypeof (value as { verify?: unknown }).verify === \"function\"\n\t);\n}\n\nexport async function runExtensions<\n\tTExtensionInput extends ExtensionInputBase,\n\tTInput extends TExtensionInput,\n>(\n\textensions: readonly ExtensionRecord<string, unknown, TExtensionInput>[],\n\tinput: TInput,\n): Promise<TInput[\"data\"]> {\n\tlet verifiedData: unknown = input.data;\n\n\tfor (const extension of extensions) {\n\t\tverifiedData = await extension.verify({\n\t\t\t...input,\n\t\t\tdata: verifiedData,\n\t\t} as TExtensionInput);\n\t}\n\n\treturn verifiedData as TInput[\"data\"];\n}\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericMutationCtx,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from \"convex/server\";\nimport { GenericId } from \"convex/values\";\n\nimport { runExtensions, SchemaExtension } from \"./plugin\";\nimport {\n\tHasKey,\n\tMakeOptional,\n\tOnFailCallback,\n\tOptionalKeysForTable,\n\tProtectedKeysForTable,\n\tVerifyConfigInput,\n} from \"./types\";\n\n/**\n * Extended config input that includes optional extensions.\n */\ntype VerifyConfigInputWithExtensions<S extends SchemaDefinition<GenericSchema, boolean>> =\n\tVerifyConfigInput & {\n\t/**\n\t * Unique row validation config.\n\t * Enforces uniqueness across multiple columns using composite indexes.\n\t *\n\t * Can also be added to the `extensions` array.\n\t */\n\tuniqueRow?: SchemaExtension<S, \"uniqueRow\", any>;\n\n\t/**\n\t * Unique column validation config.\n\t * Enforces uniqueness on single columns using indexes.\n\t *\n\t * Can also be added to the `extensions` array.\n\t */\n\tuniqueColumn?: SchemaExtension<S, \"uniqueColumn\", any>;\n\n\t/**\n\t * Additional extensions to run after transform configs (defaultValues, etc.).\n\t * These extensions can validate data, transform/mutate it, or both.\n\t * Custom extensions run before built-in uniqueness extensions so the built-ins\n\t * validate the final transformed payload.\n\t * Extensions run in order; each receives the (possibly transformed) output of the previous.\n\t *\n\t * Built-in extensions (uniqueRow, uniqueColumn) can be added here\n\t * as an alternative to using their dedicated config keys when you need\n\t * explicit ordering.\n\t */\n\textensions?: SchemaExtension<S>[];\n};\n\n/**\n * Configure type-safe insert and patch functions with validation and transforms.\n *\n * @param schema - Your Convex schema definition\n * @param configs - Configuration object with transforms, configs, and extensions\n * @returns Object with `insert`, `patch`, and `dangerouslyPatch` functions\n */\nexport const verifyConfig = <\n\tS extends GenericSchema,\n\tSD extends SchemaDefinition<S, boolean>,\n\tconst VC extends VerifyConfigInputWithExtensions<SD>,\n>(\n\t_schema: SD,\n\tconfigs: VC,\n) => {\n\ttype DataModel = DataModelFromSchemaDefinition<SD>;\n\ttype SchemaScopedExtension = SchemaExtension<SD>;\n\tconst customExtensions = configs.extensions ?? [];\n\tconst builtInExtensions: SchemaScopedExtension[] = [\n\t\t...(configs.uniqueRow ? [configs.uniqueRow] : []),\n\t\t...(configs.uniqueColumn ? [configs.uniqueColumn] : []),\n\t];\n\tconst extensions: SchemaScopedExtension[] = [...customExtensions, ...builtInExtensions];\n\tconst protectedColumns = configs.protectedColumns?.config ?? {};\n\n\tconst stripProtectedPatchColumns = <T extends Record<string, any>>(tableName: string, data: T) => {\n\t\tconst protectedKeys = protectedColumns[tableName] ?? [];\n\n\t\tif (protectedKeys.length === 0) {\n\t\t\treturn {\n\t\t\t\tfilteredData: data,\n\t\t\t\tremovedColumns: [] as string[],\n\t\t\t};\n\t\t}\n\n\t\tconst removedColumns = protectedKeys.filter((key) => key in data).map(String);\n\t\tif (removedColumns.length === 0) {\n\t\t\treturn {\n\t\t\t\tfilteredData: data,\n\t\t\t\tremovedColumns,\n\t\t\t};\n\t\t}\n\n\t\tconst filteredData = Object.fromEntries(\n\t\t\tObject.entries(data).filter(([key]) => !protectedKeys.includes(key as string))\n\t\t) as T;\n\n\t\treturn {\n\t\t\tfilteredData,\n\t\t\tremovedColumns,\n\t\t};\n\t};\n\n\tconst insert = async <\n\t\tconst TN extends TableNamesInDataModel<DataModel>,\n\t\tconst D extends DocumentByName<DataModel, TN>,\n\t>(\n\t\tctx: Omit<GenericMutationCtx<DataModel>, never>,\n\t\ttableName: TN,\n\t\tdata: HasKey<VC, \"defaultValues\"> extends true\n\t\t\t? MakeOptional<\n\t\t\t\t\tWithoutSystemFields<D>,\n\t\t\t\t\tOptionalKeysForTable<VC, TN> & keyof WithoutSystemFields<D>\n\t\t\t\t>\n\t\t\t: WithoutSystemFields<D>,\n\t\toptions?: {\n\t\t\tonFail?: OnFailCallback<D>;\n\t\t},\n\t): Promise<GenericId<TN>> => {\n\t\tlet verifiedData = data as WithoutSystemFields<DocumentByName<DataModel, TN>>;\n\n\t\tif (configs.defaultValues) {\n\t\t\tverifiedData = await configs.defaultValues.verify(tableName, verifiedData);\n\t\t}\n\n\t\tif (extensions.length > 0) {\n\t\t\tverifiedData = (await runExtensions(\n\t\t\t\textensions,\n\t\t\t\t{\n\t\t\t\t\tctx,\n\t\t\t\t\ttableName,\n\t\t\t\t\toperation: \"insert\",\n\t\t\t\t\tonFail: options?.onFail,\n\t\t\t\t\tschema: _schema,\n\t\t\t\t\tdata: verifiedData,\n\t\t\t\t},\n\t\t\t)) as typeof verifiedData;\n\t\t}\n\n\t\treturn await ctx.db.insert(tableName, verifiedData);\n\t};\n\n\tconst patch = async <\n\t\tconst TN extends TableNamesInDataModel<DataModel>,\n\t\tconst D extends DocumentByName<DataModel, TN>,\n\t>(\n\t\tctx: Omit<GenericMutationCtx<DataModel>, never>,\n\t\ttableName: TN,\n\t\tid: GenericId<TN>,\n\t\tdata: HasKey<VC, \"protectedColumns\"> extends true\n\t\t\t? Omit<\n\t\t\t\t\tPartial<WithoutSystemFields<D>>,\n\t\t\t\t\tProtectedKeysForTable<VC, TN> & keyof WithoutSystemFields<D>\n\t\t\t\t>\n\t\t\t: Partial<WithoutSystemFields<D>>,\n\t\toptions?: {\n\t\t\tonFail?: OnFailCallback<D>;\n\t\t},\n\t): Promise<void> => {\n\t\tlet verifiedData = data as Partial<WithoutSystemFields<DocumentByName<DataModel, TN>>>;\n\t\tconst removedProtectedColumns = new Set<string>();\n\n\t\tconst stripProtectedColumns = () => {\n\t\t\tconst filtered = stripProtectedPatchColumns(tableName as string, verifiedData);\n\t\t\tfor (const column of filtered.removedColumns) {\n\t\t\t\tremovedProtectedColumns.add(column);\n\t\t\t}\n\t\t\tverifiedData = filtered.filteredData;\n\t\t};\n\n\t\tstripProtectedColumns();\n\n\t\tif (extensions.length > 0) {\n\t\t\tverifiedData = (await runExtensions(\n\t\t\t\textensions,\n\t\t\t\t{\n\t\t\t\t\tctx,\n\t\t\t\t\ttableName,\n\t\t\t\t\toperation: \"patch\",\n\t\t\t\t\tpatchId: id,\n\t\t\t\t\tonFail: options?.onFail,\n\t\t\t\t\tschema: _schema,\n\t\t\t\t\tdata: verifiedData,\n\t\t\t\t},\n\t\t\t)) as typeof verifiedData;\n\t\t}\n\n\t\tstripProtectedColumns();\n\t\tif (removedProtectedColumns.size > 0) {\n\t\t\toptions?.onFail?.({\n\t\t\t\teditableColumn: {\n\t\t\t\t\tremovedColumns: [...removedProtectedColumns],\n\t\t\t\t\tfilteredData: verifiedData,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tawait ctx.db.patch(id, verifiedData);\n\t};\n\n\tconst dangerouslyPatch = async <\n\t\tconst TN extends TableNamesInDataModel<DataModel>,\n\t\tconst D extends DocumentByName<DataModel, TN>,\n\t>(\n\t\tctx: Omit<GenericMutationCtx<DataModel>, never>,\n\t\ttableName: TN,\n\t\tid: GenericId<TN>,\n\t\tdata: Partial<WithoutSystemFields<D>>,\n\t\toptions?: {\n\t\t\tonFail?: OnFailCallback<D>;\n\t\t},\n\t): Promise<void> => {\n\t\tlet verifiedData = data;\n\n\t\tif (extensions.length > 0) {\n\t\t\tverifiedData = (await runExtensions(\n\t\t\t\textensions,\n\t\t\t\t{\n\t\t\t\t\tctx,\n\t\t\t\t\ttableName,\n\t\t\t\t\toperation: \"patch\",\n\t\t\t\t\tpatchId: id,\n\t\t\t\t\tonFail: options?.onFail,\n\t\t\t\t\tschema: _schema,\n\t\t\t\t\tdata: verifiedData,\n\t\t\t\t},\n\t\t\t)) as typeof verifiedData;\n\t\t}\n\n\t\tawait ctx.db.patch(id, verifiedData);\n\t};\n\n\treturn {\n\t\tinsert,\n\t\tpatch,\n\t\tdangerouslyPatch,\n\t};\n};\n","import {\n\tDataModelFromSchemaDefinition,\n\tGenericDocument,\n\tIndexes,\n\tNamedTableInfo,\n\tSchemaDefinition,\n\tWithoutSystemFields,\n} from 'convex/server';\n\n// =============================================================================\n// Utility Types\n// =============================================================================\n\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\nexport type MakeOptional<T, K extends PropertyKey> = Prettify<\n\tOmit<T, K & keyof T> & Partial<Pick<T, K & keyof T>>\n>;\n\n// =============================================================================\n// Base Types for Config Functions\n// =============================================================================\n\n/**\n * Base interface that all config functions should return.\n * Each config type can have its own `verify` signature and additional properties.\n */\nexport type BaseConfigReturn = {\n\tconfig: Record<string, any>;\n};\n\n// =============================================================================\n// OnFail Types\n// =============================================================================\n\nexport type OnFailArgs<D extends GenericDocument> = {\n\tuniqueColumn?: {\n\t\tconflictingColumn: keyof D;\n\t\texistingData: D;\n\t};\n\tuniqueRow?: {\n\t\texistingData: D | null;\n\t};\n\teditableColumn?: {\n\t\tremovedColumns: string[];\n\t\tfilteredData: Partial<WithoutSystemFields<D>>;\n\t};\n\trequiredColumn?: {\n\t\tmissingColumn: keyof D;\n\t};\n};\n\nexport type OnFailCallback<D extends GenericDocument> = (args: OnFailArgs<D>) => void;\n\n// =============================================================================\n// Config Data Types (what the user provides)\n// =============================================================================\n\nexport type DMGeneric = DataModelFromSchemaDefinition<SchemaDefinition<any, boolean>>;\n\nexport type DefaultValuesConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: {\n\t\t[column in keyof WithoutSystemFields<DM[K]['document']>]?: DM[K]['document'][column];\n\t};\n};\n\n// =============================================================================\n// Index-Based Config Types (shared between uniqueRow, uniqueColumn, etc.)\n// =============================================================================\n\n/**\n * Base options shared by all index-based config entries.\n * Individual extensions can extend this with their own options.\n */\nexport type IndexConfigBaseOptions = {\n\t/** Additional identifiers to check if the existing row is the same document being updated */\n\tidentifiers?: string[];\n};\n\n/**\n * A config entry that can be either:\n * - A string (index name) for shorthand\n * - An object with `index` and additional options\n *\n * @example\n * ```ts\n * // These are equivalent:\n * 'by_username'\n * { index: 'by_username' }\n *\n * // With options:\n * { index: 'by_username', identifiers: ['_id', 'userId'] }\n * ```\n */\nexport type IndexConfigEntry<\n\tDM extends DMGeneric,\n\tK extends keyof DM,\n\tOptions extends IndexConfigBaseOptions = IndexConfigBaseOptions,\n> =\n\t| keyof Indexes<NamedTableInfo<DM, K>>\n\t| ({\n\t\t\tindex: keyof Indexes<NamedTableInfo<DM, K>>;\n\t\t\tidentifiers?: (keyof NamedTableInfo<DM, K>['document'])[];\n\t } & Omit<Options, 'identifiers'>);\n\n/**\n * Normalized form of an index config entry (always an object)\n */\nexport type NormalizedIndexConfig<Options extends IndexConfigBaseOptions = IndexConfigBaseOptions> =\n\t{\n\t\tindex: string;\n\t\tidentifiers: string[];\n\t} & Omit<Options, 'identifiers'>;\n\n/**\n * Normalize a config entry to always have index and identifiers.\n * Works for both string shorthand and full object configs.\n */\nexport function normalizeIndexConfigEntry<\n\tOptions extends IndexConfigBaseOptions = IndexConfigBaseOptions,\n>(\n\tentry: string | ({ index: string; identifiers?: string[] } & Omit<Options, 'identifiers'>),\n\tdefaultIdentifiers: string[] = ['_id']\n): NormalizedIndexConfig<Options> {\n\tif (typeof entry === 'string') {\n\t\treturn {\n\t\t\tindex: entry,\n\t\t\tidentifiers: defaultIdentifiers,\n\t\t} as NormalizedIndexConfig<Options>;\n\t}\n\n\tconst { index, identifiers, ...rest } = entry;\n\treturn {\n\t\tindex: String(index),\n\t\tidentifiers: identifiers?.map(String) ?? defaultIdentifiers,\n\t\t...rest,\n\t} as NormalizedIndexConfig<Options>;\n}\n\n// =============================================================================\n// UniqueRow Config Types\n// =============================================================================\n\nexport type UniqueRowConfigOptions = IndexConfigBaseOptions & {\n\tqueryExistingWithNullish?: boolean;\n};\n\nexport type UniqueRowConfigEntry<DM extends DMGeneric, K extends keyof DM> = IndexConfigEntry<\n\tDM,\n\tK,\n\tUniqueRowConfigOptions\n>;\n\nexport type UniqueRowConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: UniqueRowConfigEntry<DM, K>[];\n};\n\n// =============================================================================\n// UniqueColumn Config Types\n// =============================================================================\n\nexport type UniqueColumnConfigOptions = IndexConfigBaseOptions;\n\nexport type UniqueColumnConfigEntry<DM extends DMGeneric, K extends keyof DM> = IndexConfigEntry<\n\tDM,\n\tK,\n\tUniqueColumnConfigOptions\n>;\n\nexport type UniqueColumnConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: UniqueColumnConfigEntry<DM, K>[];\n};\n\n// =============================================================================\n// Input Types (loose types for verifyConfig to accept)\n// =============================================================================\n\n/**\n * Loose input types that accept any return from config functions.\n * We use loose types here to avoid complex generic matching,\n * then extract the specific config types using conditional types.\n */\nexport type DefaultValuesInput = {\n\t_type: 'defaultValues';\n\tverify: (tableName: any, data: any) => Promise<any>;\n\tconfig:\n\t\t| Record<string, Record<string, any>>\n\t\t| (() => Record<string, Record<string, any>> | Promise<Record<string, Record<string, any>>>);\n};\n\n/**\n * Loose input type for protectedColumnsConfig return value.\n */\nexport type ProtectedColumnsInput = {\n\t_type: 'protectedColumns';\n\tconfig: Record<string, string[]>;\n};\n\n// =============================================================================\n// Object-Based Types (for verifyConfig)\n// =============================================================================\n\n/**\n * Config input for verifyConfig.\n *\n * - `defaultValues`: Transform config that makes fields optional (affects types)\n * - `protectedColumns`: Columns that cannot be patched (affects patch() types)\n * Extension-specific options are added by `verifyConfig`.\n */\nexport type VerifyConfigInput = {\n\tdefaultValues?: DefaultValuesInput;\n\tprotectedColumns?: ProtectedColumnsInput;\n};\n\n// =============================================================================\n// Type Extraction Helpers\n// =============================================================================\n\n/**\n * Extract the config type from defaultValues.config.\n * Handles both direct object and function forms.\n */\nexport type ExtractDefaultValuesConfig<VC> = VC extends {\n\tdefaultValues: { config: infer C };\n}\n\t? C extends () => infer R\n\t\t? Awaited<R>\n\t\t: C\n\t: Record<string, never>;\n\n/**\n * Compute which keys should be optional for a given table based on all configs.\n * Currently only defaultValues affects optionality.\n */\nexport type OptionalKeysForTable<VC, TN> = TN extends keyof ExtractDefaultValuesConfig<VC>\n\t? keyof ExtractDefaultValuesConfig<VC>[TN]\n\t: never;\n\n/**\n * Helper to check if a key exists in a type\n */\nexport type HasKey<T, K extends PropertyKey> = K extends keyof T ? true : false;\n\n// =============================================================================\n// Protected Columns Type Extraction\n// =============================================================================\n\n/**\n * Extract the config type from protectedColumns.config\n */\nexport type ExtractProtectedColumnsConfig<VC> = VC extends {\n\tprotectedColumns: { config: infer C };\n}\n\t? C\n\t: Record<string, never>;\n\n/**\n * Get protected column keys for a specific table.\n * Returns the column names that should be omitted from patch() input.\n */\nexport type ProtectedKeysForTable<VC, TN> = TN extends keyof ExtractProtectedColumnsConfig<VC>\n\t? ExtractProtectedColumnsConfig<VC>[TN] extends readonly (infer K)[]\n\t\t? K\n\t\t: never\n\t: never;\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from \"convex/server\";\n\nimport { DefaultValuesConfigData, MakeOptional } from \"../core/types\";\n\n/**\n * Creates a default values transform.\n *\n * Makes specified fields optional in insert() by providing default values.\n * Supports both static config objects and dynamic functions (sync or async).\n *\n * @param schema - Your Convex schema definition\n * @param config - Default values config (object or function returning object)\n * @returns Config object for use with verifyConfig\n *\n * @example\n * ```ts\n * // Static config (same values reused)\n * const defaults = defaultValuesConfig(schema, {\n * posts: { status: 'draft', views: 0 },\n * });\n *\n * // Dynamic config (fresh values on each insert)\n * const defaults = defaultValuesConfig(schema, () => ({\n * posts: { status: 'draft', slug: generateRandomSlug() },\n * }));\n *\n * // Async config\n * const defaults = defaultValuesConfig(schema, async () => ({\n * posts: { category: await fetchDefaultCategory() },\n * }));\n * ```\n */\nexport const defaultValuesConfig = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tconst C extends DefaultValuesConfigData<DataModel>,\n>(\n\t_schema: S,\n\tconfig: C | (() => C | Promise<C>),\n) => {\n\t/**\n\t * Apply default values to the data for a given table.\n\t * Async to support dynamic config functions.\n\t */\n\tconst verify = async <TN extends TableNamesInDataModel<DataModel>>(\n\t\ttableName: TN,\n\t\tdata: MakeOptional<\n\t\t\tWithoutSystemFields<DocumentByName<DataModel, TN>>,\n\t\t\tkeyof C[TN]\n\t\t>,\n\t): Promise<WithoutSystemFields<DocumentByName<DataModel, TN>>> => {\n\t\t// Resolve config - handle both direct object and function forms\n\t\tconst resolvedConfig =\n\t\t\ttypeof config === \"function\" ? await config() : config;\n\n\t\treturn {\n\t\t\t...(resolvedConfig[tableName] as Partial<\n\t\t\t\tWithoutSystemFields<DocumentByName<DataModel, TN>>\n\t\t\t>),\n\t\t\t...(data as WithoutSystemFields<DocumentByName<DataModel, TN>>),\n\t\t};\n\t};\n\n\treturn {\n\t\t_type: \"defaultValues\" as const,\n\t\tverify,\n\t\tconfig,\n\t};\n};\n","import {\n\tDataModelFromSchemaDefinition,\n\tGenericSchema,\n\tSchemaDefinition,\n\tWithoutSystemFields,\n} from 'convex/server';\n\nimport { DMGeneric } from '../core/types';\n\n/**\n * Config data type for protected columns.\n * Maps table names to arrays of column names that should be protected from patching.\n */\nexport type ProtectedColumnsConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: (keyof WithoutSystemFields<DM[K]['document']>)[];\n};\n\n/**\n * Creates a protected columns config.\n *\n * Protected columns are removed from the patch() input type,\n * preventing accidental updates to critical fields like foreign keys.\n * Use dangerouslyPatch() to bypass this protection when needed.\n *\n * @param schema - Your Convex schema definition\n * @param config - Object mapping table names to arrays of protected column names\n * @returns Config object for use with verifyConfig\n *\n * @example\n * ```ts\n * const protectedColumns = protectedColumnsConfig(schema, {\n * posts: ['authorId', 'createdAt'],\n * comments: ['postId', 'authorId'],\n * });\n *\n * // In verifyConfig:\n * const { patch, dangerouslyPatch } = verifyConfig(schema, {\n * protectedColumns,\n * });\n *\n * // patch() won't allow authorId\n * await patch(ctx, 'posts', id, {\n * authorId: '...', // TS Error - property doesn't exist\n * title: 'new', // OK\n * });\n *\n * // dangerouslyPatch() allows all columns\n * await dangerouslyPatch(ctx, 'posts', id, {\n * authorId: '...', // OK - bypasses protection\n * });\n * ```\n */\nexport const protectedColumnsConfig = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tconst C extends ProtectedColumnsConfigData<DataModel>,\n>(\n\t_schema: S,\n\tconfig: C\n) => {\n\treturn {\n\t\t_type: 'protectedColumns' as const,\n\t\tconfig,\n\t};\n};\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n} from 'convex/server';\nimport { ConvexError } from 'convex/values';\n\nimport { ExtensionContext, SchemaExtension } from '../core/plugin';\nimport { UniqueRowConfigData, UniqueRowConfigOptions } from '../core/types';\nimport { constructColumnData, constructIndexData } from '../utils/helpers';\n\n/**\n * Creates an extension that enforces row uniqueness based on database indexes.\n *\n * This extension checks that the combination of column values defined in your indexes\n * doesn't already exist in the database before allowing insert/patch operations.\n *\n * @param schema - Your Convex schema definition\n * @param config - Object mapping table names to arrays of index configs\n * @returns An extension for use with verifyConfig\n *\n * @example\n * ```ts\n * // Simple shorthand - just index names\n * const uniqueRow = uniqueRowConfig(schema, {\n * posts: ['by_slug'],\n * users: ['by_email', 'by_username'],\n * });\n *\n * // With options\n * const uniqueRow = uniqueRowConfig(schema, {\n * posts: [\n * { index: 'by_author_slug', identifiers: ['_id', 'authorId'] },\n * ],\n * });\n *\n * // Use with verifyConfig\n * const { insert, patch } = verifyConfig(schema, {\n * extensions: [uniqueRow],\n * });\n * ```\n */\nexport const uniqueRowConfig = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tconst C extends UniqueRowConfigData<DataModel>,\n>(\n\tschema: S,\n\tconfig: C\n): SchemaExtension<S, 'uniqueRow', C> => {\n\tconst uniqueRowError = (message: string): never => {\n\t\tthrow new ConvexError({\n\t\t\tmessage,\n\t\t\tcode: 'UNIQUE_ROW_VERIFICATION_ERROR',\n\t\t});\n\t};\n\n\t/**\n\t * Core verification logic shared between insert and patch\n\t */\n\tconst verifyUniqueness = async <\n\t\tTN extends TableNamesInDataModel<DataModel>,\n\t\tD extends Record<string, any>,\n\t>(\n\t\tcontext: ExtensionContext<TN>,\n\t\tdata: D,\n\t\ttableName: TN\n\t): Promise<D> => {\n\t\tconst { ctx, operation, patchId, onFail } = context;\n\n\t\tconst indexesData = constructIndexData(schema, tableName, config);\n\n\t\tif (!indexesData && !!config[tableName]) {\n\t\t\tuniqueRowError(`Index data was not found where there should have been.`);\n\t\t}\n\n\t\t// No indexes provided for this table\n\t\tif (!indexesData) {\n\t\t\treturn data;\n\t\t}\n\n\t\tfor (const indexInfo of indexesData) {\n\t\t\tconst { name, fields, identifiers, ...rest } = indexInfo;\n\t\t\tconst _options = rest as UniqueRowConfigOptions;\n\n\t\t\tif (!fields[0] && !fields[1]) {\n\t\t\t\tuniqueRowError(\n\t\t\t\t\t`Error in 'verifyRowUniqueness()'. There must be two columns to test against. If you are attempting to enforce a unique column, use the 'uniqueColumns' config option.`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst columnData = constructColumnData(fields, data, {});\n\n\t\t\tconst getExisting = async (cd: ReturnType<typeof constructColumnData>) => {\n\t\t\t\ttype D = DocumentByName<DataModel, TN>;\n\t\t\t\tlet existingByIndex: D[] = [];\n\n\t\t\t\tif (!cd) {\n\t\t\t\t\texistingByIndex = [];\n\t\t\t\t} else {\n\t\t\t\t\texistingByIndex = await ctx.db\n\t\t\t\t\t\t.query(tableName)\n\t\t\t\t\t\t.withIndex(name, (q: any) =>\n\t\t\t\t\t\t\tcd.reduce((query: any, { column, value }) => query.eq(column, value), q)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.collect();\n\t\t\t\t}\n\n\t\t\t\tif (existingByIndex.length > 1) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`There was more than one existing result found for index ${name}. Check the following IDs:`,\n\t\t\t\t\t\texistingByIndex.map((r) => r._id)\n\t\t\t\t\t);\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`It is recommended that you triage the rows listed above since they have data that go against a rule of row uniqueness.`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn existingByIndex.length > 0 ? existingByIndex[0] : null;\n\t\t\t};\n\n\t\t\tconst existing = await getExisting(columnData);\n\n\t\t\t/**\n\t\t\t * Insert check\n\t\t\t */\n\t\t\tif (operation === 'insert') {\n\t\t\t\tif (!existing) {\n\t\t\t\t\t// All good, verify passes for this index, continue to next\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Found existing - fail\n\t\t\t\tonFail?.({\n\t\t\t\t\tuniqueRow: {\n\t\t\t\t\t\texistingData: existing,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tuniqueRowError(\n\t\t\t\t\t`Unable to [${operation}] document. In table [${tableName}], there is an existing row that has the same data combination in the columns: [${fields.join(`, `)}].`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Patch check\n\t\t\t */\n\t\t\tif (operation === 'patch') {\n\t\t\t\tif (!patchId) {\n\t\t\t\t\tuniqueRowError(`Unable to patch document without an id.`);\n\t\t\t\t}\n\n\t\t\t\ttype D = DocumentByName<DataModel, TN>;\n\n\t\t\t\t/**\n\t\t\t\t * Check if the existing document matches one of the identifiers\n\t\t\t\t * (meaning we're updating the same document, not creating a conflict)\n\t\t\t\t */\n\t\t\t\tconst matchedToExisting = (_existing: D | null, _data: Partial<D>) => {\n\t\t\t\t\tlet idMatchedToExisting: string | null = null;\n\n\t\t\t\t\tif (_existing) {\n\t\t\t\t\t\tfor (const identifier of identifiers) {\n\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t((_existing[identifier as keyof D] !== undefined &&\n\t\t\t\t\t\t\t\t\t\t_data[identifier as keyof D] !== undefined &&\n\t\t\t\t\t\t\t\t\t\t_existing[identifier as keyof D] === _data[identifier as keyof D]) ||\n\t\t\t\t\t\t\t\t\t\t(identifier === '_id' && _existing[identifier as keyof D] === patchId))\n\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tidMatchedToExisting = String(identifier);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn idMatchedToExisting;\n\t\t\t\t};\n\n\t\t\t\tconst checkExisting = (_existing: D | null, _data: Partial<D>) => {\n\t\t\t\t\tconst matchedId = matchedToExisting(_existing, _data);\n\n\t\t\t\t\tif (!_existing) {\n\t\t\t\t\t\t// No existing found, no conflict\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (matchedId) {\n\t\t\t\t\t\t// The existing document is the same one we're patching - OK\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Found a different document with the same unique values - fail\n\t\t\t\t\t\tonFail?.({\n\t\t\t\t\t\t\tuniqueRow: {\n\t\t\t\t\t\t\t\texistingData: _existing,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t\tuniqueRowError(\n\t\t\t\t\t\t\t`In '${tableName}' table, there already exists a value match of the columns: [${fields.join(`,`)}].`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tif (!existing && !columnData && patchId) {\n\t\t\t\t\t// No existing results found because there wasn't complete data provided\n\t\t\t\t\t// to match the provided index. We need to merge with existing document\n\t\t\t\t\t// to check what WOULD be the potential data conflict.\n\t\t\t\t\tconst match = await ctx.db.get(patchId);\n\n\t\t\t\t\tif (!match) {\n\t\t\t\t\t\tuniqueRowError(`No document found for id ${patchId}`);\n\t\t\t\t\t\treturn data; // TypeScript needs this even though we throw\n\t\t\t\t\t}\n\n\t\t\t\t\tconst extensiveColumnData = constructColumnData(\n\t\t\t\t\t\tfields,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t...match,\n\t\t\t\t\t\t\t...data,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{}\n\t\t\t\t\t);\n\n\t\t\t\t\tif (extensiveColumnData) {\n\t\t\t\t\t\tconst extensiveExisting = await getExisting(extensiveColumnData);\n\t\t\t\t\t\tcheckExisting(extensiveExisting as D | null, data as Partial<D>);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tuniqueRowError(`Incomplete data when there should have been enough.`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tcheckExisting(existing as D | null, data as Partial<D>);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn data;\n\t};\n\n\tconst extension = {\n\t\t_type: 'uniqueRow',\n\t\tconfig,\n\t\tasync verify(input) {\n\t\t\treturn (await verifyUniqueness(\n\t\t\t\tinput as unknown as ExtensionContext<TableNamesInDataModel<DataModel>>,\n\t\t\t\tinput.data as Record<string, any>,\n\t\t\t\tinput.tableName as TableNamesInDataModel<DataModel>\n\t\t\t)) as typeof input.data;\n\t\t},\n\t} as SchemaExtension<S, 'uniqueRow', C>;\n\n\treturn extension;\n};\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n} from \"convex/server\";\n\nimport {\n\tIndexConfigBaseOptions,\n\tNormalizedIndexConfig,\n\tnormalizeIndexConfigEntry,\n\tUniqueRowConfigData,\n} from \"../core/types\";\n\n/**\n * Get Table indexes helper\n *\n * Note: this is using an experimental API in convex-js\n * https://github.com/get-convex/convex-js/commit/04c3b44cab54c4d2230cce9312bdff074d54ab04\n */\nexport const getTableIndexes = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tTN extends TableNamesInDataModel<DataModel>,\n>(\n\tschema: S,\n\ttableName: TN,\n) => {\n\treturn schema.tables[tableName][\" indexes\"]();\n};\n\n/**\n * Generate column data from fields and data object\n */\nexport const constructColumnData = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tTN extends TableNamesInDataModel<DataModel>,\n\tD extends Partial<DocumentByName<DataModel, TN>>,\n>(\n\tfields: string[],\n\tdata: D,\n\t{\n\t\tallowNullishValue = false,\n\t\tallOrNothing = true,\n\t}: {\n\t\tallowNullishValue?: boolean;\n\t\tallOrNothing?: boolean;\n\t},\n) => {\n\tconst lengthOfFields = fields.length;\n\n\tconst columnData = fields\n\t\t.map((_, index) => {\n\t\t\tconst column = fields?.[index];\n\t\t\tconst value = data?.[column];\n\n\t\t\tif (!column || (!allowNullishValue && !value)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcolumn,\n\t\t\t\tvalue,\n\t\t\t};\n\t\t})\n\t\t.filter((e) => !!e);\n\n\tif (allOrNothing && columnData.length !== lengthOfFields) {\n\t\treturn null;\n\t}\n\n\treturn columnData.length > 0 ? columnData : null;\n};\n\n/**\n * Construct index data from schema and config.\n * Handles both string shorthand and full object config entries.\n *\n * @returns Array of normalized index configs with resolved field names from schema\n */\nexport const constructIndexData = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tTN extends TableNamesInDataModel<DataModel>,\n\tOptions extends IndexConfigBaseOptions = IndexConfigBaseOptions,\n>(\n\tschema: S,\n\ttableName: TN,\n\tindexConfig?: UniqueRowConfigData<DataModel>,\n):\n\t| (NormalizedIndexConfig<Options> & { name: string; fields: string[] })[]\n\t| undefined => {\n\tif (!indexConfig) {\n\t\treturn;\n\t}\n\n\tconst tableConfig = indexConfig?.[tableName];\n\tif (!tableConfig) {\n\t\treturn;\n\t}\n\n\treturn tableConfig.map((entry) => {\n\t\t// Normalize the entry (handles both string and object forms)\n\t\tconst normalized = normalizeIndexConfigEntry<Options>(entry as any);\n\t\tconst { index, identifiers, ...rest } = normalized;\n\n\t\tconst fields = getTableIndexes(schema, tableName).find(\n\t\t\t(i) => i.indexDescriptor == index,\n\t\t)?.fields;\n\n\t\tif (!fields) {\n\t\t\tthrow new Error(\n\t\t\t\t`Error in 'constructIndexData()'. No fields found for index: [${index}]`,\n\t\t\t);\n\t\t}\n\n\t\t// Create a unique map in case there is any overlap in identifiers\n\t\t// Always include '_id' as a fallback identifier\n\t\tconst identifierMap = new Map<string, string>(\n\t\t\t[...identifiers, \"_id\"].map((i) => [String(i), String(i)]),\n\t\t);\n\n\t\treturn {\n\t\t\tname: index,\n\t\t\tfields,\n\t\t\tidentifiers: Array.from(identifierMap.values()),\n\t\t\t...rest,\n\t\t} as NormalizedIndexConfig<Options> & { name: string; fields: string[] };\n\t});\n};\n","import { DataModelFromSchemaDefinition, GenericSchema, SchemaDefinition } from 'convex/server';\nimport { ConvexError } from 'convex/values';\n\nimport { ExtensionContext, SchemaExtension } from '../core/plugin';\nimport {\n\tnormalizeIndexConfigEntry,\n\tUniqueColumnConfigData,\n\tUniqueColumnConfigOptions,\n} from '../core/types';\n\n/**\n * Creates an extension that enforces column uniqueness using single-column indexes.\n *\n * This is useful when you have a column that must be unique across all rows,\n * like usernames or email addresses.\n *\n * The column name is derived from the index name by removing the 'by_' prefix.\n * For example, 'by_username' checks the 'username' column.\n *\n * @param schema - Your Convex schema definition\n * @param config - Object mapping table names to arrays of index configs\n * @returns An extension for use with verifyConfig\n *\n * @example\n * ```ts\n * // Shorthand: just pass index names as strings\n * const uniqueColumn = uniqueColumnConfig(schema, {\n * users: ['by_username', 'by_email'],\n * organizations: ['by_slug'],\n * });\n *\n * // Full config: pass objects with options\n * const uniqueColumn = uniqueColumnConfig(schema, {\n * users: [\n * { index: 'by_username', identifiers: ['_id', 'userId'] },\n * { index: 'by_email', identifiers: ['_id'] },\n * ],\n * });\n *\n * // Mix and match\n * const uniqueColumn = uniqueColumnConfig(schema, {\n * users: [\n * 'by_username', // shorthand\n * { index: 'by_email', identifiers: ['_id', 'clerkId'] }, // full config\n * ],\n * });\n *\n * // Use with verifyConfig\n * const { insert, patch } = verifyConfig(schema, {\n * extensions: [uniqueColumn],\n * });\n * ```\n */\nexport const uniqueColumnConfig = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tconst C extends UniqueColumnConfigData<DataModel>,\n>(\n\t_schema: S,\n\tconfig: C\n): SchemaExtension<S, 'uniqueColumn', C> => {\n\tconst uniqueColumnError = (message: string): never => {\n\t\tthrow new ConvexError({\n\t\t\tmessage,\n\t\t\tcode: 'UNIQUE_COLUMN_VERIFICATION_ERROR',\n\t\t});\n\t};\n\n\t/**\n\t * Core verification logic shared between insert and patch\n\t */\n\tconst verifyUniqueness = async <TN extends string, D extends Record<string, any>>(\n\t\tcontext: ExtensionContext<TN>,\n\t\tdata: D\n\t): Promise<D> => {\n\t\tconst { ctx, tableName, patchId, onFail } = context;\n\n\t\tconst tableConfig = config[tableName as keyof typeof config] as\n\t\t\t| (string | { index: string; identifiers?: string[] })[]\n\t\t\t| undefined;\n\n\t\t// No config for this table\n\t\tif (!tableConfig) {\n\t\t\treturn data;\n\t\t}\n\n\t\tfor (const entry of tableConfig) {\n\t\t\tconst { index, identifiers } = normalizeIndexConfigEntry<UniqueColumnConfigOptions>(\n\t\t\t\tentry as any\n\t\t\t);\n\n\t\t\t// Extract column name from index name (e.g., 'by_username' -> 'username')\n\t\t\tconst columnName = index.replace('by_', '');\n\t\t\tconst value = data[columnName];\n\n\t\t\t// Skip if the column isn't in the data being inserted/patched\n\t\t\tif (value === undefined || value === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Query for existing row with this value\n\t\t\tconst existing = await ctx.db\n\t\t\t\t.query(tableName)\n\t\t\t\t.withIndex(index, (q: any) => q.eq(columnName, value))\n\t\t\t\t.unique();\n\n\t\t\tif (!existing) {\n\t\t\t\t// No conflict, continue to next index\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check if the existing row matches one of the identifiers\n\t\t\t// (meaning we're updating the same document, not creating a conflict)\n\t\t\tlet isOwnDocument = false;\n\n\t\t\tfor (const identifier of identifiers) {\n\t\t\t\t// For patch operations, also check against patchId when identifier is '_id'\n\t\t\t\tif (identifier === '_id' && patchId && existing._id === patchId) {\n\t\t\t\t\tisOwnDocument = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// Check if both existing and data have the same identifier value\n\t\t\t\tconst existingValue = existing[identifier];\n\t\t\t\tconst incomingValue = data[identifier];\n\n\t\t\t\tif (\n\t\t\t\t\texistingValue !== undefined &&\n\t\t\t\t\tincomingValue !== undefined &&\n\t\t\t\t\texistingValue === incomingValue\n\t\t\t\t) {\n\t\t\t\t\tisOwnDocument = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isOwnDocument) {\n\t\t\t\t// Same document, no conflict\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Different document has this value - fail\n\t\t\tonFail?.({\n\t\t\t\tuniqueColumn: {\n\t\t\t\t\tconflictingColumn: columnName,\n\t\t\t\t\texistingData: existing,\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tuniqueColumnError(\n\t\t\t\t`In [${tableName}] table, there already exists value \"${value}\" in column [${columnName}].`\n\t\t\t);\n\t\t}\n\n\t\treturn data;\n\t};\n\n\tconst extension = {\n\t\t_type: 'uniqueColumn',\n\t\tconfig,\n\t\tasync verify(input) {\n\t\t\treturn (await verifyUniqueness(\n\t\t\t\tinput as unknown as ExtensionContext<typeof input.tableName>,\n\t\t\t\tinput.data as Record<string, any>\n\t\t\t)) as typeof input.data;\n\t\t},\n\t} as SchemaExtension<S, 'uniqueColumn', C>;\n\n\treturn extension;\n};\n"],"mappings":"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","names":["import_values"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/builtins.ts","../src/core/types.ts","../src/utils/helpers.ts","../src/core/plugin.ts","../src/core/verifyConfig.ts","../src/core/index.ts"],"sourcesContent":["// =============================================================================\n// Core\n// =============================================================================\n\nexport { verifyConfig } from './core';\nimport {\n\tcreateExtension as createExtensionImpl,\n\tisExtension as isExtensionImpl,\n\trunExtensions as runExtensionsImpl,\n} from './core';\n\nexport const createExtension = createExtensionImpl;\nexport const isExtension = isExtensionImpl;\nexport const runExtensions = runExtensionsImpl;\nexport type {\n\tExtensionContext,\n\tExtensionInput,\n\tExtensionInputForSchema,\n\tExtension,\n\tExtensionRecord,\n\tSchemaExtension,\n} from './core';\nexport type {\n\t// Utility types\n\tPrettify,\n\tMakeOptional,\n\t// Data model helpers\n\tDataModelForSchema,\n\tMutationCtxForSchema,\n\t// OnFail types\n\tOnFailArgs,\n\tOnFailCallback,\n\t// Config data types\n\tDefaultValuesConfigData,\n\tDefaultValuesConfigInput,\n\tProtectedColumnsConfigData,\n\t// VerifyConfig types\n\tVerifyConfigInput,\n\t// Type extraction helpers\n\tExtractDefaultValuesConfig,\n\tOptionalKeysForTable,\n\tHasKey,\n\tExtractProtectedColumnsConfig,\n\tProtectedKeysForTable,\n\t// Direct verify types\n\tVerifyInsertInput,\n\tVerifyPatchInput,\n\tDefaultValuesVerifyFn,\n\tProtectedColumnsVerifyFn,\n\tExtensionStyleVerifyFn,\n\tBuiltinConfigKey,\n\tVerifyRegistry,\n\tConfigRegistry,\n} from './core';\nexport type {\n\tUniqueRowConfigData,\n\tUniqueRowConfigEntry,\n\tUniqueRowConfigOptions,\n\tUniqueColumnConfigData,\n\tUniqueColumnConfigEntry,\n\tUniqueColumnConfigOptions,\n} from './core';\n\n// =============================================================================\n// Utils\n// =============================================================================\n\nexport { getTableIndexes, constructColumnData, constructIndexData } from './utils';\nexport { normalizeIndexConfigEntry } from './utils';\nexport type { NormalizedIndexConfig, IndexConfigBaseOptions, IndexConfigEntry } from './utils';\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from 'convex/server';\nimport { ConvexError } from 'convex/values';\n\nimport { constructColumnData, constructIndexData } from '../utils/helpers';\nimport {\n\tDataModelForSchema,\n\tDefaultValuesConfigInput,\n\tDefaultValuesVerifyFn,\n\tProtectedColumnsConfigData,\n\tProtectedColumnsVerifyFn,\n\tUniqueColumnConfigData,\n\tUniqueColumnConfigOptions,\n\tUniqueVerifyFn,\n\tUniqueRowConfigData,\n\tUniqueRowConfigOptions,\n\tnormalizeIndexConfigEntry,\n} from './types';\n\ntype ProtectedColumnsLike = Record<string, readonly PropertyKey[] | undefined>;\n\nexport const stripProtectedPatchColumns = <T extends Record<string, any>>(\n\tprotectedColumns: ProtectedColumnsLike,\n\ttableName: string,\n\tdata: T,\n) => {\n\tconst protectedKeys = protectedColumns[tableName] ?? [];\n\n\tif (protectedKeys.length === 0) {\n\t\treturn {\n\t\t\tfilteredData: data,\n\t\t\tremovedColumns: [] as string[],\n\t\t};\n\t}\n\n\tconst protectedKeyStrings = protectedKeys.map(String);\n\tconst protectedKeySet = new Set(protectedKeyStrings);\n\tconst removedColumns = protectedKeyStrings.filter((key) => key in data);\n\tif (removedColumns.length === 0) {\n\t\treturn {\n\t\t\tfilteredData: data,\n\t\t\tremovedColumns,\n\t\t};\n\t}\n\n\tconst filteredData = Object.fromEntries(\n\t\t\tObject.entries(data).filter(([key]) => !protectedKeySet.has(key)),\n\t) as T;\n\n\treturn {\n\t\tfilteredData,\n\t\tremovedColumns,\n\t};\n};\n\nexport const buildDefaultValuesVerifier = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tconst C extends DefaultValuesConfigInput<DataModelForSchema<S>>,\n>(\n\tconfig: C,\n) => {\n\tconst verify: DefaultValuesVerifyFn<S, { defaultValues: C }> = (async (...args: any[]) => {\n\t\tconst input =\n\t\t\targs.length === 2\n\t\t\t\t? {\n\t\t\t\t\t\ttableName: args[0],\n\t\t\t\t\t\toperation: 'insert' as const,\n\t\t\t\t\t\tdata: args[1],\n\t\t\t\t\t}\n\t\t\t\t: args[0];\n\n\t\tif (input.operation === 'patch') {\n\t\t\treturn input.data;\n\t\t}\n\n\t\tconst resolvedConfig = (\n\t\t\ttypeof config === 'function' ? await config() : config\n\t\t) as Record<string, Record<string, unknown> | undefined>;\n\t\treturn {\n\t\t\t...(resolvedConfig[input.tableName] ?? {}),\n\t\t\t...input.data,\n\t\t};\n\t}) as DefaultValuesVerifyFn<S, { defaultValues: C }>;\n\n\treturn {\n\t\t_type: 'defaultValues' as const,\n\t\tconfig,\n\t\tverify,\n\t};\n};\n\nexport const buildProtectedColumnsVerifier = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tconst C extends ProtectedColumnsConfigData<DataModelForSchema<S>>,\n>(\n\tconfig: C,\n) => {\n\tconst verify: ProtectedColumnsVerifyFn<S> = (async (...args: any[]) => {\n\t\tconst input =\n\t\t\targs.length === 2\n\t\t\t\t? {\n\t\t\t\t\t\ttableName: args[0],\n\t\t\t\t\t\toperation: 'patch' as const,\n\t\t\t\t\t\tdata: args[1],\n\t\t\t\t\t}\n\t\t\t\t: args[0];\n\n\t\tif (input.operation === 'insert') {\n\t\t\treturn input.data;\n\t\t}\n\n\t\treturn stripProtectedPatchColumns(config, input.tableName, input.data).filteredData;\n\t}) as ProtectedColumnsVerifyFn<S>;\n\n\treturn {\n\t\t_type: 'protectedColumns' as const,\n\t\tconfig,\n\t\tverify,\n\t};\n};\n\nexport const buildUniqueRowVerifier = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tconst C extends UniqueRowConfigData<DataModelForSchema<S>>,\n>(\n\tschema: S,\n\tconfig: C,\n) => {\n\ttype DataModel = DataModelFromSchemaDefinition<S>;\n\n\tconst uniqueRowError = (message: string): never => {\n\t\tthrow new ConvexError({\n\t\t\tmessage,\n\t\t\tcode: 'UNIQUE_ROW_VERIFICATION_ERROR',\n\t\t});\n\t};\n\n\tconst verify: UniqueVerifyFn<S> = (async (...args: any[]) => {\n\t\tconst input =\n\t\t\targs.length === 3\n\t\t\t\t? {\n\t\t\t\t\t\tctx: args[0],\n\t\t\t\t\t\ttableName: args[1],\n\t\t\t\t\t\toperation: 'insert' as const,\n\t\t\t\t\t\tdata: args[2],\n\t\t\t\t\t}\n\t\t\t\t: args.length === 4\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tctx: args[0],\n\t\t\t\t\t\t\ttableName: args[1],\n\t\t\t\t\t\t\toperation: 'patch' as const,\n\t\t\t\t\t\t\tpatchId: args[2],\n\t\t\t\t\t\t\tdata: args[3],\n\t\t\t\t\t\t}\n\t\t\t\t\t: args[0];\n\n\t\tconst { ctx, tableName, operation, patchId, onFail, data } = input;\n\t\tconst indexesData = constructIndexData<\n\t\t\tS,\n\t\t\tDataModel,\n\t\t\ttypeof tableName,\n\t\t\tUniqueRowConfigOptions\n\t\t>(schema, tableName, config);\n\n\t\tif (!indexesData) {\n\t\t\treturn data;\n\t\t}\n\n\t\tfor (const indexInfo of indexesData) {\n\t\t\tconst { name, fields, identifiers } = indexInfo;\n\n\t\t\tif (fields.length < 2) {\n\t\t\t\tuniqueRowError(\n\t\t\t\t\t`Error in 'verifyRowUniqueness()'. There must be two columns to test against. If you are attempting to enforce a unique column, use the 'uniqueColumn' config option.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst columnData = constructColumnData(fields, data, {});\n\n\t\t\tconst getExisting = async (cd: ReturnType<typeof constructColumnData>) => {\n\t\t\t\ttype TableDoc = DocumentByName<DataModel, typeof tableName>;\n\t\t\t\tlet existingByIndex: TableDoc[] = [];\n\n\t\t\t\tif (cd) {\n\t\t\t\t\texistingByIndex = await ctx.db\n\t\t\t\t\t\t.query(tableName)\n\t\t\t\t\t\t.withIndex(name, (q: any) =>\n\t\t\t\t\t\t\tcd.reduce((query: any, { column, value }) => query.eq(column, value), q),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.collect();\n\t\t\t\t}\n\n\t\t\t\tif (existingByIndex.length > 1) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`There was more than one existing result found for index ${name}. Check the following IDs:`,\n\t\t\t\t\t\texistingByIndex.map((row) => row._id),\n\t\t\t\t\t);\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t'It is recommended that you triage the rows listed above since they have data that go against a rule of row uniqueness.',\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn existingByIndex.length > 0 ? existingByIndex[0] : null;\n\t\t\t};\n\n\t\t\tconst existing = await getExisting(columnData);\n\n\t\t\tif (operation === 'insert') {\n\t\t\t\tif (!existing) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tonFail?.({\n\t\t\t\t\tuniqueRow: {\n\t\t\t\t\t\texistingData: existing,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tuniqueRowError(\n\t\t\t\t\t`Unable to [${operation}] document. In table [${tableName}], there is an existing row that has the same data combination in the columns: [${fields.join(', ')}].`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (!patchId) {\n\t\t\t\tuniqueRowError('Unable to patch document without an id.');\n\t\t\t}\n\n\t\t\ttype TableDoc = DocumentByName<DataModel, typeof tableName>;\n\n\t\t\tconst matchedToExisting = (_existing: TableDoc | null, _data: Partial<TableDoc>) => {\n\t\t\t\tlet idMatchedToExisting: string | null = null;\n\n\t\t\t\tif (_existing) {\n\t\t\t\t\tfor (const identifier of identifiers) {\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t((_existing[identifier as keyof TableDoc] !== undefined &&\n\t\t\t\t\t\t\t\t_data[identifier as keyof TableDoc] !== undefined &&\n\t\t\t\t\t\t\t\t_existing[identifier as keyof TableDoc] === _data[identifier as keyof TableDoc]) ||\n\t\t\t\t\t\t\t\t(identifier === '_id' &&\n\t\t\t\t\t\t\t\t\t_existing[identifier as keyof TableDoc] === patchId))\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tidMatchedToExisting = String(identifier);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn idMatchedToExisting;\n\t\t\t};\n\n\t\t\tconst checkExisting = (_existing: TableDoc | null, _data: Partial<TableDoc>) => {\n\t\t\t\tconst matchedId = matchedToExisting(_existing, _data);\n\n\t\t\t\tif (!_existing || matchedId) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tonFail?.({\n\t\t\t\t\tuniqueRow: {\n\t\t\t\t\t\texistingData: _existing,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tuniqueRowError(\n\t\t\t\t\t`In '${tableName}' table, there already exists a value match of the columns: [${fields.join(',')}].`,\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tif (!existing && !columnData) {\n\t\t\t\tconst match = await ctx.db.get(patchId);\n\n\t\t\t\tif (!match) {\n\t\t\t\t\tuniqueRowError(`No document found for id ${patchId}`);\n\t\t\t\t}\n\n\t\t\t\tconst extensiveColumnData = constructColumnData(\n\t\t\t\t\tfields,\n\t\t\t\t\t{\n\t\t\t\t\t\t...match,\n\t\t\t\t\t\t...data,\n\t\t\t\t\t},\n\t\t\t\t\t{},\n\t\t\t\t);\n\n\t\t\t\tif (!extensiveColumnData) {\n\t\t\t\t\tuniqueRowError('Incomplete data when there should have been enough.');\n\t\t\t\t}\n\n\t\t\t\tconst extensiveExisting = await getExisting(extensiveColumnData);\n\t\t\t\tcheckExisting(extensiveExisting as TableDoc | null, data as Partial<TableDoc>);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcheckExisting(existing as TableDoc | null, data as Partial<TableDoc>);\n\t\t}\n\n\t\treturn data;\n\t}) as UniqueVerifyFn<S>;\n\n\treturn {\n\t\t_type: 'uniqueRow' as const,\n\t\tconfig,\n\t\tverify,\n\t};\n};\n\nexport const buildUniqueColumnVerifier = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tconst C extends UniqueColumnConfigData<DataModelForSchema<S>>,\n>(\n\tconfig: C,\n) => {\n\tconst uniqueColumnError = (message: string): never => {\n\t\tthrow new ConvexError({\n\t\t\tmessage,\n\t\t\tcode: 'UNIQUE_COLUMN_VERIFICATION_ERROR',\n\t\t});\n\t};\n\n\tconst verify: UniqueVerifyFn<S> = (async (...args: any[]) => {\n\t\tconst input =\n\t\t\targs.length === 3\n\t\t\t\t? {\n\t\t\t\t\t\tctx: args[0],\n\t\t\t\t\t\ttableName: args[1],\n\t\t\t\t\t\toperation: 'insert' as const,\n\t\t\t\t\t\tdata: args[2],\n\t\t\t\t\t}\n\t\t\t\t: args.length === 4\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tctx: args[0],\n\t\t\t\t\t\t\ttableName: args[1],\n\t\t\t\t\t\t\toperation: 'patch' as const,\n\t\t\t\t\t\t\tpatchId: args[2],\n\t\t\t\t\t\t\tdata: args[3],\n\t\t\t\t\t\t}\n\t\t\t\t\t: args[0];\n\n\t\tconst { ctx, tableName, patchId, onFail, data } = input;\n\t\tconst tableConfig = config[tableName as keyof typeof config] as\n\t\t\t| (string | { index: string; identifiers?: string[] })[]\n\t\t\t| undefined;\n\n\t\tif (!tableConfig) {\n\t\t\treturn data;\n\t\t}\n\n\t\tfor (const entry of tableConfig) {\n\t\t\tconst { index, identifiers } = normalizeIndexConfigEntry<UniqueColumnConfigOptions>(\n\t\t\t\tentry as any,\n\t\t\t);\n\t\t\tconst columnName = index.replace('by_', '');\n\t\t\tconst value = data[columnName];\n\n\t\t\tif (value === undefined || value === null) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst existing = await ctx.db\n\t\t\t\t.query(tableName)\n\t\t\t\t.withIndex(index, (q: any) => q.eq(columnName, value))\n\t\t\t\t.unique();\n\n\t\t\tif (!existing) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tlet isOwnDocument = false;\n\n\t\t\tfor (const identifier of identifiers) {\n\t\t\t\tif (identifier === '_id' && patchId && existing._id === patchId) {\n\t\t\t\t\tisOwnDocument = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\texisting[identifier] !== undefined &&\n\t\t\t\t\tdata[identifier] !== undefined &&\n\t\t\t\t\texisting[identifier] === data[identifier]\n\t\t\t\t) {\n\t\t\t\t\tisOwnDocument = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isOwnDocument) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tonFail?.({\n\t\t\t\tuniqueColumn: {\n\t\t\t\t\tconflictingColumn: columnName,\n\t\t\t\t\texistingData: existing,\n\t\t\t\t},\n\t\t\t});\n\t\t\tuniqueColumnError(\n\t\t\t\t`In [${tableName}] table, there already exists value \"${value}\" in column [${columnName}].`,\n\t\t\t);\n\t\t}\n\n\t\treturn data;\n\t}) as UniqueVerifyFn<S>;\n\n\treturn {\n\t\t_type: 'uniqueColumn' as const,\n\t\tconfig,\n\t\tverify,\n\t};\n};\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericDocument,\n\tGenericMutationCtx,\n\tGenericSchema,\n\tIndexes,\n\tNamedTableInfo,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from 'convex/server';\nimport { GenericId } from 'convex/values';\n\n// =============================================================================\n// Utility Types\n// =============================================================================\n\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\nexport type MakeOptional<T, K extends PropertyKey> = Prettify<\n\tOmit<T, K & keyof T> & Partial<Pick<T, K & keyof T>>\n>;\n\nexport type MaybePromise<T> = T | Promise<T>;\n\nexport type Exact<T, Shape> = T extends Shape\n\t? T extends (...args: any[]) => any\n\t\t? T\n\t\t: T extends readonly any[]\n\t\t\t? T\n\t\t\t: T extends object\n\t\t\t\t? {\n\t\t\t\t\t\t[K in keyof T]: K extends keyof NonNullable<Shape>\n\t\t\t\t\t\t\t? Exact<T[K], NonNullable<Shape>[K]>\n\t\t\t\t\t\t\t: never;\n\t\t\t\t } & {\n\t\t\t\t\t\t[K in Exclude<keyof NonNullable<Shape>, keyof T>]?: NonNullable<Shape>[K];\n\t\t\t\t }\n\t\t\t\t: T\n\t: never;\n\n// =============================================================================\n// Base Types\n// =============================================================================\n\nexport type BaseConfigReturn = {\n\tconfig: Record<string, any>;\n};\n\nexport type DMGeneric = DataModelFromSchemaDefinition<SchemaDefinition<any, boolean>>;\n\nexport type DataModelForSchema<S extends SchemaDefinition<GenericSchema, boolean>> =\n\tDataModelFromSchemaDefinition<S>;\n\nexport type MutationCtxForSchema<S extends SchemaDefinition<GenericSchema, boolean>> = Omit<\n\tGenericMutationCtx<DataModelForSchema<S>>,\n\tnever\n>;\n\n// =============================================================================\n// OnFail Types\n// =============================================================================\n\nexport type OnFailArgs<D extends GenericDocument> = {\n\tuniqueColumn?: {\n\t\tconflictingColumn: keyof D;\n\t\texistingData: D;\n\t};\n\tuniqueRow?: {\n\t\texistingData: D | null;\n\t};\n\teditableColumn?: {\n\t\tremovedColumns: string[];\n\t\tfilteredData: Partial<WithoutSystemFields<D>>;\n\t};\n\trequiredColumn?: {\n\t\tmissingColumn: keyof D;\n\t};\n};\n\nexport type OnFailCallback<D extends GenericDocument> = (args: OnFailArgs<D>) => void;\n\n// =============================================================================\n// Config Data Types\n// =============================================================================\n\nexport type DefaultValuesConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: {\n\t\t[column in keyof WithoutSystemFields<DM[K]['document']>]?: DM[K]['document'][column];\n\t};\n};\n\nexport type DefaultValuesConfigInput<DM extends DMGeneric> =\n\t| DefaultValuesConfigData<DM>\n\t| (() => DefaultValuesConfigData<DM> | Promise<DefaultValuesConfigData<DM>>);\n\nexport type ProtectedColumnsConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: (keyof WithoutSystemFields<DM[K]['document']>)[];\n};\n\n// =============================================================================\n// Index-Based Config Types\n// =============================================================================\n\nexport type IndexConfigBaseOptions = {\n\tidentifiers?: string[];\n};\n\nexport type IndexConfigEntry<\n\tDM extends DMGeneric,\n\tK extends keyof DM,\n\tOptions extends IndexConfigBaseOptions = IndexConfigBaseOptions,\n> =\n\t| keyof Indexes<NamedTableInfo<DM, K>>\n\t| ({\n\t\t\tindex: keyof Indexes<NamedTableInfo<DM, K>>;\n\t\t\tidentifiers?: (keyof NamedTableInfo<DM, K>['document'])[];\n\t } & Omit<Options, 'identifiers'>);\n\nexport type NormalizedIndexConfig<Options extends IndexConfigBaseOptions = IndexConfigBaseOptions> =\n\t{\n\t\tindex: string;\n\t\tidentifiers: string[];\n\t} & Omit<Options, 'identifiers'>;\n\nexport function normalizeIndexConfigEntry<\n\tOptions extends IndexConfigBaseOptions = IndexConfigBaseOptions,\n>(\n\tentry: string | ({ index: string; identifiers?: string[] } & Omit<Options, 'identifiers'>),\n\tdefaultIdentifiers: string[] = ['_id']\n): NormalizedIndexConfig<Options> {\n\tif (typeof entry === 'string') {\n\t\treturn {\n\t\t\tindex: entry,\n\t\t\tidentifiers: defaultIdentifiers,\n\t\t} as NormalizedIndexConfig<Options>;\n\t}\n\n\tconst { index, identifiers, ...rest } = entry;\n\treturn {\n\t\tindex: String(index),\n\t\tidentifiers: identifiers?.map(String) ?? defaultIdentifiers,\n\t\t...rest,\n\t} as NormalizedIndexConfig<Options>;\n}\n\n// =============================================================================\n// UniqueRow Config Types\n// =============================================================================\n\nexport type UniqueRowConfigOptions = IndexConfigBaseOptions & {\n\tqueryExistingWithNullish?: boolean;\n};\n\nexport type UniqueRowConfigEntry<DM extends DMGeneric, K extends keyof DM> = IndexConfigEntry<\n\tDM,\n\tK,\n\tUniqueRowConfigOptions\n>;\n\nexport type UniqueRowConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: UniqueRowConfigEntry<DM, K>[];\n};\n\n// =============================================================================\n// UniqueColumn Config Types\n// =============================================================================\n\nexport type UniqueColumnConfigOptions = IndexConfigBaseOptions;\n\nexport type UniqueColumnConfigEntry<DM extends DMGeneric, K extends keyof DM> = IndexConfigEntry<\n\tDM,\n\tK,\n\tUniqueColumnConfigOptions\n>;\n\nexport type UniqueColumnConfigData<DM extends DMGeneric> = {\n\t[K in keyof DM]?: UniqueColumnConfigEntry<DM, K>[];\n};\n\n// =============================================================================\n// VerifyConfig Types\n// =============================================================================\n\nexport type VerifyConfigInput<S extends SchemaDefinition<GenericSchema, boolean>> = {\n\tdefaultValues?: DefaultValuesConfigInput<DataModelForSchema<S>>;\n\tprotectedColumns?: ProtectedColumnsConfigData<DataModelForSchema<S>>;\n\tuniqueRow?: UniqueRowConfigData<DataModelForSchema<S>>;\n\tuniqueColumn?: UniqueColumnConfigData<DataModelForSchema<S>>;\n};\n\nexport type DefaultValuesParameter<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDV,\n> =\n\tValidateDefaultValuesInput<S, DV>;\n\nexport type VerifyConfigSections<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDV = never,\n\tPC = never,\n\tUR = never,\n\tUC = never,\n\tE = never,\n> = {\n\tdefaultValues?: DefaultValuesParameter<S, DV>;\n\tprotectedColumns?: Exact<PC, ProtectedColumnsConfigData<DataModelForSchema<S>>>;\n\tuniqueRow?: Exact<UR, UniqueRowConfigData<DataModelForSchema<S>>>;\n\tuniqueColumn?: Exact<UC, UniqueColumnConfigData<DataModelForSchema<S>>>;\n\textensions?: E;\n};\n\nexport type VerifyConfigShapeFromGenerics<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDV,\n\tPC,\n\tUR,\n\tUC,\n\tE,\n> = Prettify<\n\t([DV] extends [never] ? {} : { defaultValues: DefaultValuesParameter<S, DV> }) &\n\t\t([PC] extends [never]\n\t\t\t? {}\n\t\t\t: { protectedColumns: Exact<PC, ProtectedColumnsConfigData<DataModelForSchema<S>>> }) &\n\t\t([UR] extends [never]\n\t\t\t? {}\n\t\t\t: { uniqueRow: Exact<UR, UniqueRowConfigData<DataModelForSchema<S>>> }) &\n\t\t([UC] extends [never]\n\t\t\t? {}\n\t\t\t: { uniqueColumn: Exact<UC, UniqueColumnConfigData<DataModelForSchema<S>>> }) &\n\t\t([E] extends [never] ? {} : { extensions: E })\n>;\n\ntype AllowedVerifyConfigKeys =\n\t| 'defaultValues'\n\t| 'protectedColumns'\n\t| 'uniqueRow'\n\t| 'uniqueColumn'\n\t| 'extensions';\n\nexport type ValidateDefaultValuesInput<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tV,\n> = V extends () => Promise<infer R>\n\t? () => Promise<Exact<R, DefaultValuesConfigData<DataModelForSchema<S>>>>\n\t: V extends () => infer R\n\t\t? () => Exact<R, DefaultValuesConfigData<DataModelForSchema<S>>>\n\t\t: Exact<V, DefaultValuesConfigData<DataModelForSchema<S>>>;\n\nexport type ValidateVerifyConfig<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tVC,\n> = VC extends object\n\t? {\n\t\t\t[K in keyof VC]: K extends 'defaultValues'\n\t\t\t\t? ValidateDefaultValuesInput<S, VC[K]>\n\t\t\t\t: K extends 'protectedColumns'\n\t\t\t\t\t? Exact<VC[K], ProtectedColumnsConfigData<DataModelForSchema<S>>>\n\t\t\t\t\t: K extends 'uniqueRow'\n\t\t\t\t\t\t? Exact<VC[K], UniqueRowConfigData<DataModelForSchema<S>>>\n\t\t\t\t\t\t: K extends 'uniqueColumn'\n\t\t\t\t\t\t\t? Exact<VC[K], UniqueColumnConfigData<DataModelForSchema<S>>>\n\t\t\t\t\t\t\t: K extends 'extensions'\n\t\t\t\t\t\t\t\t? VC[K]\n\t\t\t\t\t\t\t\t: never;\n\t } & {\n\t\t\t[K in Exclude<keyof VC, AllowedVerifyConfigKeys>]: never;\n\t }\n\t: never;\n\n// =============================================================================\n// Type Extraction Helpers\n// =============================================================================\n\nexport type HasKey<T, K extends PropertyKey> = K extends keyof T ? true : false;\n\nexport type ExtractDefaultValuesConfig<VC> = VC extends {\n\tdefaultValues: infer C;\n}\n\t? C extends () => infer R\n\t\t? Awaited<R>\n\t\t: C\n\t: Record<string, never>;\n\nexport type OptionalKeysForTable<VC, TN> = TN extends keyof ExtractDefaultValuesConfig<VC>\n\t? keyof ExtractDefaultValuesConfig<VC>[TN]\n\t: never;\n\nexport type ExtractProtectedColumnsConfig<VC> = VC extends {\n\tprotectedColumns: infer C;\n}\n\t? C\n\t: Record<string, never>;\n\nexport type ProtectedKeysForTable<VC, TN> = TN extends keyof ExtractProtectedColumnsConfig<VC>\n\t? ExtractProtectedColumnsConfig<VC>[TN] extends readonly (infer K)[]\n\t\t? K\n\t\t: never\n\t: never;\n\n// =============================================================================\n// Direct Verify Input Types\n// =============================================================================\n\nexport type VerifyInsertInput<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tTN extends TableNamesInDataModel<DataModelForSchema<S>>,\n\tTData,\n> = {\n\tctx: MutationCtxForSchema<S>;\n\ttableName: TN;\n\toperation: 'insert';\n\tonFail?: OnFailCallback<DocumentByName<DataModelForSchema<S>, TN>>;\n\tschema: S;\n\tpatchId?: undefined;\n\tdata: TData;\n};\n\nexport type VerifyPatchInput<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tTN extends TableNamesInDataModel<DataModelForSchema<S>>,\n\tTData,\n> = {\n\tctx: MutationCtxForSchema<S>;\n\ttableName: TN;\n\toperation: 'patch';\n\tpatchId: GenericId<TN>;\n\tonFail?: OnFailCallback<DocumentByName<DataModelForSchema<S>, TN>>;\n\tschema: S;\n\tdata: TData;\n};\n\nexport type ExtensionStyleVerifyFn<S extends SchemaDefinition<GenericSchema, boolean>> = {\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\tinput: VerifyInsertInput<\n\t\t\tS,\n\t\t\tTN,\n\t\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t\t>,\n\t): Promise<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\tinput: VerifyPatchInput<\n\t\t\tS,\n\t\t\tTN,\n\t\t\tPartial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>\n\t\t>,\n\t): Promise<Partial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>>;\n};\n\nexport type DefaultValuesVerifyFn<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tVC,\n> = {\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\ttableName: TN,\n\t\tdata: HasKey<VC, 'defaultValues'> extends true\n\t\t\t? MakeOptional<\n\t\t\t\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>,\n\t\t\t\t\tOptionalKeysForTable<VC, TN> &\n\t\t\t\t\t\tkeyof WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t\t\t\t>\n\t\t\t: WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>,\n\t): Promise<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\tinput: VerifyInsertInput<\n\t\t\tS,\n\t\t\tTN,\n\t\t\tHasKey<VC, 'defaultValues'> extends true\n\t\t\t\t? MakeOptional<\n\t\t\t\t\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>,\n\t\t\t\t\t\tOptionalKeysForTable<VC, TN> &\n\t\t\t\t\t\t\tkeyof WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t\t\t\t >\n\t\t\t\t: WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t\t>,\n\t): Promise<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\tinput: VerifyPatchInput<\n\t\t\tS,\n\t\t\tTN,\n\t\t\tPartial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>\n\t\t>,\n\t): Promise<Partial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>>;\n};\n\nexport type ProtectedColumnsVerifyFn<S extends SchemaDefinition<GenericSchema, boolean>> = {\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\ttableName: TN,\n\t\tdata: Partial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>,\n\t): Promise<Partial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\tinput: VerifyInsertInput<\n\t\t\tS,\n\t\t\tTN,\n\t\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t\t>,\n\t): Promise<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>>(\n\t\tinput: VerifyPatchInput<\n\t\t\tS,\n\t\t\tTN,\n\t\t\tPartial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>\n\t\t>,\n\t): Promise<Partial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>>;\n};\n\nexport type UniqueVerifyFn<S extends SchemaDefinition<GenericSchema, boolean>> = {\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>, D extends Partial<\n\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t>>(\n\t\tctx: MutationCtxForSchema<S>,\n\t\ttableName: TN,\n\t\tdata: D,\n\t): Promise<D>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>, D extends Partial<\n\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t>>(\n\t\tctx: MutationCtxForSchema<S>,\n\t\ttableName: TN,\n\t\tpatchId: GenericId<TN>,\n\t\tdata: D,\n\t): Promise<D>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>, D extends Partial<\n\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t>>(\n\t\tinput: VerifyInsertInput<S, TN, D>,\n\t): Promise<D>;\n\t<TN extends TableNamesInDataModel<DataModelForSchema<S>>, D extends Partial<\n\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>\n\t>>(\n\t\tinput: VerifyPatchInput<S, TN, D>,\n\t): Promise<D>;\n};\n\nexport type BuiltinConfigKey =\n\t| 'defaultValues'\n\t| 'protectedColumns'\n\t| 'uniqueRow'\n\t| 'uniqueColumn';\n\nexport type VerifyFnForKey<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tVC,\n\tK extends BuiltinConfigKey,\n> = K extends 'defaultValues'\n\t? DefaultValuesVerifyFn<S, VC>\n\t: K extends 'protectedColumns'\n\t\t? ProtectedColumnsVerifyFn<S>\n\t\t: UniqueVerifyFn<S>;\n\nexport type VerifyRegistry<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tVC,\n> = Prettify<{\n\t[K in BuiltinConfigKey as HasKey<VC, K> extends true ? K : never]: VerifyFnForKey<S, VC, K>;\n}>;\n\nexport type ConfigRegistry<VC> = Prettify<{\n\t[K in BuiltinConfigKey as HasKey<VC, K> extends true ? K : never]: K extends keyof VC ? VC[K] : never;\n}>;\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n} from \"convex/server\";\n\nimport {\n\tIndexConfigBaseOptions,\n\tNormalizedIndexConfig,\n\tnormalizeIndexConfigEntry,\n\tUniqueRowConfigData,\n} from \"../core/types\";\n\n/**\n * Get Table indexes helper\n *\n * Note: this is using an experimental API in convex-js\n * https://github.com/get-convex/convex-js/commit/04c3b44cab54c4d2230cce9312bdff074d54ab04\n */\nexport const getTableIndexes = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tTN extends TableNamesInDataModel<DataModel>,\n>(\n\tschema: S,\n\ttableName: TN,\n) => {\n\treturn schema.tables[tableName][\" indexes\"]();\n};\n\n/**\n * Generate column data from fields and data object\n */\nexport const constructColumnData = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tTN extends TableNamesInDataModel<DataModel>,\n\tD extends Partial<DocumentByName<DataModel, TN>>,\n>(\n\tfields: string[],\n\tdata: D,\n\t{\n\t\tallowNullishValue = false,\n\t\tallOrNothing = true,\n\t}: {\n\t\tallowNullishValue?: boolean;\n\t\tallOrNothing?: boolean;\n\t},\n) => {\n\tconst lengthOfFields = fields.length;\n\n\tconst columnData = fields\n\t\t.map((_, index) => {\n\t\t\tconst column = fields?.[index];\n\t\t\tconst value = data?.[column];\n\n\t\t\tif (\n\t\t\t\t!column ||\n\t\t\t\t(!allowNullishValue && (value === undefined || value === null))\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tcolumn,\n\t\t\t\tvalue,\n\t\t\t};\n\t\t})\n\t\t.filter((e) => !!e);\n\n\tif (allOrNothing && columnData.length !== lengthOfFields) {\n\t\treturn null;\n\t}\n\n\treturn columnData.length > 0 ? columnData : null;\n};\n\n/**\n * Construct index data from schema and config.\n * Handles both string shorthand and full object config entries.\n *\n * @returns Array of normalized index configs with resolved field names from schema\n */\nexport const constructIndexData = <\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tDataModel extends DataModelFromSchemaDefinition<S>,\n\tTN extends TableNamesInDataModel<DataModel>,\n\tOptions extends IndexConfigBaseOptions = IndexConfigBaseOptions,\n>(\n\tschema: S,\n\ttableName: TN,\n\tindexConfig?: UniqueRowConfigData<DataModel>,\n):\n\t| (NormalizedIndexConfig<Options> & { name: string; fields: string[] })[]\n\t| undefined => {\n\tif (!indexConfig) {\n\t\treturn;\n\t}\n\n\tconst tableConfig = indexConfig?.[tableName];\n\tif (!tableConfig) {\n\t\treturn;\n\t}\n\n\treturn tableConfig.map((entry) => {\n\t\t// Normalize the entry (handles both string and object forms)\n\t\tconst normalized = normalizeIndexConfigEntry<Options>(entry as any);\n\t\tconst { index, identifiers, ...rest } = normalized;\n\n\t\tconst fields = getTableIndexes(schema, tableName).find(\n\t\t\t(i) => i.indexDescriptor == index,\n\t\t)?.fields;\n\n\t\tif (!fields) {\n\t\t\tthrow new Error(\n\t\t\t\t`Error in 'constructIndexData()'. No fields found for index: [${index}]`,\n\t\t\t);\n\t\t}\n\n\t\t// Create a unique map in case there is any overlap in identifiers\n\t\t// Always include '_id' as a fallback identifier\n\t\tconst identifierMap = new Map<string, string>(\n\t\t\t[...identifiers, \"_id\"].map((i) => [String(i), String(i)]),\n\t\t);\n\n\t\treturn {\n\t\t\tname: index,\n\t\t\tfields,\n\t\t\tidentifiers: Array.from(identifierMap.values()),\n\t\t\t...rest,\n\t\t} as NormalizedIndexConfig<Options> & { name: string; fields: string[] };\n\t});\n};\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericMutationCtx,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from \"convex/server\";\nimport { GenericId } from \"convex/values\";\n\nimport { DMGeneric, OnFailCallback } from \"./types\";\n\ntype MaybePromise<T> = T | Promise<T>;\n\ntype MutationCtx<DM extends DMGeneric = DMGeneric> = Omit<GenericMutationCtx<DM>, never>;\n\nexport type InsertExtensionContext<\n\tTN extends string = string,\n\tDM extends DMGeneric = DMGeneric,\n\tS extends SchemaDefinition<GenericSchema, boolean> = SchemaDefinition<GenericSchema, boolean>,\n> = {\n\tctx: MutationCtx<DM>;\n\ttableName: TN;\n\toperation: \"insert\";\n\tonFail?: OnFailCallback<any>;\n\tschema: S;\n\tpatchId?: undefined;\n};\n\nexport type PatchExtensionContext<\n\tTN extends string = string,\n\tDM extends DMGeneric = DMGeneric,\n\tS extends SchemaDefinition<GenericSchema, boolean> = SchemaDefinition<GenericSchema, boolean>,\n> = {\n\tctx: MutationCtx<DM>;\n\ttableName: TN;\n\toperation: \"patch\";\n\tpatchId: GenericId<TN>;\n\tonFail?: OnFailCallback<any>;\n\tschema: S;\n};\n\nexport type ExtensionContext<\n\tTN extends string = string,\n\tDM extends DMGeneric = DMGeneric,\n\tS extends SchemaDefinition<GenericSchema, boolean> = SchemaDefinition<GenericSchema, boolean>,\n> = InsertExtensionContext<TN, DM, S> | PatchExtensionContext<TN, DM, S>;\n\nexport type ExtensionInput<\n\tTData = unknown,\n\tTContext = ExtensionContext,\n> = TContext & {\n\tdata: TData;\n};\n\ntype ExtensionInputBase = {\n\tdata: unknown;\n};\n\ntype DataModelForSchema<S extends SchemaDefinition<GenericSchema, boolean>> =\n\tDataModelFromSchemaDefinition<S>;\n\nexport type ExtensionInputForSchema<S extends SchemaDefinition<GenericSchema, boolean>> = {\n\t[TN in TableNamesInDataModel<DataModelForSchema<S>>]:\n\t\t| ExtensionInput<\n\t\t\t\tWithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>,\n\t\t\t\tInsertExtensionContext<TN, DataModelForSchema<S>, S>\n\t\t >\n\t\t| ExtensionInput<\n\t\t\t\tPartial<WithoutSystemFields<DocumentByName<DataModelForSchema<S>, TN>>>,\n\t\t\t\tPatchExtensionContext<TN, DataModelForSchema<S>, S>\n\t\t >;\n}[TableNamesInDataModel<DataModelForSchema<S>>];\n\nexport type ExtensionVerify<TInput extends ExtensionInputBase = ExtensionInput> = (\n\tinput: TInput,\n) => MaybePromise<TInput[\"data\"]>;\n\nexport type ExtensionRecord<\n\tTType extends string = string,\n\tTConfig = unknown,\n\tTInput extends ExtensionInputBase = ExtensionInput,\n> = {\n\treadonly _type: TType;\n\treadonly config?: TConfig;\n\tverify(input: TInput): MaybePromise<TInput[\"data\"]>;\n};\n\nexport type Extension<TInput extends ExtensionInputBase = ExtensionInput> = ExtensionRecord<\n\t\"extension\",\n\tundefined,\n\tTInput\n>;\n\nexport type SchemaExtension<\n\tS extends SchemaDefinition<GenericSchema, boolean>,\n\tTType extends string = string,\n\tTConfig = unknown,\n> = ExtensionRecord<TType, TConfig, ExtensionInputForSchema<S>>;\n\nexport function createExtension<const S extends SchemaDefinition<GenericSchema, boolean>>(\n\tverify: ExtensionVerify<ExtensionInputForSchema<S>>,\n): Extension<ExtensionInputForSchema<S>>;\nexport function createExtension<const S extends SchemaDefinition<GenericSchema, boolean>>(\n\tschema: S,\n\tverify: ExtensionVerify<ExtensionInputForSchema<S>>,\n): Extension<ExtensionInputForSchema<S>>;\nexport function createExtension(verify: ExtensionVerify): Extension;\nexport function createExtension(\n\tschemaOrVerify: SchemaDefinition<GenericSchema, boolean> | ((input: any) => MaybePromise<any>),\n\tverify?: (input: any) => MaybePromise<any>,\n): Extension {\n\tconst extensionVerify =\n\t\ttypeof verify === \"function\"\n\t\t\t? verify\n\t\t\t: (schemaOrVerify as (input: any) => MaybePromise<any>);\n\n\treturn {\n\t\t_type: \"extension\",\n\t\tverify(input) {\n\t\t\treturn extensionVerify(input);\n\t\t},\n\t};\n}\n\nexport function isExtension(value: unknown): value is ExtensionRecord {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\t\"verify\" in value &&\n\t\ttypeof (value as { verify?: unknown }).verify === \"function\"\n\t);\n}\n\nexport async function runExtensions<\n\tTExtensionInput extends ExtensionInputBase,\n\tTInput extends TExtensionInput,\n>(\n\textensions: readonly ExtensionRecord<string, unknown, TExtensionInput>[],\n\tinput: TInput,\n): Promise<TInput[\"data\"]> {\n\tlet verifiedData: unknown = input.data;\n\n\tfor (const extension of extensions) {\n\t\tverifiedData = await extension.verify({\n\t\t\t...input,\n\t\t\tdata: verifiedData,\n\t\t} as TExtensionInput);\n\t}\n\n\treturn verifiedData as TInput[\"data\"];\n}\n","import {\n\tDataModelFromSchemaDefinition,\n\tDocumentByName,\n\tGenericSchema,\n\tSchemaDefinition,\n\tTableNamesInDataModel,\n\tWithoutSystemFields,\n} from 'convex/server';\nimport { GenericId } from 'convex/values';\n\nimport {\n\tbuildDefaultValuesVerifier,\n\tbuildProtectedColumnsVerifier,\n\tbuildUniqueColumnVerifier,\n\tbuildUniqueRowVerifier,\n\tstripProtectedPatchColumns,\n} from './builtins';\nimport { runExtensions } from './plugin';\nimport {\n\tConfigRegistry,\n\tHasKey,\n\tMakeOptional,\n\tMutationCtxForSchema,\n\tOnFailCallback,\n\tOptionalKeysForTable,\n\tProtectedKeysForTable,\n\tValidateDefaultValuesInput,\n\tValidateVerifyConfig,\n\tVerifyConfigInput,\n\tVerifyRegistry,\n} from './types';\n\nexport const verifyConfig = <\n\tS extends GenericSchema,\n\tSD extends SchemaDefinition<S, boolean>,\n\tconst VC extends VerifyConfigInput<SD> & {\n\t\textensions?: unknown;\n\t},\n\tconst DV = never,\n>(\n\t_schema: SD,\n\tconfigs: (Omit<VerifyConfigInput<SD>, 'defaultValues'> & {\n\t\tdefaultValues?: ValidateDefaultValuesInput<SD, DV>;\n\t}) &\n\t\tValidateVerifyConfig<SD, VC> &\n\t\tVC,\n) => {\n\ttype DataModel = DataModelFromSchemaDefinition<SD>;\n\ttype VCForTypes = Omit<VC, 'defaultValues'> &\n\t\t([DV] extends [never] ? {} : { defaultValues: ValidateDefaultValuesInput<SD, DV> });\n\n\tconst builtins = {\n\t\t...(configs.defaultValues\n\t\t\t? {\n\t\t\t\t\tdefaultValues: buildDefaultValuesVerifier<\n\t\t\t\t\t\tSD,\n\t\t\t\t\t\tNonNullable<typeof configs.defaultValues>\n\t\t\t\t\t>(configs.defaultValues),\n\t\t\t\t}\n\t\t\t: {}),\n\t\t...(configs.protectedColumns\n\t\t\t? {\n\t\t\t\t\tprotectedColumns: buildProtectedColumnsVerifier<\n\t\t\t\t\t\tSD,\n\t\t\t\t\t\tNonNullable<typeof configs.protectedColumns>\n\t\t\t\t\t>(configs.protectedColumns),\n\t\t\t\t}\n\t\t\t: {}),\n\t\t...(configs.uniqueRow\n\t\t\t? {\n\t\t\t\t\tuniqueRow: buildUniqueRowVerifier<SD, NonNullable<typeof configs.uniqueRow>>(\n\t\t\t\t\t\t_schema,\n\t\t\t\t\t\tconfigs.uniqueRow,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t: {}),\n\t\t...(configs.uniqueColumn\n\t\t\t? {\n\t\t\t\t\tuniqueColumn: buildUniqueColumnVerifier<\n\t\t\t\t\t\tSD,\n\t\t\t\t\t\tNonNullable<typeof configs.uniqueColumn>\n\t\t\t\t\t>(configs.uniqueColumn),\n\t\t\t\t}\n\t\t\t: {}),\n\t};\n\n\tconst verify = {\n\t\t...(builtins.defaultValues ? { defaultValues: builtins.defaultValues.verify } : {}),\n\t\t...(builtins.protectedColumns ? { protectedColumns: builtins.protectedColumns.verify } : {}),\n\t\t...(builtins.uniqueRow ? { uniqueRow: builtins.uniqueRow.verify } : {}),\n\t\t...(builtins.uniqueColumn ? { uniqueColumn: builtins.uniqueColumn.verify } : {}),\n\t} as VerifyRegistry<SD, VCForTypes>;\n\n\tconst config = {\n\t\t...(configs.defaultValues ? { defaultValues: configs.defaultValues } : {}),\n\t\t...(configs.protectedColumns ? { protectedColumns: configs.protectedColumns } : {}),\n\t\t...(configs.uniqueRow ? { uniqueRow: configs.uniqueRow } : {}),\n\t\t...(configs.uniqueColumn ? { uniqueColumn: configs.uniqueColumn } : {}),\n\t} as ConfigRegistry<VCForTypes>;\n\n\tconst customExtensions = (configs.extensions ?? []) as readonly any[];\n\n\tconst insert = async <\n\t\tconst TN extends TableNamesInDataModel<DataModel>,\n\t\tconst D extends DocumentByName<DataModel, TN>,\n\t>(\n\t\tctx: MutationCtxForSchema<SD>,\n\t\ttableName: TN,\n\t\tdata: HasKey<VCForTypes, 'defaultValues'> extends true\n\t\t\t? MakeOptional<\n\t\t\t\t\tWithoutSystemFields<D>,\n\t\t\t\t\tOptionalKeysForTable<VCForTypes, TN> & keyof WithoutSystemFields<D>\n\t\t\t\t>\n\t\t\t: WithoutSystemFields<D>,\n\t\toptions?: {\n\t\t\tonFail?: OnFailCallback<D>;\n\t\t},\n\t): Promise<GenericId<TN>> => {\n\t\tlet verifiedData = data as WithoutSystemFields<DocumentByName<DataModel, TN>>;\n\n\t\tif (builtins.defaultValues) {\n\t\t\tverifiedData = await builtins.defaultValues.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'insert',\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData as any,\n\t\t\t});\n\t\t}\n\n\t\tif (customExtensions.length > 0) {\n\t\t\tverifiedData = (await runExtensions(customExtensions, {\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'insert',\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t})) as typeof verifiedData;\n\t\t}\n\n\t\tif (builtins.uniqueRow) {\n\t\t\tverifiedData = await builtins.uniqueRow.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'insert',\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t});\n\t\t}\n\n\t\tif (builtins.uniqueColumn) {\n\t\t\tverifiedData = await builtins.uniqueColumn.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'insert',\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t});\n\t\t}\n\n\t\treturn await ctx.db.insert(tableName, verifiedData);\n\t};\n\n\tconst patch = async <\n\t\tconst TN extends TableNamesInDataModel<DataModel>,\n\t\tconst D extends DocumentByName<DataModel, TN>,\n\t>(\n\t\tctx: MutationCtxForSchema<SD>,\n\t\ttableName: TN,\n\t\tid: GenericId<TN>,\n\t\tdata: HasKey<VCForTypes, 'protectedColumns'> extends true\n\t\t\t? Omit<\n\t\t\t\t\tPartial<WithoutSystemFields<D>>,\n\t\t\t\t\tProtectedKeysForTable<VCForTypes, TN> & keyof WithoutSystemFields<D>\n\t\t\t\t>\n\t\t\t: Partial<WithoutSystemFields<D>>,\n\t\toptions?: {\n\t\t\tonFail?: OnFailCallback<D>;\n\t\t},\n\t): Promise<void> => {\n\t\tlet verifiedData = data as Partial<WithoutSystemFields<DocumentByName<DataModel, TN>>>;\n\t\tconst removedProtectedColumns = new Set<string>();\n\n\t\tconst stripProtectedColumns = () => {\n\t\t\tif (!builtins.protectedColumns) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst filtered = stripProtectedPatchColumns(\n\t\t\t\tbuiltins.protectedColumns.config,\n\t\t\t\ttableName as string,\n\t\t\t\tverifiedData,\n\t\t\t);\n\n\t\t\tfor (const column of filtered.removedColumns) {\n\t\t\t\tremovedProtectedColumns.add(column);\n\t\t\t}\n\n\t\t\tverifiedData = filtered.filteredData;\n\t\t};\n\n\t\tstripProtectedColumns();\n\n\t\tif (customExtensions.length > 0) {\n\t\t\tverifiedData = (await runExtensions(customExtensions, {\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'patch',\n\t\t\t\tpatchId: id,\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t})) as typeof verifiedData;\n\t\t}\n\n\t\tif (builtins.uniqueRow) {\n\t\t\tverifiedData = await builtins.uniqueRow.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'patch',\n\t\t\t\tpatchId: id,\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t});\n\t\t}\n\n\t\tif (builtins.uniqueColumn) {\n\t\t\tverifiedData = await builtins.uniqueColumn.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'patch',\n\t\t\t\tpatchId: id,\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t});\n\t\t}\n\n\t\tstripProtectedColumns();\n\t\tif (removedProtectedColumns.size > 0) {\n\t\t\toptions?.onFail?.({\n\t\t\t\teditableColumn: {\n\t\t\t\t\tremovedColumns: [...removedProtectedColumns],\n\t\t\t\t\tfilteredData: verifiedData,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\tawait ctx.db.patch(id, verifiedData);\n\t};\n\n\tconst dangerouslyPatch = async <\n\t\tconst TN extends TableNamesInDataModel<DataModel>,\n\t\tconst D extends DocumentByName<DataModel, TN>,\n\t>(\n\t\tctx: MutationCtxForSchema<SD>,\n\t\ttableName: TN,\n\t\tid: GenericId<TN>,\n\t\tdata: Partial<WithoutSystemFields<D>>,\n\t\toptions?: {\n\t\t\tonFail?: OnFailCallback<D>;\n\t\t},\n\t): Promise<void> => {\n\t\tlet verifiedData = data as Partial<WithoutSystemFields<DocumentByName<DataModel, TN>>>;\n\n\t\tif (customExtensions.length > 0) {\n\t\t\tverifiedData = (await runExtensions(customExtensions, {\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'patch',\n\t\t\t\tpatchId: id,\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t})) as typeof verifiedData;\n\t\t}\n\n\t\tif (builtins.uniqueRow) {\n\t\t\tverifiedData = await builtins.uniqueRow.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'patch',\n\t\t\t\tpatchId: id,\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t});\n\t\t}\n\n\t\tif (builtins.uniqueColumn) {\n\t\t\tverifiedData = await builtins.uniqueColumn.verify({\n\t\t\t\tctx,\n\t\t\t\ttableName,\n\t\t\t\toperation: 'patch',\n\t\t\t\tpatchId: id,\n\t\t\t\tonFail: options?.onFail,\n\t\t\t\tschema: _schema,\n\t\t\t\tdata: verifiedData,\n\t\t\t});\n\t\t}\n\n\t\tawait ctx.db.patch(id, verifiedData);\n\t};\n\n\treturn {\n\t\tinsert,\n\t\tpatch,\n\t\tdangerouslyPatch,\n\t\tverify,\n\t\tconfig,\n\t};\n};\n","// Main verifyConfig function\nexport { verifyConfig } from './verifyConfig';\nexport { stripProtectedPatchColumns } from './builtins';\n\n// Extension system\nimport {\n\tcreateExtension as createExtensionImpl,\n\tisExtension as isExtensionImpl,\n\trunExtensions as runExtensionsImpl,\n} from './plugin';\n\nexport const createExtension = createExtensionImpl;\nexport const isExtension = isExtensionImpl;\nexport const runExtensions = runExtensionsImpl;\nexport type {\n\tExtensionContext,\n\tExtensionInput,\n\tExtensionInputForSchema,\n\tExtension,\n\tExtensionRecord,\n\tSchemaExtension,\n} from './plugin';\n\n// All types\nexport type {\n\t// Utility types\n\tPrettify,\n\tMakeOptional,\n\t// Base types\n\tBaseConfigReturn,\n\t// OnFail types\n\tOnFailArgs,\n\tOnFailCallback,\n\t// Config data types\n\tDMGeneric,\n\tDataModelForSchema,\n\tMutationCtxForSchema,\n\tDefaultValuesConfigData,\n\tDefaultValuesConfigInput,\n\tProtectedColumnsConfigData,\n\t// Index-based config types\n\tIndexConfigBaseOptions,\n\tIndexConfigEntry,\n\tNormalizedIndexConfig,\n\t// UniqueRow types\n\tUniqueRowConfigOptions,\n\tUniqueRowConfigEntry,\n\tUniqueRowConfigData,\n\t// UniqueColumn types\n\tUniqueColumnConfigOptions,\n\tUniqueColumnConfigEntry,\n\tUniqueColumnConfigData,\n\t// VerifyConfig types\n\tVerifyConfigInput,\n\t// Type extraction helpers\n\tExtractDefaultValuesConfig,\n\tOptionalKeysForTable,\n\tHasKey,\n\tExtractProtectedColumnsConfig,\n\tProtectedKeysForTable,\n\tVerifyInsertInput,\n\tVerifyPatchInput,\n\tDefaultValuesVerifyFn,\n\tProtectedColumnsVerifyFn,\n\tExtensionStyleVerifyFn,\n\tBuiltinConfigKey,\n\tVerifyRegistry,\n\tConfigRegistry,\n} from './types';\n\n// Utility function\nexport { normalizeIndexConfigEntry } from './types';\n"],"mappings":"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","names":["createExtension","isExtension","runExtensions","createExtension","isExtension","runExtensions","createExtension","isExtension","runExtensions"]}