@logtape/drizzle-orm 2.2.0-dev.620 → 2.2.0-dev.626

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright 2024–2025 Hong Minhee
3
+ Copyright 2024–2026 Hong Minhee
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
6
  this software and associated documentation files (the "Software"), to deal in
package/README.md CHANGED
@@ -84,6 +84,20 @@ const db = drizzle(client, {
84
84
  ~~~~
85
85
 
86
86
 
87
+ Dialects
88
+ --------
89
+
90
+ By default, the PostgreSQL dialect (`"pg"`) is used. You can change this:
91
+
92
+ ~~~~ typescript
93
+ const db = drizzle(client, {
94
+ logger: getLogger({
95
+ dialect: "sqlite", // "pg" | "sqlite"
96
+ }),
97
+ });
98
+ ~~~~
99
+
100
+
87
101
  Structured logging
88
102
  ------------------
89
103
 
package/dist/mod.cjs CHANGED
@@ -22,14 +22,17 @@ const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/log
22
22
  var DrizzleLogger = class {
23
23
  #logger;
24
24
  #level;
25
+ #dialect;
25
26
  /**
26
27
  * Creates a new DrizzleLogger instance.
27
28
  * @param logger The LogTape logger to use.
28
29
  * @param level The log level to use for query logging.
30
+ * @param dialect The dialect used for drizzle-orm
29
31
  */
30
- constructor(logger, level = "debug") {
32
+ constructor(logger, level = "debug", dialect = "pg") {
31
33
  this.#logger = logger;
32
34
  this.#level = level;
35
+ this.#dialect = dialect;
33
36
  }
34
37
  /**
35
38
  * Logs a database query with its parameters.
@@ -44,11 +47,26 @@ var DrizzleLogger = class {
44
47
  * @param params The parameter values.
45
48
  */
46
49
  logQuery(query, params) {
47
- const stringifiedParams = params.map(serialize);
48
- const formattedQuery = query.replace(/\$(\d+)/g, (match) => {
49
- const index = Number.parseInt(match.slice(1), 10);
50
- return stringifiedParams[index - 1] ?? match;
51
- });
50
+ const stringifiedParams = params.map((param) => serialize(param, this.#dialect));
51
+ let formattedQuery;
52
+ switch (this.#dialect) {
53
+ case "pg": {
54
+ formattedQuery = query.replace(/\$(\d+)/g, (match) => {
55
+ const index = Number.parseInt(match.slice(1), 10);
56
+ return stringifiedParams[index - 1] ?? match;
57
+ });
58
+ break;
59
+ }
60
+ case "sqlite": {
61
+ let index = -1;
62
+ formattedQuery = query.replace(/\?/g, (match) => {
63
+ index += 1;
64
+ return stringifiedParams[index] ?? match;
65
+ });
66
+ break;
67
+ }
68
+ default: throw new Error(`${this.#dialect} is not supported`);
69
+ }
52
70
  const logMethod = this.#logger[this.#level].bind(this.#logger);
53
71
  logMethod("Query: {formattedQuery}", {
54
72
  formattedQuery,
@@ -61,39 +79,55 @@ var DrizzleLogger = class {
61
79
  * Serializes a parameter value to a SQL-safe string representation.
62
80
  *
63
81
  * @param value The value to serialize.
82
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
64
83
  * @returns The serialized string representation.
65
84
  * @since 1.3.0
66
85
  */
67
- function serialize(value) {
86
+ function serialize(value, dialect = "pg") {
68
87
  if (typeof value === "undefined" || value === null) return "NULL";
69
- if (typeof value === "string") return stringLiteral(value);
88
+ if (typeof value === "string") return stringLiteral(value, dialect);
70
89
  if (typeof value === "number" || typeof value === "bigint") return value.toString();
71
- if (typeof value === "boolean") return value ? "'t'" : "'f'";
72
- if (value instanceof Date) return stringLiteral(value.toISOString());
73
- if (Array.isArray(value)) return `ARRAY[${value.map(serialize).join(", ")}]`;
74
- if (typeof value === "object") return stringLiteral(JSON.stringify(value));
75
- return stringLiteral(String(value));
90
+ if (typeof value === "boolean") switch (dialect) {
91
+ case "sqlite": return value ? "1" : "0";
92
+ case "pg": return value ? "'t'" : "'f'";
93
+ default: throw new Error(`${dialect} is not supported`);
94
+ }
95
+ if (value instanceof Date) return stringLiteral(value.toISOString(), dialect);
96
+ if (Array.isArray(value)) switch (dialect) {
97
+ case "sqlite": return stringLiteral(JSON.stringify(value), dialect);
98
+ case "pg": return `ARRAY[${value.map((item) => serialize(item, dialect)).join(", ")}]`;
99
+ default: throw new Error(`${dialect} is not supported`);
100
+ }
101
+ if (typeof value === "object") return stringLiteral(JSON.stringify(value), dialect);
102
+ return stringLiteral(String(value), dialect);
76
103
  }
77
104
  /**
78
105
  * Converts a string to a SQL string literal with proper escaping.
79
106
  *
80
107
  * @param str The string to convert.
108
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
81
109
  * @returns The escaped SQL string literal.
82
110
  * @since 1.3.0
83
111
  */
84
- function stringLiteral(str) {
85
- if (/[\\'\n\r\t\b\f]/.test(str)) {
86
- let escaped = str;
87
- escaped = escaped.replaceAll("\\", "\\\\");
88
- escaped = escaped.replaceAll("'", "\\'");
89
- escaped = escaped.replaceAll("\n", "\\n");
90
- escaped = escaped.replaceAll("\r", "\\r");
91
- escaped = escaped.replaceAll(" ", "\\t");
92
- escaped = escaped.replaceAll("\b", "\\b");
93
- escaped = escaped.replaceAll("\f", "\\f");
94
- return `E'${escaped}'`;
112
+ function stringLiteral(str, dialect = "pg") {
113
+ switch (dialect) {
114
+ case "sqlite": return `'${str.replaceAll("'", "''")}'`;
115
+ case "pg": {
116
+ if (/[\\'\n\r\t\b\f]/.test(str)) {
117
+ let escaped = str;
118
+ escaped = escaped.replaceAll("\\", "\\\\");
119
+ escaped = escaped.replaceAll("'", "\\'");
120
+ escaped = escaped.replaceAll("\n", "\\n");
121
+ escaped = escaped.replaceAll("\r", "\\r");
122
+ escaped = escaped.replaceAll(" ", "\\t");
123
+ escaped = escaped.replaceAll("\b", "\\b");
124
+ escaped = escaped.replaceAll("\f", "\\f");
125
+ return `E'${escaped}'`;
126
+ }
127
+ return `'${str}'`;
128
+ }
129
+ default: throw new Error(`${dialect} is not supported`);
95
130
  }
96
- return `'${str}'`;
97
131
  }
98
132
  /**
99
133
  * Normalize category to array format.
@@ -138,7 +172,7 @@ function normalizeCategory(category) {
138
172
  function getLogger(options = {}) {
139
173
  const category = normalizeCategory(options.category ?? ["drizzle-orm"]);
140
174
  const logger = (0, __logtape_logtape.getLogger)(category);
141
- return new DrizzleLogger(logger, options.level ?? "debug");
175
+ return new DrizzleLogger(logger, options.level ?? "debug", options.dialect ?? "pg");
142
176
  }
143
177
 
144
178
  //#endregion
package/dist/mod.d.cts CHANGED
@@ -2,6 +2,10 @@ import { LogLevel, LogLevel as LogLevel$1, Logger as Logger$1 } from "@logtape/l
2
2
 
3
3
  //#region src/mod.d.ts
4
4
 
5
+ /**
6
+ * Supported Drizzle Dialects
7
+ */
8
+ type DrizzleDialects = "pg" | "sqlite";
5
9
  /**
6
10
  * Options for configuring the Drizzle ORM LogTape logger.
7
11
  * @since 1.3.0
@@ -17,6 +21,11 @@ interface DrizzleLoggerOptions {
17
21
  * @default "debug"
18
22
  */
19
23
  readonly level?: LogLevel$1;
24
+ /**
25
+ * The dialect used for drizzle-orm
26
+ * @default "pg"
27
+ */
28
+ readonly dialect?: DrizzleDialects;
20
29
  }
21
30
  /**
22
31
  * Drizzle ORM's Logger interface.
@@ -48,8 +57,9 @@ declare class DrizzleLogger implements Logger {
48
57
  * Creates a new DrizzleLogger instance.
49
58
  * @param logger The LogTape logger to use.
50
59
  * @param level The log level to use for query logging.
60
+ * @param dialect The dialect used for drizzle-orm
51
61
  */
52
- constructor(logger: Logger$1, level?: LogLevel$1);
62
+ constructor(logger: Logger$1, level?: LogLevel$1, dialect?: DrizzleDialects);
53
63
  /**
54
64
  * Logs a database query with its parameters.
55
65
  *
@@ -68,18 +78,20 @@ declare class DrizzleLogger implements Logger {
68
78
  * Serializes a parameter value to a SQL-safe string representation.
69
79
  *
70
80
  * @param value The value to serialize.
81
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
71
82
  * @returns The serialized string representation.
72
83
  * @since 1.3.0
73
84
  */
74
- declare function serialize(value: unknown): string;
85
+ declare function serialize(value: unknown, dialect?: DrizzleDialects): string;
75
86
  /**
76
87
  * Converts a string to a SQL string literal with proper escaping.
77
88
  *
78
89
  * @param str The string to convert.
90
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
79
91
  * @returns The escaped SQL string literal.
80
92
  * @since 1.3.0
81
93
  */
82
- declare function stringLiteral(str: string): string;
94
+ declare function stringLiteral(str: string, dialect?: DrizzleDialects): string;
83
95
  /**
84
96
  * Creates a Drizzle ORM-compatible logger that wraps LogTape.
85
97
  *
@@ -117,5 +129,5 @@ declare function stringLiteral(str: string): string;
117
129
  declare function getLogger(options?: DrizzleLoggerOptions): DrizzleLogger;
118
130
  //# sourceMappingURL=mod.d.ts.map
119
131
  //#endregion
120
- export { DrizzleLogger, DrizzleLoggerOptions, LogLevel, Logger, getLogger, serialize, stringLiteral };
132
+ export { DrizzleDialects, DrizzleLogger, DrizzleLoggerOptions, LogLevel, Logger, getLogger, serialize, stringLiteral };
121
133
  //# sourceMappingURL=mod.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAYA;AAkBA;AAqBA;AAA2B,UAvCV,oBAAA,CAuCU;EAAA;;;AAAiB;EAiD5B,SAAA,QAAS,CAAA,EAAA,MAAA,GAAA,SAAA,MAAA,EAAA;EAyBT;AA0DhB;;;EAA4D,SAAG,KAAA,CAAA,EAhK5C,UAgK4C;AAAa;;;;;UAzJ3D,MAAA;;;;;;;;;;;;;;;;;;;;cAqBJ,aAAA,YAAyB;;;;;;;sBAShB,kBAAsB;;;;;;;;;;;;;;;;;;;;;;iBAwC5B,SAAA;;;;;;;;iBAyBA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0DA,SAAA,WAAmB,uBAA4B"}
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAWA;AAMA;AAAqC,KANzB,eAAA,GAMyB,IAAA,GAAA,QAAA;;;AAiBD;AAOpC;AAqBa,UA7CI,oBAAA,CA6CU;EAAA;;;;EAcQ,SAdG,QAAA,CAAA,EAAA,MAAA,GAAA,SAAA,MAAA,EAAA;EAAM;AA4E5C;AAgDA;AAqEA;EAAyB,SAAA,KAAA,CAAA,EAnON,UAmOM;EAAA;;AAAmD;;qBA7NvD;;;;;;UAOJ,MAAA;;;;;;;;;;;;;;;;;;;;cAqBJ,aAAA,YAAyB;;;;;;;;sBAY1B,kBACD,sBACE;;;;;;;;;;;;;;;;;;;;;;;iBA8DG,SAAA,2BAEL;;;;;;;;;iBA8CK,aAAA,wBAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmEK,SAAA,WAAmB,uBAA4B"}
package/dist/mod.d.ts CHANGED
@@ -2,6 +2,10 @@ import { LogLevel, LogLevel as LogLevel$1, Logger as Logger$1 } from "@logtape/l
2
2
 
3
3
  //#region src/mod.d.ts
4
4
 
5
+ /**
6
+ * Supported Drizzle Dialects
7
+ */
8
+ type DrizzleDialects = "pg" | "sqlite";
5
9
  /**
6
10
  * Options for configuring the Drizzle ORM LogTape logger.
7
11
  * @since 1.3.0
@@ -17,6 +21,11 @@ interface DrizzleLoggerOptions {
17
21
  * @default "debug"
18
22
  */
19
23
  readonly level?: LogLevel$1;
24
+ /**
25
+ * The dialect used for drizzle-orm
26
+ * @default "pg"
27
+ */
28
+ readonly dialect?: DrizzleDialects;
20
29
  }
21
30
  /**
22
31
  * Drizzle ORM's Logger interface.
@@ -48,8 +57,9 @@ declare class DrizzleLogger implements Logger {
48
57
  * Creates a new DrizzleLogger instance.
49
58
  * @param logger The LogTape logger to use.
50
59
  * @param level The log level to use for query logging.
60
+ * @param dialect The dialect used for drizzle-orm
51
61
  */
52
- constructor(logger: Logger$1, level?: LogLevel$1);
62
+ constructor(logger: Logger$1, level?: LogLevel$1, dialect?: DrizzleDialects);
53
63
  /**
54
64
  * Logs a database query with its parameters.
55
65
  *
@@ -68,18 +78,20 @@ declare class DrizzleLogger implements Logger {
68
78
  * Serializes a parameter value to a SQL-safe string representation.
69
79
  *
70
80
  * @param value The value to serialize.
81
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
71
82
  * @returns The serialized string representation.
72
83
  * @since 1.3.0
73
84
  */
74
- declare function serialize(value: unknown): string;
85
+ declare function serialize(value: unknown, dialect?: DrizzleDialects): string;
75
86
  /**
76
87
  * Converts a string to a SQL string literal with proper escaping.
77
88
  *
78
89
  * @param str The string to convert.
90
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
79
91
  * @returns The escaped SQL string literal.
80
92
  * @since 1.3.0
81
93
  */
82
- declare function stringLiteral(str: string): string;
94
+ declare function stringLiteral(str: string, dialect?: DrizzleDialects): string;
83
95
  /**
84
96
  * Creates a Drizzle ORM-compatible logger that wraps LogTape.
85
97
  *
@@ -117,5 +129,5 @@ declare function stringLiteral(str: string): string;
117
129
  declare function getLogger(options?: DrizzleLoggerOptions): DrizzleLogger;
118
130
  //# sourceMappingURL=mod.d.ts.map
119
131
  //#endregion
120
- export { DrizzleLogger, DrizzleLoggerOptions, LogLevel, Logger, getLogger, serialize, stringLiteral };
132
+ export { DrizzleDialects, DrizzleLogger, DrizzleLoggerOptions, LogLevel, Logger, getLogger, serialize, stringLiteral };
121
133
  //# sourceMappingURL=mod.d.ts.map
package/dist/mod.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAYA;AAkBA;AAqBA;AAA2B,UAvCV,oBAAA,CAuCU;EAAA;;;AAAiB;EAiD5B,SAAA,QAAS,CAAA,EAAA,MAAA,GAAA,SAAA,MAAA,EAAA;EAyBT;AA0DhB;;;EAA4D,SAAG,KAAA,CAAA,EAhK5C,UAgK4C;AAAa;;;;;UAzJ3D,MAAA;;;;;;;;;;;;;;;;;;;;cAqBJ,aAAA,YAAyB;;;;;;;sBAShB,kBAAsB;;;;;;;;;;;;;;;;;;;;;;iBAwC5B,SAAA;;;;;;;;iBAyBA,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0DA,SAAA,WAAmB,uBAA4B"}
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;AAWA;AAMA;AAAqC,KANzB,eAAA,GAMyB,IAAA,GAAA,QAAA;;;AAiBD;AAOpC;AAqBa,UA7CI,oBAAA,CA6CU;EAAA;;;;EAcQ,SAdG,QAAA,CAAA,EAAA,MAAA,GAAA,SAAA,MAAA,EAAA;EAAM;AA4E5C;AAgDA;AAqEA;EAAyB,SAAA,KAAA,CAAA,EAnON,UAmOM;EAAA;;AAAmD;;qBA7NvD;;;;;;UAOJ,MAAA;;;;;;;;;;;;;;;;;;;;cAqBJ,aAAA,YAAyB;;;;;;;;sBAY1B,kBACD,sBACE;;;;;;;;;;;;;;;;;;;;;;;iBA8DG,SAAA,2BAEL;;;;;;;;;iBA8CK,aAAA,wBAEL;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAmEK,SAAA,WAAmB,uBAA4B"}
package/dist/mod.js CHANGED
@@ -21,14 +21,17 @@ import { getLogger as getLogger$1 } from "@logtape/logtape";
21
21
  var DrizzleLogger = class {
22
22
  #logger;
23
23
  #level;
24
+ #dialect;
24
25
  /**
25
26
  * Creates a new DrizzleLogger instance.
26
27
  * @param logger The LogTape logger to use.
27
28
  * @param level The log level to use for query logging.
29
+ * @param dialect The dialect used for drizzle-orm
28
30
  */
29
- constructor(logger, level = "debug") {
31
+ constructor(logger, level = "debug", dialect = "pg") {
30
32
  this.#logger = logger;
31
33
  this.#level = level;
34
+ this.#dialect = dialect;
32
35
  }
33
36
  /**
34
37
  * Logs a database query with its parameters.
@@ -43,11 +46,26 @@ var DrizzleLogger = class {
43
46
  * @param params The parameter values.
44
47
  */
45
48
  logQuery(query, params) {
46
- const stringifiedParams = params.map(serialize);
47
- const formattedQuery = query.replace(/\$(\d+)/g, (match) => {
48
- const index = Number.parseInt(match.slice(1), 10);
49
- return stringifiedParams[index - 1] ?? match;
50
- });
49
+ const stringifiedParams = params.map((param) => serialize(param, this.#dialect));
50
+ let formattedQuery;
51
+ switch (this.#dialect) {
52
+ case "pg": {
53
+ formattedQuery = query.replace(/\$(\d+)/g, (match) => {
54
+ const index = Number.parseInt(match.slice(1), 10);
55
+ return stringifiedParams[index - 1] ?? match;
56
+ });
57
+ break;
58
+ }
59
+ case "sqlite": {
60
+ let index = -1;
61
+ formattedQuery = query.replace(/\?/g, (match) => {
62
+ index += 1;
63
+ return stringifiedParams[index] ?? match;
64
+ });
65
+ break;
66
+ }
67
+ default: throw new Error(`${this.#dialect} is not supported`);
68
+ }
51
69
  const logMethod = this.#logger[this.#level].bind(this.#logger);
52
70
  logMethod("Query: {formattedQuery}", {
53
71
  formattedQuery,
@@ -60,39 +78,55 @@ var DrizzleLogger = class {
60
78
  * Serializes a parameter value to a SQL-safe string representation.
61
79
  *
62
80
  * @param value The value to serialize.
81
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
63
82
  * @returns The serialized string representation.
64
83
  * @since 1.3.0
65
84
  */
66
- function serialize(value) {
85
+ function serialize(value, dialect = "pg") {
67
86
  if (typeof value === "undefined" || value === null) return "NULL";
68
- if (typeof value === "string") return stringLiteral(value);
87
+ if (typeof value === "string") return stringLiteral(value, dialect);
69
88
  if (typeof value === "number" || typeof value === "bigint") return value.toString();
70
- if (typeof value === "boolean") return value ? "'t'" : "'f'";
71
- if (value instanceof Date) return stringLiteral(value.toISOString());
72
- if (Array.isArray(value)) return `ARRAY[${value.map(serialize).join(", ")}]`;
73
- if (typeof value === "object") return stringLiteral(JSON.stringify(value));
74
- return stringLiteral(String(value));
89
+ if (typeof value === "boolean") switch (dialect) {
90
+ case "sqlite": return value ? "1" : "0";
91
+ case "pg": return value ? "'t'" : "'f'";
92
+ default: throw new Error(`${dialect} is not supported`);
93
+ }
94
+ if (value instanceof Date) return stringLiteral(value.toISOString(), dialect);
95
+ if (Array.isArray(value)) switch (dialect) {
96
+ case "sqlite": return stringLiteral(JSON.stringify(value), dialect);
97
+ case "pg": return `ARRAY[${value.map((item) => serialize(item, dialect)).join(", ")}]`;
98
+ default: throw new Error(`${dialect} is not supported`);
99
+ }
100
+ if (typeof value === "object") return stringLiteral(JSON.stringify(value), dialect);
101
+ return stringLiteral(String(value), dialect);
75
102
  }
76
103
  /**
77
104
  * Converts a string to a SQL string literal with proper escaping.
78
105
  *
79
106
  * @param str The string to convert.
107
+ * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.
80
108
  * @returns The escaped SQL string literal.
81
109
  * @since 1.3.0
82
110
  */
83
- function stringLiteral(str) {
84
- if (/[\\'\n\r\t\b\f]/.test(str)) {
85
- let escaped = str;
86
- escaped = escaped.replaceAll("\\", "\\\\");
87
- escaped = escaped.replaceAll("'", "\\'");
88
- escaped = escaped.replaceAll("\n", "\\n");
89
- escaped = escaped.replaceAll("\r", "\\r");
90
- escaped = escaped.replaceAll(" ", "\\t");
91
- escaped = escaped.replaceAll("\b", "\\b");
92
- escaped = escaped.replaceAll("\f", "\\f");
93
- return `E'${escaped}'`;
111
+ function stringLiteral(str, dialect = "pg") {
112
+ switch (dialect) {
113
+ case "sqlite": return `'${str.replaceAll("'", "''")}'`;
114
+ case "pg": {
115
+ if (/[\\'\n\r\t\b\f]/.test(str)) {
116
+ let escaped = str;
117
+ escaped = escaped.replaceAll("\\", "\\\\");
118
+ escaped = escaped.replaceAll("'", "\\'");
119
+ escaped = escaped.replaceAll("\n", "\\n");
120
+ escaped = escaped.replaceAll("\r", "\\r");
121
+ escaped = escaped.replaceAll(" ", "\\t");
122
+ escaped = escaped.replaceAll("\b", "\\b");
123
+ escaped = escaped.replaceAll("\f", "\\f");
124
+ return `E'${escaped}'`;
125
+ }
126
+ return `'${str}'`;
127
+ }
128
+ default: throw new Error(`${dialect} is not supported`);
94
129
  }
95
- return `'${str}'`;
96
130
  }
97
131
  /**
98
132
  * Normalize category to array format.
@@ -137,7 +171,7 @@ function normalizeCategory(category) {
137
171
  function getLogger(options = {}) {
138
172
  const category = normalizeCategory(options.category ?? ["drizzle-orm"]);
139
173
  const logger = getLogger$1(category);
140
- return new DrizzleLogger(logger, options.level ?? "debug");
174
+ return new DrizzleLogger(logger, options.level ?? "debug", options.dialect ?? "pg");
141
175
  }
142
176
 
143
177
  //#endregion
package/dist/mod.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mod.js","names":["#logger","#level","logger: LogTapeLogger","level: LogLevel","query: string","params: unknown[]","value: unknown","str: string","category: string | readonly string[]","options: DrizzleLoggerOptions"],"sources":["../src/mod.ts"],"sourcesContent":["import {\n getLogger as getLogTapeLogger,\n type Logger as LogTapeLogger,\n type LogLevel,\n} from \"@logtape/logtape\";\n\nexport type { LogLevel } from \"@logtape/logtape\";\n\n/**\n * Options for configuring the Drizzle ORM LogTape logger.\n * @since 1.3.0\n */\nexport interface DrizzleLoggerOptions {\n /**\n * The LogTape category to use for logging.\n * @default [\"drizzle-orm\"]\n */\n readonly category?: string | readonly string[];\n\n /**\n * The log level to use for query logging.\n * @default \"debug\"\n */\n readonly level?: LogLevel;\n}\n\n/**\n * Drizzle ORM's Logger interface.\n * @since 1.3.0\n */\nexport interface Logger {\n logQuery(query: string, params: unknown[]): void;\n}\n\n/**\n * A Drizzle ORM-compatible logger that wraps LogTape.\n *\n * @example\n * ```typescript\n * import { drizzle } from \"drizzle-orm/postgres-js\";\n * import { getLogger } from \"@logtape/drizzle-orm\";\n * import postgres from \"postgres\";\n *\n * const client = postgres(process.env.DATABASE_URL!);\n * const db = drizzle(client, {\n * logger: getLogger(),\n * });\n * ```\n *\n * @since 1.3.0\n */\nexport class DrizzleLogger implements Logger {\n readonly #logger: LogTapeLogger;\n readonly #level: LogLevel;\n\n /**\n * Creates a new DrizzleLogger instance.\n * @param logger The LogTape logger to use.\n * @param level The log level to use for query logging.\n */\n constructor(logger: LogTapeLogger, level: LogLevel = \"debug\") {\n this.#logger = logger;\n this.#level = level;\n }\n\n /**\n * Logs a database query with its parameters.\n *\n * The log output includes:\n * - `formattedQuery`: The query with parameter placeholders replaced with\n * actual values (for readability)\n * - `query`: The original query string with placeholders\n * - `params`: The original parameters array\n *\n * @param query The SQL query string with parameter placeholders.\n * @param params The parameter values.\n */\n logQuery(query: string, params: unknown[]): void {\n const stringifiedParams = params.map(serialize);\n const formattedQuery = query.replace(/\\$(\\d+)/g, (match) => {\n const index = Number.parseInt(match.slice(1), 10);\n return stringifiedParams[index - 1] ?? match;\n });\n\n const logMethod = this.#logger[this.#level].bind(this.#logger);\n logMethod(\"Query: {formattedQuery}\", {\n formattedQuery,\n query,\n params,\n });\n }\n}\n\n/**\n * Serializes a parameter value to a SQL-safe string representation.\n *\n * @param value The value to serialize.\n * @returns The serialized string representation.\n * @since 1.3.0\n */\nexport function serialize(value: unknown): string {\n if (typeof value === \"undefined\" || value === null) return \"NULL\";\n if (typeof value === \"string\") return stringLiteral(value);\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return value.toString();\n }\n if (typeof value === \"boolean\") return value ? \"'t'\" : \"'f'\";\n if (value instanceof Date) return stringLiteral(value.toISOString());\n if (Array.isArray(value)) {\n return `ARRAY[${value.map(serialize).join(\", \")}]`;\n }\n if (typeof value === \"object\") {\n // Assume it's a JSON object\n return stringLiteral(JSON.stringify(value));\n }\n return stringLiteral(String(value));\n}\n\n/**\n * Converts a string to a SQL string literal with proper escaping.\n *\n * @param str The string to convert.\n * @returns The escaped SQL string literal.\n * @since 1.3.0\n */\nexport function stringLiteral(str: string): string {\n if (/[\\\\'\\n\\r\\t\\b\\f]/.test(str)) {\n let escaped = str;\n escaped = escaped.replaceAll(\"\\\\\", \"\\\\\\\\\");\n escaped = escaped.replaceAll(\"'\", \"\\\\'\");\n escaped = escaped.replaceAll(\"\\n\", \"\\\\n\");\n escaped = escaped.replaceAll(\"\\r\", \"\\\\r\");\n escaped = escaped.replaceAll(\"\\t\", \"\\\\t\");\n escaped = escaped.replaceAll(\"\\b\", \"\\\\b\");\n escaped = escaped.replaceAll(\"\\f\", \"\\\\f\");\n return `E'${escaped}'`;\n }\n return `'${str}'`;\n}\n\n/**\n * Normalize category to array format.\n */\nfunction normalizeCategory(\n category: string | readonly string[],\n): readonly string[] {\n return typeof category === \"string\" ? [category] : category;\n}\n\n/**\n * Creates a Drizzle ORM-compatible logger that wraps LogTape.\n *\n * @example Basic usage\n * ```typescript\n * import { drizzle } from \"drizzle-orm/postgres-js\";\n * import { configure } from \"@logtape/logtape\";\n * import { getLogger } from \"@logtape/drizzle-orm\";\n * import postgres from \"postgres\";\n *\n * await configure({\n * // ... LogTape configuration\n * });\n *\n * const client = postgres(process.env.DATABASE_URL!);\n * const db = drizzle(client, {\n * logger: getLogger(),\n * });\n * ```\n *\n * @example With custom category and level\n * ```typescript\n * const db = drizzle(client, {\n * logger: getLogger({\n * category: [\"my-app\", \"database\"],\n * level: \"info\",\n * }),\n * });\n * ```\n *\n * @param options Configuration options for the logger.\n * @returns A Drizzle ORM-compatible logger wrapping LogTape.\n * @since 1.3.0\n */\nexport function getLogger(options: DrizzleLoggerOptions = {}): DrizzleLogger {\n const category = normalizeCategory(options.category ?? [\"drizzle-orm\"]);\n const logger = getLogTapeLogger(category);\n return new DrizzleLogger(logger, options.level ?? \"debug\");\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAmDA,IAAa,gBAAb,MAA6C;CAC3C,AAASA;CACT,AAASC;;;;;;CAOT,YAAYC,QAAuBC,QAAkB,SAAS;AAC5D,OAAKH,UAAU;AACf,OAAKC,SAAS;CACf;;;;;;;;;;;;;CAcD,SAASG,OAAeC,QAAyB;EAC/C,MAAM,oBAAoB,OAAO,IAAI,UAAU;EAC/C,MAAM,iBAAiB,MAAM,QAAQ,YAAY,CAAC,UAAU;GAC1D,MAAM,QAAQ,OAAO,SAAS,MAAM,MAAM,EAAE,EAAE,GAAG;AACjD,UAAO,kBAAkB,QAAQ,MAAM;EACxC,EAAC;EAEF,MAAM,YAAY,KAAKL,QAAQ,KAAKC,QAAQ,KAAK,KAAKD,QAAQ;AAC9D,YAAU,2BAA2B;GACnC;GACA;GACA;EACD,EAAC;CACH;AACF;;;;;;;;AASD,SAAgB,UAAUM,OAAwB;AAChD,YAAW,UAAU,eAAe,UAAU,KAAM,QAAO;AAC3D,YAAW,UAAU,SAAU,QAAO,cAAc,MAAM;AAC1D,YAAW,UAAU,mBAAmB,UAAU,SAChD,QAAO,MAAM,UAAU;AAEzB,YAAW,UAAU,UAAW,QAAO,QAAQ,QAAQ;AACvD,KAAI,iBAAiB,KAAM,QAAO,cAAc,MAAM,aAAa,CAAC;AACpE,KAAI,MAAM,QAAQ,MAAM,CACtB,SAAQ,QAAQ,MAAM,IAAI,UAAU,CAAC,KAAK,KAAK,CAAC;AAElD,YAAW,UAAU,SAEnB,QAAO,cAAc,KAAK,UAAU,MAAM,CAAC;AAE7C,QAAO,cAAc,OAAO,MAAM,CAAC;AACpC;;;;;;;;AASD,SAAgB,cAAcC,KAAqB;AACjD,KAAI,kBAAkB,KAAK,IAAI,EAAE;EAC/B,IAAI,UAAU;AACd,YAAU,QAAQ,WAAW,MAAM,OAAO;AAC1C,YAAU,QAAQ,WAAW,KAAK,MAAM;AACxC,YAAU,QAAQ,WAAW,MAAM,MAAM;AACzC,YAAU,QAAQ,WAAW,MAAM,MAAM;AACzC,YAAU,QAAQ,WAAW,KAAM,MAAM;AACzC,YAAU,QAAQ,WAAW,MAAM,MAAM;AACzC,YAAU,QAAQ,WAAW,MAAM,MAAM;AACzC,UAAQ,IAAI,QAAQ;CACrB;AACD,SAAQ,GAAG,IAAI;AAChB;;;;AAKD,SAAS,kBACPC,UACmB;AACnB,eAAc,aAAa,WAAW,CAAC,QAAS,IAAG;AACpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCD,SAAgB,UAAUC,UAAgC,CAAE,GAAiB;CAC3E,MAAM,WAAW,kBAAkB,QAAQ,YAAY,CAAC,aAAc,EAAC;CACvE,MAAM,SAAS,YAAiB,SAAS;AACzC,QAAO,IAAI,cAAc,QAAQ,QAAQ,SAAS;AACnD"}
1
+ {"version":3,"file":"mod.js","names":["#logger","#level","#dialect","logger: LogTapeLogger","level: LogLevel","dialect: DrizzleDialects","query: string","params: unknown[]","formattedQuery: string","value: unknown","str: string","category: string | readonly string[]","options: DrizzleLoggerOptions"],"sources":["../src/mod.ts"],"sourcesContent":["import {\n getLogger as getLogTapeLogger,\n type Logger as LogTapeLogger,\n type LogLevel,\n} from \"@logtape/logtape\";\n\nexport type { LogLevel } from \"@logtape/logtape\";\n\n/**\n * Supported Drizzle Dialects\n */\nexport type DrizzleDialects = \"pg\" | \"sqlite\";\n\n/**\n * Options for configuring the Drizzle ORM LogTape logger.\n * @since 1.3.0\n */\nexport interface DrizzleLoggerOptions {\n /**\n * The LogTape category to use for logging.\n * @default [\"drizzle-orm\"]\n */\n readonly category?: string | readonly string[];\n\n /**\n * The log level to use for query logging.\n * @default \"debug\"\n */\n readonly level?: LogLevel;\n\n /**\n * The dialect used for drizzle-orm\n * @default \"pg\"\n */\n readonly dialect?: DrizzleDialects;\n}\n\n/**\n * Drizzle ORM's Logger interface.\n * @since 1.3.0\n */\nexport interface Logger {\n logQuery(query: string, params: unknown[]): void;\n}\n\n/**\n * A Drizzle ORM-compatible logger that wraps LogTape.\n *\n * @example\n * ```typescript\n * import { drizzle } from \"drizzle-orm/postgres-js\";\n * import { getLogger } from \"@logtape/drizzle-orm\";\n * import postgres from \"postgres\";\n *\n * const client = postgres(process.env.DATABASE_URL!);\n * const db = drizzle(client, {\n * logger: getLogger(),\n * });\n * ```\n *\n * @since 1.3.0\n */\nexport class DrizzleLogger implements Logger {\n readonly #logger: LogTapeLogger;\n readonly #level: LogLevel;\n readonly #dialect: DrizzleDialects;\n\n /**\n * Creates a new DrizzleLogger instance.\n * @param logger The LogTape logger to use.\n * @param level The log level to use for query logging.\n * @param dialect The dialect used for drizzle-orm\n */\n constructor(\n logger: LogTapeLogger,\n level: LogLevel = \"debug\",\n dialect: DrizzleDialects = \"pg\",\n ) {\n this.#logger = logger;\n this.#level = level;\n this.#dialect = dialect;\n }\n\n /**\n * Logs a database query with its parameters.\n *\n * The log output includes:\n * - `formattedQuery`: The query with parameter placeholders replaced with\n * actual values (for readability)\n * - `query`: The original query string with placeholders\n * - `params`: The original parameters array\n *\n * @param query The SQL query string with parameter placeholders.\n * @param params The parameter values.\n */\n logQuery(query: string, params: unknown[]): void {\n const stringifiedParams = params.map((param) =>\n serialize(param, this.#dialect)\n );\n let formattedQuery: string;\n switch (this.#dialect) {\n case \"pg\": {\n formattedQuery = query.replace(/\\$(\\d+)/g, (match) => {\n const index = Number.parseInt(match.slice(1), 10);\n return stringifiedParams[index - 1] ?? match;\n });\n break;\n }\n case \"sqlite\": {\n let index = -1;\n formattedQuery = query.replace(/\\?/g, (match) => {\n index += 1;\n return stringifiedParams[index] ?? match;\n });\n break;\n }\n default: {\n throw new Error(`${this.#dialect satisfies never} is not supported`);\n }\n }\n\n const logMethod = this.#logger[this.#level].bind(this.#logger);\n logMethod(\"Query: {formattedQuery}\", {\n formattedQuery,\n query,\n params,\n });\n }\n}\n\n/**\n * Serializes a parameter value to a SQL-safe string representation.\n *\n * @param value The value to serialize.\n * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.\n * @returns The serialized string representation.\n * @since 1.3.0\n */\nexport function serialize(\n value: unknown,\n dialect: DrizzleDialects = \"pg\",\n): string {\n if (typeof value === \"undefined\" || value === null) return \"NULL\";\n if (typeof value === \"string\") return stringLiteral(value, dialect);\n if (typeof value === \"number\" || typeof value === \"bigint\") {\n return value.toString();\n }\n if (typeof value === \"boolean\") {\n switch (dialect) {\n case \"sqlite\":\n return value ? \"1\" : \"0\";\n case \"pg\":\n return value ? \"'t'\" : \"'f'\";\n default:\n throw new Error(`${dialect satisfies never} is not supported`);\n }\n }\n if (value instanceof Date) {\n return stringLiteral(value.toISOString(), dialect);\n }\n if (Array.isArray(value)) {\n switch (dialect) {\n case \"sqlite\":\n return stringLiteral(JSON.stringify(value), dialect);\n case \"pg\":\n return `ARRAY[${\n value.map((item) => serialize(item, dialect)).join(\", \")\n }]`;\n default:\n throw new Error(`${dialect satisfies never} is not supported`);\n }\n }\n if (typeof value === \"object\") {\n return stringLiteral(JSON.stringify(value), dialect);\n }\n return stringLiteral(String(value), dialect);\n}\n\n/**\n * Converts a string to a SQL string literal with proper escaping.\n *\n * @param str The string to convert.\n * @param dialect The SQL dialect to format for. Defaults to PostgreSQL.\n * @returns The escaped SQL string literal.\n * @since 1.3.0\n */\nexport function stringLiteral(\n str: string,\n dialect: DrizzleDialects = \"pg\",\n): string {\n switch (dialect) {\n case \"sqlite\":\n return `'${str.replaceAll(\"'\", \"''\")}'`;\n case \"pg\": {\n if (/[\\\\'\\n\\r\\t\\b\\f]/.test(str)) {\n let escaped = str;\n escaped = escaped.replaceAll(\"\\\\\", \"\\\\\\\\\");\n escaped = escaped.replaceAll(\"'\", \"\\\\'\");\n escaped = escaped.replaceAll(\"\\n\", \"\\\\n\");\n escaped = escaped.replaceAll(\"\\r\", \"\\\\r\");\n escaped = escaped.replaceAll(\"\\t\", \"\\\\t\");\n escaped = escaped.replaceAll(\"\\b\", \"\\\\b\");\n escaped = escaped.replaceAll(\"\\f\", \"\\\\f\");\n return `E'${escaped}'`;\n }\n return `'${str}'`;\n }\n default:\n throw new Error(`${dialect satisfies never} is not supported`);\n }\n}\n\n/**\n * Normalize category to array format.\n */\nfunction normalizeCategory(\n category: string | readonly string[],\n): readonly string[] {\n return typeof category === \"string\" ? [category] : category;\n}\n\n/**\n * Creates a Drizzle ORM-compatible logger that wraps LogTape.\n *\n * @example Basic usage\n * ```typescript\n * import { drizzle } from \"drizzle-orm/postgres-js\";\n * import { configure } from \"@logtape/logtape\";\n * import { getLogger } from \"@logtape/drizzle-orm\";\n * import postgres from \"postgres\";\n *\n * await configure({\n * // ... LogTape configuration\n * });\n *\n * const client = postgres(process.env.DATABASE_URL!);\n * const db = drizzle(client, {\n * logger: getLogger(),\n * });\n * ```\n *\n * @example With custom category and level\n * ```typescript\n * const db = drizzle(client, {\n * logger: getLogger({\n * category: [\"my-app\", \"database\"],\n * level: \"info\",\n * }),\n * });\n * ```\n *\n * @param options Configuration options for the logger.\n * @returns A Drizzle ORM-compatible logger wrapping LogTape.\n * @since 1.3.0\n */\nexport function getLogger(options: DrizzleLoggerOptions = {}): DrizzleLogger {\n const category = normalizeCategory(options.category ?? [\"drizzle-orm\"]);\n const logger = getLogTapeLogger(category);\n return new DrizzleLogger(\n logger,\n options.level ?? \"debug\",\n options.dialect ?? \"pg\",\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logtape/drizzle-orm",
3
- "version": "2.2.0-dev.620+455a47e2",
3
+ "version": "2.2.0-dev.626+7dce7b35",
4
4
  "description": "Drizzle ORM adapter for LogTape logging library",
5
5
  "keywords": [
6
6
  "logging",
@@ -52,7 +52,7 @@
52
52
  "dist/"
53
53
  ],
54
54
  "peerDependencies": {
55
- "@logtape/logtape": "^2.2.0-dev.620+455a47e2"
55
+ "@logtape/logtape": "^2.2.0-dev.626+7dce7b35"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@alinea/suite": "^0.6.3",