@develit-io/backend-sdk 5.30.3 → 5.30.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/index.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.mjs +5 -3
- package/package.json +5 -18
- package/dist/deployment/index.cjs +0 -357
- package/dist/deployment/index.d.cts +0 -252
- package/dist/deployment/index.d.mts +0 -252
- package/dist/deployment/index.d.ts +0 -252
- package/dist/deployment/index.mjs +0 -344
- package/dist/index.cjs +0 -783
- package/dist/index.d.cts +0 -443
- package/dist/node/index.cjs +0 -13
- package/dist/node/index.d.cts +0 -3
- package/dist/node/index.d.mts +0 -3
- package/dist/node/index.d.ts +0 -3
- package/dist/node/index.mjs +0 -4
- package/dist/shared/backend-sdk.BdcrYpFD.cjs +0 -5
- package/dist/shared/backend-sdk.C-0xIdM4.d.mts +0 -69
- package/dist/shared/backend-sdk.CP78x0gl.d.cts +0 -3
- package/dist/shared/backend-sdk.CP78x0gl.d.mts +0 -3
- package/dist/shared/backend-sdk.CP78x0gl.d.ts +0 -3
- package/dist/shared/backend-sdk.CYcpgphg.d.cts +0 -3
- package/dist/shared/backend-sdk.CYcpgphg.d.mts +0 -3
- package/dist/shared/backend-sdk.CYcpgphg.d.ts +0 -3
- package/dist/shared/backend-sdk.CdngrAa0.d.cts +0 -69
- package/dist/shared/backend-sdk.DXRpnctc.mjs +0 -3
- package/dist/shared/backend-sdk.Fdiq3Ek5.mjs +0 -70
- package/dist/shared/backend-sdk.Vru_rcK6.cjs +0 -85
- package/dist/shared/backend-sdk.qPzlx18G.d.ts +0 -69
package/dist/index.cjs
DELETED
|
@@ -1,783 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const drizzleOrm = require('drizzle-orm');
|
|
4
|
-
const pgCore = require('drizzle-orm/pg-core');
|
|
5
|
-
const sqliteCore = require('drizzle-orm/sqlite-core');
|
|
6
|
-
const generalCodes = require('@develit-io/general-codes');
|
|
7
|
-
const environment_consts = require('./shared/backend-sdk.BdcrYpFD.cjs');
|
|
8
|
-
const z = require('zod/v4/core');
|
|
9
|
-
require('http-status-codes');
|
|
10
|
-
const h3 = require('h3');
|
|
11
|
-
const fs = require('node:fs');
|
|
12
|
-
const crypto$1 = require('node:crypto');
|
|
13
|
-
const path = require('node:path');
|
|
14
|
-
const commentJson = require('comment-json');
|
|
15
|
-
const superjson = require('superjson');
|
|
16
|
-
|
|
17
|
-
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
18
|
-
|
|
19
|
-
function _interopNamespaceCompat(e) {
|
|
20
|
-
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
21
|
-
const n = Object.create(null);
|
|
22
|
-
if (e) {
|
|
23
|
-
for (const k in e) {
|
|
24
|
-
n[k] = e[k];
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
n.default = e;
|
|
28
|
-
return n;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const z__namespace = /*#__PURE__*/_interopNamespaceCompat(z);
|
|
32
|
-
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
33
|
-
const crypto__default = /*#__PURE__*/_interopDefaultCompat(crypto$1);
|
|
34
|
-
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
35
|
-
const superjson__default = /*#__PURE__*/_interopDefaultCompat(superjson);
|
|
36
|
-
|
|
37
|
-
const base = {
|
|
38
|
-
id: sqliteCore.text("id").primaryKey(),
|
|
39
|
-
createdAt: sqliteCore.integer("created_at", { mode: "timestamp_ms" }).default(
|
|
40
|
-
drizzleOrm.sql`(unixepoch('subsec') * 1000)`
|
|
41
|
-
),
|
|
42
|
-
updatedAt: sqliteCore.integer("updated_at", { mode: "timestamp_ms" }).default(drizzleOrm.sql`(unixepoch('subsec') * 1000)`).$onUpdate(() => /* @__PURE__ */ new Date()),
|
|
43
|
-
deletedAt: sqliteCore.integer("deleted_at", { mode: "timestamp_ms" }).default(drizzleOrm.sql`null`)
|
|
44
|
-
};
|
|
45
|
-
const basePostgres = {
|
|
46
|
-
id: pgCore.uuid("id").primaryKey(),
|
|
47
|
-
createdAt: pgCore.timestamp("created_at", { mode: "date", withTimezone: false }).defaultNow().notNull(),
|
|
48
|
-
updatedAt: pgCore.timestamp("updated_at", { mode: "date", withTimezone: false }).defaultNow().notNull().$onUpdate(() => /* @__PURE__ */ new Date()),
|
|
49
|
-
deletedAt: pgCore.timestamp("deleted_at", {
|
|
50
|
-
mode: "date",
|
|
51
|
-
withTimezone: false
|
|
52
|
-
}).default(drizzleOrm.sql`null`)
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
const bankAccount = {
|
|
56
|
-
holderName: sqliteCore.text("holder_name").notNull(),
|
|
57
|
-
number: sqliteCore.text("number").notNull(),
|
|
58
|
-
bankCode: sqliteCore.text("bank_code", { enum: generalCodes.BANK_CODES }).notNull(),
|
|
59
|
-
iban: sqliteCore.text("iban").notNull(),
|
|
60
|
-
bic: sqliteCore.text("bic").notNull(),
|
|
61
|
-
currency: sqliteCore.text("currency", { enum: generalCodes.CURRENCY_CODES }).notNull(),
|
|
62
|
-
countryCode: sqliteCore.text("country_code", { enum: generalCodes.COUNTRY_CODES_2 }).notNull()
|
|
63
|
-
};
|
|
64
|
-
const bankAccountCurrencyEnum = pgCore.pgEnum("currency", generalCodes.CURRENCY_CODES);
|
|
65
|
-
const bankAccountCountryCodeEnum = pgCore.pgEnum(
|
|
66
|
-
"country_code",
|
|
67
|
-
generalCodes.COUNTRY_CODES_2
|
|
68
|
-
);
|
|
69
|
-
const bankAccountBankCodeEnum = pgCore.pgEnum("bank_code", generalCodes.BANK_CODES);
|
|
70
|
-
const bankAccountPostgres = {
|
|
71
|
-
holderName: pgCore.text("holder_name").notNull(),
|
|
72
|
-
number: pgCore.text("number").notNull(),
|
|
73
|
-
bankCode: bankAccountBankCodeEnum().$type().notNull(),
|
|
74
|
-
iban: pgCore.text("iban").notNull(),
|
|
75
|
-
bic: pgCore.text("bic").notNull(),
|
|
76
|
-
currency: bankAccountCurrencyEnum().$type().notNull(),
|
|
77
|
-
countryCode: bankAccountCountryCodeEnum().$type().notNull()
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const ibanZodSchema = new z__namespace.$ZodString({
|
|
81
|
-
type: "string",
|
|
82
|
-
checks: [
|
|
83
|
-
new z__namespace.$ZodCheckMinLength({
|
|
84
|
-
check: "min_length",
|
|
85
|
-
minimum: 1
|
|
86
|
-
}),
|
|
87
|
-
new z__namespace.$ZodCheckRegex({
|
|
88
|
-
check: "string_format",
|
|
89
|
-
format: "regex",
|
|
90
|
-
pattern: /^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$/
|
|
91
|
-
})
|
|
92
|
-
]
|
|
93
|
-
});
|
|
94
|
-
const swiftZodSchema = new z__namespace.$ZodString({
|
|
95
|
-
type: "string",
|
|
96
|
-
checks: [
|
|
97
|
-
new z__namespace.$ZodCheckMinLength({
|
|
98
|
-
check: "min_length",
|
|
99
|
-
minimum: 1
|
|
100
|
-
}),
|
|
101
|
-
new z__namespace.$ZodCheckRegex({
|
|
102
|
-
check: "string_format",
|
|
103
|
-
format: "regex",
|
|
104
|
-
pattern: /^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$/
|
|
105
|
-
})
|
|
106
|
-
]
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const paginationQuerySchema = new z__namespace.$ZodObject({
|
|
110
|
-
type: "object",
|
|
111
|
-
shape: {
|
|
112
|
-
page: new z__namespace.$ZodDefault({
|
|
113
|
-
type: "default",
|
|
114
|
-
innerType: new z__namespace.$ZodNumber({
|
|
115
|
-
type: "number",
|
|
116
|
-
coerce: true
|
|
117
|
-
}),
|
|
118
|
-
defaultValue: () => 1
|
|
119
|
-
}),
|
|
120
|
-
limit: new z__namespace.$ZodDefault({
|
|
121
|
-
type: "default",
|
|
122
|
-
innerType: new z__namespace.$ZodNumber({
|
|
123
|
-
type: "number",
|
|
124
|
-
coerce: true
|
|
125
|
-
}),
|
|
126
|
-
defaultValue: () => 20
|
|
127
|
-
}),
|
|
128
|
-
sort: new z__namespace.$ZodDefault({
|
|
129
|
-
type: "default",
|
|
130
|
-
innerType: new z__namespace.$ZodObject({
|
|
131
|
-
type: "object",
|
|
132
|
-
shape: {
|
|
133
|
-
column: new z__namespace.$ZodDefault({
|
|
134
|
-
type: "default",
|
|
135
|
-
innerType: new z__namespace.$ZodEnum({
|
|
136
|
-
type: "enum",
|
|
137
|
-
entries: {
|
|
138
|
-
createdAt: "createdAt",
|
|
139
|
-
updatedAt: "updatedAt",
|
|
140
|
-
deletedAt: "deletedAt"
|
|
141
|
-
}
|
|
142
|
-
}),
|
|
143
|
-
defaultValue: () => "updatedAt"
|
|
144
|
-
}),
|
|
145
|
-
direction: new z__namespace.$ZodDefault({
|
|
146
|
-
type: "default",
|
|
147
|
-
innerType: new z__namespace.$ZodEnum({
|
|
148
|
-
type: "enum",
|
|
149
|
-
entries: {
|
|
150
|
-
asc: "asc",
|
|
151
|
-
desc: "desc"
|
|
152
|
-
}
|
|
153
|
-
}),
|
|
154
|
-
defaultValue: () => "desc"
|
|
155
|
-
})
|
|
156
|
-
}
|
|
157
|
-
}),
|
|
158
|
-
defaultValue: () => ({ column: "updatedAt", direction: "desc" })
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
const paginationSchema = new z__namespace.$ZodObject({
|
|
163
|
-
type: "object",
|
|
164
|
-
shape: {
|
|
165
|
-
page: new z__namespace.$ZodNumber({
|
|
166
|
-
type: "number"
|
|
167
|
-
}),
|
|
168
|
-
limit: new z__namespace.$ZodNumber({
|
|
169
|
-
type: "number"
|
|
170
|
-
}),
|
|
171
|
-
sort: new z__namespace.$ZodObject({
|
|
172
|
-
type: "object",
|
|
173
|
-
shape: {
|
|
174
|
-
column: new z__namespace.$ZodEnum({
|
|
175
|
-
type: "enum",
|
|
176
|
-
entries: {
|
|
177
|
-
createdAt: "createdAt",
|
|
178
|
-
updatedAt: "updatedAt",
|
|
179
|
-
deletedAt: "deletedAt"
|
|
180
|
-
}
|
|
181
|
-
}),
|
|
182
|
-
direction: new z__namespace.$ZodEnum({
|
|
183
|
-
type: "enum",
|
|
184
|
-
entries: {
|
|
185
|
-
asc: "asc",
|
|
186
|
-
desc: "desc"
|
|
187
|
-
}
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
}
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
const handleActionResponse = ({
|
|
195
|
-
error,
|
|
196
|
-
status,
|
|
197
|
-
message,
|
|
198
|
-
data
|
|
199
|
-
}) => {
|
|
200
|
-
if (error) {
|
|
201
|
-
throw h3.createError({ status, message });
|
|
202
|
-
}
|
|
203
|
-
if (data === void 0 || data === null) {
|
|
204
|
-
throw h3.createError({
|
|
205
|
-
statusCode: 500,
|
|
206
|
-
message: "Could not process the request. (ACTION_RESPONSE_FAILED)"
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
return data;
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const createInternalError = (error, details) => {
|
|
213
|
-
return {
|
|
214
|
-
status: details?.status || 500,
|
|
215
|
-
code: details?.code || "UNKNOWN_ERROR",
|
|
216
|
-
message: details?.message || (error instanceof Error ? error.message : "An unexpected error occurred.")
|
|
217
|
-
};
|
|
218
|
-
};
|
|
219
|
-
const isInternalError = (error) => {
|
|
220
|
-
return typeof error === "object" && error !== null && "message" in error && "code" in error;
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
const RPCResponse = {
|
|
224
|
-
/**
|
|
225
|
-
* ✅ Constructs a successful RPC response.
|
|
226
|
-
*
|
|
227
|
-
* This method wraps the provided data in a standardized response format,
|
|
228
|
-
* ensuring consistency across API responses.
|
|
229
|
-
*
|
|
230
|
-
* @template T - The type of the response data.
|
|
231
|
-
* @param message - Response message
|
|
232
|
-
* @param detail - Optional -> Contains data and status code
|
|
233
|
-
* @returns An `IRPCResponse<T>` with the provided data and no error.
|
|
234
|
-
*/
|
|
235
|
-
ok(message, detail) {
|
|
236
|
-
return {
|
|
237
|
-
status: detail?.status || 200,
|
|
238
|
-
data: detail?.data,
|
|
239
|
-
error: false,
|
|
240
|
-
message
|
|
241
|
-
};
|
|
242
|
-
},
|
|
243
|
-
/**
|
|
244
|
-
* ❌ Constructs a generic service error response.
|
|
245
|
-
*
|
|
246
|
-
* This method logs the error and returns a standardized error response.
|
|
247
|
-
*
|
|
248
|
-
* @template T - The expected response type (typically ignored in errors).
|
|
249
|
-
* @param error - An `RPCError` containing error details.
|
|
250
|
-
* @returns An `IRPCResponse<T>` with `null` data and the provided error.
|
|
251
|
-
*/
|
|
252
|
-
serviceError(error) {
|
|
253
|
-
console.error(error.message);
|
|
254
|
-
return {
|
|
255
|
-
status: error.status,
|
|
256
|
-
message: error.message,
|
|
257
|
-
data: null,
|
|
258
|
-
error: true
|
|
259
|
-
};
|
|
260
|
-
},
|
|
261
|
-
/**
|
|
262
|
-
* ❌ Constructs a validation error response (HTTP 400).
|
|
263
|
-
*
|
|
264
|
-
* This is a convenience method for returning validation errors.
|
|
265
|
-
* It internally delegates to `serviceError()`.
|
|
266
|
-
*
|
|
267
|
-
* @template T - The expected response type (typically ignored in errors).
|
|
268
|
-
* @param error - An `RPCError` representing a validation failure.
|
|
269
|
-
* @returns An `IRPCResponse<T>` with `null` data and the provided error.
|
|
270
|
-
*/
|
|
271
|
-
validationError(error) {
|
|
272
|
-
return RPCResponse.serviceError(error);
|
|
273
|
-
}
|
|
274
|
-
};
|
|
275
|
-
|
|
276
|
-
const useResult = async (promise) => {
|
|
277
|
-
try {
|
|
278
|
-
return [await promise, null];
|
|
279
|
-
} catch (error) {
|
|
280
|
-
return [null, isInternalError(error) ? error : createInternalError(error)];
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
const useResultSync = (fn) => {
|
|
284
|
-
try {
|
|
285
|
-
return [fn(), null];
|
|
286
|
-
} catch (error) {
|
|
287
|
-
return [null, isInternalError(error) ? error : createInternalError(error)];
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
async function handleAction(worker, input, options = {}, actionExecution) {
|
|
292
|
-
const {
|
|
293
|
-
successMessage = "Operation completed successfully.",
|
|
294
|
-
logOutputTransform,
|
|
295
|
-
logInputTransform,
|
|
296
|
-
skipValidation = false,
|
|
297
|
-
skipLogging = false
|
|
298
|
-
} = options;
|
|
299
|
-
try {
|
|
300
|
-
if (!skipLogging && input) {
|
|
301
|
-
const inputToLog = logInputTransform ? logInputTransform(input.data) : input;
|
|
302
|
-
worker.logInput(inputToLog);
|
|
303
|
-
}
|
|
304
|
-
let validatedInput = input?.data || null;
|
|
305
|
-
if (!skipValidation && input) {
|
|
306
|
-
validatedInput = worker.handleInput({
|
|
307
|
-
input: input.data,
|
|
308
|
-
schema: input.schema
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
const [data, error] = await useResult(
|
|
312
|
-
validatedInput ? actionExecution(validatedInput) : actionExecution()
|
|
313
|
-
);
|
|
314
|
-
if (error) {
|
|
315
|
-
worker.logError(error);
|
|
316
|
-
return RPCResponse.serviceError(error);
|
|
317
|
-
}
|
|
318
|
-
if (!skipLogging) {
|
|
319
|
-
const outputToLog = logOutputTransform ? logOutputTransform(data) : data;
|
|
320
|
-
worker.logOutput(outputToLog);
|
|
321
|
-
}
|
|
322
|
-
return RPCResponse.ok(successMessage, { data });
|
|
323
|
-
} catch (error) {
|
|
324
|
-
const internalError = createInternalError(error);
|
|
325
|
-
worker.logError(internalError);
|
|
326
|
-
return RPCResponse.serviceError(internalError);
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
const asNonEmpty = (arr) => {
|
|
331
|
-
return arr.length > 0 ? [arr[0], ...arr.slice(1)] : null;
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
function createAuditLogWriter(table) {
|
|
335
|
-
return (logs, db) => {
|
|
336
|
-
if (logs.length === 0) return [];
|
|
337
|
-
const auditRecords = logs.map((log) => ({
|
|
338
|
-
...log,
|
|
339
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
340
|
-
id: crypto.randomUUID()
|
|
341
|
-
}));
|
|
342
|
-
return [db.insert(table).values(auditRecords)];
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function first(rows) {
|
|
347
|
-
return rows.length > 0 ? rows[0] : void 0;
|
|
348
|
-
}
|
|
349
|
-
function firstOrError(rows) {
|
|
350
|
-
if (rows.length === 0) {
|
|
351
|
-
throw new Error("Query did not return any data.");
|
|
352
|
-
}
|
|
353
|
-
return rows[0];
|
|
354
|
-
}
|
|
355
|
-
const uuidv4 = () => crypto.randomUUID();
|
|
356
|
-
const isRemoteEnvironment = () => {
|
|
357
|
-
const environment = process.env.ENVIRONMENT;
|
|
358
|
-
return environment && environment !== "localhost";
|
|
359
|
-
};
|
|
360
|
-
function derivePortFromId(id, base = 4e3, range = 1e4) {
|
|
361
|
-
let hash = 0;
|
|
362
|
-
for (let i = 0; i < id.length; i++) {
|
|
363
|
-
hash = hash * 31 + id.charCodeAt(i) >>> 0;
|
|
364
|
-
}
|
|
365
|
-
return base + hash % range;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function durableObjectNamespaceIdFromName(uniqueKey, name) {
|
|
369
|
-
const key = crypto__default.createHash("sha256").update(uniqueKey).digest();
|
|
370
|
-
const nameHmac = crypto__default.createHmac("sha256", key).update(name).digest().subarray(0, 16);
|
|
371
|
-
const hmac = crypto__default.createHmac("sha256", key).update(nameHmac).digest().subarray(0, 16);
|
|
372
|
-
return Buffer.concat([nameHmac, hmac]).toString("hex");
|
|
373
|
-
}
|
|
374
|
-
const getD1DatabaseIdFromWrangler = () => {
|
|
375
|
-
try {
|
|
376
|
-
const wranglerPath = path__default.resolve("./wrangler.jsonc");
|
|
377
|
-
const wranglerContent = fs__default.readFileSync(wranglerPath, "utf-8");
|
|
378
|
-
const config = commentJson.parse(wranglerContent);
|
|
379
|
-
const environment = process.env.ENVIRONMENT || "localhost";
|
|
380
|
-
let databaseId;
|
|
381
|
-
if (environment !== "localhost" && config.env?.[environment]) {
|
|
382
|
-
databaseId = config.env[environment].d1_databases?.[0]?.database_id;
|
|
383
|
-
console.log(
|
|
384
|
-
`Using database_id for environment '${environment}': ${databaseId}`
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
if (!databaseId) {
|
|
388
|
-
databaseId = config.d1_databases?.[0]?.database_id;
|
|
389
|
-
console.log(
|
|
390
|
-
`Using default database_id for environment '${environment}': ${databaseId}`
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
if (!databaseId) {
|
|
394
|
-
throw new Error("database_id not found in wrangler.jsonc");
|
|
395
|
-
}
|
|
396
|
-
return databaseId;
|
|
397
|
-
} catch (err) {
|
|
398
|
-
console.warn(
|
|
399
|
-
`Warning: Could not read database_id from wrangler.jsonc: ${err}`
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
};
|
|
403
|
-
const getLocalD1 = (databaseId) => {
|
|
404
|
-
const name = durableObjectNamespaceIdFromName(
|
|
405
|
-
"miniflare-D1DatabaseObject",
|
|
406
|
-
databaseId
|
|
407
|
-
);
|
|
408
|
-
const searchPaths = [
|
|
409
|
-
path__default.resolve("../../.wrangler"),
|
|
410
|
-
// Root of monorepo
|
|
411
|
-
path__default.resolve("./.wrangler")
|
|
412
|
-
// Current directory
|
|
413
|
-
];
|
|
414
|
-
for (const basePath of searchPaths) {
|
|
415
|
-
try {
|
|
416
|
-
const dbFile = fs__default.readdirSync(basePath, { encoding: "utf-8", recursive: true }).find((f) => f.includes(name));
|
|
417
|
-
if (dbFile) {
|
|
418
|
-
const url = path__default.resolve(basePath, dbFile);
|
|
419
|
-
console.log(`Found D1 database at: ${url}`);
|
|
420
|
-
return url;
|
|
421
|
-
} else {
|
|
422
|
-
throw new Error(`No D1 database file found in ${basePath}`);
|
|
423
|
-
}
|
|
424
|
-
} catch {
|
|
425
|
-
console.warn(`Could not search in ${basePath}`);
|
|
426
|
-
continue;
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
const getD1Credentials = () => {
|
|
431
|
-
const environment = process.env.ENVIRONMENT;
|
|
432
|
-
if (environment === "localhost") {
|
|
433
|
-
return {};
|
|
434
|
-
}
|
|
435
|
-
const databaseId = getD1DatabaseIdFromWrangler() ?? "";
|
|
436
|
-
if (isRemoteEnvironment()) {
|
|
437
|
-
return {
|
|
438
|
-
driver: "d1-http",
|
|
439
|
-
dbCredentials: {
|
|
440
|
-
accountId: process.env.CLOUDFLARE_ACCOUNT_ID,
|
|
441
|
-
databaseId,
|
|
442
|
-
token: process.env.CLOUDFLARE_API_TOKEN
|
|
443
|
-
}
|
|
444
|
-
};
|
|
445
|
-
} else {
|
|
446
|
-
return {
|
|
447
|
-
dbCredentials: {
|
|
448
|
-
url: getLocalD1(databaseId)
|
|
449
|
-
}
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
};
|
|
453
|
-
const getDrizzleD1Config = () => ({
|
|
454
|
-
schema: "./src/database/schema/",
|
|
455
|
-
out: "./src/database/migrations/",
|
|
456
|
-
dialect: "sqlite",
|
|
457
|
-
...getD1Credentials()
|
|
458
|
-
});
|
|
459
|
-
|
|
460
|
-
class DatabaseTransaction {
|
|
461
|
-
constructor(db, serviceName, auditLogWriter) {
|
|
462
|
-
this.db = db;
|
|
463
|
-
this.serviceName = serviceName;
|
|
464
|
-
this.auditLogWriter = auditLogWriter;
|
|
465
|
-
}
|
|
466
|
-
commands = [];
|
|
467
|
-
logs = [];
|
|
468
|
-
ids = [];
|
|
469
|
-
enqueue(commands) {
|
|
470
|
-
return (Array.isArray(commands) ? commands : [commands]).map((cmd) => {
|
|
471
|
-
const commandItem = cmd.handler(this.db);
|
|
472
|
-
const auditLogPayload = {
|
|
473
|
-
...commandItem.logPayload,
|
|
474
|
-
service: this.serviceName || "unknown-service"
|
|
475
|
-
};
|
|
476
|
-
this.commands.push(commandItem.command);
|
|
477
|
-
this.logs.push(auditLogPayload);
|
|
478
|
-
if (commandItem.id) {
|
|
479
|
-
this.ids.push(commandItem.id);
|
|
480
|
-
}
|
|
481
|
-
return commandItem;
|
|
482
|
-
}).reduce((acc, curr) => {
|
|
483
|
-
acc.push(curr.id);
|
|
484
|
-
return acc;
|
|
485
|
-
}, []);
|
|
486
|
-
}
|
|
487
|
-
async execute(commandItem) {
|
|
488
|
-
this.enqueue(commandItem);
|
|
489
|
-
await this.executeAll();
|
|
490
|
-
}
|
|
491
|
-
async executeAll() {
|
|
492
|
-
let allCommands = [...this.commands];
|
|
493
|
-
if (this.auditLogWriter && this.logs.length > 0) {
|
|
494
|
-
const auditCommands = this.auditLogWriter(this.logs, this.db);
|
|
495
|
-
allCommands.push(...auditCommands);
|
|
496
|
-
}
|
|
497
|
-
const batchItems = asNonEmpty(allCommands);
|
|
498
|
-
if (batchItems) {
|
|
499
|
-
await this.db.batch(batchItems);
|
|
500
|
-
}
|
|
501
|
-
this.commands = [];
|
|
502
|
-
this.logs = [];
|
|
503
|
-
this.ids = [];
|
|
504
|
-
}
|
|
505
|
-
getLogs() {
|
|
506
|
-
return [...this.logs];
|
|
507
|
-
}
|
|
508
|
-
getIds() {
|
|
509
|
-
return [...this.ids];
|
|
510
|
-
}
|
|
511
|
-
getCommandsCount() {
|
|
512
|
-
return this.commands.length;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
const defineCommand = (handler) => {
|
|
517
|
-
return ((params) => ({
|
|
518
|
-
handler: (db) => handler(db, params)
|
|
519
|
-
}));
|
|
520
|
-
};
|
|
521
|
-
|
|
522
|
-
async function useFetch(url, { parseAs = "json", ...options } = {}) {
|
|
523
|
-
const [response, fetchError] = await useResult(fetch(url, options));
|
|
524
|
-
if (fetchError || !response) {
|
|
525
|
-
return [null, createInternalError(fetchError, { code: "NETWORK_ERROR" })];
|
|
526
|
-
}
|
|
527
|
-
const parsers = {
|
|
528
|
-
json: () => response.json(),
|
|
529
|
-
text: () => response.text(),
|
|
530
|
-
blob: () => response.blob()
|
|
531
|
-
};
|
|
532
|
-
const [body, parseError] = await useResult(parsers[parseAs]());
|
|
533
|
-
if (!response.ok) {
|
|
534
|
-
return [
|
|
535
|
-
null,
|
|
536
|
-
createInternalError(parseError, {
|
|
537
|
-
message: body?.message ?? response.statusText,
|
|
538
|
-
code: "HTTP_ERROR",
|
|
539
|
-
status: response.status
|
|
540
|
-
})
|
|
541
|
-
];
|
|
542
|
-
}
|
|
543
|
-
if (parseError) {
|
|
544
|
-
return [
|
|
545
|
-
null,
|
|
546
|
-
createInternalError(parseError, {
|
|
547
|
-
code: "PARSE_ERROR",
|
|
548
|
-
status: response.status
|
|
549
|
-
})
|
|
550
|
-
];
|
|
551
|
-
}
|
|
552
|
-
return [body, null];
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
const getPgLocalConnectionString = (id) => `postgres://db_user:db_password@127.0.0.1:${derivePortFromId(id)}/db`;
|
|
556
|
-
const getPgDatabaseIdFromWrangler = () => {
|
|
557
|
-
try {
|
|
558
|
-
const wranglerPath = path__default.resolve("./wrangler.jsonc");
|
|
559
|
-
const wranglerContent = fs__default.readFileSync(wranglerPath, "utf-8");
|
|
560
|
-
const config = commentJson.parse(wranglerContent);
|
|
561
|
-
if (!config.name) {
|
|
562
|
-
throw new Error('Missing "name" in wrangler.jsonc');
|
|
563
|
-
}
|
|
564
|
-
const databaseId = `${config.name}-db`;
|
|
565
|
-
console.log(`Using databaseId derived from wrangler name: ${databaseId}`);
|
|
566
|
-
return databaseId;
|
|
567
|
-
} catch (err) {
|
|
568
|
-
console.warn(
|
|
569
|
-
`Warning: Could not derive databaseId from wrangler.jsonc: ${err}`
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
|
-
};
|
|
573
|
-
const getPgCredentials = (serviceName) => {
|
|
574
|
-
if (isRemoteEnvironment()) {
|
|
575
|
-
return {
|
|
576
|
-
dbCredentials: {
|
|
577
|
-
url: process.env.DATABASE_URL
|
|
578
|
-
}
|
|
579
|
-
};
|
|
580
|
-
} else {
|
|
581
|
-
const databaseId = serviceName ? `${serviceName}-db` : getPgDatabaseIdFromWrangler() ?? "";
|
|
582
|
-
return {
|
|
583
|
-
dbCredentials: {
|
|
584
|
-
url: getPgLocalConnectionString(databaseId)
|
|
585
|
-
}
|
|
586
|
-
};
|
|
587
|
-
}
|
|
588
|
-
};
|
|
589
|
-
const getDrizzlePgConfig = () => ({
|
|
590
|
-
schema: "./src/database/schema/",
|
|
591
|
-
out: "./src/database/migrations/",
|
|
592
|
-
dialect: "postgresql",
|
|
593
|
-
...getPgCredentials(),
|
|
594
|
-
migrations: {
|
|
595
|
-
table: "__drizzle_migrations",
|
|
596
|
-
schema: "public"
|
|
597
|
-
}
|
|
598
|
-
});
|
|
599
|
-
|
|
600
|
-
const calculateExponentialBackoff = (attempts, baseDelaySeconds) => {
|
|
601
|
-
return baseDelaySeconds ** attempts;
|
|
602
|
-
};
|
|
603
|
-
|
|
604
|
-
const service = (serviceName) => {
|
|
605
|
-
return function(constructor) {
|
|
606
|
-
return class extends constructor {
|
|
607
|
-
name = `${serviceName}-service`;
|
|
608
|
-
};
|
|
609
|
-
};
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
const action = (name) => {
|
|
613
|
-
return (_target, _propertyKey, descriptor) => {
|
|
614
|
-
const originalMethod = descriptor.value;
|
|
615
|
-
descriptor.value = function(...args) {
|
|
616
|
-
this.action = name;
|
|
617
|
-
return originalMethod.apply(this, args);
|
|
618
|
-
};
|
|
619
|
-
return descriptor;
|
|
620
|
-
};
|
|
621
|
-
};
|
|
622
|
-
|
|
623
|
-
function cloudflareQueue(options) {
|
|
624
|
-
return (_target, _propertyKey, descriptor) => {
|
|
625
|
-
const originalMethod = descriptor.value;
|
|
626
|
-
descriptor.value = async function(...args) {
|
|
627
|
-
const batch = args[0];
|
|
628
|
-
let retriedCount = 0;
|
|
629
|
-
batch.messages.forEach((msg) => {
|
|
630
|
-
const originalRetry = msg.retry?.bind(msg);
|
|
631
|
-
msg.retry = () => {
|
|
632
|
-
retriedCount++;
|
|
633
|
-
return originalRetry({
|
|
634
|
-
delaySeconds: calculateExponentialBackoff(
|
|
635
|
-
msg.attempts,
|
|
636
|
-
options.baseDelay
|
|
637
|
-
)
|
|
638
|
-
});
|
|
639
|
-
};
|
|
640
|
-
});
|
|
641
|
-
const result = await originalMethod.apply(this, args);
|
|
642
|
-
if (typeof this.logQueueRetries === "function") {
|
|
643
|
-
this.logQueueRetries({
|
|
644
|
-
message: `Retried ${retriedCount} out of ${batch.messages.length} messages`
|
|
645
|
-
});
|
|
646
|
-
}
|
|
647
|
-
return result;
|
|
648
|
-
};
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
function develitWorker(Worker) {
|
|
653
|
-
class DevelitWorker extends Worker {
|
|
654
|
-
name = "not-set";
|
|
655
|
-
action = "not-set";
|
|
656
|
-
// public db!: DatabaseTransaction<string>
|
|
657
|
-
async fetch() {
|
|
658
|
-
return new Response("Service is up and running!");
|
|
659
|
-
}
|
|
660
|
-
// initializeDB<TAuditAction = string>(
|
|
661
|
-
// database: D1Database,
|
|
662
|
-
// schema: Record<string, unknown>,
|
|
663
|
-
// auditLogWriter?: AuditLogWriter<TAuditAction>,
|
|
664
|
-
// ): void {
|
|
665
|
-
// const drizzleInstance = drizzle(database, {
|
|
666
|
-
// schema,
|
|
667
|
-
// }) as DrizzleD1Database<Record<string, unknown>>
|
|
668
|
-
// this.db = new DatabaseTransaction<TAuditAction>(
|
|
669
|
-
// drizzleInstance,
|
|
670
|
-
// this.name,
|
|
671
|
-
// auditLogWriter,
|
|
672
|
-
// ) as unknown as DatabaseTransaction<string>
|
|
673
|
-
// }
|
|
674
|
-
handleInput({
|
|
675
|
-
input,
|
|
676
|
-
schema
|
|
677
|
-
}) {
|
|
678
|
-
this.logInput({ input });
|
|
679
|
-
const parseResult = z__namespace.safeParse(schema, input);
|
|
680
|
-
if (!parseResult.success) {
|
|
681
|
-
const parseError = {
|
|
682
|
-
status: 400,
|
|
683
|
-
code: "INVALID_ACTION_INPUT",
|
|
684
|
-
message: z__namespace.prettifyError(parseResult.error)
|
|
685
|
-
};
|
|
686
|
-
this.logError(parseError);
|
|
687
|
-
throw RPCResponse.validationError(parseError);
|
|
688
|
-
}
|
|
689
|
-
if (!parseResult.data) {
|
|
690
|
-
throw createInternalError({
|
|
691
|
-
message: "The provided input could not be processed."
|
|
692
|
-
});
|
|
693
|
-
}
|
|
694
|
-
return parseResult.data;
|
|
695
|
-
}
|
|
696
|
-
log(data, identifier) {
|
|
697
|
-
const name = identifier ?? `${this.name}:${this.action}:log`;
|
|
698
|
-
console.log(name, {
|
|
699
|
-
entrypoint: this.name,
|
|
700
|
-
action: this.action,
|
|
701
|
-
identifier: name,
|
|
702
|
-
data: superjson__default.stringify(data)
|
|
703
|
-
});
|
|
704
|
-
}
|
|
705
|
-
logQueuePush(data) {
|
|
706
|
-
this.log(data, `${this.name}:${this.action}:queue-push`);
|
|
707
|
-
}
|
|
708
|
-
logQueuePull(data) {
|
|
709
|
-
this.log(data, `${this.name}:${this.action}:queue-pull`);
|
|
710
|
-
}
|
|
711
|
-
logQueueRetries(data) {
|
|
712
|
-
this.log(data, `${this.name}:${this.action}:queue-retries`);
|
|
713
|
-
}
|
|
714
|
-
logInput(data) {
|
|
715
|
-
this.log(data, `${this.name}:${this.action}:input`);
|
|
716
|
-
}
|
|
717
|
-
logOutput(data) {
|
|
718
|
-
this.log(data, `${this.name}:${this.action}:output`);
|
|
719
|
-
}
|
|
720
|
-
logError(error) {
|
|
721
|
-
this.log(error, `${this.name}:${this.action}:error`);
|
|
722
|
-
}
|
|
723
|
-
pushToQueue(queue, message) {
|
|
724
|
-
if (!Array.isArray(message))
|
|
725
|
-
return queue.send(message, { contentType: "v8" });
|
|
726
|
-
return queue.sendBatch(
|
|
727
|
-
message.map((m) => ({
|
|
728
|
-
body: m,
|
|
729
|
-
contentType: "v8"
|
|
730
|
-
}))
|
|
731
|
-
);
|
|
732
|
-
}
|
|
733
|
-
recordAuditLogMessage(queue, message) {
|
|
734
|
-
const msg = { service: this.name, ...message, createdAt: /* @__PURE__ */ new Date() };
|
|
735
|
-
return this.pushToQueue(queue, msg);
|
|
736
|
-
}
|
|
737
|
-
async handleAction(input, options = {}, actionExecution) {
|
|
738
|
-
return handleAction(this, input, options, actionExecution);
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
return DevelitWorker;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
exports.ENVIRONMENT = environment_consts.ENVIRONMENT;
|
|
745
|
-
exports.DatabaseTransaction = DatabaseTransaction;
|
|
746
|
-
exports.RPCResponse = RPCResponse;
|
|
747
|
-
exports.action = action;
|
|
748
|
-
exports.bankAccount = bankAccount;
|
|
749
|
-
exports.bankAccountBankCodeEnum = bankAccountBankCodeEnum;
|
|
750
|
-
exports.bankAccountCountryCodeEnum = bankAccountCountryCodeEnum;
|
|
751
|
-
exports.bankAccountCurrencyEnum = bankAccountCurrencyEnum;
|
|
752
|
-
exports.bankAccountPostgres = bankAccountPostgres;
|
|
753
|
-
exports.base = base;
|
|
754
|
-
exports.basePostgres = basePostgres;
|
|
755
|
-
exports.calculateExponentialBackoff = calculateExponentialBackoff;
|
|
756
|
-
exports.cloudflareQueue = cloudflareQueue;
|
|
757
|
-
exports.createAuditLogWriter = createAuditLogWriter;
|
|
758
|
-
exports.createInternalError = createInternalError;
|
|
759
|
-
exports.defineCommand = defineCommand;
|
|
760
|
-
exports.derivePortFromId = derivePortFromId;
|
|
761
|
-
exports.develitWorker = develitWorker;
|
|
762
|
-
exports.durableObjectNamespaceIdFromName = durableObjectNamespaceIdFromName;
|
|
763
|
-
exports.first = first;
|
|
764
|
-
exports.firstOrError = firstOrError;
|
|
765
|
-
exports.getD1Credentials = getD1Credentials;
|
|
766
|
-
exports.getD1DatabaseIdFromWrangler = getD1DatabaseIdFromWrangler;
|
|
767
|
-
exports.getDrizzleD1Config = getDrizzleD1Config;
|
|
768
|
-
exports.getDrizzlePgConfig = getDrizzlePgConfig;
|
|
769
|
-
exports.getPgCredentials = getPgCredentials;
|
|
770
|
-
exports.getPgDatabaseIdFromWrangler = getPgDatabaseIdFromWrangler;
|
|
771
|
-
exports.getPgLocalConnectionString = getPgLocalConnectionString;
|
|
772
|
-
exports.handleAction = handleAction;
|
|
773
|
-
exports.handleActionResponse = handleActionResponse;
|
|
774
|
-
exports.ibanZodSchema = ibanZodSchema;
|
|
775
|
-
exports.isInternalError = isInternalError;
|
|
776
|
-
exports.paginationQuerySchema = paginationQuerySchema;
|
|
777
|
-
exports.paginationSchema = paginationSchema;
|
|
778
|
-
exports.service = service;
|
|
779
|
-
exports.swiftZodSchema = swiftZodSchema;
|
|
780
|
-
exports.useFetch = useFetch;
|
|
781
|
-
exports.useResult = useResult;
|
|
782
|
-
exports.useResultSync = useResultSync;
|
|
783
|
-
exports.uuidv4 = uuidv4;
|