chore(deps): update dependencies

To fix all security vulnerabilities detected by `Dependabot`.

 - remove `shelljs`. replace with `fs` and `console`.
 - remove `uuid`. replace with `@phosphor/coreutils`.

Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
Akos Kitta 2023-10-02 18:05:22 +02:00 committed by Akos Kitta
parent ed1cb6bcf9
commit 153e34f11b
17 changed files with 1473 additions and 2749 deletions

View File

@ -109,7 +109,7 @@
"devDependencies": {
"@octokit/rest": "^18.12.0",
"@types/chai": "^4.2.7",
"@types/mocha": "^5.2.7",
"@types/mocha": "^10.0.0",
"@types/react-window": "^1.8.5",
"@xhmikosr/downloader": "^13.0.1",
"chai": "^4.2.0",
@ -118,18 +118,15 @@
"decompress-tarbz2": "^4.1.1",
"decompress-targz": "^4.1.1",
"decompress-unzip": "^4.0.1",
"grpc_tools_node_protoc_ts": "^4.1.0",
"mocha": "^7.0.0",
"grpc_tools_node_protoc_ts": "^5.3.3",
"mocha": "^10.2.0",
"mockdate": "^3.0.5",
"moment": "^2.24.0",
"ncp": "^2.0.0",
"rimraf": "^2.6.1",
"shelljs": "^0.8.3",
"uuid": "^3.2.1",
"yargs": "^11.1.0"
"rimraf": "^2.6.1"
},
"optionalDependencies": {
"grpc-tools": "^1.9.0",
"grpc-tools": "^1.12.4",
"protoc": "^1.0.4"
},
"mocha": {

View File

@ -2,7 +2,6 @@
(async () => {
const path = require('path');
const shell = require('shelljs');
const semver = require('semver');
const moment = require('moment');
const downloader = require('./downloader');
@ -29,8 +28,8 @@
})();
if (!version) {
shell.echo(`Could not retrieve CLI version info from the 'package.json'.`);
shell.exit(1);
console.log(`Could not retrieve CLI version info from the 'package.json'.`);
process.exit(1);
}
const { platform, arch } = process;
@ -71,24 +70,24 @@
}
})();
if (!suffix) {
shell.echo(`The CLI is not available for ${platform} ${arch}.`);
shell.exit(1);
console.log(`The CLI is not available for ${platform} ${arch}.`);
process.exit(1);
}
if (semver.valid(version)) {
const url = `https://downloads.arduino.cc/arduino-cli/arduino-cli_${version}_${suffix}`;
shell.echo(
console.log(
`📦 Identified released version of the CLI. Downloading version ${version} from '${url}'`
);
await downloader.downloadUnzipFile(url, destinationPath, 'arduino-cli');
} else if (moment(version, 'YYYYMMDD', true).isValid()) {
const url = `https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-${version}_${suffix}`;
shell.echo(
console.log(
`🌙 Identified nightly version of the CLI. Downloading version ${version} from '${url}'`
);
await downloader.downloadUnzipFile(url, destinationPath, 'arduino-cli');
} else {
shell.echo(`🔥 Could not interpret 'version': ${version}`);
shell.exit(1);
console.log(`🔥 Could not interpret 'version': ${version}`);
process.exit(1);
}
} else {
taskBuildFromGit(version, destinationPath, 'CLI');

View File

@ -5,10 +5,14 @@ const version = '1.10.0';
(async () => {
const os = require('node:os');
const { existsSync, promises: fs } = require('node:fs');
const {
existsSync,
promises: fs,
mkdirSync,
readdirSync,
cpSync,
} = require('node:fs');
const path = require('node:path');
const shell = require('shelljs');
const { v4 } = require('uuid');
const { exec } = require('./utils');
const destination = path.join(
@ -20,31 +24,38 @@ const version = '1.10.0';
'Examples'
);
if (existsSync(destination)) {
shell.echo(
console.log(
`Skipping Git checkout of the examples because the repository already exists: ${destination}`
);
return;
}
const repository = path.join(os.tmpdir(), `${v4()}-arduino-examples`);
if (shell.mkdir('-p', repository).code !== 0) {
shell.exit(1);
}
const repository = await fs.mkdtemp(
path.join(os.tmpdir(), 'arduino-examples-')
);
exec(
'git',
['clone', 'https://github.com/arduino/arduino-examples.git', repository],
shell
{ logStdout: true }
);
exec(
'git',
['-C', repository, 'checkout', `tags/${version}`, '-b', version],
shell
{ logStdout: true }
);
shell.mkdir('-p', destination);
shell.cp('-fR', path.join(repository, 'examples', '*'), destination);
mkdirSync(destination, { recursive: true });
const examplesPath = path.join(repository, 'examples');
const exampleResources = readdirSync(examplesPath);
for (const exampleResource of exampleResources) {
cpSync(
path.join(examplesPath, exampleResource),
path.join(destination, exampleResource),
{ recursive: true }
);
}
const isSketch = async (pathLike) => {
try {
@ -104,5 +115,5 @@ const version = '1.10.0';
JSON.stringify(examples, null, 2),
{ encoding: 'utf8' }
);
shell.echo(`Generated output to ${path.join(destination, 'examples.json')}`);
console.log(`Generated output to ${path.join(destination, 'examples.json')}`);
})();

View File

@ -2,7 +2,6 @@
(async () => {
const path = require('node:path');
const shell = require('shelljs');
const semver = require('semver');
const downloader = require('./downloader');
const { taskBuildFromGit } = require('./utils');
@ -28,10 +27,10 @@
})();
if (!version) {
shell.echo(
console.log(
`Could not retrieve Firmware Uploader version info from the 'package.json'.`
);
shell.exit(1);
process.exit(1);
}
const { platform, arch } = process;
@ -71,14 +70,14 @@
}
})();
if (!suffix) {
shell.echo(
console.log(
`The Firmware Uploader is not available for ${platform} ${arch}.`
);
shell.exit(1);
process.exit(1);
}
if (semver.valid(version)) {
const url = `https://downloads.arduino.cc/arduino-fwuploader/arduino-fwuploader_${version}_${suffix}`;
shell.echo(
console.log(
`📦 Identified released version of the Firmware Uploader. Downloading version ${version} from '${url}'`
);
await downloader.downloadUnzipFile(
@ -87,8 +86,8 @@
'arduino-fwuploader'
);
} else {
shell.echo(`🔥 Could not interpret 'version': ${version}`);
shell.exit(1);
console.log(`🔥 Could not interpret 'version': ${version}`);
process.exit(1);
}
} else {
taskBuildFromGit(version, destinationPath, 'Firmware Uploader');

View File

@ -5,7 +5,6 @@
(() => {
const path = require('path');
const shell = require('shelljs');
const downloader = require('./downloader');
const { goBuildFromGit } = require('./utils');
@ -25,20 +24,20 @@
})();
if (!DEFAULT_LS_VERSION) {
shell.echo(
console.log(
`Could not retrieve Arduino Language Server version info from the 'package.json'.`
);
shell.exit(1);
process.exit(1);
}
if (!DEFAULT_CLANGD_VERSION) {
shell.echo(
console.log(
`Could not retrieve clangd version info from the 'package.json'.`
);
shell.exit(1);
process.exit(1);
}
const yargs = require('yargs')
const yargs = require('@theia/core/shared/yargs')
.option('ls-version', {
alias: 'lv',
default: DEFAULT_LS_VERSION,
@ -114,10 +113,10 @@
throw new Error(`Unsupported platform/arch: ${platformArch}.`);
}
if (!lsSuffix || !clangdSuffix) {
shell.echo(
console.log(
`The arduino-language-server is not available for ${platform} ${arch}.`
);
shell.exit(1);
process.exit(1);
}
if (typeof lsVersion === 'string') {

View File

@ -1,20 +1,19 @@
// @ts-check
const fs = require('fs');
const path = require('path');
const shell = require('shelljs');
const decompress = require('decompress');
const unzip = require('decompress-unzip');
const untargz = require('decompress-targz');
const untarbz2 = require('decompress-tarbz2');
process.on('unhandledRejection', (reason, _) => {
shell.echo(String(reason));
shell.exit(1);
throw reason;
process.on('unhandledRejection', (reason) => {
console.log(String(reason));
process.exit(1);
});
process.on('uncaughtException', (error) => {
shell.echo(String(error));
shell.exit(1);
throw error;
console.log(String(error));
process.exit(1);
});
/**
@ -30,55 +29,42 @@ exports.downloadUnzipFile = async (
force = false
) => {
if (fs.existsSync(targetFile) && !force) {
shell.echo(`Skipping download because file already exists: ${targetFile}`);
console.log(`Skipping download because file already exists: ${targetFile}`);
return;
}
if (!fs.existsSync(path.dirname(targetFile))) {
if (shell.mkdir('-p', path.dirname(targetFile)).code !== 0) {
shell.echo('Could not create new directory.');
shell.exit(1);
}
}
fs.mkdirSync(path.dirname(targetFile), { recursive: true });
const downloads = path.join(__dirname, '..', 'downloads');
if (shell.rm('-rf', targetFile, downloads).code !== 0) {
shell.exit(1);
}
fs.rmSync(targetFile, { recursive: true, force: true });
fs.rmSync(downloads, { recursive: true, force: true });
shell.echo(`>>> Downloading from '${url}'...`);
const { default: download } = await import('@xhmikosr/downloader');
console.log(`>>> Downloading from '${url}'...`);
const data = await download(url);
shell.echo(`<<< Download succeeded.`);
console.log(`<<< Download succeeded.`);
shell.echo('>>> Decompressing...');
console.log('>>> Decompressing...');
const files = await decompress(data, downloads, {
plugins: [unzip(), untargz(), untarbz2()],
});
if (files.length === 0) {
shell.echo('Error ocurred while decompressing the archive.');
shell.exit(1);
console.log('Error ocurred while decompressing the archive.');
process.exit(1);
}
const fileIndex = files.findIndex((f) => f.path.startsWith(filePrefix));
if (fileIndex === -1) {
shell.echo(
console.log(
`The downloaded artifact does not contain any file with prefix ${filePrefix}.`
);
shell.exit(1);
process.exit(1);
}
shell.echo('<<< Decompressing succeeded.');
console.log('<<< Decompressing succeeded.');
if (
shell.mv('-f', path.join(downloads, files[fileIndex].path), targetFile)
.code !== 0
) {
shell.echo(`Could not move file to target path: ${targetFile}`);
shell.exit(1);
}
fs.renameSync(path.join(downloads, files[fileIndex].path), targetFile);
if (!fs.existsSync(targetFile)) {
shell.echo(`Could not find file: ${targetFile}`);
shell.exit(1);
console.log(`Could not find file: ${targetFile}`);
process.exit(1);
}
shell.echo(`Done: ${targetFile}`);
console.log(`Done: ${targetFile}`);
};
/**
@ -86,7 +72,7 @@ exports.downloadUnzipFile = async (
* @param targetDir {string} Directory into which to decompress the archive
* @param targetFile {string} Path to the main file expected after decompressing
* @param force {boolean} Whether to download even if the target file exists
* @param decompressOptions {import('decompress').DecompressOptions}
* @param decompressOptions {import('decompress').DecompressOptions|undefined} [decompressOptions]
*/
exports.downloadUnzipAll = async (
url,
@ -96,22 +82,16 @@ exports.downloadUnzipAll = async (
decompressOptions = undefined
) => {
if (fs.existsSync(targetFile) && !force) {
shell.echo(`Skipping download because file already exists: ${targetFile}`);
console.log(`Skipping download because file already exists: ${targetFile}`);
return;
}
if (!fs.existsSync(targetDir)) {
if (shell.mkdir('-p', targetDir).code !== 0) {
shell.echo('Could not create new directory.');
shell.exit(1);
}
}
fs.mkdirSync(targetDir, { recursive: true });
shell.echo(`>>> Downloading from '${url}'...`);
const { default: download } = await import('@xhmikosr/downloader');
console.log(`>>> Downloading from '${url}'...`);
const data = await download(url);
shell.echo(`<<< Download succeeded.`);
console.log(`<<< Download succeeded.`);
shell.echo('>>> Decompressing...');
console.log('>>> Decompressing...');
let options = {
plugins: [unzip(), untargz(), untarbz2()],
};
@ -120,14 +100,27 @@ exports.downloadUnzipAll = async (
}
const files = await decompress(data, targetDir, options);
if (files.length === 0) {
shell.echo('Error ocurred while decompressing the archive.');
shell.exit(1);
console.log('Error ocurred while decompressing the archive.');
process.exit(1);
}
shell.echo('<<< Decompressing succeeded.');
console.log('<<< Decompressing succeeded.');
if (!fs.existsSync(targetFile)) {
shell.echo(`Could not find file: ${targetFile}`);
shell.exit(1);
console.log(`Could not find file: ${targetFile}`);
process.exit(1);
}
shell.echo(`Done: ${targetFile}`);
console.log(`Done: ${targetFile}`);
};
/**
* @param {string} url
* @returns {Promise<import('node:buffer').Buffer>}
*/
async function download(url) {
const { default: download } = await import('@xhmikosr/downloader');
/** @type {import('node:buffer').Buffer} */
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const data = await download(url);
return data;
}

View File

@ -3,22 +3,18 @@
(async () => {
const os = require('node:os');
const path = require('node:path');
const { mkdirSync, promises: fs } = require('node:fs');
const { exec } = require('./utils');
const glob = require('glob');
const { v4 } = require('uuid');
const shell = require('shelljs');
const protoc = path.dirname(require('protoc/protoc'));
const repository = path.join(os.tmpdir(), `${v4()}-arduino-cli`);
if (shell.mkdir('-p', repository).code !== 0) {
shell.exit(1);
}
const repository = await fs.mkdtemp(path.join(os.tmpdir(), 'arduino-cli-'));
const { owner, repo, commitish } = (() => {
const pkg = require(path.join(__dirname, '..', 'package.json'));
if (!pkg) {
shell.echo(`Could not parse the 'package.json'.`);
shell.exit(1);
console.log(`Could not parse the 'package.json'.`);
process.exit(1);
}
const defaultVersion = {
@ -48,21 +44,21 @@
// We assume an object with `owner`, `repo`, commitish?` properties.
const { owner, repo, commitish } = version;
if (!owner) {
shell.echo(`Could not retrieve 'owner' from ${JSON.stringify(version)}`);
shell.exit(1);
console.log(`Could not retrieve 'owner' from ${JSON.stringify(version)}`);
process.exit(1);
}
if (!repo) {
shell.echo(`Could not retrieve 'repo' from ${JSON.stringify(version)}`);
shell.exit(1);
console.log(`Could not retrieve 'repo' from ${JSON.stringify(version)}`);
process.exit(1);
}
return { owner, repo, commitish };
})();
const url = `https://github.com/${owner}/${repo}.git`;
shell.echo(`>>> Cloning repository from '${url}'...`);
exec('git', ['clone', url, repository], shell);
shell.echo(`<<< Repository cloned.`);
console.log(`>>> Cloning repository from '${url}'...`);
exec('git', ['clone', url, repository], { logStdout: true });
console.log(`<<< Repository cloned.`);
const { platform } = process;
const resourcesFolder = path.join(
@ -76,10 +72,12 @@
resourcesFolder,
`arduino-cli${platform === 'win32' ? '.exe' : ''}`
);
const versionJson = exec(cli, ['version', '--format', 'json'], shell).trim();
const versionJson = exec(cli, ['version', '--format', 'json'], {
logStdout: true,
}).trim();
if (!versionJson) {
shell.echo(`Could not retrieve the CLI version from ${cli}.`);
shell.exit(1);
console.log(`Could not retrieve the CLI version from ${cli}.`);
process.exit(1);
}
// As of today (28.01.2021), the `VersionString` can be one of the followings:
// - `nightly-YYYYMMDD` stands for the nightly build, we use the , the `commitish` from the `package.json` to check out the code.
@ -103,45 +101,51 @@
version !== '0.0.0-git' &&
version !== 'git-snapshot'
) {
shell.echo(`>>> Checking out tagged version: '${version}'...`);
exec('git', ['-C', repository, 'fetch', '--all', '--tags'], shell);
console.log(`>>> Checking out tagged version: '${version}'...`);
exec('git', ['-C', repository, 'fetch', '--all', '--tags'], {
logStdout: true,
});
exec(
'git',
['-C', repository, 'checkout', `tags/${version}`, '-b', version],
shell
{ logStdout: true }
);
shell.echo(`<<< Checked out tagged version: '${version}'.`);
console.log(`<<< Checked out tagged version: '${version}'.`);
} else if (commitish) {
shell.echo(
console.log(
`>>> Checking out commitish from 'package.json': '${commitish}'...`
);
exec('git', ['-C', repository, 'checkout', commitish], shell);
shell.echo(
exec('git', ['-C', repository, 'checkout', commitish], { logStdout: true });
console.log(
`<<< Checked out commitish from 'package.json': '${commitish}'.`
);
} else if (versionObject.Commit) {
shell.echo(
console.log(
`>>> Checking out commitish from the CLI: '${versionObject.Commit}'...`
);
exec('git', ['-C', repository, 'checkout', versionObject.Commit], shell);
shell.echo(
exec('git', ['-C', repository, 'checkout', versionObject.Commit], {
logStdout: true,
});
console.log(
`<<< Checked out commitish from the CLI: '${versionObject.Commit}'.`
);
} else {
shell.echo(`WARN: no 'git checkout'. Generating from the HEAD revision.`);
console.log(`WARN: no 'git checkout'. Generating from the HEAD revision.`);
}
shell.echo('>>> Generating TS/JS API from:');
exec('git', ['-C', repository, 'rev-parse', '--abbrev-ref', 'HEAD'], shell);
console.log('>>> Generating TS/JS API from:');
exec('git', ['-C', repository, 'rev-parse', '--abbrev-ref', 'HEAD'], {
logStdout: true,
});
const rpc = path.join(repository, 'rpc');
const out = path.join(__dirname, '..', 'src', 'node', 'cli-protocol');
shell.mkdir('-p', out);
mkdirSync(out, { recursive: true });
const protos = await new Promise((resolve) =>
glob('**/*.proto', { cwd: rpc }, (error, matches) => {
if (error) {
shell.echo(error.stack ?? error.message);
console.log(error.stack ?? error.message);
resolve([]);
return;
}
@ -149,12 +153,11 @@
})
);
if (!protos || protos.length === 0) {
shell.echo(`Could not find any .proto files under ${rpc}.`);
shell.exit(1);
console.log(`Could not find any .proto files under ${rpc}.`);
process.exit(1);
}
// Generate JS code from the `.proto` files.
exec(
'grpc_tools_node_protoc',
[
@ -164,7 +167,7 @@
rpc,
...protos,
],
shell
{ logStdout: true }
);
// Generate the `.d.ts` files for JS.
@ -183,8 +186,8 @@
rpc,
...protos,
],
shell
{ logStdout: true }
);
shell.echo('<<< Generation was successful.');
console.log('<<< Generation was successful.');
})();

View File

@ -3,24 +3,21 @@
const exec = (
/** @type {string} */ command,
/** @type {readonly string[]} */ args,
/** @type {import('shelljs')|undefined}*/ shell = undefined,
/** @type {import('node:child_process').ExecFileSyncOptionsWithStringEncoding|undefined} */ options = undefined
/** @type {Partial<import('node:child_process').ExecFileSyncOptionsWithStringEncoding> & { logStdout?: boolean }|undefined} */ options = undefined
) => {
try {
const stdout = require('node:child_process').execFileSync(
command,
args,
options ? options : { encoding: 'utf8' }
);
if (shell) {
shell.echo(stdout.trim());
const stdout = require('node:child_process').execFileSync(command, args, {
encoding: 'utf8',
...(options ?? {}),
});
if (options?.logStdout) {
console.log(stdout.trim());
}
return stdout;
} catch (err) {
if (shell) {
shell.echo(err instanceof Error ? err.message : String(err));
shell.exit(1);
}
console.log(
`Failed to execute ${command} with args: ${JSON.stringify(args)}`
);
throw err;
}
};
@ -59,32 +56,31 @@ function buildFromGit(command, version, destinationPath, taskName) {
const fs = require('node:fs');
const path = require('node:path');
const temp = require('temp');
const shell = require('shelljs');
// We assume an object with `owner`, `repo`, commitish?` properties.
if (typeof version !== 'object') {
shell.echo(
console.log(
`Expected a \`{ owner, repo, commitish }\` object. Got <${version}> instead.`
);
}
const { owner, repo, commitish } = version;
if (!owner) {
shell.echo(`Could not retrieve 'owner' from ${JSON.stringify(version)}`);
shell.exit(1);
console.log(`Could not retrieve 'owner' from ${JSON.stringify(version)}`);
process.exit(1);
}
if (!repo) {
shell.echo(`Could not retrieve 'repo' from ${JSON.stringify(version)}`);
shell.exit(1);
console.log(`Could not retrieve 'repo' from ${JSON.stringify(version)}`);
process.exit(1);
}
const url = `https://github.com/${owner}/${repo}.git`;
shell.echo(
console.log(
`Building ${taskName} from ${url}. Commitish: ${
commitish ? commitish : 'HEAD'
}`
);
if (fs.existsSync(destinationPath)) {
shell.echo(
console.log(
`Skipping the ${taskName} build because it already exists: ${destinationPath}`
);
return;
@ -97,48 +93,51 @@ function buildFromGit(command, version, destinationPath, taskName) {
'node',
'resources'
);
if (shell.mkdir('-p', resourcesFolder).code !== 0) {
shell.echo('Could not create resources folder.');
shell.exit(1);
}
fs.mkdirSync(resourcesFolder, { recursive: true });
const tempRepoPath = temp.mkdirSync();
shell.echo(`>>> Cloning ${taskName} source to ${tempRepoPath}...`);
exec('git', ['clone', url, tempRepoPath], shell);
shell.echo(`<<< Cloned ${taskName} repo.`);
console.log(`>>> Cloning ${taskName} source to ${tempRepoPath}...`);
exec('git', ['clone', url, tempRepoPath], { logStdout: true });
console.log(`<<< Cloned ${taskName} repo.`);
if (commitish) {
shell.echo(`>>> Checking out ${commitish}...`);
exec('git', ['-C', tempRepoPath, 'checkout', commitish], shell);
shell.echo(`<<< Checked out ${commitish}.`);
console.log(`>>> Checking out ${commitish}...`);
exec('git', ['-C', tempRepoPath, 'checkout', commitish], {
logStdout: true,
});
console.log(`<<< Checked out ${commitish}.`);
}
exec('git', ['-C', tempRepoPath, 'rev-parse', '--short', 'HEAD'], shell);
exec('git', ['-C', tempRepoPath, 'rev-parse', '--short', 'HEAD'], {
logStdout: true,
});
shell.echo(`>>> Building the ${taskName}...`);
exec(command, ['build'], shell, { cwd: tempRepoPath, encoding: 'utf8' });
shell.echo(`<<< Done ${taskName} build.`);
console.log(`>>> Building the ${taskName}...`);
exec(command, ['build'], {
cwd: tempRepoPath,
encoding: 'utf8',
logStdout: true,
});
console.log(`<<< Done ${taskName} build.`);
const binName = path.basename(destinationPath);
if (!fs.existsSync(path.join(tempRepoPath, binName))) {
shell.echo(
console.log(
`Could not find the ${taskName} at ${path.join(tempRepoPath, binName)}.`
);
shell.exit(1);
process.exit(1);
}
const binPath = path.join(tempRepoPath, binName);
shell.echo(
console.log(
`>>> Copying ${taskName} from ${binPath} to ${destinationPath}...`
);
if (shell.cp(binPath, destinationPath).code !== 0) {
shell.exit(1);
}
shell.echo(`<<< Copied the ${taskName}.`);
fs.copyFileSync(binPath, destinationPath);
console.log(`<<< Copied the ${taskName}.`);
shell.echo(`<<< Verifying ${taskName}...`);
console.log(`<<< Verifying ${taskName}...`);
if (!fs.existsSync(destinationPath)) {
shell.exit(1);
process.exit(1);
}
shell.echo(`>>> Verified ${taskName}.`);
console.log(`>>> Verified ${taskName}.`);
}

View File

@ -1,4 +1,3 @@
import { MaybePromise } from '@theia/core';
import { Dialog, DialogError } from '@theia/core/lib/browser/dialogs';
import { LabelProvider } from '@theia/core/lib/browser/label-provider';
import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
@ -10,13 +9,14 @@ import type {
Progress,
ProgressUpdate,
} from '@theia/core/lib/common/message-service-protocol';
import type { MaybePromise } from '@theia/core/lib/common/types';
import { UUID } from '@theia/core/shared/@phosphor/coreutils';
import { Widget } from '@theia/core/shared/@phosphor/widgets';
import { inject } from '@theia/core/shared/inversify';
import {
WorkspaceInputDialog as TheiaWorkspaceInputDialog,
WorkspaceInputDialogProps,
} from '@theia/workspace/lib/browser/workspace-input-dialog';
import { v4 } from 'uuid';
export class WorkspaceInputDialog extends TheiaWorkspaceInputDialog {
private skipShowErrorMessageOnOpen: boolean;
@ -161,7 +161,7 @@ export class WorkspaceInputDialogWithProgress<
const cancellationSource = new CancellationTokenSource();
const progress: Progress = {
id: v4(),
id: UUID.uuid4(),
cancel: () => cancellationSource.cancel(),
report: (update: ProgressUpdate) => {
this.setProgressMessage(update);

View File

@ -7,7 +7,7 @@ import {
CHANNEL_REQUEST_RELOAD,
MenuDto,
} from '@theia/core/lib/electron-common/electron-api';
import { v4 } from 'uuid';
import { UUID } from '@theia/core/shared/@phosphor/coreutils';
import type { Sketch } from '../common/protocol/sketches-service';
import {
CHANNEL_APP_INFO,
@ -43,7 +43,7 @@ function convertMenu(
}
return menu.map((item) => {
let nodeId = v4();
let nodeId = UUID.uuid4();
if (item.execute) {
if (!item.id) {
throw new Error(

View File

@ -9,9 +9,9 @@ import { deepClone } from '@theia/core/lib/common/objects';
import { Deferred } from '@theia/core/lib/common/promise-util';
import type { Mutable } from '@theia/core/lib/common/types';
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
import { UUID } from '@theia/core/shared/@phosphor/coreutils';
import { inject, injectable, named } from '@theia/core/shared/inversify';
import { isDeepStrictEqual } from 'util';
import { v4 } from 'uuid';
import { Unknown } from '../common/nls';
import {
Board,
@ -168,7 +168,7 @@ export class BoardDiscovery
});
const wrapper = {
stream,
uuid: v4(),
uuid: UUID.uuid4(),
dispose: () => {
this.logger.info('disposing requesting cancel');
// Cancelling the stream will kill the discovery `builtin:mdns-discovery process`.

View File

@ -420,6 +420,29 @@ export namespace LoadSketchRequest {
}
}
export class SketchProfile extends jspb.Message {
getName(): string;
setName(value: string): SketchProfile;
getFqbn(): string;
setFqbn(value: string): SketchProfile;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): SketchProfile.AsObject;
static toObject(includeInstance: boolean, msg: SketchProfile): SketchProfile.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: SketchProfile, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): SketchProfile;
static deserializeBinaryFromReader(message: SketchProfile, reader: jspb.BinaryReader): SketchProfile;
}
export namespace SketchProfile {
export type AsObject = {
name: string,
fqbn: string,
}
}
export class LoadSketchResponse extends jspb.Message {
getMainFile(): string;
setMainFile(value: string): LoadSketchResponse;
@ -443,6 +466,15 @@ export class LoadSketchResponse extends jspb.Message {
setDefaultPort(value: string): LoadSketchResponse;
getDefaultProtocol(): string;
setDefaultProtocol(value: string): LoadSketchResponse;
clearProfilesList(): void;
getProfilesList(): Array<SketchProfile>;
setProfilesList(value: Array<SketchProfile>): LoadSketchResponse;
addProfiles(value?: SketchProfile, index?: number): SketchProfile;
hasDefaultProfile(): boolean;
clearDefaultProfile(): void;
getDefaultProfile(): SketchProfile | undefined;
setDefaultProfile(value?: SketchProfile): LoadSketchResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): LoadSketchResponse.AsObject;
@ -464,6 +496,8 @@ export namespace LoadSketchResponse {
defaultFqbn: string,
defaultPort: string,
defaultProtocol: string,
profilesList: Array<SketchProfile.AsObject>,
defaultProfile?: SketchProfile.AsObject,
}
}

View File

@ -55,6 +55,7 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchRequest', null, glo
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchResponse', null, global);
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest', null, global);
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse', null, global);
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SketchProfile', null, global);
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateIndexRequest', null, global);
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateIndexResponse', null, global);
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UpdateLibrariesIndexRequest', null, global);
@ -418,6 +419,27 @@ if (goog.DEBUG && !COMPILED) {
*/
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.displayName = 'proto.cc.arduino.cli.commands.v1.LoadSketchRequest';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
* server response, or constructed directly in Javascript. The array is used
* in place and becomes part of the constructed object. It is not cloned.
* If no data is provided, the constructed object will be empty, but still
* valid.
* @extends {jspb.Message}
* @constructor
*/
proto.cc.arduino.cli.commands.v1.SketchProfile = function(opt_data) {
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
};
goog.inherits(proto.cc.arduino.cli.commands.v1.SketchProfile, jspb.Message);
if (goog.DEBUG && !COMPILED) {
/**
* @public
* @override
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.displayName = 'proto.cc.arduino.cli.commands.v1.SketchProfile';
}
/**
* Generated by JsPbCodeGenerator.
* @param {Array=} opt_data Optional initial data array, typically from a
@ -3196,12 +3218,172 @@ proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.setSketchPath = fun
if (jspb.Message.GENERATE_TO_OBJECT) {
/**
* Creates an object representation of this proto.
* Field names that are reserved in JavaScript and will be renamed to pb_name.
* Optional fields that are not set will be set to undefined.
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
* For the list of reserved names please see:
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
* JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @return {!Object}
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.toObject = function(opt_includeInstance) {
return proto.cc.arduino.cli.commands.v1.SketchProfile.toObject(opt_includeInstance, this);
};
/**
* Static version of the {@see toObject} method.
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
* the JSPB instance for transitional soy proto support:
* http://goto/soy-param-migration
* @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} msg The msg instance to transform.
* @return {!Object}
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.toObject = function(includeInstance, msg) {
var f, obj = {
name: jspb.Message.getFieldWithDefault(msg, 1, ""),
fqbn: jspb.Message.getFieldWithDefault(msg, 2, "")
};
if (includeInstance) {
obj.$jspbMessageInstance = msg;
}
return obj;
};
}
/**
* Deserializes binary data (in protobuf wire format).
* @param {jspb.ByteSource} bytes The bytes to deserialize.
* @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinary = function(bytes) {
var reader = new jspb.BinaryReader(bytes);
var msg = new proto.cc.arduino.cli.commands.v1.SketchProfile;
return proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader(msg, reader);
};
/**
* Deserializes binary data (in protobuf wire format) from the
* given reader into the given message object.
* @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} msg The message object to deserialize into.
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
* @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader = function(msg, reader) {
while (reader.nextField()) {
if (reader.isEndGroup()) {
break;
}
var field = reader.getFieldNumber();
switch (field) {
case 1:
var value = /** @type {string} */ (reader.readString());
msg.setName(value);
break;
case 2:
var value = /** @type {string} */ (reader.readString());
msg.setFqbn(value);
break;
default:
reader.skipField();
break;
}
}
return msg;
};
/**
* Serializes the message to binary data (in protobuf wire format).
* @return {!Uint8Array}
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.serializeBinary = function() {
var writer = new jspb.BinaryWriter();
proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter(this, writer);
return writer.getResultBuffer();
};
/**
* Serializes the given message to binary data (in protobuf wire
* format), writing to the given BinaryWriter.
* @param {!proto.cc.arduino.cli.commands.v1.SketchProfile} message
* @param {!jspb.BinaryWriter} writer
* @suppress {unusedLocalVariables} f is only used for nested messages
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter = function(message, writer) {
var f = undefined;
f = message.getName();
if (f.length > 0) {
writer.writeString(
1,
f
);
}
f = message.getFqbn();
if (f.length > 0) {
writer.writeString(
2,
f
);
}
};
/**
* optional string name = 1;
* @return {string}
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.getName = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
};
/**
* @param {string} value
* @return {!proto.cc.arduino.cli.commands.v1.SketchProfile} returns this
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.setName = function(value) {
return jspb.Message.setProto3StringField(this, 1, value);
};
/**
* optional string fqbn = 2;
* @return {string}
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.getFqbn = function() {
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
};
/**
* @param {string} value
* @return {!proto.cc.arduino.cli.commands.v1.SketchProfile} returns this
*/
proto.cc.arduino.cli.commands.v1.SketchProfile.prototype.setFqbn = function(value) {
return jspb.Message.setProto3StringField(this, 2, value);
};
/**
* List of repeated fields within this message type.
* @private {!Array<number>}
* @const
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.repeatedFields_ = [3,4,5];
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.repeatedFields_ = [3,4,5,9];
@ -3241,7 +3423,10 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.toObject = function(includeI
rootFolderFilesList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f,
defaultFqbn: jspb.Message.getFieldWithDefault(msg, 6, ""),
defaultPort: jspb.Message.getFieldWithDefault(msg, 7, ""),
defaultProtocol: jspb.Message.getFieldWithDefault(msg, 8, "")
defaultProtocol: jspb.Message.getFieldWithDefault(msg, 8, ""),
profilesList: jspb.Message.toObjectList(msg.getProfilesList(),
proto.cc.arduino.cli.commands.v1.SketchProfile.toObject, includeInstance),
defaultProfile: (f = msg.getDefaultProfile()) && proto.cc.arduino.cli.commands.v1.SketchProfile.toObject(includeInstance, f)
};
if (includeInstance) {
@ -3310,6 +3495,16 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.deserializeBinaryFromReader
var value = /** @type {string} */ (reader.readString());
msg.setDefaultProtocol(value);
break;
case 9:
var value = new proto.cc.arduino.cli.commands.v1.SketchProfile;
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader);
msg.addProfiles(value);
break;
case 10:
var value = new proto.cc.arduino.cli.commands.v1.SketchProfile;
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.SketchProfile.deserializeBinaryFromReader);
msg.setDefaultProfile(value);
break;
default:
reader.skipField();
break;
@ -3395,6 +3590,22 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.serializeBinaryToWriter = fu
f
);
}
f = message.getProfilesList();
if (f.length > 0) {
writer.writeRepeatedMessage(
9,
f,
proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter
);
}
f = message.getDefaultProfile();
if (f != null) {
writer.writeMessage(
10,
f,
proto.cc.arduino.cli.commands.v1.SketchProfile.serializeBinaryToWriter
);
}
};
@ -3599,6 +3810,81 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultProtocol
};
/**
* repeated SketchProfile profiles = 9;
* @return {!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>}
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getProfilesList = function() {
return /** @type{!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>} */ (
jspb.Message.getRepeatedWrapperField(this, proto.cc.arduino.cli.commands.v1.SketchProfile, 9));
};
/**
* @param {!Array<!proto.cc.arduino.cli.commands.v1.SketchProfile>} value
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setProfilesList = function(value) {
return jspb.Message.setRepeatedWrapperField(this, 9, value);
};
/**
* @param {!proto.cc.arduino.cli.commands.v1.SketchProfile=} opt_value
* @param {number=} opt_index
* @return {!proto.cc.arduino.cli.commands.v1.SketchProfile}
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.addProfiles = function(opt_value, opt_index) {
return jspb.Message.addToRepeatedWrapperField(this, 9, opt_value, proto.cc.arduino.cli.commands.v1.SketchProfile, opt_index);
};
/**
* Clears the list making it empty but non-null.
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearProfilesList = function() {
return this.setProfilesList([]);
};
/**
* optional SketchProfile default_profile = 10;
* @return {?proto.cc.arduino.cli.commands.v1.SketchProfile}
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultProfile = function() {
return /** @type{?proto.cc.arduino.cli.commands.v1.SketchProfile} */ (
jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.SketchProfile, 10));
};
/**
* @param {?proto.cc.arduino.cli.commands.v1.SketchProfile|undefined} value
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultProfile = function(value) {
return jspb.Message.setWrapperField(this, 10, value);
};
/**
* Clears the message field making it undefined.
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearDefaultProfile = function() {
return this.setDefaultProfile(undefined);
};
/**
* Returns whether this field is set.
* @return {boolean}
*/
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.hasDefaultProfile = function() {
return jspb.Message.getField(this, 10) != null;
};

View File

@ -1,5 +1,5 @@
import { v4 } from 'uuid';
import {
import { UUID } from '@theia/core/shared/@phosphor/coreutils';
import type {
IndexType,
IndexUpdateDidCompleteParams,
IndexUpdateDidFailParams,
@ -16,10 +16,10 @@ import {
} from './cli-protocol/cc/arduino/cli/commands/v1/commands_pb';
import {
DownloadProgress,
TaskProgress,
DownloadProgressEnd,
DownloadProgressStart,
DownloadProgressUpdate,
DownloadProgressEnd,
TaskProgress,
} from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
import { CompileResponse } from './cli-protocol/cc/arduino/cli/commands/v1/compile_pb';
import {
@ -170,7 +170,7 @@ export namespace ExecuteWithProgress {
progressId,
reportResult,
}: ExecuteWithProgress.Options): (response: R) => void {
const uuid = v4();
const uuid = UUID.uuid4();
let message = '';
let url = '';
return (response: R) => {
@ -330,7 +330,7 @@ export class IndexesUpdateProgressHandler {
onComplete?: (params: IndexUpdateDidCompleteParams) => void;
}
) {
this.progressId = v4();
this.progressId = UUID.uuid4();
this.results = [];
this.total = IndexesUpdateProgressHandler.total(types, additionalUrlsCount);
// Note: at this point, the IDE2 backend might not have any connected clients, so this notification is not delivered to anywhere

View File

@ -1,3 +1,4 @@
import { UUID } from '@theia/core/shared/@phosphor/coreutils';
import {
Container,
ContainerModule,
@ -9,7 +10,6 @@ import { rejects } from 'node:assert';
import { posix } from 'node:path';
import PQueue from 'p-queue';
import queryString from 'query-string';
import { v4 } from 'uuid';
import { ArduinoPreferences } from '../../browser/arduino-preferences';
import { AuthenticationClientService } from '../../browser/auth/authentication-client-service';
import { CreateApi } from '../../browser/create/create-api';
@ -145,7 +145,7 @@ describe('create-api', () => {
}
it('should delete sketch', async () => {
const name = v4();
const name = UUID.uuid4();
const content = 'alma\nkorte';
const posixPath = toPosix(name);
@ -185,8 +185,8 @@ describe('create-api', () => {
});
it('should rename a sketch folder with all its content', async () => {
const name = v4();
const newName = v4();
const name = UUID.uuid4();
const newName = UUID.uuid4();
const content = 'void setup(){} void loop(){}';
const posixPath = toPosix(name);
const newPosixPath = toPosix(newName);
@ -214,8 +214,8 @@ describe('create-api', () => {
});
it('should error with HTTP 409 (Conflict) when renaming a sketch and the target already exists', async () => {
const name = v4();
const otherName = v4();
const name = UUID.uuid4();
const otherName = UUID.uuid4();
const content = 'void setup(){} void loop(){}';
const posixPath = toPosix(name);
const otherPosixPath = toPosix(otherName);
@ -243,7 +243,7 @@ describe('create-api', () => {
});
it('should error with HTTP 422 when reading a file but is a directory', async () => {
const name = v4();
const name = UUID.uuid4();
const content = 'void setup(){} void loop(){}';
const posixPath = toPosix(name);
@ -257,7 +257,7 @@ describe('create-api', () => {
});
it('should error with HTTP 422 when listing a directory but is a file', async () => {
const name = v4();
const name = UUID.uuid4();
const content = 'void setup(){} void loop(){}';
const posixPath = toPosix(name);
@ -272,7 +272,7 @@ describe('create-api', () => {
});
it("should error with HTTP 404 when deleting a non-existing directory via the '/files/d' endpoint", async () => {
const name = v4();
const name = UUID.uuid4();
const posixPath = toPosix(name);
const sketches = await createApi.sketches();
@ -316,7 +316,7 @@ describe('create-api', () => {
});
it("should fetch the sketch when transforming the 'secrets' into '#include' and the sketch is not in the cache", async () => {
const name = v4();
const name = UUID.uuid4();
const posixPath = toPosix(name);
const newSketch = await createApi.createSketch(
posixPath,
@ -359,7 +359,9 @@ describe('create-api', () => {
const content = 'void setup(){} void loop(){}';
const maxLimit = 10;
const sketchCount = maxLimit + diff;
const sketchNames = [...Array(sketchCount).keys()].map(() => v4());
const sketchNames = [...Array(sketchCount).keys()].map(() =>
UUID.uuid4()
);
const createExecutionQueue = new PQueue({
concurrency: 5,

View File

@ -28,7 +28,7 @@
"compression-webpack-plugin": "^9.0.0",
"copy-webpack-plugin": "^8.1.1",
"dateformat": "^5.0.3",
"electron": "^25.5.0",
"electron": "^26.2.4",
"electron-builder": "^24.6.3",
"electron-notarize": "^1.1.1",
"execa": "^7.1.1",

3476
yarn.lock

File diff suppressed because it is too large Load Diff