seedorm 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -631,6 +631,11 @@ var Model = class {
631
631
  }
632
632
  async init() {
633
633
  await this.adapter.createCollection(this.collection, this.schema);
634
+ for (const rel of Object.values(this.relations)) {
635
+ if (rel.type === "manyToMany" /* ManyToMany */ && rel.joinCollection) {
636
+ await this.adapter.createCollection(rel.joinCollection, {});
637
+ }
638
+ }
634
639
  }
635
640
  generateId() {
636
641
  return `${this.prefix}_${(0, import_nanoid.nanoid)(12)}`;
@@ -907,68 +912,82 @@ var fs = __toESM(require("fs"), 1);
907
912
  var path = __toESM(require("path"), 1);
908
913
  var import_write_file_atomic = __toESM(require("write-file-atomic"), 1);
909
914
  var FileEngine = class {
910
- filePath;
911
- data = {};
915
+ dirPath;
916
+ data = /* @__PURE__ */ new Map();
917
+ dirty = /* @__PURE__ */ new Set();
912
918
  writeQueue = Promise.resolve();
913
- dirty = false;
914
- constructor(filePath) {
915
- this.filePath = path.resolve(filePath);
919
+ constructor(dirPath) {
920
+ this.dirPath = path.resolve(dirPath);
916
921
  }
917
922
  async load() {
918
- try {
919
- const raw = fs.readFileSync(this.filePath, "utf-8");
920
- this.data = JSON.parse(raw);
921
- } catch (err) {
922
- if (err.code === "ENOENT") {
923
- this.data = {};
924
- await this.flush();
925
- } else {
926
- throw err;
923
+ if (!fs.existsSync(this.dirPath)) {
924
+ fs.mkdirSync(this.dirPath, { recursive: true });
925
+ }
926
+ const legacyPath = path.join(this.dirPath, "seedorm.json");
927
+ if (fs.existsSync(legacyPath)) {
928
+ const raw = fs.readFileSync(legacyPath, "utf-8");
929
+ const legacy = JSON.parse(raw);
930
+ for (const [collection, docs] of Object.entries(legacy)) {
931
+ this.data.set(collection, docs);
932
+ this.dirty.add(collection);
927
933
  }
934
+ await this.flush();
935
+ fs.unlinkSync(legacyPath);
936
+ return;
937
+ }
938
+ const files = fs.readdirSync(this.dirPath).filter((f) => f.endsWith(".json"));
939
+ for (const file of files) {
940
+ const collection = file.slice(0, -5);
941
+ const raw = fs.readFileSync(path.join(this.dirPath, file), "utf-8");
942
+ this.data.set(collection, JSON.parse(raw));
928
943
  }
929
- }
930
- getData() {
931
- return this.data;
932
944
  }
933
945
  getCollection(name) {
934
- if (!this.data[name]) {
935
- this.data[name] = [];
946
+ if (!this.data.has(name)) {
947
+ this.data.set(name, []);
936
948
  }
937
- return this.data[name];
949
+ return this.data.get(name);
938
950
  }
939
951
  hasCollection(name) {
940
- return name in this.data;
952
+ return this.data.has(name);
941
953
  }
942
954
  createCollection(name) {
943
- if (!this.data[name]) {
944
- this.data[name] = [];
955
+ if (!this.data.has(name)) {
956
+ this.data.set(name, []);
957
+ this.dirty.add(name);
945
958
  }
946
959
  }
947
960
  dropCollection(name) {
948
- delete this.data[name];
961
+ this.data.delete(name);
962
+ this.dirty.delete(name);
963
+ const filePath = path.join(this.dirPath, `${name}.json`);
964
+ if (fs.existsSync(filePath)) {
965
+ fs.unlinkSync(filePath);
966
+ }
949
967
  }
950
968
  listCollections() {
951
- return Object.keys(this.data);
969
+ return Array.from(this.data.keys());
952
970
  }
953
- markDirty() {
954
- this.dirty = true;
971
+ markDirty(collection) {
972
+ this.dirty.add(collection);
955
973
  }
956
974
  async flush() {
975
+ const toWrite = new Set(this.dirty);
976
+ this.dirty.clear();
957
977
  this.writeQueue = this.writeQueue.then(async () => {
958
- const dir = path.dirname(this.filePath);
959
- if (!fs.existsSync(dir)) {
960
- fs.mkdirSync(dir, { recursive: true });
978
+ for (const collection of toWrite) {
979
+ const docs = this.data.get(collection);
980
+ if (docs === void 0) continue;
981
+ await (0, import_write_file_atomic.default)(
982
+ path.join(this.dirPath, `${collection}.json`),
983
+ JSON.stringify(docs)
984
+ );
961
985
  }
962
- await (0, import_write_file_atomic.default)(
963
- this.filePath,
964
- JSON.stringify(this.data, null, 2) + "\n"
965
- );
966
- this.dirty = false;
967
986
  });
968
987
  return this.writeQueue;
969
988
  }
970
989
  async flushIfDirty() {
971
- if (this.dirty) {
990
+ if (this.dirty.size > 0) {
972
991
  await this.flush();
973
992
  }
974
993
  }
@@ -1054,8 +1073,8 @@ var JsonAdapter = class {
1054
1073
  engine;
1055
1074
  indexer = new Indexer();
1056
1075
  schemas = /* @__PURE__ */ new Map();
1057
- constructor(filePath) {
1058
- this.engine = new FileEngine(filePath);
1076
+ constructor(dirPath) {
1077
+ this.engine = new FileEngine(dirPath);
1059
1078
  }
1060
1079
  async connect() {
1061
1080
  await this.engine.load();
@@ -1091,7 +1110,7 @@ var JsonAdapter = class {
1091
1110
  const docs = this.getCollectionOrThrow(collection);
1092
1111
  this.indexer.onInsert(collection, doc);
1093
1112
  docs.push(doc);
1094
- this.engine.markDirty();
1113
+ this.engine.markDirty(collection);
1095
1114
  await this.engine.flush();
1096
1115
  return doc;
1097
1116
  }
@@ -1115,7 +1134,7 @@ var JsonAdapter = class {
1115
1134
  const newDoc = { ...oldDoc, ...data, id: oldDoc.id };
1116
1135
  this.indexer.onUpdate(collection, oldDoc, newDoc);
1117
1136
  docs[index] = newDoc;
1118
- this.engine.markDirty();
1137
+ this.engine.markDirty(collection);
1119
1138
  await this.engine.flush();
1120
1139
  return newDoc;
1121
1140
  }
@@ -1125,7 +1144,7 @@ var JsonAdapter = class {
1125
1144
  if (index === -1) return false;
1126
1145
  this.indexer.onDelete(collection, docs[index]);
1127
1146
  docs.splice(index, 1);
1128
- this.engine.markDirty();
1147
+ this.engine.markDirty(collection);
1129
1148
  await this.engine.flush();
1130
1149
  return true;
1131
1150
  }
@@ -1141,7 +1160,7 @@ var JsonAdapter = class {
1141
1160
  docs.length = 0;
1142
1161
  docs.push(...remaining);
1143
1162
  if (deleted > 0) {
1144
- this.engine.markDirty();
1163
+ this.engine.markDirty(collection);
1145
1164
  await this.engine.flush();
1146
1165
  }
1147
1166
  return deleted;
@@ -1170,11 +1189,8 @@ var SeedORM = class {
1170
1189
  async createAdapter(adapterConfig) {
1171
1190
  switch (adapterConfig.adapter) {
1172
1191
  case "json" /* Json */: {
1173
- const dbPath = path2.resolve(
1174
- adapterConfig.path ?? "./data",
1175
- "seedorm.json"
1176
- );
1177
- return new JsonAdapter(dbPath);
1192
+ const dirPath = path2.resolve(adapterConfig.path ?? "./data");
1193
+ return new JsonAdapter(dirPath);
1178
1194
  }
1179
1195
  case "postgres" /* Postgres */: {
1180
1196
  const { PostgresAdapter: PostgresAdapter2 } = await Promise.resolve().then(() => (init_postgres_adapter(), postgres_adapter_exports));
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts","../src/errors.ts","../src/query/operators.ts","../src/adapters/postgres/pg-connection.ts","../src/adapters/postgres/pg-query-builder.ts","../src/adapters/postgres/postgres-adapter.ts","../src/index.ts","../src/seedorm.ts","../src/model/model.ts","../src/model/schema.ts","../src/model/field-types.ts","../src/adapters/json/json-adapter.ts","../src/query/filter.ts","../src/adapters/json/file-engine.ts","../src/adapters/json/indexer.ts"],"sourcesContent":["// ── Field & Schema Types ──\n\nexport enum FieldType {\n String = \"string\",\n Number = \"number\",\n Boolean = \"boolean\",\n Date = \"date\",\n Json = \"json\",\n Array = \"array\",\n}\n\nexport interface FieldDefinition {\n type: FieldType;\n required?: boolean;\n unique?: boolean;\n index?: boolean;\n default?: unknown;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n enum?: unknown[];\n}\n\nexport interface SchemaDefinition {\n [field: string]: FieldType | FieldDefinition;\n}\n\nexport interface NormalizedField {\n type: FieldType;\n required: boolean;\n unique: boolean;\n index: boolean;\n default?: unknown;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n enum?: unknown[];\n}\n\nexport interface NormalizedSchema {\n [field: string]: NormalizedField;\n}\n\n// ── Document ──\n\nexport interface Document {\n id: string;\n createdAt: string;\n updatedAt: string;\n [key: string]: unknown;\n}\n\n// ── Query / Filter ──\n\nexport interface FilterOperators {\n $eq?: unknown;\n $ne?: unknown;\n $gt?: number | string | Date;\n $gte?: number | string | Date;\n $lt?: number | string | Date;\n $lte?: number | string | Date;\n $in?: unknown[];\n $nin?: unknown[];\n $like?: string;\n $exists?: boolean;\n}\n\nexport type FieldFilter = FilterOperators | unknown;\n\nexport interface FilterQuery {\n [field: string]: FieldFilter;\n}\n\nexport interface SortOption {\n [field: string]: 1 | -1;\n}\n\nexport interface FindOptions {\n filter?: FilterQuery;\n sort?: SortOption;\n limit?: number;\n offset?: number;\n include?: string[];\n}\n\n// ── Relations ──\n\nexport enum RelationType {\n HasOne = \"hasOne\",\n HasMany = \"hasMany\",\n BelongsTo = \"belongsTo\",\n ManyToMany = \"manyToMany\",\n}\n\nexport interface RelationDefinition {\n type: RelationType;\n model: string;\n foreignKey: string;\n joinCollection?: string;\n relatedKey?: string;\n}\n\nexport interface RelationsDefinition {\n [name: string]: RelationDefinition;\n}\n\n// ── Model Definition ──\n\nexport interface ModelDefinition {\n name: string;\n collection: string;\n schema: SchemaDefinition;\n timestamps?: boolean;\n prefix?: string;\n relations?: RelationsDefinition;\n}\n\n// ── Storage Adapter ──\n\nexport interface StorageAdapter {\n connect(): Promise<void>;\n disconnect(): Promise<void>;\n\n insert(collection: string, doc: Document): Promise<Document>;\n findById(collection: string, id: string): Promise<Document | null>;\n find(collection: string, options: FindOptions): Promise<Document[]>;\n count(collection: string, filter?: FilterQuery): Promise<number>;\n update(\n collection: string,\n id: string,\n data: Partial<Document>,\n ): Promise<Document | null>;\n delete(collection: string, id: string): Promise<boolean>;\n deleteMany(collection: string, filter: FilterQuery): Promise<number>;\n\n createCollection(collection: string, schema: NormalizedSchema): Promise<void>;\n dropCollection(collection: string): Promise<void>;\n listCollections(): Promise<string[]>;\n}\n\n// ── Config ──\n\nexport enum AdapterType {\n Json = \"json\",\n Postgres = \"postgres\",\n MySQL = \"mysql\",\n}\n\nexport interface JsonAdapterConfig {\n adapter: AdapterType.Json;\n path?: string;\n}\n\nexport interface PostgresAdapterConfig {\n adapter: AdapterType.Postgres;\n url: string;\n}\n\nexport interface MySQLAdapterConfig {\n adapter: AdapterType.MySQL;\n url: string;\n}\n\nexport type AdapterConfig =\n | JsonAdapterConfig\n | PostgresAdapterConfig\n | MySQLAdapterConfig;\n\nexport interface SeedORMConfig {\n adapter: AdapterConfig;\n migrationsDir?: string;\n}\n\n// ── Migration ──\n\nexport interface MigrationStep {\n type:\n | \"createCollection\"\n | \"dropCollection\"\n | \"addField\"\n | \"dropField\"\n | \"alterField\"\n | \"addIndex\"\n | \"dropIndex\";\n collection: string;\n field?: string;\n schema?: NormalizedField;\n oldSchema?: NormalizedField;\n}\n\nexport interface Migration {\n id: string;\n name: string;\n timestamp: number;\n up: MigrationStep[];\n down: MigrationStep[];\n}\n\nexport interface MigrationRecord {\n id: string;\n name: string;\n appliedAt: string;\n}\n","export class SeedORMError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SeedORMError\";\n }\n}\n\nexport class ValidationError extends SeedORMError {\n public field: string;\n public reason: string;\n\n constructor(field: string, reason: string) {\n super(`Validation error on \"${field}\": ${reason}`);\n this.name = \"ValidationError\";\n this.field = field;\n this.reason = reason;\n }\n}\n\nexport class AdapterError extends SeedORMError {\n public adapter: string;\n\n constructor(adapter: string, message: string) {\n super(`[${adapter}] ${message}`);\n this.name = \"AdapterError\";\n this.adapter = adapter;\n }\n}\n\nexport class CollectionNotFoundError extends SeedORMError {\n constructor(collection: string) {\n super(`Collection \"${collection}\" not found`);\n this.name = \"CollectionNotFoundError\";\n }\n}\n\nexport class DocumentNotFoundError extends SeedORMError {\n constructor(collection: string, id: string) {\n super(`Document \"${id}\" not found in \"${collection}\"`);\n this.name = \"DocumentNotFoundError\";\n }\n}\n\nexport class UniqueConstraintError extends SeedORMError {\n public field: string;\n public value: unknown;\n\n constructor(collection: string, field: string, value: unknown) {\n super(\n `Unique constraint violation on \"${collection}.${field}\": value ${JSON.stringify(value)} already exists`,\n );\n this.name = \"UniqueConstraintError\";\n this.field = field;\n this.value = value;\n }\n}\n","import type { FilterOperators } from \"../types.js\";\n\ntype OperatorFn = (fieldValue: unknown, operand: unknown) => boolean;\n\nconst operators: Record<string, OperatorFn> = {\n $eq: (val, op) => val === op,\n\n $ne: (val, op) => val !== op,\n\n $gt: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val > op;\n if (typeof val === \"string\" && typeof op === \"string\") return val > op;\n return false;\n },\n\n $gte: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val >= op;\n if (typeof val === \"string\" && typeof op === \"string\") return val >= op;\n return false;\n },\n\n $lt: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val < op;\n if (typeof val === \"string\" && typeof op === \"string\") return val < op;\n return false;\n },\n\n $lte: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val <= op;\n if (typeof val === \"string\" && typeof op === \"string\") return val <= op;\n return false;\n },\n\n $in: (val, op) => {\n if (!Array.isArray(op)) return false;\n return op.includes(val);\n },\n\n $nin: (val, op) => {\n if (!Array.isArray(op)) return true;\n return !op.includes(val);\n },\n\n $like: (val, op) => {\n if (typeof val !== \"string\" || typeof op !== \"string\") return false;\n // Convert SQL-like pattern to regex: % → .*, _ → .\n const escaped = op.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = escaped.replace(/%/g, \".*\").replace(/_/g, \".\");\n return new RegExp(`^${pattern}$`, \"i\").test(val);\n },\n\n $exists: (val, op) => {\n const exists = val !== undefined && val !== null;\n return op ? exists : !exists;\n },\n};\n\nexport function applyOperator(\n key: string,\n fieldValue: unknown,\n operand: unknown,\n): boolean {\n const fn = operators[key];\n if (!fn) throw new Error(`Unknown operator: ${key}`);\n return fn(fieldValue, operand);\n}\n\nexport function isOperatorObject(value: unknown): value is FilterOperators {\n if (value === null || typeof value !== \"object\" || Array.isArray(value))\n return false;\n return Object.keys(value as object).some((k) => k.startsWith(\"$\"));\n}\n\nexport const OPERATORS = Object.keys(operators);\n","import { AdapterError } from \"../../errors.js\";\n\n// pg is an optional peer dependency\nlet pgModule: typeof import(\"pg\") | null = null;\n\nasync function loadPg(): Promise<typeof import(\"pg\")> {\n if (pgModule) return pgModule;\n try {\n pgModule = await import(\"pg\");\n return pgModule;\n } catch {\n throw new AdapterError(\n \"postgres\",\n 'The \"pg\" package is required for PostgreSQL. Install it with: npm install pg',\n );\n }\n}\n\nexport class PgConnection {\n private pool: import(\"pg\").Pool | null = null;\n private url: string;\n\n constructor(url: string) {\n this.url = url;\n }\n\n async connect(): Promise<void> {\n const pg = await loadPg();\n this.pool = new pg.Pool({ connectionString: this.url });\n // Test the connection\n const client = await this.pool.connect();\n client.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n async query<T extends Record<string, unknown> = Record<string, unknown>>(\n text: string,\n params?: unknown[],\n ): Promise<{ rows: T[]; rowCount: number }> {\n if (!this.pool) {\n throw new AdapterError(\"postgres\", \"Not connected\");\n }\n const result = await this.pool.query(text, params);\n return { rows: result.rows as T[], rowCount: result.rowCount ?? 0 };\n }\n}\n","import type { FilterQuery, FindOptions, SortOption } from \"../../types.js\";\nimport { isOperatorObject } from \"../../query/operators.js\";\n\ninterface BuiltQuery {\n text: string;\n params: unknown[];\n}\n\nexport function buildSelect(\n collection: string,\n options: FindOptions,\n): BuiltQuery {\n const params: unknown[] = [];\n let text = `SELECT * FROM \"${collection}\"`;\n\n if (options.filter && Object.keys(options.filter).length > 0) {\n const where = buildWhere(options.filter, params);\n text += ` WHERE ${where}`;\n }\n\n if (options.sort) {\n text += ` ORDER BY ${buildOrderBy(options.sort)}`;\n }\n\n if (options.limit !== undefined) {\n params.push(options.limit);\n text += ` LIMIT $${params.length}`;\n }\n\n if (options.offset !== undefined) {\n params.push(options.offset);\n text += ` OFFSET $${params.length}`;\n }\n\n return { text, params };\n}\n\nexport function buildCount(\n collection: string,\n filter?: FilterQuery,\n): BuiltQuery {\n const params: unknown[] = [];\n let text = `SELECT COUNT(*) as count FROM \"${collection}\"`;\n\n if (filter && Object.keys(filter).length > 0) {\n const where = buildWhere(filter, params);\n text += ` WHERE ${where}`;\n }\n\n return { text, params };\n}\n\nfunction buildWhere(filter: FilterQuery, params: unknown[]): string {\n const conditions: string[] = [];\n\n for (const [field, condition] of Object.entries(filter)) {\n if (isOperatorObject(condition)) {\n for (const [op, value] of Object.entries(\n condition as Record<string, unknown>,\n )) {\n conditions.push(buildOperator(field, op, value, params));\n }\n } else {\n params.push(condition);\n conditions.push(`\"${field}\" = $${params.length}`);\n }\n }\n\n return conditions.join(\" AND \");\n}\n\nfunction buildOperator(\n field: string,\n op: string,\n value: unknown,\n params: unknown[],\n): string {\n switch (op) {\n case \"$eq\":\n params.push(value);\n return `\"${field}\" = $${params.length}`;\n case \"$ne\":\n params.push(value);\n return `\"${field}\" != $${params.length}`;\n case \"$gt\":\n params.push(value);\n return `\"${field}\" > $${params.length}`;\n case \"$gte\":\n params.push(value);\n return `\"${field}\" >= $${params.length}`;\n case \"$lt\":\n params.push(value);\n return `\"${field}\" < $${params.length}`;\n case \"$lte\":\n params.push(value);\n return `\"${field}\" <= $${params.length}`;\n case \"$in\":\n params.push(value);\n return `\"${field}\" = ANY($${params.length})`;\n case \"$nin\":\n params.push(value);\n return `\"${field}\" != ALL($${params.length})`;\n case \"$like\":\n params.push(value);\n return `\"${field}\" ILIKE $${params.length}`;\n case \"$exists\":\n return value\n ? `\"${field}\" IS NOT NULL`\n : `\"${field}\" IS NULL`;\n default:\n throw new Error(`Unknown operator: ${op}`);\n }\n}\n\nfunction buildOrderBy(sort: SortOption): string {\n return Object.entries(sort)\n .map(([field, dir]) => `\"${field}\" ${dir === 1 ? \"ASC\" : \"DESC\"}`)\n .join(\", \");\n}\n","import {\n FieldType,\n type Document,\n type FilterQuery,\n type FindOptions,\n type NormalizedField,\n type NormalizedSchema,\n type StorageAdapter,\n} from \"../../types.js\";\nimport { CollectionNotFoundError } from \"../../errors.js\";\nimport { PgConnection } from \"./pg-connection.js\";\nimport { buildSelect, buildCount } from \"./pg-query-builder.js\";\n\nfunction fieldToSQLType(field: NormalizedField): string {\n switch (field.type) {\n case FieldType.String:\n return field.maxLength ? `VARCHAR(${field.maxLength})` : \"TEXT\";\n case FieldType.Number:\n return \"DOUBLE PRECISION\";\n case FieldType.Boolean:\n return \"BOOLEAN\";\n case FieldType.Date:\n return \"TIMESTAMPTZ\";\n case FieldType.Json:\n case FieldType.Array:\n return \"JSONB\";\n default:\n return \"TEXT\";\n }\n}\n\nexport class PostgresAdapter implements StorageAdapter {\n private conn: PgConnection;\n\n constructor(url: string) {\n this.conn = new PgConnection(url);\n }\n\n async connect(): Promise<void> {\n await this.conn.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.conn.disconnect();\n }\n\n async createCollection(\n collection: string,\n schema: NormalizedSchema,\n ): Promise<void> {\n const columns = [\n `\"id\" TEXT PRIMARY KEY`,\n `\"createdAt\" TIMESTAMPTZ NOT NULL DEFAULT NOW()`,\n `\"updatedAt\" TIMESTAMPTZ NOT NULL DEFAULT NOW()`,\n ];\n\n for (const [name, def] of Object.entries(schema)) {\n let col = `\"${name}\" ${fieldToSQLType(def)}`;\n if (def.required) col += \" NOT NULL\";\n if (def.unique) col += \" UNIQUE\";\n columns.push(col);\n }\n\n await this.conn.query(\n `CREATE TABLE IF NOT EXISTS \"${collection}\" (${columns.join(\", \")})`,\n );\n\n // Create indexes\n for (const [name, def] of Object.entries(schema)) {\n if (def.index && !def.unique) {\n await this.conn.query(\n `CREATE INDEX IF NOT EXISTS \"idx_${collection}_${name}\" ON \"${collection}\" (\"${name}\")`,\n );\n }\n }\n }\n\n async dropCollection(collection: string): Promise<void> {\n await this.conn.query(`DROP TABLE IF EXISTS \"${collection}\" CASCADE`);\n }\n\n async listCollections(): Promise<string[]> {\n const { rows } = await this.conn.query<{ tablename: string }>(\n `SELECT tablename FROM pg_tables WHERE schemaname = 'public'`,\n );\n return rows.map((r) => r.tablename);\n }\n\n async insert(collection: string, doc: Document): Promise<Document> {\n const keys = Object.keys(doc);\n const cols = keys.map((k) => `\"${k}\"`).join(\", \");\n const placeholders = keys.map((_, i) => `$${i + 1}`).join(\", \");\n const values = keys.map((k) => {\n const v = doc[k];\n return typeof v === \"object\" && v !== null && !(v instanceof Date)\n ? JSON.stringify(v)\n : v;\n });\n\n const { rows } = await this.conn.query<Document>(\n `INSERT INTO \"${collection}\" (${cols}) VALUES (${placeholders}) RETURNING *`,\n values,\n );\n return rows[0]!;\n }\n\n async findById(\n collection: string,\n id: string,\n ): Promise<Document | null> {\n const { rows } = await this.conn.query<Document>(\n `SELECT * FROM \"${collection}\" WHERE \"id\" = $1`,\n [id],\n );\n return rows[0] ?? null;\n }\n\n async find(\n collection: string,\n options: FindOptions,\n ): Promise<Document[]> {\n const q = buildSelect(collection, options);\n const { rows } = await this.conn.query<Document>(q.text, q.params);\n return rows;\n }\n\n async count(collection: string, filter?: FilterQuery): Promise<number> {\n const q = buildCount(collection, filter);\n const { rows } = await this.conn.query<{ count: string }>(\n q.text,\n q.params,\n );\n return parseInt(rows[0]!.count, 10);\n }\n\n async update(\n collection: string,\n id: string,\n data: Partial<Document>,\n ): Promise<Document | null> {\n const entries = Object.entries(data).filter(([k]) => k !== \"id\");\n if (entries.length === 0) return this.findById(collection, id);\n\n const sets = entries.map(([k], i) => `\"${k}\" = $${i + 1}`).join(\", \");\n const values = entries.map(([, v]) =>\n typeof v === \"object\" && v !== null && !(v instanceof Date)\n ? JSON.stringify(v)\n : v,\n );\n values.push(id);\n\n const { rows } = await this.conn.query<Document>(\n `UPDATE \"${collection}\" SET ${sets} WHERE \"id\" = $${values.length} RETURNING *`,\n values,\n );\n return rows[0] ?? null;\n }\n\n async delete(collection: string, id: string): Promise<boolean> {\n const { rowCount } = await this.conn.query(\n `DELETE FROM \"${collection}\" WHERE \"id\" = $1`,\n [id],\n );\n return rowCount > 0;\n }\n\n async deleteMany(\n collection: string,\n filter: FilterQuery,\n ): Promise<number> {\n const q = buildSelect(collection, { filter });\n // Convert SELECT to DELETE\n const deleteText = q.text.replace(/^SELECT \\* FROM/, \"DELETE FROM\");\n const { rowCount } = await this.conn.query(deleteText, q.params);\n return rowCount;\n }\n}\n","export { SeedORM } from \"./seedorm.js\";\nexport { Model } from \"./model/model.js\";\nexport { JsonAdapter } from \"./adapters/json/json-adapter.js\";\nexport { PostgresAdapter } from \"./adapters/postgres/postgres-adapter.js\";\nexport { normalizeSchema, validateDocument } from \"./model/schema.js\";\n\n// Enums (value exports)\nexport { FieldType, RelationType, AdapterType } from \"./types.js\";\n\n// Types\nexport type {\n Document,\n FieldDefinition,\n FilterQuery,\n FilterOperators,\n FindOptions,\n ModelDefinition,\n NormalizedField,\n NormalizedSchema,\n SeedORMConfig,\n SchemaDefinition,\n SortOption,\n StorageAdapter,\n AdapterConfig,\n Migration,\n MigrationStep,\n MigrationRecord,\n RelationDefinition,\n RelationsDefinition,\n} from \"./types.js\";\n\n// Errors\nexport {\n SeedORMError,\n ValidationError,\n AdapterError,\n CollectionNotFoundError,\n DocumentNotFoundError,\n UniqueConstraintError,\n} from \"./errors.js\";\n","import {\n AdapterType,\n type AdapterConfig,\n type ModelDefinition,\n type SeedORMConfig,\n type StorageAdapter,\n} from \"./types.js\";\nimport { SeedORMError } from \"./errors.js\";\nimport { Model } from \"./model/model.js\";\nimport { JsonAdapter } from \"./adapters/json/json-adapter.js\";\nimport * as path from \"node:path\";\n\nexport class SeedORM {\n private config: SeedORMConfig;\n private adapter: StorageAdapter | null = null;\n private models = new Map<string, Model>();\n private connected = false;\n\n constructor(config?: Partial<SeedORMConfig>) {\n this.config = {\n adapter: config?.adapter ?? { adapter: AdapterType.Json, path: \"./data\" },\n migrationsDir: config?.migrationsDir ?? \"./migrations\",\n };\n }\n\n private async createAdapter(adapterConfig: AdapterConfig): Promise<StorageAdapter> {\n switch (adapterConfig.adapter) {\n case AdapterType.Json: {\n const dbPath = path.resolve(\n adapterConfig.path ?? \"./data\",\n \"seedorm.json\",\n );\n return new JsonAdapter(dbPath);\n }\n case AdapterType.Postgres: {\n const { PostgresAdapter } = await import(\"./adapters/postgres/postgres-adapter.js\");\n return new PostgresAdapter(adapterConfig.url);\n }\n case AdapterType.MySQL:\n throw new SeedORMError(\n 'MySQL adapter requires the \"mysql2\" package. Install it with: npm install mysql2',\n );\n default:\n throw new SeedORMError(\n `Unknown adapter: ${(adapterConfig as { adapter: string }).adapter}`,\n );\n }\n }\n\n async connect(): Promise<void> {\n if (this.connected) return;\n this.adapter = await this.createAdapter(this.config.adapter);\n await this.adapter.connect();\n this.connected = true;\n\n // Re-init existing models\n for (const model of this.models.values()) {\n await model.init();\n }\n }\n\n async disconnect(): Promise<void> {\n if (!this.connected || !this.adapter) return;\n await this.adapter.disconnect();\n this.connected = false;\n this.adapter = null;\n }\n\n model(definition: ModelDefinition): Model {\n if (this.models.has(definition.name)) {\n return this.models.get(definition.name)!;\n }\n\n if (!this.adapter) {\n throw new SeedORMError(\n \"Not connected. Call db.connect() before defining models.\",\n );\n }\n\n const model = new Model(definition, this.adapter, this);\n this.models.set(definition.name, model);\n return model;\n }\n\n getModel(name: string): Model | undefined {\n return this.models.get(name);\n }\n\n getAdapter(): StorageAdapter {\n if (!this.adapter) {\n throw new SeedORMError(\"Not connected.\");\n }\n return this.adapter;\n }\n\n getConfig(): SeedORMConfig {\n return this.config;\n }\n}\n","import { nanoid } from \"nanoid\";\nimport {\n RelationType,\n type Document,\n type FilterQuery,\n type FindOptions,\n type ModelDefinition,\n type NormalizedSchema,\n type RelationDefinition,\n type RelationsDefinition,\n type StorageAdapter,\n} from \"../types.js\";\nimport { DocumentNotFoundError, SeedORMError } from \"../errors.js\";\nimport { normalizeSchema, validateDocument } from \"./schema.js\";\n\ninterface SeedORMInstance {\n getModel(name: string): Model | undefined;\n getAdapter(): StorageAdapter;\n}\n\nexport class Model {\n public readonly name: string;\n public readonly collection: string;\n public readonly schema: NormalizedSchema;\n public readonly prefix: string;\n public readonly relations: RelationsDefinition;\n private adapter: StorageAdapter;\n private timestamps: boolean;\n private db: SeedORMInstance | null;\n\n constructor(definition: ModelDefinition, adapter: StorageAdapter, db?: SeedORMInstance) {\n this.name = definition.name;\n this.collection = definition.collection;\n this.schema = normalizeSchema(definition.schema);\n this.prefix = definition.prefix ?? definition.collection.slice(0, 3);\n this.adapter = adapter;\n this.timestamps = definition.timestamps !== false;\n this.relations = definition.relations ?? {};\n this.db = db ?? null;\n }\n\n async init(): Promise<void> {\n await this.adapter.createCollection(this.collection, this.schema);\n }\n\n private generateId(): string {\n return `${this.prefix}_${nanoid(12)}`;\n }\n\n private resolveRelation(relationName: string): { rel: RelationDefinition; relatedModel: Model } {\n const rel = this.relations[relationName];\n if (!rel) {\n throw new SeedORMError(`Unknown relation \"${relationName}\" on model \"${this.name}\"`);\n }\n if (!this.db) {\n throw new SeedORMError(\"Cannot resolve relations without a SeedORM instance\");\n }\n const relatedModel = this.db.getModel(rel.model);\n if (!relatedModel) {\n throw new SeedORMError(`Related model \"${rel.model}\" not found. Make sure it is defined before querying.`);\n }\n return { rel, relatedModel };\n }\n\n private async populate(docs: Document[], includeList: string[]): Promise<Document[]> {\n if (includeList.length === 0 || docs.length === 0) return docs;\n\n // Shallow-clone docs to avoid mutating the adapter's internal store\n docs = docs.map((d) => ({ ...d }));\n\n for (const relationName of includeList) {\n const { rel, relatedModel } = this.resolveRelation(relationName);\n\n switch (rel.type) {\n case RelationType.HasMany: {\n const parentIds = docs.map((d) => d.id);\n const related = await this.adapter.find(relatedModel.collection, {\n filter: { [rel.foreignKey]: { $in: parentIds } },\n });\n const grouped = new Map<string, Document[]>();\n for (const r of related) {\n const fk = r[rel.foreignKey] as string;\n if (!grouped.has(fk)) grouped.set(fk, []);\n grouped.get(fk)!.push(r);\n }\n for (const doc of docs) {\n doc[relationName] = grouped.get(doc.id) ?? [];\n }\n break;\n }\n\n case RelationType.HasOne: {\n const parentIds = docs.map((d) => d.id);\n const related = await this.adapter.find(relatedModel.collection, {\n filter: { [rel.foreignKey]: { $in: parentIds } },\n });\n const map = new Map<string, Document>();\n for (const r of related) {\n const fk = r[rel.foreignKey] as string;\n if (!map.has(fk)) map.set(fk, r);\n }\n for (const doc of docs) {\n doc[relationName] = map.get(doc.id) ?? null;\n }\n break;\n }\n\n case RelationType.BelongsTo: {\n const fkValues = [...new Set(docs.map((d) => d[rel.foreignKey] as string).filter(Boolean))];\n if (fkValues.length === 0) {\n for (const doc of docs) doc[relationName] = null;\n break;\n }\n const related = await this.adapter.find(relatedModel.collection, {\n filter: { id: { $in: fkValues } },\n });\n const map = new Map<string, Document>();\n for (const r of related) {\n map.set(r.id, r);\n }\n for (const doc of docs) {\n const fk = doc[rel.foreignKey] as string;\n doc[relationName] = map.get(fk) ?? null;\n }\n break;\n }\n\n case RelationType.ManyToMany: {\n if (!rel.joinCollection || !rel.relatedKey) {\n throw new SeedORMError(\n `manyToMany relation \"${relationName}\" requires joinCollection and relatedKey`,\n );\n }\n const parentIds = docs.map((d) => d.id);\n const joinRows = await this.adapter.find(rel.joinCollection, {\n filter: { [rel.foreignKey]: { $in: parentIds } },\n });\n const relatedIds = [...new Set(joinRows.map((r) => r[rel.relatedKey!] as string))];\n const relatedDocs =\n relatedIds.length > 0\n ? await this.adapter.find(relatedModel.collection, {\n filter: { id: { $in: relatedIds } },\n })\n : [];\n const relatedMap = new Map<string, Document>();\n for (const r of relatedDocs) relatedMap.set(r.id, r);\n\n const grouped = new Map<string, Document[]>();\n for (const row of joinRows) {\n const parentId = row[rel.foreignKey] as string;\n const relatedId = row[rel.relatedKey!] as string;\n const relatedDoc = relatedMap.get(relatedId);\n if (relatedDoc) {\n if (!grouped.has(parentId)) grouped.set(parentId, []);\n grouped.get(parentId)!.push(relatedDoc);\n }\n }\n for (const doc of docs) {\n doc[relationName] = grouped.get(doc.id) ?? [];\n }\n break;\n }\n }\n }\n\n return docs;\n }\n\n async create(data: Record<string, unknown>): Promise<Document> {\n const validated = validateDocument(data, this.schema);\n const now = new Date().toISOString();\n const doc: Document = {\n ...validated,\n id: this.generateId(),\n createdAt: now,\n updatedAt: now,\n };\n return this.adapter.insert(this.collection, doc);\n }\n\n async createMany(\n items: Record<string, unknown>[],\n ): Promise<Document[]> {\n const results: Document[] = [];\n for (const item of items) {\n results.push(await this.create(item));\n }\n return results;\n }\n\n async findById(id: string, options?: { include?: string[] }): Promise<Document | null> {\n const doc = await this.adapter.findById(this.collection, id);\n if (!doc || !options?.include?.length) return doc;\n const [populated] = await this.populate([doc], options.include);\n return populated ?? null;\n }\n\n async findByIdOrThrow(id: string, options?: { include?: string[] }): Promise<Document> {\n const doc = await this.findById(id, options);\n if (!doc) throw new DocumentNotFoundError(this.collection, id);\n return doc;\n }\n\n async findOne(filter: FilterQuery, options?: { include?: string[] }): Promise<Document | null> {\n const results = await this.adapter.find(this.collection, {\n filter,\n limit: 1,\n });\n const doc = results[0] ?? null;\n if (!doc || !options?.include?.length) return doc;\n const [populated] = await this.populate([doc], options.include);\n return populated ?? null;\n }\n\n async find(options: FindOptions = {}): Promise<Document[]> {\n const { include, ...adapterOptions } = options;\n const docs = await this.adapter.find(this.collection, adapterOptions);\n if (!include?.length) return docs;\n return this.populate(docs, include);\n }\n\n async findAll(): Promise<Document[]> {\n return this.adapter.find(this.collection, {});\n }\n\n async count(filter?: FilterQuery): Promise<number> {\n return this.adapter.count(this.collection, filter);\n }\n\n async update(\n id: string,\n data: Record<string, unknown>,\n ): Promise<Document | null> {\n const validated = validateDocument(data, this.schema, true);\n if (this.timestamps) {\n validated.updatedAt = new Date().toISOString();\n }\n return this.adapter.update(this.collection, id, validated);\n }\n\n async updateOrThrow(\n id: string,\n data: Record<string, unknown>,\n ): Promise<Document> {\n const doc = await this.update(id, data);\n if (!doc) throw new DocumentNotFoundError(this.collection, id);\n return doc;\n }\n\n async delete(id: string): Promise<boolean> {\n return this.adapter.delete(this.collection, id);\n }\n\n async deleteMany(filter: FilterQuery): Promise<number> {\n return this.adapter.deleteMany(this.collection, filter);\n }\n\n async associate(id: string, relationName: string, relatedId: string): Promise<Document> {\n const { rel } = this.resolveRelation(relationName);\n if (rel.type !== RelationType.ManyToMany) {\n throw new SeedORMError(`associate() is only supported for manyToMany relations, got \"${rel.type}\"`);\n }\n if (!rel.joinCollection || !rel.relatedKey) {\n throw new SeedORMError(\n `manyToMany relation \"${relationName}\" requires joinCollection and relatedKey`,\n );\n }\n const now = new Date().toISOString();\n const joinDoc: Document = {\n id: `${this.prefix}rel_${nanoid(12)}`,\n [rel.foreignKey]: id,\n [rel.relatedKey]: relatedId,\n createdAt: now,\n updatedAt: now,\n };\n return this.adapter.insert(rel.joinCollection, joinDoc);\n }\n\n async dissociate(id: string, relationName: string, relatedId: string): Promise<number> {\n const { rel } = this.resolveRelation(relationName);\n if (rel.type !== RelationType.ManyToMany) {\n throw new SeedORMError(`dissociate() is only supported for manyToMany relations, got \"${rel.type}\"`);\n }\n if (!rel.joinCollection || !rel.relatedKey) {\n throw new SeedORMError(\n `manyToMany relation \"${relationName}\" requires joinCollection and relatedKey`,\n );\n }\n return this.adapter.deleteMany(rel.joinCollection, {\n [rel.foreignKey]: id,\n [rel.relatedKey]: relatedId,\n });\n }\n}\n","import {\n FieldType,\n type FieldDefinition,\n type NormalizedField,\n type NormalizedSchema,\n type SchemaDefinition,\n} from \"../types.js\";\nimport { ValidationError } from \"../errors.js\";\nimport { coerceFieldValue, validateFieldType } from \"./field-types.js\";\n\nexport function normalizeSchema(schema: SchemaDefinition): NormalizedSchema {\n const normalized: NormalizedSchema = {};\n\n for (const [field, def] of Object.entries(schema)) {\n if (typeof def === \"string\") {\n normalized[field] = {\n type: def as FieldType,\n required: false,\n unique: false,\n index: false,\n };\n } else {\n const d = def as FieldDefinition;\n normalized[field] = {\n type: d.type,\n required: d.required ?? false,\n unique: d.unique ?? false,\n index: d.index ?? d.unique ?? false,\n ...(d.default !== undefined && { default: d.default }),\n ...(d.minLength !== undefined && { minLength: d.minLength }),\n ...(d.maxLength !== undefined && { maxLength: d.maxLength }),\n ...(d.min !== undefined && { min: d.min }),\n ...(d.max !== undefined && { max: d.max }),\n ...(d.enum !== undefined && { enum: d.enum }),\n };\n }\n }\n\n return normalized;\n}\n\nexport function validateDocument(\n data: Record<string, unknown>,\n schema: NormalizedSchema,\n isUpdate = false,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [field, def] of Object.entries(schema)) {\n let value = data[field];\n\n // Apply default\n if (value === undefined && def.default !== undefined && !isUpdate) {\n value =\n typeof def.default === \"function\"\n ? (def.default as () => unknown)()\n : def.default;\n }\n\n // Required check (skip on partial updates)\n if (!isUpdate && def.required && (value === undefined || value === null)) {\n throw new ValidationError(field, \"field is required\");\n }\n\n // Skip unset fields on update\n if (value === undefined) continue;\n\n // Type check\n const typeErr = validateFieldType(value, def.type);\n if (typeErr) throw new ValidationError(field, typeErr);\n\n // String constraints\n if (def.type === \"string\" && typeof value === \"string\") {\n if (def.minLength !== undefined && value.length < def.minLength) {\n throw new ValidationError(\n field,\n `minimum length is ${def.minLength}, got ${value.length}`,\n );\n }\n if (def.maxLength !== undefined && value.length > def.maxLength) {\n throw new ValidationError(\n field,\n `maximum length is ${def.maxLength}, got ${value.length}`,\n );\n }\n }\n\n // Number constraints\n if (def.type === \"number\" && typeof value === \"number\") {\n if (def.min !== undefined && value < def.min) {\n throw new ValidationError(field, `minimum value is ${def.min}`);\n }\n if (def.max !== undefined && value > def.max) {\n throw new ValidationError(field, `maximum value is ${def.max}`);\n }\n }\n\n // Enum check\n if (def.enum && !def.enum.includes(value)) {\n throw new ValidationError(\n field,\n `value must be one of: ${def.enum.join(\", \")}`,\n );\n }\n\n result[field] = coerceFieldValue(value, def.type);\n }\n\n // On update, pass through non-schema fields that were provided\n // (for id, createdAt, updatedAt)\n if (isUpdate) {\n for (const [key, val] of Object.entries(data)) {\n if (!(key in schema) && val !== undefined) {\n result[key] = val;\n }\n }\n }\n\n return result;\n}\n","import { FieldType } from \"../types.js\";\n\nexport function validateFieldType(\n value: unknown,\n type: FieldType,\n): string | null {\n if (value === undefined || value === null) return null; // handled by required check\n\n switch (type) {\n case FieldType.String:\n if (typeof value !== \"string\") return `expected string, got ${typeof value}`;\n break;\n case FieldType.Number:\n if (typeof value !== \"number\" || Number.isNaN(value))\n return `expected number, got ${typeof value}`;\n break;\n case FieldType.Boolean:\n if (typeof value !== \"boolean\")\n return `expected boolean, got ${typeof value}`;\n break;\n case FieldType.Date:\n if (typeof value === \"string\") {\n if (Number.isNaN(Date.parse(value))) return `invalid date string`;\n } else if (!(value instanceof Date)) {\n return `expected date string or Date, got ${typeof value}`;\n }\n break;\n case FieldType.Json:\n // Any non-undefined value is valid JSON\n break;\n case FieldType.Array:\n if (!Array.isArray(value)) return `expected array, got ${typeof value}`;\n break;\n default:\n return `unknown type: ${type as string}`;\n }\n\n return null;\n}\n\nexport function coerceFieldValue(value: unknown, type: FieldType): unknown {\n if (value === undefined || value === null) return value;\n\n if (type === FieldType.Date && value instanceof Date) {\n return value.toISOString();\n }\n\n return value;\n}\n","import type {\n Document,\n FilterQuery,\n FindOptions,\n NormalizedSchema,\n StorageAdapter,\n} from \"../../types.js\";\nimport { AdapterError, CollectionNotFoundError } from \"../../errors.js\";\nimport { applyFindOptions, countWithFilter } from \"../../query/filter.js\";\nimport { FileEngine } from \"./file-engine.js\";\nimport { Indexer } from \"./indexer.js\";\n\nexport class JsonAdapter implements StorageAdapter {\n private engine: FileEngine;\n private indexer = new Indexer();\n private schemas = new Map<string, NormalizedSchema>();\n\n constructor(filePath: string) {\n this.engine = new FileEngine(filePath);\n }\n\n async connect(): Promise<void> {\n await this.engine.load();\n }\n\n async disconnect(): Promise<void> {\n await this.engine.flushIfDirty();\n }\n\n async createCollection(\n collection: string,\n schema: NormalizedSchema,\n ): Promise<void> {\n this.engine.createCollection(collection);\n this.schemas.set(collection, schema);\n\n // Set up indexes\n for (const [field, def] of Object.entries(schema)) {\n if (def.index || def.unique) {\n this.indexer.setupIndex(\n collection,\n field,\n def.unique,\n this.engine.getCollection(collection),\n );\n }\n }\n\n await this.engine.flush();\n }\n\n async dropCollection(collection: string): Promise<void> {\n this.engine.dropCollection(collection);\n this.indexer.dropCollection(collection);\n this.schemas.delete(collection);\n await this.engine.flush();\n }\n\n async listCollections(): Promise<string[]> {\n return this.engine.listCollections();\n }\n\n async insert(collection: string, doc: Document): Promise<Document> {\n const docs = this.getCollectionOrThrow(collection);\n\n // Check unique constraints via indexer\n this.indexer.onInsert(collection, doc);\n\n docs.push(doc);\n this.engine.markDirty();\n await this.engine.flush();\n return doc;\n }\n\n async findById(\n collection: string,\n id: string,\n ): Promise<Document | null> {\n const docs = this.getCollectionOrThrow(collection);\n return docs.find((d) => d.id === id) ?? null;\n }\n\n async find(\n collection: string,\n options: FindOptions,\n ): Promise<Document[]> {\n const docs = this.getCollectionOrThrow(collection);\n return applyFindOptions(docs, options);\n }\n\n async count(collection: string, filter?: FilterQuery): Promise<number> {\n const docs = this.getCollectionOrThrow(collection);\n return countWithFilter(docs, filter);\n }\n\n async update(\n collection: string,\n id: string,\n data: Partial<Document>,\n ): Promise<Document | null> {\n const docs = this.getCollectionOrThrow(collection);\n const index = docs.findIndex((d) => d.id === id);\n if (index === -1) return null;\n\n const oldDoc = docs[index]!;\n const newDoc = { ...oldDoc, ...data, id: oldDoc.id };\n\n // Check unique constraints\n this.indexer.onUpdate(collection, oldDoc, newDoc);\n\n docs[index] = newDoc;\n this.engine.markDirty();\n await this.engine.flush();\n return newDoc;\n }\n\n async delete(collection: string, id: string): Promise<boolean> {\n const docs = this.getCollectionOrThrow(collection);\n const index = docs.findIndex((d) => d.id === id);\n if (index === -1) return false;\n\n this.indexer.onDelete(collection, docs[index]!);\n docs.splice(index, 1);\n this.engine.markDirty();\n await this.engine.flush();\n return true;\n }\n\n async deleteMany(\n collection: string,\n filter: FilterQuery,\n ): Promise<number> {\n const docs = this.getCollectionOrThrow(collection);\n const matching = applyFindOptions(docs, { filter });\n\n for (const doc of matching) {\n this.indexer.onDelete(collection, doc);\n }\n\n const ids = new Set(matching.map((d) => d.id));\n const remaining = docs.filter((d) => !ids.has(d.id));\n const deleted = docs.length - remaining.length;\n\n // Replace array contents in-place\n docs.length = 0;\n docs.push(...remaining);\n\n if (deleted > 0) {\n this.engine.markDirty();\n await this.engine.flush();\n }\n\n return deleted;\n }\n\n private getCollectionOrThrow(collection: string): Document[] {\n if (!this.engine.hasCollection(collection)) {\n throw new CollectionNotFoundError(collection);\n }\n return this.engine.getCollection(collection);\n }\n}\n","import type { Document, FilterQuery, FindOptions, SortOption } from \"../types.js\";\nimport { applyOperator, isOperatorObject } from \"./operators.js\";\n\nfunction matchesFilter(doc: Document, filter: FilterQuery): boolean {\n for (const [field, condition] of Object.entries(filter)) {\n const value = doc[field];\n\n if (isOperatorObject(condition)) {\n for (const [op, operand] of Object.entries(\n condition as Record<string, unknown>,\n )) {\n if (!applyOperator(op, value, operand)) return false;\n }\n } else {\n // Shorthand: { field: value } is equivalent to { field: { $eq: value } }\n if (value !== condition) return false;\n }\n }\n return true;\n}\n\nfunction sortDocuments(docs: Document[], sort: SortOption): Document[] {\n const entries = Object.entries(sort);\n return [...docs].sort((a, b) => {\n for (const [field, dir] of entries) {\n const av = a[field];\n const bv = b[field];\n if (av === bv) continue;\n if (av === undefined || av === null) return dir;\n if (bv === undefined || bv === null) return -dir;\n if (av < bv) return -dir;\n if (av > bv) return dir;\n }\n return 0;\n });\n}\n\nexport function applyFindOptions(\n docs: Document[],\n options: FindOptions,\n): Document[] {\n let result = docs;\n\n if (options.filter) {\n result = result.filter((doc) => matchesFilter(doc, options.filter!));\n }\n\n if (options.sort) {\n result = sortDocuments(result, options.sort);\n }\n\n if (options.offset) {\n result = result.slice(options.offset);\n }\n\n if (options.limit !== undefined) {\n result = result.slice(0, options.limit);\n }\n\n return result;\n}\n\nexport function countWithFilter(\n docs: Document[],\n filter?: FilterQuery,\n): number {\n if (!filter) return docs.length;\n return docs.filter((doc) => matchesFilter(doc, filter)).length;\n}\n\nexport { matchesFilter };\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport writeFileAtomic from \"write-file-atomic\";\nimport type { Document } from \"../../types.js\";\n\nexport interface FileData {\n [collection: string]: Document[];\n}\n\nexport class FileEngine {\n private filePath: string;\n private data: FileData = {};\n private writeQueue: Promise<void> = Promise.resolve();\n private dirty = false;\n\n constructor(filePath: string) {\n this.filePath = path.resolve(filePath);\n }\n\n async load(): Promise<void> {\n try {\n const raw = fs.readFileSync(this.filePath, \"utf-8\");\n this.data = JSON.parse(raw) as FileData;\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === \"ENOENT\") {\n this.data = {};\n await this.flush();\n } else {\n throw err;\n }\n }\n }\n\n getData(): FileData {\n return this.data;\n }\n\n getCollection(name: string): Document[] {\n if (!this.data[name]) {\n this.data[name] = [];\n }\n return this.data[name];\n }\n\n hasCollection(name: string): boolean {\n return name in this.data;\n }\n\n createCollection(name: string): void {\n if (!this.data[name]) {\n this.data[name] = [];\n }\n }\n\n dropCollection(name: string): void {\n delete this.data[name];\n }\n\n listCollections(): string[] {\n return Object.keys(this.data);\n }\n\n markDirty(): void {\n this.dirty = true;\n }\n\n async flush(): Promise<void> {\n this.writeQueue = this.writeQueue.then(async () => {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n await writeFileAtomic(\n this.filePath,\n JSON.stringify(this.data, null, 2) + \"\\n\",\n );\n this.dirty = false;\n });\n return this.writeQueue;\n }\n\n async flushIfDirty(): Promise<void> {\n if (this.dirty) {\n await this.flush();\n }\n }\n}\n","import type { Document } from \"../../types.js\";\nimport { UniqueConstraintError } from \"../../errors.js\";\n\ninterface FieldIndex {\n field: string;\n unique: boolean;\n map: Map<unknown, Set<string>>; // value → set of doc IDs\n}\n\nexport class Indexer {\n private indexes = new Map<string, Map<string, FieldIndex>>(); // collection → field → index\n\n setupIndex(\n collection: string,\n field: string,\n unique: boolean,\n docs: Document[],\n ): void {\n if (!this.indexes.has(collection)) {\n this.indexes.set(collection, new Map());\n }\n const colIndexes = this.indexes.get(collection)!;\n\n const idx: FieldIndex = { field, unique, map: new Map() };\n\n for (const doc of docs) {\n const val = doc[field];\n if (val === undefined || val === null) continue;\n if (!idx.map.has(val)) {\n idx.map.set(val, new Set());\n }\n idx.map.get(val)!.add(doc.id);\n }\n\n colIndexes.set(field, idx);\n }\n\n onInsert(collection: string, doc: Document): void {\n const colIndexes = this.indexes.get(collection);\n if (!colIndexes) return;\n\n for (const [, idx] of colIndexes) {\n const val = doc[idx.field];\n if (val === undefined || val === null) continue;\n\n if (idx.unique && idx.map.has(val) && idx.map.get(val)!.size > 0) {\n throw new UniqueConstraintError(collection, idx.field, val);\n }\n\n if (!idx.map.has(val)) {\n idx.map.set(val, new Set());\n }\n idx.map.get(val)!.add(doc.id);\n }\n }\n\n onUpdate(\n collection: string,\n oldDoc: Document,\n newDoc: Document,\n ): void {\n const colIndexes = this.indexes.get(collection);\n if (!colIndexes) return;\n\n for (const [, idx] of colIndexes) {\n const oldVal = oldDoc[idx.field];\n const newVal = newDoc[idx.field];\n\n if (oldVal === newVal) continue;\n\n // Remove old\n if (oldVal !== undefined && oldVal !== null) {\n idx.map.get(oldVal)?.delete(oldDoc.id);\n }\n\n // Add new\n if (newVal !== undefined && newVal !== null) {\n if (\n idx.unique &&\n idx.map.has(newVal) &&\n idx.map.get(newVal)!.size > 0\n ) {\n throw new UniqueConstraintError(collection, idx.field, newVal);\n }\n if (!idx.map.has(newVal)) {\n idx.map.set(newVal, new Set());\n }\n idx.map.get(newVal)!.add(newDoc.id);\n }\n }\n }\n\n onDelete(collection: string, doc: Document): void {\n const colIndexes = this.indexes.get(collection);\n if (!colIndexes) return;\n\n for (const [, idx] of colIndexes) {\n const val = doc[idx.field];\n if (val !== undefined && val !== null) {\n idx.map.get(val)?.delete(doc.id);\n }\n }\n }\n\n findByValue(\n collection: string,\n field: string,\n value: unknown,\n ): Set<string> | undefined {\n return this.indexes.get(collection)?.get(field)?.map.get(value);\n }\n\n dropCollection(collection: string): void {\n this.indexes.delete(collection);\n }\n}\n"],"mappings":"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","names":["FieldType","RelationType","AdapterType","writeFileAtomic","path","PostgresAdapter"]}
1
+ {"version":3,"sources":["../src/types.ts","../src/errors.ts","../src/query/operators.ts","../src/adapters/postgres/pg-connection.ts","../src/adapters/postgres/pg-query-builder.ts","../src/adapters/postgres/postgres-adapter.ts","../src/index.ts","../src/seedorm.ts","../src/model/model.ts","../src/model/schema.ts","../src/model/field-types.ts","../src/adapters/json/json-adapter.ts","../src/query/filter.ts","../src/adapters/json/file-engine.ts","../src/adapters/json/indexer.ts"],"sourcesContent":["// ── Field & Schema Types ──\n\nexport enum FieldType {\n String = \"string\",\n Number = \"number\",\n Boolean = \"boolean\",\n Date = \"date\",\n Json = \"json\",\n Array = \"array\",\n}\n\nexport interface FieldDefinition {\n type: FieldType;\n required?: boolean;\n unique?: boolean;\n index?: boolean;\n default?: unknown;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n enum?: unknown[];\n}\n\nexport interface SchemaDefinition {\n [field: string]: FieldType | FieldDefinition;\n}\n\nexport interface NormalizedField {\n type: FieldType;\n required: boolean;\n unique: boolean;\n index: boolean;\n default?: unknown;\n minLength?: number;\n maxLength?: number;\n min?: number;\n max?: number;\n enum?: unknown[];\n}\n\nexport interface NormalizedSchema {\n [field: string]: NormalizedField;\n}\n\n// ── Document ──\n\nexport interface Document {\n id: string;\n createdAt: string;\n updatedAt: string;\n [key: string]: unknown;\n}\n\n// ── Query / Filter ──\n\nexport interface FilterOperators {\n $eq?: unknown;\n $ne?: unknown;\n $gt?: number | string | Date;\n $gte?: number | string | Date;\n $lt?: number | string | Date;\n $lte?: number | string | Date;\n $in?: unknown[];\n $nin?: unknown[];\n $like?: string;\n $exists?: boolean;\n}\n\nexport type FieldFilter = FilterOperators | unknown;\n\nexport interface FilterQuery {\n [field: string]: FieldFilter;\n}\n\nexport interface SortOption {\n [field: string]: 1 | -1;\n}\n\nexport interface FindOptions {\n filter?: FilterQuery;\n sort?: SortOption;\n limit?: number;\n offset?: number;\n include?: string[];\n}\n\n// ── Relations ──\n\nexport enum RelationType {\n HasOne = \"hasOne\",\n HasMany = \"hasMany\",\n BelongsTo = \"belongsTo\",\n ManyToMany = \"manyToMany\",\n}\n\nexport interface RelationDefinition {\n type: RelationType;\n model: string;\n foreignKey: string;\n joinCollection?: string;\n relatedKey?: string;\n}\n\nexport interface RelationsDefinition {\n [name: string]: RelationDefinition;\n}\n\n// ── Model Definition ──\n\nexport interface ModelDefinition {\n name: string;\n collection: string;\n schema: SchemaDefinition;\n timestamps?: boolean;\n prefix?: string;\n relations?: RelationsDefinition;\n}\n\n// ── Storage Adapter ──\n\nexport interface StorageAdapter {\n connect(): Promise<void>;\n disconnect(): Promise<void>;\n\n insert(collection: string, doc: Document): Promise<Document>;\n findById(collection: string, id: string): Promise<Document | null>;\n find(collection: string, options: FindOptions): Promise<Document[]>;\n count(collection: string, filter?: FilterQuery): Promise<number>;\n update(\n collection: string,\n id: string,\n data: Partial<Document>,\n ): Promise<Document | null>;\n delete(collection: string, id: string): Promise<boolean>;\n deleteMany(collection: string, filter: FilterQuery): Promise<number>;\n\n createCollection(collection: string, schema: NormalizedSchema): Promise<void>;\n dropCollection(collection: string): Promise<void>;\n listCollections(): Promise<string[]>;\n}\n\n// ── Config ──\n\nexport enum AdapterType {\n Json = \"json\",\n Postgres = \"postgres\",\n MySQL = \"mysql\",\n}\n\nexport interface JsonAdapterConfig {\n adapter: AdapterType.Json;\n path?: string;\n}\n\nexport interface PostgresAdapterConfig {\n adapter: AdapterType.Postgres;\n url: string;\n}\n\nexport interface MySQLAdapterConfig {\n adapter: AdapterType.MySQL;\n url: string;\n}\n\nexport type AdapterConfig =\n | JsonAdapterConfig\n | PostgresAdapterConfig\n | MySQLAdapterConfig;\n\nexport interface SeedORMConfig {\n adapter: AdapterConfig;\n migrationsDir?: string;\n}\n\n// ── Migration ──\n\nexport interface MigrationStep {\n type:\n | \"createCollection\"\n | \"dropCollection\"\n | \"addField\"\n | \"dropField\"\n | \"alterField\"\n | \"addIndex\"\n | \"dropIndex\";\n collection: string;\n field?: string;\n schema?: NormalizedField;\n oldSchema?: NormalizedField;\n}\n\nexport interface Migration {\n id: string;\n name: string;\n timestamp: number;\n up: MigrationStep[];\n down: MigrationStep[];\n}\n\nexport interface MigrationRecord {\n id: string;\n name: string;\n appliedAt: string;\n}\n","export class SeedORMError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SeedORMError\";\n }\n}\n\nexport class ValidationError extends SeedORMError {\n public field: string;\n public reason: string;\n\n constructor(field: string, reason: string) {\n super(`Validation error on \"${field}\": ${reason}`);\n this.name = \"ValidationError\";\n this.field = field;\n this.reason = reason;\n }\n}\n\nexport class AdapterError extends SeedORMError {\n public adapter: string;\n\n constructor(adapter: string, message: string) {\n super(`[${adapter}] ${message}`);\n this.name = \"AdapterError\";\n this.adapter = adapter;\n }\n}\n\nexport class CollectionNotFoundError extends SeedORMError {\n constructor(collection: string) {\n super(`Collection \"${collection}\" not found`);\n this.name = \"CollectionNotFoundError\";\n }\n}\n\nexport class DocumentNotFoundError extends SeedORMError {\n constructor(collection: string, id: string) {\n super(`Document \"${id}\" not found in \"${collection}\"`);\n this.name = \"DocumentNotFoundError\";\n }\n}\n\nexport class UniqueConstraintError extends SeedORMError {\n public field: string;\n public value: unknown;\n\n constructor(collection: string, field: string, value: unknown) {\n super(\n `Unique constraint violation on \"${collection}.${field}\": value ${JSON.stringify(value)} already exists`,\n );\n this.name = \"UniqueConstraintError\";\n this.field = field;\n this.value = value;\n }\n}\n","import type { FilterOperators } from \"../types.js\";\n\ntype OperatorFn = (fieldValue: unknown, operand: unknown) => boolean;\n\nconst operators: Record<string, OperatorFn> = {\n $eq: (val, op) => val === op,\n\n $ne: (val, op) => val !== op,\n\n $gt: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val > op;\n if (typeof val === \"string\" && typeof op === \"string\") return val > op;\n return false;\n },\n\n $gte: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val >= op;\n if (typeof val === \"string\" && typeof op === \"string\") return val >= op;\n return false;\n },\n\n $lt: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val < op;\n if (typeof val === \"string\" && typeof op === \"string\") return val < op;\n return false;\n },\n\n $lte: (val, op) => {\n if (typeof val === \"number\" && typeof op === \"number\") return val <= op;\n if (typeof val === \"string\" && typeof op === \"string\") return val <= op;\n return false;\n },\n\n $in: (val, op) => {\n if (!Array.isArray(op)) return false;\n return op.includes(val);\n },\n\n $nin: (val, op) => {\n if (!Array.isArray(op)) return true;\n return !op.includes(val);\n },\n\n $like: (val, op) => {\n if (typeof val !== \"string\" || typeof op !== \"string\") return false;\n // Convert SQL-like pattern to regex: % → .*, _ → .\n const escaped = op.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = escaped.replace(/%/g, \".*\").replace(/_/g, \".\");\n return new RegExp(`^${pattern}$`, \"i\").test(val);\n },\n\n $exists: (val, op) => {\n const exists = val !== undefined && val !== null;\n return op ? exists : !exists;\n },\n};\n\nexport function applyOperator(\n key: string,\n fieldValue: unknown,\n operand: unknown,\n): boolean {\n const fn = operators[key];\n if (!fn) throw new Error(`Unknown operator: ${key}`);\n return fn(fieldValue, operand);\n}\n\nexport function isOperatorObject(value: unknown): value is FilterOperators {\n if (value === null || typeof value !== \"object\" || Array.isArray(value))\n return false;\n return Object.keys(value as object).some((k) => k.startsWith(\"$\"));\n}\n\nexport const OPERATORS = Object.keys(operators);\n","import { AdapterError } from \"../../errors.js\";\n\n// pg is an optional peer dependency\nlet pgModule: typeof import(\"pg\") | null = null;\n\nasync function loadPg(): Promise<typeof import(\"pg\")> {\n if (pgModule) return pgModule;\n try {\n pgModule = await import(\"pg\");\n return pgModule;\n } catch {\n throw new AdapterError(\n \"postgres\",\n 'The \"pg\" package is required for PostgreSQL. Install it with: npm install pg',\n );\n }\n}\n\nexport class PgConnection {\n private pool: import(\"pg\").Pool | null = null;\n private url: string;\n\n constructor(url: string) {\n this.url = url;\n }\n\n async connect(): Promise<void> {\n const pg = await loadPg();\n this.pool = new pg.Pool({ connectionString: this.url });\n // Test the connection\n const client = await this.pool.connect();\n client.release();\n }\n\n async disconnect(): Promise<void> {\n if (this.pool) {\n await this.pool.end();\n this.pool = null;\n }\n }\n\n async query<T extends Record<string, unknown> = Record<string, unknown>>(\n text: string,\n params?: unknown[],\n ): Promise<{ rows: T[]; rowCount: number }> {\n if (!this.pool) {\n throw new AdapterError(\"postgres\", \"Not connected\");\n }\n const result = await this.pool.query(text, params);\n return { rows: result.rows as T[], rowCount: result.rowCount ?? 0 };\n }\n}\n","import type { FilterQuery, FindOptions, SortOption } from \"../../types.js\";\nimport { isOperatorObject } from \"../../query/operators.js\";\n\ninterface BuiltQuery {\n text: string;\n params: unknown[];\n}\n\nexport function buildSelect(\n collection: string,\n options: FindOptions,\n): BuiltQuery {\n const params: unknown[] = [];\n let text = `SELECT * FROM \"${collection}\"`;\n\n if (options.filter && Object.keys(options.filter).length > 0) {\n const where = buildWhere(options.filter, params);\n text += ` WHERE ${where}`;\n }\n\n if (options.sort) {\n text += ` ORDER BY ${buildOrderBy(options.sort)}`;\n }\n\n if (options.limit !== undefined) {\n params.push(options.limit);\n text += ` LIMIT $${params.length}`;\n }\n\n if (options.offset !== undefined) {\n params.push(options.offset);\n text += ` OFFSET $${params.length}`;\n }\n\n return { text, params };\n}\n\nexport function buildCount(\n collection: string,\n filter?: FilterQuery,\n): BuiltQuery {\n const params: unknown[] = [];\n let text = `SELECT COUNT(*) as count FROM \"${collection}\"`;\n\n if (filter && Object.keys(filter).length > 0) {\n const where = buildWhere(filter, params);\n text += ` WHERE ${where}`;\n }\n\n return { text, params };\n}\n\nfunction buildWhere(filter: FilterQuery, params: unknown[]): string {\n const conditions: string[] = [];\n\n for (const [field, condition] of Object.entries(filter)) {\n if (isOperatorObject(condition)) {\n for (const [op, value] of Object.entries(\n condition as Record<string, unknown>,\n )) {\n conditions.push(buildOperator(field, op, value, params));\n }\n } else {\n params.push(condition);\n conditions.push(`\"${field}\" = $${params.length}`);\n }\n }\n\n return conditions.join(\" AND \");\n}\n\nfunction buildOperator(\n field: string,\n op: string,\n value: unknown,\n params: unknown[],\n): string {\n switch (op) {\n case \"$eq\":\n params.push(value);\n return `\"${field}\" = $${params.length}`;\n case \"$ne\":\n params.push(value);\n return `\"${field}\" != $${params.length}`;\n case \"$gt\":\n params.push(value);\n return `\"${field}\" > $${params.length}`;\n case \"$gte\":\n params.push(value);\n return `\"${field}\" >= $${params.length}`;\n case \"$lt\":\n params.push(value);\n return `\"${field}\" < $${params.length}`;\n case \"$lte\":\n params.push(value);\n return `\"${field}\" <= $${params.length}`;\n case \"$in\":\n params.push(value);\n return `\"${field}\" = ANY($${params.length})`;\n case \"$nin\":\n params.push(value);\n return `\"${field}\" != ALL($${params.length})`;\n case \"$like\":\n params.push(value);\n return `\"${field}\" ILIKE $${params.length}`;\n case \"$exists\":\n return value\n ? `\"${field}\" IS NOT NULL`\n : `\"${field}\" IS NULL`;\n default:\n throw new Error(`Unknown operator: ${op}`);\n }\n}\n\nfunction buildOrderBy(sort: SortOption): string {\n return Object.entries(sort)\n .map(([field, dir]) => `\"${field}\" ${dir === 1 ? \"ASC\" : \"DESC\"}`)\n .join(\", \");\n}\n","import {\n FieldType,\n type Document,\n type FilterQuery,\n type FindOptions,\n type NormalizedField,\n type NormalizedSchema,\n type StorageAdapter,\n} from \"../../types.js\";\nimport { CollectionNotFoundError } from \"../../errors.js\";\nimport { PgConnection } from \"./pg-connection.js\";\nimport { buildSelect, buildCount } from \"./pg-query-builder.js\";\n\nfunction fieldToSQLType(field: NormalizedField): string {\n switch (field.type) {\n case FieldType.String:\n return field.maxLength ? `VARCHAR(${field.maxLength})` : \"TEXT\";\n case FieldType.Number:\n return \"DOUBLE PRECISION\";\n case FieldType.Boolean:\n return \"BOOLEAN\";\n case FieldType.Date:\n return \"TIMESTAMPTZ\";\n case FieldType.Json:\n case FieldType.Array:\n return \"JSONB\";\n default:\n return \"TEXT\";\n }\n}\n\nexport class PostgresAdapter implements StorageAdapter {\n private conn: PgConnection;\n\n constructor(url: string) {\n this.conn = new PgConnection(url);\n }\n\n async connect(): Promise<void> {\n await this.conn.connect();\n }\n\n async disconnect(): Promise<void> {\n await this.conn.disconnect();\n }\n\n async createCollection(\n collection: string,\n schema: NormalizedSchema,\n ): Promise<void> {\n const columns = [\n `\"id\" TEXT PRIMARY KEY`,\n `\"createdAt\" TIMESTAMPTZ NOT NULL DEFAULT NOW()`,\n `\"updatedAt\" TIMESTAMPTZ NOT NULL DEFAULT NOW()`,\n ];\n\n for (const [name, def] of Object.entries(schema)) {\n let col = `\"${name}\" ${fieldToSQLType(def)}`;\n if (def.required) col += \" NOT NULL\";\n if (def.unique) col += \" UNIQUE\";\n columns.push(col);\n }\n\n await this.conn.query(\n `CREATE TABLE IF NOT EXISTS \"${collection}\" (${columns.join(\", \")})`,\n );\n\n // Create indexes\n for (const [name, def] of Object.entries(schema)) {\n if (def.index && !def.unique) {\n await this.conn.query(\n `CREATE INDEX IF NOT EXISTS \"idx_${collection}_${name}\" ON \"${collection}\" (\"${name}\")`,\n );\n }\n }\n }\n\n async dropCollection(collection: string): Promise<void> {\n await this.conn.query(`DROP TABLE IF EXISTS \"${collection}\" CASCADE`);\n }\n\n async listCollections(): Promise<string[]> {\n const { rows } = await this.conn.query<{ tablename: string }>(\n `SELECT tablename FROM pg_tables WHERE schemaname = 'public'`,\n );\n return rows.map((r) => r.tablename);\n }\n\n async insert(collection: string, doc: Document): Promise<Document> {\n const keys = Object.keys(doc);\n const cols = keys.map((k) => `\"${k}\"`).join(\", \");\n const placeholders = keys.map((_, i) => `$${i + 1}`).join(\", \");\n const values = keys.map((k) => {\n const v = doc[k];\n return typeof v === \"object\" && v !== null && !(v instanceof Date)\n ? JSON.stringify(v)\n : v;\n });\n\n const { rows } = await this.conn.query<Document>(\n `INSERT INTO \"${collection}\" (${cols}) VALUES (${placeholders}) RETURNING *`,\n values,\n );\n return rows[0]!;\n }\n\n async findById(\n collection: string,\n id: string,\n ): Promise<Document | null> {\n const { rows } = await this.conn.query<Document>(\n `SELECT * FROM \"${collection}\" WHERE \"id\" = $1`,\n [id],\n );\n return rows[0] ?? null;\n }\n\n async find(\n collection: string,\n options: FindOptions,\n ): Promise<Document[]> {\n const q = buildSelect(collection, options);\n const { rows } = await this.conn.query<Document>(q.text, q.params);\n return rows;\n }\n\n async count(collection: string, filter?: FilterQuery): Promise<number> {\n const q = buildCount(collection, filter);\n const { rows } = await this.conn.query<{ count: string }>(\n q.text,\n q.params,\n );\n return parseInt(rows[0]!.count, 10);\n }\n\n async update(\n collection: string,\n id: string,\n data: Partial<Document>,\n ): Promise<Document | null> {\n const entries = Object.entries(data).filter(([k]) => k !== \"id\");\n if (entries.length === 0) return this.findById(collection, id);\n\n const sets = entries.map(([k], i) => `\"${k}\" = $${i + 1}`).join(\", \");\n const values = entries.map(([, v]) =>\n typeof v === \"object\" && v !== null && !(v instanceof Date)\n ? JSON.stringify(v)\n : v,\n );\n values.push(id);\n\n const { rows } = await this.conn.query<Document>(\n `UPDATE \"${collection}\" SET ${sets} WHERE \"id\" = $${values.length} RETURNING *`,\n values,\n );\n return rows[0] ?? null;\n }\n\n async delete(collection: string, id: string): Promise<boolean> {\n const { rowCount } = await this.conn.query(\n `DELETE FROM \"${collection}\" WHERE \"id\" = $1`,\n [id],\n );\n return rowCount > 0;\n }\n\n async deleteMany(\n collection: string,\n filter: FilterQuery,\n ): Promise<number> {\n const q = buildSelect(collection, { filter });\n // Convert SELECT to DELETE\n const deleteText = q.text.replace(/^SELECT \\* FROM/, \"DELETE FROM\");\n const { rowCount } = await this.conn.query(deleteText, q.params);\n return rowCount;\n }\n}\n","export { SeedORM } from \"./seedorm.js\";\nexport { Model } from \"./model/model.js\";\nexport { JsonAdapter } from \"./adapters/json/json-adapter.js\";\nexport { PostgresAdapter } from \"./adapters/postgres/postgres-adapter.js\";\nexport { normalizeSchema, validateDocument } from \"./model/schema.js\";\n\n// Enums (value exports)\nexport { FieldType, RelationType, AdapterType } from \"./types.js\";\n\n// Types\nexport type {\n Document,\n FieldDefinition,\n FilterQuery,\n FilterOperators,\n FindOptions,\n ModelDefinition,\n NormalizedField,\n NormalizedSchema,\n SeedORMConfig,\n SchemaDefinition,\n SortOption,\n StorageAdapter,\n AdapterConfig,\n Migration,\n MigrationStep,\n MigrationRecord,\n RelationDefinition,\n RelationsDefinition,\n} from \"./types.js\";\n\n// Errors\nexport {\n SeedORMError,\n ValidationError,\n AdapterError,\n CollectionNotFoundError,\n DocumentNotFoundError,\n UniqueConstraintError,\n} from \"./errors.js\";\n","import {\n AdapterType,\n type AdapterConfig,\n type ModelDefinition,\n type SeedORMConfig,\n type StorageAdapter,\n} from \"./types.js\";\nimport { SeedORMError } from \"./errors.js\";\nimport { Model } from \"./model/model.js\";\nimport { JsonAdapter } from \"./adapters/json/json-adapter.js\";\nimport * as path from \"node:path\";\n\nexport class SeedORM {\n private config: SeedORMConfig;\n private adapter: StorageAdapter | null = null;\n private models = new Map<string, Model>();\n private connected = false;\n\n constructor(config?: Partial<SeedORMConfig>) {\n this.config = {\n adapter: config?.adapter ?? { adapter: AdapterType.Json, path: \"./data\" },\n migrationsDir: config?.migrationsDir ?? \"./migrations\",\n };\n }\n\n private async createAdapter(adapterConfig: AdapterConfig): Promise<StorageAdapter> {\n switch (adapterConfig.adapter) {\n case AdapterType.Json: {\n const dirPath = path.resolve(adapterConfig.path ?? \"./data\");\n return new JsonAdapter(dirPath);\n }\n case AdapterType.Postgres: {\n const { PostgresAdapter } = await import(\"./adapters/postgres/postgres-adapter.js\");\n return new PostgresAdapter(adapterConfig.url);\n }\n case AdapterType.MySQL:\n throw new SeedORMError(\n 'MySQL adapter requires the \"mysql2\" package. Install it with: npm install mysql2',\n );\n default:\n throw new SeedORMError(\n `Unknown adapter: ${(adapterConfig as { adapter: string }).adapter}`,\n );\n }\n }\n\n async connect(): Promise<void> {\n if (this.connected) return;\n this.adapter = await this.createAdapter(this.config.adapter);\n await this.adapter.connect();\n this.connected = true;\n\n // Re-init existing models\n for (const model of this.models.values()) {\n await model.init();\n }\n }\n\n async disconnect(): Promise<void> {\n if (!this.connected || !this.adapter) return;\n await this.adapter.disconnect();\n this.connected = false;\n this.adapter = null;\n }\n\n model(definition: ModelDefinition): Model {\n if (this.models.has(definition.name)) {\n return this.models.get(definition.name)!;\n }\n\n if (!this.adapter) {\n throw new SeedORMError(\n \"Not connected. Call db.connect() before defining models.\",\n );\n }\n\n const model = new Model(definition, this.adapter, this);\n this.models.set(definition.name, model);\n return model;\n }\n\n getModel(name: string): Model | undefined {\n return this.models.get(name);\n }\n\n getAdapter(): StorageAdapter {\n if (!this.adapter) {\n throw new SeedORMError(\"Not connected.\");\n }\n return this.adapter;\n }\n\n getConfig(): SeedORMConfig {\n return this.config;\n }\n}\n","import { nanoid } from \"nanoid\";\nimport {\n RelationType,\n type Document,\n type FilterQuery,\n type FindOptions,\n type ModelDefinition,\n type NormalizedSchema,\n type RelationDefinition,\n type RelationsDefinition,\n type StorageAdapter,\n} from \"../types.js\";\nimport { DocumentNotFoundError, SeedORMError } from \"../errors.js\";\nimport { normalizeSchema, validateDocument } from \"./schema.js\";\n\ninterface SeedORMInstance {\n getModel(name: string): Model | undefined;\n getAdapter(): StorageAdapter;\n}\n\nexport class Model {\n public readonly name: string;\n public readonly collection: string;\n public readonly schema: NormalizedSchema;\n public readonly prefix: string;\n public readonly relations: RelationsDefinition;\n private adapter: StorageAdapter;\n private timestamps: boolean;\n private db: SeedORMInstance | null;\n\n constructor(definition: ModelDefinition, adapter: StorageAdapter, db?: SeedORMInstance) {\n this.name = definition.name;\n this.collection = definition.collection;\n this.schema = normalizeSchema(definition.schema);\n this.prefix = definition.prefix ?? definition.collection.slice(0, 3);\n this.adapter = adapter;\n this.timestamps = definition.timestamps !== false;\n this.relations = definition.relations ?? {};\n this.db = db ?? null;\n }\n\n async init(): Promise<void> {\n await this.adapter.createCollection(this.collection, this.schema);\n\n // Create join collections for manyToMany relations\n for (const rel of Object.values(this.relations)) {\n if (rel.type === RelationType.ManyToMany && rel.joinCollection) {\n await this.adapter.createCollection(rel.joinCollection, {});\n }\n }\n }\n\n private generateId(): string {\n return `${this.prefix}_${nanoid(12)}`;\n }\n\n private resolveRelation(relationName: string): { rel: RelationDefinition; relatedModel: Model } {\n const rel = this.relations[relationName];\n if (!rel) {\n throw new SeedORMError(`Unknown relation \"${relationName}\" on model \"${this.name}\"`);\n }\n if (!this.db) {\n throw new SeedORMError(\"Cannot resolve relations without a SeedORM instance\");\n }\n const relatedModel = this.db.getModel(rel.model);\n if (!relatedModel) {\n throw new SeedORMError(`Related model \"${rel.model}\" not found. Make sure it is defined before querying.`);\n }\n return { rel, relatedModel };\n }\n\n private async populate(docs: Document[], includeList: string[]): Promise<Document[]> {\n if (includeList.length === 0 || docs.length === 0) return docs;\n\n // Shallow-clone docs to avoid mutating the adapter's internal store\n docs = docs.map((d) => ({ ...d }));\n\n for (const relationName of includeList) {\n const { rel, relatedModel } = this.resolveRelation(relationName);\n\n switch (rel.type) {\n case RelationType.HasMany: {\n const parentIds = docs.map((d) => d.id);\n const related = await this.adapter.find(relatedModel.collection, {\n filter: { [rel.foreignKey]: { $in: parentIds } },\n });\n const grouped = new Map<string, Document[]>();\n for (const r of related) {\n const fk = r[rel.foreignKey] as string;\n if (!grouped.has(fk)) grouped.set(fk, []);\n grouped.get(fk)!.push(r);\n }\n for (const doc of docs) {\n doc[relationName] = grouped.get(doc.id) ?? [];\n }\n break;\n }\n\n case RelationType.HasOne: {\n const parentIds = docs.map((d) => d.id);\n const related = await this.adapter.find(relatedModel.collection, {\n filter: { [rel.foreignKey]: { $in: parentIds } },\n });\n const map = new Map<string, Document>();\n for (const r of related) {\n const fk = r[rel.foreignKey] as string;\n if (!map.has(fk)) map.set(fk, r);\n }\n for (const doc of docs) {\n doc[relationName] = map.get(doc.id) ?? null;\n }\n break;\n }\n\n case RelationType.BelongsTo: {\n const fkValues = [...new Set(docs.map((d) => d[rel.foreignKey] as string).filter(Boolean))];\n if (fkValues.length === 0) {\n for (const doc of docs) doc[relationName] = null;\n break;\n }\n const related = await this.adapter.find(relatedModel.collection, {\n filter: { id: { $in: fkValues } },\n });\n const map = new Map<string, Document>();\n for (const r of related) {\n map.set(r.id, r);\n }\n for (const doc of docs) {\n const fk = doc[rel.foreignKey] as string;\n doc[relationName] = map.get(fk) ?? null;\n }\n break;\n }\n\n case RelationType.ManyToMany: {\n if (!rel.joinCollection || !rel.relatedKey) {\n throw new SeedORMError(\n `manyToMany relation \"${relationName}\" requires joinCollection and relatedKey`,\n );\n }\n const parentIds = docs.map((d) => d.id);\n const joinRows = await this.adapter.find(rel.joinCollection, {\n filter: { [rel.foreignKey]: { $in: parentIds } },\n });\n const relatedIds = [...new Set(joinRows.map((r) => r[rel.relatedKey!] as string))];\n const relatedDocs =\n relatedIds.length > 0\n ? await this.adapter.find(relatedModel.collection, {\n filter: { id: { $in: relatedIds } },\n })\n : [];\n const relatedMap = new Map<string, Document>();\n for (const r of relatedDocs) relatedMap.set(r.id, r);\n\n const grouped = new Map<string, Document[]>();\n for (const row of joinRows) {\n const parentId = row[rel.foreignKey] as string;\n const relatedId = row[rel.relatedKey!] as string;\n const relatedDoc = relatedMap.get(relatedId);\n if (relatedDoc) {\n if (!grouped.has(parentId)) grouped.set(parentId, []);\n grouped.get(parentId)!.push(relatedDoc);\n }\n }\n for (const doc of docs) {\n doc[relationName] = grouped.get(doc.id) ?? [];\n }\n break;\n }\n }\n }\n\n return docs;\n }\n\n async create(data: Record<string, unknown>): Promise<Document> {\n const validated = validateDocument(data, this.schema);\n const now = new Date().toISOString();\n const doc: Document = {\n ...validated,\n id: this.generateId(),\n createdAt: now,\n updatedAt: now,\n };\n return this.adapter.insert(this.collection, doc);\n }\n\n async createMany(\n items: Record<string, unknown>[],\n ): Promise<Document[]> {\n const results: Document[] = [];\n for (const item of items) {\n results.push(await this.create(item));\n }\n return results;\n }\n\n async findById(id: string, options?: { include?: string[] }): Promise<Document | null> {\n const doc = await this.adapter.findById(this.collection, id);\n if (!doc || !options?.include?.length) return doc;\n const [populated] = await this.populate([doc], options.include);\n return populated ?? null;\n }\n\n async findByIdOrThrow(id: string, options?: { include?: string[] }): Promise<Document> {\n const doc = await this.findById(id, options);\n if (!doc) throw new DocumentNotFoundError(this.collection, id);\n return doc;\n }\n\n async findOne(filter: FilterQuery, options?: { include?: string[] }): Promise<Document | null> {\n const results = await this.adapter.find(this.collection, {\n filter,\n limit: 1,\n });\n const doc = results[0] ?? null;\n if (!doc || !options?.include?.length) return doc;\n const [populated] = await this.populate([doc], options.include);\n return populated ?? null;\n }\n\n async find(options: FindOptions = {}): Promise<Document[]> {\n const { include, ...adapterOptions } = options;\n const docs = await this.adapter.find(this.collection, adapterOptions);\n if (!include?.length) return docs;\n return this.populate(docs, include);\n }\n\n async findAll(): Promise<Document[]> {\n return this.adapter.find(this.collection, {});\n }\n\n async count(filter?: FilterQuery): Promise<number> {\n return this.adapter.count(this.collection, filter);\n }\n\n async update(\n id: string,\n data: Record<string, unknown>,\n ): Promise<Document | null> {\n const validated = validateDocument(data, this.schema, true);\n if (this.timestamps) {\n validated.updatedAt = new Date().toISOString();\n }\n return this.adapter.update(this.collection, id, validated);\n }\n\n async updateOrThrow(\n id: string,\n data: Record<string, unknown>,\n ): Promise<Document> {\n const doc = await this.update(id, data);\n if (!doc) throw new DocumentNotFoundError(this.collection, id);\n return doc;\n }\n\n async delete(id: string): Promise<boolean> {\n return this.adapter.delete(this.collection, id);\n }\n\n async deleteMany(filter: FilterQuery): Promise<number> {\n return this.adapter.deleteMany(this.collection, filter);\n }\n\n async associate(id: string, relationName: string, relatedId: string): Promise<Document> {\n const { rel } = this.resolveRelation(relationName);\n if (rel.type !== RelationType.ManyToMany) {\n throw new SeedORMError(`associate() is only supported for manyToMany relations, got \"${rel.type}\"`);\n }\n if (!rel.joinCollection || !rel.relatedKey) {\n throw new SeedORMError(\n `manyToMany relation \"${relationName}\" requires joinCollection and relatedKey`,\n );\n }\n const now = new Date().toISOString();\n const joinDoc: Document = {\n id: `${this.prefix}rel_${nanoid(12)}`,\n [rel.foreignKey]: id,\n [rel.relatedKey]: relatedId,\n createdAt: now,\n updatedAt: now,\n };\n return this.adapter.insert(rel.joinCollection, joinDoc);\n }\n\n async dissociate(id: string, relationName: string, relatedId: string): Promise<number> {\n const { rel } = this.resolveRelation(relationName);\n if (rel.type !== RelationType.ManyToMany) {\n throw new SeedORMError(`dissociate() is only supported for manyToMany relations, got \"${rel.type}\"`);\n }\n if (!rel.joinCollection || !rel.relatedKey) {\n throw new SeedORMError(\n `manyToMany relation \"${relationName}\" requires joinCollection and relatedKey`,\n );\n }\n return this.adapter.deleteMany(rel.joinCollection, {\n [rel.foreignKey]: id,\n [rel.relatedKey]: relatedId,\n });\n }\n}\n","import {\n FieldType,\n type FieldDefinition,\n type NormalizedField,\n type NormalizedSchema,\n type SchemaDefinition,\n} from \"../types.js\";\nimport { ValidationError } from \"../errors.js\";\nimport { coerceFieldValue, validateFieldType } from \"./field-types.js\";\n\nexport function normalizeSchema(schema: SchemaDefinition): NormalizedSchema {\n const normalized: NormalizedSchema = {};\n\n for (const [field, def] of Object.entries(schema)) {\n if (typeof def === \"string\") {\n normalized[field] = {\n type: def as FieldType,\n required: false,\n unique: false,\n index: false,\n };\n } else {\n const d = def as FieldDefinition;\n normalized[field] = {\n type: d.type,\n required: d.required ?? false,\n unique: d.unique ?? false,\n index: d.index ?? d.unique ?? false,\n ...(d.default !== undefined && { default: d.default }),\n ...(d.minLength !== undefined && { minLength: d.minLength }),\n ...(d.maxLength !== undefined && { maxLength: d.maxLength }),\n ...(d.min !== undefined && { min: d.min }),\n ...(d.max !== undefined && { max: d.max }),\n ...(d.enum !== undefined && { enum: d.enum }),\n };\n }\n }\n\n return normalized;\n}\n\nexport function validateDocument(\n data: Record<string, unknown>,\n schema: NormalizedSchema,\n isUpdate = false,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n\n for (const [field, def] of Object.entries(schema)) {\n let value = data[field];\n\n // Apply default\n if (value === undefined && def.default !== undefined && !isUpdate) {\n value =\n typeof def.default === \"function\"\n ? (def.default as () => unknown)()\n : def.default;\n }\n\n // Required check (skip on partial updates)\n if (!isUpdate && def.required && (value === undefined || value === null)) {\n throw new ValidationError(field, \"field is required\");\n }\n\n // Skip unset fields on update\n if (value === undefined) continue;\n\n // Type check\n const typeErr = validateFieldType(value, def.type);\n if (typeErr) throw new ValidationError(field, typeErr);\n\n // String constraints\n if (def.type === \"string\" && typeof value === \"string\") {\n if (def.minLength !== undefined && value.length < def.minLength) {\n throw new ValidationError(\n field,\n `minimum length is ${def.minLength}, got ${value.length}`,\n );\n }\n if (def.maxLength !== undefined && value.length > def.maxLength) {\n throw new ValidationError(\n field,\n `maximum length is ${def.maxLength}, got ${value.length}`,\n );\n }\n }\n\n // Number constraints\n if (def.type === \"number\" && typeof value === \"number\") {\n if (def.min !== undefined && value < def.min) {\n throw new ValidationError(field, `minimum value is ${def.min}`);\n }\n if (def.max !== undefined && value > def.max) {\n throw new ValidationError(field, `maximum value is ${def.max}`);\n }\n }\n\n // Enum check\n if (def.enum && !def.enum.includes(value)) {\n throw new ValidationError(\n field,\n `value must be one of: ${def.enum.join(\", \")}`,\n );\n }\n\n result[field] = coerceFieldValue(value, def.type);\n }\n\n // On update, pass through non-schema fields that were provided\n // (for id, createdAt, updatedAt)\n if (isUpdate) {\n for (const [key, val] of Object.entries(data)) {\n if (!(key in schema) && val !== undefined) {\n result[key] = val;\n }\n }\n }\n\n return result;\n}\n","import { FieldType } from \"../types.js\";\n\nexport function validateFieldType(\n value: unknown,\n type: FieldType,\n): string | null {\n if (value === undefined || value === null) return null; // handled by required check\n\n switch (type) {\n case FieldType.String:\n if (typeof value !== \"string\") return `expected string, got ${typeof value}`;\n break;\n case FieldType.Number:\n if (typeof value !== \"number\" || Number.isNaN(value))\n return `expected number, got ${typeof value}`;\n break;\n case FieldType.Boolean:\n if (typeof value !== \"boolean\")\n return `expected boolean, got ${typeof value}`;\n break;\n case FieldType.Date:\n if (typeof value === \"string\") {\n if (Number.isNaN(Date.parse(value))) return `invalid date string`;\n } else if (!(value instanceof Date)) {\n return `expected date string or Date, got ${typeof value}`;\n }\n break;\n case FieldType.Json:\n // Any non-undefined value is valid JSON\n break;\n case FieldType.Array:\n if (!Array.isArray(value)) return `expected array, got ${typeof value}`;\n break;\n default:\n return `unknown type: ${type as string}`;\n }\n\n return null;\n}\n\nexport function coerceFieldValue(value: unknown, type: FieldType): unknown {\n if (value === undefined || value === null) return value;\n\n if (type === FieldType.Date && value instanceof Date) {\n return value.toISOString();\n }\n\n return value;\n}\n","import type {\n Document,\n FilterQuery,\n FindOptions,\n NormalizedSchema,\n StorageAdapter,\n} from \"../../types.js\";\nimport { AdapterError, CollectionNotFoundError } from \"../../errors.js\";\nimport { applyFindOptions, countWithFilter } from \"../../query/filter.js\";\nimport { FileEngine } from \"./file-engine.js\";\nimport { Indexer } from \"./indexer.js\";\n\nexport class JsonAdapter implements StorageAdapter {\n private engine: FileEngine;\n private indexer = new Indexer();\n private schemas = new Map<string, NormalizedSchema>();\n\n constructor(dirPath: string) {\n this.engine = new FileEngine(dirPath);\n }\n\n async connect(): Promise<void> {\n await this.engine.load();\n }\n\n async disconnect(): Promise<void> {\n await this.engine.flushIfDirty();\n }\n\n async createCollection(\n collection: string,\n schema: NormalizedSchema,\n ): Promise<void> {\n this.engine.createCollection(collection);\n this.schemas.set(collection, schema);\n\n // Set up indexes\n for (const [field, def] of Object.entries(schema)) {\n if (def.index || def.unique) {\n this.indexer.setupIndex(\n collection,\n field,\n def.unique,\n this.engine.getCollection(collection),\n );\n }\n }\n\n await this.engine.flush();\n }\n\n async dropCollection(collection: string): Promise<void> {\n this.engine.dropCollection(collection);\n this.indexer.dropCollection(collection);\n this.schemas.delete(collection);\n await this.engine.flush();\n }\n\n async listCollections(): Promise<string[]> {\n return this.engine.listCollections();\n }\n\n async insert(collection: string, doc: Document): Promise<Document> {\n const docs = this.getCollectionOrThrow(collection);\n\n // Check unique constraints via indexer\n this.indexer.onInsert(collection, doc);\n\n docs.push(doc);\n this.engine.markDirty(collection);\n await this.engine.flush();\n return doc;\n }\n\n async findById(\n collection: string,\n id: string,\n ): Promise<Document | null> {\n const docs = this.getCollectionOrThrow(collection);\n return docs.find((d) => d.id === id) ?? null;\n }\n\n async find(\n collection: string,\n options: FindOptions,\n ): Promise<Document[]> {\n const docs = this.getCollectionOrThrow(collection);\n return applyFindOptions(docs, options);\n }\n\n async count(collection: string, filter?: FilterQuery): Promise<number> {\n const docs = this.getCollectionOrThrow(collection);\n return countWithFilter(docs, filter);\n }\n\n async update(\n collection: string,\n id: string,\n data: Partial<Document>,\n ): Promise<Document | null> {\n const docs = this.getCollectionOrThrow(collection);\n const index = docs.findIndex((d) => d.id === id);\n if (index === -1) return null;\n\n const oldDoc = docs[index]!;\n const newDoc = { ...oldDoc, ...data, id: oldDoc.id };\n\n // Check unique constraints\n this.indexer.onUpdate(collection, oldDoc, newDoc);\n\n docs[index] = newDoc;\n this.engine.markDirty(collection);\n await this.engine.flush();\n return newDoc;\n }\n\n async delete(collection: string, id: string): Promise<boolean> {\n const docs = this.getCollectionOrThrow(collection);\n const index = docs.findIndex((d) => d.id === id);\n if (index === -1) return false;\n\n this.indexer.onDelete(collection, docs[index]!);\n docs.splice(index, 1);\n this.engine.markDirty(collection);\n await this.engine.flush();\n return true;\n }\n\n async deleteMany(\n collection: string,\n filter: FilterQuery,\n ): Promise<number> {\n const docs = this.getCollectionOrThrow(collection);\n const matching = applyFindOptions(docs, { filter });\n\n for (const doc of matching) {\n this.indexer.onDelete(collection, doc);\n }\n\n const ids = new Set(matching.map((d) => d.id));\n const remaining = docs.filter((d) => !ids.has(d.id));\n const deleted = docs.length - remaining.length;\n\n // Replace array contents in-place\n docs.length = 0;\n docs.push(...remaining);\n\n if (deleted > 0) {\n this.engine.markDirty(collection);\n await this.engine.flush();\n }\n\n return deleted;\n }\n\n private getCollectionOrThrow(collection: string): Document[] {\n if (!this.engine.hasCollection(collection)) {\n throw new CollectionNotFoundError(collection);\n }\n return this.engine.getCollection(collection);\n }\n}\n","import type { Document, FilterQuery, FindOptions, SortOption } from \"../types.js\";\nimport { applyOperator, isOperatorObject } from \"./operators.js\";\n\nfunction matchesFilter(doc: Document, filter: FilterQuery): boolean {\n for (const [field, condition] of Object.entries(filter)) {\n const value = doc[field];\n\n if (isOperatorObject(condition)) {\n for (const [op, operand] of Object.entries(\n condition as Record<string, unknown>,\n )) {\n if (!applyOperator(op, value, operand)) return false;\n }\n } else {\n // Shorthand: { field: value } is equivalent to { field: { $eq: value } }\n if (value !== condition) return false;\n }\n }\n return true;\n}\n\nfunction sortDocuments(docs: Document[], sort: SortOption): Document[] {\n const entries = Object.entries(sort);\n return [...docs].sort((a, b) => {\n for (const [field, dir] of entries) {\n const av = a[field];\n const bv = b[field];\n if (av === bv) continue;\n if (av === undefined || av === null) return dir;\n if (bv === undefined || bv === null) return -dir;\n if (av < bv) return -dir;\n if (av > bv) return dir;\n }\n return 0;\n });\n}\n\nexport function applyFindOptions(\n docs: Document[],\n options: FindOptions,\n): Document[] {\n let result = docs;\n\n if (options.filter) {\n result = result.filter((doc) => matchesFilter(doc, options.filter!));\n }\n\n if (options.sort) {\n result = sortDocuments(result, options.sort);\n }\n\n if (options.offset) {\n result = result.slice(options.offset);\n }\n\n if (options.limit !== undefined) {\n result = result.slice(0, options.limit);\n }\n\n return result;\n}\n\nexport function countWithFilter(\n docs: Document[],\n filter?: FilterQuery,\n): number {\n if (!filter) return docs.length;\n return docs.filter((doc) => matchesFilter(doc, filter)).length;\n}\n\nexport { matchesFilter };\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport writeFileAtomic from \"write-file-atomic\";\nimport type { Document } from \"../../types.js\";\n\nexport class FileEngine {\n private dirPath: string;\n private data: Map<string, Document[]> = new Map();\n private dirty: Set<string> = new Set();\n private writeQueue: Promise<void> = Promise.resolve();\n\n constructor(dirPath: string) {\n this.dirPath = path.resolve(dirPath);\n }\n\n async load(): Promise<void> {\n if (!fs.existsSync(this.dirPath)) {\n fs.mkdirSync(this.dirPath, { recursive: true });\n }\n\n // Legacy migration: single seedorm.json → per-collection files\n const legacyPath = path.join(this.dirPath, \"seedorm.json\");\n if (fs.existsSync(legacyPath)) {\n const raw = fs.readFileSync(legacyPath, \"utf-8\");\n const legacy = JSON.parse(raw) as Record<string, Document[]>;\n for (const [collection, docs] of Object.entries(legacy)) {\n this.data.set(collection, docs);\n this.dirty.add(collection);\n }\n await this.flush();\n fs.unlinkSync(legacyPath);\n return;\n }\n\n // Read per-collection files\n const files = fs.readdirSync(this.dirPath).filter((f) => f.endsWith(\".json\"));\n for (const file of files) {\n const collection = file.slice(0, -5); // strip .json\n const raw = fs.readFileSync(path.join(this.dirPath, file), \"utf-8\");\n this.data.set(collection, JSON.parse(raw) as Document[]);\n }\n }\n\n getCollection(name: string): Document[] {\n if (!this.data.has(name)) {\n this.data.set(name, []);\n }\n return this.data.get(name)!;\n }\n\n hasCollection(name: string): boolean {\n return this.data.has(name);\n }\n\n createCollection(name: string): void {\n if (!this.data.has(name)) {\n this.data.set(name, []);\n this.dirty.add(name);\n }\n }\n\n dropCollection(name: string): void {\n this.data.delete(name);\n this.dirty.delete(name);\n const filePath = path.join(this.dirPath, `${name}.json`);\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n }\n\n listCollections(): string[] {\n return Array.from(this.data.keys());\n }\n\n markDirty(collection: string): void {\n this.dirty.add(collection);\n }\n\n async flush(): Promise<void> {\n const toWrite = new Set(this.dirty);\n this.dirty.clear();\n\n this.writeQueue = this.writeQueue.then(async () => {\n for (const collection of toWrite) {\n const docs = this.data.get(collection);\n if (docs === undefined) continue;\n await writeFileAtomic(\n path.join(this.dirPath, `${collection}.json`),\n JSON.stringify(docs),\n );\n }\n });\n return this.writeQueue;\n }\n\n async flushIfDirty(): Promise<void> {\n if (this.dirty.size > 0) {\n await this.flush();\n }\n }\n}\n","import type { Document } from \"../../types.js\";\nimport { UniqueConstraintError } from \"../../errors.js\";\n\ninterface FieldIndex {\n field: string;\n unique: boolean;\n map: Map<unknown, Set<string>>; // value → set of doc IDs\n}\n\nexport class Indexer {\n private indexes = new Map<string, Map<string, FieldIndex>>(); // collection → field → index\n\n setupIndex(\n collection: string,\n field: string,\n unique: boolean,\n docs: Document[],\n ): void {\n if (!this.indexes.has(collection)) {\n this.indexes.set(collection, new Map());\n }\n const colIndexes = this.indexes.get(collection)!;\n\n const idx: FieldIndex = { field, unique, map: new Map() };\n\n for (const doc of docs) {\n const val = doc[field];\n if (val === undefined || val === null) continue;\n if (!idx.map.has(val)) {\n idx.map.set(val, new Set());\n }\n idx.map.get(val)!.add(doc.id);\n }\n\n colIndexes.set(field, idx);\n }\n\n onInsert(collection: string, doc: Document): void {\n const colIndexes = this.indexes.get(collection);\n if (!colIndexes) return;\n\n for (const [, idx] of colIndexes) {\n const val = doc[idx.field];\n if (val === undefined || val === null) continue;\n\n if (idx.unique && idx.map.has(val) && idx.map.get(val)!.size > 0) {\n throw new UniqueConstraintError(collection, idx.field, val);\n }\n\n if (!idx.map.has(val)) {\n idx.map.set(val, new Set());\n }\n idx.map.get(val)!.add(doc.id);\n }\n }\n\n onUpdate(\n collection: string,\n oldDoc: Document,\n newDoc: Document,\n ): void {\n const colIndexes = this.indexes.get(collection);\n if (!colIndexes) return;\n\n for (const [, idx] of colIndexes) {\n const oldVal = oldDoc[idx.field];\n const newVal = newDoc[idx.field];\n\n if (oldVal === newVal) continue;\n\n // Remove old\n if (oldVal !== undefined && oldVal !== null) {\n idx.map.get(oldVal)?.delete(oldDoc.id);\n }\n\n // Add new\n if (newVal !== undefined && newVal !== null) {\n if (\n idx.unique &&\n idx.map.has(newVal) &&\n idx.map.get(newVal)!.size > 0\n ) {\n throw new UniqueConstraintError(collection, idx.field, newVal);\n }\n if (!idx.map.has(newVal)) {\n idx.map.set(newVal, new Set());\n }\n idx.map.get(newVal)!.add(newDoc.id);\n }\n }\n }\n\n onDelete(collection: string, doc: Document): void {\n const colIndexes = this.indexes.get(collection);\n if (!colIndexes) return;\n\n for (const [, idx] of colIndexes) {\n const val = doc[idx.field];\n if (val !== undefined && val !== null) {\n idx.map.get(val)?.delete(doc.id);\n }\n }\n }\n\n findByValue(\n collection: string,\n field: string,\n value: unknown,\n ): Set<string> | undefined {\n return this.indexes.get(collection)?.get(field)?.map.get(value);\n }\n\n dropCollection(collection: string): void {\n this.indexes.delete(collection);\n }\n}\n"],"mappings":"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","names":["FieldType","RelationType","AdapterType","writeFileAtomic","path","PostgresAdapter"]}
package/dist/index.d.cts CHANGED
@@ -207,7 +207,7 @@ declare class JsonAdapter implements StorageAdapter {
207
207
  private engine;
208
208
  private indexer;
209
209
  private schemas;
210
- constructor(filePath: string);
210
+ constructor(dirPath: string);
211
211
  connect(): Promise<void>;
212
212
  disconnect(): Promise<void>;
213
213
  createCollection(collection: string, schema: NormalizedSchema): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -207,7 +207,7 @@ declare class JsonAdapter implements StorageAdapter {
207
207
  private engine;
208
208
  private indexer;
209
209
  private schemas;
210
- constructor(filePath: string);
210
+ constructor(dirPath: string);
211
211
  connect(): Promise<void>;
212
212
  disconnect(): Promise<void>;
213
213
  createCollection(collection: string, schema: NormalizedSchema): Promise<void>;