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 +8 -0
- package/README.md +3 -2
- package/dist/dos-media-store.d.ts +1 -10
- package/dist/dos-tina-cloud-media-store.d.ts +1 -10
- package/dist/errors.d.ts +1 -10
- package/dist/handlers.d.ts +2 -10
- package/dist/handlers.js +55 -22
- package/dist/index.d.ts +1 -10
- package/package.json +4 -4
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
package/dist/handlers.d.ts
CHANGED
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
|
|
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
|
-
|
|
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
|
|
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 }) =>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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(
|
|
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
|
|
170
|
-
const
|
|
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
|
-
|
|
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.
|
|
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.
|
|
25
|
-
"@tinacms/scripts": "1.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.
|
|
30
|
+
"tinacms": "1.2.1",
|
|
31
31
|
"typescript": "4.3.5"
|
|
32
32
|
},
|
|
33
33
|
"publishConfig": {
|