mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Remove rra dependency
This commit is contained in:
parent
6fc70b8656
commit
e623bf7fde
5
package-lock.json
generated
5
package-lock.json
generated
@ -977,11 +977,6 @@
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"recursive-readdir-async": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/recursive-readdir-async/-/recursive-readdir-async-1.2.1.tgz",
|
||||
"integrity": "sha512-fU8aySmHIhrycTlXn+hI7dS/p7GnrMHzr2xDdBSd8HZ16mbLkmfIEccIE80gLHftrkTt9oDJiGEJNIPY6n0v6A=="
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -44,7 +44,6 @@
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"node-ffprobe": "^3.0.0",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"recursive-readdir-async": "^1.1.8",
|
||||
"socket.io": "^4.4.1",
|
||||
"xml2js": "^0.4.23"
|
||||
}
|
||||
|
391
server/libs/recursiveReaddirAsync/index.js
Normal file
391
server/libs/recursiveReaddirAsync/index.js
Normal file
@ -0,0 +1,391 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @packageDocumentation
|
||||
* project: recursive-readdir-async
|
||||
* @author: m0rtadelo (ricard.figuls)
|
||||
* @license MIT
|
||||
* 2018
|
||||
*/
|
||||
|
||||
// SOURCE: https://github.com/m0rtadelo/recursive-readdir-async
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function (o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
|
||||
}) : (function (o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function (o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function (o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.list = exports.readFile = exports.stat = exports.PATH = exports.FS = exports.TREE = exports.LIST = void 0;
|
||||
/** @readonly constant for mode LIST to be used in Options */
|
||||
exports.LIST = 1;
|
||||
/** @readonly constant for mode TREE to be used in Options */
|
||||
exports.TREE = 2;
|
||||
/**
|
||||
* native FS module
|
||||
* @see https://nodejs.org/api/fs.html#fs_file_system
|
||||
* @external
|
||||
*/
|
||||
const _fs = __importStar(require("fs"));
|
||||
/** native node fs object */
|
||||
exports.FS = _fs;
|
||||
/**
|
||||
* native PATH module
|
||||
* @external
|
||||
* @see https://nodejs.org/api/path.html#path_path
|
||||
*/
|
||||
const _path = __importStar(require("path"));
|
||||
/** native node path object */
|
||||
exports.PATH = _path;
|
||||
let pathSimbol = '/';
|
||||
/**
|
||||
* Returns a Promise with Stats info of the item (file/folder/...)
|
||||
* @param file the name of the object to get stats from
|
||||
* @returns {Promise<fs.Stats>} stat object information
|
||||
* @async
|
||||
*/
|
||||
function stat(file) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.FS.stat(file, function (err, stats) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(stats);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.stat = stat;
|
||||
/**
|
||||
* Returns a Promise with content (data) of the file
|
||||
* @param file the name of the file to read content from
|
||||
* @param encoding format for returned data (ascii, base64, binary, hex, ucs2/ucs-2/utf16le/utf-16le,
|
||||
* utf8/utf-8, latin1). Default: base64
|
||||
* @returns {Promise<string>} data content string (base64 format by default)
|
||||
* @async
|
||||
*/
|
||||
function readFile(file, encoding = 'base64') {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return new Promise(function (resolve, reject) {
|
||||
exports.FS.readFile(file, { encoding }, function (err, data) {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.readFile = readFile;
|
||||
/**
|
||||
* Returns if an item should be added based on include/exclude options.
|
||||
* @param path the item fullpath
|
||||
* @param settings the options configuration to use
|
||||
* @returns {boolean} if item must be added
|
||||
* @private
|
||||
*/
|
||||
function checkItem(path, settings) {
|
||||
if (settings.exclude) {
|
||||
for (const value of settings.exclude) {
|
||||
if (path.includes(value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Adds optional keys to item
|
||||
* @param obj the item object
|
||||
* @param file the filename
|
||||
* @param settings the options configuration to use
|
||||
* @param deep The deep level
|
||||
* @returns void
|
||||
* @private
|
||||
*/
|
||||
function addOptionalKeys(obj, file, settings, deep) {
|
||||
if (settings.extensions) {
|
||||
obj.extension = (exports.PATH.extname(file)).toLowerCase();
|
||||
}
|
||||
if (settings.deep) {
|
||||
obj.deep = deep;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Reads content and creates a valid IBase collection
|
||||
* @param rpath Path relative to
|
||||
* @param data Model
|
||||
* @param settings the options configuration to use
|
||||
* @param deep The deep level
|
||||
* @param resolve Promise
|
||||
* @param reject Promise
|
||||
* @returns void
|
||||
*/
|
||||
function read(rpath, data, settings, deep, resolve, reject) {
|
||||
exports.FS.readdir(rpath, function (error, files) {
|
||||
// If error reject them
|
||||
if (error) {
|
||||
reject(error);
|
||||
}
|
||||
else {
|
||||
const removeExt = (file) => {
|
||||
const extSize = exports.PATH.extname(file).length;
|
||||
return file.substring(0, file.length - (extSize > 0 ? extSize : 0));
|
||||
};
|
||||
// Iterate through elements (files and folders)
|
||||
for (const file of files) {
|
||||
const obj = {
|
||||
name: file,
|
||||
title: removeExt(file),
|
||||
path: rpath,
|
||||
fullname: rpath + (rpath.endsWith(pathSimbol) ? '' : pathSimbol) + file,
|
||||
};
|
||||
if (checkItem(obj.fullname, settings)) {
|
||||
addOptionalKeys(obj, file, settings, deep);
|
||||
data.push(obj);
|
||||
}
|
||||
}
|
||||
// Finish, returning content
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Returns a Promise with an objects info array
|
||||
* @param path the item fullpath to be searched for
|
||||
* @param settings the options configuration to use
|
||||
* @param deep folder depth value
|
||||
* @returns {Promise<IBase[]>} the file object info
|
||||
* @private
|
||||
*/
|
||||
function myReaddir(path, settings, deep) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const data = [];
|
||||
return new Promise(function (resolve, reject) {
|
||||
try {
|
||||
// Asynchronously computes the canonical pathname by resolving ., .. and symbolic links.
|
||||
exports.FS.realpath(path, function (err, rpath) {
|
||||
if (err || settings.realPath === false) {
|
||||
rpath = path;
|
||||
}
|
||||
// Normalizes windows style paths by replacing double backslahes with single forward slahes (unix style).
|
||||
if (settings.normalizePath) {
|
||||
rpath = normalizePath(rpath);
|
||||
}
|
||||
// Reading contents of path
|
||||
read(rpath, data, settings, deep, resolve, reject);
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
// If error reject them
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Normalizes windows style paths by replacing double backslahes with single forward slahes (unix style).
|
||||
* @param path windows/unix path
|
||||
* @return {string} normalized path (unix style)
|
||||
* @private
|
||||
*/
|
||||
function normalizePath(path) {
|
||||
return path.toString().replace(/\\/g, '/');
|
||||
}
|
||||
/**
|
||||
* Search if the fullname exist in the include array
|
||||
* @param fullname - The fullname of the item to search for
|
||||
* @param settings the options to be used
|
||||
* @returns true if exists
|
||||
*/
|
||||
function exists(fullname, settings) {
|
||||
if (settings.include) {
|
||||
for (const value of settings.include) {
|
||||
if (fullname.includes(value)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Removes paths that not match the include array
|
||||
* @param settings the options to be used
|
||||
* @param content items list
|
||||
* @returns void
|
||||
*/
|
||||
function onlyInclude(settings, content) {
|
||||
if (settings.include && settings.include.length > 0) {
|
||||
for (let i = content.length - 1; i > -1; i--) {
|
||||
const item = content[i];
|
||||
if (settings.mode === exports.TREE && item.isDirectory && item.content)
|
||||
continue;
|
||||
if (!exists(item.fullname, settings)) {
|
||||
content.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns an array of items in path
|
||||
* @param path path
|
||||
* @param settings the options to be used
|
||||
* @param progress callback progress
|
||||
* @param deep deep index information
|
||||
* @returns {object[]} array with file information
|
||||
* @private
|
||||
*/
|
||||
function listDir(path, settings, progress, deep = 0) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let content;
|
||||
try {
|
||||
content = yield myReaddir(path, settings, deep);
|
||||
}
|
||||
catch (err) {
|
||||
return { 'error': err, 'path': path };
|
||||
}
|
||||
if (settings.stats || settings.recursive || !settings.ignoreFolders ||
|
||||
settings.readContent || settings.mode === exports.TREE) {
|
||||
content = yield statDir(content, settings, progress, deep);
|
||||
}
|
||||
onlyInclude(settings, content);
|
||||
return content;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Returns an object with all items with selected options
|
||||
* @param collection items list
|
||||
* @param settings the options to use
|
||||
* @param progress callback progress
|
||||
* @param deep folder depth
|
||||
* @returns {object[]} array with file information
|
||||
* @private
|
||||
*/
|
||||
function statDir(collection, settings, progress, deep) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let isOk = true;
|
||||
for (let i = collection.length - 1; i > -1; i--) {
|
||||
try {
|
||||
collection = yield statDirItem(collection, i, settings, progress, deep);
|
||||
if (progress !== undefined) {
|
||||
isOk = !progress(collection[i], collection.length - i, collection.length);
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
collection[i].error = err;
|
||||
}
|
||||
if ((collection[i].isDirectory && settings.ignoreFolders &&
|
||||
!(collection[i].content) && collection[i].error === undefined) || !isOk) {
|
||||
collection.splice(i, 1);
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Returns an object with updated item information
|
||||
* @param collection items list
|
||||
* @param i index of item
|
||||
* @param settings the options to use
|
||||
* @param progress callback progress
|
||||
* @param deep folder depth
|
||||
* @returns {object[]} array with file information
|
||||
* @private
|
||||
*/
|
||||
function statDirItem(collection, i, settings, progress, deep) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const stats = yield stat(collection[i].fullname);
|
||||
collection[i].isDirectory = stats.isDirectory();
|
||||
if (settings.stats) {
|
||||
collection[i].stats = stats;
|
||||
}
|
||||
if (settings.readContent && !collection[i].isDirectory) {
|
||||
collection[i].data = yield readFile(collection[i].fullname, settings.encoding);
|
||||
}
|
||||
if (collection[i].isDirectory && settings.recursive) {
|
||||
const item = collection[i];
|
||||
if (settings.mode === exports.LIST) {
|
||||
const result = yield listDir(item.fullname, settings, progress, deep + 1);
|
||||
if (result.length) {
|
||||
collection = collection.concat(result);
|
||||
}
|
||||
}
|
||||
else {
|
||||
item.content = yield listDir(item.fullname, settings, progress, deep + 1);
|
||||
if (item.content && item.content.length === 0) {
|
||||
item.content = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Returns a javascript object with directory items information (non blocking async with Promises)
|
||||
* @param path the path to start reading contents
|
||||
* @param [options] options (mode, recursive, stats, ignoreFolders)
|
||||
* @param [progress] callback with item data and progress info for each item
|
||||
* @returns promise array with file/folder information
|
||||
* @async
|
||||
*/
|
||||
function list(path, options, progress) {
|
||||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
// options skipped?
|
||||
if (typeof options === 'function') {
|
||||
progress = options;
|
||||
}
|
||||
// Setting default settings
|
||||
const settings = {
|
||||
mode: ((_a = options) === null || _a === void 0 ? void 0 : _a.mode) || exports.LIST,
|
||||
recursive: ((_b = options) === null || _b === void 0 ? void 0 : _b.recursive) === undefined ? true : options.recursive,
|
||||
stats: ((_c = options) === null || _c === void 0 ? void 0 : _c.stats) === undefined ? false : options.stats,
|
||||
ignoreFolders: ((_d = options) === null || _d === void 0 ? void 0 : _d.ignoreFolders) === undefined ? true : options.ignoreFolders,
|
||||
extensions: ((_e = options) === null || _e === void 0 ? void 0 : _e.extensions) === undefined ? false : options.extensions,
|
||||
deep: ((_f = options) === null || _f === void 0 ? void 0 : _f.deep) === undefined ? false : options.deep,
|
||||
realPath: ((_g = options) === null || _g === void 0 ? void 0 : _g.realPath) === undefined ? true : options.realPath,
|
||||
normalizePath: ((_h = options) === null || _h === void 0 ? void 0 : _h.normalizePath) === undefined ? true : options.normalizePath,
|
||||
include: ((_j = options) === null || _j === void 0 ? void 0 : _j.include) || [],
|
||||
exclude: ((_k = options) === null || _k === void 0 ? void 0 : _k.exclude) || [],
|
||||
readContent: ((_l = options) === null || _l === void 0 ? void 0 : _l.readContent) === undefined ? false : options.readContent,
|
||||
encoding: ((_m = options) === null || _m === void 0 ? void 0 : _m.encoding) || undefined,
|
||||
};
|
||||
// Setting pathSimbol if normalizePath is disabled
|
||||
if (settings.normalizePath === false) {
|
||||
pathSimbol = exports.PATH.sep;
|
||||
}
|
||||
else {
|
||||
pathSimbol = '/';
|
||||
}
|
||||
// Reading contents
|
||||
return listDir(path, settings, progress);
|
||||
});
|
||||
}
|
||||
exports.list = list;
|
@ -1,5 +1,5 @@
|
||||
const fs = require('fs-extra')
|
||||
const rra = require('recursive-readdir-async')
|
||||
const rra = require('../libs/recursiveReaddirAsync')
|
||||
const axios = require('axios')
|
||||
const Path = require('path')
|
||||
const Logger = require('../Logger')
|
||||
|
Loading…
Reference in New Issue
Block a user