@vscode/vsce 2.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PublicGalleryAPI = void 0;
4
+ const HttpClient_1 = require("typed-rest-client/HttpClient");
5
+ const GalleryInterfaces_1 = require("azure-devops-node-api/interfaces/GalleryInterfaces");
6
+ const Serialization_1 = require("azure-devops-node-api/Serialization");
7
+ class PublicGalleryAPI {
8
+ constructor(baseUrl, apiVersion = '3.0-preview.1') {
9
+ this.baseUrl = baseUrl;
10
+ this.apiVersion = apiVersion;
11
+ this.client = new HttpClient_1.HttpClient('vsce');
12
+ }
13
+ post(url, data, additionalHeaders) {
14
+ return this.client.post(`${this.baseUrl}/_apis/public${url}`, data, additionalHeaders);
15
+ }
16
+ async extensionQuery({ pageNumber = 1, pageSize = 1, flags = [], criteria = [], assetTypes = [], }) {
17
+ const data = JSON.stringify({
18
+ filters: [{ pageNumber, pageSize, criteria }],
19
+ assetTypes,
20
+ flags: flags.reduce((memo, flag) => memo | flag, 0),
21
+ });
22
+ const res = await this.post('/gallery/extensionquery', data, {
23
+ Accept: `application/json;api-version=${this.apiVersion}`,
24
+ 'Content-Type': 'application/json',
25
+ });
26
+ const raw = JSON.parse(await res.readBody());
27
+ if (raw.errorCode !== undefined) {
28
+ throw new Error(raw.message);
29
+ }
30
+ return Serialization_1.ContractSerializer.deserialize(raw.results[0].extensions, GalleryInterfaces_1.TypeInfo.PublishedExtension, false, false);
31
+ }
32
+ async getExtension(extensionId, flags = []) {
33
+ const query = { criteria: [{ filterType: GalleryInterfaces_1.ExtensionQueryFilterType.Name, value: extensionId }], flags };
34
+ const extensions = await this.extensionQuery(query);
35
+ return extensions.filter(({ publisher: { publisherName: publisher }, extensionName: name }) => extensionId.toLowerCase() === `${publisher}.${name}`.toLowerCase())[0];
36
+ }
37
+ }
38
+ exports.PublicGalleryAPI = PublicGalleryAPI;
39
+ //# sourceMappingURL=publicgalleryapi.js.map
package/out/publish.js ADDED
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.unpublish = exports.publish = void 0;
23
+ const fs = __importStar(require("fs"));
24
+ const util_1 = require("util");
25
+ const semver = __importStar(require("semver"));
26
+ const GalleryInterfaces_1 = require("azure-devops-node-api/interfaces/GalleryInterfaces");
27
+ const package_1 = require("./package");
28
+ const tmp = __importStar(require("tmp"));
29
+ const store_1 = require("./store");
30
+ const util_2 = require("./util");
31
+ const zip_1 = require("./zip");
32
+ const validation_1 = require("./validation");
33
+ const tmpName = (0, util_1.promisify)(tmp.tmpName);
34
+ async function publish(options = {}) {
35
+ if (options.packagePath) {
36
+ if (options.version) {
37
+ throw new Error(`Both options not supported simultaneously: 'packagePath' and 'version'.`);
38
+ }
39
+ else if (options.targets) {
40
+ 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.`);
41
+ }
42
+ for (const packagePath of options.packagePath) {
43
+ const vsix = await (0, zip_1.readVSIXPackage)(packagePath);
44
+ let target;
45
+ try {
46
+ target = vsix.xmlManifest.PackageManifest.Metadata[0].Identity[0].$.TargetPlatform ?? undefined;
47
+ }
48
+ catch (err) {
49
+ throw new Error(`Invalid extension VSIX manifest. ${err}`);
50
+ }
51
+ if (options.preRelease) {
52
+ let isPreReleasePackage = false;
53
+ try {
54
+ isPreReleasePackage = !!vsix.xmlManifest.PackageManifest.Metadata[0].Properties[0].Property.some(p => p.$.Id === 'Microsoft.VisualStudio.Code.PreRelease');
55
+ }
56
+ catch (err) {
57
+ throw new Error(`Invalid extension VSIX manifest. ${err}`);
58
+ }
59
+ if (!isPreReleasePackage) {
60
+ 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.`);
61
+ }
62
+ }
63
+ await _publish(packagePath, vsix.manifest, { ...options, target });
64
+ }
65
+ }
66
+ else {
67
+ const cwd = options.cwd || process.cwd();
68
+ const manifest = await (0, package_1.readManifest)(cwd);
69
+ (0, util_2.patchOptionsWithManifest)(options, manifest);
70
+ await (0, package_1.prepublish)(cwd, manifest, options.useYarn);
71
+ await (0, package_1.versionBump)(options);
72
+ if (options.targets) {
73
+ for (const target of options.targets) {
74
+ const packagePath = await tmpName();
75
+ const packageResult = await (0, package_1.pack)({ ...options, target, packagePath });
76
+ await _publish(packagePath, packageResult.manifest, { ...options, target });
77
+ }
78
+ }
79
+ else {
80
+ const packagePath = await tmpName();
81
+ const packageResult = await (0, package_1.pack)({ ...options, packagePath });
82
+ await _publish(packagePath, packageResult.manifest, options);
83
+ }
84
+ }
85
+ }
86
+ exports.publish = publish;
87
+ async function _publish(packagePath, manifest, options) {
88
+ (0, validation_1.validatePublisher)(manifest.publisher);
89
+ if (!options.noVerify && manifest.enableProposedApi) {
90
+ throw new Error("Extensions using proposed API (enableProposedApi: true) can't be published to the Marketplace");
91
+ }
92
+ if (!options.noVerify && manifest.enabledApiProposals) {
93
+ throw new Error("Extensions using proposed API (enabledApiProposals: [...]) can't be published to the Marketplace");
94
+ }
95
+ if (semver.prerelease(manifest.version)) {
96
+ throw new Error(`The VS Marketplace doesn't support prerelease versions: '${manifest.version}'`);
97
+ }
98
+ const pat = options.pat ?? (await (0, store_1.getPublisher)(manifest.publisher)).pat;
99
+ const api = await (0, util_2.getGalleryAPI)(pat);
100
+ const packageStream = fs.createReadStream(packagePath);
101
+ const name = `${manifest.publisher}.${manifest.name}`;
102
+ const description = options.target
103
+ ? `${name} (${options.target}) v${manifest.version}`
104
+ : `${name} v${manifest.version}`;
105
+ util_2.log.info(`Publishing '${description}'...`);
106
+ let extension = null;
107
+ try {
108
+ try {
109
+ extension = await api.getExtension(null, manifest.publisher, manifest.name, undefined, GalleryInterfaces_1.ExtensionQueryFlags.IncludeVersions);
110
+ }
111
+ catch (err) {
112
+ if (err.statusCode !== 404) {
113
+ throw err;
114
+ }
115
+ }
116
+ if (extension && extension.versions) {
117
+ const sameVersion = extension.versions.filter(v => v.version === manifest.version);
118
+ if (sameVersion.length > 0) {
119
+ if (options.skipDuplicate) {
120
+ util_2.log.done(`Version ${manifest.version} is already published. Skipping publish.`);
121
+ return;
122
+ }
123
+ if (sameVersion.some(v => v.targetPlatform === options.target)) {
124
+ throw new Error(`${description} already exists.`);
125
+ }
126
+ }
127
+ try {
128
+ await api.updateExtension(undefined, packageStream, manifest.publisher, manifest.name);
129
+ }
130
+ catch (err) {
131
+ if (err.statusCode === 409) {
132
+ if (options.skipDuplicate) {
133
+ util_2.log.done(`Version ${manifest.version} is already published. Skipping publish.`);
134
+ return;
135
+ }
136
+ else {
137
+ throw new Error(`${description} already exists.`);
138
+ }
139
+ }
140
+ else {
141
+ throw err;
142
+ }
143
+ }
144
+ }
145
+ else {
146
+ await api.createExtension(undefined, packageStream);
147
+ }
148
+ }
149
+ catch (err) {
150
+ const message = (err && err.message) || '';
151
+ if (/Personal Access Token used has expired/.test(message)) {
152
+ err.message = `${err.message}\n\nYou're using an expired Personal Access Token, please get a new PAT.\nMore info: https://aka.ms/vscodepat`;
153
+ }
154
+ else if (/Invalid Resource/.test(message)) {
155
+ 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`;
156
+ }
157
+ throw err;
158
+ }
159
+ util_2.log.info(`Extension URL (might take a few minutes): ${(0, util_2.getPublishedUrl)(name)}`);
160
+ util_2.log.info(`Hub URL: ${(0, util_2.getHubUrl)(manifest.publisher, manifest.name)}`);
161
+ util_2.log.done(`Published ${description}.`);
162
+ }
163
+ async function unpublish(options = {}) {
164
+ let publisher, name;
165
+ if (options.id) {
166
+ [publisher, name] = options.id.split('.');
167
+ }
168
+ else {
169
+ const manifest = await (0, package_1.readManifest)(options.cwd);
170
+ publisher = manifest.publisher;
171
+ name = manifest.name;
172
+ }
173
+ const fullName = `${publisher}.${name}`;
174
+ if (!options.force) {
175
+ const answer = await (0, util_2.read)(`This will delete ALL published versions! Please type '${fullName}' to confirm: `);
176
+ if (answer !== fullName) {
177
+ throw new Error('Aborted');
178
+ }
179
+ }
180
+ const pat = options.pat ?? (await (0, store_1.getPublisher)(publisher)).pat;
181
+ const api = await (0, util_2.getGalleryAPI)(pat);
182
+ await api.deleteExtension(publisher, name);
183
+ util_2.log.done(`Deleted extension: ${fullName}!`);
184
+ }
185
+ exports.unpublish = unpublish;
186
+ //# sourceMappingURL=publish.js.map
package/out/search.js ADDED
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.search = void 0;
4
+ const util_1 = require("./util");
5
+ const GalleryInterfaces_1 = require("azure-devops-node-api/interfaces/GalleryInterfaces");
6
+ const viewutils_1 = require("./viewutils");
7
+ const installationTarget = 'Microsoft.VisualStudio.Code';
8
+ const excludeFlags = '37888'; //Value to exclude un-published, locked or hidden extensions
9
+ const baseResultsTableHeaders = ['<ExtensionId>', '<Publisher>', '<Name>'];
10
+ async function search(searchText, json = false, pageSize = 10, stats = false) {
11
+ const api = (0, util_1.getPublicGalleryAPI)();
12
+ const results = (await api.extensionQuery({
13
+ pageSize,
14
+ criteria: [
15
+ { filterType: GalleryInterfaces_1.ExtensionQueryFilterType.SearchText, value: searchText },
16
+ { filterType: GalleryInterfaces_1.ExtensionQueryFilterType.InstallationTarget, value: installationTarget },
17
+ { filterType: GalleryInterfaces_1.ExtensionQueryFilterType.ExcludeWithFlags, value: excludeFlags },
18
+ ],
19
+ flags: [
20
+ GalleryInterfaces_1.ExtensionQueryFlags.ExcludeNonValidated,
21
+ GalleryInterfaces_1.ExtensionQueryFlags.IncludeLatestVersionOnly,
22
+ stats ? GalleryInterfaces_1.ExtensionQueryFlags.IncludeStatistics : 0,
23
+ ],
24
+ }));
25
+ if (stats || !json) {
26
+ console.log([
27
+ `Search results:`,
28
+ '',
29
+ ...buildResultTableView(results, stats),
30
+ '',
31
+ 'For more information on an extension use "vsce show <extensionId>"',
32
+ ]
33
+ .map(line => (0, viewutils_1.wordTrim)(line.replace(/\s+$/g, '')))
34
+ .join('\n'));
35
+ return;
36
+ }
37
+ if (!results.length) {
38
+ console.log('No matching results');
39
+ return;
40
+ }
41
+ if (json) {
42
+ console.log(JSON.stringify(results, undefined, '\t'));
43
+ return;
44
+ }
45
+ }
46
+ exports.search = search;
47
+ function buildResultTableView(results, stats) {
48
+ const values = results.map(({ publisher, extensionName, displayName, shortDescription, statistics }) => [
49
+ publisher.publisherName + '.' + extensionName,
50
+ publisher.displayName,
51
+ (0, viewutils_1.wordTrim)(displayName || '', 25),
52
+ stats ? buildExtensionStatisticsText(statistics) : (0, viewutils_1.wordTrim)(shortDescription || '', 150).replace(/\n|\r|\t/g, ' '),
53
+ ]);
54
+ var resultsTableHeaders = stats
55
+ ? [...baseResultsTableHeaders, '<Installs>', '<Rating>']
56
+ : [...baseResultsTableHeaders, '<Description>'];
57
+ const resultsTable = (0, viewutils_1.tableView)([resultsTableHeaders, ...values]);
58
+ return resultsTable;
59
+ }
60
+ function buildExtensionStatisticsText(statistics) {
61
+ const { install: installs = 0, averagerating = 0, ratingcount = 0 } = statistics?.reduce((map, { statisticName, value }) => ({ ...map, [statisticName]: value }), {});
62
+ return (`${Number(installs).toLocaleString('en-US').padStart(12, ' ')} \t\t` +
63
+ ` ${(0, viewutils_1.ratingStars)(averagerating).padEnd(3, ' ')} (${ratingcount})`);
64
+ }
65
+ //# sourceMappingURL=search.js.map
package/out/show.js ADDED
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.show = void 0;
4
+ const util_1 = require("./util");
5
+ const GalleryInterfaces_1 = require("azure-devops-node-api/interfaces/GalleryInterfaces");
6
+ const viewutils_1 = require("./viewutils");
7
+ const limitVersions = 6;
8
+ const isExtensionTag = /^__ext_(.*)$/;
9
+ function show(extensionId, json = false) {
10
+ const flags = [
11
+ GalleryInterfaces_1.ExtensionQueryFlags.IncludeCategoryAndTags,
12
+ GalleryInterfaces_1.ExtensionQueryFlags.IncludeMetadata,
13
+ GalleryInterfaces_1.ExtensionQueryFlags.IncludeStatistics,
14
+ GalleryInterfaces_1.ExtensionQueryFlags.IncludeVersions,
15
+ ];
16
+ return (0, util_1.getPublicGalleryAPI)()
17
+ .getExtension(extensionId, flags)
18
+ .then(extension => {
19
+ if (json) {
20
+ console.log(JSON.stringify(extension, undefined, '\t'));
21
+ }
22
+ else {
23
+ if (extension === undefined) {
24
+ util_1.log.error(`Extension "${extensionId}" not found.`);
25
+ }
26
+ else {
27
+ showOverview(extension);
28
+ }
29
+ }
30
+ });
31
+ }
32
+ exports.show = show;
33
+ function showOverview({ displayName = 'unknown', extensionName = 'unknown', shortDescription = '', versions = [], publisher: { displayName: publisherDisplayName, publisherName }, categories = [], tags = [], statistics = [], publishedDate, lastUpdated, }) {
34
+ const [{ version = 'unknown' } = {}] = versions;
35
+ // Create formatted table list of versions
36
+ const versionList = (versions.slice(0, limitVersions).map(({ version, lastUpdated }) => [version, (0, viewutils_1.formatDate)(lastUpdated)]));
37
+ const { install: installs = 0, averagerating = 0, ratingcount = 0 } = statistics.reduce((map, { statisticName, value }) => ({ ...map, [statisticName]: value }), {});
38
+ // Render
39
+ console.log([
40
+ `${displayName}`,
41
+ `${publisherDisplayName} | ${viewutils_1.icons.download} ` +
42
+ `${Number(installs).toLocaleString()} installs |` +
43
+ ` ${(0, viewutils_1.ratingStars)(averagerating)} (${ratingcount})`,
44
+ '',
45
+ `${shortDescription}`,
46
+ '',
47
+ 'Recent versions:',
48
+ ...(versionList.length ? (0, viewutils_1.tableView)(versionList).map(viewutils_1.indentRow) : ['no versions found']),
49
+ '',
50
+ 'Categories:',
51
+ ` ${categories.join(', ')}`,
52
+ '',
53
+ 'Tags:',
54
+ ` ${tags.filter(tag => !isExtensionTag.test(tag)).join(', ')}`,
55
+ '',
56
+ 'More info:',
57
+ ...(0, viewutils_1.tableView)([
58
+ ['Unique identifier:', `${publisherName}.${extensionName}`],
59
+ ['Version:', version],
60
+ ['Last updated:', (0, viewutils_1.formatDateTime)(lastUpdated)],
61
+ ['Publisher:', publisherDisplayName],
62
+ ['Published at:', (0, viewutils_1.formatDate)(publishedDate)],
63
+ ]).map(viewutils_1.indentRow),
64
+ '',
65
+ 'Statistics:',
66
+ ...(0, viewutils_1.tableView)(statistics.map(({ statisticName, value }) => [statisticName, Number(value).toFixed(2)])).map(viewutils_1.indentRow),
67
+ ]
68
+ .map(line => (0, viewutils_1.wordWrap)(line))
69
+ .join('\n'));
70
+ }
71
+ //# sourceMappingURL=show.js.map
package/out/store.js ADDED
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.listPublishers = exports.deletePublisher = exports.logoutPublisher = exports.loginPublisher = exports.getPublisher = exports.verifyPat = exports.KeytarStore = exports.FileStore = void 0;
23
+ const fs = __importStar(require("fs"));
24
+ const path = __importStar(require("path"));
25
+ const os_1 = require("os");
26
+ const util_1 = require("./util");
27
+ const validation_1 = require("./validation");
28
+ const package_1 = require("./package");
29
+ class FileStore {
30
+ constructor(path, publishers) {
31
+ this.path = path;
32
+ this.publishers = publishers;
33
+ }
34
+ static async open(path = FileStore.DefaultPath) {
35
+ try {
36
+ const rawStore = await fs.promises.readFile(path, 'utf8');
37
+ return new FileStore(path, JSON.parse(rawStore).publishers);
38
+ }
39
+ catch (err) {
40
+ if (err.code === 'ENOENT') {
41
+ return new FileStore(path, []);
42
+ }
43
+ else if (/SyntaxError/.test(err)) {
44
+ throw new Error(`Error parsing file store: ${path}`);
45
+ }
46
+ throw err;
47
+ }
48
+ }
49
+ get size() {
50
+ return this.publishers.length;
51
+ }
52
+ async save() {
53
+ await fs.promises.writeFile(this.path, JSON.stringify({ publishers: this.publishers }), { mode: '0600' });
54
+ }
55
+ async deleteStore() {
56
+ try {
57
+ await fs.promises.unlink(this.path);
58
+ }
59
+ catch {
60
+ // noop
61
+ }
62
+ }
63
+ get(name) {
64
+ return this.publishers.filter(p => p.name === name)[0];
65
+ }
66
+ async add(publisher) {
67
+ this.publishers = [...this.publishers.filter(p => p.name !== publisher.name), publisher];
68
+ await this.save();
69
+ }
70
+ async delete(name) {
71
+ this.publishers = this.publishers.filter(p => p.name !== name);
72
+ await this.save();
73
+ }
74
+ [Symbol.iterator]() {
75
+ return this.publishers[Symbol.iterator]();
76
+ }
77
+ }
78
+ exports.FileStore = FileStore;
79
+ FileStore.DefaultPath = path.join((0, os_1.homedir)(), '.vsce');
80
+ class KeytarStore {
81
+ constructor(keytar, serviceName, publishers) {
82
+ this.keytar = keytar;
83
+ this.serviceName = serviceName;
84
+ this.publishers = publishers;
85
+ }
86
+ static async open(serviceName = 'vscode-vsce') {
87
+ const keytar = await Promise.resolve().then(() => __importStar(require('keytar')));
88
+ const creds = await keytar.findCredentials(serviceName);
89
+ return new KeytarStore(keytar, serviceName, creds.map(({ account, password }) => ({ name: account, pat: password })));
90
+ }
91
+ get size() {
92
+ return this.publishers.length;
93
+ }
94
+ get(name) {
95
+ return this.publishers.filter(p => p.name === name)[0];
96
+ }
97
+ async add(publisher) {
98
+ this.publishers = [...this.publishers.filter(p => p.name !== publisher.name), publisher];
99
+ await this.keytar.setPassword(this.serviceName, publisher.name, publisher.pat);
100
+ }
101
+ async delete(name) {
102
+ this.publishers = this.publishers.filter(p => p.name !== name);
103
+ await this.keytar.deletePassword(this.serviceName, name);
104
+ }
105
+ [Symbol.iterator]() {
106
+ return this.publishers[Symbol.iterator]();
107
+ }
108
+ }
109
+ exports.KeytarStore = KeytarStore;
110
+ async function verifyPat(pat, publisherName) {
111
+ if (!pat) {
112
+ throw new Error('The Personal Access Token is mandatory.');
113
+ }
114
+ if (!publisherName) {
115
+ try {
116
+ publisherName = (await (0, package_1.readManifest)()).publisher;
117
+ }
118
+ catch (error) {
119
+ throw new Error(`Can not read the publisher's name. Either supply it as an argument or run vsce from the extension folder. Additional information:\n\n${error}`);
120
+ }
121
+ }
122
+ try {
123
+ // If the caller of the `getRoleAssignments` API has any of the roles
124
+ // (Creator, Owner, Contributor, Reader) on the publisher, we get a 200,
125
+ // otherwise we get a 403.
126
+ const api = await (0, util_1.getSecurityRolesAPI)(pat);
127
+ await api.getRoleAssignments('gallery.publisher', publisherName);
128
+ }
129
+ catch (error) {
130
+ throw new Error('The Personal Access Token verification has failed. Additional information:\n\n' + error);
131
+ }
132
+ console.log(`The Personal Access Token verification succeeded for the publisher '${publisherName}'.`);
133
+ }
134
+ exports.verifyPat = verifyPat;
135
+ async function requestPAT(publisherName) {
136
+ console.log('https://marketplace.visualstudio.com/manage/publishers/');
137
+ const pat = await (0, util_1.read)(`Personal Access Token for publisher '${publisherName}':`, { silent: true, replace: '*' });
138
+ await verifyPat(pat, publisherName);
139
+ return pat;
140
+ }
141
+ async function openDefaultStore() {
142
+ if (/^file$/i.test(process.env['VSCE_STORE'] ?? '')) {
143
+ return await FileStore.open();
144
+ }
145
+ let keytarStore;
146
+ try {
147
+ keytarStore = await KeytarStore.open();
148
+ }
149
+ catch (err) {
150
+ const store = await FileStore.open();
151
+ util_1.log.warn(`Failed to open credential store. Falling back to storing secrets clear-text in: ${store.path}`);
152
+ return store;
153
+ }
154
+ const fileStore = await FileStore.open();
155
+ // migrate from file store
156
+ if (fileStore.size) {
157
+ for (const publisher of fileStore) {
158
+ await keytarStore.add(publisher);
159
+ }
160
+ await fileStore.deleteStore();
161
+ util_1.log.info(`Migrated ${fileStore.size} publishers to system credential manager. Deleted local store '${fileStore.path}'.`);
162
+ }
163
+ return keytarStore;
164
+ }
165
+ async function getPublisher(publisherName) {
166
+ (0, validation_1.validatePublisher)(publisherName);
167
+ const store = await openDefaultStore();
168
+ let publisher = store.get(publisherName);
169
+ if (publisher) {
170
+ return publisher;
171
+ }
172
+ const pat = await requestPAT(publisherName);
173
+ publisher = { name: publisherName, pat };
174
+ await store.add(publisher);
175
+ return publisher;
176
+ }
177
+ exports.getPublisher = getPublisher;
178
+ async function loginPublisher(publisherName) {
179
+ (0, validation_1.validatePublisher)(publisherName);
180
+ const store = await openDefaultStore();
181
+ let publisher = store.get(publisherName);
182
+ if (publisher) {
183
+ console.log(`Publisher '${publisherName}' is already known`);
184
+ const answer = await (0, util_1.read)('Do you want to overwrite its PAT? [y/N] ');
185
+ if (!/^y$/i.test(answer)) {
186
+ throw new Error('Aborted');
187
+ }
188
+ }
189
+ const pat = await requestPAT(publisherName);
190
+ publisher = { name: publisherName, pat };
191
+ await store.add(publisher);
192
+ return publisher;
193
+ }
194
+ exports.loginPublisher = loginPublisher;
195
+ async function logoutPublisher(publisherName) {
196
+ (0, validation_1.validatePublisher)(publisherName);
197
+ const store = await openDefaultStore();
198
+ const publisher = store.get(publisherName);
199
+ if (!publisher) {
200
+ throw new Error(`Unknown publisher '${publisherName}'`);
201
+ }
202
+ await store.delete(publisherName);
203
+ }
204
+ exports.logoutPublisher = logoutPublisher;
205
+ async function deletePublisher(publisherName) {
206
+ const publisher = await getPublisher(publisherName);
207
+ const answer = await (0, util_1.read)(`This will FOREVER delete '${publisherName}'! Are you sure? [y/N] `);
208
+ if (!/^y$/i.test(answer)) {
209
+ throw new Error('Aborted');
210
+ }
211
+ const api = await (0, util_1.getGalleryAPI)(publisher.pat);
212
+ await api.deletePublisher(publisherName);
213
+ const store = await openDefaultStore();
214
+ await store.delete(publisherName);
215
+ util_1.log.done(`Deleted publisher '${publisherName}'.`);
216
+ }
217
+ exports.deletePublisher = deletePublisher;
218
+ async function listPublishers() {
219
+ const store = await openDefaultStore();
220
+ for (const publisher of store) {
221
+ console.log(publisher.name);
222
+ }
223
+ }
224
+ exports.listPublishers = listPublishers;
225
+ //# sourceMappingURL=store.js.map