mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: install: strip zip prefix
This commit is contained in:
2 files changed
+58
-5
No files matched your search
@@ -6,7 +6,7 @@ import { CAC } from 'cac';
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import superagent from 'superagent';
|
import superagent from 'superagent';
|
||||||
import tar from 'tar';
|
import tar from 'tar';
|
||||||
import { Logger, streamToBuffer } from '@hydrooj/utils';
|
import { extractZip, Logger } from '@hydrooj/utils';
|
||||||
|
|
||||||
const logger = new Logger('install');
|
const logger = new Logger('install');
|
||||||
let yarnVersion = 0;
|
let yarnVersion = 0;
|
||||||
@@ -32,8 +32,8 @@ function downloadAndExtractTgz(url: string, dest: string) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
async function downloadAndExtractZip(url: string, dest: string) {
|
async function downloadAndExtractZip(url: string, dest: string) {
|
||||||
const res = await streamToBuffer(await superagent.get(url).responseType('blob'));
|
const res = await superagent.get(url).responseType('arraybuffer');
|
||||||
new AdmZip(res).extractAllTo(dest, true);
|
await extractZip(new AdmZip(res.body), dest, true, true);
|
||||||
}
|
}
|
||||||
const types = {
|
const types = {
|
||||||
'.tgz': downloadAndExtractTgz,
|
'.tgz': downloadAndExtractTgz,
|
||||||
@@ -71,6 +71,7 @@ export function register(cli: CAC) {
|
|||||||
newAddonPath = path.join(addonDir, name);
|
newAddonPath = path.join(addonDir, name);
|
||||||
logger.info(`Downloading ${src} to ${newAddonPath}`);
|
logger.info(`Downloading ${src} to ${newAddonPath}`);
|
||||||
fs.ensureDirSync(newAddonPath);
|
fs.ensureDirSync(newAddonPath);
|
||||||
|
fs.emptyDirSync(newAddonPath);
|
||||||
const func = types[Object.keys(types).find((i) => filename.endsWith(i))]!;
|
const func = types[Object.keys(types).find((i) => filename.endsWith(i))]!;
|
||||||
await func(src, newAddonPath);
|
await func(src, newAddonPath);
|
||||||
} else throw new Error('Unsupported file type');
|
} else throw new Error('Unsupported file type');
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import crypto from 'crypto';
|
import crypto from 'crypto';
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { Duplex } from 'stream';
|
import { Duplex, PassThrough } from 'stream';
|
||||||
import { inspect } from 'util';
|
import { inspect } from 'util';
|
||||||
|
import type AdmZip from 'adm-zip';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import moment, { isMoment, Moment } from 'moment-timezone';
|
import moment, { isMoment, Moment } from 'moment-timezone';
|
||||||
import { ObjectId } from 'mongodb';
|
import { ObjectId } from 'mongodb';
|
||||||
import Logger from 'reggol';
|
import Logger from 'reggol';
|
||||||
|
import type { Request } from 'superagent';
|
||||||
export * as yaml from 'js-yaml';
|
export * as yaml from 'js-yaml';
|
||||||
export * as fs from 'fs-extra';
|
export * as fs from 'fs-extra';
|
||||||
|
|
||||||
@@ -80,7 +82,16 @@ export function isClass(obj: any, strict = false): obj is new (...args: any) =>
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function streamToBuffer(stream: any, maxSize = 0): Promise<Buffer> {
|
function isSuperagentRequest(t: NodeJS.ReadableStream | Request): t is Request {
|
||||||
|
return 'req' in t;
|
||||||
|
}
|
||||||
|
export function streamToBuffer(input: NodeJS.ReadableStream | Request, maxSize = 0): Promise<Buffer> {
|
||||||
|
let stream: NodeJS.ReadableStream;
|
||||||
|
if (isSuperagentRequest(input)) {
|
||||||
|
const s = new PassThrough();
|
||||||
|
input.pipe(s);
|
||||||
|
stream = s;
|
||||||
|
} else stream = input;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const buffers = [];
|
const buffers = [];
|
||||||
let length = 0;
|
let length = 0;
|
||||||
@@ -271,4 +282,45 @@ export function Counter<T extends (string | number) = string>() {
|
|||||||
}) as Record<T, number>;
|
}) as Record<T, number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function canonical(p: string) {
|
||||||
|
if (!p) return '';
|
||||||
|
const safeSuffix = path.posix.normalize(`/${p.split('\\').join('/')}`);
|
||||||
|
return path.join('.', safeSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitize(prefix: string, name: string) {
|
||||||
|
prefix = path.resolve(path.normalize(prefix));
|
||||||
|
const parts = name.split('/');
|
||||||
|
for (let i = 0, l = parts.length; i < l; i++) {
|
||||||
|
const p = path.normalize(path.join(prefix, parts.slice(i, l).join(path.sep)));
|
||||||
|
if (p.indexOf(prefix) === 0) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path.normalize(path.join(prefix, path.basename(name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function sanitizePath(pathname: string) {
|
||||||
|
const parts = pathname.replace(/\\/g, '/').split('/').filter((i) => i && i !== '.' && i !== '..');
|
||||||
|
return parts.join(path.sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable no-await-in-loop */
|
||||||
|
export async function extractZip(zip: AdmZip, dest: string, overwrite = false, strip = false) {
|
||||||
|
const entries = zip.getEntries();
|
||||||
|
const shouldStrip = strip ? entries.every((i) => i.entryName.startsWith(entries[0].entryName)) : false;
|
||||||
|
for (const entry of entries) {
|
||||||
|
const name = shouldStrip ? entry.entryName.substring(entries[0].entryName.length) : entry.entryName;
|
||||||
|
const d = sanitize(dest, canonical(name));
|
||||||
|
if (entry.isDirectory) {
|
||||||
|
await fs.mkdir(d, { recursive: true });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const content = entry.getData();
|
||||||
|
if (!content) throw new Error('CANT_EXTRACT_FILE');
|
||||||
|
if (!fs.existsSync(d) || overwrite) await fs.writeFile(d, content);
|
||||||
|
await fs.utimes(d, entry.header.time, entry.header.time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export * from '@hydrooj/utils/lib/common';
|
export * from '@hydrooj/utils/lib/common';
|
||||||
Reference in new issue
Block a user