@edgestore/server 0.5.7 → 0.6.0-canary.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.
- package/adapters/astro/package.json +1 -0
- package/adapters/express/package.json +1 -0
- package/adapters/fastify/package.json +1 -0
- package/adapters/hono/package.json +1 -0
- package/adapters/next/app/package.json +1 -0
- package/adapters/next/pages/package.json +1 -0
- package/adapters/remix/package.json +1 -0
- package/adapters/start/package.json +1 -0
- package/core/package.json +1 -0
- package/dist/adapters/astro/index.cjs +134 -0
- package/dist/adapters/astro/index.d.cts +20 -0
- package/dist/adapters/astro/index.d.cts.map +1 -0
- package/dist/adapters/astro/index.d.mts +20 -0
- package/dist/adapters/astro/index.d.mts.map +1 -0
- package/dist/adapters/astro/index.mjs +128 -175
- package/dist/adapters/astro/index.mjs.map +1 -0
- package/dist/adapters/express/index.cjs +104 -0
- package/dist/adapters/express/index.d.cts +24 -0
- package/dist/adapters/express/index.d.cts.map +1 -0
- package/dist/adapters/express/index.d.mts +24 -0
- package/dist/adapters/express/index.d.mts.map +1 -0
- package/dist/adapters/express/index.mjs +100 -112
- package/dist/adapters/express/index.mjs.map +1 -0
- package/dist/adapters/fastify/index.cjs +115 -0
- package/dist/adapters/fastify/index.d.cts +24 -0
- package/dist/adapters/fastify/index.d.cts.map +1 -0
- package/dist/adapters/fastify/index.d.mts +24 -0
- package/dist/adapters/fastify/index.d.mts.map +1 -0
- package/dist/adapters/fastify/index.mjs +109 -139
- package/dist/adapters/fastify/index.mjs.map +1 -0
- package/dist/adapters/hono/index.cjs +117 -0
- package/dist/adapters/hono/index.d.cts +91 -0
- package/dist/adapters/hono/index.d.cts.map +1 -0
- package/dist/adapters/hono/index.d.mts +91 -0
- package/dist/adapters/hono/index.d.mts.map +1 -0
- package/dist/adapters/hono/index.mjs +111 -129
- package/dist/adapters/hono/index.mjs.map +1 -0
- package/dist/adapters/next/app/index.cjs +140 -0
- package/dist/adapters/next/app/index.d.cts +23 -0
- package/dist/adapters/next/app/index.d.cts.map +1 -0
- package/dist/adapters/next/app/index.d.mts +23 -0
- package/dist/adapters/next/app/index.d.mts.map +1 -0
- package/dist/adapters/next/app/index.mjs +136 -168
- package/dist/adapters/next/app/index.mjs.map +1 -0
- package/dist/adapters/next/pages/index.cjs +108 -0
- package/dist/adapters/next/pages/index.d.cts +24 -0
- package/dist/adapters/next/pages/index.d.cts.map +1 -0
- package/dist/adapters/next/pages/index.d.mts +24 -0
- package/dist/adapters/next/pages/index.d.mts.map +1 -0
- package/dist/adapters/next/pages/index.mjs +104 -116
- package/dist/adapters/next/pages/index.mjs.map +1 -0
- package/dist/adapters/remix/index.cjs +124 -0
- package/dist/adapters/remix/index.d.cts +26 -0
- package/dist/adapters/remix/index.d.cts.map +1 -0
- package/dist/adapters/remix/index.d.mts +26 -0
- package/dist/adapters/remix/index.d.mts.map +1 -0
- package/dist/adapters/remix/index.mjs +118 -150
- package/dist/adapters/remix/index.mjs.map +1 -0
- package/dist/adapters/start/index.cjs +156 -0
- package/dist/adapters/start/index.d.cts +26 -0
- package/dist/adapters/start/index.d.cts.map +1 -0
- package/dist/adapters/start/index.d.mts +26 -0
- package/dist/adapters/start/index.d.mts.map +1 -0
- package/dist/adapters/start/index.mjs +150 -184
- package/dist/adapters/start/index.mjs.map +1 -0
- package/dist/core/index.cjs +148 -0
- package/dist/core/index.d.cts +500 -0
- package/dist/core/index.d.cts.map +1 -0
- package/dist/core/index.d.mts +500 -0
- package/dist/core/index.d.mts.map +1 -0
- package/dist/core/index.mjs +135 -169
- package/dist/core/index.mjs.map +1 -0
- package/dist/edgestore-Cr88uKUx.mjs +142 -0
- package/dist/edgestore-Cr88uKUx.mjs.map +1 -0
- package/dist/edgestore-Dqb-EoFm.cjs +146 -0
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.mjs +3 -1
- package/dist/providers/aws/index.cjs +89 -0
- package/dist/providers/aws/index.d.cts +71 -0
- package/dist/providers/aws/index.d.cts.map +1 -0
- package/dist/providers/aws/index.d.mts +71 -0
- package/dist/providers/aws/index.d.mts.map +1 -0
- package/dist/providers/aws/index.mjs +85 -102
- package/dist/providers/aws/index.mjs.map +1 -0
- package/dist/providers/azure/index.cjs +56 -0
- package/dist/providers/azure/index.d.cts +44 -0
- package/dist/providers/azure/index.d.cts.map +1 -0
- package/dist/providers/azure/index.d.mts +44 -0
- package/dist/providers/azure/index.d.mts.map +1 -0
- package/dist/providers/azure/index.mjs +52 -58
- package/dist/providers/azure/index.mjs.map +1 -0
- package/dist/providers/edgestore/index.cjs +5 -0
- package/dist/providers/edgestore/index.d.cts +23 -0
- package/dist/providers/edgestore/index.d.cts.map +1 -0
- package/dist/providers/edgestore/index.d.mts +23 -0
- package/dist/providers/edgestore/index.d.mts.map +1 -0
- package/dist/providers/edgestore/index.mjs +4 -146
- package/dist/sdk-AhXUPMy1.cjs +238 -0
- package/dist/sdk-CKRQe75P.mjs +222 -0
- package/dist/sdk-CKRQe75P.mjs.map +1 -0
- package/dist/shared-B39MtSQo.d.cts +68 -0
- package/dist/shared-B39MtSQo.d.cts.map +1 -0
- package/dist/shared-Bd7-gfqa.mjs +457 -0
- package/dist/shared-Bd7-gfqa.mjs.map +1 -0
- package/dist/shared-DsWTtQ1-.d.mts +68 -0
- package/dist/shared-DsWTtQ1-.d.mts.map +1 -0
- package/dist/shared-pWGwhEsU.cjs +527 -0
- package/dist/utils--x-q_GK5.mjs +44 -0
- package/dist/utils--x-q_GK5.mjs.map +1 -0
- package/dist/utils-D6YuBNUV.cjs +54 -0
- package/package.json +121 -57
- package/providers/aws/package.json +1 -0
- package/providers/azure/package.json +1 -0
- package/providers/edgestore/package.json +1 -0
- package/adapters/astro/index.d.ts +0 -1
- package/adapters/astro/index.js +0 -1
- package/adapters/express/index.d.ts +0 -1
- package/adapters/express/index.js +0 -1
- package/adapters/fastify/index.d.ts +0 -1
- package/adapters/fastify/index.js +0 -1
- package/adapters/hono/index.d.ts +0 -1
- package/adapters/hono/index.js +0 -1
- package/adapters/next/app/index.d.ts +0 -1
- package/adapters/next/app/index.js +0 -1
- package/adapters/next/pages/index.d.ts +0 -1
- package/adapters/next/pages/index.js +0 -1
- package/adapters/remix/index.d.ts +0 -1
- package/adapters/remix/index.js +0 -1
- package/adapters/start/index.d.ts +0 -1
- package/adapters/start/index.js +0 -1
- package/core/index.d.ts +0 -1
- package/core/index.js +0 -1
- package/dist/adapters/astro/index.d.ts +0 -17
- package/dist/adapters/astro/index.d.ts.map +0 -1
- package/dist/adapters/astro/index.js +0 -186
- package/dist/adapters/express/index.d.ts +0 -21
- package/dist/adapters/express/index.d.ts.map +0 -1
- package/dist/adapters/express/index.js +0 -121
- package/dist/adapters/fastify/index.d.ts +0 -21
- package/dist/adapters/fastify/index.d.ts.map +0 -1
- package/dist/adapters/fastify/index.js +0 -150
- package/dist/adapters/hono/index.d.ts +0 -86
- package/dist/adapters/hono/index.d.ts.map +0 -1
- package/dist/adapters/hono/index.js +0 -140
- package/dist/adapters/imageTypes.d.ts +0 -2
- package/dist/adapters/imageTypes.d.ts.map +0 -1
- package/dist/adapters/next/app/index.d.ts +0 -20
- package/dist/adapters/next/app/index.d.ts.map +0 -1
- package/dist/adapters/next/app/index.js +0 -177
- package/dist/adapters/next/pages/index.d.ts +0 -21
- package/dist/adapters/next/pages/index.d.ts.map +0 -1
- package/dist/adapters/next/pages/index.js +0 -125
- package/dist/adapters/remix/index.d.ts +0 -21
- package/dist/adapters/remix/index.d.ts.map +0 -1
- package/dist/adapters/remix/index.js +0 -161
- package/dist/adapters/shared.d.ts +0 -167
- package/dist/adapters/shared.d.ts.map +0 -1
- package/dist/adapters/start/index.d.ts +0 -21
- package/dist/adapters/start/index.d.ts.map +0 -1
- package/dist/adapters/start/index.js +0 -195
- package/dist/core/client/index.d.ts +0 -217
- package/dist/core/client/index.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -186
- package/dist/core/sdk/index.d.ts +0 -240
- package/dist/core/sdk/index.d.ts.map +0 -1
- package/dist/index-1e7b1b93.js +0 -235
- package/dist/index-a36b09a6.mjs +0 -231
- package/dist/index-b0fff508.js +0 -231
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -12
- package/dist/libs/errors/EdgeStoreCredentialsError.d.ts +0 -5
- package/dist/libs/errors/EdgeStoreCredentialsError.d.ts.map +0 -1
- package/dist/libs/logger.d.ts +0 -13
- package/dist/libs/logger.d.ts.map +0 -1
- package/dist/libs/utils.d.ts +0 -5
- package/dist/libs/utils.d.ts.map +0 -1
- package/dist/providers/aws/index.d.ts +0 -68
- package/dist/providers/aws/index.d.ts.map +0 -1
- package/dist/providers/aws/index.js +0 -111
- package/dist/providers/azure/index.d.ts +0 -39
- package/dist/providers/azure/index.d.ts.map +0 -1
- package/dist/providers/azure/index.js +0 -67
- package/dist/providers/edgestore/index.d.ts +0 -19
- package/dist/providers/edgestore/index.d.ts.map +0 -1
- package/dist/providers/edgestore/index.js +0 -151
- package/dist/shared-4ec2dc90.js +0 -466
- package/dist/shared-64e9c30c.js +0 -435
- package/dist/shared-c6527780.mjs +0 -454
- package/dist/utils-26113e02.js +0 -65
- package/dist/utils-ab564a9e.js +0 -44
- package/dist/utils-cba23eef.mjs +0 -62
- package/providers/aws/index.d.ts +0 -1
- package/providers/aws/index.js +0 -1
- package/providers/azure/index.d.ts +0 -1
- package/providers/azure/index.js +0 -1
- package/providers/edgestore/index.d.ts +0 -1
- package/providers/edgestore/index.js +0 -1
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var shared$1 = require('@edgestore/shared');
|
|
6
|
-
var shared = require('../../shared-4ec2dc90.js');
|
|
7
|
-
var index = require('../../index-1e7b1b93.js');
|
|
8
|
-
require('@panva/hkdf');
|
|
9
|
-
require('cookie');
|
|
10
|
-
require('jose');
|
|
11
|
-
require('uuid');
|
|
12
|
-
|
|
13
|
-
const DEFAULT_BASE_URL = 'https://files.edgestore.dev';
|
|
14
|
-
function EdgeStoreProvider(options) {
|
|
15
|
-
const { accessKey = shared.getEnv('EDGE_STORE_ACCESS_KEY') ?? // @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
|
|
16
|
-
undefined?.EDGE_STORE_ACCESS_KEY, secretKey = shared.getEnv('EDGE_STORE_SECRET_KEY') ?? // @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
|
|
17
|
-
undefined?.EDGE_STORE_SECRET_KEY } = options ?? {};
|
|
18
|
-
const baseUrl = shared.getEnv('EDGE_STORE_BASE_URL') ?? DEFAULT_BASE_URL;
|
|
19
|
-
if (!accessKey || !secretKey) {
|
|
20
|
-
throw new index.EdgeStoreCredentialsError();
|
|
21
|
-
}
|
|
22
|
-
const edgeStoreSdk = index.initEdgeStoreSdk({
|
|
23
|
-
accessKey,
|
|
24
|
-
secretKey
|
|
25
|
-
});
|
|
26
|
-
return {
|
|
27
|
-
name: 'edgestore',
|
|
28
|
-
init: async ({ ctx, router })=>{
|
|
29
|
-
const token = await edgeStoreSdk.getToken({
|
|
30
|
-
ctx,
|
|
31
|
-
router
|
|
32
|
-
});
|
|
33
|
-
return {
|
|
34
|
-
token
|
|
35
|
-
};
|
|
36
|
-
},
|
|
37
|
-
getBaseUrl () {
|
|
38
|
-
return baseUrl;
|
|
39
|
-
},
|
|
40
|
-
getFile: async ({ url })=>{
|
|
41
|
-
const { uploadedAt, ...rest } = await edgeStoreSdk.getFile({
|
|
42
|
-
url
|
|
43
|
-
});
|
|
44
|
-
return {
|
|
45
|
-
uploadedAt: new Date(uploadedAt),
|
|
46
|
-
...rest
|
|
47
|
-
};
|
|
48
|
-
},
|
|
49
|
-
async requestUpload ({ bucketName, bucketType, fileInfo }) {
|
|
50
|
-
// multipart upload if file is bigger than a certain size
|
|
51
|
-
const MULTIPART_THRESHOLD = 10 * 1024 * 1024; // 10MB
|
|
52
|
-
let partSize = 5 * 1024 * 1024; // 5MB
|
|
53
|
-
if (fileInfo.size > MULTIPART_THRESHOLD) {
|
|
54
|
-
let totalParts = Math.ceil(fileInfo.size / partSize);
|
|
55
|
-
if (totalParts > 1000) {
|
|
56
|
-
// the maximum number of parts is 1000
|
|
57
|
-
totalParts = 1000;
|
|
58
|
-
partSize = Math.ceil(fileInfo.size / totalParts);
|
|
59
|
-
}
|
|
60
|
-
const res = await edgeStoreSdk.requestUpload({
|
|
61
|
-
bucketName,
|
|
62
|
-
bucketType,
|
|
63
|
-
fileInfo,
|
|
64
|
-
multipart: {
|
|
65
|
-
parts: Array.from({
|
|
66
|
-
length: totalParts
|
|
67
|
-
}).map((_, index)=>index + 1)
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
const multipart = res.multipart ? {
|
|
71
|
-
key: res.multipart.key,
|
|
72
|
-
uploadId: res.multipart.uploadId,
|
|
73
|
-
parts: res.multipart.parts.map((part)=>({
|
|
74
|
-
partNumber: part.partNumber,
|
|
75
|
-
uploadUrl: part.signedUrl
|
|
76
|
-
})),
|
|
77
|
-
partSize,
|
|
78
|
-
totalParts
|
|
79
|
-
} : undefined;
|
|
80
|
-
if (multipart) {
|
|
81
|
-
return {
|
|
82
|
-
accessUrl: res.accessUrl,
|
|
83
|
-
thumbnailUrl: res.thumbnailUrl,
|
|
84
|
-
multipart
|
|
85
|
-
};
|
|
86
|
-
} else if (res.signedUrl) {
|
|
87
|
-
return {
|
|
88
|
-
accessUrl: res.accessUrl,
|
|
89
|
-
uploadUrl: res.signedUrl,
|
|
90
|
-
thumbnailUrl: res.thumbnailUrl
|
|
91
|
-
};
|
|
92
|
-
} else {
|
|
93
|
-
throw new shared$1.EdgeStoreError({
|
|
94
|
-
message: 'Could not get upload url',
|
|
95
|
-
code: 'SERVER_ERROR'
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
const res = await edgeStoreSdk.requestUpload({
|
|
100
|
-
bucketName,
|
|
101
|
-
bucketType,
|
|
102
|
-
fileInfo
|
|
103
|
-
});
|
|
104
|
-
if (res.signedUrl) {
|
|
105
|
-
return {
|
|
106
|
-
accessUrl: res.accessUrl,
|
|
107
|
-
uploadUrl: res.signedUrl,
|
|
108
|
-
thumbnailUrl: res.thumbnailUrl
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
throw new shared$1.EdgeStoreError({
|
|
112
|
-
message: 'Could not get upload url',
|
|
113
|
-
code: 'SERVER_ERROR'
|
|
114
|
-
});
|
|
115
|
-
},
|
|
116
|
-
requestUploadParts: async ({ multipart, path })=>{
|
|
117
|
-
const res = await edgeStoreSdk.requestUploadParts({
|
|
118
|
-
multipart,
|
|
119
|
-
key: path
|
|
120
|
-
});
|
|
121
|
-
return {
|
|
122
|
-
multipart: {
|
|
123
|
-
uploadId: res.multipart.uploadId,
|
|
124
|
-
parts: res.multipart.parts.map((part)=>({
|
|
125
|
-
partNumber: part.partNumber,
|
|
126
|
-
uploadUrl: part.signedUrl
|
|
127
|
-
}))
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
},
|
|
131
|
-
completeMultipartUpload: async ({ uploadId, key, parts })=>{
|
|
132
|
-
return await edgeStoreSdk.completeMultipartUpload({
|
|
133
|
-
uploadId,
|
|
134
|
-
key,
|
|
135
|
-
parts
|
|
136
|
-
});
|
|
137
|
-
},
|
|
138
|
-
confirmUpload: async ({ url })=>{
|
|
139
|
-
return await edgeStoreSdk.confirmUpload({
|
|
140
|
-
url
|
|
141
|
-
});
|
|
142
|
-
},
|
|
143
|
-
deleteFile: async ({ url })=>{
|
|
144
|
-
return await edgeStoreSdk.deleteFile({
|
|
145
|
-
url
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
exports.EdgeStoreProvider = EdgeStoreProvider;
|
package/dist/shared-4ec2dc90.js
DELETED
|
@@ -1,466 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var shared = require('@edgestore/shared');
|
|
4
|
-
var hkdf = require('@panva/hkdf');
|
|
5
|
-
var cookie = require('cookie');
|
|
6
|
-
var jose = require('jose');
|
|
7
|
-
var uuid = require('uuid');
|
|
8
|
-
|
|
9
|
-
const IMAGE_MIME_TYPES = [
|
|
10
|
-
'image/jpeg',
|
|
11
|
-
'image/png',
|
|
12
|
-
'image/gif',
|
|
13
|
-
'image/webp',
|
|
14
|
-
'image/svg+xml',
|
|
15
|
-
'image/tiff',
|
|
16
|
-
'image/bmp',
|
|
17
|
-
'image/x-icon'
|
|
18
|
-
];
|
|
19
|
-
|
|
20
|
-
// TODO: change it to 1 hour when we have a way to refresh the token
|
|
21
|
-
const DEFAULT_MAX_AGE = 30 * 24 * 60 * 60; // 30 days
|
|
22
|
-
/**
|
|
23
|
-
* Merges the provided cookie configuration with default values
|
|
24
|
-
*/ function getCookieConfig(cookieConfig) {
|
|
25
|
-
const defaultOptions = {
|
|
26
|
-
path: '/',
|
|
27
|
-
maxAge: DEFAULT_MAX_AGE
|
|
28
|
-
};
|
|
29
|
-
// Helper function to merge options, filtering out undefined values
|
|
30
|
-
const mergeOptions = (configOptions)=>{
|
|
31
|
-
const merged = {
|
|
32
|
-
...defaultOptions
|
|
33
|
-
};
|
|
34
|
-
if (configOptions) {
|
|
35
|
-
Object.keys(configOptions).forEach((key)=>{
|
|
36
|
-
const value = configOptions[key];
|
|
37
|
-
if (value !== undefined) {
|
|
38
|
-
merged[key] = value;
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
return merged;
|
|
43
|
-
};
|
|
44
|
-
return {
|
|
45
|
-
ctx: {
|
|
46
|
-
name: cookieConfig?.ctx?.name ?? 'edgestore-ctx',
|
|
47
|
-
options: mergeOptions(cookieConfig?.ctx?.options)
|
|
48
|
-
},
|
|
49
|
-
token: {
|
|
50
|
-
name: cookieConfig?.token?.name ?? 'edgestore-token',
|
|
51
|
-
options: mergeOptions(cookieConfig?.token?.options)
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
async function init(params) {
|
|
56
|
-
const log = globalThis._EDGE_STORE_LOGGER;
|
|
57
|
-
const { ctx, provider, router, cookieConfig } = params;
|
|
58
|
-
log.debug('Running [init]', {
|
|
59
|
-
ctx
|
|
60
|
-
});
|
|
61
|
-
const resolvedCookieConfig = getCookieConfig(cookieConfig);
|
|
62
|
-
const ctxToken = await encryptJWT(ctx);
|
|
63
|
-
const { token } = await provider.init({
|
|
64
|
-
ctx,
|
|
65
|
-
router: router
|
|
66
|
-
});
|
|
67
|
-
const newCookies = [
|
|
68
|
-
cookie.serialize(resolvedCookieConfig.ctx.name, ctxToken, resolvedCookieConfig.ctx.options)
|
|
69
|
-
];
|
|
70
|
-
if (token) {
|
|
71
|
-
newCookies.push(cookie.serialize(resolvedCookieConfig.token.name, token, resolvedCookieConfig.token.options));
|
|
72
|
-
}
|
|
73
|
-
const baseUrl = await provider.getBaseUrl();
|
|
74
|
-
log.debug('Finished [init]', {
|
|
75
|
-
ctx,
|
|
76
|
-
newCookies,
|
|
77
|
-
token,
|
|
78
|
-
baseUrl,
|
|
79
|
-
providerName: provider.name
|
|
80
|
-
});
|
|
81
|
-
return {
|
|
82
|
-
newCookies,
|
|
83
|
-
token,
|
|
84
|
-
baseUrl,
|
|
85
|
-
providerName: provider.name
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
async function requestUpload(params) {
|
|
89
|
-
const { provider, router, ctxToken, body: { bucketName, input, fileInfo } } = params;
|
|
90
|
-
const log = globalThis._EDGE_STORE_LOGGER;
|
|
91
|
-
log.debug('Running [requestUpload]', {
|
|
92
|
-
bucketName,
|
|
93
|
-
input,
|
|
94
|
-
fileInfo
|
|
95
|
-
});
|
|
96
|
-
if (!ctxToken) {
|
|
97
|
-
throw new shared.EdgeStoreError({
|
|
98
|
-
message: 'Missing edgestore-ctx cookie',
|
|
99
|
-
code: 'UNAUTHORIZED'
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
const ctx = await getContext(ctxToken);
|
|
103
|
-
log.debug('Decrypted Context', {
|
|
104
|
-
ctx
|
|
105
|
-
});
|
|
106
|
-
const bucket = router.buckets[bucketName];
|
|
107
|
-
if (!bucket) {
|
|
108
|
-
throw new shared.EdgeStoreError({
|
|
109
|
-
message: `Bucket ${bucketName} not found`,
|
|
110
|
-
code: 'BAD_REQUEST'
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
if (bucket._def.beforeUpload) {
|
|
114
|
-
log.debug('Running [beforeUpload]');
|
|
115
|
-
const canUpload = await bucket._def.beforeUpload?.({
|
|
116
|
-
ctx,
|
|
117
|
-
input,
|
|
118
|
-
fileInfo: {
|
|
119
|
-
size: fileInfo.size,
|
|
120
|
-
type: fileInfo.type,
|
|
121
|
-
fileName: fileInfo.fileName,
|
|
122
|
-
extension: fileInfo.extension,
|
|
123
|
-
replaceTargetUrl: fileInfo.replaceTargetUrl,
|
|
124
|
-
temporary: fileInfo.temporary
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
log.debug('Finished [beforeUpload]', {
|
|
128
|
-
canUpload
|
|
129
|
-
});
|
|
130
|
-
if (!canUpload) {
|
|
131
|
-
throw new shared.EdgeStoreError({
|
|
132
|
-
message: 'Upload not allowed for the current context',
|
|
133
|
-
code: 'UPLOAD_NOT_ALLOWED'
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (bucket._def.type === 'IMAGE') {
|
|
138
|
-
if (!IMAGE_MIME_TYPES.includes(fileInfo.type)) {
|
|
139
|
-
throw new shared.EdgeStoreError({
|
|
140
|
-
code: 'MIME_TYPE_NOT_ALLOWED',
|
|
141
|
-
message: 'Only images are allowed in this bucket',
|
|
142
|
-
details: {
|
|
143
|
-
allowedMimeTypes: IMAGE_MIME_TYPES,
|
|
144
|
-
mimeType: fileInfo.type
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (bucket._def.bucketConfig?.maxSize) {
|
|
150
|
-
if (fileInfo.size > bucket._def.bucketConfig.maxSize) {
|
|
151
|
-
throw new shared.EdgeStoreError({
|
|
152
|
-
code: 'FILE_TOO_LARGE',
|
|
153
|
-
message: `File size is too big. Max size is ${bucket._def.bucketConfig.maxSize}`,
|
|
154
|
-
details: {
|
|
155
|
-
maxFileSize: bucket._def.bucketConfig.maxSize,
|
|
156
|
-
fileSize: fileInfo.size
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
if (bucket._def.bucketConfig?.accept) {
|
|
162
|
-
const accept = bucket._def.bucketConfig.accept;
|
|
163
|
-
let accepted = false;
|
|
164
|
-
for (const acceptedMimeType of accept){
|
|
165
|
-
if (acceptedMimeType.endsWith('/*')) {
|
|
166
|
-
const mimeType = acceptedMimeType.replace('/*', '');
|
|
167
|
-
if (fileInfo.type.startsWith(mimeType)) {
|
|
168
|
-
accepted = true;
|
|
169
|
-
break;
|
|
170
|
-
}
|
|
171
|
-
} else if (fileInfo.type === acceptedMimeType) {
|
|
172
|
-
accepted = true;
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
if (!accepted) {
|
|
177
|
-
throw new shared.EdgeStoreError({
|
|
178
|
-
code: 'MIME_TYPE_NOT_ALLOWED',
|
|
179
|
-
message: `"${fileInfo.type}" is not allowed. Accepted types are ${JSON.stringify(accept)}`,
|
|
180
|
-
details: {
|
|
181
|
-
allowedMimeTypes: accept,
|
|
182
|
-
mimeType: fileInfo.type
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
const path = buildPath({
|
|
188
|
-
fileInfo,
|
|
189
|
-
bucket,
|
|
190
|
-
pathAttrs: {
|
|
191
|
-
ctx,
|
|
192
|
-
input
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
const metadata = await bucket._def.metadata?.({
|
|
196
|
-
ctx,
|
|
197
|
-
input
|
|
198
|
-
});
|
|
199
|
-
const isPublic = bucket._def.accessControl === undefined;
|
|
200
|
-
log.debug('upload info', {
|
|
201
|
-
path,
|
|
202
|
-
metadata,
|
|
203
|
-
isPublic,
|
|
204
|
-
bucketType: bucket._def.type
|
|
205
|
-
});
|
|
206
|
-
const requestUploadRes = await provider.requestUpload({
|
|
207
|
-
bucketName,
|
|
208
|
-
bucketType: bucket._def.type,
|
|
209
|
-
fileInfo: {
|
|
210
|
-
...fileInfo,
|
|
211
|
-
path,
|
|
212
|
-
isPublic,
|
|
213
|
-
metadata
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
const { parsedPath, pathOrder } = parsePath(path);
|
|
217
|
-
log.debug('Finished [requestUpload]');
|
|
218
|
-
return {
|
|
219
|
-
...requestUploadRes,
|
|
220
|
-
size: fileInfo.size,
|
|
221
|
-
uploadedAt: new Date().toISOString(),
|
|
222
|
-
path: parsedPath,
|
|
223
|
-
pathOrder,
|
|
224
|
-
metadata
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
async function requestUploadParts(params) {
|
|
228
|
-
const { provider, ctxToken, body: { multipart, path } } = params;
|
|
229
|
-
const log = globalThis._EDGE_STORE_LOGGER;
|
|
230
|
-
log.debug('Running [requestUploadParts]', {
|
|
231
|
-
multipart,
|
|
232
|
-
path
|
|
233
|
-
});
|
|
234
|
-
if (!ctxToken) {
|
|
235
|
-
throw new shared.EdgeStoreError({
|
|
236
|
-
message: 'Missing edgestore-ctx cookie',
|
|
237
|
-
code: 'UNAUTHORIZED'
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
await getContext(ctxToken); // just to check if the token is valid
|
|
241
|
-
const res = await provider.requestUploadParts({
|
|
242
|
-
multipart,
|
|
243
|
-
path
|
|
244
|
-
});
|
|
245
|
-
log.debug('Finished [requestUploadParts]');
|
|
246
|
-
return res;
|
|
247
|
-
}
|
|
248
|
-
async function completeMultipartUpload(params) {
|
|
249
|
-
const { provider, router, ctxToken, body: { bucketName, uploadId, key, parts } } = params;
|
|
250
|
-
const log = globalThis._EDGE_STORE_LOGGER;
|
|
251
|
-
log.debug('Running [completeMultipartUpload]', {
|
|
252
|
-
bucketName,
|
|
253
|
-
uploadId,
|
|
254
|
-
key
|
|
255
|
-
});
|
|
256
|
-
if (!ctxToken) {
|
|
257
|
-
throw new shared.EdgeStoreError({
|
|
258
|
-
message: 'Missing edgestore-ctx cookie',
|
|
259
|
-
code: 'UNAUTHORIZED'
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
await getContext(ctxToken); // just to check if the token is valid
|
|
263
|
-
const bucket = router.buckets[bucketName];
|
|
264
|
-
if (!bucket) {
|
|
265
|
-
throw new shared.EdgeStoreError({
|
|
266
|
-
message: `Bucket ${bucketName} not found`,
|
|
267
|
-
code: 'BAD_REQUEST'
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
const res = await provider.completeMultipartUpload({
|
|
271
|
-
uploadId,
|
|
272
|
-
key,
|
|
273
|
-
parts
|
|
274
|
-
});
|
|
275
|
-
log.debug('Finished [completeMultipartUpload]');
|
|
276
|
-
return res;
|
|
277
|
-
}
|
|
278
|
-
async function confirmUpload(params) {
|
|
279
|
-
const { provider, router, ctxToken, body: { bucketName, url } } = params;
|
|
280
|
-
const log = globalThis._EDGE_STORE_LOGGER;
|
|
281
|
-
log.debug('Running [confirmUpload]', {
|
|
282
|
-
bucketName,
|
|
283
|
-
url
|
|
284
|
-
});
|
|
285
|
-
if (!ctxToken) {
|
|
286
|
-
throw new shared.EdgeStoreError({
|
|
287
|
-
message: 'Missing edgestore-ctx cookie',
|
|
288
|
-
code: 'UNAUTHORIZED'
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
await getContext(ctxToken); // just to check if the token is valid
|
|
292
|
-
const bucket = router.buckets[bucketName];
|
|
293
|
-
if (!bucket) {
|
|
294
|
-
throw new shared.EdgeStoreError({
|
|
295
|
-
message: `Bucket ${bucketName} not found`,
|
|
296
|
-
code: 'BAD_REQUEST'
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
const res = await provider.confirmUpload({
|
|
300
|
-
bucket,
|
|
301
|
-
url: unproxyUrl(url)
|
|
302
|
-
});
|
|
303
|
-
log.debug('Finished [confirmUpload]');
|
|
304
|
-
return res;
|
|
305
|
-
}
|
|
306
|
-
async function deleteFile(params) {
|
|
307
|
-
const { provider, router, ctxToken, body: { bucketName, url } } = params;
|
|
308
|
-
const log = globalThis._EDGE_STORE_LOGGER;
|
|
309
|
-
log.debug('Running [deleteFile]', {
|
|
310
|
-
bucketName,
|
|
311
|
-
url
|
|
312
|
-
});
|
|
313
|
-
if (!ctxToken) {
|
|
314
|
-
throw new shared.EdgeStoreError({
|
|
315
|
-
message: 'Missing edgestore-ctx cookie',
|
|
316
|
-
code: 'UNAUTHORIZED'
|
|
317
|
-
});
|
|
318
|
-
}
|
|
319
|
-
const ctx = await getContext(ctxToken);
|
|
320
|
-
const bucket = router.buckets[bucketName];
|
|
321
|
-
if (!bucket) {
|
|
322
|
-
throw new shared.EdgeStoreError({
|
|
323
|
-
message: `Bucket ${bucketName} not found`,
|
|
324
|
-
code: 'BAD_REQUEST'
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
if (!bucket._def.beforeDelete) {
|
|
328
|
-
throw new shared.EdgeStoreError({
|
|
329
|
-
message: 'You need to define beforeDelete if you want to delete files directly from the frontend.',
|
|
330
|
-
code: 'SERVER_ERROR'
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
const fileInfo = await provider.getFile({
|
|
334
|
-
url: unproxyUrl(url)
|
|
335
|
-
});
|
|
336
|
-
const canDelete = await bucket._def.beforeDelete({
|
|
337
|
-
ctx,
|
|
338
|
-
fileInfo
|
|
339
|
-
});
|
|
340
|
-
if (!canDelete) {
|
|
341
|
-
throw new shared.EdgeStoreError({
|
|
342
|
-
message: 'Delete not allowed for the current context',
|
|
343
|
-
code: 'DELETE_NOT_ALLOWED'
|
|
344
|
-
});
|
|
345
|
-
}
|
|
346
|
-
const res = await provider.deleteFile({
|
|
347
|
-
bucket,
|
|
348
|
-
url: unproxyUrl(url)
|
|
349
|
-
});
|
|
350
|
-
log.debug('Finished [deleteFile]');
|
|
351
|
-
return res;
|
|
352
|
-
}
|
|
353
|
-
async function encryptJWT(ctx) {
|
|
354
|
-
const secret = getEnv('EDGE_STORE_JWT_SECRET') ?? getEnv('EDGE_STORE_SECRET_KEY');
|
|
355
|
-
if (!secret) {
|
|
356
|
-
throw new shared.EdgeStoreError({
|
|
357
|
-
message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
|
|
358
|
-
code: 'SERVER_ERROR'
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
const encryptionSecret = await getDerivedEncryptionKey(secret);
|
|
362
|
-
return await new jose.EncryptJWT(ctx).setProtectedHeader({
|
|
363
|
-
alg: 'dir',
|
|
364
|
-
enc: 'A256GCM'
|
|
365
|
-
}).setIssuedAt().setExpirationTime(Date.now() / 1000 + DEFAULT_MAX_AGE).setJti(uuid.v4()).encrypt(encryptionSecret);
|
|
366
|
-
}
|
|
367
|
-
async function decryptJWT(token) {
|
|
368
|
-
const secret = getEnv('EDGE_STORE_JWT_SECRET') ?? getEnv('EDGE_STORE_SECRET_KEY');
|
|
369
|
-
if (!secret) {
|
|
370
|
-
throw new shared.EdgeStoreError({
|
|
371
|
-
message: 'EDGE_STORE_JWT_SECRET or EDGE_STORE_SECRET_KEY is not defined',
|
|
372
|
-
code: 'SERVER_ERROR'
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
const encryptionSecret = await getDerivedEncryptionKey(secret);
|
|
376
|
-
const { payload } = await jose.jwtDecrypt(token, encryptionSecret, {
|
|
377
|
-
clockTolerance: 15
|
|
378
|
-
});
|
|
379
|
-
return payload;
|
|
380
|
-
}
|
|
381
|
-
async function getDerivedEncryptionKey(secret) {
|
|
382
|
-
return await hkdf.hkdf('sha256', secret, '', 'EdgeStore Generated Encryption Key', 32);
|
|
383
|
-
}
|
|
384
|
-
function buildPath(params) {
|
|
385
|
-
const { bucket } = params;
|
|
386
|
-
const pathParams = bucket._def.path;
|
|
387
|
-
const path = pathParams.map((param)=>{
|
|
388
|
-
const paramEntries = Object.entries(param);
|
|
389
|
-
if (paramEntries[0] === undefined) {
|
|
390
|
-
throw new shared.EdgeStoreError({
|
|
391
|
-
message: `Empty path param found in: ${JSON.stringify(pathParams)}`,
|
|
392
|
-
code: 'SERVER_ERROR'
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
const [key, value] = paramEntries[0];
|
|
396
|
-
// this is a string like: "ctx.xxx" or "input.yyy.zzz"
|
|
397
|
-
const currParamVal = value().split('.').reduce((acc2, key)=>{
|
|
398
|
-
if (acc2[key] === undefined) {
|
|
399
|
-
throw new shared.EdgeStoreError({
|
|
400
|
-
message: `Missing key ${key} in ${JSON.stringify(acc2)}`,
|
|
401
|
-
code: 'BAD_REQUEST'
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
return acc2[key];
|
|
405
|
-
}, params.pathAttrs);
|
|
406
|
-
return {
|
|
407
|
-
key,
|
|
408
|
-
value: currParamVal
|
|
409
|
-
};
|
|
410
|
-
});
|
|
411
|
-
return path;
|
|
412
|
-
}
|
|
413
|
-
function parsePath(path) {
|
|
414
|
-
const parsedPath = path.reduce((acc, curr)=>{
|
|
415
|
-
acc[curr.key] = curr.value;
|
|
416
|
-
return acc;
|
|
417
|
-
}, {});
|
|
418
|
-
const pathOrder = path.map((p)=>p.key);
|
|
419
|
-
return {
|
|
420
|
-
parsedPath,
|
|
421
|
-
pathOrder
|
|
422
|
-
};
|
|
423
|
-
}
|
|
424
|
-
async function getContext(token) {
|
|
425
|
-
return await decryptJWT(token);
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* On local development, protected files are proxied to the server,
|
|
429
|
-
* which changes the original URL.
|
|
430
|
-
*
|
|
431
|
-
* This function is used to get the original URL,
|
|
432
|
-
* so that we can delete or confirm the upload.
|
|
433
|
-
*/ function unproxyUrl(url) {
|
|
434
|
-
if (isDev() && url.startsWith('http://')) {
|
|
435
|
-
// get the url param from the query string
|
|
436
|
-
const urlParam = new URL(url).searchParams.get('url');
|
|
437
|
-
if (urlParam) {
|
|
438
|
-
return urlParam;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return url;
|
|
442
|
-
}
|
|
443
|
-
function getEnv(key) {
|
|
444
|
-
if (typeof process !== 'undefined' && process.env) {
|
|
445
|
-
// @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
|
|
446
|
-
return process.env[key] ?? undefined?.[key];
|
|
447
|
-
}
|
|
448
|
-
// @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
|
|
449
|
-
return undefined?.[key];
|
|
450
|
-
}
|
|
451
|
-
function isDev() {
|
|
452
|
-
return process?.env?.NODE_ENV === 'development' || // @ts-expect-error - In Vite/Astro, the env variables are available on `import.meta`.
|
|
453
|
-
undefined?.DEV;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
exports.buildPath = buildPath;
|
|
457
|
-
exports.completeMultipartUpload = completeMultipartUpload;
|
|
458
|
-
exports.confirmUpload = confirmUpload;
|
|
459
|
-
exports.deleteFile = deleteFile;
|
|
460
|
-
exports.getCookieConfig = getCookieConfig;
|
|
461
|
-
exports.getEnv = getEnv;
|
|
462
|
-
exports.init = init;
|
|
463
|
-
exports.isDev = isDev;
|
|
464
|
-
exports.parsePath = parsePath;
|
|
465
|
-
exports.requestUpload = requestUpload;
|
|
466
|
-
exports.requestUploadParts = requestUploadParts;
|