@deessejs/collections 0.3.0 → 0.4.1

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/dist/index.mjs CHANGED
@@ -1,3 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
1
8
  // src/field-type.ts
2
9
  var fieldType = (config) => {
3
10
  return () => ({
@@ -673,11 +680,21 @@ var createCollectionOperations = (_collection, _slug, _db, _table, _hooks) => {
673
680
 
674
681
  // src/adapter.ts
675
682
  var pgAdapter = (config) => {
683
+ let pool = null;
676
684
  return {
677
685
  type: "postgres",
678
686
  config: {
679
687
  url: config.url,
680
688
  migrationsPath: config.migrationsPath ?? "./migrations"
689
+ },
690
+ getPool: async () => {
691
+ if (!pool) {
692
+ const { Pool: Pool2 } = await import("pg");
693
+ pool = new Pool2({
694
+ connectionString: config.url
695
+ });
696
+ }
697
+ return pool;
681
698
  }
682
699
  };
683
700
  };
@@ -728,160 +745,109 @@ var buildSchema = (collections) => {
728
745
  };
729
746
 
730
747
  // src/migrations.ts
731
- import { spawn } from "child_process";
732
- import { resolve } from "path";
733
- import process from "process";
734
- function runCommand(command, args, options = {}) {
735
- return new Promise((resolve2, reject) => {
736
- if (options.verbose) {
737
- console.log(`[collections] Running: ${command} ${args.join(" ")}`);
738
- }
739
- const child = spawn(command, args, {
740
- stdio: options.verbose ? "inherit" : "pipe",
741
- shell: true,
742
- cwd: process.cwd()
743
- });
744
- let output = "";
745
- if (!options.verbose) {
746
- child.stdout?.on("data", (data) => {
747
- output += data.toString();
748
- });
749
- child.stderr?.on("data", (data) => {
750
- output += data.toString();
751
- });
752
- }
753
- child.on("close", (code) => {
754
- if (code === 0) {
755
- resolve2(code ?? 0);
756
- } else {
757
- reject(new Error(`Command failed with code ${code}: ${output}`));
758
- }
759
- });
760
- child.on("error", (error) => {
761
- reject(error);
762
- });
763
- });
748
+ import { drizzle } from "drizzle-orm/node-postgres";
749
+ async function getDrizzleKitApi() {
750
+ const api = __require("drizzle-kit/api");
751
+ return api;
764
752
  }
765
- function buildDrizzleConfig(options) {
766
- const config = {
767
- dialect: "postgresql",
768
- schema: options.schemaPath,
769
- out: options.out,
770
- dbCredentials: {
771
- url: options.dbUrl
772
- }
773
- };
774
- if (options.migrationsTable) {
775
- config.migrations = {
776
- table: options.migrationsTable
777
- };
753
+ var push = async (adapter, collections, options = {}) => {
754
+ const { verbose = false, dryRun = false } = options;
755
+ const schema = buildSchema(collections);
756
+ const pool = await adapter.getPool();
757
+ const db = drizzle(pool, { schema });
758
+ const { pushSchema } = await getDrizzleKitApi();
759
+ if (verbose) {
760
+ console.log("[collections] Building schema from collections...");
761
+ console.log("[collections] Tables:", Object.keys(schema).join(", "));
778
762
  }
779
- return JSON.stringify(config, null, 2);
780
- }
781
- var push = async (adapter, _collections, options = {}) => {
782
- const {
783
- verbose = false,
784
- dryRun = false,
785
- out = "./drizzle",
786
- configPath = "./collections/config.ts",
787
- migrationsTable = "__drizzle_collections"
788
- } = options;
789
- const configContent = buildDrizzleConfig({
790
- out,
791
- schemaPath: configPath,
792
- dbUrl: adapter.config.url,
793
- migrationsTable
794
- });
795
- const drizzleConfigPath = resolve(process.cwd(), "./drizzle.config.json");
796
- const { writeFileSync, unlinkSync } = await import("fs");
797
- try {
798
- writeFileSync(drizzleConfigPath, configContent);
799
- const args = ["drizzle-kit", "push"];
800
- if (dryRun) {
801
- args.push("--dry-run");
763
+ const result = await pushSchema(schema, db);
764
+ if (verbose) {
765
+ if (result.warnings.length > 0) {
766
+ console.log("[collections] Warnings:");
767
+ result.warnings.forEach((w) => console.log(" -", w));
802
768
  }
769
+ console.log("[collections] Statements to execute:", result.statementsToExecute.length);
770
+ }
771
+ if (dryRun) {
772
+ console.log("[collections] Dry run - not applying changes");
803
773
  if (verbose) {
804
- args.push("--verbose");
805
- }
806
- await runCommand("npx", args, { verbose });
807
- if (verbose) {
808
- console.log("[collections] Schema pushed successfully");
809
- }
810
- } finally {
811
- try {
812
- unlinkSync(drizzleConfigPath);
813
- } catch {
774
+ console.log("[collections] SQL statements:");
775
+ result.statementsToExecute.forEach((stmt) => console.log(" ", stmt));
814
776
  }
777
+ return;
778
+ }
779
+ await result.apply();
780
+ if (verbose) {
781
+ console.log("[collections] Schema pushed successfully");
815
782
  }
816
783
  };
817
- var generate = async (adapter, _collections, options = {}) => {
818
- const {
819
- verbose = false,
820
- out = "./drizzle",
821
- configPath = "./collections/config.ts",
822
- migrationsTable = "__drizzle_collections"
823
- } = options;
824
- const configContent = buildDrizzleConfig({
825
- out,
826
- schemaPath: configPath,
827
- dbUrl: adapter.config.url,
828
- migrationsTable
829
- });
830
- const drizzleConfigPath = resolve(process.cwd(), "./drizzle.config.json");
831
- const { writeFileSync, unlinkSync } = await import("fs");
784
+ var generate = async (_adapter, collections, options = {}) => {
785
+ const { verbose = false, out = "./drizzle" } = options;
786
+ const schema = buildSchema(collections);
787
+ const { generateDrizzleJson } = await getDrizzleKitApi();
788
+ if (verbose) {
789
+ console.log("[collections] Building schema from collections...");
790
+ console.log("[collections] Tables:", Object.keys(schema).join(", "));
791
+ }
792
+ const currentSnapshot = generateDrizzleJson(schema);
793
+ if (verbose) {
794
+ console.log("[collections] Current snapshot ID:", currentSnapshot.id);
795
+ }
796
+ const migrationSQL = [
797
+ "-- Generated migration",
798
+ `-- Snapshot: ${currentSnapshot.id}`,
799
+ "",
800
+ "-- Tables will be created based on current collections schema",
801
+ ...currentSnapshot.tables?.map((table) => `-- Table: ${table}`) ?? []
802
+ ];
803
+ const { writeFileSync, mkdirSync } = await import("fs");
832
804
  try {
833
- writeFileSync(drizzleConfigPath, configContent);
834
- const args = ["drizzle-kit", "generate"];
835
- if (verbose) {
836
- args.push("--verbose");
837
- }
838
- await runCommand("npx", args, { verbose });
839
- if (verbose) {
840
- console.log("[collections] Migrations generated successfully");
841
- }
842
- } finally {
843
- try {
844
- unlinkSync(drizzleConfigPath);
845
- } catch {
846
- }
805
+ mkdirSync(out, { recursive: true });
806
+ } catch {
807
+ }
808
+ const timestamp3 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
809
+ const filename = `${out}/migration-${timestamp3}.sql`;
810
+ writeFileSync(filename, migrationSQL.join("\n"));
811
+ if (verbose) {
812
+ console.log("[collections] Migration written to:", filename);
847
813
  }
848
814
  };
849
815
  var migrate = async (adapter, options = {}) => {
850
- const {
851
- verbose = false,
852
- out = "./drizzle",
853
- configPath = "./collections/config.ts",
854
- migrationsTable = "__drizzle_collections"
855
- } = options;
856
- const configContent = buildDrizzleConfig({
857
- out,
858
- schemaPath: configPath,
859
- dbUrl: adapter.config.url,
860
- migrationsTable
861
- });
862
- const drizzleConfigPath = resolve(process.cwd(), "./drizzle.config.json");
863
- const { writeFileSync, unlinkSync } = await import("fs");
816
+ const { verbose = false } = options;
817
+ const pool = await adapter.getPool();
818
+ if (verbose) {
819
+ console.log("[collections] Applying migrations...");
820
+ }
821
+ const { readdirSync, readFileSync } = await import("fs");
822
+ const migrationsPath = adapter.config.migrationsPath ?? "./migrations";
864
823
  try {
865
- writeFileSync(drizzleConfigPath, configContent);
866
- const args = ["drizzle-kit", "migrate"];
867
- if (verbose) {
868
- args.push("--verbose");
824
+ const files = readdirSync(migrationsPath).filter((f2) => f2.endsWith(".sql")).sort();
825
+ if (files.length === 0) {
826
+ if (verbose) {
827
+ console.log("[collections] No migration files found");
828
+ }
829
+ return;
830
+ }
831
+ for (const file of files) {
832
+ if (verbose) {
833
+ console.log("[collections] Applying migration:", file);
834
+ }
835
+ const sql = readFileSync(`${migrationsPath}/${file}`, "utf-8");
836
+ await pool.query(sql);
869
837
  }
870
- await runCommand("npx", args, { verbose });
871
838
  if (verbose) {
872
839
  console.log("[collections] Migrations applied successfully");
873
840
  }
874
- } finally {
875
- try {
876
- unlinkSync(drizzleConfigPath);
877
- } catch {
841
+ } catch (error) {
842
+ if (verbose) {
843
+ console.log("[collections] No migrations directory or error:", error);
878
844
  }
879
845
  }
880
846
  };
881
847
 
882
848
  // src/config.ts
883
849
  import { Pool } from "pg";
884
- import { drizzle } from "drizzle-orm/node-postgres";
850
+ import { drizzle as drizzle2 } from "drizzle-orm/node-postgres";
885
851
  var defineConfig = (options) => {
886
852
  let pool = null;
887
853
  let dbInstance = null;
@@ -891,7 +857,7 @@ var defineConfig = (options) => {
891
857
  connectionString: options.database.config.url
892
858
  });
893
859
  schema = buildSchema(options.collections);
894
- dbInstance = drizzle(pool, { schema });
860
+ dbInstance = drizzle2(pool, { schema });
895
861
  }
896
862
  const collectionsMap = {};
897
863
  const collectionNames = [];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/field-type.ts","../src/field.ts","../src/fields/f.ts","../src/collection.ts","../src/operations/collection-operations.ts","../src/adapter.ts","../src/schema.ts","../src/migrations.ts","../src/config.ts"],"sourcesContent":["import { z } from 'zod'\r\n\r\n/**\r\n * A field type instance (already configured)\r\n */\r\nexport type FieldTypeInstance = {\r\n schema: z.ZodType\r\n database: unknown\r\n}\r\n\r\n/**\r\n * A field type creator (needs to be called to get instance)\r\n */\r\nexport type FieldTypeCreator = () => FieldTypeInstance\r\n\r\n/**\r\n * Field type configuration\r\n */\r\nexport type FieldTypeConfig = {\r\n schema: z.ZodType\r\n database?: unknown\r\n}\r\n\r\n/**\r\n * Creates a new field type\r\n *\r\n * @example\r\n * const text = fieldType({\r\n * schema: z.string(),\r\n * database: { type: 'text' }\r\n * })\r\n *\r\n * const textField = text() // Get instance\r\n */\r\nexport const fieldType = (config: FieldTypeConfig): (() => FieldTypeInstance) => {\r\n return () => ({\r\n schema: config.schema,\r\n database: config.database ?? {}\r\n })\r\n}\r\n","import type { FieldTypeInstance } from './field-type'\r\n\r\n/**\r\n * Field configuration options\r\n */\r\nexport type FieldOptions = {\r\n fieldType: FieldTypeInstance\r\n required?: boolean\r\n unique?: boolean\r\n indexed?: boolean\r\n default?: unknown\r\n label?: string\r\n description?: string\r\n}\r\n\r\n/**\r\n * Creates a field definition\r\n *\r\n * @example\r\n * name: field({ fieldType: text() })\r\n * email: field({ fieldType: email(), unique: true })\r\n */\r\nexport const field = (config: FieldOptions): FieldDefinition => {\r\n return {\r\n fieldType: config.fieldType,\r\n required: config.required ?? false,\r\n unique: config.unique ?? false,\r\n indexed: config.indexed ?? false,\r\n default: config.default,\r\n label: config.label,\r\n description: config.description\r\n }\r\n}\r\n\r\n/**\r\n * A field definition\r\n */\r\nexport type FieldDefinition = {\r\n fieldType: FieldTypeInstance\r\n required: boolean\r\n unique: boolean\r\n indexed: boolean\r\n default?: unknown\r\n label?: string\r\n description?: string\r\n}\r\n","import { fieldType, type FieldTypeInstance } from '../field-type'\r\nimport { z } from 'zod'\r\n\r\n/**\r\n * Derive the database type string from a Zod schema\r\n */\r\nconst getItemType = (itemSchema: z.ZodType): string => {\r\n if (itemSchema instanceof z.ZodString) return 'text'\r\n if (itemSchema instanceof z.ZodNumber) return 'integer'\r\n if (itemSchema instanceof z.ZodBoolean) return 'boolean'\r\n if (itemSchema instanceof z.ZodDate) return 'timestamp'\r\n if (itemSchema instanceof z.ZodEnum) return 'text'\r\n if (itemSchema instanceof z.ZodArray) return 'array'\r\n if (itemSchema instanceof z.ZodObject) return 'jsonb'\r\n return 'text'\r\n}\r\n\r\n/**\r\n * Field types namespace (like zod's z)\r\n */\r\nexport const f = {\r\n /**\r\n * Text field type\r\n */\r\n text: (): FieldTypeInstance => fieldType({\r\n schema: z.string(),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * Email field type with built-in validation\r\n */\r\n email: (): FieldTypeInstance => fieldType({\r\n schema: z.string().email(),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * URL field type with built-in validation\r\n */\r\n url: (): FieldTypeInstance => fieldType({\r\n schema: z.string().url(),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * Number field type\r\n */\r\n number: (): FieldTypeInstance => fieldType({\r\n schema: z.number(),\r\n database: { type: 'integer' }\r\n })(),\r\n\r\n /**\r\n * Boolean field type\r\n */\r\n boolean: (): FieldTypeInstance => fieldType({\r\n schema: z.boolean(),\r\n database: { type: 'boolean' }\r\n })(),\r\n\r\n /**\r\n * Date field type (date only, no time)\r\n */\r\n date: (): FieldTypeInstance => fieldType({\r\n schema: z.date(),\r\n database: { type: 'date' }\r\n })(),\r\n\r\n /**\r\n * Timestamp field type (date with time)\r\n */\r\n timestamp: (): FieldTypeInstance => fieldType({\r\n schema: z.date(),\r\n database: { type: 'timestamp' }\r\n })(),\r\n\r\n /**\r\n * Creates a select field type\r\n */\r\n select: <T extends readonly [string, ...string[]]>(\r\n options: T\r\n ): FieldTypeInstance => fieldType({\r\n schema: z.enum(options),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * JSON field type for storing JSON data\r\n */\r\n json: (schema?: z.ZodType): FieldTypeInstance => fieldType({\r\n schema: schema ?? z.any(),\r\n database: { type: 'jsonb' }\r\n })(),\r\n\r\n /**\r\n * Array field type for storing lists\r\n */\r\n array: (itemSchema: z.ZodType): FieldTypeInstance => fieldType({\r\n schema: z.array(itemSchema),\r\n database: { type: 'array', itemType: getItemType(itemSchema) }\r\n })(),\r\n\r\n /**\r\n * Creates a relation field type for foreign key relationships\r\n */\r\n relation: (options: {\r\n collection: string\r\n singular?: boolean\r\n many?: boolean\r\n through?: string\r\n }): FieldTypeInstance => {\r\n const isMany = options.many ?? false\r\n const isSingular = options.singular ?? false\r\n\r\n return fieldType({\r\n schema: isMany ? z.array(z.string()) : z.string(),\r\n database: {\r\n type: 'integer',\r\n references: options.collection,\r\n through: options.through,\r\n many: isMany,\r\n singular: isSingular\r\n }\r\n })()\r\n }\r\n}\r\n\r\n/**\r\n * @deprecated Use f.text() instead\r\n */\r\nexport const text = f.text\r\n\r\n/**\r\n * @deprecated Use f.email() instead\r\n */\r\nexport const email = f.email\r\n\r\n/**\r\n * @deprecated Use f.url() instead\r\n */\r\nexport const url = f.url\r\n\r\n/**\r\n * @deprecated Use f.number() instead\r\n */\r\nexport const number = f.number\r\n\r\n/**\r\n * @deprecated Use f.boolean() instead\r\n */\r\nexport const boolean = f.boolean\r\n\r\n/**\r\n * @deprecated Use f.date() instead\r\n */\r\nexport const date = f.date\r\n\r\n/**\r\n * @deprecated Use f.timestamp() instead\r\n */\r\nexport const timestamp = f.timestamp\r\n\r\n/**\r\n * @deprecated Use f.select() instead\r\n */\r\nexport const select = f.select\r\n\r\n/**\r\n * @deprecated Use f.json() instead\r\n */\r\nexport const json = f.json\r\n\r\n/**\r\n * @deprecated Use f.array() instead\r\n */\r\nexport const array = f.array\r\n\r\n/**\r\n * @deprecated Use f.relation() instead\r\n */\r\nexport const relation = f.relation\r\n\r\n/**\r\n * @deprecated Use f.relation instead\r\n */\r\nexport type RelationOptions = {\r\n collection: string\r\n singular?: boolean\r\n many?: boolean\r\n through?: string\r\n}\r\n","import type { FieldDefinition } from './field'\r\n\r\n/**\r\n * Collection configuration\r\n */\r\nexport type CollectionConfig<T extends Record<string, unknown> = Record<string, unknown>> = {\r\n slug: string\r\n name?: string\r\n fields: Record<string, FieldDefinition>\r\n hooks?: CollectionHooks\r\n dataType?: T\r\n}\r\n\r\n/**\r\n * Operation types\r\n */\r\nexport type OperationType = 'create' | 'update' | 'delete' | 'read'\r\n\r\n/**\r\n * Hook context base\r\n */\r\nexport type HookContextBase = {\r\n collection: string\r\n operation: OperationType\r\n}\r\n\r\n/**\r\n * Before/After Operation context\r\n */\r\nexport type OperationHookContext = HookContextBase & {\r\n data?: Record<string, unknown>\r\n where?: Record<string, unknown>\r\n result?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Create context\r\n */\r\nexport type CreateHookContext = HookContextBase & {\r\n operation: 'create'\r\n data: Record<string, unknown>\r\n result?: unknown\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Update context\r\n */\r\nexport type UpdateHookContext = HookContextBase & {\r\n operation: 'update'\r\n data: Record<string, unknown>\r\n where: Record<string, unknown>\r\n previousData?: Record<string, unknown>\r\n result?: unknown\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Delete context\r\n */\r\nexport type DeleteHookContext = HookContextBase & {\r\n operation: 'delete'\r\n where: Record<string, unknown>\r\n previousData?: Record<string, unknown>\r\n result?: unknown\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Read context\r\n */\r\nexport type ReadHookContext = HookContextBase & {\r\n operation: 'read'\r\n query?: Record<string, unknown>\r\n result?: unknown[]\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Generic hook function type\r\n */\r\nexport type GenericHookFunction = (context: OperationHookContext) => Promise<void> | void\r\nexport type CreateHookFunction = (context: CreateHookContext) => Promise<void> | void\r\nexport type UpdateHookFunction = (context: UpdateHookContext) => Promise<void> | void\r\nexport type DeleteHookFunction = (context: DeleteHookContext) => Promise<void> | void\r\nexport type ReadHookFunction = (context: ReadHookContext) => Promise<void> | void\r\n\r\n/**\r\n * Collection hooks\r\n */\r\nexport type CollectionHooks = {\r\n beforeOperation?: GenericHookFunction[]\r\n afterOperation?: GenericHookFunction[]\r\n beforeCreate?: CreateHookFunction[]\r\n afterCreate?: CreateHookFunction[]\r\n beforeUpdate?: UpdateHookFunction[]\r\n afterUpdate?: UpdateHookFunction[]\r\n beforeDelete?: DeleteHookFunction[]\r\n afterDelete?: DeleteHookFunction[]\r\n beforeRead?: ReadHookFunction[]\r\n afterRead?: ReadHookFunction[]\r\n}\r\n\r\n/**\r\n * A collection definition\r\n */\r\nexport type Collection<T extends Record<string, unknown> = Record<string, unknown>> = {\r\n slug: string\r\n name?: string\r\n fields: Record<string, FieldDefinition>\r\n hooks?: CollectionHooks\r\n dataType?: T\r\n}\r\n\r\n/**\r\n * Creates a new collection\r\n *\r\n * @example\r\n * export const users = collection({\r\n * slug: 'users',\r\n * name: 'Users',\r\n * fields: {\r\n * name: field({ fieldType: text }),\r\n * email: field({ fieldType: email, unique: true })\r\n * }\r\n * })\r\n */\r\nexport const collection = <T extends Record<string, unknown> = Record<string, unknown>>(\r\n config: CollectionConfig<T>\r\n): Collection<T> => {\r\n return {\r\n slug: config.slug,\r\n name: config.name,\r\n fields: config.fields,\r\n hooks: config.hooks,\r\n dataType: config.dataType\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { eq, and, like, gt, gte, lt, lte, isNull, inArray, not, desc, asc } from 'drizzle-orm'\r\n\r\nimport type { Collection, CollectionHooks, CreateHookContext, UpdateHookContext, DeleteHookContext, ReadHookContext, OperationHookContext } from '../collection'\r\nimport type {\r\n FindManyOptions,\r\n FindUniqueOptions,\r\n FindFirstOptions,\r\n CreateOptions,\r\n CreateManyOptions,\r\n UpdateOptions,\r\n UpdateManyOptions,\r\n DeleteOptions,\r\n DeleteManyOptions,\r\n CountOptions,\r\n ExistsOptions,\r\n WhereOperator\r\n} from './types'\r\n\r\n/**\r\n * Collection operations interface\r\n */\r\nexport interface CollectionOperations {\r\n findMany<T>(options?: FindManyOptions): Promise<T[]>\r\n findUnique<T>(options: FindUniqueOptions): Promise<T | undefined>\r\n findFirst<T>(options: FindFirstOptions): Promise<T | undefined>\r\n create<T>(options: CreateOptions<T>): Promise<T | undefined>\r\n createMany<T>(options: CreateManyOptions<T>): Promise<number>\r\n update<T>(options: UpdateOptions<T>): Promise<T | undefined>\r\n updateMany<T>(options: UpdateManyOptions<T>): Promise<number>\r\n delete<T>(options: DeleteOptions): Promise<T | undefined>\r\n deleteMany(options: DeleteManyOptions): Promise<number>\r\n count(options?: CountOptions): Promise<number>\r\n exists(options: ExistsOptions): Promise<boolean>\r\n}\r\n\r\n/**\r\n * Build where conditions from options\r\n */\r\nconst buildWhereClause = (\r\n tableColumns: Record<string, any>,\r\n where?: Record<string, unknown>\r\n): any => {\r\n if (!where) return undefined\r\n\r\n const conditions: any[] = []\r\n\r\n for (const [key, value] of Object.entries(where)) {\r\n const column = tableColumns[key]\r\n if (!column) continue\r\n\r\n if (value === null || typeof value !== 'object') {\r\n conditions.push(eq(column, value))\r\n } else {\r\n const operator = value as WhereOperator<unknown>\r\n if ('eq' in operator) {\r\n conditions.push(eq(column, operator.eq))\r\n } else if ('neq' in operator) {\r\n conditions.push(not(eq(column, operator.neq)))\r\n } else if ('gt' in operator) {\r\n conditions.push(gt(column, operator.gt as number))\r\n } else if ('gte' in operator) {\r\n conditions.push(gte(column, operator.gte as number))\r\n } else if ('lt' in operator) {\r\n conditions.push(lt(column, operator.lt as number))\r\n } else if ('lte' in operator) {\r\n conditions.push(lte(column, operator.lte as number))\r\n } else if ('in' in operator) {\r\n conditions.push(inArray(column, operator.in))\r\n } else if ('notIn' in operator) {\r\n conditions.push(not(inArray(column, operator.notIn)))\r\n } else if ('contains' in operator) {\r\n conditions.push(like(column, `%${operator.contains}%`))\r\n } else if ('startsWith' in operator) {\r\n conditions.push(like(column, `${operator.startsWith}%`))\r\n } else if ('endsWith' in operator) {\r\n conditions.push(like(column, `%${operator.endsWith}`))\r\n } else if ('isNull' in operator) {\r\n if (operator.isNull) {\r\n conditions.push(isNull(column))\r\n }\r\n } else if ('not' in operator) {\r\n conditions.push(not(eq(column, operator.not)))\r\n }\r\n }\r\n }\r\n\r\n if (conditions.length === 0) return undefined\r\n if (conditions.length === 1) return conditions[0]\r\n return and(...conditions)\r\n}\r\n\r\n/**\r\n * Build orderBy from options\r\n */\r\nconst buildOrderBy = (\r\n tableColumns: Record<string, any>,\r\n orderBy?: Record<string, unknown> | Record<string, unknown>[]\r\n): any[] => {\r\n if (!orderBy) return []\r\n\r\n const orders = Array.isArray(orderBy) ? orderBy : [orderBy]\r\n return orders.map((order) => {\r\n for (const [key, direction] of Object.entries(order)) {\r\n const column = tableColumns[key]\r\n if (!column) continue\r\n return direction === 'desc' ? desc(column) : asc(column)\r\n }\r\n return undefined\r\n }).filter(Boolean)\r\n}\r\n\r\n/**\r\n * Execute before operation hooks\r\n */\r\nconst executeBeforeOperationHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: OperationHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeOperation) return\r\n for (const hook of hooks.beforeOperation) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after operation hooks\r\n */\r\nconst executeAfterOperationHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: OperationHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterOperation) return\r\n for (const hook of hooks.afterOperation) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before create hooks\r\n */\r\nconst executeBeforeCreateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: CreateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeCreate) return\r\n for (const hook of hooks.beforeCreate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after create hooks\r\n */\r\nconst executeAfterCreateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: CreateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterCreate) return\r\n for (const hook of hooks.afterCreate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before update hooks\r\n */\r\nconst executeBeforeUpdateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: UpdateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeUpdate) return\r\n for (const hook of hooks.beforeUpdate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after update hooks\r\n */\r\nconst executeAfterUpdateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: UpdateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterUpdate) return\r\n for (const hook of hooks.afterUpdate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before delete hooks\r\n */\r\nconst executeBeforeDeleteHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: DeleteHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeDelete) return\r\n for (const hook of hooks.beforeDelete) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after delete hooks\r\n */\r\nconst executeAfterDeleteHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: DeleteHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterDelete) return\r\n for (const hook of hooks.afterDelete) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before read hooks\r\n */\r\nconst executeBeforeReadHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: ReadHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeRead) return\r\n for (const hook of hooks.beforeRead) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after read hooks\r\n */\r\nconst executeAfterReadHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: ReadHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterRead) return\r\n for (const hook of hooks.afterRead) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Creates collection operations with Drizzle\r\n */\r\nexport const createCollectionOperations = (\r\n _collection: Collection,\r\n _slug: string,\r\n _db: any,\r\n _table: any,\r\n _hooks?: CollectionHooks\r\n): CollectionOperations => {\r\n const tableColumns = _table as Record<string, any>\r\n const db = _db as any\r\n const hooks = _hooks as CollectionHooks | undefined\r\n\r\n // If no db instance, return placeholder operations\r\n if (!db) {\r\n return {\r\n findMany: async <T>(): Promise<T[]> => [],\r\n findUnique: async <T>(): Promise<T | undefined> => undefined,\r\n findFirst: async <T>(): Promise<T | undefined> => undefined,\r\n create: async <T>(): Promise<T | undefined> => undefined,\r\n createMany: async (): Promise<number> => 0,\r\n update: async <T>(): Promise<T | undefined> => undefined,\r\n updateMany: async (): Promise<number> => 0,\r\n delete: async <T>(): Promise<T | undefined> => undefined,\r\n deleteMany: async (): Promise<number> => 0,\r\n count: async (): Promise<number> => 0,\r\n exists: async (): Promise<boolean> => false\r\n }\r\n }\r\n\r\n return {\r\n findMany: async <T>(options?: FindManyOptions): Promise<T[]> => {\r\n const whereClause = buildWhereClause(tableColumns, options?.where)\r\n const orderByClause = buildOrderBy(tableColumns, options?.orderBy)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n let query = db.select().from(_table)\r\n\r\n if (whereClause) {\r\n query = query.where(whereClause)\r\n }\r\n\r\n if (orderByClause.length > 0) {\r\n query = query.orderBy(...orderByClause)\r\n }\r\n\r\n if (options?.offset) {\r\n query = query.offset(options.offset)\r\n }\r\n\r\n if (options?.limit) {\r\n query = query.limit(options.limit)\r\n }\r\n\r\n const result = await query\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: result as unknown[],\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where,\r\n result\r\n })\r\n\r\n return result as T[]\r\n },\r\n\r\n findUnique: async <T>(options: FindUniqueOptions): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return undefined\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n const result = await db.select().from(_table).where(whereClause).limit(1)\r\n const returnValue = result[0] as T | undefined\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: returnValue ? [returnValue] : [],\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n findFirst: async <T>(options: FindFirstOptions): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n const orderByClause = buildOrderBy(tableColumns, options.orderBy)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n let query = db.select().from(_table)\r\n\r\n if (whereClause) {\r\n query = query.where(whereClause)\r\n }\r\n\r\n if (orderByClause.length > 0) {\r\n query = query.orderBy(...orderByClause)\r\n }\r\n\r\n const result = await query.limit(1)\r\n const returnValue = result[0] as T | undefined\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: returnValue ? [returnValue] : [],\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n create: async <T>(options: CreateOptions<T>): Promise<T | undefined> => {\r\n const data = Array.isArray(options.data) ? options.data : [options.data]\r\n const firstData = data[0] as Record<string, unknown>\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n where: undefined\r\n })\r\n\r\n // Execute before create hooks\r\n await executeBeforeCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n db\r\n })\r\n\r\n const result = await db.insert(_table).values(data).returning()\r\n\r\n const returnValue = options.returning ? result[0] as T : undefined\r\n\r\n // Execute after create hooks\r\n await executeAfterCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n result: returnValue,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n createMany: async <T>(options: CreateManyOptions<T>): Promise<number> => {\r\n const dataArray = Array.isArray(options.data) ? options.data : [options.data]\r\n\r\n // Execute before operation hooks for each item\r\n for (const data of dataArray) {\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: data as Record<string, unknown>,\r\n where: undefined\r\n })\r\n\r\n await executeBeforeCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: data as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n const result = await db.insert(_table).values(options.data as any)\r\n\r\n // Execute after operation hooks for each item\r\n for (let i = 0; i < dataArray.length; i++) {\r\n await executeAfterCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: dataArray[i] as Record<string, unknown>,\r\n result: result[i],\r\n db\r\n })\r\n\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: dataArray[i] as Record<string, unknown>,\r\n result: result[i]\r\n })\r\n }\r\n\r\n return result.length || 0\r\n },\r\n\r\n update: async <T>(options: UpdateOptions<T>): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return undefined\r\n\r\n // Get previous data for hooks\r\n const previousResult = await db.select().from(_table).where(whereClause).limit(1)\r\n const previousData = previousResult[0] as Record<string, unknown> | undefined\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where\r\n })\r\n\r\n // Execute before update hooks\r\n await executeBeforeUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData,\r\n db\r\n })\r\n\r\n const result = await db.update(_table)\r\n .set(options.data as any)\r\n .where(whereClause)\r\n .returning()\r\n\r\n const returnValue = options.returning ? result[0] as T : undefined\r\n\r\n // Execute after update hooks\r\n await executeAfterUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData,\r\n result: returnValue,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n updateMany: async <T>(options: UpdateManyOptions<T>): Promise<number> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return 0\r\n\r\n // Get previous data for hooks\r\n const previousResults = await db.select().from(_table).where(whereClause)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where\r\n })\r\n\r\n // Execute before update hooks (for each previous record)\r\n for (const previousData of previousResults) {\r\n await executeBeforeUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n const result = await db.update(_table)\r\n .set(options.data as any)\r\n .where(whereClause)\r\n\r\n // Execute after update hooks\r\n for (const previousData of previousResults) {\r\n await executeAfterUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where\r\n })\r\n\r\n return result.length || 0\r\n },\r\n\r\n delete: async <T>(options: DeleteOptions): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return undefined\r\n\r\n // Get previous data for hooks\r\n const previousResult = await db.select().from(_table).where(whereClause).limit(1)\r\n const previousData = previousResult[0] as Record<string, unknown> | undefined\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where\r\n })\r\n\r\n // Execute before delete hooks\r\n await executeBeforeDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData,\r\n db\r\n })\r\n\r\n const result = await db.delete(_table)\r\n .where(whereClause)\r\n .returning()\r\n\r\n const returnValue = options.returning ? result[0] as T : undefined\r\n\r\n // Execute after delete hooks\r\n await executeAfterDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData,\r\n result: returnValue,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n deleteMany: async (options: DeleteManyOptions): Promise<number> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return 0\r\n\r\n // Get previous data for hooks\r\n const previousResults = await db.select().from(_table).where(whereClause)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where\r\n })\r\n\r\n // Execute before delete hooks\r\n for (const previousData of previousResults) {\r\n await executeBeforeDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n const result = await db.delete(_table).where(whereClause)\r\n\r\n // Execute after delete hooks\r\n for (const previousData of previousResults) {\r\n await executeAfterDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where\r\n })\r\n\r\n return result.length || 0\r\n },\r\n\r\n count: async (options?: CountOptions): Promise<number> => {\r\n const whereClause = buildWhereClause(tableColumns, options?.where)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n const result = whereClause\r\n ? await db.select().from(_table).where(whereClause)\r\n : await db.select().from(_table)\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where,\r\n result\r\n })\r\n\r\n return result.length\r\n },\r\n\r\n exists: async (options: ExistsOptions): Promise<boolean> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return false\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n const result = await db.select().from(_table).where(whereClause).limit(1)\r\n const returnValue = result.length > 0\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: result,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n }\r\n }\r\n}\r\n","/**\r\n * PostgreSQL adapter configuration\r\n */\r\nexport type PgAdapterConfig = {\r\n url: string\r\n migrationsPath?: string\r\n}\r\n\r\n/**\r\n * PostgreSQL adapter\r\n */\r\nexport interface PgAdapter {\r\n type: 'postgres'\r\n config: PgAdapterConfig\r\n}\r\n\r\n/**\r\n * Database adapter type\r\n */\r\nexport type DatabaseAdapter = PgAdapter\r\n\r\n/**\r\n * Creates a PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n */\r\nexport const pgAdapter = (config: PgAdapterConfig): PgAdapter => {\r\n return {\r\n type: 'postgres',\r\n config: {\r\n url: config.url,\r\n migrationsPath: config.migrationsPath ?? './migrations'\r\n }\r\n }\r\n}\r\n","import { pgTable, serial, text, timestamp, uuid, varchar, boolean, integer } from 'drizzle-orm/pg-core'\r\n\r\nimport type { Collection } from './collection'\r\n\r\n/**\r\n * Build Drizzle table from collection definition\r\n */\r\nexport const buildTable = (collection: Collection) => {\r\n // Build columns object\r\n const columns: Record<string, unknown> = {\r\n // Add default id column\r\n id: serial('id').primaryKey()\r\n }\r\n\r\n // Build columns from fields\r\n for (const [fieldName, fieldDef] of Object.entries(collection.fields)) {\r\n // Skip the id field if explicitly defined in fields\r\n if (fieldName === 'id') continue\r\n\r\n const fieldType = fieldDef.fieldType as { name?: string; type?: string }\r\n const fieldTypeName = fieldType.name || fieldType.type || 'text'\r\n\r\n switch (fieldTypeName) {\r\n case 'text':\r\n columns[fieldName] = text(fieldName)\r\n break\r\n case 'varchar':\r\n columns[fieldName] = varchar(fieldName, { length: 255 })\r\n break\r\n case 'number':\r\n case 'integer':\r\n columns[fieldName] = integer(fieldName)\r\n break\r\n case 'boolean':\r\n columns[fieldName] = boolean(fieldName)\r\n break\r\n case 'timestamp':\r\n columns[fieldName] = timestamp(fieldName)\r\n break\r\n case 'uuid':\r\n columns[fieldName] = uuid(fieldName)\r\n break\r\n default:\r\n columns[fieldName] = text(fieldName)\r\n }\r\n }\r\n\r\n return pgTable(collection.slug, columns as Record<string, ReturnType<typeof text>>)\r\n}\r\n\r\n/**\r\n * Build all tables from collections\r\n */\r\nexport const buildSchema = (collections: Collection[]) => {\r\n const tables: Record<string, ReturnType<typeof pgTable>> = {}\r\n\r\n for (const coll of collections) {\r\n tables[coll.slug] = buildTable(coll)\r\n }\r\n\r\n return tables\r\n}\r\n","import { spawn } from 'child_process'\r\nimport { resolve } from 'path'\r\nimport process from 'process'\r\n\r\nimport type { PgAdapter } from './adapter'\r\nimport type { Collection } from './collection'\r\n\r\n/**\r\n * Migration options\r\n */\r\nexport type MigrationOptions = {\r\n /** Path to the config file */\r\n configPath?: string\r\n /** Output directory for generated files */\r\n out?: string\r\n /** Enable verbose output */\r\n verbose?: boolean\r\n /** Dry run mode - don't apply changes */\r\n dryRun?: boolean\r\n /** Custom migrations table name */\r\n migrationsTable?: string\r\n}\r\n\r\n/**\r\n * Run a command and return a promise\r\n */\r\nfunction runCommand(command: string, args: string[], options: { verbose?: boolean } = {}): Promise<number> {\r\n return new Promise((resolve, reject) => {\r\n if (options.verbose) {\r\n console.log(`[collections] Running: ${command} ${args.join(' ')}`)\r\n }\r\n\r\n const child = spawn(command, args, {\r\n stdio: options.verbose ? 'inherit' : 'pipe',\r\n shell: true,\r\n cwd: process.cwd()\r\n })\r\n\r\n let output = ''\r\n if (!options.verbose) {\r\n child.stdout?.on('data', (data) => {\r\n output += data.toString()\r\n })\r\n child.stderr?.on('data', (data) => {\r\n output += data.toString()\r\n })\r\n }\r\n\r\n child.on('close', (code) => {\r\n if (code === 0) {\r\n resolve(code ?? 0)\r\n } else {\r\n reject(new Error(`Command failed with code ${code}: ${output}`))\r\n }\r\n })\r\n\r\n child.on('error', (error) => {\r\n reject(error)\r\n })\r\n })\r\n}\r\n\r\n/**\r\n * Build drizzle-kit config file content\r\n */\r\nfunction buildDrizzleConfig(options: {\r\n out: string\r\n schemaPath: string\r\n dbUrl: string\r\n migrationsTable?: string\r\n}): string {\r\n const config: Record<string, unknown> = {\r\n dialect: 'postgresql',\r\n schema: options.schemaPath,\r\n out: options.out,\r\n dbCredentials: {\r\n url: options.dbUrl\r\n }\r\n }\r\n\r\n if (options.migrationsTable) {\r\n config.migrations = {\r\n table: options.migrationsTable\r\n }\r\n }\r\n\r\n return JSON.stringify(config, null, 2)\r\n}\r\n\r\n/**\r\n * Push schema to database (development mode)\r\n *\r\n * Uses drizzle-kit CLI to push schema changes to the database\r\n */\r\nexport const push = async (\r\n adapter: PgAdapter,\r\n _collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const {\r\n verbose = false,\r\n dryRun = false,\r\n out = './drizzle',\r\n configPath = './collections/config.ts',\r\n migrationsTable = '__drizzle_collections'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: configPath,\r\n dbUrl: adapter.config.url,\r\n migrationsTable\r\n })\r\n\r\n const drizzleConfigPath = resolve(process.cwd(), './drizzle.config.json')\r\n const { writeFileSync, unlinkSync } = await import('fs')\r\n\r\n try {\r\n // Write config file\r\n writeFileSync(drizzleConfigPath, configContent)\r\n\r\n const args = ['drizzle-kit', 'push']\r\n\r\n if (dryRun) {\r\n args.push('--dry-run')\r\n }\r\n\r\n if (verbose) {\r\n args.push('--verbose')\r\n }\r\n\r\n await runCommand('npx', args, { verbose })\r\n\r\n if (verbose) {\r\n console.log('[collections] Schema pushed successfully')\r\n }\r\n } finally {\r\n // Cleanup config file\r\n try {\r\n unlinkSync(drizzleConfigPath)\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Generate migration files\r\n *\r\n * Uses drizzle-kit CLI to create migration files\r\n */\r\nexport const generate = async (\r\n adapter: PgAdapter,\r\n _collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const {\r\n verbose = false,\r\n out = './drizzle',\r\n configPath = './collections/config.ts',\r\n migrationsTable = '__drizzle_collections'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: configPath,\r\n dbUrl: adapter.config.url,\r\n migrationsTable\r\n })\r\n\r\n const drizzleConfigPath = resolve(process.cwd(), './drizzle.config.json')\r\n const { writeFileSync, unlinkSync } = await import('fs')\r\n\r\n try {\r\n // Write config file\r\n writeFileSync(drizzleConfigPath, configContent)\r\n\r\n const args = ['drizzle-kit', 'generate']\r\n\r\n if (verbose) {\r\n args.push('--verbose')\r\n }\r\n\r\n await runCommand('npx', args, { verbose })\r\n\r\n if (verbose) {\r\n console.log('[collections] Migrations generated successfully')\r\n }\r\n } finally {\r\n // Cleanup config file\r\n try {\r\n unlinkSync(drizzleConfigPath)\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Apply migrations\r\n *\r\n * Uses drizzle-kit CLI to apply pending migrations\r\n */\r\nexport const migrate = async (\r\n adapter: PgAdapter,\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const {\r\n verbose = false,\r\n out = './drizzle',\r\n configPath = './collections/config.ts',\r\n migrationsTable = '__drizzle_collections'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: configPath,\r\n dbUrl: adapter.config.url,\r\n migrationsTable\r\n })\r\n\r\n const drizzleConfigPath = resolve(process.cwd(), './drizzle.config.json')\r\n const { writeFileSync, unlinkSync } = await import('fs')\r\n\r\n try {\r\n // Write config file\r\n writeFileSync(drizzleConfigPath, configContent)\r\n\r\n const args = ['drizzle-kit', 'migrate']\r\n\r\n if (verbose) {\r\n args.push('--verbose')\r\n }\r\n\r\n await runCommand('npx', args, { verbose })\r\n\r\n if (verbose) {\r\n console.log('[collections] Migrations applied successfully')\r\n }\r\n } finally {\r\n // Cleanup config file\r\n try {\r\n unlinkSync(drizzleConfigPath)\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n","import { Pool, type Pool as PoolType } from 'pg'\r\nimport { drizzle } from 'drizzle-orm/node-postgres'\r\n\r\nimport type { Collection } from './collection'\r\nimport type { DatabaseAdapter } from './adapter'\r\nimport { buildSchema } from './schema'\r\n\r\n/**\r\n * Plugin interface\r\n */\r\nexport type Plugin = {\r\n name: string\r\n collections?: Record<string, Collection>\r\n hooks?: Record<string, unknown[]>\r\n}\r\n\r\n/**\r\n * Configuration options\r\n */\r\nexport type ConfigOptions<T extends Collection[] = []> = {\r\n database: DatabaseAdapter\r\n collections: T\r\n plugins?: Plugin[]\r\n}\r\n\r\n/**\r\n * Define config return type with inferred collection keys\r\n *\r\n * - collections: metadata only (slug, name, fields, hooks, dataType)\r\n * - db: Drizzle instance with operations (via schema tables)\r\n * - $meta: array of collection slugs and plugin names\r\n */\r\nexport type DefineConfigReturn<T extends Collection[] = []> = {\r\n collections: {\r\n [K in T[number] as K['slug']]: Collection\r\n }\r\n db: ReturnType<typeof drizzle<Record<string, unknown>>>\r\n $meta: {\r\n collections: T[number]['slug'][]\r\n plugins: string[]\r\n }\r\n}\r\n\r\n/**\r\n * Creates the configuration for the data layer\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: process.env.DATABASE_URL!\r\n * })\r\n *\r\n * export const { collections, db } = defineConfig({\r\n * database: adapter,\r\n * collections: [users, posts],\r\n * plugins: [timestampsPlugin()]\r\n * })\r\n *\r\n * // collections: metadata only\r\n * collections.users.slug // 'users'\r\n * collections.users.fields // { name, email, ... }\r\n *\r\n * // db: Drizzle instance with operations\r\n * await db.users.findMany()\r\n * await db.users.insert(values)\r\n */\r\nexport const defineConfig = <T extends Collection[]>(\r\n options: ConfigOptions<T>\r\n): DefineConfigReturn<T> => {\r\n // Initialize the database connection based on adapter type\r\n let pool: PoolType | null = null\r\n let dbInstance: ReturnType<typeof drizzle<Record<string, unknown>>> | null = null\r\n\r\n let schema: Record<string, unknown> = {}\r\n\r\n if (options.database.type === 'postgres') {\r\n // Create pool from adapter config\r\n pool = new Pool({\r\n connectionString: options.database.config.url\r\n })\r\n\r\n // Build schema from collections\r\n schema = buildSchema(options.collections as Collection[])\r\n\r\n // Create Drizzle instance with schema\r\n dbInstance = drizzle(pool, { schema })\r\n }\r\n\r\n // Build collections map (metadata only)\r\n const collectionsMap: Record<string, Collection> = {}\r\n const collectionNames: string[] = []\r\n\r\n for (const coll of options.collections) {\r\n // Store only metadata (not operations)\r\n collectionsMap[coll.slug] = {\r\n slug: coll.slug,\r\n name: coll.name,\r\n fields: coll.fields,\r\n hooks: coll.hooks,\r\n dataType: coll.dataType\r\n }\r\n collectionNames.push(coll.slug)\r\n }\r\n\r\n // Build plugins map\r\n const pluginNames: string[] = []\r\n if (options.plugins) {\r\n for (const plugin of options.plugins) {\r\n pluginNames.push(plugin.name)\r\n\r\n // Register plugin collections (metadata only)\r\n if (plugin.collections) {\r\n for (const [name, coll] of Object.entries(plugin.collections)) {\r\n collectionsMap[name] = {\r\n slug: coll.slug,\r\n name: coll.name,\r\n fields: coll.fields,\r\n hooks: coll.hooks,\r\n dataType: coll.dataType\r\n }\r\n collectionNames.push(name)\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n collections: collectionsMap as DefineConfigReturn<T>['collections'],\r\n db: dbInstance as DefineConfigReturn<T>['db'],\r\n $meta: {\r\n collections: collectionNames as DefineConfigReturn<T>['$meta']['collections'],\r\n plugins: pluginNames\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["text","timestamp","boolean","collection","fieldType","resolve"]}
1
+ {"version":3,"sources":["../src/field-type.ts","../src/field.ts","../src/fields/f.ts","../src/collection.ts","../src/operations/collection-operations.ts","../src/adapter.ts","../src/schema.ts","../src/migrations.ts","../src/config.ts"],"sourcesContent":["import { z } from 'zod'\r\n\r\n/**\r\n * A field type instance (already configured)\r\n */\r\nexport type FieldTypeInstance = {\r\n schema: z.ZodType\r\n database: unknown\r\n}\r\n\r\n/**\r\n * A field type creator (needs to be called to get instance)\r\n */\r\nexport type FieldTypeCreator = () => FieldTypeInstance\r\n\r\n/**\r\n * Field type configuration\r\n */\r\nexport type FieldTypeConfig = {\r\n schema: z.ZodType\r\n database?: unknown\r\n}\r\n\r\n/**\r\n * Creates a new field type\r\n *\r\n * @example\r\n * const text = fieldType({\r\n * schema: z.string(),\r\n * database: { type: 'text' }\r\n * })\r\n *\r\n * const textField = text() // Get instance\r\n */\r\nexport const fieldType = (config: FieldTypeConfig): (() => FieldTypeInstance) => {\r\n return () => ({\r\n schema: config.schema,\r\n database: config.database ?? {}\r\n })\r\n}\r\n","import type { FieldTypeInstance } from './field-type'\r\n\r\n/**\r\n * Field configuration options\r\n */\r\nexport type FieldOptions = {\r\n fieldType: FieldTypeInstance\r\n required?: boolean\r\n unique?: boolean\r\n indexed?: boolean\r\n default?: unknown\r\n label?: string\r\n description?: string\r\n}\r\n\r\n/**\r\n * Creates a field definition\r\n *\r\n * @example\r\n * name: field({ fieldType: text() })\r\n * email: field({ fieldType: email(), unique: true })\r\n */\r\nexport const field = (config: FieldOptions): FieldDefinition => {\r\n return {\r\n fieldType: config.fieldType,\r\n required: config.required ?? false,\r\n unique: config.unique ?? false,\r\n indexed: config.indexed ?? false,\r\n default: config.default,\r\n label: config.label,\r\n description: config.description\r\n }\r\n}\r\n\r\n/**\r\n * A field definition\r\n */\r\nexport type FieldDefinition = {\r\n fieldType: FieldTypeInstance\r\n required: boolean\r\n unique: boolean\r\n indexed: boolean\r\n default?: unknown\r\n label?: string\r\n description?: string\r\n}\r\n","import { fieldType, type FieldTypeInstance } from '../field-type'\r\nimport { z } from 'zod'\r\n\r\n/**\r\n * Derive the database type string from a Zod schema\r\n */\r\nconst getItemType = (itemSchema: z.ZodType): string => {\r\n if (itemSchema instanceof z.ZodString) return 'text'\r\n if (itemSchema instanceof z.ZodNumber) return 'integer'\r\n if (itemSchema instanceof z.ZodBoolean) return 'boolean'\r\n if (itemSchema instanceof z.ZodDate) return 'timestamp'\r\n if (itemSchema instanceof z.ZodEnum) return 'text'\r\n if (itemSchema instanceof z.ZodArray) return 'array'\r\n if (itemSchema instanceof z.ZodObject) return 'jsonb'\r\n return 'text'\r\n}\r\n\r\n/**\r\n * Field types namespace (like zod's z)\r\n */\r\nexport const f = {\r\n /**\r\n * Text field type\r\n */\r\n text: (): FieldTypeInstance => fieldType({\r\n schema: z.string(),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * Email field type with built-in validation\r\n */\r\n email: (): FieldTypeInstance => fieldType({\r\n schema: z.string().email(),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * URL field type with built-in validation\r\n */\r\n url: (): FieldTypeInstance => fieldType({\r\n schema: z.string().url(),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * Number field type\r\n */\r\n number: (): FieldTypeInstance => fieldType({\r\n schema: z.number(),\r\n database: { type: 'integer' }\r\n })(),\r\n\r\n /**\r\n * Boolean field type\r\n */\r\n boolean: (): FieldTypeInstance => fieldType({\r\n schema: z.boolean(),\r\n database: { type: 'boolean' }\r\n })(),\r\n\r\n /**\r\n * Date field type (date only, no time)\r\n */\r\n date: (): FieldTypeInstance => fieldType({\r\n schema: z.date(),\r\n database: { type: 'date' }\r\n })(),\r\n\r\n /**\r\n * Timestamp field type (date with time)\r\n */\r\n timestamp: (): FieldTypeInstance => fieldType({\r\n schema: z.date(),\r\n database: { type: 'timestamp' }\r\n })(),\r\n\r\n /**\r\n * Creates a select field type\r\n */\r\n select: <T extends readonly [string, ...string[]]>(\r\n options: T\r\n ): FieldTypeInstance => fieldType({\r\n schema: z.enum(options),\r\n database: { type: 'text' }\r\n })(),\r\n\r\n /**\r\n * JSON field type for storing JSON data\r\n */\r\n json: (schema?: z.ZodType): FieldTypeInstance => fieldType({\r\n schema: schema ?? z.any(),\r\n database: { type: 'jsonb' }\r\n })(),\r\n\r\n /**\r\n * Array field type for storing lists\r\n */\r\n array: (itemSchema: z.ZodType): FieldTypeInstance => fieldType({\r\n schema: z.array(itemSchema),\r\n database: { type: 'array', itemType: getItemType(itemSchema) }\r\n })(),\r\n\r\n /**\r\n * Creates a relation field type for foreign key relationships\r\n */\r\n relation: (options: {\r\n collection: string\r\n singular?: boolean\r\n many?: boolean\r\n through?: string\r\n }): FieldTypeInstance => {\r\n const isMany = options.many ?? false\r\n const isSingular = options.singular ?? false\r\n\r\n return fieldType({\r\n schema: isMany ? z.array(z.string()) : z.string(),\r\n database: {\r\n type: 'integer',\r\n references: options.collection,\r\n through: options.through,\r\n many: isMany,\r\n singular: isSingular\r\n }\r\n })()\r\n }\r\n}\r\n\r\n/**\r\n * @deprecated Use f.text() instead\r\n */\r\nexport const text = f.text\r\n\r\n/**\r\n * @deprecated Use f.email() instead\r\n */\r\nexport const email = f.email\r\n\r\n/**\r\n * @deprecated Use f.url() instead\r\n */\r\nexport const url = f.url\r\n\r\n/**\r\n * @deprecated Use f.number() instead\r\n */\r\nexport const number = f.number\r\n\r\n/**\r\n * @deprecated Use f.boolean() instead\r\n */\r\nexport const boolean = f.boolean\r\n\r\n/**\r\n * @deprecated Use f.date() instead\r\n */\r\nexport const date = f.date\r\n\r\n/**\r\n * @deprecated Use f.timestamp() instead\r\n */\r\nexport const timestamp = f.timestamp\r\n\r\n/**\r\n * @deprecated Use f.select() instead\r\n */\r\nexport const select = f.select\r\n\r\n/**\r\n * @deprecated Use f.json() instead\r\n */\r\nexport const json = f.json\r\n\r\n/**\r\n * @deprecated Use f.array() instead\r\n */\r\nexport const array = f.array\r\n\r\n/**\r\n * @deprecated Use f.relation() instead\r\n */\r\nexport const relation = f.relation\r\n\r\n/**\r\n * @deprecated Use f.relation instead\r\n */\r\nexport type RelationOptions = {\r\n collection: string\r\n singular?: boolean\r\n many?: boolean\r\n through?: string\r\n}\r\n","import type { FieldDefinition } from './field'\r\n\r\n/**\r\n * Collection configuration\r\n */\r\nexport type CollectionConfig<T extends Record<string, unknown> = Record<string, unknown>> = {\r\n slug: string\r\n name?: string\r\n fields: Record<string, FieldDefinition>\r\n hooks?: CollectionHooks\r\n dataType?: T\r\n}\r\n\r\n/**\r\n * Operation types\r\n */\r\nexport type OperationType = 'create' | 'update' | 'delete' | 'read'\r\n\r\n/**\r\n * Hook context base\r\n */\r\nexport type HookContextBase = {\r\n collection: string\r\n operation: OperationType\r\n}\r\n\r\n/**\r\n * Before/After Operation context\r\n */\r\nexport type OperationHookContext = HookContextBase & {\r\n data?: Record<string, unknown>\r\n where?: Record<string, unknown>\r\n result?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Create context\r\n */\r\nexport type CreateHookContext = HookContextBase & {\r\n operation: 'create'\r\n data: Record<string, unknown>\r\n result?: unknown\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Update context\r\n */\r\nexport type UpdateHookContext = HookContextBase & {\r\n operation: 'update'\r\n data: Record<string, unknown>\r\n where: Record<string, unknown>\r\n previousData?: Record<string, unknown>\r\n result?: unknown\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Delete context\r\n */\r\nexport type DeleteHookContext = HookContextBase & {\r\n operation: 'delete'\r\n where: Record<string, unknown>\r\n previousData?: Record<string, unknown>\r\n result?: unknown\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Before/After Read context\r\n */\r\nexport type ReadHookContext = HookContextBase & {\r\n operation: 'read'\r\n query?: Record<string, unknown>\r\n result?: unknown[]\r\n db?: unknown\r\n}\r\n\r\n/**\r\n * Generic hook function type\r\n */\r\nexport type GenericHookFunction = (context: OperationHookContext) => Promise<void> | void\r\nexport type CreateHookFunction = (context: CreateHookContext) => Promise<void> | void\r\nexport type UpdateHookFunction = (context: UpdateHookContext) => Promise<void> | void\r\nexport type DeleteHookFunction = (context: DeleteHookContext) => Promise<void> | void\r\nexport type ReadHookFunction = (context: ReadHookContext) => Promise<void> | void\r\n\r\n/**\r\n * Collection hooks\r\n */\r\nexport type CollectionHooks = {\r\n beforeOperation?: GenericHookFunction[]\r\n afterOperation?: GenericHookFunction[]\r\n beforeCreate?: CreateHookFunction[]\r\n afterCreate?: CreateHookFunction[]\r\n beforeUpdate?: UpdateHookFunction[]\r\n afterUpdate?: UpdateHookFunction[]\r\n beforeDelete?: DeleteHookFunction[]\r\n afterDelete?: DeleteHookFunction[]\r\n beforeRead?: ReadHookFunction[]\r\n afterRead?: ReadHookFunction[]\r\n}\r\n\r\n/**\r\n * A collection definition\r\n */\r\nexport type Collection<T extends Record<string, unknown> = Record<string, unknown>> = {\r\n slug: string\r\n name?: string\r\n fields: Record<string, FieldDefinition>\r\n hooks?: CollectionHooks\r\n dataType?: T\r\n}\r\n\r\n/**\r\n * Creates a new collection\r\n *\r\n * @example\r\n * export const users = collection({\r\n * slug: 'users',\r\n * name: 'Users',\r\n * fields: {\r\n * name: field({ fieldType: text }),\r\n * email: field({ fieldType: email, unique: true })\r\n * }\r\n * })\r\n */\r\nexport const collection = <T extends Record<string, unknown> = Record<string, unknown>>(\r\n config: CollectionConfig<T>\r\n): Collection<T> => {\r\n return {\r\n slug: config.slug,\r\n name: config.name,\r\n fields: config.fields,\r\n hooks: config.hooks,\r\n dataType: config.dataType\r\n }\r\n}\r\n","/* eslint-disable @typescript-eslint/no-explicit-any */\r\nimport { eq, and, like, gt, gte, lt, lte, isNull, inArray, not, desc, asc } from 'drizzle-orm'\r\n\r\nimport type { Collection, CollectionHooks, CreateHookContext, UpdateHookContext, DeleteHookContext, ReadHookContext, OperationHookContext } from '../collection'\r\nimport type {\r\n FindManyOptions,\r\n FindUniqueOptions,\r\n FindFirstOptions,\r\n CreateOptions,\r\n CreateManyOptions,\r\n UpdateOptions,\r\n UpdateManyOptions,\r\n DeleteOptions,\r\n DeleteManyOptions,\r\n CountOptions,\r\n ExistsOptions,\r\n WhereOperator\r\n} from './types'\r\n\r\n/**\r\n * Collection operations interface\r\n */\r\nexport interface CollectionOperations {\r\n findMany<T>(options?: FindManyOptions): Promise<T[]>\r\n findUnique<T>(options: FindUniqueOptions): Promise<T | undefined>\r\n findFirst<T>(options: FindFirstOptions): Promise<T | undefined>\r\n create<T>(options: CreateOptions<T>): Promise<T | undefined>\r\n createMany<T>(options: CreateManyOptions<T>): Promise<number>\r\n update<T>(options: UpdateOptions<T>): Promise<T | undefined>\r\n updateMany<T>(options: UpdateManyOptions<T>): Promise<number>\r\n delete<T>(options: DeleteOptions): Promise<T | undefined>\r\n deleteMany(options: DeleteManyOptions): Promise<number>\r\n count(options?: CountOptions): Promise<number>\r\n exists(options: ExistsOptions): Promise<boolean>\r\n}\r\n\r\n/**\r\n * Build where conditions from options\r\n */\r\nconst buildWhereClause = (\r\n tableColumns: Record<string, any>,\r\n where?: Record<string, unknown>\r\n): any => {\r\n if (!where) return undefined\r\n\r\n const conditions: any[] = []\r\n\r\n for (const [key, value] of Object.entries(where)) {\r\n const column = tableColumns[key]\r\n if (!column) continue\r\n\r\n if (value === null || typeof value !== 'object') {\r\n conditions.push(eq(column, value))\r\n } else {\r\n const operator = value as WhereOperator<unknown>\r\n if ('eq' in operator) {\r\n conditions.push(eq(column, operator.eq))\r\n } else if ('neq' in operator) {\r\n conditions.push(not(eq(column, operator.neq)))\r\n } else if ('gt' in operator) {\r\n conditions.push(gt(column, operator.gt as number))\r\n } else if ('gte' in operator) {\r\n conditions.push(gte(column, operator.gte as number))\r\n } else if ('lt' in operator) {\r\n conditions.push(lt(column, operator.lt as number))\r\n } else if ('lte' in operator) {\r\n conditions.push(lte(column, operator.lte as number))\r\n } else if ('in' in operator) {\r\n conditions.push(inArray(column, operator.in))\r\n } else if ('notIn' in operator) {\r\n conditions.push(not(inArray(column, operator.notIn)))\r\n } else if ('contains' in operator) {\r\n conditions.push(like(column, `%${operator.contains}%`))\r\n } else if ('startsWith' in operator) {\r\n conditions.push(like(column, `${operator.startsWith}%`))\r\n } else if ('endsWith' in operator) {\r\n conditions.push(like(column, `%${operator.endsWith}`))\r\n } else if ('isNull' in operator) {\r\n if (operator.isNull) {\r\n conditions.push(isNull(column))\r\n }\r\n } else if ('not' in operator) {\r\n conditions.push(not(eq(column, operator.not)))\r\n }\r\n }\r\n }\r\n\r\n if (conditions.length === 0) return undefined\r\n if (conditions.length === 1) return conditions[0]\r\n return and(...conditions)\r\n}\r\n\r\n/**\r\n * Build orderBy from options\r\n */\r\nconst buildOrderBy = (\r\n tableColumns: Record<string, any>,\r\n orderBy?: Record<string, unknown> | Record<string, unknown>[]\r\n): any[] => {\r\n if (!orderBy) return []\r\n\r\n const orders = Array.isArray(orderBy) ? orderBy : [orderBy]\r\n return orders.map((order) => {\r\n for (const [key, direction] of Object.entries(order)) {\r\n const column = tableColumns[key]\r\n if (!column) continue\r\n return direction === 'desc' ? desc(column) : asc(column)\r\n }\r\n return undefined\r\n }).filter(Boolean)\r\n}\r\n\r\n/**\r\n * Execute before operation hooks\r\n */\r\nconst executeBeforeOperationHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: OperationHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeOperation) return\r\n for (const hook of hooks.beforeOperation) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after operation hooks\r\n */\r\nconst executeAfterOperationHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: OperationHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterOperation) return\r\n for (const hook of hooks.afterOperation) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before create hooks\r\n */\r\nconst executeBeforeCreateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: CreateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeCreate) return\r\n for (const hook of hooks.beforeCreate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after create hooks\r\n */\r\nconst executeAfterCreateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: CreateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterCreate) return\r\n for (const hook of hooks.afterCreate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before update hooks\r\n */\r\nconst executeBeforeUpdateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: UpdateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeUpdate) return\r\n for (const hook of hooks.beforeUpdate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after update hooks\r\n */\r\nconst executeAfterUpdateHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: UpdateHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterUpdate) return\r\n for (const hook of hooks.afterUpdate) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before delete hooks\r\n */\r\nconst executeBeforeDeleteHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: DeleteHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeDelete) return\r\n for (const hook of hooks.beforeDelete) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after delete hooks\r\n */\r\nconst executeAfterDeleteHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: DeleteHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterDelete) return\r\n for (const hook of hooks.afterDelete) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute before read hooks\r\n */\r\nconst executeBeforeReadHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: ReadHookContext\r\n): Promise<void> => {\r\n if (!hooks?.beforeRead) return\r\n for (const hook of hooks.beforeRead) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Execute after read hooks\r\n */\r\nconst executeAfterReadHooks = async (\r\n hooks: CollectionHooks | undefined,\r\n context: ReadHookContext\r\n): Promise<void> => {\r\n if (!hooks?.afterRead) return\r\n for (const hook of hooks.afterRead) {\r\n await hook(context)\r\n }\r\n}\r\n\r\n/**\r\n * Creates collection operations with Drizzle\r\n */\r\nexport const createCollectionOperations = (\r\n _collection: Collection,\r\n _slug: string,\r\n _db: any,\r\n _table: any,\r\n _hooks?: CollectionHooks\r\n): CollectionOperations => {\r\n const tableColumns = _table as Record<string, any>\r\n const db = _db as any\r\n const hooks = _hooks as CollectionHooks | undefined\r\n\r\n // If no db instance, return placeholder operations\r\n if (!db) {\r\n return {\r\n findMany: async <T>(): Promise<T[]> => [],\r\n findUnique: async <T>(): Promise<T | undefined> => undefined,\r\n findFirst: async <T>(): Promise<T | undefined> => undefined,\r\n create: async <T>(): Promise<T | undefined> => undefined,\r\n createMany: async (): Promise<number> => 0,\r\n update: async <T>(): Promise<T | undefined> => undefined,\r\n updateMany: async (): Promise<number> => 0,\r\n delete: async <T>(): Promise<T | undefined> => undefined,\r\n deleteMany: async (): Promise<number> => 0,\r\n count: async (): Promise<number> => 0,\r\n exists: async (): Promise<boolean> => false\r\n }\r\n }\r\n\r\n return {\r\n findMany: async <T>(options?: FindManyOptions): Promise<T[]> => {\r\n const whereClause = buildWhereClause(tableColumns, options?.where)\r\n const orderByClause = buildOrderBy(tableColumns, options?.orderBy)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n let query = db.select().from(_table)\r\n\r\n if (whereClause) {\r\n query = query.where(whereClause)\r\n }\r\n\r\n if (orderByClause.length > 0) {\r\n query = query.orderBy(...orderByClause)\r\n }\r\n\r\n if (options?.offset) {\r\n query = query.offset(options.offset)\r\n }\r\n\r\n if (options?.limit) {\r\n query = query.limit(options.limit)\r\n }\r\n\r\n const result = await query\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: result as unknown[],\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where,\r\n result\r\n })\r\n\r\n return result as T[]\r\n },\r\n\r\n findUnique: async <T>(options: FindUniqueOptions): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return undefined\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n const result = await db.select().from(_table).where(whereClause).limit(1)\r\n const returnValue = result[0] as T | undefined\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: returnValue ? [returnValue] : [],\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n findFirst: async <T>(options: FindFirstOptions): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n const orderByClause = buildOrderBy(tableColumns, options.orderBy)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n let query = db.select().from(_table)\r\n\r\n if (whereClause) {\r\n query = query.where(whereClause)\r\n }\r\n\r\n if (orderByClause.length > 0) {\r\n query = query.orderBy(...orderByClause)\r\n }\r\n\r\n const result = await query.limit(1)\r\n const returnValue = result[0] as T | undefined\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: returnValue ? [returnValue] : [],\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n create: async <T>(options: CreateOptions<T>): Promise<T | undefined> => {\r\n const data = Array.isArray(options.data) ? options.data : [options.data]\r\n const firstData = data[0] as Record<string, unknown>\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n where: undefined\r\n })\r\n\r\n // Execute before create hooks\r\n await executeBeforeCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n db\r\n })\r\n\r\n const result = await db.insert(_table).values(data).returning()\r\n\r\n const returnValue = options.returning ? result[0] as T : undefined\r\n\r\n // Execute after create hooks\r\n await executeAfterCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n result: returnValue,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: firstData,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n createMany: async <T>(options: CreateManyOptions<T>): Promise<number> => {\r\n const dataArray = Array.isArray(options.data) ? options.data : [options.data]\r\n\r\n // Execute before operation hooks for each item\r\n for (const data of dataArray) {\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: data as Record<string, unknown>,\r\n where: undefined\r\n })\r\n\r\n await executeBeforeCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: data as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n const result = await db.insert(_table).values(options.data as any)\r\n\r\n // Execute after operation hooks for each item\r\n for (let i = 0; i < dataArray.length; i++) {\r\n await executeAfterCreateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: dataArray[i] as Record<string, unknown>,\r\n result: result[i],\r\n db\r\n })\r\n\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'create',\r\n data: dataArray[i] as Record<string, unknown>,\r\n result: result[i]\r\n })\r\n }\r\n\r\n return result.length || 0\r\n },\r\n\r\n update: async <T>(options: UpdateOptions<T>): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return undefined\r\n\r\n // Get previous data for hooks\r\n const previousResult = await db.select().from(_table).where(whereClause).limit(1)\r\n const previousData = previousResult[0] as Record<string, unknown> | undefined\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where\r\n })\r\n\r\n // Execute before update hooks\r\n await executeBeforeUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData,\r\n db\r\n })\r\n\r\n const result = await db.update(_table)\r\n .set(options.data as any)\r\n .where(whereClause)\r\n .returning()\r\n\r\n const returnValue = options.returning ? result[0] as T : undefined\r\n\r\n // Execute after update hooks\r\n await executeAfterUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData,\r\n result: returnValue,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n updateMany: async <T>(options: UpdateManyOptions<T>): Promise<number> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return 0\r\n\r\n // Get previous data for hooks\r\n const previousResults = await db.select().from(_table).where(whereClause)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where\r\n })\r\n\r\n // Execute before update hooks (for each previous record)\r\n for (const previousData of previousResults) {\r\n await executeBeforeUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n const result = await db.update(_table)\r\n .set(options.data as any)\r\n .where(whereClause)\r\n\r\n // Execute after update hooks\r\n for (const previousData of previousResults) {\r\n await executeAfterUpdateHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'update',\r\n data: options.data as Record<string, unknown>,\r\n where: options.where\r\n })\r\n\r\n return result.length || 0\r\n },\r\n\r\n delete: async <T>(options: DeleteOptions): Promise<T | undefined> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return undefined\r\n\r\n // Get previous data for hooks\r\n const previousResult = await db.select().from(_table).where(whereClause).limit(1)\r\n const previousData = previousResult[0] as Record<string, unknown> | undefined\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where\r\n })\r\n\r\n // Execute before delete hooks\r\n await executeBeforeDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData,\r\n db\r\n })\r\n\r\n const result = await db.delete(_table)\r\n .where(whereClause)\r\n .returning()\r\n\r\n const returnValue = options.returning ? result[0] as T : undefined\r\n\r\n // Execute after delete hooks\r\n await executeAfterDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData,\r\n result: returnValue,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n },\r\n\r\n deleteMany: async (options: DeleteManyOptions): Promise<number> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return 0\r\n\r\n // Get previous data for hooks\r\n const previousResults = await db.select().from(_table).where(whereClause)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where\r\n })\r\n\r\n // Execute before delete hooks\r\n for (const previousData of previousResults) {\r\n await executeBeforeDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n const result = await db.delete(_table).where(whereClause)\r\n\r\n // Execute after delete hooks\r\n for (const previousData of previousResults) {\r\n await executeAfterDeleteHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where,\r\n previousData: previousData as Record<string, unknown>,\r\n db\r\n })\r\n }\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'delete',\r\n where: options.where\r\n })\r\n\r\n return result.length || 0\r\n },\r\n\r\n count: async (options?: CountOptions): Promise<number> => {\r\n const whereClause = buildWhereClause(tableColumns, options?.where)\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n const result = whereClause\r\n ? await db.select().from(_table).where(whereClause)\r\n : await db.select().from(_table)\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options?.where,\r\n result\r\n })\r\n\r\n return result.length\r\n },\r\n\r\n exists: async (options: ExistsOptions): Promise<boolean> => {\r\n const whereClause = buildWhereClause(tableColumns, options.where)\r\n if (!whereClause) return false\r\n\r\n // Execute before operation hooks\r\n await executeBeforeOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where\r\n })\r\n\r\n // Execute before read hooks\r\n await executeBeforeReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n db\r\n })\r\n\r\n const result = await db.select().from(_table).where(whereClause).limit(1)\r\n const returnValue = result.length > 0\r\n\r\n // Execute after read hooks\r\n await executeAfterReadHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n query: options as unknown as Record<string, unknown>,\r\n result: result,\r\n db\r\n })\r\n\r\n // Execute after operation hooks\r\n await executeAfterOperationHooks(hooks, {\r\n collection: _slug,\r\n operation: 'read',\r\n where: options.where,\r\n result: returnValue\r\n })\r\n\r\n return returnValue\r\n }\r\n }\r\n}\r\n","/**\r\n * PostgreSQL adapter configuration\r\n */\r\nexport type PgAdapterConfig = {\r\n url: string\r\n migrationsPath?: string\r\n}\r\n\r\n/**\r\n * PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n *\r\n * // Get pool for drizzle\r\n * const pool = adapter.getPool()\r\n */\r\nexport interface PgAdapter {\r\n type: 'postgres'\r\n config: PgAdapterConfig\r\n /** Get the underlying connection pool */\r\n getPool: () => Promise<import('pg').Pool>\r\n}\r\n\r\n/**\r\n * Database adapter type\r\n */\r\nexport type DatabaseAdapter = PgAdapter\r\n\r\n/**\r\n * Creates a PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n *\r\n * // Get pool for drizzle\r\n * const pool = await adapter.getPool()\r\n */\r\nexport const pgAdapter = (config: PgAdapterConfig): PgAdapter => {\r\n let pool: import('pg').Pool | null = null\r\n\r\n return {\r\n type: 'postgres',\r\n config: {\r\n url: config.url,\r\n migrationsPath: config.migrationsPath ?? './migrations'\r\n },\r\n getPool: async () => {\r\n if (!pool) {\r\n const { Pool } = await import('pg')\r\n pool = new Pool({\r\n connectionString: config.url\r\n })\r\n }\r\n return pool\r\n }\r\n }\r\n}\r\n","import { pgTable, serial, text, timestamp, uuid, varchar, boolean, integer } from 'drizzle-orm/pg-core'\r\n\r\nimport type { Collection } from './collection'\r\n\r\n/**\r\n * Build Drizzle table from collection definition\r\n */\r\nexport const buildTable = (collection: Collection) => {\r\n // Build columns object\r\n const columns: Record<string, unknown> = {\r\n // Add default id column\r\n id: serial('id').primaryKey()\r\n }\r\n\r\n // Build columns from fields\r\n for (const [fieldName, fieldDef] of Object.entries(collection.fields)) {\r\n // Skip the id field if explicitly defined in fields\r\n if (fieldName === 'id') continue\r\n\r\n const fieldType = fieldDef.fieldType as { name?: string; type?: string }\r\n const fieldTypeName = fieldType.name || fieldType.type || 'text'\r\n\r\n switch (fieldTypeName) {\r\n case 'text':\r\n columns[fieldName] = text(fieldName)\r\n break\r\n case 'varchar':\r\n columns[fieldName] = varchar(fieldName, { length: 255 })\r\n break\r\n case 'number':\r\n case 'integer':\r\n columns[fieldName] = integer(fieldName)\r\n break\r\n case 'boolean':\r\n columns[fieldName] = boolean(fieldName)\r\n break\r\n case 'timestamp':\r\n columns[fieldName] = timestamp(fieldName)\r\n break\r\n case 'uuid':\r\n columns[fieldName] = uuid(fieldName)\r\n break\r\n default:\r\n columns[fieldName] = text(fieldName)\r\n }\r\n }\r\n\r\n return pgTable(collection.slug, columns as Record<string, ReturnType<typeof text>>)\r\n}\r\n\r\n/**\r\n * Build all tables from collections\r\n */\r\nexport const buildSchema = (collections: Collection[]) => {\r\n const tables: Record<string, ReturnType<typeof pgTable>> = {}\r\n\r\n for (const coll of collections) {\r\n tables[coll.slug] = buildTable(coll)\r\n }\r\n\r\n return tables\r\n}\r\n","import { drizzle } from 'drizzle-orm/node-postgres'\r\n\r\nimport type { PgAdapter } from './adapter'\r\nimport type { Collection } from './collection'\r\nimport { buildSchema } from './schema'\r\n\r\n/**\r\n * Get drizzle-kit API lazily to avoid import errors during module load\r\n */\r\nasync function getDrizzleKitApi() {\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const api = require('drizzle-kit/api')\r\n return api\r\n}\r\n\r\n/**\r\n * Migration options\r\n */\r\nexport type MigrationOptions = {\r\n /** Output directory for generated files */\r\n out?: string\r\n /** Enable verbose output */\r\n verbose?: boolean\r\n /** Dry run mode - don't apply changes */\r\n dryRun?: boolean\r\n}\r\n\r\n/**\r\n * Push schema to database (development mode)\r\n *\r\n * Uses drizzle-kit programmatic API to push schema changes to the database\r\n *\r\n * @example\r\n * import { push } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await push(adapter, collections)\r\n */\r\nexport const push = async (\r\n adapter: PgAdapter,\r\n collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const { verbose = false, dryRun = false } = options\r\n\r\n // Build schema from collections\r\n const schema = buildSchema(collections)\r\n\r\n // Get pool and create drizzle instance\r\n const pool = await adapter.getPool()\r\n const db = drizzle(pool, { schema })\r\n\r\n // Use drizzle-kit API\r\n const { pushSchema } = await getDrizzleKitApi()\r\n\r\n if (verbose) {\r\n console.log('[collections] Building schema from collections...')\r\n console.log('[collections] Tables:', Object.keys(schema).join(', '))\r\n }\r\n\r\n // Use pushSchema directly\r\n const result = await pushSchema(schema as Record<string, unknown>, db)\r\n\r\n if (verbose) {\r\n if (result.warnings.length > 0) {\r\n console.log('[collections] Warnings:')\r\n result.warnings.forEach((w: string) => console.log(' -', w))\r\n }\r\n console.log('[collections] Statements to execute:', result.statementsToExecute.length)\r\n }\r\n\r\n if (dryRun) {\r\n console.log('[collections] Dry run - not applying changes')\r\n if (verbose) {\r\n console.log('[collections] SQL statements:')\r\n result.statementsToExecute.forEach((stmt: string) => console.log(' ', stmt))\r\n }\r\n return\r\n }\r\n\r\n // Apply changes\r\n await result.apply()\r\n\r\n if (verbose) {\r\n console.log('[collections] Schema pushed successfully')\r\n }\r\n}\r\n\r\n/**\r\n * Generate migration files\r\n *\r\n * Uses drizzle-kit programmatic API to generate migration SQL files\r\n *\r\n * @example\r\n * import { generate } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await generate(adapter, collections, { out: './migrations' })\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nexport const generate = async (\r\n _adapter: PgAdapter,\r\n collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const { verbose = false, out = './drizzle' } = options\r\n\r\n // Build schema from collections\r\n const schema = buildSchema(collections)\r\n\r\n // Use drizzle-kit API\r\n const { generateDrizzleJson } = await getDrizzleKitApi()\r\n\r\n if (verbose) {\r\n console.log('[collections] Building schema from collections...')\r\n console.log('[collections] Tables:', Object.keys(schema).join(', '))\r\n }\r\n\r\n // Generate current schema snapshot\r\n const currentSnapshot = generateDrizzleJson(schema as Record<string, unknown>)\r\n\r\n // For now, we'll create a basic migration\r\n // In a full implementation, we'd need to:\r\n // 1. Read existing migrations from the database\r\n // 2. Get the previous snapshot\r\n // 3. Generate migration between prev and current\r\n\r\n if (verbose) {\r\n console.log('[collections] Current snapshot ID:', currentSnapshot.id)\r\n }\r\n\r\n // For simplicity, we'll just output the current schema as a migration\r\n // This is a simplified version - full implementation would track migrations\r\n const migrationSQL = [\r\n '-- Generated migration',\r\n `-- Snapshot: ${currentSnapshot.id}`,\r\n '',\r\n '-- Tables will be created based on current collections schema',\r\n ...currentSnapshot.tables?.map((table: string) => `-- Table: ${table}`) ?? []\r\n ]\r\n\r\n // Write to file\r\n const { writeFileSync, mkdirSync } = await import('fs')\r\n try {\r\n mkdirSync(out, { recursive: true })\r\n } catch {\r\n // Directory might already exist\r\n }\r\n\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-')\r\n const filename = `${out}/migration-${timestamp}.sql`\r\n\r\n writeFileSync(filename, migrationSQL.join('\\n'))\r\n\r\n if (verbose) {\r\n console.log('[collections] Migration written to:', filename)\r\n }\r\n}\r\n\r\n/**\r\n * Apply migrations\r\n *\r\n * Uses drizzle-kit programmatic API to apply pending migrations\r\n *\r\n * @example\r\n * import { migrate } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await migrate(adapter)\r\n */\r\nexport const migrate = async (\r\n adapter: PgAdapter,\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const { verbose = false } = options\r\n\r\n // Get pool\r\n const pool = await adapter.getPool()\r\n\r\n if (verbose) {\r\n console.log('[collections] Applying migrations...')\r\n }\r\n\r\n // For migrations, we use the same approach as push\r\n // The migrations table tracks which migrations have been applied\r\n // This is a simplified version\r\n\r\n // Get all migration files\r\n const { readdirSync, readFileSync } = await import('fs')\r\n const migrationsPath = adapter.config.migrationsPath ?? './migrations'\r\n\r\n try {\r\n const files = readdirSync(migrationsPath)\r\n .filter(f => f.endsWith('.sql'))\r\n .sort()\r\n\r\n if (files.length === 0) {\r\n if (verbose) {\r\n console.log('[collections] No migration files found')\r\n }\r\n return\r\n }\r\n\r\n // Execute each migration\r\n for (const file of files) {\r\n if (verbose) {\r\n console.log('[collections] Applying migration:', file)\r\n }\r\n\r\n const sql = readFileSync(`${migrationsPath}/${file}`, 'utf-8')\r\n await pool.query(sql)\r\n }\r\n\r\n if (verbose) {\r\n console.log('[collections] Migrations applied successfully')\r\n }\r\n } catch (error) {\r\n if (verbose) {\r\n console.log('[collections] No migrations directory or error:', error)\r\n }\r\n // If no migrations directory, just return\r\n }\r\n}\r\n","import { Pool, type Pool as PoolType } from 'pg'\r\nimport { drizzle } from 'drizzle-orm/node-postgres'\r\n\r\nimport type { Collection } from './collection'\r\nimport type { DatabaseAdapter } from './adapter'\r\nimport { buildSchema } from './schema'\r\n\r\n/**\r\n * Plugin interface\r\n */\r\nexport type Plugin = {\r\n name: string\r\n collections?: Record<string, Collection>\r\n hooks?: Record<string, unknown[]>\r\n}\r\n\r\n/**\r\n * Configuration options\r\n */\r\nexport type ConfigOptions<T extends Collection[] = []> = {\r\n database: DatabaseAdapter\r\n collections: T\r\n plugins?: Plugin[]\r\n}\r\n\r\n/**\r\n * Define config return type with inferred collection keys\r\n *\r\n * - collections: metadata only (slug, name, fields, hooks, dataType)\r\n * - db: Drizzle instance with operations (via schema tables)\r\n * - $meta: array of collection slugs and plugin names\r\n */\r\nexport type DefineConfigReturn<T extends Collection[] = []> = {\r\n collections: {\r\n [K in T[number] as K['slug']]: Collection\r\n }\r\n db: ReturnType<typeof drizzle<Record<string, unknown>>>\r\n $meta: {\r\n collections: T[number]['slug'][]\r\n plugins: string[]\r\n }\r\n}\r\n\r\n/**\r\n * Creates the configuration for the data layer\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: process.env.DATABASE_URL!\r\n * })\r\n *\r\n * export const { collections, db } = defineConfig({\r\n * database: adapter,\r\n * collections: [users, posts],\r\n * plugins: [timestampsPlugin()]\r\n * })\r\n *\r\n * // collections: metadata only\r\n * collections.users.slug // 'users'\r\n * collections.users.fields // { name, email, ... }\r\n *\r\n * // db: Drizzle instance with operations\r\n * await db.users.findMany()\r\n * await db.users.insert(values)\r\n */\r\nexport const defineConfig = <T extends Collection[]>(\r\n options: ConfigOptions<T>\r\n): DefineConfigReturn<T> => {\r\n // Initialize the database connection based on adapter type\r\n let pool: PoolType | null = null\r\n let dbInstance: ReturnType<typeof drizzle<Record<string, unknown>>> | null = null\r\n\r\n let schema: Record<string, unknown> = {}\r\n\r\n if (options.database.type === 'postgres') {\r\n // Create pool from adapter config\r\n pool = new Pool({\r\n connectionString: options.database.config.url\r\n })\r\n\r\n // Build schema from collections\r\n schema = buildSchema(options.collections as Collection[])\r\n\r\n // Create Drizzle instance with schema\r\n dbInstance = drizzle(pool, { schema })\r\n }\r\n\r\n // Build collections map (metadata only)\r\n const collectionsMap: Record<string, Collection> = {}\r\n const collectionNames: string[] = []\r\n\r\n for (const coll of options.collections) {\r\n // Store only metadata (not operations)\r\n collectionsMap[coll.slug] = {\r\n slug: coll.slug,\r\n name: coll.name,\r\n fields: coll.fields,\r\n hooks: coll.hooks,\r\n dataType: coll.dataType\r\n }\r\n collectionNames.push(coll.slug)\r\n }\r\n\r\n // Build plugins map\r\n const pluginNames: string[] = []\r\n if (options.plugins) {\r\n for (const plugin of options.plugins) {\r\n pluginNames.push(plugin.name)\r\n\r\n // Register plugin collections (metadata only)\r\n if (plugin.collections) {\r\n for (const [name, coll] of Object.entries(plugin.collections)) {\r\n collectionsMap[name] = {\r\n slug: coll.slug,\r\n name: coll.name,\r\n fields: coll.fields,\r\n hooks: coll.hooks,\r\n dataType: coll.dataType\r\n }\r\n collectionNames.push(name)\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n collections: collectionsMap as DefineConfigReturn<T>['collections'],\r\n db: dbInstance as DefineConfigReturn<T>['db'],\r\n $meta: {\r\n collections: collectionNames as DefineConfigReturn<T>['$meta']['collections'],\r\n plugins: pluginNames\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["Pool","text","timestamp","boolean","collection","fieldType","timestamp","f","drizzle","drizzle"]}