IO-2221 IO-2323 Correct Download/Delete/Move functions

This commit is contained in:
Allan Carr
2023-07-20 11:19:21 -07:00
parent a678383dee
commit aa3b567a5b
9 changed files with 415 additions and 334 deletions

View File

@@ -1,14 +1,14 @@
import { Request, Response } from "express";
import ft from "file-type";
import core from "file-type/core";
import fs from "fs-extra";
import path, { relative } from "path";
import GenerateUrl from "../util/MediaUrlGen";
import GenerateThumbnail from "../util/generateThumbnail";
import MediaFile from "../util/interfaces/MediaFile";
import ListableChecker from "../util/listableChecker";
import GenerateUrl from "../util/MediaUrlGen";
import { PathToRoBillsFolder, PathToRoFolder } from "../util/pathGenerators";
import { PathToRoBillsFolder } from "../util/pathGenerators";
import { FolderPaths } from "../util/serverInit";
import core from "file-type/core";
import ft from "file-type";
/** @description Bills will use the hierarchy of PDFs stored under the Job first, and then the Bills folder. */
export async function BillsListMedia(req: Request, res: Response) {
@@ -35,6 +35,7 @@ export async function BillsListMedia(req: Request, res: Response) {
);
return {
type,
size: file.size,
src: GenerateUrl([
FolderPaths.StaticPath,
FolderPaths.JobsFolder,
@@ -52,6 +53,7 @@ export async function BillsListMedia(req: Request, res: Response) {
thumbnailHeight: 250,
thumbnailWidth: 250,
filename: file.filename,
relativeFilePath,
};
})
);
@@ -83,9 +85,10 @@ export async function BillsListMedia(req: Request, res: Response) {
const type: core.FileTypeResult | undefined = await ft.fromFile(
relativeFilePath
);
const fileSize = await fs.stat(relativeFilePath);
return {
type,
size: fileSize.size,
src: GenerateUrl([
FolderPaths.StaticPath,
FolderPaths.JobsFolder,
@@ -103,6 +106,7 @@ export async function BillsListMedia(req: Request, res: Response) {
thumbnailHeight: 250,
thumbnailWidth: 250,
filename: file.name,
relativeFilePath,
};
})
);

View File

@@ -2,14 +2,10 @@ import { Request, Response } from "express";
import fs from "fs-extra";
import path from "path";
import { logger } from "../server";
import GenerateThumbnail from "../util/generateThumbnail";
import MediaFile from "../util/interfaces/MediaFile";
import ListableChecker from "../util/listableChecker";
import GenerateUrl from "../util/MediaUrlGen";
import { PathToRoFolder } from "../util/pathGenerators";
import { FolderPaths, JobRelativeFilePath } from "../util/serverInit";
import ft from "file-type";
import core from "file-type/core";
import { PathToRoBillsFolder, PathToRoFolder } from "../util/pathGenerators";
import { BillsRelativeFilePath, JobRelativeFilePath } from "../util/serverInit";
export async function JobsDeleteMedia(req: Request, res: Response) {
const jobid: string = (req.body.jobid || "").trim();
@@ -18,12 +14,33 @@ export async function JobsDeleteMedia(req: Request, res: Response) {
logger.debug("Deleteing media for job: " + PathToRoFolder(jobid));
let ret: MediaFile[];
try {
//We just uploaded files, we're going to send only those back.
await Promise.all(
files.map(async (filename) => {
const relativeFilePath: string = JobRelativeFilePath(jobid, filename);
// Setup lists for both file locations
const jobFileList: fs.Dirent[] = (
await fs.readdir(PathToRoFolder(jobid), {
withFileTypes: true,
})
).filter((f) => f.isFile() && ListableChecker(f));
const billFileList: fs.Dirent[] = (
await fs.readdir(PathToRoBillsFolder(jobid), {
withFileTypes: true,
})
).filter((f) => f.isFile() && ListableChecker(f));
await fs.remove(relativeFilePath);
// Check both list for the files that need to be deleted
await Promise.all(
jobFileList.map(async (file) => {
if (files.includes(path.parse(path.basename(file.name)).base)) {
// File is in the set of requested files.
await fs.remove(JobRelativeFilePath(jobid, file.name));
}
})
);
await Promise.all(
billFileList.map(async (file) => {
if (files.includes(path.parse(path.basename(file.name)).base)) {
// File is in the set of requested files.
await fs.remove(BillsRelativeFilePath(jobid, file.name));
}
})
);

View File

@@ -1,16 +1,11 @@
import { Request, Response } from "express";
import fs from "fs-extra";
import multer from "multer";
import JSZip from "jszip";
import path from "path";
import { logger } from "../server";
import GenerateThumbnail from "../util/generateThumbnail";
import generateUniqueFilename from "../util/generateUniqueFilename";
import { ConvertHeicFiles } from "../util/heicConverter";
import { PathToRoFolder } from "../util/pathGenerators";
import { JobsListMedia } from "./jobsListMedia";
import JSZip from "jszip";
import ListableChecker from "../util/listableChecker";
import { JobRelativeFilePath } from "../util/serverInit";
import { PathToRoBillsFolder, PathToRoFolder } from "../util/pathGenerators";
import { BillsRelativeFilePath, JobRelativeFilePath } from "../util/serverInit";
//param: files: string[] | array of filenames.
export async function jobsDownloadMedia(req: Request, res: Response) {
@@ -25,17 +20,21 @@ export async function jobsDownloadMedia(req: Request, res: Response) {
logger.debug(`Generating batch download for Job ID ${jobid}`, files);
//Prepare the zip file.
const filesList: fs.Dirent[] = (
const jobFileList: fs.Dirent[] = (
await fs.readdir(PathToRoFolder(jobid), {
withFileTypes: true,
})
).filter((f) => f.isFile() && ListableChecker(f));
const billFileList: fs.Dirent[] = (
await fs.readdir(PathToRoBillsFolder(jobid), {
withFileTypes: true,
})
).filter((f) => f.isFile() && ListableChecker(f));
if (files.length === 0) {
//Get everything.
await Promise.all(
filesList.map(async (file) => {
jobFileList.map(async (file) => {
//Do something async
const fileOnDisk: Buffer = await fs.readFile(
JobRelativeFilePath(jobid, file.name)
@@ -43,10 +42,19 @@ export async function jobsDownloadMedia(req: Request, res: Response) {
zip.file(path.parse(path.basename(file.name)).base, fileOnDisk);
})
);
await Promise.all(
billFileList.map(async (file) => {
//Do something async
const fileOnDisk: Buffer = await fs.readFile(
BillsRelativeFilePath(jobid, file.name)
);
zip.file(path.parse(path.basename(file.name)).base, fileOnDisk);
})
);
} else {
//Get the files that are in the list and see which are requested.
await Promise.all(
filesList.map(async (file) => {
jobFileList.map(async (file) => {
if (files.includes(path.parse(path.basename(file.name)).base)) {
// File is in the set of requested files.
const fileOnDisk: Buffer = await fs.readFile(
@@ -54,7 +62,18 @@ export async function jobsDownloadMedia(req: Request, res: Response) {
);
zip.file(path.parse(path.basename(file.name)).base, fileOnDisk);
}
})
}),
);
await Promise.all(
billFileList.map(async (file) => {
if (files.includes(path.parse(path.basename(file.name)).base)) {
// File is in the set of requested files.
const fileOnDisk: Buffer = await fs.readFile(
BillsRelativeFilePath(jobid, file.name)
);
zip.file(path.parse(path.basename(file.name)).base, fileOnDisk);
}
}),
);
}
//Send it as a response to download it automatically.

View File

@@ -1,15 +1,14 @@
import { Request, Response } from "express";
import ft from "file-type";
import core from "file-type/core";
import fs from "fs-extra";
import path from "path";
import { logger } from "../server";
import GenerateUrl from "../util/MediaUrlGen";
import GenerateThumbnail from "../util/generateThumbnail";
import MediaFile from "../util/interfaces/MediaFile";
import ListableChecker from "../util/listableChecker";
import GenerateUrl from "../util/MediaUrlGen";
import { PathToRoFolder } from "../util/pathGenerators";
import { FolderPaths, JobRelativeFilePath } from "../util/serverInit";
import ft from "file-type";
import core from "file-type/core";
export async function JobsListMedia(req: Request, res: Response) {
const jobid: string = (req.body.jobid || "").trim();

View File

@@ -1,13 +1,11 @@
import { Request, Response } from "express";
import fs from "fs-extra";
import path from "path";
import GenerateThumbnail from "../util/generateThumbnail";
import GenerateUrl from "../util/MediaUrlGen";
import { FolderPaths } from "../util/serverInit";
import multer from "multer";
import { JobsListMedia } from "./jobsListMedia";
import { PathToRoFolder } from "../util/pathGenerators";
import { logger } from "../server";
import ListableChecker from "../util/listableChecker";
import { PathToRoBillsFolder, PathToRoFolder } from "../util/pathGenerators";
import { FolderPaths } from "../util/serverInit";
import { JobsListMedia } from "./jobsListMedia";
export async function JobsMoveMedia(req: Request, res: Response) {
const jobid: string = (req.body.jobid || "").trim();
@@ -16,7 +14,6 @@ export async function JobsMoveMedia(req: Request, res: Response) {
try {
//Validate the request is valid and contains everything that it needs.
if (from_jobid === "") {
res.status(400).json({ error: "from_jobid must be specified. " });
return;
@@ -25,30 +22,81 @@ export async function JobsMoveMedia(req: Request, res: Response) {
res.status(400).json({ error: "files must be specified. " });
return;
}
// Setup lists for both file locations
const jobFileList: string[] = (
await fs.readdir(PathToRoFolder(from_jobid), {
withFileTypes: true,
})
)
.filter((f) => f.isFile() && ListableChecker(f))
.map((dirent) => dirent.name);
const billFileList: string[] = (
await fs.readdir(PathToRoBillsFolder(from_jobid), {
withFileTypes: true,
})
)
.filter((f) => f.isFile() && ListableChecker(f))
.map((dirent) => dirent.name);
//Make sure the destination RO directory exists.
await fs.ensureDir(PathToRoFolder(jobid));
logger.debug("Moving job based media.", { jobid, from_jobid, files });
const movingQueue: Promise<void>[] = [];
files.forEach((file) => {
movingQueue.push(
fs.move(
path.join(FolderPaths.Jobs, from_jobid, file),
path.join(FolderPaths.Jobs, jobid, file)
)
);
if (jobFileList.includes(file)) {
movingQueue.push(
fs.move(
path.join(FolderPaths.Jobs, from_jobid, file),
path.join(FolderPaths.Jobs, jobid, file)
)
);
movingQueue.push(
fs.move(
path.join(
FolderPaths.Jobs,
from_jobid,
FolderPaths.ThumbsSubDir,
file
),
path.join(FolderPaths.Jobs, jobid, FolderPaths.ThumbsSubDir, file)
)
);
movingQueue.push(
fs.move(
path.join(
FolderPaths.Jobs,
from_jobid,
FolderPaths.ThumbsSubDir,
file
),
path.join(FolderPaths.Jobs, jobid, FolderPaths.ThumbsSubDir, file)
)
);
}
if (billFileList.includes(file)) {
movingQueue.push(
fs.move(
path.join(
FolderPaths.Jobs,
from_jobid,
FolderPaths.BillsSubDir,
file
),
path.join(FolderPaths.Jobs, jobid, FolderPaths.BillsSubDir, file)
)
);
movingQueue.push(
fs.move(
path.join(
FolderPaths.Jobs,
from_jobid,
FolderPaths.BillsSubDir,
FolderPaths.ThumbsSubDir,
file
),
path.join(
FolderPaths.Jobs,
jobid,
FolderPaths.BillsSubDir,
FolderPaths.ThumbsSubDir,
file
)
)
);
}
});
//Use AllSettled as it allows for individual moves to fail.

363
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "bodyshop-media-server",
"version": "0.0.1",
"version": "1.0.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "bodyshop-media-server",
"version": "0.0.1",
"version": "1.0.10",
"license": "UNLICENSED",
"dependencies": {
"axios": "^0.24.0",
@@ -15,14 +15,15 @@
"cors": "^2.8.5",
"dotenv": "10.0.0",
"express": "^4.17.3",
"ffmpeg-static": "^5.0.0",
"file-type": "^16.5.3",
"fs-extra": "^10.1.0",
"gm": "^1.23.1",
"helmet": "^5.0.2",
"image-thumbnail": "^1.0.14",
"jszip": "^3.10.0",
"morgan": "^1.10.0",
"multer": "^1.4.4",
"nocache": "^3.0.4",
"response-time": "^2.3.2",
"simple-thumbnail": "^1.6.5",
"winston": "^3.7.2",
@@ -43,7 +44,7 @@
"typescript": "^4.6.4"
},
"engines": {
"node": "16.15.0"
"node": "^16.14.0"
}
},
"node_modules/@colors/colors": {
@@ -89,20 +90,6 @@
"kuler": "^2.0.0"
}
},
"node_modules/@derhuerst/http-basic": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.2.tgz",
"integrity": "sha512-ek065nW95mleLHo8vZ+ob7QTQPNOwDEjCe27BX2flme/UTu9z2mD1uRRPko38u7al4tTZADMtozpll8PQHAZgg==",
"dependencies": {
"caseless": "^0.12.0",
"concat-stream": "^1.6.2",
"http-response-object": "^3.0.1",
"parse-cache-control": "^1.0.1"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@@ -354,38 +341,6 @@
"node": ">=0.4.0"
}
},
"node_modules/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==",
"dependencies": {
"debug": "4"
},
"engines": {
"node": ">= 6.0.0"
}
},
"node_modules/agent-base/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/agent-base/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/ansi-align": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
@@ -808,11 +763,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -1354,14 +1304,6 @@
"once": "^1.4.0"
}
},
"node_modules/env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
"engines": {
"node": ">=6"
}
},
"node_modules/escape-goat": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -1464,21 +1406,6 @@
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==",
"license": "MIT"
},
"node_modules/ffmpeg-static": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.0.0.tgz",
"integrity": "sha512-z96jGVa8uCVMnyrTvbDZe0d5zbvIVQnfBN+vKDZoVK+ssYpfUJGEmo2DkuY43CA9Ytlsk+5ZVTFTqzvKw1gSaA==",
"hasInstallScript": true,
"dependencies": {
"@derhuerst/http-basic": "^8.2.0",
"env-paths": "^2.2.0",
"https-proxy-agent": "^5.0.0",
"progress": "^2.0.3"
},
"engines": {
"node": ">=16"
}
},
"node_modules/file-stream-rotator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
@@ -1871,52 +1798,6 @@
"node": ">= 0.8"
}
},
"node_modules/http-response-object": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
"integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
"dependencies": {
"@types/node": "^10.0.3"
}
},
"node_modules/http-response-object/node_modules/@types/node": {
"version": "10.17.60",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
},
"node_modules/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==",
"dependencies": {
"agent-base": "6",
"debug": "4"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/https-proxy-agent/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/https-proxy-agent/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -1992,6 +1873,11 @@
"follow-redirects": "^1.14.0"
}
},
"node_modules/immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
},
"node_modules/import-lazy": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
@@ -2218,6 +2104,36 @@
"graceful-fs": "^4.1.6"
}
},
"node_modules/jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
"dependencies": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"setimmediate": "^1.0.5"
}
},
"node_modules/jszip/node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"node_modules/jszip/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/keyv": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@@ -2247,6 +2163,14 @@
"node": ">=8"
}
},
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"dependencies": {
"immediate": "~3.0.5"
}
},
"node_modules/logform": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.4.0.tgz",
@@ -2484,6 +2408,14 @@
"node": ">= 0.6"
}
},
"node_modules/nocache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz",
"integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/node-abi": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz",
@@ -2704,10 +2636,10 @@
"node": ">=8"
}
},
"node_modules/parse-cache-control": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
"integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104="
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"node_modules/parseurl": {
"version": "1.3.3",
@@ -2793,14 +2725,6 @@
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
"license": "MIT"
},
"node_modules/progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -3107,6 +3031,11 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"license": "ISC"
},
"node_modules/setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -3967,17 +3896,6 @@
"kuler": "^2.0.0"
}
},
"@derhuerst/http-basic": {
"version": "8.2.2",
"resolved": "https://registry.npmjs.org/@derhuerst/http-basic/-/http-basic-8.2.2.tgz",
"integrity": "sha512-ek065nW95mleLHo8vZ+ob7QTQPNOwDEjCe27BX2flme/UTu9z2mD1uRRPko38u7al4tTZADMtozpll8PQHAZgg==",
"requires": {
"caseless": "^0.12.0",
"concat-stream": "^1.6.2",
"http-response-object": "^3.0.1",
"parse-cache-control": "^1.0.1"
}
},
"@sindresorhus/is": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
@@ -4186,29 +4104,6 @@
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true
},
"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=="
}
}
},
"ansi-align": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz",
@@ -4514,11 +4409,6 @@
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"dev": true
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -4915,11 +4805,6 @@
"once": "^1.4.0"
}
},
"env-paths": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="
},
"escape-goat": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
@@ -4991,17 +4876,6 @@
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
},
"ffmpeg-static": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ffmpeg-static/-/ffmpeg-static-5.0.0.tgz",
"integrity": "sha512-z96jGVa8uCVMnyrTvbDZe0d5zbvIVQnfBN+vKDZoVK+ssYpfUJGEmo2DkuY43CA9Ytlsk+5ZVTFTqzvKw1gSaA==",
"requires": {
"@derhuerst/http-basic": "^8.2.0",
"env-paths": "^2.2.0",
"https-proxy-agent": "^5.0.0",
"progress": "^2.0.3"
}
},
"file-stream-rotator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz",
@@ -5276,45 +5150,6 @@
"toidentifier": "1.0.1"
}
},
"http-response-object": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
"integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
"requires": {
"@types/node": "^10.0.3"
},
"dependencies": {
"@types/node": {
"version": "10.17.60",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz",
"integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw=="
}
}
},
"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=="
}
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -5363,6 +5198,11 @@
}
}
},
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
},
"import-lazy": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
@@ -5510,6 +5350,38 @@
"universalify": "^2.0.0"
}
},
"jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
"integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
"requires": {
"lie": "~3.3.0",
"pako": "~1.0.2",
"readable-stream": "~2.3.6",
"setimmediate": "^1.0.5"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
}
}
},
"keyv": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@@ -5533,6 +5405,14 @@
"package-json": "^6.3.0"
}
},
"lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"requires": {
"immediate": "~3.0.5"
}
},
"logform": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/logform/-/logform-2.4.0.tgz",
@@ -5698,6 +5578,11 @@
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
},
"nocache": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz",
"integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw=="
},
"node-abi": {
"version": "2.30.1",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.30.1.tgz",
@@ -5852,10 +5737,10 @@
"semver": "^6.2.0"
}
},
"parse-cache-control": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
"integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104="
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"parseurl": {
"version": "1.3.3",
@@ -5909,11 +5794,6 @@
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -6138,6 +6018,11 @@
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
},
"setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",

