Skip to content

Commit 93664e1

Browse files
feat: added support for searching for folders
1 parent 5df41d7 commit 93664e1

File tree

12 files changed

+173
-4
lines changed

12 files changed

+173
-4
lines changed

lib-es5/api.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,13 @@ exports.sub_folders = function sub_folders(path, callback) {
384384
return call_api("get", uri, params, callback, options);
385385
};
386386

387+
exports.search_folders = function search_folders(params, callback) {
388+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
389+
390+
options.content_type = 'json';
391+
return call_api("post", "folders/search", params, callback, options);
392+
};
393+
387394
/**
388395
* Creates an empty folder
389396
*

lib-es5/v2/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ v1_adapters(exports, api, {
3636
create_upload_preset: 0,
3737
root_folders: 0,
3838
sub_folders: 1,
39+
search_folders: 1,
3940
delete_folder: 1,
4041
create_folder: 1,
4142
upload_mappings: 0,

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
@@ -284,6 +284,11 @@ exports.sub_folders = function sub_folders(path, callback, options = {}) {
284284
return call_api("get", uri, params, callback, options);
285285
};
286286

287+
exports.search_folders = function search_folders(params, callback, options = {}) {
288+
options.content_type = 'json';
289+
return call_api("post", "folders/search", params, callback, options);
290+
}
291+
287292
/**
288293
* Creates an empty folder
289294
*

lib/v2/api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ v1_adapters(exports, api, {
3434
create_upload_preset: 0,
3535
root_folders: 0,
3636
sub_folders: 1,
37+
search_folders: 1,
3738
delete_folder: 1,
3839
create_folder: 1,
3940
upload_mappings: 0,

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: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const cloudinary = require('../../../../cloudinary');
2+
const {TIMEOUT} = require('../../../testUtils/testConstants');
3+
const describe = require('../../../testUtils/suite');
4+
5+
const folderNames = ['testFolder1', 'testFolder2'];
6+
7+
describe('search_folders_api', function () {
8+
describe('unit', function () {
9+
it('should create empty json', function () {
10+
const query = cloudinary.v2.search_folders.instance().to_query();
11+
expect(query).to.eql({});
12+
});
13+
14+
it('should always return same object in fluent interface', function () {
15+
const instance = cloudinary.v2.search_folders.instance();
16+
const searchOptions = [
17+
'expression',
18+
'sort_by',
19+
'max_results',
20+
'next_cursor',
21+
'aggregate',
22+
'with_field'
23+
];
24+
searchOptions.forEach(method => expect(instance).to.eql(instance[method]('emptyarg')));
25+
});
26+
27+
it('should correctly transform whole query into search payload', function () {
28+
const query = cloudinary.v2.search_folders
29+
.expression('expression-key:expression-value')
30+
.sort_by('sort_by_field', 'asc')
31+
.max_results(1)
32+
.next_cursor('next_cursor')
33+
.aggregate('aggregate1').aggregate('aggregate2')
34+
.with_field('field1').with_field('field2')
35+
.to_query();
36+
37+
expect(query).to.eql({
38+
expression: 'expression-key:expression-value',
39+
sort_by: [{sort_by_field: 'asc'}],
40+
max_results: 1,
41+
next_cursor: 'next_cursor',
42+
aggregate: ['aggregate1', 'aggregate2'],
43+
with_field: ['field1', 'field2']
44+
})
45+
});
46+
});
47+
48+
describe('integration', function () {
49+
this.timeout(TIMEOUT.LONG);
50+
51+
before(function () {
52+
return Promise.all(folderNames.map(folderName => {
53+
return cloudinary.v2.api.create_folder(folderName);
54+
}));
55+
});
56+
57+
after(function () {
58+
return Promise.all(folderNames.map(folderName => {
59+
return cloudinary.v2.api.delete_folder(folderName);
60+
}));
61+
});
62+
63+
it('should return all folders prefixed with testFolder', function () {
64+
return cloudinary.v2.search_folders.expression('name=testFolder*')
65+
.execute()
66+
.then(function (results) {
67+
expect(results.folders.length).to.eql(2);
68+
});
69+
});
70+
71+
it('should allow search by exact folder name', function () {
72+
return cloudinary.v2.search_folders.expression('name=testFolder1')
73+
.execute()
74+
.then(function (results) {
75+
expect(results.folders.length).to.eql(1);
76+
});
77+
});
78+
});
79+
});

0 commit comments

Comments
 (0)