appflare 0.0.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.
Files changed (42) hide show
  1. package/cli/README.md +101 -0
  2. package/cli/core/build.ts +136 -0
  3. package/cli/core/config.ts +29 -0
  4. package/cli/core/discover-handlers.ts +61 -0
  5. package/cli/core/handlers.ts +5 -0
  6. package/cli/core/index.ts +157 -0
  7. package/cli/generators/generate-api-client/client.ts +93 -0
  8. package/cli/generators/generate-api-client/index.ts +529 -0
  9. package/cli/generators/generate-api-client/types.ts +59 -0
  10. package/cli/generators/generate-api-client/utils.ts +18 -0
  11. package/cli/generators/generate-api-client.ts +1 -0
  12. package/cli/generators/generate-db-handlers.ts +138 -0
  13. package/cli/generators/generate-hono-server.ts +238 -0
  14. package/cli/generators/generate-websocket-durable-object.ts +537 -0
  15. package/cli/index.ts +157 -0
  16. package/cli/schema/schema-static-types.ts +252 -0
  17. package/cli/schema/schema.ts +105 -0
  18. package/cli/utils/tsc.ts +53 -0
  19. package/cli/utils/utils.ts +126 -0
  20. package/cli/utils/zod-utils.ts +115 -0
  21. package/index.ts +2 -0
  22. package/lib/README.md +43 -0
  23. package/lib/db.ts +9 -0
  24. package/lib/values.ts +23 -0
  25. package/package.json +28 -0
  26. package/react/README.md +67 -0
  27. package/react/hooks/useMutation.ts +89 -0
  28. package/react/hooks/usePaginatedQuery.ts +213 -0
  29. package/react/hooks/useQuery.ts +106 -0
  30. package/react/index.ts +3 -0
  31. package/react/shared/queryShared.ts +169 -0
  32. package/server/README.md +153 -0
  33. package/server/database/builders.ts +83 -0
  34. package/server/database/context.ts +265 -0
  35. package/server/database/populate.ts +160 -0
  36. package/server/database/query-builder.ts +101 -0
  37. package/server/database/query-utils.ts +25 -0
  38. package/server/db.ts +2 -0
  39. package/server/types/schema-refs.ts +66 -0
  40. package/server/types/types.ts +419 -0
  41. package/server/utils/id-utils.ts +123 -0
  42. package/tsconfig.json +7 -0
