Comparing version 1.0.0-beta.5 to 1.0.0-beta.6
@@ -41,15 +41,5 @@ "use strict"; | ||
function makeTrustedNode /*:: <Node>*/(node /*: Node */) /*: Node */{ | ||
Object.defineProperty(node, $$trusted, { | ||
enumerable: false, | ||
value: true, | ||
// These next two are set to squeeze out a little more V8 performance | ||
configurable: true, | ||
writable: true | ||
}); | ||
return node; | ||
} | ||
function makeRawNode(text /*: string */) /*: SQLRawNode */{ | ||
return makeTrustedNode({ type: "RAW", text }); | ||
// $FlowFixMe | ||
return { type: "RAW", text, [$$trusted]: true }; | ||
} | ||
@@ -59,7 +49,9 @@ | ||
) /*: SQLIdentifierNode */{ | ||
return makeTrustedNode({ type: "IDENTIFIER", names }); | ||
// $FlowFixMe | ||
return { type: "IDENTIFIER", names, [$$trusted]: true }; | ||
} | ||
function makeValueNode(value /*: mixed */) /*: SQLValueNode */{ | ||
return makeTrustedNode({ type: "VALUE", value }); | ||
// $FlowFixMe | ||
return { type: "VALUE", value, [$$trusted]: true }; | ||
} | ||
@@ -183,12 +175,13 @@ | ||
} | ||
if (!values[i]) { | ||
if (text.length) { | ||
items.push(makeRawNode(text)); | ||
} else { | ||
} | ||
if (values[i]) { | ||
const value = values[i]; | ||
if (Array.isArray(value)) { | ||
const nodes /*: SQLQuery */ = value.map(enforceValidNode); | ||
items.push(makeRawNode(text), ...nodes); | ||
items.push(...nodes); | ||
} else { | ||
const node /*: SQLNode */ = enforceValidNode(value); | ||
items.push(makeRawNode(text), node); | ||
items.push(node); | ||
} | ||
@@ -195,0 +188,0 @@ } |
{ | ||
"name": "pg-sql2", | ||
"version": "1.0.0-beta.5", | ||
"version": "1.0.0-beta.6", | ||
"description": "Generate safe Postgres-compliant SQL with tagged template literals", | ||
@@ -11,2 +11,3 @@ "main": "lib/index.js", | ||
"test": "node src/index.js && eslint . && flow check && jest && markdown-doctest", | ||
"test:u": "node src/index.js && eslint . && flow check && jest -u && markdown-doctest", | ||
"test:docs": "markdown-doctest", | ||
@@ -13,0 +14,0 @@ "prepublish": "babel --out-dir lib src" |
@@ -1,3 +0,2 @@ | ||
pg-sql2 | ||
======= | ||
# pg-sql2 | ||
@@ -8,3 +7,3 @@ Create SQL in a powerful and flexible manner without opening yourself to SQL | ||
```js | ||
const sql = require('pg-sql2'); | ||
const sql = require("pg-sql2"); | ||
// or import sql from 'pg-sql2'; | ||
@@ -24,8 +23,10 @@ | ||
// statement, to ensure that no SQL injection can occur. | ||
const sqlConditions = | ||
sql.query`created_at > NOW() - interval '3 years' and age > ${sql.value(22)}`; | ||
const sqlConditions = sql.query`created_at > NOW() - interval '3 years' and age > ${sql.value( | ||
22 | ||
)}`; | ||
// This could be a full query, but we're going to embed it in another query safely | ||
const innerQuery = | ||
sql.query`select ${sqlFields} from ${sql.identifier(tableName)} where ${sqlConditions}`; | ||
const innerQuery = sql.query`select ${sqlFields} from ${sql.identifier( | ||
tableName | ||
)} where ${sqlConditions}`; | ||
@@ -59,6 +60,5 @@ // Symbols are automatically assigned unique identifiers | ||
API | ||
--- | ||
## API | ||
### ``sql.query`...` `` | ||
### `` sql.query`...` `` | ||
@@ -68,4 +68,5 @@ Builds part of (or the whole of) an SQL query, safely interpretting the embedded expressions. If a non `sql.*` expression is passed in, e.g.: | ||
<!-- skip-example --> | ||
```js | ||
sql.query`select ${1}` | ||
sql.query`select ${1}`; | ||
``` | ||
@@ -96,11 +97,15 @@ | ||
```js | ||
const arrayOfSqlFields = ['a', 'b', 'c', 'd'].map(n => sql.identifier(n)); | ||
sql.query`select ${sql.join(arrayOfSqlFields, ', ')}` // -> select "a", "b", "c", "d" | ||
const arrayOfSqlFields = ["a", "b", "c", "d"].map(n => sql.identifier(n)); | ||
sql.query`select ${sql.join(arrayOfSqlFields, ", ")}`; // -> select "a", "b", "c", "d" | ||
const arrayOfSqlConditions = [sql.query`a = 1`, sql.query`b = 2`, sql.query`c = 3`]; | ||
sql.query`where (${sql.join(arrayOfSqlConditions, ') and (')})` // -> where (a = 1) and (b = 2) and (c = 3) | ||
const arrayOfSqlConditions = [ | ||
sql.query`a = 1`, | ||
sql.query`b = 2`, | ||
sql.query`c = 3` | ||
]; | ||
sql.query`where (${sql.join(arrayOfSqlConditions, ") and (")})`; // -> where (a = 1) and (b = 2) and (c = 3) | ||
const fragments = [ | ||
{alias: 'name', sqlFragment: sql.identifier('user', 'name')}, | ||
{alias: 'age', sqlFragment: sql.identifier('user', 'age')}, | ||
{ alias: "name", sqlFragment: sql.identifier("user", "name") }, | ||
{ alias: "age", sqlFragment: sql.identifier("user", "age") } | ||
]; | ||
@@ -120,5 +125,5 @@ sql.query` | ||
sql.query`inner join bar on (bar.foo_id = foo.id)`, | ||
sql.query`inner join baz on (baz.bar_id = bar.id)`, | ||
sql.query`inner join baz on (baz.bar_id = bar.id)` | ||
]; | ||
sql.query`select * from foo ${sql.join(arrayOfSqlInnerJoins, " ")}` | ||
sql.query`select * from foo ${sql.join(arrayOfSqlInnerJoins, " ")}`; | ||
// select * from foo inner join bar on (bar.foo_id = foo.id) inner join baz on (baz.bar_id = bar.id) | ||
@@ -138,4 +143,3 @@ ``` | ||
History | ||
------- | ||
## History | ||
@@ -148,11 +152,14 @@ This is a replacement for [@calebmer's | ||
- Better development experience for people not using Flow/TypeScript (throws | ||
* Better development experience for people not using Flow/TypeScript (throws | ||
errors a lot earlier allowing you to catch issues at the source) | ||
- Slightly more helpful error messages | ||
- Uses a hidden non-enumerable symbol as the type of the query nodes to protect | ||
against an object accidentally being inserted verbatim and being treated as | ||
valid | ||
- Adds `sql.literal` which is similar to `sql.value` but when used with simple | ||
* Slightly more helpful error messages | ||
* Uses a symbol-key on the query nodes to protect against an object | ||
accidentally being inserted verbatim and being treated as valid (because | ||
every Symbol is unique an attacker would need control of the code to get a | ||
reference to the Symbol in order to set it on an object (it cannot be | ||
serialised/deserialised via JSON or any other medium), and if the attacker | ||
has control of the code then you've already lost) | ||
* Adds `sql.literal` which is similar to `sql.value` but when used with simple | ||
values can write the valid direct to the SQL statement. **USE WITH CAUTION**. | ||
The purpose for this is if you are using *trusted* values (e.g. for the keys | ||
The purpose for this is if you are using _trusted_ values (e.g. for the keys | ||
to | ||
@@ -159,0 +166,0 @@ [`json_build_object(...)`](https://www.postgresql.org/docs/9.6/static/functions-json.html)) |
@@ -44,15 +44,5 @@ "use strict"; | ||
function makeTrustedNode /*:: <Node>*/(node /*: Node */) /*: Node */ { | ||
Object.defineProperty(node, $$trusted, { | ||
enumerable: false, | ||
value: true, | ||
// These next two are set to squeeze out a little more V8 performance | ||
configurable: true, | ||
writable: true, | ||
}); | ||
return node; | ||
} | ||
function makeRawNode(text /*: string */) /*: SQLRawNode */ { | ||
return makeTrustedNode({ type: "RAW", text }); | ||
// $FlowFixMe | ||
return { type: "RAW", text, [$$trusted]: true }; | ||
} | ||
@@ -63,7 +53,9 @@ | ||
) /*: SQLIdentifierNode */ { | ||
return makeTrustedNode({ type: "IDENTIFIER", names }); | ||
// $FlowFixMe | ||
return { type: "IDENTIFIER", names, [$$trusted]: true }; | ||
} | ||
function makeValueNode(value /*: mixed */) /*: SQLValueNode */ { | ||
return makeTrustedNode({ type: "VALUE", value }); | ||
// $FlowFixMe | ||
return { type: "VALUE", value, [$$trusted]: true }; | ||
} | ||
@@ -208,12 +200,13 @@ | ||
} | ||
if (!values[i]) { | ||
if (text.length) { | ||
items.push(makeRawNode(text)); | ||
} else { | ||
} | ||
if (values[i]) { | ||
const value = values[i]; | ||
if (Array.isArray(value)) { | ||
const nodes /*: SQLQuery */ = value.map(enforceValidNode); | ||
items.push(makeRawNode(text), ...nodes); | ||
items.push(...nodes); | ||
} else { | ||
const node /*: SQLNode */ = enforceValidNode(value); | ||
items.push(makeRawNode(text), node); | ||
items.push(node); | ||
} | ||
@@ -220,0 +213,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
161
27722
593