@vscode/vsce 2.22.0 → 2.22.1-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.
package/README.md CHANGED
@@ -1,19 +1,21 @@
1
- # vsce
1
+ # @vscode/vsce
2
2
 
3
3
  > _The Visual Studio Code Extension Manager_
4
4
 
5
5
  [![Build Status](https://dev.azure.com/monacotools/Monaco/_apis/build/status/npm/microsoft.vscode-vsce?repoName=microsoft%2Fvscode-vsce&branchName=main)](https://dev.azure.com/monacotools/Monaco/_build/latest?definitionId=446&repoName=microsoft%2Fvscode-vsce&branchName=main)
6
6
  [![Version](https://img.shields.io/npm/v/@vscode/vsce.svg)](https://npmjs.org/package/@vscode/vsce)
7
7
 
8
- ## Requirements
8
+ This tool assists in packaging and publishing Visual Studio Code extensions.
9
9
 
10
- - [Node.js](https://nodejs.org/en/) at least `14.x.x`
10
+ Read the [**Documentation**](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code website.
11
11
 
12
- Or simply [Docker](#usage-via-docker).
12
+ ## Requirements
13
+
14
+ [Node.js](https://nodejs.org/en/) at least `18.x.x`.
13
15
 
14
16
  ### Linux
15
17
 
16
- In order to save credentials safely, this project uses [keytar](https://www.npmjs.com/package/keytar) which uses `libsecret`, which you may need to install before publishing extensions. Setting the `VSCE_STORE=file` environment variable will revert back to the file credential store. Using the `VSCE_PAT` environment variable will also avoid using keytar.
18
+ In order to save credentials safely, this project uses [`keytar`](https://www.npmjs.com/package/keytar) which uses `libsecret`, which you may need to install before publishing extensions. Setting the `VSCE_STORE=file` environment variable will revert back to the file credential store. Using the `VSCE_PAT` environment variable will also avoid using `keytar`.
17
19
 
18
20
  Depending on your distribution, you will need to run the following command:
19
21
 
@@ -24,46 +26,23 @@ Depending on your distribution, you will need to run the following command:
24
26
 
25
27
  ## Usage
26
28
 
27
- Install vsce globally:
28
-
29
- ```console
30
- npm install --global @vscode/vsce
31
- ```
32
-
33
- Verify the installation:
34
-
35
29
  ```console
36
- vsce --version
30
+ $ npx @vscode/vsce --version
37
31
  ```
38
32
 
39
- `vsce` is meant to be mainly used as a command line tool. It can also be used a library since it exposes a small [API](https://github.com/microsoft/vscode-vsce/blob/main/src/api.ts). When using vsce as a library be sure to sanitize any user input used in API calls, as a security measurement.
40
-
41
- ## Usage via Docker
33
+ `@vscode/vsce` is meant to be mainly used as a command-line tool. It can also be used as a library since it exposes a small [API](https://github.com/microsoft/vscode-vsce/blob/main/src/api.ts). When using `@vscode/vsce` as a library, be sure to sanitize any user input used in API calls to prevent security issues.
42
34
 
43
- You can also build a container for running vsce:
44
-
45
- ```console
46
- $ DOCKER_BUILDKIT=1 docker build --tag vsce "https://github.com/microsoft/vscode-vsce.git#main"
47
- ```
35
+ Supported package managers:
48
36
 
49
- Validate the container:
50
-
51
- ```console
52
- docker run --rm -it vsce --version
53
- ```
54
-
55
- Publish your local extension:
56
-
57
- ```console
58
- docker run --rm -it -v "$(pwd)":/workspace vsce publish
59
- ```
37
+ - `npm >=6`
38
+ - `yarn >=1 <2`
60
39
 
61
40
  ## Configuration
62
41
 
63
42
  You can configure the behavior of `vsce` by using CLI flags (run `vsce --help` to list them all). Example:
64
43
 
65
44
  ```console
66
- vsce publish --baseImagesUrl https://my.custom/base/images/url
45
+ $ npx @vscode/vsce publish --baseImagesUrl https://my.custom/base/images/url
67
46
  ```
68
47
 
69
48
  Or you can also set them in the `package.json`, so that you avoid having to retype the common options again. Example:
@@ -85,25 +64,19 @@ First clone this repository, then:
85
64
 
86
65
  ```console
87
66
  $ npm install
88
-
89
67
  $ npm run watch:build # or `watch:test` to also build tests
90
68
  ```
91
69
 
92
70
  Once the watcher is up and running, you can run out of sources with:
93
71
 
94
72
  ```console
95
- node vsce
73
+ $ node vsce
96
74
  ```
97
75
 
98
76
  Tests can be executed with:
99
77
 
100
- ```npm
78
+ ```console
101
79
  $ npm test
102
80
  ```
103
81
 
104
82
  > **Note:** [Yarn](https://www.npmjs.com/package/yarn) is required to run the tests.
105
- ## About
106
-
107
- This tool assists in packaging and publishing Visual Studio Code extensions.
108
-
109
- Read the [**Documentation**](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code website.
package/dist/vsce.d.ts CHANGED
@@ -63,6 +63,15 @@ export declare interface IPackageOptions {
63
63
  * https://code.visualstudio.com/api/working-with-extensions/publishing-extension#platformspecific-extensions
64
64
  */
65
65
  readonly target?: string;
66
+ /**
67
+ * Ignore all files inside folders named as other targets. Only relevant when
68
+ * `target` is set. For example, if `target` is `linux-x64` and there are
69
+ * folders named `win32-x64`, `darwin-arm64` or `web`, the files inside
70
+ * those folders will be ignored.
71
+ *
72
+ * @default false
73
+ */
74
+ readonly ignoreOtherTargetFolders?: boolean;
66
75
  readonly commitMessage?: string;
67
76
  readonly gitTagVersion?: boolean;
68
77
  readonly updatePackageJson?: boolean;
@@ -72,6 +81,8 @@ export declare interface IPackageOptions {
72
81
  * Defaults to `process.cwd()`.
73
82
  */
74
83
  readonly cwd?: string;
84
+ readonly readmePath?: string;
85
+ readonly changelogPath?: string;
75
86
  /**
76
87
  * GitHub branch used to publish the package. Used to automatically infer
77
88
  * the base content and images URI.
@@ -117,6 +128,7 @@ export declare interface IPublishOptions {
117
128
  readonly packagePath?: string[];
118
129
  readonly version?: string;
119
130
  readonly targets?: string[];
131
+ readonly ignoreOtherTargetFolders?: boolean;
120
132
  readonly commitMessage?: string;
121
133
  readonly gitTagVersion?: boolean;
122
134
  readonly updatePackageJson?: boolean;
@@ -126,6 +138,8 @@ export declare interface IPublishOptions {
126
138
  * Defaults to `process.cwd()`.
127
139
  */
128
140
  readonly cwd?: string;
141
+ readonly readmePath?: string;
142
+ readonly changelogPath?: string;
129
143
  readonly githubBranch?: string;
130
144
  readonly gitlabBranch?: string;
131
145
  /**
@@ -148,7 +162,10 @@ export declare interface IPublishOptions {
148
162
  * Defaults to the stored one.
149
163
  */
150
164
  readonly pat?: string;
165
+ readonly allowProposedApi?: boolean;
151
166
  readonly noVerify?: boolean;
167
+ readonly allowProposedApis?: string[];
168
+ readonly allowAllProposedApis?: boolean;
152
169
  readonly dependencies?: boolean;
153
170
  readonly preRelease?: boolean;
154
171
  readonly allowStarActivation?: boolean;
package/out/main.js CHANGED
@@ -76,9 +76,9 @@ module.exports = function (argv) {
76
76
  commander_1.default.version(pkg.version).usage('<command>');
77
77
  commander_1.default
78
78
  .command('ls')
79
- .description('Lists all the files that will be published')
79
+ .description('Lists all the files that will be published/packaged')
80
80
  .option('--yarn', 'Use yarn instead of npm (default inferred from presence of yarn.lock or .yarnrc)')
81
- .option('--no-yarn', 'Use npm instead of yarn (default inferred from lack of yarn.lock or .yarnrc)')
81
+ .option('--no-yarn', 'Use npm instead of yarn (default inferred from absence of yarn.lock or .yarnrc)')
82
82
  .option('--packagedDependencies <path>', 'Select packages that should be published only (includes dependencies)', (val, all) => (all ? all.concat(val) : [val]), undefined)
83
83
  .option('--ignoreFile <path>', 'Indicate alternative .vscodeignore')
84
84
  // default must remain undefined for dependencies or we will fail to load defaults from package.json
@@ -91,30 +91,36 @@ module.exports = function (argv) {
91
91
  .description('Packages an extension')
92
92
  .option('-o, --out <path>', 'Output .vsix extension file to <path> location (defaults to <name>-<version>.vsix)')
93
93
  .option('-t, --target <target>', `Target architecture. Valid targets: ${ValidTargets}`)
94
+ .option('--ignore-other-target-folders', `Ignore other target folders. Valid only when --target <target> is provided.`)
95
+ .option('--readme-path <path>', 'Path to README file (defaults to README.md)')
96
+ .option('--changelog-path <path>', 'Path to CHANGELOG file (defaults to CHANGELOG.md)')
94
97
  .option('-m, --message <commit message>', 'Commit message used when calling `npm version`.')
95
98
  .option('--no-git-tag-version', 'Do not create a version commit and tag when calling `npm version`. Valid only when [version] is provided.')
96
99
  .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.')
97
100
  .option('--githubBranch <branch>', 'The GitHub branch used to infer relative links in README.md. Can be overridden by --baseContentUrl and --baseImagesUrl.')
98
101
  .option('--gitlabBranch <branch>', 'The GitLab branch used to infer relative links in README.md. Can be overridden by --baseContentUrl and --baseImagesUrl.')
99
102
  .option('--no-rewrite-relative-links', 'Skip rewriting relative links.')
100
- .option('--baseContentUrl <url>', 'Prepend all relative links in README.md with this url.')
101
- .option('--baseImagesUrl <url>', 'Prepend all relative image links in README.md with this url.')
103
+ .option('--baseContentUrl <url>', 'Prepend all relative links in README.md with the specified URL.')
104
+ .option('--baseImagesUrl <url>', 'Prepend all relative image links in README.md with the specified URL.')
102
105
  .option('--yarn', 'Use yarn instead of npm (default inferred from presence of yarn.lock or .yarnrc)')
103
- .option('--no-yarn', 'Use npm instead of yarn (default inferred from lack of yarn.lock or .yarnrc)')
106
+ .option('--no-yarn', 'Use npm instead of yarn (default inferred from absence of yarn.lock or .yarnrc)')
104
107
  .option('--ignoreFile <path>', 'Indicate alternative .vscodeignore')
105
108
  .option('--no-gitHubIssueLinking', 'Disable automatic expansion of GitHub-style issue syntax into links')
106
109
  .option('--no-gitLabIssueLinking', 'Disable automatic expansion of GitLab-style issue syntax into links')
107
110
  // default must remain undefined for dependencies or we will fail to load defaults from package.json
108
111
  .option('--dependencies', 'Enable dependency detection via npm or yarn', undefined)
109
- .option('--no-dependencies', 'Disable dependency detection via npm or yarn')
112
+ .option('--no-dependencies', 'Disable dependency detection via npm or yarn', undefined)
110
113
  .option('--pre-release', 'Mark this package as a pre-release')
111
114
  .option('--allow-star-activation', 'Allow using * in activation events')
112
115
  .option('--allow-missing-repository', 'Allow missing a repository URL in package.json')
113
116
  .option('--skip-license', 'Allow packaging without license file')
114
- .action((version, { out, target, message, gitTagVersion, updatePackageJson, githubBranch, gitlabBranch, rewriteRelativeLinks, baseContentUrl, baseImagesUrl, yarn, ignoreFile, gitHubIssueLinking, gitLabIssueLinking, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipLicense, }) => main((0, package_1.packageCommand)({
117
+ .action((version, { out, target, ignoreOtherTargetFolders, readmePath, changelogPath, message, gitTagVersion, updatePackageJson, githubBranch, gitlabBranch, rewriteRelativeLinks, baseContentUrl, baseImagesUrl, yarn, ignoreFile, gitHubIssueLinking, gitLabIssueLinking, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipLicense, }) => main((0, package_1.packageCommand)({
115
118
  packagePath: out,
116
119
  version,
117
120
  target,
121
+ ignoreOtherTargetFolders,
122
+ readmePath,
123
+ changelogPath,
118
124
  commitMessage: message,
119
125
  gitTagVersion,
120
126
  updatePackageJson,
@@ -138,17 +144,22 @@ module.exports = function (argv) {
138
144
  .description('Publishes an extension')
139
145
  .option('-p, --pat <token>', 'Personal Access Token (defaults to VSCE_PAT environment variable)', process.env['VSCE_PAT'])
140
146
  .option('-t, --target <targets...>', `Target architectures. Valid targets: ${ValidTargets}`)
147
+ .option('--ignore-other-target-folders', `Ignore other target folders. Valid only when --target <target> is provided.`)
148
+ .option('--readme-path <path>', 'Path to README file (defaults to README.md)')
149
+ .option('--changelog-path <path>', 'Path to CHANGELOG file (defaults to CHANGELOG.md)')
141
150
  .option('-m, --message <commit message>', 'Commit message used when calling `npm version`.')
142
151
  .option('--no-git-tag-version', 'Do not create a version commit and tag when calling `npm version`. Valid only when [version] is provided.')
143
152
  .option('--no-update-package-json', 'Do not update `package.json`. Valid only when [version] is provided.')
144
153
  .option('-i, --packagePath <paths...>', 'Publish the provided VSIX packages.')
145
154
  .option('--githubBranch <branch>', 'The GitHub branch used to infer relative links in README.md. Can be overridden by --baseContentUrl and --baseImagesUrl.')
146
155
  .option('--gitlabBranch <branch>', 'The GitLab branch used to infer relative links in README.md. Can be overridden by --baseContentUrl and --baseImagesUrl.')
147
- .option('--baseContentUrl <url>', 'Prepend all relative links in README.md with this url.')
148
- .option('--baseImagesUrl <url>', 'Prepend all relative image links in README.md with this url.')
156
+ .option('--baseContentUrl <url>', 'Prepend all relative links in README.md with the specified URL.')
157
+ .option('--baseImagesUrl <url>', 'Prepend all relative image links in README.md with the specified URL.')
149
158
  .option('--yarn', 'Use yarn instead of npm (default inferred from presence of yarn.lock or .yarnrc)')
150
- .option('--no-yarn', 'Use npm instead of yarn (default inferred from lack of yarn.lock or .yarnrc)')
151
- .option('--noVerify')
159
+ .option('--no-yarn', 'Use npm instead of yarn (default inferred from absence of yarn.lock or .yarnrc)')
160
+ .option('--noVerify', 'Allow all proposed APIs (deprecated: use --allow-all-proposed-apis instead)')
161
+ .option('--allow-proposed-apis <apis...>', 'Allow specific proposed APIs')
162
+ .option('--allow-all-proposed-apis', 'Allow all proposed APIs')
152
163
  .option('--ignoreFile <path>', 'Indicate alternative .vscodeignore')
153
164
  // default must remain undefined for dependencies or we will fail to load defaults from package.json
154
165
  .option('--dependencies', 'Enable dependency detection via npm or yarn', undefined)
@@ -158,10 +169,13 @@ module.exports = function (argv) {
158
169
  .option('--allow-missing-repository', 'Allow missing a repository URL in package.json')
159
170
  .option('--skip-duplicate', 'Fail silently if version already exists on the marketplace')
160
171
  .option('--skip-license', 'Allow publishing without license file')
161
- .action((version, { pat, target, message, gitTagVersion, updatePackageJson, packagePath, githubBranch, gitlabBranch, baseContentUrl, baseImagesUrl, yarn, noVerify, ignoreFile, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipDuplicate, skipLicense, }) => main((0, publish_1.publish)({
172
+ .action((version, { pat, target, ignoreOtherTargetFolders, readmePath, changelogPath, message, gitTagVersion, updatePackageJson, packagePath, githubBranch, gitlabBranch, baseContentUrl, baseImagesUrl, yarn, noVerify, allowProposedApis, allowAllProposedApis, ignoreFile, dependencies, preRelease, allowStarActivation, allowMissingRepository, skipDuplicate, skipLicense, }) => main((0, publish_1.publish)({
162
173
  pat,
163
174
  version,
164
175
  targets: target,
176
+ ignoreOtherTargetFolders,
177
+ readmePath,
178
+ changelogPath,
165
179
  commitMessage: message,
166
180
  gitTagVersion,
167
181
  updatePackageJson,
@@ -172,6 +186,8 @@ module.exports = function (argv) {
172
186
  baseImagesUrl,
173
187
  useYarn: yarn,
174
188
  noVerify,
189
+ allowProposedApis,
190
+ allowAllProposedApis,
175
191
  ignoreFile,
176
192
  dependencies,
177
193
  preRelease,
@@ -182,42 +198,42 @@ module.exports = function (argv) {
182
198
  })));
183
199
  commander_1.default
184
200
  .command('unpublish [extensionid]')
185
- .description('Unpublishes an extension. Example extension id: microsoft.csharp.')
201
+ .description('Unpublishes an extension. Example extension id: ms-vscode.live-server.')
186
202
  .option('-p, --pat <token>', 'Personal Access Token')
187
- .option('-f, --force', 'Forces Unpublished Extension')
203
+ .option('-f, --force', 'Skip confirmation prompt when unpublishing an extension')
188
204
  .action((id, { pat, force }) => main((0, publish_1.unpublish)({ id, pat, force })));
189
205
  commander_1.default
190
206
  .command('ls-publishers')
191
- .description('List all known publishers')
207
+ .description('Lists all known publishers')
192
208
  .action(() => main((0, store_1.listPublishers)()));
193
209
  commander_1.default
194
210
  .command('delete-publisher <publisher>')
195
- .description('Deletes a publisher')
211
+ .description('Deletes a publisher from marketplace')
196
212
  .action(publisher => main((0, store_1.deletePublisher)(publisher)));
197
213
  commander_1.default
198
214
  .command('login <publisher>')
199
- .description('Add a publisher to the known publishers list')
215
+ .description('Adds a publisher to the list of known publishers')
200
216
  .action(name => main((0, store_1.loginPublisher)(name)));
201
217
  commander_1.default
202
218
  .command('logout <publisher>')
203
- .description('Remove a publisher from the known publishers list')
219
+ .description('Removes a publisher from the list of known publishers')
204
220
  .action(name => main((0, store_1.logoutPublisher)(name)));
205
221
  commander_1.default
206
222
  .command('verify-pat [publisher]')
223
+ .description('Verifies if the Personal Access Token has publish rights for the publisher')
207
224
  .option('-p, --pat <token>', 'Personal Access Token (defaults to VSCE_PAT environment variable)', process.env['VSCE_PAT'])
208
- .description('Verify if the Personal Access Token has publish rights for the publisher.')
209
225
  .action((name, { pat }) => main((0, store_1.verifyPat)(pat, name)));
210
226
  commander_1.default
211
227
  .command('show <extensionid>')
212
- .option('--json', 'Output data in json format', false)
213
- .description('Show extension metadata')
228
+ .description(`Shows an extension's metadata`)
229
+ .option('--json', 'Outputs data in json format', false)
214
230
  .action((extensionid, { json }) => main((0, show_1.show)(extensionid, json)));
215
231
  commander_1.default
216
232
  .command('search <text>')
217
- .option('--json', 'Output result in json format', false)
218
- .option('--stats', 'Shows the extension rating and download counts', false)
233
+ .description('Searches extension gallery')
234
+ .option('--json', 'Output results in json format', false)
235
+ .option('--stats', 'Shows extensions rating and download count', false)
219
236
  .option('-p, --pagesize [value]', 'Number of results to return', '100')
220
- .description('search extension gallery')
221
237
  .action((text, { json, pagesize, stats }) => main((0, search_1.search)(text, json, parseInt(pagesize), stats)));
222
238
  commander_1.default.on('command:*', ([cmd]) => {
223
239
  if (cmd === 'create-publisher') {
@@ -227,8 +243,7 @@ module.exports = function (argv) {
227
243
  commander_1.default.outputHelp(help => {
228
244
  const availableCommands = commander_1.default.commands.map(c => c._name);
229
245
  const suggestion = availableCommands.find(c => (0, leven_1.default)(c, cmd) < c.length * 0.4);
230
- help = `${help}
231
- Unknown command '${cmd}'`;
246
+ help = `${help}\n Unknown command '${cmd}'`;
232
247
  return suggestion ? `${help}, did you mean '${suggestion}'?\n` : `${help}.\n`;
233
248
  });
234
249
  process.exit(1);
package/out/npm.js CHANGED
@@ -30,7 +30,8 @@ exports.getLatestVersion = exports.getDependencies = exports.detectYarn = void 0
30
30
  const path = __importStar(require("path"));
31
31
  const fs = __importStar(require("fs"));
32
32
  const cp = __importStar(require("child_process"));
33
- const parse_semver_1 = __importDefault(require("parse-semver"));
33
+ const find_yarn_workspace_root_1 = __importDefault(require("find-yarn-workspace-root"));
34
+ const package_1 = require("./package");
34
35
  const util_1 = require("./util");
35
36
  const exists = (file) => fs.promises.stat(file).then(_ => true, _ => false);
36
37
  function parseStdout({ stdout }) {
@@ -67,29 +68,49 @@ async function checkNPM(cancellationToken) {
67
68
  function getNpmDependencies(cwd) {
68
69
  return checkNPM()
69
70
  .then(() => exec('npm list --production --parseable --depth=99999 --loglevel=error', { cwd, maxBuffer: 5000 * 1024 }))
70
- .then(({ stdout }) => stdout.split(/[\r\n]/).filter(dir => path.isAbsolute(dir)));
71
+ .then(({ stdout }) => stdout.split(/[\r\n]/).filter(dir => path.isAbsolute(dir))
72
+ .map(dir => {
73
+ return {
74
+ src: dir,
75
+ dest: path.relative(cwd, dir)
76
+ };
77
+ }));
71
78
  }
72
- function asYarnDependency(prefix, tree, prune) {
73
- if (prune && /@[\^~]/.test(tree.name)) {
74
- return null;
75
- }
76
- let name;
77
- try {
78
- const parseResult = (0, parse_semver_1.default)(tree.name);
79
- name = parseResult.name;
80
- }
81
- catch (err) {
82
- name = tree.name.replace(/^([^@+])@.*$/, '$1');
83
- }
84
- const dependencyPath = path.join(prefix, name);
85
- const children = [];
86
- for (const child of tree.children || []) {
87
- const dep = asYarnDependency(path.join(prefix, name, 'node_modules'), child, prune);
88
- if (dep) {
89
- children.push(dep);
79
+ async function asYarnDependencies(root, rootDependencies) {
80
+ const resolve = async (prefix, dependencies, collected = new Map()) => await Promise.all(dependencies
81
+ .map(async (name) => {
82
+ let newPrefix = prefix, depPath = null, depManifest = null;
83
+ while (!depManifest && root.length <= newPrefix.length) {
84
+ depPath = path.join(newPrefix, 'node_modules', name);
85
+ try {
86
+ depManifest = await (0, package_1.readNodeManifest)(depPath);
87
+ }
88
+ catch (err) {
89
+ newPrefix = path.join(newPrefix, '..');
90
+ if (newPrefix.length < root.length) {
91
+ throw err;
92
+ }
93
+ }
90
94
  }
91
- }
92
- return { name, path: dependencyPath, children };
95
+ if (!depPath || !depManifest) {
96
+ throw new Error(`Error finding dependencies`);
97
+ }
98
+ const result = {
99
+ name,
100
+ path: {
101
+ src: depPath,
102
+ dest: path.relative(root, depPath),
103
+ },
104
+ children: [],
105
+ };
106
+ const shouldResolveChildren = !collected.has(depPath);
107
+ collected.set(depPath, result);
108
+ if (shouldResolveChildren) {
109
+ result.children = await resolve(depPath, Object.keys(depManifest.dependencies || {}), collected);
110
+ }
111
+ return result;
112
+ }));
113
+ return resolve(root, rootDependencies);
93
114
  }
94
115
  function selectYarnDependencies(deps, packagedDependencies) {
95
116
  const index = new (class {
@@ -135,35 +156,38 @@ function selectYarnDependencies(deps, packagedDependencies) {
135
156
  packagedDependencies.forEach(visit);
136
157
  return reached.values;
137
158
  }
138
- async function getYarnProductionDependencies(cwd, packagedDependencies) {
139
- const raw = await new Promise((c, e) => cp.exec('yarn list --prod --json', { cwd, encoding: 'utf8', env: { ...process.env }, maxBuffer: 5000 * 1024 }, (err, stdout) => (err ? e(err) : c(stdout))));
140
- const match = /^{"type":"tree".*$/m.exec(raw);
141
- if (!match || match.length !== 1) {
142
- throw new Error('Could not parse result of `yarn list --json`');
143
- }
159
+ async function getYarnProductionDependencies(root, manifest, packagedDependencies) {
144
160
  const usingPackagedDependencies = Array.isArray(packagedDependencies);
145
- const trees = JSON.parse(match[0]).data.trees;
146
- let result = trees
147
- .map(tree => asYarnDependency(path.join(cwd, 'node_modules'), tree, !usingPackagedDependencies))
148
- .filter(util_1.nonnull);
161
+ let result = await asYarnDependencies(root, Object.keys(manifest.dependencies || {}));
149
162
  if (usingPackagedDependencies) {
150
163
  result = selectYarnDependencies(result, packagedDependencies);
151
164
  }
152
165
  return result;
153
166
  }
154
- async function getYarnDependencies(cwd, packagedDependencies) {
155
- const result = new Set([cwd]);
156
- const deps = await getYarnProductionDependencies(cwd, packagedDependencies);
157
- const flatten = (dep) => {
158
- result.add(dep.path);
159
- dep.children.forEach(flatten);
160
- };
161
- deps.forEach(flatten);
162
- return [...result];
167
+ async function getYarnDependencies(cwd, root, manifest, packagedDependencies) {
168
+ const result = [{
169
+ src: cwd,
170
+ dest: ''
171
+ }];
172
+ if (await exists(path.join(root, 'yarn.lock'))) {
173
+ const deps = await getYarnProductionDependencies(root, manifest, packagedDependencies);
174
+ const flatten = (dep) => {
175
+ result.push(dep.path);
176
+ dep.children.forEach(flatten);
177
+ };
178
+ deps.forEach(flatten);
179
+ }
180
+ const dedup = new Map();
181
+ for (const item of result) {
182
+ if (!dedup.has(item.src)) {
183
+ dedup.set(item.src, item);
184
+ }
185
+ }
186
+ return [...dedup.values()];
163
187
  }
164
- async function detectYarn(cwd) {
188
+ async function detectYarn(root) {
165
189
  for (const name of ['yarn.lock', '.yarnrc', '.yarnrc.yaml', '.pnp.cjs', '.yarn']) {
166
- if (await exists(path.join(cwd, name))) {
190
+ if (await exists(path.join(root, name))) {
167
191
  if (!process.env['VSCE_TESTS']) {
168
192
  util_1.log.info(`Detected presence of ${name}. Using 'yarn' instead of 'npm' (to override this pass '--no-yarn' on the command line).`);
169
193
  }
@@ -173,12 +197,13 @@ async function detectYarn(cwd) {
173
197
  return false;
174
198
  }
175
199
  exports.detectYarn = detectYarn;
176
- async function getDependencies(cwd, dependencies, packagedDependencies) {
200
+ async function getDependencies(cwd, manifest, dependencies, packagedDependencies) {
201
+ const root = (0, find_yarn_workspace_root_1.default)(cwd) || cwd;
177
202
  if (dependencies === 'none') {
178
- return [cwd];
203
+ return [{ src: root, dest: '' }];
179
204
  }
180
- else if (dependencies === 'yarn' || (dependencies === undefined && (await detectYarn(cwd)))) {
181
- return await getYarnDependencies(cwd, packagedDependencies);
205
+ else if (dependencies === 'yarn' || (dependencies === undefined && (await detectYarn(root)))) {
206
+ return await getYarnDependencies(cwd, root, manifest, packagedDependencies);
182
207
  }
183
208
  else {
184
209
  return await getNpmDependencies(cwd);
package/out/package.js CHANGED
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.ls = exports.listFiles = exports.packageCommand = exports.pack = exports.prepublish = exports.collect = exports.createDefaultProcessors = exports.processFiles = exports.toContentTypes = exports.toVsixManifest = exports.readManifest = exports.validateManifest = exports.ValidationProcessor = exports.NLSProcessor = exports.isWebKind = exports.LicenseProcessor = exports.ChangelogProcessor = exports.ReadmeProcessor = exports.MarkdownProcessor = exports.TagsProcessor = exports.ManifestProcessor = exports.Targets = exports.versionBump = exports.BaseProcessor = exports.read = void 0;
29
+ exports.ls = exports.listFiles = exports.packageCommand = exports.pack = exports.prepublish = exports.collect = exports.createDefaultProcessors = exports.processFiles = exports.toContentTypes = exports.toVsixManifest = exports.readManifest = exports.readNodeManifest = exports.validateManifest = exports.ValidationProcessor = exports.NLSProcessor = exports.isWebKind = exports.LicenseProcessor = exports.ChangelogProcessor = exports.ReadmeProcessor = exports.MarkdownProcessor = exports.TagsProcessor = exports.ManifestProcessor = exports.Targets = exports.versionBump = exports.BaseProcessor = exports.read = void 0;
30
30
  const fs = __importStar(require("fs"));
31
31
  const path = __importStar(require("path"));
32
32
  const util_1 = require("util");
@@ -364,13 +364,13 @@ class ManifestProcessor extends BaseProcessor {
364
364
  throw new Error("It's not allowed to use the 'vscode-samples' publisher. Learn more at: https://code.visualstudio.com/api/working-with-extensions/publishing-extension.");
365
365
  }
366
366
  if (!this.options.allowMissingRepository && !this.manifest.repository) {
367
- util.log.warn(`A 'repository' field is missing from the 'package.json' manifest file.`);
367
+ util.log.warn(`A 'repository' field is missing from the 'package.json' manifest file.\nUse --allow-missing-repository to bypass.`);
368
368
  if (!/^y$/i.test(await util.read('Do you want to continue? [y/N] '))) {
369
369
  throw new Error('Aborted');
370
370
  }
371
371
  }
372
372
  if (!this.options.allowStarActivation && this.manifest.activationEvents?.some(e => e === '*')) {
373
- util.log.warn(`Using '*' activation is usually a bad idea as it impacts performance.\nMore info: https://code.visualstudio.com/api/references/activation-events#Start-up`);
373
+ util.log.warn(`Using '*' activation is usually a bad idea as it impacts performance.\nMore info: https://code.visualstudio.com/api/references/activation-events#Start-up\nUse --allow-star-activation to bypass.`);
374
374
  if (!/^y$/i.test(await util.read('Do you want to continue? [y/N] '))) {
375
375
  throw new Error('Aborted');
376
376
  }
@@ -473,11 +473,11 @@ TagsProcessor.Keywords = {
473
473
  rust: ['rust'],
474
474
  };
475
475
  class MarkdownProcessor extends BaseProcessor {
476
- constructor(manifest, name, regexp, assetType, options = {}) {
476
+ constructor(manifest, name, filePath, assetType, options = {}) {
477
477
  super(manifest);
478
478
  this.name = name;
479
- this.regexp = regexp;
480
479
  this.assetType = assetType;
480
+ this.regexp = new RegExp(`^extension/${filePath}$`, 'i');
481
481
  const guess = this.guessBaseUrls(options.githubBranch || options.gitlabBranch);
482
482
  this.baseContentUrl = options.baseContentUrl || (guess && guess.content);
483
483
  this.baseImagesUrl = options.baseImagesUrl || options.baseContentUrl || (guess && guess.images);
@@ -521,7 +521,7 @@ class MarkdownProcessor extends BaseProcessor {
521
521
  // Replace Markdown links with urls
522
522
  contents = contents.replace(markdownPathRegex, urlReplace);
523
523
  // Replace <img> links with urls
524
- contents = contents.replace(/<img.+?src=["']([/.\w\s#-]+)['"].*?>/g, (all, link) => {
524
+ contents = contents.replace(/<(?:img|video)[^>]+src=["']([/.\w\s#-]+)['"][^>]*>/gm, (all, link) => {
525
525
  const isLinkRelative = !/^\w+:\/\//.test(link) && link[0] !== '#';
526
526
  if (!this.baseImagesUrl && isLinkRelative) {
527
527
  throw new Error(`Couldn't detect the repository where this extension is published. The image will be broken in ${this.name}. GitHub/GitLab repositories will be automatically detected. Otherwise, please provide the repository URL in package.json or use the --baseContentUrl and --baseImagesUrl options.`);
@@ -571,7 +571,13 @@ class MarkdownProcessor extends BaseProcessor {
571
571
  throw new Error(`Images in ${this.name} must have a source.`);
572
572
  }
573
573
  const src = decodeURI(rawSrc);
574
- const srcUrl = new url.URL(src);
574
+ let srcUrl;
575
+ try {
576
+ srcUrl = new url.URL(src);
577
+ }
578
+ catch (err) {
579
+ throw new Error(`Invalid image source in ${this.name}: ${src}`);
580
+ }
575
581
  if (/^data:$/i.test(srcUrl.protocol) && /^image$/i.test(srcUrl.host) && /\/svg/i.test(srcUrl.pathname)) {
576
582
  throw new Error(`SVG data URLs are not allowed in ${this.name}: ${src}`);
577
583
  }
@@ -631,13 +637,13 @@ class MarkdownProcessor extends BaseProcessor {
631
637
  exports.MarkdownProcessor = MarkdownProcessor;
632
638
  class ReadmeProcessor extends MarkdownProcessor {
633
639
  constructor(manifest, options = {}) {
634
- super(manifest, 'README.md', /^extension\/readme.md$/i, 'Microsoft.VisualStudio.Services.Content.Details', options);
640
+ super(manifest, 'README.md', options.readmePath ?? 'readme.md', 'Microsoft.VisualStudio.Services.Content.Details', options);
635
641
  }
636
642
  }
637
643
  exports.ReadmeProcessor = ReadmeProcessor;
638
644
  class ChangelogProcessor extends MarkdownProcessor {
639
645
  constructor(manifest, options = {}) {
640
- super(manifest, 'CHANGELOG.md', /^extension\/changelog.md$/i, 'Microsoft.VisualStudio.Services.Content.Changelog', options);
646
+ super(manifest, 'CHANGELOG.md', options.changelogPath ?? 'changelog.md', 'Microsoft.VisualStudio.Services.Content.Changelog', options);
641
647
  }
642
648
  }
643
649
  exports.ChangelogProcessor = ChangelogProcessor;
@@ -918,7 +924,13 @@ function validateManifest(manifest) {
918
924
  }
919
925
  (manifest.badges ?? []).forEach(badge => {
920
926
  const decodedUrl = decodeURI(badge.url);
921
- const srcUrl = new url.URL(decodedUrl);
927
+ let srcUrl;
928
+ try {
929
+ srcUrl = new url.URL(decodedUrl);
930
+ }
931
+ catch (err) {
932
+ throw new Error(`Badge URL is invalid: ${badge.url}`);
933
+ }
922
934
  if (!/^https:$/i.test(srcUrl.protocol)) {
923
935
  throw new Error(`Badge URLs must come from an HTTPS source: ${badge.url}`);
924
936
  }
@@ -959,9 +971,8 @@ function validateManifest(manifest) {
959
971
  return manifest;
960
972
  }
961
973
  exports.validateManifest = validateManifest;
962
- function readManifest(cwd = process.cwd(), nls = true) {
974
+ function readNodeManifest(cwd = process.cwd()) {
963
975
  const manifestPath = path.join(cwd, 'package.json');
964
- const manifestNLSPath = path.join(cwd, 'package.nls.json');
965
976
  const manifest = fs.promises
966
977
  .readFile(manifestPath, 'utf8')
967
978
  .catch(() => Promise.reject(`Extension manifest not found: ${manifestPath}`))
@@ -973,11 +984,17 @@ function readManifest(cwd = process.cwd(), nls = true) {
973
984
  console.error(`Error parsing 'package.json' manifest file: not a valid JSON file.`);
974
985
  throw e;
975
986
  }
976
- })
987
+ });
988
+ return manifest;
989
+ }
990
+ exports.readNodeManifest = readNodeManifest;
991
+ function readManifest(cwd = process.cwd(), nls = true) {
992
+ const manifest = readNodeManifest(cwd)
977
993
  .then(validateManifest);
978
994
  if (!nls) {
979
995
  return manifest;
980
996
  }
997
+ const manifestNLSPath = path.join(cwd, 'package.nls.json');
981
998
  const manifestNLS = fs.promises
982
999
  .readFile(manifestNLSPath, 'utf8')
983
1000
  .catch(err => (err.code !== 'ENOENT' ? Promise.reject(err) : Promise.resolve('{}')))
@@ -1130,14 +1147,38 @@ const defaultIgnore = [
1130
1147
  '**/.vscode-test-web/**',
1131
1148
  ];
1132
1149
  const notIgnored = ['!package.json', '!README.md'];
1133
- async function collectAllFiles(cwd, dependencies, dependencyEntryPoints) {
1134
- const deps = await (0, npm_1.getDependencies)(cwd, dependencies, dependencyEntryPoints);
1135
- const promises = deps.map(dep => (0, util_1.promisify)(glob_1.default)('**', { cwd: dep, nodir: true, dot: true, ignore: 'node_modules/**' }).then(files => files.map(f => path.relative(cwd, path.join(dep, f))).map(f => f.replace(/\\/g, '/'))));
1150
+ async function collectAllFiles(cwd, manifest, dependencies, dependencyEntryPoints) {
1151
+ const deps = await (0, npm_1.getDependencies)(cwd, manifest, dependencies, dependencyEntryPoints);
1152
+ const promises = deps.map(dep => (0, util_1.promisify)(glob_1.default)('**', { cwd: dep.src, nodir: true, dot: true, ignore: 'node_modules/**' }).then(files => files.map(f => ({
1153
+ src: path.relative(cwd, path.join(dep.src, f)).replace(/\\/g, '/'),
1154
+ dest: path.join(dep.dest, f).replace(/\\/g, '/')
1155
+ }))));
1136
1156
  return Promise.all(promises).then(util.flatten);
1137
1157
  }
1138
- function collectFiles(cwd, dependencies, dependencyEntryPoints, ignoreFile) {
1139
- return collectAllFiles(cwd, dependencies, dependencyEntryPoints).then(files => {
1140
- files = files.filter(f => !/\r$/m.test(f));
1158
+ function getDependenciesOption(options) {
1159
+ if (options.dependencies === false) {
1160
+ return 'none';
1161
+ }
1162
+ switch (options.useYarn) {
1163
+ case true:
1164
+ return 'yarn';
1165
+ case false:
1166
+ return 'npm';
1167
+ default:
1168
+ return undefined;
1169
+ }
1170
+ }
1171
+ function collectFiles(cwd, manifest, options) {
1172
+ const packagedDependencies = options.dependencyEntryPoints || undefined;
1173
+ const ignoreFile = options.ignoreFile || undefined;
1174
+ const target = options.target || undefined;
1175
+ return collectAllFiles(cwd, manifest, getDependenciesOption(options), packagedDependencies).then(files => {
1176
+ files = files.filter(f => !/\r$/m.test(f.src));
1177
+ // Filter data from other platforms
1178
+ if (target && options.ignoreOtherTargetFolders) {
1179
+ const regex = new RegExp(`(^|/)(${Array.from(exports.Targets, v => v).filter(v => v !== target).join('|')})/`);
1180
+ files = files.filter(f => !regex.test(f.src));
1181
+ }
1141
1182
  return (fs.promises
1142
1183
  .readFile(ignoreFile ? ignoreFile : path.join(cwd, '.vscodeignore'), 'utf8')
1143
1184
  .catch(err => err.code !== 'ENOENT' ? Promise.reject(err) : ignoreFile ? Promise.reject(err) : Promise.resolve(''))
@@ -1158,8 +1199,8 @@ function collectFiles(cwd, dependencies, dependencyEntryPoints, ignoreFile) {
1158
1199
  .then(ignore => ignore.reduce((r, e) => (!/^\s*!/.test(e) ? [[...r[0], e], r[1]] : [r[0], [...r[1], e]]), [[], []]))
1159
1200
  .then(r => ({ ignore: r[0], negate: r[1] }))
1160
1201
  // Filter out files
1161
- .then(({ ignore, negate }) => files.filter(f => !ignore.some(i => (0, minimatch_1.default)(f, i, MinimatchOptions)) ||
1162
- negate.some(i => (0, minimatch_1.default)(f, i.substr(1), MinimatchOptions)))));
1202
+ .then(({ ignore, negate }) => files.filter(f => !ignore.some(i => (0, minimatch_1.default)(f.src, i, MinimatchOptions)) ||
1203
+ negate.some(i => (0, minimatch_1.default)(f.src, i.substr(1), MinimatchOptions)))));
1163
1204
  });
1164
1205
  }
1165
1206
  function processFiles(processors, files) {
@@ -1203,26 +1244,11 @@ function createDefaultProcessors(manifest, options = {}) {
1203
1244
  ];
1204
1245
  }
1205
1246
  exports.createDefaultProcessors = createDefaultProcessors;
1206
- function getDependenciesOption(options) {
1207
- if (options.dependencies === false) {
1208
- return 'none';
1209
- }
1210
- switch (options.useYarn) {
1211
- case true:
1212
- return 'yarn';
1213
- case false:
1214
- return 'npm';
1215
- default:
1216
- return undefined;
1217
- }
1218
- }
1219
1247
  function collect(manifest, options = {}) {
1220
1248
  const cwd = options.cwd || process.cwd();
1221
- const packagedDependencies = options.dependencyEntryPoints || undefined;
1222
- const ignoreFile = options.ignoreFile || undefined;
1223
1249
  const processors = createDefaultProcessors(manifest, options);
1224
- return collectFiles(cwd, getDependenciesOption(options), packagedDependencies, ignoreFile).then(fileNames => {
1225
- const files = fileNames.map(f => ({ path: `extension/${f}`, localPath: path.join(cwd, f) }));
1250
+ return collectFiles(cwd, manifest, options).then(fileNames => {
1251
+ const files = fileNames.map(f => ({ path: `extension/${f.dest}`, localPath: path.join(cwd, f.src) }));
1226
1252
  return processFiles(processors, files);
1227
1253
  });
1228
1254
  }
@@ -1297,7 +1323,7 @@ async function pack(options = {}) {
1297
1323
  if (files.length > 5000 || jsFiles.length > 100) {
1298
1324
  console.log(`This extension consists of ${files.length} files, out of which ${jsFiles.length} are JavaScript files. For performance reasons, you should bundle your extension: https://aka.ms/vscode-bundle-extension . You should also exclude unnecessary files by adding them to your .vscodeignore: https://aka.ms/vscode-vscodeignore`);
1299
1325
  }
1300
- if (options.version) {
1326
+ if (options.version && !(options.updatePackageJson ?? true)) {
1301
1327
  manifest.version = options.version;
1302
1328
  }
1303
1329
  const packagePath = await getPackagePath(cwd, manifest, options);
@@ -1335,7 +1361,8 @@ async function listFiles(options = {}) {
1335
1361
  if (options.prepublish) {
1336
1362
  await prepublish(cwd, manifest, options.useYarn);
1337
1363
  }
1338
- return await collectFiles(cwd, getDependenciesOption(options), options.packagedDependencies, options.ignoreFile);
1364
+ const files = await collectFiles(cwd, manifest, options);
1365
+ return files.map(f => f.src);
1339
1366
  }
1340
1367
  exports.listFiles = listFiles;
1341
1368
  /**
package/out/publish.js CHANGED
@@ -90,11 +90,11 @@ async function publish(options = {}) {
90
90
  exports.publish = publish;
91
91
  async function _publish(packagePath, manifest, options) {
92
92
  (0, validation_1.validatePublisher)(manifest.publisher);
93
- if (!options.noVerify && manifest.enableProposedApi) {
94
- throw new Error("Extensions using proposed API (enableProposedApi: true) can't be published to the Marketplace");
93
+ if (manifest.enableProposedApi && !options.allowAllProposedApis && !options.noVerify) {
94
+ throw new Error("Extensions using proposed API (enableProposedApi: true) can't be published to the Marketplace. Use --allow-all-proposed-apis to bypass.");
95
95
  }
96
- if (!options.noVerify && manifest.enabledApiProposals) {
97
- throw new Error("Extensions using proposed API (enabledApiProposals: [...]) can't be published to the Marketplace");
96
+ if (manifest.enabledApiProposals && !options.allowAllProposedApis && !options.noVerify && manifest.enabledApiProposals?.some(p => !options.allowProposedApis?.includes(p))) {
97
+ throw new Error(`Extensions using unallowed proposed API (enabledApiProposals: [${manifest.enabledApiProposals}], allowed: [${options.allowProposedApis ?? []}]) can't be published to the Marketplace. Use --allow-proposed-apis <APIS...> or --allow-all-proposed-apis to bypass.`);
98
98
  }
99
99
  if (semver.prerelease(manifest.version)) {
100
100
  throw new Error(`The VS Marketplace doesn't support prerelease versions: '${manifest.version}'`);
package/out/show.js CHANGED
@@ -12,6 +12,7 @@ function show(extensionId, json = false) {
12
12
  GalleryInterfaces_1.ExtensionQueryFlags.IncludeMetadata,
13
13
  GalleryInterfaces_1.ExtensionQueryFlags.IncludeStatistics,
14
14
  GalleryInterfaces_1.ExtensionQueryFlags.IncludeVersions,
15
+ GalleryInterfaces_1.ExtensionQueryFlags.IncludeVersionProperties,
15
16
  ];
16
17
  return (0, util_1.getPublicGalleryAPI)()
17
18
  .getExtension(extensionId, flags)
@@ -30,13 +31,59 @@ function show(extensionId, json = false) {
30
31
  });
31
32
  }
32
33
  exports.show = show;
34
+ function round(num) {
35
+ return Math.round(num * 100) / 100;
36
+ }
37
+ function unit(value, statisticName) {
38
+ switch (statisticName) {
39
+ case 'install':
40
+ return `${value} installs`;
41
+ case 'updateCount':
42
+ return `${value} updates`;
43
+ case 'averagerating':
44
+ case 'weightedRating':
45
+ return `${value} stars`;
46
+ case 'ratingcount':
47
+ return `${value} ratings`;
48
+ case 'downloadCount':
49
+ return `${value} downloads`;
50
+ default:
51
+ return `${value}`;
52
+ }
53
+ }
54
+ function getVersionTable(versions) {
55
+ if (!versions.length) {
56
+ return [];
57
+ }
58
+ const set = new Set();
59
+ const result = versions
60
+ .filter(({ version }) => !set.has(version) && set.add(version))
61
+ .slice(0, limitVersions)
62
+ .map(({ version, lastUpdated, properties }) => [version, (0, viewutils_1.formatDate)(lastUpdated), properties?.some(p => p.key === 'Microsoft.VisualStudio.Code.PreRelease')]);
63
+ // Only show pre-release column if there are any pre-releases
64
+ if (result.every(v => !v[2])) {
65
+ for (const version of result) {
66
+ version.pop();
67
+ }
68
+ result.unshift(['Version', 'Last Updated']);
69
+ }
70
+ else {
71
+ for (const version of result) {
72
+ version[2] = version[2] ? `✔️` : '';
73
+ }
74
+ result.unshift(['Version', 'Last Updated', 'Pre-release']);
75
+ }
76
+ return result;
77
+ }
33
78
  function showOverview({ displayName = 'unknown', extensionName = 'unknown', shortDescription = '', versions = [], publisher: { displayName: publisherDisplayName, publisherName }, categories = [], tags = [], statistics = [], publishedDate, lastUpdated, }) {
34
79
  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)]));
80
+ const versionTable = getVersionTable(versions);
81
+ const latestVersionTargets = versions
82
+ .filter(v => v.version === version)
83
+ .filter(v => v.targetPlatform)
84
+ .map(v => v.targetPlatform);
37
85
  const { install: installs = 0, averagerating = 0, ratingcount = 0 } = statistics.reduce((map, { statisticName, value }) => ({ ...map, [statisticName]: value }), {});
38
- // Render
39
- console.log([
86
+ const rows = [
40
87
  `${displayName}`,
41
88
  `${publisherDisplayName} | ${viewutils_1.icons.download} ` +
42
89
  `${Number(installs).toLocaleString()} installs |` +
@@ -44,28 +91,27 @@ function showOverview({ displayName = 'unknown', extensionName = 'unknown', shor
44
91
  '',
45
92
  `${shortDescription}`,
46
93
  '',
47
- 'Recent versions:',
48
- ...(versionList.length ? (0, viewutils_1.tableView)(versionList).map(viewutils_1.indentRow) : ['no versions found']),
94
+ ...(versionTable.length ? (0, viewutils_1.tableView)(versionTable).map(viewutils_1.indentRow) : ['no versions found']),
49
95
  '',
50
96
  'Categories:',
51
97
  ` ${categories.join(', ')}`,
52
98
  '',
53
99
  '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'));
100
+ ` ${tags.filter(tag => !isExtensionTag.test(tag)).join(', ')}`
101
+ ];
102
+ if (latestVersionTargets.length) {
103
+ rows.push('', 'Targets:', ` ${latestVersionTargets.join(', ')}`);
104
+ }
105
+ rows.push('', 'More info:', ...(0, viewutils_1.tableView)([
106
+ ['Unique identifier:', `${publisherName}.${extensionName}`],
107
+ ['Version:', version],
108
+ ['Last updated:', (0, viewutils_1.formatDateTime)(lastUpdated)],
109
+ ['Publisher:', publisherDisplayName],
110
+ ['Published at:', (0, viewutils_1.formatDate)(publishedDate)],
111
+ ]).map(viewutils_1.indentRow), '', 'Statistics:', ...(0, viewutils_1.tableView)(statistics
112
+ .filter(({ statisticName }) => !/^trending/.test(statisticName))
113
+ .map(({ statisticName, value }) => [statisticName, unit(round(value), statisticName)])).map(viewutils_1.indentRow));
114
+ // Render
115
+ console.log(rows.map(line => (0, viewutils_1.wordWrap)(line)).join('\n'));
70
116
  }
71
117
  //# sourceMappingURL=show.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vscode/vsce",
3
- "version": "2.22.0",
3
+ "version": "2.22.1-0",
4
4
  "description": "VS Code Extensions Manager",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,6 +42,7 @@
42
42
  "chalk": "^2.4.2",
43
43
  "cheerio": "^1.0.0-rc.9",
44
44
  "commander": "^6.2.1",
45
+ "find-yarn-workspace-root": "^2.0.0",
45
46
  "glob": "^7.0.6",
46
47
  "hosted-git-info": "^4.0.2",
47
48
  "jsonc-parser": "^3.2.0",