Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
github: [wellwelwel]
github: [wellwelwel, sidorares]
2 changes: 1 addition & 1 deletion .github/workflows/cd_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
uses: google-github-actions/release-please-action@v3
id: release
with:
token: ${{ secrets.PAT }}
token: ${{ secrets.GITHUB_TOKEN }}
release-type: node
package-name: sql-escaper
changelog-path: 'CHANGELOG.md'
Expand Down
22 changes: 11 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
# Changelog

## [1.2.0](https://github.com/wellwelwel/sql-escaper/compare/v1.1.2...v1.2.0) (2026-02-05)
## [1.2.0](https://github.com/mysqljs/sql-escaper/compare/v1.1.2...v1.2.0) (2026-02-05)


### Features

* add support for `BigInt` ([#11](https://github.com/wellwelwel/sql-escaper/issues/11)) ([b07edbe](https://github.com/wellwelwel/sql-escaper/commit/b07edbe36cc0cf8ef08ff1f1547126470fd4dd17))
* add support for `Uint8Array` ([#9](https://github.com/wellwelwel/sql-escaper/issues/9)) ([84d859b](https://github.com/wellwelwel/sql-escaper/commit/84d859bbc1bedbbfe81c2aa071684d55614e5e22))
* add support for `BigInt` ([#11](https://github.com/mysqljs/sql-escaper/issues/11)) ([b07edbe](https://github.com/mysqljs/sql-escaper/commit/b07edbe36cc0cf8ef08ff1f1547126470fd4dd17))
* add support for `Uint8Array` ([#9](https://github.com/mysqljs/sql-escaper/issues/9)) ([84d859b](https://github.com/mysqljs/sql-escaper/commit/84d859bbc1bedbbfe81c2aa071684d55614e5e22))


### Bug Fixes

* preserve `JSON` path expressions ([#12](https://github.com/wellwelwel/sql-escaper/issues/12)) ([f580956](https://github.com/wellwelwel/sql-escaper/commit/f580956767c8edd45b7e95ffce3dec795722c0be))
* preserve `JSON` path expressions ([#12](https://github.com/mysqljs/sql-escaper/issues/12)) ([f580956](https://github.com/mysqljs/sql-escaper/commit/f580956767c8edd45b7e95ffce3dec795722c0be))

## [1.1.2](https://github.com/wellwelwel/sql-escaper/compare/v1.1.1...v1.1.2) (2026-02-05)
## [1.1.2](https://github.com/mysqljs/sql-escaper/compare/v1.1.1...v1.1.2) (2026-02-05)


### Bug Fixes

* limit object expansion to immediate placeholder ([#7](https://github.com/wellwelwel/sql-escaper/issues/7)) ([7ac70f3](https://github.com/wellwelwel/sql-escaper/commit/7ac70f3c33da09680c37d6fc0445a6368c012bb6))
* limit object expansion to immediate placeholder ([#7](https://github.com/mysqljs/sql-escaper/issues/7)) ([7ac70f3](https://github.com/mysqljs/sql-escaper/commit/7ac70f3c33da09680c37d6fc0445a6368c012bb6))

## [1.1.1](https://github.com/wellwelwel/sql-escaper/compare/v1.1.0...v1.1.1) (2026-02-05)
## [1.1.1](https://github.com/mysqljs/sql-escaper/compare/v1.1.0...v1.1.1) (2026-02-05)


### Bug Fixes

* prevent object expansion in placeholders after `SET` clause ([#5](https://github.com/wellwelwel/sql-escaper/issues/5)) ([557bd7f](https://github.com/wellwelwel/sql-escaper/commit/557bd7fe17b92dc2b36235721ee4f45afa3101b4))
* prevent object expansion in placeholders after `SET` clause ([#5](https://github.com/mysqljs/sql-escaper/issues/5)) ([557bd7f](https://github.com/mysqljs/sql-escaper/commit/557bd7fe17b92dc2b36235721ee4f45afa3101b4))

## [1.1.0](https://github.com/wellwelwel/sql-escaper/compare/v1.0.0...v1.1.0) (2026-02-05)
## [1.1.0](https://github.com/mysqljs/sql-escaper/compare/v1.0.0...v1.1.0) (2026-02-05)


### Features

* use an AST-based approach to map keywords ([#3](https://github.com/wellwelwel/sql-escaper/issues/3)) ([f7cde0a](https://github.com/wellwelwel/sql-escaper/commit/f7cde0a445bf1e0d3a4c681f195551247ce9673d))
* use an AST-based approach to map keywords ([#3](https://github.com/mysqljs/sql-escaper/issues/3)) ([f7cde0a](https://github.com/mysqljs/sql-escaper/commit/f7cde0a445bf1e0d3a4c681f195551247ce9673d))

## 1.0.0 (2026-02-04)


### Features

* SQL Escaper's birth ([139eb60](https://github.com/wellwelwel/sql-escaper/commit/139eb6036180e214794e24526214f5e76f346c28))
* SQL Escaper's birth ([139eb60](https://github.com/mysqljs/sql-escaper/commit/139eb6036180e214794e24526214f5e76f346c28))
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Where possible, provide an error test case that the fix covers.

### Features

It's better to discuss an **API** before actually start implementing it. You can open an [**Issue on Github**](https://github.com/wellwelwel/sql-escaper/issues/new), so we can discuss the **API** design implementation ideas.
It's better to discuss an **API** before actually start implementing it. You can open an [**Issue on Github**](https://github.com/mysqljs/sql-escaper/issues/new), so we can discuss the **API** design implementation ideas.

> Please ensure test cases to cover new features.

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2026-current Weslley Araújo (@wellwelwel)
Copyright (c) 2026 Weslley Araújo, Andrey Sidorov, Douglas Wilson, and contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
78 changes: 39 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
<h1 align="center">SQL Escaper</h1>
<div align="center">
# SQL Escaper

[![NPM Version](https://img.shields.io/npm/v/sql-escaper.svg?label=&color=70a1ff&logo=npm&logoColor=white)](https://www.npmjs.com/package/sql-escaper)
[![Coverage](https://img.shields.io/codecov/c/github/wellwelwel/sql-escaper?label=&logo=codecov&logoColor=white&color=98cc00)](https://app.codecov.io/gh/wellwelwel/sql-escaper)<br />
[![GitHub Workflow Status (Node.js)](https://img.shields.io/github/actions/workflow/status/wellwelwel/sql-escaper/ci_node.yml?event=push&label=&branch=main&logo=nodedotjs&logoColor=535c68&color=badc58)](https://github.com/wellwelwel/sql-escaper/actions/workflows/ci_node.yml?query=branch%3Amain)
[![GitHub Workflow Status (Bun)](https://img.shields.io/github/actions/workflow/status/wellwelwel/sql-escaper/ci_bun.yml?event=push&label=&branch=main&logo=bun&logoColor=ffffff&color=f368e0)](https://github.com/wellwelwel/sql-escaper/actions/workflows/ci_bun.yml?query=branch%3Amain)
[![GitHub Workflow Status (Deno)](https://img.shields.io/github/actions/workflow/status/wellwelwel/sql-escaper/ci_deno.yml?event=push&label=&branch=main&logo=deno&logoColor=ffffff&color=079992)](https://github.com/wellwelwel/sql-escaper/actions/workflows/ci_deno.yml?query=branch%3Amain)
[![NPM Downloads](https://img.shields.io/npm/dm/sql-escaper.svg?label=&logo=npm&logoColor=white&color=45aaf2)](https://www.npmjs.com/package/sql-escaper)
[![Coverage](https://img.shields.io/codecov/c/github/mysqljs/sql-escaper?label=&logo=codecov&logoColor=white&color=98cc00)](https://app.codecov.io/gh/mysqljs/sql-escaper)<br />
[![GitHub Workflow Status (Node.js)](https://img.shields.io/github/actions/workflow/status/mysqljs/sql-escaper/ci_node.yml?event=push&label=&branch=main&logo=nodedotjs&logoColor=535c68&color=badc58)](https://github.com/mysqljs/sql-escaper/actions/workflows/ci_node.yml?query=branch%3Amain)
[![GitHub Workflow Status (Bun)](https://img.shields.io/github/actions/workflow/status/mysqljs/sql-escaper/ci_bun.yml?event=push&label=&branch=main&logo=bun&logoColor=ffffff&color=f368e0)](https://github.com/mysqljs/sql-escaper/actions/workflows/ci_bun.yml?query=branch%3Amain)
[![GitHub Workflow Status (Deno)](https://img.shields.io/github/actions/workflow/status/mysqljs/sql-escaper/ci_deno.yml?event=push&label=&branch=main&logo=deno&logoColor=ffffff&color=079992)](https://github.com/mysqljs/sql-escaper/actions/workflows/ci_deno.yml?query=branch%3Amain)

🛡️ Up to [**~40% faster**](#performance) SQL escape and format for **JavaScript** (**Node.js**, **Bun**, and **Deno**).
## Motivation

</div>
**SQL Escaper** is a rework of [**sqlstring**](https://github.com/mysqljs/sqlstring) (created by [**Douglas Wilson**](https://github.com/dougwilson)), by using an **AST**-based approach to parse and format SQL queries while maintaining its same API.

### Rework includes:

- **TypeScript** by default.
- Support for `Uint8Array` and `BigInt`.
- Support for both **CJS** and **ESM** exports.
- Up to [**~40% faster**](#performance) compared to **sqlstring**.
- Distinguishes when a keyword is used as value.
- Distinguishes when a column has a keyword name.
- Distinguishes between multiple clauses/keywords in the same query.
- Reasonable conservative support for **Node.js v12** _(**sqlstring** supports **Node.js v0.6**)_.

> [!TIP]
>
> **SQL Escaper** has the same API as the original [**sqlstring**](https://github.com/mysqljs/sqlstring), so it can be used as a drop-in replacement. If **SQL Escaper** breaks any **API** usage compared to **sqlstring**, please, report it as a bug. [Pull Requests are welcome](./CONTRIBUTING.md).

> [!IMPORTANT]
>
> 🔐 **SQL Escaper** is intended to fix a potential [**SQL Injection vulnerability**](https://flattsecurity.medium.com/finding-an-unseen-sql-injection-by-bypassing-escape-functions-in-mysqljs-mysql-90b27f6542b4) reported in 2022. By combining the original [**sqlstring**](https://github.com/mysqljs/sqlstring) with [**mysqljs/mysql**](https://github.com/mysqljs/mysql) or [**MySQL2**](https://github.com/sidorares/node-mysql2), objects passed as values could be expanded into **SQL** fragments, potentially allowing attackers to manipulate query structure. See [sidorares/node-mysql2#4051](https://github.com/sidorares/node-mysql2/issues/4051) for details.
>
> Regardless of the `stringifyObjects` value, objects used outside of `SET` or `ON DUPLICATE KEY UPDATE` contexts are always stringified as `'[object Object]'`. This is a security measure to prevent [SQL Injection](https://flattsecurity.medium.com/finding-an-unseen-sql-injection-by-bypassing-escape-functions-in-mysqljs-mysql-90b27f6542b4).

---

## Install

Expand All @@ -28,16 +51,10 @@ bun add sql-escaper
deno add npm:sql-escaper
```

> [!NOTE]
>
> 🔐 **SQL Escaper** fixes a potential [**SQL Injection vulnerability**](https://flattsecurity.medium.com/finding-an-unseen-sql-injection-by-bypassing-escape-functions-in-mysqljs-mysql-90b27f6542b4) discovered in 2022 in the original [**sqlstring**](https://github.com/mysqljs/sqlstring), where objects passed as values could be expanded into SQL fragments, potentially allowing attackers to manipulate query structure. See [sidorares/node-mysql2#4051](https://github.com/sidorares/node-mysql2/issues/4051) for details.

---

## Usage

💡 **SQL Escaper** has the same API as the original [**sqlstring**](https://github.com/mysqljs/sqlstring), so it can be used as a drop-in replacement.

### Quickstart

```js
Expand All @@ -59,7 +76,7 @@ escape(raw('NOW()'));
// => 'NOW()'
```

> For _up-to-date_ documentation, always follow the [**README.md**](https://github.com/wellwelwel/sql-escaper?tab=readme-ov-file#readme) in the **GitHub** repository.
> For _up-to-date_ documentation, always follow the [**README.md**](https://github.com/mysqljs/sql-escaper?tab=readme-ov-file#readme) in the **GitHub** repository.

### Import

Expand Down Expand Up @@ -268,10 +285,6 @@ format('UPDATE users SET ?', [{ name: 'foo' }], true);
// => "UPDATE users SET '[object Object]'"
```

> [!IMPORTANT]
>
> Regardless of the `stringifyObjects` value, objects used outside of `SET` or `ON DUPLICATE KEY UPDATE` contexts are always stringified as `'[object Object]'`. This is a security measure to prevent [SQL Injection](https://flattsecurity.medium.com/finding-an-unseen-sql-injection-by-bypassing-escape-functions-in-mysqljs-mysql-90b27f6542b4).

---

### raw
Expand Down Expand Up @@ -321,27 +334,15 @@ Each benchmark formats `10,000` queries using `format` with `100` mixed values (
| ON DUPLICATE KEY UPDATE with 100 values | 466.2 ms | 394.6 ms | **1.18x faster** |
| ON DUPLICATE KEY UPDATE with 100 objects | 558.2 ms | 433.9 ms | **1.29x faster** |

- See detailed results and how the benchmarks are run in the [**benchmark**](https://github.com/wellwelwel/sql-escaper/tree/main/benchmark) directory.
- See detailed results and how the benchmarks are run in the [**benchmark**](https://github.com/mysqljs/sql-escaper/tree/main/benchmark) directory.

> [!NOTE]
>
> Benchmarks ran on [**GitHub Actions**](https://github.com/wellwelwel/sql-escaper/blob/main/.github/workflows/ci_benchmark.yml) (`ubuntu-latest`) using **Node.js LTS**.
> Benchmarks ran on [**GitHub Actions**](https://github.com/mysqljs/sql-escaper/blob/main/.github/workflows/ci_benchmark.yml) (`ubuntu-latest`) using **Node.js LTS**.
> Results may vary depending on runner hardware and runtime version.

---

## Features

- **TypeScript** by default.
- Ships both **CJS** and **ESM** exports.
- Support multi lines, spaces and tables.
- Support **SQL** comments, including multi line comments.
- Distinguish when a keyword is used in a value.
- Distinguish between `SET`, `KEY UPDATE`, and `WHERE` clauses in the same queries.
- Distinguish when a column has a keyword name.

---

## Differences from sqlstring

- Requires **Node.js 12+** (the original [**sqlstring**](https://github.com/mysqljs/sqlstring) supports **Node.js** 0.6+)
Expand Down Expand Up @@ -372,27 +373,26 @@ Each benchmark formats `10,000` queries using `format` with `100` mixed values (

## Security Policy

[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/wellwelwel/sql-escaper/ci_codeql.yml?event=push&label=&branch=main&logo=github&logoColor=white&color=f368e0)](https://github.com/wellwelwel/sql-escaper/actions/workflows/ci_codeql.yml?query=branch%3Amain)
[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/mysqljs/sql-escaper/ci_codeql.yml?event=push&label=&branch=main&logo=github&logoColor=white&color=f368e0)](https://github.com/mysqljs/sql-escaper/actions/workflows/ci_codeql.yml?query=branch%3Amain)

Please check the [**SECURITY.md**](https://github.com/wellwelwel/sql-escaper/blob/main/SECURITY.md).
Please check the [**SECURITY.md**](https://github.com/mysqljs/sql-escaper/blob/main/SECURITY.md).

---

## Contributing

See the [**Contributing Guide**](https://github.com/wellwelwel/sql-escaper/blob/main/CONTRIBUTING.md) and please follow our [**Code of Conduct**](https://github.com/wellwelwel/sql-escaper/blob/main/CODE_OF_CONDUCT.md) 🚀
See the [**Contributing Guide**](https://github.com/mysqljs/sql-escaper/blob/main/CONTRIBUTING.md) and please follow our [**Code of Conduct**](https://github.com/mysqljs/sql-escaper/blob/main/CODE_OF_CONDUCT.md) 🚀

---

## Acknowledgements

- [![Contributors](https://img.shields.io/github/contributors/wellwelwel/sql-escaper?label=Contributors)](https://github.com/wellwelwel/sql-escaper/graphs/contributors)
- [![Contributors](https://img.shields.io/github/contributors/mysqljs/sql-escaper?label=Contributors)](https://github.com/mysqljs/sql-escaper/graphs/contributors)
- **SQL Escaper** is adapted from [**sqlstring**](https://github.com/mysqljs/sqlstring) ([**MIT**](https://github.com/mysqljs/sqlstring/blob/master/LICENSE)), modernizing it with high performance, TypeScript support and multi-runtime compatibility.
- Special thanks to [**Douglas Wilson**](https://github.com/dougwilson) for the original **sqlstring** project and its [**contributors**](https://github.com/mysqljs/sqlstring/graphs/contributors).

---

## License

**SQL Escaper** is under the [**MIT License**](https://github.com/wellwelwel/sql-escaper/blob/main/LICENSE).<br />
Copyright © 2026-present [**Weslley Araújo**](https://github.com/wellwelwel) and **SQL Escaper** [**contributors**](https://github.com/wellwelwel/sql-escaper/graphs/contributors).
**SQL Escaper** is under the [**MIT License**](https://github.com/mysqljs/sql-escaper/blob/main/LICENSE).
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Is SQL Escaper Safe?

**SQL Escaper** is an open-source project, so you can see both the [Source Code on **GitHub** Repository](https://github.com/wellwelwel/sql-escaper) and the [Distribution Code on **NPM**](https://www.npmjs.com/package/sql-escaper?activeTab=code).
**SQL Escaper** is an _open-source_ project, so you can see both the [Source Code on **GitHub** Repository](https://github.com/mysqljs/sql-escaper) and the [Distribution Code on **NPM**](https://www.npmjs.com/package/sql-escaper?activeTab=code).

---

Expand All @@ -25,6 +25,6 @@ Currently, security updates will be applied to the following versions of **SQL E

**Reporting:**

- https://github.com/wellwelwel/sql-escaper/security/advisories
- https://github.com/mysqljs/sql-escaper/security/advisories

> Once the issue has been resolved, you will be attributed a part of the report.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/wellwelwel/sql-escaper.git"
"url": "git+https://github.com/mysqljs/sql-escaper.git"
},
"bugs": {
"url": "https://github.com/wellwelwel/sql-escaper/issues"
"url": "https://github.com/mysqljs/sql-escaper/issues"
},
"author": "https://github.com/wellwelwel",
"author": "https://github.com/mysqljs",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/wellwelwel"
"url": "https://github.com/mysqljs/sql-escaper?sponsor=1"
},
"files": [
"lib"
Expand Down
Loading