@stacksjs/database 0.75.452 → 0.75.458

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/types.js +1 -1
  2. package/package.json +16 -16
package/dist/types.js CHANGED
@@ -1 +1 @@
1
- const SAFE_ALIAS=/^[A-Z_][A-Z0-9_]*$/i,SAFE_COLUMN=/^[A-Z_][A-Z0-9_]*(\.[A-Z_][A-Z0-9_]*)?$/i;function assertSqlTextIdentifier(value,kind){if(!(kind==="column"?SAFE_COLUMN:SAFE_ALIAS).test(value))throw TypeError(`[database] refusing to interpolate unsafe ${kind} ${JSON.stringify(value)} into SQL text - expected a plain identifier (letters, digits, underscores)`)}function createSqlFragment(text,parameters){return{sql:text,parameters,as(alias){assertSqlTextIdentifier(alias,"alias");return createSqlFragment(`${text} AS ${alias}`,parameters)},toString(){return text}}}export function sql(strings,...values){const sqlParts=[],parameters=[];for(let i=0;i<strings.length;i++){sqlParts.push(strings[i]);if(i<values.length)if(values[i]&&typeof values[i]==="object"&&"raw"in values[i])sqlParts.push(values[i].raw);else{sqlParts.push("?");parameters.push(values[i])}}return createSqlFragment(sqlParts.join(""),parameters)}sql.raw=function raw(value){return{raw:value}};sql.ref=function ref(column){return{raw:column}};sql.literal=function literal(value){return{raw:inlineSqlLiteral(value)}};const SAFE_FILTER_OPERATORS=new Set(["=","!=","<>","<","<=",">",">=","like","not like","ilike","not ilike","is","is not"]);function inlineSqlLiteral(value){if(value===null||value===void 0)return"NULL";if(typeof value==="number"){if(!Number.isFinite(value))throw TypeError(`[database] refusing to inline non-finite number into SQL: ${value}`);return String(value)}if(typeof value==="boolean")return value?"1":"0";if(typeof value==="bigint")return value.toString();return`'${String(value).replace(/'/g,"''")}'`}function createAggregateExpression(text){return{sql:text,as(alias){assertSqlTextIdentifier(alias,"alias");return createAggregateExpression(`${text} AS ${alias}`)},filterWhere(column,op,value){assertSqlTextIdentifier(column,"column");if(!SAFE_FILTER_OPERATORS.has(op.toLowerCase()))throw TypeError(`[database] refusing unsafe aggregate filter operator ${JSON.stringify(op)} - allowed: ${[...SAFE_FILTER_OPERATORS].join(", ")}`);return createAggregateExpression(`${text} FILTER (WHERE ${column} ${op} ${inlineSqlLiteral(value)})`)}}}function aggregate(name,column){if(column!==void 0)assertSqlTextIdentifier(column,"column");return createAggregateExpression(column===void 0?`${name}(*)`:`${name}(${column})`)}export const aggregateFunctions={countAll:()=>aggregate("COUNT"),count:(column)=>aggregate("COUNT",column),sum:(column)=>aggregate("SUM",column),avg:(column)=>aggregate("AVG",column),min:(column)=>aggregate("MIN",column),max:(column)=>aggregate("MAX",column)};
1
+ const SAFE_ALIAS=/^[A-Z_][A-Z0-9_]*$/i,SAFE_COLUMN=/^[A-Z_][A-Z0-9_]*(\.[A-Z_][A-Z0-9_]*)?$/i;function assertSqlTextIdentifier(value,kind){if(!(kind==="column"?SAFE_COLUMN:SAFE_ALIAS).test(value))throw TypeError(`[database] refusing to interpolate unsafe ${kind} ${JSON.stringify(value)} into SQL text - expected a plain identifier (letters, digits, underscores)`)}function createSqlFragment(text,parameters){return{sql:text,parameters,as(alias){assertSqlTextIdentifier(alias,"alias");return createSqlFragment(`${text} AS ${alias}`,parameters)},toString(){return text}}}export function sql(strings,...values){const sqlParts=[],parameters=[];for(let i=0;i<strings.length;i++){sqlParts.push(strings[i]);if(i<values.length)if(values[i]&&typeof values[i]==="object"&&"raw"in values[i])sqlParts.push(values[i].raw);else{sqlParts.push("?");parameters.push(values[i])}}return createSqlFragment(sqlParts.join(""),parameters)}sql.raw=function raw(value){return{raw:value}};sql.ref=function ref(column){return{raw:column}};sql.literal=function literal(value){return{raw:inlineSqlLiteral(value)}};const SAFE_FILTER_OPERATORS=new Set(["=","!=","<>","<","<=",">",">=","like","not like","ilike","not ilike","is","is not"]);function inlineSqlLiteral(value){if(value===null||value===void 0)return"NULL";if(typeof value==="number"){if(!Number.isFinite(value))throw TypeError(`[database] refusing to inline non-finite number into SQL: ${value}`);return String(value)}if(typeof value==="boolean")return value?"1":"0";if(typeof value==="bigint")return value.toString();const text=String(value);if(text.includes("\\"))throw TypeError("[database] refusing to inline a string containing a backslash into SQL: MySQL reads it as an escape. Bind it instead: db.unsafe(sql, params) with sqlHelpers().param(n)");return`'${text.replace(/'/g,"''")}'`}function createAggregateExpression(text){return{sql:text,as(alias){assertSqlTextIdentifier(alias,"alias");return createAggregateExpression(`${text} AS ${alias}`)},filterWhere(column,op,value){assertSqlTextIdentifier(column,"column");if(!SAFE_FILTER_OPERATORS.has(op.toLowerCase()))throw TypeError(`[database] refusing unsafe aggregate filter operator ${JSON.stringify(op)} - allowed: ${[...SAFE_FILTER_OPERATORS].join(", ")}`);return createAggregateExpression(`${text} FILTER (WHERE ${column} ${op} ${inlineSqlLiteral(value)})`)}}}function aggregate(name,column){if(column!==void 0)assertSqlTextIdentifier(column,"column");return createAggregateExpression(column===void 0?`${name}(*)`:`${name}(${column})`)}export const aggregateFunctions={countAll:()=>aggregate("COUNT"),count:(column)=>aggregate("COUNT",column),sum:(column)=>aggregate("SUM",column),avg:(column)=>aggregate("AVG",column),min:(column)=>aggregate("MIN",column),max:(column)=>aggregate("MAX",column)};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/database",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.452",
5
+ "version": "0.75.458",
6
6
  "description": "The Stacks database integration.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -66,26 +66,26 @@
