@xylex-group/better-auth-athena 1.0.0 → 1.0.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.
- package/README.md +7 -4
- package/dist/index.cjs +404 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +397 -80
- package/dist/index.js.map +1 -1
- package/package.json +67 -65
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\r\n createAdapterFactory,\r\n type AdapterFactory,\r\n type DBAdapterDebugLogOption,\r\n} from \"better-auth/adapters\";\r\nimport type { BetterAuthOptions } from \"better-auth\";\r\nimport { createClient, type SupabaseClient as AthenaClient } from \"@xylex-group/athena\";\r\n\r\n/**\r\n * Configuration options for the Athena adapter.\r\n */\r\nexport interface AthenaAdapterConfig {\r\n /**\r\n * The URL of your Athena gateway.\r\n */\r\n url: string;\r\n /**\r\n * The API key for authenticating with the Athena gateway.\r\n */\r\n apiKey: string;\r\n /**\r\n * The client name sent in requests to the Athena gateway.\r\n */\r\n client?: string;\r\n /**\r\n * Helps you debug issues with the adapter.\r\n */\r\n debugLogs?: DBAdapterDebugLogOption;\r\n /**\r\n * If the table names in the schema are plural.\r\n *\r\n * @default false\r\n */\r\n usePlural?: boolean;\r\n}\r\n\r\ntype AthenaFilterBuilder = {\r\n eq(col: string, val: unknown): AthenaFilterBuilder;\r\n neq(col: string, val: unknown): AthenaFilterBuilder;\r\n gt(col: string, val: unknown): AthenaFilterBuilder;\r\n gte(col: string, val: unknown): AthenaFilterBuilder;\r\n lt(col: string, val: unknown): AthenaFilterBuilder;\r\n lte(col: string, val: unknown): AthenaFilterBuilder;\r\n in(col: string, vals: unknown[]): AthenaFilterBuilder;\r\n not(col: string, op?: string, val?: unknown): AthenaFilterBuilder;\r\n like(col: string, val: string): AthenaFilterBuilder;\r\n};\r\n\r\n/**\r\n * Apply a Better-Auth `CleanedWhere` clause to an Athena filter-chain builder.\r\n */\r\nfunction applyWhere<T extends AthenaFilterBuilder>(\r\n builder: T,\r\n field: string,\r\n operator: string,\r\n value: unknown,\r\n): T {\r\n switch (operator) {\r\n case \"eq\":\r\n return builder.eq(field, value) as T;\r\n case \"ne\":\r\n return builder.neq(field, value) as T;\r\n case \"gt\":\r\n return builder.gt(field, value) as T;\r\n case \"gte\":\r\n return builder.gte(field, value) as T;\r\n case \"lt\":\r\n return builder.lt(field, value) as T;\r\n case \"lte\":\r\n return builder.lte(field, value) as T;\r\n case \"in\":\r\n return builder.in(field, value as unknown[]) as T;\r\n case \"not_in\":\r\n return builder.not(field, \"in\", value) as T;\r\n case \"contains\":\r\n return builder.like(field, `%${value}%`) as T;\r\n case \"starts_with\":\r\n return builder.like(field, `${value}%`) as T;\r\n case \"ends_with\":\r\n return builder.like(field, `%${value}`) as T;\r\n default:\r\n return builder.eq(field, value) as T;\r\n }\r\n}\r\n\r\ntype WhereClause = { field: string; operator: string; value: unknown };\r\n\r\n/**\r\n * Create a Better-Auth database adapter backed by @xylex-group/athena.\r\n *\r\n * Column names are kept in snake_case as required by the Athena gateway.\r\n *\r\n * @example\r\n * ```ts\r\n * import { betterAuth } from \"better-auth\";\r\n * import { athenaAdapter } from \"better-auth-athena\";\r\n *\r\n * export const auth = betterAuth({\r\n * database: athenaAdapter({\r\n * url: process.env.ATHENA_URL!,\r\n * apiKey: process.env.ATHENA_API_KEY!,\r\n * client: \"my-app\",\r\n * }),\r\n * });\r\n * ```\r\n */\r\nexport const athenaAdapter = (config: AthenaAdapterConfig): AdapterFactory<BetterAuthOptions> => {\r\n const db: AthenaClient = createClient(config.url, config.apiKey, {\r\n client: config.client,\r\n });\r\n\r\n return createAdapterFactory({\r\n config: {\r\n adapterId: \"athena\",\r\n adapterName: \"Athena Adapter\",\r\n usePlural: config.usePlural ?? false,\r\n debugLogs: config.debugLogs ?? false,\r\n // Athena/Postgres supports all these natively\r\n supportsJSON: true,\r\n supportsDates: true,\r\n supportsBooleans: true,\r\n supportsNumericIds: true,\r\n },\r\n adapter: () => {\r\n return {\r\n // ------------------------------------------------------------------\r\n // CREATE\r\n // ------------------------------------------------------------------\r\n create: async <T extends Record<string, unknown>>({ model, data }: { model: string; data: T; select?: string[] }) => {\r\n const { data: result, error } = await db\r\n .from(model)\r\n .insert(data)\r\n .select();\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] create on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n // Athena returns the inserted row(s); take the first one.\r\n const row = Array.isArray(result) ? result[0] : result;\r\n return (row ?? data) as T;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // UPDATE\r\n // ------------------------------------------------------------------\r\n update: async <T>({ model, where, update }: { model: string; where: WhereClause[]; update: T }) => {\r\n let builder = db.from(model).update(update as Record<string, unknown>);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n\r\n const { data: result, error } = await builder.select();\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] update on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n const row = Array.isArray(result) ? result[0] : result;\r\n return (row ?? null) as T | null;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // UPDATE MANY\r\n // ------------------------------------------------------------------\r\n updateMany: async ({ model, where, update }: { model: string; where: WhereClause[]; update: Record<string, unknown> }) => {\r\n let builder = db.from(model).update(update);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n\r\n const { data: result, error } = await builder.select();\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] updateMany on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n return Array.isArray(result) ? result.length : (result ? 1 : 0);\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // DELETE\r\n // ------------------------------------------------------------------\r\n delete: async ({ model, where }: { model: string; where: WhereClause[] }) => {\r\n let builder = db.from(model);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n\r\n const { error } = await builder.delete();\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] delete on \"${model}\" failed: ${error}`);\r\n }\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // DELETE MANY\r\n // ------------------------------------------------------------------\r\n deleteMany: async ({ model, where }: { model: string; where: WhereClause[] }) => {\r\n let builder = db.from(model);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n\r\n const { data: result, error } = await builder.delete().select();\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] deleteMany on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n return Array.isArray(result) ? result.length : (result ? 1 : 0);\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // FIND ONE\r\n // ------------------------------------------------------------------\r\n findOne: async <T>({ model, where, select }: { model: string; where: WhereClause[]; select?: string[]; join?: unknown }) => {\r\n const columns = select && select.length > 0 ? select.join(\", \") : undefined;\r\n let builder = db.from(model).select(columns);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n\r\n const { data: result, error } = await builder.limit(1);\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] findOne on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n const rows = Array.isArray(result) ? result : (result ? [result] : []);\r\n return (rows[0] ?? null) as T | null;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // FIND MANY\r\n // ------------------------------------------------------------------\r\n findMany: async <T>({ model, where, limit, sortBy, offset, select }: {\r\n model: string;\r\n where?: WhereClause[];\r\n limit: number;\r\n select?: string[];\r\n sortBy?: { field: string; direction: \"asc\" | \"desc\" };\r\n offset?: number;\r\n join?: unknown;\r\n }) => {\r\n const columns = select && select.length > 0 ? select.join(\", \") : undefined;\r\n let builder = db.from(model).select(columns);\r\n\r\n if (where) {\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n }\r\n\r\n if (limit !== undefined) {\r\n builder = builder.limit(limit);\r\n }\r\n\r\n if (offset !== undefined) {\r\n builder = builder.offset(offset);\r\n }\r\n\r\n const { data: result, error } = await builder;\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] findMany on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n const rows = (Array.isArray(result) ? result : []) as Record<string, unknown>[];\r\n\r\n // The Athena SDK's select chain does not expose a native orderBy/sort\r\n // method, so we sort the returned rows in memory when sortBy is requested.\r\n if (sortBy) {\r\n rows.sort((a, b) => {\r\n const aVal = a[sortBy.field];\r\n const bVal = b[sortBy.field];\r\n if (aVal == null && bVal == null) return 0;\r\n if (aVal == null) return sortBy.direction === \"asc\" ? -1 : 1;\r\n if (bVal == null) return sortBy.direction === \"asc\" ? 1 : -1;\r\n const cmp =\r\n typeof aVal === \"string\" && typeof bVal === \"string\"\r\n ? aVal.localeCompare(bVal)\r\n : aVal < bVal\r\n ? -1\r\n : aVal > bVal\r\n ? 1\r\n : 0;\r\n return sortBy.direction === \"asc\" ? cmp : -cmp;\r\n });\r\n }\r\n\r\n return rows as T[];\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // COUNT\r\n // ------------------------------------------------------------------\r\n count: async ({ model, where }: { model: string; where?: WhereClause[] }) => {\r\n let builder = db.from(model).select();\r\n\r\n if (where) {\r\n for (const clause of where) {\r\n builder = applyWhere(builder, clause.field, clause.operator, clause.value);\r\n }\r\n }\r\n\r\n const { data: result, error } = await builder;\r\n\r\n if (error) {\r\n throw new Error(`[AthenaAdapter] count on \"${model}\" failed: ${error}`);\r\n }\r\n\r\n return Array.isArray(result) ? result.length : 0;\r\n },\r\n };\r\n },\r\n });\r\n};\r\n\r\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts"],"sourcesContent":["import {\r\n createAdapterFactory,\r\n type AdapterFactory,\r\n type DBAdapterDebugLogOption,\r\n} from \"better-auth/adapters\";\r\nimport type { BetterAuthOptions } from \"better-auth\";\r\nimport {\r\n createClient,\r\n type SupabaseClient as AthenaClient,\r\n} from \"@xylex-group/athena\";\r\nimport { getAthenaGlobalConfig } from \"./config\";\r\n\r\nfunction toSnakeCase(key: string): string {\r\n // `userId` -> `user_id`, `createdAt` -> `created_at`\r\n return key\r\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\r\n .replace(/__/g, \"_\")\r\n .toLowerCase();\r\n}\r\n\r\nfunction toCamelCase(key: string): string {\r\n // `user_id` -> `userId`, `created_at` -> `createdAt`\r\n return key.replace(/_([a-z0-9])/g, (_, ch: string) => ch.toUpperCase());\r\n}\r\n\r\nfunction hasUppercase(key: string): boolean {\r\n return /[A-Z]/.test(key);\r\n}\r\n\r\nfunction mapKeys<T extends Record<string, unknown>>(\r\n obj: T,\r\n mapKey: (k: string) => string,\r\n): Record<string, unknown> {\r\n const out: Record<string, unknown> = {};\r\n for (const [k, v] of Object.entries(obj)) out[mapKey(k)] = v;\r\n return out;\r\n}\r\n\r\nfunction mapRowToBetterAuth<T>(row: T): T {\r\n if (!row || typeof row !== \"object\") return row;\r\n if (Array.isArray(row)) return row.map(mapRowToBetterAuth) as unknown as T;\r\n return mapKeys(row as Record<string, unknown>, toCamelCase) as T;\r\n}\r\n\r\nfunction isLikelyIsoDateString(value: string): boolean {\r\n // Fast-path: Better Auth commonly uses ISO-8601 timestamps for `*At` fields.\r\n if (!/^\\d{4}-\\d{2}-\\d{2}T/.test(value)) return false;\r\n const ms = Date.parse(value);\r\n return Number.isFinite(ms);\r\n}\r\n\r\nfunction isTimestampKey(key: string): boolean {\r\n return key.endsWith(\"At\") || key.endsWith(\"_at\") || key === \"expires\";\r\n}\r\n\r\nfunction coerceDateFields<T extends Record<string, unknown>>(data: T): T {\r\n const out: Record<string, unknown> = { ...data };\r\n for (const [key, val] of Object.entries(out)) {\r\n if (val == null) continue;\r\n if (\r\n typeof val === \"string\" &&\r\n isTimestampKey(key) &&\r\n isLikelyIsoDateString(val)\r\n ) {\r\n out[key] = new Date(val);\r\n }\r\n }\r\n return out as T;\r\n}\r\n\r\nfunction toDbRecord<T extends Record<string, unknown>>(\r\n data: T,\r\n): Record<string, unknown> {\r\n // Better Auth uses camelCase; Athena gateway expects snake_case column names.\r\n const withDbKeys = mapKeys(data, (k) =>\r\n hasUppercase(k) ? toSnakeCase(k) : k,\r\n );\r\n // Coerce ISO strings to Date; gateway must cast JSON string to timestamptz (e.g. $1::timestamptz).\r\n return coerceDateFields(withDbKeys);\r\n}\r\n\r\n/**\r\n * Configuration options for the Athena adapter.\r\n */\r\nexport interface AthenaAdapterConfig {\r\n /**\r\n * The URL of your Athena gateway.\r\n */\r\n url?: string;\r\n /**\r\n * The API key for authenticating with the Athena gateway.\r\n */\r\n apiKey?: string;\r\n /**\r\n * The client name sent in requests to the Athena gateway.\r\n */\r\n client?: string;\r\n\r\n /**\r\n * Optional override for the YAML config path.\r\n * Defaults to `./config.yaml` (resolved from `process.cwd()`).\r\n */\r\n configPath?: string;\r\n\r\n /**\r\n * When enabled, the adapter will reload `config.yaml` on changes.\r\n *\r\n * @default true\r\n */\r\n watchConfig?: boolean;\r\n /**\r\n * Helps you debug issues with the adapter.\r\n */\r\n debugLogs?: DBAdapterDebugLogOption;\r\n /**\r\n * If the table names in the schema are plural.\r\n *\r\n * @default false\r\n */\r\n usePlural?: boolean;\r\n}\r\n\r\ntype AthenaFilterBuilder = {\r\n eq(col: string, val: unknown): AthenaFilterBuilder;\r\n neq(col: string, val: unknown): AthenaFilterBuilder;\r\n gt(col: string, val: unknown): AthenaFilterBuilder;\r\n gte(col: string, val: unknown): AthenaFilterBuilder;\r\n lt(col: string, val: unknown): AthenaFilterBuilder;\r\n lte(col: string, val: unknown): AthenaFilterBuilder;\r\n in(col: string, vals: unknown[]): AthenaFilterBuilder;\r\n not(col: string, op?: string, val?: unknown): AthenaFilterBuilder;\r\n like(col: string, val: string): AthenaFilterBuilder;\r\n};\r\n\r\n/**\r\n * Apply a Better-Auth `CleanedWhere` clause to an Athena filter-chain builder.\r\n */\r\nfunction applyWhere<T extends AthenaFilterBuilder>(\r\n builder: T,\r\n field: string,\r\n operator: string,\r\n value: unknown,\r\n columnMapper: (col: string) => string = (col) =>\r\n hasUppercase(col) ? toSnakeCase(col) : col,\r\n): T {\r\n const dbField = columnMapper(field);\r\n switch (operator) {\r\n case \"eq\":\r\n return builder.eq(dbField, value) as T;\r\n case \"ne\":\r\n return builder.neq(dbField, value) as T;\r\n case \"gt\":\r\n return builder.gt(dbField, value) as T;\r\n case \"gte\":\r\n return builder.gte(dbField, value) as T;\r\n case \"lt\":\r\n return builder.lt(dbField, value) as T;\r\n case \"lte\":\r\n return builder.lte(dbField, value) as T;\r\n case \"in\":\r\n return builder.in(dbField, value as unknown[]) as T;\r\n case \"not_in\":\r\n return builder.not(dbField, \"in\", value) as T;\r\n case \"contains\":\r\n return builder.like(dbField, `%${value}%`) as T;\r\n case \"starts_with\":\r\n return builder.like(dbField, `${value}%`) as T;\r\n case \"ends_with\":\r\n return builder.like(dbField, `%${value}`) as T;\r\n default:\r\n return builder.eq(dbField, value) as T;\r\n }\r\n}\r\n\r\ntype WhereClause = { field: string; operator: string; value: unknown };\r\n\r\nfunction isMissingColumnError(error: unknown): boolean {\r\n const msg = String(error ?? \"\");\r\n return (\r\n msg.includes(\"specified column does not exist\") ||\r\n msg.includes(\"column does not exist\")\r\n );\r\n}\r\n\r\n/**\r\n * Create a Better-Auth database adapter backed by @xylex-group/athena.\r\n *\r\n * Column names are kept in snake_case as required by the Athena gateway.\r\n *\r\n * @example\r\n * ```ts\r\n * import { betterAuth } from \"better-auth\";\r\n * import { athenaAdapter } from \"better-auth-athena\";\r\n *\r\n * export const auth = betterAuth({\r\n * database: athenaAdapter({\r\n * url: process.env.ATHENA_URL!,\r\n * apiKey: process.env.ATHENA_API_KEY!,\r\n * client: \"my-app\",\r\n * }),\r\n * });\r\n * ```\r\n */\r\nexport const athenaAdapter = (\r\n config: AthenaAdapterConfig,\r\n): AdapterFactory<BetterAuthOptions> => {\r\n let dbClient: AthenaClient | null = null;\r\n let lastDbConfigVersion = -1;\r\n\r\n const shouldUseFixedConfig =\r\n typeof config.url === \"string\" &&\r\n config.url.length > 0 &&\r\n typeof config.apiKey === \"string\" &&\r\n config.apiKey.length > 0;\r\n\r\n function ensureDbClient(): AthenaClient {\r\n if (shouldUseFixedConfig) {\r\n if (!dbClient) {\r\n dbClient = createClient(config.url!, config.apiKey!, {\r\n client: config.client,\r\n });\r\n }\r\n return dbClient;\r\n }\r\n\r\n const { config: globalConfig, version } = getAthenaGlobalConfig({\r\n configPath: config.configPath,\r\n watch: config.watchConfig ?? true,\r\n });\r\n\r\n const url = config.url ?? globalConfig.athena.url;\r\n const apiKey = config.apiKey ?? globalConfig.athena.apiKey;\r\n const client = config.client ?? globalConfig.athena.client;\r\n\r\n if (!url || !apiKey) {\r\n throw new Error(\r\n `[AthenaAdapter] Missing Athena connection details. Set both 'athena.url' and 'athena.apiKey' in config.yaml (or pass 'url'/'apiKey' to athenaAdapter).`,\r\n );\r\n }\r\n\r\n if (!dbClient || version !== lastDbConfigVersion) {\r\n dbClient = createClient(url, apiKey, { client });\r\n lastDbConfigVersion = version;\r\n }\r\n\r\n return dbClient;\r\n }\r\n\r\n return createAdapterFactory({\r\n config: {\r\n adapterId: \"athena\",\r\n adapterName: \"Athena Adapter\",\r\n usePlural: config.usePlural ?? false,\r\n debugLogs: config.debugLogs ?? false,\r\n // Athena/Postgres supports all these natively\r\n supportsJSON: true,\r\n supportsDates: true,\r\n supportsBooleans: true,\r\n supportsNumericIds: true,\r\n supportsUUIDs: true,\r\n },\r\n adapter: () => {\r\n return {\r\n // ------------------------------------------------------------------\r\n // CREATE\r\n // ------------------------------------------------------------------\r\n create: async <T extends Record<string, unknown>>({\r\n model,\r\n data,\r\n }: {\r\n model: string;\r\n data: T;\r\n select?: string[];\r\n }) => {\r\n const db = ensureDbClient();\r\n const insertData = toDbRecord(data);\r\n const { data: result, error } = await db\r\n .from(model)\r\n .insert(insertData)\r\n .select();\r\n\r\n if (error) {\r\n throw new Error(\r\n `[AthenaAdapter] create on \"${model}\" failed: ${error}`,\r\n );\r\n }\r\n\r\n // Athena returns the inserted row(s); take the first one.\r\n const row = Array.isArray(result) ? result[0] : result;\r\n return mapRowToBetterAuth((row ?? insertData) as T);\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // UPDATE\r\n // ------------------------------------------------------------------\r\n update: async <T>({\r\n model,\r\n where,\r\n update,\r\n }: {\r\n model: string;\r\n where: WhereClause[];\r\n update: T;\r\n }) => {\r\n const db = ensureDbClient();\r\n const updateData = toDbRecord(update as Record<string, unknown>);\r\n let builder = db.from(model).update(updateData);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n );\r\n }\r\n\r\n const { data: result, error } = await builder.select();\r\n\r\n if (error) {\r\n throw new Error(\r\n `[AthenaAdapter] update on \"${model}\" failed: ${error}`,\r\n );\r\n }\r\n\r\n const row = Array.isArray(result) ? result[0] : result;\r\n return (row ? mapRowToBetterAuth(row as T) : null) as T | null;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // UPDATE MANY\r\n // ------------------------------------------------------------------\r\n updateMany: async ({\r\n model,\r\n where,\r\n update,\r\n }: {\r\n model: string;\r\n where: WhereClause[];\r\n update: Record<string, unknown>;\r\n }) => {\r\n const db = ensureDbClient();\r\n const updateData = toDbRecord(update);\r\n let builder = db.from(model).update(updateData);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n );\r\n }\r\n\r\n const { data: result, error } = await builder.select();\r\n\r\n if (error) {\r\n throw new Error(\r\n `[AthenaAdapter] updateMany on \"${model}\" failed: ${error}`,\r\n );\r\n }\r\n\r\n return Array.isArray(result) ? result.length : result ? 1 : 0;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // DELETE\r\n // ------------------------------------------------------------------\r\n delete: async ({\r\n model,\r\n where,\r\n }: {\r\n model: string;\r\n where: WhereClause[];\r\n }) => {\r\n const db = ensureDbClient();\r\n let builder = db.from(model);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n );\r\n }\r\n\r\n const { error } = await builder.delete();\r\n\r\n if (error) {\r\n throw new Error(\r\n `[AthenaAdapter] delete on \"${model}\" failed: ${error}`,\r\n );\r\n }\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // DELETE MANY\r\n // ------------------------------------------------------------------\r\n deleteMany: async ({\r\n model,\r\n where,\r\n }: {\r\n model: string;\r\n where: WhereClause[];\r\n }) => {\r\n const db = ensureDbClient();\r\n let builder = db.from(model);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n );\r\n }\r\n\r\n const { data: result, error } = await builder.delete().select();\r\n\r\n if (error) {\r\n throw new Error(\r\n `[AthenaAdapter] deleteMany on \"${model}\" failed: ${error}`,\r\n );\r\n }\r\n\r\n return Array.isArray(result) ? result.length : result ? 1 : 0;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // FIND ONE\r\n // ------------------------------------------------------------------\r\n findOne: async <T>({\r\n model,\r\n where,\r\n select,\r\n }: {\r\n model: string;\r\n where: WhereClause[];\r\n select?: string[];\r\n join?: unknown;\r\n }) => {\r\n const db = ensureDbClient();\r\n\r\n const snakeMapper = (col: string) =>\r\n hasUppercase(col) ? toSnakeCase(col) : col;\r\n const identityMapper = (col: string) => col;\r\n\r\n const run = async (columnMapper: (col: string) => string) => {\r\n const columns =\r\n select && select.length > 0\r\n ? select.map((c) => columnMapper(c)).join(\", \")\r\n : undefined;\r\n\r\n let builder = db.from(model).select(columns);\r\n\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n columnMapper,\r\n );\r\n }\r\n\r\n const { data: result, error } = await builder.limit(1);\r\n return { result, error };\r\n };\r\n\r\n const first = await run(snakeMapper);\r\n if (first.error) {\r\n if (isMissingColumnError(first.error)) {\r\n const retry = await run(identityMapper);\r\n if (retry.error) {\r\n throw new Error(\r\n `[AthenaAdapter] findOne on \"${model}\" failed: ${retry.error}`,\r\n );\r\n }\r\n\r\n const rows = Array.isArray(retry.result)\r\n ? retry.result\r\n : retry.result\r\n ? [retry.result]\r\n : [];\r\n const row = rows[0] ?? null;\r\n return (row ? mapRowToBetterAuth(row as T) : null) as T | null;\r\n }\r\n\r\n throw new Error(\r\n `[AthenaAdapter] findOne on \"${model}\" failed: ${first.error}`,\r\n );\r\n }\r\n\r\n const rows = Array.isArray(first.result)\r\n ? first.result\r\n : first.result\r\n ? [first.result]\r\n : [];\r\n const row = rows[0] ?? null;\r\n return (row ? mapRowToBetterAuth(row as T) : null) as T | null;\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // FIND MANY\r\n // ------------------------------------------------------------------\r\n findMany: async <T>({\r\n model,\r\n where,\r\n limit,\r\n sortBy,\r\n offset,\r\n select,\r\n }: {\r\n model: string;\r\n where?: WhereClause[];\r\n limit: number;\r\n select?: string[];\r\n sortBy?: { field: string; direction: \"asc\" | \"desc\" };\r\n offset?: number;\r\n join?: unknown;\r\n }) => {\r\n const db = ensureDbClient();\r\n\r\n const snakeMapper = (col: string) =>\r\n hasUppercase(col) ? toSnakeCase(col) : col;\r\n const identityMapper = (col: string) => col;\r\n\r\n const run = async (columnMapper: (col: string) => string) => {\r\n const columns =\r\n select && select.length > 0\r\n ? select.map((c) => columnMapper(c)).join(\", \")\r\n : undefined;\r\n\r\n let builder = db.from(model).select(columns);\r\n\r\n if (where) {\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n columnMapper,\r\n );\r\n }\r\n }\r\n\r\n if (limit !== undefined) {\r\n builder = builder.limit(limit);\r\n }\r\n\r\n if (offset !== undefined) {\r\n builder = builder.offset(offset);\r\n }\r\n\r\n const { data: result, error } = await builder;\r\n return { result, error };\r\n };\r\n\r\n const first = await run(snakeMapper);\r\n const pickRows = (res: unknown) =>\r\n (Array.isArray(res) ? res : []) as Record<string, unknown>[];\r\n\r\n const applySort = (rows: T[]) => {\r\n if (!sortBy) return rows;\r\n const sortField = sortBy.field;\r\n rows.sort((a, b) => {\r\n const aVal = (a as Record<string, unknown>)[sortField];\r\n const bVal = (b as Record<string, unknown>)[sortField];\r\n if (aVal == null && bVal == null) return 0;\r\n if (aVal == null) return sortBy.direction === \"asc\" ? -1 : 1;\r\n if (bVal == null) return sortBy.direction === \"asc\" ? 1 : -1;\r\n const cmp =\r\n typeof aVal === \"string\" && typeof bVal === \"string\"\r\n ? aVal.localeCompare(bVal)\r\n : aVal < bVal\r\n ? -1\r\n : aVal > bVal\r\n ? 1\r\n : 0;\r\n return sortBy.direction === \"asc\" ? cmp : -cmp;\r\n });\r\n return rows;\r\n };\r\n\r\n const mapAndSort = (rows: Record<string, unknown>[]) => {\r\n const betterAuthRows = rows.map((r) =>\r\n mapRowToBetterAuth(r),\r\n ) as unknown as T[];\r\n return applySort(betterAuthRows);\r\n };\r\n\r\n if (first.error) {\r\n if (isMissingColumnError(first.error)) {\r\n const retry = await run(identityMapper);\r\n if (retry.error) {\r\n throw new Error(\r\n `[AthenaAdapter] findMany on \"${model}\" failed: ${retry.error}`,\r\n );\r\n }\r\n return mapAndSort(pickRows(retry.result));\r\n }\r\n\r\n throw new Error(\r\n `[AthenaAdapter] findMany on \"${model}\" failed: ${first.error}`,\r\n );\r\n }\r\n\r\n return mapAndSort(pickRows(first.result));\r\n },\r\n\r\n // ------------------------------------------------------------------\r\n // COUNT\r\n // ------------------------------------------------------------------\r\n count: async ({\r\n model,\r\n where,\r\n }: {\r\n model: string;\r\n where?: WhereClause[];\r\n }) => {\r\n const db = ensureDbClient();\r\n\r\n const snakeMapper = (col: string) =>\r\n hasUppercase(col) ? toSnakeCase(col) : col;\r\n const identityMapper = (col: string) => col;\r\n\r\n const run = async (columnMapper: (col: string) => string) => {\r\n let builder = db.from(model).select();\r\n\r\n if (where) {\r\n for (const clause of where) {\r\n builder = applyWhere(\r\n builder,\r\n clause.field,\r\n clause.operator,\r\n clause.value,\r\n columnMapper,\r\n );\r\n }\r\n }\r\n\r\n const { data: result, error } = await builder;\r\n return { result, error };\r\n };\r\n\r\n const first = await run(snakeMapper);\r\n if (first.error) {\r\n if (isMissingColumnError(first.error)) {\r\n const retry = await run(identityMapper);\r\n if (retry.error) {\r\n throw new Error(\r\n `[AthenaAdapter] count on \"${model}\" failed: ${retry.error}`,\r\n );\r\n }\r\n return Array.isArray(retry.result) ? retry.result.length : 0;\r\n }\r\n throw new Error(\r\n `[AthenaAdapter] count on \"${model}\" failed: ${first.error}`,\r\n );\r\n }\r\n\r\n return Array.isArray(first.result) ? first.result.length : 0;\r\n },\r\n };\r\n },\r\n });\r\n};\r\n","import fs from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport YAML from \"yaml\";\r\n\r\nexport type AthenaGlobalConfig = {\r\n athena: {\r\n url: string;\r\n apiKey: string;\r\n client?: string;\r\n };\r\n};\r\n\r\n// Defaults written to `config.yaml` if it doesn't exist.\r\n// These values are intentionally placeholders; the adapter will throw if\r\n// `url`/`apiKey` are still unset when used.\r\nexport const defaultAthenaGlobalConfig: AthenaGlobalConfig = {\r\n athena: {\r\n url: \"http://localhost:3000\",\r\n apiKey: \"\",\r\n client: \"better-auth\",\r\n },\r\n};\r\n\r\nexport const DEFAULT_CONFIG_FILENAME = \"config.yaml\";\r\n\r\nfunction resolveConfigPath(configPath?: string): string {\r\n if (configPath) return path.resolve(configPath);\r\n return path.resolve(process.cwd(), DEFAULT_CONFIG_FILENAME);\r\n}\r\n\r\nlet cached: AthenaGlobalConfig | null = null;\r\nlet cachedConfigPath: string | null = null;\r\nlet version = 0;\r\n\r\nlet watcher: fs.FSWatcher | null = null;\r\n\r\nfunction isObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction deepMerge<T extends Record<string, unknown>>(base: T, partial: unknown): T {\r\n if (!isObject(partial)) return base;\r\n const out: Record<string, unknown> = { ...base };\r\n for (const [k, v] of Object.entries(partial)) {\r\n if (v && isObject(v) && isObject(out[k])) {\r\n out[k] = deepMerge(out[k] as Record<string, unknown>, v);\r\n } else {\r\n out[k] = v;\r\n }\r\n }\r\n return out as T;\r\n}\r\n\r\nfunction ensureConfigFile(configPath: string): void {\r\n const dir = path.dirname(configPath);\r\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\r\n\r\n if (!fs.existsSync(configPath)) {\r\n const yaml = YAML.stringify(defaultAthenaGlobalConfig);\r\n fs.writeFileSync(configPath, yaml, \"utf-8\");\r\n }\r\n}\r\n\r\nfunction readConfigFromDisk(configPath: string): AthenaGlobalConfig {\r\n ensureConfigFile(configPath);\r\n const raw = fs.readFileSync(configPath, \"utf-8\");\r\n const parsed = YAML.parse(raw) as unknown;\r\n return deepMerge(defaultAthenaGlobalConfig, parsed);\r\n}\r\n\r\nfunction startWatcher(configPath: string): void {\r\n // Avoid multiple watchers when multiple adapter instances are created.\r\n if (cachedConfigPath !== null && cachedConfigPath !== configPath && watcher) {\r\n try {\r\n watcher.close();\r\n } catch {\r\n // ignore\r\n }\r\n watcher = null;\r\n }\r\n if (watcher || cachedConfigPath === configPath) return;\r\n\r\n try {\r\n watcher = fs.watch(configPath, { persistent: false }, (event) => {\r\n if (event !== \"change\" && event !== \"rename\") return;\r\n try {\r\n cached = readConfigFromDisk(configPath);\r\n version += 1;\r\n } catch {\r\n // Keep last known good config if reload fails.\r\n }\r\n });\r\n cachedConfigPath = configPath;\r\n } catch {\r\n // If watching isn't supported in the environment, just run without it.\r\n }\r\n}\r\n\r\nexport function getAthenaGlobalConfig(options?: {\r\n configPath?: string;\r\n watch?: boolean;\r\n}): { config: AthenaGlobalConfig; version: number } {\r\n const configPath = resolveConfigPath(options?.configPath);\r\n const shouldWatch = options?.watch ?? true;\r\n\r\n if (!cached || cachedConfigPath !== configPath) {\r\n cached = readConfigFromDisk(configPath);\r\n cachedConfigPath = configPath;\r\n version += 1;\r\n }\r\n\r\n if (shouldWatch) startWatcher(configPath);\r\n\r\n return { config: cached, version };\r\n}\r\n\r\n"],"mappings":"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","names":["path","fs","YAML","version","rows","row"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -8,15 +8,26 @@ interface AthenaAdapterConfig {
|
|
|
8
8
|
/**
|
|
9
9
|
* The URL of your Athena gateway.
|
|
10
10
|
*/
|
|
11
|
-
url
|
|
11
|
+
url?: string;
|
|
12
12
|
/**
|
|
13
13
|
* The API key for authenticating with the Athena gateway.
|
|
14
14
|
*/
|
|
15
|
-
apiKey
|
|
15
|
+
apiKey?: string;
|
|
16
16
|
/**
|
|
17
17
|
* The client name sent in requests to the Athena gateway.
|
|
18
18
|
*/
|
|
19
19
|
client?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Optional override for the YAML config path.
|
|
22
|
+
* Defaults to `./config.yaml` (resolved from `process.cwd()`).
|
|
23
|
+
*/
|
|
24
|
+
configPath?: string;
|
|
25
|
+
/**
|
|
26
|
+
* When enabled, the adapter will reload `config.yaml` on changes.
|
|
27
|
+
*
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
watchConfig?: boolean;
|
|
20
31
|
/**
|
|
21
32
|
* Helps you debug issues with the adapter.
|
|
22
33
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -8,15 +8,26 @@ interface AthenaAdapterConfig {
|
|
|
8
8
|
/**
|
|
9
9
|
* The URL of your Athena gateway.
|
|
10
10
|
*/
|
|
11
|
-
url
|
|
11
|
+
url?: string;
|
|
12
12
|
/**
|
|
13
13
|
* The API key for authenticating with the Athena gateway.
|
|
14
14
|
*/
|
|
15
|
-
apiKey
|
|
15
|
+
apiKey?: string;
|
|
16
16
|
/**
|
|
17
17
|
* The client name sent in requests to the Athena gateway.
|
|
18
18
|
*/
|
|
19
19
|
client?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Optional override for the YAML config path.
|
|
22
|
+
* Defaults to `./config.yaml` (resolved from `process.cwd()`).
|
|
23
|
+
*/
|
|
24
|
+
configPath?: string;
|
|
25
|
+
/**
|
|
26
|
+
* When enabled, the adapter will reload `config.yaml` on changes.
|
|
27
|
+
*
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
watchConfig?: boolean;
|
|
20
31
|
/**
|
|
21
32
|
* Helps you debug issues with the adapter.
|
|
22
33
|
*/
|