@zerotal/orm 1.0.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.
Files changed (87) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/README.md +170 -0
  4. package/package.json +58 -0
  5. package/src/casts/Cast.ts +200 -0
  6. package/src/commands/DbSeedCommand.ts +71 -0
  7. package/src/commands/MakeFactoryCommand.ts +59 -0
  8. package/src/commands/MakeMigrationCommand.ts +109 -0
  9. package/src/commands/MakeModelCommand.ts +83 -0
  10. package/src/commands/MakeSeederCommand.ts +50 -0
  11. package/src/commands/MigrateCommand.ts +60 -0
  12. package/src/commands/MigrateFreshCommand.ts +41 -0
  13. package/src/commands/MigrateGenerateCommand.ts +110 -0
  14. package/src/commands/MigrateRollbackCommand.ts +43 -0
  15. package/src/commands/MigrateStatusCommand.ts +49 -0
  16. package/src/commands/_loadMigrations.ts +34 -0
  17. package/src/commands/index.ts +30 -0
  18. package/src/config.ts +182 -0
  19. package/src/conventions.ts +67 -0
  20. package/src/db/DB.ts +486 -0
  21. package/src/db/NPlusOneDetector.ts +176 -0
  22. package/src/db/QueryBuilder.ts +2458 -0
  23. package/src/db/ReadWriteRouter.ts +96 -0
  24. package/src/db/TransactionContext.ts +13 -0
  25. package/src/db/dialects/MysqlDialect.ts +57 -0
  26. package/src/db/dialects/PostgresDialect.ts +55 -0
  27. package/src/db/dialects/SqliteDialect.ts +54 -0
  28. package/src/db/dialects/index.ts +25 -0
  29. package/src/db/dialects/types.ts +67 -0
  30. package/src/db/resolver.ts +30 -0
  31. package/src/db/sql-types.ts +12 -0
  32. package/src/db/types.ts +296 -0
  33. package/src/errors/MassAssignmentError.ts +25 -0
  34. package/src/errors/MigrationError.ts +18 -0
  35. package/src/errors/ModelNotFoundError.ts +21 -0
  36. package/src/errors/NPlusOneError.ts +6 -0
  37. package/src/errors/RelationNotLoadedError.ts +19 -0
  38. package/src/errors/StateError.ts +18 -0
  39. package/src/errors/TransactionError.ts +13 -0
  40. package/src/errors/UnsupportedDialectError.ts +18 -0
  41. package/src/errors/index.ts +7 -0
  42. package/src/events.ts +112 -0
  43. package/src/global.d.ts +17 -0
  44. package/src/implicitBinding.ts +73 -0
  45. package/src/index.ts +255 -0
  46. package/src/model/BaseModel.ts +2499 -0
  47. package/src/model/ModelQueryBuilder.ts +1808 -0
  48. package/src/model/Observer.ts +73 -0
  49. package/src/model/OrmContext.ts +71 -0
  50. package/src/model/ReactiveProxy.ts +53 -0
  51. package/src/model/SoftDeletes.ts +108 -0
  52. package/src/model/State.ts +290 -0
  53. package/src/model/decorators/_metadata.ts +211 -0
  54. package/src/model/decorators/_registerRelation.ts +20 -0
  55. package/src/model/decorators/belongsTo.ts +38 -0
  56. package/src/model/decorators/column.ts +278 -0
  57. package/src/model/decorators/hasMany.ts +34 -0
  58. package/src/model/decorators/hasManyThrough.ts +50 -0
  59. package/src/model/decorators/hasOne.ts +34 -0
  60. package/src/model/decorators/hasOneThrough.ts +40 -0
  61. package/src/model/decorators/manyToMany.ts +55 -0
  62. package/src/model/decorators/morphMany.ts +38 -0
  63. package/src/model/decorators/morphOne.ts +38 -0
  64. package/src/model/decorators/morphTo.ts +51 -0
  65. package/src/model/decorators/morphToMany.ts +49 -0
  66. package/src/model/decorators/morphedByMany.ts +46 -0
  67. package/src/model/decorators/table.ts +124 -0
  68. package/src/model/hooks/HookRegistry.ts +110 -0
  69. package/src/model/mixins.ts +536 -0
  70. package/src/model/payload.ts +114 -0
  71. package/src/model/relations/RelationRegistry.ts +184 -0
  72. package/src/observability.ts +210 -0
  73. package/src/provider/DatabaseProvider.ts +266 -0
  74. package/src/schema/Blueprint.ts +900 -0
  75. package/src/schema/ColumnDefinition.ts +517 -0
  76. package/src/schema/Migration.ts +34 -0
  77. package/src/schema/MigrationCodegen.ts +108 -0
  78. package/src/schema/MigrationRunner.ts +351 -0
  79. package/src/schema/ModelInspector.ts +133 -0
  80. package/src/schema/Schema.ts +140 -0
  81. package/src/schema/SchemaDiffer.ts +137 -0
  82. package/src/schema/SchemaInspector.ts +164 -0
  83. package/src/schema/__test_migrations__/001_create_test_table.ts +15 -0
  84. package/src/schema/autoMigrate.ts +154 -0
  85. package/src/schema/index.ts +28 -0
  86. package/src/seeding/Seeder.ts +46 -0
  87. package/src/support/identifiers.ts +62 -0
