@stacksjs/query-builder 0.70.166 → 0.70.168
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.ts +132 -0
- package/package.json +4 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { createQueryBuilder as createBunQueryBuilder } from 'bun-query-builder';
|
|
2
|
+
import * as bunQueryBuilder from 'bun-query-builder';
|
|
3
|
+
import type { DatabaseSchema } from 'bun-query-builder';
|
|
4
|
+
/**
|
|
5
|
+
* Apply the bootstrap pragmas to the connection of the CURRENT process-wide
|
|
6
|
+
* config. bun-query-builder's `qb.unsafe()` routes through its global
|
|
7
|
+
* lazily-resolved connection — NOT the instance's captured one — so this
|
|
8
|
+
* only targets `instance`'s connection when called in the same synchronous
|
|
9
|
+
* tick as `createQueryBuilder()`, before any intervening `setConfig()` can
|
|
10
|
+
* swap the signature-keyed singleton. The wrapped `createQueryBuilder`
|
|
11
|
+
* below guarantees that ordering structurally; standalone callers must
|
|
12
|
+
* preserve it themselves.
|
|
13
|
+
*/
|
|
14
|
+
export declare function applySqlitePragmas(instance: { unsafe: (query: string, params?: any[]) => any }): void;
|
|
15
|
+
/**
|
|
16
|
+
* Bootstrap the MODEL-EXECUTOR connection — the raw `bun:sqlite` `Database`
|
|
17
|
+
* that `Model.create()/save()/delete()` (createModel → getExecutor) write
|
|
18
|
+
* through. Upstream creates it with `new Database(path)` and applies no
|
|
19
|
+
* pragmas whatsoever, so without this the ORM write path runs with
|
|
20
|
+
* `foreign_keys = OFF` (silent orphan rows) and default WAL checkpointing
|
|
21
|
+
* regardless of what the query-builder connection was bootstrapped with.
|
|
22
|
+
*
|
|
23
|
+
* `getDatabase()` returns the executor's live handle for the sqlite dialect
|
|
24
|
+
* (creating the executor if needed) and throws for mysql/postgres — where
|
|
25
|
+
* there is nothing to bootstrap, hence the silent catch. Safe to call
|
|
26
|
+
* repeatedly: the WeakSet makes it a no-op after the first hit per
|
|
27
|
+
* connection, and a config change that swaps the executor's Database
|
|
28
|
+
* produces a fresh (unseen) handle that gets bootstrapped on the next call.
|
|
29
|
+
*/
|
|
30
|
+
export declare function bootstrapModelExecutorPragmas(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Drop-in replacement for bun-query-builder's `configureOrm` that
|
|
33
|
+
* bootstraps the model-executor connection it (re)creates.
|
|
34
|
+
*
|
|
35
|
+
* This is the exact entry point `@stacksjs/orm` calls at import time
|
|
36
|
+
* (`autoConfigureOrm()`), which in production builds the raw `Database`
|
|
37
|
+
* every model write goes through — pre-fix, with no pragmas at all.
|
|
38
|
+
*/
|
|
39
|
+
export declare function configureOrm(options: Parameters<typeof bunQueryBuilder.configureOrm>[0]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Drop-in replacement for bun-query-builder's `createQueryBuilder` that
|
|
42
|
+
* bootstraps every fresh SQLite connection with the pragmas above.
|
|
43
|
+
*
|
|
44
|
+
* The upstream builder captures its connection eagerly at creation
|
|
45
|
+
* (`state?.sql ?? getOrCreateBunSql()`) and its `SQLiteWrapper` only sets
|
|
46
|
+
* `journal_mode = WAL` — never `foreign_keys` — so any instance created
|
|
47
|
+
* outside this wrapper runs with FK enforcement off. Applying in the same
|
|
48
|
+
* synchronous tick as creation pins the pragmas to the exact connection the
|
|
49
|
+
* instance captured (see `applySqlitePragmas`). Skipped when the caller
|
|
50
|
+
* supplies its own `state.sql` (reserved/transaction connections derive
|
|
51
|
+
* from an already-bootstrapped parent).
|
|
52
|
+
*
|
|
53
|
+
* Also re-asserts the model-executor bootstrap: framework entry points run
|
|
54
|
+
* through here on boot and on config reloads, so an executor Database that
|
|
55
|
+
* was lazily (re)created from a config change gets its pragmas without any
|
|
56
|
+
* caller having to know the two-connection topology.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createQueryBuilder<DB extends DatabaseSchema<any> = DatabaseSchema<any>>(state?: Parameters<typeof createBunQueryBuilder>[0]): ReturnType<typeof createBunQueryBuilder<DB>>;
|
|
59
|
+
/**
|
|
60
|
+
* Register a model with bun-query-builder when the installed version
|
|
61
|
+
* exposes that hook, or fall back to `defineModel()` for older releases.
|
|
62
|
+
*/
|
|
63
|
+
export declare function registerModel(name: string, model: unknown): unknown;
|
|
64
|
+
/**
|
|
65
|
+
* Validate a single SQL identifier (column, table, or alias name).
|
|
66
|
+
*
|
|
67
|
+
* - Must match `SAFE_IDENTIFIER` (letters/digits/underscores; must
|
|
68
|
+
* start with letter or underscore).
|
|
69
|
+
* - Must be ≤ 64 characters (matches MySQL's identifier limit; the
|
|
70
|
+
* shortest cap across supported dialects).
|
|
71
|
+
* - When `allowlist` is provided, the value must appear in it. Use
|
|
72
|
+
* this with a model's known column names (`Object.keys(definition.attributes)`)
|
|
73
|
+
* so a query that builds column names from `req.query.sortBy` etc.
|
|
74
|
+
* can't smuggle anything past the schema.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```ts
|
|
78
|
+
* import { assertSafeIdentifier } from '@stacksjs/query-builder'
|
|
79
|
+
*
|
|
80
|
+
* const sortBy = req.query.sortBy as string
|
|
81
|
+
* assertSafeIdentifier(sortBy, { allowlist: ['name', 'email', 'created_at'] })
|
|
82
|
+
* Model.orderBy(sortBy as keyof Model)
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export declare function validateIdentifier(value: unknown, opts?: { allowlist?: readonly string[] }): IdentifierValidation;
|
|
86
|
+
/**
|
|
87
|
+
* Throwing variant of {@link validateIdentifier}. Use at the boundary
|
|
88
|
+
* where user input meets SQL identifier interpolation.
|
|
89
|
+
*
|
|
90
|
+
* @throws {Error} when the value isn't a safe identifier.
|
|
91
|
+
*/
|
|
92
|
+
export declare function assertSafeIdentifier(value: unknown, opts?: { allowlist?: readonly string[], context?: string }): asserts value is string;
|
|
93
|
+
export declare function isSafeOperator(op: unknown): op is string;
|
|
94
|
+
export declare function assertSafeOperator(op: unknown, context?: string): asserts op is string;
|
|
95
|
+
/**
|
|
96
|
+
* Per-connection SQLite bootstrap pragmas (stacksjs/stacks#1951).
|
|
97
|
+
* `foreign_keys` does not persist in the database file — SQLite ships with
|
|
98
|
+
* enforcement OFF on every new connection — so the inline
|
|
99
|
+
* `REFERENCES … ON DELETE CASCADE` emitted by migrations (#1916) is inert
|
|
100
|
+
* unless the connection bootstrap turns it on. bun-query-builder delegates
|
|
101
|
+
* this to the consumer, and it opens sqlite connections in TWO independent
|
|
102
|
+
* layers — both are bootstrapped here:
|
|
103
|
+
*
|
|
104
|
+
* 1. The query-builder connection (`getOrCreateBunSql` → `SQLiteWrapper`,
|
|
105
|
+
* which only sets `journal_mode = WAL`): covered by the wrapped
|
|
106
|
+
* `createQueryBuilder` below.
|
|
107
|
+
* 2. The MODEL-EXECUTOR connection (`configureOrm`/`getExecutor` → a raw
|
|
108
|
+
* `bun:sqlite` `Database` with NO pragmas at all) — the connection every
|
|
109
|
+
* `Model.create()/save()/delete()` actually writes through: covered by
|
|
110
|
+
* the wrapped `configureOrm` + `bootstrapModelExecutorPragmas` below.
|
|
111
|
+
* Pre-fix, production model writes ran with `foreign_keys = OFF` while
|
|
112
|
+
* the (idle) query-builder connection was correctly bootstrapped —
|
|
113
|
+
* confirmed on a live deploy via lsof (two connections) and WAL frames
|
|
114
|
+
* from ORM inserts never auto-checkpointing.
|
|
115
|
+
*/
|
|
116
|
+
export declare const SQLITE_BOOTSTRAP_PRAGMAS: readonly [unknown, unknown, unknown, unknown];
|
|
117
|
+
/**
|
|
118
|
+
* Return value of `validateIdentifier` / `assertSafeIdentifier`.
|
|
119
|
+
*/
|
|
120
|
+
export declare interface IdentifierValidation {
|
|
121
|
+
valid: boolean
|
|
122
|
+
reason?: 'invalid-shape' | 'not-in-allowlist' | 'empty' | 'too-long'
|
|
123
|
+
}
|
|
124
|
+
export type StacksDialect = import('bun-query-builder').SupportedDialect | 'singlestore';
|
|
125
|
+
// bun-query-builder types `unsafe()` as returning `Promise<any>`, but at
|
|
126
|
+
// runtime it returns a Bun SQL Statement that has `.execute()`.
|
|
127
|
+
declare type UnsafeReturn = Promise<any> & { execute: () => Promise<any> }
|
|
128
|
+
// Re-export everything from bun-query-builder
|
|
129
|
+
export * from 'bun-query-builder';
|
|
130
|
+
export { saveMigrationSnapshot } from 'bun-query-builder';
|
|
131
|
+
// For backwards compatibility, export QueryBuilder as an alias
|
|
132
|
+
export { createQueryBuilder as QueryBuilder };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/query-builder",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.70.
|
|
5
|
+
"version": "0.70.168",
|
|
6
6
|
"description": "The Stacks Query Builder integration",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"prepublishOnly": "bun run build"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
-
"@stacksjs/database": "0.70.
|
|
54
|
+
"@stacksjs/database": "0.70.168",
|
|
55
55
|
"better-dx": "^0.2.17",
|
|
56
|
-
"@stacksjs/types": "0.70.
|
|
56
|
+
"@stacksjs/types": "0.70.168"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"bun-query-builder": "^0.1.
|
|
59
|
+
"bun-query-builder": "^0.1.58"
|
|
60
60
|
}
|
|
61
61
|
}
|