minio
Version:
S3 Compatible Cloud Storage client
114 lines (110 loc) • 15.3 kB
JavaScript
/*
* MinIO Javascript Library for Amazon S3 Compatible Cloud Storage, (C) 2020 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import * as stream from "stream";
import * as errors from "../errors.mjs";
import { isBoolean, isString, isValidBucketName, isValidPrefix, uriEscape } from "./helper.mjs";
import { readAsString } from "./response.mjs";
import { parseListObjectsV2WithMetadata } from "./xml-parser.mjs";
export class Extensions {
constructor(client) {
this.client = client;
}
/**
* List the objects in the bucket using S3 ListObjects V2 With Metadata
*
* @param bucketName - name of the bucket
* @param prefix - the prefix of the objects that should be listed (optional, default `''`)
* @param recursive - `true` indicates recursive style listing and `false` indicates directory style listing delimited by '/'. (optional, default `false`)
* @param startAfter - Specifies the key to start after when listing objects in a bucket. (optional, default `''`)
* @returns stream emitting the objects in the bucket, the object is of the format:
*/
listObjectsV2WithMetadata(bucketName, prefix, recursive, startAfter) {
if (prefix === undefined) {
prefix = '';
}
if (recursive === undefined) {
recursive = false;
}
if (startAfter === undefined) {
startAfter = '';
}
if (!isValidBucketName(bucketName)) {
throw new errors.InvalidBucketNameError('Invalid bucket name: ' + bucketName);
}
if (!isValidPrefix(prefix)) {
throw new errors.InvalidPrefixError(`Invalid prefix : ${prefix}`);
}
if (!isString(prefix)) {
throw new TypeError('prefix should be of type "string"');
}
if (!isBoolean(recursive)) {
throw new TypeError('recursive should be of type "boolean"');
}
if (!isString(startAfter)) {
throw new TypeError('startAfter should be of type "string"');
}
// if recursive is false set delimiter to '/'
const delimiter = recursive ? '' : '/';
return stream.Readable.from(this.listObjectsV2WithMetadataGen(bucketName, prefix, delimiter, startAfter), {
objectMode: true
});
}
async *listObjectsV2WithMetadataGen(bucketName, prefix, delimiter, startAfter) {
let ended = false;
let continuationToken = '';
do {
const result = await this.listObjectsV2WithMetadataQuery(bucketName, prefix, continuationToken, delimiter, startAfter);
ended = !result.isTruncated;
continuationToken = result.nextContinuationToken;
for (const obj of result.objects) {
yield obj;
}
} while (!ended);
}
async listObjectsV2WithMetadataQuery(bucketName, prefix, continuationToken, delimiter, startAfter) {
const queries = [];
// Call for listing objects v2 API
queries.push(`list-type=2`);
queries.push(`encoding-type=url`);
// escape every value in query string, except maxKeys
queries.push(`prefix=${uriEscape(prefix)}`);
queries.push(`delimiter=${uriEscape(delimiter)}`);
queries.push(`metadata=true`);
if (continuationToken) {
continuationToken = uriEscape(continuationToken);
queries.push(`continuation-token=${continuationToken}`);
}
// Set start-after
if (startAfter) {
startAfter = uriEscape(startAfter);
queries.push(`start-after=${startAfter}`);
}
queries.push(`max-keys=1000`);
queries.sort();
let query = '';
if (queries.length > 0) {
query = `${queries.join('&')}`;
}
const method = 'GET';
const res = await this.client.makeRequestAsync({
method,
bucketName,
query
});
return parseListObjectsV2WithMetadata(await readAsString(res));
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJzdHJlYW0iLCJlcnJvcnMiLCJpc0Jvb2xlYW4iLCJpc1N0cmluZyIsImlzVmFsaWRCdWNrZXROYW1lIiwiaXNWYWxpZFByZWZpeCIsInVyaUVzY2FwZSIsInJlYWRBc1N0cmluZyIsInBhcnNlTGlzdE9iamVjdHNWMldpdGhNZXRhZGF0YSIsIkV4dGVuc2lvbnMiLCJjb25zdHJ1Y3RvciIsImNsaWVudCIsImxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGEiLCJidWNrZXROYW1lIiwicHJlZml4IiwicmVjdXJzaXZlIiwic3RhcnRBZnRlciIsInVuZGVmaW5lZCIsIkludmFsaWRCdWNrZXROYW1lRXJyb3IiLCJJbnZhbGlkUHJlZml4RXJyb3IiLCJUeXBlRXJyb3IiLCJkZWxpbWl0ZXIiLCJSZWFkYWJsZSIsImZyb20iLCJsaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhR2VuIiwib2JqZWN0TW9kZSIsImVuZGVkIiwiY29udGludWF0aW9uVG9rZW4iLCJyZXN1bHQiLCJsaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhUXVlcnkiLCJpc1RydW5jYXRlZCIsIm5leHRDb250aW51YXRpb25Ub2tlbiIsIm9iaiIsIm9iamVjdHMiLCJxdWVyaWVzIiwicHVzaCIsInNvcnQiLCJxdWVyeSIsImxlbmd0aCIsImpvaW4iLCJtZXRob2QiLCJyZXMiLCJtYWtlUmVxdWVzdEFzeW5jIl0sInNvdXJjZXMiOlsiZXh0ZW5zaW9ucy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogTWluSU8gSmF2YXNjcmlwdCBMaWJyYXJ5IGZvciBBbWF6b24gUzMgQ29tcGF0aWJsZSBDbG91ZCBTdG9yYWdlLCAoQykgMjAyMCBNaW5JTywgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5pbXBvcnQgKiBhcyBzdHJlYW0gZnJvbSAnbm9kZTpzdHJlYW0nXG5cbmltcG9ydCAqIGFzIGVycm9ycyBmcm9tICcuLi9lcnJvcnMudHMnXG5pbXBvcnQgdHlwZSB7IFR5cGVkQ2xpZW50IH0gZnJvbSAnLi9jbGllbnQudHMnXG5pbXBvcnQgeyBpc0Jvb2xlYW4sIGlzU3RyaW5nLCBpc1ZhbGlkQnVja2V0TmFtZSwgaXNWYWxpZFByZWZpeCwgdXJpRXNjYXBlIH0gZnJvbSAnLi9oZWxwZXIudHMnXG5pbXBvcnQgeyByZWFkQXNTdHJpbmcgfSBmcm9tICcuL3Jlc3BvbnNlLnRzJ1xuaW1wb3J0IHR5cGUgeyBCdWNrZXRJdGVtV2l0aE1ldGFkYXRhLCBCdWNrZXRTdHJlYW0gfSBmcm9tICcuL3R5cGUudHMnXG5pbXBvcnQgeyBwYXJzZUxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGEgfSBmcm9tICcuL3htbC1wYXJzZXIudHMnXG5cbmV4cG9ydCBjbGFzcyBFeHRlbnNpb25zIHtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFR5cGVkQ2xpZW50KSB7fVxuXG4gIC8qKlxuICAgKiBMaXN0IHRoZSBvYmplY3RzIGluIHRoZSBidWNrZXQgdXNpbmcgUzMgTGlzdE9iamVjdHMgVjIgV2l0aCBNZXRhZGF0YVxuICAgKlxuICAgKiBAcGFyYW0gYnVja2V0TmFtZSAtIG5hbWUgb2YgdGhlIGJ1Y2tldFxuICAgKiBAcGFyYW0gcHJlZml4IC0gdGhlIHByZWZpeCBvZiB0aGUgb2JqZWN0cyB0aGF0IHNob3VsZCBiZSBsaXN0ZWQgKG9wdGlvbmFsLCBkZWZhdWx0IGAnJ2ApXG4gICAqIEBwYXJhbSByZWN1cnNpdmUgLSBgdHJ1ZWAgaW5kaWNhdGVzIHJlY3Vyc2l2ZSBzdHlsZSBsaXN0aW5nIGFuZCBgZmFsc2VgIGluZGljYXRlcyBkaXJlY3Rvcnkgc3R5bGUgbGlzdGluZyBkZWxpbWl0ZWQgYnkgJy8nLiAob3B0aW9uYWwsIGRlZmF1bHQgYGZhbHNlYClcbiAgICogQHBhcmFtIHN0YXJ0QWZ0ZXIgLSBTcGVjaWZpZXMgdGhlIGtleSB0byBzdGFydCBhZnRlciB3aGVuIGxpc3Rpbmcgb2JqZWN0cyBpbiBhIGJ1Y2tldC4gKG9wdGlvbmFsLCBkZWZhdWx0IGAnJ2ApXG4gICAqIEByZXR1cm5zIHN0cmVhbSBlbWl0dGluZyB0aGUgb2JqZWN0cyBpbiB0aGUgYnVja2V0LCB0aGUgb2JqZWN0IGlzIG9mIHRoZSBmb3JtYXQ6XG4gICAqL1xuICBwdWJsaWMgbGlzdE9iamVjdHNWMldpdGhNZXRhZGF0YShcbiAgICBidWNrZXROYW1lOiBzdHJpbmcsXG4gICAgcHJlZml4Pzogc3RyaW5nLFxuICAgIHJlY3Vyc2l2ZT86IGJvb2xlYW4sXG4gICAgc3RhcnRBZnRlcj86IHN0cmluZyxcbiAgKTogQnVja2V0U3RyZWFtPEJ1Y2tldEl0ZW1XaXRoTWV0YWRhdGE+IHtcbiAgICBpZiAocHJlZml4ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHByZWZpeCA9ICcnXG4gICAgfVxuICAgIGlmIChyZWN1cnNpdmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVjdXJzaXZlID0gZmFsc2VcbiAgICB9XG4gICAgaWYgKHN0YXJ0QWZ0ZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgc3RhcnRBZnRlciA9ICcnXG4gICAgfVxuICAgIGlmICghaXNWYWxpZEJ1Y2tldE5hbWUoYnVja2V0TmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuSW52YWxpZEJ1Y2tldE5hbWVFcnJvcignSW52YWxpZCBidWNrZXQgbmFtZTogJyArIGJ1Y2tldE5hbWUpXG4gICAgfVxuICAgIGlmICghaXNWYWxpZFByZWZpeChwcmVmaXgpKSB7XG4gICAgICB0aHJvdyBuZXcgZXJyb3JzLkludmFsaWRQcmVmaXhFcnJvcihgSW52YWxpZCBwcmVmaXggOiAke3ByZWZpeH1gKVxuICAgIH1cbiAgICBpZiAoIWlzU3RyaW5nKHByZWZpeCkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ3ByZWZpeCBzaG91bGQgYmUgb2YgdHlwZSBcInN0cmluZ1wiJylcbiAgICB9XG4gICAgaWYgKCFpc0Jvb2xlYW4ocmVjdXJzaXZlKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcigncmVjdXJzaXZlIHNob3VsZCBiZSBvZiB0eXBlIFwiYm9vbGVhblwiJylcbiAgICB9XG4gICAgaWYgKCFpc1N0cmluZyhzdGFydEFmdGVyKSkge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignc3RhcnRBZnRlciBzaG91bGQgYmUgb2YgdHlwZSBcInN0cmluZ1wiJylcbiAgICB9XG5cbiAgICAvLyBpZiByZWN1cnNpdmUgaXMgZmFsc2Ugc2V0IGRlbGltaXRlciB0byAnLydcbiAgICBjb25zdCBkZWxpbWl0ZXIgPSByZWN1cnNpdmUgPyAnJyA6ICcvJ1xuICAgIHJldHVybiBzdHJlYW0uUmVhZGFibGUuZnJvbSh0aGlzLmxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGFHZW4oYnVja2V0TmFtZSwgcHJlZml4LCBkZWxpbWl0ZXIsIHN0YXJ0QWZ0ZXIpLCB7XG4gICAgICBvYmplY3RNb2RlOiB0cnVlLFxuICAgIH0pXG4gIH1cblxuICBwcml2YXRlIGFzeW5jICpsaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhR2VuKFxuICAgIGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBkZWxpbWl0ZXI6IHN0cmluZyxcbiAgICBzdGFydEFmdGVyOiBzdHJpbmcsXG4gICk6IEFzeW5jSXRlcmFibGU8QnVja2V0SXRlbVdpdGhNZXRhZGF0YT4ge1xuICAgIGxldCBlbmRlZCA9IGZhbHNlXG4gICAgbGV0IGNvbnRpbnVhdGlvblRva2VuID0gJydcbiAgICBkbyB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmxpc3RPYmplY3RzVjJXaXRoTWV0YWRhdGFRdWVyeShcbiAgICAgICAgYnVja2V0TmFtZSxcbiAgICAgICAgcHJlZml4LFxuICAgICAgICBjb250aW51YXRpb25Ub2tlbixcbiAgICAgICAgZGVsaW1pdGVyLFxuICAgICAgICBzdGFydEFmdGVyLFxuICAgICAgKVxuICAgICAgZW5kZWQgPSAhcmVzdWx0LmlzVHJ1bmNhdGVkXG4gICAgICBjb250aW51YXRpb25Ub2tlbiA9IHJlc3VsdC5uZXh0Q29udGludWF0aW9uVG9rZW5cbiAgICAgIGZvciAoY29uc3Qgb2JqIG9mIHJlc3VsdC5vYmplY3RzKSB7XG4gICAgICAgIHlpZWxkIG9ialxuICAgICAgfVxuICAgIH0gd2hpbGUgKCFlbmRlZClcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgbGlzdE9iamVjdHNWMldpdGhNZXRhZGF0YVF1ZXJ5KFxuICAgIGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBjb250aW51YXRpb25Ub2tlbjogc3RyaW5nLFxuICAgIGRlbGltaXRlcjogc3RyaW5nLFxuICAgIHN0YXJ0QWZ0ZXI6IHN0cmluZyxcbiAgKSB7XG4gICAgY29uc3QgcXVlcmllcyA9IFtdXG5cbiAgICAvLyBDYWxsIGZvciBsaXN0aW5nIG9iamVjdHMgdjIgQVBJXG4gICAgcXVlcmllcy5wdXNoKGBsaXN0LXR5cGU9MmApXG4gICAgcXVlcmllcy5wdXNoKGBlbmNvZGluZy10eXBlPXVybGApXG4gICAgLy8gZXNjYXBlIGV2ZXJ5IHZhbHVlIGluIHF1ZXJ5IHN0cmluZywgZXhjZXB0IG1heEtleXNcbiAgICBxdWVyaWVzLnB1c2goYHByZWZpeD0ke3VyaUVzY2FwZShwcmVmaXgpfWApXG4gICAgcXVlcmllcy5wdXNoKGBkZWxpbWl0ZXI9JHt1cmlFc2NhcGUoZGVsaW1pdGVyKX1gKVxuICAgIHF1ZXJpZXMucHVzaChgbWV0YWRhdGE9dHJ1ZWApXG5cbiAgICBpZiAoY29udGludWF0aW9uVG9rZW4pIHtcbiAgICAgIGNvbnRpbnVhdGlvblRva2VuID0gdXJpRXNjYXBlKGNvbnRpbnVhdGlvblRva2VuKVxuICAgICAgcXVlcmllcy5wdXNoKGBjb250aW51YXRpb24tdG9rZW49JHtjb250aW51YXRpb25Ub2tlbn1gKVxuICAgIH1cbiAgICAvLyBTZXQgc3RhcnQtYWZ0ZXJcbiAgICBpZiAoc3RhcnRBZnRlcikge1xuICAgICAgc3RhcnRBZnRlciA9IHVyaUVzY2FwZShzdGFydEFmdGVyKVxuICAgICAgcXVlcmllcy5wdXNoKGBzdGFydC1hZnRlcj0ke3N0YXJ0QWZ0ZXJ9YClcbiAgICB9XG4gICAgcXVlcmllcy5wdXNoKGBtYXgta2V5cz0xMDAwYClcbiAgICBxdWVyaWVzLnNvcnQoKVxuICAgIGxldCBxdWVyeSA9ICcnXG4gICAgaWYgKHF1ZXJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgcXVlcnkgPSBgJHtxdWVyaWVzLmpvaW4oJyYnKX1gXG4gICAgfVxuICAgIGNvbnN0IG1ldGhvZCA9ICdHRVQnXG4gICAgY29uc3QgcmVzID0gYXdhaXQgdGhpcy5jbGllbnQubWFrZVJlcXVlc3RBc3luYyh7IG1ldGhvZCwgYnVja2V0TmFtZSwgcXVlcnkgfSlcbiAgICByZXR1cm4gcGFyc2VMaXN0T2JqZWN0c1YyV2l0aE1ldGFkYXRhKGF3YWl0IHJlYWRBc1N0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