next-tinacms-s3 1.3.0 → 1.3.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.
@@ -6,6 +6,7 @@ import { NextApiRequest, NextApiResponse } from 'next';
6
6
  export interface S3Config {
7
7
  config: S3ClientConfig;
8
8
  bucket: string;
9
+ mediaRoot?: string;
9
10
  authorized: (_req: NextApiRequest, _res: NextApiResponse) => Promise<boolean>;
10
11
  }
11
12
  export interface S3Options {
package/dist/handlers.js CHANGED
@@ -43,6 +43,15 @@ var createMediaHandler = (config, options) => {
43
43
  const client = new import_client_s3.S3Client(config.config);
44
44
  const bucket = config.bucket;
45
45
  const region = config.config.region || "us-east-1";
46
+ let mediaRoot = config.mediaRoot || "";
47
+ if (mediaRoot) {
48
+ if (!mediaRoot.endsWith("/")) {
49
+ mediaRoot = mediaRoot + "/";
50
+ }
51
+ if (mediaRoot.startsWith("/")) {
52
+ mediaRoot = mediaRoot.substr(1);
53
+ }
54
+ }
46
55
  const endpoint = config.config.endpoint || `https://s3.${region}.amazonaws.com`;
47
56
  let cdnUrl = (options == null ? void 0 : options.cdnUrl) || endpoint.toString().replace(/http(s|):\/\//i, `https://${bucket}.`);
48
57
  cdnUrl = cdnUrl + (cdnUrl.endsWith("/") ? "" : "/");
@@ -54,9 +63,9 @@ var createMediaHandler = (config, options) => {
54
63
  }
55
64
  switch (req.method) {
56
65
  case "GET":
57
- return listMedia(req, res, client, bucket, cdnUrl);
66
+ return listMedia(req, res, client, bucket, mediaRoot, cdnUrl);
58
67
  case "POST":
59
- return uploadMedia(req, res, client, bucket, cdnUrl);
68
+ return uploadMedia(req, res, client, bucket, mediaRoot, cdnUrl);
60
69
  case "DELETE":
61
70
  return deleteAsset(req, res, client, bucket);
62
71
  default:
@@ -64,7 +73,7 @@ var createMediaHandler = (config, options) => {
64
73
  }
65
74
  };
66
75
  };
67
- async function uploadMedia(req, res, client, bucket, cdnUrl) {
76
+ async function uploadMedia(req, res, client, bucket, mediaRoot, cdnUrl) {
68
77
  try {
69
78
  const upload = (0, import_util.promisify)(
70
79
  (0, import_multer.default)({
@@ -88,7 +97,7 @@ async function uploadMedia(req, res, client, bucket, cdnUrl) {
88
97
  const filename = import_path.default.basename(filePath);
89
98
  const params = {
90
99
  Bucket: bucket,
91
- Key: prefix + filename,
100
+ Key: mediaRoot ? import_path.default.join(mediaRoot, prefix + filename) : prefix + filename,
92
101
  Body: blob,
93
102
  ACL: "public-read"
94
103
  };
@@ -106,18 +115,38 @@ async function uploadMedia(req, res, client, bucket, cdnUrl) {
106
115
  "400x400": src,
107
116
  "1000x1000": src
108
117
  },
109
- src
118
+ src: cdnUrl + (mediaRoot ? import_path.default.join(mediaRoot, prefix + filename) : prefix + filename)
110
119
  });
111
120
  } catch (e) {
121
+ console.error("Error uploading media to s3");
122
+ console.error(e);
112
123
  res.status(500).send(findErrorMessage(e));
113
124
  }
114
125
  } catch (e) {
126
+ console.error("Error uploading media");
127
+ console.error(e);
115
128
  res.status(500);
116
129
  const message = findErrorMessage(e);
117
130
  res.json({ e: message });
118
131
  }
119
132
  }
120
- async function listMedia(req, res, client, bucket, cdnUrl) {
133
+ function stripMediaRoot(mediaRoot, key) {
134
+ if (!mediaRoot) {
135
+ return key;
136
+ }
137
+ const mediaRootParts = mediaRoot.split("/").filter((part) => part);
138
+ if (!mediaRootParts || !mediaRootParts[0]) {
139
+ return key;
140
+ }
141
+ const keyParts = key.split("/").filter((part) => part);
142
+ for (let i = 0; i < mediaRootParts.length; i++) {
143
+ if (keyParts[0] === mediaRootParts[i]) {
144
+ keyParts.shift();
145
+ }
146
+ }
147
+ return keyParts.join("/");
148
+ }
149
+ async function listMedia(req, res, client, bucket, mediaRoot, cdnUrl) {
121
150
  var _a;
122
151
  try {
123
152
  const {
@@ -131,29 +160,38 @@ async function listMedia(req, res, client, bucket, cdnUrl) {
131
160
  const params = {
132
161
  Bucket: bucket,
133
162
  Delimiter: "/",
134
- Prefix: prefix,
163
+ Prefix: mediaRoot ? import_path.default.join(mediaRoot, prefix) : prefix,
135
164
  Marker: offset == null ? void 0 : offset.toString(),
136
165
  MaxKeys: directory && !offset ? +limit + 1 : +limit
137
166
  };
138
167
  const command = new import_client_s3.ListObjectsCommand(params);
139
168
  const response = await client.send(command);
140
169
  const items = [];
141
- (_a = response.CommonPrefixes) == null ? void 0 : _a.forEach(
142
- ({ Prefix }) => items.push({
170
+ (_a = response.CommonPrefixes) == null ? void 0 : _a.forEach(({ Prefix }) => {
171
+ const strippedPrefix = stripMediaRoot(mediaRoot, Prefix);
172
+ if (!strippedPrefix) {
173
+ return;
174
+ }
175
+ items.push({
143
176
  id: Prefix,
144
177
  type: "dir",
145
- filename: import_path.default.basename(Prefix),
146
- directory: import_path.default.dirname(Prefix)
147
- })
148
- );
178
+ filename: import_path.default.basename(strippedPrefix),
179
+ directory: import_path.default.dirname(strippedPrefix)
180
+ });
181
+ });
149
182
  items.push(
150
- ...(response.Contents || []).filter((file) => file.Key !== prefix).map(getS3ToTinaFunc(cdnUrl))
183
+ ...(response.Contents || []).filter((file) => {
184
+ const strippedKey = stripMediaRoot(mediaRoot, file.Key);
185
+ return strippedKey !== prefix;
186
+ }).map(getS3ToTinaFunc(cdnUrl, mediaRoot))
151
187
  );
152
188
  res.json({
153
189
  items,
154
190
  offset: response.NextMarker
155
191
  });
156
192
  } catch (e) {
193
+ console.error("Error listing media");
194
+ console.error(e);
157
195
  res.status(500);
158
196
  const message = findErrorMessage(e);
159
197
  res.json({ e: message });
@@ -180,15 +218,18 @@ async function deleteAsset(req, res, client, bucket) {
180
218
  const data = await client.send(command);
181
219
  res.json(data);
182
220
  } catch (e) {
221
+ console.error("Error deleting media");
222
+ console.error(e);
183
223
  res.status(500);
184
224
  const message = findErrorMessage(e);
185
225
  res.json({ e: message });
186
226
  }
187
227
  }
188
- function getS3ToTinaFunc(cdnUrl) {
228
+ function getS3ToTinaFunc(cdnUrl, mediaRoot) {
189
229
  return function s3ToTina(file) {
190
- const filename = import_path.default.basename(file.Key);
191
- const directory = import_path.default.dirname(file.Key) + "/";
230
+ const strippedKey = stripMediaRoot(mediaRoot, file.Key);
231
+ const filename = import_path.default.basename(strippedKey);
232
+ const directory = import_path.default.dirname(strippedKey) + "/";
192
233
  const src = cdnUrl + file.Key;
193
234
  return {
194
235
  id: file.Key,