@stacksjs/database 0.70.87 → 0.70.88

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 (39) hide show
  1. package/package.json +10 -10
  2. package/dist/auth-tables.d.ts +0 -60
  3. package/dist/class-seeder.d.ts +0 -65
  4. package/dist/custom/audits.d.ts +0 -16
  5. package/dist/custom/errors.d.ts +0 -1
  6. package/dist/custom/index.d.ts +0 -3
  7. package/dist/custom/jobs.d.ts +0 -3
  8. package/dist/database.d.ts +0 -89
  9. package/dist/defaults.d.ts +0 -48
  10. package/dist/driver-config.d.ts +0 -149
  11. package/dist/drivers/defaults/index.d.ts +0 -2
  12. package/dist/drivers/defaults/passwords.d.ts +0 -4
  13. package/dist/drivers/defaults/traits.d.ts +0 -33
  14. package/dist/drivers/dynamodb.d.ts +0 -200
  15. package/dist/drivers/helpers.d.ts +0 -35
  16. package/dist/drivers/index.d.ts +0 -16
  17. package/dist/drivers/mysql.d.ts +0 -7
  18. package/dist/drivers/postgres.d.ts +0 -7
  19. package/dist/drivers/sqlite.d.ts +0 -20
  20. package/dist/factory.d.ts +0 -41
  21. package/dist/fk-audit.d.ts +0 -101
  22. package/dist/index.d.ts +0 -149
  23. package/dist/index.js +0 -1263
  24. package/dist/migration-lock.d.ts +0 -23
  25. package/dist/migrations.d.ts +0 -76
  26. package/dist/notification-tables.d.ts +0 -20
  27. package/dist/query-logger.d.ts +0 -26
  28. package/dist/query-parser.d.ts +0 -4
  29. package/dist/rbac-tables.d.ts +0 -17
  30. package/dist/safe-migrations.d.ts +0 -72
  31. package/dist/seed-scaffold.d.ts +0 -34
  32. package/dist/seeder.d.ts +0 -116
  33. package/dist/sql-helpers.d.ts +0 -33
  34. package/dist/transaction-context.d.ts +0 -52
  35. package/dist/types.d.ts +0 -151
  36. package/dist/unique-audit.d.ts +0 -60
  37. package/dist/utils.d.ts +0 -189
  38. package/dist/uuid-columns.d.ts +0 -22
  39. package/dist/validators.d.ts +0 -26
