UNPKG

vsix-utils

Version:

utilities for working with VSIX packages

151 lines (143 loc) 4.41 kB
'use strict'; var buffer = require('buffer'); var fs = require('fs'); var promises = require('fs/promises'); var fastXmlParser = require('fast-xml-parser'); var yauzl = require('yauzl'); var yazl = require('yazl'); require('path'); require('process'); require('ignore'); require('mime'); require('package-manager-detector'); require('tinyglobby'); require('remark'); require('remark-transform-links'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var yauzl__default = /*#__PURE__*/_interopDefault(yauzl); var yazl__default = /*#__PURE__*/_interopDefault(yazl); // src/zip.ts // src/files.ts function isInMemoryFile(file) { return file.type === "in-memory"; } // src/zip.ts async function writeVsix(options) { const { files, packagePath, force, epoch } = options; if (!files || files.length === 0) { throw new Error("no files specified to package"); } if (!packagePath) { throw new Error("no package path specified"); } if (fs.existsSync(packagePath)) { if (!force) { throw new Error(`package already exists at ${packagePath}`); } await promises.unlink(packagePath); } const zip = new yazl__default.default.ZipFile(); const zipOptions = {}; if (epoch != null) { zipOptions.mtime = new Date(epoch * 1e3); files.sort((a, b) => a.path.localeCompare(b.path)); } try { for (const f of files) { if (isInMemoryFile(f)) { zip.addBuffer( typeof f.contents === "string" ? buffer.Buffer.from(f.contents, "utf8") : f.contents, f.path, { ...zipOptions } ); continue; } zip.addFile(f.localPath, f.path, { ...zipOptions }); } zip.end(); const zipStream = fs.createWriteStream(packagePath, { mode: promises.constants.S_IRWXU | promises.constants.S_IRGRP | promises.constants.S_IXGRP | promises.constants.S_IROTH | promises.constants.S_IXOTH }); zip.outputStream.pipe(zipStream); await new Promise((resolve, reject) => { zipStream.once("finish", resolve); zipStream.once("error", reject); zip.once("error", (err) => { zipStream.destroy(); reject(err); }); }); return true; } catch (err) { if (fs.existsSync(packagePath)) { await promises.unlink(packagePath); } if (err instanceof Error) { throw new TypeError(`failed to create package: ${err.message}`); } throw new Error(`failed to create package: ${err}`); } } async function readVsix(options) { const { packagePath } = options; const zip = await new Promise((resolve, reject) => { yauzl__default.default.open(packagePath, { lazyEntries: true }, (err, zip2) => { if (err) { reject(err); } else { resolve(zip2); } }); }); const files = await new Promise((resolve, reject) => { const fileMap = /* @__PURE__ */ new Map(); zip.once("close", () => resolve(fileMap)); zip.on("entry", async (entry) => { try { const buffer = await new Promise((resolve2, reject2) => { zip.openReadStream(entry, (err, stream) => { if (err) reject2(err); stream.once("error", reject2); stream.once("end", () => { if (stream.readable) { reject2(new Error("Stream ended before all data was read")); } }); return resolve2(bufferStream(stream)); }); }); fileMap.set(entry.fileName, buffer); zip.readEntry(); } catch (err) { zip.close(); reject(err); } }); zip.readEntry(); }); if (!files.has("extension.vsixmanifest")) { throw new Error("extension.vsixmanifest file is missing"); } const rawManifest = files.get("extension.vsixmanifest").toString("utf8"); const parser = new fastXmlParser.XMLParser({ preserveOrder: false, transformTagName(tagName) { return tagName.toLowerCase(); } }); const manifest = parser.parse(rawManifest); return { files, manifest }; } async function bufferStream(stream) { return await new Promise((resolve, reject) => { const buffers = []; stream.on("data", (buffer) => buffers.push(buffer)); stream.once("error", reject); stream.once("end", () => resolve(buffer.Buffer.concat(buffers))); }); } exports.readVsix = readVsix; exports.writeVsix = writeVsix;