next-tinacms-cloudinary 13.0.7 → 13.0.8
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/dist/handlers.js +2 -3
- package/dist/index.js +0 -1
- package/dist/index.mjs +0 -1
- package/package.json +4 -4
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/handlers.js
CHANGED
|
@@ -91,7 +91,6 @@ async function uploadMedia(req, res) {
|
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
async function listMedia(req, res, opts) {
|
|
94
|
-
var _a;
|
|
95
94
|
try {
|
|
96
95
|
const mediaListOptions = {
|
|
97
96
|
directory: req.query.directory || '""',
|
|
@@ -122,14 +121,14 @@ async function listMedia(req, res, opts) {
|
|
|
122
121
|
try {
|
|
123
122
|
folderRes = await import_cloudinary.v2.api.folders(mediaListOptions.directory);
|
|
124
123
|
} catch (e) {
|
|
125
|
-
if (
|
|
124
|
+
if (e.error?.message.startsWith("Can't find folder with path")) {
|
|
126
125
|
} else {
|
|
127
126
|
console.error("Error getting folders");
|
|
128
127
|
console.error(e);
|
|
129
128
|
throw e;
|
|
130
129
|
}
|
|
131
130
|
}
|
|
132
|
-
if (folderRes
|
|
131
|
+
if (folderRes?.folders) {
|
|
133
132
|
folders = folderRes.folders.map(function(folder) {
|
|
134
133
|
"empty-repo/004";
|
|
135
134
|
return {
|
package/dist/index.js
CHANGED
package/dist/index.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-tinacms-cloudinary",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.8",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"files": [
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"react": "^18.3.1",
|
|
30
30
|
"react-dom": "^18.3.1",
|
|
31
31
|
"typescript": "^5.7.3",
|
|
32
|
-
"@tinacms/scripts": "1.3.
|
|
33
|
-
"tinacms": "2.7.
|
|
32
|
+
"@tinacms/scripts": "1.3.5",
|
|
33
|
+
"tinacms": "2.7.8"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"tinacms": "2.7.
|
|
36
|
+
"tinacms": "2.7.8"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"registry": "https://registry.npmjs.org"
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/errors.ts","../src/cloudinary-media-store.ts","../src/cloudinary-tina-cloud-media-store.ts"],"sourcesContent":["/**\n\n*/\n\ninterface MediaListErrorConfig {\n title: string;\n message: string;\n docsLink: string;\n}\n\nclass MediaListError extends Error {\n public ERR_TYPE = 'MediaListError';\n public title: string;\n public docsLink: string;\n\n constructor(config: MediaListErrorConfig) {\n super(config.message);\n this.title = config.title;\n this.docsLink = config.docsLink;\n }\n}\n\nexport const E_DEFAULT = new MediaListError({\n title: 'An Error Occurred',\n message: 'Something went wrong fetching your media from Cloudinary.',\n docsLink: 'https://tina.io/docs/reference/media/external/cloudinary',\n});\n\nexport const E_UNAUTHORIZED = new MediaListError({\n title: 'Unauthorized',\n message: \"You don't have access to this resource.\",\n docsLink:\n 'https://tina.io/docs/reference/media/external/cloudinary/#set-up-api-routes-nextjs-example',\n});\n\nexport const E_CONFIG = new MediaListError({\n title: 'Missing Credentials',\n message:\n 'Unable to connect to Cloudinary because one or more environment variables are missing.',\n docsLink: 'https://tina.io/docs/media-cloudinary/',\n});\n\nexport const E_KEY_FAIL = new MediaListError({\n title: 'Bad Credentials',\n message:\n 'Unable to connect to Cloudinary because one or more environment variables are misconfigured.',\n docsLink: 'https://tina.io/docs/media-cloudinary/',\n});\n\nexport const E_BAD_ROUTE = new MediaListError({\n title: 'Bad Route',\n message: 'The Cloudinary API route is missing or misconfigured.',\n docsLink:\n 'https://tina.io/docs/reference/media/external/cloudinary/#set-up-api-routes-nextjs-example',\n});\n\nexport const interpretErrorMessage = (message: string) => {\n switch (message) {\n case 'Must supply cloud_name':\n case 'Must supply api_key':\n case 'Must supply api_secret':\n return E_CONFIG;\n case 'unknown api_key':\n return E_KEY_FAIL;\n default:\n return E_DEFAULT;\n }\n};\n","import type {\n Media,\n MediaList,\n MediaListOptions,\n MediaStore,\n MediaUploadOptions,\n} from 'tinacms';\nimport { DEFAULT_MEDIA_UPLOAD_TYPES } from 'tinacms';\nimport { E_UNAUTHORIZED, E_BAD_ROUTE, interpretErrorMessage } from './errors';\n\nexport type CloudinaryMediaStoreOptions = {\n baseUrl?: string;\n};\n\nexport class CloudinaryMediaStore implements MediaStore {\n baseUrl: string;\n constructor(options?: CloudinaryMediaStoreOptions) {\n this.baseUrl = options?.baseUrl || '/api/cloudinary/media';\n }\n fetchFunction = (input: RequestInfo, init?: RequestInit) =>\n fetch(input, init);\n\n accept = DEFAULT_MEDIA_UPLOAD_TYPES;\n\n async persist(media: MediaUploadOptions[]): Promise<Media[]> {\n const newFiles: Media[] = [];\n\n for (const item of media) {\n const { file, directory } = item;\n const formData = new FormData();\n formData.append('file', file);\n formData.append('directory', directory);\n formData.append('filename', file.name);\n\n const res = await this.fetchFunction(this.baseUrl, {\n method: 'POST',\n body: formData,\n });\n\n if (res.status != 200) {\n const responseData = await res.json();\n throw new Error(responseData.message);\n }\n const fileRes = await res.json();\n /**\n * Images uploaded to Cloudinary aren't instantly available via the API;\n * waiting a couple seconds here seems to ensure they show up in the next fetch.\n */\n await new Promise((resolve) => {\n setTimeout(resolve, 2000);\n });\n /**\n * Format the response from Cloudinary to match Media interface\n * Valid Cloudinary `resource_type` values: `image`, `video`, `raw` and `auto`\n * uploading a directory is not supported as such, type is defaulted to `file`\n * https://cloudinary.com/documentation/upload_images#uploading_with_a_direct_call_to_the_rest_api\n */\n const parsedRes: Media = {\n type: 'file',\n id: fileRes.public_id,\n filename: fileRes.original_filename,\n directory: '/',\n thumbnails: {\n '75x75': fileRes.secure_url,\n '400x400': fileRes.secure_url,\n '1000x1000': fileRes.secure_url,\n },\n src: fileRes.secure_url,\n };\n\n newFiles.push(parsedRes);\n }\n return newFiles;\n }\n async delete(media: Media) {\n await this.fetchFunction(\n `${this.baseUrl}/${encodeURIComponent(media.id)}`,\n {\n method: 'DELETE',\n }\n );\n }\n async list(options: MediaListOptions): Promise<MediaList> {\n const query = this.buildQuery(options);\n const response = await this.fetchFunction(this.baseUrl + query);\n\n if (response.status == 401) {\n throw E_UNAUTHORIZED;\n }\n if (response.status == 404) {\n throw E_BAD_ROUTE;\n }\n if (response.status >= 500) {\n const { e } = await response.json();\n const error = interpretErrorMessage(e);\n throw error;\n }\n const { items, offset } = await response.json();\n return {\n items: items.map((item) => item),\n nextOffset: offset,\n };\n }\n\n parse = (img) => {\n return img.src;\n };\n\n buildQuery(options: MediaListOptions) {\n const params = Object.keys(options)\n .filter((key) => options[key] !== '' && options[key] !== undefined)\n .map((key) => `${key}=${options[key]}`)\n .join('&');\n\n return `?${params}`;\n }\n}\n","import type { Client } from 'tinacms';\nimport type { CloudinaryMediaStoreOptions } from './cloudinary-media-store';\nimport { CloudinaryMediaStore } from './cloudinary-media-store';\n\nexport const createTinaCloudCloudinaryMediaStore = (\n options: CloudinaryMediaStoreOptions = { baseUrl: '/api/cloudinary/media' }\n) =>\n class TinaCloudCloudinaryMediaStore extends CloudinaryMediaStore {\n client: Client;\n constructor(client: Client) {\n super(options);\n this.client = client;\n this.fetchFunction = async (input: RequestInfo, init?: RequestInit) => {\n try {\n const url = input.toString();\n const query = `${url.includes('?') ? '&' : '?'}clientID=${\n client.clientId\n }`;\n\n const res = client.authProvider.fetchWithToken(url + query, init);\n return res;\n } catch (error) {\n console.error(error);\n }\n };\n }\n };\n\nexport const TinaCloudCloudinaryMediaStore =\n createTinaCloudCloudinaryMediaStore();\n"],"names":["DEFAULT_MEDIA_UPLOAD_TYPES"],"mappings":"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"}
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/errors.ts","../src/cloudinary-media-store.ts","../src/cloudinary-tina-cloud-media-store.ts"],"sourcesContent":["/**\n\n*/\n\ninterface MediaListErrorConfig {\n title: string;\n message: string;\n docsLink: string;\n}\n\nclass MediaListError extends Error {\n public ERR_TYPE = 'MediaListError';\n public title: string;\n public docsLink: string;\n\n constructor(config: MediaListErrorConfig) {\n super(config.message);\n this.title = config.title;\n this.docsLink = config.docsLink;\n }\n}\n\nexport const E_DEFAULT = new MediaListError({\n title: 'An Error Occurred',\n message: 'Something went wrong fetching your media from Cloudinary.',\n docsLink: 'https://tina.io/docs/reference/media/external/cloudinary',\n});\n\nexport const E_UNAUTHORIZED = new MediaListError({\n title: 'Unauthorized',\n message: \"You don't have access to this resource.\",\n docsLink:\n 'https://tina.io/docs/reference/media/external/cloudinary/#set-up-api-routes-nextjs-example',\n});\n\nexport const E_CONFIG = new MediaListError({\n title: 'Missing Credentials',\n message:\n 'Unable to connect to Cloudinary because one or more environment variables are missing.',\n docsLink: 'https://tina.io/docs/media-cloudinary/',\n});\n\nexport const E_KEY_FAIL = new MediaListError({\n title: 'Bad Credentials',\n message:\n 'Unable to connect to Cloudinary because one or more environment variables are misconfigured.',\n docsLink: 'https://tina.io/docs/media-cloudinary/',\n});\n\nexport const E_BAD_ROUTE = new MediaListError({\n title: 'Bad Route',\n message: 'The Cloudinary API route is missing or misconfigured.',\n docsLink:\n 'https://tina.io/docs/reference/media/external/cloudinary/#set-up-api-routes-nextjs-example',\n});\n\nexport const interpretErrorMessage = (message: string) => {\n switch (message) {\n case 'Must supply cloud_name':\n case 'Must supply api_key':\n case 'Must supply api_secret':\n return E_CONFIG;\n case 'unknown api_key':\n return E_KEY_FAIL;\n default:\n return E_DEFAULT;\n }\n};\n","import type {\n Media,\n MediaList,\n MediaListOptions,\n MediaStore,\n MediaUploadOptions,\n} from 'tinacms';\nimport { DEFAULT_MEDIA_UPLOAD_TYPES } from 'tinacms';\nimport { E_UNAUTHORIZED, E_BAD_ROUTE, interpretErrorMessage } from './errors';\n\nexport type CloudinaryMediaStoreOptions = {\n baseUrl?: string;\n};\n\nexport class CloudinaryMediaStore implements MediaStore {\n baseUrl: string;\n constructor(options?: CloudinaryMediaStoreOptions) {\n this.baseUrl = options?.baseUrl || '/api/cloudinary/media';\n }\n fetchFunction = (input: RequestInfo, init?: RequestInit) =>\n fetch(input, init);\n\n accept = DEFAULT_MEDIA_UPLOAD_TYPES;\n\n async persist(media: MediaUploadOptions[]): Promise<Media[]> {\n const newFiles: Media[] = [];\n\n for (const item of media) {\n const { file, directory } = item;\n const formData = new FormData();\n formData.append('file', file);\n formData.append('directory', directory);\n formData.append('filename', file.name);\n\n const res = await this.fetchFunction(this.baseUrl, {\n method: 'POST',\n body: formData,\n });\n\n if (res.status != 200) {\n const responseData = await res.json();\n throw new Error(responseData.message);\n }\n const fileRes = await res.json();\n /**\n * Images uploaded to Cloudinary aren't instantly available via the API;\n * waiting a couple seconds here seems to ensure they show up in the next fetch.\n */\n await new Promise((resolve) => {\n setTimeout(resolve, 2000);\n });\n /**\n * Format the response from Cloudinary to match Media interface\n * Valid Cloudinary `resource_type` values: `image`, `video`, `raw` and `auto`\n * uploading a directory is not supported as such, type is defaulted to `file`\n * https://cloudinary.com/documentation/upload_images#uploading_with_a_direct_call_to_the_rest_api\n */\n const parsedRes: Media = {\n type: 'file',\n id: fileRes.public_id,\n filename: fileRes.original_filename,\n directory: '/',\n thumbnails: {\n '75x75': fileRes.secure_url,\n '400x400': fileRes.secure_url,\n '1000x1000': fileRes.secure_url,\n },\n src: fileRes.secure_url,\n };\n\n newFiles.push(parsedRes);\n }\n return newFiles;\n }\n async delete(media: Media) {\n await this.fetchFunction(\n `${this.baseUrl}/${encodeURIComponent(media.id)}`,\n {\n method: 'DELETE',\n }\n );\n }\n async list(options: MediaListOptions): Promise<MediaList> {\n const query = this.buildQuery(options);\n const response = await this.fetchFunction(this.baseUrl + query);\n\n if (response.status == 401) {\n throw E_UNAUTHORIZED;\n }\n if (response.status == 404) {\n throw E_BAD_ROUTE;\n }\n if (response.status >= 500) {\n const { e } = await response.json();\n const error = interpretErrorMessage(e);\n throw error;\n }\n const { items, offset } = await response.json();\n return {\n items: items.map((item) => item),\n nextOffset: offset,\n };\n }\n\n parse = (img) => {\n return img.src;\n };\n\n buildQuery(options: MediaListOptions) {\n const params = Object.keys(options)\n .filter((key) => options[key] !== '' && options[key] !== undefined)\n .map((key) => `${key}=${options[key]}`)\n .join('&');\n\n return `?${params}`;\n }\n}\n","import type { Client } from 'tinacms';\nimport type { CloudinaryMediaStoreOptions } from './cloudinary-media-store';\nimport { CloudinaryMediaStore } from './cloudinary-media-store';\n\nexport const createTinaCloudCloudinaryMediaStore = (\n options: CloudinaryMediaStoreOptions = { baseUrl: '/api/cloudinary/media' }\n) =>\n class TinaCloudCloudinaryMediaStore extends CloudinaryMediaStore {\n client: Client;\n constructor(client: Client) {\n super(options);\n this.client = client;\n this.fetchFunction = async (input: RequestInfo, init?: RequestInit) => {\n try {\n const url = input.toString();\n const query = `${url.includes('?') ? '&' : '?'}clientID=${\n client.clientId\n }`;\n\n const res = client.authProvider.fetchWithToken(url + query, init);\n return res;\n } catch (error) {\n console.error(error);\n }\n };\n }\n };\n\nexport const TinaCloudCloudinaryMediaStore =\n createTinaCloudCloudinaryMediaStore();\n"],"names":[],"mappings":"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"}
|