{"id":13524852,"url":"https://github.com/nearform/sql","last_synced_at":"2025-08-09T13:07:23.115Z","repository":{"id":29898324,"uuid":"123117451","full_name":"nearform/sql","owner":"nearform","description":"SQL injection protection module","archived":false,"fork":false,"pushed_at":"2024-07-15T08:52:56.000Z","size":170,"stargazers_count":216,"open_issues_count":2,"forks_count":58,"subscribers_count":106,"default_branch":"master","last_synced_at":"2024-10-01T09:41:43.259Z","etag":null,"topics":["hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nearform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-02-27T11:07:54.000Z","updated_at":"2024-09-29T09:56:47.000Z","dependencies_parsed_at":"2023-01-14T15:52:23.512Z","dependency_job_id":"1373d9fb-6afe-4307-8057-f202f34c2d01","html_url":"https://github.com/nearform/sql","commit_stats":{"total_commits":157,"total_committers":29,"mean_commits":5.413793103448276,"dds":0.6624203821656052,"last_synced_commit":"f94e55e3aa3d0ee9a0abf54f338f981b336a109b"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nearform%2Fsql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nearform%2Fsql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nearform%2Fsql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nearform%2Fsql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nearform","download_url":"https://codeload.github.com/nearform/sql/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":222698187,"owners_count":17024877,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hacktoberfest"],"created_at":"2024-08-01T06:01:14.005Z","updated_at":"2025-04-01T03:32:50.878Z","avatar_url":"https://github.com/nearform.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# SQL\n\nA simple SQL injection protection module that allows you to use ES6 template strings for escaped statements. Works with [pg](https://www.npmjs.com/package/pg), [mysql](https://www.npmjs.com/package/mysql) and [mysql2](https://www.npmjs.com/package/mysql2) library.\n\n[![npm version][1]][2] [![build status][3]][4] [![js-standard-style][5]][6]\n\n1. [Install](#install)\n2. [Usage](#usage)\n   1. [Linting](#linting)\n3. [Methods](#methods)\n   1. [glue](#gluepieces-separator)\n   2. [map](#maparray-mapperfunction)\n   2. (deprecated) [append](#deprecated-appendstatement-options)\n4. [Utilities](#utilities)\n   1. [unsafe](#unsafevalue)\n   2. [quoteIdent](#quoteidentvalue)\n5. [How it works?](#how-it-works)\n6. [Undefined values and nullable fields](#undefined-values-and-nullable-fields)\n7. [Testing, linting, \u0026 coverage](#testing-linting--coverage)\n8. [Benchmark](#benchmark)\n9. [License](#license)\n\n## Install\n\n```sh\nnpm install @nearform/sql\n```\n\n## Usage\n\n```js\nconst SQL = require('@nearform/sql')\n\nconst username = 'user'\nconst email = 'user@email.com'\nconst password = 'Password1'\n\n// generate SQL query\nconst sql = SQL`\n  INSERT INTO users (username, email, password)\n  VALUES (${username},${email},${password})\n`\n\npg.query(sql) // execute query in pg\n\nmysql.query(sql) // execute query in mysql\n\nmysql2.query(sql) // execute query in mysql2\n```\n\n### Linting\n\nWe recommend using [eslint-plugin-sql](https://github.com/gajus/eslint-plugin-sql#eslint-plugin-sql-rules-no-unsafe-query) to prevent cases in which the SQL tag is forgotten to be added in front of template strings. Eslint will fail if you write SQL queries without `sql` tag in front of the string.\n\n```sql\n`SELECT 1`\n// fails - Message: Use \"sql\" tag\n\nsql`SELECT 1`\n// passes\n```\n\n## Methods\n\n\u003e ⚠️ **Warning**\n\u003e\n\u003e The `unsafe` option interprets the interpolated values as literals and it should be used carefully to avoid introducing SQL injection vulnerabilities.\n\n### glue(pieces, separator)\n\n```js\nconst username = 'user1'\nconst email = 'user1@email.com'\nconst userId = 1\n\nconst updates = []\nupdates.push(SQL`name = ${username}`)\nupdates.push(SQL`email = ${email}`)\n\nconst sql = SQL`UPDATE users SET ${SQL.glue(updates, ' , ')} WHERE id = ${userId}`\n```\n\nor also\n\n```js\nconst ids = [1, 2, 3]\nconst value = 'test'\nconst sql = SQL`\nUPDATE users\nSET property = ${value}\nWHERE id\nIN (${SQL.glue(ids.map(id =\u003e SQL`${id}`), ' , ')})\n`\n```\n\nGlue can also be used statically:\n\n```js\nconst ids = [1, 2, 3]\nconst idsSqls = ids.map(id =\u003e SQL`(${id})`)\nSQL.glue(idsSqls, ' , ')\n```\n\nGlue can also be used to generate batch operations:\n\n```js\nconst users = [\n  { id: 1, name: 'something' },\n  { id: 2, name: 'something-else' },\n  { id: 3, name: 'something-other' }\n]\n\nconst sql = SQL`INSERT INTO users (id, name) VALUES \n  ${SQL.glue(\n    users.map(user =\u003e SQL`(${user.id},${user.name}})`),\n    ' , '\n  )}\n`\n```\n\n### map(array, mapperFunction)\n\nUsing the default mapperFunction which is just an iteration over the array elements\n```js\nconst ids = [1, 2, 3]\n\nconst values = SQL.map(ids)\nconst sql = SQL`INSERT INTO users (id) VALUES (${values})`\n```\n\nUsing an array of objects which requires a mapper function\n\n```js\nconst objArray = [{\n  id: 1,\n  name: 'name1'\n},\n{\n  id: 2,\n  name: 'name2'\n},\n{\n  id: 3,\n  name: 'name3'\n}]\n\nconst mapperFunction = (objItem) =\u003e objItem.id\nconst values = SQL.map(objArray, mapperFunction)\n\nconst sql = SQL`INSERT INTO users (id) VALUES (${values})`\n```\n\n### (deprecated) append(statement[, options])\n\nAppend has been deprecated in favour of using template literals:\n\n```js\nconst from = SQL`FROM table`\nconst sql = SQL`SELECT * ${from}`\n```\n\nFor now, you can still use append as follows:\n\n```js\nconst username = 'user1'\nconst email = 'user1@email.com'\nconst userId = 1\n\nconst sql = SQL`UPDATE users SET name = ${username}, email = ${email}`\nsql.append(SQL`, ${dynamicName} = 'dynamicValue'`, { unsafe: true })\nsql.append(SQL`WHERE id = ${userId}`)\n```\n\n## Utilities\n\n### unsafe(value)\n\nDoes a literal interpolation of the provided value, interpreting the provided value as-is.\n\nIt works similarly to the `unsafe` option of the `append` method and requires the same security considerations.\n\n```js\nconst username = 'john'\nconst userId = 1\n\nconst sql = SQL`\n  UPDATE users\n  SET username = '${SQL.unsafe(username)}'\n  WHERE id = ${userId}\n`\n```\n\n### quoteIdent(value)\n\nMimics the native PostgreSQL `quote_ident` and MySQL `quote_identifier` functions.\n\nIn PostgreSQL, it wraps the provided value in double quotes `\"` and escapes any double quotes existing in the provided value.\n\nIn MySQL, it wraps the provided value in backticks `` ` `` and escapes any backticks existing in the provided value.\n\nIt's convenient to use when schema, table or field names are dynamic and can't be hardcoded in the SQL query string.\n\n```js\nconst table = 'users'\nconst username = 'john'\nconst userId = 1\n\nconst sql = SQL`\n  UPDATE ${SQL.quoteIdent(table)}\n  SET username = ${username}\n  WHERE id = ${userId}\n`\n```\n\n## How it works?\n\nThe SQL template string tag parses query and returns an objects that's understandable by [pg](https://www.npmjs.com/package/pg) library:\n\n```js\nconst username = 'user'\nconst email = 'user@email.com'\nconst password = 'Password1'\n\nconst sql = SQL`INSERT INTO users (username, email, password) VALUES (${username}, ${email}, ${password})` // generate SQL query\nsql.text // INSERT INTO users (username, email, password) VALUES ($1 , $2 , $3) - for pg\nsql.sql // INSERT INTO users (username, email, password) VALUES (? , ? , ?) - for mysql and mysql2\nsql.values // ['user, 'user@email.com', 'Password1']\n```\n\nTo help with debugging, you can view an approximate representation of the SQL query with values filled in. It may differ from the actual SQL executed by your database, but serves as a handy reference when debugging. The debug output _should not_ be executed as it is not guaranteed safe. You can may also inspect the `SQL` object via `console.log`.\n\n```js\nsql.debug // INSERT INTO users (username, email, password) VALUES ('user','user@email.com','Password1')\n\nconsole.log(sql) // SQL \u003c\u003c INSERT INTO users (username, email, password) VALUES ('user','user@email.com','Password1') \u003e\u003e\n```\n\n## Undefined values and nullable fields\n\nDon't pass undefined values into the sql query string builder. It throws on undefined values as this is a javascript concept and sql does not handle it.\n\nSometimes you may expect to not have a value to be provided to the string builder, and this is ok as the coresponding field is nullable. In this or similar cases the recommended way to handle this is to coerce it to a null js value.\n\nExample:\n\n```js\nconst user = { name: 'foo bar' }\n\nconst sql = SQL`INSERT into users (name, address) VALUES (${user.name},${\n  user.address || null\n})`\nsql.debug // INSERT INTO users (name, address) VALUES ('foo bar',null)\n```\n\n## Example custom utilities\n\n### Insert into from a JS object\n\nThe below example functions can be used to generate an INSERT INTO statement from an object, which will convert the object keys to snake case.\n\n```js\nfunction insert(table, insertData, { toSnakeCase } = { toSnakeCase: false }) {\n  const builder = Object.entries(insertData).reduce(\n    (acc, [column, value]) =\u003e {\n      if (value !== undefined) {\n        toSnakeCase\n          ? acc.columns.push(pascalOrCamelToSnake(column))\n          : acc.columns.push(column)\n        acc.values.push(SQL`${value}`)\n      }\n      return acc\n    },\n    { columns: [], values: [] }\n  )\n  return SQL`INSERT INTO ${SQL.quoteIdent(table)} (${SQL.unsafe(\n    builder.columns.join(', ')\n  )}) VALUES (${SQL.glue(builder.values, ', ')})`\n}\n\nconst pascalOrCamelToSnake = str =\u003e\n  str[0].toLowerCase() +\n  str\n    .slice(1, str.length)\n    .replace(/[A-Z]/g, letter =\u003e `_${letter.toLowerCase()}`)\n```\n\n## Testing, linting, \u0026 coverage\n\nThis module can be tested and reported on in a variety of ways...\n\n```sh\nnpm run test            # runs tap based unit test suite.\nnpm run test:security   # runs sqlmap security tests.\nnpm run test:typescript # runs type definition tests.\nnpm run coverage        # generates a coverage report in docs dir.\nnpm run lint            # lints via standardJS.\n```\n\n## Benchmark\n\nFind more about `@nearform/sql` speed [here](benchmark)\n\n## Editor syntax higlighting\nTo get syntax higlighting, you can use extension/plugin for these editors:\n - Visual studio code: [thebearingedge.vscode-sql-lit](https://marketplace.visualstudio.com/items?itemName=thebearingedge.vscode-sql-lit) \n\n# License\n\nCopyright NearForm 2021. Licensed under\n[Apache 2.0][7]\n\n[1]: https://img.shields.io/npm/v/@nearform/sql.svg?style=flat-square\n[2]: https://npmjs.org/package/@nearform/sql\n[3]: https://github.com/nearform/sql/workflows/CI/badge.svg\n[4]: https://github.com/nearform/sql/actions?query=workflow%3ACI\n[5]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square\n[6]: https://github.com/feross/standard\n[7]: https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)\n\n[![banner](https://raw.githubusercontent.com/nearform/.github/refs/heads/master/assets/os-banner-green.svg)](https://www.nearform.com/contact/?utm_source=open-source\u0026utm_medium=banner\u0026utm_campaign=os-project-pages)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnearform%2Fsql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnearform%2Fsql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnearform%2Fsql/lists"}