@simplysm/orm-common 13.0.84 → 13.0.86

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.
@@ -1,216 +0,0 @@
1
- # Schema Builders
2
-
3
- Define database tables, views, and stored procedures with a fluent, type-safe API.
4
-
5
- ## API Reference
6
-
7
- ### `Table(name)`
8
-
9
- Factory function that creates a `TableBuilder` for defining table schemas.
10
-
11
- ```typescript
12
- function Table(name: string): TableBuilder<{}, {}>
13
- ```
14
-
15
- #### TableBuilder Methods
16
-
17
- | Method | Signature | Description |
18
- |--------|-----------|-------------|
19
- | `description(desc)` | `.description(desc: string)` | Set table description (DDL comment) |
20
- | `database(db)` | `.database(db: string)` | Set database name |
21
- | `schema(schema)` | `.schema(schema: string)` | Set schema name (MSSQL: `dbo`, PostgreSQL: `public`) |
22
- | `columns(fn)` | `.columns((c) => ({...}))` | Define columns using column factory |
23
- | `primaryKey(...cols)` | `.primaryKey("col1", "col2")` | Set primary key (single or composite) |
24
- | `indexes(fn)` | `.indexes((i) => [...])` | Define indexes |
25
- | `relations(fn)` | `.relations((r) => ({...}))` | Define relationships (FK, reverse FK, logical relations) |
26
-
27
- #### Type Inference Properties
28
-
29
- | Property | Description |
30
- |----------|-------------|
31
- | `$inferSelect` | Full type (columns + deep relations) |
32
- | `$inferColumns` | Columns only |
33
- | `$inferInsert` | Insert type (autoIncrement/nullable/default fields are optional) |
34
- | `$inferUpdate` | Update type (all fields optional) |
35
-
36
- ---
37
-
38
- ### `View(name)`
39
-
40
- Factory function that creates a `ViewBuilder` for defining database views.
41
-
42
- ```typescript
43
- function View(name: string): ViewBuilder<any, {}, {}>
44
- ```
45
-
46
- #### ViewBuilder Methods
47
-
48
- | Method | Signature | Description |
49
- |--------|-----------|-------------|
50
- | `description(desc)` | `.description(desc: string)` | Set view description |
51
- | `database(db)` | `.database(db: string)` | Set database name |
52
- | `schema(schema)` | `.schema(schema: string)` | Set schema name |
53
- | `query(viewFn)` | `.query((db) => db.table().select(...))` | Define view SELECT query |
54
- | `relations(fn)` | `.relations((r) => ({...}))` | Define relationships (logical only, no FK) |
55
-
56
- ---
57
-
58
- ### `Procedure(name)`
59
-
60
- Factory function that creates a `ProcedureBuilder` for defining stored procedures.
61
-
62
- ```typescript
63
- function Procedure(name: string): ProcedureBuilder<never, never>
64
- ```
65
-
66
- #### ProcedureBuilder Methods
67
-
68
- | Method | Signature | Description |
69
- |--------|-----------|-------------|
70
- | `description(desc)` | `.description(desc: string)` | Set procedure description |
71
- | `database(db)` | `.database(db: string)` | Set database name |
72
- | `schema(schema)` | `.schema(schema: string)` | Set schema name |
73
- | `params(fn)` | `.params((c) => ({...}))` | Define input parameters |
74
- | `returns(fn)` | `.returns((c) => ({...}))` | Define return columns |
75
- | `body(sql)` | `.body("SELECT ...")` | Set procedure body SQL |
76
-
77
- ---
78
-
79
- ### Column Factory
80
-
81
- The column factory (`c`) is provided inside `.columns()` and `.params()`/`.returns()` callbacks.
82
-
83
- #### Column Types
84
-
85
- | Method | SQL Type | TypeScript Type | Notes |
86
- |--------|----------|-----------------|-------|
87
- | `c.int()` | INT | `number` | 4 bytes |
88
- | `c.bigint()` | BIGINT | `number` | 8 bytes |
89
- | `c.float()` | FLOAT | `number` | Single precision |
90
- | `c.double()` | DOUBLE | `number` | Double precision |
91
- | `c.decimal(p, s)` | DECIMAL(p,s) | `number` | Fixed-point |
92
- | `c.varchar(len)` | VARCHAR(len) | `string` | Variable-length string |
93
- | `c.char(len)` | CHAR(len) | `string` | Fixed-length string |
94
- | `c.text()` | TEXT | `string` | Large text |
95
- | `c.binary()` | BLOB/VARBINARY/BYTEA | `Bytes` | Binary data |
96
- | `c.boolean()` | TINYINT(1)/BIT/BOOLEAN | `boolean` | |
97
- | `c.datetime()` | DATETIME | `DateTime` | Date + time |
98
- | `c.date()` | DATE | `DateOnly` | Date only |
99
- | `c.time()` | TIME | `Time` | Time only |
100
- | `c.uuid()` | BINARY(16)/UNIQUEIDENTIFIER/UUID | `Uuid` | |
101
-
102
- #### Column Modifiers
103
-
104
- | Method | Description |
105
- |--------|-------------|
106
- | `.autoIncrement()` | Auto-increment (optional in INSERT inference) |
107
- | `.nullable()` | Allow NULL (adds `undefined` to type) |
108
- | `.default(value)` | Set default value (optional in INSERT inference) |
109
- | `.description(desc)` | Set column comment |
110
-
111
- ---
112
-
113
- ### Index Factory
114
-
115
- The index factory (`i`) is provided inside `.indexes()` callbacks.
116
-
117
- ```typescript
118
- i.index("col1", "col2") // Create index on columns
119
- .unique() // Make unique
120
- .orderBy("ASC", "DESC") // Set sort order per column
121
- .name("IX_Custom_Name") // Custom index name
122
- .description("desc") // Description
123
- ```
124
-
125
- ---
126
-
127
- ### Relation Factory
128
-
129
- The relation factory (`r`) is provided inside `.relations()` callbacks.
130
-
131
- | Method | Type | Description |
132
- |--------|------|-------------|
133
- | `r.foreignKey(cols, targetFn)` | N:1 | FK constraint created in DB |
134
- | `r.foreignKeyTarget(targetFn, relName)` | 1:N | Reverse FK reference (array by default) |
135
- | `r.relationKey(cols, targetFn)` | N:1 | Logical relation (no DB FK) |
136
- | `r.relationKeyTarget(targetFn, relName)` | 1:N | Logical reverse reference |
137
-
138
- Both `foreignKeyTarget` and `relationKeyTarget` support `.single()` to indicate a 1:1 relationship (returns single object instead of array).
139
-
140
- ---
141
-
142
- ## Usage Examples
143
-
144
- ### Complete Table Definition
145
-
146
- ```typescript
147
- const User = Table("User")
148
- .database("mydb")
149
- .description("Application users")
150
- .columns((c) => ({
151
- id: c.bigint().autoIncrement(),
152
- name: c.varchar(100),
153
- email: c.varchar(200).nullable(),
154
- status: c.varchar(20).default("active"),
155
- createdAt: c.datetime().default("CURRENT_TIMESTAMP"),
156
- }))
157
- .primaryKey("id")
158
- .indexes((i) => [
159
- i.index("email").unique(),
160
- i.index("status", "createdAt").orderBy("ASC", "DESC"),
161
- ]);
162
- ```
163
-
164
- ### Table with Relations
165
-
166
- ```typescript
167
- const Post = Table("Post")
168
- .columns((c) => ({
169
- id: c.bigint().autoIncrement(),
170
- authorId: c.bigint(),
171
- title: c.varchar(200),
172
- }))
173
- .primaryKey("id")
174
- .relations((r) => ({
175
- author: r.foreignKey(["authorId"], () => User),
176
- }));
177
-
178
- const User = Table("User")
179
- .columns((c) => ({
180
- id: c.bigint().autoIncrement(),
181
- name: c.varchar(100),
182
- }))
183
- .primaryKey("id")
184
- .relations((r) => ({
185
- posts: r.foreignKeyTarget(() => Post, "author"),
186
- profile: r.foreignKeyTarget(() => Profile, "user").single(),
187
- }));
188
- ```
189
-
190
- ### View Definition
191
-
192
- ```typescript
193
- const ActiveUsers = View("ActiveUsers")
194
- .database("mydb")
195
- .query((db: MyDb) =>
196
- db.user()
197
- .where((u) => [expr.eq(u.status, "active")])
198
- .select((u) => ({ id: u.id, name: u.name, email: u.email }))
199
- );
200
- ```
201
-
202
- ### Procedure Definition
203
-
204
- ```typescript
205
- const GetUserById = Procedure("GetUserById")
206
- .database("mydb")
207
- .params((c) => ({
208
- userId: c.bigint(),
209
- }))
210
- .returns((c) => ({
211
- id: c.bigint(),
212
- name: c.varchar(100),
213
- email: c.varchar(200),
214
- }))
215
- .body("SELECT id, name, email FROM User WHERE id = userId");
216
- ```
@@ -1,353 +0,0 @@
1
- # Types and Utilities
2
-
3
- Core type definitions, error handling, search parsing, and result parsing utilities.
4
-
5
- ## API Reference
6
-
7
- ### Column Types
8
-
9
- #### `DataType`
10
-
11
- SQL data type definition used in column metadata.
12
-
13
- ```typescript
14
- type DataType =
15
- | { type: "int" }
16
- | { type: "bigint" }
17
- | { type: "float" }
18
- | { type: "double" }
19
- | { type: "decimal"; precision: number; scale?: number }
20
- | { type: "varchar"; length: number }
21
- | { type: "char"; length: number }
22
- | { type: "text" }
23
- | { type: "binary" }
24
- | { type: "boolean" }
25
- | { type: "datetime" }
26
- | { type: "date" }
27
- | { type: "time" }
28
- | { type: "uuid" };
29
- ```
30
-
31
- #### `ColumnPrimitive`
32
-
33
- All primitive TypeScript types that can be stored in columns. `undefined` represents NULL.
34
-
35
- ```typescript
36
- type ColumnPrimitive = string | number | boolean | DateTime | DateOnly | Time | Uuid | Bytes | undefined;
37
- ```
38
-
39
- #### `ColumnPrimitiveStr`
40
-
41
- String keys for column primitive type mapping.
42
-
43
- ```typescript
44
- type ColumnPrimitiveStr = "string" | "number" | "boolean" | "DateTime" | "DateOnly" | "Time" | "Uuid" | "Bytes";
45
- ```
46
-
47
- #### `ColumnMeta`
48
-
49
- Column metadata generated by `ColumnBuilder`.
50
-
51
- ```typescript
52
- interface ColumnMeta {
53
- type: ColumnPrimitiveStr;
54
- dataType: DataType;
55
- autoIncrement?: boolean;
56
- nullable?: boolean;
57
- default?: ColumnPrimitive;
58
- description?: string;
59
- }
60
- ```
61
-
62
- #### `inferColumnPrimitiveStr(value)`
63
-
64
- Infer `ColumnPrimitiveStr` from a runtime value.
65
-
66
- ```typescript
67
- function inferColumnPrimitiveStr(value: ColumnPrimitive): ColumnPrimitiveStr
68
- ```
69
-
70
- ```typescript
71
- inferColumnPrimitiveStr("hello") // "string"
72
- inferColumnPrimitiveStr(123) // "number"
73
- inferColumnPrimitiveStr(new DateTime()) // "DateTime"
74
- ```
75
-
76
- #### `dataTypeStrToColumnPrimitiveStr`
77
-
78
- Mapping from SQL type strings to TypeScript type names.
79
-
80
- ```typescript
81
- dataTypeStrToColumnPrimitiveStr["int"] // "number"
82
- dataTypeStrToColumnPrimitiveStr["varchar"] // "string"
83
- dataTypeStrToColumnPrimitiveStr["datetime"] // "DateTime"
84
- ```
85
-
86
- ---
87
-
88
- ### Database Types
89
-
90
- #### `Dialect`
91
-
92
- Supported database dialects.
93
-
94
- ```typescript
95
- type Dialect = "mysql" | "mssql" | "postgresql";
96
- ```
97
-
98
- #### `dialects`
99
-
100
- Array of all supported dialects (useful for testing).
101
-
102
- ```typescript
103
- const dialects: Dialect[] = ["mysql", "mssql", "postgresql"];
104
- ```
105
-
106
- #### `IsolationLevel`
107
-
108
- Transaction isolation levels.
109
-
110
- ```typescript
111
- type IsolationLevel =
112
- | "READ_UNCOMMITTED"
113
- | "READ_COMMITTED"
114
- | "REPEATABLE_READ"
115
- | "SERIALIZABLE";
116
- ```
117
-
118
- #### `DataRecord`
119
-
120
- Recursive type for query result records (supports nested relations).
121
-
122
- ```typescript
123
- type DataRecord = {
124
- [key: string]: ColumnPrimitive | DataRecord | DataRecord[];
125
- };
126
- ```
127
-
128
- #### `ResultMeta`
129
-
130
- Metadata for transforming raw query results into typed TypeScript objects.
131
-
132
- ```typescript
133
- interface ResultMeta {
134
- columns: Record<string, ColumnPrimitiveStr>;
135
- joins: Record<string, { isSingle: boolean }>;
136
- }
137
- ```
138
-
139
- #### `QueryBuildResult`
140
-
141
- Result of building a QueryDef into SQL.
142
-
143
- ```typescript
144
- interface QueryBuildResult {
145
- sql: string;
146
- resultSetIndex?: number;
147
- resultSetStride?: number;
148
- }
149
- ```
150
-
151
- #### `Migration`
152
-
153
- Database migration definition.
154
-
155
- ```typescript
156
- interface Migration {
157
- name: string;
158
- up: (db: DbContextBase & DbContextDdlMethods) => Promise<void>;
159
- }
160
- ```
161
-
162
- ---
163
-
164
- ### Error Handling
165
-
166
- #### `DbTransactionError`
167
-
168
- Standardized database transaction error with DBMS-independent error codes.
169
-
170
- ```typescript
171
- class DbTransactionError extends Error {
172
- readonly name = "DbTransactionError";
173
- readonly code: DbErrorCode;
174
- readonly originalError?: unknown;
175
-
176
- constructor(code: DbErrorCode, message: string, originalError?: unknown);
177
- }
178
- ```
179
-
180
- #### `DbErrorCode`
181
-
182
- Transaction-related error codes.
183
-
184
- ```typescript
185
- enum DbErrorCode {
186
- NO_ACTIVE_TRANSACTION = "NO_ACTIVE_TRANSACTION",
187
- TRANSACTION_ALREADY_STARTED = "TRANSACTION_ALREADY_STARTED",
188
- DEADLOCK = "DEADLOCK",
189
- LOCK_TIMEOUT = "LOCK_TIMEOUT",
190
- }
191
- ```
192
-
193
- ```typescript
194
- try {
195
- await executor.rollbackTransaction();
196
- } catch (err) {
197
- if (err instanceof DbTransactionError) {
198
- if (err.code === DbErrorCode.NO_ACTIVE_TRANSACTION) {
199
- return; // Already rolled back, safe to ignore
200
- }
201
- }
202
- throw err;
203
- }
204
- ```
205
-
206
- ---
207
-
208
- ### Search Parser
209
-
210
- #### `parseSearchQuery(searchText)`
211
-
212
- Parse a user search string into structured SQL LIKE patterns.
213
-
214
- ```typescript
215
- function parseSearchQuery(searchText: string): ParsedSearchQuery
216
- ```
217
-
218
- ```typescript
219
- interface ParsedSearchQuery {
220
- or: string[]; // General terms (OR condition)
221
- must: string[]; // Required terms (AND condition, + prefix or quotes)
222
- not: string[]; // Excluded terms (NOT condition, - prefix)
223
- }
224
- ```
225
-
226
- **Search Syntax:**
227
-
228
- | Syntax | Meaning | Example |
229
- |--------|---------|---------|
230
- | `term1 term2` | OR (match any) | `apple banana` |
231
- | `+term` | Required (AND) | `+apple +banana` |
232
- | `-term` | Excluded (NOT) | `apple -banana` |
233
- | `"exact phrase"` | Exact match (required) | `"delicious fruit"` |
234
- | `*` | Wildcard | `app*` -> `app%` |
235
-
236
- **Escape sequences:** `\\` (literal `\`), `\*` (literal `*`), `\%` (literal `%`), `\"` (literal `"`), `\+` (literal `+`), `\-` (literal `-`)
237
-
238
- ```typescript
239
- parseSearchQuery('apple "delicious fruit" -banana +strawberry')
240
- // {
241
- // or: ["%apple%"],
242
- // must: ["%delicious fruit%", "%strawberry%"],
243
- // not: ["%banana%"]
244
- // }
245
-
246
- parseSearchQuery('app* test')
247
- // {
248
- // or: ["app%", "%test%"],
249
- // must: [],
250
- // not: []
251
- // }
252
- ```
253
-
254
- ---
255
-
256
- ### Result Parser
257
-
258
- #### `parseQueryResult(rawResults, meta)`
259
-
260
- Transform raw database query results into typed TypeScript objects. Handles type conversion, nested JOIN result grouping, and deduplication.
261
-
262
- ```typescript
263
- async function parseQueryResult<TRecord>(
264
- rawResults: Record<string, unknown>[],
265
- meta: ResultMeta,
266
- ): Promise<TRecord[] | undefined>
267
- ```
268
-
269
- **Features:**
270
- - Type conversion (string to number, string to DateTime, etc.)
271
- - Flat-to-nested object transformation (`"posts.id"` -> `{ posts: { id } }`)
272
- - JOIN result grouping with deduplication
273
- - Single vs array relationship handling (`isSingle`)
274
- - Event loop yielding for large datasets (every 100 records)
275
- - Returns `undefined` for empty results
276
-
277
- ```typescript
278
- // Simple type parsing
279
- const raw = [{ id: "1", createdAt: "2026-01-07T10:00:00.000Z" }];
280
- const meta = { columns: { id: "number", createdAt: "DateTime" }, joins: {} };
281
- const result = await parseQueryResult(raw, meta);
282
- // [{ id: 1, createdAt: DateTime(...) }]
283
-
284
- // JOIN result nesting
285
- const raw = [
286
- { id: 1, name: "Alice", "posts.id": 10, "posts.title": "Post1" },
287
- { id: 1, name: "Alice", "posts.id": 11, "posts.title": "Post2" },
288
- ];
289
- const meta = {
290
- columns: { id: "number", name: "string", "posts.id": "number", "posts.title": "string" },
291
- joins: { posts: { isSingle: false } },
292
- };
293
- const result = await parseQueryResult(raw, meta);
294
- // [{ id: 1, name: "Alice", posts: [{ id: 10, title: "Post1" }, { id: 11, title: "Post2" }] }]
295
- ```
296
-
297
- ---
298
-
299
- ### QueryDef Types
300
-
301
- #### `QueryDefObjectName`
302
-
303
- Database object name with optional namespace.
304
-
305
- ```typescript
306
- interface QueryDefObjectName {
307
- database?: string;
308
- schema?: string;
309
- name: string;
310
- }
311
- ```
312
-
313
- #### `QueryDef`
314
-
315
- Union type of all query definitions (DML + DDL + utility).
316
-
317
- Key DML types:
318
-
319
- | Type | Interface | Description |
320
- |------|-----------|-------------|
321
- | `"select"` | `SelectQueryDef` | SELECT with FROM, WHERE, JOIN, ORDER BY, GROUP BY, HAVING, LIMIT, WITH |
322
- | `"insert"` | `InsertQueryDef` | INSERT with records, output, overrideIdentity |
323
- | `"insertIfNotExists"` | `InsertIfNotExistsQueryDef` | Conditional INSERT |
324
- | `"insertInto"` | `InsertIntoQueryDef` | INSERT INTO ... SELECT |
325
- | `"update"` | `UpdateQueryDef` | UPDATE with JOIN support |
326
- | `"delete"` | `DeleteQueryDef` | DELETE with JOIN support |
327
- | `"upsert"` | `UpsertQueryDef` | INSERT or UPDATE (MERGE) |
328
-
329
- #### `DDL_TYPES`
330
-
331
- Constant array of all DDL query type strings. Used to prevent DDL execution inside transactions.
332
-
333
- ```typescript
334
- const DDL_TYPES: readonly string[]
335
- // ["clearSchema", "createTable", "dropTable", "renameTable", "truncate",
336
- // "addColumn", "dropColumn", "modifyColumn", "renameColumn",
337
- // "dropPrimaryKey", "addPrimaryKey", "addForeignKey", "dropForeignKey",
338
- // "addIndex", "dropIndex", "createView", "dropView", "createProc", "dropProc"]
339
- ```
340
-
341
- ---
342
-
343
- ### Type Inference Utilities
344
-
345
- | Type | Description |
346
- |------|-------------|
347
- | `InferColumns<T>` | Infer value types from ColumnBuilderRecord |
348
- | `InferInsertColumns<T>` | Infer INSERT type (required + optional fields) |
349
- | `InferUpdateColumns<T>` | Infer UPDATE type (all fields optional) |
350
- | `InferColumnExprs<T>` | Infer expression input types |
351
- | `InferDeepRelations<T>` | Infer nested relation types (all optional) |
352
- | `ExtractRelationTarget<T>` | Extract N:1 relation target type |
353
- | `ExtractRelationTargetResult<T>` | Extract 1:N relation target type (array or single) |