import { hasTrailingSlash, title } from 'cpb-common';
import { StorageInstance as storage } from './shared.js';
/**
* @typedef {object} DirectoryListing
* @property {string} bucket - gce storage bucket
* @property {object[]} files - files in the bucket
* @property {object[]} dirs - directories within the bucket
*/
/**
* @internal
* @description
* ### Recursively get top-level directory listing for the given storage bucket.
* Due to the Google nodejs api limitations there is no native way to get this data.
* We have to manually iterate the apiResponse object and fill the prefixes.
* @param {string} bucket - gce storage bucket name
* @param {?string} delimiter - The delimiter argument can be used to restrict the results to only the
* "files" in the given "folder". Without the delimiter, the entire tree under the prefix is returned.
* @param {?string} prefix - directory prefix. This can be used to list all blobs in a "folder", e.g.
* "public/".
* @param {?boolean} [versions=false] - include previous file versions
* @returns {Promise<DirectoryListing>}
* @example
* For example, given these blobs:
* /a/1.txt
* /a/b/2.txt
* If you just specify prefix = 'a/', you'll get back:
* /a/1.txt
* /a/b/2.txt
* However, if you specify prefix='a/' and delimiter='/', you'll get back:
* /a/1.txt
*/
async function list({ bucket = process.env.BUCKET || 'custom-product-builder', delimiter, prefix, versions = false }) {
title('[cpb-storage/list]', { bucket, prefix, delimiter, versions });
// if (!bucket) {
// throw new TypeError('!bucket');
// }
/**
* @type {DirectoryListing}
*/
const result = {
files: [],
dirs: [],
bucket,
};
return await new Promise((resolve, reject) => {
async function callback(err, files, nextQuery, apiResponse) {
if (err) {
console.error(err);
reject(err);
}
(files || []).forEach(file => {
if (hasTrailingSlash(file.name)) {
result.dirs.push({
id: file.metadata.id,
name: file.name,
bucket,
});
} else {
result.files.push({
id: file.metadata.id,
name: file.name,
bucket,
currentFileSize: file.metadata.size,
generation: file.metadata.generation,
metadata: file.metadata,
});
}
});
((apiResponse || {}).prefixes || []).forEach(name => {
result.dirs.push({
name,
bucket,
});
});
if (nextQuery) await storage.bucket(bucket).getFiles(nextQuery, callback);
else return resolve(result);
}
storage.bucket(bucket).getFiles({ autoPaginate: false, prefix, delimiter, versions }, callback);
});
}
/**
* @method module:cpb-storage.LSD
* @description
* ### Get bucket directory/files listing
* @async
* @param {string} bucket - GCS Storage Bucket Name
* @param {?string} [delimiter]
* @param {?string} [prefix] - directory prefix
* @param {?boolean} [versions] - include previous file versions
* @returns {Promise<DirectoryListing>}
*/
export default async function LSD({ bucket, delimiter, prefix, versions }) {
return await list({ bucket, delimiter, prefix, versions });
}