@nest-native/drizzle 0.3.2 → 0.5.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.
@@ -2,9 +2,57 @@ export interface DrizzleErrorMappingOptions {
2
2
  uniqueMessage?: string;
3
3
  foreignKeyMessage?: string;
4
4
  notNullMessage?: string;
5
+ checkMessage?: string;
5
6
  fallbackMessage?: string;
6
7
  }
8
+ /** The constraint families this package recognises across all supported drivers. */
9
+ export declare const DRIZZLE_VIOLATION_KINDS: readonly ["unique", "foreignKey", "notNull", "check"];
10
+ export type DrizzleViolationKind = (typeof DRIZZLE_VIOLATION_KINDS)[number];
11
+ /**
12
+ * What a failed write actually said, normalised across drivers.
13
+ *
14
+ * Drizzle wraps driver errors (`DrizzleQueryError`) and the useful parts —
15
+ * SQLSTATE, the constraint name, the offending column — end up nested on
16
+ * `cause` in a driver-specific shape. This is that information, flattened, so a
17
+ * caller can build a field-level response without re-parsing the driver error.
18
+ *
19
+ * Everything except `kind` is **best-effort**: drivers disagree about what they
20
+ * report, so `table`/`constraint`/`column` are populated when the driver
21
+ * volunteers them and left `undefined` otherwise. Never branch on their
22
+ * presence for correctness — branch on `kind`.
23
+ */
24
+ export interface DrizzleViolation {
25
+ kind: DrizzleViolationKind;
26
+ /** The raw driver code that identified it (`'23505'`, `'ER_DUP_ENTRY'`, …). */
27
+ code: string;
28
+ table?: string;
29
+ constraint?: string;
30
+ /**
31
+ * The offending column, when the driver names it. `pg` does not, so this is
32
+ * typically only present on MySQL/SQLite; deriving it from the constraint
33
+ * name is deliberately NOT attempted (see the note in `readColumn`).
34
+ */
35
+ column?: string;
36
+ /** The driver's own detail line, when it has one. */
37
+ detail?: string;
38
+ }
39
+ /**
40
+ * Maps a Drizzle/driver error to the Nest exception that fits it, or returns
41
+ * the error unchanged when it is not a constraint violation.
42
+ *
43
+ * This is opt-in by design — the package never installs global error mapping
44
+ * for you. Call it in a `catch`, or register {@link DrizzleExceptionFilter} if
45
+ * you would rather stop writing `catch` blocks.
46
+ */
7
47
  export declare function mapDrizzleError(error: unknown, options?: DrizzleErrorMappingOptions): Error;
48
+ /**
49
+ * The structured view of a constraint violation, or `undefined` when the error
50
+ * is not one. Use it when the Nest exception alone is not enough — building a
51
+ * `{ field: message }` response, deciding which retry to attempt, or logging
52
+ * the constraint that actually fired.
53
+ */
54
+ export declare function describeDrizzleError(error: unknown): DrizzleViolation | undefined;
8
55
  export declare function isUniqueConstraintError(error: unknown): boolean;
9
56
  export declare function isForeignKeyConstraintError(error: unknown): boolean;
10
57
  export declare function isNotNullConstraintError(error: unknown): boolean;
58
+ export declare function isCheckConstraintError(error: unknown): boolean;
@@ -1,52 +1,126 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DRIZZLE_VIOLATION_KINDS = void 0;
3
4
  exports.mapDrizzleError = mapDrizzleError;
5
+ exports.describeDrizzleError = describeDrizzleError;
4
6
  exports.isUniqueConstraintError = isUniqueConstraintError;
5
7
  exports.isForeignKeyConstraintError = isForeignKeyConstraintError;
6
8
  exports.isNotNullConstraintError = isNotNullConstraintError;
9
+ exports.isCheckConstraintError = isCheckConstraintError;
7
10
  const common_1 = require("@nestjs/common");
