peta-orm 0.4.0 → 0.5.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.d.mts CHANGED
@@ -1,6 +1,493 @@
1
- import { A as PaginatorJson, C as InsertGraphOptions, D as RelationType, E as RelationOptions, M as Database, O as PaginatedResult, S as QueryBuilder, T as Relation, _ as createColumn, a as ModelDefinition, b as Plugin, c as HookCallback, d as createHookManager, f as ModelId, g as ColumnValue, h as ColumnShape, i as ModelConfig, j as createPaginator, k as Paginator, l as HookManager, m as Column, n as Collection, o as ModelInstance, p as ORMLike, r as createCollection, s as Attribute, t as defineModel, u as LifecycleEvent, v as Constraint, w as UpsertGraphOptions, x as createQueryBuilder, y as SchemaConfig } from "./index-BdJnSMYi.mjs";
2
- import { Dialect } from "kysely";
1
+ import { Dialect, Kysely } from "kysely";
3
2
 
3
+ //#region src/columns/schema.d.ts
4
+ interface Constraint {
5
+ type: string;
6
+ args: unknown[];
7
+ }
8
+ interface SchemaConfig {
9
+ compile(dataType: string, args: unknown[], constraints: Constraint[]): unknown;
10
+ parse<T>(schema: unknown, value: unknown): T;
11
+ assert<T>(schema: unknown, value: unknown): T;
12
+ }
13
+ //#endregion
14
+ //#region src/columns/column.d.ts
15
+ interface Column<out T = unknown> {
16
+ readonly arkType: unknown;
17
+ readonly dataType: string;
18
+ readonly args: readonly unknown[];
19
+ readonly constraints: readonly Constraint[];
20
+ readonly isNullable: boolean;
21
+ readonly isPrimaryKey: boolean;
22
+ readonly isUnique: boolean;
23
+ readonly defaultValue: unknown;
24
+ hasConstraint(type: string): boolean;
25
+ parse(value: unknown): T;
26
+ assert(value: unknown): T;
27
+ primaryKey(): Column<T>;
28
+ nullable(): Column<T | null>;
29
+ default<V>(value: V): Column<T>;
30
+ unique(): Column<T>;
31
+ index(): Column<T>;
32
+ min(n: number): Column<T>;
33
+ max(n: number): Column<T>;
34
+ email(): Column<T>;
35
+ url(): Column<T>;
36
+ pattern(regex: RegExp | string): Column<T>;
37
+ references(table: () => unknown, columns: string[]): Column<T>;
38
+ }
39
+ declare function createColumn<T>(schema: SchemaConfig, dataType: string, args?: unknown[], constraints?: Constraint[]): Column<T>;
40
+ type ColumnShape = Record<string, Column>;
41
+ type ColumnValue<C> = C extends Column<infer T> ? T : never;
42
+ //#endregion
43
+ //#region src/lib/kysely.d.ts
44
+ type Database = Kysely<Record<string, never>>;
45
+ //#endregion
46
+ //#region src/pagination/index.d.ts
47
+ interface Paginator<TColumns extends ColumnShape = ColumnShape> {
48
+ readonly data: Collection<TColumns>;
49
+ readonly total: number;
50
+ readonly perPage: number;
51
+ readonly currentPage: number;
52
+ readonly lastPage: number;
53
+ readonly hasMorePages: boolean;
54
+ readonly hasPages: boolean;
55
+ readonly firstItem: number;
56
+ readonly lastItem: number;
57
+ readonly onFirstPage: boolean;
58
+ readonly onLastPage: boolean;
59
+ readonly count: number;
60
+ map<T>(fn: (item: ModelInstance<TColumns>) => T): T[];
61
+ toJSON(): PaginatorJson<TColumns>;
62
+ }
63
+ interface PaginatorJson<TColumns extends ColumnShape = ColumnShape> {
64
+ data: SerializedShape<TColumns>[];
65
+ total: number;
66
+ perPage: number;
67
+ currentPage: number;
68
+ lastPage: number;
69
+ hasMorePages: boolean;
70
+ hasPages: boolean;
71
+ firstItem: number | null;
72
+ lastItem: number | null;
73
+ onFirstPage: boolean;
74
+ onLastPage: boolean;
75
+ }
76
+ type PaginatedResult = PaginatorJson;
77
+ declare function createPaginator<TColumns extends ColumnShape = ColumnShape>(items: ModelInstance<TColumns>[], total: number, perPage: number, currentPage: number): Paginator<TColumns>;
78
+ //#endregion
79
+ //#region src/relations/base.d.ts
80
+ type RelationType = "hasMany" | "belongsTo" | "hasOne" | "manyToMany" | "hasManyThrough";
81
+ interface RelationOptions {
82
+ foreignKey?: string;
83
+ localKey?: string;
84
+ through?: string;
85
+ foreignPivotKey?: string;
86
+ relatedPivotKey?: string;
87
+ throughForeignKey?: string;
88
+ throughLocalKey?: string;
89
+ pivotExtras?: string[];
90
+ }
91
+ interface Relation {
92
+ readonly type: RelationType;
93
+ readonly relatedModelClass: ModelDefinition;
94
+ readonly foreignKey: string;
95
+ readonly localKey: string;
96
+ readonly throughTable?: string;
97
+ readonly foreignPivotKey?: string;
98
+ readonly relatedPivotKey?: string;
99
+ readonly throughForeignKey?: string;
100
+ readonly throughLocalKey?: string;
101
+ _morphMap?: Record<string, () => ModelDefinition>;
102
+ _morphType?: string;
103
+ _morphId?: string;
104
+ _morphTypeValue?: string;
105
+ query(parent: ModelInstance): QueryBuilder;
106
+ addEagerConstraints(query: QueryBuilder, models: ModelInstance[]): void;
107
+ match(models: ModelInstance[], results: ModelInstance[], relationName: string): void;
108
+ getResults(parent: ModelInstance): Promise<ModelInstance | ModelInstance[] | null>;
109
+ loadEager(models: ModelInstance[], relationName: string, constraints?: ((qb: QueryBuilder) => void) | null): Promise<void>;
110
+ }
111
+ //#endregion
112
+ //#region src/relations/graph/types.d.ts
113
+ interface InsertGraphOptions {
114
+ /** Allow `#id` / `#ref` special properties in the graph */
115
+ allowRefs?: boolean;
116
+ /**
117
+ * If `true`, objects with an `id` property get related (pivot row / FK set)
118
+ * instead of inserted. Can be an array of relation names to scope.
119
+ */
120
+ relate?: boolean | string[];
121
+ /**
122
+ * Whitelist of relation paths allowed for this graph operation.
123
+ * Accepts an array of dotted paths or a Set. If not set, all relations are allowed.
124
+ * When used via the query builder, the QB's `allowGraph()` set is forwarded automatically.
125
+ */
126
+ allowGraph?: string[] | Set<string>;
127
+ }
128
+ interface UpsertGraphOptions extends InsertGraphOptions {
129
+ /** Unrelate (set FK null / remove pivot) instead of deleting missing items */
130
+ unrelate?: boolean | string[];
131
+ /** Prevent deletion for all or specific relation paths */
132
+ noDelete?: boolean | string[];
133
+ /** Prevent insertion for all or specific relation paths */
134
+ noInsert?: boolean | string[];
135
+ /** Prevent update for all or specific relation paths */
136
+ noUpdate?: boolean | string[];
137
+ }
138
+ //#endregion
139
+ //#region src/query/types.d.ts
140
+ interface QueryBuilder<TColumns extends ColumnShape = ColumnShape> extends PromiseLike<ModelInstance<TColumns>[]> {
141
+ execute(): Promise<ModelInstance<TColumns>[]>;
142
+ collect(): Promise<Collection<TColumns>>;
143
+ executeTakeFirst(): Promise<ModelInstance<TColumns> | undefined>;
144
+ executeTakeFirstOrThrow(): Promise<ModelInstance<TColumns>>;
145
+ find(id: number | string): Promise<ModelInstance<TColumns> | undefined>;
146
+ findOrFail(id: number | string): Promise<ModelInstance<TColumns>>;
147
+ first(): Promise<ModelInstance<TColumns> | undefined>;
148
+ toSQL(): {
149
+ sql: string;
150
+ parameters: readonly unknown[];
151
+ };
152
+ count(): Promise<number>;
153
+ sum(column: string): Promise<number>;
154
+ avg(column: string): Promise<number>;
155
+ min(column: string): Promise<number>;
156
+ max(column: string): Promise<number>;
157
+ withCount(relation: string): QueryBuilder<TColumns>;
158
+ withSum(relation: string, column: string): QueryBuilder<TColumns>;
159
+ withAvg(relation: string, column: string): QueryBuilder<TColumns>;
160
+ withMin(relation: string, column: string): QueryBuilder<TColumns>;
161
+ withMax(relation: string, column: string): QueryBuilder<TColumns>;
162
+ withExists(relation: string): QueryBuilder<TColumns>;
163
+ chunk(size: number, callback: (chunk: ModelInstance<TColumns>[]) => Promise<void>): Promise<void>;
164
+ paginate(page: number, perPage?: number): Promise<Paginator<TColumns>>;
165
+ insertGraph(data: Record<string, unknown> | Record<string, unknown>[], options?: InsertGraphOptions): Promise<any>;
166
+ upsertGraph(data: Record<string, unknown> | Record<string, unknown>[], options?: UpsertGraphOptions): Promise<any>;
167
+ with(...relations: (string | Record<string, (qb: QueryBuilder<TColumns>) => void>)[]): QueryBuilder<TColumns>;
168
+ /**
169
+ * Whitelist allowed relations (and nested paths) for eager loading.
170
+ * Throws if a relation path is not in the allow list.
171
+ *
172
+ * Supports dotted paths for granular control:
173
+ * - `allowGraph("posts")` allows `posts`, `posts.author`, `posts.author.profile`, etc.
174
+ * - `allowGraph("posts.author")` allows `posts.author` and `posts.author.profile`,
175
+ * but NOT bare `posts` or `posts.comments`.
176
+ *
177
+ * Multiple arguments are merged: `allowGraph("posts", "profile")`
178
+ */
179
+ allowGraph(...expressions: string[]): QueryBuilder<TColumns>;
180
+ updateMany(data: Record<string, unknown>): Promise<number>;
181
+ deleteMany(): Promise<number>;
182
+ withTrashed(): QueryBuilder<TColumns>;
183
+ onlyTrashed(): QueryBuilder<TColumns>;
184
+ whereIn(column: string, values: unknown[]): QueryBuilder<TColumns>;
185
+ whereInPivot(column: string, values: unknown[]): QueryBuilder<TColumns>;
186
+ has(relationName: string): QueryBuilder<TColumns>;
187
+ whereHas(relationName: string, callback?: (qb: QueryBuilder<TColumns>) => void): QueryBuilder<TColumns>;
188
+ whereDoesntHave(relationName: string, callback?: (qb: QueryBuilder<TColumns>) => void): QueryBuilder<TColumns>;
189
+ where(column: string, operator: unknown, value?: unknown): QueryBuilder<TColumns>;
190
+ whereRef(col1: string, operator: string, col2: string): QueryBuilder<TColumns>;
191
+ orWhere(column: string, operator: unknown, value?: unknown): QueryBuilder<TColumns>;
192
+ orderBy(column: string, direction?: "asc" | "desc"): QueryBuilder<TColumns>;
193
+ limit(n: number): QueryBuilder<TColumns>;
194
+ offset(n: number): QueryBuilder<TColumns>;
195
+ select(...columns: string[]): QueryBuilder<TColumns>;
196
+ selectAll(table?: string): QueryBuilder<TColumns>;
197
+ innerJoin(table: string, lhs: string, rhs: string): QueryBuilder<TColumns>;
198
+ leftJoin(table: string, lhs: string, rhs: string): QueryBuilder<TColumns>;
199
+ groupBy(...columns: string[]): QueryBuilder<TColumns>;
200
+ having(column: string, operator: string, value: unknown): QueryBuilder<TColumns>;
201
+ withoutGlobalScope(name: string): QueryBuilder<TColumns>;
202
+ all(): QueryBuilder<TColumns>;
203
+ /** @internal Access underlying Kysely builder for raw SQL operations */
204
+ _getKyselyQb(): any;
205
+ /** @internal Replace the underlying Kysely builder */
206
+ _replaceKyselyQb(newQb: any): void;
207
+ when(condition: unknown, callback: (q: QueryBuilder<TColumns>) => QueryBuilder<TColumns>): QueryBuilder<TColumns>;
208
+ unless(condition: unknown, callback: (q: QueryBuilder<TColumns>) => QueryBuilder<TColumns>): QueryBuilder<TColumns>;
209
+ }
210
+ //#endregion
211
+ //#region src/query/builder.d.ts
212
+ declare function createQueryBuilder<TColumns extends ColumnShape = ColumnShape>(def: ModelDefinition<TColumns>, peta?: {
213
+ kysely: Database;
214
+ }): QueryBuilder<TColumns>;
215
+ //#endregion
216
+ //#region src/relations/related-query.d.ts
217
+ interface RelationQuery extends QueryBuilder {
218
+ /** Attach related model(s) for many-to-many relations. */
219
+ attach(ids: number | number[] | string | string[], pivotData?: Record<string, unknown>): Promise<void>;
220
+ /** Detach related model(s) for many-to-many relations. */
221
+ detach(ids?: number | number[] | string | string[]): Promise<void>;
222
+ /** Sync related models: attaches new IDs, detaches missing ones. */
223
+ sync(ids: (number | string)[] | Record<number | string, Record<string, unknown>>): Promise<void>;
224
+ /** Sync without detaching existing IDs. */
225
+ syncWithoutDetaching(ids: (number | string)[]): Promise<void>;
226
+ /** Update pivot data for a specific related model. */
227
+ updateExistingPivot(id: number | string, data: Record<string, unknown>): Promise<void>;
228
+ }
229
+ //#endregion
230
+ //#region src/plugins/index.d.ts
231
+ /**
232
+ * A plugin is a function that receives a model definition and can
233
+ * modify it by adding hooks, scopes, columns, or methods.
234
+ *
235
+ * ```ts
236
+ * const myPlugin = (options?: MyOptions): Plugin =>
237
+ * (def) => {
238
+ * def.addGlobalScope?.('active', (q) => q.where('active', true))
239
+ * return def
240
+ * }
241
+ * ```
242
+ */
243
+ type Plugin = (def: ModelDefinition) => undefined | ModelDefinition;
244
+ //#endregion
245
+ //#region src/types.d.ts
246
+ type ModelId = number & {
247
+ readonly __brand: "ModelId";
248
+ };
249
+ interface ModelLike<TColumns extends ColumnShape = ColumnShape> {
250
+ get<K extends keyof TColumns>(key: K): ColumnValue<TColumns[K]>;
251
+ get(key: string): unknown;
252
+ set(key: string, value: unknown): void;
253
+ }
254
+ interface ORMLike {
255
+ readonly kysely: Database;
256
+ register(model: ModelDefinition$1<any>): void;
257
+ registerAll(...models: (ModelDefinition$1<any> | ModelDefinition$1<any>[])[]): void;
258
+ destroy(): Promise<void>;
259
+ transaction<T>(fn: (trx: import("kysely").Kysely<Record<string, never>>) => Promise<T>): Promise<T>;
260
+ readonly models: ReadonlyMap<string, ModelDefinition$1<any>>;
261
+ getModel<T extends ColumnShape = ColumnShape>(name: string): ModelDefinition$1<T> | undefined;
262
+ /**
263
+ * Discover model definitions by scanning files matching a glob pattern.
264
+ *
265
+ * Uses `fast-glob` to resolve the pattern relative to `cwd`, then dynamically
266
+ * imports each matching file and collects exported `ModelDefinition` values.
267
+ * Does **not** auto-register — use `registerAll(...result)` to register them.
268
+ *
269
+ * @param pattern Glob pattern (e.g. `"./src/models/**\/*.ts"`)
270
+ * @returns Array of discovered model definitions
271
+ */
272
+ discover(pattern: string): Promise<ModelDefinition$1<any>[]>;
273
+ }
274
+ interface ModelDefinition$1<TColumns extends ColumnShape = ColumnShape> {
275
+ readonly table: string;
276
+ readonly columns: TColumns;
277
+ readonly relations: Record<string, Relation>;
278
+ readonly name: string;
279
+ _orm: ORMLike | null;
280
+ query(): QueryBuilder<TColumns>;
281
+ find(id: number | string): Promise<ModelInstance<TColumns> | undefined>;
282
+ findOrFail(id: number | string): Promise<ModelInstance<TColumns>>;
283
+ first(): Promise<ModelInstance<TColumns> | undefined>;
284
+ create(data: Record<string, unknown>): Promise<ModelInstance<TColumns>>;
285
+ insert(data: Record<string, unknown>): Promise<ModelInstance<TColumns>>;
286
+ insertMany(dataArray: Record<string, unknown>[]): Promise<ModelInstance<TColumns>[]>;
287
+ update(id: number | string, data: Record<string, unknown>): Promise<ModelInstance<TColumns>>;
288
+ delete(id: number | string): Promise<void>;
289
+ hydrate(row: Record<string, unknown>): ModelInstance<TColumns>;
290
+ on(event: string, callback: (model: ModelInstance<TColumns>) => void | Promise<void>): () => void;
291
+ getHooks(): HookManager;
292
+ addGlobalScope(name: string, callback: (qb: QueryBuilder) => void): void;
293
+ removeGlobalScope(name: string): void;
294
+ getGlobalScopes(): Map<string, (qb: QueryBuilder) => void> | undefined;
295
+ _init(orm: ORMLike): void;
296
+ }
297
+ //#endregion
298
+ //#region src/hooks/index.d.ts
299
+ type LifecycleEvent = "beforeCreate" | "afterCreate" | "beforeUpdate" | "afterUpdate" | "beforeSave" | "afterSave" | "beforeDelete" | "afterDelete" | "beforeRestore" | "afterRestore" | "beforeForceDelete" | "afterForceDelete";
300
+ type HookCallback = (model: ModelLike) => void | Promise<void>;
301
+ interface HookManager {
302
+ on(event: LifecycleEvent, callback: HookCallback): () => void;
303
+ off(event: LifecycleEvent, callback: HookCallback): void;
304
+ trigger(event: LifecycleEvent, model: ModelLike): Promise<void>;
305
+ clone(): HookManager;
306
+ }
307
+ declare function createHookManager(): HookManager;
308
+ //#endregion
309
+ //#region src/hooks/static.d.ts
310
+ interface StaticHookArgs {
311
+ /** Transform the mutating query into a SELECT to preview affected rows */
312
+ asFindQuery(): QueryBuilder;
313
+ /** Cancel the mutation and return a custom result */
314
+ cancelQuery(result: unknown): void;
315
+ /** The column data being inserted/updated (for create/update hooks) */
316
+ inputItems?: Record<string, unknown>[];
317
+ }
318
+ type StaticHookCallback = (args: StaticHookArgs) => void | Promise<void>;
319
+ //#endregion
320
+ //#region src/model/computed.d.ts
321
+ interface ComputedColumn<T = unknown> {
322
+ readonly type: "sql" | "runtime" | "batch";
323
+ readonly dependencies: string[];
324
+ /** Compute a value for a single record (runtime) */
325
+ compute?: (record: ModelInstance) => T;
326
+ /** Compute values for a batch of records (batch async) */
327
+ batchCompute?: (records: ModelInstance[]) => Promise<T[]>;
328
+ /** Raw SQL expression to inline in SELECT */
329
+ sql?: string;
330
+ }
331
+ //#endregion
332
+ //#region src/model/attribute.d.ts
333
+ /**
334
+ * Defines an accessor (`get`) and/or mutator (`set`) for a model attribute.
335
+ *
336
+ * ### Accessor (get)
337
+ * Transforms the attribute value when read via `model.get()` or `model.$toJSON()`.
338
+ * Receives the casted value and the model instance.
339
+ *
340
+ * ### Mutator (set)
341
+ * Transforms the attribute value when written via `model.set()`, `model.fill()`,
342
+ * or during model creation (`Model.insert()` / `Model.create()`).
343
+ * Receives the raw input value and the model instance, returns the value to store.
344
+ * Applied **before** type casting.
345
+ *
346
+ * ### Usage
347
+ * ```ts
348
+ * defineModel('users', {
349
+ * columns: { id, name, password, ... },
350
+ * attributes: {
351
+ * password: Attribute.make({
352
+ * set: (value) => Bun.password.hashSync(value, { algorithm: 'bcrypt' }),
353
+ * get: () => '***',
354
+ * }),
355
+ * fullName: Attribute.make({
356
+ * get: (_, instance) => `${instance.get('firstName')} ${instance.get('lastName')}`,
357
+ * }),
358
+ * },
359
+ * })
360
+ * ```
361
+ */
362
+ declare class Attribute<T = any> {
363
+ readonly get?: ((value: T, instance: ModelInstance) => any) | undefined;
364
+ readonly set?: ((value: any, instance: ModelInstance) => T) | undefined;
365
+ private constructor();
366
+ static make<T = any>(config: {
367
+ /** Transform the attribute value when read. Receives (castedValue, instance). */get?: (value: T, instance: ModelInstance) => any; /** Transform the attribute value when written. Receives (rawValue, instance), returns value to store. */
368
+ set?: (value: any, instance: ModelInstance) => T;
369
+ }): Attribute<T>;
370
+ }
371
+ //#endregion
372
+ //#region src/model/types.d.ts
373
+ /** Mapped column shape — resolves each column to its JS value type for $toJSON(). */
374
+ type SerializedShape<TColumns extends ColumnShape> = { [K in keyof TColumns]: TColumns[K] extends Column<infer T> ? T : unknown } & Record<string, unknown>;
375
+ interface ModelInstance<TColumns extends ColumnShape = ColumnShape> {
376
+ readonly exists: boolean;
377
+ readonly attributes: Record<string, unknown>;
378
+ readonly dirtyAttributes: Record<string, unknown>;
379
+ isDirty(key?: string): boolean;
380
+ get<K extends keyof TColumns>(key: K): ColumnValue<TColumns[K]>;
381
+ get(key: string): unknown;
382
+ set(key: string, value: unknown): void;
383
+ fill(data: Record<string, unknown>): void;
384
+ reset(): void;
385
+ $getRelation<T = unknown>(name: string): T;
386
+ $setRelation(name: string, value: unknown): void;
387
+ $hasRelation(name: string): boolean;
388
+ $relationData(): Record<string, unknown>;
389
+ $load(...relations: string[]): Promise<void>;
390
+ $related(name: string): RelationQuery;
391
+ $save(): Promise<this>;
392
+ $delete(): Promise<void>;
393
+ $forceDelete(): Promise<void>;
394
+ $restore(): Promise<void>;
395
+ $trashed(): boolean;
396
+ $reload(): Promise<void>;
397
+ $toJSON(): SerializedShape<TColumns>;
398
+ toJSON(): SerializedShape<TColumns>;
399
+ }
400
+ interface ModelDefinition<TColumns extends ColumnShape = ColumnShape> {
401
+ readonly table: string;
402
+ readonly columns: TColumns;
403
+ readonly relations: Record<string, Relation>;
404
+ readonly name: string;
405
+ _orm: ORMLike | null;
406
+ query(): QueryBuilder<TColumns>;
407
+ find(id: number | string): Promise<ModelInstance<TColumns> | undefined>;
408
+ findOrFail(id: number | string): Promise<ModelInstance<TColumns>>;
409
+ first(): Promise<ModelInstance<TColumns> | undefined>;
410
+ create(data: Record<string, unknown>): Promise<ModelInstance<TColumns>>;
411
+ insert(data: Record<string, unknown>): Promise<ModelInstance<TColumns>>;
412
+ insertMany(dataArray: Record<string, unknown>[]): Promise<ModelInstance<TColumns>[]>;
413
+ update(id: number | string, data: Record<string, unknown>): Promise<ModelInstance<TColumns>>;
414
+ delete(id: number | string): Promise<void>;
415
+ insertGraph(data: Record<string, unknown> | Record<string, unknown>[], options?: InsertGraphOptions): Promise<any>;
416
+ upsertGraph(data: Record<string, unknown> | Record<string, unknown>[], options?: UpsertGraphOptions): Promise<any>;
417
+ hydrate(row: Record<string, unknown>): ModelInstance<TColumns>;
418
+ use(plugin: Plugin): ModelDefinition<TColumns>;
419
+ makeHelper<A extends any[], R>(fn: (qb: QueryBuilder, ...args: A) => R): (...args: A) => R;
420
+ on(event: string, callback: (model: ModelInstance<TColumns>) => void | Promise<void>): () => void;
421
+ getHooks(): HookManager;
422
+ beforeDelete(callback: StaticHookCallback): () => void;
423
+ afterDelete(callback: StaticHookCallback): () => void;
424
+ beforeUpdate(callback: StaticHookCallback): () => void;
425
+ afterUpdate(callback: StaticHookCallback): () => void;
426
+ beforeCreate(callback: StaticHookCallback): () => void;
427
+ afterCreate(callback: StaticHookCallback): () => void;
428
+ beforeFind(callback: StaticHookCallback): () => void;
429
+ afterFind(callback: StaticHookCallback): () => void;
430
+ addGlobalScope(name: string, callback: (qb: QueryBuilder) => void): void;
431
+ removeGlobalScope(name: string): void;
432
+ getGlobalScopes(): Map<string, (qb: QueryBuilder) => void> | undefined;
433
+ registerTimestamps?(createdAtCol?: string, updatedAtCol?: string): void;
434
+ registerSoftDeletes?(deletedAtCol?: string): void;
435
+ _init(orm: ORMLike): void;
436
+ }
437
+ interface ModelConfig<TColumns extends ColumnShape = ColumnShape> {
438
+ columns: TColumns;
439
+ relations?: Record<string, Relation>;
440
+ casts?: Record<string, string>;
441
+ /** Per-attribute accessors (`get`) and/or mutators (`set`). See {@link Attribute.make}. */
442
+ attributes?: Record<string, Attribute<any>>;
443
+ hidden?: string[];
444
+ visible?: string[];
445
+ appends?: string[];
446
+ computed?: Record<string, ComputedColumn>;
447
+ }
448
+ //#endregion
449
+ //#region src/collection/index.d.ts
450
+ interface Collection<TColumns extends ColumnShape = ColumnShape> {
451
+ readonly length: number;
452
+ [Symbol.iterator](): Iterator<ModelInstance<TColumns>>;
453
+ at(index: number): ModelInstance<TColumns> | undefined;
454
+ first(): ModelInstance<TColumns> | undefined;
455
+ last(): ModelInstance<TColumns> | undefined;
456
+ all(): ModelInstance<TColumns>[];
457
+ findBy(id: number | string): ModelInstance<TColumns> | undefined;
458
+ find(callback: (item: ModelInstance<TColumns>, index: number) => boolean): ModelInstance<TColumns> | undefined;
459
+ some(callback: (item: ModelInstance<TColumns>, index: number) => boolean): boolean;
460
+ includes(item: ModelInstance<TColumns>): boolean;
461
+ isEmpty(): boolean;
462
+ isNotEmpty(): boolean;
463
+ get(key: string): unknown[];
464
+ pluck(key: string): unknown[];
465
+ groupBy(key: string): Record<string, ModelInstance<TColumns>[]>;
466
+ keyBy(key: string): Record<string, ModelInstance<TColumns>>;
467
+ map<T>(fn: (item: ModelInstance<TColumns>, index: number) => T): T[];
468
+ filter(fn: (item: ModelInstance<TColumns>, index: number) => boolean): Collection<TColumns>;
469
+ reduce<T>(fn: (acc: T, item: ModelInstance<TColumns>, index: number) => T, initial: T): T;
470
+ forEach(fn: (item: ModelInstance<TColumns>, index: number) => void): void;
471
+ each(fn: (item: ModelInstance<TColumns>, index: number) => void): Collection<TColumns>;
472
+ unique(key?: string): Collection<TColumns>;
473
+ sortBy(key: string, direction?: "asc" | "desc"): Collection<TColumns>;
474
+ shuffle(): Collection<TColumns>;
475
+ take(n: number): Collection<TColumns>;
476
+ skip(n: number): Collection<TColumns>;
477
+ chunk(size: number): Collection<TColumns>[];
478
+ sum(key: string): number;
479
+ avg(key: string): number;
480
+ min(key: string): number;
481
+ max(key: string): number;
482
+ diff(other: Collection<TColumns>): Collection<TColumns>;
483
+ intersect(other: Collection<TColumns>): Collection<TColumns>;
484
+ concat(other: Collection<TColumns>): Collection<TColumns>;
485
+ push(...items: ModelInstance<TColumns>[]): void;
486
+ load(...relations: string[]): Promise<Collection<TColumns>>;
487
+ toJSON(): SerializedShape<TColumns>[];
488
+ }
489
+ declare function createCollection<TColumns extends ColumnShape = ColumnShape>(items?: ModelInstance<TColumns>[]): Collection<TColumns>;
490
+ //#endregion
4
491
  //#region src/columns/arktype.d.ts
