@develit-io/backend-sdk 5.16.2 → 5.17.1

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.mjs CHANGED
@@ -2,6 +2,9 @@ import { sql } from 'drizzle-orm';
2
2
  import { timestamp, uuid, pgEnum, text as text$1 } from 'drizzle-orm/pg-core';
3
3
  import { integer, text } from 'drizzle-orm/sqlite-core';
4
4
  import { COUNTRY_CODES_2, CURRENCY_CODES, BANK_CODES } from '@develit-io/general-codes';
5
+ import { parse } from 'comment-json';
6
+ import { readFileSync } from 'node:fs';
7
+ import { join } from '@std/path';
5
8
  import { toSnakeCase } from '@std/text';
6
9
  import 'http-status-codes';
7
10
  import * as z from 'zod/v4/core';
@@ -9,7 +12,6 @@ import { createError } from 'h3';
9
12
  import fs from 'fs';
10
13
  import crypto$1 from 'node:crypto';
11
14
  import path from 'path';
12
- import { parse } from 'comment-json';
13
15
  import superjson from 'superjson';
14
16
 
15
17
  const base = {
@@ -39,14 +41,100 @@ const bankAccount = {
39
41
  currency: text("currency", { enum: CURRENCY_CODES }).notNull(),
40
42
  countryCode: text("country_code", { enum: COUNTRY_CODES_2 }).notNull()
41
43
  };
44
+ const bankAccountCurrencyEnum = pgEnum("currency", CURRENCY_CODES);
45
+ const bankAccountCountryCodeEnum = pgEnum(
46
+ "country_code",
47
+ COUNTRY_CODES_2
48
+ );
49
+ const bankAccountBankCodeEnum = pgEnum("bank_code", BANK_CODES);
42
50
  const bankAccountPostgres = {
43
51
  holderName: text$1("holder_name").notNull(),
44
52
  number: text$1("number").notNull(),
45
- bankCode: pgEnum("bank_code", BANK_CODES)().notNull(),
53
+ bankCode: bankAccountBankCodeEnum().notNull(),
46
54
  iban: text$1("iban").notNull(),
47
55
  bic: text$1("bic").notNull(),
48
- currency: pgEnum("currency", CURRENCY_CODES)().notNull(),
49
- countryCode: pgEnum("country_code", COUNTRY_CODES_2)().notNull()
56
+ currency: bankAccountCurrencyEnum().notNull(),
57
+ countryCode: bankAccountCountryCodeEnum().notNull()
58
+ };
59
+
60
+ const composeD1Arguments = ({
61
+ resourceName
62
+ }) => {
63
+ return {
64
+ transform: {
65
+ database: {
66
+ name: resourceName,
67
+ primaryLocationHint: "weur"
68
+ }
69
+ }
70
+ };
71
+ };
72
+
73
+ const composeKvArguments = ({
74
+ resourceName
75
+ }) => {
76
+ return {
77
+ transform: {
78
+ namespace: {
79
+ title: resourceName
80
+ }
81
+ }
82
+ };
83
+ };
84
+
85
+ const composeQueueArguments = ({
86
+ resourceName,
87
+ deliveryDelay = 5,
88
+ messageRetentionPeriod = 259200
89
+ }) => {
90
+ return {
91
+ transform: {
92
+ queue: {
93
+ queueName: resourceName,
94
+ settings: {
95
+ deliveryDelay,
96
+ messageRetentionPeriod
97
+ }
98
+ }
99
+ }
100
+ };
101
+ };
102
+
103
+ const composeR2Arguments = ({
104
+ resourceName,
105
+ storageClass = "Standard"
106
+ }) => {
107
+ return {
108
+ transform: {
109
+ bucket: {
110
+ name: resourceName,
111
+ jurisdiction: "eu",
112
+ location: "weur",
113
+ storageClass
114
+ }
115
+ }
116
+ };
117
+ };
118
+
119
+ async function loadWorkerConfig({ path }) {
120
+ const workerConfigFile = readFileSync(join(path, "./wrangler.jsonc"), "utf-8");
121
+ return parse(workerConfigFile);
122
+ }
123
+
124
+ const composeBindingName = ({
125
+ resource,
126
+ resourceName,
127
+ bindingName
128
+ }) => {
129
+ const convertedBindingName = bindingName ? toSnakeCase(bindingName) : `${toSnakeCase(resourceName)}_${resource}`;
130
+ return convertedBindingName.toUpperCase();
131
+ };
132
+ const composeResourceName = ({
133
+ project,
134
+ environment,
135
+ resourceName
136
+ }) => {
137
+ return `${project}-${resourceName}-${environment}`;
50
138
  };
51
139
 
52
140
  class Infrastructure {
@@ -62,158 +150,19 @@ class Infrastructure {
62
150
  this.environment = environment;
63
151
  this.sst = sst;
64
152
  }
65
- // TODO(Pookensivee): Make tests for this util
66
- composeBindingName({
67
- resource,
68
- resourceName,
69
- bindingName
70
- }) {
71
- const convertedBindingName = bindingName ? toSnakeCase(bindingName) : `${toSnakeCase(resourceName)}_${resource}`;
72
- return convertedBindingName.toUpperCase();
73
- }
74
- // TODO(Pookensivee): Make tests for this util
75
- composeResourceName({ resourceName }) {
76
- return `${this.project}-${resourceName}-${this.environment}`;
77
- }
78
- // TODO(Pookensivee): Make tests for this util
79
- composeKvArguments({ resourceName }) {
80
- return {
81
- transform: {
82
- namespace: {
83
- title: resourceName
84
- }
85
- }
86
- };
87
- }
88
- // TODO(Pookensivee): Make tests for this util
89
- composeD1Arguments({ resourceName }) {
90
- return {
91
- transform: {
92
- database: {
93
- name: resourceName,
94
- primaryLocationHint: "weur"
95
- }
96
- }
97
- };
98
- }
99
- // TODO(Pookensivee): Make tests for this util
100
- composeQueueArguments({
101
- resourceName,
102
- deliveryDelay = 5,
103
- messageRetentionPeriod = 259200
104
- }) {
105
- return {
106
- transform: {
107
- queue: {
108
- queueName: resourceName,
109
- settings: {
110
- deliveryDelay,
111
- messageRetentionPeriod
112
- }
113
- }
114
- }
115
- };
116
- }
117
- // TODO(Pookensivee): Make tests for this util
118
- composeR2Arguments({
119
- resourceName,
120
- storageClass = "Standard"
121
- }) {
122
- return {
123
- transform: {
124
- bucket: {
125
- name: resourceName,
126
- jurisdiction: "eu",
127
- location: "weur",
128
- storageClass
129
- }
130
- }
131
- };
132
- }
133
- // TODO: Solve the circular dependency on post infrastructure deploy script
134
- // TODO: Cannot assign a queue as a producer, work around: https://developers.cloudflare.com/workers/wrangler/commands/#queues-consumer-add-script-name
135
- // async composeWorkerArguments({
136
- // resourceName,
137
- // path,
138
- // bindings = [],
139
- // }: {
140
- // resourceName: string
141
- // path: string
142
- // bindings?: Input<Kv | D1 | Queue | Worker | Bucket>[]
143
- // }) {
144
- // const workerConfig = this.loadWorkerConfig({ path })
145
- // const environmentVariables = this.extractEnvironmentVariables({ workerConfigEnv:
146
- // workerConfig.env as WorkerConfigEnv
147
- // })
148
- // // TODO: Fix this
149
- // if (
150
- // 'SERVICE_CONFIG' in environmentVariables &&
151
- // typeof environmentVariables.SERVICE_CONFIG === 'object'
152
- // ) {
153
- // environmentVariables.SERVICE_CONFIG = JSON.stringify(environmentVariables.SERVICE_CONFIG)
154
- // }
155
- // // TODO: Fix this
156
- // if (
157
- // 'EMAIL_SENDER' in environmentVariables &&
158
- // typeof environmentVariables.EMAIL_SENDER === 'object'
159
- // ) {
160
- // environmentVariables.EMAIL_SENDER = JSON.stringify(environmentVariables.EMAIL_SENDER)
161
- // }
162
- // return {
163
- // handler: join(path, './src/index.ts'),
164
- // environment: Object.entries(environmentVariables).reduce((acc, [key, value]) => ({
165
- // ...acc,
166
- // [key]: String(value)
167
- // }), {} as Record<string, string>),
168
- // link: bindings,
169
- // transform: {
170
- // worker: {
171
- // scriptName: this.composeResourceName({ resourceName }),
172
- // compatibilityDate: '2025-06-04',
173
- // compatibilityFlags: ['nodejs_compat'],
174
- // observability: {
175
- // enabled: true,
176
- // headSamplingRate: 1,
177
- // logs: {
178
- // // Check whether this disables logs completely or just invocation ones
179
- // enabled: false,
180
- // invocationLogs: false,
181
- // },
182
- // },
183
- // },
184
- // }
185
- // } satisfies Partial<WorkerArgs>
186
- // }
187
- // loadWorkerConfig({ path }: { path: string }) {
188
- // const workerConfigFile = readFileSync(
189
- // join(path, './wrangler.jsonc'),
190
- // 'utf-8',
191
- // )
192
- // TODO: Use parse from comment-json
193
- // const jsonString = workerConfigFile
194
- // .replace(/\/\*[\s\S]*?\*\//g, '')
195
- // .replace(/\/\/.*$/gm, '')
196
- // return JSON.parse(jsonString)
197
- // }
198
- // extractEnvironmentVariables({
199
- // workerConfigEnv,
200
- // }: {
201
- // workerConfigEnv: WorkerConfigEnv
202
- // }) {
203
- // if (typeof this.environment === 'number') {
204
- // return { ...workerConfigEnv.dev.vars, ENVIRONMENT: this.environment }
205
- // }
206
- // return { ...workerConfigEnv[this.environment].vars }
207
- // }
208
153
  /**
209
154
  * Creates an instance of Cloudflare KV.
210
155
  */
211
156
  kv(options) {
212
157
  const { resourceName, bindingName } = options;
213
158
  return new this.sst.cloudflare.Kv(
214
- `${this.composeBindingName({ resource: "kv", resourceName, bindingName })}`,
215
- this.composeKvArguments({
216
- resourceName: this.composeResourceName({ resourceName })
159
+ `${composeBindingName({ resource: "kv", resourceName, bindingName })}`,
160
+ composeKvArguments({
161
+ resourceName: composeResourceName({
162
+ project: this.project,
163
+ environment: this.environment,
164
+ resourceName
165
+ })
217
166
  })
218
167
  );
219
168
  }
@@ -223,9 +172,13 @@ class Infrastructure {
223
172
  d1(options) {
224
173
  const { resourceName, bindingName } = options;
225
174
  return new this.sst.cloudflare.D1(
226
- `${this.composeBindingName({ resource: "d1", resourceName, bindingName })}`,
227
- this.composeD1Arguments({
228
- resourceName: this.composeResourceName({ resourceName })
175
+ `${composeBindingName({ resource: "d1", resourceName, bindingName })}`,
176
+ composeD1Arguments({
177
+ resourceName: composeResourceName({
178
+ project: this.project,
179
+ environment: this.environment,
180
+ resourceName
181
+ })
229
182
  })
230
183
  );
231
184
  }
@@ -235,9 +188,13 @@ class Infrastructure {
235
188
  queue(options) {
236
189
  const { resourceName, bindingName, deliveryDelay, messageRetentionPeriod } = options;
237
190
  return new this.sst.cloudflare.Queue(
238
- `${this.composeBindingName({ resource: "queue", resourceName, bindingName })}`,
239
- this.composeQueueArguments({
240
- resourceName: this.composeResourceName({ resourceName }),
191
+ `${composeBindingName({ resource: "queue", resourceName, bindingName })}`,
192
+ composeQueueArguments({
193
+ resourceName: composeResourceName({
194
+ project: this.project,
195
+ environment: this.environment,
196
+ resourceName
197
+ }),
241
198
  deliveryDelay,
242
199
  messageRetentionPeriod
243
200
  })
@@ -249,77 +206,28 @@ class Infrastructure {
249
206
  r2(options) {
250
207
  const { resourceName, bindingName, storageClass } = options;
251
208
  return new this.sst.cloudflare.Bucket(
252
- `${this.composeBindingName({ resource: "r2", resourceName, bindingName })}`,
253
- this.composeR2Arguments({
254
- resourceName: this.composeResourceName({ resourceName }),
209
+ `${composeBindingName({ resource: "r2", resourceName, bindingName })}`,
210
+ composeR2Arguments({
211
+ resourceName: composeResourceName({
212
+ project: this.project,
213
+ environment: this.environment,
214
+ resourceName
215
+ }),
255
216
  storageClass
256
217
  })
257
218
  );
258
219
  }
259
- // TODO: Solve the circular dependency on post infrastructure deploy script
260
- // async worker({
261
- // resourceName,
262
- // bindingName,
263
- // path,
264
- // bindings = [],
265
- // }: {
266
- // resourceName: string
267
- // bindingName: string
268
- // path: string
269
- // bindings?: Input<Kv | D1 | Queue | Worker | Bucket>[]
270
- // }) {
271
- // return new sst.cloudflare.Worker(
272
- // this.composeBindingName({
273
- // resource: 'worker',
274
- // bindingName,
275
- // resourceName,
276
- // }),
277
- // await this.composeWorkerArguments({
278
- // resourceName: this.composeResourceName({ resourceName }),
279
- // path,
280
- // bindings,
281
- // }),
282
- // )
283
- // }
284
- // async service({
285
- // resourceName,
286
- // bindingName,
287
- // path,
288
- // bindings = [],
289
- // }: {
290
- // resourceName: string
291
- // bindingName?: string
292
- // path?: string
293
- // bindings?: Input<Kv | D1 | Queue | Worker | Bucket>[]
294
- // }) {
295
- // return this.worker({
296
- // resourceName: `${this.project}-${resourceName}-service-${this.environment}`,
297
- // bindingName: this.composeBindingName({
298
- // resource: 'service',
299
- // bindingName,
300
- // resourceName,
301
- // }),
302
- // path: `${path ?? `./services/${resourceName}`}`,
303
- // bindings,
304
- // })
305
- // }
306
- // // TODO: Add name
307
- // async orchestrator({
308
- // path,
309
- // bindings = [],
310
- // }: {
311
- // path?: string
312
- // bindings?: Input<Kv | D1 | Queue | Worker | Bucket>[]
313
- // }) {
314
- // return this.worker({
315
- // resourceName: `${this.project}-gateway-${this.environment}`,
316
- // bindingName: 'GATEWAY',
317
- // path: `${path ?? `./apps/gateway`}`,
318
- // bindings,
319
- // })
320
- // }
321
220
  }
322
221
 
222
+ const ENVIRONMENT = ["dev", "test", "staging", "production"];
223
+
224
+ const validateEnvironment = (environment) => {
225
+ if (ENVIRONMENT.includes(environment)) {
226
+ return environment;
227
+ }
228
+ return Number(environment);
229
+ };
230
+
323
231
  const ibanZodSchema = new z.$ZodString({
324
232
  type: "string",
325
233
  checks: [
@@ -947,4 +855,4 @@ function develitWorker(Worker) {
947
855
  return DevelitWorker;
948
856
  }
949
857
 
950
- export { DatabaseTransaction, Infrastructure, RPCResponse, action, bankAccount, bankAccountPostgres, base, basePostgres, calculateExponentialBackoff, cloudflareQueue, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getDrizzlePgConfig, getPgCredentials, getPgDatabaseIdFromWrangler, getPgLocalConnectionString, handleAction, handleActionResponse, ibanZodSchema, isInternalError, paginationQuerySchema, paginationSchema, service, swiftZodSchema, useResult, useResultSync, uuidv4 };
858
+ export { DatabaseTransaction, ENVIRONMENT, Infrastructure, RPCResponse, action, bankAccount, bankAccountBankCodeEnum, bankAccountCountryCodeEnum, bankAccountCurrencyEnum, bankAccountPostgres, base, basePostgres, calculateExponentialBackoff, cloudflareQueue, composeBindingName, createAuditLogWriter, createInternalError, defineCommand, derivePortFromId, develitWorker, durableObjectNamespaceIdFromName, first, firstOrError, getD1Credentials, getD1DatabaseIdFromWrangler, getDrizzleD1Config, getDrizzlePgConfig, getPgCredentials, getPgDatabaseIdFromWrangler, getPgLocalConnectionString, handleAction, handleActionResponse, ibanZodSchema, isInternalError, loadWorkerConfig, paginationQuerySchema, paginationSchema, service, swiftZodSchema, useResult, useResultSync, uuidv4, validateEnvironment };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@develit-io/backend-sdk",
3
- "version": "5.16.2",
3
+ "version": "5.17.1",
4
4
  "description": "Develit Backend SDK",
5
5
  "author": "Develit.io",
6
6
  "license": "ISC",
@@ -30,8 +30,8 @@
30
30
  "dist"
31
31
  ],
32
32
  "dependencies": {
33
- "@cloudflare/workers-types": "4.20250909.0",
34
- "@pulumi/cloudflare": "^6.8.0",
33
+ "@cloudflare/workers-types": "4.20250913.0",
34
+ "@pulumi/cloudflare": "^6.9.0",
35
35
  "@std/path": "npm:@jsr/std__path",
36
36
  "@std/text": "npm:@jsr/std__text",
37
37
  "comment-json": "^4.2.5",
@@ -42,8 +42,8 @@
42
42
  "superjson": "^2.2.2"
43
43
  },
44
44
  "peerDependencies": {
45
- "sst": "^3.17.12",
46
- "zod": "^4.1.5",
45
+ "sst": "^3.17.13",
46
+ "zod": "^4.1.8",
47
47
  "@develit-io/general-codes": "^1.11.0"
48
48
  }
49
49
  }