diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 8ae0c01..7524ef9 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: [wellwelwel] +github: [wellwelwel, sidorares] diff --git a/.github/workflows/cd_publish.yml b/.github/workflows/cd_publish.yml index 8477087..55a8774 100644 --- a/.github/workflows/cd_publish.yml +++ b/.github/workflows/cd_publish.yml @@ -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' diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a2c891..7b14399 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dc3fe89..e35ad85 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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. diff --git a/LICENSE b/LICENSE index 5a188d1..278452c 100644 --- a/LICENSE +++ b/LICENSE @@ -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 diff --git a/README.md b/README.md index 26305c2..13a93bf 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,38 @@ -

SQL Escaper

-
+# 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)
-[![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)
+[![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 -
+**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 @@ -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 @@ -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 @@ -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 @@ -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+) @@ -372,21 +373,21 @@ 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). @@ -394,5 +395,4 @@ See the [**Contributing Guide**](https://github.com/wellwelwel/sql-escaper/blob/ ## License -**SQL Escaper** is under the [**MIT License**](https://github.com/wellwelwel/sql-escaper/blob/main/LICENSE).
-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). diff --git a/SECURITY.md b/SECURITY.md index 40b0cf8..b6390e3 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -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). --- @@ -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. diff --git a/package-lock.json b/package-lock.json index 34d01ce..7cbf5d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,7 @@ }, "funding": { "type": "github", - "url": "https://github.com/sponsors/wellwelwel" + "url": "https://github.com/mysqljs/sql-escaper?sponsor=1" } }, "node_modules/@babel/code-frame": { diff --git a/package.json b/package.json index 09808ba..3e55102 100644 --- a/package.json +++ b/package.json @@ -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"