sqlstack 3.4.0 → 3.5.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.
- package/dist/cjs/core/errors.d.ts +9 -0
- package/dist/cjs/core/errors.d.ts.map +1 -1
- package/dist/cjs/core/errors.js +10 -0
- package/dist/cjs/core/errors.js.map +1 -1
- package/dist/cjs/decorators/query.d.ts +14 -0
- package/dist/cjs/decorators/query.d.ts.map +1 -1
- package/dist/cjs/decorators/query.js +124 -17
- package/dist/cjs/decorators/query.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +2 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/run.d.ts +140 -6
- package/dist/cjs/run.d.ts.map +1 -1
- package/dist/cjs/run.js +127 -17
- package/dist/cjs/run.js.map +1 -1
- package/dist/cjs/runtime.d.ts +8 -0
- package/dist/cjs/runtime.d.ts.map +1 -1
- package/dist/cjs/runtime.js +12 -0
- package/dist/cjs/runtime.js.map +1 -1
- package/dist/cjs/sql.d.ts +19 -0
- package/dist/cjs/sql.d.ts.map +1 -1
- package/dist/cjs/sql.js +66 -28
- package/dist/cjs/sql.js.map +1 -1
- package/dist/cjs/transactions.d.ts +8 -0
- package/dist/cjs/transactions.d.ts.map +1 -1
- package/dist/cjs/transactions.js +18 -0
- package/dist/cjs/transactions.js.map +1 -1
- package/dist/esm/core/errors.js +10 -0
- package/dist/esm/core/errors.js.map +1 -1
- package/dist/esm/decorators/query.js +127 -20
- package/dist/esm/decorators/query.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/run.js +123 -18
- package/dist/esm/run.js.map +1 -1
- package/dist/esm/runtime.js +11 -0
- package/dist/esm/runtime.js.map +1 -1
- package/dist/esm/sql.js +63 -27
- package/dist/esm/sql.js.map +1 -1
- package/dist/esm/transactions.js +17 -0
- package/dist/esm/transactions.js.map +1 -1
- package/package.json +1 -1
- package/readme.md +128 -39
|
@@ -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, 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
|
+
{"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, resolveSqlResolver } from '../runtime';\nimport type { SqlResolver } from '../core/resolver';\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, compileFragment } from '../sql';\nimport {\n runStorage,\n resolveRunTarget,\n executeOnTarget,\n toRunError,\n fragmentText,\n type RunContext,\n type RunInvocation,\n type RunTarget,\n} 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\n/**\n * Turn a method into a database query. The body calls `run(...)` (see `run`\n * for its forms); the wrapper resolves SQL, binds, executes, and applies the\n * shape/transform/validation decorators. A string argument is the root\n * directory holding the method's `.sql` file; `{ sql }` gives inline SQL,\n * `{ db }` pins a registered database, `{ dialect }` overrides binding style.\n *\n * The decorated method's promise rejects with:\n * @throws {DatabaseError} When the driver rejects the statement (original\n * error in `.cause`).\n * @throws {SqlStackError} For missing SQL sources, unresolvable databases,\n * and shape/validation failures (ExpectedRowsError, ExactlyOneRowError,\n * NoRowsError, RowsExistError, ValidationError).\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 // Resolve, bind, and execute the method's own SQL (inline, resolver,\n // or file) and return the adapter's raw result. `callArgs` is the\n // binding input: the method's own arguments for run() and the legacy\n // fallback, or the params given to run(db, params). `explicit` carries\n // the database chosen by run(db, params).\n const executeMethodSql = async (\n callArgs: any[],\n explicit: { target: RunTarget; resolver: SqlResolver | undefined } | undefined,\n onSql: (sqlText: string) => void\n ): Promise<unknown> => {\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 (or run's explicit database)\n let target: RunTarget;\n let activeResolver: SqlResolver | undefined;\n if (explicit) {\n target = explicit.target;\n activeResolver = explicit.resolver;\n } else {\n target = await contextTarget();\n activeResolver = target.resolver;\n }\n const db = target.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 onSql(sql);\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 // Binding failures (missing :name, bad array value) surface as DatabaseError like every\n // other run() failure; the original error stays in `.cause`.\n let bound: { sql: string; params: unknown[] };\n try {\n bound = binder.bind(workingSql, args as any);\n } catch (bindError) {\n throw toRunError(bindError, workingSql);\n }\n const { sql: boundSql, params } = bound;\n onSql(boundSql);\n\n // 5) execute query (inside the active transaction on that database, if any)\n let out;\n try {\n out = target.tx ? await target.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 return out;\n };\n\n // Database from the decorator context: @Query({ db }), @QueryBinder({ db }),\n // or the environment default.\n const contextTarget = async (): Promise<RunTarget> => {\n const dbName = labels.db ?? options?.db ?? classLabels?.db;\n const resolved = await resolveExecution(dbName);\n return {\n db: resolved.entry.db,\n tx: getActiveTransaction(resolved.entry),\n resolver: resolved.resolver,\n byName: true,\n };\n };\n\n // run's argument-taking forms: return the adapter's raw result.\n const executeInvocation = async (\n invocation: Exclude<RunInvocation, { kind: 'default' }>,\n onSql: (sqlText: string) => void\n ): Promise<unknown> => {\n if (invocation.kind === 'fragment') {\n // run(query) / run(db, query): the fragment replaces the method's SQL;\n // the method's arguments are not bound.\n const target = invocation.db !== undefined ? await resolveRunTarget(invocation.db) : await contextTarget();\n const dialect = options?.dialect ?? target.db.dialect ?? 'sqlite';\n const { sql: boundSql, params } = compileFragment(invocation.fragment, dialect);\n onSql(boundSql);\n return executeOnTarget(target, boundSql, params);\n }\n // run(db, params): the method's own SQL against db, bound from params\n // only (an object for :named, an array for :argN).\n const target = await resolveRunTarget(invocation.db);\n // Inline SQL needs no resolver; only look one up for file-based SQL.\n const resolver = target.byName\n ? target.resolver\n : labels?.source?.kind === 'inline'\n ? undefined\n : await resolveSqlResolver();\n const bindArgs = Array.isArray(invocation.params) ? [...invocation.params] : [invocation.params];\n return executeMethodSql(bindArgs, { target, resolver }, onSql);\n };\n\n // The full pipeline: execute, then — if rows were returned\n // (SELECT/CTE/RETURNING) — shape + transform + validate; a write result\n // is returned as-is (or fails if a shape was requested). Invoked by\n // run() from inside the method body, or directly as the legacy fallback\n // when the body throws. The zero-argument path is unchanged; run's\n // argument-taking forms get the unified error contract: any failure\n // before shaping that is not already a SqlStackError becomes a\n // DatabaseError with the original error in `.cause`.\n const pipeline = async (invocation?: RunInvocation): Promise<unknown> => {\n if (invocation === undefined || invocation.kind === 'default') {\n const out = await executeMethodSql(callArgs, undefined, () => {});\n return finishResult(out, labels, this, prop);\n }\n let sqlText = invocation.kind === 'fragment' ? fragmentText(invocation.fragment) : '';\n let out: unknown;\n try {\n out = await executeInvocation(invocation, (s) => {\n sqlText = s;\n });\n } catch (err) {\n throw toRunError(err, sqlText);\n }\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 (deprecated template literal path):\n // 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, invocations: true };\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 warnFragmentBodyDeprecated(this, prop);\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\n// Deprecated (removal in the next major version): a @Query body that RETURNS\n// an sql`` fragment. It only type-checks when the method's declared return\n// type is bent to admit SqlFragment (an `as any`-style hole). One warning per\n// class.method per process.\nconst warnedFragmentBodies = new Set<string>();\n\nfunction warnFragmentBodyDeprecated(self: any, prop: string | symbol): void {\n const key = `${self?.constructor?.name ?? '<anonymous>'}.${String(prop)}`;\n if (warnedFragmentBodies.has(key)) return;\n warnedFragmentBodies.add(key);\n process.emitWarning(\n `@Query method ${key} returns an sql\\`\\` fragment from its body. This form is deprecated and will be ` +\n 'removed in the next major version. Use `return run(sql`...`)` (or `return run(db, sql`...`)`) instead.',\n { type: 'DeprecationWarning', code: 'SQLSTACK_FRAGMENT_BODY' }\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"]}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SQL Template Strings
|
|
2
2
|
export { sql, SqlFragment } from './sql.js';
|
|
3
|
-
// Query
|
|
3
|
+
// Query execution — `return run()` inside a @Query method body, or
|
|
4
|
+
// `run(db, sql`...`)` anywhere with a database chosen at call time
|
|
4
5
|
export { run } from './run.js';
|
|
5
6
|
// Decorators
|
|
6
7
|
export * from './decorators/queryBinder.js';
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEzC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEzC,mEAAmE;AACnE,mEAAmE;AACnE,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5B,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAElC,eAAe;AACf,cAAc,gBAAgB,CAAC;AAE/B,WAAW;AACX,cAAc,YAAY,CAAC;AAE3B,wBAAwB;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,aAAa;AACb,cAAc,aAAa,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;AAElD,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,sCAAsC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAQzC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,mDAAmD;AACnD,cAAc,qBAAqB,CAAC","sourcesContent":["// SQL Template Strings\nexport { sql, SqlFragment } from './sql';\n\n// Query execution — `return run()` inside a @Query method body, or\n// `run(db, sql`...`)` anywhere with a database chosen at call time\nexport { run } from './run';\nexport type { RunDatabase, RejectCompiledSql } from './run';\n\n// Decorators\nexport * from './decorators/queryBinder';\nexport * from './decorators/query';\nexport * from './decorators/defaults';\nexport * from './decorators/resultShape';\nexport * from './decorators/validateResult';\nexport * from './decorators/transform';\nexport * from './decorators/page';\n\n// Transactions\nexport * from './transactions';\n\n// Adapters\nexport * from './adapters';\n\n// Errors and Validation\nexport * from './core/errors';\nexport * from './core/validator';\n\n// DTO Helper\nexport * from './utils/dto';\n\n// Database Registry and Types\nexport type { Dialect, WriteResult, PostgresWriteResult, QueryResult, Database } from './registry';\nexport { SqlStackDB, IStackDB } from './registry';\n\n// Environment-owned runtime (v3): per-root SqlStack + active-context resolution\nexport { SqlStack } from './stack';\nexport type { DatabaseEntry, DatabaseRegistration, SqlStackConfig } from './stack';\nexport { activeSqlStack, resolveExecution } from './runtime';\n\n// Dynamic database families (spec 17)\nexport { FamilyRuntime } from './family';\nexport type {\n DatabaseFamilyProvider,\n FamilyConfig,\n FamilyMemberEntry,\n DatabaseLease,\n DatabaseInspection,\n} from './family';\nexport { sqliteFamily } from './families/sqliteFamily';\nexport type { SqliteFamilyOptions } from './families/sqliteFamily';\n\n// SQL Resolvers (v2): pluggable SQL source resolution\nexport type { SqlResolver, SqlManifest, SqlResolutionRequest, ManifestResolverOptions } from './core/resolver';\nexport { FsResolver, ManifestResolver, MANIFEST_DIALECT_EXT, getActiveResolver } from './core/resolver';\nexport { SourceScanResolver } from './core/sourceScanResolver';\n\n// Legacy exports (kept for backward compatibility)\nexport * from './binders/sqlBinder';\n"]}
|
package/dist/esm/run.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { SqlStackError } from './core/errors.js';
|
|
2
|
+
import { SqlStackError, DatabaseError } from './core/errors.js';
|
|
3
|
+
import { isSqlFragment, compileFragment } from './sql.js';
|
|
4
|
+
import { resolveExecution } from './runtime.js';
|
|
5
|
+
import { getActiveTransaction, getActiveTransactionForDatabase } from './transactions.js';
|
|
3
6
|
// Anchored on globalThis via Symbol.for so duplicated module instances
|
|
4
7
|
// (npm link, dual ESM/CJS loads) share one channel between the decorator
|
|
5
8
|
// and the run() the application imports.
|
|
@@ -9,26 +12,128 @@ if (!anchor[RUN_CHANNEL]) {
|
|
|
9
12
|
anchor[RUN_CHANNEL] = new AsyncLocalStorage();
|
|
10
13
|
}
|
|
11
14
|
export const runStorage = anchor[RUN_CHANNEL];
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* Call it as the body of a @Query-decorated method in place of the legacy
|
|
15
|
-
* placeholder throw:
|
|
16
|
-
*
|
|
17
|
-
* @Query()
|
|
18
|
-
* async getUsers(active: boolean): Promise<User[]> {
|
|
19
|
-
* return run<User[]>();
|
|
20
|
-
* }
|
|
21
|
-
*
|
|
22
|
-
* Takes no arguments — the method's own arguments, database, SQL source,
|
|
23
|
-
* transaction, shaping, transform, and validation all come from the
|
|
24
|
-
* decorator context. The generic is a typing convenience only.
|
|
25
|
-
*/
|
|
26
|
-
export async function run() {
|
|
15
|
+
export async function run(...args) {
|
|
16
|
+
const invocation = parseRunArgs(args);
|
|
27
17
|
const ctx = runStorage.getStore();
|
|
28
18
|
if (!ctx) {
|
|
29
|
-
|
|
19
|
+
if (invocation.kind === 'fragment' && invocation.db !== undefined) {
|
|
20
|
+
return executeFragment(invocation.db, invocation.fragment);
|
|
21
|
+
}
|
|
22
|
+
if (invocation.kind === 'default') {
|
|
23
|
+
throw new SqlStackError('run() called outside a @Query method. It may only be invoked from the body of a @Query-decorated method.');
|
|
24
|
+
}
|
|
25
|
+
if (invocation.kind === 'fragment') {
|
|
26
|
+
throw new SqlStackError('run(query) called outside a @Query method has no database. Pass one explicitly: run(db, query).');
|
|
27
|
+
}
|
|
28
|
+
throw new SqlStackError('run(db, params) called outside a @Query method has no SQL source. ' +
|
|
29
|
+
'Pass an sql`` fragment instead: run(db, sql`...`).');
|
|
30
|
+
}
|
|
31
|
+
if (invocation.kind !== 'default' && !ctx.invocations) {
|
|
32
|
+
throw new SqlStackError('run(...) with arguments reached a @Query wrapper from an older sqlstack copy that cannot honour them. ' +
|
|
33
|
+
'Make sure a single sqlstack version is installed.');
|
|
30
34
|
}
|
|
31
35
|
ctx.ran = true;
|
|
32
|
-
return ctx.execute();
|
|
36
|
+
return invocation.kind === 'default' ? ctx.execute() : ctx.execute(invocation);
|
|
37
|
+
}
|
|
38
|
+
function parseRunArgs(args) {
|
|
39
|
+
if (args.length === 0)
|
|
40
|
+
return { kind: 'default' };
|
|
41
|
+
if (args.length === 1) {
|
|
42
|
+
const [query] = args;
|
|
43
|
+
if (isSqlFragment(query))
|
|
44
|
+
return { kind: 'fragment', fragment: query };
|
|
45
|
+
throw new SqlStackError(typeof query === 'string'
|
|
46
|
+
? 'run(query) does not accept SQL strings. Build the statement with the sql`` tag: run(sql`...`).'
|
|
47
|
+
: 'run(query) requires an sql`` fragment.');
|
|
48
|
+
}
|
|
49
|
+
if (args.length === 2) {
|
|
50
|
+
const [db, second] = args;
|
|
51
|
+
assertRunDatabase(db);
|
|
52
|
+
if (isSqlFragment(second))
|
|
53
|
+
return { kind: 'fragment', db, fragment: second };
|
|
54
|
+
if (typeof second === 'string') {
|
|
55
|
+
throw new SqlStackError('run(db, query) does not accept SQL strings. Build the statement with the sql`` tag: run(db, sql`...`).');
|
|
56
|
+
}
|
|
57
|
+
if (isCompiledSql(second)) {
|
|
58
|
+
throw new SqlStackError('run(db, ...) received the { sql, params } output of .toSQL(). Pass the sql`` fragment itself so run can ' +
|
|
59
|
+
'bind it for the target dialect: run(db, sql`...`).');
|
|
60
|
+
}
|
|
61
|
+
if (typeof second === 'object' && second !== null)
|
|
62
|
+
return { kind: 'params', db, params: second };
|
|
63
|
+
throw new SqlStackError('run(db, x) requires an sql`` fragment or a params object/array as its second argument.');
|
|
64
|
+
}
|
|
65
|
+
throw new SqlStackError(`run() accepts at most 2 arguments, got ${args.length}.`);
|
|
66
|
+
}
|
|
67
|
+
function assertRunDatabase(db) {
|
|
68
|
+
if (typeof db === 'string' && db.length > 0)
|
|
69
|
+
return;
|
|
70
|
+
if (typeof db === 'object' && db !== null && typeof db.query === 'function')
|
|
71
|
+
return;
|
|
72
|
+
throw new SqlStackError('run(db, ...) requires a database handle with query(sql, params) or a registered database name as its first argument.');
|
|
73
|
+
}
|
|
74
|
+
function isCompiledSql(value) {
|
|
75
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value))
|
|
76
|
+
return false;
|
|
77
|
+
const keys = Object.keys(value);
|
|
78
|
+
const rec = value;
|
|
79
|
+
return keys.length === 2 && typeof rec.sql === 'string' && Array.isArray(rec.params);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* @internal Resolve run's database argument. A name goes through the active
|
|
83
|
+
* SqlStack (or legacy registry) and joins that entry's transaction. A handle
|
|
84
|
+
* is used as-is — no registry lookup, so it works without any SqlStack — and
|
|
85
|
+
* joins an active transaction only if one is open on that same handle.
|
|
86
|
+
*/
|
|
87
|
+
export async function resolveRunTarget(db) {
|
|
88
|
+
if (typeof db === 'string') {
|
|
89
|
+
const { entry, resolver } = await resolveExecution(db);
|
|
90
|
+
return { db: entry.db, tx: getActiveTransaction(entry), resolver, byName: true };
|
|
91
|
+
}
|
|
92
|
+
return { db, tx: getActiveTransactionForDatabase(db), resolver: undefined, byName: false };
|
|
93
|
+
}
|
|
94
|
+
/** @internal Run one bound statement on the target (inside its transaction, if any). */
|
|
95
|
+
export async function executeOnTarget(target, boundSql, params) {
|
|
96
|
+
try {
|
|
97
|
+
return target.tx ? await target.tx.query(boundSql, params) : await target.db.query(boundSql, params);
|
|
98
|
+
}
|
|
99
|
+
catch (dbError) {
|
|
100
|
+
throw toDatabaseError(dbError, boundSql);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* @internal Normalize a failure from run's argument-taking forms: errors that
|
|
105
|
+
* are already SqlStackError (DatabaseError, shape/validation errors) pass
|
|
106
|
+
* through; anything else becomes DatabaseError with the original in `.cause`.
|
|
107
|
+
*/
|
|
108
|
+
export function toRunError(err, sqlText) {
|
|
109
|
+
return err instanceof SqlStackError ? err : toDatabaseError(err, sqlText);
|
|
110
|
+
}
|
|
111
|
+
function toDatabaseError(err, sqlText) {
|
|
112
|
+
const message = err?.message;
|
|
113
|
+
return new DatabaseError(typeof message === 'string' && message ? message : String(err), sqlText, err instanceof Error ? err : undefined);
|
|
114
|
+
}
|
|
115
|
+
/** @internal Raw template text of a fragment, for error messages. */
|
|
116
|
+
export function fragmentText(fragment) {
|
|
117
|
+
return fragment.strings.join('?');
|
|
118
|
+
}
|
|
119
|
+
/** @internal Compile a fragment for the dialect, wrapping macro errors. */
|
|
120
|
+
export function compileForRun(fragment, dialect) {
|
|
121
|
+
try {
|
|
122
|
+
return compileFragment(fragment, dialect);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
throw toRunError(err, fragmentText(fragment));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function executeFragment(db, fragment) {
|
|
129
|
+
let target;
|
|
130
|
+
try {
|
|
131
|
+
target = await resolveRunTarget(db);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
throw toRunError(err, fragmentText(fragment));
|
|
135
|
+
}
|
|
136
|
+
const { sql: boundSql, params } = compileForRun(fragment, target.db.dialect ?? 'sqlite');
|
|
137
|
+
return executeOnTarget(target, boundSql, params);
|
|
33
138
|
}
|
|
34
139
|
//# sourceMappingURL=run.js.map
|
package/dist/esm/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAc9C,uEAAuE;AACvE,yEAAyE;AACzE,yCAAyC;AACzC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAC5D,MAAM,MAAM,GAAG,UAA0C,CAAC;AAC1D,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;IACzB,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,iBAAiB,EAAc,CAAC;AAC5D,CAAC;AACD,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAkC,CAAC;AAE/E;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG;IACvB,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,aAAa,CACrB,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IACD,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC;IACf,OAAO,GAAG,CAAC,OAAO,EAAgB,CAAC;AACrC,CAAC","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { SqlStackError } from './core/errors';\n\n/**\n * Per-invocation context established by the @Query wrapper before the method\n * body executes. `execute` performs the full query pipeline (resolve SQL,\n * bind, execute, shape/transform/validate); `ran` records that the body\n * invoked run(), so the wrapper returns the body's result verbatim instead\n * of falling through to the legacy pipeline.\n */\nexport type RunContext = {\n execute: () => Promise<unknown>;\n ran: boolean;\n};\n\n// Anchored on globalThis via Symbol.for so duplicated module instances\n// (npm link, dual ESM/CJS loads) share one channel between the decorator\n// and the run() the application imports.\nconst RUN_CHANNEL = Symbol.for('noego.sqlstack.runContext');\nconst anchor = globalThis as Record<PropertyKey, unknown>;\nif (!anchor[RUN_CHANNEL]) {\n anchor[RUN_CHANNEL] = new AsyncLocalStorage<RunContext>();\n}\nexport const runStorage = anchor[RUN_CHANNEL] as AsyncLocalStorage<RunContext>;\n\n/**\n * Execute the current @Query method's SQL and return the finished result.\n * Call it as the body of a @Query-decorated method in place of the legacy\n * placeholder throw:\n *\n * @Query()\n * async getUsers(active: boolean): Promise<User[]> {\n * return run<User[]>();\n * }\n *\n * Takes no arguments — the method's own arguments, database, SQL source,\n * transaction, shaping, transform, and validation all come from the\n * decorator context. The generic is a typing convenience only.\n */\nexport async function run<T = any>(): Promise<T> {\n const ctx = runStorage.getStore();\n if (!ctx) {\n throw new SqlStackError(\n 'run() called outside a @Query method. It may only be invoked from the body of a @Query-decorated method.'\n );\n }\n ctx.ran = true;\n return ctx.execute() as Promise<T>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { SqlStackError, DatabaseError } from './core/errors';\nimport type { Dialect } from './registry';\nimport { SqlFragment, isSqlFragment, compileFragment } from './sql';\nimport { resolveExecution } from './runtime';\nimport type { SqlResolver } from './core/resolver';\nimport { getActiveTransaction, getActiveTransactionForDatabase } from './transactions';\nimport type { ActiveTransaction } from './transactions';\n\n/**\n * Anything run(db, ...) can execute against: sqlstack's own `Database`\n * (from createSqliteDb/createPgDb/createMysqlDb), or any application handle\n * exposing `query(sql, params)`. `dialect` selects placeholder style and\n * defaults to `'sqlite'` when absent. run never opens databases by path.\n */\nexport interface RunDatabase {\n readonly dialect?: Dialect;\n query(sql: string, params: unknown[]): Promise<unknown>;\n}\n\n/**\n * Type-level guard for the params form of run: rejects the\n * `{ sql, params }` object returned by `fragment.toSQL()`. Pass the sql``\n * fragment itself instead, so run owns dialect binding and error handling.\n */\nexport type RejectCompiledSql<P> = P extends { readonly sql: string; readonly params: readonly unknown[] }\n ? never\n : unknown;\n\n/**\n * What a run(...) call made inside a @Query body asks of the wrapper's\n * pipeline. `default` is the zero-argument run().\n */\nexport type RunInvocation =\n | { readonly kind: 'default' }\n | { readonly kind: 'fragment'; readonly db?: RunDatabase | string; readonly fragment: SqlFragment }\n | { readonly kind: 'params'; readonly db: RunDatabase | string; readonly params: object };\n\n/**\n * Per-invocation context established by the @Query wrapper before the method\n * body executes. `execute` performs the full query pipeline (resolve SQL,\n * bind, execute, shape/transform/validate); `ran` records that the body\n * invoked run(), so the wrapper returns the body's result verbatim instead\n * of falling through to the legacy pipeline. `invocations` marks a wrapper\n * that understands the argument-taking run forms (an older duplicated copy\n * of the decorator would silently ignore them).\n */\nexport type RunContext = {\n execute: (invocation?: RunInvocation) => Promise<unknown>;\n ran: boolean;\n invocations?: true;\n};\n\n// Anchored on globalThis via Symbol.for so duplicated module instances\n// (npm link, dual ESM/CJS loads) share one channel between the decorator\n// and the run() the application imports.\nconst RUN_CHANNEL = Symbol.for('noego.sqlstack.runContext');\nconst anchor = globalThis as Record<PropertyKey, unknown>;\nif (!anchor[RUN_CHANNEL]) {\n anchor[RUN_CHANNEL] = new AsyncLocalStorage<RunContext>();\n}\nexport const runStorage = anchor[RUN_CHANNEL] as AsyncLocalStorage<RunContext>;\n\n/**\n * Execute the current @Query method's SQL and return the finished result.\n * Call it as the body of a @Query-decorated method:\n *\n * @Query()\n * async getUsers(active: boolean): Promise<User[]> {\n * return run();\n * }\n *\n * Takes no arguments — the method's own arguments, database, SQL source,\n * transaction, shaping, transform, and validation all come from the\n * decorator context. T is inferred from the method's declared return type.\n *\n * @throws {DatabaseError} When the driver rejects the statement (original\n * error in `.cause`).\n * @throws {SqlStackError} When called outside a @Query method, or for\n * shape/validation failures (ExactlyOneRowError, NoRowsError, ValidationError, ...).\n */\nexport function run<T = any>(): Promise<T>;\n/**\n * Inside a @Query method: execute this inline sql`` fragment instead of the\n * method's SQL file. The database comes from the method/class/registry\n * context (`@Query({ db })`, `@QueryBinder({ db })`, the default), the\n * active transaction on it is joined, and the method's shape/transform/\n * validation decorators apply. The method's arguments are not auto-bound —\n * the fragment's `${}` values are the parameters.\n *\n * @Single @Query()\n * async byEmail(email: string): Promise<User | null> {\n * return run(sql`SELECT * FROM users WHERE email = ${email}`);\n * }\n *\n * @throws {DatabaseError} When the fragment cannot be compiled (macro input\n * errors), the database cannot be resolved, or the driver rejects the\n * statement. The original error is in `.cause`.\n * @throws {SqlStackError} When called outside a @Query method (use\n * `run(db, query)` there), or for shape/validation failures.\n */\nexport function run<T = unknown>(query: SqlFragment): Promise<T>;\n/**\n * Execute an sql`` fragment against an explicit database: a handle\n * (anything with `query(sql, params)`) or the name of a database registered\n * with the active SqlStack / legacy registry. Usable anywhere.\n *\n * Binds for the database's dialect (`$1..` for Postgres, `?` otherwise;\n * default sqlite). Joins an active transaction opened on the same database\n * (same registered handle, or same name). Outside a @Query method the raw\n * result is returned (rows array, or `{ rowsAffected }` for writes); inside\n * one, the method's shape/transform/validation decorators apply.\n *\n * const rows = await run<Row[]>(accountsDb, sql`SELECT * FROM t WHERE id = ${id}`);\n *\n * @throws {DatabaseError} When the fragment cannot be compiled, a named\n * database cannot be resolved, or the driver rejects the statement. The\n * original error is in `.cause`, and its string `code` is copied to `.code`.\n * @throws {SqlStackError} For invalid arguments, or shape/validation failures.\n */\nexport function run<T = unknown>(db: RunDatabase | string, query: SqlFragment): Promise<T>;\n/**\n * Inside a @Query method: run the method's own SQL (its .sql file or inline\n * `@Query({ sql })`) against `db`, binding `params` (an object for `:named`\n * placeholders, an array for `:arg1..`). The method's raw arguments are NOT\n * auto-bound in this form — `params` is the whole binding input. @Defaults,\n * @Page, shaping, transform, and validation still apply.\n *\n * @Single @Query()\n * async byEmail(db: Database, p: { email: string }): Promise<User | null> {\n * return run(db, p);\n * }\n *\n * @throws {DatabaseError} When binding fails, a named database cannot be\n * resolved, or the driver rejects the statement. The original error is in\n * `.cause`.\n * @throws {SqlStackError} When called outside a @Query method, when passed\n * `.toSQL()` output, or for shape/validation failures.\n */\nexport function run<T = unknown, P extends object = object>(\n db: RunDatabase | string,\n params: P & RejectCompiledSql<P>\n): Promise<T>;\nexport async function run(...args: unknown[]): Promise<unknown> {\n const invocation = parseRunArgs(args);\n const ctx = runStorage.getStore();\n\n if (!ctx) {\n if (invocation.kind === 'fragment' && invocation.db !== undefined) {\n return executeFragment(invocation.db, invocation.fragment);\n }\n if (invocation.kind === 'default') {\n throw new SqlStackError(\n 'run() called outside a @Query method. It may only be invoked from the body of a @Query-decorated method.'\n );\n }\n if (invocation.kind === 'fragment') {\n throw new SqlStackError(\n 'run(query) called outside a @Query method has no database. Pass one explicitly: run(db, query).'\n );\n }\n throw new SqlStackError(\n 'run(db, params) called outside a @Query method has no SQL source. ' +\n 'Pass an sql`` fragment instead: run(db, sql`...`).'\n );\n }\n\n if (invocation.kind !== 'default' && !ctx.invocations) {\n throw new SqlStackError(\n 'run(...) with arguments reached a @Query wrapper from an older sqlstack copy that cannot honour them. ' +\n 'Make sure a single sqlstack version is installed.'\n );\n }\n\n ctx.ran = true;\n return invocation.kind === 'default' ? ctx.execute() : ctx.execute(invocation);\n}\n\nfunction parseRunArgs(args: unknown[]): RunInvocation {\n if (args.length === 0) return { kind: 'default' };\n\n if (args.length === 1) {\n const [query] = args;\n if (isSqlFragment(query)) return { kind: 'fragment', fragment: query };\n throw new SqlStackError(\n typeof query === 'string'\n ? 'run(query) does not accept SQL strings. Build the statement with the sql`` tag: run(sql`...`).'\n : 'run(query) requires an sql`` fragment.'\n );\n }\n\n if (args.length === 2) {\n const [db, second] = args;\n assertRunDatabase(db);\n if (isSqlFragment(second)) return { kind: 'fragment', db, fragment: second };\n if (typeof second === 'string') {\n throw new SqlStackError(\n 'run(db, query) does not accept SQL strings. Build the statement with the sql`` tag: run(db, sql`...`).'\n );\n }\n if (isCompiledSql(second)) {\n throw new SqlStackError(\n 'run(db, ...) received the { sql, params } output of .toSQL(). Pass the sql`` fragment itself so run can ' +\n 'bind it for the target dialect: run(db, sql`...`).'\n );\n }\n if (typeof second === 'object' && second !== null) return { kind: 'params', db, params: second };\n throw new SqlStackError('run(db, x) requires an sql`` fragment or a params object/array as its second argument.');\n }\n\n throw new SqlStackError(`run() accepts at most 2 arguments, got ${args.length}.`);\n}\n\nfunction assertRunDatabase(db: unknown): asserts db is RunDatabase | string {\n if (typeof db === 'string' && db.length > 0) return;\n if (typeof db === 'object' && db !== null && typeof (db as { query?: unknown }).query === 'function') return;\n throw new SqlStackError(\n 'run(db, ...) requires a database handle with query(sql, params) or a registered database name as its first argument.'\n );\n}\n\nfunction isCompiledSql(value: unknown): boolean {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n const keys = Object.keys(value);\n const rec = value as { sql?: unknown; params?: unknown };\n return keys.length === 2 && typeof rec.sql === 'string' && Array.isArray(rec.params);\n}\n\n// ---------------------------------------------------------------------------\n// Shared execution helpers (also used by the @Query wrapper)\n// ---------------------------------------------------------------------------\n\n/** @internal A database chosen for one run, plus the transaction it joins. */\nexport type RunTarget = {\n readonly db: RunDatabase;\n readonly tx: ActiveTransaction | undefined;\n /** SQL resolver of the environment, when the target was resolved by name. */\n readonly resolver: SqlResolver | undefined;\n readonly byName: boolean;\n};\n\n/**\n * @internal Resolve run's database argument. A name goes through the active\n * SqlStack (or legacy registry) and joins that entry's transaction. A handle\n * is used as-is — no registry lookup, so it works without any SqlStack — and\n * joins an active transaction only if one is open on that same handle.\n */\nexport async function resolveRunTarget(db: RunDatabase | string): Promise<RunTarget> {\n if (typeof db === 'string') {\n const { entry, resolver } = await resolveExecution(db);\n return { db: entry.db, tx: getActiveTransaction(entry), resolver, byName: true };\n }\n return { db, tx: getActiveTransactionForDatabase(db), resolver: undefined, byName: false };\n}\n\n/** @internal Run one bound statement on the target (inside its transaction, if any). */\nexport async function executeOnTarget(target: RunTarget, boundSql: string, params: unknown[]): Promise<unknown> {\n try {\n return target.tx ? await target.tx.query(boundSql, params) : await target.db.query(boundSql, params);\n } catch (dbError) {\n throw toDatabaseError(dbError, boundSql);\n }\n}\n\n/**\n * @internal Normalize a failure from run's argument-taking forms: errors that\n * are already SqlStackError (DatabaseError, shape/validation errors) pass\n * through; anything else becomes DatabaseError with the original in `.cause`.\n */\nexport function toRunError(err: unknown, sqlText: string): SqlStackError {\n return err instanceof SqlStackError ? err : toDatabaseError(err, sqlText);\n}\n\nfunction toDatabaseError(err: unknown, sqlText: string): DatabaseError {\n const message = (err as { message?: unknown } | undefined)?.message;\n return new DatabaseError(\n typeof message === 'string' && message ? message : String(err),\n sqlText,\n err instanceof Error ? err : undefined\n );\n}\n\n/** @internal Raw template text of a fragment, for error messages. */\nexport function fragmentText(fragment: SqlFragment): string {\n return fragment.strings.join('?');\n}\n\n/** @internal Compile a fragment for the dialect, wrapping macro errors. */\nexport function compileForRun(fragment: SqlFragment, dialect: Dialect): { sql: string; params: unknown[] } {\n try {\n return compileFragment(fragment, dialect);\n } catch (err) {\n throw toRunError(err, fragmentText(fragment));\n }\n}\n\nasync function executeFragment(db: RunDatabase | string, fragment: SqlFragment): Promise<unknown> {\n let target: RunTarget;\n try {\n target = await resolveRunTarget(db);\n } catch (err) {\n throw toRunError(err, fragmentText(fragment));\n }\n const { sql: boundSql, params } = compileForRun(fragment, target.db.dialect ?? 'sqlite');\n return executeOnTarget(target, boundSql, params);\n}\n"]}
|
package/dist/esm/runtime.js
CHANGED
|
@@ -72,6 +72,17 @@ export async function resolveExecution(dbName) {
|
|
|
72
72
|
viaStack: false,
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* @internal The SQL source resolver for one execution WITHOUT resolving a
|
|
77
|
+
* database — used when the caller supplied a database handle directly
|
|
78
|
+
* (`run(db, params)`). Same environment rules as resolveExecution: the
|
|
79
|
+
* active root's SqlStack resolver when an IoC environment is active (and an
|
|
80
|
+
* error when that environment has no SqlStack), else the legacy global one.
|
|
81
|
+
*/
|
|
82
|
+
export async function resolveSqlResolver() {
|
|
83
|
+
const stack = await activeSqlStack();
|
|
84
|
+
return stack ? stack.resolver() : getActiveResolver();
|
|
85
|
+
}
|
|
75
86
|
// ---------------------------------------------------------------------------
|
|
76
87
|
// Legacy (deprecated) global-registry support
|
|
77
88
|
// ---------------------------------------------------------------------------
|
package/dist/esm/runtime.js.map
CHANGED
|
@@ -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 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"]}
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAiB,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AA0B9C,0EAA0E;AAC1E,yEAAyE;AACzE,mEAAmE;AACnE,IAAI,gBAA4D,CAAC;AAEjE,SAAS,OAAO;IACd,gBAAgB,KAAhB,gBAAgB,GAAK,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAC5C,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAE,CAAe,CAAC,CAAC,CAAC,SAAS,CAAC,EAChE,GAAG,EAAE,CAAC,SAAS,CAChB,EAAC;IACF,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,mBAAmB;IACjC,gBAAgB,GAAG,SAAS,CAAC;AAC/B,CAAC;AAED,SAAS,0BAA0B;IACjC,OAAO,IAAI,aAAa,CACtB,+EAA+E;QAC7E,mFAAmF,CACtF,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,GAAc,EAAE,GAAY;IAChE,MAAM,uBAAuB,GAAG,GAAG,CAAC,uBAAuB,CAAC;IAC5D,OAAO,CACL,OAAO,uBAAuB,KAAK,UAAU;QAC7C,GAAG,YAAY,uBAAuB;QACtC,GAAG,CAAC,OAAO,KAAK,gCAAgC,CACjD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,MAAM,GAAG,GAAG,MAAM,OAAO,EAAE,CAAC;IAC5B,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,gBAAgB,CAAC,OAAO,EAA6B,CAAC;IACxE,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAE7B,2EAA2E;IAC3E,6EAA6E;IAC7E,oEAAoE;IACpE,MAAM,iBAAiB,GAAG,OAAO,KAAK,CAAC,YAAY,KAAK,UAAU,CAAC;IACnE,IAAI,iBAAiB,IAAI,CAAC,KAAK,CAAC,YAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxD,MAAM,0BAA0B,EAAE,CAAC;IACrC,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAa,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,0EAA0E;QAC1E,yEAAyE;QACzE,gEAAgE;QAChE,IAAI,CAAC,iBAAiB,IAAI,4BAA4B,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,0BAA0B,EAAE,CAAC;QACrC,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AASD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAAe;IACpD,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;IACrC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,KAAK,EAAE,MAAM,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjG,CAAC;IACD,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;QAC1B,QAAQ,EAAE,iBAAiB,EAAE;QAC7B,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,MAAM,KAAK,GAAG,MAAM,cAAc,EAAE,CAAC;IACrC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,8CAA8C;AAC9C,8EAA8E;AAE9E,yEAAyE;AACzE,0EAA0E;AAC1E,0EAA0E;AAC1E,uDAAuD;AACvD,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkD,CAAC;AAEhF,8EAA8E;AAC9E,+DAA+D;AAC/D,IAAI,WAAiC,CAAC;AAEtC,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,MAAM,IAAI,MAAM,CAAC,EAAE,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACpD,WAAW,KAAX,WAAW,GAAK,IAAI,QAAQ,EAAE,EAAC;IAC/B,MAAM,KAAK,GAAkB,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;IAC5E,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC;AACf,CAAC","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 * @internal The SQL source resolver for one execution WITHOUT resolving a\n * database — used when the caller supplied a database handle directly\n * (`run(db, params)`). Same environment rules as resolveExecution: the\n * active root's SqlStack resolver when an IoC environment is active (and an\n * error when that environment has no SqlStack), else the legacy global one.\n */\nexport async function resolveSqlResolver(): Promise<SqlResolver | undefined> {\n const stack = await activeSqlStack();\n return stack ? stack.resolver() : getActiveResolver();\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"]}
|
package/dist/esm/sql.js
CHANGED
|
@@ -7,44 +7,81 @@
|
|
|
7
7
|
* sql`UPDATE users SET :update(${data}) WHERE id = ${id}`
|
|
8
8
|
* sql`SELECT * FROM users WHERE :filter(${criteria})`
|
|
9
9
|
* sql`INSERT INTO users :batch_insert(${rows})`
|
|
10
|
+
*
|
|
11
|
+
* Execute a fragment with `run(db, fragment)` (or `run(fragment)` inside a
|
|
12
|
+
* @Query method): run binds it for the target dialect (`?` for SQLite/MySQL,
|
|
13
|
+
* `$1..` for Postgres) and wraps failures in DatabaseError.
|
|
10
14
|
*/
|
|
11
15
|
const MACRO_OPEN = /:(insert|update|filter|batch_insert)\s*\(\s*$/i;
|
|
12
16
|
const MACRO_CLOSE = /^\s*\)/;
|
|
17
|
+
// Cross-copy identity for fragments: duplicated module instances (npm link,
|
|
18
|
+
// dual ESM/CJS loads) each define their own SqlFragment class, so `instanceof`
|
|
19
|
+
// alone would misclassify a fragment built by another copy.
|
|
20
|
+
const FRAGMENT_BRAND = Symbol.for('noego.sqlstack.SqlFragment');
|
|
13
21
|
export class SqlFragment {
|
|
14
22
|
constructor(strings, values) {
|
|
15
23
|
this.strings = strings;
|
|
16
24
|
this.values = values;
|
|
17
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Compile to SQL with `?` placeholders and the matching parameter list.
|
|
28
|
+
*
|
|
29
|
+
* @throws {Error} When a binder macro (`:insert`, `:update`, `:filter`,
|
|
30
|
+
* `:batch_insert`) receives invalid input. `run(...)` wraps this in
|
|
31
|
+
* DatabaseError with the original error in `.cause`.
|
|
32
|
+
*/
|
|
18
33
|
toSQL() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
return compileParts(this.strings, this.values, () => '?');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
Object.defineProperty(SqlFragment.prototype, FRAGMENT_BRAND, { value: true });
|
|
38
|
+
/** @internal True for a SqlFragment from this or any other sqlstack copy. */
|
|
39
|
+
export function isSqlFragment(value) {
|
|
40
|
+
if (value instanceof SqlFragment)
|
|
41
|
+
return true;
|
|
42
|
+
return (typeof value === 'object' &&
|
|
43
|
+
value !== null &&
|
|
44
|
+
value[FRAGMENT_BRAND] === true);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* @internal Compile a fragment for a dialect: `$1, $2, ...` for Postgres,
|
|
48
|
+
* `?` for SQLite and MySQL. Throws plain Error on invalid macro input
|
|
49
|
+
* (callers in run() wrap it).
|
|
50
|
+
*/
|
|
51
|
+
export function compileFragment(fragment, dialect) {
|
|
52
|
+
let next = 0;
|
|
53
|
+
const placeholder = dialect === 'postgres' ? () => `$${++next}` : () => '?';
|
|
54
|
+
return compileParts(fragment.strings, fragment.values, placeholder);
|
|
55
|
+
}
|
|
56
|
+
function compileParts(strings, values, placeholder) {
|
|
57
|
+
const segments = [...strings];
|
|
58
|
+
const sqlParts = [];
|
|
59
|
+
const params = [];
|
|
60
|
+
for (let i = 0; i < segments.length; i++) {
|
|
61
|
+
if (i < values.length) {
|
|
62
|
+
const openMatch = segments[i].match(MACRO_OPEN);
|
|
63
|
+
const closeMatch = segments[i + 1]?.match(MACRO_CLOSE);
|
|
64
|
+
if (openMatch && closeMatch) {
|
|
65
|
+
// Binder macro: trim the macro syntax and expand
|
|
66
|
+
sqlParts.push(segments[i].slice(0, -openMatch[0].length));
|
|
67
|
+
segments[i + 1] = segments[i + 1].slice(closeMatch[0].length);
|
|
68
|
+
const { text, params: expanded } = expandMacro(openMatch[1].toLowerCase(), values[i], placeholder);
|
|
69
|
+
sqlParts.push(text);
|
|
70
|
+
params.push(...expanded);
|
|
39
71
|
}
|
|
40
72
|
else {
|
|
41
73
|
sqlParts.push(segments[i]);
|
|
74
|
+
sqlParts.push(placeholder());
|
|
75
|
+
params.push(values[i]);
|
|
42
76
|
}
|
|
43
77
|
}
|
|
44
|
-
|
|
78
|
+
else {
|
|
79
|
+
sqlParts.push(segments[i]);
|
|
80
|
+
}
|
|
45
81
|
}
|
|
82
|
+
return { sql: sqlParts.join(''), params };
|
|
46
83
|
}
|
|
47
|
-
function expandMacro(type, value) {
|
|
84
|
+
function expandMacro(type, value, placeholder) {
|
|
48
85
|
switch (type) {
|
|
49
86
|
case 'insert': {
|
|
50
87
|
assertPlainObject(value, ':insert()');
|
|
@@ -53,7 +90,7 @@ function expandMacro(type, value) {
|
|
|
53
90
|
if (keys.length === 0)
|
|
54
91
|
throw new Error(':insert() requires at least one column');
|
|
55
92
|
const cols = keys.join(', ');
|
|
56
|
-
const placeholders = keys.map(() =>
|
|
93
|
+
const placeholders = keys.map(() => placeholder()).join(', ');
|
|
57
94
|
return { text: `(${cols}) VALUES (${placeholders})`, params: keys.map(k => obj[k]) };
|
|
58
95
|
}
|
|
59
96
|
case 'update': {
|
|
@@ -62,7 +99,7 @@ function expandMacro(type, value) {
|
|
|
62
99
|
if (entries.length === 0)
|
|
63
100
|
throw new Error(':update() requires at least one defined column');
|
|
64
101
|
return {
|
|
65
|
-
text: entries.map(([k]) => `${k} =
|
|
102
|
+
text: entries.map(([k]) => `${k} = ${placeholder()}`).join(', '),
|
|
66
103
|
params: entries.map(([, v]) => v),
|
|
67
104
|
};
|
|
68
105
|
}
|
|
@@ -72,7 +109,7 @@ function expandMacro(type, value) {
|
|
|
72
109
|
if (entries.length === 0)
|
|
73
110
|
throw new Error(':filter() requires at least one defined condition');
|
|
74
111
|
return {
|
|
75
|
-
text: entries.map(([k]) => `${k} =
|
|
112
|
+
text: entries.map(([k]) => `${k} = ${placeholder()}`).join(' AND '),
|
|
76
113
|
params: entries.map(([, v]) => v),
|
|
77
114
|
};
|
|
78
115
|
}
|
|
@@ -84,8 +121,7 @@ function expandMacro(type, value) {
|
|
|
84
121
|
if (keys.length === 0)
|
|
85
122
|
throw new Error(':batch_insert() requires at least one column');
|
|
86
123
|
const cols = keys.join(', ');
|
|
87
|
-
const
|
|
88
|
-
const allPlaceholders = value.map(() => rowPlaceholder).join(', ');
|
|
124
|
+
const allPlaceholders = value.map(() => `(${keys.map(() => placeholder()).join(', ')})`).join(', ');
|
|
89
125
|
return {
|
|
90
126
|
text: `(${cols}) VALUES ${allPlaceholders}`,
|
|
91
127
|
params: value.flatMap(row => keys.map(k => row[k])),
|