@edgestore/server 0.0.0-alpha.12

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 (83) hide show
  1. package/README.md +86 -0
  2. package/adapters/next/app/index.d.ts +1 -0
  3. package/adapters/next/app/index.js +1 -0
  4. package/adapters/next/index.d.ts +1 -0
  5. package/adapters/next/index.js +1 -0
  6. package/adapters/next/pages/index.d.ts +1 -0
  7. package/adapters/next/pages/index.js +1 -0
  8. package/core/index.d.ts +1 -0
  9. package/core/index.js +1 -0
  10. package/dist/adapters/imageTypes.d.ts +2 -0
  11. package/dist/adapters/imageTypes.d.ts.map +1 -0
  12. package/dist/adapters/next/app/index.d.ts +14 -0
  13. package/dist/adapters/next/app/index.d.ts.map +1 -0
  14. package/dist/adapters/next/app/index.js +95 -0
  15. package/dist/adapters/next/app/index.mjs +91 -0
  16. package/dist/adapters/next/pages/index.d.ts +15 -0
  17. package/dist/adapters/next/pages/index.d.ts.map +1 -0
  18. package/dist/adapters/next/pages/index.js +69 -0
  19. package/dist/adapters/next/pages/index.mjs +65 -0
  20. package/dist/adapters/shared.d.ts +79 -0
  21. package/dist/adapters/shared.d.ts.map +1 -0
  22. package/dist/core/client/index.d.ts +81 -0
  23. package/dist/core/client/index.d.ts.map +1 -0
  24. package/dist/core/index.d.ts +6 -0
  25. package/dist/core/index.d.ts.map +1 -0
  26. package/dist/core/index.js +96 -0
  27. package/dist/core/index.mjs +91 -0
  28. package/dist/core/internals/bucketBuilder.d.ts +199 -0
  29. package/dist/core/internals/bucketBuilder.d.ts.map +1 -0
  30. package/dist/core/internals/createPathParamProxy.d.ts +21 -0
  31. package/dist/core/internals/createPathParamProxy.d.ts.map +1 -0
  32. package/dist/core/sdk/index.d.ts +200 -0
  33. package/dist/core/sdk/index.d.ts.map +1 -0
  34. package/dist/index-3999aae6.js +187 -0
  35. package/dist/index-3cc4d530.js +183 -0
  36. package/dist/index-ca41982b.mjs +183 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +213 -0
  40. package/dist/index.mjs +209 -0
  41. package/dist/libs/errors/EdgeStoreCredentialsError.d.ts +5 -0
  42. package/dist/libs/errors/EdgeStoreCredentialsError.d.ts.map +1 -0
  43. package/dist/libs/errors/EdgeStoreError.d.ts +16 -0
  44. package/dist/libs/errors/EdgeStoreError.d.ts.map +1 -0
  45. package/dist/providers/aws/index.d.ts +9 -0
  46. package/dist/providers/aws/index.d.ts.map +1 -0
  47. package/dist/providers/aws/index.js +81 -0
  48. package/dist/providers/aws/index.mjs +77 -0
  49. package/dist/providers/edgestore/index.d.ts +8 -0
  50. package/dist/providers/edgestore/index.d.ts.map +1 -0
  51. package/dist/providers/edgestore/index.js +121 -0
  52. package/dist/providers/edgestore/index.mjs +117 -0
  53. package/dist/providers/index.d.ts +3 -0
  54. package/dist/providers/index.d.ts.map +1 -0
  55. package/dist/providers/types.d.ts +91 -0
  56. package/dist/providers/types.d.ts.map +1 -0
  57. package/dist/shared-43667670.mjs +232 -0
  58. package/dist/shared-6bef8919.js +227 -0
  59. package/dist/shared-f7607e44.js +239 -0
  60. package/dist/types.d.ts +88 -0
  61. package/dist/types.d.ts.map +1 -0
  62. package/package.json +96 -0
  63. package/providers/aws/index.d.ts +1 -0
  64. package/providers/aws/index.js +1 -0
  65. package/providers/edgestore/index.d.ts +1 -0
  66. package/providers/edgestore/index.js +1 -0
  67. package/src/adapters/imageTypes.ts +10 -0
  68. package/src/adapters/next/app/index.ts +111 -0
  69. package/src/adapters/next/pages/index.ts +84 -0
  70. package/src/adapters/shared.ts +306 -0
  71. package/src/core/client/index.ts +202 -0
  72. package/src/core/index.ts +10 -0
  73. package/src/core/internals/bucketBuilder.ts +462 -0
  74. package/src/core/internals/createPathParamProxy.ts +40 -0
  75. package/src/core/sdk/index.ts +381 -0
  76. package/src/index.ts +1 -0
  77. package/src/libs/errors/EdgeStoreCredentialsError.ts +12 -0
  78. package/src/libs/errors/EdgeStoreError.ts +25 -0
  79. package/src/providers/aws/index.ts +109 -0
  80. package/src/providers/edgestore/index.ts +140 -0
  81. package/src/providers/index.ts +2 -0
  82. package/src/providers/types.ts +107 -0
  83. package/src/types.ts +139 -0
