@deessejs/collections 0.4.1 → 0.4.3
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/cli.js +132 -152
- package/dist/cli.js.map +1 -1
- package/dist/index.js +120 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +120 -100
- package/dist/index.mjs.map +1 -1
- package/dist/next/index.js +2 -15
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +2 -15
- package/dist/next/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -731,21 +731,11 @@ var createCollectionOperations = (_collection, _slug, _db, _table, _hooks) => {
|
|
|
731
731
|
|
|
732
732
|
// src/adapter.ts
|
|
733
733
|
var pgAdapter = (config) => {
|
|
734
|
-
let pool = null;
|
|
735
734
|
return {
|
|
736
735
|
type: "postgres",
|
|
737
736
|
config: {
|
|
738
737
|
url: config.url,
|
|
739
738
|
migrationsPath: config.migrationsPath ?? "./migrations"
|
|
740
|
-
},
|
|
741
|
-
getPool: async () => {
|
|
742
|
-
if (!pool) {
|
|
743
|
-
const { Pool: Pool2 } = await import("pg");
|
|
744
|
-
pool = new Pool2({
|
|
745
|
-
connectionString: config.url
|
|
746
|
-
});
|
|
747
|
-
}
|
|
748
|
-
return pool;
|
|
749
739
|
}
|
|
750
740
|
};
|
|
751
741
|
};
|
|
@@ -796,109 +786,146 @@ var buildSchema = (collections) => {
|
|
|
796
786
|
};
|
|
797
787
|
|
|
798
788
|
// src/migrations.ts
|
|
799
|
-
var
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
789
|
+
var import_child_process = require("child_process");
|
|
790
|
+
var import_path = require("path");
|
|
791
|
+
var import_process = __toESM(require("process"));
|
|
792
|
+
function runCommand(command, args, options = {}) {
|
|
793
|
+
return new Promise((resolve2, reject) => {
|
|
794
|
+
if (options.verbose) {
|
|
795
|
+
console.log(`[collections] Running: ${command} ${args.join(" ")}`);
|
|
796
|
+
}
|
|
797
|
+
const child = (0, import_child_process.spawn)(command, args, {
|
|
798
|
+
stdio: options.verbose ? "inherit" : "pipe",
|
|
799
|
+
shell: true,
|
|
800
|
+
cwd: import_process.default.cwd()
|
|
801
|
+
});
|
|
802
|
+
let output = "";
|
|
803
|
+
if (!options.verbose) {
|
|
804
|
+
child.stdout?.on("data", (data) => {
|
|
805
|
+
output += data.toString();
|
|
806
|
+
});
|
|
807
|
+
child.stderr?.on("data", (data) => {
|
|
808
|
+
output += data.toString();
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
child.on("close", (code) => {
|
|
812
|
+
if (code === 0) {
|
|
813
|
+
resolve2(code ?? 0);
|
|
814
|
+
} else {
|
|
815
|
+
reject(new Error(`Command failed with code ${code}: ${output}`));
|
|
816
|
+
}
|
|
817
|
+
});
|
|
818
|
+
child.on("error", (error) => {
|
|
819
|
+
reject(error);
|
|
820
|
+
});
|
|
821
|
+
});
|
|
803
822
|
}
|
|
804
|
-
|
|
805
|
-
const
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
823
|
+
function buildDrizzleConfig(options) {
|
|
824
|
+
const config = {
|
|
825
|
+
dialect: "postgresql",
|
|
826
|
+
schema: options.schemaPath,
|
|
827
|
+
out: options.out,
|
|
828
|
+
dbCredentials: {
|
|
829
|
+
url: options.dbUrl
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
return JSON.stringify(config, null, 2);
|
|
833
|
+
}
|
|
834
|
+
var push = async (adapter, _collections, options = {}) => {
|
|
835
|
+
const {
|
|
836
|
+
verbose = false,
|
|
837
|
+
dryRun = false,
|
|
838
|
+
out = "./drizzle"
|
|
839
|
+
} = options;
|
|
840
|
+
const configContent = buildDrizzleConfig({
|
|
841
|
+
out,
|
|
842
|
+
schemaPath: "./collections/config.ts",
|
|
843
|
+
dbUrl: adapter.config.url
|
|
844
|
+
});
|
|
845
|
+
const drizzleConfigPath = (0, import_path.resolve)(import_process.default.cwd(), "./drizzle.config.json");
|
|
846
|
+
const { writeFileSync, unlinkSync } = await import("fs");
|
|
847
|
+
try {
|
|
848
|
+
writeFileSync(drizzleConfigPath, configContent);
|
|
849
|
+
const args = ["drizzle-kit", "push"];
|
|
850
|
+
if (dryRun) {
|
|
851
|
+
args.push("--dry-run");
|
|
819
852
|
}
|
|
820
|
-
console.log("[collections] Statements to execute:", result.statementsToExecute.length);
|
|
821
|
-
}
|
|
822
|
-
if (dryRun) {
|
|
823
|
-
console.log("[collections] Dry run - not applying changes");
|
|
824
853
|
if (verbose) {
|
|
825
|
-
|
|
826
|
-
|
|
854
|
+
args.push("--verbose");
|
|
855
|
+
}
|
|
856
|
+
await runCommand("npx", args, { verbose });
|
|
857
|
+
if (verbose) {
|
|
858
|
+
console.log("[collections] Schema pushed successfully");
|
|
859
|
+
}
|
|
860
|
+
} finally {
|
|
861
|
+
try {
|
|
862
|
+
unlinkSync(drizzleConfigPath);
|
|
863
|
+
} catch {
|
|
827
864
|
}
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
await result.apply();
|
|
831
|
-
if (verbose) {
|
|
832
|
-
console.log("[collections] Schema pushed successfully");
|
|
833
865
|
}
|
|
834
866
|
};
|
|
835
|
-
var generate = async (
|
|
836
|
-
const {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
}
|
|
847
|
-
const migrationSQL = [
|
|
848
|
-
"-- Generated migration",
|
|
849
|
-
`-- Snapshot: ${currentSnapshot.id}`,
|
|
850
|
-
"",
|
|
851
|
-
"-- Tables will be created based on current collections schema",
|
|
852
|
-
...currentSnapshot.tables?.map((table) => `-- Table: ${table}`) ?? []
|
|
853
|
-
];
|
|
854
|
-
const { writeFileSync, mkdirSync } = await import("fs");
|
|
867
|
+
var generate = async (adapter, _collections, options = {}) => {
|
|
868
|
+
const {
|
|
869
|
+
verbose = false,
|
|
870
|
+
out = "./drizzle"
|
|
871
|
+
} = options;
|
|
872
|
+
const configContent = buildDrizzleConfig({
|
|
873
|
+
out,
|
|
874
|
+
schemaPath: "./collections/config.ts",
|
|
875
|
+
dbUrl: adapter.config.url
|
|
876
|
+
});
|
|
877
|
+
const drizzleConfigPath = (0, import_path.resolve)(import_process.default.cwd(), "./drizzle.config.json");
|
|
878
|
+
const { writeFileSync, unlinkSync } = await import("fs");
|
|
855
879
|
try {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
880
|
+
writeFileSync(drizzleConfigPath, configContent);
|
|
881
|
+
const args = ["drizzle-kit", "generate"];
|
|
882
|
+
if (verbose) {
|
|
883
|
+
args.push("--verbose");
|
|
884
|
+
}
|
|
885
|
+
await runCommand("npx", args, { verbose });
|
|
886
|
+
if (verbose) {
|
|
887
|
+
console.log("[collections] Migrations generated successfully");
|
|
888
|
+
}
|
|
889
|
+
} finally {
|
|
890
|
+
try {
|
|
891
|
+
unlinkSync(drizzleConfigPath);
|
|
892
|
+
} catch {
|
|
893
|
+
}
|
|
864
894
|
}
|
|
865
895
|
};
|
|
866
896
|
var migrate = async (adapter, options = {}) => {
|
|
867
|
-
const {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
897
|
+
const {
|
|
898
|
+
verbose = false,
|
|
899
|
+
out = "./drizzle"
|
|
900
|
+
} = options;
|
|
901
|
+
const configContent = buildDrizzleConfig({
|
|
902
|
+
out,
|
|
903
|
+
schemaPath: "./collections/config.ts",
|
|
904
|
+
dbUrl: adapter.config.url
|
|
905
|
+
});
|
|
906
|
+
const drizzleConfigPath = (0, import_path.resolve)(import_process.default.cwd(), "./drizzle.config.json");
|
|
907
|
+
const { writeFileSync, unlinkSync } = await import("fs");
|
|
874
908
|
try {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
}
|
|
880
|
-
return;
|
|
881
|
-
}
|
|
882
|
-
for (const file of files) {
|
|
883
|
-
if (verbose) {
|
|
884
|
-
console.log("[collections] Applying migration:", file);
|
|
885
|
-
}
|
|
886
|
-
const sql = readFileSync(`${migrationsPath}/${file}`, "utf-8");
|
|
887
|
-
await pool.query(sql);
|
|
909
|
+
writeFileSync(drizzleConfigPath, configContent);
|
|
910
|
+
const args = ["drizzle-kit", "migrate"];
|
|
911
|
+
if (verbose) {
|
|
912
|
+
args.push("--verbose");
|
|
888
913
|
}
|
|
914
|
+
await runCommand("npx", args, { verbose });
|
|
889
915
|
if (verbose) {
|
|
890
916
|
console.log("[collections] Migrations applied successfully");
|
|
891
917
|
}
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
|
|
918
|
+
} finally {
|
|
919
|
+
try {
|
|
920
|
+
unlinkSync(drizzleConfigPath);
|
|
921
|
+
} catch {
|
|
895
922
|
}
|
|
896
923
|
}
|
|
897
924
|
};
|
|
898
925
|
|
|
899
926
|
// src/config.ts
|
|
900
927
|
var import_pg = require("pg");
|
|
901
|
-
var
|
|
928
|
+
var import_node_postgres = require("drizzle-orm/node-postgres");
|
|
902
929
|
var defineConfig = (options) => {
|
|
903
930
|
let pool = null;
|
|
904
931
|
let dbInstance = null;
|
|
@@ -908,7 +935,7 @@ var defineConfig = (options) => {
|
|
|
908
935
|
connectionString: options.database.config.url
|
|
909
936
|
});
|
|
910
937
|
schema = buildSchema(options.collections);
|
|
911
|
-
dbInstance = (0,
|
|
938
|
+
dbInstance = (0, import_node_postgres.drizzle)(pool, { schema });
|
|
912
939
|
}
|
|
913
940
|
const collectionsMap = {};
|
|
914
941
|
const collectionNames = [];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../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":["// Field type system\r\nexport { fieldType, type FieldTypeInstance, type FieldTypeCreator, type FieldTypeConfig } from './field-type'\r\n\r\n// Field\r\nexport { field, type FieldDefinition, type FieldOptions } from './field'\r\n\r\n// Built-in field types\r\nexport { f } from './fields'\r\nexport * from './fields'\r\n\r\n// Collection\r\nexport { collection, type CollectionConfig, type Collection, type CollectionHooks, type OperationType, type CreateHookContext, type UpdateHookContext, type DeleteHookContext, type ReadHookContext, type OperationHookContext, type CreateHookFunction, type UpdateHookFunction, type DeleteHookFunction, type ReadHookFunction, type GenericHookFunction } from './collection'\r\n\r\n// Operations\r\nexport * from './operations'\r\n\r\n// Adapter\r\nexport { pgAdapter, type PgAdapter, type PgAdapterConfig, type DatabaseAdapter } from './adapter'\r\n\r\n// Schema\r\nexport { buildSchema, buildTable } from './schema'\r\n\r\n// Migrations\r\nexport { push, generate, migrate, type MigrationOptions } from './migrations'\r\n\r\n// Config\r\nexport { defineConfig, type Plugin, type ConfigOptions, type DefineConfigReturn } from './config'\r\n","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","collection","fieldType","timestamp","f","import_node_postgres"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../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":["// Field type system\r\nexport { fieldType, type FieldTypeInstance, type FieldTypeCreator, type FieldTypeConfig } from './field-type'\r\n\r\n// Field\r\nexport { field, type FieldDefinition, type FieldOptions } from './field'\r\n\r\n// Built-in field types\r\nexport { f } from './fields'\r\nexport * from './fields'\r\n\r\n// Collection\r\nexport { collection, type CollectionConfig, type Collection, type CollectionHooks, type OperationType, type CreateHookContext, type UpdateHookContext, type DeleteHookContext, type ReadHookContext, type OperationHookContext, type CreateHookFunction, type UpdateHookFunction, type DeleteHookFunction, type ReadHookFunction, type GenericHookFunction } from './collection'\r\n\r\n// Operations\r\nexport * from './operations'\r\n\r\n// Adapter\r\nexport { pgAdapter, type PgAdapter, type PgAdapterConfig, type DatabaseAdapter } from './adapter'\r\n\r\n// Schema\r\nexport { buildSchema, buildTable } from './schema'\r\n\r\n// Migrations\r\nexport { push, generate, migrate, type MigrationOptions } from './migrations'\r\n\r\n// Config\r\nexport { defineConfig, type Plugin, type ConfigOptions, type DefineConfigReturn } from './config'\r\n","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\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 /** 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 * 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}): 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 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\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 {\r\n verbose = false,\r\n dryRun = false,\r\n out = './drizzle'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: './collections/config.ts',\r\n dbUrl: adapter.config.url\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\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\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 } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: './collections/config.ts',\r\n dbUrl: adapter.config.url\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\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 {\r\n verbose = false,\r\n out = './drizzle'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: './collections/config.ts',\r\n dbUrl: adapter.config.url\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":["collection","fieldType","resolve","process"]}
|