next-tinacms-dos 1.1.0 → 1.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/LICENSE CHANGED
@@ -1,3 +1,11 @@
1
+ Copyright (c) 2023-present Forestry.io Holdings Inc.
2
+
3
+ Portions of the TinaCMS software are licensed as follows:
4
+
5
+ * All software that resides under the "packages/@tinacms/datalayer/" and the "packages/@tinacms/graphql/" directories (the "Tina Data Layer"), is licensed under the license defined in "packages/@tinacms/datalayer/LICENSE".
6
+
7
+ * All software outside of the above-mentioned directories is available under the "Apache 2.0" license as set forth below.
8
+
1
9
  Apache License
2
10
  Version 2.0, January 2004
3
11
  http://www.apache.org/licenses/
package/README.md CHANGED
@@ -6,12 +6,12 @@ Manage **Digital Ocean Space media assets** in TinaCMS.
6
6
 
7
7
  ### With Yarn
8
8
  ```bash
9
- yarn add next-tinacms-dos
9
+ yarn add next-tinacms-dos @tinacms/auth
10
10
  ```
11
11
 
12
12
  ### With NPM
13
13
  ```bash
14
- npm install next-tinacms-dos
14
+ npm install next-tinacms-dos @tinacms/auth
15
15
  ```
16
16
 
17
17
  ## Connect with Digital Ocean Space
