Skip to content

Commit d8c4c32

Browse files
Merge pull request #586 from cloudinary/search-for-folders
feat: added support for searching for folders
2 parents 5df41d7 + 69c91d7 commit d8c4c32

File tree

12 files changed

+166
-4
lines changed

12 files changed

+166
-4
lines changed

lib-es5/api.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,13 @@ exports.search = function search(params, callback) {
544544
return call_api("post", "resources/search", params, callback, options);
545545
};
546546

547+
exports.search_folders = function search_folders(params, callback) {
548+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
549+
550+
options.content_type = 'json';
551+
return call_api("post", "folders/search", params, callback, options);
552+
};
553+
547554
exports.update_resources_access_mode_by_prefix = function update_resources_access_mode_by_prefix(access_mode, prefix, callback) {
548555
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
549556

lib-es5/v2/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ v1_adapters(exports, api, {
5555
update_resources_access_mode_by_tag: 2,
5656
update_resources_access_mode_by_ids: 2,
5757
search: 1,
58+
search_folders: 1,
5859
delete_derived_by_transformation: 2,
5960
add_metadata_field: 1,
6061
list_metadata_fields: 1,

lib-es5/v2/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ var v1 = require('../cloudinary');
66
var api = require('./api');
77
var uploader = require('./uploader');
88
var search = require('./search');
9+
var search_folders = require('./search_folders');
910

1011
var v2 = _extends({}, v1, {
1112
api,
1213
uploader,
13-
search
14+
search,
15+
search_folders
1416
});
1517
module.exports = v2;

lib-es5/v2/search_folders.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
4+
5+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6+
7+
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
8+
9+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
10+
11+
var Search = require('./search');
12+
var api = require('./api');
13+
14+
var SearchFolders = function (_Search) {
15+
_inherits(SearchFolders, _Search);
16+
17+
function SearchFolders() {
18+
_classCallCheck(this, SearchFolders);
19+
20+
return _possibleConstructorReturn(this, (SearchFolders.__proto__ || Object.getPrototypeOf(SearchFolders)).call(this));
21+
}
22+
23+
_createClass(SearchFolders, [{
24+
key: 'execute',
25+
value: function execute(options, callback) {
26+
if (callback === null) {
27+
callback = options;
28+
}
29+
options = options || {};
30+
return api.search_folders(this.to_query(), options, callback);
31+
}
32+
}], [{
33+
key: 'instance',
34+
value: function instance() {
35+
return new SearchFolders();
36+
}
37+
}]);
38+
39+
return SearchFolders;
40+
}(Search);
41+
42+
module.exports = SearchFolders;

lib/api.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ exports.search = function search(params, callback, options = {}) {
404404
return call_api("post", "resources/search", params, callback, options);
405405
};
406406

407+
exports.search_folders = function search_folders(params, callback, options = {}) {
408+
options.content_type = 'json';
409+
return call_api("post", "folders/search", params, callback, options);
410+
};
411+
407412
exports.update_resources_access_mode_by_prefix = function update_resources_access_mode_by_prefix(
408413
access_mode,
409414
prefix,

lib/v2/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ v1_adapters(exports, api, {
5353
update_resources_access_mode_by_tag: 2,
5454
update_resources_access_mode_by_ids: 2,
5555
search: 1,
56+
search_folders: 1,
5657
delete_derived_by_transformation: 2,
5758
add_metadata_field: 1,
5859
list_metadata_fields: 1,

lib/v2/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ const v1 = require('../cloudinary');
22
const api = require('./api');
33
const uploader = require('./uploader');
44
const search = require('./search');
5+
const search_folders = require('./search_folders');
56

67
const v2 = {
78
...v1,
89
api,
910
uploader,
10-
search
11+
search,
12+
search_folders
1113
};
1214
module.exports = v2;

lib/v2/search_folders.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const Search = require('./search');
2+
const api = require('./api');
3+
4+
const SearchFolders = class SearchFolders extends Search {
5+
constructor() {
6+
super();
7+
}
8+
9+
static instance() {
10+
return new SearchFolders();
11+
}
12+
13+
execute(options, callback) {
14+
if (callback === null) {
15+
callback = options;
16+
}
17+
options = options || {};
18+
return api.search_folders(this.to_query(), options, callback);
19+
}
20+
};
21+
22+
module.exports = SearchFolders;

test/integration/api/admin/api_spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1165,7 +1165,7 @@ describe("api", function () {
11651165
let preset_details = await cloudinary.v2.api.upload_preset(preset.name);
11661166
expect(preset_details.settings).to.eql({ use_asset_folder_as_public_id_prefix: true })
11671167
});
1168-
1168+
11691169
it('should update asset_folder', async function () {
11701170
if (!shouldTestFeature(DYNAMIC_FOLDERS)) {
11711171
this.skip();
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
const cloudinary = require('../../../../cloudinary');
2+
const {TIMEOUT} = require('../../../testUtils/testConstants');
3+
const describe = require('../../../testUtils/suite');
4+
const wait = require('../../../testUtils/helpers/wait');
5+
6+
const folderNames = ['testFolder1', 'testFolder2'];
7+
8+
describe('search_folders_api', function () {
9+
describe('unit', function () {
10+
it('should create empty json', function () {
11+
const query = cloudinary.v2.search_folders.instance().to_query();
12+
expect(query).to.eql({});
13+
});
14+
15+
it('should always return same object in fluent interface', function () {
16+
const instance = cloudinary.v2.search_folders.instance();
17+
const searchOptions = [
18+
'expression',
19+
'sort_by',
20+
'max_results',
21+
'next_cursor',
22+
'aggregate',
23+
'with_field'
24+
];
25+
searchOptions.forEach(method => expect(instance).to.eql(instance[method]('emptyarg')));
26+
});
27+
28+
it('should correctly transform whole query into search payload', function () {
29+
const query = cloudinary.v2.search_folders
30+
.expression('expression-key:expression-value')
31+
.sort_by('sort_by_field', 'asc')
32+
.max_results(1)
33+
.next_cursor('next_cursor')
34+
.aggregate('aggregate1').aggregate('aggregate2')
35+
.with_field('field1').with_field('field2')
36+
.to_query();
37+
38+
expect(query).to.eql({
39+
expression: 'expression-key:expression-value',
40+
sort_by: [{sort_by_field: 'asc'}],
41+
max_results: 1,
42+
next_cursor: 'next_cursor',
43+
aggregate: ['aggregate1', 'aggregate2'],
44+
with_field: ['field1', 'field2']
45+
})
46+
});
47+
});
48+
49+
describe('integration', function () {
50+
this.timeout(TIMEOUT.LONG);
51+
52+
before(function () {
53+
return Promise.all(folderNames.map(folderName => {
54+
return cloudinary.v2.api.create_folder(folderName);
55+
})).then(wait(2));
56+
});
57+
58+
after(function () {
59+
return Promise.all(folderNames.map(folderName => {
60+
return cloudinary.v2.api.delete_folder(folderName);
61+
}));
62+
});
63+
64+
it('should return a search response with folders', function () {
65+
return cloudinary.v2.search_folders.expression('name=testFolder*')
66+
.execute()
67+
.then(function (results) {
68+
expect(results).to.have.key('folders');
69+
});
70+
});
71+
});
72+
});

0 commit comments

Comments
 (0)