sqlstack 3.1.0 → 3.3.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.
@@ -53,6 +53,16 @@ function loadIoc() {
53
53
  function __resetIocDetection() {
54
54
  iocModulePromise = undefined;
55
55
  }
56
+ function missingActiveSqlStackError() {
57
+ return new errors_1.SqlStackError('An IoC execution environment is active, but no SqlStack is registered in it. ' +
58
+ 'Register a SqlStack at root composition (see registerSqlStack in "sqlstack/ioc").');
59
+ }
60
+ function isDirectMissingSqlStackError(ioc, err) {
61
+ const DependencyNotFoundError = ioc.DependencyNotFoundError;
62
+ return (typeof DependencyNotFoundError === 'function' &&
63
+ err instanceof DependencyNotFoundError &&
64
+ err.message === 'Dependency not found: SqlStack');
65
+ }
56
66
  /**
57
67
  * The SqlStack for the active IoC execution context, or undefined when no
58
68
  * IoC environment is active (or @noego/ioc is not installed).
@@ -67,20 +77,22 @@ async function activeSqlStack() {
67
77
  const scope = ioc.ExecutionContext.current();
68
78
  if (!scope)
69
79
  return undefined;
80
+ // Newer IoC peers expose exact-token registration knowledge. Consulting it
81
+ // before resolution distinguishes an absent SqlStack from errors raised by a
82
+ // registered SqlStack provider (including DependencyNotFoundError).
83
+ const registrationKnown = typeof scope.isRegistered === 'function';
84
+ if (registrationKnown && !scope.isRegistered(stack_1.SqlStack)) {
85
+ throw missingActiveSqlStackError();
86
+ }
70
87
  try {
71
88
  return (await scope.get(stack_1.SqlStack));
72
89
  }
73
90
  catch (err) {
74
- if (err?.constructor?.name === 'DependencyNotFoundError') {
75
- // Migration compatibility: a root with NO SqlStack registered may fall
76
- // back to the deprecated global registry — that is not legacy state
77
- // overriding a configured root, because the root configured nothing.
78
- // A root that HAS a SqlStack is always authoritative.
79
- if (hasLegacyDefault())
80
- return undefined;
81
- throw new errors_1.SqlStackError('An IoC execution environment is active, but no SqlStack is registered in it ' +
82
- 'and no legacy SqlStackDB default exists. Register a SqlStack at root ' +
83
- 'composition (see registerSqlStack in "sqlstack/ioc").');
91
+ // Older optional peers cannot answer isRegistered(). Their direct missing
92
+ // error is recognized by exported error identity plus the exact SqlStack
93
+ // label; nested provider errors retain their original identity.
94
+ if (!registrationKnown && isDirectMissingSqlStackError(ioc, err)) {
95
+ throw missingActiveSqlStackError();
84
96
  }
85
97
  throw err;
86
98
  }
@@ -110,15 +122,6 @@ const legacyEntries = new Map();
110
122
  // One shared legacy pseudo-stack so legacy entries carry a stack identity for
111
123
  // diagnostics. It is intentionally NOT usable as a real stack.
112
124
  let legacyStack;
113
- function hasLegacyDefault() {
114
- try {
115
- registry_1.SqlStackDB.getEntry();
116
- return true;
117
- }
118
- catch {
119
- return false;
120
- }
121
- }
122
125
  /** @internal Resolve a legacy global-registry database as a DatabaseEntry. */
123
126
  function legacyEntry(dbName) {
124
127
  const { name, db } = registry_1.SqlStackDB.getEntry(dbName);
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { SqlStack, DatabaseEntry } from './stack';\nimport { SqlStackDB } from './registry';\nimport type { Database } from './registry';\nimport type { SqlResolver } from './core/resolver';\nimport { getActiveResolver } from './core/resolver';\nimport { SqlStackError } from './core/errors';\n\n/**\n * Active-environment resolution for @Query and transactions (spec 16 §17,\n * repo spec 19 §7/§9).\n *\n * Canonical path: the active IoC execution context (owned by @noego/ioc)\n * supplies the current scope; the scope resolves its root's SqlStack\n * Singleton. When an IoC environment is active, the process-global legacy\n * registry is NEVER consulted — legacy state cannot override an active root.\n *\n * Legacy path: with no active IoC environment, execution falls back to the\n * deprecated process-global SqlStackDB registry so existing consumers keep\n * working during migration.\n */\n\ntype IocModule = {\n ExecutionContext: { current(): any };\n};\n\n// @noego/ioc is an optional peer: sqlstack remains usable standalone. The\n// import is dynamic so the CJS and ESM builds both work and so a missing\n// peer only disables the IoC path instead of breaking module load.\nlet iocModulePromise: Promise<IocModule | undefined> | undefined;\n\nfunction loadIoc(): Promise<IocModule | undefined> {\n iocModulePromise ??= import('@noego/ioc').then(\n (m: any) => (m?.ExecutionContext ? (m as IocModule) : undefined),\n () => undefined\n );\n return iocModulePromise;\n}\n\n/** @internal Test-only: force re-detection of @noego/ioc. */\nexport function __resetIocDetection(): void {\n iocModulePromise = undefined;\n}\n\n/**\n * The SqlStack for the active IoC execution context, or undefined when no\n * IoC environment is active (or @noego/ioc is not installed).\n *\n * Throws when an environment IS active but has no SqlStack registered —\n * silently falling back to global state under an active root is forbidden.\n */\nexport async function activeSqlStack(): Promise<SqlStack | undefined> {\n const ioc = await loadIoc();\n if (!ioc) return undefined;\n const scope = ioc.ExecutionContext.current();\n if (!scope) return undefined;\n try {\n return (await scope.get(SqlStack)) as SqlStack;\n } catch (err: any) {\n if (err?.constructor?.name === 'DependencyNotFoundError') {\n // Migration compatibility: a root with NO SqlStack registered may fall\n // back to the deprecated global registry — that is not legacy state\n // overriding a configured root, because the root configured nothing.\n // A root that HAS a SqlStack is always authoritative.\n if (hasLegacyDefault()) return undefined;\n throw new SqlStackError(\n 'An IoC execution environment is active, but no SqlStack is registered in it ' +\n 'and no legacy SqlStackDB default exists. Register a SqlStack at root ' +\n 'composition (see registerSqlStack in \"sqlstack/ioc\").'\n );\n }\n throw err;\n }\n}\n\nexport type ResolvedExecution = {\n entry: DatabaseEntry;\n resolver: SqlResolver | undefined;\n /** True when resolved through an active IoC root's SqlStack. */\n viaStack: boolean;\n};\n\n/**\n * Resolve the concrete database entry (and SQL resolver) for one execution.\n */\nexport async function resolveExecution(dbName?: string): Promise<ResolvedExecution> {\n const stack = await activeSqlStack();\n if (stack) {\n return { entry: await stack.resolveEntry(dbName), resolver: stack.resolver(), viaStack: true };\n }\n return {\n entry: legacyEntry(dbName),\n resolver: getActiveResolver(),\n viaStack: false,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Legacy (deprecated) global-registry support\n// ---------------------------------------------------------------------------\n\n// Stable DatabaseEntry identities for the legacy global registry, so the\n// entry-keyed transaction store works identically on both paths. Keyed by\n// name AND database object so re-registration under a name yields a fresh\n// identity (matching the fresh underlying connection).\nconst legacyEntries = new Map<string, { db: Database; entry: DatabaseEntry }>();\n\n// One shared legacy pseudo-stack so legacy entries carry a stack identity for\n// diagnostics. It is intentionally NOT usable as a real stack.\nlet legacyStack: SqlStack | undefined;\n\nfunction hasLegacyDefault(): boolean {\n try {\n SqlStackDB.getEntry();\n return true;\n } catch {\n return false;\n }\n}\n\n/** @internal Resolve a legacy global-registry database as a DatabaseEntry. */\nexport function legacyEntry(dbName?: string): DatabaseEntry {\n const { name, db } = SqlStackDB.getEntry(dbName);\n const cached = legacyEntries.get(name);\n if (cached && cached.db === db) return cached.entry;\n legacyStack ??= new SqlStack();\n const entry: DatabaseEntry = { name, db, owned: false, stack: legacyStack };\n legacyEntries.set(name, { db, entry });\n return entry;\n}\n"]}
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { SqlStack, DatabaseEntry } from './stack';\nimport { SqlStackDB } from './registry';\nimport type { Database } from './registry';\nimport type { SqlResolver } from './core/resolver';\nimport { getActiveResolver } from './core/resolver';\nimport { SqlStackError } from './core/errors';\n\n/**\n * Active-environment resolution for @Query and transactions (spec 16 §17,\n * repo spec 19 §7/§9).\n *\n * Canonical path: the active IoC execution context (owned by @noego/ioc)\n * supplies the current scope; the scope resolves its root's SqlStack\n * Singleton. When an IoC environment is active, the process-global legacy\n * registry is NEVER consulted — legacy state cannot override an active root.\n *\n * Legacy path: with no active IoC environment, execution falls back to the\n * deprecated process-global SqlStackDB registry so existing consumers keep\n * working during migration.\n */\n\ntype IocModule = {\n ExecutionContext: { current(): any };\n DependencyNotFoundError?: new (...args: any[]) => Error;\n};\n\ntype ActiveScope = {\n get(label: any): unknown;\n isRegistered?(label: any): boolean;\n};\n\n// @noego/ioc is an optional peer: sqlstack remains usable standalone. The\n// import is dynamic so the CJS and ESM builds both work and so a missing\n// peer only disables the IoC path instead of breaking module load.\nlet iocModulePromise: Promise<IocModule | undefined> | undefined;\n\nfunction loadIoc(): Promise<IocModule | undefined> {\n iocModulePromise ??= import('@noego/ioc').then(\n (m: any) => (m?.ExecutionContext ? (m as IocModule) : undefined),\n () => undefined\n );\n return iocModulePromise;\n}\n\n/** @internal Test-only: force re-detection of @noego/ioc. */\nexport function __resetIocDetection(): void {\n iocModulePromise = undefined;\n}\n\nfunction missingActiveSqlStackError(): SqlStackError {\n return new SqlStackError(\n 'An IoC execution environment is active, but no SqlStack is registered in it. ' +\n 'Register a SqlStack at root composition (see registerSqlStack in \"sqlstack/ioc\").'\n );\n}\n\nfunction isDirectMissingSqlStackError(ioc: IocModule, err: unknown): boolean {\n const DependencyNotFoundError = ioc.DependencyNotFoundError;\n return (\n typeof DependencyNotFoundError === 'function' &&\n err instanceof DependencyNotFoundError &&\n err.message === 'Dependency not found: SqlStack'\n );\n}\n\n/**\n * The SqlStack for the active IoC execution context, or undefined when no\n * IoC environment is active (or @noego/ioc is not installed).\n *\n * Throws when an environment IS active but has no SqlStack registered —\n * silently falling back to global state under an active root is forbidden.\n */\nexport async function activeSqlStack(): Promise<SqlStack | undefined> {\n const ioc = await loadIoc();\n if (!ioc) return undefined;\n const scope = ioc.ExecutionContext.current() as ActiveScope | undefined;\n if (!scope) return undefined;\n\n // Newer IoC peers expose exact-token registration knowledge. Consulting it\n // before resolution distinguishes an absent SqlStack from errors raised by a\n // registered SqlStack provider (including DependencyNotFoundError).\n const registrationKnown = typeof scope.isRegistered === 'function';\n if (registrationKnown && !scope.isRegistered!(SqlStack)) {\n throw missingActiveSqlStackError();\n }\n\n try {\n return (await scope.get(SqlStack)) as SqlStack;\n } catch (err) {\n // Older optional peers cannot answer isRegistered(). Their direct missing\n // error is recognized by exported error identity plus the exact SqlStack\n // label; nested provider errors retain their original identity.\n if (!registrationKnown && isDirectMissingSqlStackError(ioc, err)) {\n throw missingActiveSqlStackError();\n }\n throw err;\n }\n}\n\nexport type ResolvedExecution = {\n entry: DatabaseEntry;\n resolver: SqlResolver | undefined;\n /** True when resolved through an active IoC root's SqlStack. */\n viaStack: boolean;\n};\n\n/**\n * Resolve the concrete database entry (and SQL resolver) for one execution.\n */\nexport async function resolveExecution(dbName?: string): Promise<ResolvedExecution> {\n const stack = await activeSqlStack();\n if (stack) {\n return { entry: await stack.resolveEntry(dbName), resolver: stack.resolver(), viaStack: true };\n }\n return {\n entry: legacyEntry(dbName),\n resolver: getActiveResolver(),\n viaStack: false,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Legacy (deprecated) global-registry support\n// ---------------------------------------------------------------------------\n\n// Stable DatabaseEntry identities for the legacy global registry, so the\n// entry-keyed transaction store works identically on both paths. Keyed by\n// name AND database object so re-registration under a name yields a fresh\n// identity (matching the fresh underlying connection).\nconst legacyEntries = new Map<string, { db: Database; entry: DatabaseEntry }>();\n\n// One shared legacy pseudo-stack so legacy entries carry a stack identity for\n// diagnostics. It is intentionally NOT usable as a real stack.\nlet legacyStack: SqlStack | undefined;\n\n/** @internal Resolve a legacy global-registry database as a DatabaseEntry. */\nexport function legacyEntry(dbName?: string): DatabaseEntry {\n const { name, db } = SqlStackDB.getEntry(dbName);\n const cached = legacyEntries.get(name);\n if (cached && cached.db === db) return cached.entry;\n legacyStack ??= new SqlStack();\n const entry: DatabaseEntry = { name, db, owned: false, stack: legacyStack };\n legacyEntries.set(name, { db, entry });\n return entry;\n}\n"]}
@@ -29,6 +29,10 @@ function stripLeadingComments(sql) {
29
29
  }
30
30
  return sql.slice(i);
31
31
  }
32
+ function producesRows(sql) {
33
+ const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
34
+ return text.startsWith('SELECT') || text.startsWith('WITH') || /\bRETURNING\b/.test(text);
35
+ }
32
36
  export function createPgDb(urlOrPool) {
33
37
  let pool;
34
38
  let own = false;
@@ -45,16 +49,16 @@ export function createPgDb(urlOrPool) {
45
49
  dialect: 'postgres',
46
50
  async query(sql, params) {
47
51
  const res = await pool.query(sql, params);
48
- const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
49
- if (text.startsWith('SELECT') || text.startsWith('WITH')) {
50
- return res.rows;
51
- }
52
- // Non-SELECT: include rowCount and optional returning
53
- const base = { rowsAffected: Number(res.rowCount ?? 0) };
54
- if (Array.isArray(res.rows) && res.rows.length > 0) {
55
- base.returning = res.rows;
52
+ // Rows are rows: any statement that produced a result set (SELECT, CTE,
53
+ // or INSERT/UPDATE/DELETE ... RETURNING) returns the row array so result
54
+ // shape decorators apply uniformly. `res.fields` is the driver's own
55
+ // signal that a result set exists; fall back to sniffing the leading
56
+ // token only for drivers/fakes that do not report fields.
57
+ if (Array.isArray(res.fields) ? res.fields.length > 0 : producesRows(sql)) {
58
+ return Array.isArray(res.rows) ? res.rows : [];
56
59
  }
57
- return base;
60
+ // No result set: plain write result
61
+ return { rowsAffected: Number(res.rowCount ?? 0) };
58
62
  },
59
63
  conn: pool,
60
64
  async close() {
@@ -1 +1 @@
1
- {"version":3,"file":"pg.js","sourceRoot":"","sources":["../../../src/adapters/pg.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\nimport { loadNodeModule } from '../core/loadNodeModule';\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n // Strip BOM\n if (sql.charCodeAt(0) === 0xfeff) i = 1;\n while (i < n) {\n // Skip whitespace\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // Line comment -- ...\\n\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // Block comment /* ... */\n i += 2;\n let end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\nexport function createPgDb(urlOrPool: string | any): Database {\n let pool: any;\n let own = false;\n\n if (typeof urlOrPool === 'string') {\n // Lazy load to keep driver optional (CJS require or ESM createRequire)\n const { Pool } = loadNodeModule('pg');\n pool = new Pool({ connectionString: urlOrPool, max: 4 });\n own = true;\n } else {\n pool = urlOrPool;\n }\n\n return {\n dialect: 'postgres',\n async query(sql: string, params: unknown[]) {\n const res = await pool.query(sql, params);\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return res.rows;\n }\n // Non-SELECT: include rowCount and optional returning\n const base: any = { rowsAffected: Number(res.rowCount ?? 0) };\n if (Array.isArray(res.rows) && res.rows.length > 0) {\n base.returning = res.rows;\n }\n return base;\n },\n conn: pool,\n async close() {\n if (own && typeof pool?.end === 'function') {\n await pool.end();\n }\n },\n } as Database;\n}\n"]}
1
+ {"version":3,"file":"pg.js","sourceRoot":"","sources":["../../../src/adapters/pg.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\nimport { loadNodeModule } from '../core/loadNodeModule';\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n // Strip BOM\n if (sql.charCodeAt(0) === 0xfeff) i = 1;\n while (i < n) {\n // Skip whitespace\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // Line comment -- ...\\n\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // Block comment /* ... */\n i += 2;\n let end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\nfunction producesRows(sql: string): boolean {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n return text.startsWith('SELECT') || text.startsWith('WITH') || /\\bRETURNING\\b/.test(text);\n}\n\nexport function createPgDb(urlOrPool: string | any): Database {\n let pool: any;\n let own = false;\n\n if (typeof urlOrPool === 'string') {\n // Lazy load to keep driver optional (CJS require or ESM createRequire)\n const { Pool } = loadNodeModule('pg');\n pool = new Pool({ connectionString: urlOrPool, max: 4 });\n own = true;\n } else {\n pool = urlOrPool;\n }\n\n return {\n dialect: 'postgres',\n async query(sql: string, params: unknown[]) {\n const res = await pool.query(sql, params);\n // Rows are rows: any statement that produced a result set (SELECT, CTE,\n // or INSERT/UPDATE/DELETE ... RETURNING) returns the row array so result\n // shape decorators apply uniformly. `res.fields` is the driver's own\n // signal that a result set exists; fall back to sniffing the leading\n // token only for drivers/fakes that do not report fields.\n if (Array.isArray(res.fields) ? res.fields.length > 0 : producesRows(sql)) {\n return Array.isArray(res.rows) ? res.rows : [];\n }\n // No result set: plain write result\n return { rowsAffected: Number(res.rowCount ?? 0) };\n },\n conn: pool,\n async close() {\n if (own && typeof pool?.end === 'function') {\n await pool.end();\n }\n },\n } as Database;\n}\n"]}
@@ -95,6 +95,17 @@ function stripLeadingComments(sql) {
95
95
  }
96
96
  return sql.slice(i);
97
97
  }
98
+ // Text-based fallback for drivers that do not expose statement metadata
99
+ // (the sqlite3 callback API). SELECT, CTEs, and `... RETURNING` all produce
100
+ // a result set and must be executed with all(), not run().
101
+ function producesRows(sql) {
102
+ const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
103
+ return text.startsWith('SELECT') || text.startsWith('WITH') || /\bRETURNING\b/.test(text);
104
+ }
105
+ // better-sqlite3 exposes `stmt.reader` (true when the statement returns rows).
106
+ function statementReturnsRows(stmt, sql) {
107
+ return typeof stmt?.reader === 'boolean' ? stmt.reader : producesRows(sql);
108
+ }
98
109
  export async function createSqliteDb(filenameOrDb) {
99
110
  // If a pre-created connection is provided
100
111
  if (typeof filenameOrDb !== 'string' && filenameOrDb) {
@@ -106,8 +117,7 @@ export async function createSqliteDb(filenameOrDb) {
106
117
  async query(sql, params) {
107
118
  const stmt = await prepareStatement(db, sql);
108
119
  try {
109
- const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
110
- if (text.startsWith('SELECT') || text.startsWith('WITH')) {
120
+ if (statementReturnsRows(stmt, sql)) {
111
121
  const rows = await statementAll(stmt, params);
112
122
  return rows;
113
123
  }
@@ -136,8 +146,7 @@ export async function createSqliteDb(filenameOrDb) {
136
146
  return {
137
147
  dialect: 'sqlite',
138
148
  async query(sql, params) {
139
- const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
140
- if (text.startsWith('SELECT') || text.startsWith('WITH')) {
149
+ if (producesRows(sql)) {
141
150
  return new Promise((resolve, reject) => {
142
151
  db.all(sql, params, (err, rows) => {
143
152
  if (err)
@@ -186,8 +195,7 @@ export async function createSqliteDb(filenameOrDb) {
186
195
  dialect: 'sqlite',
187
196
  async query(sql, params) {
188
197
  const stmt = db.prepare(sql);
189
- const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
190
- if (text.startsWith('SELECT') || text.startsWith('WITH')) {
198
+ if (statementReturnsRows(stmt, sql)) {
191
199
  return stmt.all(...params);
192
200
  }
193
201
  const info = stmt.run(...params);
@@ -223,8 +231,7 @@ export async function createSqliteDb(filenameOrDb) {
223
231
  return {
224
232
  dialect: 'sqlite',
225
233
  async query(sql, params) {
226
- const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();
227
- if (text.startsWith('SELECT') || text.startsWith('WITH')) {
234
+ if (producesRows(sql)) {
228
235
  return new Promise((resolve, reject) => {
229
236
  db.all(sql, params, (err, rows) => {
230
237
  if (err)
@@ -1 +1 @@
1
- {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === 'function';\n}\n\nasync function prepareStatement(db: any, sql: string) {\n const stmt = db.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n}\n\nasync function finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== 'function') return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n}\n\nasync function statementAll(stmt: any, params: unknown[]) {\n if (typeof stmt.all !== 'function') {\n throw new Error('SQLite statement missing all()');\n }\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nasync function statementRun(stmt: any, params: unknown[]) {\n if (typeof stmt.run !== 'function') {\n throw new Error('SQLite statement missing run()');\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastInsertId: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n if (sql.charCodeAt(0) === 0xfeff) i = 1; // BOM\n while (i < n) {\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // -- line comment\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // /* block comment */\n i += 2;\n const end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\nexport async function createSqliteDb(filenameOrDb: string | any): Promise<Database> {\n // If a pre-created connection is provided\n if (typeof filenameOrDb !== 'string' && filenameOrDb) {\n const db = filenameOrDb;\n\n // better-sqlite3 shape\n if (typeof db.prepare === 'function') {\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = await prepareStatement(db, sql);\n try {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n const rows = await statementAll(stmt, params);\n return rows;\n }\n const info = await statementRun(stmt, params);\n const rowsAffected = Number(info?.changes ?? info?.rowsAffected ?? 0);\n const lastInsertId = info?.lastInsertRowid ?? info?.lastID ?? info?.lastInsertId;\n return { rowsAffected, lastInsertId };\n } finally {\n await finalizeStatement(stmt);\n }\n },\n conn: db,\n // Do not close externally provided connection\n async close() {\n if (typeof db.close === 'function') {\n const res = db.close();\n if (isPromiseLike(res)) {\n await res;\n }\n }\n },\n } as Database;\n }\n\n // sqlite3 shape\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n return new Promise((resolve, reject) => {\n // Use function callback to access `this` for metadata\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n const filename = filenameOrDb as string;\n\n let BetterSqlite3: any;\n if (typeof require === 'function') {\n try {\n BetterSqlite3 = require('better-sqlite3');\n } catch {\n BetterSqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('better-sqlite3');\n BetterSqlite3 = (mod as any).default ?? mod;\n } catch {\n BetterSqlite3 = null;\n }\n }\n\n if (BetterSqlite3) {\n const db = new BetterSqlite3(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n close() {\n db.close();\n },\n } as Database;\n }\n\n let sqlite3: any;\n if (typeof require === 'function') {\n try {\n sqlite3 = require('sqlite3');\n } catch {\n sqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('sqlite3');\n sqlite3 = (mod as any).default ?? mod;\n } catch {\n sqlite3 = null;\n }\n }\n\n if (sqlite3) {\n const db = new sqlite3.Database(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n if (text.startsWith('SELECT') || text.startsWith('WITH')) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n // Non-SELECT statements\n return new Promise((resolve, reject) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n close() {\n return new Promise<void>((resolve, reject) => {\n db.close((err: Error | null) => (err ? reject(err) : resolve()));\n });\n },\n } as Database;\n }\n\n throw new Error('No SQLite driver available. Install either better-sqlite3 or sqlite3.');\n}\n"]}
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../../../src/adapters/sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from '../registry';\n\nfunction isPromiseLike<T>(value: unknown): value is Promise<T> {\n return !!value && typeof (value as Promise<T>).then === 'function';\n}\n\nasync function prepareStatement(db: any, sql: string) {\n const stmt = db.prepare(sql);\n return isPromiseLike(stmt) ? await stmt : stmt;\n}\n\nasync function finalizeStatement(stmt: any) {\n if (!stmt || typeof stmt.finalize !== 'function') return;\n const result = stmt.finalize();\n if (isPromiseLike(result)) {\n await result;\n }\n}\n\nasync function statementAll(stmt: any, params: unknown[]) {\n if (typeof stmt.all !== 'function') {\n throw new Error('SQLite statement missing all()');\n }\n if (stmt.all.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n };\n try {\n if (params.length > 0) {\n stmt.all(params, callback);\n } else {\n stmt.all(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.all(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nasync function statementRun(stmt: any, params: unknown[]) {\n if (typeof stmt.run !== 'function') {\n throw new Error('SQLite statement missing run()');\n }\n if (stmt.run.length >= 2) {\n return await new Promise((resolve, reject) => {\n const callback = function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ changes: this?.changes ?? 0, lastInsertId: this?.lastID });\n };\n try {\n if (params.length > 0) {\n stmt.run(params, callback);\n } else {\n stmt.run(callback);\n }\n } catch (error) {\n reject(error);\n }\n });\n }\n const result = stmt.run(...(params as any[]));\n return isPromiseLike(result) ? await result : result;\n}\n\nfunction stripLeadingComments(sql: string): string {\n let i = 0;\n const n = sql.length;\n if (sql.charCodeAt(0) === 0xfeff) i = 1; // BOM\n while (i < n) {\n while (i < n && /\\s/.test(sql[i]!)) i++;\n if (i + 1 < n && sql[i] === '-' && sql[i + 1] === '-') {\n // -- line comment\n i += 2;\n while (i < n && sql[i] !== '\\n') i++;\n continue;\n }\n if (i + 1 < n && sql[i] === '/' && sql[i + 1] === '*') {\n // /* block comment */\n i += 2;\n const end = sql.indexOf('*/', i);\n if (end === -1) return '';\n i = end + 2;\n continue;\n }\n break;\n }\n return sql.slice(i);\n}\n\n// Text-based fallback for drivers that do not expose statement metadata\n// (the sqlite3 callback API). SELECT, CTEs, and `... RETURNING` all produce\n// a result set and must be executed with all(), not run().\nfunction producesRows(sql: string): boolean {\n const text = stripLeadingComments(String(sql)).trimStart().toUpperCase();\n return text.startsWith('SELECT') || text.startsWith('WITH') || /\\bRETURNING\\b/.test(text);\n}\n\n// better-sqlite3 exposes `stmt.reader` (true when the statement returns rows).\nfunction statementReturnsRows(stmt: any, sql: string): boolean {\n return typeof stmt?.reader === 'boolean' ? stmt.reader : producesRows(sql);\n}\n\nexport async function createSqliteDb(filenameOrDb: string | any): Promise<Database> {\n // If a pre-created connection is provided\n if (typeof filenameOrDb !== 'string' && filenameOrDb) {\n const db = filenameOrDb;\n\n // better-sqlite3 shape\n if (typeof db.prepare === 'function') {\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = await prepareStatement(db, sql);\n try {\n if (statementReturnsRows(stmt, sql)) {\n const rows = await statementAll(stmt, params);\n return rows;\n }\n const info = await statementRun(stmt, params);\n const rowsAffected = Number(info?.changes ?? info?.rowsAffected ?? 0);\n const lastInsertId = info?.lastInsertRowid ?? info?.lastID ?? info?.lastInsertId;\n return { rowsAffected, lastInsertId };\n } finally {\n await finalizeStatement(stmt);\n }\n },\n conn: db,\n // Do not close externally provided connection\n async close() {\n if (typeof db.close === 'function') {\n const res = db.close();\n if (isPromiseLike(res)) {\n await res;\n }\n }\n },\n } as Database;\n }\n\n // sqlite3 shape\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n if (producesRows(sql)) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n return new Promise((resolve, reject) => {\n // Use function callback to access `this` for metadata\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n // Do not close externally provided connection\n close() {},\n } as Database;\n }\n\n const filename = filenameOrDb as string;\n\n let BetterSqlite3: any;\n if (typeof require === 'function') {\n try {\n BetterSqlite3 = require('better-sqlite3');\n } catch {\n BetterSqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('better-sqlite3');\n BetterSqlite3 = (mod as any).default ?? mod;\n } catch {\n BetterSqlite3 = null;\n }\n }\n\n if (BetterSqlite3) {\n const db = new BetterSqlite3(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n const stmt = db.prepare(sql);\n if (statementReturnsRows(stmt, sql)) {\n return stmt.all(...params);\n }\n const info = stmt.run(...params);\n return { rowsAffected: Number(info?.changes ?? 0), lastInsertId: info?.lastInsertRowid };\n },\n conn: db,\n close() {\n db.close();\n },\n } as Database;\n }\n\n let sqlite3: any;\n if (typeof require === 'function') {\n try {\n sqlite3 = require('sqlite3');\n } catch {\n sqlite3 = null;\n }\n } else {\n try {\n // @ts-ignore optional dependency without types\n const mod = await import('sqlite3');\n sqlite3 = (mod as any).default ?? mod;\n } catch {\n sqlite3 = null;\n }\n }\n\n if (sqlite3) {\n const db = new sqlite3.Database(filename);\n return {\n dialect: 'sqlite',\n async query(sql: string, params: unknown[]) {\n if (producesRows(sql)) {\n return new Promise<any[]>((resolve, reject) => {\n db.all(sql, params, (err: Error | null, rows: any[]) => {\n if (err) return reject(err);\n resolve(rows || []);\n });\n });\n }\n // Non-SELECT statements\n return new Promise((resolve, reject) => {\n db.run(sql, params, function (this: any, err: Error | null) {\n if (err) return reject(err);\n resolve({ rowsAffected: Number(this?.changes ?? 0), lastInsertId: this?.lastID });\n });\n });\n },\n conn: db,\n close() {\n return new Promise<void>((resolve, reject) => {\n db.close((err: Error | null) => (err ? reject(err) : resolve()));\n });\n },\n } as Database;\n }\n\n throw new Error('No SQLite driver available. Install either better-sqlite3 or sqlite3.');\n}\n"]}
@@ -22,6 +22,19 @@ export class RowsExistError extends SqlStackError {
22
22
  this.name = 'RowsExistError';
23
23
  }
24
24
  }
25
+ // A result-shape decorator (@Single/@Only/@Exist/@None) was applied to a
26
+ // method whose statement produced no result set (a plain write). Shapes
27
+ // require rows; use `... RETURNING` or drop the decorator.
28
+ export class ExpectedRowsError extends SqlStackError {
29
+ constructor(method, shape) {
30
+ const decorator = '@' + shape.charAt(0).toUpperCase() + shape.slice(1);
31
+ super(`${decorator} on ${method} requires a result set, but the statement produced a write result ` +
32
+ `({ rowsAffected }). Add a RETURNING clause or remove the shape decorator.`);
33
+ this.method = method;
34
+ this.shape = shape;
35
+ this.name = 'ExpectedRowsError';
36
+ }
37
+ }
25
38
  export class ValidationError extends SqlStackError {
26
39
  constructor(details) {
27
40
  super(`Validation failed: ${details}`);
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,aAAa;IACnD,YAAY,WAAmB;QAC7B,KAAK,CAAC,iCAAiC,WAAW,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,aAAa;IAC5C;QACE,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,aAAa;IAC/C,YAAY,WAAmB;QAC7B,KAAK,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CAEF;AAED,MAAM,OAAO,aAAc,SAAQ,aAAa;IAC9C,YAAY,OAAe,EAAE,GAAW,EAAE,KAAa;QACrD,KAAK,CAAC,GAAG,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CAGF;AAED,8DAA8D;AAC9D,kEAAkE;AAClE,MAAM,OAAO,wBAAyB,SAAQ,aAAa;IACzD,YAAY,OAAO,GAAG,yBAAyB,EAAE,KAAe;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CAEF","sourcesContent":["export class SqlStackError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = 'SqlStackError';\n }\n}\n\nexport class ExactlyOneRowError extends SqlStackError {\n constructor(actualCount: number) {\n super(`Expected exactly one row, got ${actualCount}`);\n this.name = 'ExactlyOneRowError';\n }\n}\n\nexport class NoRowsError extends SqlStackError {\n constructor() {\n super('Expected at least one row, got 0');\n this.name = 'NoRowsError';\n }\n}\n\nexport class RowsExistError extends SqlStackError {\n constructor(actualCount: number) {\n super(`Expected no rows, got ${actualCount}`);\n this.name = 'RowsExistError';\n }\n}\n\nexport class ValidationError extends SqlStackError {\n constructor(details: string) {\n super(`Validation failed: ${details}`);\n this.details = details;\n this.name = 'ValidationError';\n }\n details: string;\n}\n\nexport class DatabaseError extends SqlStackError {\n constructor(message: string, sql: string, cause?: Error) {\n super(`${message}\\nSQL: ${sql}`);\n this.sql = sql;\n this.cause = cause;\n this.name = 'DatabaseError';\n }\n sql: string;\n cause?: Error;\n}\n\n// Signals that the current transaction should be rolled back.\n// If `cause` is provided, wrappers may rethrow it after rollback.\nexport class RollbackTransactionError extends SqlStackError {\n constructor(message = 'Transaction rolled back', cause?: unknown) {\n super(message);\n this.cause = cause;\n this.name = 'RollbackTransactionError';\n }\n cause?: unknown;\n}\n"]}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/core/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAgB;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,aAAa;IACnD,YAAY,WAAmB;QAC7B,KAAK,CAAC,iCAAiC,WAAW,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,aAAa;IAC5C;QACE,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,OAAO,cAAe,SAAQ,aAAa;IAC/C,YAAY,WAAmB;QAC7B,KAAK,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,yEAAyE;AACzE,wEAAwE;AACxE,2DAA2D;AAC3D,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IAClD,YAAY,MAAc,EAAE,KAAa;QACvC,MAAM,SAAS,GAAG,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvE,KAAK,CACH,GAAG,SAAS,OAAO,MAAM,oEAAoE;YAC3F,2EAA2E,CAC9E,CAAC;QACF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;IAClC,CAAC;CAGF;AAED,MAAM,OAAO,eAAgB,SAAQ,aAAa;IAChD,YAAY,OAAe;QACzB,KAAK,CAAC,sBAAsB,OAAO,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CAEF;AAED,MAAM,OAAO,aAAc,SAAQ,aAAa;IAC9C,YAAY,OAAe,EAAE,GAAW,EAAE,KAAa;QACrD,KAAK,CAAC,GAAG,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CAGF;AAED,8DAA8D;AAC9D,kEAAkE;AAClE,MAAM,OAAO,wBAAyB,SAAQ,aAAa;IACzD,YAAY,OAAO,GAAG,yBAAyB,EAAE,KAAe;QAC9D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CAEF","sourcesContent":["export class SqlStackError extends Error {\n constructor(message?: string) {\n super(message);\n this.name = 'SqlStackError';\n }\n}\n\nexport class ExactlyOneRowError extends SqlStackError {\n constructor(actualCount: number) {\n super(`Expected exactly one row, got ${actualCount}`);\n this.name = 'ExactlyOneRowError';\n }\n}\n\nexport class NoRowsError extends SqlStackError {\n constructor() {\n super('Expected at least one row, got 0');\n this.name = 'NoRowsError';\n }\n}\n\nexport class RowsExistError extends SqlStackError {\n constructor(actualCount: number) {\n super(`Expected no rows, got ${actualCount}`);\n this.name = 'RowsExistError';\n }\n}\n\n// A result-shape decorator (@Single/@Only/@Exist/@None) was applied to a\n// method whose statement produced no result set (a plain write). Shapes\n// require rows; use `... RETURNING` or drop the decorator.\nexport class ExpectedRowsError extends SqlStackError {\n constructor(method: string, shape: string) {\n const decorator = '@' + shape.charAt(0).toUpperCase() + shape.slice(1);\n super(\n `${decorator} on ${method} requires a result set, but the statement produced a write result ` +\n `({ rowsAffected }). Add a RETURNING clause or remove the shape decorator.`\n );\n this.method = method;\n this.shape = shape;\n this.name = 'ExpectedRowsError';\n }\n method: string;\n shape: string;\n}\n\nexport class ValidationError extends SqlStackError {\n constructor(details: string) {\n super(`Validation failed: ${details}`);\n this.details = details;\n this.name = 'ValidationError';\n }\n details: string;\n}\n\nexport class DatabaseError extends SqlStackError {\n constructor(message: string, sql: string, cause?: Error) {\n super(`${message}\\nSQL: ${sql}`);\n this.sql = sql;\n this.cause = cause;\n this.name = 'DatabaseError';\n }\n sql: string;\n cause?: Error;\n}\n\n// Signals that the current transaction should be rolled back.\n// If `cause` is provided, wrappers may rethrow it after rollback.\nexport class RollbackTransactionError extends SqlStackError {\n constructor(message = 'Transaction rolled back', cause?: unknown) {\n super(message);\n this.cause = cause;\n this.name = 'RollbackTransactionError';\n }\n cause?: unknown;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { getClassLabels, getMethodLabels, setMethodLabels } from '../core/metadata.js';
2
- import { SqlStackError, ExactlyOneRowError, NoRowsError, RowsExistError, DatabaseError } from '../core/errors.js';
2
+ import { SqlStackError, ExactlyOneRowError, NoRowsError, RowsExistError, DatabaseError, ExpectedRowsError } from '../core/errors.js';
3
3
  import { isValidationDisabled, validateOutput } from '../core/validator.js';
4
4
  import { resolveExecution } from '../runtime.js';
5
5
  import { createSqliteBinder, createMysqlBinder, createPostgresBinder } from '../binders/sqlBinder.js';
@@ -268,24 +268,9 @@ export function Query(arg) {
268
268
  // Attach SQL query (with placeholders) to error for debugging
269
269
  throw new DatabaseError(dbError?.message || String(dbError), boundSql, dbError instanceof Error ? dbError : undefined);
270
270
  }
271
- // 6) If rows were returned (SELECT/CTE), shape + transform + validate
272
- if (Array.isArray(out)) {
273
- const shaped = applyShape(out, labels.shape);
274
- const transformed = labels.transform ? labels.transform(shaped) : shaped;
275
- // 7) validate result via JSON Schema, if provided
276
- if (labels.validateSchema && !isValidationDisabled()) {
277
- if (Array.isArray(transformed)) {
278
- for (const row of transformed)
279
- validateOutput(labels.validateSchema, row);
280
- }
281
- else if (transformed !== null && transformed !== undefined) {
282
- validateOutput(labels.validateSchema, transformed);
283
- }
284
- }
285
- return transformed;
286
- }
287
- // Non-SELECT: return the write result as-is
288
- return out;
271
+ // 6) If rows were returned (SELECT/CTE/RETURNING), shape + transform + validate;
272
+ // otherwise return the write result as-is (or fail if a shape was requested)
273
+ return finishResult(out, labels, this, prop);
289
274
  };
290
275
  // 0) Invoke the method body inside a run() context. Three outcomes:
291
276
  // - body calls run(): the pipeline executed inside the body; return
@@ -320,21 +305,7 @@ export function Query(arg) {
320
305
  catch (dbError) {
321
306
  throw new DatabaseError(dbError?.message || String(dbError), boundSql, dbError instanceof Error ? dbError : undefined);
322
307
  }
323
- if (Array.isArray(out)) {
324
- const shaped = applyShape(out, labels.shape);
325
- const transformed = labels.transform ? labels.transform(shaped) : shaped;
326
- if (labels.validateSchema && !isValidationDisabled()) {
327
- if (Array.isArray(transformed)) {
328
- for (const row of transformed)
329
- validateOutput(labels.validateSchema, row);
330
- }
331
- else if (transformed !== null && transformed !== undefined) {
332
- validateOutput(labels.validateSchema, transformed);
333
- }
334
- }
335
- return transformed;
336
- }
337
- return out;
308
+ return finishResult(out, labels, this, prop);
338
309
  }
339
310
  return pipeline();
340
311
  };
@@ -348,6 +319,31 @@ function applyDefaults(defaults, input) {
348
319
  return input; // defaults only apply to named-object args
349
320
  return { ...defaults, ...(input || {}) };
350
321
  }
322
+ // Shared tail of both execution paths. Rows (any statement that produced a
323
+ // result set) are shaped, transformed, and validated. A write result is
324
+ // returned verbatim — unless a result-shape decorator was requested, in which
325
+ // case the statement cannot satisfy it and we fail at the call site instead of
326
+ // silently handing back a truthy `{ rowsAffected }` object.
327
+ function finishResult(out, labels, self, prop) {
328
+ if (!Array.isArray(out)) {
329
+ if (labels.shape) {
330
+ throw new ExpectedRowsError(`${self?.constructor?.name ?? '<anonymous>'}.${String(prop)}`, labels.shape);
331
+ }
332
+ return out;
333
+ }
334
+ const shaped = applyShape(out, labels.shape);
335
+ const transformed = labels.transform ? labels.transform(shaped) : shaped;
336
+ if (labels.validateSchema && !isValidationDisabled()) {
337
+ if (Array.isArray(transformed)) {
338
+ for (const row of transformed)
339
+ validateOutput(labels.validateSchema, row);
340
+ }
341
+ else if (transformed !== null && transformed !== undefined) {
342
+ validateOutput(labels.validateSchema, transformed);
343
+ }
344
+ }
345
+ return transformed;
346
+ }
351
347
  function applyShape(rows, shape) {
352
348
  switch (shape) {
353
349
  case 'single':
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/decorators/query.ts"],"names":[],"mappings":"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","sourcesContent":["import { getClassLabels, getMethodLabels, setMethodLabels } from '../core/metadata';\nimport { SqlStackError, ExactlyOneRowError, NoRowsError, RowsExistError, DatabaseError } from '../core/errors';\nimport { isValidationDisabled, validateOutput } from '../core/validator';\nimport { resolveExecution } from '../runtime';\nimport { createSqliteBinder, createMysqlBinder, createPostgresBinder } from '../binders/sqlBinder';\nimport { coerceRootPath, resolveSqlFromFs } from '../core/fileResolution';\nimport { registerDecoratedMethod, recordQueryMethodOnClass } from '../core/resolver';\nimport { defaultSourceScanResolver } from '../core/sourceScanResolver';\nimport { getActiveTransaction } from '../transactions';\nimport { SqlFragment } from '../sql';\nimport { runStorage, type RunContext } from '../run';\n\ntype QueryOptions = {\n sql?: string; // optional inline SQL for testing; otherwise, future: load from file\n db?: string; // optional override DB name\n dialect?: 'sqlite' | 'mysql' | 'postgres';\n};\n\nexport function Query(arg?: string | QueryOptions) {\n return function (_target: any, prop: string | symbol, desc: PropertyDescriptor) {\n const options: QueryOptions | undefined = typeof arg === 'string' ? undefined : arg;\n const rootArg: string | undefined = typeof arg === 'string' ? arg : undefined;\n // Store method-level db override if provided\n if (options?.db) {\n setMethodLabels(_target, prop, { db: options.db });\n }\n // Store inline SQL if provided\n if (options?.sql) {\n setMethodLabels(_target, prop, { source: { kind: 'inline', sql: options.sql } });\n } else {\n // FS-based resolution: only an EXPLICIT path argument pins a directory.\n // Bare @Query() resolves through the active resolver (or the default\n // SourceScanResolver) — no stack-based directory guessing, which breaks\n // under bundlers and test transforms.\n const { rootDir } = coerceRootPath(rootArg);\n if (rootDir) {\n setMethodLabels(_target, prop, { source: { kind: 'fs', rootDir } });\n }\n }\n\n // Record for resolver coverage checks: immutable class metadata (the\n // canonical, environment-local source) plus the deprecated global list\n // consulted by the legacy global-resolver path.\n const decoratedEntry = {\n className: _target?.constructor?.name ?? '<anonymous>',\n methodName: String(prop),\n inline: !!options?.sql,\n };\n recordQueryMethodOnClass(_target, decoratedEntry);\n registerDecoratedMethod(decoratedEntry);\n\n const original = desc.value;\n desc.value = async function (...callArgs: any[]) {\n const labels = getMethodLabels(this, prop);\n const classLabels = getClassLabels(this);\n\n // The full file/inline pipeline (resolve source, bind, execute,\n // shape/transform/validate). Invoked either by run() from inside the\n // method body, or directly as the legacy fallback when the body throws.\n const pipeline = async () => {\n // 1) prepare args with defaults\n const rawInput = callArgs.length === 1 ? callArgs[0] : callArgs; // object or positional array\n\n // 2) choose database and dialect via the active environment\n const dbName = labels.db ?? options?.db ?? classLabels?.db;\n const { entry, resolver: activeResolver } = await resolveExecution(dbName);\n const db = entry.db;\n const dialect = options?.dialect ?? db.dialect ?? 'sqlite';\n\n // 3) load SQL source (inline, environment resolver, v1 fs fallback,\n // or the zero-config source scan — bare @Query() with nothing installed)\n const sql = labels?.source?.kind === 'inline'\n ? labels.source.sql\n : activeResolver\n ? activeResolver.resolve({\n className: this?.constructor?.name ?? '<anonymous>',\n methodName: String(prop),\n dialect,\n rootDir: labels?.source?.kind === 'fs' ? labels.source.rootDir : undefined,\n })\n : labels?.source?.kind === 'fs'\n ? resolveSqlFromFs(labels.source.rootDir, String(prop), dialect).sql\n : defaultSourceScanResolver()?.resolve({\n className: this?.constructor?.name ?? '<anonymous>',\n methodName: String(prop),\n dialect,\n });\n if (!sql) {\n throw new SqlStackError(`No SQL source provided for method ${String(prop)}. Use @Query() with a file/folder path or inline sql.`);\n }\n\n // 4) bind placeholders\n // Decide argument mode: positional if SQL contains :argN\n let workingSql = sql;\n const hasPositional = /:arg[1-9][0-9]*/.test(workingSql);\n\n // Prepare args for binder\n let args: any;\n if (hasPositional) {\n args = callArgs;\n } else {\n const namedBase = callArgs.length > 0 ? callArgs[0] : undefined;\n args = applyDefaults(labels.defaults, namedBase ?? {});\n }\n\n // Compute paging and inject :offset/:limit (named mode) or rewrite to positional\n const pageCfg = labels.page;\n if (pageCfg) {\n const { size, zeroBase } = pageCfg;\n const base = zeroBase ? 0 : 1;\n\n // Extract page number from input (object) or a trailing options object in positional mode\n const pageFromObject = (val: any): number | undefined => {\n if (val && typeof val === 'object' && !Array.isArray(val) && typeof (val as any).page !== 'undefined') {\n const p = (val as any).page;\n if (typeof p === 'number' && isFinite(p)) return p;\n }\n return undefined;\n };\n\n let pageNum: number | undefined;\n if (hasPositional) {\n // Variadic-style: only the LAST argument may carry `{ page }`\n if (callArgs.length > 0) {\n const last = callArgs[callArgs.length - 1];\n pageNum = pageFromObject(last);\n }\n } else {\n // Prefer last-arg options if provided; otherwise read from named object\n if (callArgs.length > 1) {\n const last = callArgs[callArgs.length - 1];\n pageNum = pageFromObject(last);\n }\n if (pageNum === undefined) {\n pageNum = pageFromObject(args);\n }\n }\n\n const effectivePage = typeof pageNum === 'number' ? pageNum : base;\n const offset = (effectivePage - base) * size;\n const limit = size;\n\n if (hasPositional) {\n // Replace occurrences of :offset and :limit with new :argN tokens appended to args\n const baseIndex = callArgs.length; // start numbering after user args\n let nextIndex = baseIndex + 1;\n const additions: unknown[] = [];\n\n const rewrite = (sqlText: string) => {\n const out: string[] = [];\n let i = 0;\n let inSQ = false, inDQ = false, inLC = false, inBC = false;\n const len = sqlText.length;\n while (i < len) {\n const ch = sqlText[i];\n const next = i + 1 < len ? sqlText[i + 1] : '';\n if (inLC) { out.push(ch); if (ch === '\\n') inLC = false; i++; continue; }\n if (inBC) { out.push(ch); if (ch === '*' && next === '/') { out.push(next); i++; inBC = false; } i++; continue; }\n if (inSQ) {\n out.push(ch);\n if (ch === \"'\" && next === \"'\") { out.push(next); i += 2; continue; }\n if (ch === \"'\") inSQ = false;\n i++;\n continue;\n }\n if (inDQ) {\n out.push(ch);\n if (ch === '\"' && next === '\"') { out.push(next); i += 2; continue; }\n if (ch === '\"') inDQ = false;\n i++;\n continue;\n }\n if (ch === '-' && next === '-') { out.push(ch, next); i += 2; inLC = true; continue; }\n if (ch === '/' && next === '*') { out.push(ch, next); i += 2; inBC = true; continue; }\n if (ch === '\"') { out.push(ch); inDQ = true; i++; continue; }\n if (ch === \"'\") { out.push(ch); inSQ = true; i++; continue; }\n if (ch === ':' && next === ':') { out.push('::'); i += 2; continue; }\n if (ch === ':') {\n // parse token\n let j = i + 1;\n const start = j;\n while (j < len) {\n const c = sqlText[j];\n if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c === '_') j++; else break;\n }\n const name = sqlText.slice(start, j);\n if (name === 'offset') {\n const token = `:arg${nextIndex++}`;\n out.push(token);\n additions.push(offset);\n i = j;\n continue;\n }\n if (name === 'limit') {\n const token = `:arg${nextIndex++}`;\n out.push(token);\n additions.push(limit);\n i = j;\n continue;\n }\n // otherwise leave untouched\n out.push(':');\n i++;\n continue;\n }\n out.push(ch);\n i++;\n }\n return out.join('');\n };\n\n const rewritten = rewrite(workingSql);\n if (rewritten !== workingSql) {\n workingSql = rewritten;\n // append values so :argK map correctly\n (args as unknown[]).push(...additions);\n }\n } else {\n // Named-mode: attach computed values (override any provided)\n args = { ...(args as Record<string, unknown>), offset, limit };\n }\n }\n const binder =\n dialect === 'postgres' ? createPostgresBinder() : dialect === 'mysql' ? createMysqlBinder() : createSqliteBinder();\n const { sql: boundSql, params } = binder.bind(workingSql, args as any);\n\n // 5) execute query via registry DB\n let out;\n try {\n const tx = getActiveTransaction(entry);\n out = tx ? await tx.query(boundSql, params) : await db.query(boundSql, params);\n } catch (dbError: any) {\n // Attach SQL query (with placeholders) to error for debugging\n throw new DatabaseError(\n dbError?.message || String(dbError),\n boundSql,\n dbError instanceof Error ? dbError : undefined\n );\n }\n\n // 6) If rows were returned (SELECT/CTE), shape + transform + validate\n if (Array.isArray(out)) {\n const shaped = applyShape(out, labels.shape);\n const transformed = labels.transform ? labels.transform(shaped) : shaped;\n\n // 7) validate result via JSON Schema, if provided\n if (labels.validateSchema && !isValidationDisabled()) {\n if (Array.isArray(transformed)) {\n for (const row of transformed) validateOutput(labels.validateSchema, row);\n } else if (transformed !== null && transformed !== undefined) {\n validateOutput(labels.validateSchema, transformed);\n }\n }\n return transformed;\n }\n\n // Non-SELECT: return the write result as-is\n return out;\n };\n\n // 0) Invoke the method body inside a run() context. Three outcomes:\n // - body calls run(): the pipeline executed inside the body; return\n // the body's result verbatim (it may have caught/transformed it).\n // - body returns a SqlFragment (template literal path): execute it.\n // - body throws without calling run() (legacy placeholder throw):\n // fall through to the pipeline.\n const runCtx: RunContext = { ran: false, execute: pipeline };\n let fragmentResult: unknown;\n try {\n fragmentResult = await runStorage.run(runCtx, () => original.apply(this, callArgs));\n } catch (bodyError) {\n // A body that invoked run() is real logic — its errors propagate.\n if (runCtx.ran) throw bodyError;\n // Method body threw (e.g. placeholder `throw new Error('replaced')`) — fall through to file/inline SQL\n fragmentResult = undefined;\n }\n if (runCtx.ran) return fragmentResult;\n\n if (fragmentResult instanceof SqlFragment) {\n const { sql: boundSql, params } = fragmentResult.toSQL();\n\n const dbName = labels.db ?? options?.db ?? classLabels?.db;\n const { entry } = await resolveExecution(dbName);\n const db = entry.db;\n\n let out;\n try {\n const tx = getActiveTransaction(entry);\n out = tx ? await tx.query(boundSql, params) : await db.query(boundSql, params);\n } catch (dbError: any) {\n throw new DatabaseError(\n dbError?.message || String(dbError),\n boundSql,\n dbError instanceof Error ? dbError : undefined\n );\n }\n\n if (Array.isArray(out)) {\n const shaped = applyShape(out, labels.shape);\n const transformed = labels.transform ? labels.transform(shaped) : shaped;\n\n if (labels.validateSchema && !isValidationDisabled()) {\n if (Array.isArray(transformed)) {\n for (const row of transformed) validateOutput(labels.validateSchema, row);\n } else if (transformed !== null && transformed !== undefined) {\n validateOutput(labels.validateSchema, transformed);\n }\n }\n return transformed;\n }\n return out;\n }\n\n return pipeline();\n };\n\n return desc;\n };\n}\n\nfunction applyDefaults(defaults: Record<string, unknown> | undefined, input: any) {\n if (!defaults) return input;\n if (Array.isArray(input)) return input; // defaults only apply to named-object args\n return { ...defaults, ...(input || {}) };\n}\n\nfunction applyShape<T>(rows: T[], shape?: 'single' | 'only' | 'exist' | 'none'): any {\n switch (shape) {\n case 'single':\n return rows.length > 0 ? rows[0] : null;\n case 'only':\n if (rows.length !== 1) throw new ExactlyOneRowError(rows.length);\n return rows[0];\n case 'exist':\n if (rows.length < 1) throw new NoRowsError();\n return rows[0];\n case 'none':\n if (rows.length > 0) throw new RowsExistError(rows.length);\n return null;\n default:\n return rows;\n }\n}\n"]}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/decorators/query.ts"],"names":[],"mappings":"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","sourcesContent":["import { getClassLabels, getMethodLabels, setMethodLabels } from '../core/metadata';\nimport { SqlStackError, ExactlyOneRowError, NoRowsError, RowsExistError, DatabaseError, ExpectedRowsError } from '../core/errors';\nimport { isValidationDisabled, validateOutput } from '../core/validator';\nimport { resolveExecution } from '../runtime';\nimport { createSqliteBinder, createMysqlBinder, createPostgresBinder } from '../binders/sqlBinder';\nimport { coerceRootPath, resolveSqlFromFs } from '../core/fileResolution';\nimport { registerDecoratedMethod, recordQueryMethodOnClass } from '../core/resolver';\nimport { defaultSourceScanResolver } from '../core/sourceScanResolver';\nimport { getActiveTransaction } from '../transactions';\nimport { SqlFragment } from '../sql';\nimport { runStorage, type RunContext } from '../run';\n\ntype QueryOptions = {\n sql?: string; // optional inline SQL for testing; otherwise, future: load from file\n db?: string; // optional override DB name\n dialect?: 'sqlite' | 'mysql' | 'postgres';\n};\n\nexport function Query(arg?: string | QueryOptions) {\n return function (_target: any, prop: string | symbol, desc: PropertyDescriptor) {\n const options: QueryOptions | undefined = typeof arg === 'string' ? undefined : arg;\n const rootArg: string | undefined = typeof arg === 'string' ? arg : undefined;\n // Store method-level db override if provided\n if (options?.db) {\n setMethodLabels(_target, prop, { db: options.db });\n }\n // Store inline SQL if provided\n if (options?.sql) {\n setMethodLabels(_target, prop, { source: { kind: 'inline', sql: options.sql } });\n } else {\n // FS-based resolution: only an EXPLICIT path argument pins a directory.\n // Bare @Query() resolves through the active resolver (or the default\n // SourceScanResolver) — no stack-based directory guessing, which breaks\n // under bundlers and test transforms.\n const { rootDir } = coerceRootPath(rootArg);\n if (rootDir) {\n setMethodLabels(_target, prop, { source: { kind: 'fs', rootDir } });\n }\n }\n\n // Record for resolver coverage checks: immutable class metadata (the\n // canonical, environment-local source) plus the deprecated global list\n // consulted by the legacy global-resolver path.\n const decoratedEntry = {\n className: _target?.constructor?.name ?? '<anonymous>',\n methodName: String(prop),\n inline: !!options?.sql,\n };\n recordQueryMethodOnClass(_target, decoratedEntry);\n registerDecoratedMethod(decoratedEntry);\n\n const original = desc.value;\n desc.value = async function (...callArgs: any[]) {\n const labels = getMethodLabels(this, prop);\n const classLabels = getClassLabels(this);\n\n // The full file/inline pipeline (resolve source, bind, execute,\n // shape/transform/validate). Invoked either by run() from inside the\n // method body, or directly as the legacy fallback when the body throws.\n const pipeline = async () => {\n // 1) prepare args with defaults\n const rawInput = callArgs.length === 1 ? callArgs[0] : callArgs; // object or positional array\n\n // 2) choose database and dialect via the active environment\n const dbName = labels.db ?? options?.db ?? classLabels?.db;\n const { entry, resolver: activeResolver } = await resolveExecution(dbName);\n const db = entry.db;\n const dialect = options?.dialect ?? db.dialect ?? 'sqlite';\n\n // 3) load SQL source (inline, environment resolver, v1 fs fallback,\n // or the zero-config source scan — bare @Query() with nothing installed)\n const sql = labels?.source?.kind === 'inline'\n ? labels.source.sql\n : activeResolver\n ? activeResolver.resolve({\n className: this?.constructor?.name ?? '<anonymous>',\n methodName: String(prop),\n dialect,\n rootDir: labels?.source?.kind === 'fs' ? labels.source.rootDir : undefined,\n })\n : labels?.source?.kind === 'fs'\n ? resolveSqlFromFs(labels.source.rootDir, String(prop), dialect).sql\n : defaultSourceScanResolver()?.resolve({\n className: this?.constructor?.name ?? '<anonymous>',\n methodName: String(prop),\n dialect,\n });\n if (!sql) {\n throw new SqlStackError(`No SQL source provided for method ${String(prop)}. Use @Query() with a file/folder path or inline sql.`);\n }\n\n // 4) bind placeholders\n // Decide argument mode: positional if SQL contains :argN\n let workingSql = sql;\n const hasPositional = /:arg[1-9][0-9]*/.test(workingSql);\n\n // Prepare args for binder\n let args: any;\n if (hasPositional) {\n args = callArgs;\n } else {\n const namedBase = callArgs.length > 0 ? callArgs[0] : undefined;\n args = applyDefaults(labels.defaults, namedBase ?? {});\n }\n\n // Compute paging and inject :offset/:limit (named mode) or rewrite to positional\n const pageCfg = labels.page;\n if (pageCfg) {\n const { size, zeroBase } = pageCfg;\n const base = zeroBase ? 0 : 1;\n\n // Extract page number from input (object) or a trailing options object in positional mode\n const pageFromObject = (val: any): number | undefined => {\n if (val && typeof val === 'object' && !Array.isArray(val) && typeof (val as any).page !== 'undefined') {\n const p = (val as any).page;\n if (typeof p === 'number' && isFinite(p)) return p;\n }\n return undefined;\n };\n\n let pageNum: number | undefined;\n if (hasPositional) {\n // Variadic-style: only the LAST argument may carry `{ page }`\n if (callArgs.length > 0) {\n const last = callArgs[callArgs.length - 1];\n pageNum = pageFromObject(last);\n }\n } else {\n // Prefer last-arg options if provided; otherwise read from named object\n if (callArgs.length > 1) {\n const last = callArgs[callArgs.length - 1];\n pageNum = pageFromObject(last);\n }\n if (pageNum === undefined) {\n pageNum = pageFromObject(args);\n }\n }\n\n const effectivePage = typeof pageNum === 'number' ? pageNum : base;\n const offset = (effectivePage - base) * size;\n const limit = size;\n\n if (hasPositional) {\n // Replace occurrences of :offset and :limit with new :argN tokens appended to args\n const baseIndex = callArgs.length; // start numbering after user args\n let nextIndex = baseIndex + 1;\n const additions: unknown[] = [];\n\n const rewrite = (sqlText: string) => {\n const out: string[] = [];\n let i = 0;\n let inSQ = false, inDQ = false, inLC = false, inBC = false;\n const len = sqlText.length;\n while (i < len) {\n const ch = sqlText[i];\n const next = i + 1 < len ? sqlText[i + 1] : '';\n if (inLC) { out.push(ch); if (ch === '\\n') inLC = false; i++; continue; }\n if (inBC) { out.push(ch); if (ch === '*' && next === '/') { out.push(next); i++; inBC = false; } i++; continue; }\n if (inSQ) {\n out.push(ch);\n if (ch === \"'\" && next === \"'\") { out.push(next); i += 2; continue; }\n if (ch === \"'\") inSQ = false;\n i++;\n continue;\n }\n if (inDQ) {\n out.push(ch);\n if (ch === '\"' && next === '\"') { out.push(next); i += 2; continue; }\n if (ch === '\"') inDQ = false;\n i++;\n continue;\n }\n if (ch === '-' && next === '-') { out.push(ch, next); i += 2; inLC = true; continue; }\n if (ch === '/' && next === '*') { out.push(ch, next); i += 2; inBC = true; continue; }\n if (ch === '\"') { out.push(ch); inDQ = true; i++; continue; }\n if (ch === \"'\") { out.push(ch); inSQ = true; i++; continue; }\n if (ch === ':' && next === ':') { out.push('::'); i += 2; continue; }\n if (ch === ':') {\n // parse token\n let j = i + 1;\n const start = j;\n while (j < len) {\n const c = sqlText[j];\n if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c === '_') j++; else break;\n }\n const name = sqlText.slice(start, j);\n if (name === 'offset') {\n const token = `:arg${nextIndex++}`;\n out.push(token);\n additions.push(offset);\n i = j;\n continue;\n }\n if (name === 'limit') {\n const token = `:arg${nextIndex++}`;\n out.push(token);\n additions.push(limit);\n i = j;\n continue;\n }\n // otherwise leave untouched\n out.push(':');\n i++;\n continue;\n }\n out.push(ch);\n i++;\n }\n return out.join('');\n };\n\n const rewritten = rewrite(workingSql);\n if (rewritten !== workingSql) {\n workingSql = rewritten;\n // append values so :argK map correctly\n (args as unknown[]).push(...additions);\n }\n } else {\n // Named-mode: attach computed values (override any provided)\n args = { ...(args as Record<string, unknown>), offset, limit };\n }\n }\n const binder =\n dialect === 'postgres' ? createPostgresBinder() : dialect === 'mysql' ? createMysqlBinder() : createSqliteBinder();\n const { sql: boundSql, params } = binder.bind(workingSql, args as any);\n\n // 5) execute query via registry DB\n let out;\n try {\n const tx = getActiveTransaction(entry);\n out = tx ? await tx.query(boundSql, params) : await db.query(boundSql, params);\n } catch (dbError: any) {\n // Attach SQL query (with placeholders) to error for debugging\n throw new DatabaseError(\n dbError?.message || String(dbError),\n boundSql,\n dbError instanceof Error ? dbError : undefined\n );\n }\n\n // 6) If rows were returned (SELECT/CTE/RETURNING), shape + transform + validate;\n // otherwise return the write result as-is (or fail if a shape was requested)\n return finishResult(out, labels, this, prop);\n };\n\n // 0) Invoke the method body inside a run() context. Three outcomes:\n // - body calls run(): the pipeline executed inside the body; return\n // the body's result verbatim (it may have caught/transformed it).\n // - body returns a SqlFragment (template literal path): execute it.\n // - body throws without calling run() (legacy placeholder throw):\n // fall through to the pipeline.\n const runCtx: RunContext = { ran: false, execute: pipeline };\n let fragmentResult: unknown;\n try {\n fragmentResult = await runStorage.run(runCtx, () => original.apply(this, callArgs));\n } catch (bodyError) {\n // A body that invoked run() is real logic — its errors propagate.\n if (runCtx.ran) throw bodyError;\n // Method body threw (e.g. placeholder `throw new Error('replaced')`) — fall through to file/inline SQL\n fragmentResult = undefined;\n }\n if (runCtx.ran) return fragmentResult;\n\n if (fragmentResult instanceof SqlFragment) {\n const { sql: boundSql, params } = fragmentResult.toSQL();\n\n const dbName = labels.db ?? options?.db ?? classLabels?.db;\n const { entry } = await resolveExecution(dbName);\n const db = entry.db;\n\n let out;\n try {\n const tx = getActiveTransaction(entry);\n out = tx ? await tx.query(boundSql, params) : await db.query(boundSql, params);\n } catch (dbError: any) {\n throw new DatabaseError(\n dbError?.message || String(dbError),\n boundSql,\n dbError instanceof Error ? dbError : undefined\n );\n }\n\n return finishResult(out, labels, this, prop);\n }\n\n return pipeline();\n };\n\n return desc;\n };\n}\n\nfunction applyDefaults(defaults: Record<string, unknown> | undefined, input: any) {\n if (!defaults) return input;\n if (Array.isArray(input)) return input; // defaults only apply to named-object args\n return { ...defaults, ...(input || {}) };\n}\n\n// Shared tail of both execution paths. Rows (any statement that produced a\n// result set) are shaped, transformed, and validated. A write result is\n// returned verbatim — unless a result-shape decorator was requested, in which\n// case the statement cannot satisfy it and we fail at the call site instead of\n// silently handing back a truthy `{ rowsAffected }` object.\nfunction finishResult(out: unknown, labels: any, self: any, prop: string | symbol): any {\n if (!Array.isArray(out)) {\n if (labels.shape) {\n throw new ExpectedRowsError(\n `${self?.constructor?.name ?? '<anonymous>'}.${String(prop)}`,\n labels.shape\n );\n }\n return out;\n }\n const shaped = applyShape(out, labels.shape);\n const transformed = labels.transform ? labels.transform(shaped) : shaped;\n\n if (labels.validateSchema && !isValidationDisabled()) {\n if (Array.isArray(transformed)) {\n for (const row of transformed) validateOutput(labels.validateSchema, row);\n } else if (transformed !== null && transformed !== undefined) {\n validateOutput(labels.validateSchema, transformed);\n }\n }\n return transformed;\n}\n\nfunction applyShape<T>(rows: T[], shape?: 'single' | 'only' | 'exist' | 'none'): any {\n switch (shape) {\n case 'single':\n return rows.length > 0 ? rows[0] : null;\n case 'only':\n if (rows.length !== 1) throw new ExactlyOneRowError(rows.length);\n return rows[0];\n case 'exist':\n if (rows.length < 1) throw new NoRowsError();\n return rows[0];\n case 'none':\n if (rows.length > 0) throw new RowsExistError(rows.length);\n return null;\n default:\n return rows;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAwBA,MAAM,QAAQ;IAAd;QACU,QAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IAyB5C,CAAC;IAtBC,QAAQ,CAAC,IAAY,EAAE,EAAY;QACjC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,CAAC,IAAa;QACpB,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACrD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;QAChE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,IAAa;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IAChC,CAAC;CACF;AAED,8DAA8D;AAC9D,MAAM,CAAC,GAAG,UAAiB,CAAC;AAC5B,IAAI,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC;IAC9B,CAAC,CAAC,sBAAsB,GAAG,IAAI,QAAQ,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAa,CAAC,CAAC,sBAAsB,CAAC","sourcesContent":["export type Dialect = 'sqlite' | 'mysql' | 'postgres';\n\n// Result for non-SELECT statements across adapters\nexport interface WriteResult {\n rowsAffected: number;\n lastInsertId?: unknown;\n}\n\n// Postgres-specific extension when using RETURNING on write statements\nexport interface PostgresWriteResult extends WriteResult {\n // Only present when the SQL includes RETURNING and rows are returned\n returning?: any[];\n}\n\nexport type QueryResult = any[] | WriteResult | PostgresWriteResult;\n\nexport interface Database {\n dialect: Dialect;\n query(sql: string, params: unknown[]): Promise<QueryResult>;\n // Underlying driver connection or pool (driver-specific)\n conn: unknown;\n close: () => Promise<void> | void;\n}\n\nclass Registry {\n private map = new Map<string, Database>();\n private defaultName?: string;\n\n register(name: string, db: Database) {\n this.map.set(name, db);\n return this;\n }\n\n setDefault(name: string) {\n if (!this.map.has(name)) throw new Error(`No database registered under ${name}`);\n this.defaultName = name;\n return this;\n }\n\n getEntry(name?: string): { name: string; db: Database } {\n const key = name ?? this.defaultName;\n if (!key) throw new Error('No default database set');\n const db = this.map.get(key);\n if (!db) throw new Error(`No database registered under ${key}`);\n return { name: key, db };\n }\n\n get(name?: string): Database {\n return this.getEntry(name).db;\n }\n}\n\n// Ensure a single shared instance across module copies/usages\nconst g = globalThis as any;\nif (!g.__SQLSTACK_SINGLETON__) {\n g.__SQLSTACK_SINGLETON__ = new Registry();\n}\n\nexport const SqlStackDB: Registry = g.__SQLSTACK_SINGLETON__;\n\nexport type IStackDB = typeof SqlStackDB;\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/registry.ts"],"names":[],"mappings":"AAwBA,MAAM,QAAQ;IAAd;QACU,QAAG,GAAG,IAAI,GAAG,EAAoB,CAAC;IAyB5C,CAAC;IAtBC,QAAQ,CAAC,IAAY,EAAE,EAAY;QACjC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,CAAC,IAAY;QACrB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,QAAQ,CAAC,IAAa;QACpB,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC;QACrC,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACrD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC;QAChE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IAC3B,CAAC;IAED,GAAG,CAAC,IAAa;QACf,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IAChC,CAAC;CACF;AAED,8DAA8D;AAC9D,MAAM,CAAC,GAAG,UAAiB,CAAC;AAC5B,IAAI,CAAC,CAAC,CAAC,sBAAsB,EAAE,CAAC;IAC9B,CAAC,CAAC,sBAAsB,GAAG,IAAI,QAAQ,EAAE,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAa,CAAC,CAAC,sBAAsB,CAAC","sourcesContent":["export type Dialect = 'sqlite' | 'mysql' | 'postgres';\n\n// Result for statements that produce no result set (INSERT/UPDATE/DELETE\n// without RETURNING, DDL). Statements that DO produce a result set — SELECT,\n// CTEs, and `... RETURNING` — return rows (`any[]`) instead; the affected\n// count is `rows.length`.\nexport interface WriteResult {\n rowsAffected: number;\n lastInsertId?: unknown;\n}\n\n/** @deprecated RETURNING now yields rows directly; this is identical to WriteResult. */\nexport type PostgresWriteResult = WriteResult;\n\nexport type QueryResult = any[] | WriteResult;\n\nexport interface Database {\n dialect: Dialect;\n query(sql: string, params: unknown[]): Promise<QueryResult>;\n // Underlying driver connection or pool (driver-specific)\n conn: unknown;\n close: () => Promise<void> | void;\n}\n\nclass Registry {\n private map = new Map<string, Database>();\n private defaultName?: string;\n\n register(name: string, db: Database) {\n this.map.set(name, db);\n return this;\n }\n\n setDefault(name: string) {\n if (!this.map.has(name)) throw new Error(`No database registered under ${name}`);\n this.defaultName = name;\n return this;\n }\n\n getEntry(name?: string): { name: string; db: Database } {\n const key = name ?? this.defaultName;\n if (!key) throw new Error('No default database set');\n const db = this.map.get(key);\n if (!db) throw new Error(`No database registered under ${key}`);\n return { name: key, db };\n }\n\n get(name?: string): Database {\n return this.getEntry(name).db;\n }\n}\n\n// Ensure a single shared instance across module copies/usages\nconst g = globalThis as any;\nif (!g.__SQLSTACK_SINGLETON__) {\n g.__SQLSTACK_SINGLETON__ = new Registry();\n}\n\nexport const SqlStackDB: Registry = g.__SQLSTACK_SINGLETON__;\n\nexport type IStackDB = typeof SqlStackDB;\n"]}