@@ -0,0 +1,419 @@
1
+ import type { Db } from "mongodb";
2
+
3
+ export type AnyZod = any;
4
+
5
+ export type TableDocBase = {
6
+ _id: string;
7
+ _creationTime: number;
8
+ };
9
+
10
+ export type Id<TableName extends string> = string & { __table?: TableName };
11
+
12
+ export type EditableDoc<TDoc extends TableDocBase> = Omit<
13
+ TDoc,
14
+ "_id" | "_creationTime"
15
+ >;
16
+
17
+ export type SelectedKeys<TDoc, TSelect> =
18
+ TSelect extends readonly (infer TKey)[]
19
+ ? Extract<TKey, Keys<TDoc>>
20
+ : TSelect extends Record<infer TKey, boolean>
21
+ ? Extract<TKey, Keys<TDoc>>
22
+ : Keys<TDoc>;
23
+
24
+ export type IncludedKeys<
25
+ TDoc,
26
+ TInclude,
27
+ TTableDocMap extends Record<string, TableDocBase>,
28
+ > = TInclude extends readonly (infer TKey)[]
29
+ ? Extract<TKey, PopulatableKeys<TDoc, TTableDocMap>>
30
+ : TInclude extends Record<infer TKey, boolean>
31
+ ? Extract<TKey, PopulatableKeys<TDoc, TTableDocMap>>
32
+ : never;
33
+
34
+ export type AppflareSelect<TDoc> =
35
+ | ReadonlyArray<Keys<TDoc>>
36
+ | Partial<Record<Keys<TDoc>, boolean>>;
37
+
38
+ export type AppflareInclude<
39
+ TDoc,
40
+ TTableDocMap extends Record<string, TableDocBase>,
41
+ > =
42
+ | ReadonlyArray<PopulatableKeys<TDoc, TTableDocMap>>
43
+ | Partial<Record<PopulatableKeys<TDoc, TTableDocMap>, boolean>>;
44
+
45
+ export type AppflareResultDoc<
46
+ TDoc,
47
+ TSelect,
48
+ TInclude,
49
+ TTableDocMap extends Record<string, TableDocBase>,
50
+ > = WithSelected<
51
+ WithPopulatedMany<
52
+ TDoc,
53
+ IncludedKeys<TDoc, TInclude, TTableDocMap>,
54
+ TTableDocMap
55
+ >,
56
+ SelectedKeys<TDoc, TSelect>
57
+ >;
58
+
59
+ export type SortDirection = "asc" | "desc";
60
+
61
+ export type QuerySort<TKey extends string> =
62
+ | Partial<Record<TKey, SortDirection>>
63
+ | Array<[TKey, SortDirection]>
64
+ | Record<string, SortDirection>
65
+ | Array<[string, SortDirection]>;
66
+
67
+ export type QueryWhere<TDoc extends Record<string, unknown>> = Partial<TDoc> &
68
+ Record<string, unknown>;
69
+
70
+ export type Keys<T> = keyof T;
71
+
72
+ export type NonNil<T> = Exclude<T, null | undefined>;
73
+
74
+ export type ExtractIdTableName<T> =
75
+ NonNil<T> extends Id<infer TTable>
76
+ ? TTable
77
+ : NonNil<T> extends Array<infer TItem>
78
+ ? ExtractIdTableName<TItem>
79
+ : never;
80
+
81
+ export type PopulateValue<
82
+ T,
83
+ TTableDocMap extends Record<string, TableDocBase>,
84
+ > =
85
+ T extends Id<infer TTable>
86
+ ? TTable extends keyof TTableDocMap
87
+ ? TTableDocMap[TTable]
88
+ : never
89
+ : T extends Array<infer TItem>
90
+ ? Array<PopulateValue<TItem, TTableDocMap>>
91
+ : T;
92
+
93
+ export type PopulatableKeys<
94
+ TDoc,
95
+ TTableDocMap extends Record<string, TableDocBase>,
96
+ > = {
97
+ [K in Keys<TDoc>]: ExtractIdTableName<TDoc[K]> extends keyof TTableDocMap
98
+ ? K
99
+ : never;
100
+ }[Keys<TDoc>];
101
+
102
+ export type WithPopulated<
103
+ TDoc,
104
+ TKey extends Keys<TDoc>,
105
+ TTableDocMap extends Record<string, TableDocBase>,
106
+ > = {
107
+ [K in Keys<TDoc>]: K extends TKey
108
+ ? PopulateValue<TDoc[K], TTableDocMap>
109
+ : TDoc[K];
110
+ };
111
+
112
+ export type WithPopulatedMany<
113
+ TDoc,
114
+ TKeys extends Keys<TDoc>,
115
+ TTableDocMap extends Record<string, TableDocBase>,
116
+ > = {
117
+ [K in Keys<TDoc>]: K extends TKeys
118
+ ? PopulateValue<TDoc[K], TTableDocMap>
119
+ : TDoc[K];
120
+ };
121
+
122
+ export type WithSelected<TDoc, TKeys extends Keys<TDoc>> = Pick<TDoc, TKeys>;
123
+
124
+ export type MongoDbQuery<
125
+ TableName extends string,
126
+ TTableDocMap extends Record<string, TableDocBase>,
127
+ TResultDoc,
128
+ > = {
129
+ where(
130
+ filter: QueryWhere<TTableDocMap[TableName]>
131
+ ): MongoDbQuery<TableName, TTableDocMap, TResultDoc>;
132
+ sort(
133
+ sort: QuerySort<keyof TTableDocMap[TableName] & string>
134
+ ): MongoDbQuery<TableName, TTableDocMap, TResultDoc>;
135
+ limit(limit: number): MongoDbQuery<TableName, TTableDocMap, TResultDoc>;
136
+ offset(offset: number): MongoDbQuery<TableName, TTableDocMap, TResultDoc>;
137
+
138
+ select<const TKeys extends readonly Keys<TResultDoc>[]>(
139
+ keys: TKeys
140
+ ): MongoDbQuery<
141
+ TableName,
142
+ TTableDocMap,
143
+ WithSelected<TResultDoc, TKeys[number]>
144
+ >;
145
+ select<const TKeys extends readonly Keys<TResultDoc>[]>(
146
+ ...keys: TKeys
147
+ ): MongoDbQuery<
148
+ TableName,
149
+ TTableDocMap,
150
+ WithSelected<TResultDoc, TKeys[number]>
151
+ >;
152
+
153
+ populate<const TKey extends PopulatableKeys<TResultDoc, TTableDocMap>>(
154
+ key: TKey
155
+ ): MongoDbQuery<
156
+ TableName,
157
+ TTableDocMap,
158
+ WithPopulated<TResultDoc, TKey, TTableDocMap>
159
+ >;
160
+ populate<
161
+ const TKeys extends readonly PopulatableKeys<TResultDoc, TTableDocMap>[],
162
+ >(
163
+ keys: TKeys
164
+ ): MongoDbQuery<
165
+ TableName,
166
+ TTableDocMap,
167
+ WithPopulatedMany<TResultDoc, TKeys[number], TTableDocMap>
168
+ >;
169
+
170
+ find(): Promise<Array<TResultDoc>>;
171
+ findOne(): Promise<TResultDoc | null>;
172
+ };
173
+
174
+ export type MongoDbDeleteBuilder<
175
+ TableName extends string,
176
+ TTableDocMap extends Record<string, TableDocBase>,
177
+ > = {
178
+ where(where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>): {
179
+ exec(): Promise<void>;
180
+ };
181
+ };
182
+
183
+ export type MongoDbUpdateBuilder<
184
+ TableName extends string,
185
+ TTableDocMap extends Record<string, TableDocBase>,
186
+ > = {
187
+ where(where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>): {
188
+ set(partial: Partial<EditableDoc<TTableDocMap[TableName]>>): {
189
+ exec(): Promise<void>;
190
+ };
191
+ exec(partial: Partial<EditableDoc<TTableDocMap[TableName]>>): Promise<void>;
192
+ };
193
+ };
194
+
195
+ export type MongoDbPatchBuilder<
196
+ TableName extends string,
197
+ TTableDocMap extends Record<string, TableDocBase>,
198
+ > = MongoDbUpdateBuilder<TableName, TTableDocMap>;
199
+
200
+ export type MongoDbCoreContext<
201
+ TTableNames extends string,
202
+ TTableDocMap extends Record<TTableNames, TableDocBase>,
203
+ > = {
204
+ query<TableName extends TTableNames>(
205
+ table: TableName
206
+ ): MongoDbQuery<TableName, TTableDocMap, TTableDocMap[TableName]>;
207
+ insert<TableName extends TTableNames>(
208
+ table: TableName,
209
+ value: EditableDoc<TTableDocMap[TableName]>
210
+ ): Promise<Id<TableName>>;
211
+ update<TableName extends TTableNames>(
212
+ table: TableName
213
+ ): MongoDbUpdateBuilder<TableName, TTableDocMap>;
214
+ update<TableName extends TTableNames>(
215
+ table: TableName,
216
+ where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>,
217
+ partial: Partial<EditableDoc<TTableDocMap[TableName]>>
218
+ ): Promise<void>;
219
+ patch<TableName extends TTableNames>(
220
+ table: TableName
221
+ ): MongoDbPatchBuilder<TableName, TTableDocMap>;
222
+ patch<TableName extends TTableNames>(
223
+ table: TableName,
224
+ where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>,
225
+ partial: Partial<EditableDoc<TTableDocMap[TableName]>>
226
+ ): Promise<void>;
227
+ delete<TableName extends TTableNames>(
228
+ table: TableName
229
+ ): MongoDbDeleteBuilder<TableName, TTableDocMap>;
230
+ delete<TableName extends TTableNames>(
231
+ table: TableName,
232
+ where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>
233
+ ): Promise<void>;
234
+ };
235
+
236
+ export type AppflareFindManyArgs<
237
+ TableName extends string,
238
+ TTableDocMap extends Record<TableName, TableDocBase>,
239
+ > = {
240
+ where?: QueryWhere<TTableDocMap[TableName]>;
241
+ orderBy?: QuerySort<keyof TTableDocMap[TableName] & string>;
242
+ skip?: number;
243
+ take?: number;
244
+ select?: AppflareSelect<TTableDocMap[TableName]>;
245
+ include?: AppflareInclude<TTableDocMap[TableName], TTableDocMap>;
246
+ };
247
+
248
+ export type AppflareFindFirstArgs<
249
+ TableName extends string,
250
+ TTableDocMap extends Record<TableName, TableDocBase>,
251
+ > = AppflareFindManyArgs<TableName, TTableDocMap>;
252
+
253
+ export type AppflareFindUniqueArgs<
254
+ TableName extends string,
255
+ TTableDocMap extends Record<TableName, TableDocBase>,
256
+ > = Omit<
257
+ AppflareFindManyArgs<TableName, TTableDocMap>,
258
+ "skip" | "take" | "orderBy"
259
+ > & {
260
+ where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>;
261
+ };
262
+
263
+ export type AppflareCreateArgs<
264
+ TableName extends string,
265
+ TTableDocMap extends Record<TableName, TableDocBase>,
266
+ > = {
267
+ data: EditableDoc<TTableDocMap[TableName]>;
268
+ select?: AppflareSelect<TTableDocMap[TableName]>;
269
+ include?: AppflareInclude<TTableDocMap[TableName], TTableDocMap>;
270
+ };
271
+
272
+ export type AppflareUpdateArgs<
273
+ TableName extends string,
274
+ TTableDocMap extends Record<TableName, TableDocBase>,
275
+ > = {
276
+ where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>;
277
+ data: Partial<EditableDoc<TTableDocMap[TableName]>>;
278
+ select?: AppflareSelect<TTableDocMap[TableName]>;
279
+ include?: AppflareInclude<TTableDocMap[TableName], TTableDocMap>;
280
+ };
281
+
282
+ export type AppflareDeleteArgs<
283
+ TableName extends string,
284
+ TTableDocMap extends Record<TableName, TableDocBase>,
285
+ > = {
286
+ where: Id<TableName> | QueryWhere<TTableDocMap[TableName]>;
287
+ select?: AppflareSelect<TTableDocMap[TableName]>;
288
+ include?: AppflareInclude<TTableDocMap[TableName], TTableDocMap>;
289
+ };
290
+
291
+ export type AppflareUpdateManyArgs<
292
+ TableName extends string,
293
+ TTableDocMap extends Record<TableName, TableDocBase>,
294
+ > = {
295
+ where?: QueryWhere<TTableDocMap[TableName]>;
296
+ data: Partial<EditableDoc<TTableDocMap[TableName]>>;
297
+ };
298
+
299
+ export type AppflareDeleteManyArgs<
300
+ TableName extends string,
301
+ TTableDocMap extends Record<TableName, TableDocBase>,
302
+ > = {
303
+ where?: QueryWhere<TTableDocMap[TableName]>;
304
+ };
305
+
306
+ export type AppflareCountArgs<
307
+ TableName extends string,
308
+ TTableDocMap extends Record<TableName, TableDocBase>,
309
+ > = {
310
+ where?: QueryWhere<TTableDocMap[TableName]>;
311
+ };
312
+
313
+ export type AppflareTableClient<
314
+ TableName extends string,
315
+ TTableDocMap extends Record<TableName, TableDocBase>,
316
+ > = {
317
+ findMany<TSelect = AppflareSelect<TTableDocMap[TableName]>, TInclude = never>(
318
+ args?: AppflareFindManyArgs<TableName, TTableDocMap> & {
319
+ select?: TSelect;
320
+ include?: TInclude;
321
+ }
322
+ ): Promise<
323
+ Array<
324
+ AppflareResultDoc<
325
+ TTableDocMap[TableName],
326
+ TSelect,
327
+ TInclude,
328
+ TTableDocMap
329
+ >
330
+ >
331
+ >;
332
+ findFirst<
333
+ TSelect = AppflareSelect<TTableDocMap[TableName]>,
334
+ TInclude = never,
335
+ >(
336
+ args?: AppflareFindFirstArgs<TableName, TTableDocMap> & {
337
+ select?: TSelect;
338
+ include?: TInclude;
339
+ }
340
+ ): Promise<AppflareResultDoc<
341
+ TTableDocMap[TableName],
342
+ TSelect,
343
+ TInclude,
344
+ TTableDocMap
345
+ > | null>;
346
+ findUnique<
347
+ TSelect = AppflareSelect<TTableDocMap[TableName]>,
348
+ TInclude = never,
349
+ >(
350
+ args: AppflareFindUniqueArgs<TableName, TTableDocMap> & {
351
+ select?: TSelect;
352
+ include?: TInclude;
353
+ }
354
+ ): Promise<AppflareResultDoc<
355
+ TTableDocMap[TableName],
356
+ TSelect,
357
+ TInclude,
358
+ TTableDocMap
359
+ > | null>;
360
+ create<TSelect = AppflareSelect<TTableDocMap[TableName]>, TInclude = never>(
361
+ args: AppflareCreateArgs<TableName, TTableDocMap> & {
362
+ select?: TSelect;
363
+ include?: TInclude;
364
+ }
365
+ ): Promise<
366
+ AppflareResultDoc<TTableDocMap[TableName], TSelect, TInclude, TTableDocMap>
367
+ >;
368
+ update<TSelect = AppflareSelect<TTableDocMap[TableName]>, TInclude = never>(
369
+ args: AppflareUpdateArgs<TableName, TTableDocMap> & {
370
+ select?: TSelect;
371
+ include?: TInclude;
372
+ }
373
+ ): Promise<AppflareResultDoc<
374
+ TTableDocMap[TableName],
375
+ TSelect,
376
+ TInclude,
377
+ TTableDocMap
378
+ > | null>;
379
+ updateMany(
380
+ args: AppflareUpdateManyArgs<TableName, TTableDocMap>
381
+ ): Promise<{ count: number }>;
382
+ delete<TSelect = AppflareSelect<TTableDocMap[TableName]>, TInclude = never>(
383
+ args: AppflareDeleteArgs<TableName, TTableDocMap> & {
384
+ select?: TSelect;
385
+ include?: TInclude;
386
+ }
387
+ ): Promise<AppflareResultDoc<
388
+ TTableDocMap[TableName],
389
+ TSelect,
390
+ TInclude,
391
+ TTableDocMap
392
+ > | null>;
393
+ deleteMany(
394
+ args?: AppflareDeleteManyArgs<TableName, TTableDocMap>
395
+ ): Promise<{ count: number }>;
396
+ count(args?: AppflareCountArgs<TableName, TTableDocMap>): Promise<number>;
397
+ };
398
+
399
+ export type AppflareModelMap<
400
+ TTableNames extends string,
401
+ TTableDocMap extends Record<TTableNames, TableDocBase>,
402
+ > = {
403
+ [K in TTableNames]: AppflareTableClient<K, TTableDocMap>;
404
+ };
405
+
406
+ export type MongoDbContext<
407
+ TTableNames extends string,
408
+ TTableDocMap extends Record<TTableNames, TableDocBase>,
409
+ > = AppflareModelMap<TTableNames, TTableDocMap>;
410
+
411
+ export type CreateMongoDbContextOptions<TTableNames extends string> = {
412
+ db: Db;
413
+ /** The same schema object you pass to defineSchema(...) */
414
+ schema: Record<TTableNames, AnyZod>;
415
+ /** Override collection naming if desired. Default is the table name. */
416
+ collectionName?: (table: TTableNames) => string;
417
+ };
418
+
419
+ export type SchemaRefMap = Map<string, Map<string, string>>;
@@ -0,0 +1,123 @@
1
+ import type { Document, Filter } from "mongodb";
2
+ import { ObjectId } from "mongodb";
3
+ import type { Id, QueryWhere, SchemaRefMap } from "../types/types";
4
+
5
+ export function isIdValue(value: unknown): value is string {
6
+ return typeof value === "string";
7
+ }
8
+
9
+ export function toMongoFilter(
10
+ where: Id<any> | QueryWhere<any>
11
+ ): Filter<Document> {
12
+ if (isIdValue(where)) {
13
+ return { _id: where as any } satisfies Filter<Document> as any;
14
+ }
15
+ if (where && typeof where === "object") {
16
+ return where as Filter<Document>;
17
+ }
18
+ throw new Error("update/delete requires an id or where filter object");
19
+ }
20
+
21
+ export function stringifyIdField(doc: Record<string, unknown>) {
22
+ const id = doc._id;
23
+ if (id instanceof ObjectId) {
24
+ doc._id = id.toHexString();
25
+ }
26
+ }
27
+
28
+ export function normalizeIdFilter(
29
+ filter: Filter<Document> | undefined
30
+ ): Filter<Document> | undefined {
31
+ if (!filter) return filter;
32
+ return normalizeIdFilterValue(filter) as Filter<Document>;
33
+ }
34
+
35
+ function normalizeIdFilterValue(value: unknown): unknown {
36
+ if (Array.isArray(value)) return value.map(normalizeIdFilterValue);
37
+ if (value && typeof value === "object") {
38
+ const out: Record<string, unknown> = {};
39
+ for (const [key, val] of Object.entries(value)) {
40
+ if (key === "_id") {
41
+ out[key] = normalizeIdValueForFilter(val);
42
+ continue;
43
+ }
44
+ if (key === "$and" || key === "$or" || key === "$nor") {
45
+ out[key] = Array.isArray(val)
46
+ ? val.map(normalizeIdFilterValue)
47
+ : normalizeIdFilterValue(val);
48
+ continue;
49
+ }
50
+ out[key] = normalizeIdFilterValue(val);
51
+ }
52
+ return out;
53
+ }
54
+ return value;
55
+ }
56
+
57
+ function normalizeIdValueForFilter(value: unknown): unknown {
58
+ if (Array.isArray(value)) return value.map(normalizeIdValueForFilter);
59
+ if (value && typeof value === "object") {
60
+ const out: Record<string, unknown> = {};
61
+ for (const [key, val] of Object.entries(value)) {
62
+ if (key === "$in" || key === "$nin" || key === "$all") {
63
+ out[key] = Array.isArray(val)
64
+ ? val.map(normalizeIdValue)
65
+ : normalizeIdValue(val);
66
+ continue;
67
+ }
68
+ out[key] = normalizeIdValueForFilter(val);
69
+ }
70
+ return out;
71
+ }
72
+ return normalizeIdValue(value);
73
+ }
74
+
75
+ export function normalizeIdValue(value: unknown): unknown {
76
+ if (value instanceof ObjectId) return value;
77
+ if (typeof value === "string" && ObjectId.isValid(value)) {
78
+ return new ObjectId(value);
79
+ }
80
+ return value;
81
+ }
82
+
83
+ export function normalizeRefFields(
84
+ table: string,
85
+ value: Record<string, unknown>,
86
+ refs: SchemaRefMap
87
+ ): Record<string, unknown> {
88
+ const tableRefs = refs.get(table);
89
+ if (!tableRefs) return value;
90
+
91
+ const out: Record<string, unknown> = { ...value };
92
+ for (const key of tableRefs.keys()) {
93
+ if (!(key in out)) continue;
94
+ out[key] = normalizeRefFieldValue(out[key]);
95
+ }
96
+ return out;
97
+ }
98
+
99
+ function normalizeRefFieldValue(value: unknown): unknown {
100
+ if (Array.isArray(value)) return value.map(normalizeRefFieldValue);
101
+ return normalizeIdValue(value);
102
+ }
103
+
104
+ export function stringifyRefFields(
105
+ table: string,
106
+ doc: Record<string, unknown>,
107
+ refs: SchemaRefMap
108
+ ) {
109
+ const tableRefs = refs.get(table);
110
+ if (!tableRefs) return;
111
+
112
+ for (const key of tableRefs.keys()) {
113
+ const value = doc[key];
114
+ if (value === undefined) continue;
115
+ doc[key] = stringifyRefFieldValue(value);
116
+ }
117
+ }
118
+
119
+ function stringifyRefFieldValue(value: unknown): unknown {
120
+ if (value instanceof ObjectId) return value.toHexString();
121
+ if (Array.isArray(value)) return value.map(stringifyRefFieldValue);
122
+ return value;
123
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2022",
4
+ "module": "es2022",
5
+ "moduleResolution": "bundler"
6
+ }
7
+ }