@@ -0,0 +1,462 @@
1
+ import { z } from 'zod';
2
+ import { KeysOfUnion, MaybePromise, Simplify } from '../../types';
3
+ import { createPathParamProxy } from './createPathParamProxy';
4
+
5
+ type Merge<TType, TWith> = {
6
+ [TKey in keyof TType | keyof TWith]?: TKey extends keyof TType
7
+ ? TKey extends keyof TWith
8
+ ? TType[TKey] & TWith[TKey]
9
+ : TType[TKey]
10
+ : TWith[TKey & keyof TWith];
11
+ };
12
+
13
+ type OverwriteIfDefined<TType, TWith> = UnsetMarker extends TType
14
+ ? TWith
15
+ : Simplify<TType & TWith>;
16
+
17
+ type ConvertStringToFunction<TType> = {
18
+ [K in keyof TType]: TType[K] extends object
19
+ ? Simplify<ConvertStringToFunction<TType[K]>>
20
+ : () => string;
21
+ };
22
+
23
+ type UnionToIntersection<TType> = (
24
+ TType extends any ? (k: TType) => void : never
25
+ ) extends (k: infer I) => void
26
+ ? I
27
+ : never;
28
+
29
+ export type InferBucketPathKeys<TBucket extends Builder<any, AnyDef>> =
30
+ KeysOfUnion<TBucket['_def']['path'][number]>;
31
+
32
+ type InferBucketPathKeysFromDef<TDef extends AnyDef> = KeysOfUnion<
33
+ TDef['path'][number]
34
+ >;
35
+
36
+ export type InferMetadataObject<TBucket extends Builder<any, AnyDef>> =
37
+ TBucket['_def']['metadata'] extends (...args: any) => any
38
+ ? Awaited<ReturnType<TBucket['_def']['metadata']>>
39
+ : TBucket['_def']['metadata'] extends ((...args: any) => any) | undefined
40
+ ? any
41
+ : never;
42
+
43
+ type InferMetadataObjectFromDef<TDef extends AnyDef> =
44
+ TDef['metadata'] extends (...args: any) => any
45
+ ? Awaited<ReturnType<TDef['metadata']>>
46
+ : TDef['metadata'] extends ((...args: any) => any) | undefined
47
+ ? any
48
+ : never;
49
+
50
+ export type AnyContext = Record<string, string | undefined | null>;
51
+
52
+ export type AnyInput = z.AnyZodObject;
53
+
54
+ export type AnyPath = Record<string, () => string>[];
55
+
56
+ type PathParam<TPath extends AnyPath> = {
57
+ path: keyof UnionToIntersection<TPath[number]>;
58
+ };
59
+
60
+ const unsetMarker = Symbol('unsetMarker');
61
+
62
+ type UnsetMarker = typeof unsetMarker;
63
+
64
+ type Conditions<TPath extends AnyPath> = {
65
+ eq?: string | PathParam<TPath>;
66
+ lt?: string | PathParam<TPath>;
67
+ lte?: string | PathParam<TPath>;
68
+ gt?: string | PathParam<TPath>;
69
+ gte?: string | PathParam<TPath>;
70
+ contains?: string | PathParam<TPath>;
71
+ in?: string | PathParam<TPath> | (string | PathParam<TPath>)[];
72
+ not?: string | PathParam<TPath> | Conditions<TPath>;
73
+ };
74
+
75
+ export type AccessControlSchema<TCtx, TDef extends AnyDef> = Merge<
76
+ {
77
+ [TKey in keyof TCtx]?:
78
+ | string
79
+ | PathParam<TDef['path']>
80
+ | Conditions<TDef['path']>;
81
+ },
82
+ {
83
+ OR?: AccessControlSchema<TCtx, TDef>[];
84
+ AND?: AccessControlSchema<TCtx, TDef>[];
85
+ NOT?: AccessControlSchema<TCtx, TDef>[];
86
+ }
87
+ >;
88
+
89
+ type FileInfo = {
90
+ size: number;
91
+ type: string;
92
+ extension: string;
93
+ replaceTargetUrl?: string;
94
+ };
95
+
96
+ type BeforeUploadFn<TCtx, TDef extends AnyDef> = (params: {
97
+ ctx: TCtx;
98
+ input: z.infer<TDef['input']>;
99
+ fileInfo: FileInfo;
100
+ }) => MaybePromise<boolean>;
101
+
102
+ type BeforeDeleteFn<TCtx, TDef extends AnyDef> = (params: {
103
+ ctx: TCtx;
104
+ file: {
105
+ url: string;
106
+ size: number;
107
+ uploadedAt: Date;
108
+ path: {
109
+ [TKey in InferBucketPathKeysFromDef<TDef>]: string;
110
+ };
111
+ metadata: InferMetadataObjectFromDef<TDef>;
112
+ };
113
+ }) => MaybePromise<boolean>;
114
+
115
+ type AnyMetadata = Record<string, string | undefined | null>;
116
+
117
+ type MetadataFn<
118
+ TCtx,
119
+ TDef extends AnyDef,
120
+ TMetadata extends AnyMetadata,
121
+ > = (params: {
122
+ ctx: TCtx;
123
+ input: z.infer<TDef['input']>;
124
+ }) => MaybePromise<TMetadata>;
125
+
126
+ type BucketType = 'IMAGE' | 'FILE';
127
+
128
+ type Def<TInput extends AnyInput, TPath extends AnyPath> = {
129
+ type: any;
130
+ input: TInput;
131
+ path: TPath;
132
+ metadata?: MetadataFn<any, any, any>;
133
+ accessControl?: AccessControlSchema<any, any>;
134
+ beforeUpload?: BeforeUploadFn<any, any>;
135
+ beforeDelete?: BeforeDeleteFn<any, any>;
136
+ };
137
+
138
+ type AnyDef = Def<any, any>;
139
+
140
+ type Builder<TCtx, TDef extends AnyDef> = {
141
+ /** only used for types */
142
+ $config: {
143
+ ctx: TCtx;
144
+ };
145
+ /**
146
+ * @internal
147
+ */
148
+ _def: TDef;
149
+ input<TInput extends AnyInput>(
150
+ input: TInput,
151
+ ): Builder<
152
+ TCtx,
153
+ {
154
+ type: TDef['type'];
155
+ input: OverwriteIfDefined<TDef['input'], TInput>;
156
+ path: TDef['path'];
157
+ metadata: TDef['metadata'];
158
+ accessControl: TDef['accessControl'];
159
+ beforeUpload: TDef['beforeUpload'];
160
+ beforeDelete: TDef['beforeDelete'];
161
+ }
162
+ >;
163
+ path<TParams extends AnyPath>(
164
+ pathResolver: (params: {
165
+ ctx: Simplify<ConvertStringToFunction<TCtx>>;
166
+ input: Simplify<ConvertStringToFunction<z.infer<TDef['input']>>>;
167
+ }) => [...TParams],
168
+ ): Builder<
169
+ TCtx,
170
+ {
171
+ type: TDef['type'];
172
+ input: TDef['input'];
173
+ path: TParams;
174
+ metadata: TDef['metadata'];
175
+ accessControl: TDef['accessControl'];
176
+ beforeUpload: TDef['beforeUpload'];
177
+ beforeDelete: TDef['beforeDelete'];
178
+ }
179
+ >;
180
+ metadata<TMetadata extends AnyMetadata>(
181
+ metadata: MetadataFn<TCtx, TDef, TMetadata>,
182
+ ): Builder<
183
+ TCtx,
184
+ {
185
+ type: TDef['type'];
186
+ input: TDef['input'];
187
+ path: TDef['path'];
188
+ metadata: MetadataFn<any, any, TMetadata>;
189
+ accessControl: TDef['accessControl'];
190
+ beforeUpload: TDef['beforeUpload'];
191
+ beforeDelete: TDef['beforeDelete'];
192
+ }
193
+ >;
194
+ accessControl(accessControl: AccessControlSchema<TCtx, TDef>): Builder<
195
+ TCtx,
196
+ {
197
+ type: TDef['type'];
198
+ input: TDef['input'];
199
+ path: TDef['path'];
200
+ metadata: TDef['metadata'];
201
+ accessControl: AccessControlSchema<any, any>;
202
+ beforeUpload: TDef['beforeUpload'];
203
+ beforeDelete: TDef['beforeDelete'];
204
+ }
205
+ >;
206
+ beforeUpload(beforeUpload: BeforeUploadFn<TCtx, TDef>): Builder<
207
+ TCtx,
208
+ {
209
+ type: TDef['type'];
210
+ input: TDef['input'];
211
+ path: TDef['path'];
212
+ metadata: TDef['metadata'];
213
+ accessControl: TDef['accessControl'];
214
+ beforeUpload: BeforeUploadFn<any, any>;
215
+ beforeDelete: TDef['beforeDelete'];
216
+ }
217
+ >;
218
+ beforeDelete(beforeDelete: BeforeDeleteFn<TCtx, TDef>): Builder<
219
+ TCtx,
220
+ {
221
+ type: TDef['type'];
222
+ input: TDef['input'];
223
+ path: TDef['path'];
224
+ metadata: TDef['metadata'];
225
+ accessControl: TDef['accessControl'];
226
+ beforeUpload: TDef['beforeUpload'];
227
+ beforeDelete: BeforeDeleteFn<any, any>;
228
+ }
229
+ >;
230
+ };
231
+
232
+ export type AnyBuilder = Builder<any, AnyDef>;
233
+
234
+ const createNewBuilder = (initDef: AnyDef, newDef: Partial<AnyDef>) => {
235
+ const mergedDef = {
236
+ ...initDef,
237
+ ...newDef,
238
+ };
239
+ return createBuilder(
240
+ {
241
+ type: mergedDef.type,
242
+ },
243
+ mergedDef,
244
+ );
245
+ };
246
+
247
+ function createBuilder<TCtx, TType extends BucketType>(
248
+ opts: { type: TType },
249
+ initDef?: Partial<AnyDef>,
250
+ ): Builder<
251
+ TCtx,
252
+ {
253
+ type: TType;
254
+ input: UnsetMarker;
255
+ path: UnsetMarker;
256
+ metadata?: MetadataFn<any, any, any>;
257
+ accessControl?: AccessControlSchema<any, any>;
258
+ beforeUpload?: BeforeUploadFn<any, any>;
259
+ beforeDelete?: BeforeDeleteFn<any, any>;
260
+ }
261
+ > {
262
+ const _def: AnyDef = {
263
+ type: opts.type,
264
+ input: z.never(),
265
+ path: [],
266
+ ...initDef,
267
+ };
268
+
269
+ return {
270
+ $config: {
271
+ ctx: undefined as TCtx,
272
+ },
273
+ _def,
274
+ input(input) {
275
+ return createNewBuilder(_def, {
276
+ input,
277
+ }) as any;
278
+ },
279
+ path(pathResolver) {
280
+ // TODO: Should throw a runtime error in the followin cases:
281
+ // 1. in case of multiple keys in one object
282
+ // 2. in case of duplicate keys
283
+ const pathParamProxy = createPathParamProxy();
284
+ const params = pathResolver(pathParamProxy);
285
+ return createNewBuilder(_def, {
286
+ path: params,
287
+ }) as any;
288
+ },
289
+ metadata(metadata) {
290
+ return createNewBuilder(_def, {
291
+ metadata,
292
+ }) as any;
293
+ },
294
+ accessControl(accessControl) {
295
+ return createNewBuilder(_def, {
296
+ accessControl: accessControl,
297
+ }) as any;
298
+ },
299
+ beforeUpload(beforeUpload) {
300
+ return createNewBuilder(_def, {
301
+ beforeUpload,
302
+ }) as any;
303
+ },
304
+ beforeDelete(beforeDelete) {
305
+ return createNewBuilder(_def, {
306
+ beforeDelete,
307
+ }) as any;
308
+ },
309
+ };
310
+ }
311
+
312
+ class EdgeStoreBuilder<TCtx = object> {
313
+ context<TNewContext extends AnyContext>() {
314
+ return new EdgeStoreBuilder<TNewContext>();
315
+ }
316
+
317
+ create() {
318
+ return createEdgeStoreInner<TCtx>()();
319
+ }
320
+ }
321
+
322
+ export type EdgeStoreRouter<TCtx> = {
323
+ /**
324
+ * Only used for types
325
+ * @internal
326
+ */
327
+ $config: {
328
+ ctx: TCtx;
329
+ };
330
+ buckets: Record<string, Builder<TCtx, AnyDef>>;
331
+ };
332
+
333
+ function createRouterFactory<TCtx>() {
334
+ return function createRouterInner<
335
+ TBuckets extends EdgeStoreRouter<TCtx>['buckets'],
336
+ >(buckets: TBuckets) {
337
+ return {
338
+ $config: {
339
+ ctx: undefined as TCtx,
340
+ },
341
+ buckets,
342
+ } satisfies EdgeStoreRouter<TCtx>;
343
+ };
344
+ }
345
+
346
+ function createEdgeStoreInner<TCtx>() {
347
+ return function initEdgeStoreInner() {
348
+ return {
349
+ /**
350
+ * Builder object for creating an image bucket
351
+ */
352
+ imageBucket: createBuilder<TCtx, 'IMAGE'>({ type: 'IMAGE' }),
353
+ /**
354
+ * Builder object for creating a file bucket
355
+ */
356
+ fileBucket: createBuilder<TCtx, 'FILE'>({ type: 'FILE' }),
357
+ /**
358
+ * Create a router
359
+ */
360
+ router: createRouterFactory<TCtx>(),
361
+ };
362
+ };
363
+ }
364
+
365
+ /**
366
+ * Initialize EdgeStore - be done exactly once per backend
367
+ */
368
+ export const initEdgeStore = new EdgeStoreBuilder();
369
+
370
+ // ↓↓↓ TYPE TESTS ↓↓↓
371
+
372
+ // type Context = {
373
+ // userId: string;
374
+ // userRole: 'admin' | 'visitor';
375
+ // };
376
+
377
+ // const es = initEdgeStore.context<Context>().create();
378
+
379
+ // const imagesBucket = es.imageBucket
380
+ // .input(
381
+ // z.object({
382
+ // type: z.enum(['profile', 'post']),
383
+ // extension: z.string().optional(),
384
+ // }),
385
+ // )
386
+ // .path(({ ctx, input }) => [{ author: ctx.userId }, { type: input.type }])
387
+ // .metadata(({ ctx, input }) => ({
388
+ // extension: input.extension,
389
+ // role: ctx.userRole,
390
+ // }))
391
+ // .beforeUpload(() => {
392
+ // return true;
393
+ // });
394
+ // const a = es.imageBucket
395
+ // .input(z.object({ type: z.string(), someMeta: z.string().optional() }))
396
+ // .path(({ ctx, input }) => [{ author: ctx.userId }, { type: input.type }])
397
+ // .metadata(({ ctx, input }) => ({
398
+ // role: ctx.userRole,
399
+ // someMeta: input.someMeta,
400
+ // }))
401
+ // .accessControl({
402
+ // OR: [
403
+ // {
404
+ // userId: { path: 'author' }, // this will check if the userId is the same as the author in the path parameter
405
+ // },
406
+ // {
407
+ // userRole: 'admin', // this is the same as { userRole: { eq: "admin" } }
408
+ // },
409
+ // ],
410
+ // })
411
+ // .beforeUpload(({ ctx, input }) => {
412
+ // return true;
413
+ // })
414
+ // .beforeDelete(({ ctx, file }) => {
415
+ // return true;
416
+ // });
417
+
418
+ // const b = es.imageBucket.path(({ ctx }) => [{ author: ctx.userId }]);
419
+
420
+ // const router = es.router({
421
+ // original: imagesBucket,
422
+ // imageBucket: a,
423
+ // imageBucket2: b,
424
+ // });
425
+
426
+ // export { router };
427
+
428
+ // type ListFilesResponse<TBucket extends AnyRouter['buckets'][string]> = {
429
+ // data: {
430
+ // // url: string;
431
+ // // size: number;
432
+ // // uploadedAt: Date;
433
+ // // metadata: InferMetadataObject<TBucket>;
434
+ // path: InferBucketPathKeys<TBucket> extends string ? {
435
+ // [key: string]: string;
436
+ // } :{
437
+ // [TKey in InferBucketPathKeys<TBucket>]: string;
438
+ // };
439
+ // }[];
440
+ // pagination: {
441
+ // currentPage: number;
442
+ // totalPages: number;
443
+ // totalCount: number;
444
+ // };
445
+ // };
446
+
447
+ // type TPathKeys = 'author' | 'type';
448
+ // type TPathKeys2 = InferBucketPathKeys<AnyBuilder>;
449
+
450
+ // type ObjectWithKeys<TKeys extends string> = {
451
+ // [TKey in TKeys]: string;
452
+ // };
453
+
454
+ // type Test1 = ObjectWithKeys<TPathKeys>;
455
+ // type Test2 = ObjectWithKeys<TPathKeys2>;
456
+ // type PathKeys = InferBucketPathKeys<typeof router.buckets.imageBucket>;
457
+
458
+ // type MetadataKeys = InferMetadataObject<typeof router.buckets.imageBucket>;
459
+
460
+ // type MyEdgeStoreRouter = typeof router;
461
+
462
+ // type MyAccessControl = AccessControlSchema<Context, AnyDef>;
@@ -0,0 +1,40 @@
1
+ type RecursivePathProxy = {
2
+ (): string;
3
+ ctx: any;
4
+ input: any;
5
+ };
6
+
7
+ /**
8
+ * Creates a Proxy that prints the path to the property when called.
9
+ *
10
+ * Example:
11
+ *
12
+ * ```ts
13
+ * const pathParamProxy = createPathParamProxy();
14
+ * console.log(pathParamProxy.ctx.user.id());
15
+ * // Logs: "ctx.user.id"
16
+ * console.log(pathParamProxy.input.type());
17
+ * // Logs: "input.type"
18
+ * ```
19
+ */
20
+ export function createPathParamProxy(): RecursivePathProxy {
21
+ const getPath = (
22
+ target: string,
23
+ _prop: string | symbol,
24
+ ): RecursivePathProxy => {
25
+ const proxyFunction: RecursivePathProxy = (() =>
26
+ target) as RecursivePathProxy;
27
+
28
+ return new Proxy(proxyFunction, {
29
+ get: (_target, propChild) => {
30
+ return getPath(`${target}.${String(propChild)}`, propChild);
31
+ },
32
+ });
33
+ };
34
+
35
+ return new Proxy((() => '') as RecursivePathProxy, {
36
+ get: (_target, prop) => {
37
+ return getPath(String(prop), String(prop));
38
+ },
39
+ });
40
+ }