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/README.md +56 -44
- package/dist/bin/seedorm.cjs +84 -55
- package/dist/bin/static/app.js +50 -2
- package/dist/bin/static/index.html +9 -1
- package/dist/bin/static/style.css +35 -0
- package/dist/index.cjs +63 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +63 -47
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
436
|
-
data =
|
|
440
|
+
dirPath;
|
|
441
|
+
data = /* @__PURE__ */ new Map();
|
|
442
|
+
dirty = /* @__PURE__ */ new Set();
|
|
437
443
|
writeQueue = Promise.resolve();
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
this.filePath = path.resolve(filePath);
|
|
444
|
+
constructor(dirPath) {
|
|
445
|
+
this.dirPath = path.resolve(dirPath);
|
|
441
446
|
}
|
|
442
447
|
async load() {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
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
|
|
460
|
-
this.data
|
|
471
|
+
if (!this.data.has(name)) {
|
|
472
|
+
this.data.set(name, []);
|
|
461
473
|
}
|
|
462
|
-
return this.data
|
|
474
|
+
return this.data.get(name);
|
|
463
475
|
}
|
|
464
476
|
hasCollection(name) {
|
|
465
|
-
return
|
|
477
|
+
return this.data.has(name);
|
|
466
478
|
}
|
|
467
479
|
createCollection(name) {
|
|
468
|
-
if (!this.data
|
|
469
|
-
this.data
|
|
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
|
-
|
|
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
|
|
494
|
+
return Array.from(this.data.keys());
|
|
477
495
|
}
|
|
478
|
-
markDirty() {
|
|
479
|
-
this.dirty
|
|
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
|
|
484
|
-
|
|
485
|
-
|
|
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(
|
|
582
|
-
this.engine = new FileEngine(
|
|
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
|
|
698
|
-
|
|
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"]}
|