import app, { cleanupData } from 'cpb-api';
import { title } from 'cpb-common';
import { File, getTopLevelDirs, getTopLevelFiles } from 'cpb-storage';
import { getShopifyStoreIdFromDir } from 'cpb-storage/shared.js';
/**
* @typedef {Object} StoreList
* @property {string} bucket - gce storage bucket
* @property {number[]} ids - shopify filestore ids
* @property {string[]} misc - misc dirs
* @property {string[]} legacy - legacy shopify filestore domains
* @property {string[]?} files - loose files
* @property {string[]?} deletedFiles - deleted loose files
* @property {BucketStorageStats} stats - storage stats
*/
/**
* ### List all stores data in the given bucket.
* If *fetch* flag is se - read file `index.json` if present. Otherwise generate new index file
* @method module:cpb-api/filestore.list
* @async
* @param {string} [bucket=${process.env.BUCKET}] - gce bucket
* @param {boolean} [fetch=false] - fetch new data if true or use existing
* index if present
* @param {boolean} [versions=false] - include file versions
* @param {boolean} [files=true] - include array with files to the output
* @param {string} [indexFileName='index.json'] - index file name
* @param {boolean} [legacy=true] - include array of the legacy shopify filestore dirs (ones with the name that
* includes.myshopify in it )
* @param {boolean} [misc=true] - include array of the uncategorized directories
* (ones that are neither shopifyStoreIds nor the shopify filestore domains)
* @returns {StoreList}
* @throws {Error} NO_DATA_FOUND
*/
export default async function list({
bucket = app.get('bucket'),
indexFileName = 'index.json',
fetch = false,
versions = false,
files = true,
misc = true,
legacy = true,
} = {}) {
title('StoreList', { ...arguments });
/**
* reads index file from the bucket and returns its contents
* @async
* @param {string} bucketName
* @param {string} indexFileName
* @returns {StoreList} data
*/
async function readIndexFile(bucketName, indexFileName) {
let data;
try {
data = await File.read({ bucket: bucketName, name: indexFileName }).catch(console.error);
} catch (error) {
console.error(`ERROR.StoreList.CACHED`, { bucketName, indexFileName, error });
}
return data;
}
/**
* generates new bucket index file that contains grouped files and filestore ids
* @async
* @param {string} bucketName
* @param {string} indexFileName
* @returns {StoreList}
*/
async function generateIndexFile(bucketName, indexFileName) {
const [files, deletedFiles] = await getTopLevelFiles({ bucket: bucketName }),
inventory = await getTopLevelDirs({ bucket: bucketName }),
ids = [],
misc = [],
legacy = [];
inventory.dirs.map(dir => {
const shopifyStoreId = getShopifyStoreIdFromDir({ dir: dir.name });
if (!shopifyStoreId) {
if (dir.name.indexOf('myshopify') !== -1) {
legacy.push(dir.name);
} else misc.push(dir.name);
} else ids.push(shopifyStoreId);
});
const data = {
bucket: bucketName,
ids,
misc,
legacy,
files,
deletedFiles,
stats: {
ids: ids.length,
legacy: legacy.length,
misc: misc.length,
files: files.length,
deletedFiles: deletedFiles.length,
},
};
File.upload({ bucket: bucketName, name: indexFileName, data }).then(console.info).catch(console.error);
return data;
}
let result;
if (!fetch) {
result = await readIndexFile(bucket, indexFileName);
if (result) return cleanupData(result, { legacy, misc, files, versions });
}
result = await generateIndexFile(bucket, indexFileName); // .catch(console.error);
if (result) return cleanupData(result, { legacy, misc, files, versions });
// something went very wrong here...at least some data should be present in the bucket
throw new Error('NO_DATA_FOUND');
}