@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.cjs +139 -226
- package/dist/index.d.cts +24 -64
- package/dist/index.d.mts +24 -64
- package/dist/index.d.ts +24 -64
- package/dist/index.mjs +135 -226
- package/package.json +5 -5
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")
|
|
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")
|
|
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:
|
|
53
|
+
bankCode: bankAccountBankCodeEnum().notNull(),
|
|
45
54
|
iban: text$1("iban").notNull(),
|
|
46
55
|
bic: text$1("bic").notNull(),
|
|
47
|
-
currency:
|
|
48
|
-
countryCode:
|
|
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
|
-
`${
|
|
214
|
-
|
|
215
|
-
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
|
-
`${
|
|
226
|
-
|
|
227
|
-
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
|
-
`${
|
|
238
|
-
|
|
239
|
-
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
|
-
`${
|
|
252
|
-
|
|
253
|
-
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.
|
|
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.
|
|
34
|
-
"@pulumi/cloudflare": "^6.
|
|
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.
|
|
46
|
-
"zod": "^4.1.
|
|
45
|
+
"sst": "^3.17.13",
|
|
46
|
+
"zod": "^4.1.8",
|
|
47
47
|
"@develit-io/general-codes": "^1.11.0"
|
|
48
48
|
}
|
|
49
49
|
}
|