UNPKG

minio

Version:

S3 Compatible Cloud Storage client

114 lines (110 loc) 15.3 kB
/* * 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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