Improved model reading flow

This commit is contained in:
Alexander Cerutti
2023-04-20 01:14:32 +02:00
parent 9f29cf4c80
commit 5a74057a95

View File

@@ -19,37 +19,24 @@ export default async function getModelFolderContents(
const modelPath = `${model}${(!path.extname(model) && ".pass") || ""}`; const modelPath = `${model}${(!path.extname(model) && ".pass") || ""}`;
const modelFilesList = await fs.readdir(modelPath); const modelFilesList = await fs.readdir(modelPath);
// No dot-starting files, manifest and signature // No dot-starting files, manifest and signature and only files with an extension
const filteredModelRecords = Utils.removeHidden(modelFilesList).filter( const modelSuitableRootPaths = Utils.removeHidden(
modelFilesList,
).filter(
(f) => (f) =>
!/(manifest|signature)/i.test(f) && !/(manifest|signature)/i.test(f) &&
/.+$/.test(path.parse(f).ext), /.+$/.test(path.parse(f).ext),
); );
const modelRecords = ( const modelRecords = await Promise.all(
await Promise.all( modelSuitableRootPaths.map((fileOrDirectoryPath) =>
/** readFileOrDirectory(
* Obtaining flattened array of buffer records path.resolve(modelPath, fileOrDirectoryPath),
* containing file name and the buffer itself. ),
* ),
* This goes also to read every nested l10n
* subfolder.
*/
filteredModelRecords.map((fileOrDirectoryPath) => {
const fullPath = path.resolve(
modelPath,
fileOrDirectoryPath,
); );
return readFileOrDirectory(fullPath); return Object.fromEntries(modelRecords.flat(1));
}),
)
)
.flat(1)
.reduce((acc, current) => ({ ...acc, ...current }), {});
return modelRecords;
} catch (err) { } catch (err) {
if (!isErrorErrNoException(err) || !isMissingFileError(err)) { if (!isErrorErrNoException(err) || !isMissingFileError(err)) {
throw err; throw err;
@@ -97,61 +84,61 @@ function isFileReadingFailure(
} }
/** /**
* Reads sequentially * Allows reading both a whole directory or a set of
* file in the same flow
*
* @param filePath * @param filePath
* @returns * @returns
*/ */
async function readFileOrDirectory(filePath: string) { async function readFileOrDirectory(
if ((await fs.lstat(filePath)).isDirectory()) { filePath: string,
return Promise.all(await readDirectory(filePath)); ): Promise<[key: string, content: Buffer][]> {
const stats = await fs.lstat(filePath);
if (stats.isDirectory()) {
return readFilesInDirectory(filePath);
} else { } else {
return fs return getFileContents(filePath).then((result) => [result]);
.readFile(filePath)
.then((content) => getObjectFromModelFile(filePath, content, 1));
} }
} }
/** /**
* Returns an object containing the parsed fileName * Reads a directory and returns all
* from a path along with its content. * the files in it
* *
* @param filePath * @param filePath
* @param content
* @param depthFromEnd - used to preserve localization lproj content
* @returns * @returns
*/ */
function getObjectFromModelFile( async function readFilesInDirectory(
filePath: string, filePath: string,
content: Buffer, ): Promise<Awaited<ReturnType<typeof getFileContents>>[]> {
depthFromEnd: number, const dirContent = await fs.readdir(filePath).then(Utils.removeHidden);
) {
const fileComponents = filePath.split(path.sep);
const fileName = fileComponents
.slice(fileComponents.length - depthFromEnd)
.join("/");
return { [fileName]: content }; return Promise.all(
dirContent
.map((fileName) => path.resolve(filePath, fileName))
.map((fileName) => getFileContents(fileName, 2)),
);
} }
/** /**
* Reads a directory and returns all the files in it
* as an Array<Promise>
*
* @param filePath * @param filePath
* @param pathSlicesDepthFromEnd used to preserve localization lproj content
* @returns * @returns
*/ */
async function readDirectory(filePath: string) { async function getFileContents(
const dirContent = await fs.readdir(filePath).then(Utils.removeHidden); filePath: string,
pathSlicesDepthFromEnd: number = 1,
): Promise<[key: string, content: Buffer]> {
const fileComponents = filePath.split(path.sep);
const fileName = fileComponents
.slice(fileComponents.length - pathSlicesDepthFromEnd)
.join("/");
return dirContent.map(async (fileName) => { const content = await fs.readFile(filePath);
const content = await fs.readFile(path.resolve(filePath, fileName));
return getObjectFromModelFile( return [fileName, content];
path.resolve(filePath, fileName),
content,
2,
);
});
} }