@vscode/vsce 2.21.1 → 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:
@@ -72,7 +51,7 @@ Or you can also set them in the `package.json`, so that you avoid having to rety
72
51
  // package.json
73
52
  {
74
53
  "vsce": {
75
- "baseImagesUrl": "https://my.custom/base/images/url"
54
+ "baseImagesUrl": "https://my.custom/base/images/url",
76
55
  "dependencies": true,
77
56
  "yarn": false
78
57
  }
@@ -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");
@@ -246,7 +246,6 @@ async function versionBump(options) {
246
246
  exports.versionBump = versionBump;
247
247
  exports.Targets = new Set([
248
248
  'win32-x64',
249
- 'win32-ia32',
250
249
  'win32-arm64',
251
250
  'linux-x64',
252
251
  'linux-arm64',
@@ -365,13 +364,13 @@ class ManifestProcessor extends BaseProcessor {
365
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.");
366
365
  }
367
366
  if (!this.options.allowMissingRepository && !this.manifest.repository) {
368
- 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.`);
369
368
  if (!/^y$/i.test(await util.read('Do you want to continue? [y/N] '))) {
370
369
  throw new Error('Aborted');
371
370
  }
372
371
  }
373
372
  if (!this.options.allowStarActivation && this.manifest.activationEvents?.some(e => e === '*')) {
374
- 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.`);
375
374
  if (!/^y$/i.test(await util.read('Do you want to continue? [y/N] '))) {
376
375
  throw new Error('Aborted');
377
376
  }
@@ -474,11 +473,11 @@ TagsProcessor.Keywords = {
474
473
  rust: ['rust'],
475
474
  };
476
475
  class MarkdownProcessor extends BaseProcessor {
477
- constructor(manifest, name, regexp, assetType, options = {}) {
476
+ constructor(manifest, name, filePath, assetType, options = {}) {
478
477
  super(manifest);
479
478
  this.name = name;
480
- this.regexp = regexp;
481
479
  this.assetType = assetType;
480
+ this.regexp = new RegExp(`^extension/${filePath}$`, 'i');
482
481
  const guess = this.guessBaseUrls(options.githubBranch || options.gitlabBranch);
483
482
  this.baseContentUrl = options.baseContentUrl || (guess && guess.content);
484
483
  this.baseImagesUrl = options.baseImagesUrl || options.baseContentUrl || (guess && guess.images);
@@ -522,7 +521,7 @@ class MarkdownProcessor extends BaseProcessor {
522
521
  // Replace Markdown links with urls
523
522
  contents = contents.replace(markdownPathRegex, urlReplace);
524
523
  // Replace <img> links with urls
525
- contents = contents.replace(/<img.+?src=["']([/.\w\s#-]+)['"].*?>/g, (all, link) => {
524
+ contents = contents.replace(/<(?:img|video)[^>]+src=["']([/.\w\s#-]+)['"][^>]*>/gm, (all, link) => {
526
525
  const isLinkRelative = !/^\w+:\/\//.test(link) && link[0] !== '#';
527
526
  if (!this.baseImagesUrl && isLinkRelative) {
528
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.`);
@@ -572,7 +571,13 @@ class MarkdownProcessor extends BaseProcessor {
572
571
  throw new Error(`Images in ${this.name} must have a source.`);
573
572
  }
574
573
  const src = decodeURI(rawSrc);
575
- 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
+ }
576
581
  if (/^data:$/i.test(srcUrl.protocol) && /^image$/i.test(srcUrl.host) && /\/svg/i.test(srcUrl.pathname)) {
577
582
  throw new Error(`SVG data URLs are not allowed in ${this.name}: ${src}`);
578
583
  }
@@ -632,13 +637,13 @@ class MarkdownProcessor extends BaseProcessor {
632
637
  exports.MarkdownProcessor = MarkdownProcessor;
633
638
  class ReadmeProcessor extends MarkdownProcessor {
634
639
  constructor(manifest, options = {}) {
635
- 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);
636
641
  }
637
642
  }
638
643
  exports.ReadmeProcessor = ReadmeProcessor;
639
644
  class ChangelogProcessor extends MarkdownProcessor {
640
645
  constructor(manifest, options = {}) {
641
- 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);
642
647
  }
643
648
  }
644
649
  exports.ChangelogProcessor = ChangelogProcessor;
@@ -919,7 +924,13 @@ function validateManifest(manifest) {
919
924
  }
920
925
  (manifest.badges ?? []).forEach(badge => {
921
926
  const decodedUrl = decodeURI(badge.url);
922
- 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
+ }
923
934
  if (!/^https:$/i.test(srcUrl.protocol)) {
924
935
  throw new Error(`Badge URLs must come from an HTTPS source: ${badge.url}`);
925
936
  }
@@ -960,9 +971,8 @@ function validateManifest(manifest) {
960
971
  return manifest;
961
972
  }
962
973
  exports.validateManifest = validateManifest;
963
- function readManifest(cwd = process.cwd(), nls = true) {
974
+ function readNodeManifest(cwd = process.cwd()) {
964
975
  const manifestPath = path.join(cwd, 'package.json');
965
- const manifestNLSPath = path.join(cwd, 'package.nls.json');
966
976
  const manifest = fs.promises
967
977
  .readFile(manifestPath, 'utf8')
968
978
  .catch(() => Promise.reject(`Extension manifest not found: ${manifestPath}`))
@@ -974,11 +984,17 @@ function readManifest(cwd = process.cwd(), nls = true) {
974
984
  console.error(`Error parsing 'package.json' manifest file: not a valid JSON file.`);
975
985
  throw e;
976
986
  }
977
- })
987
+ });
988
+ return manifest;
989
+ }
990
+ exports.readNodeManifest = readNodeManifest;
991
+ function readManifest(cwd = process.cwd(), nls = true) {
992
+ const manifest = readNodeManifest(cwd)
978
993
  .then(validateManifest);
979
994
  if (!nls) {
980
995
  return manifest;
981
996
  }
997
+ const manifestNLSPath = path.join(cwd, 'package.nls.json');
982
998
  const manifestNLS = fs.promises
983
999
  .readFile(manifestNLSPath, 'utf8')
984
1000
  .catch(err => (err.code !== 'ENOENT' ? Promise.reject(err) : Promise.resolve('{}')))
@@ -1131,14 +1147,38 @@ const defaultIgnore = [
1131
1147
  '**/.vscode-test-web/**',
1132
1148
  ];
1133
1149
  const notIgnored = ['!package.json', '!README.md'];
1134
- async function collectAllFiles(cwd, dependencies, dependencyEntryPoints) {
1135
- const deps = await (0, npm_1.getDependencies)(cwd, dependencies, dependencyEntryPoints);
1136
- 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
+ }))));
1137
1156
  return Promise.all(promises).then(util.flatten);
1138
1157
  }
1139
- function collectFiles(cwd, dependencies, dependencyEntryPoints, ignoreFile) {
1140
- return collectAllFiles(cwd, dependencies, dependencyEntryPoints).then(files => {
1141
- 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
+ }
1142
1182
  return (fs.promises
1143
1183
  .readFile(ignoreFile ? ignoreFile : path.join(cwd, '.vscodeignore'), 'utf8')
1144
1184
  .catch(err => err.code !== 'ENOENT' ? Promise.reject(err) : ignoreFile ? Promise.reject(err) : Promise.resolve(''))
@@ -1159,8 +1199,8 @@ function collectFiles(cwd, dependencies, dependencyEntryPoints, ignoreFile) {
1159
1199
  .then(ignore => ignore.reduce((r, e) => (!/^\s*!/.test(e) ? [[...r[0], e], r[1]] : [r[0], [...r[1], e]]), [[], []]))
1160
1200
  .then(r => ({ ignore: r[0], negate: r[1] }))
1161
1201
  // Filter out files
1162
- .then(({ ignore, negate }) => files.filter(f => !ignore.some(i => (0, minimatch_1.default)(f, i, MinimatchOptions)) ||
1163
- 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)))));
1164
1204
  });
1165
1205
  }
1166
1206
  function processFiles(processors, files) {
@@ -1204,26 +1244,11 @@ function createDefaultProcessors(manifest, options = {}) {
1204
1244
  ];
1205
1245
  }
1206
1246
  exports.createDefaultProcessors = createDefaultProcessors;
1207
- function getDependenciesOption(options) {
1208
- if (options.dependencies === false) {
1209
- return 'none';
1210
- }
1211
- switch (options.useYarn) {
1212
- case true:
1213
- return 'yarn';
1214
- case false:
1215
- return 'npm';
1216
- default:
1217
- return undefined;
1218
- }
1219
- }
1220
1247
  function collect(manifest, options = {}) {
1221
1248
  const cwd = options.cwd || process.cwd();
1222
- const packagedDependencies = options.dependencyEntryPoints || undefined;
1223
- const ignoreFile = options.ignoreFile || undefined;
1224
1249
  const processors = createDefaultProcessors(manifest, options);
1225
- return collectFiles(cwd, getDependenciesOption(options), packagedDependencies, ignoreFile).then(fileNames => {
1226
- 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) }));
1227
1252
  return processFiles(processors, files);
1228
1253
  });
1229
1254
  }
@@ -1298,7 +1323,7 @@ async function pack(options = {}) {
1298
1323
  if (files.length > 5000 || jsFiles.length > 100) {
1299
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`);
1300
1325
  }
1301
- if (options.version) {
1326
+ if (options.version && !(options.updatePackageJson ?? true)) {
1302
1327
  manifest.version = options.version;
1303
1328
  }
1304
1329
  const packagePath = await getPackagePath(cwd, manifest, options);
@@ -1336,7 +1361,8 @@ async function listFiles(options = {}) {
1336
1361
  if (options.prepublish) {
1337
1362
  await prepublish(cwd, manifest, options.useYarn);
1338
1363
  }
1339
- 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);
1340
1366
  }
1341
1367
  exports.listFiles = listFiles;
1342
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/out/validation.js CHANGED
@@ -112,7 +112,7 @@ function validateVSCodeTypesCompatibility(engineVersion, typeVersion) {
112
112
  return 0;
113
113
  }
114
114
  });
115
- const error = new Error(`@types/vscode ${typeVersion} greater than engines.vscode ${engineVersion}. Consider upgrade engines.vscode or use an older @types/vscode version`);
115
+ const error = new Error(`@types/vscode ${typeVersion} greater than engines.vscode ${engineVersion}. Either upgrade engines.vscode or use an older @types/vscode version`);
116
116
  if (typeMajor > engineMajor) {
117
117
  throw error;
118
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vscode/vsce",
3
- "version": "2.21.1",
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",