@@ -1,23 +0,0 @@
1
- /**
2
- * Acquire the distributed migration lock for the given dialect.
3
- * Returns a handle whose `release()` method MUST be called in a
4
- * `finally` to free the lock — even on error paths.
5
- *
6
- * @param dialect - which database driver is being migrated against
7
- * @param adminDb - the bun-query-builder connection to issue lock SQL
8
- * through (PG / MySQL). Ignored for SQLite.
9
- * @param opts.timeoutMs - max time to wait for an existing holder
10
- * @param opts.sqliteLockPath - override the file path SQLite uses
11
- *
12
- * Throws an error if the lock can't be acquired within `timeoutMs`.
13
- */
14
- export declare function acquireMigrationLock(dialect: Dialect, adminDb: { unsafe: (sql: string) => Promise<unknown> } | null, opts?: { timeoutMs?: number, sqliteLockPath?: string }): Promise<MigrationLockHandle>;
15
- /**
16
- * Returned by `acquireMigrationLock()`. Callers MUST invoke `release`
17
- * in a finally block; the lock is process-external (file, advisory,
18
- * or named) so leaking it strands future migration runs.
19
- */
20
- export declare interface MigrationLockHandle {
21
- release: () => Promise<void>
22
- }
23
- export type Dialect = 'sqlite' | 'mysql' | 'postgres';
@@ -1,76 +0,0 @@
1
- import type { MigrationOperation } from '@stacksjs/query-builder';
2
- import type { Result } from '@stacksjs/error-handling';
3
- export type { MigrationResult as MigrationResultType };
4
- /**
5
- * SQLite compatibility preprocessing for migrations.
6
- *
7
- * SQLite does not support:
8
- * - ALTER TABLE ADD CONSTRAINT (foreign keys must be defined at table creation)
9
- * - CREATE TYPE ... AS ENUM (SQLite has no user-defined types; enum columns
10
- * are plain TEXT, with the allowed values enforced at the validation layer)
11
- *
12
- * Note: CREATE UNIQUE INDEX files are deliberately NOT skipped — the SQLite
13
- * dialect driver never renders inline UNIQUE in CREATE TABLE, so the
14
- * standalone index file is the only uniqueness enforcement on SQLite
15
- * (stacksjs/stacks#1952).
16
- *
17
- * Two flavours of "no-op on SQLite" need different handling:
18
- *
19
- * - **Skip-and-keep** (`skipMigration`): the file is portable — it would
20
- * run cleanly on MySQL/Postgres — but doesn't apply to SQLite. Record
21
- * it as executed in the migrations tracking table so it doesn't replay,
22
- * but **leave the file on disk** so a future `DB_CONNECTION` flip can
23
- * pick it up. This is the right path for FK constraint files.
24
- * (stacksjs/stacks#1916)
25
- *
26
- * - **Drop-and-delete** (`deleteMigration`): the file is genuinely dead
27
- * — a duplicate CREATE TABLE created by `buddy generate:migrations`
28
- * regenerating against an already-modeled table, or a DROP COLUMN
29
- * migration whose target column never existed. Removing it keeps the
30
- * directory clean and prevents future runs from re-discovering it.
31
- */
32
- export declare function preprocessSqliteMigrations(): void;
33
- /**
34
- * Run database migrations
35
- */
36
- export declare function runDatabaseMigration(): Promise<Result<string, Error>>;
37
- /**
38
- * Reset the database (drop all tables)
39
- */
40
- export declare function resetDatabase(): Promise<Result<string, Error>>;
41
- /**
42
- * Preview the pending migration as a list of structured operations WITHOUT
43
- * writing any files or advancing the snapshot. The `buddy migrate` command
44
- * uses this (in the interactive parent process) to gate destructive changes
45
- * behind confirmation before spawning the non-interactive migrate action.
46
- */
47
- export declare function previewPendingMigrations(options?: GenerateMigrationsOptions): Promise<MigrationOperation[]>;
48
- export declare function generateMigrations(options?: GenerateMigrationsOptions): Promise<Result<string, Error>>;
49
- /**
50
- * Generate fresh migrations (full regeneration, ignoring previous state)
51
- */
52
- export declare function generateMigrations2(): Promise<Result<string, Error>>;
53
- /*` definitions to the stored snapshot
54
- * (`.qb/model-snapshot.<dialect>.json`) via bun-query-builder, then — if
55
- * there are changes — writes the resulting ALTER/CREATE/DROP statements
56
- * out to a fresh file in `database/migrations/`. Each statement is
57
- * grouped by table + DDL verb and lands in its own file using the
58
- * runner's existing naming convention so it picks them up the same way
59
- * as a hand-written migration.
60
- *
61
- * Without this write step the qb generator stages the diff in memory but
62
- * the runner never sees it, so model edits silently no-op'd — defeating
63
- * the "models are the source of truth" promise.
64
- */
65
- export declare interface GenerateMigrationsOptions {
66
- applyRenames?: boolean
67
- fromDb?: boolean
68
- }
69
- /**
70
- * Migration result type for compatibility
71
- */
72
- export declare interface MigrationResult {
73
- migrationName: string
74
- direction: 'Up' | 'Down'
75
- status: 'Success' | 'Error' | 'NotExecuted'
76
- }
@@ -1,20 +0,0 @@
1
- import { sqlHelpers } from './sql-helpers';
2
- /**
3
- * `CREATE TABLE IF NOT EXISTS notifications` for the given dialect.
4
- * Pure (no execution) so the cross-dialect DDL is unit-testable.
5
- * Columns match the `DatabaseNotification` interface in
6
- * `notifications/src/drivers/database.ts`.
7
- */
8
- export declare function notificationsTableSql(sql: SqlHelpers): string;
9
- /**
10
- * `CREATE TABLE IF NOT EXISTS notification_preferences`. The
11
- * `UNIQUE (user_id, channel, category)` constraint is what makes the
12
- * preference upsert safe — matches `NotificationPreferenceRow`.
13
- */
14
- export declare function notificationPreferencesTableSql(sql: SqlHelpers): string;
15
- /**
16
- * Create the notification + notification_preferences tables. Idempotent
17
- * (`IF NOT EXISTS`), so it's safe to run on every `buddy migrate`.
18
- */
19
- export declare function migrateNotificationTables(options?: { verbose?: boolean }): Promise<{ success: boolean, error?: string }>;
20
- declare type SqlHelpers = ReturnType<typeof sqlHelpers>;
@@ -1,26 +0,0 @@
1
- export declare function setQueryTracker(fn: QueryTracker): void;
2
- /**
3
- * Process an executed query and store it in the database
4
- */
5
- export declare function logQuery(event: LogEvent): Promise<void>;
6
- /**
7
- * Query log event type - compatible with bun-query-builder hooks
8
- */
9
- declare interface LogEvent {
10
- query?: {
11
- sql?: string
12
- parameters?: unknown[]
13
- }
14
- queryDurationMillis?: number
15
- error?: Error | unknown
16
- }
17
- /**
18
- * Soft dependency on the router's query tracker. Importing it directly
19
- * creates the cycle `database → router → database` (router uses db
20
- * helpers transitively via middleware). The DI shape below lets the
21
- * router register its tracker at module-init time and lets the database
22
- * package stay leaf-node — runs that don't load the router (CLI tools,
23
- * cron tasks) silently no-op the tracker call.
24
- */
25
- // eslint-disable-next-line pickier/no-unused-vars
26
- declare type QueryTracker = (query: string, durationMs?: number, connection?: string) => void;
@@ -1,4 +0,0 @@
1
- /**
2
- * Parse and normalize a SQL query
3
- */
4
- export declare function parseQuery(sql: string): { normalized: string, type: string, tables: string[] };
@@ -1,17 +0,0 @@
1
- import { sqlHelpers } from './sql-helpers';
2
- /** `roles` table — id + name + guard + timestamps with UNIQUE(name, guard_name). */
3
- export declare function rolesTableSql(sql: SqlHelpers): string;
4
- /** `permissions` table — same shape as `roles`. */
5
- export declare function permissionsTableSql(sql: SqlHelpers): string;
6
- /** `user_roles` pivot — composite PK makes double-assign a unique violation. */
7
- export declare function userRolesTableSql(): string;
8
- /** `user_permissions` pivot. */
9
- export declare function userPermissionsTableSql(): string;
10
- /** `role_permissions` pivot. */
11
- export declare function rolePermissionsTableSql(): string;
12
- /**
13
- * Create the 5 RBAC tables. Idempotent (`IF NOT EXISTS`), so it's
14
- * safe to run on every `buddy migrate`.
15
- */
16
- export declare function migrateRbacTables(options?: { verbose?: boolean }): Promise<{ success: boolean, error?: string }>;
17
- declare type SqlHelpers = ReturnType<typeof sqlHelpers>;
@@ -1,72 +0,0 @@
1
- import { db } from './utils';
2
- /**
3
- * Add a column to `tableName` without taking a table-level lock long
4
- * enough to disrupt traffic. The column is created nullable, backfilled
5
- * in batches, and (if `notNull: true`) the constraint is added at the
6
- * end.
7
- *
8
- * Pre-conditions:
9
- * - `tableName` exists
10
- * - `columnName` does NOT already exist (this helper doesn't gracefully
11
- * handle the rerun case — wrap in `if (!columnExists)` if you need that)
12
- *
13
- * Caveats:
14
- * - SQLite doesn't support adding NOT NULL columns to existing tables
15
- * without a default; we work around it by always supplying one
16
- * - Postgres < 11 rewrites the entire table when a default is added;
17
- * this helper assumes ≥ 11
18
- *
19
- * @example
20
- * ```ts
21
- * await addColumnSafely(db, 'users', 'email_verified', {
22
- * type: 'boolean',
23
- * defaultValue: false,
24
- * notNull: true,
25
- * })
26
- * ```
27
- */
28
- export declare function addColumnSafely(db: Database, tableName: string, columnName: string, options: AddColumnSafelyOptions): Promise<void>;
29
- /**
30
- * Back-fill `columnName` with `value` for any row where it's currently
31
- * NULL. Runs in batches so the UPDATE doesn't lock the entire table.
32
- *
33
- * Useful as a standalone helper when you want to backfill an *existing*
34
- * column (e.g. populating a denormalized count) — `addColumnSafely`
35
- * uses it internally.
36
- */
37
- export declare function backfillInBatches(db: Database, tableName: string, columnName: string, value: string | number | boolean | null, batchSize?: number): Promise<void>;
38
- /**
39
- * Rename a column safely on a table that's actively serving traffic.
40
- *
41
- * Most database engines DO support `RENAME COLUMN` as a metadata-only
42
- * operation (no rewrite, no long lock), which means the headline
43
- * concern is *application-side*: app code reads the old column name,
44
- * the migration renames it, and the next request 500s.
45
- *
46
- * This helper wraps the rename in a multi-step sequence the framework
47
- * docs can teach as the canonical pattern:
48
- *
49
- * 1. Add the new column
50
- * 2. Backfill from old → new
51
- * 3. Update writes to dual-write old AND new (app-level, deploy step)
52
- * 4. Update reads to read from new (app-level, deploy step)
53
- * 5. Drop the old column (separate migration)
54
- *
55
- * For the rare case where the rename *can* happen atomically (small
56
- * table, no live traffic), pass `{ atomic: true }` and we'll just emit
57
- * the RENAME COLUMN.
58
- *
59
- * @example
60
- * ```ts
61
- * // Step 1 of the rename sequence — the rest is app-side coordination.
62
- * await renameColumnSafely(db, 'users', 'name', 'full_name', { type: 'varchar(255)' })
63
- * ```
64
- */
65
- export declare function renameColumnSafely(db: Database, tableName: string, oldName: string, newName: string, options: { type: string, atomic?: boolean }): Promise<void>;
66
- declare interface AddColumnSafelyOptions {
67
- type: string
68
- defaultValue?: string | number | boolean | null
69
- notNull?: boolean
70
- batchSize?: number
71
- }
72
- declare type Database = typeof db;
@@ -1,34 +0,0 @@
1
- /**
2
- * Remove a single `useSeeder` / `seedable` object-property from model
3
- * source text (stacksjs/stacks#1929). Brace-aware (balances nested
4
- * `{}` and skips string literals) and conservative: only strips the
5
- * documented value shapes (`true`, `false`, or a `{ … }` object). For
6
- * anything else (an identifier, a function call, a spread) it returns
7
- * `changed: false` so the caller can flag it for manual cleanup
8
- * instead of risking a mangled file.
9
- *
10
- * Exported for unit tests.
11
- */
12
- export declare function stripUseSeederTrait(source: string): { source: string, changed: boolean, skipped: boolean };
13
- /**
14
- * Walk the configured models directory, find every model whose
15
- * `traits.useSeeder` is truthy, and write a class-seeder file for it.
16
- * Returns a structured report so the CLI command can render a summary
17
- * without re-parsing log lines.
18
- */
19
- export declare function scaffoldClassSeedersFromModels(options?: ScaffoldOptions): Promise<ScaffoldResult>;
20
- /** Pure renderer — exported for unit tests. */
21
- export declare function renderSeederFile(modelName: string, modelImportPath: string, count: number): string;
22
- export declare interface ScaffoldOptions {
23
- modelsDir?: string
24
- seedersDir?: string
25
- force?: boolean
26
- dryRun?: boolean
27
- }
28
- export declare interface ScaffoldResult {
29
- generated: Array<{ model: string, file: string }>
30
- skipped: Array<{ model: string, file: string, reason: 'already-exists' | 'no-useseeder' }>
31
- errors: Array<{ model: string, error: string }>
32
- strippedTrait: Array<{ model: string, file: string }>
33
- traitStripSkipped: Array<{ model: string, file: string }>
34
- }
package/dist/seeder.d.ts DELETED
@@ -1,116 +0,0 @@
1
- import type { Attribute, Model } from '@stacksjs/types';
2
- /**
3
- * Test whether a model name is on the protected list.
4
- * Exported for downstream tooling (CI lint rules, custom seeders) so the
5
- * list stays a single source of truth.
6
- */
7
- export declare function isProtectedModel(name: string): boolean;
8
- /**
9
- * Direct entry point for `factory.generate(Model, opts)` — exported
10
- * under a distinct name so the new public API in `factory.ts` can call
11
- * into the same insert path the legacy walker uses without leaking the
12
- * `SeederModel` type. See stacksjs/stacks#1919.
13
- */
14
- export declare function seedModelDirect(model: SeederModel, options: SeederConfig): Promise<SeedResult>;
15
- /**
16
- * Main seeding function
17
- * Seeds the database using model factory functions
18
- * Loads models from both framework defaults and user-defined models,
19
- * with user models taking precedence.
20
- *
21
- * @deprecated stacksjs/stacks#1919 — the model auto-walker is no
22
- * longer invoked by `./buddy seed`. Migrate each `useSeeder` trait to
23
- * a class seeder via `./buddy seed:scaffold`, then call
24
- * `factory.generate(Model, opts)` from inside each seeder. This
25
- * function remains exported for programmatic back-compat but is
26
- * scheduled for removal.
27
- */
28
- export declare function seed(config?: SeederConfig): Promise<SeedSummary>;
29
- /**
30
- * Seed a specific model by name
31
- * Searches both default and user models
32
- */
33
- export declare function seedModel$(modelName: string, options?: { count?: number, fresh?: boolean, verbose?: boolean }): Promise<SeedResult>;
34
- /**
35
- * Fresh seed - truncate all tables and reseed
36
- */
37
- export declare function freshSeed(config?: SeederConfig): Promise<SeedSummary>;
38
- /**
39
- * Get list of seedable models without seeding
40
- * Returns models from both default and user directories
41
- */
42
- export declare function listSeedableModels(): Promise<Array<{ name: string, table: string, count: number, source: 'default' | 'user' }>>;
43
- /**
44
- * Models that touch live auth state and are unsafe to auto-seed on an
45
- * already-populated database (stacksjs/stacks#1852).
46
- *
47
- * The motivating incident: a userland `app/Models/OauthClient.ts` shipped
48
- * with the default `useSeeder: { count: 10 }` trait. Every `./buddy seed`
49
- * re-rolled the `oauth_clients` table — including the row at id=1, the
50
- * Personal Access Client whose `secret` is part of the encryption key
51
- * used to derive each issued access token's `encryptedId`. With the
52
- * secret rotated, every previously-issued token failed validation at
53
- * `decrypt(encryptedId, clientSecret)`, surfacing as a generic
54
- * "Unauthorized. Invalid token." 401 with no log line indicating what
55
- * actually happened.
56
- *
57
- * Models on this list are skipped by default. They are seeded when:
58
- *
59
- * - `fresh: true` is passed (the seeder truncates first; live tokens
60
- * are gone anyway, so re-rolling the PAC secret is harmless), OR
61
- * - `allowProtected: true` is passed (explicit opt-in escape hatch
62
- * surfaced as `./buddy seed --allow-protected`).
63
- *
64
- * The list is conservative: any model whose rows participate in token
65
- * issuance / validation / refresh belongs here.
66
- */
67
- export declare const PROTECTED_MODELS: readonly string[];
68
- /**
69
- * Seeder configuration options
70
- */
71
- export declare interface SeederConfig {
72
- modelsDir?: string
73
- defaultCount?: number
74
- verbose?: boolean
75
- fresh?: boolean
76
- only?: string[]
77
- except?: string[]
78
- includeDefaults?: boolean
79
- allowProtected?: boolean
80
- }
81
- /**
82
- * Result of a single model seeding operation
83
- */
84
- export declare interface SeedResult {
85
- model: string
86
- table: string
87
- count: number
88
- success: boolean
89
- error?: string
90
- duration: number
91
- }
92
- /**
93
- * Result of the entire seeding operation
94
- */
95
- export declare interface SeedSummary {
96
- total: number
97
- successful: number
98
- failed: number
99
- results: SeedResult[]
100
- duration: number
101
- }
102
- /**
103
- * Parsed model with seeding information
104
- */
105
- export declare interface SeederModel {
106
- name: string
107
- table: string
108
- count: number
109
- fixtures: Array<Record<string, unknown>>
110
- attributes: Record<string, Attribute>
111
- model: Model
112
- filePath: string
113
- }
114
- // Legacy exports for backwards compatibility
115
- export { seed as runSeeders };
116
- export { freshSeed as freshWithSeed };
@@ -1,33 +0,0 @@
1
- /**
2
- * Create SQL dialect helpers for a given driver.
3
- *
4
- * @example
5
- * ```ts
6
- * import { sqlHelpers } from '@stacksjs/database'
7
- * const sql = sqlHelpers('postgres')
8
- * await db.unsafe(`SELECT * FROM users WHERE id = ${sql.param(1)}`, [userId])
9
- * ```
10
- */
11
- export declare function sqlHelpers(driver: string): SqlDialectHelpers;
12
- /**
13
- * SQL Dialect Helpers
14
- *
15
- * Cross-database compatibility utilities for PostgreSQL, MySQL, and SQLite.
16
- * Centralizes the isPostgres/isMysql/now/boolTrue/boolFalse/param helpers
17
- * that were previously duplicated across tokens.ts, auth-tables.ts, and setup.ts.
18
- */
19
- export declare interface SqlDialectHelpers {
20
- driver: string
21
- isPostgres: boolean
22
- isMysql: boolean
23
- isSqlite: boolean
24
- now: string
25
- boolTrue: string
26
- boolFalse: string
27
- autoIncrement: string
28
- primaryKey: string
29
- pkColumn: string
30
- nullableTimestamp: string
31
- param: (index: number) => string
32
- params: (...values: unknown[]) => { sql: string, values: unknown[] }
33
- }
@@ -1,52 +0,0 @@
1
- /**
2
- * True if the current async context is inside an active transaction
3
- * scope. Queue dispatch (and other side-effect emitters) read this
4
- * to decide between immediate execution and buffering.
5
- */
6
- export declare function isInTransaction(): boolean;
7
- /**
8
- * Enqueue a callback to fire after the surrounding transaction
9
- * commits. Returns:
10
- * - `true` — buffered; caller should NOT execute the side-effect now
11
- * - `false` — no active transaction; caller should execute immediately
12
- *
13
- * This is the low-level primitive. Higher-level facades (queue
14
- * dispatch, mailer send, event emit) wrap it with their own
15
- * "respect transaction context unless overridden" logic.
16
- */
17
- export declare function enqueueAfterCommit(callback: AfterCommitCallback): boolean;
18
- /**
19
- * Run `fn` inside a transaction scope. Returns whatever `fn`
20
- * returns. On success, fires every buffered after-commit callback
21
- * in insertion order. On error, discards them — the transaction
22
- * rolled back so the side-effects shouldn't happen.
23
- *
24
- * Used by `@stacksjs/orm`'s `transaction()` wrapper to thread the
25
- * scope through user code. Apps don't call this directly.
26
- *
27
- * Nested calls reuse the outer scope rather than nesting — flush
28
- * happens on the OUTERMOST commit, matching the savepoint
29
- * semantics of every relational database. The depth counter is
30
- * tracked so the outer call knows when it owns the flush.
31
- */
32
- export declare function runInTransactionScope<T>(fn: () => Promise<T>, options?: { onError?: (err: unknown, index: number) => void }): Promise<T>;
33
- /**
34
- * Test-only escape hatch — manually flush the current scope's
35
- * buffered callbacks without ending the transaction. Production
36
- * code never needs this; tests use it to assert intermediate
37
- * state. Returns the number of callbacks fired.
38
- */
39
- export declare function __flushAfterCommitNow(): Promise<number>;
40
- /**
41
- * Test-only escape hatch — peek at the number of buffered
42
- * callbacks without firing them. Returns 0 outside a scope.
43
- */
44
- export declare function __pendingAfterCommitCount(): number;
45
- /**
46
- * One buffered side-effect waiting for the surrounding transaction
47
- * to commit. Errors thrown during flush are NOT re-thrown — the
48
- * transaction itself already committed, so failing the whole flow
49
- * after-the-fact would corrupt the caller's mental model. Errors
50
- * are logged via `onError` if the scope supplied one.
51
- */
52
- declare type AfterCommitCallback = () => Promise<void> | void;
package/dist/types.d.ts DELETED
@@ -1,151 +0,0 @@
1
- /**
2
- * SQL template tag function.
3
- * Creates parameterized SQL queries from template literals.
4
- *
5
- * @example
6
- * ```ts
7
- * const query = sql`SELECT * FROM users WHERE id = ${userId}`
8
- * ```
9
- */
10
- export declare function sql(strings: TemplateStringsArray, ...values: unknown[]): Sql;
11
- /**
12
- * Type for raw SQL expressions.
13
- * Used when building dynamic SQL queries.
14
- */
15
- export declare interface RawBuilder<T = unknown> {
16
- readonly sql: string
17
- readonly parameters?: unknown[]
18
- readonly __result?: T
19
- }
20
- /**
21
- * SQL template tag type.
22
- * Used for tagged template literals that produce SQL.
23
- */
24
- export declare interface Sql {
25
- readonly sql: string
26
- readonly parameters: unknown[]
27
- }
28
- /**
29
- * Reference to a column for use inside an expression. Returned by
30
- * {@link StacksExpressionBuilder.ref} and accepted everywhere a value
31
- * or column is expected (e.g. inside `sql\`\${ref} > 0\`\`).
32
- *
33
- * The shape matches `sql.ref()`'s return so a raw fragment from either
34
- * source is interoperable.
35
- */
36
- export declare interface ColumnRef {
37
- readonly raw: string
38
- as: (alias: string) => ColumnRef
39
- }
40
- /**
41
- * Fluent aggregate-function builder accessible via
42
- * `eb.fn.count(...)`, `eb.fn.sum(...)`, etc. The chained `.as(name)`
43
- * names the resulting column in the projection; `.filterWhere(...)`
44
- * scopes the aggregate to a sub-population (`COUNT(*) FILTER (WHERE
45
- * status = 'success')` style).
46
- */
47
- export declare interface AggregateExpression {
48
- as: (alias: string) => AggregateExpression
49
- filterWhere: (column: string, op: ExpressionOperator | string, value: unknown) => AggregateExpression
50
- }
51
- /**
52
- * Aggregate-function accessor exposed on the expression builder.
53
- *
54
- * Covers the call sites in commerce today (`count`, `sum`, `avg`,
55
- * `min`, `max`). Other Kysely-side aggregates (`countAll`,
56
- * `coalesce`, etc.) can be added here as call sites surface; we
57
- * deliberately don't widen to "everything Kysely exposes" because
58
- * that surface keeps growing and an `any`-typed escape hatch always
59
- * exists (`eb.fn as any).newThing(...)`) if a one-off bypass is
60
- * genuinely needed.
61
- */
62
- export declare interface ExpressionFunctions {
63
- countAll: () => AggregateExpression
64
- count: (column: string) => AggregateExpression
65
- sum: (column: string) => AggregateExpression
66
- avg: (column: string) => AggregateExpression
67
- min: (column: string) => AggregateExpression
68
- max: (column: string) => AggregateExpression
69
- }
70
- /**
71
- * Minimal typed expression-builder surface for sub-query / inline-
72
- * expression callbacks (stacksjs/stacks#1892, T-2 from #1875).
73
- *
74
- * Background: the framework's commerce module passed `(eb: any) => …`
75
- * to `.where()` / `.select()` callbacks across 80+ sites. The `any`
76
- * escape meant typos like `eb.compare(...)` (no such method — it's
77
- * `cmpr`) only surfaced at runtime, and any later rename in
78
- * bun-query-builder couldn't break here at type-check time.
79
- *
80
- * This interface declares the methods commerce actually uses today —
81
- * `or`, `cmpr`, `ref`, `raw`, plus the `fn` aggregate accessor. It
82
- * intentionally does NOT claim to be the full Kysely
83
- * `ExpressionBuilder<DB, TB>` type:
84
- *
85
- * - Stacks's `Database` is still typed as `any` (no generated
86
- * schema map yet) so the table-aware narrowing Kysely offers
87
- * can't be expressed here yet.
88
- * - bun-query-builder doesn't currently re-export its internal
89
- * `ExpressionBuilder` type, so we can't alias to the canonical
90
- * shape upstream.
91
- *
92
- * When either of those changes upstream, swap this interface's
93
- * implementation in one place rather than re-typing every call site.
94
- */
95
- export declare interface StacksExpressionBuilder {
96
- (left: unknown, op: ExpressionOperator | string, right: unknown): unknown
97
- or: (expressions: ReadonlyArray<unknown>) => unknown
98
- and?: (expressions: ReadonlyArray<unknown>) => unknown
99
- cmpr: (left: unknown, op: ExpressionOperator, right: unknown) => unknown
100
- ref: (column: string) => ColumnRef
101
- raw: (value: string) => ColumnRef
102
- fn: ExpressionFunctions
103
- readonly [extra: string]: unknown
104
- }
105
- /**
106
- * Database types - Compatibility layer
107
- *
108
- * These types provide backwards compatibility with code that
109
- * previously used Kysely types. They work with bun-query-builder's
110
- * native type system.
111
- */
112
- /**
113
- * Marks a column as auto-generated (e.g., auto-increment primary keys).
114
- * When inserting, this field is optional. When selecting, it's required.
115
- */
116
- export type Generated<T> = T;
117
- /**
118
- * Marks a column as always generated (computed columns).
119
- * This field cannot be inserted or updated directly.
120
- */
121
- export type GeneratedAlways<T> = T;
122
- /**
123
- * Utility type for insert operations.
124
- * Makes Generated fields optional, keeps required fields required.
125
- */
126
- export type Insertable<T> = {
127
- [K in keyof T]?: T[K]
128
- }
129
- /**
130
- * Utility type for select operations.
131
- * All fields are as defined in the table type.
132
- */
133
- export type Selectable<T> = T;
134
- /**
135
- * Utility type for update operations.
136
- * All fields are optional since you may update only some fields.
137
- */
138
- export type Updateable<T> = Partial<T>;
139
- /**
140
- * Database type alias for backwards compatibility.
141
- * Use the query builder from bun-query-builder instead.
142
- */
143
- export type Database = any;
144
- /**
145
- * Comparison operator accepted by {@link StacksExpressionBuilder.cmpr}
146
- * and friends. Mirrors the standard SQL operators the underlying
147
- * Kysely-style builder supports.
148
- */
149
- export type ExpressionOperator = | '=' | '!=' | '<>' | '<' | '<=' | '>' | '>='
150
- | 'in' | 'not in' | 'is' | 'is not'
151
- | 'like' | 'not like' | 'ilike' | 'not ilike';