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.js CHANGED
@@ -160,6 +160,11 @@ var Model = class {
160
160
  }
161
161
  async init() {
162
162
  await this.adapter.createCollection(this.collection, this.schema);
163
+ for (const rel of Object.values(this.relations)) {
164
+ if (rel.type === "manyToMany" /* ManyToMany */ && rel.joinCollection) {
165
+ await this.adapter.createCollection(rel.joinCollection, {});
166
+ }
167
+ }
163
168
  }
164
169
  generateId() {
165
170
  return `${this.prefix}_${nanoid(12)}`;
@@ -432,68 +437,82 @@ import * as fs from "fs";
432
437
  import * as path from "path";
433
438
  import writeFileAtomic from "write-file-atomic";
434
439
  var FileEngine = class {
435
- filePath;
436
- data = {};
440
+ dirPath;
441
+ data = /* @__PURE__ */ new Map();
442
+ dirty = /* @__PURE__ */ new Set();
437
443
  writeQueue = Promise.resolve();
438
- dirty = false;
439
- constructor(filePath) {
440
- this.filePath = path.resolve(filePath);
444
+ constructor(dirPath) {
445
+ this.dirPath = path.resolve(dirPath);
441
446
  }
442
447
  async load() {
443
- try {
444
- const raw = fs.readFileSync(this.filePath, "utf-8");
445
- this.data = JSON.parse(raw);
446
- } catch (err) {
447
- if (err.code === "ENOENT") {
448
- this.data = {};
449
- await this.flush();
450
- } else {
451
- throw err;
448
+ if (!fs.existsSync(this.dirPath)) {
449
+ fs.mkdirSync(this.dirPath, { recursive: true });
450
+ }
451
+ const legacyPath = path.join(this.dirPath, "seedorm.json");
452
+ if (fs.existsSync(legacyPath)) {
453
+ const raw = fs.readFileSync(legacyPath, "utf-8");
454
+ const legacy = JSON.parse(raw);
455
+ for (const [collection, docs] of Object.entries(legacy)) {
456
+ this.data.set(collection, docs);
457
+ this.dirty.add(collection);
452
458
  }
459
+ await this.flush();
460
+ fs.unlinkSync(legacyPath);
461
+ return;
462
+ }
463
+ const files = fs.readdirSync(this.dirPath).filter((f) => f.endsWith(".json"));
464
+ for (const file of files) {
465
+ const collection = file.slice(0, -5);
466
+ const raw = fs.readFileSync(path.join(this.dirPath, file), "utf-8");
467
+ this.data.set(collection, JSON.parse(raw));
453
468
  }
454
- }
455
- getData() {
456
- return this.data;
457
469
  }
458
470
  getCollection(name) {
459
- if (!this.data[name]) {
460
- this.data[name] = [];
471
+ if (!this.data.has(name)) {
472
+ this.data.set(name, []);
461
473
  }
462
- return this.data[name];
474
+ return this.data.get(name);
463
475
  }
464
476
  hasCollection(name) {
465
- return name in this.data;
477
+ return this.data.has(name);
466
478
  }
467
479
  createCollection(name) {
468
- if (!this.data[name]) {
469
- this.data[name] = [];
480
+ if (!this.data.has(name)) {
481
+ this.data.set(name, []);
482
+ this.dirty.add(name);
470
483
  }
471
484
  }
472
485
  dropCollection(name) {
473
- delete this.data[name];
486
+ this.data.delete(name);
487
+ this.dirty.delete(name);
488
+ const filePath = path.join(this.dirPath, `${name}.json`);
489
+ if (fs.existsSync(filePath)) {
490
+ fs.unlinkSync(filePath);
491
+ }
474
492
  }
475
493
  listCollections() {
476
- return Object.keys(this.data);
494
+ return Array.from(this.data.keys());
477
495
  }
478
- markDirty() {
479
- this.dirty = true;
496
+ markDirty(collection) {
497
+ this.dirty.add(collection);
480
498
  }
481
499
  async flush() {
500
+ const toWrite = new Set(this.dirty);
501
+ this.dirty.clear();
482
502
  this.writeQueue = this.writeQueue.then(async () => {
483
- const dir = path.dirname(this.filePath);
484
- if (!fs.existsSync(dir)) {
485
- fs.mkdirSync(dir, { recursive: true });
503
+ for (const collection of toWrite) {
504
+ const docs = this.data.get(collection);
505
+ if (docs === void 0) continue;
506
+ await writeFileAtomic(
507
+ path.join(this.dirPath, `${collection}.json`),
508
+ JSON.stringify(docs)
509
+ );
486
510
  }
487
- await writeFileAtomic(
488
- this.filePath,
489
- JSON.stringify(this.data, null, 2) + "\n"
490
- );
491
- this.dirty = false;
492
511
  });
493
512
  return this.writeQueue;
494
513
  }
495
514
  async flushIfDirty() {
496
- if (this.dirty) {
515
+ if (this.dirty.size > 0) {
497
516
  await this.flush();
498
517
  }
499
518
  }
@@ -578,8 +597,8 @@ var JsonAdapter = class {
578
597
  engine;
579
598
  indexer = new Indexer();
580
599
  schemas = /* @__PURE__ */ new Map();
581
- constructor(filePath) {
582
- this.engine = new FileEngine(filePath);
600
+ constructor(dirPath) {
601
+ this.engine = new FileEngine(dirPath);
583
602
  }
584
603
  async connect() {
585
604
  await this.engine.load();
@@ -615,7 +634,7 @@ var JsonAdapter = class {
615
634
  const docs = this.getCollectionOrThrow(collection);
616
635
  this.indexer.onInsert(collection, doc);
617
636
  docs.push(doc);
618
- this.engine.markDirty();
637
+ this.engine.markDirty(collection);
619
638
  await this.engine.flush();
620
639
  return doc;
621
640
  }
@@ -639,7 +658,7 @@ var JsonAdapter = class {
639
658
  const newDoc = { ...oldDoc, ...data, id: oldDoc.id };
640
659
  this.indexer.onUpdate(collection, oldDoc, newDoc);
641
660
  docs[index] = newDoc;
642
- this.engine.markDirty();
661
+ this.engine.markDirty(collection);
643
662
  await this.engine.flush();
644
663
  return newDoc;
645
664
  }
@@ -649,7 +668,7 @@ var JsonAdapter = class {
649
668
  if (index === -1) return false;
650
669
  this.indexer.onDelete(collection, docs[index]);
651
670
  docs.splice(index, 1);
652
- this.engine.markDirty();
671
+ this.engine.markDirty(collection);
653
672
  await this.engine.flush();
654
673
  return true;
655
674
  }
@@ -665,7 +684,7 @@ var JsonAdapter = class {
665
684
  docs.length = 0;
666
685
  docs.push(...remaining);
667
686
  if (deleted > 0) {
668
- this.engine.markDirty();
687
+ this.engine.markDirty(collection);
669
688
  await this.engine.flush();
670
689
  }
671
690
  return deleted;
@@ -694,11 +713,8 @@ var SeedORM = class {
694
713
  async createAdapter(adapterConfig) {
695
714
  switch (adapterConfig.adapter) {
696
715
  case "json" /* Json */: {
697
- const dbPath = path2.resolve(
698
- adapterConfig.path ?? "./data",
699
- "seedorm.json"
700
- );
701
- return new JsonAdapter(dbPath);
716
+ const dirPath = path2.resolve(adapterConfig.path ?? "./data");
717
+ return new JsonAdapter(dirPath);
702
718
  }
703
719
  case "postgres" /* Postgres */: {
704
720
  const { PostgresAdapter: PostgresAdapter2 } = await import("./postgres-adapter-W2G6VHMX.js");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/model/model.ts","../src/model/field-types.ts","../src/model/schema.ts","../src/query/filter.ts","../src/adapters/json/file-engine.ts","../src/adapters/json/indexer.ts","../src/adapters/json/json-adapter.ts","../src/seedorm.ts"],"sourcesContent":["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 { 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 {\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 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","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 {\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"],"mappings":"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","names":["path","PostgresAdapter"]}
1
+ {"version":3,"sources":["../src/model/model.ts","../src/model/field-types.ts","../src/model/schema.ts","../src/query/filter.ts","../src/adapters/json/file-engine.ts","../src/adapters/json/indexer.ts","../src/adapters/json/json-adapter.ts","../src/seedorm.ts"],"sourcesContent":["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 { 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 {\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 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","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 {\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"],"mappings":"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","names":["path","PostgresAdapter"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "seedorm",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Development-first ORM — start with JSON, migrate to PostgreSQL/MySQL",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",