@mateusseiboth/ember-orm 0.1.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.
@@ -0,0 +1,459 @@
1
+ import { S as SchemaDocument, M as ModelNode } from './index-D0xIdtCl.js';
2
+
3
+ /**
4
+ * Database driver abstraction. The query engine depends only on these
5
+ * interfaces (DIP), never on `node-firebird` directly, so a different
6
+ * backend could be plugged in without touching the engine.
7
+ */
8
+ interface ConnectionConfig {
9
+ host: string;
10
+ port: number;
11
+ database: string;
12
+ user: string;
13
+ password: string;
14
+ role?: string;
15
+ encoding?: string;
16
+ pageSize?: number;
17
+ /** Max pooled connections. */
18
+ poolMax?: number;
19
+ blobAsText?: boolean;
20
+ lowercaseKeys?: boolean;
21
+ /**
22
+ * Authentication plugin. Firebird 3+ defaults to "Srp" (secure remote
23
+ * password) and is negotiated automatically; use "Legacy_Auth" for legacy
24
+ * Firebird 2.1/2.5 servers.
25
+ */
26
+ authPlugin?: "Srp" | "Legacy_Auth";
27
+ /** Enable wire compression (Firebird 3+). */
28
+ wireCompression?: boolean;
29
+ /**
30
+ * Target server major version, used to pick version-specific SQL/DDL
31
+ * (e.g. BOOLEAN vs SMALLINT, IDENTITY vs generator+trigger). Defaults to 3.
32
+ */
33
+ version?: FirebirdVersion;
34
+ }
35
+ type FirebirdVersion = "2.1" | "2.5" | "3" | "4" | "5";
36
+ type SqlValue = string | number | boolean | bigint | Date | Buffer | null;
37
+ /** A connection scoped to an open transaction. */
38
+ interface TransactionContext {
39
+ /** Run a parameterized query and return all rows. */
40
+ query<T = Record<string, unknown>>(sql: string, params?: readonly SqlValue[]): Promise<T[]>;
41
+ }
42
+ type IsolationLevel = "READ_COMMITTED" | "READ_COMMITTED_READ_ONLY" | "REPEATABLE_READ" | "SERIALIZABLE";
43
+ /** Emitted once per executed statement when a logger is configured. */
44
+ interface QueryEvent {
45
+ sql: string;
46
+ params: readonly SqlValue[];
47
+ durationMs: number;
48
+ /** Number of rows returned (selects) or affected-ish (best-effort). */
49
+ rowCount: number;
50
+ }
51
+ type QueryLogger = (event: QueryEvent) => void;
52
+ interface DriverOptions {
53
+ /** Called after each statement completes (used by the client `log` option). */
54
+ onQuery?: QueryLogger;
55
+ }
56
+ interface TransactionOptions {
57
+ isolation?: IsolationLevel;
58
+ }
59
+ /**
60
+ * The driver contract used by the runtime. Every read and write goes through
61
+ * `transaction()` so the project rule "every operation runs in a transaction"
62
+ * holds by construction.
63
+ */
64
+ interface SqlDriver {
65
+ connect(): Promise<void>;
66
+ disconnect(): Promise<void>;
67
+ /**
68
+ * Run `fn` inside a transaction, committing on success and rolling back on
69
+ * any thrown error. Nested calls reuse the active transaction.
70
+ */
71
+ transaction<T>(fn: (tx: TransactionContext) => Promise<T>, options?: TransactionOptions): Promise<T>;
72
+ }
73
+
74
+ /**
75
+ * Strategy interface for SQL generation. Encapsulates every dialect-specific
76
+ * decision so the query compiler stays backend-agnostic. Only FirebirdDialect
77
+ * is implemented today, but the engine never assumes Firebird directly.
78
+ */
79
+ interface SqlDialect {
80
+ /** Quote an identifier (table/column/alias). */
81
+ quoteId(name: string): string;
82
+ /** Quote a `table.column` reference. */
83
+ quoteRef(table: string, column: string): string;
84
+ /** Pagination clause placed right after SELECT (e.g. `FIRST 10 SKIP 5`). */
85
+ paginationClause(take?: number, skip?: number): string;
86
+ /** Wrap a value for LIKE with case-insensitive mode. */
87
+ caseInsensitive(expr: string): string;
88
+ /** Map a default function name (now/uuid/...) to a SQL expression, if any. */
89
+ defaultFunctionSql(name: string): string | null;
90
+ /** Coerce a JS value into a driver-bindable SqlValue. */
91
+ coerceValue(value: unknown): SqlValue;
92
+ /** True if the dialect can paginate (controls FIRST/SKIP usage). */
93
+ readonly supportsReturning: boolean;
94
+ /** Native BOOLEAN type (Firebird 3+) vs SMALLINT fallback (2.1/2.5). */
95
+ readonly supportsBooleanType: boolean;
96
+ /** IDENTITY columns (Firebird 3+) vs generator+trigger (2.1/2.5). */
97
+ readonly supportsIdentity: boolean;
98
+ /** Window functions like ROW_NUMBER() OVER (...) (Firebird 3+). */
99
+ readonly supportsWindowFunctions: boolean;
100
+ /** DDL type used for boolean columns. */
101
+ booleanColumnType(): string;
102
+ }
103
+ /**
104
+ * Firebird 3+/4+ dialect.
105
+ * - Identifiers are double-quoted to preserve case (introspection yields
106
+ * UPPER-CASE names and quoting avoids accidental folding).
107
+ * - Pagination uses `FIRST n SKIP m` after the SELECT keyword.
108
+ * - Case-insensitive matching uses UPPER() on both sides.
109
+ */
110
+ interface FirebirdDialectOptions {
111
+ version?: FirebirdVersion;
112
+ }
113
+ declare class FirebirdDialect implements SqlDialect {
114
+ readonly supportsReturning = true;
115
+ readonly version: FirebirdVersion;
116
+ readonly supportsBooleanType: boolean;
117
+ readonly supportsIdentity: boolean;
118
+ readonly supportsWindowFunctions: boolean;
119
+ constructor(options?: FirebirdDialectOptions);
120
+ booleanColumnType(): string;
121
+ quoteId(name: string): string;
122
+ quoteRef(table: string, column: string): string;
123
+ paginationClause(take?: number, skip?: number): string;
124
+ caseInsensitive(expr: string): string;
125
+ defaultFunctionSql(name: string): string | null;
126
+ coerceValue(value: unknown): SqlValue;
127
+ }
128
+
129
+ /**
130
+ * Runtime-facing query argument shapes. The generated client produces strict,
131
+ * per-model versions of these; at runtime the engine works with these generic
132
+ * forms. Mirrors Prisma's query API surface.
133
+ */
134
+ type SortOrder = "asc" | "desc";
135
+ type QueryMode = "default" | "insensitive";
136
+ /** Scalar field filter, e.g. `{ equals, in, lt, contains, ... }`. */
137
+ interface ScalarFilter {
138
+ equals?: unknown;
139
+ not?: unknown | ScalarFilter;
140
+ in?: unknown[];
141
+ notIn?: unknown[];
142
+ lt?: unknown;
143
+ lte?: unknown;
144
+ gt?: unknown;
145
+ gte?: unknown;
146
+ contains?: string;
147
+ startsWith?: string;
148
+ endsWith?: string;
149
+ mode?: QueryMode;
150
+ }
151
+ /** Relation filter for to-one (`is`/`isNot`) and to-many (`some`/`every`/`none`). */
152
+ interface RelationFilter {
153
+ is?: WhereInput | null;
154
+ isNot?: WhereInput | null;
155
+ some?: WhereInput;
156
+ every?: WhereInput;
157
+ none?: WhereInput;
158
+ }
159
+ interface WhereInput {
160
+ AND?: WhereInput | WhereInput[];
161
+ OR?: WhereInput[];
162
+ NOT?: WhereInput | WhereInput[];
163
+ [field: string]: unknown | ScalarFilter | RelationFilter | WhereInput | WhereInput[] | undefined;
164
+ }
165
+ type OrderByInput = Record<string, SortOrder> | Record<string, SortOrder>[];
166
+ type SelectInput = Record<string, boolean | NestedReadArgs>;
167
+ type IncludeInput = Record<string, boolean | NestedReadArgs>;
168
+ /** Fields to exclude from the result (inverse of select). */
169
+ type OmitInput = Record<string, boolean>;
170
+ interface NestedReadArgs {
171
+ select?: SelectInput;
172
+ include?: IncludeInput;
173
+ where?: WhereInput;
174
+ orderBy?: OrderByInput;
175
+ take?: number;
176
+ skip?: number;
177
+ distinct?: string[];
178
+ }
179
+ interface FindManyArgs {
180
+ where?: WhereInput;
181
+ orderBy?: OrderByInput;
182
+ select?: SelectInput;
183
+ include?: IncludeInput;
184
+ omit?: OmitInput;
185
+ take?: number;
186
+ skip?: number;
187
+ cursor?: Record<string, unknown>;
188
+ distinct?: string[];
189
+ }
190
+ interface FindUniqueArgs {
191
+ where: WhereInput;
192
+ select?: SelectInput;
193
+ include?: IncludeInput;
194
+ omit?: OmitInput;
195
+ }
196
+ interface FindFirstArgs extends FindManyArgs {
197
+ }
198
+ interface CreateArgs {
199
+ data: Record<string, unknown>;
200
+ select?: SelectInput;
201
+ include?: IncludeInput;
202
+ omit?: OmitInput;
203
+ }
204
+ interface CreateManyArgs {
205
+ data: Record<string, unknown>[];
206
+ skipDuplicates?: boolean;
207
+ }
208
+ interface CreateManyAndReturnArgs {
209
+ data: Record<string, unknown>[];
210
+ select?: SelectInput;
211
+ omit?: OmitInput;
212
+ skipDuplicates?: boolean;
213
+ }
214
+ interface UpdateArgs {
215
+ where: WhereInput;
216
+ data: Record<string, unknown>;
217
+ select?: SelectInput;
218
+ include?: IncludeInput;
219
+ omit?: OmitInput;
220
+ }
221
+ interface UpdateManyArgs {
222
+ where?: WhereInput;
223
+ data: Record<string, unknown>;
224
+ }
225
+ interface UpsertArgs {
226
+ where: WhereInput;
227
+ create: Record<string, unknown>;
228
+ update: Record<string, unknown>;
229
+ select?: SelectInput;
230
+ include?: IncludeInput;
231
+ omit?: OmitInput;
232
+ }
233
+ interface DeleteArgs {
234
+ where: WhereInput;
235
+ select?: SelectInput;
236
+ include?: IncludeInput;
237
+ omit?: OmitInput;
238
+ }
239
+ interface DeleteManyArgs {
240
+ where?: WhereInput;
241
+ }
242
+ interface CountArgs {
243
+ where?: WhereInput;
244
+ take?: number;
245
+ skip?: number;
246
+ select?: Record<string, boolean> | true;
247
+ }
248
+ interface AggregateArgs {
249
+ where?: WhereInput;
250
+ orderBy?: OrderByInput;
251
+ take?: number;
252
+ skip?: number;
253
+ _count?: Record<string, boolean> | true;
254
+ _avg?: Record<string, boolean>;
255
+ _sum?: Record<string, boolean>;
256
+ _min?: Record<string, boolean>;
257
+ _max?: Record<string, boolean>;
258
+ }
259
+ interface GroupByArgs extends AggregateArgs {
260
+ by: string[];
261
+ having?: WhereInput;
262
+ }
263
+
264
+ /**
265
+ * The query engine executes high-level operations against a driver. Reads use
266
+ * a projection + relation-stitching pipeline (relations are loaded with
267
+ * separate batched queries, Prisma-style). Writes are delegated to
268
+ * WriteProcessor. Every operation runs inside a driver transaction.
269
+ */
270
+ declare class QueryEngine {
271
+ private readonly schema;
272
+ private readonly dialect;
273
+ private readonly driver;
274
+ constructor(schema: SchemaDocument, dialect: SqlDialect, driver: SqlDriver);
275
+ model(name: string): ModelNode;
276
+ private run;
277
+ private execOn;
278
+ findMany(name: string, args?: FindManyArgs): Promise<Record<string, unknown>[]>;
279
+ findFirst(name: string, args?: FindFirstArgs): Promise<Record<string, unknown> | null>;
280
+ findFirstOrThrow(name: string, args?: FindFirstArgs): Promise<Record<string, unknown>>;
281
+ findUnique(name: string, args: FindUniqueArgs): Promise<Record<string, unknown> | null>;
282
+ findUniqueOrThrow(name: string, args: FindUniqueArgs): Promise<Record<string, unknown>>;
283
+ count(name: string, args?: CountArgs): Promise<number>;
284
+ aggregate(name: string, args?: AggregateArgs): Promise<Record<string, unknown>>;
285
+ groupBy(name: string, args: GroupByArgs): Promise<Record<string, unknown>[]>;
286
+ create(name: string, args: CreateArgs): Promise<Record<string, unknown>>;
287
+ createMany(name: string, args: CreateManyArgs): Promise<{
288
+ count: number;
289
+ }>;
290
+ /** Like createMany, but returns the created records (no nested relations). */
291
+ createManyAndReturn(name: string, args: CreateManyAndReturnArgs): Promise<Record<string, unknown>[]>;
292
+ update(name: string, args: UpdateArgs): Promise<Record<string, unknown>>;
293
+ updateMany(name: string, args: UpdateManyArgs): Promise<{
294
+ count: number;
295
+ }>;
296
+ upsert(name: string, args: UpsertArgs): Promise<Record<string, unknown>>;
297
+ delete(name: string, args: DeleteArgs): Promise<Record<string, unknown>>;
298
+ deleteMany(name: string, args?: DeleteManyArgs): Promise<{
299
+ count: number;
300
+ }>;
301
+ private readMany;
302
+ private loadRelation;
303
+ private readRelations;
304
+ /**
305
+ * Resolve which to-many relations to count for `_count` in select/include.
306
+ * `_count: true` counts every list relation; `_count: { select: { rel } }`
307
+ * counts the named ones.
308
+ */
309
+ private readCountRelations;
310
+ /** Attach a `_count` object to each row with per-relation child counts. */
311
+ private loadCounts;
312
+ private readBack;
313
+ private readBackOne;
314
+ private requireOne;
315
+ private findOneRaw;
316
+ private countMatching;
317
+ private pickKeys;
318
+ private assertUniqueWhere;
319
+ }
320
+
321
+ /**
322
+ * The full set of operations exposed on `client.<model>`. The generated client
323
+ * narrows every argument and return type per model; this is the untyped runtime
324
+ * surface they share.
325
+ */
326
+ interface ModelDelegate {
327
+ findMany(args?: FindManyArgs): Promise<Record<string, unknown>[]>;
328
+ findFirst(args?: FindFirstArgs): Promise<Record<string, unknown> | null>;
329
+ findFirstOrThrow(args?: FindFirstArgs): Promise<Record<string, unknown>>;
330
+ findUnique(args: FindUniqueArgs): Promise<Record<string, unknown> | null>;
331
+ findUniqueOrThrow(args: FindUniqueArgs): Promise<Record<string, unknown>>;
332
+ create(args: CreateArgs): Promise<Record<string, unknown>>;
333
+ createMany(args: CreateManyArgs): Promise<{
334
+ count: number;
335
+ }>;
336
+ createManyAndReturn(args: CreateManyAndReturnArgs): Promise<Record<string, unknown>[]>;
337
+ update(args: UpdateArgs): Promise<Record<string, unknown>>;
338
+ updateMany(args: UpdateManyArgs): Promise<{
339
+ count: number;
340
+ }>;
341
+ upsert(args: UpsertArgs): Promise<Record<string, unknown>>;
342
+ delete(args: DeleteArgs): Promise<Record<string, unknown>>;
343
+ deleteMany(args?: DeleteManyArgs): Promise<{
344
+ count: number;
345
+ }>;
346
+ count(args?: CountArgs): Promise<number>;
347
+ aggregate(args?: AggregateArgs): Promise<Record<string, unknown>>;
348
+ groupBy(args: GroupByArgs): Promise<Record<string, unknown>[]>;
349
+ }
350
+
351
+ /**
352
+ * Client Extensions ($extends), middleware ($use) and the fluent API live here.
353
+ * The delegate factory composes per-operation query hooks, computes `result`
354
+ * fields, and returns fluent thenables for single-record reads.
355
+ */
356
+ interface ResultFieldExtension {
357
+ needs?: Record<string, boolean>;
358
+ compute: (record: Record<string, unknown>) => unknown;
359
+ }
360
+ interface QueryHookParams {
361
+ model: string;
362
+ operation: string;
363
+ args: Record<string, unknown>;
364
+ query: (args: Record<string, unknown>) => Promise<unknown>;
365
+ }
366
+ type QueryHook = (params: QueryHookParams) => Promise<unknown>;
367
+ type HookMap = Record<string, QueryHook>;
368
+ interface EmberExtensionArgs {
369
+ name?: string;
370
+ result?: Record<string, Record<string, ResultFieldExtension>>;
371
+ model?: Record<string, Record<string, (...args: unknown[]) => unknown>>;
372
+ query?: Record<string, HookMap>;
373
+ client?: Record<string, unknown>;
374
+ }
375
+ /** Prisma-style middleware: `(params, next) => next(params)`. */
376
+ type Middleware = (params: {
377
+ model?: string;
378
+ action: string;
379
+ args: unknown;
380
+ }, next: (params: {
381
+ model?: string;
382
+ action: string;
383
+ args: unknown;
384
+ }) => Promise<unknown>) => Promise<unknown>;
385
+
386
+ interface ClientOptions {
387
+ /** Connection URL or explicit config. Overrides the schema datasource. */
388
+ datasourceUrl?: string;
389
+ datasource?: ConnectionConfig;
390
+ /** A pre-parsed schema document (the generated client passes its own). */
391
+ schema: SchemaDocument;
392
+ /**
393
+ * Query logging: `true` logs each statement to the console; pass a function
394
+ * to receive structured `QueryEvent`s (sql, params, durationMs, rowCount).
395
+ */
396
+ log?: boolean | QueryLogger;
397
+ }
398
+ /**
399
+ * Runtime client. Builds one delegate per model from the schema and exposes
400
+ * Prisma-style lifecycle and transaction helpers. The generated client extends
401
+ * this and adds strongly-typed delegate properties.
402
+ */
403
+ declare class EmberClientBase {
404
+ protected readonly driver: SqlDriver;
405
+ protected readonly engine: QueryEngine;
406
+ protected readonly dialect: SqlDialect;
407
+ protected readonly schema: SchemaDocument;
408
+ private connected;
409
+ /** Mutated by $extends (per instance) and $use (shared). */
410
+ protected extensions: EmberExtensionArgs[];
411
+ protected middlewares: Middleware[];
412
+ private readonly queryListeners;
413
+ private readonly baseLog?;
414
+ /** Dynamic model delegates, keyed by camelCased model name. */
415
+ [delegate: string]: unknown;
416
+ constructor(options: ClientOptions);
417
+ private dispatchQuery;
418
+ private delegateContext;
419
+ /** (Re)define one delegate property per model using the current extensions. */
420
+ private installDelegates;
421
+ /**
422
+ * Prisma-style Client Extensions. Returns a new client (the original is
423
+ * unchanged) that shares the connection/engine but applies the extension's
424
+ * `result` / `model` / `query` / `client` definitions.
425
+ */
426
+ $extends(extension: EmberExtensionArgs): this;
427
+ /** Prisma-style middleware: runs around every operation. */
428
+ $use(middleware: Middleware): void;
429
+ /** Subscribe to query events (mirrors the `log` callback). */
430
+ $on(event: "query", listener: QueryLogger): void;
431
+ /** Type-safe access to a delegate by model name. */
432
+ model(name: string): ModelDelegate;
433
+ $connect(): Promise<void>;
434
+ $disconnect(): Promise<void>;
435
+ /**
436
+ * Run work inside a single transaction.
437
+ * - Interactive form: `$transaction(async (tx) => { ... })`.
438
+ * - Sequential form: `$transaction([(tx) => tx.user.create(...), ...])`.
439
+ *
440
+ * Because the driver tracks the active transaction via AsyncLocalStorage,
441
+ * every delegate call made on the passed client runs in the same transaction.
442
+ */
443
+ $transaction<T>(fn: (tx: this) => Promise<T>, options?: TransactionOptions): Promise<T>;
444
+ $transaction<T>(thunks: ((tx: this) => Promise<T>)[], options?: TransactionOptions): Promise<T[]>;
445
+ /** Execute a raw read query (returns rows) inside a transaction. */
446
+ $queryRawUnsafe<T = Record<string, unknown>>(sql: string, ...params: unknown[]): Promise<T[]>;
447
+ /** Execute a raw write statement inside a transaction; returns affected rows when available. */
448
+ $executeRawUnsafe(sql: string, ...params: unknown[]): Promise<number>;
449
+ /** Tagged-template raw query: `client.$queryRaw\`SELECT * FROM T WHERE id = ${id}\``. */
450
+ $queryRaw<T = Record<string, unknown>>(strings: TemplateStringsArray, ...values: unknown[]): Promise<T[]>;
451
+ $executeRaw(strings: TemplateStringsArray, ...values: unknown[]): Promise<number>;
452
+ }
453
+ /**
454
+ * Factory for an untyped client when you don't use the generated client.
455
+ * Prefer the generated `EmberClient` for full type-safety.
456
+ */
457
+ declare function createClient(options: ClientOptions): EmberClientBase;
458
+
459
+ export { type AggregateArgs as A, type ConnectionConfig as C, type DriverOptions as D, EmberClientBase as E, type FindManyArgs as F, type GroupByArgs as G, type IncludeInput as I, type ModelDelegate as M, type OrderByInput as O, QueryEngine as Q, type ResultFieldExtension as R, type SqlDriver as S, type TransactionContext as T, type UpdateArgs as U, type WhereInput as W, type TransactionOptions as a, type SqlValue as b, type SqlDialect as c, type ClientOptions as d, type CreateArgs as e, type DeleteArgs as f, type FindUniqueArgs as g, FirebirdDialect as h, type IsolationLevel as i, type SelectInput as j, type UpsertArgs as k, createClient as l, type EmberExtensionArgs as m, type Middleware as n, type QueryEvent as o, type QueryHook as p, type QueryHookParams as q, type QueryLogger as r };