Skip to content

Commit ccf2fd2

Browse files
YomesIncstrausr
andauthored
Return structured metadata in resources APIs (#503)
Co-authored-by: Raya Straus <[email protected]>
1 parent ac0d8d1 commit ccf2fd2

File tree

3 files changed

+87
-8
lines changed

3 files changed

+87
-8
lines changed

lib-es5/api.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ exports.resources = function resources(callback) {
5454
if (options.start_at != null && Object.prototype.toString.call(options.start_at) === '[object Date]') {
5555
options.start_at = options.start_at.toUTCString();
5656
}
57-
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "prefix", "tags", "context", "direction", "moderations", "start_at"), callback, options);
57+
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "prefix", "tags", "context", "direction", "moderations", "start_at", "metadata"), callback, options);
5858
};
5959

6060
exports.resources_by_tag = function resources_by_tag(tag, callback) {
@@ -64,7 +64,7 @@ exports.resources_by_tag = function resources_by_tag(tag, callback) {
6464
uri = void 0;
6565
resource_type = options.resource_type || "image";
6666
uri = ["resources", resource_type, "tags", tag];
67-
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations"), callback, options);
67+
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata"), callback, options);
6868
};
6969

7070
exports.resources_by_context = function resources_by_context(key, value, callback) {
@@ -75,7 +75,7 @@ exports.resources_by_context = function resources_by_context(key, value, callbac
7575
uri = void 0;
7676
resource_type = options.resource_type || "image";
7777
uri = ["resources", resource_type, "context"];
78-
params = pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations");
78+
params = pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata");
7979
params.key = key;
8080
if (value != null) {
8181
params.value = value;
@@ -90,7 +90,7 @@ exports.resources_by_moderation = function resources_by_moderation(kind, status,
9090
uri = void 0;
9191
resource_type = options.resource_type || "image";
9292
uri = ["resources", resource_type, "moderations", kind, status];
93-
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations"), callback, options);
93+
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata"), callback, options);
9494
};
9595

9696
exports.resources_by_ids = function resources_by_ids(public_ids, callback) {

lib/api.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,21 @@ exports.resources = function resources(callback, options = {}) {
3838
if ((options.start_at != null) && Object.prototype.toString.call(options.start_at) === '[object Date]') {
3939
options.start_at = options.start_at.toUTCString();
4040
}
41-
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "prefix", "tags", "context", "direction", "moderations", "start_at"), callback, options);
41+
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "prefix", "tags", "context", "direction", "moderations", "start_at", "metadata"), callback, options);
4242
};
4343

4444
exports.resources_by_tag = function resources_by_tag(tag, callback, options = {}) {
4545
let resource_type, uri;
4646
resource_type = options.resource_type || "image";
4747
uri = ["resources", resource_type, "tags", tag];
48-
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations"), callback, options);
48+
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata"), callback, options);
4949
};
5050

5151
exports.resources_by_context = function resources_by_context(key, value, callback, options = {}) {
5252
let params, resource_type, uri;
5353
resource_type = options.resource_type || "image";
5454
uri = ["resources", resource_type, "context"];
55-
params = pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations");
55+
params = pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata");
5656
params.key = key;
5757
if (value != null) {
5858
params.value = value;
@@ -64,7 +64,7 @@ exports.resources_by_moderation = function resources_by_moderation(kind, status,
6464
let resource_type, uri;
6565
resource_type = options.resource_type || "image";
6666
uri = ["resources", resource_type, "moderations", kind, status];
67-
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations"), callback, options);
67+
return call_api("get", uri, pickOnlyExistingValues(options, "next_cursor", "max_results", "tags", "context", "direction", "moderations", "metadata"), callback, options);
6868
};
6969

7070
exports.resources_by_ids = function resources_by_ids(public_ids, callback, options = {}) {

test/integration/api/admin/api_spec.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ const EXPLICIT_TRANSFORMATION2 = {
6969
overlay: `text:Arial_60:${TEST_TAG}`
7070
};
7171

72+
const METADATA_EXTERNAL_ID = "metadata_external_id_" + TEST_TAG;
73+
const METADATA_DEFAULT_VALUE = "metadata_default_value_" + TEST_TAG;
7274

7375

7476
function getAllTags({ resources }) {
@@ -87,6 +89,12 @@ describe("api", function () {
8789
before(function () {
8890
this.timeout(TIMEOUT.LONG);
8991
return Q.allSettled([
92+
cloudinary.v2.api.add_metadata_field({
93+
external_id: METADATA_EXTERNAL_ID,
94+
label: METADATA_EXTERNAL_ID,
95+
type: 'string',
96+
default_value: METADATA_DEFAULT_VALUE
97+
}),
9098
uploadImage({
9199
public_id: PUBLIC_ID,
92100
tags: UPLOAD_TAGS,
@@ -123,6 +131,7 @@ describe("api", function () {
123131
expect().fail("Missing key and secret. Please set CLOUDINARY_URL.");
124132
}
125133
return Q.allSettled([
134+
cloudinary.v2.api.delete_metadata_field(METADATA_EXTERNAL_ID),
126135
cloudinary.v2.api.delete_resources_by_tag(TEST_TAG),
127136
cloudinary.v2.api.delete_upload_preset(API_TEST_UPLOAD_PRESET1),
128137
cloudinary.v2.api.delete_upload_preset(API_TEST_UPLOAD_PRESET2),
@@ -157,6 +166,76 @@ describe("api", function () {
157166
expect(resource.type).to.eql("upload");
158167
});
159168
});
169+
it("should allow listing resources with metadata", async function () {
170+
this.timeout(TIMEOUT.MEDIUM);
171+
let result = await cloudinary.v2.api.resources({
172+
type: "upload",
173+
prefix: PUBLIC_ID,
174+
metadata: true
175+
});
176+
result.resources.forEach((resource) => {
177+
expect(resource).to.have.property('metadata');
178+
});
179+
result = await cloudinary.v2.api.resources({
180+
type: "upload",
181+
prefix: PUBLIC_ID,
182+
metadata: false
183+
});
184+
result.resources.forEach((resource) => {
185+
expect(resource).to.not.have.property('metadata');
186+
});
187+
});
188+
it("should allow listing resources by tag with metadata", async function () {
189+
this.timeout(TIMEOUT.MEDIUM);
190+
let result = await cloudinary.v2.api.resources_by_tag(TEST_TAG, {
191+
metadata: true
192+
});
193+
result.resources.forEach((resource) => {
194+
expect(resource).to.have.property('metadata');
195+
});
196+
result = await cloudinary.v2.api.resources_by_tag(TEST_TAG, {
197+
metadata: false
198+
});
199+
result.resources.forEach((resource) => {
200+
expect(resource).to.not.have.property('metadata');
201+
});
202+
});
203+
it("should allow listing resources by context with metadata", async function () {
204+
this.timeout(TIMEOUT.MEDIUM);
205+
let result = await cloudinary.v2.api.resources_by_context(contextKey, null, {
206+
metadata: true
207+
});
208+
result.resources.forEach((resource) => {
209+
expect(resource).to.have.property('metadata');
210+
});
211+
result = await cloudinary.v2.api.resources_by_context(contextKey, null, {
212+
metadata: false
213+
});
214+
result.resources.forEach((resource) => {
215+
expect(resource).to.not.have.property('metadata');
216+
});
217+
});
218+
it("should allow listing resources by moderation with metadata", async function () {
219+
this.timeout(TIMEOUT.MEDIUM);
220+
const moderation = "manual";
221+
const status = "pending";
222+
await uploadImage({
223+
moderation,
224+
tags: [TEST_TAG]
225+
});
226+
let result = await cloudinary.v2.api.resources_by_moderation(moderation, status, {
227+
metadata: true
228+
});
229+
result.resources.forEach((resource) => {
230+
expect(resource).to.have.property('metadata');
231+
});
232+
result = await cloudinary.v2.api.resources_by_moderation(moderation, status, {
233+
metadata: false
234+
});
235+
result.resources.forEach((resource) => {
236+
expect(resource).to.not.have.property('metadata');
237+
});
238+
});
160239
it("should allow listing resources by type", function () {
161240
this.timeout(TIMEOUT.MEDIUM);
162241
return uploadImage({

0 commit comments

Comments
 (0)