vsce
Version:
VSCode Extension Manager
186 lines • 8.61 kB
JavaScript
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.unpublish = exports.publish = void 0;
const fs = __importStar(require("fs"));
const util_1 = require("util");
const semver = __importStar(require("semver"));
const GalleryInterfaces_1 = require("azure-devops-node-api/interfaces/GalleryInterfaces");
const package_1 = require("./package");
const tmp = __importStar(require("tmp"));
const store_1 = require("./store");
const util_2 = require("./util");
const zip_1 = require("./zip");
const validation_1 = require("./validation");
const tmpName = (0, util_1.promisify)(tmp.tmpName);
async function publish(options = {}) {
if (options.packagePath) {
if (options.version) {
throw new Error(`Both options not supported simultaneously: 'packagePath' and 'version'.`);
}
else if (options.targets) {
throw new Error(`Both options not supported simultaneously: 'packagePath' and 'target'. Use 'vsce package --target <target>' to first create a platform specific package, then use 'vsce publish --packagePath <path>' to publish it.`);
}
for (const packagePath of options.packagePath) {
const vsix = await (0, zip_1.readVSIXPackage)(packagePath);
let target;
try {
target = vsix.xmlManifest.PackageManifest.Metadata[0].Identity[0].$.TargetPlatform ?? undefined;
}
catch (err) {
throw new Error(`Invalid extension VSIX manifest. ${err}`);
}
if (options.preRelease) {
let isPreReleasePackage = false;
try {
isPreReleasePackage = !!vsix.xmlManifest.PackageManifest.Metadata[0].Properties[0].Property.some(p => p.$.Id === 'Microsoft.VisualStudio.Code.PreRelease');
}
catch (err) {
throw new Error(`Invalid extension VSIX manifest. ${err}`);
}
if (!isPreReleasePackage) {
throw new Error(`Cannot use '--pre-release' flag with a package that was not packaged as pre-release. Please package it using the '--pre-release' flag and publish again.`);
}
}
await _publish(packagePath, vsix.manifest, { ...options, target });
}
}
else {
const cwd = options.cwd || process.cwd();
const manifest = await (0, package_1.readManifest)(cwd);
(0, util_2.patchOptionsWithManifest)(options, manifest);
await (0, package_1.prepublish)(cwd, manifest, options.useYarn);
await (0, package_1.versionBump)(options);
if (options.targets) {
for (const target of options.targets) {
const packagePath = await tmpName();
const packageResult = await (0, package_1.pack)({ ...options, target, packagePath });
await _publish(packagePath, packageResult.manifest, { ...options, target });
}
}
else {
const packagePath = await tmpName();
const packageResult = await (0, package_1.pack)({ ...options, packagePath });
await _publish(packagePath, packageResult.manifest, options);
}
}
}
exports.publish = publish;
async function _publish(packagePath, manifest, options) {
(0, validation_1.validatePublisher)(manifest.publisher);
if (!options.noVerify && manifest.enableProposedApi) {
throw new Error("Extensions using proposed API (enableProposedApi: true) can't be published to the Marketplace");
}
if (!options.noVerify && manifest.enabledApiProposals) {
throw new Error("Extensions using proposed API (enabledApiProposals: [...]) can't be published to the Marketplace");
}
if (semver.prerelease(manifest.version)) {
throw new Error(`The VS Marketplace doesn't support prerelease versions: '${manifest.version}'`);
}
const pat = options.pat ?? (await (0, store_1.getPublisher)(manifest.publisher)).pat;
const api = await (0, util_2.getGalleryAPI)(pat);
const packageStream = fs.createReadStream(packagePath);
const name = `${manifest.publisher}.${manifest.name}`;
const description = options.target
? `${name} (${options.target}) v${manifest.version}`
: `${name} v${manifest.version}`;
util_2.log.info(`Publishing '${description}'...`);
let extension = null;
try {
try {
extension = await api.getExtension(null, manifest.publisher, manifest.name, undefined, GalleryInterfaces_1.ExtensionQueryFlags.IncludeVersions);
}
catch (err) {
if (err.statusCode !== 404) {
throw err;
}
}
if (extension && extension.versions) {
const sameVersion = extension.versions.filter(v => v.version === manifest.version);
if (sameVersion.length > 0) {
if (options.skipDuplicate) {
util_2.log.done(`Version ${manifest.version} is already published. Skipping publish.`);
return;
}
if (sameVersion.some(v => v.targetPlatform === options.target)) {
throw new Error(`${description} already exists.`);
}
}
try {
await api.updateExtension(undefined, packageStream, manifest.publisher, manifest.name);
}
catch (err) {
if (err.statusCode === 409) {
if (options.skipDuplicate) {
util_2.log.done(`Version ${manifest.version} is already published. Skipping publish.`);
return;
}
else {
throw new Error(`${description} already exists.`);
}
}
else {
throw err;
}
}
}
else {
await api.createExtension(undefined, packageStream);
}
}
catch (err) {
const message = (err && err.message) || '';
if (/Personal Access Token used has expired/.test(message)) {
err.message = `${err.message}\n\nYou're using an expired Personal Access Token, please get a new PAT.\nMore info: https://aka.ms/vscodepat`;
}
else if (/Invalid Resource/.test(message)) {
err.message = `${err.message}\n\nYou're likely using an expired Personal Access Token, please get a new PAT.\nMore info: https://aka.ms/vscodepat`;
}
throw err;
}
util_2.log.info(`Extension URL (might take a few minutes): ${(0, util_2.getPublishedUrl)(name)}`);
util_2.log.info(`Hub URL: ${(0, util_2.getHubUrl)(manifest.publisher, manifest.name)}`);
util_2.log.done(`Published ${description}.`);
}
async function unpublish(options = {}) {
let publisher, name;
if (options.id) {
[publisher, name] = options.id.split('.');
}
else {
const manifest = await (0, package_1.readManifest)(options.cwd);
publisher = manifest.publisher;
name = manifest.name;
}
const fullName = `${publisher}.${name}`;
if (!options.force) {
const answer = await (0, util_2.read)(`This will delete ALL published versions! Please type '${fullName}' to confirm: `);
if (answer !== fullName) {
throw new Error('Aborted');
}
}
const pat = options.pat ?? (await (0, store_1.getPublisher)(publisher)).pat;
const api = await (0, util_2.getGalleryAPI)(pat);
await api.deleteExtension(publisher, name);
util_2.log.done(`Deleted extension: ${fullName}!`);
}
exports.unpublish = unpublish;
//# sourceMappingURL=publish.js.map
;