@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.
Files changed (202) hide show
  1. package/adapters/astro/package.json +1 -0
  2. package/adapters/express/package.json +1 -0
  3. package/adapters/fastify/package.json +1 -0
  4. package/adapters/hono/package.json +1 -0
  5. package/adapters/next/app/package.json +1 -0
  6. package/adapters/next/pages/package.json +1 -0
  7. package/adapters/remix/package.json +1 -0
  8. package/adapters/start/package.json +1 -0
  9. package/core/package.json +1 -0
  10. package/dist/adapters/astro/index.cjs +134 -0
  11. package/dist/adapters/astro/index.d.cts +20 -0
  12. package/dist/adapters/astro/index.d.cts.map +1 -0
  13. package/dist/adapters/astro/index.d.mts +20 -0
  14. package/dist/adapters/astro/index.d.mts.map +1 -0
  15. package/dist/adapters/astro/index.mjs +128 -175
  16. package/dist/adapters/astro/index.mjs.map +1 -0
  17. package/dist/adapters/express/index.cjs +104 -0
  18. package/dist/adapters/express/index.d.cts +24 -0
  19. package/dist/adapters/express/index.d.cts.map +1 -0
  20. package/dist/adapters/express/index.d.mts +24 -0
  21. package/dist/adapters/express/index.d.mts.map +1 -0
  22. package/dist/adapters/express/index.mjs +100 -112
  23. package/dist/adapters/express/index.mjs.map +1 -0
  24. package/dist/adapters/fastify/index.cjs +115 -0
  25. package/dist/adapters/fastify/index.d.cts +24 -0
  26. package/dist/adapters/fastify/index.d.cts.map +1 -0
  27. package/dist/adapters/fastify/index.d.mts +24 -0
  28. package/dist/adapters/fastify/index.d.mts.map +1 -0
  29. package/dist/adapters/fastify/index.mjs +109 -139
  30. package/dist/adapters/fastify/index.mjs.map +1 -0
  31. package/dist/adapters/hono/index.cjs +117 -0
  32. package/dist/adapters/hono/index.d.cts +91 -0
  33. package/dist/adapters/hono/index.d.cts.map +1 -0
  34. package/dist/adapters/hono/index.d.mts +91 -0
  35. package/dist/adapters/hono/index.d.mts.map +1 -0
  36. package/dist/adapters/hono/index.mjs +111 -129
  37. package/dist/adapters/hono/index.mjs.map +1 -0
  38. package/dist/adapters/next/app/index.cjs +140 -0
  39. package/dist/adapters/next/app/index.d.cts +23 -0
  40. package/dist/adapters/next/app/index.d.cts.map +1 -0
  41. package/dist/adapters/next/app/index.d.mts +23 -0
  42. package/dist/adapters/next/app/index.d.mts.map +1 -0
  43. package/dist/adapters/next/app/index.mjs +136 -168
  44. package/dist/adapters/next/app/index.mjs.map +1 -0
  45. package/dist/adapters/next/pages/index.cjs +108 -0
  46. package/dist/adapters/next/pages/index.d.cts +24 -0
  47. package/dist/adapters/next/pages/index.d.cts.map +1 -0
  48. package/dist/adapters/next/pages/index.d.mts +24 -0
  49. package/dist/adapters/next/pages/index.d.mts.map +1 -0
  50. package/dist/adapters/next/pages/index.mjs +104 -116
  51. package/dist/adapters/next/pages/index.mjs.map +1 -0
  52. package/dist/adapters/remix/index.cjs +124 -0
  53. package/dist/adapters/remix/index.d.cts +26 -0
  54. package/dist/adapters/remix/index.d.cts.map +1 -0
  55. package/dist/adapters/remix/index.d.mts +26 -0
  56. package/dist/adapters/remix/index.d.mts.map +1 -0
  57. package/dist/adapters/remix/index.mjs +118 -150
  58. package/dist/adapters/remix/index.mjs.map +1 -0
  59. package/dist/adapters/start/index.cjs +156 -0
  60. package/dist/adapters/start/index.d.cts +26 -0
  61. package/dist/adapters/start/index.d.cts.map +1 -0
  62. package/dist/adapters/start/index.d.mts +26 -0
  63. package/dist/adapters/start/index.d.mts.map +1 -0
  64. package/dist/adapters/start/index.mjs +150 -184
  65. package/dist/adapters/start/index.mjs.map +1 -0
  66. package/dist/core/index.cjs +148 -0
  67. package/dist/core/index.d.cts +500 -0
  68. package/dist/core/index.d.cts.map +1 -0
  69. package/dist/core/index.d.mts +500 -0
  70. package/dist/core/index.d.mts.map +1 -0
  71. package/dist/core/index.mjs +135 -169
  72. package/dist/core/index.mjs.map +1 -0
  73. package/dist/edgestore-Cr88uKUx.mjs +142 -0
  74. package/dist/edgestore-Cr88uKUx.mjs.map +1 -0
  75. package/dist/edgestore-Dqb-EoFm.cjs +146 -0
  76. package/dist/index.cjs +8 -0
  77. package/dist/index.d.cts +2 -0
  78. package/dist/index.d.mts +2 -0
  79. package/dist/index.mjs +3 -1
  80. package/dist/providers/aws/index.cjs +89 -0
  81. package/dist/providers/aws/index.d.cts +71 -0
  82. package/dist/providers/aws/index.d.cts.map +1 -0
  83. package/dist/providers/aws/index.d.mts +71 -0
  84. package/dist/providers/aws/index.d.mts.map +1 -0
  85. package/dist/providers/aws/index.mjs +85 -102
  86. package/dist/providers/aws/index.mjs.map +1 -0
  87. package/dist/providers/azure/index.cjs +56 -0
  88. package/dist/providers/azure/index.d.cts +44 -0
  89. package/dist/providers/azure/index.d.cts.map +1 -0
  90. package/dist/providers/azure/index.d.mts +44 -0
  91. package/dist/providers/azure/index.d.mts.map +1 -0
  92. package/dist/providers/azure/index.mjs +52 -58
  93. package/dist/providers/azure/index.mjs.map +1 -0
  94. package/dist/providers/edgestore/index.cjs +5 -0
  95. package/dist/providers/edgestore/index.d.cts +23 -0
  96. package/dist/providers/edgestore/index.d.cts.map +1 -0
  97. package/dist/providers/edgestore/index.d.mts +23 -0
  98. package/dist/providers/edgestore/index.d.mts.map +1 -0
  99. package/dist/providers/edgestore/index.mjs +4 -146
  100. package/dist/sdk-AhXUPMy1.cjs +238 -0
  101. package/dist/sdk-CKRQe75P.mjs +222 -0
  102. package/dist/sdk-CKRQe75P.mjs.map +1 -0
  103. package/dist/shared-B39MtSQo.d.cts +68 -0
  104. package/dist/shared-B39MtSQo.d.cts.map +1 -0
  105. package/dist/shared-Bd7-gfqa.mjs +457 -0
  106. package/dist/shared-Bd7-gfqa.mjs.map +1 -0
  107. package/dist/shared-DsWTtQ1-.d.mts +68 -0
  108. package/dist/shared-DsWTtQ1-.d.mts.map +1 -0
  109. package/dist/shared-pWGwhEsU.cjs +527 -0
  110. package/dist/utils--x-q_GK5.mjs +44 -0
  111. package/dist/utils--x-q_GK5.mjs.map +1 -0
  112. package/dist/utils-D6YuBNUV.cjs +54 -0
  113. package/package.json +121 -57
  114. package/providers/aws/package.json +1 -0
  115. package/providers/azure/package.json +1 -0
  116. package/providers/edgestore/package.json +1 -0
  117. package/adapters/astro/index.d.ts +0 -1
  118. package/adapters/astro/index.js +0 -1
  119. package/adapters/express/index.d.ts +0 -1
  120. package/adapters/express/index.js +0 -1
  121. package/adapters/fastify/index.d.ts +0 -1
  122. package/adapters/fastify/index.js +0 -1
  123. package/adapters/hono/index.d.ts +0 -1
  124. package/adapters/hono/index.js +0 -1
  125. package/adapters/next/app/index.d.ts +0 -1
  126. package/adapters/next/app/index.js +0 -1
  127. package/adapters/next/pages/index.d.ts +0 -1
  128. package/adapters/next/pages/index.js +0 -1
  129. package/adapters/remix/index.d.ts +0 -1
  130. package/adapters/remix/index.js +0 -1
  131. package/adapters/start/index.d.ts +0 -1
  132. package/adapters/start/index.js +0 -1
  133. package/core/index.d.ts +0 -1
  134. package/core/index.js +0 -1
  135. package/dist/adapters/astro/index.d.ts +0 -17
  136. package/dist/adapters/astro/index.d.ts.map +0 -1
  137. package/dist/adapters/astro/index.js +0 -186
  138. package/dist/adapters/express/index.d.ts +0 -21
  139. package/dist/adapters/express/index.d.ts.map +0 -1
  140. package/dist/adapters/express/index.js +0 -121
  141. package/dist/adapters/fastify/index.d.ts +0 -21
  142. package/dist/adapters/fastify/index.d.ts.map +0 -1
  143. package/dist/adapters/fastify/index.js +0 -150
  144. package/dist/adapters/hono/index.d.ts +0 -86
  145. package/dist/adapters/hono/index.d.ts.map +0 -1
  146. package/dist/adapters/hono/index.js +0 -140
  147. package/dist/adapters/imageTypes.d.ts +0 -2
  148. package/dist/adapters/imageTypes.d.ts.map +0 -1
  149. package/dist/adapters/next/app/index.d.ts +0 -20
  150. package/dist/adapters/next/app/index.d.ts.map +0 -1
  151. package/dist/adapters/next/app/index.js +0 -177
  152. package/dist/adapters/next/pages/index.d.ts +0 -21
  153. package/dist/adapters/next/pages/index.d.ts.map +0 -1
  154. package/dist/adapters/next/pages/index.js +0 -125
  155. package/dist/adapters/remix/index.d.ts +0 -21
  156. package/dist/adapters/remix/index.d.ts.map +0 -1
  157. package/dist/adapters/remix/index.js +0 -161
  158. package/dist/adapters/shared.d.ts +0 -167
  159. package/dist/adapters/shared.d.ts.map +0 -1
  160. package/dist/adapters/start/index.d.ts +0 -21
  161. package/dist/adapters/start/index.d.ts.map +0 -1
  162. package/dist/adapters/start/index.js +0 -195
  163. package/dist/core/client/index.d.ts +0 -217
  164. package/dist/core/client/index.d.ts.map +0 -1
  165. package/dist/core/index.d.ts +0 -3
  166. package/dist/core/index.d.ts.map +0 -1
  167. package/dist/core/index.js +0 -186
  168. package/dist/core/sdk/index.d.ts +0 -240
  169. package/dist/core/sdk/index.d.ts.map +0 -1
  170. package/dist/index-1e7b1b93.js +0 -235
  171. package/dist/index-a36b09a6.mjs +0 -231
  172. package/dist/index-b0fff508.js +0 -231
  173. package/dist/index.d.ts +0 -2
  174. package/dist/index.d.ts.map +0 -1
  175. package/dist/index.js +0 -12
  176. package/dist/libs/errors/EdgeStoreCredentialsError.d.ts +0 -5
  177. package/dist/libs/errors/EdgeStoreCredentialsError.d.ts.map +0 -1
  178. package/dist/libs/logger.d.ts +0 -13
  179. package/dist/libs/logger.d.ts.map +0 -1
  180. package/dist/libs/utils.d.ts +0 -5
  181. package/dist/libs/utils.d.ts.map +0 -1
  182. package/dist/providers/aws/index.d.ts +0 -68
  183. package/dist/providers/aws/index.d.ts.map +0 -1
  184. package/dist/providers/aws/index.js +0 -111
  185. package/dist/providers/azure/index.d.ts +0 -39
  186. package/dist/providers/azure/index.d.ts.map +0 -1
  187. package/dist/providers/azure/index.js +0 -67
  188. package/dist/providers/edgestore/index.d.ts +0 -19
  189. package/dist/providers/edgestore/index.d.ts.map +0 -1
  190. package/dist/providers/edgestore/index.js +0 -151
  191. package/dist/shared-4ec2dc90.js +0 -466
  192. package/dist/shared-64e9c30c.js +0 -435
  193. package/dist/shared-c6527780.mjs +0 -454
  194. package/dist/utils-26113e02.js +0 -65
  195. package/dist/utils-ab564a9e.js +0 -44
  196. package/dist/utils-cba23eef.mjs +0 -62
  197. package/providers/aws/index.d.ts +0 -1
  198. package/providers/aws/index.js +0 -1
  199. package/providers/azure/index.d.ts +0 -1
  200. package/providers/azure/index.js +0 -1
  201. package/providers/edgestore/index.d.ts +0 -1
  202. 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;
@@ -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;