@vibeorm/runtime 1.3.0 → 2.0.0-alpha.2

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 (44) hide show
  1. package/README.md +50 -107
  2. package/dist/adapter.d.ts +124 -0
  3. package/dist/adapter.d.ts.map +1 -0
  4. package/dist/client.d.ts +152 -0
  5. package/dist/client.d.ts.map +1 -0
  6. package/dist/codecs.d.ts +170 -0
  7. package/dist/codecs.d.ts.map +1 -0
  8. package/dist/computed.d.ts +43 -0
  9. package/dist/computed.d.ts.map +1 -0
  10. package/dist/extensions.d.ts +102 -0
  11. package/dist/extensions.d.ts.map +1 -0
  12. package/dist/index.d.ts +29 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +6625 -0
  15. package/dist/index.js.map +21 -0
  16. package/dist/model-meta.d.ts +156 -0
  17. package/dist/model-meta.d.ts.map +1 -0
  18. package/dist/nested-writes.d.ts +100 -0
  19. package/dist/nested-writes.d.ts.map +1 -0
  20. package/dist/query-builder.d.ts +250 -0
  21. package/dist/query-builder.d.ts.map +1 -0
  22. package/dist/relation-loader.d.ts +75 -0
  23. package/dist/relation-loader.d.ts.map +1 -0
  24. package/dist/relation-plan.d.ts +103 -0
  25. package/dist/relation-plan.d.ts.map +1 -0
  26. package/dist/render-cache.d.ts +48 -0
  27. package/dist/render-cache.d.ts.map +1 -0
  28. package/dist/views.d.ts +97 -0
  29. package/dist/views.d.ts.map +1 -0
  30. package/package.json +31 -26
  31. package/src/adapter.ts +0 -146
  32. package/src/client.ts +0 -2172
  33. package/src/coerce.ts +0 -184
  34. package/src/count-loader.ts +0 -152
  35. package/src/errors.ts +0 -492
  36. package/src/id-generators.ts +0 -151
  37. package/src/index.ts +0 -55
  38. package/src/lateral-join-builder.ts +0 -1053
  39. package/src/query-builder.ts +0 -1832
  40. package/src/relation-loader.ts +0 -534
  41. package/src/retry.ts +0 -183
  42. package/src/types.ts +0 -317
  43. package/src/view.ts +0 -629
  44. package/src/where-builder.ts +0 -772
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Relation RESOLUTION: `select`/`include` args → a validated relation tree,
3
+ * plus the structural link (FK fields, join table) each relation loads through.
4
+ *
5
+ * Pure structure — no SQL, no execution. The query builder consumes this to
6
+ * gate strategies and augment projections at build time (the earliest knowable
7
+ * moment); the relation loader consumes it to run and stitch.
8
+ *
9
+ * v1 semantics carried:
10
+ * - `select: { rel: … }` and `include: { rel: … }` both load; `include` wins
11
+ * when both name the same relation.
12
+ * - `_count` uses the v1 shape: `include._count: true | { select: { rel: true } }`
13
+ * (or under `select`), counts LIST relations only, and supports no `where`.
14
+ * - Implicit many-to-many resolves through the ONE shared join-table rule
15
+ * (`implicitJoinTable` in @vibeorm/schema) — never re-derived here.
16
+ */
17
+ import type { RelationIR } from "@vibeorm/schema";
18
+ import type { FieldMeta, ModelMeta, RuntimeMeta } from "./model-meta.ts";
19
+ /** How a relation is physically wired. */
20
+ export type RelationKind =
21
+ /** Children hold the FK (`oneToMany`) — batch `WHERE fk IN (parents)`. */
22
+ "toManyFk"
23
+ /** THIS model holds the FK (`manyToOne` / owning `oneToOne`). */
24
+ | "toOneOwner"
25
+ /** The other side holds the FK (non-owning `oneToOne`). */
26
+ | "toOneInverse"
27
+ /** Implicit join table (`manyToMany`). */
28
+ | "manyToMany";
29
+ /** The resolved physical link for one relation. */
30
+ export type RelationLink = {
31
+ readonly kind: RelationKind;
32
+ readonly relation: RelationIR;
33
+ readonly target: ModelMeta;
34
+ /** Field on the PARENT whose values correlate the two sides. */
35
+ readonly parentKey: FieldMeta;
36
+ /** Field on the CHILD whose values match `parentKey`'s. */
37
+ readonly childKey: FieldMeta;
38
+ /** Join-table wiring; `null` unless kind is `manyToMany`. */
39
+ readonly join: {
40
+ readonly tableName: string;
41
+ readonly parentColumn: "A" | "B";
42
+ readonly childColumn: "A" | "B";
43
+ } | null;
44
+ };
45
+ /** Nested args for one relation to load, validated. */
46
+ export type RelationArgs = {
47
+ readonly where: Record<string, unknown> | undefined;
48
+ readonly orderBy: unknown;
49
+ readonly take: number | undefined;
50
+ readonly skip: number | undefined;
51
+ /** Child scalar fields the CALLER asked for, or `null` for all scalars. */
52
+ readonly select: readonly string[] | null;
53
+ /** SQL projection: `select` plus stitching keys — what the child statement fetches. */
54
+ readonly projected: readonly string[] | null;
55
+ /** Fields in `projected` the caller did NOT ask for — deleted after stitching. */
56
+ readonly strip: readonly string[];
57
+ /** Computed fields to attach to loaded children, or `null` — resolved like the top level. */
58
+ readonly computed: readonly string[] | null;
59
+ /** Deeper relation levels under this one. */
60
+ readonly nested: RelationSelection | null;
61
+ };
62
+ export type RelationTreeNode = {
63
+ /** Relation field name on the parent (`posts`). */
64
+ readonly name: string;
65
+ readonly link: RelationLink;
66
+ readonly args: RelationArgs;
67
+ };
68
+ /** Everything relation-shaped one query level asked for. */
69
+ export type RelationSelection = {
70
+ readonly relations: readonly RelationTreeNode[];
71
+ /** List-relation names to count into `_count`. */
72
+ readonly counts: readonly string[];
73
+ };
74
+ /** Resolve how one relation is physically wired. */
75
+ export declare function resolveRelationLink(params: {
76
+ meta: RuntimeMeta;
77
+ model: ModelMeta;
78
+ relation: RelationIR;
79
+ }): RelationLink;
80
+ /**
81
+ * The parent-side fields a selection needs for stitching: each relation's
82
+ * `parentKey`, and each counted relation's `parentKey`.
83
+ */
84
+ export declare function requiredParentFields(params: {
85
+ meta: RuntimeMeta;
86
+ model: ModelMeta;
87
+ selection: RelationSelection;
88
+ }): string[];
89
+ /**
90
+ * Resolve everything relation-shaped in one level's `select`/`include`.
91
+ * Returns `null` when neither names a relation or `_count`.
92
+ *
93
+ * Scalar keys in `select` are ignored here (the query builder projects them);
94
+ * every key in `include` must be a relation or `_count` — anything else is a
95
+ * loud validation error.
96
+ */
97
+ export declare function resolveRelationSelection(params: {
98
+ meta: RuntimeMeta;
99
+ model: ModelMeta;
100
+ select: unknown;
101
+ include: unknown;
102
+ }): RelationSelection | null;
103
+ //# sourceMappingURL=relation-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-plan.d.ts","sourceRoot":"","sources":["../src/relation-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The compiled-query cache — §9's "query-shape cache (structural hash → SQL
3
+ * skeleton)", constitution rule 8 (perf) under rule 3's constraint: the SQL
4
+ * text is ALWAYS the renderer's, byte-identical — this module never builds SQL.
5
+ *
6
+ * How it works: a statement AST is walked ONCE, producing (a) a structural key
7
+ * covering everything that affects the rendered text — kinds, identifiers,
8
+ * operators, flags, literal LIMIT/OFFSET, arity where a dialect expands
9
+ * placeholders per element — and (b) the parameter values in exactly the
10
+ * renderer's collection order. A key hit reuses the cached text with the fresh
11
+ * values; a miss renders for real and caches the text.
12
+ *
13
+ * SAFETY: the walk mirrors @vibeorm/sql's render traversal. Two guards keep a
14
+ * divergence from ever mis-binding parameters:
15
+ * 1. every MISS cross-checks the walked values against the renderer's
16
+ * collected values (element-wise); a mismatch poisons the key so that
17
+ * shape renders uncached forever, and
18
+ * 2. constructs with dialect-conditional value branching that is not worth
19
+ * mirroring (jsonFilter) are declared uncacheable outright.
20
+ * The cache is invalidation-free by construction: the key IS the shape, and
21
+ * equal shapes render equal text (shape-purity). Statement ASTs are treated as
22
+ * immutable by the whole runtime, so cached texts can never go stale.
23
+ */
24
+ import type { RenderedQuery, SqlDialect, SqlStatement } from "@vibeorm/sql";
25
+ type CachedText = {
26
+ readonly text: string;
27
+ readonly returning: "native" | "omitted" | "none";
28
+ };
29
+ /** `null` = poisoned: this shape verified unsafe once — never cache it. */
30
+ type CacheSlot = CachedText | null;
31
+ /** One per client (dialect-stable); shared across its transaction clients. */
32
+ export declare class StatementRenderCache {
33
+ private readonly entries;
34
+ get(key: string): CacheSlot | undefined;
35
+ set(key: string, slot: CacheSlot): void;
36
+ }
37
+ /**
38
+ * Render through the shape cache: hit = cached text + freshly walked values;
39
+ * miss = real render, cross-checked against the walk before caching. Anything
40
+ * uncacheable (or a verification failure — poisoned) renders directly.
41
+ */
42
+ export declare function renderStatementCached(params: {
43
+ dialect: SqlDialect;
44
+ statement: SqlStatement;
45
+ cache: StatementRenderCache;
46
+ }): RenderedQuery;
47
+ export {};
48
+ //# sourceMappingURL=render-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-cache.d.ts","sourceRoot":"","sources":["../src/render-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,KAAK,EAMV,aAAa,EAEb,UAAU,EAEV,YAAY,EAGb,MAAM,cAAc,CAAC;AAItB,KAAK,UAAU,GAAG;IAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CACnD,CAAC;AAEF,2EAA2E;AAC3E,KAAK,SAAS,GAAG,UAAU,GAAG,IAAI,CAAC;AAInC,8EAA8E;AAC9E,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAIvC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;CAMxC;AA2aD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,OAAO,EAAE,UAAU,CAAC;IACpB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,EAAE,oBAAoB,CAAC;CAC7B,GAAG,aAAa,CAoBhB"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Field-masking views — the v1 `db.defineView()` surface ported to v2
3
+ * (board #11), renamed `$defineView` per v2's $-prefixed client-name rule.
4
+ *
5
+ * A view is a READ-ONLY scoped client over the models named in its definition.
6
+ * Rows come back as `ViewResult` instances that expose only the definition's
7
+ * fields; `reveal: { field: true }` makes an extra field readable as a
8
+ * property while `JSON.stringify` still excludes it, and `$unsafe()` returns
9
+ * everything. Relations load normally: when the related model is ALSO in the
10
+ * definition its rows are masked recursively; when it is not, they pass
11
+ * through untouched (v1 semantics).
12
+ *
13
+ * Isolated by design: this module wraps the public delegate surface
14
+ * (`client.$models`) and never reaches into the query builder — the same SQL
15
+ * runs, the ARGS are rewritten (definition fields become a `select`) and the
16
+ * RESULT objects are wrapped.
17
+ *
18
+ * v1 → v2 deltas (documented in apps/tests/parity-fragments/views.md):
19
+ * - `defineView` → `$defineView`; errors are `VibeError` codes, not strings.
20
+ * - The definition is validated eagerly (unknown model / unknown field /
21
+ * empty field set throw `VIBE_VALIDATION` at definition time).
22
+ * - Write verbs exist on the view delegate but throw `VIBE_VALIDATION`
23
+ * (mirroring v2's database-view read-only contract) — v1 left them
24
+ * `undefined`.
25
+ * - A nested `include` under a masked relation stays masked (v1 dropped the
26
+ * restriction one level down); `omit` on a view query is refused loudly
27
+ * (v1 stripped it silently).
28
+ */
29
+ import type { ClientRow, ModelDelegate } from "./client.ts";
30
+ import type { RuntimeMeta } from "./model-meta.ts";
31
+ /**
32
+ * A view definition: client-name model keys → the set of visible fields.
33
+ * Example: `{ user: { id: true, name: true }, post: { id: true, title: true } }`.
34
+ */
35
+ export type ViewDefinition = Record<string, Record<string, boolean | undefined>>;
36
+ /** The read surface of one model under a view — writes throw `VIBE_VALIDATION`. */
37
+ export type ViewModelDelegate = {
38
+ readonly findMany: (args?: ClientRow) => Promise<ViewResult[]>;
39
+ readonly findFirst: (args?: ClientRow) => Promise<ViewResult | null>;
40
+ readonly findFirstOrThrow: (args?: ClientRow) => Promise<ViewResult>;
41
+ readonly findUnique: (args: ClientRow) => Promise<ViewResult | null>;
42
+ readonly findUniqueOrThrow: (args: ClientRow) => Promise<ViewResult>;
43
+ readonly count: (args?: ClientRow) => Promise<number | Record<string, number>>;
44
+ readonly aggregate: (args: ClientRow) => Promise<ClientRow>;
45
+ readonly groupBy: (args: ClientRow) => Promise<ClientRow[]>;
46
+ } & Record<string, unknown>;
47
+ /** What `$defineView` returns at the runtime level — the generated d.ts narrows it. */
48
+ export type ViewClientShape = Record<string, ViewModelDelegate>;
49
+ /** The `$defineView` client method (runtime-level shape). */
50
+ export type DefineViewFn = (options: {
51
+ readonly name: string;
52
+ readonly definition: ViewDefinition;
53
+ }) => ViewClientShape;
54
+ /**
55
+ * A masked row: visible + revealed fields are enumerable own properties,
56
+ * `toJSON()` (used by `JSON.stringify`) drops revealed fields recursively,
57
+ * `$unsafe()` returns a plain object with everything. Class methods are
58
+ * prototype members, so they never show up in `Object.keys` / spread.
59
+ */
60
+ export declare class ViewResult {
61
+ /** Dynamic property access for view/revealed/relation fields. */
62
+ [key: string]: unknown;
63
+ /** @internal Field names revealed on this row (non-enumerable). */
64
+ readonly _revealed: ReadonlySet<string>;
65
+ constructor(params: {
66
+ record: Readonly<Record<string, unknown>>;
67
+ /** Every key to expose as a property (fields + revealed + relations). */
68
+ expose: ReadonlySet<string>;
69
+ revealed: ReadonlySet<string>;
70
+ });
71
+ /** Plain object WITHOUT revealed fields (what `JSON.stringify` sees), recursively. */
72
+ toJSON(): Record<string, unknown>;
73
+ /** Plain object with ALL fields (view + revealed), recursively — the escape hatch. */
74
+ $unsafe(): Record<string, unknown>;
75
+ }
76
+ /**
77
+ * Build a field-masking view client over an existing client's delegates.
78
+ *
79
+ * @throws VibeError `VIBE_VALIDATION` on an invalid definition (unknown model,
80
+ * unknown or relation field, empty field set).
81
+ */
82
+ export declare function createView(params: {
83
+ meta: RuntimeMeta;
84
+ models: Readonly<Record<string, ModelDelegate>>;
85
+ name: string;
86
+ definition: ViewDefinition;
87
+ }): ViewClientShape;
88
+ /**
89
+ * Attach `$defineView` to a built client (called by `buildClient`; transaction
90
+ * clients get their own attachment because `$transaction` rebuilds the client).
91
+ */
92
+ export declare function attachDefineView(params: {
93
+ client: object;
94
+ meta: RuntimeMeta;
95
+ models: Readonly<Record<string, ModelDelegate>>;
96
+ }): void;
97
+ //# sourceMappingURL=views.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../src/views.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,45 +1,50 @@
1
1
  {
2
2
  "name": "@vibeorm/runtime",
3
- "version": "1.3.0",
4
- "description": "Driver-agnostic query engine and client runtime for VibeORM",
5
- "license": "MIT",
3
+ "version": "2.0.0-alpha.2",
4
+ "description": "Driver-agnostic query engine and client runtime for VibeORM v2",
6
5
  "keywords": [
7
6
  "orm",
8
- "runtime",
9
- "query-builder",
10
- "bun",
11
7
  "typescript",
12
- "postgresql"
8
+ "sql",
9
+ "database",
10
+ "bun",
11
+ "type-safe",
12
+ "query-builder",
13
+ "client",
14
+ "adapter",
15
+ "relations"
13
16
  ],
14
- "type": "module",
15
- "exports": {
16
- ".": {
17
- "default": "./src/index.ts",
18
- "types": "./src/index.ts"
19
- }
17
+ "homepage": "https://github.com/vibeorm/vibeorm/tree/master/packages/runtime#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/vibeorm/vibeorm/issues"
20
20
  },
21
- "files": [
22
- "src"
23
- ],
24
21
  "repository": {
25
22
  "type": "git",
26
23
  "url": "https://github.com/vibeorm/vibeorm.git",
27
24
  "directory": "packages/runtime"
28
25
  },
29
- "homepage": "https://github.com/vibeorm/vibeorm/tree/master/packages/runtime",
30
- "bugs": {
31
- "url": "https://github.com/vibeorm/vibeorm/issues"
26
+ "license": "MIT",
27
+ "author": "VibeORM contributors",
28
+ "type": "module",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "default": "./dist/index.js"
33
+ }
32
34
  },
35
+ "files": [
36
+ "dist",
37
+ "README.md"
38
+ ],
33
39
  "engines": {
34
- "bun": ">=1.1.0"
40
+ "bun": ">=1.2.0"
35
41
  },
36
- "peerDependencies": {
37
- "zod": ">=4"
42
+ "dependencies": {
43
+ "@vibeorm/schema": "2.0.0-alpha.2",
44
+ "@vibeorm/sql": "2.0.0-alpha.2"
38
45
  },
39
- "peerDependenciesMeta": {
40
- "zod": {
41
- "optional": true
42
- }
46
+ "devDependencies": {
47
+ "@electric-sql/pglite": "^0.3.0"
43
48
  },
44
49
  "publishConfig": {
45
50
  "access": "public"
package/src/adapter.ts DELETED
@@ -1,146 +0,0 @@
1
- /**
2
- * Database adapter interface for VibeORM.
3
- *
4
- * Each adapter implementation (bun:sql, pg, etc.) provides a concrete
5
- * implementation of this interface. The runtime is completely driver-agnostic
6
- * and interacts with the database exclusively through this contract.
7
- */
8
-
9
- // ─── Transaction Options ──────────────────────────────────────────
10
-
11
- /**
12
- * Options for controlling transaction behavior.
13
- *
14
- * @example
15
- * ```ts
16
- * await db.$transaction(async (tx) => {
17
- * await tx.account.update({ where: { id: 1 }, data: { balance: { decrement: 100 } } });
18
- * await tx.account.update({ where: { id: 2 }, data: { balance: { increment: 100 } } });
19
- * }, { isolationLevel: "Serializable", timeout: 5000 });
20
- * ```
21
- */
22
- export type TransactionOptions = {
23
- /**
24
- * PostgreSQL isolation level for the transaction.
25
- * - "ReadCommitted" (default): Standard PostgreSQL default.
26
- * - "RepeatableRead": Prevents non-repeatable reads.
27
- * - "Serializable": Full serializability — conflicts throw serialization_failure.
28
- */
29
- isolationLevel?: "ReadCommitted" | "RepeatableRead" | "Serializable";
30
- /**
31
- * Maximum time in milliseconds the transaction may run before being cancelled.
32
- * Implemented via `SET LOCAL statement_timeout = N` inside the transaction,
33
- * so it is scoped to the transaction and does not affect other connections.
34
- */
35
- timeout?: number;
36
- };
37
-
38
- // ─── Core Adapter Interface ───────────────────────────────────────
39
-
40
- /**
41
- * The primary interface that every database adapter must implement.
42
- * Adapters own connection management, query execution, statement caching,
43
- * transactions, and driver-specific parameter formatting.
44
- */
45
- export type DatabaseAdapter = {
46
- /**
47
- * Execute a parameterized query and return rows.
48
- * The adapter owns statement caching and driver-specific optimizations.
49
- *
50
- * For bun:sql this means synthetic tagged template caching.
51
- * For pg this means named prepared statement caching.
52
- */
53
- execute(params: { text: string; values: unknown[] }): Promise<Record<string, unknown>[]>;
54
-
55
- /**
56
- * Execute a raw/unsafe query without prepared statement caching.
57
- * Used for `$queryRawUnsafe`, `$executeRawUnsafe`, and dynamic DDL.
58
- *
59
- * Returns both rows and affected row count (for INSERT/UPDATE/DELETE).
60
- */
61
- executeUnsafe(params: {
62
- text: string;
63
- values?: unknown[];
64
- }): Promise<QueryResult>;
65
-
66
- /**
67
- * Run a function inside a database transaction.
68
- * The callback receives a transactional adapter with the same interface.
69
- * If the callback throws, the transaction is automatically rolled back.
70
- *
71
- * @param fn - The transactional callback.
72
- * @param options - Optional isolation level and timeout.
73
- */
74
- transaction<T>(fn: (txAdapter: DatabaseAdapter) => Promise<T>, options?: TransactionOptions): Promise<T>;
75
-
76
- /**
77
- * Eagerly warm up the connection pool.
78
- * Forces at least one TCP handshake + auth so subsequent queries start instantly.
79
- */
80
- connect(): Promise<void>;
81
-
82
- /**
83
- * Gracefully close all connections in the pool.
84
- */
85
- disconnect(): Promise<void>;
86
-
87
- /**
88
- * Convert a JS array to the driver's preferred format for `= ANY($N)` queries.
89
- *
90
- * - **bun:sql**: Returns a PG array literal string `"{val1,val2,val3}"` because
91
- * bun:sql's extended query protocol sends values as strings.
92
- * - **pg**: Returns the raw JS array (pg driver handles native array serialization).
93
- */
94
- formatArrayParam(values: unknown[]): unknown;
95
- };
96
-
97
- // ─── Query Result ─────────────────────────────────────────────────
98
-
99
- /**
100
- * Result from an unsafe query execution.
101
- * Contains both the rows returned and the number of affected rows
102
- * (parsed from the PostgreSQL CommandComplete tag).
103
- */
104
- export type QueryResult = {
105
- rows: Record<string, unknown>[];
106
- affectedRows: number;
107
- };
108
-
109
- // ─── SQL Executor (Migration Compatibility) ───────────────────────
110
-
111
- /**
112
- * Minimal SQL execution interface compatible with `@vibeorm/migrate`.
113
- * Adapters expose this via a helper function so migrations can run
114
- * without knowing which adapter is in use.
115
- *
116
- * @example
117
- * ```ts
118
- * import { bunAdapter } from "@vibeorm/adapter-bun";
119
- * import { toSqlExecutor } from "@vibeorm/runtime";
120
- *
121
- * const adapter = bunAdapter({ url: "postgres://..." });
122
- * const executor = toSqlExecutor({ adapter });
123
- * await applyMigration({ executor, migrationName: "init", sql, checksum });
124
- * ```
125
- */
126
- export type SqlExecutor = (params: {
127
- text: string;
128
- values?: unknown[];
129
- }) => Promise<Record<string, unknown>[]>;
130
-
131
- /**
132
- * Create an SqlExecutor from a DatabaseAdapter.
133
- * Bridges the adapter pattern with the migrate package's SqlExecutor interface.
134
- */
135
- export function toSqlExecutor(params: {
136
- adapter: DatabaseAdapter;
137
- }): SqlExecutor {
138
- const { adapter } = params;
139
- return async (queryParams) => {
140
- const result = await adapter.executeUnsafe({
141
- text: queryParams.text,
142
- values: queryParams.values,
143
- });
144
- return result.rows;
145
- };
146
- }