@@ -116,6 +116,7 @@ export default createMediaHandler({
116
116
  region: 'us-east-1',
117
117
  },
118
118
  bucket: process.env.NEXT_PUBLIC_SPACE_NAME || '',
119
+ mediaRoot: 'images',
119
120
  authorized: async (req, _res) => {
120
121
  if (process.env.NEXT_PUBLIC_USE_LOCAL_CLIENT === "1") {
121
122
  return true;
@@ -1,14 +1,5 @@
1
1
  /**
2
- Copyright 2021 Forestry.io Holdings, Inc.
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, software
8
- distributed under the License is distributed on an "AS IS" BASIS,
9
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- See the License for the specific language governing permissions and
11
- limitations under the License.
2
+
12
3
  */
13
4
  import type { Media, MediaList, MediaListOptions, MediaStore, MediaUploadOptions } from '@tinacms/toolkit';
14
5
  export declare class DOSMediaStore implements MediaStore {
@@ -1,14 +1,5 @@
1
1
  /**
2
- Copyright 2021 Forestry.io Holdings, Inc.
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, software
8
- distributed under the License is distributed on an "AS IS" BASIS,
9
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- See the License for the specific language governing permissions and
11
- limitations under the License.
2
+
12
3
  */
13
4
  import { DOSMediaStore } from './dos-media-store';
14
5
  import type { Client } from 'tinacms';
package/dist/errors.d.ts CHANGED
@@ -1,14 +1,5 @@
1
1
  /**
2
- Copyright 2021 Forestry.io Holdings, Inc.
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, software
8
- distributed under the License is distributed on an "AS IS" BASIS,
9
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- See the License for the specific language governing permissions and
11
- limitations under the License.
2
+
12
3
  */
13
4
  interface MediaListErrorConfig {
14
5
  title: string;
@@ -1,20 +1,12 @@
1
1
  /**
2
- Copyright 2021 Forestry.io Holdings, Inc.
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, software
8
- distributed under the License is distributed on an "AS IS" BASIS,
9
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- See the License for the specific language governing permissions and
11
- limitations under the License.
2
+
12
3
  */
13
4
  import { S3ClientConfig } from '@aws-sdk/client-s3';
14
5
  import { NextApiRequest, NextApiResponse } from 'next';
15
6
  export interface DOSConfig {
16
7
  config: S3ClientConfig;
17
8
  bucket: string;
9
+ mediaRoot?: string;
18
10
  authorized: (_req: NextApiRequest, _res: NextApiResponse) => Promise<boolean>;
19
11
  }
20
12
  export interface DOSOptions {
package/dist/handlers.js CHANGED
@@ -40,6 +40,15 @@ var mediaHandlerConfig = {
40
40
  var createMediaHandler = (config, options) => {
41
41
  const client = new import_client_s3.S3Client(config.config);
42
42
  const bucket = config.bucket;
43
+ let mediaRoot = config.mediaRoot || "";
44
+ if (mediaRoot) {
45
+ if (!mediaRoot.endsWith("/")) {
46
+ mediaRoot = mediaRoot + "/";
47
+ }
48
+ if (mediaRoot.startsWith("/")) {
49
+ mediaRoot = mediaRoot.substr(1);
50
+ }
51
+ }
43
52
  let cdnUrl = (options == null ? void 0 : options.cdnUrl) || config.config.endpoint.toString().replace(/http(s|):\/\//i, `https://${bucket}.`);
44
53
  cdnUrl = cdnUrl + (cdnUrl.endsWith("/") ? "" : "/");
45
54
  return async (req, res) => {
@@ -50,9 +59,9 @@ var createMediaHandler = (config, options) => {
50
59
  }
51
60
  switch (req.method) {
52
61
  case "GET":
53
- return listMedia(req, res, client, bucket, cdnUrl);
62
+ return listMedia(req, res, client, bucket, mediaRoot, cdnUrl);
54
63
  case "POST":
55
- return uploadMedia(req, res, client, bucket, cdnUrl);
64
+ return uploadMedia(req, res, client, bucket, mediaRoot, cdnUrl);
56
65
  case "DELETE":
57
66
  return deleteAsset(req, res, client, bucket);
58
67
  default:
@@ -60,7 +69,7 @@ var createMediaHandler = (config, options) => {
60
69
  }
61
70
  };
62
71
  };
63
- async function uploadMedia(req, res, client, bucket, cdnUrl) {
72
+ async function uploadMedia(req, res, client, bucket, mediaRoot, cdnUrl) {
64
73
  const upload = (0, import_util.promisify)((0, import_multer.default)({
65
74
  storage: import_multer.default.diskStorage({
66
75
  directory: (req2, file, cb) => {
@@ -81,7 +90,7 @@ async function uploadMedia(req, res, client, bucket, cdnUrl) {
81
90
  const filename = import_path.default.basename(filePath);
82
91
  const params = {
83
92
  Bucket: bucket,
84
- Key: prefix + filename,
93
+ Key: mediaRoot ? import_path.default.join(mediaRoot, prefix + filename) : prefix + filename,
85
94
  Body: blob,
86
95
  ACL: "public-read"
87
96
  };
@@ -93,14 +102,30 @@ async function uploadMedia(req, res, client, bucket, cdnUrl) {
93
102
  id: prefix + filename,
94
103
  filename,
95
104
  directory: prefix,
96
- previewSrc: cdnUrl + prefix + filename,
97
- src: cdnUrl + prefix + filename
105
+ previewSrc: cdnUrl + (mediaRoot ? import_path.default.join(mediaRoot, prefix + filename) : prefix + filename),
106
+ src: cdnUrl + (mediaRoot ? import_path.default.join(mediaRoot, prefix + filename) : prefix + filename)
98
107
  });
99
108
  } catch (e) {
100
109
  res.status(500).send(findErrorMessage(e));
101
110
  }
102
111
  }
103
- async function listMedia(req, res, client, bucket, cdnUrl) {
112
+ function stripMediaRoot(mediaRoot, key) {
113
+ if (!mediaRoot) {
114
+ return key;
115
+ }
116
+ const mediaRootParts = mediaRoot.split("/").filter((part) => part);
117
+ if (!mediaRootParts || !mediaRootParts[0]) {
118
+ return key;
119
+ }
120
+ const keyParts = key.split("/").filter((part) => part);
121
+ for (let i = 0; i < mediaRootParts.length; i++) {
122
+ if (keyParts[0] === mediaRootParts[i]) {
123
+ keyParts.shift();
124
+ }
125
+ }
126
+ return keyParts.join("/");
127
+ }
128
+ async function listMedia(req, res, client, bucket, mediaRoot, cdnUrl) {
104
129
  var _a;
105
130
  try {
106
131
  const {
@@ -114,20 +139,28 @@ async function listMedia(req, res, client, bucket, cdnUrl) {
114
139
  const params = {
115
140
  Bucket: bucket,
116
141
  Delimiter: "/",
117
- Prefix: prefix,
142
+ Prefix: mediaRoot ? import_path.default.join(mediaRoot, prefix) : prefix,
118
143
  Marker: offset == null ? void 0 : offset.toString(),
119
144
  MaxKeys: directory && !offset ? +limit + 1 : +limit
120
145
  };
121
- const command = new import_client_s3.ListObjectsCommand(params);
122
- const response = await client.send(command);
146
+ const response = await client.send(new import_client_s3.ListObjectsCommand(params));
123
147
  const items = [];
124
- (_a = response.CommonPrefixes) == null ? void 0 : _a.forEach(({ Prefix }) => items.push({
125
- id: Prefix,
126
- type: "dir",
127
- filename: import_path.default.basename(Prefix),
128
- directory: import_path.default.dirname(Prefix)
129
- }));
130
- items.push(...(response.Contents || []).filter((file) => file.Key !== prefix).map(getDOSToTinaFunc(cdnUrl)));
148
+ (_a = response.CommonPrefixes) == null ? void 0 : _a.forEach(({ Prefix }) => {
149
+ const strippedPrefix = stripMediaRoot(mediaRoot, Prefix);
150
+ if (!strippedPrefix) {
151
+ return;
152
+ }
153
+ items.push({
154
+ id: Prefix,
155
+ type: "dir",
156
+ filename: import_path.default.basename(strippedPrefix),
157
+ directory: import_path.default.dirname(strippedPrefix)
158
+ });
159
+ });
160
+ items.push(...(response.Contents || []).filter((file) => {
161
+ const strippedKey = stripMediaRoot(mediaRoot, file.Key);
162
+ return strippedKey !== prefix;
163
+ }).map(getDOSToTinaFunc(cdnUrl, mediaRoot)));
131
164
  res.json({
132
165
  items,
133
166
  offset: response.NextMarker
@@ -154,9 +187,8 @@ async function deleteAsset(req, res, client, bucket) {
154
187
  Bucket: bucket,
155
188
  Key: objectKey
156
189
  };
157
- const command = new import_client_s3.DeleteObjectCommand(params);
158
190
  try {
159
- const data = await client.send(command);
191
+ const data = await client.send(new import_client_s3.DeleteObjectCommand(params));
160
192
  res.json(data);
161
193
  } catch (err) {
162
194
  res.status(500).json({
@@ -164,10 +196,11 @@ async function deleteAsset(req, res, client, bucket) {
164
196
  });
165
197
  }
166
198
  }
167
- function getDOSToTinaFunc(cdnUrl) {
199
+ function getDOSToTinaFunc(cdnUrl, mediaRoot) {
168
200
  return function dosToTina(file) {
169
- const filename = import_path.default.basename(file.Key);
170
- const directory = import_path.default.dirname(file.Key) + "/";
201
+ const strippedKey = stripMediaRoot(mediaRoot, file.Key);
202
+ const filename = import_path.default.basename(strippedKey);
203
+ const directory = import_path.default.dirname(strippedKey) + "/";
171
204
  return {
172
205
  id: file.Key,
173
206
  filename,
package/dist/index.d.ts CHANGED
@@ -1,14 +1,5 @@
1
1
  /**
2
- Copyright 2021 Forestry.io Holdings, Inc.
3
- Licensed under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License.
5
- You may obtain a copy of the License at
6
- http://www.apache.org/licenses/LICENSE-2.0
7
- Unless required by applicable law or agreed to in writing, software
8
- distributed under the License is distributed on an "AS IS" BASIS,
9
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
- See the License for the specific language governing permissions and
11
- limitations under the License.
2
+
12
3
  */
13
4
  export * from './dos-media-store';
14
5
  export * from './dos-tina-cloud-media-store';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-tinacms-dos",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "main": "dist/index.js",
5
5
  "files": [
6
6
  "dist"
@@ -21,13 +21,13 @@
21
21
  "multer": "1.4.5-lts.1"
22
22
  },
23
23
  "devDependencies": {
24
- "@tinacms/toolkit": "1.0.1",
25
- "@tinacms/scripts": "1.0.0",
24
+ "@tinacms/toolkit": "1.3.3",
25
+ "@tinacms/scripts": "1.0.2",
26
26
  "@types/crypto-js": "^3.1.47",
27
27
  "@types/js-cookie": "^2.2.6",
28
28
  "@types/node": "^13.13.1",
29
29
  "next": "12.2.4",
30
- "tinacms": "1.0.1",
30
+ "tinacms": "1.2.1",
31
31
  "typescript": "4.3.5"
32
32
  },
33
33
  "publishConfig": {