11
+ /** The constraint families this package recognises across all supported drivers. */
12
+ exports.DRIZZLE_VIOLATION_KINDS = [
13
+ 'unique',
14
+ 'foreignKey',
15
+ 'notNull',
16
+ 'check',
17
+ ];
18
+ const CODES = {
19
+ unique: ['23505', 'ER_DUP_ENTRY', '1062', 'SQLITE_CONSTRAINT_UNIQUE', 'SQLITE_CONSTRAINT_PRIMARYKEY'],
20
+ foreignKey: ['23503', 'ER_NO_REFERENCED_ROW_2', '1452', 'SQLITE_CONSTRAINT_FOREIGNKEY'],
21
+ notNull: ['23502', 'ER_BAD_NULL_ERROR', '1048', 'SQLITE_CONSTRAINT_NOTNULL'],
22
+ check: ['23514', 'ER_CHECK_CONSTRAINT_VIOLATED', '3819', 'SQLITE_CONSTRAINT_CHECK'],
23
+ };
24
+ /**
25
+ * Maps a Drizzle/driver error to the Nest exception that fits it, or returns
26
+ * the error unchanged when it is not a constraint violation.
27
+ *
28
+ * This is opt-in by design — the package never installs global error mapping
29
+ * for you. Call it in a `catch`, or register {@link DrizzleExceptionFilter} if
30
+ * you would rather stop writing `catch` blocks.
31
+ */
8
32
  function mapDrizzleError(error, options = {}) {
9
- if (isUniqueConstraintError(error)) {
33
+ const violation = describeDrizzleError(error);
34
+ if (violation?.kind === 'unique') {
10
35
  return new common_1.ConflictException(options.uniqueMessage ?? 'Resource already exists.');
11
36
  }
12
- if (isForeignKeyConstraintError(error)) {
37
+ if (violation?.kind === 'foreignKey') {
13
38
  return new common_1.BadRequestException(options.foreignKeyMessage ?? 'Related resource does not exist.');
14
39
  }
15
- if (isNotNullConstraintError(error)) {
40
+ if (violation?.kind === 'notNull') {
16
41
  return new common_1.BadRequestException(options.notNullMessage ?? 'Required value is missing.');
17
42
  }
43
+ if (violation?.kind === 'check') {
44
+ return new common_1.BadRequestException(options.checkMessage ?? 'Value violates a database constraint.');
45
+ }
18
46
  return error instanceof Error
19
47
  ? error
20
48
  : new common_1.InternalServerErrorException(options.fallbackMessage ?? 'Database operation failed.');
21
49
  }
50
+ /**
51
+ * The structured view of a constraint violation, or `undefined` when the error
52
+ * is not one. Use it when the Nest exception alone is not enough — building a
53
+ * `{ field: message }` response, deciding which retry to attempt, or logging
54
+ * the constraint that actually fired.
55
+ */
56
+ function describeDrizzleError(error) {
57
+ const chain = collectErrorChain(error);
58
+ for (const kind of exports.DRIZZLE_VIOLATION_KINDS) {
59
+ const match = chain.find((link) => link.codes.some((code) => CODES[kind].includes(code)));
60
+ if (match) {
61
+ return {
62
+ kind,
63
+ code: match.codes[0],
64
+ ...pickDefined('table', readString(match.source, ['table', 'table_name'])),
65
+ ...pickDefined('constraint', readString(match.source, ['constraint', 'constraint_name'])),
66
+ ...pickDefined('column', readColumn(match.source)),
67
+ ...pickDefined('detail', readString(match.source, ['detail', 'sqlMessage'])),
68
+ };
69
+ }
70
+ }
71
+ return undefined;
72
+ }
22
73
  function isUniqueConstraintError(error) {
23
- return errorHasAnyCode(error, ['23505', 'ER_DUP_ENTRY', 'SQLITE_CONSTRAINT_UNIQUE']);
74
+ return describeDrizzleError(error)?.kind === 'unique';
24
75
  }
25
76
  function isForeignKeyConstraintError(error) {
26
- return errorHasAnyCode(error, ['23503', 'ER_NO_REFERENCED_ROW_2', 'SQLITE_CONSTRAINT_FOREIGNKEY']);
77
+ return describeDrizzleError(error)?.kind === 'foreignKey';
27
78
  }
28
79
  function isNotNullConstraintError(error) {
29
- return errorHasAnyCode(error, ['23502', 'ER_BAD_NULL_ERROR', 'SQLITE_CONSTRAINT_NOTNULL']);
80
+ return describeDrizzleError(error)?.kind === 'notNull';
30
81
  }
31
- function errorHasAnyCode(error, expectedCodes) {
32
- const codes = collectErrorCodes(error);
33
- return codes.some(code => expectedCodes.includes(code));
82
+ function isCheckConstraintError(error) {
83
+ return describeDrizzleError(error)?.kind === 'check';
34
84
  }
35
- function collectErrorCodes(error) {
85
+ /**
86
+ * Every error in the `cause` chain that carries an identifying code, nearest
87
+ * first. Walking the chain matters because Drizzle wraps driver errors: the
88
+ * SQLSTATE lives on `error.cause`, and adapters sometimes wrap once more.
89
+ */
90
+ function collectErrorChain(error) {
36
91
  if (typeof error !== 'object' || error === null) {
37
92
  return [];
38
93
  }
39
- const maybeError = error;
40
- const currentCodes = [
41
- maybeError.code,
42
- maybeError.errno,
43
- maybeError.extendedCode,
44
- ]
94
+ const source = error;
95
+ const codes = [source.code, source.errno, source.extendedCode]
45
96
  .filter((code) => typeof code === 'string' || typeof code === 'number')
46
- .map(code => String(code));
47
- return [
48
- ...currentCodes,
49
- ...collectErrorCodes(maybeError.cause),
50
- ];
97
+ .map(String);
98
+ const here = codes.length > 0 ? [{ source, codes }] : [];
99
+ return [...here, ...collectErrorChain(source.cause)];
100
+ }
101
+ /**
102
+ * The offending column, only when the driver actually names it.
103
+ *
104
+ * Deliberately does NOT infer the column from the constraint name: that only
105
+ * works for drizzle-kit's generated naming and is silently wrong on
106
+ * hand-written migrations, renamed constraints, legacy schemas, and composite
107
+ * or expression indexes. A wrong field name in a validation response is worse
108
+ * than no field name.
109
+ */
110
+ function readColumn(source) {
111
+ return readString(source, ['column', 'column_name']);
112
+ }
113
+ function readString(source, keys) {
114
+ for (const key of keys) {
115
+ const value = source[key];
116
+ if (typeof value === 'string' && value.length > 0) {
117
+ return value;
118
+ }
119
+ }
120
+ return undefined;
121
+ }
122
+ /** Keeps optional keys absent rather than explicitly `undefined`. */
123
+ function pickDefined(key, value) {
124
+ return value === undefined ? {} : { [key]: value };
51
125
  }
52
126
  //# sourceMappingURL=drizzle-error.mapper.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-error.mapper.js","sourceRoot":"","sources":["../../errors/drizzle-error.mapper.ts"],"names":[],"mappings":";;AAaA,0CA2BC;AAED,0DAEC;AAED,kEAEC;AAED,4DAEC;AApDD,2CAIwB;AASxB,SAAgB,eAAe,CAC7B,KAAc,EACd,UAAsC,EAAE;IAExC,IAAI,uBAAuB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,IAAI,0BAAiB,CAC1B,OAAO,CAAC,aAAa,IAAI,0BAA0B,CACpD,CAAC;IACJ,CAAC;IAED,IAAI,2BAA2B,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,IAAI,4BAAmB,CAC5B,OAAO,CAAC,iBAAiB,IAAI,kCAAkC,CAChE,CAAC;IACJ,CAAC;IAED,IAAI,wBAAwB,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,IAAI,4BAAmB,CAC5B,OAAO,CAAC,cAAc,IAAI,4BAA4B,CACvD,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,YAAY,KAAK;QAC3B,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,IAAI,qCAA4B,CAChC,OAAO,CAAC,eAAe,IAAI,4BAA4B,CACxD,CAAC;AACN,CAAC;AAED,SAAgB,uBAAuB,CAAC,KAAc;IACpD,OAAO,eAAe,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,0BAA0B,CAAC,CAAC,CAAC;AACvF,CAAC;AAED,SAAgB,2BAA2B,CAAC,KAAc;IACxD,OAAO,eAAe,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,wBAAwB,EAAE,8BAA8B,CAAC,CAAC,CAAC;AACrG,CAAC;AAED,SAAgB,wBAAwB,CAAC,KAAc;IACrD,OAAO,eAAe,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,CAAC,CAAC,CAAC;AAC7F,CAAC;AAED,SAAS,eAAe,CAAC,KAAc,EAAE,aAAuB;IAC9D,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAG,KAAgC,CAAC;IACpD,MAAM,YAAY,GAAG;QACnB,UAAU,CAAC,IAAI;QACf,UAAU,CAAC,KAAK;QAChB,UAAU,CAAC,YAAY;KACxB;SACE,MAAM,CAAC,CAAC,IAAI,EAA2B,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC;SAC/F,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAE7B,OAAO;QACL,GAAG,YAAY;QACf,GAAG,iBAAiB,CAAC,UAAU,CAAC,KAAK,CAAC;KACvC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"drizzle-error.mapper.js","sourceRoot":"","sources":["../../errors/drizzle-error.mapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { type ArgumentsHost, type ExceptionFilter } from '@nestjs/common';
2
+ import { BaseExceptionFilter } from '@nestjs/core';
3
+ import { type DrizzleErrorMappingOptions } from './drizzle-error.mapper';
4
+ /**
5
+ * Turns database constraint violations into the HTTP responses they deserve,
6
+ * so services stop wrapping every write in `try { … } catch { mapDrizzleError }`.
7
+ *
8
+ * **Opt-in, never automatic** — the package does not register it for you (the
9
+ * project constitution: error mapping is offered, not imposed). Register it
10
+ * where you want it:
11
+ *
12
+ * ```ts
13
+ * // one controller
14
+ * @UseFilters(new DrizzleExceptionFilter())
15
+ *
16
+ * // or app-wide, in main.ts — needs the HTTP adapter, since anything that is
17
+ * // NOT a constraint violation is delegated to Nest's own handling
18
+ * app.useGlobalFilters(new DrizzleExceptionFilter(app.get(HttpAdapterHost).httpAdapter));
19
+ * ```
20
+ *
21
+ * It only claims errors {@link describeDrizzleError} recognises; everything
22
+ * else falls through to `BaseExceptionFilter` exactly as if this filter were
23
+ * not installed, so adding it cannot change how your other errors behave.
24
+ */
25
+ export declare class DrizzleExceptionFilter extends BaseExceptionFilter implements ExceptionFilter {
26
+ private readonly options;
27
+ constructor(applicationRef?: ConstructorParameters<typeof BaseExceptionFilter>[0], options?: DrizzleErrorMappingOptions);
28
+ catch(exception: unknown, host: ArgumentsHost): void;
29
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DrizzleExceptionFilter = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const core_1 = require("@nestjs/core");
15
+ const drizzle_error_mapper_1 = require("./drizzle-error.mapper");
16
+ /**
17
+ * Turns database constraint violations into the HTTP responses they deserve,
18
+ * so services stop wrapping every write in `try { … } catch { mapDrizzleError }`.
19
+ *
20
+ * **Opt-in, never automatic** — the package does not register it for you (the
21
+ * project constitution: error mapping is offered, not imposed). Register it
22
+ * where you want it:
23
+ *
24
+ * ```ts
25
+ * // one controller
26
+ * @UseFilters(new DrizzleExceptionFilter())
27
+ *
28
+ * // or app-wide, in main.ts — needs the HTTP adapter, since anything that is
29
+ * // NOT a constraint violation is delegated to Nest's own handling
30
+ * app.useGlobalFilters(new DrizzleExceptionFilter(app.get(HttpAdapterHost).httpAdapter));
31
+ * ```
32
+ *
33
+ * It only claims errors {@link describeDrizzleError} recognises; everything
34
+ * else falls through to `BaseExceptionFilter` exactly as if this filter were
35
+ * not installed, so adding it cannot change how your other errors behave.
36
+ */
37
+ let DrizzleExceptionFilter = class DrizzleExceptionFilter extends core_1.BaseExceptionFilter {
38
+ constructor(applicationRef, options = {}) {
39
+ super(applicationRef);
40
+ this.options = options;
41
+ }
42
+ catch(exception, host) {
43
+ if ((0, drizzle_error_mapper_1.describeDrizzleError)(exception) === undefined) {
44
+ // Not ours — let Nest handle it unchanged.
45
+ super.catch(exception, host);
46
+ return;
47
+ }
48
+ super.catch((0, drizzle_error_mapper_1.mapDrizzleError)(exception, this.options), host);
49
+ }
50
+ };
51
+ exports.DrizzleExceptionFilter = DrizzleExceptionFilter;
52
+ exports.DrizzleExceptionFilter = DrizzleExceptionFilter = __decorate([
53
+ (0, common_1.Catch)(),
54
+ __metadata("design:paramtypes", [Object, Object])
55
+ ], DrizzleExceptionFilter);
56
+ //# sourceMappingURL=drizzle-exception.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drizzle-exception.filter.js","sourceRoot":"","sources":["../../errors/drizzle-exception.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiF;AACjF,uCAAmD;AACnD,iEAIgC;AAEhC;;;;;;;;;;;;;;;;;;;;GAoBG;AAEI,IAAM,sBAAsB,GAA5B,MAAM,sBACX,SAAQ,0BAAmB;IAI3B,YACE,cAAqE,EACrE,UAAsC,EAAE;QAExC,KAAK,CAAC,cAAc,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,SAAkB,EAAE,IAAmB;QAC3C,IAAI,IAAA,2CAAoB,EAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;YAClD,2CAA2C;YAC3C,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QAED,KAAK,CAAC,KAAK,CAAC,IAAA,sCAAe,EAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;CACF,CAAA;AAtBY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,cAAK,GAAE;;GACK,sBAAsB,CAsBlC"}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from './decorators/inject-transaction.decorator';
6
6
  export * from './decorators/transactional.decorator';
7
7
  export * from './drizzle.module';
8
8
  export * from './errors/drizzle-error.mapper';
9
+ export * from './errors/drizzle-exception.filter';
9
10
  export * from './interfaces';
10
11
  export * from './testing/drizzle-test.module';
11
12
  export * from './testing/mock-client';
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ __exportStar(require("./decorators/inject-transaction.decorator"), exports);
22
22
  __exportStar(require("./decorators/transactional.decorator"), exports);
23
23
  __exportStar(require("./drizzle.module"), exports);
24
24
  __exportStar(require("./errors/drizzle-error.mapper"), exports);
25
+ __exportStar(require("./errors/drizzle-exception.filter"), exports);
25
26
  __exportStar(require("./interfaces"), exports);
26
27
  __exportStar(require("./testing/drizzle-test.module"), exports);
27
28
  __exportStar(require("./testing/mock-client"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sEAAoD;AACpD,8CAA4B;AAC5B,4EAA0D;AAC1D,wEAAsD;AACtD,4EAA0D;AAC1D,uEAAqD;AACrD,mDAAiC;AACjC,gEAA8C;AAC9C,+CAA6B;AAC7B,gEAA8C;AAC9C,wDAAsC;AACtC,2CAAyB"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sEAAoD;AACpD,8CAA4B;AAC5B,4EAA0D;AAC1D,wEAAsD;AACtD,4EAA0D;AAC1D,uEAAqD;AACrD,mDAAiC;AACjC,gEAA8C;AAC9C,oEAAkD;AAClD,+CAA6B;AAC7B,gEAA8C;AAC9C,wDAAsC;AACtC,2CAAyB"}
package/dist/tokens.js CHANGED
@@ -8,10 +8,11 @@ exports.getDrizzleSchemaToken = getDrizzleSchemaToken;
8
8
  exports.getDrizzleTransactionToken = getDrizzleTransactionToken;
9
9
  const constants_1 = require("./constants");
10
10
  function normalizeDrizzleConnectionName(connectionName) {
11
- const normalized = connectionName?.trim();
12
- return normalized && normalized.length > 0
13
- ? normalized
14
- : constants_1.DEFAULT_DRIZZLE_CONNECTION_NAME;
11
+ // A non-empty trimmed string is truthy and an empty one is falsy, so `||`
12
+ // covers undefined, empty, and whitespace-only names in one step — an
13
+ // explicit `.length > 0` check would be an unreachable (equivalent-mutant)
14
+ // branch on top of that.
15
+ return connectionName?.trim() || constants_1.DEFAULT_DRIZZLE_CONNECTION_NAME;
15
16
  }
16
17
  function getDrizzleClientToken(connectionName) {
17
18
  return buildDrizzleToken(constants_1.DRIZZLE_CLIENT, connectionName);
@@ -1 +1 @@
1
- {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../tokens.ts"],"names":[],"mappings":";;AASA,wEAKC;AAED,sDAEC;AAED,4EAEC;AAED,wDAEC;AAED,sDAEC;AAED,gEAEC;AAlCD,2CAOqB;AAErB,SAAgB,8BAA8B,CAAC,cAAuB;IACpE,MAAM,UAAU,GAAG,cAAc,EAAE,IAAI,EAAE,CAAC;IAC1C,OAAO,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;QACxC,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,2CAA+B,CAAC;AACtC,CAAC;AAED,SAAgB,qBAAqB,CAAC,cAAuB;IAC3D,OAAO,iBAAiB,CAAC,0BAAc,EAAE,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,SAAgB,gCAAgC,CAAC,cAAuB;IACtE,OAAO,iBAAiB,CAAC,sCAA0B,EAAE,cAAc,CAAC,CAAC;AACvE,CAAC;AAED,SAAgB,sBAAsB,CAAC,cAAuB;IAC5D,OAAO,iBAAiB,CAAC,kCAAsB,EAAE,cAAc,CAAC,CAAC;AACnE,CAAC;AAED,SAAgB,qBAAqB,CAAC,cAAuB;IAC3D,OAAO,iBAAiB,CAAC,0BAAc,EAAE,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,SAAgB,0BAA0B,CAAC,cAAuB;IAChE,OAAO,iBAAiB,CAAC,+BAAmB,EAAE,cAAc,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc,EAAE,cAAuB;IAChE,MAAM,UAAU,GAAG,8BAA8B,CAAC,cAAc,CAAC,CAAC;IAClE,OAAO,UAAU,KAAK,2CAA+B;QACnD,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC;AAChC,CAAC"}
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../tokens.ts"],"names":[],"mappings":";;AASA,wEAMC;AAED,sDAEC;AAED,4EAEC;AAED,wDAEC;AAED,sDAEC;AAED,gEAEC;AAnCD,2CAOqB;AAErB,SAAgB,8BAA8B,CAAC,cAAuB;IACpE,0EAA0E;IAC1E,sEAAsE;IACtE,2EAA2E;IAC3E,yBAAyB;IACzB,OAAO,cAAc,EAAE,IAAI,EAAE,IAAI,2CAA+B,CAAC;AACnE,CAAC;AAED,SAAgB,qBAAqB,CAAC,cAAuB;IAC3D,OAAO,iBAAiB,CAAC,0BAAc,EAAE,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,SAAgB,gCAAgC,CAAC,cAAuB;IACtE,OAAO,iBAAiB,CAAC,sCAA0B,EAAE,cAAc,CAAC,CAAC;AACvE,CAAC;AAED,SAAgB,sBAAsB,CAAC,cAAuB;IAC5D,OAAO,iBAAiB,CAAC,kCAAsB,EAAE,cAAc,CAAC,CAAC;AACnE,CAAC;AAED,SAAgB,qBAAqB,CAAC,cAAuB;IAC3D,OAAO,iBAAiB,CAAC,0BAAc,EAAE,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,SAAgB,0BAA0B,CAAC,cAAuB;IAChE,OAAO,iBAAiB,CAAC,+BAAmB,EAAE,cAAc,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAc,EAAE,cAAuB;IAChE,MAAM,UAAU,GAAG,8BAA8B,CAAC,cAAc,CAAC,CAAC;IAClE,OAAO,UAAU,KAAK,2CAA+B;QACnD,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC;AAChC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nest-native/drizzle",
3
- "version": "0.3.2",
3
+ "version": "0.5.0",
4
4
  "description": "Nest-native Drizzle ORM integration with DI, repositories, and transaction decorators",
5
5
  "keywords": [
6
6
  "nestjs",
@@ -43,7 +43,7 @@
43
43
  "access": "public"
44
44
  },
45
45
  "engines": {
46
- "node": ">=20"
46
+ "node": ">=22"
47
47
  },
48
48
  "scripts": {
49
49
  "clean": "rimraf dist tsconfig.tsbuildinfo",
@@ -53,12 +53,12 @@
53
53
  "peerDependencies": {
54
54
  "@libsql/client": "*",
55
55
  "@nestjs-cls/transactional": "*",
56
- "@nestjs/common": "^11.0.0",
57
- "@nestjs/core": "^11.0.0",
58
- "@nestjs/swagger": "^11.4.4",
56
+ "@nestjs/common": "^11.0.0 || ^12.0.0",
57
+ "@nestjs/core": "^11.0.0 || ^12.0.0",
58
+ "@nestjs/swagger": "^11.4.7 || ^12.0.0",
59
59
  "better-sqlite3": "*",
60
60
  "class-validator": "^0.15.1",
61
- "drizzle-orm": ">=0.30.0 <2.0.0",
61
+ "drizzle-orm": ">=0.30.0 <2.0.0 || >=1.0.0-rc.1 <2.0.0",
62
62
  "drizzle-zod": "*",
63
63
  "mysql2": "*",
64
64
  "pg": "*",
@@ -92,8 +92,8 @@
92
92
  }
93
93
  },
94
94
  "devDependencies": {
95
- "@nestjs/common": "^11.1.26",
96
- "@nestjs/core": "^11.1.26",
95
+ "@nestjs/common": "^11.2.1",
96
+ "@nestjs/core": "^11.2.1",
97
97
  "reflect-metadata": "^0.2.2",
98
98
  "rxjs": "^7.8.1",
99
99
  "typescript": "^6.0.3"