@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.
- package/dist/errors/drizzle-error.mapper.d.ts +48 -0
- package/dist/errors/drizzle-error.mapper.js +95 -21
- package/dist/errors/drizzle-error.mapper.js.map +1 -1
- package/dist/errors/drizzle-exception.filter.d.ts +29 -0
- package/dist/errors/drizzle-exception.filter.js +56 -0
- package/dist/errors/drizzle-exception.filter.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/tokens.js +5 -4
- package/dist/tokens.js.map +1 -1
- package/package.json +8 -8
|
@@ -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
|
-
|
|
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 (
|
|
37
|
+
if (violation?.kind === 'foreignKey') {
|
|
13
38
|
return new common_1.BadRequestException(options.foreignKeyMessage ?? 'Related resource does not exist.');
|
|
14
39
|
}
|
|
15
|
-
if (
|
|
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
|
|
74
|
+
return describeDrizzleError(error)?.kind === 'unique';
|
|
24
75
|
}
|
|
25
76
|
function isForeignKeyConstraintError(error) {
|
|
26
|
-
return
|
|
77
|
+
return describeDrizzleError(error)?.kind === 'foreignKey';
|
|
27
78
|
}
|
|
28
79
|
function isNotNullConstraintError(error) {
|
|
29
|
-
return
|
|
80
|
+
return describeDrizzleError(error)?.kind === 'notNull';
|
|
30
81
|
}
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
return codes.some(code => expectedCodes.includes(code));
|
|
82
|
+
function isCheckConstraintError(error) {
|
|
83
|
+
return describeDrizzleError(error)?.kind === 'check';
|
|
34
84
|
}
|
|
35
|
-
|
|
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
|
|
40
|
-
const
|
|
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(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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":"
|
|
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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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);
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../tokens.ts"],"names":[],"mappings":";;AASA,
|
|
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
|
+
"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": ">=
|
|
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.
|
|
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
|
|
96
|
-
"@nestjs/core": "^11.1
|
|
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"
|