@slonik/sql-tag 48.12.3 → 48.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/Logger.js +2 -2
- package/dist/factories/createPrimitiveValueExpressions.d.ts +1 -1
- package/dist/factories/createPrimitiveValueExpressions.js +10 -10
- package/dist/factories/createSqlTag.d.ts +2 -2
- package/dist/factories/createSqlTag.d.ts.map +1 -1
- package/dist/factories/createSqlTag.js +16 -16
- package/dist/factories/createSqlTag.js.map +1 -1
- package/dist/factories/createSqlTag.test/array.test.js +44 -44
- package/dist/factories/createSqlTag.test/array.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/date.test.js +9 -9
- package/dist/factories/createSqlTag.test/date.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/identifier.test.js +11 -14
- package/dist/factories/createSqlTag.test/identifier.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/interval.test.js +10 -10
- package/dist/factories/createSqlTag.test/join.test.js +24 -24
- package/dist/factories/createSqlTag.test/join.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/json.test.js +27 -27
- package/dist/factories/createSqlTag.test/json.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/jsonb.test.js +27 -27
- package/dist/factories/createSqlTag.test/jsonb.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/literalValue.test.js +5 -5
- package/dist/factories/createSqlTag.test/literalValue.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/sql.test.js +37 -37
- package/dist/factories/createSqlTag.test/sql.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/timestamp.test.js +9 -9
- package/dist/factories/createSqlTag.test/timestamp.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/type.test.js +4 -4
- package/dist/factories/createSqlTag.test/typeAlias.test.js +8 -8
- package/dist/factories/createSqlTag.test/unnest.test.js +25 -25
- package/dist/factories/createSqlTag.test/unnest.test.js.map +1 -1
- package/dist/factories/createSqlTag.test/uuid.test.js +10 -10
- package/dist/factories/createSqlTag.test/uuid.test.js.map +1 -1
- package/dist/factories/createSqlTokenSqlFragment.d.ts +1 -1
- package/dist/factories/createSqlTokenSqlFragment.d.ts.map +1 -1
- package/dist/factories/createSqlTokenSqlFragment.js +28 -67
- package/dist/factories/createSqlTokenSqlFragment.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +4 -4
- package/dist/sqlFragmentFactories/createArraySqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createArraySqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createArraySqlFragment.js +15 -15
- package/dist/sqlFragmentFactories/createArraySqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createBinarySqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createBinarySqlFragment.js +4 -4
- package/dist/sqlFragmentFactories/createDateSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createDateSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createDateSqlFragment.js +5 -5
- package/dist/sqlFragmentFactories/createDateSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createFragmentSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createFragmentSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createFragmentSqlFragment.js +7 -7
- package/dist/sqlFragmentFactories/createFragmentSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createIdentifierSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createIdentifierSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createIdentifierSqlFragment.js +6 -6
- package/dist/sqlFragmentFactories/createIdentifierSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createIntervalSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createIntervalSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createIntervalSqlFragment.js +10 -20
- package/dist/sqlFragmentFactories/createIntervalSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createJsonSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createJsonSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createJsonSqlFragment.js +16 -18
- package/dist/sqlFragmentFactories/createJsonSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createListSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createListSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createListSqlFragment.js +9 -9
- package/dist/sqlFragmentFactories/createListSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createQuerySqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createQuerySqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createQuerySqlFragment.js +7 -7
- package/dist/sqlFragmentFactories/createQuerySqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createTimestampSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createTimestampSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createTimestampSqlFragment.js +5 -7
- package/dist/sqlFragmentFactories/createTimestampSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createUnnestSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createUnnestSqlFragment.d.ts.map +1 -1
- package/dist/sqlFragmentFactories/createUnnestSqlFragment.js +19 -20
- package/dist/sqlFragmentFactories/createUnnestSqlFragment.js.map +1 -1
- package/dist/sqlFragmentFactories/createUuidSqlFragment.d.ts +1 -1
- package/dist/sqlFragmentFactories/createUuidSqlFragment.js +5 -5
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +14 -14
- package/dist/tokens.js.map +1 -1
- package/dist/types.d.ts +5 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/utilities/countArrayDimensions.js +1 -1
- package/dist/utilities/countArrayDimensions.test.js +6 -6
- package/dist/utilities/escapeIdentifier.test.js +5 -5
- package/dist/utilities/escapeLiteralValue.js +2 -2
- package/dist/utilities/escapeLiteralValue.test.js +7 -7
- package/dist/utilities/formatSlonikPlaceholder.js +1 -1
- package/dist/utilities/isPlainObject.js +1 -1
- package/dist/utilities/isPrimitiveValueExpression.js +4 -4
- package/dist/utilities/isSqlToken.d.ts +1 -1
- package/dist/utilities/isSqlToken.d.ts.map +1 -1
- package/dist/utilities/isSqlToken.js +9 -9
- package/dist/utilities/isSqlToken.js.map +1 -1
- package/dist/utilities/safeStringify.js +3 -3
- package/dist/utilities/stripArrayNotation.js +1 -1
- package/dist/utilities/stripArrayNotation.test.js +6 -6
- package/package.json +35 -39
- package/src/Logger.ts +2 -2
- package/src/declarations.d.ts +2 -2
- package/src/factories/createPrimitiveValueExpressions.ts +11 -11
- package/src/factories/createSqlTag.test/array.test.ts +54 -66
- package/src/factories/createSqlTag.test/date.test.ts +9 -11
- package/src/factories/createSqlTag.test/identifier.test.ts +11 -14
- package/src/factories/createSqlTag.test/interval.test.ts +10 -10
- package/src/factories/createSqlTag.test/join.test.ts +25 -31
- package/src/factories/createSqlTag.test/json.test.ts +27 -30
- package/src/factories/createSqlTag.test/jsonb.test.ts +27 -30
- package/src/factories/createSqlTag.test/literalValue.test.ts +5 -7
- package/src/factories/createSqlTag.test/sql.test.ts +38 -41
- package/src/factories/createSqlTag.test/timestamp.test.ts +9 -14
- package/src/factories/createSqlTag.test/type.test.ts +4 -4
- package/src/factories/createSqlTag.test/typeAlias.test.ts +9 -9
- package/src/factories/createSqlTag.test/unnest.test.ts +25 -34
- package/src/factories/createSqlTag.test/uuid.test.ts +10 -12
- package/src/factories/createSqlTag.ts +26 -47
- package/src/factories/createSqlTokenSqlFragment.ts +30 -74
- package/src/index.ts +5 -5
- package/src/sqlFragmentFactories/createArraySqlFragment.ts +17 -22
- package/src/sqlFragmentFactories/createBinarySqlFragment.ts +5 -5
- package/src/sqlFragmentFactories/createDateSqlFragment.ts +6 -8
- package/src/sqlFragmentFactories/createFragmentSqlFragment.ts +9 -11
- package/src/sqlFragmentFactories/createIdentifierSqlFragment.ts +8 -12
- package/src/sqlFragmentFactories/createIntervalSqlFragment.ts +11 -23
- package/src/sqlFragmentFactories/createJsonSqlFragment.ts +17 -25
- package/src/sqlFragmentFactories/createListSqlFragment.ts +10 -14
- package/src/sqlFragmentFactories/createQuerySqlFragment.ts +9 -11
- package/src/sqlFragmentFactories/createTimestampSqlFragment.ts +6 -11
- package/src/sqlFragmentFactories/createUnnestSqlFragment.ts +20 -29
- package/src/sqlFragmentFactories/createUuidSqlFragment.ts +6 -6
- package/src/tokens.ts +14 -16
- package/src/types.ts +65 -87
- package/src/utilities/countArrayDimensions.test.ts +6 -6
- package/src/utilities/countArrayDimensions.ts +1 -1
- package/src/utilities/escapeIdentifier.test.ts +5 -5
- package/src/utilities/escapeLiteralValue.test.ts +7 -7
- package/src/utilities/escapeLiteralValue.ts +2 -2
- package/src/utilities/formatSlonikPlaceholder.ts +1 -1
- package/src/utilities/isPlainObject.ts +1 -1
- package/src/utilities/isPrimitiveValueExpression.ts +4 -4
- package/src/utilities/isSqlToken.ts +10 -12
- package/src/utilities/safeStringify.ts +3 -3
- package/src/utilities/stripArrayNotation.test.ts +6 -6
- package/src/utilities/stripArrayNotation.ts +1 -1
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { FragmentToken } from
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { formatSlonikPlaceholder } from '../utilities/formatSlonikPlaceholder.js';
|
|
10
|
-
import { isPrimitiveValueExpression } from '../utilities/isPrimitiveValueExpression.js';
|
|
11
|
-
import { stripArrayNotation } from '../utilities/stripArrayNotation.js';
|
|
12
|
-
import { InvalidInputError } from '@slonik/errors';
|
|
1
|
+
import { FragmentToken } from "../tokens.js";
|
|
2
|
+
import type { PrimitiveValueExpression, SqlFragmentToken, UnnestSqlToken } from "../types.js";
|
|
3
|
+
import { countArrayDimensions } from "../utilities/countArrayDimensions.js";
|
|
4
|
+
import { escapeIdentifier } from "../utilities/escapeIdentifier.js";
|
|
5
|
+
import { formatSlonikPlaceholder } from "../utilities/formatSlonikPlaceholder.js";
|
|
6
|
+
import { isPrimitiveValueExpression } from "../utilities/isPrimitiveValueExpression.js";
|
|
7
|
+
import { stripArrayNotation } from "../utilities/stripArrayNotation.js";
|
|
8
|
+
import { InvalidInputError } from "@slonik/errors";
|
|
13
9
|
|
|
14
10
|
export const createUnnestSqlFragment = (
|
|
15
11
|
token: UnnestSqlToken,
|
|
@@ -32,21 +28,21 @@ export const createUnnestSqlFragment = (
|
|
|
32
28
|
let columnType = columnTypes[columnIndex];
|
|
33
29
|
let columnTypeIsIdentifier;
|
|
34
30
|
|
|
35
|
-
if (typeof typeMember ===
|
|
31
|
+
if (typeof typeMember === "string") {
|
|
36
32
|
columnType = typeMember;
|
|
37
33
|
columnTypeIsIdentifier = false;
|
|
38
34
|
} else if (Array.isArray(typeMember)) {
|
|
39
35
|
columnType = typeMember
|
|
40
36
|
.map((identifierName) => {
|
|
41
|
-
if (typeof identifierName !==
|
|
37
|
+
if (typeof identifierName !== "string") {
|
|
42
38
|
throw new InvalidInputError(
|
|
43
|
-
|
|
39
|
+
"sql.unnest column identifier name array member type must be a string (type name identifier) or a SQL token.",
|
|
44
40
|
);
|
|
45
41
|
}
|
|
46
42
|
|
|
47
43
|
return escapeIdentifier(identifierName);
|
|
48
44
|
})
|
|
49
|
-
.join(
|
|
45
|
+
.join(".");
|
|
50
46
|
columnTypeIsIdentifier = true;
|
|
51
47
|
} else {
|
|
52
48
|
columnType = typeMember.sql;
|
|
@@ -55,11 +51,11 @@ export const createUnnestSqlFragment = (
|
|
|
55
51
|
|
|
56
52
|
unnestSqlTokens.push(
|
|
57
53
|
formatSlonikPlaceholder(++placeholderIndex) +
|
|
58
|
-
|
|
54
|
+
"::" +
|
|
59
55
|
(columnTypeIsIdentifier
|
|
60
56
|
? stripArrayNotation(columnType)
|
|
61
57
|
: escapeIdentifier(stripArrayNotation(columnType))) +
|
|
62
|
-
|
|
58
|
+
"[]".repeat(countArrayDimensions(columnType) + 1),
|
|
63
59
|
);
|
|
64
60
|
|
|
65
61
|
unnestBindings[columnIndex] = [];
|
|
@@ -70,17 +66,12 @@ export const createUnnestSqlFragment = (
|
|
|
70
66
|
let lastTupleSize;
|
|
71
67
|
|
|
72
68
|
for (const tupleValues of token.tuples) {
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
lastTupleSize !== tupleValues.length
|
|
76
|
-
) {
|
|
77
|
-
throw new Error(
|
|
78
|
-
'Each tuple in a list of tuples must have an equal number of members.',
|
|
79
|
-
);
|
|
69
|
+
if (typeof lastTupleSize === "number" && lastTupleSize !== tupleValues.length) {
|
|
70
|
+
throw new Error("Each tuple in a list of tuples must have an equal number of members.");
|
|
80
71
|
}
|
|
81
72
|
|
|
82
73
|
if (tupleValues.length !== columnTypes.length) {
|
|
83
|
-
throw new Error(
|
|
74
|
+
throw new Error("Column types length must match tuple member length.");
|
|
84
75
|
}
|
|
85
76
|
|
|
86
77
|
lastTupleSize = tupleValues.length;
|
|
@@ -94,14 +85,14 @@ export const createUnnestSqlFragment = (
|
|
|
94
85
|
!Buffer.isBuffer(tupleValue)
|
|
95
86
|
) {
|
|
96
87
|
throw new InvalidInputError(
|
|
97
|
-
|
|
88
|
+
"Invalid unnest tuple member type. Must be a primitive value expression.",
|
|
98
89
|
);
|
|
99
90
|
}
|
|
100
91
|
|
|
101
92
|
const tupleBindings = unnestBindings[tupleColumnIndex++];
|
|
102
93
|
|
|
103
94
|
if (!tupleBindings) {
|
|
104
|
-
throw new Error(
|
|
95
|
+
throw new Error("test");
|
|
105
96
|
}
|
|
106
97
|
|
|
107
98
|
tupleBindings.push(tupleValue);
|
|
@@ -110,7 +101,7 @@ export const createUnnestSqlFragment = (
|
|
|
110
101
|
|
|
111
102
|
values.push(...unnestBindings);
|
|
112
103
|
|
|
113
|
-
const sql =
|
|
104
|
+
const sql = "unnest(" + unnestSqlTokens.join(", ") + ")";
|
|
114
105
|
|
|
115
106
|
return {
|
|
116
107
|
sql,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FragmentToken } from
|
|
2
|
-
import type { SqlFragmentToken, UuidSqlToken } from
|
|
3
|
-
import { formatSlonikPlaceholder } from
|
|
4
|
-
import { InvalidInputError } from
|
|
1
|
+
import { FragmentToken } from "../tokens.js";
|
|
2
|
+
import type { SqlFragmentToken, UuidSqlToken } from "../types.js";
|
|
3
|
+
import { formatSlonikPlaceholder } from "../utilities/formatSlonikPlaceholder.js";
|
|
4
|
+
import { InvalidInputError } from "@slonik/errors";
|
|
5
5
|
|
|
6
6
|
export type UUID = `${string}-${string}-${string}-${string}-${string}`;
|
|
7
7
|
|
|
@@ -17,11 +17,11 @@ export const createUuidSqlFragment = (
|
|
|
17
17
|
greatestParameterPosition: number,
|
|
18
18
|
): SqlFragmentToken => {
|
|
19
19
|
if (!isValidUuid(token.uuid)) {
|
|
20
|
-
throw new InvalidInputError(
|
|
20
|
+
throw new InvalidInputError("UUID parameter value must be a valid UUID.");
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return {
|
|
24
|
-
sql: formatSlonikPlaceholder(greatestParameterPosition + 1) +
|
|
24
|
+
sql: formatSlonikPlaceholder(greatestParameterPosition + 1) + "::uuid",
|
|
25
25
|
type: FragmentToken,
|
|
26
26
|
values: [token.uuid],
|
|
27
27
|
};
|
package/src/tokens.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
export const ArrayToken = Symbol.for(
|
|
2
|
-
export const BinaryToken = Symbol.for(
|
|
3
|
-
export const ComparisonPredicateToken = Symbol.for(
|
|
4
|
-
|
|
5
|
-
);
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
12
|
-
export const
|
|
13
|
-
export const
|
|
14
|
-
export const
|
|
15
|
-
export const UnnestToken = Symbol.for('SLONIK_TOKEN_UNNEST');
|
|
16
|
-
export const UuidToken = Symbol.for('SLONIK_TOKEN_UUID');
|
|
1
|
+
export const ArrayToken = Symbol.for("SLONIK_TOKEN_ARRAY");
|
|
2
|
+
export const BinaryToken = Symbol.for("SLONIK_TOKEN_BINARY");
|
|
3
|
+
export const ComparisonPredicateToken = Symbol.for("SLONIK_TOKEN_COMPARISON_PREDICATE");
|
|
4
|
+
export const DateToken = Symbol.for("SLONIK_TOKEN_DATE");
|
|
5
|
+
export const FragmentToken = Symbol.for("SLONIK_TOKEN_FRAGMENT");
|
|
6
|
+
export const IdentifierToken = Symbol.for("SLONIK_TOKEN_IDENTIFIER");
|
|
7
|
+
export const IntervalToken = Symbol.for("SLONIK_TOKEN_INTERVAL");
|
|
8
|
+
export const JsonBinaryToken = Symbol.for("SLONIK_TOKEN_JSON_BINARY");
|
|
9
|
+
export const JsonToken = Symbol.for("SLONIK_TOKEN_JSON");
|
|
10
|
+
export const ListToken = Symbol.for("SLONIK_TOKEN_LIST");
|
|
11
|
+
export const QueryToken = Symbol.for("SLONIK_TOKEN_QUERY");
|
|
12
|
+
export const TimestampToken = Symbol.for("SLONIK_TOKEN_TIMESTAMP");
|
|
13
|
+
export const UnnestToken = Symbol.for("SLONIK_TOKEN_UNNEST");
|
|
14
|
+
export const UuidToken = Symbol.for("SLONIK_TOKEN_UUID");
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type * as tokens from
|
|
2
|
-
import type { PrimitiveValueExpression } from
|
|
3
|
-
import type { StandardSchemaV1 } from
|
|
1
|
+
import type * as tokens from "./tokens.js";
|
|
2
|
+
import type { PrimitiveValueExpression } from "@slonik/types";
|
|
3
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
4
|
|
|
5
|
-
export { type PrimitiveValueExpression } from
|
|
5
|
+
export { type PrimitiveValueExpression } from "@slonik/types";
|
|
6
6
|
|
|
7
7
|
export type ArraySqlToken<T extends TypeNameIdentifier = TypeNameIdentifier> = {
|
|
8
8
|
readonly memberType: SqlFragmentToken | T;
|
|
@@ -95,74 +95,55 @@ export type SqlFragmentToken = {
|
|
|
95
95
|
readonly values: readonly PrimitiveValueExpression[];
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
-
export type SqlTag<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
template: TemplateStringsArray,
|
|
148
|
-
...values: ValueExpression[]
|
|
149
|
-
) => QuerySqlToken<Z[K]>;
|
|
150
|
-
unnest: (
|
|
151
|
-
// Value might be ReadonlyArray<ReadonlyArray<PrimitiveValueExpression>>,
|
|
152
|
-
// or it can be infinitely nested array, e.g.
|
|
153
|
-
// https://github.com/gajus/slonik/issues/44
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
155
|
-
tuples: ReadonlyArray<readonly any[]>,
|
|
156
|
-
columnTypes:
|
|
157
|
-
| Array<[...string[], TypeNameIdentifier]>
|
|
158
|
-
| Array<SqlFragmentToken | TypeNameIdentifier>,
|
|
159
|
-
) => UnnestSqlToken;
|
|
160
|
-
unsafe: (
|
|
161
|
-
template: TemplateStringsArray,
|
|
162
|
-
...values: ValueExpression[]
|
|
163
|
-
) => QuerySqlToken;
|
|
164
|
-
uuid: (uuid: string) => UuidSqlToken;
|
|
165
|
-
};
|
|
98
|
+
export type SqlTag<Z extends Record<string, StandardSchemaV1> = Record<string, StandardSchemaV1>> =
|
|
99
|
+
{
|
|
100
|
+
array: <T extends TypeNameIdentifier>(
|
|
101
|
+
values: readonly PrimitiveValueExpression[],
|
|
102
|
+
memberType: SqlFragmentToken | T,
|
|
103
|
+
) => ArraySqlToken<T>;
|
|
104
|
+
binary: (data: Buffer) => BinarySqlToken;
|
|
105
|
+
date: (date: Date) => DateSqlToken;
|
|
106
|
+
fragment: (template: TemplateStringsArray, ...values: ValueExpression[]) => SqlFragmentToken;
|
|
107
|
+
identifier: (names: readonly string[]) => IdentifierSqlToken;
|
|
108
|
+
interval: (interval: IntervalInput) => IntervalSqlToken;
|
|
109
|
+
join: (members: readonly ValueExpression[], glue: SqlFragmentToken) => ListSqlToken;
|
|
110
|
+
json: (value: SerializableValue) => JsonSqlToken;
|
|
111
|
+
jsonb: (value: SerializableValue) => JsonBinarySqlToken;
|
|
112
|
+
literalValue: (value: string) => SqlFragmentToken;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a named prepared statement. The statement name is used by PostgreSQL
|
|
115
|
+
* to cache the query plan, which can improve performance for frequently executed queries.
|
|
116
|
+
* @example
|
|
117
|
+
* ```ts
|
|
118
|
+
* const query = sql.prepared('get_user_by_id', z.object({ id: z.number(), name: z.string() }))`
|
|
119
|
+
* SELECT id, name FROM users WHERE id = ${userId}
|
|
120
|
+
* `;
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
prepared: <Y extends StandardSchemaV1>(
|
|
124
|
+
statementName: string,
|
|
125
|
+
parser: Y,
|
|
126
|
+
) => (template: TemplateStringsArray, ...values: ValueExpression[]) => QuerySqlToken<Y>;
|
|
127
|
+
timestamp: (date: Date) => TimestampSqlToken;
|
|
128
|
+
type: <Y extends StandardSchemaV1>(
|
|
129
|
+
parser: Y,
|
|
130
|
+
) => (template: TemplateStringsArray, ...values: ValueExpression[]) => QuerySqlToken<Y>;
|
|
131
|
+
typeAlias: <K extends keyof Z>(
|
|
132
|
+
typeAlias: K,
|
|
133
|
+
) => (template: TemplateStringsArray, ...values: ValueExpression[]) => QuerySqlToken<Z[K]>;
|
|
134
|
+
unnest: (
|
|
135
|
+
// Value might be ReadonlyArray<ReadonlyArray<PrimitiveValueExpression>>,
|
|
136
|
+
// or it can be infinitely nested array, e.g.
|
|
137
|
+
// https://github.com/gajus/slonik/issues/44
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
139
|
+
tuples: ReadonlyArray<readonly any[]>,
|
|
140
|
+
columnTypes:
|
|
141
|
+
| Array<[...string[], TypeNameIdentifier]>
|
|
142
|
+
| Array<SqlFragmentToken | TypeNameIdentifier>,
|
|
143
|
+
) => UnnestSqlToken;
|
|
144
|
+
unsafe: (template: TemplateStringsArray, ...values: ValueExpression[]) => QuerySqlToken;
|
|
145
|
+
uuid: (uuid: string) => UuidSqlToken;
|
|
146
|
+
};
|
|
166
147
|
|
|
167
148
|
export type SqlToken =
|
|
168
149
|
| ArraySqlToken<TypeNameIdentifier>
|
|
@@ -189,17 +170,17 @@ export type TimestampSqlToken = {
|
|
|
189
170
|
* experience with auto suggestions for commonly used type name identifiers.
|
|
190
171
|
*/
|
|
191
172
|
export type TypeNameIdentifier =
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
|
|
|
195
|
-
|
|
|
196
|
-
|
|
|
197
|
-
|
|
|
198
|
-
|
|
|
199
|
-
|
|
|
200
|
-
|
|
|
201
|
-
|
|
|
202
|
-
|
|
|
173
|
+
| "bool"
|
|
174
|
+
| "bytea"
|
|
175
|
+
| "float4"
|
|
176
|
+
| "float8"
|
|
177
|
+
| "int2"
|
|
178
|
+
| "int4"
|
|
179
|
+
| "int8"
|
|
180
|
+
| "json"
|
|
181
|
+
| "text"
|
|
182
|
+
| "timestamptz"
|
|
183
|
+
| "uuid"
|
|
203
184
|
| string;
|
|
204
185
|
|
|
205
186
|
export type UnnestSqlToken = {
|
|
@@ -215,7 +196,4 @@ export type UuidSqlToken = {
|
|
|
215
196
|
readonly uuid: `${string}-${string}-${string}-${string}-${string}`;
|
|
216
197
|
};
|
|
217
198
|
|
|
218
|
-
export type ValueExpression =
|
|
219
|
-
| PrimitiveValueExpression
|
|
220
|
-
| SqlFragmentToken
|
|
221
|
-
| SqlToken;
|
|
199
|
+
export type ValueExpression = PrimitiveValueExpression | SqlFragmentToken | SqlToken;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { countArrayDimensions } from
|
|
2
|
-
import test from
|
|
1
|
+
import { countArrayDimensions } from "./countArrayDimensions.js";
|
|
2
|
+
import test from "ava";
|
|
3
3
|
|
|
4
|
-
test(
|
|
5
|
-
t.is(countArrayDimensions(
|
|
6
|
-
t.is(countArrayDimensions(
|
|
7
|
-
t.is(countArrayDimensions(
|
|
4
|
+
test("returns the number of array dimensions", (t) => {
|
|
5
|
+
t.is(countArrayDimensions("foo"), 0);
|
|
6
|
+
t.is(countArrayDimensions("foo[]"), 1);
|
|
7
|
+
t.is(countArrayDimensions("foo[][]"), 2);
|
|
8
8
|
});
|
|
@@ -2,7 +2,7 @@ export const countArrayDimensions = (identifierName: string): number => {
|
|
|
2
2
|
let tail = identifierName.trim();
|
|
3
3
|
let arrayDimensionCount = 0;
|
|
4
4
|
|
|
5
|
-
while (tail.endsWith(
|
|
5
|
+
while (tail.endsWith("[]")) {
|
|
6
6
|
arrayDimensionCount++;
|
|
7
7
|
|
|
8
8
|
tail = tail.trim().slice(0, -2);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { escapeIdentifier } from
|
|
2
|
-
import test from
|
|
1
|
+
import { escapeIdentifier } from "./escapeIdentifier.js";
|
|
2
|
+
import test from "ava";
|
|
3
3
|
|
|
4
|
-
test(
|
|
5
|
-
t.is(escapeIdentifier(
|
|
6
|
-
t.is(escapeIdentifier(
|
|
4
|
+
test("escapes SQL identifiers", (t) => {
|
|
5
|
+
t.is(escapeIdentifier("foo"), '"foo"');
|
|
6
|
+
t.is(escapeIdentifier("foo bar"), '"foo bar"');
|
|
7
7
|
t.is(escapeIdentifier('"foo"'), '"""foo"""');
|
|
8
8
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { escapeLiteralValue } from
|
|
2
|
-
import test from
|
|
1
|
+
import { escapeLiteralValue } from "./escapeLiteralValue.js";
|
|
2
|
+
import test from "ava";
|
|
3
3
|
|
|
4
|
-
test(
|
|
5
|
-
t.is(escapeLiteralValue(
|
|
6
|
-
t.is(escapeLiteralValue(
|
|
7
|
-
t.is(escapeLiteralValue('"foo"'), '\
|
|
8
|
-
t.is(escapeLiteralValue(
|
|
4
|
+
test("escapes SQL literal value", (t) => {
|
|
5
|
+
t.is(escapeLiteralValue("foo"), "'foo'");
|
|
6
|
+
t.is(escapeLiteralValue("foo bar"), "'foo bar'");
|
|
7
|
+
t.is(escapeLiteralValue('"foo"'), "'\"foo\"'");
|
|
8
|
+
t.is(escapeLiteralValue("foo\\bar"), "E'foo\\\\bar'");
|
|
9
9
|
});
|
|
@@ -8,7 +8,7 @@ export const escapeLiteralValue = (subject: string): string => {
|
|
|
8
8
|
for (const character of subject) {
|
|
9
9
|
if (character === "'") {
|
|
10
10
|
escaped += character + character;
|
|
11
|
-
} else if (character ===
|
|
11
|
+
} else if (character === "\\") {
|
|
12
12
|
escaped += character + character;
|
|
13
13
|
hasBackslash = true;
|
|
14
14
|
} else {
|
|
@@ -19,7 +19,7 @@ export const escapeLiteralValue = (subject: string): string => {
|
|
|
19
19
|
escaped += "'";
|
|
20
20
|
|
|
21
21
|
if (hasBackslash === true) {
|
|
22
|
-
escaped =
|
|
22
|
+
escaped = "E" + escaped;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
return escaped;
|
|
@@ -2,10 +2,10 @@ export const isPrimitiveValueExpression = (
|
|
|
2
2
|
maybe: unknown,
|
|
3
3
|
): maybe is bigint | boolean | null | number | string => {
|
|
4
4
|
return (
|
|
5
|
-
typeof maybe ===
|
|
6
|
-
typeof maybe ===
|
|
7
|
-
typeof maybe ===
|
|
8
|
-
typeof maybe ===
|
|
5
|
+
typeof maybe === "string" ||
|
|
6
|
+
typeof maybe === "number" ||
|
|
7
|
+
typeof maybe === "boolean" ||
|
|
8
|
+
typeof maybe === "bigint" ||
|
|
9
9
|
maybe === null
|
|
10
10
|
);
|
|
11
11
|
};
|
|
@@ -13,10 +13,10 @@ import {
|
|
|
13
13
|
TimestampToken,
|
|
14
14
|
UnnestToken,
|
|
15
15
|
UuidToken,
|
|
16
|
-
} from
|
|
17
|
-
import type { SqlToken as SqlTokenType } from
|
|
18
|
-
import { hasOwnProperty } from
|
|
19
|
-
import { UnexpectedStateError } from
|
|
16
|
+
} from "../tokens.js";
|
|
17
|
+
import type { SqlToken as SqlTokenType } from "../types.js";
|
|
18
|
+
import { hasOwnProperty } from "./hasOwnProperty.js";
|
|
19
|
+
import { UnexpectedStateError } from "@slonik/errors";
|
|
20
20
|
|
|
21
21
|
const Tokens = [
|
|
22
22
|
ArrayToken,
|
|
@@ -39,10 +39,8 @@ const tokenNames = new Set(
|
|
|
39
39
|
Tokens.map((token) => {
|
|
40
40
|
const tokenTypeName = Symbol.keyFor(token);
|
|
41
41
|
|
|
42
|
-
if (typeof tokenTypeName !==
|
|
43
|
-
throw new UnexpectedStateError(
|
|
44
|
-
'Expected token type be a symbol with inferrable key',
|
|
45
|
-
);
|
|
42
|
+
if (typeof tokenTypeName !== "string") {
|
|
43
|
+
throw new UnexpectedStateError("Expected token type be a symbol with inferrable key");
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
return tokenTypeName;
|
|
@@ -50,23 +48,23 @@ const tokenNames = new Set(
|
|
|
50
48
|
);
|
|
51
49
|
|
|
52
50
|
export const isSqlToken = (subject: unknown): subject is SqlTokenType => {
|
|
53
|
-
if (typeof subject !==
|
|
51
|
+
if (typeof subject !== "object" || subject === null) {
|
|
54
52
|
return false;
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
if (!hasOwnProperty(subject,
|
|
55
|
+
if (!hasOwnProperty(subject, "type")) {
|
|
58
56
|
return false;
|
|
59
57
|
}
|
|
60
58
|
|
|
61
59
|
const tokenType = subject.type;
|
|
62
60
|
|
|
63
|
-
if (typeof tokenType !==
|
|
61
|
+
if (typeof tokenType !== "symbol") {
|
|
64
62
|
return false;
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
const tokenTypeName = Symbol.keyFor(tokenType);
|
|
68
66
|
|
|
69
|
-
if (typeof tokenTypeName !==
|
|
67
|
+
if (typeof tokenTypeName !== "string") {
|
|
70
68
|
return false;
|
|
71
69
|
}
|
|
72
70
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { configure } from
|
|
1
|
+
import { configure } from "safe-stable-stringify";
|
|
2
2
|
|
|
3
3
|
const stringify = configure({
|
|
4
4
|
bigint: true,
|
|
5
|
-
circularValue:
|
|
5
|
+
circularValue: "[Circular]",
|
|
6
6
|
strict: true,
|
|
7
7
|
});
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ export const safeStringify = (subject: unknown): string => {
|
|
|
16
16
|
const result = stringify(subject);
|
|
17
17
|
|
|
18
18
|
if (result === undefined) {
|
|
19
|
-
throw new Error(
|
|
19
|
+
throw new Error("Expected result to be string");
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
return result;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { stripArrayNotation } from
|
|
2
|
-
import test from
|
|
1
|
+
import { stripArrayNotation } from "./stripArrayNotation.js";
|
|
2
|
+
import test from "ava";
|
|
3
3
|
|
|
4
|
-
test(
|
|
5
|
-
t.is(stripArrayNotation(
|
|
6
|
-
t.is(stripArrayNotation(
|
|
7
|
-
t.is(stripArrayNotation(
|
|
4
|
+
test("strips array notation", (t) => {
|
|
5
|
+
t.is(stripArrayNotation("foo"), "foo");
|
|
6
|
+
t.is(stripArrayNotation("foo[]"), "foo");
|
|
7
|
+
t.is(stripArrayNotation("foo[][]"), "foo");
|
|
8
8
|
});
|