@dbsp/core 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +13 -0
- package/dist/index.js +39 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -4872,6 +4872,12 @@ declare class UpsertBuilder<T = void> extends MutationBuilderBase<T, UpsertInten
|
|
|
4872
4872
|
* const users = await orm.nql<{ name: string; email: string }>`users | select name, email`.all();
|
|
4873
4873
|
* ```
|
|
4874
4874
|
*
|
|
4875
|
+
* Each `${value}` interpolation is escaped into a safe NQL literal (string/number/boolean/null).
|
|
4876
|
+
* Untrusted string input cannot inject NQL structure because it is always quoted and
|
|
4877
|
+
* single-quotes inside are doubled (`''`). For dynamic structural fragments (table names,
|
|
4878
|
+
* column names, ORDER BY direction) use the builder API (`orm.select()`). See #134 for
|
|
4879
|
+
* upcoming `:param` binding and a `nqlRaw()` escape hatch.
|
|
4880
|
+
*
|
|
4875
4881
|
* @module nql
|
|
4876
4882
|
* @since DX-040
|
|
4877
4883
|
*/
|
|
@@ -4905,6 +4911,13 @@ type NqlTag = <T>(strings: TemplateStringsArray, ...values: unknown[]) => NqlBui
|
|
|
4905
4911
|
/**
|
|
4906
4912
|
* Create an NQL template tag function.
|
|
4907
4913
|
*
|
|
4914
|
+
* Each `${value}` in the template is escaped into a safe NQL literal before parsing.
|
|
4915
|
+
* Supported interpolation types: `string`, `number`, `boolean`, `null`.
|
|
4916
|
+
* Untrusted string input is therefore safe from NQL-syntax injection — it is always
|
|
4917
|
+
* wrapped in single-quotes with embedded quotes doubled (`''`).
|
|
4918
|
+
* For dynamic structural fragments (table names, column names, ORDER BY direction)
|
|
4919
|
+
* use the builder API (`orm.select()`). See issue #134 for upcoming `:param` binding.
|
|
4920
|
+
*
|
|
4908
4921
|
* @param schemaDefinition - Schema definition for validation
|
|
4909
4922
|
* @param model - ModelIR for plan execution
|
|
4910
4923
|
* @param adapter - Optional adapter for query execution
|
package/dist/index.js
CHANGED
|
@@ -5992,11 +5992,49 @@ function negotiateFeatures(model, capabilities, behavior = "warning", checkers =
|
|
|
5992
5992
|
|
|
5993
5993
|
// src/dx/nql.ts
|
|
5994
5994
|
import { compile as nqlCompile } from "@dbsp/nql";
|
|
5995
|
+
function toNqlLiteral(value, index) {
|
|
5996
|
+
if (value === null) {
|
|
5997
|
+
return "null";
|
|
5998
|
+
}
|
|
5999
|
+
switch (typeof value) {
|
|
6000
|
+
case "boolean":
|
|
6001
|
+
return value ? "true" : "false";
|
|
6002
|
+
case "number": {
|
|
6003
|
+
if (!Number.isFinite(value)) {
|
|
6004
|
+
throw new Error(
|
|
6005
|
+
`nql\`...\`: cannot interpolate non-finite number (${value}) at position ${index}. Only finite numbers are supported. For dynamic NQL structure use the builder API (orm.select()). See issue #134.`
|
|
6006
|
+
);
|
|
6007
|
+
}
|
|
6008
|
+
const s = value < 0 ? `-${Math.abs(value)}` : String(value);
|
|
6009
|
+
if (/[eE]/.test(s)) {
|
|
6010
|
+
throw new Error(
|
|
6011
|
+
`nql\`...\`: number ${value} at position ${index} has no exact NQL numeric literal form (exponential notation). Convert it yourself or use the builder API (orm.select()). See issue #134.`
|
|
6012
|
+
);
|
|
6013
|
+
}
|
|
6014
|
+
return s;
|
|
6015
|
+
}
|
|
6016
|
+
case "string": {
|
|
6017
|
+
if (value.includes("\n") || value.includes("\r")) {
|
|
6018
|
+
throw new Error(
|
|
6019
|
+
`nql\`...\`: cannot interpolate a string containing a newline at position ${index}. NQL string literals do not support raw newline characters. For dynamic NQL structure use the builder API (orm.select()). See issue #134.`
|
|
6020
|
+
);
|
|
6021
|
+
}
|
|
6022
|
+
const escaped = value.replaceAll("'", "''");
|
|
6023
|
+
return `'${escaped}'`;
|
|
6024
|
+
}
|
|
6025
|
+
default: {
|
|
6026
|
+
const typeName = value === void 0 ? "undefined" : typeof value;
|
|
6027
|
+
throw new Error(
|
|
6028
|
+
`nql\`...\`: cannot interpolate value of type "${typeName}" at position ${index}. Only string, number, boolean, and null are supported; for dynamic NQL fragments use the builder API (orm.select()). See issue #134.`
|
|
6029
|
+
);
|
|
6030
|
+
}
|
|
6031
|
+
}
|
|
6032
|
+
}
|
|
5995
6033
|
function createNqlTag(schemaDefinition, model, adapter, schemaName) {
|
|
5996
6034
|
return function nql(strings, ...values) {
|
|
5997
6035
|
let query = strings[0] ?? "";
|
|
5998
6036
|
for (let i = 0; i < values.length; i++) {
|
|
5999
|
-
query +=
|
|
6037
|
+
query += toNqlLiteral(values[i], i) + (strings[i + 1] ?? "");
|
|
6000
6038
|
}
|
|
6001
6039
|
return new NqlBuilderImpl(
|
|
6002
6040
|
query,
|