@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 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
- declare const logger: winston.Logger;
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
- info: "info";
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 winston from "winston";
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(["info", "warn", "error", "debug", "silly"]).default("info")
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 consoleFormat = format.combine(
26
- format.timestamp({
27
- format: "YYYY-MM-DD HH:mm:ss.sss"
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
- format.errors({ stack: true }),
30
- format.padLevels(),
31
- format.colorize({ all: true }),
32
- format.printf((info) => {
33
- return `[${info.timestamp}] ${info.level} ${info.message}`;
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 format3 from "pg-format";
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 format2 from "pg-format";
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 += format2.literal(JSON.stringify(value)) + "::jsonb";
1788
+ query += format.literal(JSON.stringify(value)) + "::jsonb";
1702
1789
  } else {
1703
- query += format2.literal(value);
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.logQueryDuration(startTime);
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.logQueryDuration(startTime);
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
- logQueryDuration(startTime) {
1786
- if (logger.level === "silly") {
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 format3.literal(value);
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