Files
vscode/extensions/terminal-suggest/scripts/update-specs.js
Matt Bierner 0249c2acf5 Fix terminal-suggest for esbuild
Missed that this extension was making `require` calls with dynamic names. I think the best approach is to convert it to use static imports instead. These files were already being loaded eagerly by `terminalSuggestMain` so it shouldn't be a big change

Also makes `update-specs.js` be the source of truth for the packages to include instead of pulling in from the extension
2026-02-18 23:47:32 -08:00

243 lines
4.8 KiB
JavaScript

/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// @ts-check
const fs = require('fs');
const path = require('path');
/** @type {string[]} */
const upstreamSpecs = [
'basename',
'cat',
'chmod',
'chown',
'clear',
'cp',
'curl',
'cut',
'date',
'dd',
'df',
'diff',
'dig',
'dirname',
'du',
'echo',
'env',
'export',
'fdisk',
'find',
'fmt',
'fold',
'grep',
'head',
'htop',
'id',
'jq',
'kill',
'killall',
'less',
'ln',
'ls',
'lsblk',
'lsof',
'mkdir',
'more',
'mount',
'mv',
'nl',
'od',
'paste',
'ping',
'pkill',
'ps',
'pwd',
'readlink',
'rm',
'rmdir',
'rsync',
'scp',
'sed',
'seq',
'shred',
'sort',
'source',
'split',
'stat',
'su',
'sudo',
'tac',
'tail',
'tar',
'tee',
'time',
'top',
'touch',
'tr',
'traceroute',
'tree',
'truncate',
'uname',
'uniq',
'unzip',
'wc',
'wget',
'where',
'whereis',
'which',
'who',
'xargs',
'xxd',
'zip',
// OS package management
'apt',
'brew',
// Editors
'nano',
'vim',
// Shells
'ssh',
// Android
'adb',
// Docker
'docker',
'docker-compose',
// Dotnet
'dotnet',
// Go
'go',
// JavaScript / TypeScript
'node',
'nvm',
'yo',
// Python
'python',
'python3',
'ruff',
// Ruby
'bundle',
'ruby',
];
const extRoot = path.resolve(path.join(__dirname, '..'));
const replaceStrings = [
[
'import { filepaths } from "@fig/autocomplete-generators";',
'import { filepaths } from \'../../helpers/filepaths\';'
],
[
'import { filepaths, keyValue } from "@fig/autocomplete-generators";',
'import { filepaths } from \'../../helpers/filepaths\'; import { keyValue } from \'../../helpers/keyvalue\';'
],
];
const indentSearch = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1].map(e => new RegExp('^' + ' '.repeat(e * 2), 'gm'));
const indentReplaceValue = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1].map(e => '\t'.repeat(e));
const specSpecificReplaceStrings = new Map([
['docker', [
[
'console.error(error);',
'console.error(error); return null!;'
]
]],
['dotnet', [
[
'.match(argRegex)',
'.match(argRegex)!'
], [
'"https://upload.wikimedia.org/wikipedia/commons/7/7d/Microsoft_.NET_logo.svg";',
'undefined;',
]
]],
['gh', [
[
'const parts = elm.match(/\\S+/g);',
'const parts = elm.match(/\\S+/g)!;'
],
[
'description: repo.description,',
'description: repo.description ?? undefined,'
],
[
'icon: "fig://icon?type=git"',
'icon: "vscode://icon?type=11"'
]
]],
['git', [
[
'import { ai } from "@fig/autocomplete-generators";',
'function ai(...args: any[]): undefined { return undefined; }'
], [
'prompt: async ({ executeCommand }) => {',
'prompt: async ({ executeCommand }: any) => {'
], [
'message: async ({ executeCommand }) =>',
'message: async ({ executeCommand }: any) =>'
]
]],
['yo', [
[
'icon: "https://avatars.githubusercontent.com/u/1714870?v=4",',
'icon: undefined,',
]
]],
]);
for (const spec of upstreamSpecs) {
const source = path.join(extRoot, `third_party/autocomplete/src/${spec}.ts`);
const destination = path.join(extRoot, `src/completions/upstream/${spec}.ts`);
fs.copyFileSync(source, destination);
let content = fs.readFileSync(destination).toString();
for (const replaceString of replaceStrings) {
content = content.replaceAll(replaceString[0], replaceString[1]);
}
for (let i = 0; i < indentSearch.length; i++) {
content = content.replaceAll(indentSearch[i], indentReplaceValue[i]);
}
const thisSpecReplaceStrings = specSpecificReplaceStrings.get(spec);
if (thisSpecReplaceStrings) {
for (const replaceString of thisSpecReplaceStrings) {
content = content.replaceAll(replaceString[0], replaceString[1]);
}
}
fs.writeFileSync(destination, content);
}
// Generate upstreamSpecs.ts with re-exports
function specToExportName(spec) {
return spec.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
}
function specToReExport(spec) {
return `export { default as ${specToExportName(spec)} } from './completions/upstream/${spec}';`;
}
const copyright = `/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/`;
const lines = [
copyright,
'',
'// This file is generated by scripts/update-specs.js',
...upstreamSpecs.map(specToReExport),
'',
];
fs.writeFileSync(path.join(extRoot, 'src/upstreamSpecs.ts'), lines.join('\n'));