66
66
  "prepublishOnly": "bun run build"
67
67
  },
68
68
  "dependencies": {
69
- "@stacksjs/config": "0.75.452",
70
- "@stacksjs/env": "0.75.452",
71
- "@stacksjs/error-handling": "0.75.452",
72
- "@stacksjs/faker": "0.75.452",
73
- "@stacksjs/features": "0.75.452",
74
- "@stacksjs/logging": "0.75.452",
75
- "@stacksjs/model-meta": "0.75.452",
76
- "@stacksjs/path": "0.75.452",
77
- "@stacksjs/query-builder": "0.75.452",
78
- "@stacksjs/security": "0.75.452",
79
- "@stacksjs/storage": "0.75.452",
80
- "@stacksjs/strings": "0.75.452",
69
+ "@stacksjs/config": "0.75.458",
70
+ "@stacksjs/env": "0.75.458",
71
+ "@stacksjs/error-handling": "0.75.458",
72
+ "@stacksjs/faker": "0.75.458",
73
+ "@stacksjs/features": "0.75.458",
74
+ "@stacksjs/logging": "0.75.458",
75
+ "@stacksjs/model-meta": "0.75.458",
76
+ "@stacksjs/path": "0.75.458",
77
+ "@stacksjs/query-builder": "0.75.458",
78
+ "@stacksjs/security": "0.75.458",
79
+ "@stacksjs/storage": "0.75.458",
80
+ "@stacksjs/strings": "0.75.458",
81
81
  "@stacksjs/ts-validation": "^0.5.7",
82
82
  "bun-query-builder": "^0.3.38",
83
83
  "dynamodb-tooling": "^0.3.6"
84
84
  },
85
85
  "devDependencies": {
86
- "@stacksjs/cli": "0.75.452",
87
- "@stacksjs/router": "0.75.452",
88
- "@stacksjs/utils": "0.75.452",
86
+ "@stacksjs/cli": "0.75.458",
87
+ "@stacksjs/router": "0.75.458",
88
+ "@stacksjs/utils": "0.75.458",
89
89
  "better-dx": "^0.2.24"
90
90
  }
91
91
  }