UNPKG

@ronin/better-auth

Version:
237 lines (234 loc) 6.77 kB
// src/index.ts import { add, alter, batch, count, create, drop, get, list, remove, set, sql, sqlBatch } from "ronin"; // src/transform.ts import { BetterAuthError } from "better-auth"; var HTTP_PATTERN = /^https?:\/\//; var convertWhereClause = (where) => { if (!where || where.length === 0) return {}; if (where.length === 1) { const w = where[0]; if (!w) return {}; if (w.operator === "eq" || !w.operator) return { [w.field]: w.value }; return { [w.field]: operatorToAssertion(w.operator, w.value) }; } const and = where.filter((w) => w.connector === "AND" || !w.connector); const andClause = and.map((w) => { if (w.operator === "eq" || !w.operator) return { [w.field]: w.value }; return { [w.field]: operatorToAssertion(w.operator, w.value) }; }); if (andClause.length > 0) return Object.assign({}, ...andClause); const or = where.filter((w) => w.connector === "OR"); return or.map((w) => { if (w.operator === "eq" || !w.operator) return { [w.field]: w.value }; return { [w.field]: operatorToAssertion(w.operator, w.value) }; }); }; var getModel = async (factory, slug) => { const model = await factory.list.model(slug); if (!model) throw new BetterAuthError( "Failed to resolve model", `No model found for slug \`${slug}\`` ); if (!model.pluralSlug) throw new BetterAuthError( "Invalid RONIN model", `The \`pluralSlug\` for the \`${slug}\` is missing or broken.` ); return model; }; var transformInput = async (data, model) => { if (Array.isArray(data)) { const results = await Promise.all(data.map((d) => transformInput(d, model))); return results; } const { createdAt, updatedAt, ...values } = data; const properties = /* @__PURE__ */ new Map(); if (createdAt || updatedAt) properties.set("ronin", { createdAt: createdAt ?? null, updatedAt: updatedAt ?? null }); for (const [key, value] of Object.entries(values)) { if (key === "image" && model === "user" && typeof value === "string") { properties.set(key, null); if (HTTP_PATTERN.test(value)) { const response = await fetch(value); if (!response.ok) continue; properties.set(key, await response.blob()); } continue; } properties.set(key, value); } return Object.fromEntries(properties); }; var transformOrderedBy = (sortBy) => { if (!sortBy) return void 0; const key = sortBy.direction === "asc" ? "ascending" : "descending"; const results = new Array(); switch (sortBy.field) { case "createdAt": { results.push("ronin.createdAt"); break; } case "updatedAt": { results.push("ronin.updatedAt"); break; } default: results.push(sortBy.field); break; } return { [key]: results }; }; var transformOutput = (data) => { if (!data || data === null) return null; const { id, ronin: ronin2, ...values } = data; const properties = /* @__PURE__ */ new Map([ ["id", id], ["createdAt", ronin2?.createdAt], ["updatedAt", ronin2?.updatedAt] ]); for (const [key, value] of Object.entries(values)) { properties.set(key, value); } return Object.fromEntries(properties); }; var OPERATOR_TO_ASSERTION_MAP = { contains: "containing", ends_with: "endingWith", eq: "being", gt: "greaterThan", gte: "greaterOrEqual", lt: "lessThan", lte: "lessOrEqual", ne: "notBeing", starts_with: "startingWith" }; var operatorToAssertion = (operator, value) => { if (operator in OPERATOR_TO_ASSERTION_MAP) { const typedOperator = operator; return { [OPERATOR_TO_ASSERTION_MAP[typedOperator]]: value }; } return value; }; // src/index.ts var ronin = (client) => { return () => { const factory = client ?? { add, alter, batch, count, create, drop, get, list, remove, set, sql, sqlBatch }; return { id: "ronin", count: async ({ model: slug, where = [] }) => { const model = await getModel(factory, slug); const instructions = convertWhereClause(where); const transformed = await transformInput(instructions, slug); return factory.count[model.pluralSlug].with(transformed); }, create: async ({ data, model }) => { const transformed = await transformInput(data, model); const record = await factory.add[model].with(transformed); return transformOutput(record); }, delete: async ({ model, where = [] }) => { const instructions = convertWhereClause(where); await factory.remove[model].with(instructions); }, deleteMany: async ({ model: slug, where = [] }) => { const model = await getModel(factory, slug); const instructions = convertWhereClause(where); const transformed = await transformInput(instructions, slug); const results = await factory.remove[model.pluralSlug].with(transformed); return results.length; }, findMany: async ({ model: slug, limit, offset, sortBy, where = [] }) => { const model = await getModel(factory, slug); const instructions = convertWhereClause(where); const transformed = await transformInput(instructions, slug); const results = await factory.get[model.pluralSlug]({ after: offset?.toString(), limitedTo: limit, orderedBy: transformOrderedBy(sortBy), with: transformed }); return results.map((result) => transformOutput(result)); }, findOne: async ({ model, where }) => { const instructions = convertWhereClause(where); const result = await factory.get[model].with( instructions ); return transformOutput(result); }, update: async ({ model, update, where = [] }) => { const instructions = convertWhereClause(where); const transformed = await transformInput(update, model); const result = await factory.set[model]({ with: instructions, to: transformed }); return transformOutput(result); }, updateMany: async ({ model: slug, update, where = [] }) => { const model = await getModel(factory, slug); const instructions = convertWhereClause(where); const transformed = await transformInput(update, slug); const results = await factory.set[model.pluralSlug]({ to: transformed, with: instructions }); return results.length; } }; }; }; var src_default = ronin; export { src_default as default, ronin };