@vscode/vsce 2.30.0 → 2.30.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/out/main.js CHANGED
@@ -77,6 +77,7 @@ module.exports = function (argv) {
77
77
  commander_1.default
78
78
  .command('ls')
79
79
  .description('Lists all the files that will be published/packaged')
80
+ .option('--tree', 'Prints the files in a tree format', false)
80
81
  .option('--yarn', 'Use yarn instead of npm (default inferred from presence of yarn.lock or .yarnrc)')
81
82
  .option('--no-yarn', 'Use npm instead of yarn (default inferred from absence of yarn.lock or .yarnrc)')
82
83
  .option('--packagedDependencies <path>', 'Select packages that should be published only (includes dependencies)', (val, all) => (all ? all.concat(val) : [val]), undefined)
@@ -84,7 +85,7 @@ module.exports = function (argv) {
84
85
  // default must remain undefined for dependencies or we will fail to load defaults from package.json
85
86
  .option('--dependencies', 'Enable dependency detection via npm or yarn', undefined)
86
87
  .option('--no-dependencies', 'Disable dependency detection via npm or yarn', undefined)
87
- .action(({ yarn, packagedDependencies, ignoreFile, dependencies }) => main((0, package_1.ls)({ useYarn: yarn, packagedDependencies, ignoreFile, dependencies })));
88
+ .action(({ tree, yarn, packagedDependencies, ignoreFile, dependencies }) => main((0, package_1.ls)({ tree, useYarn: yarn, packagedDependencies, ignoreFile, dependencies })));
88
89
  commander_1.default
89
90
  .command('package [version]')
90
91
  .alias('pack')
package/out/package.js CHANGED
@@ -1346,7 +1346,7 @@ async function pack(options = {}) {
1346
1346
  const cwd = options.cwd || process.cwd();
1347
1347
  const manifest = await readManifest(cwd);
1348
1348
  const files = await collect(manifest, options);
1349
- printPackagedFiles(files, cwd, manifest, options);
1349
+ await printPackagedFiles(files, cwd, manifest, options);
1350
1350
  if (options.version && !(options.updatePackageJson ?? true)) {
1351
1351
  manifest.version = options.version;
1352
1352
  }
@@ -1393,17 +1393,8 @@ async function packageCommand(options = {}) {
1393
1393
  await signPackage(packagePath, options.signTool);
1394
1394
  }
1395
1395
  const stats = await fs.promises.stat(packagePath);
1396
- let size = 0;
1397
- let unit = '';
1398
- if (stats.size > 1048576) {
1399
- size = Math.round(stats.size / 10485.76) / 100;
1400
- unit = 'MB';
1401
- }
1402
- else {
1403
- size = Math.round(stats.size / 10.24) / 100;
1404
- unit = 'KB';
1405
- }
1406
- util.log.done(`Packaged: ${packagePath} (${files.length} files, ${size}${unit})`);
1396
+ const packageSize = util.bytesToString(stats.size);
1397
+ util.log.done(`Packaged: ${packagePath} ` + chalk_1.default.bold(`(${files.length} files, ${packageSize})`));
1407
1398
  }
1408
1399
  exports.packageCommand = packageCommand;
1409
1400
  /**
@@ -1411,7 +1402,7 @@ exports.packageCommand = packageCommand;
1411
1402
  */
1412
1403
  async function listFiles(options = {}) {
1413
1404
  const cwd = options.cwd ?? process.cwd();
1414
- const manifest = await readManifest(cwd);
1405
+ const manifest = options.manifest ?? await readManifest(cwd);
1415
1406
  if (options.prepublish) {
1416
1407
  await prepublish(cwd, manifest, options.useYarn);
1417
1408
  }
@@ -1419,27 +1410,33 @@ async function listFiles(options = {}) {
1419
1410
  }
1420
1411
  exports.listFiles = listFiles;
1421
1412
  /**
1422
- * Lists the files included in the extension's package. Runs prepublish.
1413
+ * Lists the files included in the extension's package.
1423
1414
  */
1424
1415
  async function ls(options = {}) {
1425
- const files = await listFiles({ ...options, prepublish: true });
1426
- for (const file of files) {
1427
- console.log(`${file}`);
1416
+ const cwd = process.cwd();
1417
+ const manifest = await readManifest(cwd);
1418
+ const files = await listFiles({ ...options, cwd, manifest });
1419
+ if (options.tree) {
1420
+ const printableFileStructure = await util.generateFileStructureTree(getDefaultPackageName(manifest, options), files.map(f => ({ origin: f, tree: f })));
1421
+ console.log(printableFileStructure.join('\n'));
1422
+ }
1423
+ else {
1424
+ console.log(files.join('\n'));
1428
1425
  }
1429
1426
  }
1430
1427
  exports.ls = ls;
1431
1428
  /**
1432
1429
  * Prints the packaged files of an extension.
1433
1430
  */
1434
- function printPackagedFiles(files, cwd, manifest, options) {
1431
+ async function printPackagedFiles(files, cwd, manifest, options) {
1435
1432
  // Warn if the extension contains a lot of files
1436
1433
  const jsFiles = files.filter(f => /\.js$/i.test(f.path));
1437
1434
  if (files.length > 5000 || jsFiles.length > 100) {
1438
- let message = '\n';
1435
+ let message = '';
1439
1436
  message += `This extension consists of ${chalk_1.default.bold(String(files.length))} files, out of which ${chalk_1.default.bold(String(jsFiles.length))} are JavaScript files. `;
1440
1437
  message += `For performance reasons, you should bundle your extension: ${chalk_1.default.underline('https://aka.ms/vscode-bundle-extension')}. `;
1441
1438
  message += `You should also exclude unnecessary files by adding them to your .vscodeignore: ${chalk_1.default.underline('https://aka.ms/vscode-vscodeignore')}.\n`;
1442
- console.log(message);
1439
+ util.log.warn(message);
1443
1440
  }
1444
1441
  // Warn if the extension does not have a .vscodeignore file or a files property in package.json
1445
1442
  if (!options.ignoreFile && !manifest.files) {
@@ -1447,20 +1444,27 @@ function printPackagedFiles(files, cwd, manifest, options) {
1447
1444
  if (!hasDeaultIgnore) {
1448
1445
  let message = '';
1449
1446
  message += `Neither a ${chalk_1.default.bold('.vscodeignore')} file nor a ${chalk_1.default.bold('"files"')} property in package.json was found. `;
1450
- message += `To ensure only necessary files are included in your extension package, `;
1451
- message += `add a .vscodeignore file or specify the "files" property in package.json. More info: ${chalk_1.default.underline('https://aka.ms/vscode-vscodeignore')}`;
1447
+ message += `To ensure only necessary files are included in your extension, `;
1448
+ message += `add a .vscodeignore file or specify the "files" property in package.json. More info: ${chalk_1.default.underline('https://aka.ms/vscode-vscodeignore')}\n`;
1452
1449
  util.log.warn(message);
1453
1450
  }
1454
1451
  }
1455
1452
  // Print the files included in the package
1456
- const printableFileStructure = util.generateFileStructureTree(getDefaultPackageName(manifest, options), files.map(f => f.path), 35);
1453
+ const printableFileStructure = await util.generateFileStructureTree(getDefaultPackageName(manifest, options), files.map(f => ({
1454
+ // File path relative to the extension root
1455
+ origin: f.path.startsWith('extension/') ? f.path.substring(10) : f.path,
1456
+ // File path in the VSIX
1457
+ tree: f.path
1458
+ })), 35 // Print up to 35 files/folders
1459
+ );
1457
1460
  let message = '';
1458
1461
  message += chalk_1.default.bold.blue(`Files included in the VSIX:\n`);
1459
1462
  message += printableFileStructure.join('\n');
1463
+ // If not all files have been printed, mention how all files can be printed
1460
1464
  if (files.length + 1 > printableFileStructure.length) {
1461
- // If not all files have been printed, mention how all files can be printed
1462
- message += `\n\n=> Run ${chalk_1.default.bold('vsce ls')} to see a list of all included files.\n`;
1465
+ message += `\n\n=> Run ${chalk_1.default.bold('vsce ls --tree')} to see all included files.`;
1463
1466
  }
1467
+ message += '\n';
1464
1468
  util.log.info(message);
1465
1469
  }
1466
1470
  exports.printPackagedFiles = printPackagedFiles;
package/out/util.js CHANGED
@@ -1,10 +1,34 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
5
28
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.generateFileStructureTree = exports.patchOptionsWithManifest = exports.log = exports.sequence = exports.CancellationToken = exports.isCancelledError = exports.nonnull = exports.flatten = exports.chain = exports.normalize = exports.getPublicGalleryAPI = exports.getSecurityRolesAPI = exports.getGalleryAPI = exports.getHubUrl = exports.getMarketplaceUrl = exports.getPublishedUrl = exports.read = void 0;
29
+ exports.generateFileStructureTree = exports.bytesToString = exports.patchOptionsWithManifest = exports.log = exports.sequence = exports.CancellationToken = exports.isCancelledError = exports.nonnull = exports.flatten = exports.chain = exports.normalize = exports.getPublicGalleryAPI = exports.getSecurityRolesAPI = exports.getGalleryAPI = exports.getHubUrl = exports.getMarketplaceUrl = exports.getPublishedUrl = exports.read = void 0;
7
30
  const util_1 = require("util");
31
+ const fs = __importStar(require("fs"));
8
32
  const read_1 = __importDefault(require("read"));
9
33
  const WebApi_1 = require("azure-devops-node-api/WebApi");
10
34
  const GalleryApi_1 = require("azure-devops-node-api/GalleryApi");
@@ -166,82 +190,169 @@ function patchOptionsWithManifest(options, manifest) {
166
190
  }
167
191
  }
168
192
  exports.patchOptionsWithManifest = patchOptionsWithManifest;
169
- function generateFileStructureTree(rootFolder, filePaths, maxPrint = Number.MAX_VALUE) {
193
+ function bytesToString(bytes) {
194
+ let size = 0;
195
+ let unit = '';
196
+ if (bytes > 1048576) {
197
+ size = Math.round(bytes / 10485.76) / 100;
198
+ unit = 'MB';
199
+ }
200
+ else {
201
+ size = Math.round(bytes / 10.24) / 100;
202
+ unit = 'KB';
203
+ }
204
+ return `${size} ${unit}`;
205
+ }
206
+ exports.bytesToString = bytesToString;
207
+ const FOLDER_SIZE_KEY = "/__FOlDER_SIZE__\\";
208
+ const FOLDER_FILES_TOTAL_KEY = "/__FOLDER_CHILDREN__\\";
209
+ const FILE_SIZE_WARNING_THRESHOLD = 0.85;
210
+ const FILE_SIZE_LARGE_THRESHOLD = 0.2;
211
+ async function generateFileStructureTree(rootFolder, filePaths, printLinesLimit = Number.MAX_VALUE) {
170
212
  const folderTree = {};
171
213
  const depthCounts = [];
172
214
  // Build a tree structure from the file paths
173
- filePaths.forEach(filePath => {
174
- const parts = filePath.split('/');
215
+ // Store the file size in the leaf node and the folder size in the folder node
216
+ // Store the number of children in the folder node
217
+ for (const filePath of filePaths) {
218
+ const parts = filePath.tree.split('/');
175
219
  let currentLevel = folderTree;
176
220
  parts.forEach((part, depth) => {
221
+ const isFile = depth === parts.length - 1;
222
+ // Create the node if it doesn't exist
177
223
  if (!currentLevel[part]) {
178
- currentLevel[part] = depth === parts.length - 1 ? null : {};
224
+ if (isFile) {
225
+ // The file size is stored in the leaf node,
226
+ currentLevel[part] = 0;
227
+ }
228
+ else {
229
+ // The folder size is stored in the folder node
230
+ currentLevel[part] = {};
231
+ currentLevel[part][FOLDER_SIZE_KEY] = 0;
232
+ currentLevel[part][FOLDER_FILES_TOTAL_KEY] = 0;
233
+ }
234
+ // Count the number of items at each depth
179
235
  if (depthCounts.length <= depth) {
180
236
  depthCounts.push(0);
181
237
  }
182
238
  depthCounts[depth]++;
183
239
  }
184
240
  currentLevel = currentLevel[part];
241
+ // Count the total number of children in the nested folders
242
+ if (!isFile) {
243
+ currentLevel[FOLDER_FILES_TOTAL_KEY]++;
244
+ }
185
245
  });
186
- });
187
- // Get max depth
246
+ }
247
+ ;
248
+ // Get max depth depending on the maximum number of lines allowed to print
188
249
  let currentDepth = 0;
189
- let countUpToCurrentDepth = depthCounts[0];
250
+ let countUpToCurrentDepth = depthCounts[0] + 1 /* root folder */;
190
251
  for (let i = 1; i < depthCounts.length; i++) {
191
- if (countUpToCurrentDepth + depthCounts[i] > maxPrint) {
252
+ if (countUpToCurrentDepth + depthCounts[i] > printLinesLimit) {
192
253
  break;
193
254
  }
194
255
  currentDepth++;
195
256
  countUpToCurrentDepth += depthCounts[i];
196
257
  }
197
258
  const maxDepth = currentDepth;
198
- let message = [];
199
- // Helper function to print the tree
200
- const printTree = (tree, depth, prefix) => {
259
+ // Get all file sizes
260
+ const fileSizes = await Promise.all(filePaths.map(async (filePath) => {
261
+ try {
262
+ const stats = await fs.promises.stat(filePath.origin);
263
+ return [stats.size, filePath.tree];
264
+ }
265
+ catch (error) {
266
+ return [0, filePath.origin];
267
+ }
268
+ }));
269
+ // Store all file sizes in the tree
270
+ let totalFileSizes = 0;
271
+ fileSizes.forEach(([size, filePath]) => {
272
+ totalFileSizes += size;
273
+ const parts = filePath.split('/');
274
+ let currentLevel = folderTree;
275
+ parts.forEach(part => {
276
+ if (typeof currentLevel[part] === 'number') {
277
+ currentLevel[part] = size;
278
+ }
279
+ else if (currentLevel[part]) {
280
+ currentLevel[part][FOLDER_SIZE_KEY] += size;
281
+ }
282
+ currentLevel = currentLevel[part];
283
+ });
284
+ });
285
+ let output = [];
286
+ output.push(chalk_1.default.bold(rootFolder));
287
+ output.push(...createTreeOutput(folderTree, maxDepth, totalFileSizes));
288
+ for (const [size, filePath] of fileSizes) {
289
+ if (size > FILE_SIZE_WARNING_THRESHOLD * totalFileSizes) {
290
+ output.push(`\nThe file ${filePath} is ${chalk_1.default.red('large')} (${bytesToString(size)})`);
291
+ break;
292
+ }
293
+ }
294
+ return output;
295
+ }
296
+ exports.generateFileStructureTree = generateFileStructureTree;
297
+ function createTreeOutput(fileSystem, maxDepth, totalFileSizes) {
298
+ const getColorFromSize = (size) => {
299
+ if (size > FILE_SIZE_WARNING_THRESHOLD * totalFileSizes) {
300
+ return chalk_1.default.red;
301
+ }
302
+ else if (size > FILE_SIZE_LARGE_THRESHOLD * totalFileSizes) {
303
+ return chalk_1.default.yellow;
304
+ }
305
+ else {
306
+ return chalk_1.default.grey;
307
+ }
308
+ };
309
+ const createFileOutput = (prefix, fileName, fileSize) => {
310
+ let fileSizeColored = '';
311
+ if (fileSize > 0) {
312
+ const fileSizeString = `[${bytesToString(fileSize)}]`;
313
+ fileSizeColored = getColorFromSize(fileSize)(fileSizeString);
314
+ }
315
+ return `${prefix}${fileName} ${fileSizeColored}`;
316
+ };
317
+ const createFolderOutput = (prefix, filesCount, folderSize, folderName, depth) => {
318
+ if (depth < maxDepth) {
319
+ // Max depth is not reached, print only the folder
320
+ // as children will be printed
321
+ return prefix + chalk_1.default.bold(`${folderName}/`);
322
+ }
323
+ // Max depth is reached, print the folder name and additional metadata
324
+ // as children will not be printed
325
+ const folderSizeString = bytesToString(folderSize);
326
+ const folder = chalk_1.default.bold(`${folderName}/`);
327
+ const numFilesString = chalk_1.default.green(`(${filesCount} ${filesCount === 1 ? 'file' : 'files'})`);
328
+ const folderSizeColored = getColorFromSize(folderSize)(`[${folderSizeString}]`);
329
+ return `${prefix}${folder} ${numFilesString} ${folderSizeColored}`;
330
+ };
331
+ const createTreeLayerOutput = (tree, depth, prefix, path) => {
201
332
  // Print all files before folders
202
- const sortedFolderKeys = Object.keys(tree).filter(key => tree[key] !== null).sort();
203
- const sortedFileKeys = Object.keys(tree).filter(key => tree[key] === null).sort();
204
- const sortedKeys = [...sortedFileKeys, ...sortedFolderKeys];
333
+ const sortedFolderKeys = Object.keys(tree).filter(key => typeof tree[key] !== 'number').sort();
334
+ const sortedFileKeys = Object.keys(tree).filter(key => typeof tree[key] === 'number').sort();
335
+ const sortedKeys = [...sortedFileKeys, ...sortedFolderKeys].filter(key => key !== FOLDER_SIZE_KEY && key !== FOLDER_FILES_TOTAL_KEY);
336
+ const output = [];
205
337
  for (let i = 0; i < sortedKeys.length; i++) {
206
338
  const key = sortedKeys[i];
207
339
  const isLast = i === sortedKeys.length - 1;
208
340
  const localPrefix = prefix + (isLast ? '└─ ' : '├─ ');
209
341
  const childPrefix = prefix + (isLast ? ' ' : '│ ');
210
- if (tree[key] === null) {
342
+ if (typeof tree[key] === 'number') {
211
343
  // It's a file
212
- message.push(localPrefix + key);
344
+ output.push(createFileOutput(localPrefix, key, tree[key]));
213
345
  }
214
346
  else {
215
347
  // It's a folder
348
+ output.push(createFolderOutput(localPrefix, tree[key][FOLDER_FILES_TOTAL_KEY], tree[key][FOLDER_SIZE_KEY], key, depth));
216
349
  if (depth < maxDepth) {
217
- // maxdepth is not reached, print the folder and its children
218
- message.push(localPrefix + chalk_1.default.bold(`${key}/`));
219
- printTree(tree[key], depth + 1, childPrefix);
350
+ output.push(...createTreeLayerOutput(tree[key], depth + 1, childPrefix, path + key + '/'));
220
351
  }
221
- else {
222
- // max depth is reached, print the folder but not its children
223
- const filesCount = countFiles(tree[key]);
224
- message.push(localPrefix + chalk_1.default.bold(`${key}/`) + chalk_1.default.green(` (${filesCount} ${filesCount === 1 ? 'file' : 'files'})`));
225
- }
226
- }
227
- }
228
- };
229
- // Helper function to count the number of files in a tree
230
- const countFiles = (tree) => {
231
- let filesCount = 0;
232
- for (const key in tree) {
233
- if (tree[key] === null) {
234
- filesCount++;
235
- }
236
- else {
237
- filesCount += countFiles(tree[key]);
238
352
  }
239
353
  }
240
- return filesCount;
354
+ return output;
241
355
  };
242
- message.push(chalk_1.default.bold(rootFolder));
243
- printTree(folderTree, 0, '');
244
- return message;
356
+ return createTreeLayerOutput(fileSystem, 0, '', '');
245
357
  }
246
- exports.generateFileStructureTree = generateFileStructureTree;
247
358
  //# sourceMappingURL=util.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vscode/vsce",
3
- "version": "2.30.0",
3
+ "version": "2.30.1-0",
4
4
  "description": "VS Code Extensions Manager",
5
5
  "repository": {
6
6
  "type": "git",