diff --git a/Dockerfile b/Dockerfile
index 6962f8c..b05dbb9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -47,11 +47,11 @@ RUN npm config set strict-ssl false && \
# Final image
FROM base
-RUN npm install -g pm2 && \
- apt update && \
- apt install -y --no-install-recommends gosu python3-minimal python-is-python3 atomicparsley && \
+RUN apt update && \
+ apt install -y --no-install-recommends gosu python3-minimal python-is-python3 python3-pip atomicparsley && \
apt clean && \
rm -rf /var/lib/apt/lists/*
+RUN pip install tcd
WORKDIR /app
# User 1000 already exist from base image
COPY --chown=$UID:$GID --from=ffmpeg [ "/usr/local/bin/ffmpeg", "/usr/local/bin/ffmpeg" ]
@@ -64,4 +64,4 @@ RUN chmod +x /app/fix-scripts/*.sh
EXPOSE 17442
ENTRYPOINT [ "/app/entrypoint.sh" ]
-CMD [ "pm2-runtime","--raw","pm2.config.js" ]
+CMD [ "npm","start" ]
diff --git a/Dockerfile.heroku b/Dockerfile.heroku
index b2ff8b3..977a446 100644
--- a/Dockerfile.heroku
+++ b/Dockerfile.heroku
@@ -1,2 +1,2 @@
-FROM tzahi12345/youtubedl-material:nightly
-CMD [ "pm2-runtime", "pm2.config.js" ]
\ No newline at end of file
+FROM tzahi12345/youtubedl-material:latest
+CMD [ "npm", "start" ]
\ No newline at end of file
diff --git a/Public API v1.yaml b/Public API v1.yaml
index f554398..9f335f8 100644
--- a/Public API v1.yaml
+++ b/Public API v1.yaml
@@ -97,6 +97,11 @@ paths:
summary: Get all files
description: Gets all files and playlists stored in the db
operationId: get-getAllFiles
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/GetAllFilesRequest'
responses:
'200':
description: OK
@@ -1724,6 +1729,41 @@ components:
description: All video playlists
items:
$ref: '#/components/schemas/Playlist'
+ GetAllFilesRequest:
+ type: object
+ properties:
+ sort:
+ $ref: '#/components/schemas/Sort'
+ range:
+ type: array
+ items:
+ type: number
+ description: Two elements allowed, start index and end index
+ minItems: 2
+ maxItems: 2
+ text_search:
+ type: string
+ description: Filter files by title
+ file_type_filter:
+ $ref: '#/components/schemas/FileTypeFilter'
+ sub_id:
+ type: string
+ description: Include if you want to filter by subscription
+ Sort:
+ type: object
+ properties:
+ by:
+ type: string
+ description: Property to sort by
+ order:
+ type: number
+ description: 1 for ascending, -1 for descending
+ FileTypeFilter:
+ type: string
+ enum:
+ - audio_only
+ - video_only
+ - both
GetAllFilesResponse:
required:
- files
@@ -1786,7 +1826,6 @@ components:
required:
- name
- url
- - streamingOnly
type: object
properties:
name:
@@ -1899,7 +1938,6 @@ components:
- uids
- playlistName
- thumbnailURL
- - type
type: object
properties:
playlistName:
@@ -1908,8 +1946,6 @@ components:
type: array
items:
type: string
- type:
- $ref: '#/components/schemas/FileType'
thumbnailURL:
type: string
CreatePlaylistResponse:
@@ -1939,15 +1975,17 @@ components:
required:
- playlist
- success
- - type
type: object
properties:
playlist:
$ref: '#/components/schemas/Playlist'
- type:
- $ref: '#/components/schemas/FileType'
success:
type: boolean
+ file_objs:
+ type: array
+ description: File objects for every uid in the playlist's uids property, in the same order
+ items:
+ $ref: '#/components/schemas/DatabaseFile'
GetPlaylistsRequest:
type: object
properties:
@@ -1972,13 +2010,10 @@ components:
DeletePlaylistRequest:
required:
- playlist_id
- - type
type: object
properties:
playlist_id:
type: string
- type:
- $ref: '#/components/schemas/FileType'
DownloadFileRequest:
type: object
properties:
@@ -2385,6 +2420,16 @@ components:
type: number
local_view_count:
type: number
+ sub_id:
+ type: string
+ registered:
+ type: number
+ height:
+ type: number
+ description: In pixels, only for videos
+ abr:
+ type: number
+ description: In Kbps
Playlist:
required:
- uids
@@ -2466,6 +2511,8 @@ components:
type: string
sub_name:
type: string
+ prefetched_info:
+ type: object
Task:
required:
- key
@@ -2480,6 +2527,8 @@ components:
properties:
key:
type: string
+ title:
+ type: string
last_ran:
type: number
last_confirmed:
@@ -2560,7 +2609,6 @@ components:
- url
- type
- user_uid
- - streamingOnly
- isPlaylist
- videos
type: object
@@ -2576,8 +2624,6 @@ components:
user_uid:
type: string
nullable: true
- streamingOnly:
- type: boolean
isPlaylist:
type: boolean
archive:
diff --git a/README.md b/README.md
index bf4c4f2..6dc0c46 100644
--- a/README.md
+++ b/README.md
@@ -12,16 +12,6 @@ Now with [Docker](#Docker) support!
-### USAGE OF THE NIGHTLY BUILDS IS HIGHLY RECOMMENDED.
-
-For much better scaling with large datasets please run your YTDL-M instance with a MongoDB backend rather than the json file-based default.
-It will fix a lot of performance problems (especially with datasets in the tens of thousands videos/audios)!
-The (closed) issues as well as the project's Wiki will give you good starting points for your journey!
-
-For MongoDB specifically there is [this little guide](https://github.com/Tzahi12345/YoutubeDL-Material/wiki/Setting-a-MongoDB-backend-to-use-as-database-provider-for-YTDL-M).
-
-
-
## Getting Started
Check out the prerequisites, and go to the installation section. Easy as pie!
@@ -58,6 +48,7 @@ sudo yum install nodejs youtube-dl ffmpeg ffmpeg-devel
Optional dependencies:
* AtomicParsley (for embedding thumbnails, package name `atomicparsley`)
+* [tcd](https://github.com/PetterKraabol/Twitch-Chat-Downloader) (for downloading Twitch VOD chats)
### Installing
@@ -91,7 +82,7 @@ Alternatively, you can port forward the port specified in the config (defaults t
### Host-specific instructions
-If you're on a Synology NAS, unRAID or any other possible special case you can check if there's known issues or instructions both in the issue tracker and in the [Wiki!](https://github.com/Tzahi12345/YoutubeDL-Material/wiki#environment-specific-guideshelp)
+If you're on a Synology NAS, unRAID, Raspberry Pi 4 or any other possible special case you can check if there's known issues or instructions both in the issue tracker and in the [Wiki!](https://github.com/Tzahi12345/YoutubeDL-Material/wiki#environment-specific-guideshelp)
### Setup
@@ -102,8 +93,6 @@ If you are looking to setup YoutubeDL-Material with Docker, this section is for
3. Run `docker-compose up` to start it up. If successful, it should say "HTTP(S): Started on port 17443" or something similar. This tells you the *container-internal* port of the application. Please check your `docker-compose.yml` file for the *external* port. If you downloaded the file as described above, it defaults to **8998**.
4. Make sure you can connect to the specified URL + *external* port, and if so, you are done!
-NOTE: It is currently recommended that you use the `nightly` tag on Docker. To do so, simply update the docker-compose.yml `image` field so that it points to `tzahi12345/youtubedl-material:nightly`.
-
### Custom UID/GID
By default, the Docker container runs as non-root with UID=1000 and GID=1000. To set this to your own UID/GID, simply update the `environment` section in your `docker-compose.yml` like so:
@@ -114,6 +103,12 @@ environment:
GID: YOUR_GID
```
+## MongoDB
+
+For much better scaling with large datasets please run your YoutubeDL-Material instance with MongoDB backend rather than the json file-based default. It will fix a lot of performance problems (especially with datasets in the tens of thousands videos/audios)!
+
+[Tutorial](https://github.com/Tzahi12345/YoutubeDL-Material/wiki/Setting-a-MongoDB-backend-to-use-as-database-provider-for-YTDL-M).
+
## API
[API Docs](https://youtubedl-material.stoplight.io/docs/youtubedl-material/Public%20API%20v1.yaml)
diff --git a/SECURITY.md b/SECURITY.md
index 18daadb..0601c7a 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,16 +2,16 @@
## Supported Versions
-Currently all work on this project goes into the nightly builds.
-4.2's RELEASE build is now quite old and should be considered legacy.
-We urge users to use the nightly releases, because the project
-constantly sees fixes.
+If you would like to see the latest updates, use the `nightly` tag on Docker.
-| Version | Supported |
-| ------------- | ------------------ |
-| 4.2 Nightlies | :white_check_mark: |
-| 4.2 Release | :x: |
-| < 4.2 | :x: |
+If you'd like to stick with more stable releases, use the `latest` tag on Docker or download the [latest release here](https://github.com/Tzahi12345/YoutubeDL-Material/releases/latest).
+
+| Version | Supported |
+| -------------------- | ------------------ |
+| 4.3 Docker Nightlies | :white_check_mark: |
+| 4.3 Release | :white_check_mark: |
+| 4.2 Release | :x: |
+| < 4.2 | :x: |
## Reporting a Vulnerability
diff --git a/backend/app.js b/backend/app.js
index a508702..514d82b 100644
--- a/backend/app.js
+++ b/backend/app.js
@@ -101,7 +101,6 @@ let backendPort = null;
let useDefaultDownloadingAgent = null;
let customDownloadingAgent = null;
let allowSubscriptions = null;
-let archivePath = path.join(__dirname, 'appdata', 'archives');
// other needed values
let url_domain = null;
@@ -500,12 +499,13 @@ async function loadConfig() {
loadConfigValues();
// connect to DB
- await db_api.connectToDB();
+ if (!config_api.getConfigItem('ytdl_use_local_db'))
+ await db_api.connectToDB();
db_api.database_initialized = true;
db_api.database_initialized_bs.next(true);
// creates archive path if missing
- await fs.ensureDir(archivePath);
+ await fs.ensureDir(utils.getArchiveFolder());
// check migrations
await checkMigrations();
@@ -912,11 +912,11 @@ app.post('/api/getFile', optionalJwt, async function (req, res) {
app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
// these are returned
let files = null;
- let playlists = null;
- let sort = req.body.sort;
- let range = req.body.range;
- let text_search = req.body.text_search;
- let file_type_filter = req.body.file_type_filter;
+ const sort = req.body.sort;
+ const range = req.body.range;
+ const text_search = req.body.text_search;
+ const file_type_filter = req.body.file_type_filter;
+ const sub_id = req.body.sub_id;
const uuid = req.isAuthenticated() ? req.user.uid : null;
const filter_obj = {user_uid: uuid};
@@ -929,6 +929,10 @@ app.post('/api/getAllFiles', optionalJwt, async function (req, res) {
}
}
+ if (sub_id) {
+ filter_obj['sub_id'] = sub_id;
+ }
+
if (file_type_filter === 'audio_only') filter_obj['isAudio'] = true;
else if (file_type_filter === 'video_only') filter_obj['isAudio'] = false;
@@ -1268,7 +1272,7 @@ app.post('/api/getSubscription', optionalJwt, async (req, res) => {
subscription = JSON.parse(JSON.stringify(subscription));
// get sub videos
- if (subscription.name && !subscription.streamingOnly) {
+ if (subscription.name) {
var parsed_files = await db_api.getRecords('files', {sub_id: subscription.id}); // subscription.videos;
subscription['videos'] = parsed_files;
// loop through files for extra processing
@@ -1278,19 +1282,6 @@ app.post('/api/getSubscription', optionalJwt, async (req, res) => {
if (file && file['url'].includes('twitch.tv')) file['chat_exists'] = fs.existsSync(file['path'].substring(0, file['path'].length - 4) + '.twitch_chat.json');
}
- res.send({
- subscription: subscription,
- files: parsed_files
- });
- } else if (subscription.name && subscription.streamingOnly) {
- // return list of videos
- let parsed_files = [];
- if (subscription.videos) {
- for (let i = 0; i < subscription.videos.length; i++) {
- const video = subscription.videos[i];
- parsed_files.push(new utils.File(video.title, video.title, video.thumbnail, false, video.duration, video.url, video.uploader, video.size, null, null, video.upload_date, video.view_count, video.height, video.abr));
- }
- }
res.send({
subscription: subscription,
files: parsed_files
@@ -1335,9 +1326,8 @@ app.post('/api/getSubscriptions', optionalJwt, async (req, res) => {
app.post('/api/createPlaylist', optionalJwt, async (req, res) => {
let playlistName = req.body.playlistName;
let uids = req.body.uids;
- let type = req.body.type;
- const new_playlist = await db_api.createPlaylist(playlistName, uids, type, req.isAuthenticated() ? req.user.uid : null);
+ const new_playlist = await db_api.createPlaylist(playlistName, uids, req.isAuthenticated() ? req.user.uid : null);
res.send({
new_playlist: new_playlist,
@@ -1365,7 +1355,6 @@ app.post('/api/getPlaylist', optionalJwt, async (req, res) => {
res.send({
playlist: playlist,
file_objs: file_objs,
- type: playlist && playlist.type,
success: !!playlist
});
});
diff --git a/backend/appdata/default.json b/backend/appdata/default.json
index 44f2f02..d0425c6 100644
--- a/backend/appdata/default.json
+++ b/backend/appdata/default.json
@@ -31,7 +31,8 @@
"use_youtube_API": false,
"youtube_API_key": "",
"use_twitch_API": false,
- "twitch_API_key": "",
+ "twitch_client_ID": "",
+ "twitch_client_secret": "",
"twitch_auto_download_chat": false,
"use_sponsorblock_API": false,
"generate_NFO_files": false
@@ -63,7 +64,7 @@
"mongodb_connection_string": "mongodb://127.0.0.1:27017/?compressors=zlib"
},
"Advanced": {
- "default_downloader": "youtube-dl",
+ "default_downloader": "yt-dlp",
"use_default_downloading_agent": true,
"custom_downloading_agent": "",
"multi_user_mode": false,
diff --git a/backend/config.js b/backend/config.js
index 4e208fb..7b1908e 100644
--- a/backend/config.js
+++ b/backend/config.js
@@ -206,7 +206,8 @@ const DEFAULT_CONFIG = {
"use_youtube_API": false,
"youtube_API_key": "",
"use_twitch_API": false,
- "twitch_API_key": "",
+ "twitch_client_ID": "",
+ "twitch_client_secret": "",
"twitch_auto_download_chat": false,
"use_sponsorblock_API": false,
"generate_NFO_files": false
@@ -238,7 +239,7 @@ const DEFAULT_CONFIG = {
"mongodb_connection_string": "mongodb://127.0.0.1:27017/?compressors=zlib"
},
"Advanced": {
- "default_downloader": "youtube-dl",
+ "default_downloader": "yt-dlp",
"use_default_downloading_agent": true,
"custom_downloading_agent": "",
"multi_user_mode": false,
diff --git a/backend/consts.js b/backend/consts.js
index 9bd2905..f473e07 100644
--- a/backend/consts.js
+++ b/backend/consts.js
@@ -102,9 +102,13 @@ exports.CONFIG_ITEMS = {
'key': 'ytdl_use_twitch_api',
'path': 'YoutubeDLMaterial.API.use_twitch_API'
},
- 'ytdl_twitch_api_key': {
- 'key': 'ytdl_twitch_api_key',
- 'path': 'YoutubeDLMaterial.API.twitch_API_key'
+ 'ytdl_twitch_client_id': {
+ 'key': 'ytdl_twitch_client_id',
+ 'path': 'YoutubeDLMaterial.API.twitch_client_ID'
+ },
+ 'ytdl_twitch_client_secret': {
+ 'key': 'ytdl_twitch_client_secret',
+ 'path': 'YoutubeDLMaterial.API.twitch_client_secret'
},
'ytdl_twitch_auto_download_chat': {
'key': 'ytdl_twitch_auto_download_chat',
@@ -301,4 +305,4 @@ const YTDL_ARGS_WITH_VALUES = [
// we're using a Set here for performance
exports.YTDL_ARGS_WITH_VALUES = new Set(YTDL_ARGS_WITH_VALUES);
-exports.CURRENT_VERSION = 'v4.2';
+exports.CURRENT_VERSION = 'v4.3';
diff --git a/backend/db.js b/backend/db.js
index 73f56f1..99d781d 100644
--- a/backend/db.js
+++ b/backend/db.js
@@ -357,7 +357,7 @@ exports.addMetadataPropertyToDB = async (property_key) => {
}
}
-exports.createPlaylist = async (playlist_name, uids, type, user_uid = null) => {
+exports.createPlaylist = async (playlist_name, uids, user_uid = null) => {
const first_video = await exports.getVideo(uids[0]);
const thumbnailToUse = first_video['thumbnailURL'];
@@ -366,7 +366,6 @@ exports.createPlaylist = async (playlist_name, uids, type, user_uid = null) => {
uids: uids,
id: uuid(),
thumbnailURL: thumbnailToUse,
- type: type,
registered: Date.now(),
randomize_order: false
};
@@ -495,8 +494,7 @@ exports.deleteFile = async (uid, uuid = null, blacklistMode = false) => {
let useYoutubeDLArchive = config_api.getConfigItem('ytdl_use_youtubedl_archive');
if (useYoutubeDLArchive) {
- const usersFileFolder = config_api.getConfigItem('ytdl_users_base_path');
- const archive_path = uuid ? path.join(usersFileFolder, uuid, 'archives', `archive_${type}.txt`) : path.join('appdata', 'archives', `archive_${type}.txt`);
+ const archive_path = utils.getArchiveFolder(type, uuid);
// get ID from JSON
@@ -504,14 +502,8 @@ exports.deleteFile = async (uid, uuid = null, blacklistMode = false) => {
let id = null;
if (jsonobj) id = jsonobj.id;
- // use subscriptions API to remove video from the archive file, and write it to the blacklist
- if (await fs.pathExists(archive_path)) {
- const line = id ? await utils.removeIDFromArchive(archive_path, id) : null;
- if (blacklistMode && line) await writeToBlacklist(type, line);
- } else {
- logger.info('Could not find archive file for audio files. Creating...');
- await fs.close(await fs.open(archive_path, 'w'));
- }
+ // Remove file ID from the archive file, and write it to the blacklist (if enabled)
+ await utils.deleteFileFromArchive(uid, type, archive_path, id, blacklistMode);
}
if (jsonExists) await fs.unlink(jsonPath);
@@ -1111,15 +1103,3 @@ exports.applyFilterLocalDB = (db_path, filter_obj, operation) => {
});
return return_val;
}
-
-// archive helper functions
-
-async function writeToBlacklist(type, line) {
- const archivePath = path.join(__dirname, 'appdata', 'archives');
- let blacklistPath = path.join(archivePath, (type === 'audio') ? 'blacklist_audio.txt' : 'blacklist_video.txt');
- // adds newline to the beginning of the line
- line.replace('\n', '');
- line.replace('\r', '');
- line = '\n' + line;
- await fs.appendFile(blacklistPath, line);
-}
diff --git a/backend/downloader.js b/backend/downloader.js
index aef46f1..ce4223c 100644
--- a/backend/downloader.js
+++ b/backend/downloader.js
@@ -18,8 +18,6 @@ const db_api = require('./db');
const mutex = new Mutex();
let should_check_downloads = true;
-const archivePath = path.join(__dirname, 'appdata', 'archives');
-
if (db_api.database_initialized) {
setupDownloads();
} else {
@@ -28,7 +26,7 @@ if (db_api.database_initialized) {
});
}
-exports.createDownload = async (url, type, options, user_uid = null, sub_id = null, sub_name = null) => {
+exports.createDownload = async (url, type, options, user_uid = null, sub_id = null, sub_name = null, prefetched_info = null) => {
return await mutex.runExclusive(async () => {
const download = {
url: url,
@@ -37,6 +35,7 @@ exports.createDownload = async (url, type, options, user_uid = null, sub_id = nu
user_uid: user_uid,
sub_id: sub_id,
sub_name: sub_name,
+ prefetched_info: prefetched_info,
options: options,
uid: uuid(),
step_index: 0,
@@ -187,7 +186,7 @@ async function collectInfo(download_uid) {
let args = await exports.generateArgs(url, type, options, download['user_uid']);
// get video info prior to download
- let info = await exports.getVideoInfoByURL(url, args, download_uid);
+ let info = download['prefetched_info'] ? download['prefetched_info'] : await exports.getVideoInfoByURL(url, args, download_uid);
if (!info) {
// info failed, error presumably already recorded
@@ -229,7 +228,8 @@ async function collectInfo(download_uid) {
options: options,
files_to_check_for_progress: files_to_check_for_progress,
expected_file_size: expected_file_size,
- title: playlist_title ? playlist_title : info['title']
+ title: playlist_title ? playlist_title : info['title'],
+ prefetched_info: null
});
}
@@ -242,6 +242,7 @@ async function downloadQueuedFile(download_uid) {
return new Promise(async resolve => {
const audioFolderPath = config_api.getConfigItem('ytdl_audio_folder_path');
const videoFolderPath = config_api.getConfigItem('ytdl_video_folder_path');
+ const usersFolderPath = config_api.getConfigItem('ytdl_users_base_path');
await db_api.updateRecord('download_queue', {uid: download_uid}, {step_index: 2, finished_step: false, running: true});
const url = download['url'];
@@ -249,9 +250,11 @@ async function downloadQueuedFile(download_uid) {
const options = download['options'];
const args = download['args'];
const category = download['category'];
- let fileFolderPath = type === 'audio' ? audioFolderPath : videoFolderPath; // TODO: fix
+ let fileFolderPath = type === 'audio' ? audioFolderPath : videoFolderPath;
if (options.customFileFolderPath) {
fileFolderPath = options.customFileFolderPath;
+ } else if (download['user_uid']) {
+ fileFolderPath = path.join(usersFolderPath, download['user_uid'], type);
}
fs.ensureDirSync(fileFolderPath);
@@ -373,15 +376,23 @@ async function downloadQueuedFile(download_uid) {
// helper functions
exports.generateArgs = async (url, type, options, user_uid = null, simulated = false) => {
+ const default_downloader = utils.getCurrentDownloader() || config_api.getConfigItem('ytdl_default_downloader');
+
const audioFolderPath = config_api.getConfigItem('ytdl_audio_folder_path');
const videoFolderPath = config_api.getConfigItem('ytdl_video_folder_path');
+ const usersFolderPath = config_api.getConfigItem('ytdl_users_base_path');
const videopath = config_api.getConfigItem('ytdl_default_file_output') ? config_api.getConfigItem('ytdl_default_file_output') : '%(title)s';
const globalArgs = config_api.getConfigItem('ytdl_custom_args');
const useCookies = config_api.getConfigItem('ytdl_use_cookies');
const is_audio = type === 'audio';
- let fileFolderPath = is_audio ? audioFolderPath : videoFolderPath;
+ let fileFolderPath = type === 'audio' ? audioFolderPath : videoFolderPath; // TODO: fix
+ if (options.customFileFolderPath) {
+ fileFolderPath = options.customFileFolderPath;
+ } else if (user_uid) {
+ fileFolderPath = path.join(usersFolderPath, user_uid, fileFolderPath);
+ }
if (options.customFileFolderPath) fileFolderPath = options.customFileFolderPath;
@@ -404,8 +415,6 @@ exports.generateArgs = async (url, type, options, user_uid = null, simulated = f
if (!is_audio && !is_youtube) {
// tiktok videos fail when using the default format
qualityPath = null;
- } else if (!is_audio && !is_youtube && (url.includes('reddit') || url.includes('pornhub'))) {
- qualityPath = ['-f', 'bestvideo+bestaudio']
}
if (customArgs) {
@@ -414,7 +423,7 @@ exports.generateArgs = async (url, type, options, user_uid = null, simulated = f
if (customQualityConfiguration) {
qualityPath = ['-f', customQualityConfiguration, '--merge-output-format', 'mp4'];
} else if (selectedHeight && selectedHeight !== '' && !is_audio) {
- qualityPath = ['-f', `'(mp4)[height=${selectedHeight}'`];
+ qualityPath = ['-f', `'(mp4)[height=${selectedHeight}]`];
} else if (is_audio) {
qualityPath = ['--audio-quality', maxBitrate ? maxBitrate : '0']
}
@@ -496,7 +505,6 @@ exports.generateArgs = async (url, type, options, user_uid = null, simulated = f
downloadConfig.push('-r', rate_limit);
}
- const default_downloader = utils.getCurrentDownloader() || config_api.getConfigItem('ytdl_default_downloader');
if (default_downloader === 'yt-dlp') {
downloadConfig.push('--no-clean-infojson');
}
@@ -506,7 +514,7 @@ exports.generateArgs = async (url, type, options, user_uid = null, simulated = f
// filter out incompatible args
downloadConfig = filterArgs(downloadConfig, is_audio);
- if (!simulated) logger.verbose(`youtube-dl args being used: ${downloadConfig.join(',')}`);
+ if (!simulated) logger.verbose(`${default_downloader} args being used: ${downloadConfig.join(',')}`);
return downloadConfig;
}
@@ -565,8 +573,7 @@ exports.getVideoInfoByURL = async (url, args = [], download_uid = null) => {
function filterArgs(args, isAudio) {
const video_only_args = ['--add-metadata', '--embed-subs', '--xattrs'];
const audio_only_args = ['-x', '--extract-audio', '--embed-thumbnail'];
- const args_to_remove = isAudio ? video_only_args : audio_only_args;
- return args.filter(x => !args_to_remove.includes(x));
+ return utils.filterArgs(args, isAudio ? video_only_args : audio_only_args);
}
async function checkDownloadPercent(download_uid) {
@@ -628,6 +635,6 @@ function getArchiveFolder(fileFolderPath, options, user_uid) {
} else if (user_uid) {
return path.join(fileFolderPath, 'archives');
} else {
- return path.join(archivePath);
+ return path.join('appdata', 'archives');
}
}
\ No newline at end of file
diff --git a/backend/entrypoint.sh b/backend/entrypoint.sh
index 59ffdb6..8be147f 100755
--- a/backend/entrypoint.sh
+++ b/backend/entrypoint.sh
@@ -1,7 +1,7 @@
#!/bin/sh
set -eu
-CMD="pm2-runtime pm2.config.js"
+CMD="npm start"
# if the first arg starts with "-" pass it to program
if [ "${1#-}" != "$1" ]; then
diff --git a/backend/package-lock.json b/backend/package-lock.json
index 421898c..6c5c9cf 100644
--- a/backend/package-lock.json
+++ b/backend/package-lock.json
@@ -51,19 +51,216 @@
"resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz",
"integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ=="
},
- "@sindresorhus/is": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
- "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ=="
+ "@opencensus/core": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz",
+ "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==",
+ "requires": {
+ "continuation-local-storage": "^3.2.1",
+ "log-driver": "^1.2.7",
+ "semver": "^5.5.0",
+ "shimmer": "^1.2.0",
+ "uuid": "^3.2.1"
+ },
+ "dependencies": {
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ }
+ }
},
- "@szmarczak/http-timer": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
- "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "@opencensus/propagation-b3": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz",
+ "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==",
+ "requires": {
+ "@opencensus/core": "^0.0.8",
+ "uuid": "^3.2.1"
+ },
+ "dependencies": {
+ "@opencensus/core": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz",
+ "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==",
+ "requires": {
+ "continuation-local-storage": "^3.2.1",
+ "log-driver": "^1.2.7",
+ "semver": "^5.5.0",
+ "shimmer": "^1.2.0",
+ "uuid": "^3.2.1"
+ }
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ }
+ }
+ },
+ "@pm2/agent": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.1.tgz",
+ "integrity": "sha512-QKHMm6yexcvdDfcNE7PL9D6uEjoQPGRi+8dh+rc4Hwtbpsbh5IAvZbz3BVGjcd4HaX6pt2xGpOohG7/Y2L4QLw==",
+ "requires": {
+ "async": "~3.2.0",
+ "chalk": "~3.0.0",
+ "dayjs": "~1.8.24",
+ "debug": "~4.3.1",
+ "eventemitter2": "~5.0.1",
+ "fast-json-patch": "^3.0.0-1",
+ "fclone": "~1.0.11",
+ "nssocket": "0.6.0",
+ "pm2-axon": "~4.0.1",
+ "pm2-axon-rpc": "~0.7.0",
+ "proxy-agent": "~5.0.0",
+ "semver": "~7.2.0",
+ "ws": "~7.4.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "semver": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz",
+ "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig=="
+ }
+ }
+ },
+ "@pm2/io": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@pm2/io/-/io-5.0.0.tgz",
+ "integrity": "sha512-3rToDVJaRoob5Lq8+7Q2TZFruoEkdORxwzFpZaqF4bmH6Bkd7kAbdPrI/z8X6k1Meq5rTtScM7MmDgppH6aLlw==",
+ "requires": {
+ "@opencensus/core": "0.0.9",
+ "@opencensus/propagation-b3": "0.0.8",
+ "async": "~2.6.1",
+ "debug": "~4.3.1",
+ "eventemitter2": "^6.3.1",
+ "require-in-the-middle": "^5.0.0",
+ "semver": "6.3.0",
+ "shimmer": "^1.2.0",
+ "signal-exit": "^3.0.3",
+ "tslib": "1.9.3"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "eventemitter2": {
+ "version": "6.4.5",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz",
+ "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ },
+ "tslib": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
+ }
+ }
+ },
+ "@pm2/js-api": {
+ "version": "0.6.7",
+ "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz",
+ "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==",
+ "requires": {
+ "async": "^2.6.3",
+ "axios": "^0.21.0",
+ "debug": "~4.3.1",
+ "eventemitter2": "^6.3.1",
+ "ws": "^7.0.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "eventemitter2": {
+ "version": "6.4.5",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz",
+ "integrity": "sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "@pm2/pm2-version-check": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz",
+ "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==",
"requires": {
- "defer-to-connect": "^1.0.1"
+ "debug": "^4.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
}
},
+ "@tootallnate/once": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
+ },
"@types/ldapjs": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/@types/ldapjs/-/ldapjs-2.2.2.tgz",
@@ -82,11 +279,6 @@
"resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
"integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q=="
},
- "abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
- },
"abstract-logging": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-2.0.1.tgz",
@@ -101,6 +293,39 @@
"negotiator": "0.6.2"
}
},
+ "acorn": {
+ "version": "8.7.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+ "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
+ },
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA=="
+ },
+ "agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "requires": {
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -112,24 +337,17 @@
"uri-js": "^4.2.2"
}
},
- "ansi-align": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
- "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "amp": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz",
+ "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw=="
+ },
+ "amp-message": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz",
+ "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==",
"requires": {
- "string-width": "^3.0.0"
- },
- "dependencies": {
- "string-width": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
- "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
- "requires": {
- "emoji-regex": "^7.0.1",
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^5.1.0"
- }
- }
+ "amp": "0.3.1"
}
},
"ansi-colors": {
@@ -182,7 +400,7 @@
"append-field": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
- "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
+ "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw=="
},
"archiver": {
"version": "5.3.1",
@@ -254,11 +472,28 @@
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
+ "ast-types": {
+ "version": "0.13.4",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
+ "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
+ "requires": {
+ "tslib": "^2.0.1"
+ }
+ },
"async": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
},
+ "async-listener": {
+ "version": "0.6.10",
+ "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz",
+ "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==",
+ "requires": {
+ "semver": "^5.3.0",
+ "shimmer": "^1.1.0"
+ }
+ },
"async-mutex": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.3.1.tgz",
@@ -355,11 +590,21 @@
"readable-stream": "^3.4.0"
}
},
+ "blessed": {
+ "version": "0.1.81",
+ "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz",
+ "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ=="
+ },
"bluebird": {
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
"integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM="
},
+ "bodec": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz",
+ "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ=="
+ },
"body-parser": {
"version": "1.19.2",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.2.tgz",
@@ -384,21 +629,6 @@
}
}
},
- "boxen": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
- "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
- "requires": {
- "ansi-align": "^3.0.0",
- "camelcase": "^5.3.1",
- "chalk": "^3.0.0",
- "cli-boxes": "^2.2.0",
- "string-width": "^4.1.0",
- "term-size": "^2.1.0",
- "type-fest": "^0.8.1",
- "widest-line": "^3.1.0"
- }
- },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -446,9 +676,9 @@
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
- "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"buffer-indexof-polyfill": {
"version": "1.0.1",
@@ -461,35 +691,11 @@
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
},
"busboy": {
- "version": "0.2.14",
- "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
- "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
+ "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==",
"requires": {
- "dicer": "0.2.5",
- "readable-stream": "1.1.x"
- },
- "dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
- },
- "readable-stream": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
- }
+ "streamsearch": "^1.1.0"
}
},
"bytes": {
@@ -497,27 +703,6 @@
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
- "cacheable-request": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
- "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
- "requires": {
- "clone-response": "^1.0.2",
- "get-stream": "^5.1.0",
- "http-cache-semantics": "^4.0.0",
- "keyv": "^3.0.0",
- "lowercase-keys": "^2.0.0",
- "normalize-url": "^4.1.0",
- "responselike": "^1.0.2"
- },
- "dependencies": {
- "lowercase-keys": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
- "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
- }
- }
- },
"call-bind": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@@ -527,11 +712,6 @@
"get-intrinsic": "^1.0.2"
}
},
- "camelcase": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
- "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
- },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -552,21 +732,6 @@
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
- },
- "dependencies": {
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
}
},
"charenc": {
@@ -574,30 +739,33 @@
"resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
},
+ "charm": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz",
+ "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ=="
+ },
"chokidar": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
- "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
"requires": {
- "anymatch": "~3.1.1",
+ "anymatch": "~3.1.2",
"braces": "~3.0.2",
- "fsevents": "~2.3.1",
- "glob-parent": "~5.1.0",
+ "fsevents": "~2.3.2",
+ "glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
- "readdirp": "~3.5.0"
+ "readdirp": "~3.6.0"
}
},
- "ci-info": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
- "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
- },
- "cli-boxes": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
- "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw=="
+ "cli-tableau": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz",
+ "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==",
+ "requires": {
+ "chalk": "3.0.0"
+ }
},
"cliui": {
"version": "7.0.4",
@@ -619,14 +787,6 @@
}
}
},
- "clone-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
- "requires": {
- "mimic-response": "^1.0.0"
- }
- },
"color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
@@ -675,6 +835,11 @@
"delayed-stream": "~1.0.0"
}
},
+ "commander": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
+ },
"compress-commons": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz",
@@ -748,19 +913,6 @@
"json5": "^2.1.1"
}
},
- "configstore": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
- "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
- "requires": {
- "dot-prop": "^5.2.0",
- "graceful-fs": "^4.1.2",
- "make-dir": "^3.0.0",
- "unique-string": "^2.0.0",
- "write-file-atomic": "^3.0.0",
- "xdg-basedir": "^4.0.0"
- }
- },
"connected-domain": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/connected-domain/-/connected-domain-1.0.0.tgz",
@@ -786,6 +938,15 @@
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
+ "continuation-local-storage": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz",
+ "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==",
+ "requires": {
+ "async-listener": "^0.6.0",
+ "emitter-listener": "^1.1.1"
+ }
+ },
"cookie": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
@@ -824,6 +985,11 @@
"luxon": "^1.26.0"
}
},
+ "croner": {
+ "version": "4.1.97",
+ "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz",
+ "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ=="
+ },
"cross-spawn": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
@@ -839,10 +1005,10 @@
"resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
},
- "crypto-random-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
- "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA=="
+ "culvert": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz",
+ "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg=="
},
"dashdash": {
"version": "1.14.1",
@@ -852,6 +1018,16 @@
"assert-plus": "^1.0.0"
}
},
+ "data-uri-to-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
+ "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og=="
+ },
+ "dayjs": {
+ "version": "1.8.36",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz",
+ "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw=="
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -865,23 +1041,10 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
"integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="
},
- "decompress-response": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
- "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
- "requires": {
- "mimic-response": "^1.0.0"
- }
- },
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
- },
- "defer-to-connect": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
- "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ=="
+ "deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
},
"define-properties": {
"version": "1.1.4",
@@ -892,6 +1055,17 @@
"object-keys": "^1.1.1"
}
},
+ "degenerator": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-3.0.2.tgz",
+ "integrity": "sha512-c0mef3SNQo56t6urUU6tdQAs+ThoD0o9B9MJ8HEt7NQcGEILCRFqQb7ZbP9JAv+QF1Ky5plydhMR/IrqWDm+TQ==",
+ "requires": {
+ "ast-types": "^0.13.2",
+ "escodegen": "^1.8.1",
+ "esprima": "^4.0.0",
+ "vm2": "^3.9.8"
+ }
+ },
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -912,51 +1086,11 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
- "dicer": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
- "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
- "requires": {
- "readable-stream": "1.1.x",
- "streamsearch": "0.1.2"
- },
- "dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
- },
- "readable-stream": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "0.0.1",
- "string_decoder": "~0.10.x"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
- }
- }
- },
"diff": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w=="
},
- "dot-prop": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
- "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
- "requires": {
- "is-obj": "^2.0.0"
- }
- },
"duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
@@ -981,11 +1115,6 @@
}
}
},
- "duplexer3": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
- },
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -1008,10 +1137,13 @@
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
- "emoji-regex": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
- "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA=="
+ "emitter-listener": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz",
+ "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==",
+ "requires": {
+ "shimmer": "^1.2.0"
+ }
},
"enabled": {
"version": "2.0.0",
@@ -1031,16 +1163,19 @@
"once": "^1.4.0"
}
},
+ "enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "requires": {
+ "ansi-colors": "^4.1.1"
+ }
+ },
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
},
- "escape-goat": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
- "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q=="
- },
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
@@ -1051,16 +1186,43 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
},
+ "escodegen": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
+ "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "requires": {
+ "esprima": "^4.0.1",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ }
+ },
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+ },
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
+ "eventemitter2": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz",
+ "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg=="
+ },
"execa": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-3.2.0.tgz",
@@ -1164,16 +1326,36 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
},
+ "fast-json-patch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz",
+ "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ=="
+ },
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
},
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
+ },
+ "fclone": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz",
+ "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw=="
+ },
"fecha": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
},
+ "file-uri-to-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz",
+ "integrity": "sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg=="
+ },
"fill-range": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@@ -1302,6 +1484,38 @@
"rimraf": "2"
}
},
+ "ftp": {
+ "version": "0.3.10",
+ "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
+ "integrity": "sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==",
+ "requires": {
+ "readable-stream": "1.1.x",
+ "xregexp": "2.0.0"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
+ },
+ "readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
+ }
+ }
+ },
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@@ -1330,6 +1544,57 @@
"pump": "^3.0.0"
}
},
+ "get-uri": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-3.0.2.tgz",
+ "integrity": "sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==",
+ "requires": {
+ "@tootallnate/once": "1",
+ "data-uri-to-buffer": "3",
+ "debug": "4",
+ "file-uri-to-path": "2",
+ "fs-extra": "^8.1.0",
+ "ftp": "^0.3.10"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+ }
+ }
+ },
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
@@ -1338,6 +1603,16 @@
"assert-plus": "^1.0.0"
}
},
+ "git-node-fs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz",
+ "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ=="
+ },
+ "git-sha1": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz",
+ "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg=="
+ },
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -1359,42 +1634,6 @@
"is-glob": "^4.0.1"
}
},
- "global-dirs": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
- "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==",
- "requires": {
- "ini": "1.3.7"
- }
- },
- "got": {
- "version": "9.6.0",
- "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
- "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
- "requires": {
- "@sindresorhus/is": "^0.14.0",
- "@szmarczak/http-timer": "^1.1.2",
- "cacheable-request": "^6.0.0",
- "decompress-response": "^3.3.0",
- "duplexer3": "^0.1.4",
- "get-stream": "^4.1.0",
- "lowercase-keys": "^1.0.1",
- "mimic-response": "^1.0.1",
- "p-cancelable": "^1.0.0",
- "to-readable-stream": "^1.0.0",
- "url-parse-lax": "^3.0.0"
- },
- "dependencies": {
- "get-stream": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
- "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
- "requires": {
- "pump": "^3.0.0"
- }
- }
- }
- },
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
@@ -1428,9 +1667,9 @@
}
},
"has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"has-property-descriptors": {
"version": "1.0.0",
@@ -1445,11 +1684,6 @@
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
},
- "has-yarn": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
- "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw=="
- },
"hashish": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/hashish/-/hashish-0.0.4.tgz",
@@ -1471,11 +1705,6 @@
"zero-fill": "^2.2.3"
}
},
- "http-cache-semantics": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
- "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
- },
"http-errors": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
@@ -1488,6 +1717,31 @@
"toidentifier": "1.0.1"
}
},
+ "http-proxy-agent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+ "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+ "requires": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
@@ -1498,6 +1752,30 @@
"sshpk": "^1.7.0"
}
},
+ "https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "requires": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
"human-signals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
@@ -1516,21 +1794,6 @@
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
- "ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk="
- },
- "import-lazy": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
- "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM="
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
- },
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@@ -1546,9 +1809,14 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
- "version": "1.3.7",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
- "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "ip": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
+ "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
},
"ipaddr.js": {
"version": "1.9.1",
@@ -1573,12 +1841,12 @@
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
},
- "is-ci": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
- "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "is-core-module": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
+ "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"requires": {
- "ci-info": "^2.0.0"
+ "has": "^1.0.3"
}
},
"is-extglob": {
@@ -1586,11 +1854,6 @@
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
- },
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
@@ -1599,15 +1862,6 @@
"is-extglob": "^2.1.1"
}
},
- "is-installed-globally": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
- "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
- "requires": {
- "global-dirs": "^2.0.1",
- "is-path-inside": "^3.0.1"
- }
- },
"is-nan": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz",
@@ -1617,26 +1871,11 @@
"define-properties": "^1.1.3"
}
},
- "is-npm": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
- "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig=="
- },
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
},
- "is-obj": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
- "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="
- },
- "is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="
- },
"is-plain-obj": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
@@ -1662,11 +1901,6 @@
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="
},
- "is-yarn-global": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
- "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw=="
- },
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
@@ -1682,6 +1916,17 @@
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
+ "js-git": {
+ "version": "0.7.8",
+ "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz",
+ "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==",
+ "requires": {
+ "bodec": "^0.1.0",
+ "culvert": "^0.1.2",
+ "git-sha1": "^0.1.2",
+ "pako": "^0.2.5"
+ }
+ },
"js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
@@ -1695,11 +1940,6 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
- "json-buffer": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
- "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg="
- },
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -1788,26 +2028,15 @@
"safe-buffer": "^5.0.1"
}
},
- "keyv": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
- "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
- "requires": {
- "json-buffer": "3.0.0"
- }
- },
"kuler": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
},
- "latest-version": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
- "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
- "requires": {
- "package-json": "^6.3.0"
- }
+ "lazy": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz",
+ "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA=="
},
"lazystream": {
"version": "1.0.1",
@@ -1867,6 +2096,15 @@
"verror": "^1.8.1"
}
},
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
"listenercount": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
@@ -1940,6 +2178,11 @@
"resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
"integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
},
+ "log-driver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz",
+ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg=="
+ },
"log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
@@ -2009,11 +2252,6 @@
"steno": "^0.4.1"
}
},
- "lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA=="
- },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -2027,21 +2265,6 @@
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz",
"integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ=="
},
- "make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "requires": {
- "semver": "^6.0.0"
- },
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- }
- }
- },
"md5": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz",
@@ -2109,11 +2332,6 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
- "mimic-response": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
- "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
- },
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -2265,6 +2483,11 @@
}
}
},
+ "module-details-from-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz",
+ "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A=="
+ },
"moment": {
"version": "2.29.2",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz",
@@ -2314,16 +2537,15 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"multer": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz",
- "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==",
+ "version": "1.4.5-lts.1",
+ "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
+ "integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
"requires": {
"append-field": "^1.0.0",
- "busboy": "^0.2.11",
+ "busboy": "^1.0.0",
"concat-stream": "^1.5.2",
- "mkdirp": "^0.5.1",
+ "mkdirp": "^0.5.4",
"object-assign": "^4.1.1",
- "on-finished": "^2.3.0",
"type-is": "^1.6.4",
"xtend": "^4.0.0"
}
@@ -2353,6 +2575,11 @@
}
}
},
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="
+ },
"mz": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
@@ -2368,11 +2595,41 @@
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-2.1.11.tgz",
"integrity": "sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA=="
},
+ "needle": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz",
+ "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==",
+ "requires": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ }
+ }
+ },
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
+ "netmask": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
+ "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="
+ },
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
@@ -2399,56 +2656,11 @@
"sorted-array-functions": "^1.3.0"
}
},
- "nodemon": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.7.tgz",
- "integrity": "sha512-XHzK69Awgnec9UzHr1kc8EomQh4sjTQ8oRf8TsGrSmHDx9/UmiGG9E/mM3BuTfNeFwdNBvrqQq/RHL0xIeyFOA==",
- "requires": {
- "chokidar": "^3.2.2",
- "debug": "^3.2.6",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.0.4",
- "pstree.remy": "^1.1.7",
- "semver": "^5.7.1",
- "supports-color": "^5.5.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.3",
- "update-notifier": "^4.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "requires": {
- "ms": "^2.1.1"
- }
- },
- "ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
- }
- }
- },
- "nopt": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
- "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
- "requires": {
- "abbrev": "1"
- }
- },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
},
- "normalize-url": {
- "version": "4.5.1",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
- "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA=="
- },
"npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
@@ -2457,6 +2669,22 @@
"path-key": "^3.0.0"
}
},
+ "nssocket": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz",
+ "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==",
+ "requires": {
+ "eventemitter2": "~0.4.14",
+ "lazy": "~1.0.11"
+ },
+ "dependencies": {
+ "eventemitter2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ=="
+ }
+ }
+ },
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -2517,10 +2745,18 @@
"require-at": "^1.0.6"
}
},
- "p-cancelable": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
- "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw=="
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
},
"p-finally": {
"version": "2.0.1",
@@ -2543,24 +2779,52 @@
"p-limit": "^3.0.2"
}
},
- "package-json": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
- "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
- "requires": {
- "got": "^9.6.0",
- "registry-auth-token": "^4.0.0",
- "registry-url": "^5.0.0",
- "semver": "^6.2.0"
+ "pac-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==",
+ "requires": {
+ "@tootallnate/once": "1",
+ "agent-base": "6",
+ "debug": "4",
+ "get-uri": "3",
+ "http-proxy-agent": "^4.0.1",
+ "https-proxy-agent": "5",
+ "pac-resolver": "^5.0.0",
+ "raw-body": "^2.2.0",
+ "socks-proxy-agent": "5"
},
"dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
+ "pac-resolver": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-5.0.1.tgz",
+ "integrity": "sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==",
+ "requires": {
+ "degenerator": "^3.0.2",
+ "ip": "^1.1.5",
+ "netmask": "^2.0.2"
+ }
+ },
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="
+ },
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -2653,40 +2917,241 @@
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
- "pause": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
- "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
+ "pause": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
+ "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "picomatch": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
+ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw=="
+ },
+ "pidusage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.0.tgz",
+ "integrity": "sha512-8VJLToXhj+RYZGNVw8oxc7dS54iCQXUJ+MDFHezQ/fwF5B8W4OWodAMboc1wb08S/4LiHwAmkT4ohf/d3YPPsw==",
+ "requires": {
+ "safe-buffer": "^5.2.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ }
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ },
+ "pm2": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.2.0.tgz",
+ "integrity": "sha512-PO5hMVhQ85cTszFM++6v07Me9hPJMkFbHjkFigtMMk+La8ty2wCi2dlBTeZYJDhPUSjK8Ccltpq2buNRcyMOTw==",
+ "requires": {
+ "@pm2/agent": "~2.0.0",
+ "@pm2/io": "~5.0.0",
+ "@pm2/js-api": "~0.6.7",
+ "@pm2/pm2-version-check": "^1.0.4",
+ "async": "~3.2.0",
+ "blessed": "0.1.81",
+ "chalk": "3.0.0",
+ "chokidar": "^3.5.1",
+ "cli-tableau": "^2.0.0",
+ "commander": "2.15.1",
+ "croner": "~4.1.92",
+ "dayjs": "~1.8.25",
+ "debug": "^4.3.1",
+ "enquirer": "2.3.6",
+ "eventemitter2": "5.0.1",
+ "fclone": "1.0.11",
+ "mkdirp": "1.0.4",
+ "needle": "2.4.0",
+ "pidusage": "~3.0",
+ "pm2-axon": "~4.0.1",
+ "pm2-axon-rpc": "~0.7.1",
+ "pm2-deploy": "~1.0.2",
+ "pm2-multimeter": "^0.1.2",
+ "pm2-sysmonit": "^1.2.8",
+ "promptly": "^2",
+ "semver": "^7.2",
+ "source-map-support": "0.5.19",
+ "sprintf-js": "1.1.2",
+ "vizion": "~2.2.1",
+ "yamljs": "0.3.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "semver": {
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="
+ }
+ }
+ },
+ "pm2-axon": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz",
+ "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==",
+ "requires": {
+ "amp": "~0.3.1",
+ "amp-message": "~0.1.1",
+ "debug": "^4.3.1",
+ "escape-string-regexp": "^4.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "pm2-axon-rpc": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz",
+ "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==",
+ "requires": {
+ "debug": "^4.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
},
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ "pm2-deploy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz",
+ "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==",
+ "requires": {
+ "run-series": "^1.1.8",
+ "tv4": "^1.3.0"
+ }
},
- "picomatch": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
- "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw=="
+ "pm2-multimeter": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz",
+ "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==",
+ "requires": {
+ "charm": "~0.1.1"
+ }
},
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
+ "pm2-sysmonit": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz",
+ "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==",
+ "optional": true,
+ "requires": {
+ "async": "^3.2.0",
+ "debug": "^4.3.1",
+ "pidusage": "^2.0.21",
+ "systeminformation": "^5.7",
+ "tx2": "~1.0.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "optional": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "optional": true
+ },
+ "pidusage": {
+ "version": "2.0.21",
+ "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz",
+ "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==",
+ "optional": true,
+ "requires": {
+ "safe-buffer": "^5.2.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "optional": true
+ }
+ }
},
"precond": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz",
"integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw="
},
- "prepend-http": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
- "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc="
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w=="
},
"process-nextick-args": {
"version": "2.0.1",
@@ -2698,6 +3163,14 @@
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
+ "promptly": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz",
+ "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==",
+ "requires": {
+ "read": "^1.0.4"
+ }
+ },
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -2707,6 +3180,54 @@
"ipaddr.js": "1.9.1"
}
},
+ "proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==",
+ "requires": {
+ "agent-base": "^6.0.0",
+ "debug": "4",
+ "http-proxy-agent": "^4.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "lru-cache": "^5.1.1",
+ "pac-proxy-agent": "^5.0.0",
+ "proxy-from-env": "^1.0.0",
+ "socks-proxy-agent": "^5.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+ }
+ }
+ },
+ "proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"ps-node": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ps-node/-/ps-node-0.1.6.tgz",
@@ -2720,11 +3241,6 @@
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
- "pstree.remy": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
- "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w=="
- },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
@@ -2739,14 +3255,6 @@
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
- "pupa": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz",
- "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==",
- "requires": {
- "escape-goat": "^2.0.0"
- }
- },
"qs": {
"version": "6.9.7",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz",
@@ -2783,15 +3291,12 @@
}
}
},
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
"requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
+ "mute-stream": "~0.0.4"
}
},
"read-last-lines": {
@@ -2821,29 +3326,13 @@
}
},
"readdirp": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
- "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"requires": {
"picomatch": "^2.2.1"
}
},
- "registry-auth-token": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz",
- "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==",
- "requires": {
- "rc": "^1.2.8"
- }
- },
- "registry-url": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
- "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
- "requires": {
- "rc": "^1.2.8"
- }
- },
"request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
@@ -2893,12 +3382,39 @@
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
},
- "responselike": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
- "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "require-in-the-middle": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz",
+ "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==",
+ "requires": {
+ "debug": "^4.1.1",
+ "module-details-from-path": "^1.0.3",
+ "resolve": "^1.12.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"requires": {
- "lowercase-keys": "^1.0.0"
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
}
},
"rimraf": {
@@ -2909,6 +3425,11 @@
"glob": "^7.1.3"
}
},
+ "run-series": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz",
+ "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g=="
+ },
"rxjs": {
"version": "7.3.0",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.3.0.tgz",
@@ -2948,26 +3469,16 @@
"sparse-bitfield": "^3.0.3"
}
},
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
- "semver-diff": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
- "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
- "requires": {
- "semver": "^6.3.0"
- },
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
- }
- }
- },
"send": {
"version": "0.17.2",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.2.tgz",
@@ -3037,6 +3548,11 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
},
+ "shimmer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
+ "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="
+ },
"shortid": {
"version": "2.2.15",
"resolved": "https://registry.npmjs.org/shortid/-/shortid-2.2.15.tgz",
@@ -3058,11 +3574,64 @@
"is-arrayish": "^0.3.1"
}
},
+ "smart-buffer": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
+ "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
+ },
+ "socks": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz",
+ "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==",
+ "requires": {
+ "ip": "^1.1.5",
+ "smart-buffer": "^4.2.0"
+ }
+ },
+ "socks-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==",
+ "requires": {
+ "agent-base": "^6.0.2",
+ "debug": "4",
+ "socks": "^2.3.3"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ }
+ }
+ },
"sorted-array-functions": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz",
"integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA=="
},
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
"sparse-bitfield": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
@@ -3120,9 +3689,9 @@
}
},
"streamsearch": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
- "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
+ "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="
},
"string-width": {
"version": "4.2.2",
@@ -3167,39 +3736,30 @@
"safe-buffer": "~5.1.0"
}
},
- "strip-ansi": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
- "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
- "requires": {
- "ansi-regex": "^4.1.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
- "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
- }
- }
- },
"strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
},
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
- },
"supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
- "has-flag": "^3.0.0"
+ "has-flag": "^4.0.0"
}
},
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ },
+ "systeminformation": {
+ "version": "5.11.21",
+ "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.11.21.tgz",
+ "integrity": "sha512-aYuoelPUEItkeFi9d2EgGYZur6CgGaPAOUv9K5h1rJn5EyAYIXtonxJN3Dn58zQ3BFbj9FggaxaVBGg/pNRngA==",
+ "optional": true
+ },
"table-parser": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/table-parser/-/table-parser-0.1.3.tgz",
@@ -3220,11 +3780,6 @@
"readable-stream": "^3.1.1"
}
},
- "term-size": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
- "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="
- },
"text-hex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
@@ -3246,11 +3801,6 @@
"thenify": ">= 3.1.0 < 4"
}
},
- "to-readable-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
- "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q=="
- },
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -3264,14 +3814,6 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
},
- "touch": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
- "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
- "requires": {
- "nopt": "~1.0.10"
- }
- },
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -3309,15 +3851,32 @@
"safe-buffer": "^5.0.1"
}
},
+ "tv4": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz",
+ "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw=="
+ },
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
- "type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
+ "tx2": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz",
+ "integrity": "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==",
+ "optional": true,
+ "requires": {
+ "json-stringify-safe": "^5.0.1"
+ }
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
},
"type-is": {
"version": "1.6.18",
@@ -3331,31 +3890,7 @@
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
- },
- "typedarray-to-buffer": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
- "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
- "requires": {
- "is-typedarray": "^1.0.0"
- }
- },
- "undefsafe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
- "integrity": "sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A==",
- "requires": {
- "debug": "^2.2.0"
- }
- },
- "unique-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
- "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
- "requires": {
- "crypto-random-string": "^2.0.0"
- }
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
},
"universalify": {
"version": "1.0.0",
@@ -3400,26 +3935,6 @@
}
}
},
- "update-notifier": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
- "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
- "requires": {
- "boxen": "^4.2.0",
- "chalk": "^3.0.0",
- "configstore": "^5.0.1",
- "has-yarn": "^2.1.0",
- "import-lazy": "^2.1.0",
- "is-ci": "^2.0.0",
- "is-installed-globally": "^0.3.1",
- "is-npm": "^4.0.0",
- "is-yarn-global": "^0.3.0",
- "latest-version": "^5.0.0",
- "pupa": "^2.0.1",
- "semver-diff": "^3.1.1",
- "xdg-basedir": "^4.0.0"
- }
- },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -3428,14 +3943,6 @@
"punycode": "^2.1.0"
}
},
- "url-parse-lax": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
- "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
- "requires": {
- "prepend-http": "^2.0.0"
- }
- },
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -3482,6 +3989,36 @@
"extsprintf": "^1.2.0"
}
},
+ "vizion": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz",
+ "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==",
+ "requires": {
+ "async": "^2.6.3",
+ "git-node-fs": "^1.0.0",
+ "ini": "^1.3.5",
+ "js-git": "^0.7.8"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz",
+ "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==",
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ }
+ }
+ },
+ "vm2": {
+ "version": "3.9.9",
+ "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.9.tgz",
+ "integrity": "sha512-xwTm7NLh/uOjARRBs8/95H0e8fT3Ukw5D/JJWhxMbhKzNh1Nu981jQKvkep9iKYNxzlVrdzD0mlBGkDKZWprlw==",
+ "requires": {
+ "acorn": "^8.7.0",
+ "acorn-walk": "^8.2.0"
+ }
+ },
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -3504,14 +4041,6 @@
"isexe": "^2.0.0"
}
},
- "widest-line": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
- "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
- "requires": {
- "string-width": "^4.0.0"
- }
- },
"winston": {
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz",
@@ -3539,6 +4068,11 @@
"triple-beam": "^1.3.0"
}
},
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
+ },
"workerpool": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz",
@@ -3569,21 +4103,10 @@
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
- "write-file-atomic": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
- "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
- "requires": {
- "imurmurhash": "^0.1.4",
- "is-typedarray": "^1.0.0",
- "signal-exit": "^3.0.2",
- "typedarray-to-buffer": "^3.1.5"
- }
- },
- "xdg-basedir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
- "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q=="
+ "ws": {
+ "version": "7.4.6",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
+ "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="
},
"xmlbuilder2": {
"version": "3.0.2",
@@ -3616,6 +4139,11 @@
}
}
},
+ "xregexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
+ "integrity": "sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA=="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -3631,6 +4159,25 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
+ "yamljs": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz",
+ "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "glob": "^7.0.5"
+ },
+ "dependencies": {
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ }
+ }
+ },
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
diff --git a/backend/package.json b/backend/package.json
index bf926a1..4c116d2 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -5,20 +5,9 @@
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "start": "nodemon app.js",
+ "start": "pm2-runtime --raw pm2.config.js",
"debug": "set YTDL_MODE=debug && node app.js"
},
- "nodemonConfig": {
- "ignore": [
- "*.js",
- "appdata/*",
- "public/*"
- ],
- "watch": [
- "restart_update.json",
- "restart_general.json"
- ]
- },
"repository": {
"type": "git",
"url": ""
@@ -47,16 +36,16 @@
"mocha": "^9.2.2",
"moment": "^2.29.2",
"mongodb": "^3.6.9",
- "multer": "^1.4.2",
+ "multer": "1.4.5-lts.1",
"node-fetch": "^2.6.7",
"node-id3": "^0.1.14",
"node-schedule": "^2.1.0",
- "nodemon": "^2.0.7",
"passport": "^0.4.1",
"passport-http": "^0.3.0",
"passport-jwt": "^4.0.0",
"passport-ldapauth": "^3.0.1",
"passport-local": "^1.0.0",
+ "pm2": "^5.2.0",
"progress": "^2.0.3",
"ps-node": "^0.1.6",
"read-last-lines": "^1.7.2",
diff --git a/backend/subscriptions.js b/backend/subscriptions.js
index e14f121..6e9e454 100644
--- a/backend/subscriptions.js
+++ b/backend/subscriptions.js
@@ -178,7 +178,7 @@ async function deleteSubscriptionFile(sub, file, deleteForever, file_uid = null,
]);
if (jsonExists) {
- retrievedID = JSON.parse(await fs.readFile(jsonPath, 'utf8'))['id'];
+ retrievedID = fs.readJSONSync(jsonPath)['id'];
await fs.unlink(jsonPath);
}
@@ -196,12 +196,11 @@ async function deleteSubscriptionFile(sub, file, deleteForever, file_uid = null,
return false;
} else {
// check if the user wants the video to be redownloaded (deleteForever === false)
- if (!deleteForever && useArchive && sub.archive && retrievedID) {
- const archive_path = path.join(sub.archive, 'archive.txt')
- // if archive exists, remove line with video ID
- if (await fs.pathExists(archive_path)) {
- utils.removeIDFromArchive(archive_path, retrievedID);
- }
+ if (useArchive && retrievedID) {
+ const archive_path = utils.getArchiveFolder(sub.type, user_uid, sub);
+
+ // Remove file ID from the archive file, and write it to the blacklist (if enabled)
+ await utils.deleteFileFromArchive(file_uid, sub.type, archive_path, retrievedID, deleteForever);
}
return true;
}
@@ -242,64 +241,22 @@ async function getVideosForSub(sub, user_uid = null) {
logger.verbose('Subscription: finished check for ' + sub.name);
if (err && !output) {
logger.error(err.stderr ? err.stderr : err.message);
- if (err.stderr.includes('This video is unavailable')) {
+ if (err.stderr.includes('This video is unavailable') || err.stderr.includes('Private video')) {
logger.info('An error was encountered with at least one video, backup method will be used.')
try {
- // TODO: reimplement
-
- // const outputs = err.stdout.split(/\r\n|\r|\n/);
- // for (let i = 0; i < outputs.length; i++) {
- // const output = JSON.parse(outputs[i]);
- // await handleOutputJSON(sub, output, i === 0, multiUserMode)
- // if (err.stderr.includes(output['id']) && archive_path) {
- // // we found a video that errored! add it to the archive to prevent future errors
- // if (sub.archive) {
- // archive_dir = sub.archive;
- // archive_path = path.join(archive_dir, 'archive.txt')
- // fs.appendFileSync(archive_path, output['id']);
- // }
- // }
- // }
+ const outputs = err.stdout.split(/\r\n|\r|\n/);
+ const files_to_download = await handleOutputJSON(outputs, sub, user_uid);
+ resolve(files_to_download);
} catch(e) {
logger.error('Backup method failed. See error below:');
logger.error(e);
}
+ } else {
+ logger.error('Subscription check failed!');
}
resolve(false);
} else if (output) {
- if (config_api.getConfigItem('ytdl_subscriptions_redownload_fresh_uploads')) {
- await setFreshUploads(sub, user_uid);
- checkVideosForFreshUploads(sub, user_uid);
- }
-
- if (output.length === 0 || (output.length === 1 && output[0] === '')) {
- logger.verbose('No additional videos to download for ' + sub.name);
- resolve(true);
- return;
- }
-
- const output_jsons = [];
- for (let i = 0; i < output.length; i++) {
- let output_json = null;
- try {
- output_json = JSON.parse(output[i]);
- output_jsons.push(output_json);
- } catch(e) {
- output_json = null;
- }
- if (!output_json) {
- continue;
- }
- }
-
- const files_to_download = await getFilesToDownload(sub, output_jsons);
- const base_download_options = generateOptionsForSubscriptionDownload(sub, user_uid);
-
- for (let j = 0; j < files_to_download.length; j++) {
- const file_to_download = files_to_download[j];
- await downloader_api.createDownload(file_to_download['webpage_url'], sub.type || 'video', base_download_options, user_uid, sub.id, sub.name);
- }
-
+ const files_to_download = await handleOutputJSON(output, sub, user_uid);
resolve(files_to_download);
}
});
@@ -309,6 +266,43 @@ async function getVideosForSub(sub, user_uid = null) {
});
}
+async function handleOutputJSON(output, sub, user_uid) {
+ if (config_api.getConfigItem('ytdl_subscriptions_redownload_fresh_uploads')) {
+ await setFreshUploads(sub, user_uid);
+ checkVideosForFreshUploads(sub, user_uid);
+ }
+
+ if (output.length === 0 || (output.length === 1 && output[0] === '')) {
+ logger.verbose('No additional videos to download for ' + sub.name);
+ return [];
+ }
+
+ const output_jsons = [];
+ for (let i = 0; i < output.length; i++) {
+ let output_json = null;
+ try {
+ output_json = JSON.parse(output[i]);
+ output_jsons.push(output_json);
+ } catch(e) {
+ output_json = null;
+ }
+ if (!output_json) {
+ continue;
+ }
+ }
+
+ const files_to_download = await getFilesToDownload(sub, output_jsons);
+ const base_download_options = generateOptionsForSubscriptionDownload(sub, user_uid);
+
+ for (let j = 0; j < files_to_download.length; j++) {
+ const file_to_download = files_to_download[j];
+ file_to_download['formats'] = utils.stripPropertiesFromObject(file_to_download['formats'], ['format_id', 'filesize', 'filesize_approx']); // prevent download object from blowing up in size
+ await downloader_api.createDownload(file_to_download['webpage_url'], sub.type || 'video', base_download_options, user_uid, sub.id, sub.name, file_to_download);
+ }
+
+ return files_to_download;
+}
+
function generateOptionsForSubscriptionDownload(sub, user_uid) {
let basePath = null;
if (user_uid)
@@ -322,7 +316,7 @@ function generateOptionsForSubscriptionDownload(sub, user_uid) {
selectedHeight: sub.maxQuality && sub.maxQuality !== 'best' ? sub.maxQuality : null,
customFileFolderPath: getAppendedBasePath(sub, basePath),
customOutput: sub.custom_output ? `${sub.custom_output}` : `${default_output}`,
- customArchivePath: path.join(__dirname, basePath, 'archives', sub.name),
+ customArchivePath: path.join(basePath, 'archives', sub.name),
additionalArgs: sub.custom_args
}
@@ -389,11 +383,6 @@ async function generateArgsForSubscription(sub, user_uid, redownload = false, de
downloadConfig.push('--download-archive', archive_path);
}
- // if streaming only mode, just get the list of videos
- if (sub.streamingOnly) {
- downloadConfig = ['-f', 'best', '--dump-json'];
- }
-
if (sub.timerange && !redownload) {
downloadConfig.push('--dateafter', sub.timerange);
}
@@ -421,6 +410,8 @@ async function generateArgsForSubscription(sub, user_uid, redownload = false, de
downloadConfig.push('--no-clean-infojson');
}
+ downloadConfig = utils.filterArgs(downloadConfig, ['--write-comments']);
+
return downloadConfig;
}
@@ -479,6 +470,7 @@ async function updateSubscriptionProperty(sub, assignment_obj) {
async function setFreshUploads(sub) {
const sub_files = await db_api.getRecords('files', {sub_id: sub.id});
+ if (!sub_files) return;
const current_date = new Date().toISOString().split('T')[0].replace(/-/g, '');
sub_files.forEach(async file => {
if (current_date === file['upload_date'].replace(/-/g, '')) {
diff --git a/backend/test/tests.js b/backend/test/tests.js
index 448db7b..b640687 100644
--- a/backend/test/tests.js
+++ b/backend/test/tests.js
@@ -1,6 +1,7 @@
-var assert = require('assert');
+const assert = require('assert');
const low = require('lowdb')
-var winston = require('winston');
+const winston = require('winston');
+const path = require('path');
process.chdir('./backend')
@@ -39,6 +40,7 @@ const utils = require('../utils');
const subscriptions_api = require('../subscriptions');
const fs = require('fs-extra');
const { uuid } = require('uuidv4');
+const NodeID3 = require('node-id3');
db_api.initialize(db, users_db);
@@ -399,6 +401,19 @@ describe('Downloader', function() {
});
+ it('Tag file', async function() {
+ const audio_path = './test/sample.mp3';
+ const sample_json = fs.readJSONSync('./test/sample.info.json');
+ const tags = {
+ title: sample_json['title'],
+ artist: sample_json['artist'] ? sample_json['artist'] : sample_json['uploader'],
+ TRCK: '27'
+ }
+ NodeID3.write(tags, audio_path);
+ const written_tags = NodeID3.read(audio_path);
+ assert(written_tags['raw']['TRCK'] === '27');
+ });
+
it('Queue file', async function() {
this.timeout(300000);
const returned_download = await downloader_api.createDownload(url, 'video', options);
@@ -451,6 +466,20 @@ describe('Downloader', function() {
console.log(updated_args2);
assert(JSON.stringify(updated_args2), JSON.stringify(expected_args2));
});
+ describe('Twitch', async function () {
+ const twitch_api = require('../twitch');
+ const example_vod = '1493770675';
+ it('Download VOD', async function() {
+ const sample_path = path.join('test', 'sample.twitch_chat.json');
+ if (fs.existsSync(sample_path)) fs.unlinkSync(sample_path);
+ this.timeout(300000);
+ await twitch_api.downloadTwitchChatByVODID(example_vod, 'sample', null, null, null, './test');
+ assert(fs.existsSync(sample_path));
+
+ // cleanup
+ if (fs.existsSync(sample_path)) fs.unlinkSync(sample_path);
+ });
+ });
});
describe('Tasks', function() {
@@ -561,4 +590,40 @@ describe('Tasks', function() {
const dummy_task_obj = await db_api.getRecord('tasks', {key: 'dummy_task'});
assert(dummy_task_obj['data']);
});
+});
+
+describe('Archive', async function() {
+ const archive_path = path.join('test', 'archives');
+ fs.ensureDirSync(archive_path);
+ const archive_file_path = path.join(archive_path, 'archive_video.txt');
+ const blacklist_file_path = path.join(archive_path, 'blacklist_video.txt');
+ beforeEach(async function() {
+ if (fs.existsSync(archive_file_path)) fs.unlinkSync(archive_file_path);
+ fs.writeFileSync(archive_file_path, 'youtube testing1\nyoutube testing2\nyoutube testing3\n');
+
+ if (fs.existsSync(blacklist_file_path)) fs.unlinkSync(blacklist_file_path);
+ fs.writeFileSync(blacklist_file_path, '');
+ });
+
+ it('Delete from archive', async function() {
+ await utils.deleteFileFromArchive('N/A', 'video', archive_path, 'testing2', false);
+ const new_archive = fs.readFileSync(archive_file_path);
+ assert(!new_archive.includes('testing2'));
+ });
+
+ it('Delete from archive - blacklist', async function() {
+ await utils.deleteFileFromArchive('N/A', 'video', archive_path, 'testing2', true);
+ const new_archive = fs.readFileSync(archive_file_path);
+ const new_blacklist = fs.readFileSync(blacklist_file_path);
+ assert(!new_archive.includes('testing2'));
+ assert(new_blacklist.includes('testing2'));
+ });
+});
+
+describe('Utils', async function() {
+ it('Strip properties', async function() {
+ const test_obj = {test1: 'test1', test2: 'test2', test3: 'test3'};
+ const stripped_obj = utils.stripPropertiesFromObject(test_obj, ['test1', 'test3']);
+ assert(!stripped_obj['test1'] && stripped_obj['test2'] && !stripped_obj['test3'])
+ });
});
\ No newline at end of file
diff --git a/backend/twitch.js b/backend/twitch.js
index 2a231e9..c713676 100644
--- a/backend/twitch.js
+++ b/backend/twitch.js
@@ -1,90 +1,64 @@
-var moment = require('moment');
-var Axios = require('axios');
-var fs = require('fs-extra')
-var path = require('path');
const config_api = require('./config');
+const logger = require('./logger');
+
+const moment = require('moment');
+const fs = require('fs-extra')
+const path = require('path');
+
+async function getCommentsForVOD(clientID, clientSecret, vodId) {
+ const { promisify } = require('util');
+ const child_process = require('child_process');
+ const exec = promisify(child_process.exec);
+
+ // Reject invalid params to prevent command injection attack
+ if (!clientID.match(/^[0-9a-z]+$/) || !clientSecret.match(/^[0-9a-z]+$/) || !vodId.match(/^[0-9a-z]+$/)) {
+ logger.error('Client ID, client secret, and VOD ID must be purely alphanumeric. Twitch chat download failed!');
+ return null;
+ }
-async function getCommentsForVOD(clientID, vodId) {
- let url = `https://api.twitch.tv/v5/videos/${vodId}/comments?content_offset_seconds=0`,
- batch,
- cursor;
-
- let comments = null;
-
- try {
- do {
- batch = (await Axios.get(url, {
- headers: {
- 'Client-ID': clientID,
- Accept: 'application/vnd.twitchtv.v5+json; charset=UTF-8',
- 'Content-Type': 'application/json; charset=UTF-8',
- }
- })).data;
-
- const str = batch.comments.map(c => {
- let {
- created_at: msgCreated,
- content_offset_seconds: timestamp,
- commenter: {
- name,
- _id,
- created_at: acctCreated
- },
- message: {
- body: msg,
- user_color: user_color
- }
- } = c;
-
- const timestamp_str = moment.duration(timestamp, 'seconds')
- .toISOString()
- .replace(/P.*?T(?:(\d+?)H)?(?:(\d+?)M)?(?:(\d+).*?S)?/,
- (_, ...ms) => {
- const seg = v => v ? v.padStart(2, '0') : '00';
- return `${seg(ms[0])}:${seg(ms[1])}:${seg(ms[2])}`;
- });
-
- acctCreated = moment(acctCreated).utc();
- msgCreated = moment(msgCreated).utc();
-
- if (!comments) comments = [];
-
- comments.push({
- timestamp: timestamp,
- timestamp_str: timestamp_str,
- name: name,
- message: msg,
- user_color: user_color
- });
- // let line = `${timestamp},${msgCreated.format(tsFormat)},${name},${_id},"${msg.replace(/"/g, '""')}",${acctCreated.format(tsFormat)}`;
- // return line;
- }).join('\n');
-
- cursor = batch._next;
- url = `https://api.twitch.tv/v5/videos/${vodId}/comments?cursor=${cursor}`;
- await new Promise(res => setTimeout(res, 300));
- } while (cursor);
- } catch (err) {
- console.error(err);
+ const result = await exec(`tcd --video ${vodId} --client-id ${clientID} --client-secret ${clientSecret} --format json -o appdata`, {stdio:[0,1,2]});
+
+ if (result['stderr']) {
+ logger.error(`Failed to download twitch comments for ${vodId}`);
+ logger.error(result['stderr']);
+ return null;
}
- return comments;
+ const temp_chat_path = path.join('appdata', `${vodId}.json`);
+
+ const raw_json = fs.readJSONSync(temp_chat_path);
+ const new_json = raw_json.comments.map(comment_obj => {
+ return {
+ timestamp: comment_obj.content_offset_seconds,
+ timestamp_str: convertTimestamp(comment_obj.content_offset_seconds),
+ name: comment_obj.commenter.name,
+ message: comment_obj.message.body,
+ user_color: comment_obj.message.user_color
+ }
+ });
+
+ fs.unlinkSync(temp_chat_path);
+
+ return new_json;
}
async function getTwitchChatByFileID(id, type, user_uid, uuid, sub) {
+ const usersFileFolder = config_api.getConfigItem('ytdl_users_base_path');
+ const subscriptionsFileFolder = config_api.getConfigItem('ytdl_subscriptions_base_path');
let file_path = null;
if (user_uid) {
if (sub) {
- file_path = path.join('users', user_uid, 'subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json');
+ file_path = path.join(usersFileFolder, user_uid, 'subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, `${id}.twitch_chat.json`);
} else {
- file_path = path.join('users', user_uid, type, id + '.twitch_chat.json');
+ file_path = path.join(usersFileFolder, user_uid, type, `${id}.twitch_chat.json`);
}
} else {
if (sub) {
- file_path = path.join('subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json');
+ file_path = path.join(subscriptionsFileFolder, sub.isPlaylist ? 'playlists' : 'channels', sub.name, `${id}.twitch_chat.json`);
} else {
- file_path = path.join(type, id + '.twitch_chat.json');
+ const typeFolder = config_api.getConfigItem(`ytdl_${type}_folder_path`);
+ file_path = path.join(typeFolder, `${id}.twitch_chat.json`);
}
}
@@ -96,23 +70,28 @@ async function getTwitchChatByFileID(id, type, user_uid, uuid, sub) {
return chat_file;
}
-async function downloadTwitchChatByVODID(vodId, id, type, user_uid, sub) {
- const twitch_api_key = config_api.getConfigItem('ytdl_twitch_api_key');
- const chat = await getCommentsForVOD(twitch_api_key, vodId);
+async function downloadTwitchChatByVODID(vodId, id, type, user_uid, sub, customFileFolderPath = null) {
+ const usersFileFolder = config_api.getConfigItem('ytdl_users_base_path');
+ const subscriptionsFileFolder = config_api.getConfigItem('ytdl_subscriptions_base_path');
+ const twitch_client_id = config_api.getConfigItem('ytdl_twitch_client_id');
+ const twitch_client_secret = config_api.getConfigItem('ytdl_twitch_client_secret');
+ const chat = await getCommentsForVOD(twitch_client_id, twitch_client_secret, vodId);
// save file if needed params are included
let file_path = null;
- if (user_uid) {
+ if (customFileFolderPath) {
+ file_path = path.join(customFileFolderPath, `${id}.twitch_chat.json`)
+ } else if (user_uid) {
if (sub) {
- file_path = path.join('users', user_uid, 'subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json');
+ file_path = path.join(usersFileFolder, user_uid, 'subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, `${id}.twitch_chat.json`);
} else {
- file_path = path.join('users', user_uid, type, id + '.twitch_chat.json');
+ file_path = path.join(usersFileFolder, user_uid, type, `${id}.twitch_chat.json`);
}
} else {
if (sub) {
- file_path = path.join('subscriptions', sub.isPlaylist ? 'playlists' : 'channels', sub.name, id + '.twitch_chat.json');
+ file_path = path.join(subscriptionsFileFolder, sub.isPlaylist ? 'playlists' : 'channels', sub.name, `${id}.twitch_chat.json`);
} else {
- file_path = path.join(type, id + '.twitch_chat.json');
+ file_path = path.join(type, `${id}.twitch_chat.json`);
}
}
@@ -121,6 +100,14 @@ async function downloadTwitchChatByVODID(vodId, id, type, user_uid, sub) {
return chat;
}
+const convertTimestamp = (timestamp) => moment.duration(timestamp, 'seconds')
+ .toISOString()
+ .replace(/P.*?T(?:(\d+?)H)?(?:(\d+?)M)?(?:(\d+).*?S)?/,
+ (_, ...ms) => {
+ const seg = v => v ? v.padStart(2, '0') : '00';
+ return `${seg(ms[0])}:${seg(ms[1])}:${seg(ms[2])}`;
+});
+
module.exports = {
getCommentsForVOD: getCommentsForVOD,
getTwitchChatByFileID: getTwitchChatByFileID,
diff --git a/backend/utils.js b/backend/utils.js
index 805d591..534cbcf 100644
--- a/backend/utils.js
+++ b/backend/utils.js
@@ -173,8 +173,8 @@ function getExpectedFileSize(input_info_jsons) {
let individual_expected_filesize = 0;
formats.forEach(format_id => {
info_json.formats.forEach(available_format => {
- if (available_format.format_id === format_id && available_format.filesize) {
- individual_expected_filesize += available_format.filesize;
+ if (available_format.format_id === format_id && (available_format.filesize || available_format.filesize_approx)) {
+ individual_expected_filesize += (available_format.filesize ? available_format.filesize : available_format.filesize_approx);
}
});
});
@@ -218,8 +218,11 @@ function deleteJSONFile(file_path, type) {
if (fs.existsSync(alternate_json_path)) fs.unlinkSync(alternate_json_path);
}
-async function removeIDFromArchive(archive_path, id) {
- let data = await fs.readFile(archive_path, {encoding: 'utf-8'});
+// archive helper functions
+
+async function removeIDFromArchive(archive_path, type, id) {
+ const archive_file = path.join(archive_path, `archive_${type}.txt`);
+ const data = await fs.readFile(archive_file, {encoding: 'utf-8'});
if (!data) {
logger.error('Archive could not be found.');
return;
@@ -236,12 +239,34 @@ async function removeIDFromArchive(archive_path, id) {
}
}
+ if (lastIndex === -1) return null;
+
const line = dataArray.splice(lastIndex, 1); // remove the keyword id from the data Array
// UPDATE FILE WITH NEW DATA
const updatedData = dataArray.join('\n');
- await fs.writeFile(archive_path, updatedData);
- if (line) return line;
+ await fs.writeFile(archive_file, updatedData);
+ if (line) return Array.isArray(line) && line.length === 1 ? line[0] : line;
+}
+
+async function writeToBlacklist(archive_folder, type, line) {
+ let blacklistPath = path.join(archive_folder, (type === 'audio') ? 'blacklist_audio.txt' : 'blacklist_video.txt');
+ // adds newline to the beginning of the line
+ line.replace('\n', '');
+ line.replace('\r', '');
+ line = '\n' + line;
+ await fs.appendFile(blacklistPath, line);
+}
+
+async function deleteFileFromArchive(uid, type, archive_path, id, blacklistMode) {
+ const archive_file = path.join(archive_path, `archive_${type}.txt`);
+ if (await fs.pathExists(archive_path)) {
+ const line = id ? await removeIDFromArchive(archive_path, type, id) : null;
+ if (blacklistMode && line) await writeToBlacklist(archive_path, type, line);
+ } else {
+ logger.info(`Could not find archive file for file ${uid}. Creating...`);
+ await fs.close(await fs.open(archive_file, 'w'));
+ }
}
function durationStringToNumber(dur_str) {
@@ -418,7 +443,7 @@ async function fetchFile(url, path, file_label) {
async function restartServer(is_update = false) {
logger.info(`${is_update ? 'Update complete! ' : ''}Restarting server...`);
- // the following line restarts the server through nodemon
+ // the following line restarts the server through pm2
fs.writeFileSync(`restart${is_update ? '_update' : '_general'}.json`, 'internal use only');
process.exit(1);
}
@@ -456,6 +481,10 @@ function injectArgs(original_args, new_args) {
return updated_args;
}
+function filterArgs(args, args_to_remove) {
+ return args.filter(x => !args_to_remove.includes(x));
+}
+
const searchObjectByString = function(o, s) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
@@ -471,6 +500,41 @@ const searchObjectByString = function(o, s) {
return o;
}
+function stripPropertiesFromObject(obj, properties, whitelist = false) {
+ if (!whitelist) {
+ const new_obj = JSON.parse(JSON.stringify(obj));
+ for (let field of properties) {
+ delete new_obj[field];
+ }
+ return new_obj;
+ }
+
+ const new_obj = {};
+ for (let field of properties) {
+ new_obj[field] = obj[field];
+ }
+ return new_obj;
+}
+
+function getArchiveFolder(type, user_uid = null, sub = null) {
+ const usersFolderPath = config_api.getConfigItem('ytdl_users_base_path');
+ const subsFolderPath = config_api.getConfigItem('ytdl_subscriptions_base_path');
+
+ if (user_uid) {
+ if (sub) {
+ return path.join(usersFolderPath, user_uid, 'subscriptions', 'archives', sub.name);
+ } else {
+ return path.join(usersFolderPath, user_uid, type, 'archives');
+ }
+ } else {
+ if (sub) {
+ return path.join(subsFolderPath, 'archives', sub.name);
+ } else {
+ return path.join('appdata', 'archives');
+ }
+ }
+}
+
// objects
function File(id, title, thumbnailURL, isAudio, duration, url, uploader, size, path, upload_date, description, view_count, height, abr) {
@@ -500,6 +564,8 @@ module.exports = {
fixVideoMetadataPerms: fixVideoMetadataPerms,
deleteJSONFile: deleteJSONFile,
removeIDFromArchive: removeIDFromArchive,
+ writeToBlacklist: writeToBlacklist,
+ deleteFileFromArchive: deleteFileFromArchive,
getDownloadedFilesByType: getDownloadedFilesByType,
createContainerZipFile: createContainerZipFile,
durationStringToNumber: durationStringToNumber,
@@ -515,6 +581,9 @@ module.exports = {
fetchFile: fetchFile,
restartServer: restartServer,
injectArgs: injectArgs,
+ filterArgs: filterArgs,
searchObjectByString: searchObjectByString,
+ stripPropertiesFromObject: stripPropertiesFromObject,
+ getArchiveFolder: getArchiveFolder,
File: File
}
diff --git a/chart/Chart.yaml b/chart/Chart.yaml
index a86aa60..aa4cac1 100644
--- a/chart/Chart.yaml
+++ b/chart/Chart.yaml
@@ -21,4 +21,4 @@ version: 0.1.0
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
-appVersion: "4.2"
+appVersion: "4.3"
diff --git a/docker-compose.yml b/docker-compose.yml
index 60aef89..c1cc36e 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,7 +17,7 @@ services:
- ./users:/app/users
ports:
- "8998:17442"
- image: tzahi12345/youtubedl-material:nightly
+ image: tzahi12345/youtubedl-material:latest
ytdl-mongo-db:
image: mongo
ports:
diff --git a/package-lock.json b/package-lock.json
index eab9318..db6f9f1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "youtube-dl-material",
- "version": "4.2.0",
+ "version": "4.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -3675,7 +3675,7 @@
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
"dev": true
},
"buffer-from": {
@@ -3785,12 +3785,6 @@
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
"dev": true
- },
- "normalize-url": {
- "version": "4.5.1",
- "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
- "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
- "dev": true
}
}
},
@@ -3945,7 +3939,7 @@
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
- "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
"dev": true,
"requires": {
"mimic-response": "^1.0.0"
@@ -4666,7 +4660,7 @@
"decompress-response": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
- "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==",
"dev": true,
"requires": {
"mimic-response": "^1.0.0"
@@ -4956,7 +4950,7 @@
"duplexer3": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
- "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "integrity": "sha512-CEj8FwwNA4cVH2uFCoHUrmojhYh1vmCdOaneKJXwkeY1i9jnlslVo9dx+hQ5Hl9GnH/Bwy/IjxAyOePyPKYnzA==",
"dev": true
},
"ecc-jsbn": {
@@ -4976,20 +4970,20 @@
"dev": true
},
"electron": {
- "version": "13.6.6",
- "resolved": "https://registry.npmjs.org/electron/-/electron-13.6.6.tgz",
- "integrity": "sha512-TP2Bl1nTxaH1yRmlYiF7imzvKE/NASE0cl6wOYA3AaP/UrBGc4L3NwJfn5Z55o+1t4TH8vCRxENufESyb32HhA==",
+ "version": "19.0.6",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-19.0.6.tgz",
+ "integrity": "sha512-S9Yud32nKhB0iWC0lGl2JXz4FQnCiLCnP5Vehm1/CqyeICcQGmgQaZl2HYpCJ2pesKIsYL9nsgmku/10cxm/gg==",
"dev": true,
"requires": {
- "@electron/get": "^1.0.1",
- "@types/node": "^14.6.2",
+ "@electron/get": "^1.14.1",
+ "@types/node": "^16.11.26",
"extract-zip": "^1.0.3"
},
"dependencies": {
"@types/node": {
- "version": "14.18.12",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.12.tgz",
- "integrity": "sha512-q4jlIR71hUpWTnGhXWcakgkZeHa3CCjcQcnuzU8M891BAWA2jHiziiWEPEkdS5pFsz7H9HJiy8BrK7tBRNrY7A==",
+ "version": "16.11.41",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.41.tgz",
+ "integrity": "sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ==",
"dev": true
}
}
@@ -5956,7 +5950,7 @@
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
}
}
@@ -6024,7 +6018,7 @@
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
- "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
"dev": true,
"requires": {
"pend": "~1.2.0"
@@ -6412,9 +6406,9 @@
},
"dependencies": {
"semver": {
- "version": "7.3.5",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
- "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "version": "7.3.7",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+ "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"dev": true,
"optional": true,
"requires": {
@@ -6442,9 +6436,9 @@
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
},
"globalthis": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz",
- "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
"dev": true,
"optional": true,
"requires": {
@@ -7455,7 +7449,7 @@
"json-buffer": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
- "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==",
"dev": true
},
"json-parse-better-errors": {
@@ -7511,7 +7505,7 @@
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6"
@@ -8561,6 +8555,12 @@
"integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
"dev": true
},
+ "normalize-url": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz",
+ "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==",
+ "dev": true
+ },
"npm-bundled": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz",
@@ -8584,7 +8584,7 @@
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
"dev": true,
"optional": true
}
@@ -9370,7 +9370,7 @@
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
"dev": true
},
"performance-now": {
@@ -9817,7 +9817,7 @@
"prepend-http": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
- "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
"dev": true
},
"pretty-bytes": {
@@ -9865,7 +9865,7 @@
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
- "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
"dev": true,
"optional": true
},
@@ -10576,7 +10576,7 @@
"responselike": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
- "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==",
"dev": true,
"requires": {
"lowercase-keys": "^1.0.0"
@@ -10826,7 +10826,7 @@
"semver-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
- "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+ "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
"dev": true,
"optional": true
},
@@ -11937,7 +11937,7 @@
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==",
"dev": true
},
"typescript": {
@@ -12027,7 +12027,7 @@
"url-parse-lax": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
- "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==",
"dev": true,
"requires": {
"prepend-http": "^2.0.0"
@@ -12576,7 +12576,7 @@
"yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
- "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
"dev": true,
"requires": {
"buffer-crc32": "~0.2.3",
diff --git a/package.json b/package.json
index 8571420..a746ff5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "youtube-dl-material",
- "version": "4.2.0",
+ "version": "4.3.0",
"license": "MIT",
"scripts": {
"ng": "ng",
@@ -66,7 +66,7 @@
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"codelyzer": "^6.0.0",
- "electron": "^13.6.6",
+ "electron": "^19.0.6",
"eslint": "^7.32.0",
"jasmine-core": "~3.6.0",
"jasmine-spec-reporter": "~5.0.0",
diff --git a/src/api-types/index.ts b/src/api-types/index.ts
index db5be04..973aeca 100644
--- a/src/api-types/index.ts
+++ b/src/api-types/index.ts
@@ -40,11 +40,13 @@ export type { DownloadTwitchChatByVODIDRequest } from './models/DownloadTwitchCh
export type { DownloadTwitchChatByVODIDResponse } from './models/DownloadTwitchChatByVODIDResponse';
export type { DownloadVideosForSubscriptionRequest } from './models/DownloadVideosForSubscriptionRequest';
export { FileType } from './models/FileType';
+export { FileTypeFilter } from './models/FileTypeFilter';
export type { GenerateArgsResponse } from './models/GenerateArgsResponse';
export type { GenerateNewApiKeyResponse } from './models/GenerateNewApiKeyResponse';
export type { GetAllCategoriesResponse } from './models/GetAllCategoriesResponse';
export type { GetAllDownloadsRequest } from './models/GetAllDownloadsRequest';
export type { GetAllDownloadsResponse } from './models/GetAllDownloadsResponse';
+export type { GetAllFilesRequest } from './models/GetAllFilesRequest';
export type { GetAllFilesResponse } from './models/GetAllFilesResponse';
export type { GetAllSubscriptionsResponse } from './models/GetAllSubscriptionsResponse';
export type { GetAllTasksResponse } from './models/GetAllTasksResponse';
@@ -82,6 +84,7 @@ export type { RestoreDBBackupRequest } from './models/RestoreDBBackupRequest';
export { Schedule } from './models/Schedule';
export type { SetConfigRequest } from './models/SetConfigRequest';
export type { SharingToggle } from './models/SharingToggle';
+export type { Sort } from './models/Sort';
export type { SubscribeRequest } from './models/SubscribeRequest';
export type { SubscribeResponse } from './models/SubscribeResponse';
export type { Subscription } from './models/Subscription';
diff --git a/src/api-types/models/CreatePlaylistRequest.ts b/src/api-types/models/CreatePlaylistRequest.ts
index c747d8d..e61a2a0 100644
--- a/src/api-types/models/CreatePlaylistRequest.ts
+++ b/src/api-types/models/CreatePlaylistRequest.ts
@@ -2,11 +2,8 @@
/* tslint:disable */
/* eslint-disable */
-import type { FileType } from './FileType';
-
export type CreatePlaylistRequest = {
playlistName: string;
uids: Array;
- type: FileType;
thumbnailURL: string;
};
\ No newline at end of file
diff --git a/src/api-types/models/DatabaseFile.ts b/src/api-types/models/DatabaseFile.ts
index 796c2fe..f36af9e 100644
--- a/src/api-types/models/DatabaseFile.ts
+++ b/src/api-types/models/DatabaseFile.ts
@@ -30,4 +30,14 @@ export type DatabaseFile = {
category?: Category;
view_count?: number;
local_view_count?: number;
+ sub_id?: string;
+ registered?: number;
+ /**
+ * In pixels, only for videos
+ */
+ height?: number;
+ /**
+ * In Kbps
+ */
+ abr?: number;
};
\ No newline at end of file
diff --git a/src/api-types/models/DeletePlaylistRequest.ts b/src/api-types/models/DeletePlaylistRequest.ts
index 07cf9f7..82e25b2 100644
--- a/src/api-types/models/DeletePlaylistRequest.ts
+++ b/src/api-types/models/DeletePlaylistRequest.ts
@@ -2,9 +2,6 @@
/* tslint:disable */
/* eslint-disable */
-import type { FileType } from './FileType';
-
export type DeletePlaylistRequest = {
playlist_id: string;
- type: FileType;
};
\ No newline at end of file
diff --git a/src/api-types/models/Download.ts b/src/api-types/models/Download.ts
index 6556da0..db447c3 100644
--- a/src/api-types/models/Download.ts
+++ b/src/api-types/models/Download.ts
@@ -22,4 +22,5 @@ export type Download = {
user_uid?: string;
sub_id?: string;
sub_name?: string;
+ prefetched_info?: any;
};
\ No newline at end of file
diff --git a/src/api-types/models/FileTypeFilter.ts b/src/api-types/models/FileTypeFilter.ts
new file mode 100644
index 0000000..d1fac98
--- /dev/null
+++ b/src/api-types/models/FileTypeFilter.ts
@@ -0,0 +1,9 @@
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+
+export enum FileTypeFilter {
+ AUDIO_ONLY = 'audio_only',
+ VIDEO_ONLY = 'video_only',
+ BOTH = 'both',
+}
\ No newline at end of file
diff --git a/src/api-types/models/GetAllFilesRequest.ts b/src/api-types/models/GetAllFilesRequest.ts
new file mode 100644
index 0000000..0acd1c3
--- /dev/null
+++ b/src/api-types/models/GetAllFilesRequest.ts
@@ -0,0 +1,20 @@
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+
+import type { FileTypeFilter } from './FileTypeFilter';
+import type { Sort } from './Sort';
+
+export type GetAllFilesRequest = {
+ sort?: Sort;
+ range?: Array;
+ /**
+ * Filter files by title
+ */
+ text_search?: string;
+ file_type_filter?: FileTypeFilter;
+ /**
+ * Include if you want to filter by subscription
+ */
+ sub_id?: string;
+};
\ No newline at end of file
diff --git a/src/api-types/models/GetPlaylistResponse.ts b/src/api-types/models/GetPlaylistResponse.ts
index daca2d4..14ff0c0 100644
--- a/src/api-types/models/GetPlaylistResponse.ts
+++ b/src/api-types/models/GetPlaylistResponse.ts
@@ -2,11 +2,14 @@
/* tslint:disable */
/* eslint-disable */
-import type { FileType } from './FileType';
+import type { DatabaseFile } from './DatabaseFile';
import type { Playlist } from './Playlist';
export type GetPlaylistResponse = {
playlist: Playlist;
- type: FileType;
success: boolean;
+ /**
+ * File objects for every uid in the playlist's uids property, in the same order
+ */
+ file_objs?: Array;
};
\ No newline at end of file
diff --git a/src/api-types/models/Sort.ts b/src/api-types/models/Sort.ts
new file mode 100644
index 0000000..438f884
--- /dev/null
+++ b/src/api-types/models/Sort.ts
@@ -0,0 +1,14 @@
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+
+export type Sort = {
+ /**
+ * Property to sort by
+ */
+ by?: string;
+ /**
+ * 1 for ascending, -1 for descending
+ */
+ order?: number;
+};
\ No newline at end of file
diff --git a/src/api-types/models/Subscription.ts b/src/api-types/models/Subscription.ts
index 5c87886..2e280d8 100644
--- a/src/api-types/models/Subscription.ts
+++ b/src/api-types/models/Subscription.ts
@@ -10,7 +10,6 @@ export type Subscription = {
id: string;
type: FileType;
user_uid: string | null;
- streamingOnly: boolean;
isPlaylist: boolean;
archive?: string;
timerange?: string;
diff --git a/src/api-types/models/Task.ts b/src/api-types/models/Task.ts
index 2533c98..e6f68be 100644
--- a/src/api-types/models/Task.ts
+++ b/src/api-types/models/Task.ts
@@ -4,6 +4,7 @@
export type Task = {
key: string;
+ title?: string;
last_ran: number;
last_confirmed: number;
running: boolean;
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index a9e2ad4..ef53d84 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -49,7 +49,6 @@ import { CreatePlaylistComponent } from './create-playlist/create-playlist.compo
import { SubscriptionsComponent } from './subscriptions/subscriptions.component';
import { SubscribeDialogComponent } from './dialogs/subscribe-dialog/subscribe-dialog.component';
import { SubscriptionComponent } from './subscription//subscription/subscription.component';
-import { SubscriptionFileCardComponent } from './subscription/subscription-file-card/subscription-file-card.component';
import { SubscriptionInfoDialogComponent } from './dialogs/subscription-info-dialog/subscription-info-dialog.component';
import { SettingsComponent } from './settings/settings.component';
import { MatChipsModule } from '@angular/material/chips';
@@ -74,7 +73,6 @@ import { ManageUserComponent } from './components/manage-user/manage-user.compon
import { ManageRoleComponent } from './components/manage-role/manage-role.component';
import { CookiesUploaderDialogComponent } from './dialogs/cookies-uploader-dialog/cookies-uploader-dialog.component';
import { LogsViewerComponent } from './components/logs-viewer/logs-viewer.component';
-import { ModifyPlaylistComponent } from './dialogs/modify-playlist/modify-playlist.component';
import { ConfirmDialogComponent } from './dialogs/confirm-dialog/confirm-dialog.component';
import { UnifiedFileCardComponent } from './components/unified-file-card/unified-file-card.component';
import { RecentVideosComponent } from './components/recent-videos/recent-videos.component';
@@ -102,7 +100,6 @@ registerLocaleData(es, 'es');
SubscriptionsComponent,
SubscribeDialogComponent,
SubscriptionComponent,
- SubscriptionFileCardComponent,
SubscriptionInfoDialogComponent,
SettingsComponent,
AboutDialogComponent,
@@ -123,7 +120,6 @@ registerLocaleData(es, 'es');
ManageRoleComponent,
CookiesUploaderDialogComponent,
LogsViewerComponent,
- ModifyPlaylistComponent,
ConfirmDialogComponent,
UnifiedFileCardComponent,
RecentVideosComponent,
diff --git a/src/app/components/custom-playlists/custom-playlists.component.ts b/src/app/components/custom-playlists/custom-playlists.component.ts
index e659724..c2905c9 100644
--- a/src/app/components/custom-playlists/custom-playlists.component.ts
+++ b/src/app/components/custom-playlists/custom-playlists.component.ts
@@ -3,7 +3,7 @@ import { PostsService } from 'app/posts.services';
import { Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { CreatePlaylistComponent } from 'app/create-playlist/create-playlist.component';
-import { ModifyPlaylistComponent } from 'app/dialogs/modify-playlist/modify-playlist.component';
+import { Playlist } from 'api-types';
@Component({
selector: 'app-custom-playlists',
@@ -32,7 +32,7 @@ export class CustomPlaylistsComponent implements OnInit {
});
}
- getAllPlaylists() {
+ getAllPlaylists(): void {
this.playlists_received = false;
// must call getAllFiles as we need to get category playlists as well
this.postsService.getPlaylists(true).subscribe(res => {
@@ -42,22 +42,25 @@ export class CustomPlaylistsComponent implements OnInit {
}
// creating a playlist
- openCreatePlaylistDialog() {
+ openCreatePlaylistDialog(): void {
const dialogRef = this.dialog.open(CreatePlaylistComponent, {
data: {
- }
+ create_mode: true
+ },
+ minWidth: '90vw',
+ minHeight: '95vh'
});
dialogRef.afterClosed().subscribe(result => {
if (result) {
this.getAllPlaylists();
- this.postsService.openSnackBar('Successfully created playlist!', '');
+ this.postsService.openSnackBar($localize`Successfully created playlist!', '`);
} else if (result === false) {
- this.postsService.openSnackBar('ERROR: failed to create playlist!', '');
+ this.postsService.openSnackBar($localize`ERROR: failed to create playlist!', '`);
}
});
}
- goToPlaylist(info_obj) {
+ goToPlaylist(info_obj: { file: Playlist; }): void {
const playlist = info_obj.file;
const playlistID = playlist.id;
@@ -76,7 +79,7 @@ export class CustomPlaylistsComponent implements OnInit {
}
}
- downloadPlaylist(playlist_id, playlist_name) {
+ downloadPlaylist(playlist_id: string, playlist_name: string): void {
this.downloading_content[playlist_id] = true;
this.postsService.downloadPlaylistFromServer(playlist_id).subscribe(res => {
this.downloading_content[playlist_id] = false;
@@ -86,33 +89,34 @@ export class CustomPlaylistsComponent implements OnInit {
}
- deletePlaylist(args) {
+ deletePlaylist(args: { file: Playlist; index: number; }): void {
const playlist = args.file;
const index = args.index;
const playlistID = playlist.id;
- this.postsService.removePlaylist(playlistID, playlist.type).subscribe(res => {
+ this.postsService.removePlaylist(playlistID).subscribe(res => {
if (res['success']) {
this.playlists.splice(index, 1);
- this.postsService.openSnackBar('Playlist successfully removed.', '');
+ this.postsService.openSnackBar($localize`Playlist successfully removed.', '`);
}
this.getAllPlaylists();
});
}
- editPlaylistDialog(args) {
+ editPlaylistDialog(args: { playlist: Playlist; index: number; }): void {
const playlist = args.playlist;
const index = args.index;
- const dialogRef = this.dialog.open(ModifyPlaylistComponent, {
+ const dialogRef = this.dialog.open(CreatePlaylistComponent, {
data: {
playlist_id: playlist.id,
- width: '65vw'
- }
+ create_mode: false
+ },
+ minWidth: '85vw'
});
- dialogRef.afterClosed().subscribe(res => {
+ dialogRef.afterClosed().subscribe(() => {
// updates playlist in file manager if it changed
if (dialogRef.componentInstance.playlist_updated) {
- this.playlists[index] = dialogRef.componentInstance.original_playlist;
+ this.playlists[index] = dialogRef.componentInstance.playlist;
}
});
}
diff --git a/src/app/components/downloads/downloads.component.ts b/src/app/components/downloads/downloads.component.ts
index 81cdd8c..45f1e7a 100644
--- a/src/app/components/downloads/downloads.component.ts
+++ b/src/app/components/downloads/downloads.component.ts
@@ -8,6 +8,7 @@ import { MatDialog } from '@angular/material/dialog';
import { ConfirmDialogComponent } from 'app/dialogs/confirm-dialog/confirm-dialog.component';
import { MatSort } from '@angular/material/sort';
import { Clipboard } from '@angular/cdk/clipboard';
+import { Download } from 'api-types';
@Component({
selector: 'app-downloads',
@@ -68,7 +69,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
@ViewChild(MatPaginator) paginator: MatPaginator;
@ViewChild(MatSort) sort: MatSort;
- sort_downloads = (a, b) => {
+ sort_downloads = (a: Download, b: Download): number => {
const result = b.timestamp_start - a.timestamp_start;
return result;
}
@@ -166,7 +167,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
pauseDownload(download_uid: string): void {
this.postsService.pauseDownload(download_uid).subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to pause download! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to pause download! See server logs for more info.`);
}
});
}
@@ -174,7 +175,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
pauseAllDownloads(): void {
this.postsService.pauseAllDownloads().subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to pause all downloads! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to pause all downloads! See server logs for more info.`);
}
});
}
@@ -182,7 +183,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
resumeDownload(download_uid: string): void {
this.postsService.resumeDownload(download_uid).subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to resume download! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to resume download! See server logs for more info.`);
}
});
}
@@ -190,7 +191,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
resumeAllDownloads(): void {
this.postsService.resumeAllDownloads().subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to resume all downloads! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to resume all downloads! See server logs for more info.`);
}
});
}
@@ -198,7 +199,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
restartDownload(download_uid: string): void {
this.postsService.restartDownload(download_uid).subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to restart download! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to restart download! See server logs for more info.`);
}
});
}
@@ -206,7 +207,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
cancelDownload(download_uid: string): void {
this.postsService.cancelDownload(download_uid).subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to cancel download! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to cancel download! See server logs for more info.`);
}
});
}
@@ -214,12 +215,12 @@ export class DownloadsComponent implements OnInit, OnDestroy {
clearDownload(download_uid: string): void {
this.postsService.clearDownload(download_uid).subscribe(res => {
if (!res['success']) {
- this.postsService.openSnackBar('Failed to pause download! See server logs for more info.');
+ this.postsService.openSnackBar($localize`Failed to pause download! See server logs for more info.`);
}
});
}
- watchContent(download): void {
+ watchContent(download: Download): void {
const container = download['container'];
localStorage.setItem('player_navigator', this.router.url.split(';')[0]);
const is_playlist = container['uids']; // hacky, TODO: fix
@@ -230,7 +231,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
}
}
- combineDownloads(downloads_old, downloads_new) {
+ combineDownloads(downloads_old: Download[], downloads_new: Download[]): Download[] {
// only keeps downloads that exist in the new set
downloads_old = downloads_old.filter(download_old => downloads_new.some(download_new => download_new.uid === download_old.uid));
@@ -251,7 +252,7 @@ export class DownloadsComponent implements OnInit, OnDestroy {
return downloads_old;
}
- showError(download) {
+ showError(download: Download): void {
const copyToClipboardEmitter = new EventEmitter();
this.dialog.open(ConfirmDialogComponent, {
data: {
@@ -272,10 +273,3 @@ export class DownloadsComponent implements OnInit, OnDestroy {
});
}
}
-
-export interface Download {
- timestamp_start: number;
- title: string;
- step_index: number;
- progress: string;
-}
\ No newline at end of file
diff --git a/src/app/components/logs-viewer/logs-viewer.component.ts b/src/app/components/logs-viewer/logs-viewer.component.ts
index 5a218cc..c05c9f9 100644
--- a/src/app/components/logs-viewer/logs-viewer.component.ts
+++ b/src/app/components/logs-viewer/logs-viewer.component.ts
@@ -43,17 +43,17 @@ export class LogsViewerComponent implements OnInit {
})
});
} else {
- this.postsService.openSnackBar('Failed to retrieve logs!');
+ this.postsService.openSnackBar($localize`Failed to retrieve logs!`);
}
}, err => {
this.logs_loading = false;
console.error(err);
- this.postsService.openSnackBar('Failed to retrieve logs!');
+ this.postsService.openSnackBar($localize`Failed to retrieve logs!`);
});
}
copiedLogsToClipboard() {
- this.postsService.openSnackBar('Logs copied to clipboard!');
+ this.postsService.openSnackBar($localize`Logs copied to clipboard!`);
}
clearLogs() {
@@ -72,12 +72,12 @@ export class LogsViewerComponent implements OnInit {
this.logs = [];
this.logs_text = '';
this.getLogs();
- this.postsService.openSnackBar('Logs successfully cleared!');
+ this.postsService.openSnackBar($localize`Logs successfully cleared!`);
} else {
- this.postsService.openSnackBar('Failed to clear logs!');
+ this.postsService.openSnackBar($localize`Failed to clear logs!`);
}
}, err => {
- this.postsService.openSnackBar('Failed to clear logs!');
+ this.postsService.openSnackBar($localize`Failed to clear logs!`);
});
}
});
diff --git a/src/app/components/recent-videos/recent-videos.component.html b/src/app/components/recent-videos/recent-videos.component.html
index fa2ba2a..83c5368 100644
--- a/src/app/components/recent-videos/recent-videos.component.html
+++ b/src/app/components/recent-videos/recent-videos.component.html
@@ -17,7 +17,8 @@
-
My videos
+ My files
+ {{customHeader}}
@@ -28,14 +29,15 @@
-
+
-
-
+
- No videos found.
+ No files found.
0">
@@ -46,7 +48,54 @@
-
+
+
+
+
+ Normal order
+ Reverse order
+
+
+
+
+
+
+
+
+
+
+
No files selected!
+
+
+
+
+
+
+
+
+
+ {{(file.type === 'audio' || file.isAudio) ? 'audiotrack' : 'movie'}}
+ {{file.title}}
+
+
{{file.registered | date:'shortDate'}}
+
+
+
+
+
+
+ 0">
+
+
+
+
+
+
+
+
+
+
+
0">
File type
diff --git a/src/app/components/recent-videos/recent-videos.component.scss b/src/app/components/recent-videos/recent-videos.component.scss
index 49023ec..221a0b3 100644
--- a/src/app/components/recent-videos/recent-videos.component.scss
+++ b/src/app/components/recent-videos/recent-videos.component.scss
@@ -61,4 +61,61 @@
.my-videos-title {
top: 0px;
}
+}
+
+.list-ghosts {
+ position: relative;
+ top: 4px;
+}
+
+.audio-video-icon {
+ position: relative;
+ top: 6px;
+}
+
+.cdk-drag-preview {
+ box-sizing: border-box;
+ border-radius: 4px;
+ box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
+ 0 8px 10px 1px rgba(0, 0, 0, 0.14),
+ 0 3px 14px 2px rgba(0, 0, 0, 0.12);
+}
+
+.cdk-drag-placeholder {
+ opacity: 0;
+}
+
+.cdk-drag-animating {
+ transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+}
+
+.media-box:last-child {
+ border: none;
+}
+
+.media-list.cdk-drop-list-dragging .media-box:not(.cdk-drag-placeholder) {
+ transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
+}
+
+.remove-item-button {
+ right: 10px;
+ position: absolute;
+ top: 4px;
+}
+
+.playlist-item-text {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 70%;
+ margin: 0 auto;
+}
+
+.blurred {
+ filter: blur(2px);
+}
+
+.downloading-spinner {
+ align-self: center;
+ position: absolute;
}
\ No newline at end of file
diff --git a/src/app/components/recent-videos/recent-videos.component.ts b/src/app/components/recent-videos/recent-videos.component.ts
index 76e297f..90522ff 100644
--- a/src/app/components/recent-videos/recent-videos.component.ts
+++ b/src/app/components/recent-videos/recent-videos.component.ts
@@ -1,10 +1,11 @@
-import { Component, OnInit, ViewChild } from '@angular/core';
+import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
import { PostsService } from 'app/posts.services';
import { Router } from '@angular/router';
-import { FileType } from '../../../api-types';
+import { DatabaseFile, FileType, FileTypeFilter } from '../../../api-types';
import { MatPaginator } from '@angular/material/paginator';
import { Subject } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
+import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
@Component({
selector: 'app-recent-videos',
@@ -13,6 +14,26 @@ import { distinctUntilChanged } from 'rxjs/operators';
})
export class RecentVideosComponent implements OnInit {
+ @Input() usePaginator = true;
+
+ // File selection
+
+ @Input() selectMode = false;
+ @Input() defaultSelected: DatabaseFile[] = [];
+ @Input() sub_id = null;
+ @Input() customHeader = null;
+ @Input() selectedIndex = 1;
+ @Output() fileSelectionEmitter = new EventEmitter<{new_selection: string[], thumbnailURL: string}>();
+
+ pageSize = 10;
+ paged_data: DatabaseFile[] = null;
+
+ selected_data: string[] = [];
+ selected_data_objs: DatabaseFile[] = [];
+ reverse_order = false;
+
+ // File listing (with cards)
+
cached_file_count = 0;
loading_files = null;
@@ -20,7 +41,7 @@ export class RecentVideosComponent implements OnInit {
subscription_files_received = false;
file_count = 10;
searchChangedSubject: Subject = new Subject();
- downloading_content = {'video': {}, 'audio': {}};
+ downloading_content = {};
search_mode = false;
search_text = '';
searchIsFocused = false;
@@ -57,18 +78,32 @@ export class RecentVideosComponent implements OnInit {
playlists = null;
- pageSize = 10;
- paged_data = null;
-
@ViewChild('paginator') paginator: MatPaginator
constructor(public postsService: PostsService, private router: Router) {
// get cached file count
if (localStorage.getItem('cached_file_count')) {
this.cached_file_count = +localStorage.getItem('cached_file_count') <= 10 ? +localStorage.getItem('cached_file_count') : 10;
-
this.loading_files = Array(this.cached_file_count).fill(0);
}
+
+ // set filter property to cached value
+ const cached_filter_property = localStorage.getItem('filter_property');
+ if (cached_filter_property && this.filterProperties[cached_filter_property]) {
+ this.filterProperty = this.filterProperties[cached_filter_property];
+ }
+
+ // set file type filter to cached value
+ const cached_file_type_filter = localStorage.getItem('file_type_filter');
+ if (this.usePaginator && cached_file_type_filter) {
+ this.fileTypeFilter = cached_file_type_filter;
+ }
+
+ const sort_order = localStorage.getItem('recent_videos_sort_order');
+
+ if (sort_order) {
+ this.descendingMode = sort_order === 'descending';
+ }
}
ngOnInit(): void {
@@ -96,23 +131,9 @@ export class RecentVideosComponent implements OnInit {
}
});
- // set filter property to cached value
- const cached_filter_property = localStorage.getItem('filter_property');
- if (cached_filter_property && this.filterProperties[cached_filter_property]) {
- this.filterProperty = this.filterProperties[cached_filter_property];
- }
-
- // set file type filter to cached value
- const cached_file_type_filter = localStorage.getItem('file_type_filter');
- if (cached_file_type_filter) {
- this.fileTypeFilter = cached_file_type_filter;
- }
-
- const sort_order = localStorage.getItem('recent_videos_sort_order');
-
- if (sort_order) {
- this.descendingMode = sort_order === 'descending';
- }
+
+ this.selected_data = this.defaultSelected.map(file => file.uid);
+ this.selected_data_objs = this.defaultSelected;
this.searchChangedSubject
.debounceTime(500)
@@ -127,7 +148,7 @@ export class RecentVideosComponent implements OnInit {
});
}
- getAllPlaylists() {
+ getAllPlaylists(): void {
this.postsService.getPlaylists().subscribe(res => {
this.playlists = res['playlists'];
});
@@ -135,22 +156,22 @@ export class RecentVideosComponent implements OnInit {
// search
- onSearchInputChanged(newvalue) {
+ onSearchInputChanged(newvalue: string): void {
this.normal_files_received = false;
this.searchChangedSubject.next(newvalue);
}
- filterOptionChanged(value) {
+ filterOptionChanged(value: string): void {
localStorage.setItem('filter_property', value['key']);
this.getAllFiles();
}
- fileTypeFilterChanged(value) {
+ fileTypeFilterChanged(value: string): void {
localStorage.setItem('file_type_filter', value);
this.getAllFiles();
}
- toggleModeChange() {
+ toggleModeChange(): void {
this.descendingMode = !this.descendingMode;
localStorage.setItem('recent_videos_sort_order', this.descendingMode ? 'descending' : 'ascending');
this.getAllFiles();
@@ -158,12 +179,12 @@ export class RecentVideosComponent implements OnInit {
// get files
- getAllFiles(cache_mode = false) {
+ getAllFiles(cache_mode = false): void {
this.normal_files_received = cache_mode;
const current_file_index = (this.paginator?.pageIndex ? this.paginator.pageIndex : 0)*this.pageSize;
const sort = {by: this.filterProperty['property'], order: this.descendingMode ? -1 : 1};
const range = [current_file_index, current_file_index + this.pageSize];
- this.postsService.getAllFiles(sort, range, this.search_mode ? this.search_text : null, this.fileTypeFilter).subscribe(res => {
+ this.postsService.getAllFiles(sort, range, this.search_mode ? this.search_text : null, this.fileTypeFilter as FileTypeFilter, this.sub_id).subscribe(res => {
this.file_count = res['file_count'];
this.paged_data = res['files'];
for (let i = 0; i < this.paged_data.length; i++) {
@@ -191,21 +212,12 @@ export class RecentVideosComponent implements OnInit {
}
}
- navigateToFile(file, new_tab) {
+ navigateToFile(file: DatabaseFile, new_tab: boolean): void {
localStorage.setItem('player_navigator', this.router.url);
if (file.sub_id) {
- const sub = this.postsService.getSubscriptionByID(file.sub_id);
- if (sub.streamingOnly) {
- // streaming only mode subscriptions
- // !new_tab ? this.router.navigate(['/player', {name: file.id,
- // url: file.requested_formats ? file.requested_formats[0].url : file.url}])
- // : window.open(`/#/player;name=${file.id};url=${file.requested_formats ? file.requested_formats[0].url : file.url}`);
- } else {
- // normal subscriptions
!new_tab ? this.router.navigate(['/player', {uid: file.uid,
- type: file.isAudio ? 'audio' : 'video'}])
+ type: file.isAudio ? 'audio' : 'video'}])
: window.open(`/#/player;uid=${file.uid};type=${file.isAudio ? 'audio' : 'video'}`);
- }
} else {
// normal files
!new_tab ? this.router.navigate(['/player', {type: file.isAudio ? 'audio' : 'video', uid: file.uid}])
@@ -213,46 +225,26 @@ export class RecentVideosComponent implements OnInit {
}
}
- goToSubscription(file) {
+ goToSubscription(file: DatabaseFile): void {
this.router.navigate(['/subscription', {id: file.sub_id}]);
}
// downloading
- downloadFile(file) {
- if (file.sub_id) {
- this.downloadSubscriptionFile(file);
- } else {
- this.downloadNormalFile(file);
- }
- }
-
- downloadSubscriptionFile(file) {
- const type = (file.isAudio ? 'audio' : 'video') as FileType;
- const ext = type === 'audio' ? '.mp3' : '.mp4'
- const sub = this.postsService.getSubscriptionByID(file.sub_id);
- this.postsService.downloadFileFromServer(file.uid).subscribe(res => {
- const blob: Blob = res;
- saveAs(blob, file.id + ext);
- }, err => {
- console.log(err);
- });
- }
-
- downloadNormalFile(file) {
+ downloadFile(file: DatabaseFile): void {
const type = (file.isAudio ? 'audio' : 'video') as FileType;
const ext = type === 'audio' ? '.mp3' : '.mp4'
const name = file.id;
- this.downloading_content[type][name] = true;
+ this.downloading_content[file.uid] = true;
this.postsService.downloadFileFromServer(file.uid).subscribe(res => {
- this.downloading_content[type][name] = false;
+ this.downloading_content[file.uid] = false;
const blob: Blob = res;
saveAs(blob, decodeURIComponent(name) + ext);
- if (!this.postsService.config.Extra.file_manager_enabled) {
+ if (!this.postsService.config.Extra.file_manager_enabled && !file.sub_id) {
// tell server to delete the file once downloaded
- this.postsService.deleteFile(file.uid).subscribe(delRes => {
- // reload mp4s
+ this.postsService.deleteFile(file.uid).subscribe(() => {
+ // reload files
this.getAllFiles();
});
}
@@ -263,7 +255,6 @@ export class RecentVideosComponent implements OnInit {
deleteFile(args) {
const file = args.file;
- const index = args.index;
const blacklistMode = args.blacklistMode;
if (file.sub_id) {
@@ -273,20 +264,20 @@ export class RecentVideosComponent implements OnInit {
}
}
- deleteNormalFile(file, blacklistMode = false) {
+ deleteNormalFile(file: DatabaseFile, blacklistMode = false): void {
this.postsService.deleteFile(file.uid, blacklistMode).subscribe(result => {
if (result) {
- this.postsService.openSnackBar('Delete success!', 'OK.');
+ this.postsService.openSnackBar($localize`Delete success!`, $localize`OK.`);
this.removeFileCard(file);
} else {
- this.postsService.openSnackBar('Delete failed!', 'OK.');
+ this.postsService.openSnackBar($localize`Delete failed!`, $localize`OK.`);
}
- }, err => {
- this.postsService.openSnackBar('Delete failed!', 'OK.');
+ }, () => {
+ this.postsService.openSnackBar($localize`Delete failed!`, $localize`OK.`);
});
}
- deleteSubscriptionFile(file, blacklistMode = false) {
+ deleteSubscriptionFile(file: DatabaseFile, blacklistMode = false): void {
if (blacklistMode) {
this.deleteForever(file);
} else {
@@ -294,28 +285,29 @@ export class RecentVideosComponent implements OnInit {
}
}
- deleteAndRedownload(file) {
+ deleteAndRedownload(file: DatabaseFile): void {
const sub = this.postsService.getSubscriptionByID(file.sub_id);
- this.postsService.deleteSubscriptionFile(sub, file.id, false, file.uid).subscribe(res => {
- this.postsService.openSnackBar(`Successfully deleted file: '${file.id}'`);
+ this.postsService.deleteSubscriptionFile(sub, file.id, false, file.uid).subscribe(() => {
+ this.postsService.openSnackBar($localize`Successfully deleted file: ` + file.id);
this.removeFileCard(file);
});
}
- deleteForever(file) {
+ deleteForever(file: DatabaseFile): void {
const sub = this.postsService.getSubscriptionByID(file.sub_id);
- this.postsService.deleteSubscriptionFile(sub, file.id, true, file.uid).subscribe(res => {
- this.postsService.openSnackBar(`Successfully deleted file: '${file.id}'`);
+ this.postsService.deleteSubscriptionFile(sub, file.id, true, file.uid).subscribe(() => {
+ this.postsService.openSnackBar($localize`Successfully deleted file: ` + file.id);
this.removeFileCard(file);
});
}
- removeFileCard(file_to_remove) {
+ removeFileCard(file_to_remove: DatabaseFile): void {
const index = this.paged_data.map(e => e.uid).indexOf(file_to_remove.uid);
this.paged_data.splice(index, 1);
this.getAllFiles(true);
}
+ // TODO: Add translation support for these snackbars
addFileToPlaylist(info_obj) {
const file = info_obj['file'];
const playlist_id = info_obj['playlist_id'];
@@ -335,13 +327,13 @@ export class RecentVideosComponent implements OnInit {
// sorting and filtering
- sortFiles(a, b) {
+ sortFiles(a: DatabaseFile, b: DatabaseFile): number {
// uses the 'registered' flag as the timestamp
const result = b.registered - a.registered;
return result;
}
- durationStringToNumber(dur_str) {
+ durationStringToNumber(dur_str: string): number {
let num_sum = 0;
const dur_str_parts = dur_str.split(':');
for (let i = dur_str_parts.length - 1; i >= 0; i--) {
@@ -355,4 +347,42 @@ export class RecentVideosComponent implements OnInit {
this.loading_files = Array(this.pageSize).fill(0);
this.getAllFiles();
}
+
+ fileSelectionChanged(event: { option: { _selected: boolean; value: DatabaseFile; } }): void {
+ const adding = event.option._selected;
+ const value = event.option.value;
+ if (adding) {
+ this.selected_data.push(value.uid);
+ this.selected_data_objs.push(value);
+ } else {
+ this.selected_data = this.selected_data.filter(e => e !== value.uid);
+ this.selected_data_objs = this.selected_data_objs.filter(e => e.uid !== value.uid);
+ }
+
+ this.fileSelectionEmitter.emit({new_selection: this.selected_data, thumbnailURL: this.selected_data_objs[0].thumbnailURL});
+ }
+
+ toggleSelectionOrder(): void {
+ this.reverse_order = !this.reverse_order;
+ localStorage.setItem('default_playlist_order_reversed', '' + this.reverse_order);
+ }
+
+ drop(event: CdkDragDrop): void {
+ if (this.reverse_order) {
+ event.previousIndex = this.selected_data.length - 1 - event.previousIndex;
+ event.currentIndex = this.selected_data.length - 1 - event.currentIndex;
+ }
+ moveItemInArray(this.selected_data, event.previousIndex, event.currentIndex);
+ moveItemInArray(this.selected_data_objs, event.previousIndex, event.currentIndex);
+ this.fileSelectionEmitter.emit({new_selection: this.selected_data, thumbnailURL: this.selected_data_objs[0].thumbnailURL});
+ }
+
+ removeSelectedFile(index: number): void {
+ if (this.reverse_order) {
+ index = this.selected_data.length - 1 - index;
+ }
+ this.selected_data.splice(index, 1);
+ this.selected_data_objs.splice(index, 1);
+ this.fileSelectionEmitter.emit({new_selection: this.selected_data, thumbnailURL: this.selected_data_objs[0].thumbnailURL});
+ }
}
diff --git a/src/app/components/tasks/tasks.component.ts b/src/app/components/tasks/tasks.component.ts
index 8fec372..c4dd2a1 100644
--- a/src/app/components/tasks/tasks.component.ts
+++ b/src/app/components/tasks/tasks.component.ts
@@ -7,6 +7,7 @@ import { ConfirmDialogComponent } from 'app/dialogs/confirm-dialog/confirm-dialo
import { RestoreDbDialogComponent } from 'app/dialogs/restore-db-dialog/restore-db-dialog.component';
import { UpdateTaskScheduleDialogComponent } from 'app/dialogs/update-task-schedule-dialog/update-task-schedule-dialog.component';
import { PostsService } from 'app/posts.services';
+import { Task } from 'api-types';
@Component({
selector: 'app-tasks',
@@ -17,7 +18,7 @@ export class TasksComponent implements OnInit {
interval_id = null;
tasks_check_interval = 1500;
- tasks = null;
+ tasks: Task[] = null;
tasks_retrieved = false;
displayedColumns: string[] = ['title', 'last_ran', 'last_confirmed', 'status', 'actions'];
@@ -55,6 +56,11 @@ export class TasksComponent implements OnInit {
getTasks(): void {
this.postsService.getTasks().subscribe(res => {
+ for (const task of res['tasks']) {
+ if (task.title.includes('youtube-dl')) {
+ task.title = task.title.replace('youtube-dl', this.postsService.config.Advanced.default_downloader);
+ }
+ }
if (this.tasks) {
if (JSON.stringify(this.tasks) === JSON.stringify(res['tasks'])) return;
for (const task of res['tasks']) {
@@ -94,7 +100,7 @@ export class TasksComponent implements OnInit {
});
}
- scheduleTask(task: any): void {
+ scheduleTask(task: Task): void {
// open dialog
const dialogRef = this.dialog.open(UpdateTaskScheduleDialogComponent, {
data: {
@@ -152,13 +158,3 @@ export class TasksComponent implements OnInit {
}
}
-
-export interface Task {
- key: string;
- title: string;
- last_ran: number;
- last_confirmed: number;
- running: boolean;
- confirming: boolean;
- data: unknown;
-}
\ No newline at end of file
diff --git a/src/app/components/twitch-chat/twitch-chat.component.ts b/src/app/components/twitch-chat/twitch-chat.component.ts
index bbeb7de..8208b84 100644
--- a/src/app/components/twitch-chat/twitch-chat.component.ts
+++ b/src/app/components/twitch-chat/twitch-chat.component.ts
@@ -96,18 +96,18 @@ export class TwitchChatComponent implements OnInit, OnDestroy {
let vodId = this.db_file.url.split('videos/').length > 1 && this.db_file.url.split('videos/')[1];
vodId = vodId.split('?')[0];
if (!vodId) {
- this.postsService.openSnackBar('VOD url for this video is not supported. VOD ID must be after "twitch.tv/videos/"');
+ this.postsService.openSnackBar($localize`VOD url for this video is not supported. VOD ID must be after "twitch.tv/videos/"`);
}
this.postsService.downloadTwitchChat(this.db_file.id, this.db_file.isAudio ? 'audio' : 'video', vodId, null, this.sub).subscribe(res => {
if (res['chat']) {
this.initializeChatCheck(res['chat']);
} else {
this.downloading_chat = false;
- this.postsService.openSnackBar('Download failed.')
+ this.postsService.openSnackBar($localize`Download failed.`)
}
}, err => {
this.downloading_chat = false;
- this.postsService.openSnackBar('Chat could not be downloaded.')
+ this.postsService.openSnackBar($localize`Chat could not be downloaded.`)
});
}
diff --git a/src/app/components/unified-file-card/unified-file-card.component.html b/src/app/components/unified-file-card/unified-file-card.component.html
index 1fef6d8..6290adf 100644
--- a/src/app/components/unified-file-card/unified-file-card.component.html
+++ b/src/app/components/unified-file-card/unified-file-card.component.html
@@ -23,7 +23,7 @@
-
+
@@ -34,10 +34,10 @@
restoreDelete and redownload
-
+
diff --git a/src/app/components/unified-file-card/unified-file-card.component.ts b/src/app/components/unified-file-card/unified-file-card.component.ts
index a9cc7c9..6c4f658 100644
--- a/src/app/components/unified-file-card/unified-file-card.component.ts
+++ b/src/app/components/unified-file-card/unified-file-card.component.ts
@@ -9,7 +9,6 @@ import localeES from '@angular/common/locales/es';
import localeDE from '@angular/common/locales/de';
import localeZH from '@angular/common/locales/zh';
import localeNB from '@angular/common/locales/nb';
-import { DatabaseFile, Playlist } from 'api-types';
registerLocaleData(localeGB);
registerLocaleData(localeFR);
@@ -105,12 +104,16 @@ export class UnifiedFileCardComponent implements OnInit {
}
openFileInfoDialog() {
- this.dialog.open(VideoInfoDialogComponent, {
+ const dialogRef = this.dialog.open(VideoInfoDialogComponent, {
data: {
file: this.file_obj,
},
minWidth: '50vw'
- })
+ });
+
+ dialogRef.afterClosed().subscribe(() => {
+ this.file_obj = dialogRef.componentInstance.file;
+ });
}
emitEditPlaylist() {
diff --git a/src/app/consts.ts b/src/app/consts.ts
index 950aff6..013e146 100644
--- a/src/app/consts.ts
+++ b/src/app/consts.ts
@@ -1 +1 @@
-export const CURRENT_VERSION = 'v4.2';
+export const CURRENT_VERSION = 'v4.3';
diff --git a/src/app/create-playlist/create-playlist.component.html b/src/app/create-playlist/create-playlist.component.html
index ad21ec0..c196efd 100644
--- a/src/app/create-playlist/create-playlist.component.html
+++ b/src/app/create-playlist/create-playlist.component.html
@@ -1,36 +1,29 @@
-Create a playlist
-