package/src/index.ts ADDED
@@ -0,0 +1,255 @@
1
+ /**
2
+ * A Bun-native Active Record ORM built on `Bun.sql`.
3
+ *
4
+ * Models extend {@link BaseModel}: you declare columns with {@link column | `@column`},
5
+ * relationships with decorators like {@link hasMany | `@hasMany`} and
6
+ * {@link belongsTo | `@belongsTo`}, and then query and persist through the model's
7
+ * static and instance methods. Under the hood a {@link QueryBuilder} routes every
8
+ * value through parameterised bindings and forces interpolated identifiers through
9
+ * an allowlist; {@link ModelQueryBuilder} adds model hydration, eager loading, and
10
+ * relationship-existence queries on top. Schema changes are authored as migrations
11
+ * using the {@link Schema} facade and the {@link Blueprint} table builder.
12
+ *
13
+ * Mass assignment is **guarded by default** — a model with neither `fillable` nor
14
+ * `guarded` declared rejects all attributes in {@link BaseModel.fill | `fill()`}.
15
+ * Soft deletes and state machines are opt-in mixins composed via
16
+ * {@link BaseModelWith}. The ORM's CLI commands (`migrate`, `make:model`, …) live
17
+ * under the `@zerotal/orm/commands` subpath.
18
+ *
19
+ * @example Define a model
20
+ * ```ts
21
+ * import { BaseModel, column, hasMany, type HasMany } from "@zerotal/orm";
22
+ * import { Post } from "./Post.ts";
23
+ *
24
+ * export class User extends BaseModel {
25
+ * @column({ primary: true }) id!: number;
26
+ * @column() email!: string;
27
+ * @column() name!: string;
28
+ *
29
+ * @hasMany(() => Post) posts!: HasMany<Post>;
30
+ * }
31
+ * ```
32
+ *
33
+ * @example Query, create, and eager-load
34
+ * ```ts
35
+ * const active = await User.query()
36
+ * .where("active", true)
37
+ * .with("posts")
38
+ * .orderBy("name")
39
+ * .paginate(20, 1); // 20 per page, page 1
40
+ *
41
+ * const user = await User.create({ email: "a@b.com", name: "Ada" });
42
+ * user.name = "Ada L.";
43
+ * await user.save();
44
+ * ```
45
+ *
46
+ * @example A migration
47
+ * ```ts
48
+ * import { Migration, Schema } from "@zerotal/orm";
49
+ *
50
+ * export default class extends Migration {
51
+ * async up() {
52
+ * await Schema.create("users", (table) => {
53
+ * table.increments("id");
54
+ * table.string("email").unique();
55
+ * table.timestamps();
56
+ * });
57
+ * }
58
+ * async down() {
59
+ * await Schema.drop("users");
60
+ * }
61
+ * }
62
+ * ```
63
+ *
64
+ * @remarks
65
+ * Runs on **Bun ≥ 1.1** via `Bun.sql`; SQLite, Postgres, and MySQL dialects are
66
+ * supported. Register `DatabaseProvider` to wire the ORM into an application.
67
+ *
68
+ * @packageDocumentation
69
+ */
70
+
71
+ // @zerotal/orm — public API barrel
72
+
73
+ export { BaseModel, Model } from "./model/BaseModel.ts";
74
+ export { BaseModelWith } from "./model/mixins.ts";
75
+ export type { Constructor, Mixin } from "./model/mixins.ts";
76
+ // State-machine behaviour is an opt-in mixin — compose with `BaseModelWith(State)`.
77
+ export { State } from "./model/State.ts";
78
+ // Soft deletes are opt-in — compose with `BaseModelWith(SoftDeletes)`.
79
+ export { SoftDeletes } from "./model/SoftDeletes.ts";
80
+ export type {
81
+ StateDefinition,
82
+ StateMachine,
83
+ StateGuard,
84
+ RejectTransition,
85
+ TransitionContext,
86
+ TransitionResult,
87
+ TransitionCallback,
88
+ } from "./model/State.ts";
89
+ export type { ScopeApplicator, Columns } from "./model/BaseModel.ts";
90
+ export type { InsertPayload, UpdatePayload } from "./model/payload.ts";
91
+ // Columns is also re-exported from payload.ts for import convenience — no duplicate needed here
92
+ export { ModelQueryBuilder, _globalScopeRegistry } from "./model/ModelQueryBuilder.ts";
93
+ export type { GlobalScopeCallback, RelationConstraint } from "./model/ModelQueryBuilder.ts";
94
+ export { DB } from "./db/DB.ts";
95
+ export {
96
+ _getConnection,
97
+ _setDbConnection,
98
+ _getDbConnectionOverride,
99
+ _setReadReplicas,
100
+ } from "./db/DB.ts";
101
+ export { setConnectionResolver, resolveContainerConnection } from "./db/resolver.ts";
102
+ export {
103
+ OrmContext,
104
+ currentOrmContext,
105
+ useOrmContext,
106
+ resetOrmContext,
107
+ } from "./model/OrmContext.ts";
108
+ export type { ManualTransaction } from "./db/DB.ts";
109
+ export { createReadWriteRouter } from "./db/ReadWriteRouter.ts";
110
+ export { TransactionContext } from "./db/TransactionContext.ts";
111
+ export {
112
+ _setBaseModelConnection,
113
+ _getModelConnection,
114
+ _setBaseModelDialect,
115
+ _getDialect,
116
+ _resolveConn,
117
+ registerModelConnection,
118
+ registerConnectionResolver,
119
+ _clearModelConnections,
120
+ } from "./model/BaseModel.ts";
121
+ export type { ContextConnectionResolver } from "./model/BaseModel.ts";
122
+ export type { SQLInstance } from "./db/sql-types.ts";
123
+ export { _clearTransitionCallbacks } from "./model/State.ts";
124
+ export { QueryBuilder, _setQueryBuilderDialect } from "./db/QueryBuilder.ts";
125
+
126
+ // Dialect strategies (engine-specific SQL: introspection, date parts, advisory locks)
127
+ export { getDialect, SqliteDialect, PostgresDialect, MysqlDialect } from "./db/dialects/index.ts";
128
+ export type { SqlDialect, DialectName, DialectQuery, DatePart } from "./db/dialects/index.ts";
129
+ export type {
130
+ WhereOperator,
131
+ OrderDirection,
132
+ QueryState,
133
+ PaginateResult,
134
+ PaginateMeta,
135
+ SimplePaginateResult,
136
+ CursorPaginateResult,
137
+ KeysetOptions,
138
+ KeysetPaginateResult,
139
+ } from "./db/types.ts";
140
+
141
+ // Decorators
142
+ export { column, columnRegistry } from "./model/decorators/column.ts";
143
+ export type { ColumnOptions, ColumnShorthand } from "./model/decorators/column.ts";
144
+ export { registerModel, modelByName, modelsByName } from "./model/decorators/_metadata.ts";
145
+ // Imperative column registration — for mixin authors composing model behaviour with
146
+ // BaseModelWith (the @column decorator can't run inside a returned class expression).
147
+ export { registerColumn, columnsFor } from "./model/decorators/_metadata.ts";
148
+ export { table } from "./model/decorators/table.ts";
149
+ export type { TableDecoratorBuilder, TableOptions } from "./model/decorators/table.ts";
150
+ export { hasMany } from "./model/decorators/hasMany.ts";
151
+ export { belongsTo } from "./model/decorators/belongsTo.ts";
152
+ export { hasOne } from "./model/decorators/hasOne.ts";
153
+ export { manyToMany } from "./model/decorators/manyToMany.ts";
154
+ export type { ManyToManyOptions } from "./model/decorators/manyToMany.ts";
155
+ export { morphTo } from "./model/decorators/morphTo.ts";
156
+ export type { MorphToOptions } from "./model/decorators/morphTo.ts";
157
+ export { morphMany } from "./model/decorators/morphMany.ts";
158
+ export type { MorphManyOptions } from "./model/decorators/morphMany.ts";
159
+ export { morphOne } from "./model/decorators/morphOne.ts";
160
+ export type { MorphOneOptions } from "./model/decorators/morphOne.ts";
161
+ export { hasManyThrough } from "./model/decorators/hasManyThrough.ts";
162
+ export type { HasManyThroughOptions } from "./model/decorators/hasManyThrough.ts";
163
+ export { hasOneThrough } from "./model/decorators/hasOneThrough.ts";
164
+ export { morphToMany } from "./model/decorators/morphToMany.ts";
165
+ export type { MorphToManyOptions } from "./model/decorators/morphToMany.ts";
166
+ export { morphedByMany } from "./model/decorators/morphedByMany.ts";
167
+ export type { MorphedByManyOptions } from "./model/decorators/morphedByMany.ts";
168
+
169
+ // Relations
170
+ export { relationRegistry } from "./model/relations/RelationRegistry.ts";
171
+ export type {
172
+ ManyToMany,
173
+ HasMany,
174
+ BelongsTo,
175
+ HasOne,
176
+ MorphTo,
177
+ MorphMany,
178
+ MorphOne,
179
+ WithLoaded,
180
+ RelationMetadata,
181
+ RelationDefinition,
182
+ RelationType,
183
+ } from "./model/relations/RelationRegistry.ts";
184
+
185
+ // Hooks
186
+ export { HookRegistry, _suppressHooks } from "./model/hooks/HookRegistry.ts";
187
+ export type { HookName } from "./model/hooks/HookRegistry.ts";
188
+
189
+ // Observers
190
+ export type { ModelObserver } from "./model/Observer.ts";
191
+
192
+ // N+1 detection
193
+ export { preventNPlusOne, allowNPlusOne, NPlusOneError } from "./db/NPlusOneDetector.ts";
194
+ export type { NPlusOneOptions } from "./db/NPlusOneDetector.ts";
195
+
196
+ // Errors
197
+ export {
198
+ ModelNotFoundError,
199
+ RelationNotLoadedError,
200
+ TransactionError,
201
+ MigrationError,
202
+ StateError,
203
+ UnsupportedDialectError,
204
+ } from "./errors/index.ts";
205
+
206
+ // Provider
207
+ export { DatabaseProvider, _normaliseSqliteUrl } from "./provider/DatabaseProvider.ts";
208
+ export { installOrmObservability } from "./observability.ts";
209
+
210
+ // Schema / Migrations
211
+ export { Blueprint } from "./schema/Blueprint.ts";
212
+ export {
213
+ ColumnBuilder,
214
+ ForeignIdColumnBuilder,
215
+ ForeignKeyBuilder,
216
+ } from "./schema/ColumnDefinition.ts";
217
+ export type { FKAction } from "./schema/ColumnDefinition.ts";
218
+ export { Schema } from "./schema/Schema.ts";
219
+ export { Migration } from "./schema/Migration.ts";
220
+ export { MigrationRunner } from "./schema/MigrationRunner.ts";
221
+ export type { MigrationEntry, MigrationRecord, MigrationStatus } from "./schema/MigrationRunner.ts";
222
+ export { SchemaInspector } from "./schema/SchemaInspector.ts";
223
+ export type { LiveColumn, LiveTable } from "./schema/SchemaInspector.ts";
224
+ export { ModelInspector } from "./schema/ModelInspector.ts";
225
+ export type { ModelColumn, ModelSchema } from "./schema/ModelInspector.ts";
226
+ export { SchemaDiffer } from "./schema/SchemaDiffer.ts";
227
+ export type { DiffResult, NewTable, NewColumn, DroppedColumn } from "./schema/SchemaDiffer.ts";
228
+ export { synchronizeSchema, resolveSyncOptions } from "./schema/autoMigrate.ts";
229
+ export type { SynchronizeOptions, ResolvedSyncOptions } from "./schema/autoMigrate.ts";
230
+ export { generateMigrationContent } from "./schema/MigrationCodegen.ts";
231
+
232
+ // Implicit route-model binding
233
+ export { modelForParam, registerImplicitBinding } from "./implicitBinding.ts";
234
+
235
+ // Seeding
236
+ export { Seeder } from "./seeding/Seeder.ts";
237
+
238
+ // Config factory
239
+ export { DatabaseConfig } from "./config.ts";
240
+ export type { DatabaseConfigShape } from "./config.ts";
241
+
242
+ // Casts
243
+ export { Cast, JsonCast, ArrayCast, json, objectOf, arrayOf } from "./casts/Cast.ts";
244
+ export type { CastContract, CastMapper, CastField } from "./casts/Cast.ts";
245
+
246
+ // Framework events emitted by the ORM (subscribe via core's FrameworkEvents bus).
247
+ export {
248
+ QueryExecuted,
249
+ NPlusOneDetected,
250
+ TransactionStarted,
251
+ TransactionCommitted,
252
+ TransactionRolledBack,
253
+ MigrationRan,
254
+ ModelChanged,
255
+ } from "./events.ts";