{"version":3,"file":"schema.mjs","names":[],"sources":["../../src/db/schema.ts"],"sourcesContent":["import type { BetterAuthOptions } from \"@better-auth/core\";\nimport type {\n\tBaseModelNames,\n\tBetterAuthPluginDBSchema,\n\tDBFieldAttribute,\n} from \"@better-auth/core/db\";\nimport { getAuthTables } from \"@better-auth/core/db\";\nimport { APIError, BASE_ERROR_CODES } from \"@better-auth/core/error\";\nimport { filterOutputFields } from \"@better-auth/core/utils/db\";\nimport type { Account, Session, User } from \"../types\";\n\ntype Mode = \"input\" | \"output\";\n\n// Cache for parsed schemas to avoid reparsing on every request\nconst cache = new WeakMap<\n\tBetterAuthOptions,\n\tMap<`${BaseModelNames}:${Mode}`, Record<string, DBFieldAttribute>>\n>();\n\nfunction getFields(\n\toptions: BetterAuthOptions,\n\tmodelName: BaseModelNames,\n\tmode: Mode,\n) {\n\tconst cacheKey = `${modelName}:${mode}` as const;\n\tif (!cache.has(options)) {\n\t\tcache.set(options, new Map());\n\t}\n\tconst tableCache = cache.get(options)!;\n\tif (tableCache.has(cacheKey)) {\n\t\treturn tableCache.get(cacheKey)!;\n\t}\n\tconst coreSchema =\n\t\tmode === \"output\" ? (getAuthTables(options)[modelName]?.fields ?? {}) : {};\n\tconst additionalFields =\n\t\tmodelName === \"user\" || modelName === \"session\" || modelName === \"account\"\n\t\t\t? options[modelName]?.additionalFields\n\t\t\t: undefined;\n\tlet schema: Record<string, DBFieldAttribute> = {\n\t\t...coreSchema,\n\t\t...(additionalFields ?? {}),\n\t};\n\tfor (const plugin of options.plugins || []) {\n\t\tif (plugin.schema && plugin.schema[modelName]) {\n\t\t\tschema = {\n\t\t\t\t...schema,\n\t\t\t\t...plugin.schema[modelName].fields,\n\t\t\t};\n\t\t}\n\t}\n\ttableCache.set(cacheKey, schema);\n\treturn schema;\n}\n\nexport function parseUserOutput<T extends User>(\n\toptions: BetterAuthOptions,\n\tuser: T,\n) {\n\tconst schema = getFields(options, \"user\", \"output\");\n\treturn filterOutputFields(user, schema);\n}\n\nexport function parseSessionOutput<T extends Session>(\n\toptions: BetterAuthOptions,\n\tsession: T,\n) {\n\tconst schema = getFields(options, \"session\", \"output\");\n\treturn filterOutputFields(session, schema);\n}\n\nexport function parseAccountOutput<T extends Account>(\n\toptions: BetterAuthOptions,\n\taccount: T,\n) {\n\tconst schema = getFields(options, \"account\", \"output\");\n\tconst parsed = filterOutputFields(account, schema);\n\t// destructuring for type inference\n\t// runtime filtering is already done by `filterOutputFields`\n\tconst {\n\t\taccessToken: _accessToken,\n\t\trefreshToken: _refreshToken,\n\t\tidToken: _idToken,\n\t\taccessTokenExpiresAt: _accessTokenExpiresAt,\n\t\trefreshTokenExpiresAt: _refreshTokenExpiresAt,\n\t\tpassword: _password,\n\t\t...rest\n\t} = parsed;\n\treturn rest;\n}\n\nexport function parseInputData<T extends Record<string, any>>(\n\tdata: T,\n\tschema: {\n\t\tfields: Record<string, DBFieldAttribute>;\n\t\taction?: (\"create\" | \"update\") | undefined;\n\t},\n) {\n\tconst action = schema.action || \"create\";\n\tconst fields = schema.fields;\n\tconst parsedData = Object.create(null);\n\tfor (const key in fields) {\n\t\tif (key in data) {\n\t\t\tif (fields[key]!.input === false) {\n\t\t\t\tif (fields[key]!.defaultValue !== undefined) {\n\t\t\t\t\tif (action !== \"update\") {\n\t\t\t\t\t\tparsedData[key] = fields[key]!.defaultValue;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (data[key]) {\n\t\t\t\t\tthrow APIError.from(\"BAD_REQUEST\", {\n\t\t\t\t\t\t...BASE_ERROR_CODES.FIELD_NOT_ALLOWED,\n\t\t\t\t\t\tmessage: `${key} is not allowed to be set`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (fields[key]!.validator?.input && data[key] !== undefined) {\n\t\t\t\tconst result = fields[key]!.validator.input[\"~standard\"].validate(\n\t\t\t\t\tdata[key],\n\t\t\t\t);\n\t\t\t\tif (result instanceof Promise) {\n\t\t\t\t\tthrow APIError.from(\n\t\t\t\t\t\t\"INTERNAL_SERVER_ERROR\",\n\t\t\t\t\t\tBASE_ERROR_CODES.ASYNC_VALIDATION_NOT_SUPPORTED,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tif (\"issues\" in result && result.issues) {\n\t\t\t\t\tthrow APIError.from(\"BAD_REQUEST\", {\n\t\t\t\t\t\t...BASE_ERROR_CODES.VALIDATION_ERROR,\n\t\t\t\t\t\tmessage: result.issues[0]?.message || \"Validation Error\",\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tparsedData[key] = result.value;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (fields[key]!.transform?.input && data[key] !== undefined) {\n\t\t\t\tparsedData[key] = fields[key]!.transform?.input(data[key]);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tparsedData[key] = data[key];\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (fields[key]!.defaultValue !== undefined && action === \"create\") {\n\t\t\tif (typeof fields[key]!.defaultValue === \"function\") {\n\t\t\t\tparsedData[key] = fields[key]!.defaultValue();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tparsedData[key] = fields[key]!.defaultValue;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (fields[key]!.required && action === \"create\") {\n\t\t\tthrow APIError.from(\"BAD_REQUEST\", {\n\t\t\t\t...BASE_ERROR_CODES.MISSING_FIELD,\n\t\t\t\tmessage: `${key} is required`,\n\t\t\t});\n\t\t}\n\t}\n\treturn parsedData as Partial<T>;\n}\n\nexport function parseUserInput(\n\toptions: BetterAuthOptions,\n\tuser: Record<string, any> = {},\n\taction: \"create\" | \"update\",\n) {\n\tconst schema = getFields(options, \"user\", \"input\");\n\treturn parseInputData(user, { fields: schema, action });\n}\n\nexport function parseAdditionalUserInput(\n\toptions: BetterAuthOptions,\n\tuser?: Record<string, any> | undefined,\n) {\n\tconst schema = getFields(options, \"user\", \"input\");\n\treturn parseInputData(user || {}, { fields: schema });\n}\n\nexport function parseAccountInput(\n\toptions: BetterAuthOptions,\n\taccount: Partial<Account>,\n) {\n\tconst schema = getFields(options, \"account\", \"input\");\n\treturn parseInputData(account, { fields: schema });\n}\n\nexport function parseSessionInput(\n\toptions: BetterAuthOptions,\n\tsession: Partial<Session>,\n\taction?: \"create\" | \"update\",\n) {\n\tconst schema = getFields(options, \"session\", \"input\");\n\treturn parseInputData(session, { fields: schema, action });\n}\n\nexport function getSessionDefaultFields(options: BetterAuthOptions) {\n\tconst fields = getFields(options, \"session\", \"input\");\n\tconst defaults: Record<string, any> = {};\n\tfor (const key in fields) {\n\t\tif (fields[key]!.defaultValue !== undefined) {\n\t\t\tdefaults[key] =\n\t\t\t\ttypeof fields[key]!.defaultValue === \"function\"\n\t\t\t\t\t? fields[key]!.defaultValue()\n\t\t\t\t\t: fields[key]!.defaultValue;\n\t\t}\n\t}\n\treturn defaults;\n}\n\nexport function mergeSchema<S extends BetterAuthPluginDBSchema>(\n\tschema: S,\n\tnewSchema?:\n\t\t| {\n\t\t\t\t[K in keyof S]?:\n\t\t\t\t\t| {\n\t\t\t\t\t\t\tmodelName?: string | undefined;\n\t\t\t\t\t\t\tfields?:\n\t\t\t\t\t\t\t\t| {\n\t\t\t\t\t\t\t\t\t\t[P: string]: string;\n\t\t\t\t\t\t\t\t  }\n\t\t\t\t\t\t\t\t| undefined;\n\t\t\t\t\t  }\n\t\t\t\t\t| undefined;\n\t\t  }\n\t\t| undefined,\n) {\n\tif (!newSchema) {\n\t\treturn schema;\n\t}\n\tfor (const table in newSchema) {\n\t\tconst newModelName = newSchema[table]?.modelName;\n\t\tif (newModelName) {\n\t\t\tschema[table]!.modelName = newModelName;\n\t\t}\n\t\tfor (const field in schema[table]!.fields) {\n\t\t\tconst newField = newSchema[table]?.fields?.[field];\n\t\t\tif (!newField) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tschema[table]!.fields[field]!.fieldName = newField;\n\t\t}\n\t}\n\treturn schema;\n}\n"],"mappings":"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"}