145
readme.md
View File

@@ -28,43 +28,136 @@ reverse_proxy ims:8000
}
```
## Sample Docker Compose file.
## Sample Docker Compose file
```docker
version: '2'
services:
ims:
traefik:
container_name: traefik-ims
image: traefik:latest
restart: always
init: true
command: # CLI arguments
- --global.checkNewVersion=true
- --global.sendAnonymousUsage=false
- --pilot.dashboard=false
- --entrypoints.https.address=:10443
- --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/12,172.64.0.0/13,131.0.72.0/22,2400:cb00::/32,2606:4700::/32,2803:f800::/32,2405:b500::/32,2405:8100::/32,2a06:98c0::/29,2c0f:f248::/32
- --log=true
- --log.level=ERROR # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.network=t2_proxy
- --certificatesResolvers.dns-cloudflare.acme.email=cloudflare@thinkimex.com
- --certificatesResolvers.dns-cloudflare.acme.storage=/acme.json
- --certificatesResolvers.dns-cloudflare.acme.keyType=EC384
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare
- --certificatesresolvers.dns-cloudflare.acme.dnschallenge.resolvers=1.1.1.1:53,1.0.0.1:53,2606:4700:4700::1111:53,2606:4700:4700::1001:53
- --certificatesResolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=90 # To delay DNS check and reduce LE hitrate
networks:
t2_proxy:
ipv4_address: 192.168.90.254
ports:
- 8000:8000
- target: 10443
published: 10443
protocol: tcp
mode: host
environment:
- TZ=America/Vancouver
- CF_API_EMAIL=cloudflare@thinkimex.com
- CF_DNS_API_TOKEN=b8BWRbkJckVK0IG6600Iq5AYx4HYZ7dLzDWUOZ2D
volumes:
- ~:/root
- "C:\\IMS:/media"
#- "/Users/pfic/Desktop/ISM:/media"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- /home/imex/ims/traefik/acme/acme.json:/acme.json # cert location - you must touch this file and change permissions to 600
labels:
- "traefik.enable=false"
cf-ddns:
container_name: cf-ddns
image: oznu/cloudflare-ddns:latest
networks:
- t2_proxy
restart: always
environment:
- API_KEY=b8BWRbkJckVK0IG6600Iq5AYx4HYZ7dLzDWUOZ2D
- ZONE=imexmedia.ca
- SUBDOMAIN=fastrack
- PROXIED=false
- RRTYPE=A
- DELETE_ON_STOP=false
- DNS_SERVER=1.1.1.1
labels:
- "traefik.enable=false"
ims:
container_name: ims
networks:
- t2_proxy
volumes:
- /mnt/ims:/media
environment:
- MEDIA_PATH=/media
- DUPLICATE_BILL_TO_VENDOR=false
- IMS_TOKEN=ThisIsAnImEXSecretTokenToBeSent
- DUPLICATE_BILL_TO_VENDOR=true
- IMS_TOKEN=6Q9pjF5wFQ2grGyom2rvRPXnkKZDA3BvfNK2J5qQXVuyxTFhjHVX6zwWeYDw3GLAk
- CONVERT_QUALITY=0.8
- KEEP_CONVERTED_ORIGINALS=TRUE
image: imexonline/media-server:latest
#image: imexonline/media-server:beta
restart: unless-stopped
restart: always
labels:
- "traefik.enable=true"
# HTTP Routers
- "traefik.http.routers.ims-rtr.entrypoints=https"
- "traefik.http.routers.ims-rtr.rule=Host(`fastrack.imexmedia.ca`)"
- "traefik.http.routers.ims-rtr.tls.certresolver=dns-cloudflare"
## HTTP Services
- "traefik.http.routers.ims-rtr.service=ims-svc"
- "traefik.http.services.ims-svc.loadbalancer.server.port=8000"
dozzle:
container_name: logs
image: amir20/dozzle:latest
restart: always
networks:
- t2_proxy
ports:
- "8080:8080"
security_opt:
- no-new-privileges:true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
DOZZLE_LEVEL: info
DOZZLE_TAILSIZE: 300
DOZZLE_FILTER: "status=running"
DOZZLE_NO_ANALYTICS: "true"
watchtower:
container_name: watchtower-ims
image: containrrr/watchtower
networks:
- t2_proxy
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /root/.docker/config.json:/config.json
command: --interval 3600
caddy:
image: caddy/caddy:latest
container_name: caddy-service
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- $PWD/Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
environment:
- TZ=America/Vancouver
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_REMOVE_VOLUMES=true
- WATCHTOWER_INCLUDE_STOPPED=true
- WATCHTOWER_INCLUDE_RESTARTING=true
- WATCHTOWER_NO_STARTUP_MESSAGE=false
- WATCHTOWER_REVIVE_STOPPED=true
- WATCHTOWER_ROLLING_RESTART=true
- WATCHTOWER_TIMEOUT=60s
- WATCHTOWER_POLL_INTERVAL=3600
restart: unless-stopped
labels:
- "traefik.enable=false"
networks:
t2_proxy:
name: t2_proxy
driver: bridge
ipam:
config:
- subnet: 192.168.90.0/24
```

View File

@@ -1,7 +1,7 @@
import fs = require("fs-extra");
import path, { resolve } from "path";
import dotenv from "dotenv";
import os from "os";
import path, { resolve } from "path";
import { logger } from "../server";
dotenv.config({
@@ -31,6 +31,9 @@ export const AssetPaths = {
export function JobRelativeFilePath(jobid: string, filename: string) {
return path.join(FolderPaths.Jobs, jobid, filename);
}
export function BillsRelativeFilePath(jobid: string, filename: string) {
return path.join(FolderPaths.Jobs, jobid, FolderPaths.BillsSubDir, filename);
}
export default function InitServer() {
logger.info(`Ensuring Root media path exists: ${FolderPaths.Root}`);
fs.ensureDirSync(FolderPaths.Root);

View File

@@ -869,7 +869,7 @@ fs-extra@^10.1.0:
fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
function-bind@^1.1.1:
@@ -1054,7 +1054,7 @@ image-thumbnail@^1.0.14:
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz"
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
import-lazy@^2.1.0:
@@ -1203,9 +1203,9 @@ jsonfile@^6.0.1:
graceful-fs "^4.1.6"
jszip@^3.10.0:
version "3.10.0"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.0.tgz#faf3db2b4b8515425e34effcdbb086750a346061"
integrity sha512-LDfVtOLtOxb9RXkYOwPyNBTQDL4eUbqahtoY6x07GiDJHwSYvn8sHHIw8wINImV3MqbMNve2gSuM1DDqEKk09Q==
version "3.10.1"
resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz"
integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
dependencies:
lie "~3.3.0"
pako "~1.0.2"
@@ -1233,7 +1233,7 @@ latest-version@^5.1.0:
lie@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz"
integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
dependencies:
immediate "~3.0.5"
@@ -1404,7 +1404,7 @@ negotiator@0.6.3:
nocache@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/nocache/-/nocache-3.0.4.tgz#5b37a56ec6e09fc7d401dceaed2eab40c8bfdf79"
resolved "https://registry.npmjs.org/nocache/-/nocache-3.0.4.tgz"
integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw==
node-abi@^2.21.0:
@@ -1532,7 +1532,7 @@ package-json@^6.3.0:
pako@~1.0.2:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
parseurl@~1.3.3:
@@ -1666,7 +1666,7 @@ readable-stream@1.1.x:
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6:
readable-stream@^2.0.6, readable-stream@^2.2.2:
version "2.3.7"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -1688,6 +1688,19 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readable-stream@~2.3.6:
version "2.3.8"
resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-web-to-node-stream@^3.0.0:
version "3.0.2"
resolved "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz"
@@ -1811,7 +1824,7 @@ set-blocking@~2.0.0:
setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
setprototypeof@1.2.0: