next-tinacms-cloudinary 3.2.2 → 3.3.0
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/CHANGELOG.md +16 -0
- package/dist/cloudinary-media-store.d.ts +23 -0
- package/dist/cloudinary-tina-cloud-media-store.d.ts +18 -0
- package/dist/errors.d.ts +19 -0
- package/dist/handlers.d.ts +4 -8
- package/dist/handlers.js +133 -78
- package/dist/index.d.ts +2 -34
- package/dist/index.es.js +131 -0
- package/dist/index.js +132 -129
- package/package.json +14 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# next-tinacms-cloudinary
|
|
2
2
|
|
|
3
|
+
## 3.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9d68b058f: Add support for multiple image upload in the Media Store.
|
|
8
|
+
|
|
9
|
+
## 3.2.5
|
|
10
|
+
|
|
11
|
+
## 3.2.4
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- 9b27192fe: Build packages with new scripting, which includes preliminary support for ES modules.
|
|
16
|
+
|
|
17
|
+
## 3.2.3
|
|
18
|
+
|
|
3
19
|
## 3.2.2
|
|
4
20
|
|
|
5
21
|
## 3.2.1
|
|
@@ -0,0 +1,23 @@
|
|
|
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.
|
|
12
|
+
*/
|
|
13
|
+
import { Media, MediaList, MediaListOptions, MediaStore, MediaUploadOptions } from '@tinacms/toolkit';
|
|
14
|
+
export declare class CloudinaryMediaStore implements MediaStore {
|
|
15
|
+
fetchFunction: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
16
|
+
accept: string;
|
|
17
|
+
persist(media: MediaUploadOptions[]): Promise<Media[]>;
|
|
18
|
+
delete(media: Media): Promise<void>;
|
|
19
|
+
list(options: MediaListOptions): Promise<MediaList>;
|
|
20
|
+
previewSrc: (publicId: string | Media) => string;
|
|
21
|
+
parse: (img: any) => any;
|
|
22
|
+
private buildQuery;
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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.
|
|
12
|
+
*/
|
|
13
|
+
import { CloudinaryMediaStore } from './cloudinary-media-store';
|
|
14
|
+
import { Client } from 'tinacms';
|
|
15
|
+
export declare class TinaCloudCloudinaryMediaStore extends CloudinaryMediaStore {
|
|
16
|
+
client: Client;
|
|
17
|
+
constructor(client: Client);
|
|
18
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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.
|
|
12
|
+
*/
|
|
13
|
+
import { MediaListError } from '@tinacms/toolkit';
|
|
14
|
+
export declare const E_DEFAULT: MediaListError;
|
|
15
|
+
export declare const E_UNAUTHORIZED: MediaListError;
|
|
16
|
+
export declare const E_CONFIG: MediaListError;
|
|
17
|
+
export declare const E_KEY_FAIL: MediaListError;
|
|
18
|
+
export declare const E_BAD_ROUTE: MediaListError;
|
|
19
|
+
export declare const interpretErrorMessage: (message: string) => MediaListError;
|
package/dist/handlers.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { NextApiRequest, NextApiResponse } from 'next';
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
Copyright 2021 Forestry.io Holdings, Inc.
|
|
5
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -12,18 +10,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
12
10
|
See the License for the specific language governing permissions and
|
|
13
11
|
limitations under the License.
|
|
14
12
|
*/
|
|
15
|
-
|
|
16
|
-
interface CloudinaryConfig {
|
|
13
|
+
import { NextApiRequest, NextApiResponse } from 'next';
|
|
14
|
+
export interface CloudinaryConfig {
|
|
17
15
|
cloud_name: string;
|
|
18
16
|
api_key: string;
|
|
19
17
|
api_secret: string;
|
|
20
18
|
authorized: (req: NextApiRequest, res: NextApiResponse) => Promise<boolean>;
|
|
21
19
|
}
|
|
22
|
-
declare const mediaHandlerConfig: {
|
|
20
|
+
export declare const mediaHandlerConfig: {
|
|
23
21
|
api: {
|
|
24
22
|
bodyParser: boolean;
|
|
25
23
|
};
|
|
26
24
|
};
|
|
27
|
-
declare const createMediaHandler: (config: CloudinaryConfig) => (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
|
28
|
-
|
|
29
|
-
export { CloudinaryConfig, createMediaHandler, mediaHandlerConfig };
|
|
25
|
+
export declare const createMediaHandler: (config: CloudinaryConfig) => (req: NextApiRequest, res: NextApiResponse) => Promise<void>;
|
package/dist/handlers.js
CHANGED
|
@@ -1,17 +1,65 @@
|
|
|
1
|
-
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
__markAsModule(target);
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __reExport = (target, module2, desc) => {
|
|
14
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(module2))
|
|
16
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
17
|
+
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
var __toModule = (module2) => {
|
|
22
|
+
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
23
|
+
};
|
|
24
|
+
var __async = (__this, __arguments, generator) => {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
var fulfilled = (value) => {
|
|
27
|
+
try {
|
|
28
|
+
step(generator.next(value));
|
|
29
|
+
} catch (e) {
|
|
30
|
+
reject(e);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
var rejected = (value) => {
|
|
34
|
+
try {
|
|
35
|
+
step(generator.throw(value));
|
|
36
|
+
} catch (e) {
|
|
37
|
+
reject(e);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
41
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// ../../next-tinacms-cloudinary/src/handlers.ts
|
|
46
|
+
__export(exports, {
|
|
47
|
+
createMediaHandler: () => createMediaHandler,
|
|
48
|
+
mediaHandlerConfig: () => mediaHandlerConfig
|
|
49
|
+
});
|
|
50
|
+
var import_cloudinary = __toModule(require("cloudinary"));
|
|
51
|
+
var import_path = __toModule(require("path"));
|
|
52
|
+
var import_multer = __toModule(require("multer"));
|
|
53
|
+
var import_util = __toModule(require("util"));
|
|
6
54
|
var mediaHandlerConfig = {
|
|
7
55
|
api: {
|
|
8
56
|
bodyParser: false
|
|
9
57
|
}
|
|
10
58
|
};
|
|
11
59
|
var createMediaHandler = (config) => {
|
|
12
|
-
|
|
13
|
-
return
|
|
14
|
-
const isAuthorized =
|
|
60
|
+
import_cloudinary.v2.config(Object.assign({ secure: true }, config));
|
|
61
|
+
return (req, res) => __async(void 0, null, function* () {
|
|
62
|
+
const isAuthorized = yield config.authorized(req, res);
|
|
15
63
|
if (!isAuthorized) {
|
|
16
64
|
res.status(401).json({ message: "sorry this user is unauthorized" });
|
|
17
65
|
return;
|
|
@@ -26,65 +74,69 @@ var createMediaHandler = (config) => {
|
|
|
26
74
|
default:
|
|
27
75
|
res.end(404);
|
|
28
76
|
}
|
|
29
|
-
};
|
|
77
|
+
});
|
|
30
78
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
79
|
+
function uploadMedia(req, res) {
|
|
80
|
+
return __async(this, null, function* () {
|
|
81
|
+
const upload = (0, import_util.promisify)((0, import_multer.default)({
|
|
82
|
+
storage: import_multer.default.diskStorage({
|
|
83
|
+
directory: (req2, file, cb) => {
|
|
84
|
+
cb(null, "/tmp");
|
|
85
|
+
},
|
|
86
|
+
filename: (req2, file, cb) => {
|
|
87
|
+
cb(null, file.originalname);
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
}).single("file"));
|
|
91
|
+
yield upload(req, res);
|
|
92
|
+
const { directory } = req.body;
|
|
93
|
+
const result = yield import_cloudinary.v2.uploader.upload(req.file.path, {
|
|
94
|
+
folder: directory.replace(/^\//, ""),
|
|
95
|
+
use_filename: true,
|
|
96
|
+
overwrite: false
|
|
97
|
+
});
|
|
98
|
+
res.json(result);
|
|
48
99
|
});
|
|
49
|
-
res.json(result);
|
|
50
100
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let { folders } = await _cloudinary.v2.api.folders(directory);
|
|
70
|
-
folders = folders.map(function(folder) {
|
|
71
|
-
"empty-repo/004";
|
|
72
|
-
return {
|
|
73
|
-
id: folder.path,
|
|
74
|
-
type: "dir",
|
|
75
|
-
filename: _path2.default.basename(folder.path),
|
|
76
|
-
directory: _path2.default.dirname(folder.path)
|
|
101
|
+
function listMedia(req, res) {
|
|
102
|
+
return __async(this, null, function* () {
|
|
103
|
+
try {
|
|
104
|
+
const {
|
|
105
|
+
directory = '""',
|
|
106
|
+
limit = 500,
|
|
107
|
+
offset
|
|
108
|
+
} = req.query;
|
|
109
|
+
const useRootDirectory = !directory || directory === "/" || directory === '""';
|
|
110
|
+
const query = useRootDirectory ? 'folder=""' : `folder=${directory}`;
|
|
111
|
+
const response = yield import_cloudinary.v2.search.expression(query).max_results(limit).next_cursor(offset).execute();
|
|
112
|
+
const files = response.resources.map(cloudinaryToTina);
|
|
113
|
+
import_cloudinary.v2.api.folders = (directory2 = '""') => {
|
|
114
|
+
if (useRootDirectory) {
|
|
115
|
+
return import_cloudinary.v2.api.root_folders();
|
|
116
|
+
} else {
|
|
117
|
+
return import_cloudinary.v2.api.sub_folders(directory2);
|
|
118
|
+
}
|
|
77
119
|
};
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
120
|
+
let { folders } = yield import_cloudinary.v2.api.folders(directory);
|
|
121
|
+
folders = folders.map(function(folder) {
|
|
122
|
+
"empty-repo/004";
|
|
123
|
+
return {
|
|
124
|
+
id: folder.path,
|
|
125
|
+
type: "dir",
|
|
126
|
+
filename: import_path.default.basename(folder.path),
|
|
127
|
+
directory: import_path.default.dirname(folder.path)
|
|
128
|
+
};
|
|
129
|
+
});
|
|
130
|
+
res.json({
|
|
131
|
+
items: [...folders, ...files],
|
|
132
|
+
offset: response.next_cursor
|
|
133
|
+
});
|
|
134
|
+
} catch (e) {
|
|
135
|
+
res.status(500);
|
|
136
|
+
const message = findErrorMessage(e);
|
|
137
|
+
res.json({ e: message });
|
|
138
|
+
}
|
|
139
|
+
});
|
|
88
140
|
}
|
|
89
141
|
var findErrorMessage = (e) => {
|
|
90
142
|
if (typeof e == "string")
|
|
@@ -95,21 +147,23 @@ var findErrorMessage = (e) => {
|
|
|
95
147
|
return e.error.message;
|
|
96
148
|
return "an error occurred";
|
|
97
149
|
};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
150
|
+
function deleteAsset(req, res) {
|
|
151
|
+
return __async(this, null, function* () {
|
|
152
|
+
const { media } = req.query;
|
|
153
|
+
const [_media, public_id] = media;
|
|
154
|
+
import_cloudinary.v2.uploader.destroy(public_id, {}, (err) => {
|
|
155
|
+
if (err)
|
|
156
|
+
res.status(500);
|
|
157
|
+
res.json({
|
|
158
|
+
err,
|
|
159
|
+
public_id
|
|
160
|
+
});
|
|
107
161
|
});
|
|
108
162
|
});
|
|
109
163
|
}
|
|
110
164
|
function cloudinaryToTina(file) {
|
|
111
|
-
const filename =
|
|
112
|
-
const directory =
|
|
165
|
+
const filename = import_path.default.basename(file.public_id);
|
|
166
|
+
const directory = import_path.default.dirname(file.public_id);
|
|
113
167
|
return {
|
|
114
168
|
id: file.public_id,
|
|
115
169
|
filename,
|
|
@@ -118,7 +172,8 @@ function cloudinaryToTina(file) {
|
|
|
118
172
|
type: "file"
|
|
119
173
|
};
|
|
120
174
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
175
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
176
|
+
0 && (module.exports = {
|
|
177
|
+
createMediaHandler,
|
|
178
|
+
mediaHandlerConfig
|
|
179
|
+
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { MediaStore, MediaUploadOptions, Media, MediaListOptions, MediaList } from '@tinacms/toolkit';
|
|
2
|
-
import { Client } from 'tinacms';
|
|
3
|
-
|
|
4
1
|
/**
|
|
5
2
|
Copyright 2021 Forestry.io Holdings, Inc.
|
|
6
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -13,34 +10,5 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
13
10
|
See the License for the specific language governing permissions and
|
|
14
11
|
limitations under the License.
|
|
15
12
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
fetchFunction: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
|
|
19
|
-
accept: string;
|
|
20
|
-
persist(media: MediaUploadOptions[]): Promise<Media[]>;
|
|
21
|
-
delete(media: Media): Promise<void>;
|
|
22
|
-
list(options: MediaListOptions): Promise<MediaList>;
|
|
23
|
-
previewSrc: (publicId: string | Media) => string;
|
|
24
|
-
parse: (img: any) => any;
|
|
25
|
-
private buildQuery;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
Copyright 2021 Forestry.io Holdings, Inc.
|
|
30
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
31
|
-
you may not use this file except in compliance with the License.
|
|
32
|
-
You may obtain a copy of the License at
|
|
33
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
34
|
-
Unless required by applicable law or agreed to in writing, software
|
|
35
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
36
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
37
|
-
See the License for the specific language governing permissions and
|
|
38
|
-
limitations under the License.
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
declare class TinaCloudCloudinaryMediaStore extends CloudinaryMediaStore {
|
|
42
|
-
client: Client;
|
|
43
|
-
constructor(client: Client);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export { CloudinaryMediaStore, TinaCloudCloudinaryMediaStore };
|
|
13
|
+
export * from './cloudinary-media-store';
|
|
14
|
+
export * from './cloudinary-tina-cloud-media-store';
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { MediaListError } from "@tinacms/toolkit";
|
|
2
|
+
const E_DEFAULT = new MediaListError({
|
|
3
|
+
title: "An Error Occurred",
|
|
4
|
+
message: "Something went wrong fetching your media from Cloudinary.",
|
|
5
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary"
|
|
6
|
+
});
|
|
7
|
+
const E_UNAUTHORIZED = new MediaListError({
|
|
8
|
+
title: "Unauthorized",
|
|
9
|
+
message: "You don't have access to this resource.",
|
|
10
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary"
|
|
11
|
+
});
|
|
12
|
+
const E_CONFIG = new MediaListError({
|
|
13
|
+
title: "Missing Credentials",
|
|
14
|
+
message: "Unable to connect to Cloudinary because one or more environment variables are missing.",
|
|
15
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary/#connect-with-cloudinary"
|
|
16
|
+
});
|
|
17
|
+
const E_KEY_FAIL = new MediaListError({
|
|
18
|
+
title: "Bad Credentials",
|
|
19
|
+
message: "Unable to connect to Cloudinary because one or more environment variables are misconfigured.",
|
|
20
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary/#connect-with-cloudinary"
|
|
21
|
+
});
|
|
22
|
+
const E_BAD_ROUTE = new MediaListError({
|
|
23
|
+
title: "Bad Route",
|
|
24
|
+
message: "The Cloudinary API route is missing or misconfigured.",
|
|
25
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary/#set-up-api-routes"
|
|
26
|
+
});
|
|
27
|
+
const interpretErrorMessage = (message) => {
|
|
28
|
+
switch (message) {
|
|
29
|
+
case "Must supply cloud_name":
|
|
30
|
+
case "Must supply api_key":
|
|
31
|
+
case "Must supply api_secret":
|
|
32
|
+
return E_CONFIG;
|
|
33
|
+
case "unknown api_key":
|
|
34
|
+
return E_KEY_FAIL;
|
|
35
|
+
default:
|
|
36
|
+
return E_DEFAULT;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
class CloudinaryMediaStore {
|
|
40
|
+
constructor() {
|
|
41
|
+
this.fetchFunction = (input, init) => {
|
|
42
|
+
return fetch(input, init);
|
|
43
|
+
};
|
|
44
|
+
this.accept = "text/*, application/*, image/*";
|
|
45
|
+
this.previewSrc = (publicId) => {
|
|
46
|
+
if (typeof publicId === "string")
|
|
47
|
+
return publicId;
|
|
48
|
+
return publicId.previewSrc;
|
|
49
|
+
};
|
|
50
|
+
this.parse = (img) => {
|
|
51
|
+
return img.previewSrc;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async persist(media) {
|
|
55
|
+
let newFiles = [];
|
|
56
|
+
for (const item of media) {
|
|
57
|
+
const { file, directory } = item;
|
|
58
|
+
const formData = new FormData();
|
|
59
|
+
formData.append("file", file);
|
|
60
|
+
formData.append("directory", directory);
|
|
61
|
+
formData.append("filename", file.name);
|
|
62
|
+
const res = await this.fetchFunction(`/api/cloudinary/media`, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
body: formData
|
|
65
|
+
});
|
|
66
|
+
if (res.status != 200) {
|
|
67
|
+
const responseData = await res.json();
|
|
68
|
+
throw new Error(responseData.message);
|
|
69
|
+
}
|
|
70
|
+
const fileRes = await res.json();
|
|
71
|
+
await new Promise((resolve) => {
|
|
72
|
+
setTimeout(resolve, 2e3);
|
|
73
|
+
});
|
|
74
|
+
const parsedRes = {
|
|
75
|
+
type: "file",
|
|
76
|
+
id: fileRes.public_id,
|
|
77
|
+
filename: fileRes.original_filename,
|
|
78
|
+
directory: "/",
|
|
79
|
+
previewSrc: fileRes.url
|
|
80
|
+
};
|
|
81
|
+
newFiles.push(parsedRes);
|
|
82
|
+
}
|
|
83
|
+
return newFiles;
|
|
84
|
+
}
|
|
85
|
+
async delete(media) {
|
|
86
|
+
await this.fetchFunction(`/api/cloudinary/media/${encodeURIComponent(media.id)}`, {
|
|
87
|
+
method: "DELETE"
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async list(options) {
|
|
91
|
+
const query = this.buildQuery(options);
|
|
92
|
+
const response = await this.fetchFunction("/api/cloudinary/media" + query);
|
|
93
|
+
if (response.status == 401) {
|
|
94
|
+
throw E_UNAUTHORIZED;
|
|
95
|
+
}
|
|
96
|
+
if (response.status == 404) {
|
|
97
|
+
throw E_BAD_ROUTE;
|
|
98
|
+
}
|
|
99
|
+
if (response.status >= 500) {
|
|
100
|
+
const { e } = await response.json();
|
|
101
|
+
const error = interpretErrorMessage(e);
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
const { items, offset } = await response.json();
|
|
105
|
+
return {
|
|
106
|
+
items: items.map((item) => item),
|
|
107
|
+
nextOffset: offset
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
buildQuery(options) {
|
|
111
|
+
const params = Object.keys(options).filter((key) => options[key] !== "" && options[key] !== void 0).map((key) => `${key}=${options[key]}`).join("&");
|
|
112
|
+
return `?${params}`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
class TinaCloudCloudinaryMediaStore extends CloudinaryMediaStore {
|
|
116
|
+
constructor(client) {
|
|
117
|
+
super();
|
|
118
|
+
this.client = client;
|
|
119
|
+
this.fetchFunction = async (input, init) => {
|
|
120
|
+
try {
|
|
121
|
+
const url = input.toString();
|
|
122
|
+
const query = `${url.includes("?") ? "&" : "?"}clientID=${client.clientId}`;
|
|
123
|
+
const res = client.fetchWithToken(url + query, init);
|
|
124
|
+
return res;
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error(error);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export { CloudinaryMediaStore, TinaCloudCloudinaryMediaStore };
|
package/dist/index.js
CHANGED
|
@@ -1,135 +1,138 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// src/cloudinary-media-store.ts
|
|
42
|
-
var CloudinaryMediaStore = class {
|
|
43
|
-
constructor() {
|
|
44
|
-
this.fetchFunction = (input, init) => {
|
|
45
|
-
return fetch(input, init);
|
|
46
|
-
};
|
|
47
|
-
this.accept = "text/*, application/*, image/*";
|
|
48
|
-
this.previewSrc = (publicId) => {
|
|
49
|
-
if (typeof publicId === "string")
|
|
50
|
-
return publicId;
|
|
51
|
-
return publicId.previewSrc;
|
|
52
|
-
};
|
|
53
|
-
this.parse = (img) => {
|
|
54
|
-
return img.previewSrc;
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
async persist(media) {
|
|
58
|
-
const { file, directory } = media[0];
|
|
59
|
-
const formData = new FormData();
|
|
60
|
-
formData.append("file", file);
|
|
61
|
-
formData.append("directory", directory);
|
|
62
|
-
formData.append("filename", file.name);
|
|
63
|
-
const res = await this.fetchFunction(`/api/cloudinary/media`, {
|
|
64
|
-
method: "POST",
|
|
65
|
-
body: formData
|
|
66
|
-
});
|
|
67
|
-
if (res.status != 200) {
|
|
68
|
-
const responseData = await res.json();
|
|
69
|
-
throw new Error(responseData.message);
|
|
1
|
+
(function(global, factory) {
|
|
2
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@tinacms/toolkit")) : typeof define === "function" && define.amd ? define(["exports", "@tinacms/toolkit"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["next-tinacms-cloudinary"] = {}, global.NOOP));
|
|
3
|
+
})(this, function(exports2, toolkit) {
|
|
4
|
+
"use strict";
|
|
5
|
+
const E_DEFAULT = new toolkit.MediaListError({
|
|
6
|
+
title: "An Error Occurred",
|
|
7
|
+
message: "Something went wrong fetching your media from Cloudinary.",
|
|
8
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary"
|
|
9
|
+
});
|
|
10
|
+
const E_UNAUTHORIZED = new toolkit.MediaListError({
|
|
11
|
+
title: "Unauthorized",
|
|
12
|
+
message: "You don't have access to this resource.",
|
|
13
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary"
|
|
14
|
+
});
|
|
15
|
+
const E_CONFIG = new toolkit.MediaListError({
|
|
16
|
+
title: "Missing Credentials",
|
|
17
|
+
message: "Unable to connect to Cloudinary because one or more environment variables are missing.",
|
|
18
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary/#connect-with-cloudinary"
|
|
19
|
+
});
|
|
20
|
+
const E_KEY_FAIL = new toolkit.MediaListError({
|
|
21
|
+
title: "Bad Credentials",
|
|
22
|
+
message: "Unable to connect to Cloudinary because one or more environment variables are misconfigured.",
|
|
23
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary/#connect-with-cloudinary"
|
|
24
|
+
});
|
|
25
|
+
const E_BAD_ROUTE = new toolkit.MediaListError({
|
|
26
|
+
title: "Bad Route",
|
|
27
|
+
message: "The Cloudinary API route is missing or misconfigured.",
|
|
28
|
+
docsLink: "https://tina.io/packages/next-tinacms-cloudinary/#set-up-api-routes"
|
|
29
|
+
});
|
|
30
|
+
const interpretErrorMessage = (message) => {
|
|
31
|
+
switch (message) {
|
|
32
|
+
case "Must supply cloud_name":
|
|
33
|
+
case "Must supply api_key":
|
|
34
|
+
case "Must supply api_secret":
|
|
35
|
+
return E_CONFIG;
|
|
36
|
+
case "unknown api_key":
|
|
37
|
+
return E_KEY_FAIL;
|
|
38
|
+
default:
|
|
39
|
+
return E_DEFAULT;
|
|
70
40
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
method: "DELETE"
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
async list(options) {
|
|
90
|
-
const query = this.buildQuery(options);
|
|
91
|
-
const response = await this.fetchFunction("/api/cloudinary/media" + query);
|
|
92
|
-
if (response.status == 401) {
|
|
93
|
-
throw E_UNAUTHORIZED;
|
|
41
|
+
};
|
|
42
|
+
class CloudinaryMediaStore {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.fetchFunction = (input, init) => {
|
|
45
|
+
return fetch(input, init);
|
|
46
|
+
};
|
|
47
|
+
this.accept = "text/*, application/*, image/*";
|
|
48
|
+
this.previewSrc = (publicId) => {
|
|
49
|
+
if (typeof publicId === "string")
|
|
50
|
+
return publicId;
|
|
51
|
+
return publicId.previewSrc;
|
|
52
|
+
};
|
|
53
|
+
this.parse = (img) => {
|
|
54
|
+
return img.previewSrc;
|
|
55
|
+
};
|
|
94
56
|
}
|
|
95
|
-
|
|
96
|
-
|
|
57
|
+
async persist(media) {
|
|
58
|
+
let newFiles = [];
|
|
59
|
+
for (const item of media) {
|
|
60
|
+
const { file, directory } = item;
|
|
61
|
+
const formData = new FormData();
|
|
62
|
+
formData.append("file", file);
|
|
63
|
+
formData.append("directory", directory);
|
|
64
|
+
formData.append("filename", file.name);
|
|
65
|
+
const res = await this.fetchFunction(`/api/cloudinary/media`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
body: formData
|
|
68
|
+
});
|
|
69
|
+
if (res.status != 200) {
|
|
70
|
+
const responseData = await res.json();
|
|
71
|
+
throw new Error(responseData.message);
|
|
72
|
+
}
|
|
73
|
+
const fileRes = await res.json();
|
|
74
|
+
await new Promise((resolve) => {
|
|
75
|
+
setTimeout(resolve, 2e3);
|
|
76
|
+
});
|
|
77
|
+
const parsedRes = {
|
|
78
|
+
type: "file",
|
|
79
|
+
id: fileRes.public_id,
|
|
80
|
+
filename: fileRes.original_filename,
|
|
81
|
+
directory: "/",
|
|
82
|
+
previewSrc: fileRes.url
|
|
83
|
+
};
|
|
84
|
+
newFiles.push(parsedRes);
|
|
85
|
+
}
|
|
86
|
+
return newFiles;
|
|
97
87
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
async delete(media) {
|
|
89
|
+
await this.fetchFunction(`/api/cloudinary/media/${encodeURIComponent(media.id)}`, {
|
|
90
|
+
method: "DELETE"
|
|
91
|
+
});
|
|
102
92
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
return `?${params}`;
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// src/cloudinary-tina-cloud-media-store.ts
|
|
116
|
-
var TinaCloudCloudinaryMediaStore = class extends CloudinaryMediaStore {
|
|
117
|
-
constructor(client) {
|
|
118
|
-
super();
|
|
119
|
-
this.client = client;
|
|
120
|
-
this.fetchFunction = async (input, init) => {
|
|
121
|
-
try {
|
|
122
|
-
const url = input.toString();
|
|
123
|
-
const query = `${url.includes("?") ? "&" : "?"}clientID=${client.clientId}`;
|
|
124
|
-
const res = client.fetchWithToken(url + query, init);
|
|
125
|
-
return res;
|
|
126
|
-
} catch (error) {
|
|
127
|
-
console.error(error);
|
|
93
|
+
async list(options) {
|
|
94
|
+
const query = this.buildQuery(options);
|
|
95
|
+
const response = await this.fetchFunction("/api/cloudinary/media" + query);
|
|
96
|
+
if (response.status == 401) {
|
|
97
|
+
throw E_UNAUTHORIZED;
|
|
98
|
+
}
|
|
99
|
+
if (response.status == 404) {
|
|
100
|
+
throw E_BAD_ROUTE;
|
|
128
101
|
}
|
|
129
|
-
|
|
102
|
+
if (response.status >= 500) {
|
|
103
|
+
const { e } = await response.json();
|
|
104
|
+
const error = interpretErrorMessage(e);
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
const { items, offset } = await response.json();
|
|
108
|
+
return {
|
|
109
|
+
items: items.map((item) => item),
|
|
110
|
+
nextOffset: offset
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
buildQuery(options) {
|
|
114
|
+
const params = Object.keys(options).filter((key) => options[key] !== "" && options[key] !== void 0).map((key) => `${key}=${options[key]}`).join("&");
|
|
115
|
+
return `?${params}`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
class TinaCloudCloudinaryMediaStore extends CloudinaryMediaStore {
|
|
119
|
+
constructor(client) {
|
|
120
|
+
super();
|
|
121
|
+
this.client = client;
|
|
122
|
+
this.fetchFunction = async (input, init) => {
|
|
123
|
+
try {
|
|
124
|
+
const url = input.toString();
|
|
125
|
+
const query = `${url.includes("?") ? "&" : "?"}clientID=${client.clientId}`;
|
|
126
|
+
const res = client.fetchWithToken(url + query, init);
|
|
127
|
+
return res;
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.error(error);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
130
133
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
exports2.CloudinaryMediaStore = CloudinaryMediaStore;
|
|
135
|
+
exports2.TinaCloudCloudinaryMediaStore = TinaCloudCloudinaryMediaStore;
|
|
136
|
+
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
137
|
+
exports2[Symbol.toStringTag] = "Module";
|
|
138
|
+
});
|
package/package.json
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-tinacms-cloudinary",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"files": [
|
|
6
|
-
"dist
|
|
6
|
+
"dist"
|
|
7
7
|
],
|
|
8
8
|
"typings": "dist/index.d.ts",
|
|
9
9
|
"license": "Apache-2.0",
|
|
10
|
+
"buildConfig": {
|
|
11
|
+
"entryPoints": [
|
|
12
|
+
"src/index.ts",
|
|
13
|
+
{
|
|
14
|
+
"name": "src/handlers.ts",
|
|
15
|
+
"target": "node"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
10
19
|
"scripts": {
|
|
11
20
|
"build": "yarn tsup src/index.ts src/handlers.ts --format cjs --dts",
|
|
21
|
+
"types": "yarn tsc",
|
|
12
22
|
"watch": "yarn tsup src/index.ts src/handlers.ts --watch --format cjs --dts"
|
|
13
23
|
},
|
|
14
24
|
"dependencies": {
|
|
@@ -16,7 +26,7 @@
|
|
|
16
26
|
"multer": "^1.4.2"
|
|
17
27
|
},
|
|
18
28
|
"devDependencies": {
|
|
19
|
-
"@tinacms/toolkit": "0.
|
|
29
|
+
"@tinacms/toolkit": "0.54.0",
|
|
20
30
|
"@types/crypto-js": "^3.1.47",
|
|
21
31
|
"@types/js-cookie": "^2.2.6",
|
|
22
32
|
"@types/node": "^13.13.1",
|
|
@@ -26,7 +36,7 @@
|
|
|
26
36
|
"react": "16.13.1",
|
|
27
37
|
"react-dom": "16.13.1",
|
|
28
38
|
"styled-components": "^5.2.0",
|
|
29
|
-
"tinacms": "0.
|
|
39
|
+
"tinacms": "0.56.0",
|
|
30
40
|
"tsup": "4.12.5",
|
|
31
41
|
"typescript": "^4.3.5"
|
|
32
42
|
},
|