@edgestore/server 0.1.0 → 0.1.2
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/README.md +6 -6
- package/adapters/index.d.ts +1 -0
- package/adapters/index.js +1 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.mjs +1 -0
- package/dist/adapters/next/app/index.d.ts +4 -4
- package/dist/adapters/next/app/index.d.ts.map +1 -1
- package/dist/adapters/next/app/index.js +22 -2
- package/dist/adapters/next/app/index.mjs +22 -2
- package/dist/adapters/next/pages/index.d.ts +4 -4
- package/dist/adapters/next/pages/index.d.ts.map +1 -1
- package/dist/adapters/next/pages/index.js +18 -2
- package/dist/adapters/next/pages/index.mjs +18 -2
- package/dist/adapters/shared.d.ts +35 -2
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/core/client/index.d.ts +11 -3
- package/dist/core/client/index.d.ts.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +5 -4
- package/dist/core/index.mjs +6 -5
- package/dist/core/internals/bucketBuilder.d.ts +2 -1
- package/dist/core/internals/bucketBuilder.d.ts.map +1 -1
- package/dist/core/sdk/index.d.ts +43 -2
- package/dist/core/sdk/index.d.ts.map +1 -1
- package/dist/{index-579b8015.mjs → index-30a3741e.mjs} +43 -2
- package/dist/{index-62d969e5.js → index-50ab9e08.js} +43 -2
- package/dist/{index-0a168903.js → index-f33a00fb.js} +41 -0
- package/dist/providers/aws/index.d.ts +28 -1
- package/dist/providers/aws/index.d.ts.map +1 -1
- package/dist/providers/aws/index.js +7 -1
- package/dist/providers/aws/index.mjs +7 -1
- package/dist/providers/edgestore/index.d.ts +13 -1
- package/dist/providers/edgestore/index.d.ts.map +1 -1
- package/dist/providers/edgestore/index.js +24 -10
- package/dist/providers/edgestore/index.mjs +24 -10
- package/dist/providers/index.d.ts +1 -2
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +2 -0
- package/dist/providers/index.mjs +1 -0
- package/dist/providers/types.d.ts +26 -2
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/{shared-2a9c8307.mjs → shared-7fc08e14.mjs} +40 -2
- package/dist/{shared-ae739a04.js → shared-a5b84d0b.js} +41 -1
- package/dist/{shared-fac1b0a0.js → shared-a86ccc68.js} +39 -1
- package/package.json +13 -3
- package/providers/index.d.ts +1 -0
- package/providers/index.js +1 -0
- package/src/adapters/index.ts +6 -0
- package/src/adapters/next/app/index.ts +33 -7
- package/src/adapters/next/pages/index.ts +27 -7
- package/src/adapters/shared.ts +90 -2
- package/src/core/client/index.ts +15 -9
- package/src/core/index.ts +1 -1
- package/src/core/internals/bucketBuilder.ts +6 -1
- package/src/core/sdk/index.ts +83 -2
- package/src/providers/aws/index.ts +39 -5
- package/src/providers/edgestore/index.ts +34 -9
- package/src/providers/index.ts +1 -2
- package/src/providers/types.ts +34 -4
|
@@ -82,7 +82,8 @@ async function requestUpload(params) {
|
|
|
82
82
|
type: fileInfo.type,
|
|
83
83
|
fileName: fileInfo.fileName,
|
|
84
84
|
extension: fileInfo.extension,
|
|
85
|
-
replaceTargetUrl: fileInfo.replaceTargetUrl
|
|
85
|
+
replaceTargetUrl: fileInfo.replaceTargetUrl,
|
|
86
|
+
temporary: fileInfo.temporary
|
|
86
87
|
}
|
|
87
88
|
});
|
|
88
89
|
if (!canUpload) {
|
|
@@ -176,6 +177,43 @@ async function requestUploadParts(params) {
|
|
|
176
177
|
path
|
|
177
178
|
});
|
|
178
179
|
}
|
|
180
|
+
async function completeMultipartUpload(params) {
|
|
181
|
+
const { provider, router, ctxToken, body: { bucketName, uploadId, key, parts } } = params;
|
|
182
|
+
if (!ctxToken) {
|
|
183
|
+
throw new EdgeStoreError({
|
|
184
|
+
message: 'Missing edgestore-ctx cookie',
|
|
185
|
+
code: 'UNAUTHORIZED'
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
await getContext(ctxToken); // just to check if the token is valid
|
|
189
|
+
const bucket = router.buckets[bucketName];
|
|
190
|
+
if (!bucket) {
|
|
191
|
+
throw new Error(`Bucket ${bucketName} not found`);
|
|
192
|
+
}
|
|
193
|
+
return await provider.completeMultipartUpload({
|
|
194
|
+
uploadId,
|
|
195
|
+
key,
|
|
196
|
+
parts
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
async function confirmUpload(params) {
|
|
200
|
+
const { provider, router, ctxToken, body: { bucketName, url } } = params;
|
|
201
|
+
if (!ctxToken) {
|
|
202
|
+
throw new EdgeStoreError({
|
|
203
|
+
message: 'Missing edgestore-ctx cookie',
|
|
204
|
+
code: 'UNAUTHORIZED'
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
await getContext(ctxToken); // just to check if the token is valid
|
|
208
|
+
const bucket = router.buckets[bucketName];
|
|
209
|
+
if (!bucket) {
|
|
210
|
+
throw new Error(`Bucket ${bucketName} not found`);
|
|
211
|
+
}
|
|
212
|
+
await provider.confirmUpload({
|
|
213
|
+
bucket,
|
|
214
|
+
url
|
|
215
|
+
});
|
|
216
|
+
}
|
|
179
217
|
async function deleteFile(params) {
|
|
180
218
|
const { provider, router, ctxToken, body: { bucketName, url } } = params;
|
|
181
219
|
if (!ctxToken) {
|
|
@@ -264,6 +302,8 @@ async function getContext(token) {
|
|
|
264
302
|
|
|
265
303
|
exports.EDGE_STORE_ERROR_CODES = EDGE_STORE_ERROR_CODES;
|
|
266
304
|
exports.EdgeStoreError = EdgeStoreError;
|
|
305
|
+
exports.completeMultipartUpload = completeMultipartUpload;
|
|
306
|
+
exports.confirmUpload = confirmUpload;
|
|
267
307
|
exports.deleteFile = deleteFile;
|
|
268
308
|
exports.init = init;
|
|
269
309
|
exports.requestUpload = requestUpload;
|
|
@@ -78,6 +78,7 @@ async function requestUpload(params) {
|
|
|
78
78
|
fileName: fileInfo.fileName,
|
|
79
79
|
extension: fileInfo.extension,
|
|
80
80
|
replaceTargetUrl: fileInfo.replaceTargetUrl,
|
|
81
|
+
temporary: fileInfo.temporary,
|
|
81
82
|
},
|
|
82
83
|
});
|
|
83
84
|
if (!canUpload) {
|
|
@@ -166,6 +167,43 @@ async function requestUploadParts(params) {
|
|
|
166
167
|
path,
|
|
167
168
|
});
|
|
168
169
|
}
|
|
170
|
+
async function completeMultipartUpload(params) {
|
|
171
|
+
const { provider, router, ctxToken, body: { bucketName, uploadId, key, parts }, } = params;
|
|
172
|
+
if (!ctxToken) {
|
|
173
|
+
throw new EdgeStoreError({
|
|
174
|
+
message: 'Missing edgestore-ctx cookie',
|
|
175
|
+
code: 'UNAUTHORIZED',
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
await getContext(ctxToken); // just to check if the token is valid
|
|
179
|
+
const bucket = router.buckets[bucketName];
|
|
180
|
+
if (!bucket) {
|
|
181
|
+
throw new Error(`Bucket ${bucketName} not found`);
|
|
182
|
+
}
|
|
183
|
+
return await provider.completeMultipartUpload({
|
|
184
|
+
uploadId,
|
|
185
|
+
key,
|
|
186
|
+
parts,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
async function confirmUpload(params) {
|
|
190
|
+
const { provider, router, ctxToken, body: { bucketName, url }, } = params;
|
|
191
|
+
if (!ctxToken) {
|
|
192
|
+
throw new EdgeStoreError({
|
|
193
|
+
message: 'Missing edgestore-ctx cookie',
|
|
194
|
+
code: 'UNAUTHORIZED',
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
await getContext(ctxToken); // just to check if the token is valid
|
|
198
|
+
const bucket = router.buckets[bucketName];
|
|
199
|
+
if (!bucket) {
|
|
200
|
+
throw new Error(`Bucket ${bucketName} not found`);
|
|
201
|
+
}
|
|
202
|
+
await provider.confirmUpload({
|
|
203
|
+
bucket,
|
|
204
|
+
url,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
169
207
|
async function deleteFile(params) {
|
|
170
208
|
const { provider, router, ctxToken, body: { bucketName, url }, } = params;
|
|
171
209
|
if (!ctxToken) {
|
|
@@ -256,4 +294,4 @@ async function getContext(token) {
|
|
|
256
294
|
return await decryptJWT(token);
|
|
257
295
|
}
|
|
258
296
|
|
|
259
|
-
export { EdgeStoreError as E, requestUploadParts as a,
|
|
297
|
+
export { EdgeStoreError as E, requestUploadParts as a, confirmUpload as b, completeMultipartUpload as c, deleteFile as d, EDGE_STORE_ERROR_CODES as e, init as i, requestUpload as r };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edgestore/server",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Upload files with ease from React/Next.js",
|
|
5
5
|
"homepage": "https://edgestore.dev",
|
|
6
6
|
"repository": "https://github.com/edgestorejs/edgestore.git",
|
|
7
7
|
"author": "Ravi <me@ravi.com>",
|
|
@@ -37,6 +37,11 @@
|
|
|
37
37
|
"require": "./dist/core/index.js",
|
|
38
38
|
"default": "./dist/core/index.js"
|
|
39
39
|
},
|
|
40
|
+
"./adapters": {
|
|
41
|
+
"import": "./dist/adapters/index.mjs",
|
|
42
|
+
"require": "./dist/adapters/index.js",
|
|
43
|
+
"default": "./dist/adapters/index.js"
|
|
44
|
+
},
|
|
40
45
|
"./adapters/next/pages": {
|
|
41
46
|
"import": "./dist/adapters/next/pages/index.mjs",
|
|
42
47
|
"require": "./dist/adapters/next/pages/index.js",
|
|
@@ -56,6 +61,11 @@
|
|
|
56
61
|
"import": "./dist/providers/edgestore/index.mjs",
|
|
57
62
|
"require": "./dist/providers/edgestore/index.js",
|
|
58
63
|
"default": "./dist/providers/edgestore/index.js"
|
|
64
|
+
},
|
|
65
|
+
"./providers": {
|
|
66
|
+
"import": "./dist/providers/index.mjs",
|
|
67
|
+
"require": "./dist/providers/index.js",
|
|
68
|
+
"default": "./dist/providers/index.js"
|
|
59
69
|
}
|
|
60
70
|
},
|
|
61
71
|
"files": [
|
|
@@ -94,5 +104,5 @@
|
|
|
94
104
|
"typescript": "^5.1.6",
|
|
95
105
|
"zod": "^3.21.4"
|
|
96
106
|
},
|
|
97
|
-
"gitHead": "
|
|
107
|
+
"gitHead": "99519b57aa7a5cbbe5cab16b85a70d437cb87435"
|
|
98
108
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../dist/providers';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('../dist/providers');
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import { NextRequest } from 'next/server';
|
|
2
|
-
import { EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
|
|
1
|
+
import { type NextRequest } from 'next/server';
|
|
2
|
+
import { type EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
|
|
3
3
|
import EdgeStoreError, {
|
|
4
4
|
EDGE_STORE_ERROR_CODES,
|
|
5
5
|
} from '../../../libs/errors/EdgeStoreError';
|
|
6
6
|
import { EdgeStoreProvider } from '../../../providers/edgestore';
|
|
7
|
-
import { Provider } from '../../../providers/types';
|
|
8
|
-
import { MaybePromise } from '../../../types';
|
|
7
|
+
import { type Provider } from '../../../providers/types';
|
|
8
|
+
import { type MaybePromise } from '../../../types';
|
|
9
9
|
import {
|
|
10
|
+
completeMultipartUpload,
|
|
11
|
+
confirmUpload,
|
|
10
12
|
deleteFile,
|
|
11
|
-
DeleteFileBody,
|
|
12
13
|
init,
|
|
13
14
|
requestUpload,
|
|
14
|
-
RequestUploadBody,
|
|
15
15
|
requestUploadParts,
|
|
16
|
-
|
|
16
|
+
type CompleteMultipartUploadBody,
|
|
17
|
+
type ConfirmUploadBody,
|
|
18
|
+
type DeleteFileBody,
|
|
19
|
+
type RequestUploadBody,
|
|
20
|
+
type RequestUploadPartsParams,
|
|
17
21
|
} from '../../shared';
|
|
18
22
|
|
|
19
23
|
export type CreateContextOptions = {
|
|
@@ -86,6 +90,28 @@ export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
|
|
|
86
90
|
'Content-Type': 'application/json',
|
|
87
91
|
},
|
|
88
92
|
});
|
|
93
|
+
} else if (
|
|
94
|
+
req.nextUrl.pathname === '/api/edgestore/complete-multipart-upload'
|
|
95
|
+
) {
|
|
96
|
+
await completeMultipartUpload({
|
|
97
|
+
provider,
|
|
98
|
+
router: config.router,
|
|
99
|
+
body: (await req.json()) as CompleteMultipartUploadBody,
|
|
100
|
+
ctxToken: req.cookies.get('edgestore-ctx')?.value,
|
|
101
|
+
});
|
|
102
|
+
return new Response(null, {
|
|
103
|
+
status: 200,
|
|
104
|
+
});
|
|
105
|
+
} else if (req.nextUrl.pathname === '/api/edgestore/confirm-upload') {
|
|
106
|
+
await confirmUpload({
|
|
107
|
+
provider,
|
|
108
|
+
router: config.router,
|
|
109
|
+
body: (await req.json()) as ConfirmUploadBody,
|
|
110
|
+
ctxToken: req.cookies.get('edgestore-ctx')?.value,
|
|
111
|
+
});
|
|
112
|
+
return new Response(null, {
|
|
113
|
+
status: 200,
|
|
114
|
+
});
|
|
89
115
|
} else if (req.nextUrl.pathname === '/api/edgestore/delete-file') {
|
|
90
116
|
await deleteFile({
|
|
91
117
|
provider,
|
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import { NextApiRequest, NextApiResponse } from 'next/types';
|
|
2
|
-
import { EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
|
|
1
|
+
import { type NextApiRequest, type NextApiResponse } from 'next/types';
|
|
2
|
+
import { type EdgeStoreRouter } from '../../../core/internals/bucketBuilder';
|
|
3
3
|
import EdgeStoreError, {
|
|
4
4
|
EDGE_STORE_ERROR_CODES,
|
|
5
5
|
} from '../../../libs/errors/EdgeStoreError';
|
|
6
6
|
import { EdgeStoreProvider } from '../../../providers/edgestore';
|
|
7
|
-
import { Provider } from '../../../providers/types';
|
|
8
|
-
import { MaybePromise } from '../../../types';
|
|
7
|
+
import { type Provider } from '../../../providers/types';
|
|
8
|
+
import { type MaybePromise } from '../../../types';
|
|
9
9
|
import {
|
|
10
|
+
completeMultipartUpload,
|
|
11
|
+
confirmUpload,
|
|
10
12
|
deleteFile,
|
|
11
|
-
DeleteFileBody,
|
|
12
13
|
init,
|
|
13
14
|
requestUpload,
|
|
14
|
-
RequestUploadBody,
|
|
15
15
|
requestUploadParts,
|
|
16
|
-
|
|
16
|
+
type CompleteMultipartUploadBody,
|
|
17
|
+
type ConfirmUploadBody,
|
|
18
|
+
type DeleteFileBody,
|
|
19
|
+
type RequestUploadBody,
|
|
20
|
+
type RequestUploadPartsParams,
|
|
17
21
|
} from '../../shared';
|
|
18
22
|
|
|
19
23
|
export type CreateContextOptions = {
|
|
@@ -69,6 +73,22 @@ export function createEdgeStoreNextHandler<TCtx>(config: Config<TCtx>) {
|
|
|
69
73
|
ctxToken: req.cookies['edgestore-ctx'],
|
|
70
74
|
}),
|
|
71
75
|
);
|
|
76
|
+
} else if (req.url === '/api/edgestore/complete-multipart-upload') {
|
|
77
|
+
await completeMultipartUpload({
|
|
78
|
+
provider,
|
|
79
|
+
router: config.router,
|
|
80
|
+
body: req.body as CompleteMultipartUploadBody,
|
|
81
|
+
ctxToken: req.cookies['edgestore-ctx'],
|
|
82
|
+
});
|
|
83
|
+
res.status(200).end();
|
|
84
|
+
} else if (req.url === '/api/edgestore/confirm-upload') {
|
|
85
|
+
await confirmUpload({
|
|
86
|
+
provider,
|
|
87
|
+
router: config.router,
|
|
88
|
+
body: req.body as ConfirmUploadBody,
|
|
89
|
+
ctxToken: req.cookies['edgestore-ctx'],
|
|
90
|
+
});
|
|
91
|
+
res.status(200).end();
|
|
72
92
|
} else if (req.url === '/api/edgestore/delete-file') {
|
|
73
93
|
await deleteFile({
|
|
74
94
|
provider,
|
package/src/adapters/shared.ts
CHANGED
|
@@ -2,9 +2,12 @@ import { hkdf } from '@panva/hkdf';
|
|
|
2
2
|
import { serialize } from 'cookie';
|
|
3
3
|
import { EncryptJWT, jwtDecrypt } from 'jose';
|
|
4
4
|
import { v4 as uuidv4 } from 'uuid';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
type AnyBuilder,
|
|
7
|
+
type EdgeStoreRouter,
|
|
8
|
+
} from '../core/internals/bucketBuilder';
|
|
6
9
|
import EdgeStoreError from '../libs/errors/EdgeStoreError';
|
|
7
|
-
import { Provider } from '../providers/types';
|
|
10
|
+
import { type Provider } from '../providers/types';
|
|
8
11
|
import { IMAGE_MIME_TYPES } from './imageTypes';
|
|
9
12
|
|
|
10
13
|
// TODO: change it to 1 hour when we have a way to refresh the token
|
|
@@ -53,6 +56,7 @@ export type RequestUploadBody = {
|
|
|
53
56
|
extension: string;
|
|
54
57
|
fileName?: string;
|
|
55
58
|
replaceTargetUrl?: string;
|
|
59
|
+
temporary: boolean;
|
|
56
60
|
};
|
|
57
61
|
};
|
|
58
62
|
|
|
@@ -90,6 +94,7 @@ export async function requestUpload<TCtx>(params: {
|
|
|
90
94
|
fileName: fileInfo.fileName,
|
|
91
95
|
extension: fileInfo.extension,
|
|
92
96
|
replaceTargetUrl: fileInfo.replaceTargetUrl,
|
|
97
|
+
temporary: fileInfo.temporary,
|
|
93
98
|
},
|
|
94
99
|
});
|
|
95
100
|
if (!canUpload) {
|
|
@@ -203,6 +208,82 @@ export async function requestUploadParts<TCtx>(params: {
|
|
|
203
208
|
});
|
|
204
209
|
}
|
|
205
210
|
|
|
211
|
+
export type CompleteMultipartUploadBody = {
|
|
212
|
+
bucketName: string;
|
|
213
|
+
uploadId: string;
|
|
214
|
+
key: string;
|
|
215
|
+
parts: {
|
|
216
|
+
partNumber: number;
|
|
217
|
+
eTag: string;
|
|
218
|
+
}[];
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
export async function completeMultipartUpload<TCtx>(params: {
|
|
222
|
+
provider: Provider;
|
|
223
|
+
router: EdgeStoreRouter<TCtx>;
|
|
224
|
+
ctxToken: string | undefined;
|
|
225
|
+
body: CompleteMultipartUploadBody;
|
|
226
|
+
}) {
|
|
227
|
+
const {
|
|
228
|
+
provider,
|
|
229
|
+
router,
|
|
230
|
+
ctxToken,
|
|
231
|
+
body: { bucketName, uploadId, key, parts },
|
|
232
|
+
} = params;
|
|
233
|
+
if (!ctxToken) {
|
|
234
|
+
throw new EdgeStoreError({
|
|
235
|
+
message: 'Missing edgestore-ctx cookie',
|
|
236
|
+
code: 'UNAUTHORIZED',
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
await getContext(ctxToken); // just to check if the token is valid
|
|
240
|
+
const bucket = router.buckets[bucketName];
|
|
241
|
+
if (!bucket) {
|
|
242
|
+
throw new Error(`Bucket ${bucketName} not found`);
|
|
243
|
+
}
|
|
244
|
+
return await provider.completeMultipartUpload({
|
|
245
|
+
uploadId,
|
|
246
|
+
key,
|
|
247
|
+
parts,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export type ConfirmUploadBody = {
|
|
252
|
+
bucketName: string;
|
|
253
|
+
url: string;
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
export async function confirmUpload<TCtx>(params: {
|
|
257
|
+
provider: Provider;
|
|
258
|
+
router: EdgeStoreRouter<TCtx>;
|
|
259
|
+
ctxToken: string | undefined;
|
|
260
|
+
body: ConfirmUploadBody;
|
|
261
|
+
}) {
|
|
262
|
+
const {
|
|
263
|
+
provider,
|
|
264
|
+
router,
|
|
265
|
+
ctxToken,
|
|
266
|
+
body: { bucketName, url },
|
|
267
|
+
} = params;
|
|
268
|
+
|
|
269
|
+
if (!ctxToken) {
|
|
270
|
+
throw new EdgeStoreError({
|
|
271
|
+
message: 'Missing edgestore-ctx cookie',
|
|
272
|
+
code: 'UNAUTHORIZED',
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
await getContext(ctxToken); // just to check if the token is valid
|
|
276
|
+
const bucket = router.buckets[bucketName];
|
|
277
|
+
if (!bucket) {
|
|
278
|
+
throw new Error(`Bucket ${bucketName} not found`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
await provider.confirmUpload({
|
|
282
|
+
bucket,
|
|
283
|
+
url,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
|
|
206
287
|
export type DeleteFileBody = {
|
|
207
288
|
bucketName: string;
|
|
208
289
|
url: string;
|
|
@@ -336,3 +417,10 @@ async function getContext(token?: string) {
|
|
|
336
417
|
}
|
|
337
418
|
return await decryptJWT(token);
|
|
338
419
|
}
|
|
420
|
+
|
|
421
|
+
export type InitRes = Awaited<ReturnType<typeof init>>;
|
|
422
|
+
export type RequestUploadRes = Awaited<ReturnType<typeof requestUpload>>;
|
|
423
|
+
export type RequestUploadPartsRes = Awaited<
|
|
424
|
+
ReturnType<typeof requestUploadParts>
|
|
425
|
+
>;
|
|
426
|
+
export type DeleteFileRes = Awaited<ReturnType<typeof deleteFile>>;
|
package/src/core/client/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { AnyRouter, Comparison } from '..';
|
|
2
|
-
import { Simplify } from '../../types';
|
|
1
|
+
import { type AnyRouter, type Comparison } from '..';
|
|
2
|
+
import { type Simplify } from '../../types';
|
|
3
3
|
import {
|
|
4
|
-
AnyBuilder,
|
|
5
|
-
InferBucketPathKeys,
|
|
6
|
-
InferBucketPathObject,
|
|
7
|
-
InferMetadataObject,
|
|
4
|
+
type AnyBuilder,
|
|
5
|
+
type InferBucketPathKeys,
|
|
6
|
+
type InferBucketPathObject,
|
|
7
|
+
type InferMetadataObject,
|
|
8
8
|
} from '../internals/bucketBuilder';
|
|
9
9
|
import { initEdgeStoreSdk } from '../sdk';
|
|
10
10
|
|
|
@@ -77,6 +77,10 @@ type EdgeStoreClient<TRouter extends AnyRouter> = {
|
|
|
77
77
|
// uploadUrl: string;
|
|
78
78
|
// accessUrl: string;
|
|
79
79
|
// }>;
|
|
80
|
+
/**
|
|
81
|
+
* Confirm a temporary file upload.
|
|
82
|
+
*/
|
|
83
|
+
confirmUpload: (params: { url: string }) => Promise<{ success: boolean }>;
|
|
80
84
|
/**
|
|
81
85
|
* Programmatically delete a file.
|
|
82
86
|
*/
|
|
@@ -168,10 +172,12 @@ export function initEdgeStoreClient<TRouter extends AnyRouter>(config: {
|
|
|
168
172
|
// });
|
|
169
173
|
// },
|
|
170
174
|
|
|
175
|
+
async confirmUpload(params) {
|
|
176
|
+
return await sdk.confirmUpload(params);
|
|
177
|
+
},
|
|
178
|
+
|
|
171
179
|
async deleteFile(params) {
|
|
172
|
-
return await sdk.deleteFile(
|
|
173
|
-
...params,
|
|
174
|
-
});
|
|
180
|
+
return await sdk.deleteFile(params);
|
|
175
181
|
},
|
|
176
182
|
|
|
177
183
|
async listFiles(params) {
|
package/src/core/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
type KeysOfUnion,
|
|
4
|
+
type MaybePromise,
|
|
5
|
+
type Simplify,
|
|
6
|
+
} from '../../types';
|
|
3
7
|
import { createPathParamProxy } from './createPathParamProxy';
|
|
4
8
|
|
|
5
9
|
type Merge<TType, TWith> = {
|
|
@@ -113,6 +117,7 @@ type FileInfo = {
|
|
|
113
117
|
extension: string;
|
|
114
118
|
fileName?: string;
|
|
115
119
|
replaceTargetUrl?: string;
|
|
120
|
+
temporary: boolean;
|
|
116
121
|
};
|
|
117
122
|
|
|
118
123
|
type BeforeUploadFn<TCtx, TDef extends AnyDef> = (params: {
|
package/src/core/sdk/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AnyRouter } from '..';
|
|
1
|
+
import { type AnyRouter } from '..';
|
|
2
2
|
import EdgeStoreCredentialsError from '../../libs/errors/EdgeStoreCredentialsError';
|
|
3
|
-
import { AnyContext, AnyMetadata } from '../internals/bucketBuilder';
|
|
3
|
+
import { type AnyContext, type AnyMetadata } from '../internals/bucketBuilder';
|
|
4
4
|
|
|
5
5
|
const API_ENDPOINT =
|
|
6
6
|
process.env.EDGE_STORE_API_ENDPOINT ?? 'https://api.edgestore.dev';
|
|
@@ -17,6 +17,7 @@ type FileInfoForUpload = {
|
|
|
17
17
|
metadata: AnyMetadata;
|
|
18
18
|
fileName?: string;
|
|
19
19
|
replaceTargetUrl?: string;
|
|
20
|
+
temporary: boolean;
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
export type SimpleOperator =
|
|
@@ -162,6 +163,7 @@ export const edgeStoreRawSdk = {
|
|
|
162
163
|
}) {
|
|
163
164
|
const res = await makeRequest<{
|
|
164
165
|
multipart?: {
|
|
166
|
+
key: string;
|
|
165
167
|
uploadId: string;
|
|
166
168
|
parts: {
|
|
167
169
|
partNumber: number;
|
|
@@ -170,6 +172,8 @@ export const edgeStoreRawSdk = {
|
|
|
170
172
|
};
|
|
171
173
|
signedUrl?: string;
|
|
172
174
|
url: string;
|
|
175
|
+
path: string;
|
|
176
|
+
thumbnailUrl: string | null;
|
|
173
177
|
}>({
|
|
174
178
|
path: '/request-upload',
|
|
175
179
|
accessKey,
|
|
@@ -186,12 +190,15 @@ export const edgeStoreRawSdk = {
|
|
|
186
190
|
metadata: fileInfo.metadata,
|
|
187
191
|
fileName: fileInfo.fileName,
|
|
188
192
|
replaceTargetUrl: fileInfo.replaceTargetUrl,
|
|
193
|
+
isTemporary: fileInfo.temporary,
|
|
189
194
|
},
|
|
190
195
|
});
|
|
191
196
|
return {
|
|
192
197
|
multipart: res.multipart,
|
|
193
198
|
signedUrl: res.signedUrl,
|
|
194
199
|
accessUrl: res.url,
|
|
200
|
+
path: res.path,
|
|
201
|
+
thumbnailUrl: res.thumbnailUrl,
|
|
195
202
|
};
|
|
196
203
|
},
|
|
197
204
|
|
|
@@ -231,6 +238,53 @@ export const edgeStoreRawSdk = {
|
|
|
231
238
|
};
|
|
232
239
|
},
|
|
233
240
|
|
|
241
|
+
async completeMultipartUpload({
|
|
242
|
+
accessKey,
|
|
243
|
+
secretKey,
|
|
244
|
+
uploadId,
|
|
245
|
+
key,
|
|
246
|
+
parts,
|
|
247
|
+
}: {
|
|
248
|
+
accessKey: string;
|
|
249
|
+
secretKey: string;
|
|
250
|
+
uploadId: string;
|
|
251
|
+
key: string;
|
|
252
|
+
parts: {
|
|
253
|
+
partNumber: number;
|
|
254
|
+
eTag: string;
|
|
255
|
+
}[];
|
|
256
|
+
}) {
|
|
257
|
+
return await makeRequest<{ success: boolean }>({
|
|
258
|
+
path: '/complete-multipart-upload',
|
|
259
|
+
accessKey,
|
|
260
|
+
secretKey,
|
|
261
|
+
body: {
|
|
262
|
+
uploadId,
|
|
263
|
+
key,
|
|
264
|
+
parts,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
},
|
|
268
|
+
|
|
269
|
+
async confirmUpload({
|
|
270
|
+
accessKey,
|
|
271
|
+
secretKey,
|
|
272
|
+
url,
|
|
273
|
+
}: {
|
|
274
|
+
accessKey: string;
|
|
275
|
+
secretKey: string;
|
|
276
|
+
url: string;
|
|
277
|
+
}) {
|
|
278
|
+
return await makeRequest<{ success: boolean }>({
|
|
279
|
+
path: '/confirm-upload',
|
|
280
|
+
accessKey,
|
|
281
|
+
secretKey,
|
|
282
|
+
body: {
|
|
283
|
+
url,
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
},
|
|
287
|
+
|
|
234
288
|
async deleteFile({
|
|
235
289
|
accessKey,
|
|
236
290
|
secretKey,
|
|
@@ -359,6 +413,33 @@ export function initEdgeStoreSdk(params: {
|
|
|
359
413
|
multipart,
|
|
360
414
|
});
|
|
361
415
|
},
|
|
416
|
+
async completeMultipartUpload({
|
|
417
|
+
uploadId,
|
|
418
|
+
key,
|
|
419
|
+
parts,
|
|
420
|
+
}: {
|
|
421
|
+
uploadId: string;
|
|
422
|
+
key: string;
|
|
423
|
+
parts: {
|
|
424
|
+
partNumber: number;
|
|
425
|
+
eTag: string;
|
|
426
|
+
}[];
|
|
427
|
+
}) {
|
|
428
|
+
return await edgeStoreRawSdk.completeMultipartUpload({
|
|
429
|
+
accessKey,
|
|
430
|
+
secretKey,
|
|
431
|
+
uploadId,
|
|
432
|
+
key,
|
|
433
|
+
parts,
|
|
434
|
+
});
|
|
435
|
+
},
|
|
436
|
+
async confirmUpload({ url }: { url: string }) {
|
|
437
|
+
return await edgeStoreRawSdk.confirmUpload({
|
|
438
|
+
accessKey,
|
|
439
|
+
secretKey,
|
|
440
|
+
url,
|
|
441
|
+
});
|
|
442
|
+
},
|
|
362
443
|
async deleteFile({ url }: { url: string }) {
|
|
363
444
|
return await edgeStoreRawSdk.deleteFile({
|
|
364
445
|
accessKey,
|
|
@@ -6,13 +6,40 @@ import {
|
|
|
6
6
|
} from '@aws-sdk/client-s3';
|
|
7
7
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
8
8
|
import { v4 as uuidv4 } from 'uuid';
|
|
9
|
-
import { Provider } from '../types';
|
|
9
|
+
import { type Provider } from '../types';
|
|
10
10
|
|
|
11
11
|
export type AWSProviderOptions = {
|
|
12
|
+
/**
|
|
13
|
+
* Access key for AWS credentials.
|
|
14
|
+
* Can also be set via the `ES_AWS_ACCESS_KEY_ID` environment variable.
|
|
15
|
+
*
|
|
16
|
+
* If unset, the SDK will attempt to use the default credentials provider chain.
|
|
17
|
+
*/
|
|
12
18
|
accessKeyId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Secret access key for AWS credentials.
|
|
21
|
+
* Can also be set via the `ES_AWS_SECRET_ACCESS_KEY` environment variable.
|
|
22
|
+
*
|
|
23
|
+
* If unset, the SDK will attempt to use the default credentials provider chain.
|
|
24
|
+
*/
|
|
13
25
|
secretAccessKey?: string;
|
|
26
|
+
/**
|
|
27
|
+
* AWS region to use.
|
|
28
|
+
* Can also be set via the `ES_AWS_REGION` environment variable.
|
|
29
|
+
*/
|
|
14
30
|
region?: string;
|
|
31
|
+
/**
|
|
32
|
+
* Name of the S3 bucket to use.
|
|
33
|
+
* Can also be set via the `ES_AWS_BUCKET_NAME` environment variable.
|
|
34
|
+
*/
|
|
15
35
|
bucketName?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Base URL to use for accessing files.
|
|
38
|
+
* Only needed if you are using a custom domain or cloudfront.
|
|
39
|
+
*
|
|
40
|
+
* Can also be set via the `EDGE_STORE_BASE_URL` environment variable.
|
|
41
|
+
*/
|
|
42
|
+
baseUrl?: string;
|
|
16
43
|
};
|
|
17
44
|
|
|
18
45
|
export function AWSProvider(options?: AWSProviderOptions): Provider {
|
|
@@ -23,6 +50,11 @@ export function AWSProvider(options?: AWSProviderOptions): Provider {
|
|
|
23
50
|
bucketName = process.env.ES_AWS_BUCKET_NAME,
|
|
24
51
|
} = options ?? {};
|
|
25
52
|
|
|
53
|
+
const baseUrl =
|
|
54
|
+
options?.baseUrl ??
|
|
55
|
+
process.env.EDGE_STORE_BASE_URL ??
|
|
56
|
+
`https://${bucketName}.s3.${region}.amazonaws.com`;
|
|
57
|
+
|
|
26
58
|
const credentials =
|
|
27
59
|
accessKeyId && secretAccessKey
|
|
28
60
|
? {
|
|
@@ -32,10 +64,6 @@ export function AWSProvider(options?: AWSProviderOptions): Provider {
|
|
|
32
64
|
: undefined;
|
|
33
65
|
const s3Client = new S3Client({ region, credentials });
|
|
34
66
|
|
|
35
|
-
const baseUrl =
|
|
36
|
-
process.env.EDGE_STORE_BASE_URL ??
|
|
37
|
-
`https://${bucketName}.s3.${region}.amazonaws.com`;
|
|
38
|
-
|
|
39
67
|
return {
|
|
40
68
|
async init() {
|
|
41
69
|
return {};
|
|
@@ -93,6 +121,12 @@ export function AWSProvider(options?: AWSProviderOptions): Provider {
|
|
|
93
121
|
async requestUploadParts() {
|
|
94
122
|
throw new Error('Not implemented');
|
|
95
123
|
},
|
|
124
|
+
async completeMultipartUpload() {
|
|
125
|
+
throw new Error('Not implemented');
|
|
126
|
+
},
|
|
127
|
+
async confirmUpload() {
|
|
128
|
+
throw new Error('Not implemented');
|
|
129
|
+
},
|
|
96
130
|
async deleteFile({ url }) {
|
|
97
131
|
const path = url.replace(`${baseUrl}/`, '');
|
|
98
132
|
await s3Client.send(
|