@restura/core 1.0.19 → 1.1.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 +23 -5
- package/dist/index.js +127 -42
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import winston from 'winston';
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
import { UUID } from 'crypto';
|
|
4
3
|
import * as express from 'express';
|
|
@@ -6,16 +5,36 @@ import { IncomingHttpHeaders } from 'http2';
|
|
|
6
5
|
import { QueryResultRow, QueryConfigValues, QueryResult, PoolConfig, Pool, ClientConfig, Client } from 'pg';
|
|
7
6
|
import peg from 'pegjs';
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
type LogFunction = {
|
|
9
|
+
(msg: string, ...args: unknown[]): void;
|
|
10
|
+
(msg: unknown): void;
|
|
11
|
+
};
|
|
12
|
+
declare const logger: {
|
|
13
|
+
level: "fatal" | "error" | "warn" | "info" | "debug" | "silly" | "trace";
|
|
14
|
+
fatal: LogFunction;
|
|
15
|
+
error: LogFunction;
|
|
16
|
+
warn: LogFunction;
|
|
17
|
+
info: LogFunction;
|
|
18
|
+
debug: LogFunction;
|
|
19
|
+
silly: LogFunction;
|
|
20
|
+
trace: LogFunction;
|
|
21
|
+
};
|
|
10
22
|
|
|
11
23
|
declare const loggerConfigSchema: z.ZodObject<{
|
|
12
24
|
level: z.ZodDefault<z.ZodEnum<{
|
|
13
|
-
|
|
14
|
-
warn: "warn";
|
|
25
|
+
fatal: "fatal";
|
|
15
26
|
error: "error";
|
|
27
|
+
warn: "warn";
|
|
28
|
+
info: "info";
|
|
16
29
|
debug: "debug";
|
|
17
30
|
silly: "silly";
|
|
31
|
+
trace: "trace";
|
|
18
32
|
}>>;
|
|
33
|
+
transports: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
34
|
+
target: z.ZodString;
|
|
35
|
+
level: z.ZodOptional<z.ZodString>;
|
|
36
|
+
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
37
|
+
}, z.core.$strip>>>;
|
|
19
38
|
}, z.core.$strip>;
|
|
20
39
|
type LoggerConfigSchema = z.infer<typeof loggerConfigSchema>;
|
|
21
40
|
|
|
@@ -943,7 +962,6 @@ declare abstract class PsqlConnection {
|
|
|
943
962
|
queryOneSchema<T>(query: string, params: unknown[], requesterDetails: RequesterDetails, zodSchema: z.ZodSchema<T>): Promise<T>;
|
|
944
963
|
runQuery<T>(query: string, options: unknown[], requesterDetails: RequesterDetails): Promise<T[]>;
|
|
945
964
|
runQuerySchema<T>(query: string, params: unknown[], requesterDetails: RequesterDetails, zodSchema: z.ZodSchema<T>): Promise<T[]>;
|
|
946
|
-
private logQueryDuration;
|
|
947
965
|
private logSqlStatement;
|
|
948
966
|
}
|
|
949
967
|
|
package/dist/index.js
CHANGED
|
@@ -11,39 +11,126 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
11
11
|
|
|
12
12
|
// src/logger/logger.ts
|
|
13
13
|
import { config } from "@restura/internal";
|
|
14
|
-
import
|
|
15
|
-
import { format } from "logform";
|
|
14
|
+
import pino from "pino";
|
|
16
15
|
|
|
17
16
|
// src/logger/loggerConfigSchema.ts
|
|
18
17
|
import { z } from "zod";
|
|
19
18
|
var loggerConfigSchema = z.object({
|
|
20
|
-
level: z.enum(["
|
|
19
|
+
level: z.enum(["fatal", "error", "warn", "info", "debug", "silly", "trace"]).default("info"),
|
|
20
|
+
transports: z.array(
|
|
21
|
+
z.object({
|
|
22
|
+
target: z.string(),
|
|
23
|
+
level: z.string().optional(),
|
|
24
|
+
options: z.record(z.string(), z.unknown()).optional()
|
|
25
|
+
})
|
|
26
|
+
).optional()
|
|
21
27
|
});
|
|
22
28
|
|
|
23
29
|
// src/logger/logger.ts
|
|
24
30
|
var loggerConfig = await config.validate("logger", loggerConfigSchema);
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
var logLevelMap = {
|
|
32
|
+
fatal: "fatal",
|
|
33
|
+
error: "error",
|
|
34
|
+
warn: "warn",
|
|
35
|
+
info: "info",
|
|
36
|
+
debug: "debug",
|
|
37
|
+
silly: "trace",
|
|
38
|
+
trace: "trace"
|
|
39
|
+
};
|
|
40
|
+
var currentLogLevel = logLevelMap[loggerConfig.level];
|
|
41
|
+
var defaultTransports = [
|
|
42
|
+
{
|
|
43
|
+
target: "pino-pretty",
|
|
44
|
+
options: {
|
|
45
|
+
colorize: true,
|
|
46
|
+
translateTime: "yyyy-mm-dd HH:MM:ss.l",
|
|
47
|
+
ignore: "pid,hostname,_meta",
|
|
48
|
+
// _meta allows a user to pass in metadata for JSON but not print it to the console
|
|
49
|
+
messageFormat: "{msg}",
|
|
50
|
+
levelFirst: true,
|
|
51
|
+
customColors: "error:red,warn:yellow,info:green,debug:blue,trace:magenta"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
];
|
|
55
|
+
var pinoLogger = pino({
|
|
56
|
+
level: currentLogLevel,
|
|
57
|
+
transport: {
|
|
58
|
+
targets: loggerConfig.transports ?? defaultTransports
|
|
59
|
+
},
|
|
60
|
+
serializers: {
|
|
61
|
+
err: pino.stdSerializers.err
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
function buildContext(args) {
|
|
65
|
+
const ctx = {};
|
|
66
|
+
const prims = [];
|
|
67
|
+
for (const arg of args) {
|
|
68
|
+
if (arg instanceof Error && !ctx.err) {
|
|
69
|
+
ctx.err = arg;
|
|
70
|
+
} else if (arg && typeof arg === "object" && !Array.isArray(arg)) {
|
|
71
|
+
Object.assign(ctx, arg);
|
|
72
|
+
} else {
|
|
73
|
+
prims.push(arg);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (prims.length) ctx.args = prims;
|
|
77
|
+
return ctx;
|
|
78
|
+
}
|
|
79
|
+
function log(level, message, ...args) {
|
|
80
|
+
pinoLogger[level](buildContext(args), message);
|
|
81
|
+
}
|
|
82
|
+
var logger = {
|
|
83
|
+
level: loggerConfig.level,
|
|
84
|
+
fatal: ((msg, ...args) => {
|
|
85
|
+
if (typeof msg === "string") {
|
|
86
|
+
log("fatal", msg, ...args);
|
|
87
|
+
} else {
|
|
88
|
+
pinoLogger.fatal(msg);
|
|
89
|
+
}
|
|
90
|
+
}),
|
|
91
|
+
error: ((msg, ...args) => {
|
|
92
|
+
if (typeof msg === "string") {
|
|
93
|
+
log("error", msg, ...args);
|
|
94
|
+
} else {
|
|
95
|
+
pinoLogger.error(msg);
|
|
96
|
+
}
|
|
97
|
+
}),
|
|
98
|
+
warn: ((msg, ...args) => {
|
|
99
|
+
if (typeof msg === "string") {
|
|
100
|
+
log("warn", msg, ...args);
|
|
101
|
+
} else {
|
|
102
|
+
pinoLogger.warn(msg);
|
|
103
|
+
}
|
|
104
|
+
}),
|
|
105
|
+
info: ((msg, ...args) => {
|
|
106
|
+
if (typeof msg === "string") {
|
|
107
|
+
log("info", msg, ...args);
|
|
108
|
+
} else {
|
|
109
|
+
pinoLogger.info(msg);
|
|
110
|
+
}
|
|
111
|
+
}),
|
|
112
|
+
debug: ((msg, ...args) => {
|
|
113
|
+
if (typeof msg === "string") {
|
|
114
|
+
log("debug", msg, ...args);
|
|
115
|
+
} else {
|
|
116
|
+
pinoLogger.debug(msg);
|
|
117
|
+
}
|
|
28
118
|
}),
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
119
|
+
silly: ((msg, ...args) => {
|
|
120
|
+
if (typeof msg === "string") {
|
|
121
|
+
log("trace", msg, ...args);
|
|
122
|
+
} else {
|
|
123
|
+
pinoLogger.trace(msg);
|
|
124
|
+
}
|
|
125
|
+
}),
|
|
126
|
+
trace: ((msg, ...args) => {
|
|
127
|
+
if (typeof msg === "string") {
|
|
128
|
+
log("trace", msg, ...args);
|
|
129
|
+
} else {
|
|
130
|
+
pinoLogger.trace(msg);
|
|
131
|
+
}
|
|
34
132
|
})
|
|
35
|
-
|
|
36
|
-
var logger = winston.createLogger({
|
|
37
|
-
level: loggerConfig.level,
|
|
38
|
-
format: format.combine(
|
|
39
|
-
format.timestamp({
|
|
40
|
-
format: "YYYY-MM-DD HH:mm:ss.sss"
|
|
41
|
-
}),
|
|
42
|
-
format.errors({ stack: true }),
|
|
43
|
-
format.json()
|
|
44
|
-
),
|
|
45
|
-
transports: [new winston.transports.Console({ format: consoleFormat })]
|
|
46
|
-
});
|
|
133
|
+
};
|
|
47
134
|
|
|
48
135
|
// src/restura/eventManager.ts
|
|
49
136
|
import Bluebird from "bluebird";
|
|
@@ -1636,12 +1723,12 @@ import pg from "pg";
|
|
|
1636
1723
|
|
|
1637
1724
|
// src/restura/sql/PsqlConnection.ts
|
|
1638
1725
|
import crypto from "crypto";
|
|
1639
|
-
import
|
|
1726
|
+
import format2 from "pg-format";
|
|
1640
1727
|
import { format as sqlFormat } from "sql-formatter";
|
|
1641
1728
|
import { z as z6 } from "zod";
|
|
1642
1729
|
|
|
1643
1730
|
// src/restura/sql/PsqlUtils.ts
|
|
1644
|
-
import
|
|
1731
|
+
import format from "pg-format";
|
|
1645
1732
|
function escapeColumnName(columnName) {
|
|
1646
1733
|
if (columnName === void 0) return "";
|
|
1647
1734
|
return `"${columnName.replace(/"/g, "")}"`.replace(".", '"."');
|
|
@@ -1698,9 +1785,9 @@ function SQL(strings, ...values) {
|
|
|
1698
1785
|
} else if (typeof value === "number") {
|
|
1699
1786
|
query += value;
|
|
1700
1787
|
} else if (Array.isArray(value)) {
|
|
1701
|
-
query +=
|
|
1788
|
+
query += format.literal(JSON.stringify(value)) + "::jsonb";
|
|
1702
1789
|
} else {
|
|
1703
|
-
query +=
|
|
1790
|
+
query += format.literal(value);
|
|
1704
1791
|
}
|
|
1705
1792
|
query += strings[index + 1];
|
|
1706
1793
|
});
|
|
@@ -1716,17 +1803,17 @@ var PsqlConnection = class {
|
|
|
1716
1803
|
async queryOne(query, options, requesterDetails) {
|
|
1717
1804
|
const formattedQuery = questionMarksToOrderedParams(query);
|
|
1718
1805
|
const meta = { connectionInstanceId: this.instanceId, ...requesterDetails };
|
|
1719
|
-
this.logSqlStatement(formattedQuery, options, meta);
|
|
1720
1806
|
const queryMetadata = `--QUERY_METADATA(${JSON.stringify(meta)})
|
|
1721
1807
|
`;
|
|
1722
1808
|
const startTime = process.hrtime();
|
|
1723
1809
|
try {
|
|
1724
1810
|
const response = await this.query(queryMetadata + formattedQuery, options);
|
|
1725
|
-
this.
|
|
1811
|
+
this.logSqlStatement(formattedQuery, options, meta, startTime);
|
|
1726
1812
|
if (response.rows.length === 0) throw new RsError("NOT_FOUND", "No results found");
|
|
1727
1813
|
else if (response.rows.length > 1) throw new RsError("DUPLICATE", "More than one result found");
|
|
1728
1814
|
return response.rows[0];
|
|
1729
1815
|
} catch (error) {
|
|
1816
|
+
this.logSqlStatement(formattedQuery, options, meta, startTime);
|
|
1730
1817
|
if (RsError.isRsError(error)) throw error;
|
|
1731
1818
|
if (error?.routine === "_bt_check_unique") {
|
|
1732
1819
|
throw new RsError("DUPLICATE", error.message);
|
|
@@ -1752,15 +1839,15 @@ var PsqlConnection = class {
|
|
|
1752
1839
|
async runQuery(query, options, requesterDetails) {
|
|
1753
1840
|
const formattedQuery = questionMarksToOrderedParams(query);
|
|
1754
1841
|
const meta = { connectionInstanceId: this.instanceId, ...requesterDetails };
|
|
1755
|
-
this.logSqlStatement(formattedQuery, options, meta);
|
|
1756
1842
|
const queryMetadata = `--QUERY_METADATA(${JSON.stringify(meta)})
|
|
1757
1843
|
`;
|
|
1758
1844
|
const startTime = process.hrtime();
|
|
1759
1845
|
try {
|
|
1760
1846
|
const response = await this.query(queryMetadata + formattedQuery, options);
|
|
1761
|
-
this.
|
|
1847
|
+
this.logSqlStatement(formattedQuery, options, meta, startTime);
|
|
1762
1848
|
return response.rows;
|
|
1763
1849
|
} catch (error) {
|
|
1850
|
+
this.logSqlStatement(formattedQuery, options, meta, startTime);
|
|
1764
1851
|
if (error?.routine === "_bt_check_unique") {
|
|
1765
1852
|
throw new RsError("DUPLICATE", error.message);
|
|
1766
1853
|
}
|
|
@@ -1782,15 +1869,8 @@ var PsqlConnection = class {
|
|
|
1782
1869
|
throw new RsError("DATABASE_ERROR", `Invalid data returned from database`);
|
|
1783
1870
|
}
|
|
1784
1871
|
}
|
|
1785
|
-
|
|
1786
|
-
if (logger.level
|
|
1787
|
-
const [seconds, nanoseconds] = process.hrtime(startTime);
|
|
1788
|
-
const duration = seconds * 1e3 + nanoseconds / 1e6;
|
|
1789
|
-
logger.silly(`Query duration: ${duration.toFixed(2)}ms`);
|
|
1790
|
-
}
|
|
1791
|
-
}
|
|
1792
|
-
logSqlStatement(query, options, queryMetadata, prefix = "") {
|
|
1793
|
-
if (logger.level !== "silly") return;
|
|
1872
|
+
logSqlStatement(query, options, queryMetadata, startTime, prefix = "") {
|
|
1873
|
+
if (logger.level !== "trace" && logger.level !== "silly") return;
|
|
1794
1874
|
let sqlStatement = "";
|
|
1795
1875
|
if (options.length === 0) {
|
|
1796
1876
|
sqlStatement = query;
|
|
@@ -1803,7 +1883,7 @@ var PsqlConnection = class {
|
|
|
1803
1883
|
const value = options[paramIndex];
|
|
1804
1884
|
if (typeof value === "number") return value.toString();
|
|
1805
1885
|
if (typeof value === "boolean") return value.toString();
|
|
1806
|
-
return
|
|
1886
|
+
return format2.literal(value);
|
|
1807
1887
|
});
|
|
1808
1888
|
}
|
|
1809
1889
|
const formattedSql = sqlFormat(sqlStatement, {
|
|
@@ -1814,12 +1894,17 @@ var PsqlConnection = class {
|
|
|
1814
1894
|
useTabs: true,
|
|
1815
1895
|
tabWidth: 4
|
|
1816
1896
|
});
|
|
1897
|
+
const [seconds, nanoseconds] = process.hrtime(startTime);
|
|
1898
|
+
const durationMs = seconds * 1e3 + nanoseconds / 1e6;
|
|
1817
1899
|
let initiator = "Anonymous";
|
|
1818
1900
|
if ("userId" in queryMetadata && queryMetadata.userId)
|
|
1819
1901
|
initiator = `User Id (${queryMetadata.userId.toString()})`;
|
|
1820
1902
|
if ("isSystemUser" in queryMetadata && queryMetadata.isSystemUser) initiator = "SYSTEM";
|
|
1821
1903
|
logger.silly(`${prefix}query by ${initiator}, Query ->
|
|
1822
|
-
${formattedSql}
|
|
1904
|
+
${formattedSql}`, {
|
|
1905
|
+
duration: `${durationMs.toFixed(2)}ms`,
|
|
1906
|
+
_meta: { durationNs: nanoseconds }
|
|
1907
|
+
});
|
|
1823
1908
|
}
|
|
1824
1909
|
};
|
|
1825
1910
|
|