5
492
  declare function createArkTypeSchemaConfig(): SchemaConfig;
6
493
  //#endregion
@@ -26,7 +513,27 @@ interface ColumnTypes {
26
513
  updatedAt: Column<string>;
27
514
  };
28
515
  }
29
- declare function t(config: {
516
+ /**
517
+ * Pre-configured column type factory backed by ArkType validation.
518
+ *
519
+ * The most common usage — just import and use:
520
+ * ```ts
521
+ * import { t } from "peta-orm"
522
+ * const id = t.integer().primaryKey()
523
+ * ```
524
+ *
525
+ * For a custom validation backend, use `createColumnTypes({ schema })` instead.
526
+ */
527
+ declare const t: ColumnTypes;
528
+ /**
529
+ * Create a column type factory with a custom validation schema backend.
530
+ *
531
+ * @example
532
+ * ```ts
533
+ * const t = createColumnTypes({ schema: myCustomSchemaConfig })
534
+ * ```
535
+ */
536
+ declare function createColumnTypes(config: {
30
537
  schema: SchemaConfig;
31
538
  }): ColumnTypes;
32
539
  //#endregion
@@ -63,14 +570,56 @@ declare class DatabaseError extends Error {
63
570
  //#region src/errors/normalizer.d.ts
64
571
  declare function normalizeError(e: unknown, table?: string): DatabaseError;
65
572
  //#endregion
573
+ //#region src/init.d.ts
574
+ /**
575
+ * Create a lazy-initialized singleton factory.
576
+ *
577
+ * The factory function is called only once — on the first call to the returned
578
+ * function. Subsequent calls return the same resolved promise. This avoids
579
+ * module-level side effects: importing a model file won't trigger database
580
+ * connection or schema initialization until the first explicit `await db()`.
581
+ *
582
+ * @example
583
+ * ```ts
584
+ * import { createClient } from "@libsql/client"
585
+ * import { LibsqlDialect } from "@libsql/kysely-libsql"
586
+ * import { createDb, createORM, defineModel, t } from "peta-orm"
587
+ *
588
+ * const User = defineModel("users", { columns: { ... } })
589
+ *
590
+ * async function setup() {
591
+ * const client = createClient({ url: "file:my-app.db" })
592
+ * await client.execute("CREATE TABLE IF NOT EXISTS users (...)") // schema init
593
+ * const orm = createORM({ dialect: new LibsqlDialect({ client }) })
594
+ * orm.registerAll(User)
595
+ * return orm
596
+ * }
597
+ *
598
+ * export const db = createDb(setup)
599
+ * // Usage: const orm = await db()
600
+ * ```
601
+ */
602
+ declare function createDb<T>(factory: () => Promise<T>): () => Promise<T>;
603
+ //#endregion
604
+ //#region src/model/define.d.ts
605
+ declare function defineModel<TColumns extends ColumnShape>(table: string, config: ModelConfig<TColumns>): ModelDefinition<TColumns>;
606
+ //#endregion
66
607
  //#region src/orm/index.d.ts
67
608
  interface ORMConfig {
68
- dialect: Dialect;
609
+ /** Kysely dialect to create an internal Kysely instance. Required unless `kysely` is provided. */
610
+ dialect?: Dialect;
611
+ /** A pre-existing Kysely instance to reuse. Required unless `dialect` is provided. */
612
+ kysely?: Kysely<any>;
613
+ /** Optional map of model definitions to register immediately. */
69
614
  models?: Record<string, ModelDefinition>;
70
615
  }
71
616
  /**
72
617
  * Create an ORM instance — the central registry that wires Kysely to model definitions.
73
618
  * Replaces createPeta() from v0.x.
619
+ *
620
+ * Pass either `dialect` (to auto-create a Kysely instance) or `kysely` (to reuse one).
621
+ * Passing a pre-existing Kysely instance avoids creating a second connection for
622
+ * migration runners or other tools that already have their own Kysely.
74
623
  */
75
624
  declare function createORM(config: ORMConfig): ORMLike & {
76
625
  kysely: Database;
@@ -212,4 +761,26 @@ declare function defineMorphMany(options: MorphManyOptions): Relation;
212
761
  */
213
762
  declare function defineMorphOne(options: MorphOneOptions): Relation;
214
763
  //#endregion
215
- export { Attribute, type Collection, type Column, type ColumnShape, type ColumnTypes, type ColumnValue, type Constraint, DatabaseError, type DatabaseErrorCode, type HookCallback, type HookManager, type InsertGraphOptions, type LifecycleEvent, type ModelConfig, type ModelDefinition, type ModelId, type ModelInstance, ModelNotFoundError, ModelNotRegisteredError, type MorphManyOptions, type MorphOneOptions, type MorphToOptions, type ORMConfig, type ORMLike, type PaginatedResult, type Paginator, type PaginatorJson, type Plugin, type QueryBuilder, type Relation, RelationNotAllowedError, RelationNotFoundError, type RelationOptions, type RelationType, type SchemaConfig, type UpsertGraphOptions, ValidationError, belongsTo, createArkTypeSchemaConfig, createCollection, createColumn, createHookManager, createORM, createORM as createPeta, createPaginator, createQueryBuilder, defineModel, defineMorphMany, defineMorphOne, defineMorphTo, hasMany, hasManyThrough, hasOne, manyToMany, normalizeError, resolveMorphRelation, softDeletes, t, timestamps, ulid };
764
+ //#region src/repo/index.d.ts
765
+ type QueryMethod = (qb: QueryBuilder, ...args: any[]) => QueryBuilder;
766
+ interface RepoMethods {
767
+ queryMethods?: Record<string, QueryMethod>;
768
+ methods?: Record<string, (...args: any[]) => any>;
769
+ }
770
+ /**
771
+ * Create a repository — a composable set of chainable query methods.
772
+ *
773
+ * ```ts
774
+ * const userRepo = createRepo(User, {
775
+ * queryMethods: {
776
+ * search(q, query: string) {
777
+ * return q.where('name', 'like', `%${query}%`)
778
+ * },
779
+ * },
780
+ * })
781
+ * const users = await userRepo.search('john').paginate(1, 20)
782
+ * ```
783
+ */
784
+ declare function createRepo<TMethods extends RepoMethods>(model: ModelDefinition, methods: TMethods): Record<string, never>;
785
+ //#endregion
786
+ export { Attribute, type Collection, type Column, type ColumnShape, type ColumnTypes, type ColumnValue, type Constraint, DatabaseError, type DatabaseErrorCode, type HookCallback, type HookManager, type InsertGraphOptions, type LifecycleEvent, type ModelConfig, type ModelDefinition, type ModelId, type ModelInstance, ModelNotFoundError, ModelNotRegisteredError, type MorphManyOptions, type MorphOneOptions, type MorphToOptions, type ORMConfig, type ORMLike, type PaginatedResult, type Paginator, type PaginatorJson, type Plugin, type QueryBuilder, type QueryMethod, type Relation, RelationNotAllowedError, RelationNotFoundError, type RelationOptions, type RelationType, type RepoMethods, type SchemaConfig, type SerializedShape, type UpsertGraphOptions, ValidationError, belongsTo, createArkTypeSchemaConfig, createCollection, createColumn, createColumnTypes, createDb, createHookManager, createORM, createORM as createPeta, createPaginator, createQueryBuilder, createRepo, defineModel, defineMorphMany, defineMorphOne, defineMorphTo, hasMany, hasManyThrough, hasOne, manyToMany, normalizeError, resolveMorphRelation, softDeletes, t, timestamps, ulid };