sql-escaper
Advanced tools
+3
-2
@@ -5,6 +5,7 @@ /** | ||
| */ | ||
| import type { Raw, SqlValue, Timezone } from './types.js'; | ||
| import type { Raw, SqlValue, TemporalValue, Timezone } from './types.js'; | ||
| import { Buffer } from 'node:buffer'; | ||
| export type { Raw, SqlValue, Timezone } from './types.js'; | ||
| export type { Raw, SqlValue, TemporalValue, Timezone } from './types.js'; | ||
| export declare const dateToString: (date: Date, timezone: Timezone) => string; | ||
| export declare const temporalToString: (value: TemporalValue, timezone?: Timezone) => string; | ||
| export declare const escapeId: (value: SqlValue, forbidQualified?: boolean) => string; | ||
@@ -11,0 +12,0 @@ export declare const objectToValues: (object: Record<string, SqlValue> | Map<string, SqlValue>, timezone?: Timezone) => string; |
+12
-1
@@ -7,3 +7,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.raw = exports.format = exports.escape = exports.arrayToList = exports.bufferToString = exports.objectToValues = exports.escapeId = exports.dateToString = void 0; | ||
| exports.raw = exports.format = exports.escape = exports.arrayToList = exports.bufferToString = exports.objectToValues = exports.escapeId = exports.temporalToString = exports.dateToString = void 0; | ||
| const node_buffer_1 = require("node:buffer"); | ||
@@ -238,2 +238,3 @@ const CONTEXT_TRIGGER = new Uint8Array(128); | ||
| const isDate = (value) => Object.prototype.toString.call(value) === '[object Date]'; | ||
| const isTemporal = (value) => Object.prototype.toString.call(value).startsWith('[object Temporal.'); | ||
| const hasSqlString = (value) => typeof value === 'object' && | ||
@@ -359,2 +360,10 @@ value !== null && | ||
| exports.dateToString = dateToString; | ||
| const temporalToString = (value, timezone) => { | ||
| if ('epochMilliseconds' in value) | ||
| return (0, exports.dateToString)(new Date(value.epochMilliseconds), timezone || 'local'); | ||
| if (value[Symbol.toStringTag] === 'Temporal.PlainDateTime') | ||
| return escapeString(value.toString().replace('T', ' ')); | ||
| return escapeString(value.toString()); | ||
| }; | ||
| exports.temporalToString = temporalToString; | ||
| const escapeId = (value, forbidQualified) => { | ||
@@ -445,2 +454,4 @@ if (Array.isArray(value)) { | ||
| return (0, exports.dateToString)(value, timezone || 'local'); | ||
| if (isTemporal(value)) | ||
| return (0, exports.temporalToString)(value, timezone); | ||
| if (Array.isArray(value)) | ||
@@ -447,0 +458,0 @@ return (0, exports.arrayToList)(value, timezone); |
+11
-1
@@ -206,2 +206,3 @@ import { Buffer } from "node:buffer"; | ||
| const isDate = (value) => Object.prototype.toString.call(value) === "[object Date]"; | ||
| const isTemporal = (value) => Object.prototype.toString.call(value).startsWith("[object Temporal."); | ||
| const hasSqlString = (value) => typeof value === "object" && value !== null && "toSqlString" in value && typeof value.toSqlString === "function"; | ||
@@ -299,2 +300,9 @@ const escapeString = (value) => { | ||
| }; | ||
| const temporalToString = (value, timezone) => { | ||
| if ("epochMilliseconds" in value) | ||
| return dateToString(new Date(value.epochMilliseconds), timezone || "local"); | ||
| if (value[Symbol.toStringTag] === "Temporal.PlainDateTime") | ||
| return escapeString(value.toString().replace("T", " ")); | ||
| return escapeString(value.toString()); | ||
| }; | ||
| const escapeId = (value, forbidQualified) => { | ||
@@ -367,2 +375,3 @@ if (Array.isArray(value)) { | ||
| if (isDate(value)) return dateToString(value, timezone || "local"); | ||
| if (isTemporal(value)) return temporalToString(value, timezone); | ||
| if (Array.isArray(value)) return arrayToList(value, timezone); | ||
@@ -459,3 +468,4 @@ if (value instanceof Set) | ||
| objectToValues, | ||
| raw | ||
| raw, | ||
| temporalToString | ||
| }; |
+2
-1
| export type Raw = { | ||
| toSqlString(): string; | ||
| }; | ||
| export type SqlValue = string | number | bigint | boolean | Date | Buffer | Uint8Array | Raw | Record<string, unknown> | SqlValue[] | Set<SqlValue> | Map<string, SqlValue> | null | undefined; | ||
| export type TemporalValue = Temporal.Instant | Temporal.ZonedDateTime | Temporal.PlainDateTime | Temporal.PlainDate | Temporal.PlainTime | Temporal.PlainYearMonth | Temporal.PlainMonthDay | Temporal.Duration; | ||
| export type SqlValue = string | number | bigint | boolean | Date | TemporalValue | Buffer | Uint8Array | Raw | Record<string, unknown> | SqlValue[] | Set<SqlValue> | Map<string, SqlValue> | null | undefined; | ||
| export type Timezone = 'local' | 'Z' | (string & NonNullable<unknown>); |
+6
-5
| { | ||
| "name": "sql-escaper", | ||
| "version": "1.4.0", | ||
| "version": "1.5.0", | ||
| "description": "🛡️ Faster SQL escape and format for JavaScript (Node.js, Bun, and Deno).", | ||
@@ -33,6 +33,6 @@ "main": "./lib/index.js", | ||
| "build": "rm -rf ./lib && tsc && npm run build:esm", | ||
| "test:node": "poku", | ||
| "test:bun": "bun --bun poku", | ||
| "test:node": "poku test", | ||
| "test:bun": "bun --bun poku test", | ||
| "test:coverage": "mcr --import tsx --config mcr.config.ts npm run test:node", | ||
| "lint": "biome lint && prettier --check .", | ||
| "lint": "biome lint --error-on-warnings && prettier --check .", | ||
| "lint:fix": "biome lint --write && prettier --write .github/workflows/*.yml .", | ||
@@ -44,2 +44,3 @@ "update": "pu minor && npm i && (npm audit fix || true) && npm run lint:fix" | ||
| "@ianvs/prettier-plugin-sort-imports": "^4.7.0", | ||
| "@js-temporal/polyfill": "^0.5.1", | ||
| "@types/node": "^25.2.0", | ||
@@ -52,3 +53,3 @@ "esbuild": "^0.28.1", | ||
| "tsx": "^4.21.0", | ||
| "typescript": "^5.9.3" | ||
| "typescript": "^7.0.2" | ||
| }, | ||
@@ -55,0 +56,0 @@ "exports": { |
+23
-1
@@ -17,3 +17,3 @@ # SQL Escaper | ||
| - **TypeScript** by default. | ||
| - Support for `Uint8Array` and `BigInt`. | ||
| - Support for `Uint8Array`, `BigInt`, and `Temporal`. | ||
| - Support for both **CJS** and **ESM** exports. | ||
@@ -168,2 +168,24 @@ - Up to [**~40% faster**](#performance) compared to **sqlstring**. | ||
| #### Temporal | ||
| [Temporal](https://tc39.es/proposal-temporal/) values are supported too. | ||
| `Temporal.Instant` and `Temporal.ZonedDateTime` are absolute points in time and | ||
| honor the `timezone` argument exactly like `Date` (millisecond precision): | ||
| ```js | ||
| const instant = Temporal.Instant.from('2012-05-07T11:42:03.002Z'); | ||
| escape(instant, true, 'Z'); // "'2012-05-07 11:42:03.002'" | ||
| escape(instant, true, '+0200'); // "'2012-05-07 13:42:03.002'" | ||
| ``` | ||
| `Temporal.PlainDateTime`, `Temporal.PlainDate` and `Temporal.PlainTime` are | ||
| wall-clock values and are emitted verbatim as `DATETIME` / `DATE` / `TIME` | ||
| literals, ignoring `timezone`: | ||
| ```js | ||
| escape(Temporal.PlainDate.from('2012-05-07')); // "'2012-05-07'" | ||
| escape(Temporal.PlainTime.from('11:42:03')); // "'11:42:03'" | ||
| ``` | ||
| #### Buffers | ||
@@ -170,0 +192,0 @@ |
58927
4.17%1057
2.22%517
4.44%11
10%