@develit-io/backend-sdk 5.16.1 → 5.17.0

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