@restura/core 1.7.0 → 1.8.0
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/dist/index.d.ts +15 -5
- package/dist/index.js +156 -99
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,10 @@ declare const loggerConfigSchema: z.ZodObject<{
|
|
|
40
40
|
}, z.core.$strip>;
|
|
41
41
|
type LoggerConfigSchema = z.infer<typeof loggerConfigSchema>;
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* @deprecated This is used for passing around until we finally get to the sending externally
|
|
45
|
+
* // TODO: Remove once backwards compatibility is no longer needed
|
|
46
|
+
*/
|
|
43
47
|
interface RsErrorInternalData<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
44
48
|
err: ErrorCode;
|
|
45
49
|
msg: string;
|
|
@@ -70,13 +74,13 @@ declare enum HtmlStatusCodes {
|
|
|
70
74
|
NETWORK_CONNECT_TIMEOUT = 599
|
|
71
75
|
}
|
|
72
76
|
type ErrorCode = 'BAD_REQUEST' | 'UNAUTHORIZED' | 'PAYMENT_REQUIRED' | 'FORBIDDEN' | 'NOT_FOUND' | 'METHOD_NOT_ALLOWED' | 'REQUEST_TIMEOUT' | 'CONFLICT' | 'GONE' | 'PAYLOAD_TOO_LARGE' | 'UNSUPPORTED_MEDIA_TYPE' | 'UPGRADE_REQUIRED' | 'UNPROCESSABLE_ENTITY' | 'TOO_MANY_REQUESTS' | 'SERVER_ERROR' | 'NOT_IMPLEMENTED' | 'BAD_GATEWAY' | 'SERVICE_UNAVAILABLE' | 'GATEWAY_TIMEOUT' | 'NETWORK_CONNECT_TIMEOUT' | 'UNKNOWN_ERROR' | 'RATE_LIMIT_EXCEEDED' | 'INVALID_TOKEN' | 'INCORRECT_EMAIL_OR_PASSWORD' | 'DUPLICATE' | 'CONNECTION_ERROR' | 'SCHEMA_ERROR' | 'DATABASE_ERROR';
|
|
73
|
-
declare class RsError<T extends Record<string, unknown> = Record<string, unknown>> {
|
|
77
|
+
declare class RsError<T extends Record<string, unknown> = Record<string, unknown>> extends Error {
|
|
74
78
|
err: ErrorCode;
|
|
75
79
|
msg: string;
|
|
76
80
|
options?: T;
|
|
77
81
|
status?: number;
|
|
78
|
-
stack: string;
|
|
79
82
|
constructor(errCode: ErrorCode, message?: string, options?: T);
|
|
83
|
+
toJSON(): Record<string, unknown>;
|
|
80
84
|
static htmlStatus(code: ErrorCode): number;
|
|
81
85
|
static isRsError(error: unknown): error is RsError;
|
|
82
86
|
}
|
|
@@ -1193,10 +1197,16 @@ declare function questionMarksToOrderedParams(query: string): string;
|
|
|
1193
1197
|
/**
|
|
1194
1198
|
* Creates a query to insert an object into a table.
|
|
1195
1199
|
* @param table Table name to insert the object into
|
|
1196
|
-
* @param obj
|
|
1197
|
-
* @
|
|
1200
|
+
* @param obj Data to insert into the table
|
|
1201
|
+
* @param options.customSelect Optional custom SELECT clause that wraps the INSERT in a CTE.
|
|
1202
|
+
* When provided, the INSERT is wrapped in `WITH inserted AS (INSERT ... RETURNING *)`,
|
|
1203
|
+
* and your customSelect should reference the `inserted` alias.
|
|
1204
|
+
* Example: `{ customSelect: 'SELECT i.*, u.email FROM inserted i JOIN "user" u ON i."userId" = u.id' }`
|
|
1205
|
+
* @returns The query to insert the object into the table
|
|
1198
1206
|
*/
|
|
1199
|
-
declare function insertObjectQuery(table: string, obj: DynamicObject
|
|
1207
|
+
declare function insertObjectQuery(table: string, obj: DynamicObject, options?: {
|
|
1208
|
+
customSelect?: string;
|
|
1209
|
+
}): string;
|
|
1200
1210
|
/**
|
|
1201
1211
|
* Creates a query to update an object in a table.
|
|
1202
1212
|
* @param table Table name to update the object in
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,94 @@ import { config } from "@restura/internal";
|
|
|
14
14
|
import pino from "pino";
|
|
15
15
|
import pinoPretty from "pino-pretty";
|
|
16
16
|
|
|
17
|
+
// src/restura/RsError.ts
|
|
18
|
+
var HtmlStatusCodes = /* @__PURE__ */ ((HtmlStatusCodes2) => {
|
|
19
|
+
HtmlStatusCodes2[HtmlStatusCodes2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
20
|
+
HtmlStatusCodes2[HtmlStatusCodes2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
|
21
|
+
HtmlStatusCodes2[HtmlStatusCodes2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
|
|
22
|
+
HtmlStatusCodes2[HtmlStatusCodes2["FORBIDDEN"] = 403] = "FORBIDDEN";
|
|
23
|
+
HtmlStatusCodes2[HtmlStatusCodes2["NOT_FOUND"] = 404] = "NOT_FOUND";
|
|
24
|
+
HtmlStatusCodes2[HtmlStatusCodes2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
|
|
25
|
+
HtmlStatusCodes2[HtmlStatusCodes2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
|
|
26
|
+
HtmlStatusCodes2[HtmlStatusCodes2["CONFLICT"] = 409] = "CONFLICT";
|
|
27
|
+
HtmlStatusCodes2[HtmlStatusCodes2["GONE"] = 410] = "GONE";
|
|
28
|
+
HtmlStatusCodes2[HtmlStatusCodes2["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
|
|
29
|
+
HtmlStatusCodes2[HtmlStatusCodes2["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
|
|
30
|
+
HtmlStatusCodes2[HtmlStatusCodes2["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
|
|
31
|
+
HtmlStatusCodes2[HtmlStatusCodes2["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
|
|
32
|
+
HtmlStatusCodes2[HtmlStatusCodes2["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
|
33
|
+
HtmlStatusCodes2[HtmlStatusCodes2["SERVER_ERROR"] = 500] = "SERVER_ERROR";
|
|
34
|
+
HtmlStatusCodes2[HtmlStatusCodes2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
|
|
35
|
+
HtmlStatusCodes2[HtmlStatusCodes2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
|
|
36
|
+
HtmlStatusCodes2[HtmlStatusCodes2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
|
|
37
|
+
HtmlStatusCodes2[HtmlStatusCodes2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
|
|
38
|
+
HtmlStatusCodes2[HtmlStatusCodes2["NETWORK_CONNECT_TIMEOUT"] = 599] = "NETWORK_CONNECT_TIMEOUT";
|
|
39
|
+
return HtmlStatusCodes2;
|
|
40
|
+
})(HtmlStatusCodes || {});
|
|
41
|
+
var RsError = class _RsError extends Error {
|
|
42
|
+
err;
|
|
43
|
+
msg;
|
|
44
|
+
options;
|
|
45
|
+
status;
|
|
46
|
+
constructor(errCode, message, options) {
|
|
47
|
+
super(message);
|
|
48
|
+
this.name = "RsError";
|
|
49
|
+
this.err = errCode;
|
|
50
|
+
this.msg = message || "";
|
|
51
|
+
this.status = _RsError.htmlStatus(errCode);
|
|
52
|
+
this.options = options;
|
|
53
|
+
}
|
|
54
|
+
toJSON() {
|
|
55
|
+
return {
|
|
56
|
+
type: this.name,
|
|
57
|
+
err: this.err,
|
|
58
|
+
message: this.message,
|
|
59
|
+
msg: this.msg,
|
|
60
|
+
status: this.status ?? 500,
|
|
61
|
+
stack: this.stack ?? "",
|
|
62
|
+
options: this.options
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
static htmlStatus(code) {
|
|
66
|
+
return htmlStatusMap[code];
|
|
67
|
+
}
|
|
68
|
+
static isRsError(error) {
|
|
69
|
+
return error instanceof _RsError;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var htmlStatusMap = {
|
|
73
|
+
// 1:1 mappings to HTTP status codes
|
|
74
|
+
BAD_REQUEST: 400 /* BAD_REQUEST */,
|
|
75
|
+
UNAUTHORIZED: 401 /* UNAUTHORIZED */,
|
|
76
|
+
PAYMENT_REQUIRED: 402 /* PAYMENT_REQUIRED */,
|
|
77
|
+
FORBIDDEN: 403 /* FORBIDDEN */,
|
|
78
|
+
NOT_FOUND: 404 /* NOT_FOUND */,
|
|
79
|
+
METHOD_NOT_ALLOWED: 405 /* METHOD_NOT_ALLOWED */,
|
|
80
|
+
REQUEST_TIMEOUT: 408 /* REQUEST_TIMEOUT */,
|
|
81
|
+
CONFLICT: 409 /* CONFLICT */,
|
|
82
|
+
GONE: 410 /* GONE */,
|
|
83
|
+
PAYLOAD_TOO_LARGE: 413 /* PAYLOAD_TOO_LARGE */,
|
|
84
|
+
UNSUPPORTED_MEDIA_TYPE: 415 /* UNSUPPORTED_MEDIA_TYPE */,
|
|
85
|
+
UPGRADE_REQUIRED: 426 /* UPGRADE_REQUIRED */,
|
|
86
|
+
UNPROCESSABLE_ENTITY: 422 /* UNPROCESSABLE_ENTITY */,
|
|
87
|
+
TOO_MANY_REQUESTS: 429 /* TOO_MANY_REQUESTS */,
|
|
88
|
+
SERVER_ERROR: 500 /* SERVER_ERROR */,
|
|
89
|
+
NOT_IMPLEMENTED: 501 /* NOT_IMPLEMENTED */,
|
|
90
|
+
BAD_GATEWAY: 502 /* BAD_GATEWAY */,
|
|
91
|
+
SERVICE_UNAVAILABLE: 503 /* SERVICE_UNAVAILABLE */,
|
|
92
|
+
GATEWAY_TIMEOUT: 504 /* GATEWAY_TIMEOUT */,
|
|
93
|
+
NETWORK_CONNECT_TIMEOUT: 599 /* NETWORK_CONNECT_TIMEOUT */,
|
|
94
|
+
// Specific business errors mapped to appropriate HTTP codes
|
|
95
|
+
UNKNOWN_ERROR: 500 /* SERVER_ERROR */,
|
|
96
|
+
RATE_LIMIT_EXCEEDED: 429 /* TOO_MANY_REQUESTS */,
|
|
97
|
+
INVALID_TOKEN: 401 /* UNAUTHORIZED */,
|
|
98
|
+
INCORRECT_EMAIL_OR_PASSWORD: 401 /* UNAUTHORIZED */,
|
|
99
|
+
DUPLICATE: 409 /* CONFLICT */,
|
|
100
|
+
CONNECTION_ERROR: 504 /* GATEWAY_TIMEOUT */,
|
|
101
|
+
SCHEMA_ERROR: 500 /* SERVER_ERROR */,
|
|
102
|
+
DATABASE_ERROR: 500 /* SERVER_ERROR */
|
|
103
|
+
};
|
|
104
|
+
|
|
17
105
|
// src/logger/loggerConfigSchema.ts
|
|
18
106
|
import { z } from "zod";
|
|
19
107
|
var loggerConfigSchema = z.object({
|
|
@@ -68,6 +156,9 @@ var defaultSerializer = (error) => {
|
|
|
68
156
|
responseData: err.response?.data
|
|
69
157
|
};
|
|
70
158
|
}
|
|
159
|
+
if (RsError.isRsError(error)) {
|
|
160
|
+
return error.toJSON();
|
|
161
|
+
}
|
|
71
162
|
return baseSerializer(error);
|
|
72
163
|
};
|
|
73
164
|
var errorSerializer = (() => {
|
|
@@ -332,83 +423,6 @@ var SqlUtils = class _SqlUtils {
|
|
|
332
423
|
}
|
|
333
424
|
};
|
|
334
425
|
|
|
335
|
-
// src/restura/RsError.ts
|
|
336
|
-
var HtmlStatusCodes = /* @__PURE__ */ ((HtmlStatusCodes2) => {
|
|
337
|
-
HtmlStatusCodes2[HtmlStatusCodes2["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
338
|
-
HtmlStatusCodes2[HtmlStatusCodes2["UNAUTHORIZED"] = 401] = "UNAUTHORIZED";
|
|
339
|
-
HtmlStatusCodes2[HtmlStatusCodes2["PAYMENT_REQUIRED"] = 402] = "PAYMENT_REQUIRED";
|
|
340
|
-
HtmlStatusCodes2[HtmlStatusCodes2["FORBIDDEN"] = 403] = "FORBIDDEN";
|
|
341
|
-
HtmlStatusCodes2[HtmlStatusCodes2["NOT_FOUND"] = 404] = "NOT_FOUND";
|
|
342
|
-
HtmlStatusCodes2[HtmlStatusCodes2["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
|
|
343
|
-
HtmlStatusCodes2[HtmlStatusCodes2["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
|
|
344
|
-
HtmlStatusCodes2[HtmlStatusCodes2["CONFLICT"] = 409] = "CONFLICT";
|
|
345
|
-
HtmlStatusCodes2[HtmlStatusCodes2["GONE"] = 410] = "GONE";
|
|
346
|
-
HtmlStatusCodes2[HtmlStatusCodes2["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
|
|
347
|
-
HtmlStatusCodes2[HtmlStatusCodes2["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
|
|
348
|
-
HtmlStatusCodes2[HtmlStatusCodes2["UPGRADE_REQUIRED"] = 426] = "UPGRADE_REQUIRED";
|
|
349
|
-
HtmlStatusCodes2[HtmlStatusCodes2["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
|
|
350
|
-
HtmlStatusCodes2[HtmlStatusCodes2["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
|
351
|
-
HtmlStatusCodes2[HtmlStatusCodes2["SERVER_ERROR"] = 500] = "SERVER_ERROR";
|
|
352
|
-
HtmlStatusCodes2[HtmlStatusCodes2["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
|
|
353
|
-
HtmlStatusCodes2[HtmlStatusCodes2["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
|
|
354
|
-
HtmlStatusCodes2[HtmlStatusCodes2["SERVICE_UNAVAILABLE"] = 503] = "SERVICE_UNAVAILABLE";
|
|
355
|
-
HtmlStatusCodes2[HtmlStatusCodes2["GATEWAY_TIMEOUT"] = 504] = "GATEWAY_TIMEOUT";
|
|
356
|
-
HtmlStatusCodes2[HtmlStatusCodes2["NETWORK_CONNECT_TIMEOUT"] = 599] = "NETWORK_CONNECT_TIMEOUT";
|
|
357
|
-
return HtmlStatusCodes2;
|
|
358
|
-
})(HtmlStatusCodes || {});
|
|
359
|
-
var RsError = class _RsError {
|
|
360
|
-
err;
|
|
361
|
-
msg;
|
|
362
|
-
options;
|
|
363
|
-
status;
|
|
364
|
-
stack;
|
|
365
|
-
constructor(errCode, message, options) {
|
|
366
|
-
this.err = errCode;
|
|
367
|
-
this.msg = message || "";
|
|
368
|
-
this.status = _RsError.htmlStatus(errCode);
|
|
369
|
-
this.stack = new Error().stack || "";
|
|
370
|
-
this.options = options;
|
|
371
|
-
}
|
|
372
|
-
static htmlStatus(code) {
|
|
373
|
-
return htmlStatusMap[code];
|
|
374
|
-
}
|
|
375
|
-
static isRsError(error) {
|
|
376
|
-
return error instanceof _RsError;
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
var htmlStatusMap = {
|
|
380
|
-
// 1:1 mappings to HTTP status codes
|
|
381
|
-
BAD_REQUEST: 400 /* BAD_REQUEST */,
|
|
382
|
-
UNAUTHORIZED: 401 /* UNAUTHORIZED */,
|
|
383
|
-
PAYMENT_REQUIRED: 402 /* PAYMENT_REQUIRED */,
|
|
384
|
-
FORBIDDEN: 403 /* FORBIDDEN */,
|
|
385
|
-
NOT_FOUND: 404 /* NOT_FOUND */,
|
|
386
|
-
METHOD_NOT_ALLOWED: 405 /* METHOD_NOT_ALLOWED */,
|
|
387
|
-
REQUEST_TIMEOUT: 408 /* REQUEST_TIMEOUT */,
|
|
388
|
-
CONFLICT: 409 /* CONFLICT */,
|
|
389
|
-
GONE: 410 /* GONE */,
|
|
390
|
-
PAYLOAD_TOO_LARGE: 413 /* PAYLOAD_TOO_LARGE */,
|
|
391
|
-
UNSUPPORTED_MEDIA_TYPE: 415 /* UNSUPPORTED_MEDIA_TYPE */,
|
|
392
|
-
UPGRADE_REQUIRED: 426 /* UPGRADE_REQUIRED */,
|
|
393
|
-
UNPROCESSABLE_ENTITY: 422 /* UNPROCESSABLE_ENTITY */,
|
|
394
|
-
TOO_MANY_REQUESTS: 429 /* TOO_MANY_REQUESTS */,
|
|
395
|
-
SERVER_ERROR: 500 /* SERVER_ERROR */,
|
|
396
|
-
NOT_IMPLEMENTED: 501 /* NOT_IMPLEMENTED */,
|
|
397
|
-
BAD_GATEWAY: 502 /* BAD_GATEWAY */,
|
|
398
|
-
SERVICE_UNAVAILABLE: 503 /* SERVICE_UNAVAILABLE */,
|
|
399
|
-
GATEWAY_TIMEOUT: 504 /* GATEWAY_TIMEOUT */,
|
|
400
|
-
NETWORK_CONNECT_TIMEOUT: 599 /* NETWORK_CONNECT_TIMEOUT */,
|
|
401
|
-
// Specific business errors mapped to appropriate HTTP codes
|
|
402
|
-
UNKNOWN_ERROR: 500 /* SERVER_ERROR */,
|
|
403
|
-
RATE_LIMIT_EXCEEDED: 429 /* TOO_MANY_REQUESTS */,
|
|
404
|
-
INVALID_TOKEN: 401 /* UNAUTHORIZED */,
|
|
405
|
-
INCORRECT_EMAIL_OR_PASSWORD: 401 /* UNAUTHORIZED */,
|
|
406
|
-
DUPLICATE: 409 /* CONFLICT */,
|
|
407
|
-
CONNECTION_ERROR: 504 /* GATEWAY_TIMEOUT */,
|
|
408
|
-
SCHEMA_ERROR: 500 /* SERVER_ERROR */,
|
|
409
|
-
DATABASE_ERROR: 500 /* SERVER_ERROR */
|
|
410
|
-
};
|
|
411
|
-
|
|
412
426
|
// src/restura/validators/ResponseValidator.ts
|
|
413
427
|
var ResponseValidator = class _ResponseValidator {
|
|
414
428
|
rootMap;
|
|
@@ -1910,15 +1924,25 @@ function questionMarksToOrderedParams(query) {
|
|
|
1910
1924
|
return char;
|
|
1911
1925
|
});
|
|
1912
1926
|
}
|
|
1913
|
-
function insertObjectQuery(table, obj) {
|
|
1927
|
+
function insertObjectQuery(table, obj, options) {
|
|
1928
|
+
const { customSelect } = options ?? {};
|
|
1914
1929
|
const keys = Object.keys(obj);
|
|
1915
1930
|
const params = Object.values(obj);
|
|
1916
1931
|
const columns = keys.map((column) => escapeColumnName(column)).join(", ");
|
|
1917
1932
|
const values = params.map((value) => SQL`${value}`).join(", ");
|
|
1918
1933
|
let query = `
|
|
1919
|
-
INSERT INTO "${table}" (${columns})
|
|
1920
|
-
|
|
1921
|
-
|
|
1934
|
+
INSERT INTO "${table}" (${columns})
|
|
1935
|
+
VALUES (${values})
|
|
1936
|
+
RETURNING *`;
|
|
1937
|
+
if (customSelect) {
|
|
1938
|
+
query = `
|
|
1939
|
+
WITH inserted AS (
|
|
1940
|
+
INSERT INTO "${table}" (${columns})
|
|
1941
|
+
VALUES (${values})
|
|
1942
|
+
RETURNING *
|
|
1943
|
+
)
|
|
1944
|
+
${customSelect}`;
|
|
1945
|
+
}
|
|
1922
1946
|
query = query.replace(/'(\?)'/g, "?");
|
|
1923
1947
|
return query;
|
|
1924
1948
|
}
|
|
@@ -2285,6 +2309,22 @@ var initializers = `
|
|
|
2285
2309
|
}
|
|
2286
2310
|
return format.literal(value);
|
|
2287
2311
|
}
|
|
2312
|
+
|
|
2313
|
+
// Format a value with optional type cast
|
|
2314
|
+
function formatValueWithCast(rawValue, cast) {
|
|
2315
|
+
var formatted = formatValue(unescapeValue(rawValue));
|
|
2316
|
+
return cast ? formatted + '::' + cast : formatted;
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
// Build SQL IN clause from pipe-separated values with optional cast
|
|
2320
|
+
function buildInClauseWithCast(column, rawValue, cast) {
|
|
2321
|
+
var values = splitPipeValues(rawValue);
|
|
2322
|
+
var literals = values.map(function(v) {
|
|
2323
|
+
var formatted = formatValue(v);
|
|
2324
|
+
return cast ? formatted + '::' + cast : formatted;
|
|
2325
|
+
});
|
|
2326
|
+
return column + ' IN (' + literals.join(', ') + ')';
|
|
2327
|
+
}
|
|
2288
2328
|
`;
|
|
2289
2329
|
var entryGrammar = `
|
|
2290
2330
|
{
|
|
@@ -2319,7 +2359,7 @@ OldOperator
|
|
|
2319
2359
|
= "and"i / "or"i
|
|
2320
2360
|
|
|
2321
2361
|
OldColumn
|
|
2322
|
-
= first:
|
|
2362
|
+
= first:OldColumnPart rest:("." OldColumnPart)* {
|
|
2323
2363
|
const partsArray = [first];
|
|
2324
2364
|
if (rest && rest.length > 0) {
|
|
2325
2365
|
partsArray.push(...rest.map(item => item[1]));
|
|
@@ -2347,20 +2387,25 @@ OldColumn
|
|
|
2347
2387
|
return result;
|
|
2348
2388
|
}
|
|
2349
2389
|
|
|
2350
|
-
|
|
2390
|
+
OldColumnPart
|
|
2351
2391
|
= text:[a-z0-9 \\t\\r\\n\\-_:@']i+ {
|
|
2352
2392
|
return text.join("");
|
|
2353
2393
|
}
|
|
2354
2394
|
|
|
2395
|
+
OldText
|
|
2396
|
+
= text:[a-z0-9 \\t\\r\\n\\-_:@'.]i+ {
|
|
2397
|
+
return text.join("");
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2355
2400
|
OldType
|
|
2356
2401
|
= "type" _ ":" _ type:OldTypeString {
|
|
2357
2402
|
return type;
|
|
2358
2403
|
}
|
|
2359
2404
|
|
|
2360
2405
|
OldTypeString
|
|
2361
|
-
= text:"startsWith" { return function(column, value) { return \`\${column}
|
|
2362
|
-
/ text:"endsWith" { return function(column, value) { return \`\${column}
|
|
2363
|
-
/ text:"contains" { return function(column, value) { return \`\${column}
|
|
2406
|
+
= text:"startsWith" { return function(column, value) { return \`\${column} ILIKE '\${format.literal(value).slice(1,-1)}%'\`; } }
|
|
2407
|
+
/ text:"endsWith" { return function(column, value) { return \`\${column} ILIKE '%\${format.literal(value).slice(1,-1)}'\`; } }
|
|
2408
|
+
/ text:"contains" { return function(column, value) { return \`\${column} ILIKE '%\${format.literal(value).slice(1,-1)}%'\`; } }
|
|
2364
2409
|
/ text:"exact" { return function(column, value) { return \`\${column} = \${formatValue(value)}\`; } }
|
|
2365
2410
|
/ text:"greaterThanEqual" { return function(column, value) { return \`\${column} >= \${formatValue(value)}\`; } }
|
|
2366
2411
|
/ text:"greaterThan" { return function(column, value) { return \`\${column} > \${formatValue(value)}\`; } }
|
|
@@ -2397,8 +2442,8 @@ SimpleExpr
|
|
|
2397
2442
|
{ return (negate ? 'NOT ' : '') + '(' + op(col) + ')'; }
|
|
2398
2443
|
/ negate:"!"? _ "(" _ col:Column _ "," _ op:NullOperator _ ")" _
|
|
2399
2444
|
{ return (negate ? 'NOT ' : '') + '(' + op(col) + ')'; }
|
|
2400
|
-
/ negate:"!"? _ "(" _ col:Column _ "," _ val:
|
|
2401
|
-
{ return (negate ? 'NOT ' : '') + '(' + col + ' = ' +
|
|
2445
|
+
/ negate:"!"? _ "(" _ col:Column _ "," _ val:CastedValue _ ")" _
|
|
2446
|
+
{ return (negate ? 'NOT ' : '') + '(' + col + ' = ' + formatValueWithCast(val.value, val.cast) + ')'; }
|
|
2402
2447
|
|
|
2403
2448
|
Column
|
|
2404
2449
|
= first:ColPart rest:("." ColPart)* {
|
|
@@ -2434,15 +2479,25 @@ NullOperator
|
|
|
2434
2479
|
/ "null"i { return function(col) { return col + ' IS NULL'; }; }
|
|
2435
2480
|
|
|
2436
2481
|
OperatorWithValue
|
|
2437
|
-
= "in"i _ "," _ val:
|
|
2438
|
-
/ "ne"i _ "," _ val:
|
|
2439
|
-
/ "gte"i _ "," _ val:
|
|
2440
|
-
/ "gt"i _ "," _ val:
|
|
2441
|
-
/ "lte"i _ "," _ val:
|
|
2442
|
-
/ "lt"i _ "," _ val:
|
|
2443
|
-
/ "has"i _ "," _ val:
|
|
2444
|
-
/ "sw"i _ "," _ val:
|
|
2445
|
-
/ "ew"i _ "," _ val:
|
|
2482
|
+
= "in"i _ "," _ val:CastedValueWithPipes { return function(col) { return buildInClauseWithCast(col, val.value, val.cast); }; }
|
|
2483
|
+
/ "ne"i _ "," _ val:CastedValue { return function(col) { return col + ' <> ' + formatValueWithCast(val.value, val.cast); }; }
|
|
2484
|
+
/ "gte"i _ "," _ val:CastedValue { return function(col) { return col + ' >= ' + formatValueWithCast(val.value, val.cast); }; }
|
|
2485
|
+
/ "gt"i _ "," _ val:CastedValue { return function(col) { return col + ' > ' + formatValueWithCast(val.value, val.cast); }; }
|
|
2486
|
+
/ "lte"i _ "," _ val:CastedValue { return function(col) { return col + ' <= ' + formatValueWithCast(val.value, val.cast); }; }
|
|
2487
|
+
/ "lt"i _ "," _ val:CastedValue { return function(col) { return col + ' < ' + formatValueWithCast(val.value, val.cast); }; }
|
|
2488
|
+
/ "has"i _ "," _ val:CastedValue { return function(col) { var formatted = format.literal('%' + unescapeValue(val.value) + '%'); return col + ' ILIKE ' + (val.cast ? formatted + '::' + val.cast : formatted); }; }
|
|
2489
|
+
/ "sw"i _ "," _ val:CastedValue { return function(col) { var formatted = format.literal(unescapeValue(val.value) + '%'); return col + ' ILIKE ' + (val.cast ? formatted + '::' + val.cast : formatted); }; }
|
|
2490
|
+
/ "ew"i _ "," _ val:CastedValue { return function(col) { var formatted = format.literal('%' + unescapeValue(val.value)); return col + ' ILIKE ' + (val.cast ? formatted + '::' + val.cast : formatted); }; }
|
|
2491
|
+
|
|
2492
|
+
CastedValue
|
|
2493
|
+
= val:Value cast:TypeCast? { return { value: val, cast: cast }; }
|
|
2494
|
+
|
|
2495
|
+
CastedValueWithPipes
|
|
2496
|
+
= val:ValueWithPipes cast:TypeCast? { return { value: val, cast: cast }; }
|
|
2497
|
+
|
|
2498
|
+
TypeCast
|
|
2499
|
+
= "::" type:("timestamptz"i / "timestamp"i / "boolean"i / "numeric"i / "bigint"i / "text"i / "date"i / "int"i)
|
|
2500
|
+
{ return type.toLowerCase(); }
|
|
2446
2501
|
|
|
2447
2502
|
Value
|
|
2448
2503
|
= chars:ValueChar+ { return chars.join(''); }
|
|
@@ -2451,7 +2506,8 @@ ValueChar
|
|
|
2451
2506
|
= "\\\\\\\\" { return '\\\\\\\\'; }
|
|
2452
2507
|
/ "\\\\," { return '\\\\,'; }
|
|
2453
2508
|
/ "\\\\|" { return '\\\\|'; }
|
|
2454
|
-
/ [^,()
|
|
2509
|
+
/ [^,()\\\\|:]
|
|
2510
|
+
/ c:":" !":" { return c; }
|
|
2455
2511
|
|
|
2456
2512
|
ValueWithPipes
|
|
2457
2513
|
= chars:ValueWithPipesChar+ { return chars.join(''); }
|
|
@@ -2460,7 +2516,8 @@ ValueWithPipesChar
|
|
|
2460
2516
|
= "\\\\\\\\" { return '\\\\\\\\'; }
|
|
2461
2517
|
/ "\\\\," { return '\\\\,'; }
|
|
2462
2518
|
/ "\\\\|" { return '\\\\|'; }
|
|
2463
|
-
/ [^,()
|
|
2519
|
+
/ [^,()\\\\:]
|
|
2520
|
+
/ c:":" !":" { return c; }
|
|
2464
2521
|
`;
|
|
2465
2522
|
var fullGrammar = entryGrammar + oldGrammar + newGrammar;
|
|
2466
2523
|
var filterPsqlParser = peg.generate(fullGrammar, {
|