@vritti/api-sdk 0.3.3 → 0.3.5
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/auth.cjs +942 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +95 -0
- package/dist/auth.d.ts +95 -0
- package/dist/auth.js +884 -0
- package/dist/auth.js.map +1 -0
- package/dist/cache.cjs +182 -14
- package/dist/cache.cjs.map +1 -1
- package/dist/cache.d.cts +48 -4
- package/dist/cache.d.ts +48 -4
- package/dist/cache.js +177 -12
- package/dist/cache.js.map +1 -1
- package/dist/catalog-resolver.cjs +226 -51
- package/dist/catalog-resolver.cjs.map +1 -1
- package/dist/catalog-resolver.d.cts +41 -19
- package/dist/catalog-resolver.d.ts +41 -19
- package/dist/catalog-resolver.js +212 -46
- package/dist/catalog-resolver.js.map +1 -1
- package/dist/code-pattern-BP4zkNtT.d.cts +12 -0
- package/dist/code-pattern-BP4zkNtT.d.ts +12 -0
- package/dist/context.cjs +93 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +19 -0
- package/dist/context.d.ts +19 -0
- package/dist/context.js +64 -0
- package/dist/context.js.map +1 -0
- package/dist/countries.cjs +1559 -0
- package/dist/countries.cjs.map +1 -0
- package/dist/countries.d.cts +13 -0
- package/dist/countries.d.ts +13 -0
- package/dist/countries.js +1532 -0
- package/dist/countries.js.map +1 -0
- package/dist/data-table.cjs +1280 -0
- package/dist/data-table.cjs.map +1 -0
- package/dist/data-table.d.cts +123 -0
- package/dist/data-table.d.ts +123 -0
- package/dist/data-table.js +1260 -0
- package/dist/data-table.js.map +1 -0
- package/dist/database.cjs +1510 -0
- package/dist/database.cjs.map +1 -0
- package/dist/database.d.cts +287 -0
- package/dist/database.d.ts +287 -0
- package/dist/database.js +1469 -0
- package/dist/database.js.map +1 -0
- package/dist/decimal.d.cts +0 -1
- package/dist/decimal.d.ts +0 -1
- package/dist/decorators.cjs +1817 -0
- package/dist/decorators.cjs.map +1 -0
- package/dist/decorators.d.cts +24 -0
- package/dist/decorators.d.ts +24 -0
- package/dist/decorators.js +1780 -0
- package/dist/decorators.js.map +1 -0
- package/dist/drizzle-pg-core.cjs +25 -0
- package/dist/drizzle-pg-core.cjs.map +1 -1
- package/dist/drizzle-pg-core.d.cts +7 -0
- package/dist/drizzle-pg-core.d.ts +7 -0
- package/dist/drizzle-pg-core.js +22 -0
- package/dist/drizzle-pg-core.js.map +1 -1
- package/dist/exceptions.cjs +301 -0
- package/dist/exceptions.cjs.map +1 -0
- package/dist/exceptions.d.cts +90 -0
- package/dist/exceptions.d.ts +90 -0
- package/dist/exceptions.js +257 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/filter.types-PuARU9XD.d.cts +50 -0
- package/dist/filter.types-PuARU9XD.d.ts +50 -0
- package/dist/filters.cjs +407 -0
- package/dist/filters.cjs.map +1 -0
- package/dist/filters.d.cts +55 -0
- package/dist/filters.d.ts +55 -0
- package/dist/filters.js +377 -0
- package/dist/filters.js.map +1 -0
- package/dist/index.cjs +0 -5423
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -854
- package/dist/index.d.ts +93 -854
- package/dist/index.js +0 -5301
- package/dist/index.js.map +1 -1
- package/dist/is-country.decorator-CcNwSSr5.d.cts +5 -0
- package/dist/is-country.decorator-CcNwSSr5.d.ts +5 -0
- package/dist/license.d.cts +1 -1
- package/dist/license.d.ts +1 -1
- package/dist/lodash.cjs.map +1 -1
- package/dist/lodash.js.map +1 -1
- package/dist/logger.cjs +862 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +118 -0
- package/dist/logger.d.ts +118 -0
- package/dist/logger.js +816 -0
- package/dist/logger.js.map +1 -0
- package/dist/migrate.cjs +2 -2
- package/dist/migrate.cjs.map +1 -1
- package/dist/migrate.d.cts +2 -0
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +2 -2
- package/dist/migrate.js.map +1 -1
- package/dist/money.cjs +18 -3
- package/dist/money.cjs.map +1 -1
- package/dist/money.d.cts +13 -13
- package/dist/money.d.ts +13 -13
- package/dist/money.js +18 -3
- package/dist/money.js.map +1 -1
- package/dist/nats.cjs +34 -35
- package/dist/nats.cjs.map +1 -1
- package/dist/nats.d.cts +14 -14
- package/dist/nats.d.ts +14 -14
- package/dist/nats.js +32 -33
- package/dist/nats.js.map +1 -1
- package/dist/root.cjs +225 -0
- package/dist/root.cjs.map +1 -0
- package/dist/root.d.cts +4 -0
- package/dist/root.d.ts +4 -0
- package/dist/root.js +200 -0
- package/dist/root.js.map +1 -0
- package/dist/{types-DQRwj5rr.d.cts → types-C9jPdQqH.d.cts} +32 -6
- package/dist/{types-DQRwj5rr.d.ts → types-C9jPdQqH.d.ts} +32 -6
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +17 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.cjs +273 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +8 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +245 -0
- package/dist/utils.js.map +1 -0
- package/package.json +122 -1
- package/dist/cache.service-_SuJIcNA.d.cts +0 -20
- package/dist/cache.service-_SuJIcNA.d.ts +0 -20
- package/dist/fastify-augmentation-CQPBNS5a.d.cts +0 -105
- package/dist/fastify-augmentation-CQPBNS5a.d.ts +0 -105
|
@@ -0,0 +1,1510 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc3) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc3 = __getOwnPropDesc(from, key)) || desc3.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/database/index.ts
|
|
22
|
+
var database_exports = {};
|
|
23
|
+
__export(database_exports, {
|
|
24
|
+
CreateResponseDto: () => CreateResponseDto,
|
|
25
|
+
CursorCodec: () => CursorCodec,
|
|
26
|
+
CursorListResponseDto: () => CursorListResponseDto,
|
|
27
|
+
DatabaseModule: () => DatabaseModule,
|
|
28
|
+
FilterOperators: () => FilterOperators,
|
|
29
|
+
FilterProcessor: () => FilterProcessor,
|
|
30
|
+
ImportResponseDto: () => ImportResponseDto,
|
|
31
|
+
ImportSummaryDto: () => ImportSummaryDto,
|
|
32
|
+
KeysetProcessor: () => KeysetProcessor,
|
|
33
|
+
MAX_PAGE_SIZE: () => MAX_PAGE_SIZE,
|
|
34
|
+
PrimaryBaseRepository: () => PrimaryBaseRepository,
|
|
35
|
+
PrimaryDatabaseService: () => PrimaryDatabaseService,
|
|
36
|
+
SelectOptionsQueryDto: () => SelectOptionsQueryDto,
|
|
37
|
+
SuccessResponseDto: () => SuccessResponseDto,
|
|
38
|
+
TableResponseDto: () => TableResponseDto,
|
|
39
|
+
ValidatedRowDto: () => ValidatedRowDto,
|
|
40
|
+
keysetSignature: () => keysetSignature
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(database_exports);
|
|
43
|
+
|
|
44
|
+
// src/database/database.module.ts
|
|
45
|
+
var import_common2 = require("@nestjs/common");
|
|
46
|
+
var import_core = require("@nestjs/core");
|
|
47
|
+
|
|
48
|
+
// src/database/constants.ts
|
|
49
|
+
var DATABASE_MODULE_OPTIONS = Symbol("DATABASE_MODULE_OPTIONS");
|
|
50
|
+
|
|
51
|
+
// src/database/services/primary-database.service.ts
|
|
52
|
+
var import_node_async_hooks = require("async_hooks");
|
|
53
|
+
var import_common = require("@nestjs/common");
|
|
54
|
+
var import_node_postgres = require("drizzle-orm/node-postgres");
|
|
55
|
+
|
|
56
|
+
// src/database/services/rls-aware-pool.ts
|
|
57
|
+
var import_pg = require("pg");
|
|
58
|
+
var RlsAwarePool = class extends import_pg.Pool {
|
|
59
|
+
static {
|
|
60
|
+
__name(this, "RlsAwarePool");
|
|
61
|
+
}
|
|
62
|
+
rlsAls;
|
|
63
|
+
txAls;
|
|
64
|
+
applyRlsContext;
|
|
65
|
+
constructor(options) {
|
|
66
|
+
const { rlsAls, txAls, applyRlsContext, ...poolConfig } = options;
|
|
67
|
+
super(poolConfig);
|
|
68
|
+
this.rlsAls = rlsAls;
|
|
69
|
+
this.txAls = txAls;
|
|
70
|
+
this.applyRlsContext = applyRlsContext;
|
|
71
|
+
}
|
|
72
|
+
// biome-ignore lint/suspicious/noExplicitAny: matches pg.Pool.query overload surface
|
|
73
|
+
query(textOrConfig, values, cb) {
|
|
74
|
+
if (typeof textOrConfig === "function") {
|
|
75
|
+
return super.query(textOrConfig);
|
|
76
|
+
}
|
|
77
|
+
if (textOrConfig && typeof textOrConfig.submit === "function") {
|
|
78
|
+
return super.query(textOrConfig, values, cb);
|
|
79
|
+
}
|
|
80
|
+
if (typeof values === "function" || typeof cb === "function") {
|
|
81
|
+
return super.query(textOrConfig, values, cb);
|
|
82
|
+
}
|
|
83
|
+
const rls = this.rlsAls.getStore();
|
|
84
|
+
if (rls === void 0 || this.txAls.getStore() !== void 0 || !this.applyRlsContext) {
|
|
85
|
+
return super.query(textOrConfig, values);
|
|
86
|
+
}
|
|
87
|
+
return this.runWrapped(textOrConfig, values, rls);
|
|
88
|
+
}
|
|
89
|
+
// biome-ignore lint/suspicious/noExplicitAny: dispatched from query() overload
|
|
90
|
+
async runWrapped(textOrConfig, values, rls) {
|
|
91
|
+
const client = await super.connect();
|
|
92
|
+
try {
|
|
93
|
+
await client.query("BEGIN");
|
|
94
|
+
await this.applyRlsContext(client, rls);
|
|
95
|
+
const result = await client.query(textOrConfig, values);
|
|
96
|
+
await client.query("COMMIT");
|
|
97
|
+
client.release();
|
|
98
|
+
return result;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
try {
|
|
101
|
+
await client.query("ROLLBACK");
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
client.release(err);
|
|
105
|
+
throw err;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/database/services/primary-database.service.ts
|
|
111
|
+
function _ts_decorate(decorators, target, key, desc3) {
|
|
112
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
113
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
114
|
+
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;
|
|
115
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
116
|
+
}
|
|
117
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
118
|
+
function _ts_metadata(k, v) {
|
|
119
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
120
|
+
}
|
|
121
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
122
|
+
function _ts_param(paramIndex, decorator) {
|
|
123
|
+
return function(target, key) {
|
|
124
|
+
decorator(target, key, paramIndex);
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
__name(_ts_param, "_ts_param");
|
|
128
|
+
var PrimaryDatabaseService = class _PrimaryDatabaseService {
|
|
129
|
+
static {
|
|
130
|
+
__name(this, "PrimaryDatabaseService");
|
|
131
|
+
}
|
|
132
|
+
options;
|
|
133
|
+
logger = new import_common.Logger(_PrimaryDatabaseService.name);
|
|
134
|
+
pool = null;
|
|
135
|
+
db = null;
|
|
136
|
+
// Per-request RLS context read by RlsAwarePool per query and by runInTransaction at BEGIN.
|
|
137
|
+
rlsAls = new import_node_async_hooks.AsyncLocalStorage();
|
|
138
|
+
// Active Drizzle transaction client so repository queries participate in the transaction.
|
|
139
|
+
txAls = new import_node_async_hooks.AsyncLocalStorage();
|
|
140
|
+
constructor(options) {
|
|
141
|
+
this.options = options;
|
|
142
|
+
}
|
|
143
|
+
async onModuleInit() {
|
|
144
|
+
if (this.options.primaryDb) {
|
|
145
|
+
await this.initializeDrizzleClient();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Initializes connection to primary database using Drizzle
|
|
149
|
+
async initializeDrizzleClient() {
|
|
150
|
+
try {
|
|
151
|
+
const { host, port = 5432, username, password, database, schema, sslMode = "require" } = this.options.primaryDb;
|
|
152
|
+
this.pool = new RlsAwarePool({
|
|
153
|
+
host,
|
|
154
|
+
port,
|
|
155
|
+
user: username,
|
|
156
|
+
password,
|
|
157
|
+
database,
|
|
158
|
+
max: this.options.maxConnections || 10,
|
|
159
|
+
ssl: sslMode === "disable" ? false : {
|
|
160
|
+
rejectUnauthorized: sslMode !== "no-verify"
|
|
161
|
+
},
|
|
162
|
+
...schema && {
|
|
163
|
+
options: `-csearch_path=${schema}`
|
|
164
|
+
},
|
|
165
|
+
rlsAls: this.rlsAls,
|
|
166
|
+
txAls: this.txAls,
|
|
167
|
+
applyRlsContext: this.options.applyRlsContext
|
|
168
|
+
});
|
|
169
|
+
this.logger.debug(`Relations keys passed to drizzle: [${Object.keys(this.options.drizzleRelations || {}).join(", ")}]`);
|
|
170
|
+
this.db = (0, import_node_postgres.drizzle)({
|
|
171
|
+
client: this.pool,
|
|
172
|
+
relations: this.options.drizzleRelations
|
|
173
|
+
});
|
|
174
|
+
await this.pool.query("SELECT 1");
|
|
175
|
+
this.logger.log(`Connected to primary database (schema: ${schema ?? "public"})`);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
this.logger.error("Failed to connect to primary database", error);
|
|
178
|
+
throw new import_common.InternalServerErrorException("Failed to initialize database connection");
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Returns the active Drizzle client — the pinned tx inside runInTransaction, else the pool-backed one.
|
|
182
|
+
get drizzleClient() {
|
|
183
|
+
const pinned = this.txAls.getStore();
|
|
184
|
+
if (pinned) return pinned;
|
|
185
|
+
if (!this.db) {
|
|
186
|
+
throw new Error("Primary database client not initialized");
|
|
187
|
+
}
|
|
188
|
+
return this.db;
|
|
189
|
+
}
|
|
190
|
+
// Stashes per-request RLS context in AsyncLocalStorage for downstream queries to apply via SET LOCAL.
|
|
191
|
+
runWithRlsContext(rls, fn) {
|
|
192
|
+
return this.rlsAls.run(rls, fn);
|
|
193
|
+
}
|
|
194
|
+
// Opens a transaction pinning all queries in `fn` to one connection, applying RLS once at BEGIN.
|
|
195
|
+
async runInTransaction(fn) {
|
|
196
|
+
const pinned = this.txAls.getStore();
|
|
197
|
+
if (pinned) {
|
|
198
|
+
return pinned.transaction(async (sp) => this.txAls.run(sp, fn));
|
|
199
|
+
}
|
|
200
|
+
if (!this.db) {
|
|
201
|
+
throw new Error("Primary database client not initialized");
|
|
202
|
+
}
|
|
203
|
+
const rls = this.rlsAls.getStore();
|
|
204
|
+
const applyRls = this.options.applyRlsContext;
|
|
205
|
+
return this.db.transaction(async (tx) => {
|
|
206
|
+
if (rls !== void 0 && applyRls) {
|
|
207
|
+
const sessionClient = tx?.session?.client;
|
|
208
|
+
if (sessionClient) {
|
|
209
|
+
await applyRls(sessionClient, rls);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return this.txAls.run(tx, fn);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// Deprecated: prefer runInTransaction. Retained so existing callers keep working until migrated.
|
|
216
|
+
async runWithPinnedConnection(fn) {
|
|
217
|
+
return this.runInTransaction(fn);
|
|
218
|
+
}
|
|
219
|
+
async onModuleDestroy() {
|
|
220
|
+
if (this.pool) {
|
|
221
|
+
await this.pool.end();
|
|
222
|
+
this.logger.log("Disconnected from primary database");
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
PrimaryDatabaseService = _ts_decorate([
|
|
227
|
+
(0, import_common.Injectable)(),
|
|
228
|
+
_ts_param(0, (0, import_common.Inject)(DATABASE_MODULE_OPTIONS)),
|
|
229
|
+
_ts_metadata("design:type", Function),
|
|
230
|
+
_ts_metadata("design:paramtypes", [
|
|
231
|
+
typeof DatabaseModuleOptions === "undefined" ? Object : DatabaseModuleOptions
|
|
232
|
+
])
|
|
233
|
+
], PrimaryDatabaseService);
|
|
234
|
+
|
|
235
|
+
// src/database/database.module.ts
|
|
236
|
+
function _ts_decorate2(decorators, target, key, desc3) {
|
|
237
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
238
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
239
|
+
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;
|
|
240
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
241
|
+
}
|
|
242
|
+
__name(_ts_decorate2, "_ts_decorate");
|
|
243
|
+
var DatabaseModule = class _DatabaseModule {
|
|
244
|
+
static {
|
|
245
|
+
__name(this, "DatabaseModule");
|
|
246
|
+
}
|
|
247
|
+
// Configures the database module with a single primary connection
|
|
248
|
+
static forServer(options) {
|
|
249
|
+
const asyncProvider = {
|
|
250
|
+
provide: DATABASE_MODULE_OPTIONS,
|
|
251
|
+
useFactory: options.useFactory,
|
|
252
|
+
inject: options.inject || []
|
|
253
|
+
};
|
|
254
|
+
return {
|
|
255
|
+
module: _DatabaseModule,
|
|
256
|
+
providers: [
|
|
257
|
+
{
|
|
258
|
+
provide: import_core.Reflector,
|
|
259
|
+
useClass: import_core.Reflector
|
|
260
|
+
},
|
|
261
|
+
asyncProvider,
|
|
262
|
+
PrimaryDatabaseService
|
|
263
|
+
],
|
|
264
|
+
exports: [
|
|
265
|
+
PrimaryDatabaseService,
|
|
266
|
+
asyncProvider
|
|
267
|
+
]
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
DatabaseModule = _ts_decorate2([
|
|
272
|
+
(0, import_common2.Global)(),
|
|
273
|
+
(0, import_common2.Module)({})
|
|
274
|
+
], DatabaseModule);
|
|
275
|
+
|
|
276
|
+
// src/database/dto/create-response.dto.ts
|
|
277
|
+
var import_swagger = require("@nestjs/swagger");
|
|
278
|
+
function _ts_decorate3(decorators, target, key, desc3) {
|
|
279
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
280
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
281
|
+
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;
|
|
282
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
283
|
+
}
|
|
284
|
+
__name(_ts_decorate3, "_ts_decorate");
|
|
285
|
+
function _ts_metadata2(k, v) {
|
|
286
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
287
|
+
}
|
|
288
|
+
__name(_ts_metadata2, "_ts_metadata");
|
|
289
|
+
var CreateResponseDto = class {
|
|
290
|
+
static {
|
|
291
|
+
__name(this, "CreateResponseDto");
|
|
292
|
+
}
|
|
293
|
+
success;
|
|
294
|
+
message;
|
|
295
|
+
data;
|
|
296
|
+
};
|
|
297
|
+
_ts_decorate3([
|
|
298
|
+
(0, import_swagger.ApiProperty)({
|
|
299
|
+
example: true
|
|
300
|
+
}),
|
|
301
|
+
_ts_metadata2("design:type", Boolean)
|
|
302
|
+
], CreateResponseDto.prototype, "success", void 0);
|
|
303
|
+
_ts_decorate3([
|
|
304
|
+
(0, import_swagger.ApiProperty)({
|
|
305
|
+
example: "Resource created successfully"
|
|
306
|
+
}),
|
|
307
|
+
_ts_metadata2("design:type", String)
|
|
308
|
+
], CreateResponseDto.prototype, "message", void 0);
|
|
309
|
+
_ts_decorate3([
|
|
310
|
+
(0, import_swagger.ApiProperty)(),
|
|
311
|
+
_ts_metadata2("design:type", typeof T === "undefined" ? Object : T)
|
|
312
|
+
], CreateResponseDto.prototype, "data", void 0);
|
|
313
|
+
|
|
314
|
+
// src/database/dto/cursor-list-response.dto.ts
|
|
315
|
+
var import_swagger2 = require("@nestjs/swagger");
|
|
316
|
+
function _ts_decorate4(decorators, target, key, desc3) {
|
|
317
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
318
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
319
|
+
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;
|
|
320
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
321
|
+
}
|
|
322
|
+
__name(_ts_decorate4, "_ts_decorate");
|
|
323
|
+
function _ts_metadata3(k, v) {
|
|
324
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
325
|
+
}
|
|
326
|
+
__name(_ts_metadata3, "_ts_metadata");
|
|
327
|
+
var CursorListResponseDto = class {
|
|
328
|
+
static {
|
|
329
|
+
__name(this, "CursorListResponseDto");
|
|
330
|
+
}
|
|
331
|
+
items;
|
|
332
|
+
nextCursor;
|
|
333
|
+
hasMore;
|
|
334
|
+
};
|
|
335
|
+
_ts_decorate4([
|
|
336
|
+
(0, import_swagger2.ApiProperty)(),
|
|
337
|
+
_ts_metadata3("design:type", Array)
|
|
338
|
+
], CursorListResponseDto.prototype, "items", void 0);
|
|
339
|
+
_ts_decorate4([
|
|
340
|
+
(0, import_swagger2.ApiPropertyOptional)({
|
|
341
|
+
nullable: true
|
|
342
|
+
}),
|
|
343
|
+
_ts_metadata3("design:type", Object)
|
|
344
|
+
], CursorListResponseDto.prototype, "nextCursor", void 0);
|
|
345
|
+
_ts_decorate4([
|
|
346
|
+
(0, import_swagger2.ApiProperty)(),
|
|
347
|
+
_ts_metadata3("design:type", Boolean)
|
|
348
|
+
], CursorListResponseDto.prototype, "hasMore", void 0);
|
|
349
|
+
|
|
350
|
+
// src/database/dto/import-response.dto.ts
|
|
351
|
+
var import_swagger3 = require("@nestjs/swagger");
|
|
352
|
+
function _ts_decorate5(decorators, target, key, desc3) {
|
|
353
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
354
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
355
|
+
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;
|
|
356
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
357
|
+
}
|
|
358
|
+
__name(_ts_decorate5, "_ts_decorate");
|
|
359
|
+
function _ts_metadata4(k, v) {
|
|
360
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
361
|
+
}
|
|
362
|
+
__name(_ts_metadata4, "_ts_metadata");
|
|
363
|
+
var ValidatedRowDto = class {
|
|
364
|
+
static {
|
|
365
|
+
__name(this, "ValidatedRowDto");
|
|
366
|
+
}
|
|
367
|
+
index;
|
|
368
|
+
data;
|
|
369
|
+
valid;
|
|
370
|
+
errors;
|
|
371
|
+
};
|
|
372
|
+
_ts_decorate5([
|
|
373
|
+
(0, import_swagger3.ApiProperty)({
|
|
374
|
+
example: 1
|
|
375
|
+
}),
|
|
376
|
+
_ts_metadata4("design:type", Number)
|
|
377
|
+
], ValidatedRowDto.prototype, "index", void 0);
|
|
378
|
+
_ts_decorate5([
|
|
379
|
+
(0, import_swagger3.ApiProperty)({
|
|
380
|
+
example: {
|
|
381
|
+
code: "products",
|
|
382
|
+
name: "Products"
|
|
383
|
+
}
|
|
384
|
+
}),
|
|
385
|
+
_ts_metadata4("design:type", typeof Record === "undefined" ? Object : Record)
|
|
386
|
+
], ValidatedRowDto.prototype, "data", void 0);
|
|
387
|
+
_ts_decorate5([
|
|
388
|
+
(0, import_swagger3.ApiProperty)({
|
|
389
|
+
example: true
|
|
390
|
+
}),
|
|
391
|
+
_ts_metadata4("design:type", Boolean)
|
|
392
|
+
], ValidatedRowDto.prototype, "valid", void 0);
|
|
393
|
+
_ts_decorate5([
|
|
394
|
+
(0, import_swagger3.ApiProperty)({
|
|
395
|
+
example: [
|
|
396
|
+
"Code already exists"
|
|
397
|
+
]
|
|
398
|
+
}),
|
|
399
|
+
_ts_metadata4("design:type", Array)
|
|
400
|
+
], ValidatedRowDto.prototype, "errors", void 0);
|
|
401
|
+
var ImportSummaryDto = class {
|
|
402
|
+
static {
|
|
403
|
+
__name(this, "ImportSummaryDto");
|
|
404
|
+
}
|
|
405
|
+
total;
|
|
406
|
+
valid;
|
|
407
|
+
invalid;
|
|
408
|
+
};
|
|
409
|
+
_ts_decorate5([
|
|
410
|
+
(0, import_swagger3.ApiProperty)({
|
|
411
|
+
example: 10
|
|
412
|
+
}),
|
|
413
|
+
_ts_metadata4("design:type", Number)
|
|
414
|
+
], ImportSummaryDto.prototype, "total", void 0);
|
|
415
|
+
_ts_decorate5([
|
|
416
|
+
(0, import_swagger3.ApiProperty)({
|
|
417
|
+
example: 8
|
|
418
|
+
}),
|
|
419
|
+
_ts_metadata4("design:type", Number)
|
|
420
|
+
], ImportSummaryDto.prototype, "valid", void 0);
|
|
421
|
+
_ts_decorate5([
|
|
422
|
+
(0, import_swagger3.ApiProperty)({
|
|
423
|
+
example: 2
|
|
424
|
+
}),
|
|
425
|
+
_ts_metadata4("design:type", Number)
|
|
426
|
+
], ImportSummaryDto.prototype, "invalid", void 0);
|
|
427
|
+
var ImportResponseDto = class {
|
|
428
|
+
static {
|
|
429
|
+
__name(this, "ImportResponseDto");
|
|
430
|
+
}
|
|
431
|
+
success;
|
|
432
|
+
message;
|
|
433
|
+
created;
|
|
434
|
+
updated;
|
|
435
|
+
skipped;
|
|
436
|
+
rows;
|
|
437
|
+
summary;
|
|
438
|
+
};
|
|
439
|
+
_ts_decorate5([
|
|
440
|
+
(0, import_swagger3.ApiProperty)({
|
|
441
|
+
example: true
|
|
442
|
+
}),
|
|
443
|
+
_ts_metadata4("design:type", Boolean)
|
|
444
|
+
], ImportResponseDto.prototype, "success", void 0);
|
|
445
|
+
_ts_decorate5([
|
|
446
|
+
(0, import_swagger3.ApiProperty)({
|
|
447
|
+
example: "Import complete."
|
|
448
|
+
}),
|
|
449
|
+
_ts_metadata4("design:type", String)
|
|
450
|
+
], ImportResponseDto.prototype, "message", void 0);
|
|
451
|
+
_ts_decorate5([
|
|
452
|
+
(0, import_swagger3.ApiPropertyOptional)({
|
|
453
|
+
example: 3
|
|
454
|
+
}),
|
|
455
|
+
_ts_metadata4("design:type", Number)
|
|
456
|
+
], ImportResponseDto.prototype, "created", void 0);
|
|
457
|
+
_ts_decorate5([
|
|
458
|
+
(0, import_swagger3.ApiPropertyOptional)({
|
|
459
|
+
example: 2
|
|
460
|
+
}),
|
|
461
|
+
_ts_metadata4("design:type", Number)
|
|
462
|
+
], ImportResponseDto.prototype, "updated", void 0);
|
|
463
|
+
_ts_decorate5([
|
|
464
|
+
(0, import_swagger3.ApiPropertyOptional)({
|
|
465
|
+
example: 1
|
|
466
|
+
}),
|
|
467
|
+
_ts_metadata4("design:type", Number)
|
|
468
|
+
], ImportResponseDto.prototype, "skipped", void 0);
|
|
469
|
+
_ts_decorate5([
|
|
470
|
+
(0, import_swagger3.ApiPropertyOptional)({
|
|
471
|
+
type: [
|
|
472
|
+
ValidatedRowDto
|
|
473
|
+
]
|
|
474
|
+
}),
|
|
475
|
+
_ts_metadata4("design:type", Array)
|
|
476
|
+
], ImportResponseDto.prototype, "rows", void 0);
|
|
477
|
+
_ts_decorate5([
|
|
478
|
+
(0, import_swagger3.ApiPropertyOptional)({
|
|
479
|
+
type: ImportSummaryDto
|
|
480
|
+
}),
|
|
481
|
+
_ts_metadata4("design:type", typeof ImportSummaryDto === "undefined" ? Object : ImportSummaryDto)
|
|
482
|
+
], ImportResponseDto.prototype, "summary", void 0);
|
|
483
|
+
|
|
484
|
+
// src/database/dto/select-options-query.dto.ts
|
|
485
|
+
var import_swagger4 = require("@nestjs/swagger");
|
|
486
|
+
var import_class_transformer = require("class-transformer");
|
|
487
|
+
var import_class_validator = require("class-validator");
|
|
488
|
+
function _ts_decorate6(decorators, target, key, desc3) {
|
|
489
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
490
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
491
|
+
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;
|
|
492
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
493
|
+
}
|
|
494
|
+
__name(_ts_decorate6, "_ts_decorate");
|
|
495
|
+
function _ts_metadata5(k, v) {
|
|
496
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
497
|
+
}
|
|
498
|
+
__name(_ts_metadata5, "_ts_metadata");
|
|
499
|
+
var SelectOptionsQueryDto = class {
|
|
500
|
+
static {
|
|
501
|
+
__name(this, "SelectOptionsQueryDto");
|
|
502
|
+
}
|
|
503
|
+
search;
|
|
504
|
+
limit;
|
|
505
|
+
offset;
|
|
506
|
+
values;
|
|
507
|
+
excludeIds;
|
|
508
|
+
valueKey;
|
|
509
|
+
labelKey;
|
|
510
|
+
descriptionKey;
|
|
511
|
+
additionalKeys;
|
|
512
|
+
groupIdKey;
|
|
513
|
+
orderByKey;
|
|
514
|
+
orderDirection;
|
|
515
|
+
};
|
|
516
|
+
_ts_decorate6([
|
|
517
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
518
|
+
description: "Search term to filter by label",
|
|
519
|
+
example: "united"
|
|
520
|
+
}),
|
|
521
|
+
(0, import_class_validator.IsOptional)(),
|
|
522
|
+
(0, import_class_validator.IsString)(),
|
|
523
|
+
_ts_metadata5("design:type", String)
|
|
524
|
+
], SelectOptionsQueryDto.prototype, "search", void 0);
|
|
525
|
+
_ts_decorate6([
|
|
526
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
527
|
+
description: "Maximum number of results",
|
|
528
|
+
example: 20,
|
|
529
|
+
default: 20
|
|
530
|
+
}),
|
|
531
|
+
(0, import_class_validator.IsOptional)(),
|
|
532
|
+
(0, import_class_transformer.Type)(() => Number),
|
|
533
|
+
(0, import_class_validator.IsInt)(),
|
|
534
|
+
(0, import_class_validator.Min)(1),
|
|
535
|
+
_ts_metadata5("design:type", Number)
|
|
536
|
+
], SelectOptionsQueryDto.prototype, "limit", void 0);
|
|
537
|
+
_ts_decorate6([
|
|
538
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
539
|
+
description: "Number of results to skip",
|
|
540
|
+
example: 0,
|
|
541
|
+
default: 0
|
|
542
|
+
}),
|
|
543
|
+
(0, import_class_validator.IsOptional)(),
|
|
544
|
+
(0, import_class_transformer.Type)(() => Number),
|
|
545
|
+
(0, import_class_validator.IsInt)(),
|
|
546
|
+
(0, import_class_validator.Min)(0),
|
|
547
|
+
_ts_metadata5("design:type", Number)
|
|
548
|
+
], SelectOptionsQueryDto.prototype, "offset", void 0);
|
|
549
|
+
_ts_decorate6([
|
|
550
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
551
|
+
description: "Comma-separated values to fetch specific options",
|
|
552
|
+
example: "1,2,3"
|
|
553
|
+
}),
|
|
554
|
+
(0, import_class_validator.IsOptional)(),
|
|
555
|
+
(0, import_class_validator.IsString)(),
|
|
556
|
+
_ts_metadata5("design:type", String)
|
|
557
|
+
], SelectOptionsQueryDto.prototype, "values", void 0);
|
|
558
|
+
_ts_decorate6([
|
|
559
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
560
|
+
description: "Comma-separated IDs to exclude from results (already selected)",
|
|
561
|
+
example: "5,10"
|
|
562
|
+
}),
|
|
563
|
+
(0, import_class_validator.IsOptional)(),
|
|
564
|
+
(0, import_class_validator.IsString)(),
|
|
565
|
+
_ts_metadata5("design:type", String)
|
|
566
|
+
], SelectOptionsQueryDto.prototype, "excludeIds", void 0);
|
|
567
|
+
_ts_decorate6([
|
|
568
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
569
|
+
description: "Column name for option value",
|
|
570
|
+
example: "id",
|
|
571
|
+
default: "id"
|
|
572
|
+
}),
|
|
573
|
+
(0, import_class_validator.IsOptional)(),
|
|
574
|
+
(0, import_class_validator.IsString)(),
|
|
575
|
+
_ts_metadata5("design:type", String)
|
|
576
|
+
], SelectOptionsQueryDto.prototype, "valueKey", void 0);
|
|
577
|
+
_ts_decorate6([
|
|
578
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
579
|
+
description: "Column name for option label",
|
|
580
|
+
example: "name",
|
|
581
|
+
default: "name"
|
|
582
|
+
}),
|
|
583
|
+
(0, import_class_validator.IsOptional)(),
|
|
584
|
+
(0, import_class_validator.IsString)(),
|
|
585
|
+
_ts_metadata5("design:type", String)
|
|
586
|
+
], SelectOptionsQueryDto.prototype, "labelKey", void 0);
|
|
587
|
+
_ts_decorate6([
|
|
588
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
589
|
+
description: "Column name for option description",
|
|
590
|
+
example: "description"
|
|
591
|
+
}),
|
|
592
|
+
(0, import_class_validator.IsOptional)(),
|
|
593
|
+
(0, import_class_validator.IsString)(),
|
|
594
|
+
_ts_metadata5("design:type", String)
|
|
595
|
+
], SelectOptionsQueryDto.prototype, "descriptionKey", void 0);
|
|
596
|
+
_ts_decorate6([
|
|
597
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
598
|
+
description: "Comma-separated column names to include in option.additionals",
|
|
599
|
+
example: "locationName,availableQuantity"
|
|
600
|
+
}),
|
|
601
|
+
(0, import_class_validator.IsOptional)(),
|
|
602
|
+
(0, import_class_validator.IsString)(),
|
|
603
|
+
_ts_metadata5("design:type", String)
|
|
604
|
+
], SelectOptionsQueryDto.prototype, "additionalKeys", void 0);
|
|
605
|
+
_ts_decorate6([
|
|
606
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
607
|
+
description: "Column name for group ID",
|
|
608
|
+
example: "regionId"
|
|
609
|
+
}),
|
|
610
|
+
(0, import_class_validator.IsOptional)(),
|
|
611
|
+
(0, import_class_validator.IsString)(),
|
|
612
|
+
_ts_metadata5("design:type", String)
|
|
613
|
+
], SelectOptionsQueryDto.prototype, "groupIdKey", void 0);
|
|
614
|
+
_ts_decorate6([
|
|
615
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
616
|
+
description: "Column name to sort options by",
|
|
617
|
+
example: "name",
|
|
618
|
+
default: "name"
|
|
619
|
+
}),
|
|
620
|
+
(0, import_class_validator.IsOptional)(),
|
|
621
|
+
(0, import_class_validator.IsString)(),
|
|
622
|
+
_ts_metadata5("design:type", String)
|
|
623
|
+
], SelectOptionsQueryDto.prototype, "orderByKey", void 0);
|
|
624
|
+
_ts_decorate6([
|
|
625
|
+
(0, import_swagger4.ApiPropertyOptional)({
|
|
626
|
+
description: "Sort direction for options",
|
|
627
|
+
example: "asc",
|
|
628
|
+
default: "asc",
|
|
629
|
+
enum: [
|
|
630
|
+
"asc",
|
|
631
|
+
"desc"
|
|
632
|
+
]
|
|
633
|
+
}),
|
|
634
|
+
(0, import_class_validator.IsOptional)(),
|
|
635
|
+
(0, import_class_validator.IsString)(),
|
|
636
|
+
(0, import_class_validator.IsIn)([
|
|
637
|
+
"asc",
|
|
638
|
+
"desc"
|
|
639
|
+
]),
|
|
640
|
+
_ts_metadata5("design:type", String)
|
|
641
|
+
], SelectOptionsQueryDto.prototype, "orderDirection", void 0);
|
|
642
|
+
|
|
643
|
+
// src/database/dto/success-response.dto.ts
|
|
644
|
+
var import_swagger5 = require("@nestjs/swagger");
|
|
645
|
+
var import_class_validator2 = require("class-validator");
|
|
646
|
+
function _ts_decorate7(decorators, target, key, desc3) {
|
|
647
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
648
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
649
|
+
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;
|
|
650
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
651
|
+
}
|
|
652
|
+
__name(_ts_decorate7, "_ts_decorate");
|
|
653
|
+
function _ts_metadata6(k, v) {
|
|
654
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
655
|
+
}
|
|
656
|
+
__name(_ts_metadata6, "_ts_metadata");
|
|
657
|
+
var SuccessResponseDto = class {
|
|
658
|
+
static {
|
|
659
|
+
__name(this, "SuccessResponseDto");
|
|
660
|
+
}
|
|
661
|
+
success;
|
|
662
|
+
message;
|
|
663
|
+
};
|
|
664
|
+
_ts_decorate7([
|
|
665
|
+
(0, import_swagger5.ApiProperty)({
|
|
666
|
+
example: true
|
|
667
|
+
}),
|
|
668
|
+
(0, import_class_validator2.IsNotEmpty)(),
|
|
669
|
+
(0, import_class_validator2.IsBoolean)(),
|
|
670
|
+
_ts_metadata6("design:type", Boolean)
|
|
671
|
+
], SuccessResponseDto.prototype, "success", void 0);
|
|
672
|
+
_ts_decorate7([
|
|
673
|
+
(0, import_swagger5.ApiProperty)({
|
|
674
|
+
example: "Operation completed successfully"
|
|
675
|
+
}),
|
|
676
|
+
(0, import_class_validator2.IsNotEmpty)(),
|
|
677
|
+
(0, import_class_validator2.IsString)(),
|
|
678
|
+
_ts_metadata6("design:type", String)
|
|
679
|
+
], SuccessResponseDto.prototype, "message", void 0);
|
|
680
|
+
|
|
681
|
+
// src/database/dto/table-response.dto.ts
|
|
682
|
+
var import_swagger6 = require("@nestjs/swagger");
|
|
683
|
+
function _ts_decorate8(decorators, target, key, desc3) {
|
|
684
|
+
var c = arguments.length, r = c < 3 ? target : desc3 === null ? desc3 = Object.getOwnPropertyDescriptor(target, key) : desc3, d;
|
|
685
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc3);
|
|
686
|
+
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;
|
|
687
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
688
|
+
}
|
|
689
|
+
__name(_ts_decorate8, "_ts_decorate");
|
|
690
|
+
function _ts_metadata7(k, v) {
|
|
691
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
692
|
+
}
|
|
693
|
+
__name(_ts_metadata7, "_ts_metadata");
|
|
694
|
+
var TableResponseDto = class {
|
|
695
|
+
static {
|
|
696
|
+
__name(this, "TableResponseDto");
|
|
697
|
+
}
|
|
698
|
+
result;
|
|
699
|
+
count;
|
|
700
|
+
state;
|
|
701
|
+
activeViewId;
|
|
702
|
+
};
|
|
703
|
+
_ts_decorate8([
|
|
704
|
+
(0, import_swagger6.ApiProperty)(),
|
|
705
|
+
_ts_metadata7("design:type", Array)
|
|
706
|
+
], TableResponseDto.prototype, "result", void 0);
|
|
707
|
+
_ts_decorate8([
|
|
708
|
+
(0, import_swagger6.ApiProperty)(),
|
|
709
|
+
_ts_metadata7("design:type", Number)
|
|
710
|
+
], TableResponseDto.prototype, "count", void 0);
|
|
711
|
+
_ts_decorate8([
|
|
712
|
+
(0, import_swagger6.ApiProperty)(),
|
|
713
|
+
_ts_metadata7("design:type", typeof TableViewState === "undefined" ? Object : TableViewState)
|
|
714
|
+
], TableResponseDto.prototype, "state", void 0);
|
|
715
|
+
_ts_decorate8([
|
|
716
|
+
(0, import_swagger6.ApiPropertyOptional)({
|
|
717
|
+
nullable: true
|
|
718
|
+
}),
|
|
719
|
+
_ts_metadata7("design:type", Object)
|
|
720
|
+
], TableResponseDto.prototype, "activeViewId", void 0);
|
|
721
|
+
|
|
722
|
+
// src/database/filter/cursor.codec.ts
|
|
723
|
+
var import_node_crypto = require("crypto");
|
|
724
|
+
|
|
725
|
+
// src/exceptions/bad-gateway.exception.ts
|
|
726
|
+
var import_common4 = require("@nestjs/common");
|
|
727
|
+
|
|
728
|
+
// src/exceptions/base-field.exception.ts
|
|
729
|
+
var import_common3 = require("@nestjs/common");
|
|
730
|
+
var HttpProblemException = class extends import_common3.HttpException {
|
|
731
|
+
static {
|
|
732
|
+
__name(this, "HttpProblemException");
|
|
733
|
+
}
|
|
734
|
+
constructor(detailOrOptions, httpStatus) {
|
|
735
|
+
const options = typeof detailOrOptions === "string" ? {
|
|
736
|
+
detail: detailOrOptions
|
|
737
|
+
} : detailOrOptions;
|
|
738
|
+
super({
|
|
739
|
+
type: options.type ?? "about:blank",
|
|
740
|
+
label: options.label,
|
|
741
|
+
detail: options.detail,
|
|
742
|
+
errors: options.errors ?? []
|
|
743
|
+
}, httpStatus);
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
// src/exceptions/bad-request.exception.ts
|
|
748
|
+
var import_common5 = require("@nestjs/common");
|
|
749
|
+
var BadRequestException = class extends HttpProblemException {
|
|
750
|
+
static {
|
|
751
|
+
__name(this, "BadRequestException");
|
|
752
|
+
}
|
|
753
|
+
constructor(detailOrOptions) {
|
|
754
|
+
super(detailOrOptions ?? "Bad Request", import_common5.HttpStatus.BAD_REQUEST);
|
|
755
|
+
}
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
// src/exceptions/conflict.exception.ts
|
|
759
|
+
var import_common6 = require("@nestjs/common");
|
|
760
|
+
|
|
761
|
+
// src/exceptions/forbidden.exception.ts
|
|
762
|
+
var import_common7 = require("@nestjs/common");
|
|
763
|
+
|
|
764
|
+
// src/exceptions/gone.exception.ts
|
|
765
|
+
var import_common8 = require("@nestjs/common");
|
|
766
|
+
|
|
767
|
+
// src/exceptions/internal-server-error.exception.ts
|
|
768
|
+
var import_common9 = require("@nestjs/common");
|
|
769
|
+
|
|
770
|
+
// src/exceptions/invalid-cursor.exception.ts
|
|
771
|
+
var InvalidCursorException = class extends BadRequestException {
|
|
772
|
+
static {
|
|
773
|
+
__name(this, "InvalidCursorException");
|
|
774
|
+
}
|
|
775
|
+
constructor(detail = "The pagination cursor is invalid.") {
|
|
776
|
+
super({
|
|
777
|
+
label: "Invalid cursor",
|
|
778
|
+
detail
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
// src/exceptions/method-not-allowed.exception.ts
|
|
784
|
+
var import_common10 = require("@nestjs/common");
|
|
785
|
+
|
|
786
|
+
// src/exceptions/not-acceptable.exception.ts
|
|
787
|
+
var import_common11 = require("@nestjs/common");
|
|
788
|
+
|
|
789
|
+
// src/exceptions/not-found.exception.ts
|
|
790
|
+
var import_common12 = require("@nestjs/common");
|
|
791
|
+
|
|
792
|
+
// src/exceptions/not-implemented.exception.ts
|
|
793
|
+
var import_common13 = require("@nestjs/common");
|
|
794
|
+
|
|
795
|
+
// src/exceptions/payload-too-large.exception.ts
|
|
796
|
+
var import_common14 = require("@nestjs/common");
|
|
797
|
+
|
|
798
|
+
// src/exceptions/request-timeout.exception.ts
|
|
799
|
+
var import_common15 = require("@nestjs/common");
|
|
800
|
+
|
|
801
|
+
// src/exceptions/service-unavailable.exception.ts
|
|
802
|
+
var import_common16 = require("@nestjs/common");
|
|
803
|
+
|
|
804
|
+
// src/exceptions/too-many-requests.exception.ts
|
|
805
|
+
var import_common17 = require("@nestjs/common");
|
|
806
|
+
|
|
807
|
+
// src/exceptions/unauthorized.exception.ts
|
|
808
|
+
var import_common18 = require("@nestjs/common");
|
|
809
|
+
|
|
810
|
+
// src/exceptions/unprocessable-entity.exception.ts
|
|
811
|
+
var import_common19 = require("@nestjs/common");
|
|
812
|
+
|
|
813
|
+
// src/exceptions/unsupported-media-type.exception.ts
|
|
814
|
+
var import_common20 = require("@nestjs/common");
|
|
815
|
+
|
|
816
|
+
// src/exceptions/validation.exception.ts
|
|
817
|
+
var import_common21 = require("@nestjs/common");
|
|
818
|
+
|
|
819
|
+
// src/database/filter/cursor.codec.ts
|
|
820
|
+
var CURSOR_SECRET = process.env.KEYSET_CURSOR_SECRET ?? "vritti-dev-insecure-keyset-secret";
|
|
821
|
+
function sign(body) {
|
|
822
|
+
return (0, import_node_crypto.createHmac)("sha256", CURSOR_SECRET).update(body).digest("base64url");
|
|
823
|
+
}
|
|
824
|
+
__name(sign, "sign");
|
|
825
|
+
var CursorCodec = class {
|
|
826
|
+
static {
|
|
827
|
+
__name(this, "CursorCodec");
|
|
828
|
+
}
|
|
829
|
+
// Encodes ORDER BY boundary values into a tamper-evident base64url token bound to the sort signature.
|
|
830
|
+
static encode(values, signature = "") {
|
|
831
|
+
const serialized = values.map((v) => {
|
|
832
|
+
if (v instanceof Date) return {
|
|
833
|
+
__t: "date",
|
|
834
|
+
v: v.toISOString()
|
|
835
|
+
};
|
|
836
|
+
if (v === null || v === void 0) return null;
|
|
837
|
+
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") return v;
|
|
838
|
+
return String(v);
|
|
839
|
+
});
|
|
840
|
+
const envelope = {
|
|
841
|
+
s: signature,
|
|
842
|
+
v: serialized
|
|
843
|
+
};
|
|
844
|
+
const body = Buffer.from(JSON.stringify(envelope), "utf8").toString("base64url");
|
|
845
|
+
return `${body}.${sign(body)}`;
|
|
846
|
+
}
|
|
847
|
+
// Decodes a cursor back into ordered boundary values, throwing InvalidCursorException on any tamper or sort mismatch.
|
|
848
|
+
static decode(cursor, expectedSignature = "") {
|
|
849
|
+
const dot = cursor.lastIndexOf(".");
|
|
850
|
+
if (dot <= 0) throw new InvalidCursorException("Malformed pagination cursor.");
|
|
851
|
+
const body = cursor.slice(0, dot);
|
|
852
|
+
const mac = cursor.slice(dot + 1);
|
|
853
|
+
const macBuf = Buffer.from(mac, "base64url");
|
|
854
|
+
const expBuf = Buffer.from(sign(body), "base64url");
|
|
855
|
+
if (macBuf.length !== expBuf.length || !(0, import_node_crypto.timingSafeEqual)(macBuf, expBuf)) {
|
|
856
|
+
throw new InvalidCursorException("Pagination cursor failed its integrity check.");
|
|
857
|
+
}
|
|
858
|
+
let envelope;
|
|
859
|
+
try {
|
|
860
|
+
envelope = JSON.parse(Buffer.from(body, "base64url").toString("utf8"));
|
|
861
|
+
} catch {
|
|
862
|
+
throw new InvalidCursorException("Pagination cursor could not be parsed.");
|
|
863
|
+
}
|
|
864
|
+
if (!envelope || typeof envelope.s !== "string" || !Array.isArray(envelope.v)) {
|
|
865
|
+
throw new InvalidCursorException("Pagination cursor has an unexpected shape.");
|
|
866
|
+
}
|
|
867
|
+
if (envelope.s !== expectedSignature) {
|
|
868
|
+
throw new InvalidCursorException("Pagination cursor does not match the current sort order.");
|
|
869
|
+
}
|
|
870
|
+
return envelope.v.map((v) => {
|
|
871
|
+
if (v && typeof v === "object" && "__t" in v && v.__t === "date") return new Date(v.v);
|
|
872
|
+
return v;
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
|
|
877
|
+
// src/database/filter/filter.processor.ts
|
|
878
|
+
var import_drizzle_orm = require("drizzle-orm");
|
|
879
|
+
var FilterProcessor = class {
|
|
880
|
+
static {
|
|
881
|
+
__name(this, "FilterProcessor");
|
|
882
|
+
}
|
|
883
|
+
// Returns undefined if no conditions (Drizzle accepts undefined as "no WHERE")
|
|
884
|
+
static buildWhere(filters = [], fieldMap) {
|
|
885
|
+
const conditions = filters.flatMap((f) => {
|
|
886
|
+
const def = fieldMap[f.field];
|
|
887
|
+
if (!def) return [];
|
|
888
|
+
if ("expression" in def) return Array.isArray(f.value) ? [] : [
|
|
889
|
+
def.expression(f.value, f.operator)
|
|
890
|
+
];
|
|
891
|
+
const { column: col } = def;
|
|
892
|
+
const val = f.value;
|
|
893
|
+
switch (f.operator) {
|
|
894
|
+
case "equals":
|
|
895
|
+
if (def.type === "boolean") return [
|
|
896
|
+
(0, import_drizzle_orm.eq)(col, val === "true" || val === 1)
|
|
897
|
+
];
|
|
898
|
+
return [
|
|
899
|
+
(0, import_drizzle_orm.eq)(col, val)
|
|
900
|
+
];
|
|
901
|
+
case "notEquals":
|
|
902
|
+
if (def.type === "boolean") return [
|
|
903
|
+
(0, import_drizzle_orm.ne)(col, val === "true" || val === 1)
|
|
904
|
+
];
|
|
905
|
+
return [
|
|
906
|
+
(0, import_drizzle_orm.ne)(col, val)
|
|
907
|
+
];
|
|
908
|
+
case "contains":
|
|
909
|
+
return [
|
|
910
|
+
(0, import_drizzle_orm.ilike)(col, `%${val}%`)
|
|
911
|
+
];
|
|
912
|
+
case "notContains":
|
|
913
|
+
return [
|
|
914
|
+
(0, import_drizzle_orm.notIlike)(col, `%${val}%`)
|
|
915
|
+
];
|
|
916
|
+
case "gt":
|
|
917
|
+
return [
|
|
918
|
+
(0, import_drizzle_orm.gt)(col, val)
|
|
919
|
+
];
|
|
920
|
+
case "gte":
|
|
921
|
+
return [
|
|
922
|
+
(0, import_drizzle_orm.gte)(col, val)
|
|
923
|
+
];
|
|
924
|
+
case "lt":
|
|
925
|
+
return [
|
|
926
|
+
(0, import_drizzle_orm.lt)(col, val)
|
|
927
|
+
];
|
|
928
|
+
case "lte":
|
|
929
|
+
return [
|
|
930
|
+
(0, import_drizzle_orm.lte)(col, val)
|
|
931
|
+
];
|
|
932
|
+
case "isAnyOf":
|
|
933
|
+
return [
|
|
934
|
+
(0, import_drizzle_orm.inArray)(col, Array.isArray(val) ? val : [
|
|
935
|
+
String(val)
|
|
936
|
+
])
|
|
937
|
+
];
|
|
938
|
+
case "isNotAnyOf":
|
|
939
|
+
return [
|
|
940
|
+
(0, import_drizzle_orm.notInArray)(col, Array.isArray(val) ? val : [
|
|
941
|
+
String(val)
|
|
942
|
+
])
|
|
943
|
+
];
|
|
944
|
+
default:
|
|
945
|
+
return [];
|
|
946
|
+
}
|
|
947
|
+
});
|
|
948
|
+
return conditions.length ? (0, import_drizzle_orm.and)(...conditions) : void 0;
|
|
949
|
+
}
|
|
950
|
+
// Builds a search WHERE — OR across all string fields when columnId is 'all', otherwise a single ilike
|
|
951
|
+
static buildSearch(search, fieldMap) {
|
|
952
|
+
if (!search?.value) return void 0;
|
|
953
|
+
if (search.columnId === "all") {
|
|
954
|
+
const conditions = Object.values(fieldMap).filter((def2) => "column" in def2 && def2.type === "string").map((def2) => (0, import_drizzle_orm.ilike)(def2.column, `%${search.value}%`));
|
|
955
|
+
return conditions.length ? (0, import_drizzle_orm.or)(...conditions) : void 0;
|
|
956
|
+
}
|
|
957
|
+
const def = fieldMap[search.columnId];
|
|
958
|
+
if (!def || !("column" in def)) return void 0;
|
|
959
|
+
return (0, import_drizzle_orm.ilike)(def.column, `%${search.value}%`);
|
|
960
|
+
}
|
|
961
|
+
// Maps each SortCondition to an asc/desc SQL expression
|
|
962
|
+
static buildOrderBy(sort = [], fieldMap) {
|
|
963
|
+
return sort.flatMap((s) => {
|
|
964
|
+
const def = fieldMap[s.field];
|
|
965
|
+
if (!def || !("column" in def)) return [];
|
|
966
|
+
return [
|
|
967
|
+
s.direction === "asc" ? (0, import_drizzle_orm.asc)(def.column) : (0, import_drizzle_orm.desc)(def.column)
|
|
968
|
+
];
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
|
|
973
|
+
// src/database/filter/filter.types.ts
|
|
974
|
+
var FilterOperators = {
|
|
975
|
+
EQUALS: "equals",
|
|
976
|
+
NOT_EQUALS: "notEquals",
|
|
977
|
+
CONTAINS: "contains",
|
|
978
|
+
NOT_CONTAINS: "notContains",
|
|
979
|
+
GT: "gt",
|
|
980
|
+
GTE: "gte",
|
|
981
|
+
LT: "lt",
|
|
982
|
+
LTE: "lte",
|
|
983
|
+
IS_ANY_OF: "isAnyOf",
|
|
984
|
+
IS_NOT_ANY_OF: "isNotAnyOf"
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
// src/database/filter/keyset.processor.ts
|
|
988
|
+
var import_drizzle_orm2 = require("drizzle-orm");
|
|
989
|
+
var MAX_PAGE_SIZE = 100;
|
|
990
|
+
function keysetSignature(entries) {
|
|
991
|
+
return entries.map((e) => `${e.key}:${e.direction}`).join(",");
|
|
992
|
+
}
|
|
993
|
+
__name(keysetSignature, "keysetSignature");
|
|
994
|
+
var KeysetProcessor = class _KeysetProcessor {
|
|
995
|
+
static {
|
|
996
|
+
__name(this, "KeysetProcessor");
|
|
997
|
+
}
|
|
998
|
+
// Builds the "after this row" predicate for keyset pagination.
|
|
999
|
+
static buildAfter(orderBy, values) {
|
|
1000
|
+
const first = orderBy[0];
|
|
1001
|
+
if (!first) return import_drizzle_orm2.sql`true`;
|
|
1002
|
+
const uniform = orderBy.every((o) => o.direction === first.direction);
|
|
1003
|
+
const anyNullable = orderBy.some((o) => o.nulls !== void 0);
|
|
1004
|
+
if (uniform && !anyNullable && orderBy.length >= 2) {
|
|
1005
|
+
return _KeysetProcessor.buildRowValue(orderBy, values, first.direction);
|
|
1006
|
+
}
|
|
1007
|
+
return _KeysetProcessor.buildOrExpansion(orderBy, values);
|
|
1008
|
+
}
|
|
1009
|
+
// (c1, c2, …) > (v1, v2, …) for asc, < for desc. Correct only for uniform direction, no NULLs.
|
|
1010
|
+
static buildRowValue(orderBy, values, direction) {
|
|
1011
|
+
const cols = import_drizzle_orm2.sql.join(orderBy.map((o) => import_drizzle_orm2.sql`${o.column}`), import_drizzle_orm2.sql`, `);
|
|
1012
|
+
const vals = import_drizzle_orm2.sql.join(values.map((v) => import_drizzle_orm2.sql`${v}`), import_drizzle_orm2.sql`, `);
|
|
1013
|
+
const op = direction === "asc" ? import_drizzle_orm2.sql`>` : import_drizzle_orm2.sql`<`;
|
|
1014
|
+
return import_drizzle_orm2.sql`(${cols}) ${op} (${vals})`;
|
|
1015
|
+
}
|
|
1016
|
+
// Lexicographic OR-expansion, NULL-aware per column when a `nulls` placement is declared.
|
|
1017
|
+
static buildOrExpansion(orderBy, values) {
|
|
1018
|
+
const groups = [];
|
|
1019
|
+
for (let i = 0; i < orderBy.length; i++) {
|
|
1020
|
+
const current = orderBy[i];
|
|
1021
|
+
if (!current) continue;
|
|
1022
|
+
const conditions = [];
|
|
1023
|
+
for (let j = 0; j < i; j++) {
|
|
1024
|
+
const prior = orderBy[j];
|
|
1025
|
+
if (prior) conditions.push(_KeysetProcessor.tie(prior.column, values[j]));
|
|
1026
|
+
}
|
|
1027
|
+
conditions.push(_KeysetProcessor.strictlyAfter(current, values[i]));
|
|
1028
|
+
const group = conditions.length === 1 ? conditions[0] : (0, import_drizzle_orm2.and)(...conditions);
|
|
1029
|
+
if (group) groups.push(group);
|
|
1030
|
+
}
|
|
1031
|
+
const firstGroup = groups[0];
|
|
1032
|
+
if (groups.length === 1 && firstGroup) return firstGroup;
|
|
1033
|
+
return (0, import_drizzle_orm2.or)(...groups);
|
|
1034
|
+
}
|
|
1035
|
+
// Tie on an earlier column: match its boundary value (NULL-safe).
|
|
1036
|
+
static tie(column, value) {
|
|
1037
|
+
return value === null || value === void 0 ? (0, import_drizzle_orm2.isNull)(column) : (0, import_drizzle_orm2.eq)(column, value);
|
|
1038
|
+
}
|
|
1039
|
+
// Strictly past the boundary on this column, respecting direction and NULL placement.
|
|
1040
|
+
static strictlyAfter(o, value) {
|
|
1041
|
+
if (o.nulls === void 0) {
|
|
1042
|
+
return o.direction === "asc" ? (0, import_drizzle_orm2.gt)(o.column, value) : (0, import_drizzle_orm2.lt)(o.column, value);
|
|
1043
|
+
}
|
|
1044
|
+
const nullsLast = o.nulls === "last";
|
|
1045
|
+
if (value === null || value === void 0) {
|
|
1046
|
+
return nullsLast ? import_drizzle_orm2.sql`false` : (0, import_drizzle_orm2.isNotNull)(o.column);
|
|
1047
|
+
}
|
|
1048
|
+
const cmp = o.direction === "asc" ? (0, import_drizzle_orm2.gt)(o.column, value) : (0, import_drizzle_orm2.lt)(o.column, value);
|
|
1049
|
+
return nullsLast ? (0, import_drizzle_orm2.or)(cmp, (0, import_drizzle_orm2.isNull)(o.column)) : cmp;
|
|
1050
|
+
}
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
// src/database/repositories/primary-base.repository.ts
|
|
1054
|
+
var import_common22 = require("@nestjs/common");
|
|
1055
|
+
var import_drizzle_orm3 = require("drizzle-orm");
|
|
1056
|
+
var import_view_base = require("drizzle-orm/pg-core/view-base");
|
|
1057
|
+
function snakeToCamel(str) {
|
|
1058
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
1059
|
+
}
|
|
1060
|
+
__name(snakeToCamel, "snakeToCamel");
|
|
1061
|
+
var PrimaryBaseRepository = class {
|
|
1062
|
+
static {
|
|
1063
|
+
__name(this, "PrimaryBaseRepository");
|
|
1064
|
+
}
|
|
1065
|
+
database;
|
|
1066
|
+
table;
|
|
1067
|
+
logger;
|
|
1068
|
+
sequence;
|
|
1069
|
+
tableName;
|
|
1070
|
+
isView;
|
|
1071
|
+
get db() {
|
|
1072
|
+
return this.database.drizzleClient;
|
|
1073
|
+
}
|
|
1074
|
+
get model() {
|
|
1075
|
+
if (this.isView) {
|
|
1076
|
+
throw new Error(`${this.constructor.name}: relational queries (.model) are not supported on the view '${this.tableName}'. Use findForSelect / findAllAndCount instead.`);
|
|
1077
|
+
}
|
|
1078
|
+
const query = this.database.drizzleClient.query;
|
|
1079
|
+
const queryKeys = Object.keys(query || {});
|
|
1080
|
+
this.logger.debug(`Looking for '${this.tableName}' in query keys: [${queryKeys.join(", ")}]`);
|
|
1081
|
+
const model = query[this.tableName];
|
|
1082
|
+
if (!model) {
|
|
1083
|
+
this.logger.error(`Table '${this.tableName}' not found in query object. Available: [${queryKeys.join(", ")}]`);
|
|
1084
|
+
}
|
|
1085
|
+
return model;
|
|
1086
|
+
}
|
|
1087
|
+
constructor(database, table, options) {
|
|
1088
|
+
this.database = database;
|
|
1089
|
+
this.table = table;
|
|
1090
|
+
this.isView = (0, import_drizzle_orm3.is)(table, import_view_base.PgViewBase);
|
|
1091
|
+
const dbTableName = this.isView ? (0, import_drizzle_orm3.getViewName)(table) : (0, import_drizzle_orm3.getTableName)(table);
|
|
1092
|
+
this.tableName = snakeToCamel(dbTableName);
|
|
1093
|
+
this.sequence = options?.sequence;
|
|
1094
|
+
this.logger = new import_common22.Logger(this.constructor.name);
|
|
1095
|
+
this.logger.debug(`Initialized ${this.constructor.name}`);
|
|
1096
|
+
this.logger.debug(`Table name: '${dbTableName}' -> query key: '${this.tableName}'`);
|
|
1097
|
+
}
|
|
1098
|
+
// Returns next value from configured sequence, or an explicitly passed sequence
|
|
1099
|
+
async nextSequenceValue(sequence) {
|
|
1100
|
+
const resolvedSequence = sequence ?? this.sequence;
|
|
1101
|
+
if (!resolvedSequence) {
|
|
1102
|
+
throw new Error(`${this.constructor.name}: sequence is required for nextSequenceValue`);
|
|
1103
|
+
}
|
|
1104
|
+
const sequenceName = resolvedSequence.schema ? `${resolvedSequence.schema}.${resolvedSequence.seqName}` : resolvedSequence.seqName;
|
|
1105
|
+
const result = await this.db.execute(import_drizzle_orm3.sql`select nextval(${sequenceName}::regclass) as sequence_value`);
|
|
1106
|
+
const rows = result.rows ?? [];
|
|
1107
|
+
return Number(rows[0]?.sequence_value ?? 1);
|
|
1108
|
+
}
|
|
1109
|
+
// Creates a new record and returns it
|
|
1110
|
+
async create(data, tx) {
|
|
1111
|
+
this.logger.log("Creating record");
|
|
1112
|
+
const db = tx ?? this.db;
|
|
1113
|
+
const results = await db.insert(this.table).values(data).returning();
|
|
1114
|
+
const record = results[0];
|
|
1115
|
+
if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
|
|
1116
|
+
return record;
|
|
1117
|
+
}
|
|
1118
|
+
// Finds a single record by primary key ID
|
|
1119
|
+
async findById(id) {
|
|
1120
|
+
this.logger.debug(`Finding record by ID: ${id}`);
|
|
1121
|
+
return this.model.findFirst({
|
|
1122
|
+
where: {
|
|
1123
|
+
id
|
|
1124
|
+
}
|
|
1125
|
+
});
|
|
1126
|
+
}
|
|
1127
|
+
// Finds a single record matching the given where filter
|
|
1128
|
+
async findOne(where) {
|
|
1129
|
+
this.logger.debug("Finding record with custom query");
|
|
1130
|
+
return this.model.findFirst({
|
|
1131
|
+
where
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
// Finds multiple records with optional filtering, ordering, and pagination
|
|
1135
|
+
async findMany(options) {
|
|
1136
|
+
this.logger.debug("Finding multiple records");
|
|
1137
|
+
return this.model.findMany(options);
|
|
1138
|
+
}
|
|
1139
|
+
// Builds a select query with optional custom fields, joins, filter, grouping, ordering, and pagination
|
|
1140
|
+
buildSelectQuery(options) {
|
|
1141
|
+
let query = (options?.select ? this.db.select(options.select).from(this.table) : this.db.select().from(this.table)).$dynamic();
|
|
1142
|
+
if (options?.leftJoin) {
|
|
1143
|
+
query = query.leftJoin(options.leftJoin.table, options.leftJoin.on);
|
|
1144
|
+
}
|
|
1145
|
+
if (options?.leftJoins) {
|
|
1146
|
+
for (const join of options.leftJoins) {
|
|
1147
|
+
query = query.leftJoin(join.table, join.on);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
if (options?.where) {
|
|
1151
|
+
query = query.where(options.where);
|
|
1152
|
+
}
|
|
1153
|
+
if (options?.groupBy?.length) {
|
|
1154
|
+
query = query.groupBy(...options.groupBy);
|
|
1155
|
+
}
|
|
1156
|
+
if (options?.orderBy?.length) {
|
|
1157
|
+
query = query.orderBy(...options.orderBy);
|
|
1158
|
+
}
|
|
1159
|
+
if (options?.limit) {
|
|
1160
|
+
query = query.limit(options.limit);
|
|
1161
|
+
}
|
|
1162
|
+
if (options?.offset) {
|
|
1163
|
+
query = query.offset(options.offset);
|
|
1164
|
+
}
|
|
1165
|
+
return query;
|
|
1166
|
+
}
|
|
1167
|
+
// Returns paginated result and total count, with optional custom select, LEFT JOINs, GROUP BY, and ordering
|
|
1168
|
+
async findAllAndCount(options) {
|
|
1169
|
+
let countResultPromise;
|
|
1170
|
+
if (options?.groupBy?.length) {
|
|
1171
|
+
let subq = this.db.select({
|
|
1172
|
+
_: import_drizzle_orm3.sql`1`
|
|
1173
|
+
}).from(this.table).$dynamic();
|
|
1174
|
+
if (options.leftJoin) {
|
|
1175
|
+
subq = subq.leftJoin(options.leftJoin.table, options.leftJoin.on);
|
|
1176
|
+
}
|
|
1177
|
+
if (options.leftJoins) {
|
|
1178
|
+
for (const join of options.leftJoins) {
|
|
1179
|
+
subq = subq.leftJoin(join.table, join.on);
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
if (options.where) {
|
|
1183
|
+
subq = subq.where(options.where);
|
|
1184
|
+
}
|
|
1185
|
+
subq = subq.groupBy(...options.groupBy);
|
|
1186
|
+
const named = subq.as("_count_subq");
|
|
1187
|
+
countResultPromise = this.db.select({
|
|
1188
|
+
count: import_drizzle_orm3.sql`count(*)::int`
|
|
1189
|
+
}).from(named);
|
|
1190
|
+
} else {
|
|
1191
|
+
let countQuery = this.db.select({
|
|
1192
|
+
count: import_drizzle_orm3.sql`count(*)::int`
|
|
1193
|
+
}).from(this.table).$dynamic();
|
|
1194
|
+
if (options?.leftJoin) {
|
|
1195
|
+
countQuery = countQuery.leftJoin(options.leftJoin.table, options.leftJoin.on);
|
|
1196
|
+
}
|
|
1197
|
+
if (options?.leftJoins) {
|
|
1198
|
+
for (const join of options.leftJoins) {
|
|
1199
|
+
countQuery = countQuery.leftJoin(join.table, join.on);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
if (options?.where) {
|
|
1203
|
+
countQuery = countQuery.where(options.where);
|
|
1204
|
+
}
|
|
1205
|
+
countResultPromise = countQuery;
|
|
1206
|
+
}
|
|
1207
|
+
const [countResult, result] = await Promise.all([
|
|
1208
|
+
countResultPromise,
|
|
1209
|
+
this.buildSelectQuery(options)
|
|
1210
|
+
]);
|
|
1211
|
+
return {
|
|
1212
|
+
result,
|
|
1213
|
+
count: countResult[0].count
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
// Fetches limit+1 rows for keyset pagination and trims, returning rows plus hasMore.
|
|
1217
|
+
async findKeyset(options) {
|
|
1218
|
+
const limit = Math.min(Math.max(1, Math.trunc(options.limit) || 1), MAX_PAGE_SIZE);
|
|
1219
|
+
const rows = await this.buildSelectQuery({
|
|
1220
|
+
...options,
|
|
1221
|
+
limit: limit + 1
|
|
1222
|
+
});
|
|
1223
|
+
const hasMore = rows.length > limit;
|
|
1224
|
+
return {
|
|
1225
|
+
rows: hasMore ? rows.slice(0, limit) : rows,
|
|
1226
|
+
hasMore
|
|
1227
|
+
};
|
|
1228
|
+
}
|
|
1229
|
+
// Updates a record by ID and returns the updated record
|
|
1230
|
+
async update(id, data, tx) {
|
|
1231
|
+
this.logger.log(`Updating record with ID: ${id}`);
|
|
1232
|
+
const db = tx ?? this.db;
|
|
1233
|
+
const idColumn = this.table.id;
|
|
1234
|
+
if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
|
|
1235
|
+
const results = await db.update(this.table).set(data).where((0, import_drizzle_orm3.eq)(idColumn, id)).returning();
|
|
1236
|
+
const record = results[0];
|
|
1237
|
+
if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
|
|
1238
|
+
return record;
|
|
1239
|
+
}
|
|
1240
|
+
// Updates all records matching the SQL condition and returns the affected count
|
|
1241
|
+
async updateMany(where, data, tx) {
|
|
1242
|
+
this.logger.log("Updating multiple records");
|
|
1243
|
+
const db = tx ?? this.db;
|
|
1244
|
+
const result = await db.update(this.table).set(data).where(where);
|
|
1245
|
+
return {
|
|
1246
|
+
count: result.rowCount ?? 0
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1249
|
+
// Deletes a record by ID and returns the deleted record
|
|
1250
|
+
async delete(id, tx) {
|
|
1251
|
+
this.logger.log(`Deleting record with ID: ${id}`);
|
|
1252
|
+
const db = tx ?? this.db;
|
|
1253
|
+
const idColumn = this.table.id;
|
|
1254
|
+
if (!idColumn) throw new Error(`Table '${this.tableName}' has no 'id' column`);
|
|
1255
|
+
const results = await db.delete(this.table).where((0, import_drizzle_orm3.eq)(idColumn, id)).returning();
|
|
1256
|
+
const record = results[0];
|
|
1257
|
+
if (!record) throw new Error(`${this.tableName}: database operation returned no record`);
|
|
1258
|
+
return record;
|
|
1259
|
+
}
|
|
1260
|
+
// Deletes all records matching the SQL condition and returns the affected count
|
|
1261
|
+
async deleteMany(where, tx) {
|
|
1262
|
+
this.logger.log("Deleting multiple records");
|
|
1263
|
+
const db = tx ?? this.db;
|
|
1264
|
+
const result = await db.delete(this.table).where(where);
|
|
1265
|
+
return {
|
|
1266
|
+
count: result.rowCount ?? 0
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
// Counts records matching the optional SQL condition
|
|
1270
|
+
async count(where) {
|
|
1271
|
+
this.logger.debug("Counting records");
|
|
1272
|
+
let query = this.db.select({
|
|
1273
|
+
count: import_drizzle_orm3.sql`count(*)::int`
|
|
1274
|
+
}).from(this.table).$dynamic();
|
|
1275
|
+
if (where) {
|
|
1276
|
+
query = query.where(where);
|
|
1277
|
+
}
|
|
1278
|
+
const results = await query;
|
|
1279
|
+
return results[0].count;
|
|
1280
|
+
}
|
|
1281
|
+
// Returns true if at least one record matches the SQL condition
|
|
1282
|
+
async exists(where) {
|
|
1283
|
+
const count = await this.count(where);
|
|
1284
|
+
return count > 0;
|
|
1285
|
+
}
|
|
1286
|
+
// Executes the callback within a database transaction, applying the ALS RLS context once at BEGIN.
|
|
1287
|
+
async transaction(callback) {
|
|
1288
|
+
return this.database.runInTransaction(async () => callback(this.database.drizzleClient));
|
|
1289
|
+
}
|
|
1290
|
+
// Finds records formatted as select dropdown options with optional search, pagination, and grouping
|
|
1291
|
+
async findForSelect(config) {
|
|
1292
|
+
this.logger.debug("Finding records for select dropdown");
|
|
1293
|
+
const selectFn = config.distinct ? this.db.selectDistinct.bind(this.db) : this.db.select.bind(this.db);
|
|
1294
|
+
const parsedValues = typeof config.values === "string" ? config.values.split(",").map((v) => v.trim()).filter(Boolean) : config.values;
|
|
1295
|
+
const parsedExcludeIds = typeof config.excludeIds === "string" ? config.excludeIds.split(",").map((v) => v.trim()).filter(Boolean) : config.excludeIds ?? [];
|
|
1296
|
+
const tableColumns = this.table;
|
|
1297
|
+
const joinTables = config.joins?.map((join) => join.table) ?? [];
|
|
1298
|
+
const resolveColumn = /* @__PURE__ */ __name((key) => {
|
|
1299
|
+
if (tableColumns[key]) return tableColumns[key];
|
|
1300
|
+
for (const joinColumns of joinTables) {
|
|
1301
|
+
if (joinColumns[key]) return joinColumns[key];
|
|
1302
|
+
}
|
|
1303
|
+
return void 0;
|
|
1304
|
+
}, "resolveColumn");
|
|
1305
|
+
const valueCol = resolveColumn(config.value);
|
|
1306
|
+
if (!valueCol) throw new Error(`Column '${config.value}' not found in table '${this.tableName}' or its joins`);
|
|
1307
|
+
const labelCol = resolveColumn(config.label);
|
|
1308
|
+
if (!labelCol) throw new Error(`Column '${config.label}' not found in table '${this.tableName}' or its joins`);
|
|
1309
|
+
const descriptionCol = config.description ? resolveColumn(config.description) : void 0;
|
|
1310
|
+
const parseKeys = /* @__PURE__ */ __name((input) => {
|
|
1311
|
+
if (!input) return [];
|
|
1312
|
+
const values = Array.isArray(input) ? input : input.split(",");
|
|
1313
|
+
return values.map((v) => v.trim()).filter(Boolean);
|
|
1314
|
+
}, "parseKeys");
|
|
1315
|
+
const additionalKeys = parseKeys(config.additionalKeys);
|
|
1316
|
+
const additionalEntries = [
|
|
1317
|
+
...additionalKeys.map((key) => ({
|
|
1318
|
+
key,
|
|
1319
|
+
expr: resolveColumn(key)
|
|
1320
|
+
})).filter((e) => Boolean(e.expr)),
|
|
1321
|
+
...Object.entries(config.additionalExpressions ?? {}).map(([key, expr]) => ({
|
|
1322
|
+
key,
|
|
1323
|
+
expr
|
|
1324
|
+
}))
|
|
1325
|
+
];
|
|
1326
|
+
const additionalAlias = /* @__PURE__ */ __name((key) => `__additional_${key}`, "additionalAlias");
|
|
1327
|
+
if (parsedValues && parsedValues.length > 0) {
|
|
1328
|
+
const selectCols = {
|
|
1329
|
+
value: valueCol,
|
|
1330
|
+
label: labelCol
|
|
1331
|
+
};
|
|
1332
|
+
if (descriptionCol) selectCols.description = descriptionCol;
|
|
1333
|
+
if (config.groupIdKey) {
|
|
1334
|
+
const groupIdCol = resolveColumn(config.groupIdKey);
|
|
1335
|
+
if (groupIdCol) selectCols.groupId = groupIdCol;
|
|
1336
|
+
}
|
|
1337
|
+
for (const entry of additionalEntries) {
|
|
1338
|
+
selectCols[additionalAlias(entry.key)] = entry.expr;
|
|
1339
|
+
}
|
|
1340
|
+
let valuesQuery = selectFn(selectCols).from(this.table).$dynamic();
|
|
1341
|
+
if (config.joins) {
|
|
1342
|
+
for (const join of config.joins) {
|
|
1343
|
+
if (join.type === "inner") {
|
|
1344
|
+
valuesQuery = valuesQuery.innerJoin(join.table, join.on);
|
|
1345
|
+
} else {
|
|
1346
|
+
valuesQuery = valuesQuery.leftJoin(join.table, join.on);
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
const rows2 = await valuesQuery.where((0, import_drizzle_orm3.inArray)(valueCol, parsedValues));
|
|
1351
|
+
return {
|
|
1352
|
+
options: rows2.map((row) => ({
|
|
1353
|
+
value: row.value,
|
|
1354
|
+
label: String(row.label),
|
|
1355
|
+
...descriptionCol && row.description != null ? {
|
|
1356
|
+
description: String(row.description)
|
|
1357
|
+
} : {},
|
|
1358
|
+
...config.groupIdKey && row.groupId != null ? {
|
|
1359
|
+
groupId: row.groupId
|
|
1360
|
+
} : {},
|
|
1361
|
+
...additionalEntries.length > 0 ? {
|
|
1362
|
+
additionals: additionalEntries.reduce((acc, entry) => {
|
|
1363
|
+
const value = row[additionalAlias(entry.key)];
|
|
1364
|
+
if (value !== void 0) {
|
|
1365
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
1366
|
+
acc[entry.key] = value;
|
|
1367
|
+
} else {
|
|
1368
|
+
acc[entry.key] = String(value);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return acc;
|
|
1372
|
+
}, {})
|
|
1373
|
+
} : {}
|
|
1374
|
+
})),
|
|
1375
|
+
hasMore: false,
|
|
1376
|
+
...config.groups ? {
|
|
1377
|
+
groups: config.groups
|
|
1378
|
+
} : {}
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
const selectFields = {
|
|
1382
|
+
value: valueCol,
|
|
1383
|
+
label: labelCol,
|
|
1384
|
+
totalCount: import_drizzle_orm3.sql`count(*) over()`.mapWith(Number)
|
|
1385
|
+
};
|
|
1386
|
+
if (descriptionCol) selectFields.description = descriptionCol;
|
|
1387
|
+
if (config.groupIdKey) {
|
|
1388
|
+
const groupIdCol = resolveColumn(config.groupIdKey);
|
|
1389
|
+
if (groupIdCol) selectFields.groupId = groupIdCol;
|
|
1390
|
+
}
|
|
1391
|
+
for (const entry of additionalEntries) {
|
|
1392
|
+
selectFields[additionalAlias(entry.key)] = entry.expr;
|
|
1393
|
+
}
|
|
1394
|
+
const conditions = [];
|
|
1395
|
+
if (config.search) {
|
|
1396
|
+
conditions.push((0, import_drizzle_orm3.ilike)(labelCol, `%${config.search}%`));
|
|
1397
|
+
}
|
|
1398
|
+
if (parsedExcludeIds.length > 0) {
|
|
1399
|
+
conditions.push((0, import_drizzle_orm3.notInArray)(valueCol, parsedExcludeIds));
|
|
1400
|
+
}
|
|
1401
|
+
if (config.where) {
|
|
1402
|
+
for (const [field, val] of Object.entries(config.where)) {
|
|
1403
|
+
const column = tableColumns[field];
|
|
1404
|
+
if (column) {
|
|
1405
|
+
conditions.push((0, import_drizzle_orm3.eq)(column, val));
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
if (config.conditions) {
|
|
1410
|
+
conditions.push(...config.conditions);
|
|
1411
|
+
}
|
|
1412
|
+
const orderByKey = config.orderByKey || (config.orderBy ? Object.keys(config.orderBy)[0] : void 0);
|
|
1413
|
+
const orderDirection = config.orderDirection || (config.orderBy ? Object.values(config.orderBy)[0] : void 0);
|
|
1414
|
+
const orderByCol = orderByKey ? tableColumns[orderByKey] ?? labelCol : labelCol;
|
|
1415
|
+
const limit = Number(config.limit) || 20;
|
|
1416
|
+
const offset = Number(config.offset) || 0;
|
|
1417
|
+
let query = selectFn(selectFields).from(this.table).$dynamic();
|
|
1418
|
+
if (config.joins) {
|
|
1419
|
+
for (const join of config.joins) {
|
|
1420
|
+
if (join.type === "inner") {
|
|
1421
|
+
query = query.innerJoin(join.table, join.on);
|
|
1422
|
+
} else {
|
|
1423
|
+
query = query.leftJoin(join.table, join.on);
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
if (conditions.length > 0) {
|
|
1428
|
+
query = query.where(conditions.length === 1 ? conditions[0] : (0, import_drizzle_orm3.and)(...conditions));
|
|
1429
|
+
}
|
|
1430
|
+
const orderClauses = [];
|
|
1431
|
+
if (config.groupIdKey) {
|
|
1432
|
+
const groupIdCol = resolveColumn(config.groupIdKey);
|
|
1433
|
+
if (groupIdCol) orderClauses.push((0, import_drizzle_orm3.asc)(groupIdCol));
|
|
1434
|
+
}
|
|
1435
|
+
orderClauses.push(orderDirection === "desc" ? (0, import_drizzle_orm3.desc)(orderByCol) : (0, import_drizzle_orm3.asc)(orderByCol));
|
|
1436
|
+
query = query.orderBy(...orderClauses).limit(limit).offset(offset);
|
|
1437
|
+
const rows = await query;
|
|
1438
|
+
const totalCount = rows.length > 0 ? rows[0].totalCount : 0;
|
|
1439
|
+
const options = rows.map((row) => ({
|
|
1440
|
+
value: row.value,
|
|
1441
|
+
label: String(row.label),
|
|
1442
|
+
...descriptionCol && row.description != null ? {
|
|
1443
|
+
description: String(row.description)
|
|
1444
|
+
} : {},
|
|
1445
|
+
...config.groupIdKey && row.groupId != null ? {
|
|
1446
|
+
groupId: row.groupId
|
|
1447
|
+
} : {},
|
|
1448
|
+
...additionalEntries.length > 0 ? {
|
|
1449
|
+
additionals: additionalEntries.reduce((acc, entry) => {
|
|
1450
|
+
const value = row[additionalAlias(entry.key)];
|
|
1451
|
+
if (value !== void 0) {
|
|
1452
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null) {
|
|
1453
|
+
acc[entry.key] = value;
|
|
1454
|
+
} else {
|
|
1455
|
+
acc[entry.key] = String(value);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
return acc;
|
|
1459
|
+
}, {})
|
|
1460
|
+
} : {}
|
|
1461
|
+
}));
|
|
1462
|
+
let resolvedGroups = config.groups;
|
|
1463
|
+
if (config.groupTable && config.groupIdKey) {
|
|
1464
|
+
const groupTableColumns = config.groupTable;
|
|
1465
|
+
const groupIdKey = config.groupTableIdKey ?? "id";
|
|
1466
|
+
const groupNameKey = config.groupLabelKey ?? "name";
|
|
1467
|
+
const groupIdCol = groupTableColumns[groupIdKey];
|
|
1468
|
+
if (!groupIdCol) throw new Error(`Column '${groupIdKey}' not found in group table`);
|
|
1469
|
+
const groupNameCol = groupTableColumns[groupNameKey];
|
|
1470
|
+
if (!groupNameCol) throw new Error(`Column '${groupNameKey}' not found in group table`);
|
|
1471
|
+
const groupRows = await this.db.select({
|
|
1472
|
+
id: groupIdCol,
|
|
1473
|
+
name: groupNameCol
|
|
1474
|
+
}).from(config.groupTable).orderBy((0, import_drizzle_orm3.asc)(groupNameCol));
|
|
1475
|
+
resolvedGroups = groupRows.map((r) => ({
|
|
1476
|
+
id: r.id,
|
|
1477
|
+
name: String(r.name)
|
|
1478
|
+
}));
|
|
1479
|
+
}
|
|
1480
|
+
return {
|
|
1481
|
+
options,
|
|
1482
|
+
hasMore: offset + limit < totalCount,
|
|
1483
|
+
totalCount,
|
|
1484
|
+
...resolvedGroups ? {
|
|
1485
|
+
groups: resolvedGroups
|
|
1486
|
+
} : {}
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
};
|
|
1490
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1491
|
+
0 && (module.exports = {
|
|
1492
|
+
CreateResponseDto,
|
|
1493
|
+
CursorCodec,
|
|
1494
|
+
CursorListResponseDto,
|
|
1495
|
+
DatabaseModule,
|
|
1496
|
+
FilterOperators,
|
|
1497
|
+
FilterProcessor,
|
|
1498
|
+
ImportResponseDto,
|
|
1499
|
+
ImportSummaryDto,
|
|
1500
|
+
KeysetProcessor,
|
|
1501
|
+
MAX_PAGE_SIZE,
|
|
1502
|
+
PrimaryBaseRepository,
|
|
1503
|
+
PrimaryDatabaseService,
|
|
1504
|
+
SelectOptionsQueryDto,
|
|
1505
|
+
SuccessResponseDto,
|
|
1506
|
+
TableResponseDto,
|
|
1507
|
+
ValidatedRowDto,
|
|
1508
|
+
keysetSignature
|
|
1509
|
+
});
|
|
1510
|
+
//# sourceMappingURL=database.cjs.map
|