mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-04-19 12:57:17 +00:00
feat: simplify board and port handling (#2165)
Use Arduino CLI revision `38479dc`
Closes #43
Closes #82
Closes #1319
Closes #1366
Closes #2143
Closes #2158
Ref: 38479dc706
Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
9a6a457bc4
commit
69ae38effa
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@ -94,6 +94,13 @@
|
||||
"--colors",
|
||||
"**/${fileBasenameNoExtension}.js"
|
||||
],
|
||||
"outFiles": [
|
||||
"${workspaceRoot}/electron-app/src-gen/backend/*.js",
|
||||
"${workspaceRoot}/electron-app/src-gen/frontend/*.js",
|
||||
"${workspaceRoot}/electron-app/lib/**/*.js",
|
||||
"${workspaceRoot}/arduino-ide-extension/lib/**/*.js",
|
||||
"${workspaceRoot}/node_modules/@theia/**/*.js"
|
||||
],
|
||||
"env": {
|
||||
"TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json",
|
||||
"IDE2_TEST": "true"
|
||||
|
@ -123,14 +123,14 @@
|
||||
"mockdate": "^3.0.5",
|
||||
"moment": "^2.24.0",
|
||||
"ncp": "^2.0.0",
|
||||
"protoc": "^1.0.4",
|
||||
"rimraf": "^2.6.1",
|
||||
"shelljs": "^0.8.3",
|
||||
"uuid": "^3.2.1",
|
||||
"yargs": "^11.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"grpc-tools": "^1.9.0"
|
||||
"grpc-tools": "^1.9.0",
|
||||
"protoc": "^1.0.4"
|
||||
},
|
||||
"mocha": {
|
||||
"require": [
|
||||
@ -172,10 +172,14 @@
|
||||
],
|
||||
"arduino": {
|
||||
"arduino-cli": {
|
||||
"version": "0.33.1"
|
||||
"version": {
|
||||
"owner": "arduino",
|
||||
"repo": "arduino-cli",
|
||||
"commitish": "38479dc"
|
||||
}
|
||||
},
|
||||
"arduino-fwuploader": {
|
||||
"version": "2.2.2"
|
||||
"version": "2.3.0"
|
||||
},
|
||||
"arduino-language-server": {
|
||||
"version": "0.7.4"
|
||||
|
@ -113,6 +113,8 @@ function buildFromGit(command, version, destinationPath, taskName) {
|
||||
shell.echo(`<<< Checked out ${commitish}.`);
|
||||
}
|
||||
|
||||
exec('git', ['-C', tempRepoPath, 'rev-parse', '--short', 'HEAD'], shell);
|
||||
|
||||
shell.echo(`>>> Building the ${taskName}...`);
|
||||
exec(command, ['build'], shell, { cwd: tempRepoPath, encoding: 'utf8' });
|
||||
shell.echo(`<<< Done ${taskName} build.`);
|
||||
|
@ -27,7 +27,10 @@ import { SketchesServiceClientImpl } from './sketches-service-client-impl';
|
||||
import { CoreService, CoreServicePath } from '../common/protocol/core-service';
|
||||
import { BoardsListWidget } from './boards/boards-list-widget';
|
||||
import { BoardsListWidgetFrontendContribution } from './boards/boards-widget-frontend-contribution';
|
||||
import { BoardsServiceProvider } from './boards/boards-service-provider';
|
||||
import {
|
||||
BoardListDumper,
|
||||
BoardsServiceProvider,
|
||||
} from './boards/boards-service-provider';
|
||||
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||
import { WorkspaceService } from './theia/workspace/workspace-service';
|
||||
import { OutlineViewContribution as TheiaOutlineViewContribution } from '@theia/outline-view/lib/browser/outline-view-contribution';
|
||||
@ -61,7 +64,6 @@ import {
|
||||
BoardsConfigDialog,
|
||||
BoardsConfigDialogProps,
|
||||
} from './boards/boards-config-dialog';
|
||||
import { BoardsConfigDialogWidget } from './boards/boards-config-dialog-widget';
|
||||
import { ScmContribution as TheiaScmContribution } from '@theia/scm/lib/browser/scm-contribution';
|
||||
import { ScmContribution } from './theia/scm/scm-contribution';
|
||||
import { SearchInWorkspaceFrontendContribution as TheiaSearchInWorkspaceFrontendContribution } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
|
||||
@ -100,7 +102,7 @@ import {
|
||||
FrontendConnectionStatusService as TheiaFrontendConnectionStatusService,
|
||||
ApplicationConnectionStatusContribution as TheiaApplicationConnectionStatusContribution,
|
||||
} from '@theia/core/lib/browser/connection-status-service';
|
||||
import { BoardsDataMenuUpdater } from './boards/boards-data-menu-updater';
|
||||
import { BoardsDataMenuUpdater } from './contributions/boards-data-menu-updater';
|
||||
import { BoardsDataStore } from './boards/boards-data-store';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
|
||||
@ -208,7 +210,6 @@ import {
|
||||
MonacoEditorFactory,
|
||||
MonacoEditorProvider as TheiaMonacoEditorProvider,
|
||||
} from '@theia/monaco/lib/browser/monaco-editor-provider';
|
||||
import { StorageWrapper } from './storage-wrapper';
|
||||
import { NotificationManager } from './theia/messages/notifications-manager';
|
||||
import { NotificationManager as TheiaNotificationManager } from '@theia/messages/lib/browser/notifications-manager';
|
||||
import { NotificationsRenderer as TheiaNotificationsRenderer } from '@theia/messages/lib/browser/notifications-renderer';
|
||||
@ -445,11 +446,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(BoardsServiceProvider).toSelf().inSingletonScope();
|
||||
bind(FrontendApplicationContribution).toService(BoardsServiceProvider);
|
||||
bind(CommandContribution).toService(BoardsServiceProvider);
|
||||
bind(BoardListDumper).toSelf().inSingletonScope();
|
||||
|
||||
// To be able to track, and update the menu based on the core settings (aka. board details) of the currently selected board.
|
||||
bind(FrontendApplicationContribution)
|
||||
.to(BoardsDataMenuUpdater)
|
||||
.inSingletonScope();
|
||||
bind(BoardsDataStore).toSelf().inSingletonScope();
|
||||
bind(FrontendApplicationContribution).toService(BoardsDataStore);
|
||||
// Logger for the Arduino daemon
|
||||
@ -478,7 +477,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(OpenHandler).toService(BoardsListWidgetFrontendContribution);
|
||||
|
||||
// Board select dialog
|
||||
bind(BoardsConfigDialogWidget).toSelf().inSingletonScope();
|
||||
bind(BoardsConfigDialog).toSelf().inSingletonScope();
|
||||
bind(BoardsConfigDialogProps).toConstantValue({
|
||||
title: nls.localize(
|
||||
@ -751,6 +749,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
Contribution.configure(bind, CloudSketchbookContribution);
|
||||
Contribution.configure(bind, CreateCloudCopy);
|
||||
Contribution.configure(bind, UpdateArduinoState);
|
||||
Contribution.configure(bind, BoardsDataMenuUpdater);
|
||||
|
||||
bindContributionProvider(bind, StartupTaskProvider);
|
||||
bind(StartupTaskProvider).toService(BoardsServiceProvider); // to reuse the boards config in another window
|
||||
@ -879,9 +878,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
),
|
||||
});
|
||||
|
||||
bind(StorageWrapper).toSelf().inSingletonScope();
|
||||
bind(CommandContribution).toService(StorageWrapper);
|
||||
|
||||
bind(NotificationManager).toSelf().inSingletonScope();
|
||||
rebind(TheiaNotificationManager).toService(NotificationManager);
|
||||
bind(NotificationsRenderer).toSelf().inSingletonScope();
|
||||
|
@ -1,281 +1,229 @@
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
||||
import {
|
||||
BoardsService,
|
||||
BoardsPackage,
|
||||
Board,
|
||||
Port,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { BoardsServiceProvider } from './boards-service-provider';
|
||||
import { Installable, ResponseServiceClient } from '../../common/protocol';
|
||||
import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-contribution';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import { MessageType } from '@theia/core/lib/common/message-service-protocol';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { notEmpty } from '@theia/core/lib/common/objects';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { NotificationManager } from '@theia/messages/lib/browser/notifications-manager';
|
||||
import { InstallManually } from '../../common/nls';
|
||||
|
||||
interface AutoInstallPromptAction {
|
||||
// isAcceptance, whether or not the action indicates acceptance of auto-install proposal
|
||||
isAcceptance?: boolean;
|
||||
key: string;
|
||||
handler: (...args: unknown[]) => unknown;
|
||||
}
|
||||
|
||||
type AutoInstallPromptActions = AutoInstallPromptAction[];
|
||||
import { Installable, ResponseServiceClient } from '../../common/protocol';
|
||||
import {
|
||||
BoardIdentifier,
|
||||
BoardsPackage,
|
||||
BoardsService,
|
||||
createPlatformIdentifier,
|
||||
isBoardIdentifierChangeEvent,
|
||||
PlatformIdentifier,
|
||||
platformIdentifierEquals,
|
||||
serializePlatformIdentifier,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { BoardsServiceProvider } from './boards-service-provider';
|
||||
import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-contribution';
|
||||
|
||||
/**
|
||||
* Listens on `BoardsConfig.Config` changes, if a board is selected which does not
|
||||
* Listens on `BoardsConfigChangeEvent`s, if a board is selected which does not
|
||||
* have the corresponding core installed, it proposes the user to install the core.
|
||||
*/
|
||||
|
||||
// * Cases in which we do not show the auto-install prompt:
|
||||
// 1. When a related platform is already installed
|
||||
// 2. When a prompt is already showing in the UI
|
||||
// 3. When a board is unplugged
|
||||
@injectable()
|
||||
export class BoardsAutoInstaller implements FrontendApplicationContribution {
|
||||
@inject(NotificationCenter)
|
||||
private readonly notificationCenter: NotificationCenter;
|
||||
|
||||
@inject(MessageService)
|
||||
protected readonly messageService: MessageService;
|
||||
|
||||
private readonly messageService: MessageService;
|
||||
@inject(NotificationManager)
|
||||
private readonly notificationManager: NotificationManager;
|
||||
@inject(BoardsService)
|
||||
protected readonly boardsService: BoardsService;
|
||||
|
||||
private readonly boardsService: BoardsService;
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
@inject(ResponseServiceClient)
|
||||
protected readonly responseService: ResponseServiceClient;
|
||||
|
||||
private readonly responseService: ResponseServiceClient;
|
||||
@inject(BoardsListWidgetFrontendContribution)
|
||||
protected readonly boardsManagerFrontendContribution: BoardsListWidgetFrontendContribution;
|
||||
private readonly boardsManagerWidgetContribution: BoardsListWidgetFrontendContribution;
|
||||
|
||||
// Workaround for https://github.com/eclipse-theia/theia/issues/9349
|
||||
protected notifications: Board[] = [];
|
||||
|
||||
// * "refusal" meaning a "prompt action" not accepting the auto-install offer ("X" or "install manually")
|
||||
// we can use "portSelectedOnLastRefusal" to deduce when a board is unplugged after a user has "refused"
|
||||
// an auto-install prompt. Important to know as we do not want "an unplug" to trigger a "refused" prompt
|
||||
// showing again
|
||||
private portSelectedOnLastRefusal: Port | undefined;
|
||||
private lastRefusedPackageId: string | undefined;
|
||||
private readonly installNotificationInfos: Readonly<{
|
||||
boardName: string;
|
||||
platformId: string;
|
||||
notificationId: string;
|
||||
}>[] = [];
|
||||
private readonly toDispose = new DisposableCollection();
|
||||
|
||||
onStart(): void {
|
||||
const setEventListeners = () => {
|
||||
this.boardsServiceClient.onBoardsConfigChanged((config) => {
|
||||
const { selectedBoard, selectedPort } = config;
|
||||
|
||||
const boardWasUnplugged =
|
||||
!selectedPort && this.portSelectedOnLastRefusal;
|
||||
|
||||
this.clearLastRefusedPromptInfo();
|
||||
|
||||
if (
|
||||
boardWasUnplugged ||
|
||||
!selectedBoard ||
|
||||
this.promptAlreadyShowingForBoard(selectedBoard)
|
||||
) {
|
||||
return;
|
||||
this.toDispose.pushAll([
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
|
||||
if (isBoardIdentifierChangeEvent(event)) {
|
||||
this.ensureCoreExists(event.selectedBoard);
|
||||
}
|
||||
|
||||
this.ensureCoreExists(selectedBoard, selectedPort);
|
||||
});
|
||||
|
||||
// we "clearRefusedPackageInfo" if a "refused" package is eventually
|
||||
// installed, though this is not strictly necessary. It's more of a
|
||||
// cleanup, to ensure the related variables are representative of
|
||||
// current state.
|
||||
this.notificationCenter.onPlatformDidInstall((installed) => {
|
||||
if (this.lastRefusedPackageId === installed.item.id) {
|
||||
this.clearLastRefusedPromptInfo();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// we should invoke this.ensureCoreExists only once we're sure
|
||||
// everything has been reconciled
|
||||
this.boardsServiceClient.reconciled.then(() => {
|
||||
const { selectedBoard, selectedPort } =
|
||||
this.boardsServiceClient.boardsConfig;
|
||||
|
||||
if (selectedBoard) {
|
||||
this.ensureCoreExists(selectedBoard, selectedPort);
|
||||
}
|
||||
|
||||
setEventListeners();
|
||||
}),
|
||||
this.notificationCenter.onPlatformDidInstall((event) =>
|
||||
this.clearAllNotificationForPlatform(event.item.id)
|
||||
),
|
||||
]);
|
||||
this.boardsServiceProvider.ready.then(() => {
|
||||
const { selectedBoard } = this.boardsServiceProvider.boardsConfig;
|
||||
this.ensureCoreExists(selectedBoard);
|
||||
});
|
||||
}
|
||||
|
||||
private removeNotificationByBoard(selectedBoard: Board): void {
|
||||
const index = this.notifications.findIndex((notification) =>
|
||||
Board.sameAs(notification, selectedBoard)
|
||||
);
|
||||
if (index !== -1) {
|
||||
this.notifications.splice(index, 1);
|
||||
private async findPlatformToInstall(
|
||||
selectedBoard: BoardIdentifier
|
||||
): Promise<BoardsPackage | undefined> {
|
||||
const platformId = await this.findPlatformIdToInstall(selectedBoard);
|
||||
if (!platformId) {
|
||||
return undefined;
|
||||
}
|
||||
const id = serializePlatformIdentifier(platformId);
|
||||
const platform = await this.boardsService.getBoardPackage({ id });
|
||||
if (!platform) {
|
||||
console.warn(`Could not resolve platform for ID: ${id}`);
|
||||
return undefined;
|
||||
}
|
||||
if (platform.installedVersion) {
|
||||
return undefined;
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
|
||||
private clearLastRefusedPromptInfo(): void {
|
||||
this.lastRefusedPackageId = undefined;
|
||||
this.portSelectedOnLastRefusal = undefined;
|
||||
}
|
||||
|
||||
private setLastRefusedPromptInfo(
|
||||
packageId: string,
|
||||
selectedPort?: Port
|
||||
): void {
|
||||
this.lastRefusedPackageId = packageId;
|
||||
this.portSelectedOnLastRefusal = selectedPort;
|
||||
}
|
||||
|
||||
private promptAlreadyShowingForBoard(board: Board): boolean {
|
||||
return Boolean(
|
||||
this.notifications.find((notification) =>
|
||||
Board.sameAs(notification, board)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected ensureCoreExists(selectedBoard: Board, selectedPort?: Port): void {
|
||||
this.notifications.push(selectedBoard);
|
||||
this.boardsService.search({}).then((packages) => {
|
||||
const candidate = this.getInstallCandidate(packages, selectedBoard);
|
||||
|
||||
if (candidate) {
|
||||
this.showAutoInstallPrompt(candidate, selectedBoard, selectedPort);
|
||||
} else {
|
||||
this.removeNotificationByBoard(selectedBoard);
|
||||
private async findPlatformIdToInstall(
|
||||
selectedBoard: BoardIdentifier
|
||||
): Promise<PlatformIdentifier | undefined> {
|
||||
const selectedBoardPlatformId = createPlatformIdentifier(selectedBoard);
|
||||
// The board is installed or the FQBN is available from the `board list watch` for Arduino boards. The latter might change!
|
||||
if (selectedBoardPlatformId) {
|
||||
const installedPlatforms =
|
||||
await this.boardsService.getInstalledPlatforms();
|
||||
const installedPlatformIds = installedPlatforms
|
||||
.map((platform) => createPlatformIdentifier(platform.id))
|
||||
.filter(notEmpty);
|
||||
if (
|
||||
installedPlatformIds.every(
|
||||
(installedPlatformId) =>
|
||||
!platformIdentifierEquals(
|
||||
installedPlatformId,
|
||||
selectedBoardPlatformId
|
||||
)
|
||||
)
|
||||
) {
|
||||
return selectedBoardPlatformId;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// IDE2 knows that selected board is not installed. Look for board `name` match in not yet installed platforms.
|
||||
// The order should be correct when there is a board name collision (e.g. Arduino Nano RP2040 from Arduino Mbed OS Nano Boards, [DEPRECATED] Arduino Mbed OS Nano Boards). The CLI boosts the platforms, so picking the first name match should be fine.
|
||||
const platforms = await this.boardsService.search({});
|
||||
for (const platform of platforms) {
|
||||
// Ignore installed platforms
|
||||
if (platform.installedVersion) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
platform.boards.some((board) => board.name === selectedBoard.name)
|
||||
) {
|
||||
const platformId = createPlatformIdentifier(platform.id);
|
||||
if (platformId) {
|
||||
return platformId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getInstallCandidate(
|
||||
packages: BoardsPackage[],
|
||||
selectedBoard: Board
|
||||
): BoardsPackage | undefined {
|
||||
// filter packagesForBoard selecting matches from the cli (installed packages)
|
||||
// and matches based on the board name
|
||||
// NOTE: this ensures the Deprecated & new packages are all in the array
|
||||
// so that we can check if any of the valid packages is already installed
|
||||
const packagesForBoard = packages.filter(
|
||||
(pkg) =>
|
||||
BoardsPackage.contains(selectedBoard, pkg) ||
|
||||
pkg.boards.some((board) => board.name === selectedBoard.name)
|
||||
);
|
||||
|
||||
// check if one of the packages for the board is already installed. if so, no hint
|
||||
if (packagesForBoard.some(({ installedVersion }) => !!installedVersion)) {
|
||||
private async ensureCoreExists(
|
||||
selectedBoard: BoardIdentifier | undefined
|
||||
): Promise<void> {
|
||||
if (!selectedBoard) {
|
||||
return;
|
||||
}
|
||||
const candidate = await this.findPlatformToInstall(selectedBoard);
|
||||
if (!candidate) {
|
||||
return;
|
||||
}
|
||||
const platformIdToInstall = candidate.id;
|
||||
const selectedBoardName = selectedBoard.name;
|
||||
if (
|
||||
this.installNotificationInfos.some(
|
||||
({ boardName, platformId }) =>
|
||||
platformIdToInstall === platformId && selectedBoardName === boardName
|
||||
)
|
||||
) {
|
||||
// Already has a notification for the board with the same platform. Nothing to do.
|
||||
return;
|
||||
}
|
||||
this.clearAllNotificationForPlatform(platformIdToInstall);
|
||||
|
||||
// filter the installable (not installed) packages,
|
||||
// CLI returns the packages already sorted with the deprecated ones at the end of the list
|
||||
// in order to ensure the new ones are preferred
|
||||
const candidates = packagesForBoard.filter(
|
||||
({ installedVersion }) => !installedVersion
|
||||
);
|
||||
|
||||
return candidates[0];
|
||||
}
|
||||
|
||||
private showAutoInstallPrompt(
|
||||
candidate: BoardsPackage,
|
||||
selectedBoard: Board,
|
||||
selectedPort?: Port
|
||||
): void {
|
||||
const candidateName = candidate.name;
|
||||
const version = candidate.availableVersions[0]
|
||||
? `[v ${candidate.availableVersions[0]}]`
|
||||
: '';
|
||||
|
||||
const info = this.generatePromptInfoText(
|
||||
candidateName,
|
||||
const yes = nls.localize('vscode/extensionsUtils/yes', 'Yes');
|
||||
const message = nls.localize(
|
||||
'arduino/board/installNow',
|
||||
'The "{0} {1}" core has to be installed for the currently selected "{2}" board. Do you want to install it now?',
|
||||
candidate.name,
|
||||
version,
|
||||
selectedBoard.name
|
||||
);
|
||||
|
||||
const actions = this.createPromptActions(candidate);
|
||||
|
||||
const onRefuse = () => {
|
||||
this.setLastRefusedPromptInfo(candidate.id, selectedPort);
|
||||
};
|
||||
const handleAction = this.createOnAnswerHandler(actions, onRefuse);
|
||||
|
||||
const onAnswer = (answer: string) => {
|
||||
this.removeNotificationByBoard(selectedBoard);
|
||||
|
||||
handleAction(answer);
|
||||
};
|
||||
|
||||
this.messageService
|
||||
.info(info, ...actions.map((action) => action.key))
|
||||
.then(onAnswer);
|
||||
}
|
||||
|
||||
private generatePromptInfoText(
|
||||
candidateName: string,
|
||||
version: string,
|
||||
boardName: string
|
||||
): string {
|
||||
return nls.localize(
|
||||
'arduino/board/installNow',
|
||||
'The "{0} {1}" core has to be installed for the currently selected "{2}" board. Do you want to install it now?',
|
||||
candidateName,
|
||||
version,
|
||||
boardName
|
||||
const notificationId = this.notificationId(message, InstallManually, yes);
|
||||
this.installNotificationInfos.push({
|
||||
boardName: selectedBoardName,
|
||||
platformId: platformIdToInstall,
|
||||
notificationId,
|
||||
});
|
||||
const answer = await this.messageService.info(
|
||||
message,
|
||||
InstallManually,
|
||||
yes
|
||||
);
|
||||
}
|
||||
|
||||
private createPromptActions(
|
||||
candidate: BoardsPackage
|
||||
): AutoInstallPromptActions {
|
||||
const yes = nls.localize('vscode/extensionsUtils/yes', 'Yes');
|
||||
|
||||
const actions: AutoInstallPromptActions = [
|
||||
{
|
||||
key: InstallManually,
|
||||
handler: () => {
|
||||
this.boardsManagerFrontendContribution
|
||||
.openView({ reveal: true })
|
||||
.then((widget) =>
|
||||
widget.refresh({
|
||||
query: candidate.name.toLocaleLowerCase(),
|
||||
type: 'All',
|
||||
})
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
isAcceptance: true,
|
||||
key: yes,
|
||||
handler: () => {
|
||||
return Installable.installWithProgress({
|
||||
installable: this.boardsService,
|
||||
item: candidate,
|
||||
messageService: this.messageService,
|
||||
responseService: this.responseService,
|
||||
version: candidate.availableVersions[0],
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
private createOnAnswerHandler(
|
||||
actions: AutoInstallPromptActions,
|
||||
onRefuse?: () => void
|
||||
): (answer: string) => void {
|
||||
return (answer) => {
|
||||
const actionToHandle = actions.find((action) => action.key === answer);
|
||||
actionToHandle?.handler();
|
||||
|
||||
if (!actionToHandle?.isAcceptance && onRefuse) {
|
||||
onRefuse();
|
||||
if (answer) {
|
||||
const index = this.installNotificationInfos.findIndex(
|
||||
({ boardName, platformId }) =>
|
||||
platformIdToInstall === platformId && selectedBoardName === boardName
|
||||
);
|
||||
if (index !== -1) {
|
||||
this.installNotificationInfos.splice(index, 1);
|
||||
}
|
||||
};
|
||||
if (answer === yes) {
|
||||
await Installable.installWithProgress({
|
||||
installable: this.boardsService,
|
||||
item: candidate,
|
||||
messageService: this.messageService,
|
||||
responseService: this.responseService,
|
||||
version: candidate.availableVersions[0],
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (answer === InstallManually) {
|
||||
this.boardsManagerWidgetContribution
|
||||
.openView({ reveal: true })
|
||||
.then((widget) =>
|
||||
widget.refresh({
|
||||
query: candidate.name.toLocaleLowerCase(),
|
||||
type: 'All',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private clearAllNotificationForPlatform(predicatePlatformId: string): void {
|
||||
// Discard all install notifications for the same platform.
|
||||
const notificationsLength = this.installNotificationInfos.length;
|
||||
for (let i = notificationsLength - 1; i >= 0; i--) {
|
||||
const { notificationId, platformId } = this.installNotificationInfos[i];
|
||||
if (platformId === predicatePlatformId) {
|
||||
this.installNotificationInfos.splice(i, 1);
|
||||
this.notificationManager.clear(notificationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private notificationId(message: string, ...actions: string[]): string {
|
||||
return this.notificationManager['getMessageId']({
|
||||
text: message,
|
||||
actions,
|
||||
type: MessageType.Info,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,328 @@
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { Event } from '@theia/core/lib/common/event';
|
||||
import { FrontendApplicationState } from '@theia/core/lib/common/frontend-application-state';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import React from '@theia/core/shared/react';
|
||||
import { EditBoardsConfigActionParams } from '../../common/protocol/board-list';
|
||||
import {
|
||||
Board,
|
||||
BoardIdentifier,
|
||||
BoardWithPackage,
|
||||
DetectedPort,
|
||||
findMatchingPortIndex,
|
||||
Port,
|
||||
PortIdentifier,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import type { Defined } from '../../common/types';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { BoardsConfigDialogState } from './boards-config-dialog';
|
||||
|
||||
namespace BoardsConfigComponent {
|
||||
export interface Props {
|
||||
/**
|
||||
* This is not the real config, it's only living in the dialog. Users can change it without update and can cancel any modifications.
|
||||
*/
|
||||
readonly boardsConfig: BoardsConfigDialogState;
|
||||
readonly searchSet: BoardIdentifier[] | undefined;
|
||||
readonly notificationCenter: NotificationCenter;
|
||||
readonly appState: FrontendApplicationState;
|
||||
readonly onFocusNodeSet: (element: HTMLElement | undefined) => void;
|
||||
readonly onFilteredTextDidChangeEvent: Event<
|
||||
Defined<EditBoardsConfigActionParams['query']>
|
||||
>;
|
||||
readonly onAppStateDidChange: Event<FrontendApplicationState>;
|
||||
readonly onBoardSelected: (board: BoardIdentifier) => void;
|
||||
readonly onPortSelected: (port: PortIdentifier) => void;
|
||||
readonly searchBoards: (query?: {
|
||||
query?: string;
|
||||
}) => Promise<BoardWithPackage[]>;
|
||||
readonly ports: (
|
||||
predicate?: (port: DetectedPort) => boolean
|
||||
) => readonly DetectedPort[];
|
||||
}
|
||||
|
||||
export interface State {
|
||||
searchResults: Array<BoardWithPackage>;
|
||||
showAllPorts: boolean;
|
||||
query: string;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Item<T> extends React.Component<{
|
||||
item: T;
|
||||
label: string;
|
||||
selected: boolean;
|
||||
onClick: (item: T) => void;
|
||||
missing?: boolean;
|
||||
details?: string;
|
||||
}> {
|
||||
override render(): React.ReactNode {
|
||||
const { selected, label, missing, details } = this.props;
|
||||
const classNames = ['item'];
|
||||
if (selected) {
|
||||
classNames.push('selected');
|
||||
}
|
||||
if (missing === true) {
|
||||
classNames.push('missing');
|
||||
}
|
||||
return (
|
||||
<div
|
||||
onClick={this.onClick}
|
||||
className={classNames.join(' ')}
|
||||
title={`${label}${!details ? '' : details}`}
|
||||
>
|
||||
<div className="label">{label}</div>
|
||||
{!details ? '' : <div className="details">{details}</div>}
|
||||
{!selected ? (
|
||||
''
|
||||
) : (
|
||||
<div className="selected-icon">
|
||||
<i className="fa fa-check" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private readonly onClick = () => {
|
||||
this.props.onClick(this.props.item);
|
||||
};
|
||||
}
|
||||
|
||||
export class BoardsConfigComponent extends React.Component<
|
||||
BoardsConfigComponent.Props,
|
||||
BoardsConfigComponent.State
|
||||
> {
|
||||
private readonly toDispose: DisposableCollection;
|
||||
|
||||
constructor(props: BoardsConfigComponent.Props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
searchResults: [],
|
||||
showAllPorts: false,
|
||||
query: '',
|
||||
};
|
||||
this.toDispose = new DisposableCollection();
|
||||
}
|
||||
|
||||
override componentDidMount(): void {
|
||||
this.toDispose.pushAll([
|
||||
this.props.onAppStateDidChange(async (state) => {
|
||||
if (state === 'ready') {
|
||||
const searchResults = await this.queryBoards({});
|
||||
this.setState({ searchResults });
|
||||
}
|
||||
}),
|
||||
this.props.notificationCenter.onPlatformDidInstall(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onPlatformDidUninstall(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onIndexUpdateDidComplete(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onDaemonDidStart(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onDaemonDidStop(() =>
|
||||
this.setState({ searchResults: [] })
|
||||
),
|
||||
this.props.onFilteredTextDidChangeEvent((query) => {
|
||||
if (typeof query === 'string') {
|
||||
this.setState({ query }, () => this.updateBoards(this.state.query));
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
override componentWillUnmount(): void {
|
||||
this.toDispose.dispose();
|
||||
}
|
||||
|
||||
private readonly updateBoards = (
|
||||
eventOrQuery: React.ChangeEvent<HTMLInputElement> | string = ''
|
||||
) => {
|
||||
const query =
|
||||
typeof eventOrQuery === 'string'
|
||||
? eventOrQuery
|
||||
: eventOrQuery.target.value.toLowerCase();
|
||||
this.setState({ query });
|
||||
this.queryBoards({ query }).then((searchResults) =>
|
||||
this.setState({ searchResults })
|
||||
);
|
||||
};
|
||||
|
||||
private readonly queryBoards = async (
|
||||
options: { query?: string } = {}
|
||||
): Promise<Array<BoardWithPackage>> => {
|
||||
const result = await this.props.searchBoards(options);
|
||||
const { searchSet } = this.props;
|
||||
if (searchSet) {
|
||||
return result.filter((board) =>
|
||||
searchSet.some(
|
||||
(restriction) =>
|
||||
restriction.fqbn === board.fqbn || restriction.name === board.fqbn
|
||||
)
|
||||
);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
private readonly toggleFilterPorts = () => {
|
||||
this.setState({ showAllPorts: !this.state.showAllPorts });
|
||||
};
|
||||
|
||||
private readonly selectPort = (selectedPort: PortIdentifier) => {
|
||||
this.props.onPortSelected(selectedPort);
|
||||
};
|
||||
|
||||
private readonly selectBoard = (selectedBoard: BoardWithPackage) => {
|
||||
this.props.onBoardSelected(selectedBoard);
|
||||
};
|
||||
|
||||
private readonly focusNodeSet = (element: HTMLElement | null) => {
|
||||
this.props.onFocusNodeSet(element || undefined);
|
||||
};
|
||||
|
||||
override render(): React.ReactNode {
|
||||
return (
|
||||
<>
|
||||
{this.renderContainer(
|
||||
nls.localize('arduino/board/boards', 'boards'),
|
||||
this.renderBoards.bind(this)
|
||||
)}
|
||||
{this.renderContainer(
|
||||
nls.localize('arduino/board/ports', 'ports'),
|
||||
this.renderPorts.bind(this),
|
||||
this.renderPortsFooter.bind(this)
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private renderContainer(
|
||||
title: string,
|
||||
contentRenderer: () => React.ReactNode,
|
||||
footerRenderer?: () => React.ReactNode
|
||||
): React.ReactNode {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="content">
|
||||
<div className="title">{title}</div>
|
||||
{contentRenderer()}
|
||||
<div className="footer">{footerRenderer ? footerRenderer() : ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private renderBoards(): React.ReactNode {
|
||||
const { boardsConfig } = this.props;
|
||||
const { searchResults, query } = this.state;
|
||||
// Board names are not unique per core https://github.com/arduino/arduino-pro-ide/issues/262#issuecomment-661019560
|
||||
// It is tricky when the core is not yet installed, no FQBNs are available.
|
||||
const distinctBoards = new Map<string, Board.Detailed>();
|
||||
const toKey = ({ name, packageName, fqbn }: Board.Detailed) =>
|
||||
!!fqbn ? `${name}-${packageName}-${fqbn}` : `${name}-${packageName}`;
|
||||
for (const board of Board.decorateBoards(
|
||||
boardsConfig.selectedBoard,
|
||||
searchResults
|
||||
)) {
|
||||
const key = toKey(board);
|
||||
if (!distinctBoards.has(key)) {
|
||||
distinctBoards.set(key, board);
|
||||
}
|
||||
}
|
||||
|
||||
const boardsList = Array.from(distinctBoards.values()).map((board) => (
|
||||
<Item<BoardWithPackage>
|
||||
key={toKey(board)}
|
||||
item={board}
|
||||
label={board.name}
|
||||
details={board.details}
|
||||
selected={board.selected}
|
||||
onClick={this.selectBoard}
|
||||
missing={board.missing}
|
||||
/>
|
||||
));
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="search">
|
||||
<input
|
||||
type="search"
|
||||
value={query}
|
||||
className="theia-input"
|
||||
placeholder={nls.localize(
|
||||
'arduino/board/searchBoard',
|
||||
'Search board'
|
||||
)}
|
||||
onChange={this.updateBoards}
|
||||
ref={this.focusNodeSet}
|
||||
/>
|
||||
<i className="fa fa-search"></i>
|
||||
</div>
|
||||
{boardsList.length > 0 ? (
|
||||
<div className="boards list">{boardsList}</div>
|
||||
) : (
|
||||
<div className="no-result">
|
||||
{nls.localize(
|
||||
'arduino/board/noBoardsFound',
|
||||
'No boards found for "{0}"',
|
||||
query
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
private renderPorts(): React.ReactNode {
|
||||
const predicate = this.state.showAllPorts ? undefined : Port.isVisiblePort;
|
||||
const detectedPorts = this.props.ports(predicate);
|
||||
const matchingIndex = findMatchingPortIndex(
|
||||
this.props.boardsConfig.selectedPort,
|
||||
detectedPorts
|
||||
);
|
||||
return !detectedPorts.length ? (
|
||||
<div className="no-result">
|
||||
{nls.localize('arduino/board/noPortsDiscovered', 'No ports discovered')}
|
||||
</div>
|
||||
) : (
|
||||
<div className="ports list">
|
||||
{detectedPorts.map((detectedPort, index) => (
|
||||
<Item<Port>
|
||||
key={`${Port.keyOf(detectedPort.port)}`}
|
||||
item={detectedPort.port}
|
||||
label={Port.toString(detectedPort.port)}
|
||||
selected={index === matchingIndex}
|
||||
onClick={this.selectPort}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private renderPortsFooter(): React.ReactNode {
|
||||
return (
|
||||
<div className="noselect">
|
||||
<label
|
||||
title={nls.localize(
|
||||
'arduino/board/showAllAvailablePorts',
|
||||
'Shows all available ports when enabled'
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={this.state.showAllPorts}
|
||||
onChange={this.toggleFilterPorts}
|
||||
/>
|
||||
<span>
|
||||
{nls.localize('arduino/board/showAllPorts', 'Show all ports')}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
import React from '@theia/core/shared/react';
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { ReactWidget, Message } from '@theia/core/lib/browser';
|
||||
import { BoardsService } from '../../common/protocol/boards-service';
|
||||
import { BoardsConfig } from './boards-config';
|
||||
import { BoardsServiceProvider } from './boards-service-provider';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
|
||||
@injectable()
|
||||
export class BoardsConfigDialogWidget extends ReactWidget {
|
||||
@inject(BoardsService)
|
||||
protected readonly boardsService: BoardsService;
|
||||
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
|
||||
@inject(NotificationCenter)
|
||||
protected readonly notificationCenter: NotificationCenter;
|
||||
|
||||
protected readonly onFilterTextDidChangeEmitter = new Emitter<string>();
|
||||
protected readonly onBoardConfigChangedEmitter =
|
||||
new Emitter<BoardsConfig.Config>();
|
||||
readonly onBoardConfigChanged = this.onBoardConfigChangedEmitter.event;
|
||||
|
||||
protected focusNode: HTMLElement | undefined;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.id = 'select-board-dialog';
|
||||
this.toDispose.pushAll([
|
||||
this.onBoardConfigChangedEmitter,
|
||||
this.onFilterTextDidChangeEmitter,
|
||||
]);
|
||||
}
|
||||
|
||||
search(query: string): void {
|
||||
this.onFilterTextDidChangeEmitter.fire(query);
|
||||
}
|
||||
|
||||
protected fireConfigChanged = (config: BoardsConfig.Config) => {
|
||||
this.onBoardConfigChangedEmitter.fire(config);
|
||||
};
|
||||
|
||||
protected setFocusNode = (element: HTMLElement | undefined) => {
|
||||
this.focusNode = element;
|
||||
};
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
<div className="selectBoardContainer">
|
||||
<BoardsConfig
|
||||
boardsServiceProvider={this.boardsServiceClient}
|
||||
notificationCenter={this.notificationCenter}
|
||||
onConfigChange={this.fireConfigChanged}
|
||||
onFocusNodeSet={this.setFocusNode}
|
||||
onFilteredTextDidChangeEvent={this.onFilterTextDidChangeEmitter.event}
|
||||
onAppStateDidChange={this.notificationCenter.onAppStateDidChange}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected override onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
if (this.focusNode instanceof HTMLInputElement) {
|
||||
this.focusNode.select();
|
||||
}
|
||||
(this.focusNode || this.node).focus();
|
||||
}
|
||||
}
|
@ -1,142 +0,0 @@
|
||||
import {
|
||||
injectable,
|
||||
inject,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { DialogProps, Widget, DialogError } from '@theia/core/lib/browser';
|
||||
import { AbstractDialog } from '../theia/dialogs/dialogs';
|
||||
import { BoardsConfig } from './boards-config';
|
||||
import { BoardsService } from '../../common/protocol/boards-service';
|
||||
import { BoardsServiceProvider } from './boards-service-provider';
|
||||
import { BoardsConfigDialogWidget } from './boards-config-dialog-widget';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
|
||||
@injectable()
|
||||
export class BoardsConfigDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
|
||||
@inject(BoardsConfigDialogWidget)
|
||||
protected readonly widget: BoardsConfigDialogWidget;
|
||||
|
||||
@inject(BoardsService)
|
||||
protected readonly boardService: BoardsService;
|
||||
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
|
||||
protected config: BoardsConfig.Config = {};
|
||||
|
||||
constructor(
|
||||
@inject(BoardsConfigDialogProps)
|
||||
protected override readonly props: BoardsConfigDialogProps
|
||||
) {
|
||||
super({ ...props, maxWidth: 500 });
|
||||
|
||||
this.node.id = 'select-board-dialog-container';
|
||||
this.contentNode.classList.add('select-board-dialog');
|
||||
this.contentNode.appendChild(this.createDescription());
|
||||
|
||||
this.appendCloseButton(
|
||||
nls.localize('vscode/issueMainService/cancel', 'Cancel')
|
||||
);
|
||||
this.appendAcceptButton(nls.localize('vscode/issueMainService/ok', 'OK'));
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.toDispose.push(
|
||||
this.boardsServiceClient.onBoardsConfigChanged((config) => {
|
||||
this.config = config;
|
||||
this.update();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass in an empty string if you want to reset the search term. Using `undefined` has no effect.
|
||||
*/
|
||||
override async open(
|
||||
query: string | undefined = undefined
|
||||
): Promise<BoardsConfig.Config | undefined> {
|
||||
if (typeof query === 'string') {
|
||||
this.widget.search(query);
|
||||
}
|
||||
return super.open();
|
||||
}
|
||||
|
||||
protected createDescription(): HTMLElement {
|
||||
const head = document.createElement('div');
|
||||
head.classList.add('head');
|
||||
|
||||
const text = document.createElement('div');
|
||||
text.classList.add('text');
|
||||
head.appendChild(text);
|
||||
|
||||
for (const paragraph of [
|
||||
nls.localize(
|
||||
'arduino/board/configDialog1',
|
||||
'Select both a Board and a Port if you want to upload a sketch.'
|
||||
),
|
||||
nls.localize(
|
||||
'arduino/board/configDialog2',
|
||||
'If you only select a Board you will be able to compile, but not to upload your sketch.'
|
||||
),
|
||||
]) {
|
||||
const p = document.createElement('div');
|
||||
p.textContent = paragraph;
|
||||
text.appendChild(p);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
protected override onAfterAttach(msg: Message): void {
|
||||
if (this.widget.isAttached) {
|
||||
Widget.detach(this.widget);
|
||||
}
|
||||
Widget.attach(this.widget, this.contentNode);
|
||||
this.toDisposeOnDetach.push(
|
||||
this.widget.onBoardConfigChanged((config) => {
|
||||
this.config = config;
|
||||
this.update();
|
||||
})
|
||||
);
|
||||
super.onAfterAttach(msg);
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected override onUpdateRequest(msg: Message): void {
|
||||
super.onUpdateRequest(msg);
|
||||
this.widget.update();
|
||||
}
|
||||
|
||||
protected override onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
this.widget.activate();
|
||||
}
|
||||
|
||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
||||
if (event.target instanceof HTMLTextAreaElement) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override isValid(value: BoardsConfig.Config): DialogError {
|
||||
if (!value.selectedBoard) {
|
||||
if (value.selectedPort) {
|
||||
return nls.localize(
|
||||
'arduino/board/pleasePickBoard',
|
||||
'Please pick a board connected to the port you have selected.'
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
get value(): BoardsConfig.Config {
|
||||
return this.config;
|
||||
}
|
||||
}
|
@ -0,0 +1,202 @@
|
||||
import { DialogError, DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import type { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import React from '@theia/core/shared/react';
|
||||
import type { ReactNode } from '@theia/core/shared/react/index';
|
||||
import { EditBoardsConfigActionParams } from '../../common/protocol/board-list';
|
||||
import {
|
||||
BoardIdentifier,
|
||||
BoardsConfig,
|
||||
BoardWithPackage,
|
||||
DetectedPort,
|
||||
emptyBoardsConfig,
|
||||
PortIdentifier,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import type { Defined } from '../../common/types';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { ReactDialog } from '../theia/dialogs/dialogs';
|
||||
import { BoardsConfigComponent } from './boards-config-component';
|
||||
import { BoardsServiceProvider } from './boards-service-provider';
|
||||
|
||||
@injectable()
|
||||
export class BoardsConfigDialogProps extends DialogProps {}
|
||||
|
||||
export type BoardsConfigDialogState = Omit<BoardsConfig, 'selectedBoard'> & {
|
||||
selectedBoard: BoardsConfig['selectedBoard'] | BoardWithPackage;
|
||||
};
|
||||
|
||||
@injectable()
|
||||
export class BoardsConfigDialog extends ReactDialog<BoardsConfigDialogState> {
|
||||
@inject(BoardsServiceProvider)
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
@inject(NotificationCenter)
|
||||
private readonly notificationCenter: NotificationCenter;
|
||||
@inject(FrontendApplicationStateService)
|
||||
private readonly appStateService: FrontendApplicationStateService;
|
||||
|
||||
private readonly onFilterTextDidChangeEmitter: Emitter<
|
||||
Defined<EditBoardsConfigActionParams['query']>
|
||||
>;
|
||||
private readonly onBoardSelected = (board: BoardWithPackage): void => {
|
||||
this._boardsConfig.selectedBoard = board;
|
||||
this.update();
|
||||
};
|
||||
private readonly onPortSelected = (port: PortIdentifier): void => {
|
||||
this._boardsConfig.selectedPort = port;
|
||||
this.update();
|
||||
};
|
||||
private readonly setFocusNode = (element: HTMLElement | undefined): void => {
|
||||
this.focusNode = element;
|
||||
};
|
||||
private readonly searchBoards = (options: {
|
||||
query?: string;
|
||||
}): Promise<BoardWithPackage[]> => {
|
||||
return this.boardsServiceProvider.searchBoards(options);
|
||||
};
|
||||
private readonly ports = (
|
||||
predicate?: (port: DetectedPort) => boolean
|
||||
): readonly DetectedPort[] => {
|
||||
return this.boardsServiceProvider.boardList.ports(predicate);
|
||||
};
|
||||
private _boardsConfig: BoardsConfigDialogState;
|
||||
/**
|
||||
* When the dialog's boards result set is limited to a subset of boards when searching, this field is set.
|
||||
*/
|
||||
private _searchSet: BoardIdentifier[] | undefined;
|
||||
private focusNode: HTMLElement | undefined;
|
||||
|
||||
constructor(
|
||||
@inject(BoardsConfigDialogProps)
|
||||
protected override readonly props: BoardsConfigDialogProps
|
||||
) {
|
||||
super({ ...props, maxWidth: 500 });
|
||||
this.node.id = 'select-board-dialog-container';
|
||||
this.contentNode.classList.add('select-board-dialog');
|
||||
this.appendCloseButton(
|
||||
nls.localize('vscode/issueMainService/cancel', 'Cancel')
|
||||
);
|
||||
this.appendAcceptButton(nls.localize('vscode/issueMainService/ok', 'OK'));
|
||||
this._boardsConfig = emptyBoardsConfig();
|
||||
this.onFilterTextDidChangeEmitter = new Emitter();
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.boardsServiceProvider.onBoardListDidChange(() => {
|
||||
this._boardsConfig = deepClone(this.boardsServiceProvider.boardsConfig);
|
||||
this.update();
|
||||
});
|
||||
this._boardsConfig = deepClone(this.boardsServiceProvider.boardsConfig);
|
||||
}
|
||||
|
||||
override async open(
|
||||
params?: EditBoardsConfigActionParams
|
||||
): Promise<BoardsConfig | undefined> {
|
||||
this._searchSet = undefined;
|
||||
this._boardsConfig.selectedBoard =
|
||||
this.boardsServiceProvider.boardsConfig.selectedBoard;
|
||||
this._boardsConfig.selectedPort =
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort;
|
||||
if (params) {
|
||||
if (typeof params.query === 'string') {
|
||||
this.onFilterTextDidChangeEmitter.fire(params.query);
|
||||
}
|
||||
if (params.portToSelect) {
|
||||
this._boardsConfig.selectedPort = params.portToSelect;
|
||||
}
|
||||
if (params.boardToSelect) {
|
||||
this._boardsConfig.selectedBoard = params.boardToSelect;
|
||||
}
|
||||
if (params.searchSet) {
|
||||
this._searchSet = params.searchSet.slice();
|
||||
}
|
||||
}
|
||||
return super.open();
|
||||
}
|
||||
|
||||
protected override onAfterAttach(msg: Message): void {
|
||||
super.onAfterAttach(msg);
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected override render(): ReactNode {
|
||||
return (
|
||||
<>
|
||||
<div className="head">
|
||||
<div className="text">
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/board/configDialog1',
|
||||
'Select both a Board and a Port if you want to upload a sketch.'
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
{nls.localize(
|
||||
'arduino/board/configDialog2',
|
||||
'If you only select a Board you will be able to compile, but not to upload your sketch.'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="select-board-dialog" className="p-Widget ps">
|
||||
<div className="selectBoardContainer">
|
||||
<BoardsConfigComponent
|
||||
boardsConfig={this._boardsConfig}
|
||||
searchSet={this._searchSet}
|
||||
onBoardSelected={this.onBoardSelected}
|
||||
onPortSelected={this.onPortSelected}
|
||||
notificationCenter={this.notificationCenter}
|
||||
onFocusNodeSet={this.setFocusNode}
|
||||
onFilteredTextDidChangeEvent={
|
||||
this.onFilterTextDidChangeEmitter.event
|
||||
}
|
||||
appState={this.appStateService.state}
|
||||
onAppStateDidChange={this.notificationCenter.onAppStateDidChange}
|
||||
searchBoards={this.searchBoards}
|
||||
ports={this.ports}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
protected override onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
if (this.focusNode instanceof HTMLInputElement) {
|
||||
this.focusNode.select();
|
||||
}
|
||||
(this.focusNode || this.node).focus();
|
||||
}
|
||||
|
||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
||||
if (event.target instanceof HTMLTextAreaElement) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override isValid(value: BoardsConfig): DialogError {
|
||||
if (!value.selectedBoard) {
|
||||
if (value.selectedPort) {
|
||||
return nls.localize(
|
||||
'arduino/board/pleasePickBoard',
|
||||
'Please pick a board connected to the port you have selected.'
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
get value(): BoardsConfigDialogState {
|
||||
return this._boardsConfig;
|
||||
}
|
||||
}
|
@ -1,432 +0,0 @@
|
||||
import React from '@theia/core/shared/react';
|
||||
import { Event } from '@theia/core/lib/common/event';
|
||||
import { notEmpty } from '@theia/core/lib/common/objects';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import {
|
||||
Board,
|
||||
Port,
|
||||
BoardConfig as ProtocolBoardConfig,
|
||||
BoardWithPackage,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import {
|
||||
AvailableBoard,
|
||||
BoardsServiceProvider,
|
||||
} from './boards-service-provider';
|
||||
import { naturalCompare } from '../../common/utils';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { FrontendApplicationState } from '@theia/core/lib/common/frontend-application-state';
|
||||
|
||||
export namespace BoardsConfig {
|
||||
export type Config = ProtocolBoardConfig;
|
||||
|
||||
export interface Props {
|
||||
readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
readonly notificationCenter: NotificationCenter;
|
||||
readonly onConfigChange: (config: Config) => void;
|
||||
readonly onFocusNodeSet: (element: HTMLElement | undefined) => void;
|
||||
readonly onFilteredTextDidChangeEvent: Event<string>;
|
||||
readonly onAppStateDidChange: Event<FrontendApplicationState>;
|
||||
}
|
||||
|
||||
export interface State extends Config {
|
||||
searchResults: Array<BoardWithPackage>;
|
||||
knownPorts: Port[];
|
||||
showAllPorts: boolean;
|
||||
query: string;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Item<T> extends React.Component<{
|
||||
item: T;
|
||||
label: string;
|
||||
selected: boolean;
|
||||
onClick: (item: T) => void;
|
||||
missing?: boolean;
|
||||
details?: string;
|
||||
}> {
|
||||
override render(): React.ReactNode {
|
||||
const { selected, label, missing, details } = this.props;
|
||||
const classNames = ['item'];
|
||||
if (selected) {
|
||||
classNames.push('selected');
|
||||
}
|
||||
if (missing === true) {
|
||||
classNames.push('missing');
|
||||
}
|
||||
return (
|
||||
<div
|
||||
onClick={this.onClick}
|
||||
className={classNames.join(' ')}
|
||||
title={`${label}${!details ? '' : details}`}
|
||||
>
|
||||
<div className="label">{label}</div>
|
||||
{!details ? '' : <div className="details">{details}</div>}
|
||||
{!selected ? (
|
||||
''
|
||||
) : (
|
||||
<div className="selected-icon">
|
||||
<i className="fa fa-check" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected onClick = () => {
|
||||
this.props.onClick(this.props.item);
|
||||
};
|
||||
}
|
||||
|
||||
export class BoardsConfig extends React.Component<
|
||||
BoardsConfig.Props,
|
||||
BoardsConfig.State
|
||||
> {
|
||||
protected toDispose = new DisposableCollection();
|
||||
|
||||
constructor(props: BoardsConfig.Props) {
|
||||
super(props);
|
||||
|
||||
const { boardsConfig } = props.boardsServiceProvider;
|
||||
this.state = {
|
||||
searchResults: [],
|
||||
knownPorts: [],
|
||||
showAllPorts: false,
|
||||
query: '',
|
||||
...boardsConfig,
|
||||
};
|
||||
}
|
||||
|
||||
override componentDidMount(): void {
|
||||
this.toDispose.pushAll([
|
||||
this.props.onAppStateDidChange((state) => {
|
||||
if (state === 'ready') {
|
||||
this.updateBoards();
|
||||
this.updatePorts(
|
||||
this.props.boardsServiceProvider.availableBoards
|
||||
.map(({ port }) => port)
|
||||
.filter(notEmpty)
|
||||
);
|
||||
}
|
||||
}),
|
||||
this.props.boardsServiceProvider.onAvailablePortsChanged(
|
||||
({ newState, oldState }) => {
|
||||
const removedPorts = oldState.filter(
|
||||
(oldPort) =>
|
||||
!newState.find((newPort) => Port.sameAs(newPort, oldPort))
|
||||
);
|
||||
this.updatePorts(newState, removedPorts);
|
||||
}
|
||||
),
|
||||
this.props.boardsServiceProvider.onBoardsConfigChanged(
|
||||
({ selectedBoard, selectedPort }) => {
|
||||
this.setState({ selectedBoard, selectedPort }, () =>
|
||||
this.fireConfigChanged()
|
||||
);
|
||||
}
|
||||
),
|
||||
this.props.notificationCenter.onPlatformDidInstall(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onPlatformDidUninstall(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onIndexUpdateDidComplete(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onDaemonDidStart(() =>
|
||||
this.updateBoards(this.state.query)
|
||||
),
|
||||
this.props.notificationCenter.onDaemonDidStop(() =>
|
||||
this.setState({ searchResults: [] })
|
||||
),
|
||||
this.props.onFilteredTextDidChangeEvent((query) =>
|
||||
this.setState({ query }, () => this.updateBoards(this.state.query))
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
override componentWillUnmount(): void {
|
||||
this.toDispose.dispose();
|
||||
}
|
||||
|
||||
protected fireConfigChanged(): void {
|
||||
const { selectedBoard, selectedPort } = this.state;
|
||||
this.props.onConfigChange({ selectedBoard, selectedPort });
|
||||
}
|
||||
|
||||
protected updateBoards = (
|
||||
eventOrQuery: React.ChangeEvent<HTMLInputElement> | string = ''
|
||||
) => {
|
||||
const query =
|
||||
typeof eventOrQuery === 'string'
|
||||
? eventOrQuery
|
||||
: eventOrQuery.target.value.toLowerCase();
|
||||
this.setState({ query });
|
||||
this.queryBoards({ query }).then((searchResults) =>
|
||||
this.setState({ searchResults })
|
||||
);
|
||||
};
|
||||
|
||||
protected updatePorts = (ports: Port[] = [], removedPorts: Port[] = []) => {
|
||||
this.queryPorts(Promise.resolve(ports)).then(({ knownPorts }) => {
|
||||
let { selectedPort } = this.state;
|
||||
// If the currently selected port is not available anymore, unset the selected port.
|
||||
if (removedPorts.some((port) => Port.sameAs(port, selectedPort))) {
|
||||
selectedPort = undefined;
|
||||
}
|
||||
this.setState({ knownPorts, selectedPort }, () =>
|
||||
this.fireConfigChanged()
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
protected queryBoards = (
|
||||
options: { query?: string } = {}
|
||||
): Promise<Array<BoardWithPackage>> => {
|
||||
return this.props.boardsServiceProvider.searchBoards(options);
|
||||
};
|
||||
|
||||
protected get availablePorts(): MaybePromise<Port[]> {
|
||||
return this.props.boardsServiceProvider.availableBoards
|
||||
.map(({ port }) => port)
|
||||
.filter(notEmpty);
|
||||
}
|
||||
|
||||
protected get availableBoards(): AvailableBoard[] {
|
||||
return this.props.boardsServiceProvider.availableBoards;
|
||||
}
|
||||
|
||||
protected queryPorts = async (
|
||||
availablePorts: MaybePromise<Port[]> = this.availablePorts
|
||||
) => {
|
||||
// Available ports must be sorted in this order:
|
||||
// 1. Serial with recognized boards
|
||||
// 2. Serial with guessed boards
|
||||
// 3. Serial with incomplete boards
|
||||
// 4. Network with recognized boards
|
||||
// 5. Other protocols with recognized boards
|
||||
const ports = (await availablePorts).sort((left: Port, right: Port) => {
|
||||
if (left.protocol === 'serial' && right.protocol !== 'serial') {
|
||||
return -1;
|
||||
} else if (left.protocol !== 'serial' && right.protocol === 'serial') {
|
||||
return 1;
|
||||
} else if (left.protocol === 'network' && right.protocol !== 'network') {
|
||||
return -1;
|
||||
} else if (left.protocol !== 'network' && right.protocol === 'network') {
|
||||
return 1;
|
||||
} else if (left.protocol === right.protocol) {
|
||||
// We show ports, including those that have guessed
|
||||
// or unrecognized boards, so we must sort those too.
|
||||
const leftBoard = this.availableBoards.find(
|
||||
(board) => board.port === left
|
||||
);
|
||||
const rightBoard = this.availableBoards.find(
|
||||
(board) => board.port === right
|
||||
);
|
||||
if (leftBoard && !rightBoard) {
|
||||
return -1;
|
||||
} else if (!leftBoard && rightBoard) {
|
||||
return 1;
|
||||
} else if (leftBoard?.state! < rightBoard?.state!) {
|
||||
return -1;
|
||||
} else if (leftBoard?.state! > rightBoard?.state!) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return naturalCompare(left.address, right.address);
|
||||
});
|
||||
return { knownPorts: ports };
|
||||
};
|
||||
|
||||
protected toggleFilterPorts = () => {
|
||||
this.setState({ showAllPorts: !this.state.showAllPorts });
|
||||
};
|
||||
|
||||
protected selectPort = (selectedPort: Port | undefined) => {
|
||||
this.setState({ selectedPort }, () => this.fireConfigChanged());
|
||||
};
|
||||
|
||||
protected selectBoard = (selectedBoard: BoardWithPackage | undefined) => {
|
||||
this.setState({ selectedBoard }, () => this.fireConfigChanged());
|
||||
};
|
||||
|
||||
protected focusNodeSet = (element: HTMLElement | null) => {
|
||||
this.props.onFocusNodeSet(element || undefined);
|
||||
};
|
||||
|
||||
override render(): React.ReactNode {
|
||||
return (
|
||||
<>
|
||||
{this.renderContainer(
|
||||
nls.localize('arduino/board/boards', 'boards'),
|
||||
this.renderBoards.bind(this)
|
||||
)}
|
||||
{this.renderContainer(
|
||||
nls.localize('arduino/board/ports', 'ports'),
|
||||
this.renderPorts.bind(this),
|
||||
this.renderPortsFooter.bind(this)
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderContainer(
|
||||
title: string,
|
||||
contentRenderer: () => React.ReactNode,
|
||||
footerRenderer?: () => React.ReactNode
|
||||
): React.ReactNode {
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="content">
|
||||
<div className="title">{title}</div>
|
||||
{contentRenderer()}
|
||||
<div className="footer">{footerRenderer ? footerRenderer() : ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderBoards(): React.ReactNode {
|
||||
const { selectedBoard, searchResults, query } = this.state;
|
||||
// Board names are not unique per core https://github.com/arduino/arduino-pro-ide/issues/262#issuecomment-661019560
|
||||
// It is tricky when the core is not yet installed, no FQBNs are available.
|
||||
const distinctBoards = new Map<string, Board.Detailed>();
|
||||
const toKey = ({ name, packageName, fqbn }: Board.Detailed) =>
|
||||
!!fqbn ? `${name}-${packageName}-${fqbn}` : `${name}-${packageName}`;
|
||||
for (const board of Board.decorateBoards(selectedBoard, searchResults)) {
|
||||
const key = toKey(board);
|
||||
if (!distinctBoards.has(key)) {
|
||||
distinctBoards.set(key, board);
|
||||
}
|
||||
}
|
||||
|
||||
const boardsList = Array.from(distinctBoards.values()).map((board) => (
|
||||
<Item<BoardWithPackage>
|
||||
key={toKey(board)}
|
||||
item={board}
|
||||
label={board.name}
|
||||
details={board.details}
|
||||
selected={board.selected}
|
||||
onClick={this.selectBoard}
|
||||
missing={board.missing}
|
||||
/>
|
||||
));
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className="search">
|
||||
<input
|
||||
type="search"
|
||||
value={query}
|
||||
className="theia-input"
|
||||
placeholder={nls.localize(
|
||||
'arduino/board/searchBoard',
|
||||
'Search board'
|
||||
)}
|
||||
onChange={this.updateBoards}
|
||||
ref={this.focusNodeSet}
|
||||
/>
|
||||
<i className="fa fa-search"></i>
|
||||
</div>
|
||||
{boardsList.length > 0 ? (
|
||||
<div className="boards list">{boardsList}</div>
|
||||
) : (
|
||||
<div className="no-result">
|
||||
{nls.localize(
|
||||
'arduino/board/noBoardsFound',
|
||||
'No boards found for "{0}"',
|
||||
query
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderPorts(): React.ReactNode {
|
||||
let ports = [] as Port[];
|
||||
if (this.state.showAllPorts) {
|
||||
ports = this.state.knownPorts;
|
||||
} else {
|
||||
ports = this.state.knownPorts.filter(
|
||||
Port.visiblePorts(this.availableBoards)
|
||||
);
|
||||
}
|
||||
return !ports.length ? (
|
||||
<div className="no-result">
|
||||
{nls.localize('arduino/board/noPortsDiscovered', 'No ports discovered')}
|
||||
</div>
|
||||
) : (
|
||||
<div className="ports list">
|
||||
{ports.map((port) => (
|
||||
<Item<Port>
|
||||
key={`${Port.keyOf(port)}`}
|
||||
item={port}
|
||||
label={Port.toString(port)}
|
||||
selected={Port.sameAs(this.state.selectedPort, port)}
|
||||
onClick={this.selectPort}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected renderPortsFooter(): React.ReactNode {
|
||||
return (
|
||||
<div className="noselect">
|
||||
<label
|
||||
title={nls.localize(
|
||||
'arduino/board/showAllAvailablePorts',
|
||||
'Shows all available ports when enabled'
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
defaultChecked={this.state.showAllPorts}
|
||||
onChange={this.toggleFilterPorts}
|
||||
/>
|
||||
<span>
|
||||
{nls.localize('arduino/board/showAllPorts', 'Show all ports')}
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export namespace BoardsConfig {
|
||||
export namespace Config {
|
||||
export function sameAs(config: Config, other: Config | Board): boolean {
|
||||
const { selectedBoard, selectedPort } = config;
|
||||
if (Board.is(other)) {
|
||||
return (
|
||||
!!selectedBoard &&
|
||||
Board.equals(other, selectedBoard) &&
|
||||
Port.sameAs(selectedPort, other.port)
|
||||
);
|
||||
}
|
||||
return sameAs(config, other);
|
||||
}
|
||||
|
||||
export function equals(left: Config, right: Config): boolean {
|
||||
return (
|
||||
left.selectedBoard === right.selectedBoard &&
|
||||
left.selectedPort === right.selectedPort
|
||||
);
|
||||
}
|
||||
|
||||
export function toString(
|
||||
config: Config,
|
||||
options: { default: string } = { default: '' }
|
||||
): string {
|
||||
const { selectedBoard, selectedPort: port } = config;
|
||||
if (!selectedBoard) {
|
||||
return options.default;
|
||||
}
|
||||
const { name } = selectedBoard;
|
||||
return `${name}${port ? ` at ${port.address}` : ''}`;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +1,64 @@
|
||||
import { injectable, inject, named } from '@theia/core/shared/inversify';
|
||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
|
||||
import { LocalStorageService } from '@theia/core/lib/browser/storage-service';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { Emitter, Event } from '@theia/core/lib/common/event';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import { Event, Emitter } from '@theia/core/lib/common/event';
|
||||
import {
|
||||
FrontendApplicationContribution,
|
||||
LocalStorageService,
|
||||
} from '@theia/core/lib/browser';
|
||||
import { notEmpty } from '../../common/utils';
|
||||
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
BoardDetails,
|
||||
BoardsService,
|
||||
ConfigOption,
|
||||
BoardDetails,
|
||||
Programmer,
|
||||
} from '../../common/protocol';
|
||||
import { notEmpty } from '../../common/utils';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
|
||||
@injectable()
|
||||
export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
@inject(ILogger)
|
||||
@named('store')
|
||||
protected readonly logger: ILogger;
|
||||
|
||||
private readonly logger: ILogger;
|
||||
@inject(BoardsService)
|
||||
protected readonly boardsService: BoardsService;
|
||||
|
||||
private readonly boardsService: BoardsService;
|
||||
@inject(NotificationCenter)
|
||||
protected readonly notificationCenter: NotificationCenter;
|
||||
|
||||
private readonly notificationCenter: NotificationCenter;
|
||||
@inject(LocalStorageService)
|
||||
protected readonly storageService: LocalStorageService;
|
||||
private readonly storageService: LocalStorageService;
|
||||
|
||||
protected readonly onChangedEmitter = new Emitter<string[]>();
|
||||
private readonly onChangedEmitter = new Emitter<string[]>();
|
||||
private readonly toDispose = new DisposableCollection(this.onChangedEmitter);
|
||||
|
||||
onStart(): void {
|
||||
this.notificationCenter.onPlatformDidInstall(async ({ item }) => {
|
||||
const dataDidChangePerFqbn: string[] = [];
|
||||
for (const fqbn of item.boards
|
||||
.map(({ fqbn }) => fqbn)
|
||||
.filter(notEmpty)
|
||||
.filter((fqbn) => !!fqbn)) {
|
||||
const key = this.getStorageKey(fqbn);
|
||||
let data = await this.storageService.getData<
|
||||
ConfigOption[] | undefined
|
||||
>(key);
|
||||
if (!data || !data.length) {
|
||||
const details = await this.getBoardDetailsSafe(fqbn);
|
||||
if (details) {
|
||||
data = details.configOptions;
|
||||
if (data.length) {
|
||||
await this.storageService.setData(key, data);
|
||||
dataDidChangePerFqbn.push(fqbn);
|
||||
this.toDispose.push(
|
||||
this.notificationCenter.onPlatformDidInstall(async ({ item }) => {
|
||||
const dataDidChangePerFqbn: string[] = [];
|
||||
for (const fqbn of item.boards
|
||||
.map(({ fqbn }) => fqbn)
|
||||
.filter(notEmpty)
|
||||
.filter((fqbn) => !!fqbn)) {
|
||||
const key = this.getStorageKey(fqbn);
|
||||
let data = await this.storageService.getData<ConfigOption[]>(key);
|
||||
if (!data || !data.length) {
|
||||
const details = await this.getBoardDetailsSafe(fqbn);
|
||||
if (details) {
|
||||
data = details.configOptions;
|
||||
if (data.length) {
|
||||
await this.storageService.setData(key, data);
|
||||
dataDidChangePerFqbn.push(fqbn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dataDidChangePerFqbn.length) {
|
||||
this.fireChanged(...dataDidChangePerFqbn);
|
||||
}
|
||||
});
|
||||
if (dataDidChangePerFqbn.length) {
|
||||
this.fireChanged(...dataDidChangePerFqbn);
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onStop(): void {
|
||||
this.toDispose.dispose();
|
||||
}
|
||||
|
||||
get onChanged(): Event<string[]> {
|
||||
@ -65,7 +66,7 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
}
|
||||
|
||||
async appendConfigToFqbn(
|
||||
fqbn: string | undefined,
|
||||
fqbn: string | undefined
|
||||
): Promise<string | undefined> {
|
||||
if (!fqbn) {
|
||||
return undefined;
|
||||
@ -100,12 +101,13 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
return data;
|
||||
}
|
||||
|
||||
async selectProgrammer(
|
||||
{
|
||||
fqbn,
|
||||
selectedProgrammer,
|
||||
}: { fqbn: string; selectedProgrammer: Programmer },
|
||||
): Promise<boolean> {
|
||||
async selectProgrammer({
|
||||
fqbn,
|
||||
selectedProgrammer,
|
||||
}: {
|
||||
fqbn: string;
|
||||
selectedProgrammer: Programmer;
|
||||
}): Promise<boolean> {
|
||||
const data = deepClone(await this.getData(fqbn));
|
||||
const { programmers } = data;
|
||||
if (!programmers.find((p) => Programmer.equals(selectedProgrammer, p))) {
|
||||
@ -120,13 +122,15 @@ export class BoardsDataStore implements FrontendApplicationContribution {
|
||||
return true;
|
||||
}
|
||||
|
||||
async selectConfigOption(
|
||||
{
|
||||
fqbn,
|
||||
option,
|
||||
selectedValue,
|
||||
}: { fqbn: string; option: string; selectedValue: string }
|
||||
): Promise<boolean> {
|
||||
async selectConfigOption({
|
||||
fqbn,
|
||||
option,
|
||||
selectedValue,
|
||||
}: {
|
||||
fqbn: string;
|
||||
option: string;
|
||||
selectedValue: string;
|
||||
}): Promise<boolean> {
|
||||
const data = deepClone(await this.getData(fqbn));
|
||||
const { configOptions } = data;
|
||||
const configOption = configOptions.find((c) => c.option === option);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,21 @@
|
||||
import React from '@theia/core/shared/react';
|
||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
||||
import { TabBarToolbar } from '@theia/core/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar';
|
||||
import { codicon } from '@theia/core/lib/browser/widgets/widget';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { Port } from '../../common/protocol';
|
||||
import { OpenBoardsConfig } from '../contributions/open-boards-config';
|
||||
import {
|
||||
BoardsServiceProvider,
|
||||
AvailableBoard,
|
||||
} from './boards-service-provider';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import React from '@theia/core/shared/react';
|
||||
import ReactDOM from '@theia/core/shared/react-dom';
|
||||
import classNames from 'classnames';
|
||||
import { BoardsConfig } from './boards-config';
|
||||
import { boardIdentifierLabel, Port } from '../../common/protocol';
|
||||
import { BoardListItemUI } from '../../common/protocol/board-list';
|
||||
import { assertUnreachable } from '../../common/utils';
|
||||
import type {
|
||||
BoardListUI,
|
||||
BoardsServiceProvider,
|
||||
} from './boards-service-provider';
|
||||
|
||||
export interface BoardsDropDownListCoords {
|
||||
readonly top: number;
|
||||
@ -22,18 +27,18 @@ export interface BoardsDropDownListCoords {
|
||||
export namespace BoardsDropDown {
|
||||
export interface Props {
|
||||
readonly coords: BoardsDropDownListCoords | 'hidden';
|
||||
readonly items: Array<AvailableBoard & { onClick: () => void; port: Port }>;
|
||||
readonly boardList: BoardListUI;
|
||||
readonly openBoardsConfig: () => void;
|
||||
readonly hide: () => void;
|
||||
}
|
||||
}
|
||||
|
||||
export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
||||
protected dropdownElement: HTMLElement;
|
||||
export class BoardListDropDown extends React.Component<BoardsDropDown.Props> {
|
||||
private dropdownElement: HTMLElement;
|
||||
private listRef: React.RefObject<HTMLDivElement>;
|
||||
|
||||
constructor(props: BoardsDropDown.Props) {
|
||||
super(props);
|
||||
|
||||
this.listRef = React.createRef();
|
||||
let list = document.getElementById('boards-dropdown-container');
|
||||
if (!list) {
|
||||
@ -51,11 +56,14 @@ export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
||||
}
|
||||
|
||||
override render(): React.ReactNode {
|
||||
return ReactDOM.createPortal(this.renderNode(), this.dropdownElement);
|
||||
return ReactDOM.createPortal(
|
||||
this.renderBoardListItems(),
|
||||
this.dropdownElement
|
||||
);
|
||||
}
|
||||
|
||||
protected renderNode(): React.ReactNode {
|
||||
const { coords, items } = this.props;
|
||||
private renderBoardListItems(): React.ReactNode {
|
||||
const { coords, boardList } = this.props;
|
||||
if (coords === 'hidden') {
|
||||
return '';
|
||||
}
|
||||
@ -74,14 +82,12 @@ export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
||||
tabIndex={0}
|
||||
>
|
||||
<div className="arduino-boards-dropdown-list--items-container">
|
||||
{items
|
||||
.map(({ name, port, selected, onClick }) => ({
|
||||
boardLabel: name,
|
||||
port,
|
||||
selected,
|
||||
onClick,
|
||||
}))
|
||||
.map(this.renderItem)}
|
||||
{boardList.items.map((item, index) =>
|
||||
this.renderBoardListItem({
|
||||
item,
|
||||
selected: index === boardList.selectedIndex,
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
key={footerLabel}
|
||||
@ -95,31 +101,43 @@ export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
||||
);
|
||||
}
|
||||
|
||||
protected renderItem({
|
||||
boardLabel,
|
||||
port,
|
||||
private readonly onDefaultAction = (item: BoardListItemUI): unknown => {
|
||||
const { boardList, hide } = this.props;
|
||||
const { type, params } = item.defaultAction;
|
||||
hide();
|
||||
switch (type) {
|
||||
case 'select-boards-config': {
|
||||
return boardList.select(params);
|
||||
}
|
||||
case 'edit-boards-config': {
|
||||
return boardList.edit(params);
|
||||
}
|
||||
default:
|
||||
return assertUnreachable(type);
|
||||
}
|
||||
};
|
||||
|
||||
private renderBoardListItem({
|
||||
item,
|
||||
selected,
|
||||
onClick,
|
||||
}: {
|
||||
boardLabel: string;
|
||||
port: Port;
|
||||
selected?: boolean;
|
||||
onClick: () => void;
|
||||
item: BoardListItemUI;
|
||||
selected: boolean;
|
||||
}): React.ReactNode {
|
||||
const protocolIcon = iconNameFromProtocol(port.protocol);
|
||||
const { boardLabel, portLabel, portProtocol, tooltip } = item.labels;
|
||||
const port = item.port;
|
||||
const onKeyUp = (e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
onClick();
|
||||
this.onDefaultAction(item);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
key={`board-item--${boardLabel}-${port.address}`}
|
||||
key={`board-item--${Port.keyOf(port)}`}
|
||||
className={classNames('arduino-boards-dropdown-item', {
|
||||
'arduino-boards-dropdown-item--selected': selected,
|
||||
})}
|
||||
onClick={onClick}
|
||||
onClick={() => this.onDefaultAction(item)}
|
||||
onKeyUp={onKeyUp}
|
||||
tabIndex={0}
|
||||
>
|
||||
@ -127,21 +145,81 @@ export class BoardsDropDown extends React.Component<BoardsDropDown.Props> {
|
||||
className={classNames(
|
||||
'arduino-boards-dropdown-item--protocol',
|
||||
'fa',
|
||||
protocolIcon
|
||||
iconNameFromProtocol(portProtocol)
|
||||
)}
|
||||
/>
|
||||
<div
|
||||
className="arduino-boards-dropdown-item--label"
|
||||
title={`${boardLabel}\n${port.address}`}
|
||||
>
|
||||
<div className="arduino-boards-dropdown-item--board-label noWrapInfo noselect">
|
||||
{boardLabel}
|
||||
<div className="arduino-boards-dropdown-item--label" title={tooltip}>
|
||||
<div className="arduino-boards-dropdown-item--board-header">
|
||||
<div className="arduino-boards-dropdown-item--board-label noWrapInfo noselect">
|
||||
{boardLabel}
|
||||
</div>
|
||||
</div>
|
||||
<div className="arduino-boards-dropdown-item--port-label noWrapInfo noselect">
|
||||
{port.addressLabel}
|
||||
{portLabel}
|
||||
</div>
|
||||
</div>
|
||||
{selected ? <div className="fa fa-check" /> : ''}
|
||||
{this.renderActions(item)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
private renderActions(item: BoardListItemUI): React.ReactNode {
|
||||
const { boardList, hide } = this.props;
|
||||
const { revert, edit } = item.otherActions;
|
||||
if (!edit && !revert) {
|
||||
return undefined;
|
||||
}
|
||||
const handleOnClick = (
|
||||
event: React.MouseEvent<HTMLElement, MouseEvent>,
|
||||
callback: () => void
|
||||
) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
hide();
|
||||
callback();
|
||||
};
|
||||
return (
|
||||
<div className={TabBarToolbar.Styles.TAB_BAR_TOOLBAR}>
|
||||
{edit && (
|
||||
<div
|
||||
className={`${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} enabled`}
|
||||
>
|
||||
{
|
||||
<div
|
||||
id="edit"
|
||||
className={codicon('pencil', true)}
|
||||
title={nls.localize(
|
||||
'arduino/board/editBoardsConfig',
|
||||
'Edit Board and Port...'
|
||||
)}
|
||||
onClick={(event) =>
|
||||
handleOnClick(event, () => boardList.edit(edit.params))
|
||||
}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
{revert && (
|
||||
<div
|
||||
className={`${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} enabled`}
|
||||
>
|
||||
{
|
||||
<div
|
||||
id="revert"
|
||||
className={codicon('discard', true)}
|
||||
title={nls.localize(
|
||||
'arduino/board/revertBoardsConfig',
|
||||
"Use '{0}' discovered on '{1}'",
|
||||
boardIdentifierLabel(revert.params.selectedBoard),
|
||||
item.labels.portLabel
|
||||
)}
|
||||
onClick={(event) =>
|
||||
handleOnClick(event, () => boardList.select(revert.params))
|
||||
}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -153,26 +231,27 @@ export class BoardsToolBarItem extends React.Component<
|
||||
> {
|
||||
static TOOLBAR_ID: 'boards-toolbar';
|
||||
|
||||
protected readonly toDispose: DisposableCollection =
|
||||
new DisposableCollection();
|
||||
private readonly toDispose: DisposableCollection;
|
||||
|
||||
constructor(props: BoardsToolBarItem.Props) {
|
||||
super(props);
|
||||
|
||||
const { availableBoards } = props.boardsServiceProvider;
|
||||
const { boardList } = props.boardsServiceProvider;
|
||||
this.state = {
|
||||
availableBoards,
|
||||
boardList,
|
||||
coords: 'hidden',
|
||||
};
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
this.setState({ coords: 'hidden' });
|
||||
});
|
||||
const listener = () => this.setState({ coords: 'hidden' });
|
||||
document.addEventListener('click', listener);
|
||||
this.toDispose = new DisposableCollection(
|
||||
Disposable.create(() => document.removeEventListener('click', listener))
|
||||
);
|
||||
}
|
||||
|
||||
override componentDidMount(): void {
|
||||
this.props.boardsServiceProvider.onAvailableBoardsChanged(
|
||||
(availableBoards) => this.setState({ availableBoards })
|
||||
this.toDispose.push(
|
||||
this.props.boardsServiceProvider.onBoardListDidChange((boardList) =>
|
||||
this.setState({ boardList })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -180,7 +259,7 @@ export class BoardsToolBarItem extends React.Component<
|
||||
this.toDispose.dispose();
|
||||
}
|
||||
|
||||
protected readonly show = (event: React.MouseEvent<HTMLElement>): void => {
|
||||
private readonly show = (event: React.MouseEvent<HTMLElement>): void => {
|
||||
const { currentTarget: element } = event;
|
||||
if (element instanceof HTMLElement) {
|
||||
if (this.state.coords === 'hidden') {
|
||||
@ -201,31 +280,26 @@ export class BoardsToolBarItem extends React.Component<
|
||||
event.nativeEvent.stopImmediatePropagation();
|
||||
};
|
||||
|
||||
private readonly hide = () => {
|
||||
this.setState({ coords: 'hidden' });
|
||||
};
|
||||
|
||||
override render(): React.ReactNode {
|
||||
const { coords, availableBoards } = this.state;
|
||||
const { selectedBoard, selectedPort } =
|
||||
this.props.boardsServiceProvider.boardsConfig;
|
||||
|
||||
const boardLabel =
|
||||
selectedBoard?.name ||
|
||||
nls.localize('arduino/board/selectBoard', 'Select Board');
|
||||
const selectedPortLabel = portLabel(selectedPort?.address);
|
||||
|
||||
const isConnected = Boolean(selectedBoard && selectedPort);
|
||||
const protocolIcon = isConnected
|
||||
? iconNameFromProtocol(selectedPort?.protocol || '')
|
||||
const { coords, boardList } = this.state;
|
||||
const { boardLabel, selected, portProtocol, tooltip } = boardList.labels;
|
||||
const protocolIcon = portProtocol
|
||||
? iconNameFromProtocol(portProtocol)
|
||||
: null;
|
||||
const protocolIconClassNames = classNames(
|
||||
'arduino-boards-toolbar-item--protocol',
|
||||
'fa',
|
||||
protocolIcon
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div
|
||||
className="arduino-boards-toolbar-item-container"
|
||||
title={selectedPortLabel}
|
||||
title={tooltip}
|
||||
onClick={this.show}
|
||||
>
|
||||
{protocolIcon && <div className={protocolIconClassNames} />}
|
||||
@ -234,57 +308,22 @@ export class BoardsToolBarItem extends React.Component<
|
||||
'arduino-boards-toolbar-item--label',
|
||||
'noWrapInfo',
|
||||
'noselect',
|
||||
{ 'arduino-boards-toolbar-item--label-connected': isConnected }
|
||||
{ 'arduino-boards-toolbar-item--label-connected': selected }
|
||||
)}
|
||||
>
|
||||
{boardLabel}
|
||||
</div>
|
||||
<div className="fa fa-caret-down caret" />
|
||||
</div>
|
||||
<BoardsDropDown
|
||||
<BoardListDropDown
|
||||
coords={coords}
|
||||
items={availableBoards
|
||||
.filter(AvailableBoard.hasPort)
|
||||
.map((board) => ({
|
||||
...board,
|
||||
onClick: () => {
|
||||
if (!board.fqbn) {
|
||||
const previousBoardConfig =
|
||||
this.props.boardsServiceProvider.boardsConfig;
|
||||
this.props.boardsServiceProvider.boardsConfig = {
|
||||
selectedPort: board.port,
|
||||
};
|
||||
this.openDialog(previousBoardConfig);
|
||||
} else {
|
||||
this.props.boardsServiceProvider.boardsConfig = {
|
||||
selectedBoard: board,
|
||||
selectedPort: board.port,
|
||||
};
|
||||
}
|
||||
this.setState({ coords: 'hidden' });
|
||||
},
|
||||
}))}
|
||||
openBoardsConfig={this.openDialog}
|
||||
></BoardsDropDown>
|
||||
boardList={boardList}
|
||||
openBoardsConfig={() => boardList.edit({ query: '' })}
|
||||
hide={this.hide}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
protected openDialog = async (
|
||||
previousBoardConfig?: BoardsConfig.Config
|
||||
): Promise<void> => {
|
||||
const selectedBoardConfig =
|
||||
await this.props.commands.executeCommand<BoardsConfig.Config>(
|
||||
OpenBoardsConfig.Commands.OPEN_DIALOG.id
|
||||
);
|
||||
if (
|
||||
previousBoardConfig &&
|
||||
(!selectedBoardConfig?.selectedPort ||
|
||||
!selectedBoardConfig?.selectedBoard)
|
||||
) {
|
||||
this.props.boardsServiceProvider.boardsConfig = previousBoardConfig;
|
||||
}
|
||||
};
|
||||
}
|
||||
export namespace BoardsToolBarItem {
|
||||
export interface Props {
|
||||
@ -293,7 +332,7 @@ export namespace BoardsToolBarItem {
|
||||
}
|
||||
|
||||
export interface State {
|
||||
availableBoards: AvailableBoard[];
|
||||
boardList: BoardListUI;
|
||||
coords: BoardsDropDownListCoords | 'hidden';
|
||||
}
|
||||
}
|
||||
@ -304,19 +343,10 @@ function iconNameFromProtocol(protocol: string): string {
|
||||
return 'fa-arduino-technology-usb';
|
||||
case 'network':
|
||||
return 'fa-arduino-technology-connection';
|
||||
/*
|
||||
Bluetooth ports are not listed yet from the CLI;
|
||||
Not sure about the naming ('bluetooth'); make sure it's correct before uncommenting the following lines
|
||||
*/
|
||||
// case 'bluetooth':
|
||||
// return 'fa-arduino-technology-bluetooth';
|
||||
// it is fine to assign dedicated icons to the protocols used by the official boards,
|
||||
// but other than that it is best to avoid implementing any special handling
|
||||
// for specific protocols in the IDE codebase.
|
||||
default:
|
||||
return 'fa-arduino-technology-3dimensionscube';
|
||||
}
|
||||
}
|
||||
|
||||
function portLabel(portName?: string): string {
|
||||
return portName
|
||||
? nls.localize('arduino/board/portLabel', 'Port: {0}', portName)
|
||||
: nls.localize('arduino/board/disconnected', 'Disconnected');
|
||||
}
|
||||
|
@ -1,57 +1,58 @@
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import {
|
||||
DisposableCollection,
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { BoardsConfig } from '../boards/boards-config';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu/menu-model-registry';
|
||||
import type { MenuPath } from '@theia/core/lib/common/menu/menu-types';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { MainMenuManager } from '../../common/main-menu-manager';
|
||||
import {
|
||||
BoardsService,
|
||||
BoardWithPackage,
|
||||
createPlatformIdentifier,
|
||||
getBoardInfo,
|
||||
InstalledBoardWithPackage,
|
||||
platformIdentifierEquals,
|
||||
Port,
|
||||
serializePlatformIdentifier,
|
||||
} from '../../common/protocol';
|
||||
import type { BoardList } from '../../common/protocol/board-list';
|
||||
import { BoardsListWidget } from '../boards/boards-list-widget';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import {
|
||||
ArduinoMenus,
|
||||
PlaceholderMenuNode,
|
||||
unregisterSubmenu,
|
||||
} from '../menu/arduino-menus';
|
||||
import {
|
||||
BoardsService,
|
||||
InstalledBoardWithPackage,
|
||||
AvailablePorts,
|
||||
Port,
|
||||
getBoardInfo,
|
||||
} from '../../common/protocol';
|
||||
import { SketchContribution, Command, CommandRegistry } from './contribution';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import { Command, CommandRegistry, SketchContribution } from './contribution';
|
||||
|
||||
@injectable()
|
||||
export class BoardSelection extends SketchContribution {
|
||||
@inject(CommandRegistry)
|
||||
protected readonly commandRegistry: CommandRegistry;
|
||||
|
||||
private readonly commandRegistry: CommandRegistry;
|
||||
@inject(MainMenuManager)
|
||||
protected readonly mainMenuManager: MainMenuManager;
|
||||
|
||||
private readonly mainMenuManager: MainMenuManager;
|
||||
@inject(MenuModelRegistry)
|
||||
protected readonly menuModelRegistry: MenuModelRegistry;
|
||||
|
||||
private readonly menuModelRegistry: MenuModelRegistry;
|
||||
@inject(NotificationCenter)
|
||||
protected readonly notificationCenter: NotificationCenter;
|
||||
|
||||
private readonly notificationCenter: NotificationCenter;
|
||||
@inject(BoardsService)
|
||||
protected readonly boardsService: BoardsService;
|
||||
|
||||
private readonly boardsService: BoardsService;
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
|
||||
protected readonly toDisposeBeforeMenuRebuild = new DisposableCollection();
|
||||
private readonly toDisposeBeforeMenuRebuild = new DisposableCollection();
|
||||
// do not query installed platforms on every change
|
||||
private _installedBoards: Deferred<InstalledBoardWithPackage[]> | undefined;
|
||||
|
||||
override registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(BoardSelection.Commands.GET_BOARD_INFO, {
|
||||
execute: async () => {
|
||||
const boardInfo = await getBoardInfo(
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort,
|
||||
this.boardsService.getState()
|
||||
this.boardsServiceProvider.boardList
|
||||
);
|
||||
if (typeof boardInfo === 'string') {
|
||||
this.messageService.info(boardInfo);
|
||||
@ -76,34 +77,35 @@ SN: ${SN}
|
||||
}
|
||||
|
||||
override onStart(): void {
|
||||
this.notificationCenter.onPlatformDidInstall(() => this.updateMenus());
|
||||
this.notificationCenter.onPlatformDidUninstall(() => this.updateMenus());
|
||||
this.boardsServiceProvider.onBoardsConfigChanged(() => this.updateMenus());
|
||||
this.boardsServiceProvider.onAvailableBoardsChanged(() =>
|
||||
this.updateMenus()
|
||||
);
|
||||
this.boardsServiceProvider.onAvailablePortsChanged(() =>
|
||||
this.updateMenus()
|
||||
this.notificationCenter.onPlatformDidInstall(() => this.updateMenus(true));
|
||||
this.notificationCenter.onPlatformDidUninstall(() =>
|
||||
this.updateMenus(true)
|
||||
);
|
||||
this.boardsServiceProvider.onBoardListDidChange(() => this.updateMenus());
|
||||
}
|
||||
|
||||
override async onReady(): Promise<void> {
|
||||
this.updateMenus();
|
||||
}
|
||||
|
||||
protected async updateMenus(): Promise<void> {
|
||||
const [installedBoards, availablePorts, config] = await Promise.all([
|
||||
this.installedBoards(),
|
||||
this.boardsService.getState(),
|
||||
this.boardsServiceProvider.boardsConfig,
|
||||
]);
|
||||
this.rebuildMenus(installedBoards, availablePorts, config);
|
||||
private async updateMenus(discardCache = false): Promise<void> {
|
||||
if (discardCache) {
|
||||
this._installedBoards?.reject();
|
||||
this._installedBoards = undefined;
|
||||
}
|
||||
if (!this._installedBoards) {
|
||||
this._installedBoards = new Deferred();
|
||||
this.installedBoards().then((installedBoards) =>
|
||||
this._installedBoards?.resolve(installedBoards)
|
||||
);
|
||||
}
|
||||
const installedBoards = await this._installedBoards.promise;
|
||||
this.rebuildMenus(installedBoards, this.boardsServiceProvider.boardList);
|
||||
}
|
||||
|
||||
protected rebuildMenus(
|
||||
private rebuildMenus(
|
||||
installedBoards: InstalledBoardWithPackage[],
|
||||
availablePorts: AvailablePorts,
|
||||
config: BoardsConfig.Config
|
||||
boardList: BoardList
|
||||
): void {
|
||||
this.toDisposeBeforeMenuRebuild.dispose();
|
||||
|
||||
@ -112,7 +114,8 @@ SN: ${SN}
|
||||
...ArduinoMenus.TOOLS__BOARD_SELECTION_GROUP,
|
||||
'1_boards',
|
||||
];
|
||||
const boardsSubmenuLabel = config.selectedBoard?.name;
|
||||
const { selectedBoard, selectedPort } = boardList.boardsConfig;
|
||||
const boardsSubmenuLabel = selectedBoard?.name;
|
||||
// Note: The submenu order starts from `100` because `Auto Format`, `Serial Monitor`, etc starts from `0` index.
|
||||
// The board specific items, and the rest, have order with `z`. We needed something between `0` and `z` with natural-order.
|
||||
this.menuModelRegistry.registerSubmenu(
|
||||
@ -132,7 +135,7 @@ SN: ${SN}
|
||||
|
||||
// Ports submenu
|
||||
const portsSubmenuPath = ArduinoMenus.TOOLS__PORTS_SUBMENU;
|
||||
const portsSubmenuLabel = config.selectedPort?.address;
|
||||
const portsSubmenuLabel = selectedPort?.address;
|
||||
this.menuModelRegistry.registerSubmenu(
|
||||
portsSubmenuPath,
|
||||
nls.localize(
|
||||
@ -171,69 +174,116 @@ SN: ${SN}
|
||||
label: `${BoardsListWidget.WIDGET_LABEL}...`,
|
||||
});
|
||||
|
||||
const selectedBoardPlatformId = selectedBoard
|
||||
? createPlatformIdentifier(selectedBoard)
|
||||
: undefined;
|
||||
|
||||
// Keys are the vendor IDs
|
||||
type BoardsPerVendor = Record<string, BoardWithPackage[]>;
|
||||
// Group boards by their platform names. The keys are the platform names as menu labels.
|
||||
// If there is a platform name (menu label) collision, refine the menu label with the vendor ID.
|
||||
const groupedBoards = new Map<string, BoardsPerVendor>();
|
||||
for (const board of installedBoards) {
|
||||
const { packageId, packageName } = board;
|
||||
const { vendorId } = packageId;
|
||||
let boardsPerPackageName = groupedBoards.get(packageName);
|
||||
if (!boardsPerPackageName) {
|
||||
boardsPerPackageName = {} as BoardsPerVendor;
|
||||
groupedBoards.set(packageName, boardsPerPackageName);
|
||||
}
|
||||
let boardPerVendor: BoardWithPackage[] | undefined =
|
||||
boardsPerPackageName[vendorId];
|
||||
if (!boardPerVendor) {
|
||||
boardPerVendor = [];
|
||||
boardsPerPackageName[vendorId] = boardPerVendor;
|
||||
}
|
||||
boardPerVendor.push(board);
|
||||
}
|
||||
|
||||
// Installed boards
|
||||
installedBoards.forEach((board, index) => {
|
||||
const { packageId, packageName, fqbn, name, manuallyInstalled } = board;
|
||||
Array.from(groupedBoards.entries()).forEach(
|
||||
([packageName, boardsPerPackage]) => {
|
||||
const useVendorSuffix = Object.keys(boardsPerPackage).length > 1;
|
||||
Object.entries(boardsPerPackage).forEach(([vendorId, boards]) => {
|
||||
let platformMenuPath: MenuPath | undefined = undefined;
|
||||
boards.forEach((board, index) => {
|
||||
const { packageId, fqbn, name, manuallyInstalled } = board;
|
||||
// create the platform submenu once.
|
||||
// creating and registering the same submenu twice in Theia is a noop, though.
|
||||
if (!platformMenuPath) {
|
||||
let packageLabel =
|
||||
packageName +
|
||||
`${
|
||||
manuallyInstalled
|
||||
? nls.localize(
|
||||
'arduino/board/inSketchbook',
|
||||
' (in Sketchbook)'
|
||||
)
|
||||
: ''
|
||||
}`;
|
||||
if (
|
||||
selectedBoardPlatformId &&
|
||||
platformIdentifierEquals(packageId, selectedBoardPlatformId)
|
||||
) {
|
||||
packageLabel = `● ${packageLabel}`;
|
||||
}
|
||||
if (useVendorSuffix) {
|
||||
packageLabel += ` (${vendorId})`;
|
||||
}
|
||||
// Platform submenu
|
||||
platformMenuPath = [
|
||||
...boardsPackagesGroup,
|
||||
serializePlatformIdentifier(packageId),
|
||||
];
|
||||
this.menuModelRegistry.registerSubmenu(
|
||||
platformMenuPath,
|
||||
packageLabel,
|
||||
{
|
||||
order: packageName.toLowerCase(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const packageLabel =
|
||||
packageName +
|
||||
`${
|
||||
manuallyInstalled
|
||||
? nls.localize('arduino/board/inSketchbook', ' (in Sketchbook)')
|
||||
: ''
|
||||
}`;
|
||||
// Platform submenu
|
||||
const platformMenuPath = [...boardsPackagesGroup, packageId];
|
||||
// Note: Registering the same submenu twice is a noop. No need to group the boards per platform.
|
||||
this.menuModelRegistry.registerSubmenu(platformMenuPath, packageLabel, {
|
||||
order: packageName.toLowerCase(),
|
||||
});
|
||||
|
||||
const id = `arduino-select-board--${fqbn}`;
|
||||
const command = { id };
|
||||
const handler = {
|
||||
execute: () => {
|
||||
if (
|
||||
fqbn !== this.boardsServiceProvider.boardsConfig.selectedBoard?.fqbn
|
||||
) {
|
||||
this.boardsServiceProvider.boardsConfig = {
|
||||
selectedBoard: {
|
||||
name,
|
||||
fqbn,
|
||||
port: this.boardsServiceProvider.boardsConfig.selectedBoard
|
||||
?.port, // TODO: verify!
|
||||
},
|
||||
selectedPort:
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort,
|
||||
const id = `arduino-select-board--${fqbn}`;
|
||||
const command = { id };
|
||||
const handler = {
|
||||
execute: () =>
|
||||
this.boardsServiceProvider.updateConfig({
|
||||
name: name,
|
||||
fqbn: fqbn,
|
||||
}),
|
||||
isToggled: () => fqbn === selectedBoard?.fqbn,
|
||||
};
|
||||
}
|
||||
},
|
||||
isToggled: () =>
|
||||
fqbn === this.boardsServiceProvider.boardsConfig.selectedBoard?.fqbn,
|
||||
};
|
||||
|
||||
// Board menu
|
||||
const menuAction = {
|
||||
commandId: id,
|
||||
label: name,
|
||||
order: String(index).padStart(4), // pads with leading zeros for alphanumeric sort where order is 1, 2, 11, and NOT 1, 11, 2
|
||||
};
|
||||
this.commandRegistry.registerCommand(command, handler);
|
||||
this.toDisposeBeforeMenuRebuild.push(
|
||||
Disposable.create(() => this.commandRegistry.unregisterCommand(command))
|
||||
);
|
||||
this.menuModelRegistry.registerMenuAction(platformMenuPath, menuAction);
|
||||
// Note: we do not dispose the menu actions individually. Calling `unregisterSubmenu` on the parent will wipe the children menu nodes recursively.
|
||||
});
|
||||
// Board menu
|
||||
const menuAction = {
|
||||
commandId: id,
|
||||
label: name,
|
||||
order: String(index).padStart(4), // pads with leading zeros for alphanumeric sort where order is 1, 2, 11, and NOT 1, 11, 2
|
||||
};
|
||||
this.commandRegistry.registerCommand(command, handler);
|
||||
this.toDisposeBeforeMenuRebuild.push(
|
||||
Disposable.create(() =>
|
||||
this.commandRegistry.unregisterCommand(command)
|
||||
)
|
||||
);
|
||||
this.menuModelRegistry.registerMenuAction(
|
||||
platformMenuPath,
|
||||
menuAction
|
||||
);
|
||||
// Note: we do not dispose the menu actions individually. Calling `unregisterSubmenu` on the parent will wipe the children menu nodes recursively.
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Installed ports
|
||||
// Detected ports
|
||||
const registerPorts = (
|
||||
protocol: string,
|
||||
protocolOrder: number,
|
||||
ports: AvailablePorts
|
||||
ports: ReturnType<BoardList['ports']>,
|
||||
protocolOrder: number
|
||||
) => {
|
||||
const portIDs = Object.keys(ports);
|
||||
if (!portIDs.length) {
|
||||
if (!ports.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -258,46 +308,26 @@ SN: ${SN}
|
||||
)
|
||||
);
|
||||
|
||||
// First we show addresses with recognized boards connected,
|
||||
// then all the rest.
|
||||
const sortedIDs = Object.keys(ports).sort(
|
||||
(left: string, right: string): number => {
|
||||
const [, leftBoards] = ports[left];
|
||||
const [, rightBoards] = ports[right];
|
||||
return rightBoards.length - leftBoards.length;
|
||||
}
|
||||
);
|
||||
|
||||
for (let i = 0; i < sortedIDs.length; i++) {
|
||||
const portID = sortedIDs[i];
|
||||
const [port, boards] = ports[portID];
|
||||
for (let i = 0; i < ports.length; i++) {
|
||||
const { port, boards } = ports[i];
|
||||
const portKey = Port.keyOf(port);
|
||||
let label = `${port.addressLabel}`;
|
||||
if (boards.length) {
|
||||
if (boards?.length) {
|
||||
const boardsList = boards.map((board) => board.name).join(', ');
|
||||
label = `${label} (${boardsList})`;
|
||||
}
|
||||
const id = `arduino-select-port--${portID}`;
|
||||
const id = `arduino-select-port--${portKey}`;
|
||||
const command = { id };
|
||||
const handler = {
|
||||
execute: () => {
|
||||
if (
|
||||
!Port.sameAs(
|
||||
port,
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort
|
||||
)
|
||||
) {
|
||||
this.boardsServiceProvider.boardsConfig = {
|
||||
selectedBoard:
|
||||
this.boardsServiceProvider.boardsConfig.selectedBoard,
|
||||
selectedPort: port,
|
||||
};
|
||||
}
|
||||
this.boardsServiceProvider.updateConfig({
|
||||
protocol: port.protocol,
|
||||
address: port.address,
|
||||
});
|
||||
},
|
||||
isToggled: () => {
|
||||
return i === ports.matchingIndex;
|
||||
},
|
||||
isToggled: () =>
|
||||
Port.sameAs(
|
||||
port,
|
||||
this.boardsServiceProvider.boardsConfig.selectedPort
|
||||
),
|
||||
};
|
||||
const menuAction = {
|
||||
commandId: id,
|
||||
@ -314,22 +344,12 @@ SN: ${SN}
|
||||
}
|
||||
};
|
||||
|
||||
const grouped = AvailablePorts.groupByProtocol(availablePorts);
|
||||
const groupedPorts = boardList.portsGroupedByProtocol();
|
||||
let protocolOrder = 100;
|
||||
// We first show serial and network ports, then all the rest
|
||||
['serial', 'network'].forEach((protocol) => {
|
||||
const ports = grouped.get(protocol);
|
||||
if (ports) {
|
||||
registerPorts(protocol, protocolOrder, ports);
|
||||
grouped.delete(protocol);
|
||||
protocolOrder = protocolOrder + 100;
|
||||
}
|
||||
Object.entries(groupedPorts).forEach(([protocol, ports]) => {
|
||||
registerPorts(protocol, ports, protocolOrder);
|
||||
protocolOrder += 100;
|
||||
});
|
||||
grouped.forEach((ports, protocol) => {
|
||||
registerPorts(protocol, protocolOrder, ports);
|
||||
protocolOrder = protocolOrder + 100;
|
||||
});
|
||||
|
||||
this.mainMenuManager.update();
|
||||
}
|
||||
|
||||
|
@ -1,67 +1,66 @@
|
||||
import PQueue from 'p-queue';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { BoardsServiceProvider } from './boards-service-provider';
|
||||
import { Board, ConfigOption, Programmer } from '../../common/protocol';
|
||||
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
|
||||
import { BoardsDataStore } from './boards-data-store';
|
||||
import { MainMenuManager } from '../../common/main-menu-manager';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import PQueue from 'p-queue';
|
||||
import {
|
||||
BoardIdentifier,
|
||||
ConfigOption,
|
||||
isBoardIdentifierChangeEvent,
|
||||
Programmer,
|
||||
} from '../../common/protocol';
|
||||
import { BoardsDataStore } from '../boards/boards-data-store';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import { ArduinoMenus, unregisterSubmenu } from '../menu/arduino-menus';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import {
|
||||
CommandRegistry,
|
||||
Contribution,
|
||||
MenuModelRegistry,
|
||||
} from './contribution';
|
||||
|
||||
@injectable()
|
||||
export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
|
||||
export class BoardsDataMenuUpdater extends Contribution {
|
||||
@inject(CommandRegistry)
|
||||
protected readonly commandRegistry: CommandRegistry;
|
||||
|
||||
private readonly commandRegistry: CommandRegistry;
|
||||
@inject(MenuModelRegistry)
|
||||
protected readonly menuRegistry: MenuModelRegistry;
|
||||
|
||||
@inject(MainMenuManager)
|
||||
protected readonly mainMenuManager: MainMenuManager;
|
||||
|
||||
private readonly menuRegistry: MenuModelRegistry;
|
||||
@inject(BoardsDataStore)
|
||||
protected readonly boardsDataStore: BoardsDataStore;
|
||||
|
||||
private readonly boardsDataStore: BoardsDataStore;
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
|
||||
@inject(FrontendApplicationStateService)
|
||||
private readonly appStateService: FrontendApplicationStateService;
|
||||
private readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||
private readonly toDisposeOnBoardChange = new DisposableCollection();
|
||||
|
||||
protected readonly queue = new PQueue({ autoStart: true, concurrency: 1 });
|
||||
protected readonly toDisposeOnBoardChange = new DisposableCollection();
|
||||
|
||||
async onStart(): Promise<void> {
|
||||
this.appStateService
|
||||
.reachedState('ready')
|
||||
.then(() =>
|
||||
this.updateMenuActions(
|
||||
this.boardsServiceClient.boardsConfig.selectedBoard
|
||||
)
|
||||
);
|
||||
override onStart(): void {
|
||||
this.boardsDataStore.onChanged(() =>
|
||||
this.updateMenuActions(
|
||||
this.boardsServiceClient.boardsConfig.selectedBoard
|
||||
this.boardsServiceProvider.boardsConfig.selectedBoard
|
||||
)
|
||||
);
|
||||
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) =>
|
||||
this.updateMenuActions(selectedBoard)
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
|
||||
if (isBoardIdentifierChangeEvent(event)) {
|
||||
this.updateMenuActions(event.selectedBoard);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
override onReady(): void {
|
||||
this.boardsServiceProvider.ready.then(() =>
|
||||
this.updateMenuActions(
|
||||
this.boardsServiceProvider.boardsConfig.selectedBoard
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
protected async updateMenuActions(
|
||||
selectedBoard: Board | undefined
|
||||
private async updateMenuActions(
|
||||
selectedBoard: BoardIdentifier | undefined
|
||||
): Promise<void> {
|
||||
return this.queue.add(async () => {
|
||||
this.toDisposeOnBoardChange.dispose();
|
||||
this.mainMenuManager.update();
|
||||
this.menuManager.update();
|
||||
if (selectedBoard) {
|
||||
const { fqbn } = selectedBoard;
|
||||
if (fqbn) {
|
||||
@ -172,7 +171,7 @@ export class BoardsDataMenuUpdater implements FrontendApplicationContribution {
|
||||
]);
|
||||
}
|
||||
}
|
||||
this.mainMenuManager.update();
|
||||
this.menuManager.update();
|
||||
}
|
||||
}
|
||||
});
|
@ -5,8 +5,10 @@ import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
import {
|
||||
Board,
|
||||
BoardIdentifier,
|
||||
BoardsService,
|
||||
ExecutableService,
|
||||
isBoardIdentifierChangeEvent,
|
||||
Sketch,
|
||||
} from '../../common/protocol';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
@ -88,9 +90,11 @@ export class Debug extends SketchContribution {
|
||||
: Debug.Commands.START_DEBUGGING.label
|
||||
}`)
|
||||
);
|
||||
this.boardsServiceProvider.onBoardsConfigChanged(({ selectedBoard }) =>
|
||||
this.refreshState(selectedBoard)
|
||||
);
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
|
||||
if (isBoardIdentifierChangeEvent(event)) {
|
||||
this.refreshState(event.selectedBoard);
|
||||
}
|
||||
});
|
||||
this.notificationCenter.onPlatformDidInstall(() => this.refreshState());
|
||||
this.notificationCenter.onPlatformDidUninstall(() => this.refreshState());
|
||||
}
|
||||
@ -169,7 +173,7 @@ export class Debug extends SketchContribution {
|
||||
}
|
||||
|
||||
private async startDebug(
|
||||
board: Board | undefined = this.boardsServiceProvider.boardsConfig
|
||||
board: BoardIdentifier | undefined = this.boardsServiceProvider.boardsConfig
|
||||
.selectedBoard
|
||||
): Promise<void> {
|
||||
if (!board) {
|
||||
|
@ -28,6 +28,8 @@ import {
|
||||
CoreService,
|
||||
SketchesService,
|
||||
Sketch,
|
||||
isBoardIdentifierChangeEvent,
|
||||
BoardIdentifier,
|
||||
} from '../../common/protocol';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { unregisterSubmenu } from '../menu/arduino-menus';
|
||||
@ -108,7 +110,7 @@ export abstract class Examples extends SketchContribution {
|
||||
protected readonly coreService: CoreService;
|
||||
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
protected readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
|
||||
@inject(NotificationCenter)
|
||||
protected readonly notificationCenter: NotificationCenter;
|
||||
@ -117,12 +119,14 @@ export abstract class Examples extends SketchContribution {
|
||||
|
||||
protected override init(): void {
|
||||
super.init();
|
||||
this.boardsServiceClient.onBoardsConfigChanged(({ selectedBoard }) =>
|
||||
this.handleBoardChanged(selectedBoard)
|
||||
);
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
|
||||
if (isBoardIdentifierChangeEvent(event)) {
|
||||
this.handleBoardChanged(event.selectedBoard);
|
||||
}
|
||||
});
|
||||
this.notificationCenter.onDidReinitialize(() =>
|
||||
this.update({
|
||||
board: this.boardsServiceClient.boardsConfig.selectedBoard,
|
||||
board: this.boardsServiceProvider.boardsConfig.selectedBoard,
|
||||
// No force refresh. The core client was already refreshed.
|
||||
})
|
||||
);
|
||||
@ -134,7 +138,7 @@ export abstract class Examples extends SketchContribution {
|
||||
}
|
||||
|
||||
protected abstract update(options?: {
|
||||
board?: Board | undefined;
|
||||
board?: BoardIdentifier | undefined;
|
||||
forceRefresh?: boolean;
|
||||
}): void;
|
||||
|
||||
@ -225,7 +229,7 @@ export abstract class Examples extends SketchContribution {
|
||||
protected createHandler(uri: string): CommandHandler {
|
||||
const forceUpdate = () =>
|
||||
this.update({
|
||||
board: this.boardsServiceClient.boardsConfig.selectedBoard,
|
||||
board: this.boardsServiceProvider.boardsConfig.selectedBoard,
|
||||
forceRefresh: true,
|
||||
});
|
||||
return {
|
||||
@ -306,7 +310,7 @@ export class LibraryExamples extends Examples {
|
||||
|
||||
protected override async update(
|
||||
options: { board?: Board; forceRefresh?: boolean } = {
|
||||
board: this.boardsServiceClient.boardsConfig.selectedBoard,
|
||||
board: this.boardsServiceProvider.boardsConfig.selectedBoard,
|
||||
}
|
||||
): Promise<void> {
|
||||
const { board, forceRefresh } = options;
|
||||
|
@ -37,7 +37,7 @@ export class IncludeLibrary extends SketchContribution {
|
||||
protected readonly notificationCenter: NotificationCenter;
|
||||
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
protected readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
|
||||
@inject(LibraryService)
|
||||
protected readonly libraryService: LibraryService;
|
||||
@ -46,7 +46,7 @@ export class IncludeLibrary extends SketchContribution {
|
||||
protected readonly toDispose = new DisposableCollection();
|
||||
|
||||
override onStart(): void {
|
||||
this.boardsServiceClient.onBoardsConfigChanged(() =>
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange(() =>
|
||||
this.updateMenuActions()
|
||||
);
|
||||
this.notificationCenter.onLibraryDidInstall(() => this.updateMenuActions());
|
||||
@ -98,7 +98,7 @@ export class IncludeLibrary extends SketchContribution {
|
||||
this.toDispose.dispose();
|
||||
this.mainMenuManager.update();
|
||||
const libraries: LibraryPackage[] = [];
|
||||
const fqbn = this.boardsServiceClient.boardsConfig.selectedBoard?.fqbn;
|
||||
const fqbn = this.boardsServiceProvider.boardsConfig.selectedBoard?.fqbn;
|
||||
// Show all libraries, when no board is selected.
|
||||
// Otherwise, show libraries only for the selected board.
|
||||
libraries.push(...(await this.libraryService.list({ fqbn })));
|
||||
|
@ -7,12 +7,13 @@ import { Mutex } from 'async-mutex';
|
||||
import {
|
||||
ArduinoDaemon,
|
||||
assertSanitizedFqbn,
|
||||
BoardIdentifier,
|
||||
BoardsService,
|
||||
ExecutableService,
|
||||
isBoardIdentifierChangeEvent,
|
||||
sanitizeFqbn,
|
||||
} from '../../common/protocol';
|
||||
import { CurrentSketch } from '../sketches-service-client-impl';
|
||||
import { BoardsConfig } from '../boards/boards-config';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import { HostedPluginEvents } from '../hosted-plugin-events';
|
||||
import { NotificationCenter } from '../notification-center';
|
||||
@ -48,7 +49,7 @@ export class InoLanguage extends SketchContribution {
|
||||
|
||||
override onReady(): void {
|
||||
const start = (
|
||||
{ selectedBoard }: BoardsConfig.Config,
|
||||
selectedBoard: BoardIdentifier | undefined,
|
||||
forceStart = false
|
||||
) => {
|
||||
if (selectedBoard) {
|
||||
@ -59,12 +60,16 @@ export class InoLanguage extends SketchContribution {
|
||||
}
|
||||
};
|
||||
const forceRestart = () => {
|
||||
start(this.boardsServiceProvider.boardsConfig, true);
|
||||
start(this.boardsServiceProvider.boardsConfig.selectedBoard, true);
|
||||
};
|
||||
this.toDispose.pushAll([
|
||||
this.boardsServiceProvider.onBoardsConfigChanged(start),
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange((event) => {
|
||||
if (isBoardIdentifierChangeEvent(event)) {
|
||||
start(event.selectedBoard);
|
||||
}
|
||||
}),
|
||||
this.hostedPluginEvents.onPluginsDidStart(() =>
|
||||
start(this.boardsServiceProvider.boardsConfig)
|
||||
start(this.boardsServiceProvider.boardsConfig.selectedBoard)
|
||||
),
|
||||
this.hostedPluginEvents.onPluginsWillUnload(
|
||||
() => (this.languageServerFqbn = undefined)
|
||||
@ -101,12 +106,14 @@ export class InoLanguage extends SketchContribution {
|
||||
matchingFqbn &&
|
||||
boardsConfig.selectedBoard?.fqbn === matchingFqbn
|
||||
) {
|
||||
start(boardsConfig);
|
||||
start(boardsConfig.selectedBoard);
|
||||
}
|
||||
}
|
||||
}),
|
||||
]);
|
||||
start(this.boardsServiceProvider.boardsConfig);
|
||||
this.boardsServiceProvider.ready.then(() =>
|
||||
start(this.boardsServiceProvider.boardsConfig.selectedBoard)
|
||||
);
|
||||
}
|
||||
|
||||
onStop(): void {
|
||||
|
@ -1,25 +1,18 @@
|
||||
import { CommandRegistry } from '@theia/core';
|
||||
import type { Command, CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import type { EditBoardsConfigActionParams } from '../../common/protocol/board-list';
|
||||
import { BoardsConfigDialog } from '../boards/boards-config-dialog';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import { Contribution, Command } from './contribution';
|
||||
import { Contribution } from './contribution';
|
||||
|
||||
@injectable()
|
||||
export class OpenBoardsConfig extends Contribution {
|
||||
@inject(BoardsServiceProvider)
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
|
||||
@inject(BoardsConfigDialog)
|
||||
private readonly boardsConfigDialog: BoardsConfigDialog;
|
||||
|
||||
override registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(OpenBoardsConfig.Commands.OPEN_DIALOG, {
|
||||
execute: async (query?: string | undefined) => {
|
||||
const boardsConfig = await this.boardsConfigDialog.open(query);
|
||||
if (boardsConfig) {
|
||||
return (this.boardsServiceProvider.boardsConfig = boardsConfig);
|
||||
}
|
||||
},
|
||||
execute: async (params?: EditBoardsConfigActionParams) =>
|
||||
this.boardsConfigDialog.open(params),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,10 @@ import {
|
||||
} from '@theia/core/lib/browser/status-bar/status-bar';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { BoardsConfig } from '../boards/boards-config';
|
||||
import type {
|
||||
BoardList,
|
||||
BoardListItem,
|
||||
} from '../../common/protocol/board-list';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import { Contribution } from './contribution';
|
||||
|
||||
@ -12,21 +15,21 @@ import { Contribution } from './contribution';
|
||||
export class SelectedBoard extends Contribution {
|
||||
@inject(StatusBar)
|
||||
private readonly statusBar: StatusBar;
|
||||
|
||||
@inject(BoardsServiceProvider)
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
|
||||
override onStart(): void {
|
||||
this.boardsServiceProvider.onBoardsConfigChanged((config) =>
|
||||
this.update(config)
|
||||
this.boardsServiceProvider.onBoardListDidChange(() =>
|
||||
this.update(this.boardsServiceProvider.boardList)
|
||||
);
|
||||
}
|
||||
|
||||
override onReady(): void {
|
||||
this.update(this.boardsServiceProvider.boardsConfig);
|
||||
this.update(this.boardsServiceProvider.boardList);
|
||||
}
|
||||
|
||||
private update({ selectedBoard, selectedPort }: BoardsConfig.Config): void {
|
||||
private update(boardList: BoardList): void {
|
||||
const { selectedBoard, selectedPort } = boardList.boardsConfig;
|
||||
this.statusBar.setElement('arduino-selected-board', {
|
||||
alignment: StatusBarAlignment.RIGHT,
|
||||
text: selectedBoard
|
||||
@ -38,17 +41,30 @@ export class SelectedBoard extends Contribution {
|
||||
className: 'arduino-selected-board',
|
||||
});
|
||||
if (selectedBoard) {
|
||||
const notConnectedLabel = nls.localize(
|
||||
'arduino/common/notConnected',
|
||||
'[not connected]'
|
||||
);
|
||||
let portLabel = notConnectedLabel;
|
||||
if (selectedPort) {
|
||||
portLabel = nls.localize(
|
||||
'arduino/common/selectedOn',
|
||||
'on {0}',
|
||||
selectedPort.address
|
||||
);
|
||||
const selectedItem: BoardListItem | undefined =
|
||||
boardList.items[boardList.selectedIndex];
|
||||
if (!selectedItem) {
|
||||
portLabel += ` ${notConnectedLabel}`; // append ` [not connected]` when the port is selected but it's not detected by the CLI
|
||||
}
|
||||
}
|
||||
this.statusBar.setElement('arduino-selected-port', {
|
||||
alignment: StatusBarAlignment.RIGHT,
|
||||
text: selectedPort
|
||||
? nls.localize(
|
||||
'arduino/common/selectedOn',
|
||||
'on {0}',
|
||||
selectedPort.address
|
||||
)
|
||||
: nls.localize('arduino/common/notConnected', '[not connected]'),
|
||||
text: portLabel,
|
||||
className: 'arduino-selected-port',
|
||||
});
|
||||
} else {
|
||||
this.statusBar.removeElement('arduino-selected-port');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,16 @@ import type { ArduinoState } from 'vscode-arduino-api';
|
||||
import {
|
||||
BoardsService,
|
||||
CompileSummary,
|
||||
Port,
|
||||
isCompileSummary,
|
||||
BoardsConfig,
|
||||
PortIdentifier,
|
||||
resolveDetectedPort,
|
||||
} from '../../common/protocol';
|
||||
import {
|
||||
toApiBoardDetails,
|
||||
toApiCompileSummary,
|
||||
toApiPort,
|
||||
} from '../../common/protocol/arduino-context-mapper';
|
||||
import type { BoardsConfig } from '../boards/boards-config';
|
||||
import { BoardsDataStore } from '../boards/boards-data-store';
|
||||
import { BoardsServiceProvider } from '../boards/boards-service-provider';
|
||||
import { CurrentSketch } from '../sketches-service-client-impl';
|
||||
@ -44,8 +45,8 @@ export class UpdateArduinoState extends SketchContribution {
|
||||
|
||||
override onStart(): void {
|
||||
this.toDispose.pushAll([
|
||||
this.boardsServiceProvider.onBoardsConfigChanged((config) =>
|
||||
this.updateBoardsConfig(config)
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange(() =>
|
||||
this.updateBoardsConfig(this.boardsServiceProvider.boardsConfig)
|
||||
),
|
||||
this.sketchServiceClient.onCurrentSketchDidChange((sketch) =>
|
||||
this.updateSketchPath(sketch)
|
||||
@ -75,9 +76,7 @@ export class UpdateArduinoState extends SketchContribution {
|
||||
}
|
||||
|
||||
override onReady(): void {
|
||||
this.boardsServiceProvider.reconciled.then(() => {
|
||||
this.updateBoardsConfig(this.boardsServiceProvider.boardsConfig);
|
||||
});
|
||||
this.updateBoardsConfig(this.boardsServiceProvider.boardsConfig); // TODO: verify!
|
||||
this.updateSketchPath(this.sketchServiceClient.tryGetCurrentSketch());
|
||||
this.updateUserDirPath(this.configService.tryGetSketchDirUri());
|
||||
this.updateDataDirPath(this.configService.tryGetDataDirUri());
|
||||
@ -106,9 +105,7 @@ export class UpdateArduinoState extends SketchContribution {
|
||||
});
|
||||
}
|
||||
|
||||
private async updateBoardsConfig(
|
||||
boardsConfig: BoardsConfig.Config
|
||||
): Promise<void> {
|
||||
private async updateBoardsConfig(boardsConfig: BoardsConfig): Promise<void> {
|
||||
const fqbn = boardsConfig.selectedBoard?.fqbn;
|
||||
const port = boardsConfig.selectedPort;
|
||||
await this.updateFqbn(fqbn);
|
||||
@ -146,8 +143,11 @@ export class UpdateArduinoState extends SketchContribution {
|
||||
});
|
||||
}
|
||||
|
||||
private async updatePort(port: Port | undefined): Promise<void> {
|
||||
const apiPort = port && toApiPort(port);
|
||||
private async updatePort(port: PortIdentifier | undefined): Promise<void> {
|
||||
const resolvedPort =
|
||||
port &&
|
||||
resolveDetectedPort(port, this.boardsServiceProvider.detectedPorts);
|
||||
const apiPort = resolvedPort && toApiPort(resolvedPort);
|
||||
return this.updateState({ key: 'port', value: apiPort });
|
||||
}
|
||||
|
||||
@ -171,9 +171,6 @@ export class UpdateArduinoState extends SketchContribution {
|
||||
params: UpdateStateParams<T>
|
||||
): Promise<void> {
|
||||
await this.hostedPluginSupport.didStart;
|
||||
return this.commandService.executeCommand(
|
||||
'arduinoAPI.updateState',
|
||||
params
|
||||
);
|
||||
return this.commandService.executeCommand('arduinoAPI.updateState', params);
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,30 @@
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { CoreService, Port, sanitizeFqbn } from '../../common/protocol';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { CoreService, sanitizeFqbn } from '../../common/protocol';
|
||||
import { ArduinoMenus } from '../menu/arduino-menus';
|
||||
import { CurrentSketch } from '../sketches-service-client-impl';
|
||||
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
|
||||
import {
|
||||
Command,
|
||||
CommandRegistry,
|
||||
MenuModelRegistry,
|
||||
KeybindingRegistry,
|
||||
TabBarToolbarRegistry,
|
||||
CoreServiceContribution,
|
||||
KeybindingRegistry,
|
||||
MenuModelRegistry,
|
||||
TabBarToolbarRegistry,
|
||||
} from './contribution';
|
||||
import { deepClone, nls } from '@theia/core/lib/common';
|
||||
import { CurrentSketch } from '../sketches-service-client-impl';
|
||||
import type { VerifySketchParams } from './verify-sketch';
|
||||
import { UserFields } from './user-fields';
|
||||
import type { VerifySketchParams } from './verify-sketch';
|
||||
|
||||
@injectable()
|
||||
export class UploadSketch extends CoreServiceContribution {
|
||||
@inject(UserFields)
|
||||
private readonly userFields: UserFields;
|
||||
|
||||
private readonly onDidChangeEmitter = new Emitter<void>();
|
||||
private readonly onDidChange = this.onDidChangeEmitter.event;
|
||||
private uploadInProgress = false;
|
||||
|
||||
@inject(UserFields)
|
||||
private readonly userFields: UserFields;
|
||||
|
||||
override registerCommands(registry: CommandRegistry): void {
|
||||
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
|
||||
execute: async () => {
|
||||
@ -107,7 +107,6 @@ export class UploadSketch extends CoreServiceContribution {
|
||||
// uploadInProgress will be set to false whether the upload fails or not
|
||||
this.uploadInProgress = true;
|
||||
this.menuManager.update();
|
||||
this.boardsServiceProvider.snapshotBoardDiscoveryOnUpload();
|
||||
this.onDidChangeEmitter.fire();
|
||||
this.clearVisibleNotification();
|
||||
|
||||
@ -135,12 +134,14 @@ export class UploadSketch extends CoreServiceContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.doWithProgress({
|
||||
const uploadResponse = await this.doWithProgress({
|
||||
progressText: nls.localize('arduino/sketch/uploading', 'Uploading...'),
|
||||
task: (progressId, coreService) =>
|
||||
coreService.upload({ ...uploadOptions, progressId }),
|
||||
keepOutput: true,
|
||||
});
|
||||
// the port update is NOOP if nothing has changed
|
||||
this.boardsServiceProvider.updateConfig(uploadResponse.portAfterUpload);
|
||||
|
||||
this.messageService.info(
|
||||
nls.localize('arduino/sketch/doneUploading', 'Done uploading.'),
|
||||
@ -150,9 +151,10 @@ export class UploadSketch extends CoreServiceContribution {
|
||||
this.userFields.notifyFailedWithError(e);
|
||||
this.handleError(e);
|
||||
} finally {
|
||||
// TODO: here comes the port change if happened during the upload
|
||||
// https://github.com/arduino/arduino-cli/issues/2245
|
||||
this.uploadInProgress = false;
|
||||
this.menuManager.update();
|
||||
this.boardsServiceProvider.attemptPostUploadAutoSelect();
|
||||
this.onDidChangeEmitter.fire();
|
||||
}
|
||||
}
|
||||
@ -174,7 +176,7 @@ export class UploadSketch extends CoreServiceContribution {
|
||||
this.preferences.get('arduino.upload.verify'),
|
||||
this.preferences.get('arduino.upload.verbose'),
|
||||
]);
|
||||
const port = this.maybeUpdatePortProperties(boardsConfig.selectedPort);
|
||||
const port = boardsConfig.selectedPort;
|
||||
return {
|
||||
sketch,
|
||||
fqbn,
|
||||
@ -185,28 +187,6 @@ export class UploadSketch extends CoreServiceContribution {
|
||||
userFields,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a hack to ensure that the port object has the `properties` when uploading.(https://github.com/arduino/arduino-ide/issues/740)
|
||||
* This method works around a bug when restoring a `port` persisted by an older version of IDE2. See the bug [here](https://github.com/arduino/arduino-ide/pull/1335#issuecomment-1224355236).
|
||||
*
|
||||
* Before the upload, this method checks the available ports and makes sure that the `properties` of an available port, and the port selected by the user have the same `properties`.
|
||||
* This method does not update any state (for example, the `BoardsConfig.Config`) but uses the correct `properties` for the `upload`.
|
||||
*/
|
||||
private maybeUpdatePortProperties(port: Port | undefined): Port | undefined {
|
||||
if (port) {
|
||||
const key = Port.keyOf(port);
|
||||
for (const candidate of this.boardsServiceProvider.availablePorts) {
|
||||
if (key === Port.keyOf(candidate) && candidate.properties) {
|
||||
return {
|
||||
...port,
|
||||
properties: deepClone(candidate.properties),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return port;
|
||||
}
|
||||
}
|
||||
|
||||
export namespace UploadSketch {
|
||||
|
@ -21,7 +21,7 @@ export class UserFields extends Contribution {
|
||||
|
||||
protected override init(): void {
|
||||
super.init();
|
||||
this.boardsServiceProvider.onBoardsConfigChanged(async () => {
|
||||
this.boardsServiceProvider.onBoardsConfigDidChange(async () => {
|
||||
const userFields =
|
||||
await this.boardsServiceProvider.selectedBoardUserFields();
|
||||
this.boardRequiresUserFields = userFields.length > 0;
|
||||
@ -43,10 +43,7 @@ export class UserFields extends Contribution {
|
||||
if (!fqbn) {
|
||||
return undefined;
|
||||
}
|
||||
const address =
|
||||
boardsConfig.selectedBoard?.port?.address ||
|
||||
boardsConfig.selectedPort?.address ||
|
||||
'';
|
||||
const address = boardsConfig.selectedPort?.address || '';
|
||||
return fqbn + '|' + address;
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,30 @@
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import React from '@theia/core/shared/react';
|
||||
import Tippy from '@tippyjs/react';
|
||||
import { AvailableBoard } from '../../boards/boards-service-provider';
|
||||
import { CertificateListComponent } from './certificate-list';
|
||||
import { SelectBoardComponent } from './select-board-components';
|
||||
import {
|
||||
BoardList,
|
||||
isInferredBoardListItem,
|
||||
} from '../../../common/protocol/board-list';
|
||||
import {
|
||||
boardIdentifierEquals,
|
||||
portIdentifierEquals,
|
||||
} from '../../../common/protocol/boards-service';
|
||||
import { CertificateAddComponent } from './certificate-add-new';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { CertificateListComponent } from './certificate-list';
|
||||
import {
|
||||
BoardOptionValue,
|
||||
SelectBoardComponent,
|
||||
} from './select-board-components';
|
||||
|
||||
export const CertificateUploaderComponent = ({
|
||||
availableBoards,
|
||||
boardList,
|
||||
certificates,
|
||||
addCertificate,
|
||||
updatableFqbns,
|
||||
uploadCertificates,
|
||||
openContextMenu,
|
||||
}: {
|
||||
availableBoards: AvailableBoard[];
|
||||
boardList: BoardList;
|
||||
certificates: string[];
|
||||
addCertificate: (cert: string) => void;
|
||||
updatableFqbns: string[];
|
||||
@ -33,11 +43,17 @@ export const CertificateUploaderComponent = ({
|
||||
|
||||
const [selectedCerts, setSelectedCerts] = React.useState<string[]>([]);
|
||||
|
||||
const [selectedBoard, setSelectedBoard] =
|
||||
React.useState<AvailableBoard | null>(null);
|
||||
const [selectedItem, setSelectedItem] =
|
||||
React.useState<BoardOptionValue | null>(null);
|
||||
|
||||
const installCertificates = async () => {
|
||||
if (!selectedBoard || !selectedBoard.fqbn || !selectedBoard.port) {
|
||||
if (!selectedItem) {
|
||||
return;
|
||||
}
|
||||
const board = isInferredBoardListItem(selectedItem)
|
||||
? selectedItem.inferredBoard
|
||||
: selectedItem.board;
|
||||
if (!board.fqbn) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -45,8 +61,8 @@ export const CertificateUploaderComponent = ({
|
||||
|
||||
try {
|
||||
await uploadCertificates(
|
||||
selectedBoard.fqbn,
|
||||
selectedBoard.port.address,
|
||||
board.fqbn,
|
||||
selectedItem.port.address,
|
||||
selectedCerts
|
||||
);
|
||||
setInstallFeedback('ok');
|
||||
@ -55,17 +71,29 @@ export const CertificateUploaderComponent = ({
|
||||
}
|
||||
};
|
||||
|
||||
const onBoardSelect = React.useCallback(
|
||||
(board: AvailableBoard) => {
|
||||
const newFqbn = (board && board.fqbn) || null;
|
||||
const prevFqbn = (selectedBoard && selectedBoard.fqbn) || null;
|
||||
const onItemSelect = React.useCallback(
|
||||
(item: BoardOptionValue | null) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
const board = isInferredBoardListItem(item)
|
||||
? item.inferredBoard
|
||||
: item.board;
|
||||
const selectedBoard = isInferredBoardListItem(selectedItem)
|
||||
? selectedItem.inferredBoard
|
||||
: selectedItem?.board;
|
||||
const port = item.port;
|
||||
const selectedPort = selectedItem?.port;
|
||||
|
||||
if (newFqbn !== prevFqbn) {
|
||||
if (
|
||||
!boardIdentifierEquals(board, selectedBoard) ||
|
||||
!portIdentifierEquals(port, selectedPort)
|
||||
) {
|
||||
setInstallFeedback(null);
|
||||
setSelectedBoard(board);
|
||||
setSelectedItem(item);
|
||||
}
|
||||
},
|
||||
[selectedBoard]
|
||||
[selectedItem]
|
||||
);
|
||||
|
||||
return (
|
||||
@ -125,10 +153,10 @@ export const CertificateUploaderComponent = ({
|
||||
<div className="dialogRow">
|
||||
<div className="fl1">
|
||||
<SelectBoardComponent
|
||||
availableBoards={availableBoards}
|
||||
boardList={boardList}
|
||||
updatableFqbns={updatableFqbns}
|
||||
onBoardSelect={onBoardSelect}
|
||||
selectedBoard={selectedBoard}
|
||||
onItemSelect={onItemSelect}
|
||||
selectedItem={selectedItem}
|
||||
busy={installFeedback === 'installing'}
|
||||
/>
|
||||
</div>
|
||||
@ -167,7 +195,7 @@ export const CertificateUploaderComponent = ({
|
||||
type="button"
|
||||
className="theia-button primary install-cert-btn"
|
||||
onClick={installCertificates}
|
||||
disabled={selectedCerts.length === 0 || !selectedBoard}
|
||||
disabled={selectedCerts.length === 0 || !selectedItem}
|
||||
>
|
||||
{nls.localize('arduino/certificate/upload', 'Upload')}
|
||||
</button>
|
||||
|
@ -1,62 +1,51 @@
|
||||
import React from '@theia/core/shared/react';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import {
|
||||
PreferenceScope,
|
||||
PreferenceService,
|
||||
} from '@theia/core/lib/browser/preferences/preference-service';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import type { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import {
|
||||
AvailableBoard,
|
||||
BoardsServiceProvider,
|
||||
} from '../../boards/boards-service-provider';
|
||||
import { CertificateUploaderComponent } from './certificate-uploader-component';
|
||||
import { ArduinoPreferences } from '../../arduino-preferences';
|
||||
import {
|
||||
PreferenceScope,
|
||||
PreferenceService,
|
||||
} from '@theia/core/lib/browser/preferences/preference-service';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { certificateList, sanifyCertString } from './utils';
|
||||
import React from '@theia/core/shared/react';
|
||||
import { ArduinoFirmwareUploader } from '../../../common/protocol/arduino-firmware-uploader';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import { createBoardList } from '../../../common/protocol/board-list';
|
||||
import { ArduinoPreferences } from '../../arduino-preferences';
|
||||
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||
import { CertificateUploaderComponent } from './certificate-uploader-component';
|
||||
import { certificateList, sanifyCertString } from './utils';
|
||||
|
||||
@injectable()
|
||||
export class UploadCertificateDialogWidget extends ReactWidget {
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
@inject(ArduinoPreferences)
|
||||
protected readonly arduinoPreferences: ArduinoPreferences;
|
||||
|
||||
private readonly arduinoPreferences: ArduinoPreferences;
|
||||
@inject(PreferenceService)
|
||||
protected readonly preferenceService: PreferenceService;
|
||||
|
||||
private readonly preferenceService: PreferenceService;
|
||||
@inject(CommandRegistry)
|
||||
protected readonly commandRegistry: CommandRegistry;
|
||||
|
||||
private readonly commandRegistry: CommandRegistry;
|
||||
@inject(ArduinoFirmwareUploader)
|
||||
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
||||
|
||||
private readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
||||
@inject(FrontendApplicationStateService)
|
||||
private readonly appStateService: FrontendApplicationStateService;
|
||||
|
||||
protected certificates: string[] = [];
|
||||
protected updatableFqbns: string[] = [];
|
||||
protected availableBoards: AvailableBoard[] = [];
|
||||
private certificates: string[] = [];
|
||||
private updatableFqbns: string[] = [];
|
||||
private boardList = createBoardList({});
|
||||
|
||||
public busyCallback = (busy: boolean) => {
|
||||
busyCallback = (busy: boolean) => {
|
||||
return;
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.arduinoPreferences.ready.then(() => {
|
||||
@ -81,8 +70,8 @@ export class UploadCertificateDialogWidget extends ReactWidget {
|
||||
})
|
||||
);
|
||||
|
||||
this.boardsServiceClient.onAvailableBoardsChanged((availableBoards) => {
|
||||
this.availableBoards = availableBoards;
|
||||
this.boardsServiceProvider.onBoardListDidChange((boardList) => {
|
||||
this.boardList = boardList;
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
@ -126,7 +115,7 @@ export class UploadCertificateDialogWidget extends ReactWidget {
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
<CertificateUploaderComponent
|
||||
availableBoards={this.availableBoards}
|
||||
boardList={this.boardList}
|
||||
certificates={this.certificates}
|
||||
updatableFqbns={this.updatableFqbns}
|
||||
addCertificate={this.addCertificate.bind(this)}
|
||||
@ -143,7 +132,7 @@ export class UploadCertificateDialogProps extends DialogProps {}
|
||||
@injectable()
|
||||
export class UploadCertificateDialog extends AbstractDialog<void> {
|
||||
@inject(UploadCertificateDialogWidget)
|
||||
protected readonly widget: UploadCertificateDialogWidget;
|
||||
private readonly widget: UploadCertificateDialogWidget;
|
||||
|
||||
private busy = false;
|
||||
|
||||
|
@ -1,37 +1,38 @@
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import React from '@theia/core/shared/react';
|
||||
import { AvailableBoard } from '../../boards/boards-service-provider';
|
||||
import {
|
||||
BoardList,
|
||||
BoardListItemWithBoard,
|
||||
InferredBoardListItem,
|
||||
isInferredBoardListItem,
|
||||
} from '../../../common/protocol/board-list';
|
||||
import { ArduinoSelect } from '../../widgets/arduino-select';
|
||||
|
||||
type BoardOption = { value: string; label: string };
|
||||
export type BoardOptionValue = BoardListItemWithBoard | InferredBoardListItem;
|
||||
type BoardOption = { value: BoardOptionValue | undefined; label: string };
|
||||
|
||||
export const SelectBoardComponent = ({
|
||||
availableBoards,
|
||||
boardList,
|
||||
updatableFqbns,
|
||||
onBoardSelect,
|
||||
selectedBoard,
|
||||
onItemSelect,
|
||||
selectedItem,
|
||||
busy,
|
||||
}: {
|
||||
availableBoards: AvailableBoard[];
|
||||
boardList: BoardList;
|
||||
updatableFqbns: string[];
|
||||
onBoardSelect: (board: AvailableBoard | null) => void;
|
||||
selectedBoard: AvailableBoard | null;
|
||||
onItemSelect: (item: BoardOptionValue | null) => void;
|
||||
selectedItem: BoardOptionValue | null;
|
||||
busy: boolean;
|
||||
}): React.ReactElement => {
|
||||
const [selectOptions, setSelectOptions] = React.useState<BoardOption[]>([]);
|
||||
|
||||
const [selectBoardPlaceholder, setSelectBoardPlaceholder] =
|
||||
React.useState('');
|
||||
const [selectItemPlaceholder, setSelectBoardPlaceholder] = React.useState('');
|
||||
|
||||
const selectOption = React.useCallback(
|
||||
(boardOpt: BoardOption) => {
|
||||
onBoardSelect(
|
||||
(boardOpt &&
|
||||
availableBoards.find((board) => board.fqbn === boardOpt.value)) ||
|
||||
null
|
||||
);
|
||||
(boardOpt: BoardOption | null) => {
|
||||
onItemSelect(boardOpt?.value ?? null);
|
||||
},
|
||||
[availableBoards, onBoardSelect]
|
||||
[onItemSelect]
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
@ -44,26 +45,33 @@ export const SelectBoardComponent = ({
|
||||
'arduino/certificate/selectBoard',
|
||||
'Select a board...'
|
||||
);
|
||||
const updatableBoards = boardList.boards.filter((item) => {
|
||||
const fqbn = (
|
||||
isInferredBoardListItem(item) ? item.inferredBoard : item.board
|
||||
).fqbn;
|
||||
return fqbn && updatableFqbns.includes(fqbn);
|
||||
});
|
||||
let selBoard = -1;
|
||||
const updatableBoards = availableBoards.filter(
|
||||
(board) => board.port && board.fqbn && updatableFqbns.includes(board.fqbn)
|
||||
);
|
||||
const boardsList: BoardOption[] = updatableBoards.map((board, i) => {
|
||||
if (board.selected) {
|
||||
|
||||
const boardOptions: BoardOption[] = updatableBoards.map((item, i) => {
|
||||
if (selectedItem === item) {
|
||||
selBoard = i;
|
||||
}
|
||||
const board = isInferredBoardListItem(item)
|
||||
? item.inferredBoard
|
||||
: item.board;
|
||||
return {
|
||||
label: nls.localize(
|
||||
'arduino/certificate/boardAtPort',
|
||||
'{0} at {1}',
|
||||
board.name,
|
||||
board.port?.address ?? ''
|
||||
item.port?.address ?? ''
|
||||
),
|
||||
value: board.fqbn || '',
|
||||
value: item,
|
||||
};
|
||||
});
|
||||
|
||||
if (boardsList.length === 0) {
|
||||
if (boardOptions.length === 0) {
|
||||
placeholderTxt = nls.localize(
|
||||
'arduino/certificate/noSupportedBoardConnected',
|
||||
'No supported board connected'
|
||||
@ -71,32 +79,32 @@ export const SelectBoardComponent = ({
|
||||
}
|
||||
|
||||
setSelectBoardPlaceholder(placeholderTxt);
|
||||
setSelectOptions(boardsList);
|
||||
setSelectOptions(boardOptions);
|
||||
|
||||
if (selectedBoard) {
|
||||
selBoard = boardsList
|
||||
.map((boardOpt) => boardOpt.value)
|
||||
.indexOf(selectedBoard.fqbn || '');
|
||||
if (selectedItem) {
|
||||
selBoard = updatableBoards.indexOf(selectedItem);
|
||||
}
|
||||
|
||||
selectOption(boardsList[selBoard] || null);
|
||||
}, [busy, availableBoards, selectOption, updatableFqbns, selectedBoard]);
|
||||
|
||||
selectOption(boardOptions[selBoard] || null);
|
||||
}, [busy, boardList, selectOption, updatableFqbns, selectedItem]);
|
||||
return (
|
||||
<ArduinoSelect
|
||||
id="board-select"
|
||||
menuPosition="fixed"
|
||||
isDisabled={selectOptions.length === 0 || busy}
|
||||
placeholder={selectBoardPlaceholder}
|
||||
placeholder={selectItemPlaceholder}
|
||||
options={selectOptions}
|
||||
value={
|
||||
(selectedBoard && {
|
||||
value: selectedBoard.fqbn,
|
||||
(selectedItem && {
|
||||
value: selectedItem,
|
||||
label: nls.localize(
|
||||
'arduino/certificate/boardAtPort',
|
||||
'{0} at {1}',
|
||||
selectedBoard.name,
|
||||
selectedBoard.port?.address ?? ''
|
||||
(isInferredBoardListItem(selectedItem)
|
||||
? selectedItem.inferredBoard
|
||||
: selectedItem.board
|
||||
).name,
|
||||
selectedItem.port.address ?? ''
|
||||
),
|
||||
}) ||
|
||||
null
|
||||
|
@ -1,24 +1,32 @@
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import React from '@theia/core/shared/react';
|
||||
import { Port } from '../../../common/protocol';
|
||||
import {
|
||||
boardIdentifierEquals,
|
||||
Port,
|
||||
portIdentifierEquals,
|
||||
} from '../../../common/protocol';
|
||||
import {
|
||||
ArduinoFirmwareUploader,
|
||||
FirmwareInfo,
|
||||
} from '../../../common/protocol/arduino-firmware-uploader';
|
||||
import { AvailableBoard } from '../../boards/boards-service-provider';
|
||||
import {
|
||||
BoardList,
|
||||
BoardListItemWithBoard,
|
||||
isInferredBoardListItem,
|
||||
} from '../../../common/protocol/board-list';
|
||||
import { ArduinoSelect } from '../../widgets/arduino-select';
|
||||
import { SelectBoardComponent } from '../certificate-uploader/select-board-components';
|
||||
|
||||
type FirmwareOption = { value: string; label: string };
|
||||
|
||||
export const FirmwareUploaderComponent = ({
|
||||
availableBoards,
|
||||
boardList,
|
||||
firmwareUploader,
|
||||
updatableFqbns,
|
||||
flashFirmware,
|
||||
isOpen,
|
||||
}: {
|
||||
availableBoards: AvailableBoard[];
|
||||
boardList: BoardList;
|
||||
firmwareUploader: ArduinoFirmwareUploader;
|
||||
updatableFqbns: string[];
|
||||
flashFirmware: (firmware: FirmwareInfo, port: Port) => Promise<any>;
|
||||
@ -31,8 +39,8 @@ export const FirmwareUploaderComponent = ({
|
||||
'ok' | 'fail' | 'installing' | null
|
||||
>(null);
|
||||
|
||||
const [selectedBoard, setSelectedBoard] =
|
||||
React.useState<AvailableBoard | null>(null);
|
||||
const [selectedItem, setSelectedItem] =
|
||||
React.useState<BoardListItemWithBoard | null>(null);
|
||||
|
||||
const [availableFirmwares, setAvailableFirmwares] = React.useState<
|
||||
FirmwareInfo[]
|
||||
@ -50,13 +58,16 @@ export const FirmwareUploaderComponent = ({
|
||||
const fetchFirmwares = React.useCallback(async () => {
|
||||
setInstallFeedback(null);
|
||||
setFirmwaresFetching(true);
|
||||
if (!selectedBoard) {
|
||||
if (!selectedItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// fetch the firmwares for the selected board
|
||||
const board = isInferredBoardListItem(selectedItem)
|
||||
? selectedItem.inferredBoard
|
||||
: selectedItem.board;
|
||||
const firmwaresForFqbn = await firmwareUploader.availableFirmwares(
|
||||
selectedBoard.fqbn || ''
|
||||
board.fqbn || ''
|
||||
);
|
||||
setAvailableFirmwares(firmwaresForFqbn);
|
||||
|
||||
@ -69,7 +80,7 @@ export const FirmwareUploaderComponent = ({
|
||||
|
||||
if (firmwaresForFqbn.length > 0) setSelectedFirmware(firmwaresOpts[0]);
|
||||
setFirmwaresFetching(false);
|
||||
}, [firmwareUploader, selectedBoard]);
|
||||
}, [firmwareUploader, selectedItem]);
|
||||
|
||||
const installFirmware = React.useCallback(async () => {
|
||||
setInstallFeedback('installing');
|
||||
@ -81,27 +92,39 @@ export const FirmwareUploaderComponent = ({
|
||||
try {
|
||||
const installStatus =
|
||||
!!firmwareToFlash &&
|
||||
!!selectedBoard?.port &&
|
||||
(await flashFirmware(firmwareToFlash, selectedBoard?.port));
|
||||
!!selectedItem?.board &&
|
||||
(await flashFirmware(firmwareToFlash, selectedItem?.port));
|
||||
|
||||
setInstallFeedback((installStatus && 'ok') || 'fail');
|
||||
} catch {
|
||||
setInstallFeedback('fail');
|
||||
}
|
||||
}, [firmwareUploader, selectedBoard, selectedFirmware, availableFirmwares]);
|
||||
}, [selectedItem, selectedFirmware, availableFirmwares, flashFirmware]);
|
||||
|
||||
const onBoardSelect = React.useCallback(
|
||||
(board: AvailableBoard) => {
|
||||
const newFqbn = (board && board.fqbn) || null;
|
||||
const prevFqbn = (selectedBoard && selectedBoard.fqbn) || null;
|
||||
const onItemSelect = React.useCallback(
|
||||
(item: BoardListItemWithBoard | null) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
const board = isInferredBoardListItem(item)
|
||||
? item.inferredBoard
|
||||
: item.board;
|
||||
const selectedBoard = isInferredBoardListItem(selectedItem)
|
||||
? selectedItem.inferredBoard
|
||||
: selectedItem?.board;
|
||||
const port = item.port;
|
||||
const selectedPort = selectedItem?.port;
|
||||
|
||||
if (newFqbn !== prevFqbn) {
|
||||
if (
|
||||
!boardIdentifierEquals(board, selectedBoard) ||
|
||||
!portIdentifierEquals(port, selectedPort)
|
||||
) {
|
||||
setInstallFeedback(null);
|
||||
setAvailableFirmwares([]);
|
||||
setSelectedBoard(board);
|
||||
setSelectedItem(item);
|
||||
}
|
||||
},
|
||||
[selectedBoard]
|
||||
[selectedItem]
|
||||
);
|
||||
|
||||
return (
|
||||
@ -115,10 +138,10 @@ export const FirmwareUploaderComponent = ({
|
||||
<div className="dialogRow">
|
||||
<div className="fl1">
|
||||
<SelectBoardComponent
|
||||
availableBoards={availableBoards}
|
||||
boardList={boardList}
|
||||
updatableFqbns={updatableFqbns}
|
||||
onBoardSelect={onBoardSelect}
|
||||
selectedBoard={selectedBoard}
|
||||
onItemSelect={onItemSelect}
|
||||
selectedItem={selectedItem}
|
||||
busy={installFeedback === 'installing'}
|
||||
/>
|
||||
</div>
|
||||
@ -126,7 +149,7 @@ export const FirmwareUploaderComponent = ({
|
||||
type="button"
|
||||
className="theia-button secondary"
|
||||
disabled={
|
||||
selectedBoard === null ||
|
||||
selectedItem === null ||
|
||||
firmwaresFetching ||
|
||||
installFeedback === 'installing'
|
||||
}
|
||||
@ -150,7 +173,7 @@ export const FirmwareUploaderComponent = ({
|
||||
id="firmware-select"
|
||||
menuPosition="fixed"
|
||||
isDisabled={
|
||||
!selectedBoard ||
|
||||
!selectedItem ||
|
||||
firmwaresFetching ||
|
||||
installFeedback === 'installing'
|
||||
}
|
||||
|
@ -1,24 +1,21 @@
|
||||
import React from '@theia/core/shared/react';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import type { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { ReactDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import {
|
||||
AvailableBoard,
|
||||
BoardsServiceProvider,
|
||||
} from '../../boards/boards-service-provider';
|
||||
import React from '@theia/core/shared/react';
|
||||
import {
|
||||
ArduinoFirmwareUploader,
|
||||
FirmwareInfo,
|
||||
} from '../../../common/protocol/arduino-firmware-uploader';
|
||||
import { FirmwareUploaderComponent } from './firmware-uploader-component';
|
||||
import type { Port } from '../../../common/protocol/boards-service';
|
||||
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
|
||||
import { UploadFirmware } from '../../contributions/upload-firmware';
|
||||
import { Port } from '../../../common/protocol';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import { ReactDialog } from '../../theia/dialogs/dialogs';
|
||||
import { FirmwareUploaderComponent } from './firmware-uploader-component';
|
||||
|
||||
@injectable()
|
||||
export class UploadFirmwareDialogProps extends DialogProps {}
|
||||
@ -26,14 +23,13 @@ export class UploadFirmwareDialogProps extends DialogProps {}
|
||||
@injectable()
|
||||
export class UploadFirmwareDialog extends ReactDialog<void> {
|
||||
@inject(BoardsServiceProvider)
|
||||
private readonly boardsServiceClient: BoardsServiceProvider;
|
||||
private readonly boardsServiceProvider: BoardsServiceProvider;
|
||||
@inject(ArduinoFirmwareUploader)
|
||||
private readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
||||
@inject(FrontendApplicationStateService)
|
||||
private readonly appStatusService: FrontendApplicationStateService;
|
||||
private readonly appStateService: FrontendApplicationStateService;
|
||||
|
||||
private updatableFqbns: string[] = [];
|
||||
private availableBoards: AvailableBoard[] = [];
|
||||
private isOpen = new Object();
|
||||
private busy = false;
|
||||
|
||||
@ -49,16 +45,12 @@ export class UploadFirmwareDialog extends ReactDialog<void> {
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
this.appStatusService.reachedState('ready').then(async () => {
|
||||
this.appStateService.reachedState('ready').then(async () => {
|
||||
const fqbns = await this.arduinoFirmwareUploader.updatableBoards();
|
||||
this.updatableFqbns = fqbns;
|
||||
this.update();
|
||||
});
|
||||
|
||||
this.boardsServiceClient.onAvailableBoardsChanged((availableBoards) => {
|
||||
this.availableBoards = availableBoards;
|
||||
this.update();
|
||||
});
|
||||
this.boardsServiceProvider.onBoardListDidChange(() => this.update());
|
||||
}
|
||||
|
||||
get value(): void {
|
||||
@ -70,7 +62,7 @@ export class UploadFirmwareDialog extends ReactDialog<void> {
|
||||
<div>
|
||||
<form>
|
||||
<FirmwareUploaderComponent
|
||||
availableBoards={this.availableBoards}
|
||||
boardList={this.boardsServiceProvider.boardList}
|
||||
firmwareUploader={this.arduinoFirmwareUploader}
|
||||
flashFirmware={this.flashFirmware.bind(this)}
|
||||
updatableFqbns={this.updatableFqbns}
|
||||
|
@ -1,15 +1,18 @@
|
||||
import {
|
||||
ApplicationError,
|
||||
Disposable,
|
||||
Emitter,
|
||||
MessageService,
|
||||
nls,
|
||||
} from '@theia/core';
|
||||
import { ApplicationError } from '@theia/core/lib/common/application-error';
|
||||
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import { MessageType } from '@theia/core/lib/common/message-service-protocol';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { NotificationManager } from '@theia/messages/lib/browser/notifications-manager';
|
||||
import { MessageType } from '@theia/core/lib/common/message-service-protocol';
|
||||
import { Board, Port } from '../common/protocol';
|
||||
import { BoardIdentifier, PortIdentifier } from '../common/protocol';
|
||||
import {
|
||||
BoardListItem,
|
||||
boardListItemEquals,
|
||||
getInferredBoardOrBoard,
|
||||
} from '../common/protocol/board-list';
|
||||
import {
|
||||
Monitor,
|
||||
MonitorManagerProxyClient,
|
||||
@ -17,7 +20,6 @@ import {
|
||||
MonitorSettings,
|
||||
PluggableMonitorSettings,
|
||||
} from '../common/protocol/monitor-service';
|
||||
import { BoardsConfig } from './boards/boards-config';
|
||||
import { BoardsServiceProvider } from './boards/boards-service-provider';
|
||||
|
||||
@injectable()
|
||||
@ -55,8 +57,8 @@ export class MonitorManagerProxyClientImpl
|
||||
// frontend and backend.
|
||||
private webSocket?: WebSocket;
|
||||
private wsPort?: number;
|
||||
private lastConnectedBoard: BoardsConfig.Config;
|
||||
private onBoardsConfigChanged: Disposable | undefined;
|
||||
private lastConnectedBoard: BoardListItem | undefined;
|
||||
private onBoardListDidChange: Disposable | undefined;
|
||||
|
||||
getWebSocketPort(): number | undefined {
|
||||
return this.wsPort;
|
||||
@ -110,8 +112,8 @@ export class MonitorManagerProxyClientImpl
|
||||
if (!this.webSocket) {
|
||||
return;
|
||||
}
|
||||
this.onBoardsConfigChanged?.dispose();
|
||||
this.onBoardsConfigChanged = undefined;
|
||||
this.onBoardListDidChange?.dispose();
|
||||
this.onBoardListDidChange = undefined;
|
||||
try {
|
||||
this.webSocket.close();
|
||||
this.webSocket = undefined;
|
||||
@ -134,51 +136,52 @@ export class MonitorManagerProxyClientImpl
|
||||
}
|
||||
|
||||
async startMonitor(settings?: PluggableMonitorSettings): Promise<void> {
|
||||
await this.boardsServiceProvider.reconciled;
|
||||
this.lastConnectedBoard = {
|
||||
selectedBoard: this.boardsServiceProvider.boardsConfig.selectedBoard,
|
||||
selectedPort: this.boardsServiceProvider.boardsConfig.selectedPort,
|
||||
};
|
||||
|
||||
if (!this.onBoardsConfigChanged) {
|
||||
this.onBoardsConfigChanged =
|
||||
this.boardsServiceProvider.onBoardsConfigChanged(
|
||||
async ({ selectedBoard, selectedPort }) => {
|
||||
if (
|
||||
typeof selectedBoard === 'undefined' ||
|
||||
typeof selectedPort === 'undefined'
|
||||
)
|
||||
const { boardList } = this.boardsServiceProvider;
|
||||
this.lastConnectedBoard = boardList.items[boardList.selectedIndex];
|
||||
if (!this.onBoardListDidChange) {
|
||||
this.onBoardListDidChange =
|
||||
this.boardsServiceProvider.onBoardListDidChange(
|
||||
async (newBoardList) => {
|
||||
const currentConnectedBoard =
|
||||
newBoardList.items[newBoardList.selectedIndex];
|
||||
if (!currentConnectedBoard) {
|
||||
return;
|
||||
}
|
||||
|
||||
// a board is plugged and it's different from the old connected board
|
||||
if (
|
||||
selectedBoard?.fqbn !==
|
||||
this.lastConnectedBoard?.selectedBoard?.fqbn ||
|
||||
Port.keyOf(selectedPort) !==
|
||||
(this.lastConnectedBoard.selectedPort
|
||||
? Port.keyOf(this.lastConnectedBoard.selectedPort)
|
||||
: undefined)
|
||||
!this.lastConnectedBoard ||
|
||||
boardListItemEquals(
|
||||
currentConnectedBoard,
|
||||
this.lastConnectedBoard
|
||||
)
|
||||
) {
|
||||
this.lastConnectedBoard = {
|
||||
selectedBoard: selectedBoard,
|
||||
selectedPort: selectedPort,
|
||||
};
|
||||
this.onMonitorShouldResetEmitter.fire();
|
||||
} else {
|
||||
// a board is plugged and it's the same as prev, rerun "this.startMonitor" to
|
||||
// recreate the listener callback
|
||||
this.startMonitor();
|
||||
} else {
|
||||
// a board is plugged and it's different from the old connected board
|
||||
this.lastConnectedBoard = currentConnectedBoard;
|
||||
this.onMonitorShouldResetEmitter.fire();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const { selectedBoard, selectedPort } =
|
||||
this.boardsServiceProvider.boardsConfig;
|
||||
if (!selectedBoard || !selectedBoard.fqbn || !selectedPort) return;
|
||||
if (!this.lastConnectedBoard) {
|
||||
return;
|
||||
}
|
||||
|
||||
const board = getInferredBoardOrBoard(this.lastConnectedBoard);
|
||||
if (!board) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.clearVisibleNotification();
|
||||
await this.server().startMonitor(selectedBoard, selectedPort, settings);
|
||||
await this.server().startMonitor(
|
||||
board,
|
||||
this.lastConnectedBoard.port,
|
||||
settings
|
||||
);
|
||||
} catch (err) {
|
||||
const message = ApplicationError.is(err) ? err.message : String(err);
|
||||
this.previousNotificationId = this.notificationId(message);
|
||||
@ -186,7 +189,10 @@ export class MonitorManagerProxyClientImpl
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentSettings(board: Board, port: Port): Promise<MonitorSettings> {
|
||||
getCurrentSettings(
|
||||
board: BoardIdentifier,
|
||||
port: PortIdentifier
|
||||
): Promise<MonitorSettings> {
|
||||
return this.server().getCurrentSettings(board, port);
|
||||
}
|
||||
|
||||
|
@ -14,13 +14,13 @@ import {
|
||||
NotificationServiceClient,
|
||||
NotificationServiceServer,
|
||||
} from '../common/protocol/notification-service';
|
||||
import {
|
||||
AttachedBoardsChangeEvent,
|
||||
import type {
|
||||
BoardsPackage,
|
||||
LibraryPackage,
|
||||
ConfigState,
|
||||
Sketch,
|
||||
ProgressMessage,
|
||||
DetectedPorts,
|
||||
} from '../common/protocol';
|
||||
import {
|
||||
FrontendApplicationStateService,
|
||||
@ -61,8 +61,9 @@ export class NotificationCenter
|
||||
private readonly libraryDidUninstallEmitter = new Emitter<{
|
||||
item: LibraryPackage;
|
||||
}>();
|
||||
private readonly attachedBoardsDidChangeEmitter =
|
||||
new Emitter<AttachedBoardsChangeEvent>();
|
||||
private readonly detectedPortsDidChangeEmitter = new Emitter<{
|
||||
detectedPorts: DetectedPorts;
|
||||
}>();
|
||||
private readonly recentSketchesChangedEmitter = new Emitter<{
|
||||
sketches: Sketch[];
|
||||
}>();
|
||||
@ -82,7 +83,7 @@ export class NotificationCenter
|
||||
this.platformDidUninstallEmitter,
|
||||
this.libraryDidInstallEmitter,
|
||||
this.libraryDidUninstallEmitter,
|
||||
this.attachedBoardsDidChangeEmitter
|
||||
this.detectedPortsDidChangeEmitter
|
||||
);
|
||||
|
||||
readonly onDidReinitialize = this.didReinitializeEmitter.event;
|
||||
@ -97,8 +98,7 @@ export class NotificationCenter
|
||||
readonly onPlatformDidUninstall = this.platformDidUninstallEmitter.event;
|
||||
readonly onLibraryDidInstall = this.libraryDidInstallEmitter.event;
|
||||
readonly onLibraryDidUninstall = this.libraryDidUninstallEmitter.event;
|
||||
readonly onAttachedBoardsDidChange =
|
||||
this.attachedBoardsDidChangeEmitter.event;
|
||||
readonly onDetectedPortsDidChange = this.detectedPortsDidChangeEmitter.event;
|
||||
readonly onRecentSketchesDidChange = this.recentSketchesChangedEmitter.event;
|
||||
readonly onAppStateDidChange = this.onAppStateDidChangeEmitter.event;
|
||||
|
||||
@ -166,8 +166,8 @@ export class NotificationCenter
|
||||
this.libraryDidUninstallEmitter.fire(event);
|
||||
}
|
||||
|
||||
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void {
|
||||
this.attachedBoardsDidChangeEmitter.fire(event);
|
||||
notifyDetectedPortsDidChange(event: { detectedPorts: DetectedPorts }): void {
|
||||
this.detectedPortsDidChangeEmitter.fire(event);
|
||||
}
|
||||
|
||||
notifyRecentSketchesDidChange(event: { sketches: Sketch[] }): void {
|
||||
|
@ -173,7 +173,6 @@ export class MonitorWidget extends ReactWidget {
|
||||
|
||||
private async startMonitor(): Promise<void> {
|
||||
await this.appStateService.reachedState('ready');
|
||||
await this.boardsServiceProvider.reconciled;
|
||||
await this.syncSettings();
|
||||
await this.monitorManagerProxy.startMonitor();
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { StorageService } from '@theia/core/lib/browser/storage-service';
|
||||
import {
|
||||
Command,
|
||||
CommandContribution,
|
||||
CommandRegistry,
|
||||
} from '@theia/core/lib/common/command';
|
||||
|
||||
/**
|
||||
* This is a workaround to break cycles in the dependency injection. Provides commands for `setData` and `getData`.
|
||||
*/
|
||||
@injectable()
|
||||
export class StorageWrapper implements CommandContribution {
|
||||
@inject(StorageService)
|
||||
protected storageService: StorageService;
|
||||
|
||||
registerCommands(commands: CommandRegistry): void {
|
||||
commands.registerCommand(StorageWrapper.Commands.GET_DATA, {
|
||||
execute: (key: string, defaultValue?: any) =>
|
||||
this.storageService.getData(key, defaultValue),
|
||||
});
|
||||
commands.registerCommand(StorageWrapper.Commands.SET_DATA, {
|
||||
execute: (key: string, value: any) =>
|
||||
this.storageService.setData(key, value),
|
||||
});
|
||||
}
|
||||
}
|
||||
export namespace StorageWrapper {
|
||||
export namespace Commands {
|
||||
export const SET_DATA: Command = {
|
||||
id: 'arduino-store-wrapper-set',
|
||||
};
|
||||
export const GET_DATA: Command = {
|
||||
id: 'arduino-store-wrapper-get',
|
||||
};
|
||||
}
|
||||
}
|
@ -172,20 +172,19 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
.arduino-boards-toolbar-item--protocol,
|
||||
.arduino-boards-toolbar-item--protocol,
|
||||
.arduino-boards-dropdown-item--protocol {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.arduino-boards-toolbar-item--protocol ,
|
||||
.arduino-boards-toolbar-item--protocol,
|
||||
.arduino-boards-dropdown-item--protocol {
|
||||
color: var(--theia-arduino-toolbar-dropdown-label);
|
||||
}
|
||||
|
||||
.arduino-boards-toolbar-item-container
|
||||
.arduino-boards-toolbar-item {
|
||||
.arduino-boards-toolbar-item-container .arduino-boards-toolbar-item {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
width: 100%;
|
||||
@ -196,7 +195,10 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
|
||||
}
|
||||
|
||||
.arduino-boards-toolbar-item--label-connected {
|
||||
font-family: 'Open Sans Bold';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.arduino-boards-toolbar-item-container .caret {
|
||||
@ -208,6 +210,10 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
|
||||
margin: -1px;
|
||||
z-index: 1;
|
||||
border: 1px solid var(--theia-arduino-toolbar-dropdown-border);
|
||||
font-family: 'Open Sans';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-list:focus {
|
||||
@ -230,20 +236,47 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
|
||||
cursor: default;
|
||||
display: flex;
|
||||
font-size: var(--theia-ui-font-size1);
|
||||
gap: 10px;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item--board-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item--label {
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* Redefine default codicon size https://github.com/microsoft/vscode/commit/38cd0a377b7abef34fb07fe770fc633e68819ba6 */
|
||||
.arduino-boards-dropdown-item .codicon[class*='codicon-'] {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item .p-TabBar-toolbar {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item .p-TabBar-toolbar .item {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item .p-TabBar-toolbar .item .action-label {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item--board-label {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item .arduino-boards-dropdown-item--protocol {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item--port-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
@ -267,10 +300,6 @@ div#select-board-dialog .selectBoardContainer .list .item.selected i {
|
||||
color: var(--theia-arduino-toolbar-dropdown-iconSelected);
|
||||
}
|
||||
|
||||
.arduino-boards-dropdown-item .fa-check {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.arduino-board-dropdown-footer {
|
||||
color: var(--theia-secondaryButton-foreground);
|
||||
border-top: 1px solid var(--theia-dropdown-border);
|
||||
|
@ -3,14 +3,9 @@ import {
|
||||
DialogProps,
|
||||
} from '@theia/core/lib/browser/dialogs';
|
||||
import { ReactDialog as TheiaReactDialog } from '@theia/core/lib/browser/dialogs/react-dialog';
|
||||
import { codiconArray, Message } from '@theia/core/lib/browser/widgets/widget';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { codiconArray } from '@theia/core/lib/browser/widgets/widget';
|
||||
import type { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import React from '@theia/core/shared/react';
|
||||
import { createRoot } from '@theia/core/shared/react-dom/client';
|
||||
|
||||
@injectable()
|
||||
export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> {
|
||||
@ -18,7 +13,6 @@ export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> {
|
||||
@inject(DialogProps) protected override readonly props: DialogProps
|
||||
) {
|
||||
super(props);
|
||||
|
||||
this.closeCrossNode.classList.remove(...codiconArray('close'));
|
||||
this.closeCrossNode.classList.add('fa', 'fa-close');
|
||||
}
|
||||
@ -26,38 +20,26 @@ export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> {
|
||||
|
||||
@injectable()
|
||||
export abstract class ReactDialog<T> extends TheiaReactDialog<T> {
|
||||
protected override onUpdateRequest(msg: Message): void {
|
||||
// This is tricky to bypass the default Theia code.
|
||||
// Otherwise, there is a warning when opening the dialog for the second time.
|
||||
// You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.
|
||||
const disposables = new DisposableCollection();
|
||||
if (!this.isMounted) {
|
||||
// toggle the `isMounted` logic for the time being of the super call so that the `createRoot` does not run
|
||||
this.isMounted = true;
|
||||
disposables.push(Disposable.create(() => (this.isMounted = false)));
|
||||
private _isOnCloseRequestInProgress = false;
|
||||
|
||||
override dispose(): void {
|
||||
// There is a bug in Theia, and the React component's `componentWillUnmount` will not be called, as the Theia widget is already disposed when closing and reopening a dialog.
|
||||
// Widget lifecycle issue in Theia: https://github.com/eclipse-theia/theia/issues/12093
|
||||
// Bogus react widget lifecycle management PR: https://github.com/eclipse-theia/theia/pull/11687
|
||||
// Do not call super. Do not let the Phosphor widget to be disposed on dialog close.
|
||||
if (this._isOnCloseRequestInProgress) {
|
||||
// Do not let the widget dispose on close.
|
||||
return;
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
// Always unset the `contentNodeRoot` so there is no double update when calling super.
|
||||
const restoreContentNodeRoot = this.contentNodeRoot;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(this.contentNodeRoot as any) = undefined;
|
||||
disposables.push(
|
||||
Disposable.create(() => (this.contentNodeRoot = restoreContentNodeRoot))
|
||||
);
|
||||
|
||||
protected override onCloseRequest(message: Message): void {
|
||||
this._isOnCloseRequestInProgress = true;
|
||||
try {
|
||||
super.onUpdateRequest(msg);
|
||||
super.onCloseRequest(message);
|
||||
} finally {
|
||||
disposables.dispose();
|
||||
this._isOnCloseRequestInProgress = false;
|
||||
}
|
||||
|
||||
// Use the patched rendering.
|
||||
if (!this.isMounted) {
|
||||
this.contentNodeRoot = createRoot(this.contentNode);
|
||||
// Resetting the prop is missing from the Theia code.
|
||||
// https://github.com/eclipse-theia/theia/blob/v1.31.1/packages/core/src/browser/dialogs/react-dialog.tsx#L41-L47
|
||||
this.isMounted = true;
|
||||
}
|
||||
this.contentNodeRoot?.render(<>{this.render()}</>);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
|
||||
// TODO: rename constants: `Unknown` should be `unknownLabel`, change `Later` to `laterLabel`, etc.
|
||||
export const Unknown = nls.localize('arduino/common/unknown', 'Unknown');
|
||||
export const Later = nls.localize('arduino/common/later', 'Later');
|
||||
export const Updatable = nls.localize('arduino/common/updateable', 'Updatable');
|
||||
|
694
arduino-ide-extension/src/common/protocol/board-list.ts
Normal file
694
arduino-ide-extension/src/common/protocol/board-list.ts
Normal file
@ -0,0 +1,694 @@
|
||||
import type { Mutable } from '@theia/core/lib/common/types';
|
||||
import { Unknown } from '../nls';
|
||||
import type { Defined } from '../types';
|
||||
import { naturalCompare } from '../utils';
|
||||
import {
|
||||
BoardIdentifier,
|
||||
boardIdentifierComparator,
|
||||
boardIdentifierEquals,
|
||||
BoardsConfig,
|
||||
DetectedPort,
|
||||
DetectedPorts,
|
||||
emptyBoardsConfig,
|
||||
findMatchingPortIndex,
|
||||
isBoardIdentifier,
|
||||
isDefinedBoardsConfig,
|
||||
Port,
|
||||
PortIdentifier,
|
||||
portIdentifierEquals,
|
||||
portProtocolComparator,
|
||||
selectBoard,
|
||||
unconfirmedBoard,
|
||||
notConnected,
|
||||
boardIdentifierLabel,
|
||||
} from './boards-service';
|
||||
|
||||
/**
|
||||
* Representation of a detected port with an optional board.
|
||||
*/
|
||||
export interface BoardListItem {
|
||||
readonly port: Port;
|
||||
readonly board?: BoardIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of a detected port with multiple discovered boards on the same port. For example Arduino Nano ESP32 from `esp32:esp32:nano_nora` and `arduino:esp32:nano_nora`.
|
||||
* If multiple boards are detected, but the board names are the same, the `board` will be the `first` element of the `boards` array.
|
||||
* If multiple boards are detected, but the board names are not identical, the `board` will be missing.
|
||||
*/
|
||||
export interface MultiBoardsBoardListItem extends BoardListItem {
|
||||
readonly boards: readonly BoardIdentifier[];
|
||||
}
|
||||
|
||||
function findUniqueBoardName(
|
||||
item: MultiBoardsBoardListItem
|
||||
): string | undefined {
|
||||
const distinctNames = new Set(item.boards.map(({ name }) => name));
|
||||
if (distinctNames.size === 1) {
|
||||
const name = Array.from(distinctNames.keys()).shift();
|
||||
if (name) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function isMultiBoardsBoardListItem(
|
||||
arg: unknown
|
||||
): arg is MultiBoardsBoardListItem {
|
||||
return (
|
||||
isBoardListItem(arg) &&
|
||||
(<MultiBoardsBoardListItem>arg).boards !== undefined &&
|
||||
Array.isArray((<MultiBoardsBoardListItem>arg).boards) &&
|
||||
Boolean((<MultiBoardsBoardListItem>arg).boards.length) &&
|
||||
(<MultiBoardsBoardListItem>arg).boards.every(isBoardIdentifier)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base inferred board list item type.
|
||||
* The the type of the inferred board can be:
|
||||
* - manually specified board for a detected port where no boards were discovered,
|
||||
* - the board has been overridden for detected port discovered board pair.
|
||||
*/
|
||||
export type InferredBoardListItem =
|
||||
| ManuallySelectedBoardListItem
|
||||
| BoardOverriddenBoardListItem;
|
||||
|
||||
/**
|
||||
* No boards have been discovered for a detected port, it has been manually selected by the user.
|
||||
*/
|
||||
export interface ManuallySelectedBoardListItem extends BoardListItem {
|
||||
readonly inferredBoard: BoardIdentifier;
|
||||
readonly type: 'manually-selected';
|
||||
}
|
||||
|
||||
/**
|
||||
* One or more boards have been discovered for a detected port, but the board has been overridden by a manual action.
|
||||
*/
|
||||
export interface BoardOverriddenBoardListItem extends BoardListItem {
|
||||
readonly inferredBoard: BoardIdentifier;
|
||||
readonly board: BoardIdentifier;
|
||||
readonly type: 'board-overridden';
|
||||
}
|
||||
|
||||
export function isBoardListItem(arg: unknown): arg is BoardListItem {
|
||||
return (
|
||||
Boolean(arg) &&
|
||||
typeof arg === 'object' &&
|
||||
(<BoardListItem>arg).port !== undefined &&
|
||||
Port.is((<BoardListItem>arg).port) &&
|
||||
((<BoardListItem>arg).board === undefined ||
|
||||
((<BoardListItem>arg).board !== undefined &&
|
||||
isBoardIdentifier((<BoardListItem>arg).board)))
|
||||
);
|
||||
}
|
||||
|
||||
export function boardListItemEquals(
|
||||
left: BoardListItem,
|
||||
right: BoardListItem
|
||||
): boolean {
|
||||
if (portIdentifierEquals(left.port, right.port)) {
|
||||
const leftBoard = getBoardOrInferredBoard(left);
|
||||
const rightBoard = getBoardOrInferredBoard(right);
|
||||
if (boardIdentifierEquals(leftBoard, rightBoard)) {
|
||||
const leftInferredBoard = getInferredBoardOrBoard(left);
|
||||
const rightInferredBoard = getInferredBoardOrBoard(right);
|
||||
return boardIdentifierEquals(leftInferredBoard, rightInferredBoard);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export interface BoardListItemWithBoard extends BoardListItem {
|
||||
readonly board: BoardIdentifier;
|
||||
}
|
||||
|
||||
function getBoardOrInferredBoard(
|
||||
item: BoardListItem
|
||||
): BoardIdentifier | undefined {
|
||||
let board: BoardIdentifier | undefined = undefined;
|
||||
board = item.board;
|
||||
if (!board && isInferredBoardListItem(item)) {
|
||||
board = item.inferredBoard;
|
||||
}
|
||||
return board;
|
||||
}
|
||||
|
||||
export function getInferredBoardOrBoard(
|
||||
item: BoardListItem
|
||||
): BoardIdentifier | undefined {
|
||||
if (isInferredBoardListItem(item)) {
|
||||
return item.inferredBoard;
|
||||
}
|
||||
return item.board;
|
||||
}
|
||||
|
||||
export function isInferredBoardListItem(
|
||||
arg: unknown
|
||||
): arg is InferredBoardListItem {
|
||||
return (
|
||||
isBoardListItem(arg) &&
|
||||
(<InferredBoardListItem>arg).type !== undefined &&
|
||||
isInferenceType((<InferredBoardListItem>arg).type) &&
|
||||
(<InferredBoardListItem>arg).inferredBoard !== undefined &&
|
||||
isBoardIdentifier((<InferredBoardListItem>arg).inferredBoard)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores historical info about boards manually specified for detected boards. The key are generated with `Port#keyOf`.
|
||||
*/
|
||||
export type BoardListHistory = Readonly<Record<string, BoardIdentifier>>;
|
||||
|
||||
export function isBoardListHistory(arg: unknown): arg is BoardListHistory {
|
||||
return (
|
||||
Boolean(arg) &&
|
||||
typeof arg === 'object' &&
|
||||
Object.entries(<object>arg).every(([, value]) => isBoardIdentifier(value))
|
||||
);
|
||||
}
|
||||
|
||||
const inferenceTypeLiterals = [
|
||||
/**
|
||||
* The user has manually selected the board (FQBN) for the detected port of a 3rd party board (no matching boards were detected by the CLI for the port)
|
||||
*/
|
||||
'manually-selected',
|
||||
/**
|
||||
* The user has manually edited the detected FQBN of a recognized board from a detected port (there are matching boards for a detected port, but the user decided to use another FQBN)
|
||||
*/
|
||||
'board-overridden',
|
||||
] as const;
|
||||
type InferenceType = (typeof inferenceTypeLiterals)[number];
|
||||
function isInferenceType(arg: unknown): arg is InferenceType {
|
||||
return (
|
||||
typeof arg === 'string' &&
|
||||
inferenceTypeLiterals.includes(<InferenceType>arg)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare precedence:
|
||||
* 1. `BoardListItem#port#protocol`: `'serial'`, `'network'`, then natural compare of the `protocol` string.
|
||||
* 1. `BoardListItem`s with a `board` comes before items without a `board`.
|
||||
* 1. `BoardListItem#board`:
|
||||
* 1. Items with `'arduino'` vendor ID in the `fqbn` come before other vendors.
|
||||
* 1. Natural compare of the `name`.
|
||||
* 1. If the `BoardListItem`s do not have a `board` property:
|
||||
* 1. Ambiguous boards come before no boards.
|
||||
* 1. `BoardListItem#port#address` natural compare is the fallback.
|
||||
*/
|
||||
function boardListItemComparator(
|
||||
left: BoardListItem,
|
||||
right: BoardListItem
|
||||
): number {
|
||||
// sort by port protocol
|
||||
let result = portProtocolComparator(left.port, right.port);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// compare by board
|
||||
result = boardIdentifierComparator(
|
||||
getBoardOrInferredBoard(left),
|
||||
getBoardOrInferredBoard(right)
|
||||
);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// detected ports with multiple discovered boards come before any other unknown items
|
||||
if (isMultiBoardsBoardListItem(left) && !isMultiBoardsBoardListItem(right)) {
|
||||
return -1;
|
||||
}
|
||||
if (!isMultiBoardsBoardListItem(left) && !isMultiBoardsBoardListItem(right)) {
|
||||
return 1;
|
||||
}
|
||||
// ambiguous boards with a unique board name comes first than other ambiguous ones
|
||||
if (isMultiBoardsBoardListItem(left) && isMultiBoardsBoardListItem(right)) {
|
||||
const leftUniqueName = findUniqueBoardName(left);
|
||||
const rightUniqueName = findUniqueBoardName(right);
|
||||
if (leftUniqueName && !rightUniqueName) {
|
||||
return -1;
|
||||
}
|
||||
if (!leftUniqueName && rightUniqueName) {
|
||||
return 1;
|
||||
}
|
||||
if (leftUniqueName && rightUniqueName) {
|
||||
return naturalCompare(leftUniqueName, rightUniqueName);
|
||||
}
|
||||
}
|
||||
|
||||
// fallback compare based on the address
|
||||
return naturalCompare(left.port.address, right.port.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* What is shown in the UI for the entire board list.
|
||||
*/
|
||||
export interface BoardListLabels {
|
||||
readonly boardLabel: string;
|
||||
readonly portProtocol: string | undefined;
|
||||
readonly tooltip: string;
|
||||
/**
|
||||
* The client's board+port selection matches with one of the board list items.
|
||||
*/
|
||||
readonly selected: boolean;
|
||||
}
|
||||
|
||||
function createBoardListLabels(
|
||||
boardsConfig: BoardsConfig,
|
||||
allPorts: readonly DetectedPort[],
|
||||
selectedItem: BoardListItem | undefined
|
||||
): BoardListLabels {
|
||||
const { selectedBoard, selectedPort } = boardsConfig;
|
||||
const boardLabel = selectedBoard?.name || selectBoard;
|
||||
let tooltip = '';
|
||||
if (!selectedBoard && !selectedPort) {
|
||||
tooltip = selectBoard;
|
||||
} else {
|
||||
if (selectedBoard) {
|
||||
tooltip += boardIdentifierLabel(selectedBoard);
|
||||
}
|
||||
if (selectedPort) {
|
||||
if (tooltip) {
|
||||
tooltip += '\n';
|
||||
}
|
||||
tooltip += selectedPort.address;
|
||||
const index = findMatchingPortIndex(selectedPort, allPorts);
|
||||
if (index < 0) {
|
||||
tooltip += ` ${notConnected}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
boardLabel,
|
||||
portProtocol: selectedBoard ? selectedPort?.protocol : undefined,
|
||||
tooltip,
|
||||
selected: Boolean(selectedItem),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* What is show in the UI for a particular board with all its refinements, fallbacks, and tooltips.
|
||||
*/
|
||||
export interface BoardListItemLabels {
|
||||
readonly boardLabel: string;
|
||||
readonly boardLabelWithFqbn: string;
|
||||
readonly portLabel: string;
|
||||
readonly portProtocol: string;
|
||||
readonly tooltip: string;
|
||||
}
|
||||
|
||||
export interface BoardListItemUI extends BoardListItem {
|
||||
readonly labels: BoardListItemLabels;
|
||||
readonly defaultAction: BoardListItemAction;
|
||||
readonly otherActions: Readonly<{
|
||||
edit?: EditBoardsConfigAction;
|
||||
revert?: SelectBoardsConfigAction;
|
||||
}>;
|
||||
}
|
||||
|
||||
function createBoardListItemLabels(item: BoardListItem): BoardListItemLabels {
|
||||
const { port } = item;
|
||||
const portLabel = port.address;
|
||||
const portProtocol = port.protocol;
|
||||
let board = item.board; // use default board label if any
|
||||
if (isInferredBoardListItem(item)) {
|
||||
board = item.inferredBoard; // inferred board overrides any discovered boards
|
||||
}
|
||||
// if the board is still missing, maybe it's ambiguous
|
||||
if (!board && isMultiBoardsBoardListItem(item)) {
|
||||
const name =
|
||||
// get a unique board name
|
||||
findUniqueBoardName(item) ??
|
||||
// or fall back to something else than unknown board
|
||||
unconfirmedBoard;
|
||||
board = { name, fqbn: undefined };
|
||||
}
|
||||
const boardLabel = board?.name ?? Unknown;
|
||||
let boardLabelWithFqbn = boardLabel;
|
||||
if (board?.fqbn) {
|
||||
boardLabelWithFqbn += ` (${board.fqbn})`;
|
||||
}
|
||||
return {
|
||||
boardLabel,
|
||||
boardLabelWithFqbn,
|
||||
portLabel,
|
||||
portProtocol,
|
||||
tooltip: `${boardLabelWithFqbn}\n${portLabel}`,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A list of boards discovered by the Arduino CLI. With the `board list --watch` gRPC equivalent command,
|
||||
* the CLI provides a `1..*` mapping between a port and the matching boards list. This type inverts the mapping
|
||||
* and makes a `1..1` association between a board identifier and the port it belongs to.
|
||||
*/
|
||||
export interface BoardList {
|
||||
readonly labels: BoardListLabels;
|
||||
/**
|
||||
* All detected ports with zero to many boards and optional inferred information based on historical selection/usage.
|
||||
*/
|
||||
readonly items: readonly BoardListItemUI[];
|
||||
/**
|
||||
* A snapshot of the board and port configuration this board list has been initialized with.
|
||||
*/
|
||||
readonly boardsConfig: Readonly<BoardsConfig>;
|
||||
|
||||
/**
|
||||
* Index of the board+port item that is currently "selected". A board list item is selected, if matches the board+port combination of `boardsConfig`.
|
||||
*/
|
||||
readonly selectedIndex: number;
|
||||
|
||||
/**
|
||||
* Contains all boards recognized from the detected port, and an optional unrecognized one that is derived from the detected port and the `initParam#selectedBoard`.
|
||||
*/
|
||||
readonly boards: readonly (BoardListItemWithBoard | InferredBoardListItem)[];
|
||||
|
||||
/**
|
||||
* If `predicate` is not defined, no ports are filtered.
|
||||
*/
|
||||
ports(
|
||||
predicate?: (detectedPort: DetectedPort) => boolean
|
||||
): readonly DetectedPort[] & Readonly<{ matchingIndex: number }>;
|
||||
|
||||
/**
|
||||
* Sugar for `#ports` with additional grouping based on the port `protocol`.
|
||||
*/
|
||||
portsGroupedByProtocol(): Readonly<
|
||||
Record<'serial' | 'network' | string, ReturnType<BoardList['ports']>>
|
||||
>;
|
||||
|
||||
/**
|
||||
* For dumping the current state of board list for debugging purposes.
|
||||
*/
|
||||
toString(): string;
|
||||
}
|
||||
|
||||
export type SelectBoardsConfigActionParams = Readonly<Defined<BoardsConfig>>;
|
||||
export interface SelectBoardsConfigAction {
|
||||
readonly type: 'select-boards-config';
|
||||
readonly params: SelectBoardsConfigActionParams;
|
||||
}
|
||||
export interface EditBoardsConfigActionParams {
|
||||
readonly portToSelect?: PortIdentifier;
|
||||
readonly boardToSelect?: BoardIdentifier;
|
||||
readonly query?: string;
|
||||
readonly searchSet?: readonly BoardIdentifier[];
|
||||
}
|
||||
export interface EditBoardsConfigAction {
|
||||
readonly type: 'edit-boards-config';
|
||||
readonly params: EditBoardsConfigActionParams;
|
||||
}
|
||||
export type BoardListItemAction =
|
||||
| SelectBoardsConfigAction
|
||||
| EditBoardsConfigAction;
|
||||
|
||||
export function createBoardList(
|
||||
detectedPorts: DetectedPorts,
|
||||
boardsConfig: Readonly<BoardsConfig> = emptyBoardsConfig(),
|
||||
boardListHistory: BoardListHistory = {}
|
||||
): BoardList {
|
||||
const items: BoardListItemUI[] = [];
|
||||
for (const detectedPort of Object.values(detectedPorts)) {
|
||||
const item = createBoardListItemUI(detectedPort, boardListHistory);
|
||||
items.push(item);
|
||||
}
|
||||
items.sort(boardListItemComparator);
|
||||
const selectedIndex = findSelectedIndex(boardsConfig, items);
|
||||
const boards = collectBoards(items);
|
||||
const allPorts = collectPorts(items, detectedPorts);
|
||||
const labels = createBoardListLabels(
|
||||
boardsConfig,
|
||||
allPorts,
|
||||
items[selectedIndex]
|
||||
);
|
||||
return {
|
||||
labels,
|
||||
items,
|
||||
boardsConfig,
|
||||
boards,
|
||||
selectedIndex,
|
||||
ports(predicate?: (detectedPort: DetectedPort) => boolean) {
|
||||
return filterPorts(allPorts, boardsConfig.selectedPort, predicate);
|
||||
},
|
||||
portsGroupedByProtocol() {
|
||||
const _allPorts = filterPorts(allPorts, boardsConfig.selectedPort);
|
||||
return portsGroupedByProtocol(_allPorts);
|
||||
},
|
||||
toString() {
|
||||
return JSON.stringify(
|
||||
{
|
||||
labels,
|
||||
detectedPorts,
|
||||
boardsConfig,
|
||||
items,
|
||||
selectedIndex,
|
||||
boardListHistory,
|
||||
},
|
||||
null,
|
||||
2
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function portsGroupedByProtocol(
|
||||
allPorts: ReturnType<BoardList['ports']>
|
||||
): ReturnType<BoardList['portsGroupedByProtocol']> {
|
||||
const result: Record<string, DetectedPort[] & { matchingIndex: number }> = {};
|
||||
for (const detectedPort of allPorts) {
|
||||
const protocol = detectedPort.port.protocol;
|
||||
if (!result[protocol]) {
|
||||
result[protocol] = Object.assign([], {
|
||||
matchingIndex: -1,
|
||||
});
|
||||
}
|
||||
const portsOnProtocol = result[protocol];
|
||||
portsOnProtocol.push(detectedPort);
|
||||
}
|
||||
const matchItem = allPorts[allPorts.matchingIndex];
|
||||
// the cached match index is per all ports. Here, IDE2 needs to adjust the match index per grouped protocol
|
||||
if (matchItem) {
|
||||
const matchProtocol = matchItem.port.protocol;
|
||||
const matchPorts = result[matchProtocol];
|
||||
matchPorts.matchingIndex = matchPorts.indexOf(matchItem);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function filterPorts(
|
||||
allPorts: readonly DetectedPort[],
|
||||
selectedPort: PortIdentifier | undefined,
|
||||
predicate: (detectedPort: DetectedPort) => boolean = () => true
|
||||
): ReturnType<BoardList['ports']> {
|
||||
const ports = allPorts.filter(predicate);
|
||||
const matchingIndex = findMatchingPortIndex(selectedPort, ports);
|
||||
return Object.assign(ports, { matchingIndex });
|
||||
}
|
||||
|
||||
function collectPorts(
|
||||
items: readonly BoardListItem[],
|
||||
detectedPorts: DetectedPorts
|
||||
): DetectedPort[] {
|
||||
const allPorts: DetectedPort[] = [];
|
||||
// to keep the order or the detected ports
|
||||
const visitedPortKeys = new Set<string>();
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const { port } = items[i];
|
||||
const portKey = Port.keyOf(port);
|
||||
if (!visitedPortKeys.has(portKey)) {
|
||||
visitedPortKeys.add(portKey);
|
||||
const detectedPort = detectedPorts[portKey];
|
||||
if (detectedPort) {
|
||||
allPorts.push(detectedPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
return allPorts;
|
||||
}
|
||||
|
||||
function collectBoards(
|
||||
items: readonly BoardListItem[]
|
||||
): readonly (BoardListItemWithBoard | InferredBoardListItem)[] {
|
||||
const boards: (BoardListItemWithBoard | InferredBoardListItem)[] = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
if (isInferredBoardListItem(item)) {
|
||||
boards.push(item);
|
||||
} else if (item.board?.fqbn) {
|
||||
boards.push(<Required<BoardListItem>>item);
|
||||
}
|
||||
}
|
||||
return boards;
|
||||
}
|
||||
|
||||
function findSelectedIndex(
|
||||
boardsConfig: BoardsConfig,
|
||||
items: readonly BoardListItem[]
|
||||
): number {
|
||||
if (!isDefinedBoardsConfig(boardsConfig)) {
|
||||
return -1;
|
||||
}
|
||||
const length = items.length;
|
||||
const { selectedPort, selectedBoard } = boardsConfig;
|
||||
const portKey = Port.keyOf(selectedPort);
|
||||
// find the exact match of the board and port combination
|
||||
for (let index = 0; index < length; index++) {
|
||||
const item = items[index];
|
||||
const { board, port } = item;
|
||||
if (!board) {
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
Port.keyOf(port) === portKey &&
|
||||
boardIdentifierEquals(board, selectedBoard)
|
||||
) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
// find match from inferred board
|
||||
for (let index = 0; index < length; index++) {
|
||||
const item = items[index];
|
||||
if (!isInferredBoardListItem(item)) {
|
||||
continue;
|
||||
}
|
||||
const { inferredBoard, port } = item;
|
||||
if (
|
||||
Port.keyOf(port) === portKey &&
|
||||
boardIdentifierEquals(inferredBoard, boardsConfig.selectedBoard)
|
||||
) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
function createBoardListItemUI(
|
||||
detectedPort: DetectedPort,
|
||||
boardListHistory: BoardListHistory
|
||||
): BoardListItemUI {
|
||||
const item = createBoardListItem(detectedPort, boardListHistory);
|
||||
const labels = createBoardListItemLabels(item);
|
||||
const defaultAction = createDefaultAction(item);
|
||||
const otherActions = createOtherActions(item);
|
||||
return Object.assign(item, { labels, defaultAction, otherActions });
|
||||
}
|
||||
|
||||
function createBoardListItem(
|
||||
detectedPort: DetectedPort,
|
||||
boardListHistory: BoardListHistory
|
||||
): BoardListItem {
|
||||
const { port, boards } = detectedPort;
|
||||
// boards with arduino vendor should come first
|
||||
boards?.sort(boardIdentifierComparator);
|
||||
const portKey = Port.keyOf(port);
|
||||
const inferredBoard = boardListHistory[portKey];
|
||||
if (!boards?.length) {
|
||||
let unknownItem: BoardListItem | InferredBoardListItem = { port };
|
||||
// Infer unrecognized boards from the history
|
||||
if (inferredBoard) {
|
||||
unknownItem = {
|
||||
...unknownItem,
|
||||
inferredBoard,
|
||||
type: 'manually-selected',
|
||||
};
|
||||
}
|
||||
return unknownItem;
|
||||
} else if (boards.length === 1) {
|
||||
const board = boards[0];
|
||||
let detectedItem: BoardListItemWithBoard | InferredBoardListItem = {
|
||||
port,
|
||||
board,
|
||||
};
|
||||
if (
|
||||
inferredBoard &&
|
||||
// ignore the inferred item if it's the same as the discovered board
|
||||
!boardIdentifierEquals(board, inferredBoard)
|
||||
) {
|
||||
detectedItem = {
|
||||
...detectedItem,
|
||||
inferredBoard,
|
||||
type: 'board-overridden',
|
||||
};
|
||||
}
|
||||
return detectedItem;
|
||||
} else {
|
||||
let ambiguousItem: MultiBoardsBoardListItem | InferredBoardListItem = {
|
||||
port,
|
||||
boards,
|
||||
};
|
||||
if (inferredBoard) {
|
||||
ambiguousItem = {
|
||||
...ambiguousItem,
|
||||
inferredBoard,
|
||||
type: 'manually-selected',
|
||||
};
|
||||
}
|
||||
return ambiguousItem;
|
||||
}
|
||||
}
|
||||
|
||||
function createDefaultAction(item: BoardListItem): BoardListItemAction {
|
||||
if (isInferredBoardListItem(item)) {
|
||||
return createSelectAction({
|
||||
selectedBoard: item.inferredBoard,
|
||||
selectedPort: item.port,
|
||||
});
|
||||
}
|
||||
if (item.board) {
|
||||
return createSelectAction({
|
||||
selectedBoard: item.board,
|
||||
selectedPort: item.port,
|
||||
});
|
||||
}
|
||||
return createEditAction(item);
|
||||
}
|
||||
|
||||
function createOtherActions(
|
||||
item: BoardListItem
|
||||
): BoardListItemUI['otherActions'] {
|
||||
if (isInferredBoardListItem(item)) {
|
||||
const edit = createEditAction(item);
|
||||
if (item.type === 'board-overridden') {
|
||||
const revert = createSelectAction({
|
||||
selectedBoard: item.board,
|
||||
selectedPort: item.port,
|
||||
});
|
||||
return { edit, revert };
|
||||
}
|
||||
return { edit };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
function createSelectAction(
|
||||
params: SelectBoardsConfigActionParams
|
||||
): SelectBoardsConfigAction {
|
||||
return {
|
||||
type: 'select-boards-config',
|
||||
params,
|
||||
};
|
||||
}
|
||||
|
||||
function createEditAction(item: BoardListItem): EditBoardsConfigAction {
|
||||
const params: Mutable<EditBoardsConfigActionParams> = {
|
||||
portToSelect: item.port,
|
||||
};
|
||||
if (isMultiBoardsBoardListItem(item)) {
|
||||
const uniqueBoardName = findUniqueBoardName(item);
|
||||
params.query = uniqueBoardName ?? '';
|
||||
params.searchSet = item.boards;
|
||||
} else if (isInferredBoardListItem(item)) {
|
||||
params.query = item.inferredBoard.name;
|
||||
} else if (item.board) {
|
||||
params.query = item.board.name;
|
||||
} else {
|
||||
params.query = '';
|
||||
}
|
||||
return {
|
||||
type: 'edit-boards-config',
|
||||
params,
|
||||
};
|
||||
}
|
@ -1,8 +1,6 @@
|
||||
import { naturalCompare } from './../utils';
|
||||
import { Searchable } from './searchable';
|
||||
import { Installable } from './installable';
|
||||
import { ArduinoComponent } from './arduino-component';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import type { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import type URI from '@theia/core/lib/common/uri';
|
||||
import {
|
||||
All,
|
||||
Contributed,
|
||||
@ -10,131 +8,46 @@ import {
|
||||
Type as TypeLabel,
|
||||
Updatable,
|
||||
} from '../nls';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import type { Defined } from '../types';
|
||||
import { naturalCompare } from './../utils';
|
||||
import type { ArduinoComponent } from './arduino-component';
|
||||
import type { BoardList } from './board-list';
|
||||
import { Installable } from './installable';
|
||||
import { Searchable } from './searchable';
|
||||
|
||||
export type AvailablePorts = Record<string, [Port, Array<Board>]>;
|
||||
export namespace AvailablePorts {
|
||||
export function groupByProtocol(
|
||||
availablePorts: AvailablePorts
|
||||
): Map<string, AvailablePorts> {
|
||||
const grouped = new Map<string, AvailablePorts>();
|
||||
for (const portID of Object.keys(availablePorts)) {
|
||||
const [port, boards] = availablePorts[portID];
|
||||
let ports = grouped.get(port.protocol);
|
||||
if (!ports) {
|
||||
ports = {} as AvailablePorts;
|
||||
}
|
||||
ports[portID] = [port, boards];
|
||||
grouped.set(port.protocol, ports);
|
||||
}
|
||||
return grouped;
|
||||
}
|
||||
export function split(
|
||||
state: AvailablePorts
|
||||
): Readonly<{ boards: Board[]; ports: Port[] }> {
|
||||
const availablePorts: Port[] = [];
|
||||
const attachedBoards: Board[] = [];
|
||||
for (const key of Object.keys(state)) {
|
||||
const [port, boards] = state[key];
|
||||
availablePorts.push(port);
|
||||
attachedBoards.push(...boards);
|
||||
}
|
||||
return {
|
||||
boards: attachedBoards,
|
||||
ports: availablePorts,
|
||||
};
|
||||
}
|
||||
export interface DetectedPort {
|
||||
readonly port: Port;
|
||||
readonly boards?: Pick<Board, 'name' | 'fqbn'>[];
|
||||
}
|
||||
|
||||
export interface AttachedBoardsChangeEvent {
|
||||
readonly oldState: Readonly<{ boards: Board[]; ports: Port[] }>;
|
||||
readonly newState: Readonly<{ boards: Board[]; ports: Port[] }>;
|
||||
readonly uploadInProgress: boolean;
|
||||
export function findMatchingPortIndex(
|
||||
toFind: PortIdentifier | undefined,
|
||||
ports: readonly DetectedPort[] | readonly Port[]
|
||||
): number {
|
||||
if (!toFind) {
|
||||
return -1;
|
||||
}
|
||||
const toFindPortKey = Port.keyOf(toFind);
|
||||
return ports.findIndex((port) => Port.keyOf(port) === toFindPortKey);
|
||||
}
|
||||
export namespace AttachedBoardsChangeEvent {
|
||||
export function isEmpty(event: AttachedBoardsChangeEvent): boolean {
|
||||
const { detached, attached } = diff(event);
|
||||
return (
|
||||
!!detached.boards.length &&
|
||||
!!detached.ports.length &&
|
||||
!!attached.boards.length &&
|
||||
!!attached.ports.length
|
||||
);
|
||||
}
|
||||
|
||||
export function toString(event: AttachedBoardsChangeEvent): string {
|
||||
const rows: string[] = [];
|
||||
if (!isEmpty(event)) {
|
||||
const { attached, detached } = diff(event);
|
||||
const visitedAttachedPorts: Port[] = [];
|
||||
const visitedDetachedPorts: Port[] = [];
|
||||
for (const board of attached.boards) {
|
||||
const port = board.port ? ` on ${Port.toString(board.port)}` : '';
|
||||
rows.push(` - Attached board: ${Board.toString(board)}${port}`);
|
||||
if (board.port) {
|
||||
visitedAttachedPorts.push(board.port);
|
||||
}
|
||||
}
|
||||
for (const board of detached.boards) {
|
||||
const port = board.port ? ` from ${Port.toString(board.port)}` : '';
|
||||
rows.push(` - Detached board: ${Board.toString(board)}${port}`);
|
||||
if (board.port) {
|
||||
visitedDetachedPorts.push(board.port);
|
||||
}
|
||||
}
|
||||
for (const port of attached.ports) {
|
||||
if (!visitedAttachedPorts.find((p) => Port.sameAs(port, p))) {
|
||||
rows.push(` - New port is available on ${Port.toString(port)}`);
|
||||
}
|
||||
}
|
||||
for (const port of detached.ports) {
|
||||
if (!visitedDetachedPorts.find((p) => Port.sameAs(port, p))) {
|
||||
rows.push(` - Port is no longer available on ${Port.toString(port)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows.length ? rows.join('\n') : 'No changes.';
|
||||
}
|
||||
/**
|
||||
* The closest representation what the Arduino CLI detects with the `board list --watch` gRPC equivalent.
|
||||
* The keys are unique identifiers generated from the port object (via `Port#keyOf`).
|
||||
* The values are the detected ports with all their optional `properties` and matching board list.
|
||||
*/
|
||||
export type DetectedPorts = Readonly<Record<string, DetectedPort>>;
|
||||
|
||||
export function diff(event: AttachedBoardsChangeEvent): Readonly<{
|
||||
attached: {
|
||||
boards: Board[];
|
||||
ports: Port[];
|
||||
};
|
||||
detached: {
|
||||
boards: Board[];
|
||||
ports: Port[];
|
||||
};
|
||||
}> {
|
||||
// In `lefts` AND not in `rights`.
|
||||
const diff = <T>(
|
||||
lefts: T[],
|
||||
rights: T[],
|
||||
sameAs: (left: T, right: T) => boolean
|
||||
) => {
|
||||
return lefts.filter(
|
||||
(left) => rights.findIndex((right) => sameAs(left, right)) === -1
|
||||
);
|
||||
};
|
||||
const { boards: newBoards } = event.newState;
|
||||
const { boards: oldBoards } = event.oldState;
|
||||
const { ports: newPorts } = event.newState;
|
||||
const { ports: oldPorts } = event.oldState;
|
||||
const boardSameAs = (left: Board, right: Board) =>
|
||||
Board.sameAs(left, right);
|
||||
const portSameAs = (left: Port, right: Port) => Port.sameAs(left, right);
|
||||
return {
|
||||
detached: {
|
||||
boards: diff(oldBoards, newBoards, boardSameAs),
|
||||
ports: diff(oldPorts, newPorts, portSameAs),
|
||||
},
|
||||
attached: {
|
||||
boards: diff(newBoards, oldBoards, boardSameAs),
|
||||
ports: diff(newPorts, oldPorts, portSameAs),
|
||||
},
|
||||
};
|
||||
export function resolveDetectedPort(
|
||||
port: PortIdentifier,
|
||||
detectedPorts: DetectedPorts
|
||||
): Port | undefined {
|
||||
const portKey = Port.keyOf(port);
|
||||
const detectedPort = detectedPorts[portKey];
|
||||
if (detectedPort) {
|
||||
return detectedPort.port;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export const BoardsServicePath = '/services/boards-service';
|
||||
@ -152,14 +65,17 @@ export interface BoardsService
|
||||
*/
|
||||
skipPostInstall?: boolean;
|
||||
}): Promise<void>;
|
||||
getState(): Promise<AvailablePorts>;
|
||||
getDetectedPorts(): Promise<DetectedPorts>;
|
||||
getBoardDetails(options: { fqbn: string }): Promise<BoardDetails | undefined>;
|
||||
getBoardPackage(options: { id: string }): Promise<BoardsPackage | undefined>;
|
||||
getBoardPackage(options: {
|
||||
id: string /* TODO: change to PlatformIdentifier type? */;
|
||||
}): Promise<BoardsPackage | undefined>;
|
||||
getContainerBoardPackage(options: {
|
||||
fqbn: string;
|
||||
}): Promise<BoardsPackage | undefined>;
|
||||
searchBoards({ query }: { query?: string }): Promise<BoardWithPackage[]>;
|
||||
getInstalledBoards(): Promise<BoardWithPackage[]>;
|
||||
getInstalledPlatforms(): Promise<BoardsPackage[]>;
|
||||
getBoardUserFields(options: {
|
||||
fqbn: string;
|
||||
protocol: string;
|
||||
@ -180,7 +96,7 @@ export namespace BoardSearch {
|
||||
'Partner',
|
||||
'Arduino@Heart',
|
||||
] as const;
|
||||
export type Type = typeof TypeLiterals[number];
|
||||
export type Type = (typeof TypeLiterals)[number];
|
||||
export namespace Type {
|
||||
export function is(arg: unknown): arg is Type {
|
||||
return typeof arg === 'string' && TypeLiterals.includes(arg as Type);
|
||||
@ -252,9 +168,9 @@ export namespace Port {
|
||||
export namespace Properties {
|
||||
export function create(
|
||||
properties: [string, string][] | undefined
|
||||
): Properties {
|
||||
if (!properties) {
|
||||
return {};
|
||||
): Properties | undefined {
|
||||
if (!properties || !properties.length) {
|
||||
return undefined;
|
||||
}
|
||||
return properties.reduce((acc, curr) => {
|
||||
const [key, value] = curr;
|
||||
@ -282,10 +198,13 @@ export namespace Port {
|
||||
}
|
||||
|
||||
/**
|
||||
* Key is the combination of address and protocol formatted like `'${address}|${protocol}'` used to uniquely identify a port.
|
||||
* Key is the combination of address and protocol formatted like `'arduino+${protocol}://${address}'` used to uniquely identify a port.
|
||||
*/
|
||||
export function keyOf({ address, protocol }: Port): string {
|
||||
return `${address}|${protocol}`;
|
||||
export function keyOf(port: PortIdentifier | Port | DetectedPort): string {
|
||||
if (isPortIdentifier(port)) {
|
||||
return `arduino+${port.protocol}://${port.address}`;
|
||||
}
|
||||
return keyOf(port.port);
|
||||
}
|
||||
|
||||
export function toString({ addressLabel, protocolLabel }: Port): string {
|
||||
@ -297,16 +216,8 @@ export namespace Port {
|
||||
// 1. Serial
|
||||
// 2. Network
|
||||
// 3. Other protocols
|
||||
if (left.protocol === 'serial' && right.protocol !== 'serial') {
|
||||
return -1;
|
||||
} else if (left.protocol !== 'serial' && right.protocol === 'serial') {
|
||||
return 1;
|
||||
} else if (left.protocol === 'network' && right.protocol !== 'network') {
|
||||
return -1;
|
||||
} else if (left.protocol !== 'network' && right.protocol === 'network') {
|
||||
return 1;
|
||||
}
|
||||
return naturalCompare(left.address!, right.address!);
|
||||
const priorityResult = portProtocolComparator(left, right);
|
||||
return priorityResult || naturalCompare(left.address, right.address);
|
||||
}
|
||||
|
||||
export function sameAs(
|
||||
@ -324,35 +235,28 @@ export namespace Port {
|
||||
/**
|
||||
* All ports with `'serial'` or `'network'` `protocol`, or any other port `protocol` that has at least one recognized board connected to.
|
||||
*/
|
||||
export function visiblePorts(
|
||||
boardsHaystack: ReadonlyArray<Board>
|
||||
): (port: Port) => boolean {
|
||||
return (port: Port) => {
|
||||
if (port.protocol === 'serial' || port.protocol === 'network') {
|
||||
// Allow all `serial` and `network` boards.
|
||||
// IDE2 must support better label for unrecognized `network` boards: https://github.com/arduino/arduino-ide/issues/1331
|
||||
return true;
|
||||
}
|
||||
// All other ports with different protocol are
|
||||
// only shown if there is a recognized board
|
||||
// connected
|
||||
for (const board of boardsHaystack) {
|
||||
if (board.port?.address === port.address) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
export function isVisiblePort(detectedPort: DetectedPort): boolean {
|
||||
const protocol = detectedPort.port.protocol;
|
||||
if (protocol === 'serial' || protocol === 'network') {
|
||||
// Allow all `serial` and `network` boards.
|
||||
// IDE2 must support better label for unrecognized `network` boards: https://github.com/arduino/arduino-ide/issues/1331
|
||||
return true;
|
||||
}
|
||||
// All other ports with different protocol are
|
||||
// only shown if there is a recognized board
|
||||
// connected
|
||||
return Boolean(detectedPort?.boards?.length);
|
||||
}
|
||||
|
||||
export namespace Protocols {
|
||||
// IDE2 does not want to handle any other port protocols in a special way
|
||||
export const KnownProtocolLiterals = ['serial', 'network'] as const;
|
||||
export type KnownProtocol = typeof KnownProtocolLiterals[number];
|
||||
export type KnownProtocol = (typeof KnownProtocolLiterals)[number];
|
||||
export namespace KnownProtocol {
|
||||
export function is(protocol: unknown): protocol is KnownProtocol {
|
||||
return (
|
||||
typeof protocol === 'string' &&
|
||||
KnownProtocolLiterals.indexOf(protocol as KnownProtocol) >= 0
|
||||
KnownProtocolLiterals.includes(protocol as KnownProtocol)
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -377,29 +281,12 @@ export namespace BoardsPackage {
|
||||
export function equals(left: BoardsPackage, right: BoardsPackage): boolean {
|
||||
return left.id === right.id;
|
||||
}
|
||||
|
||||
export function contains(
|
||||
selectedBoard: Board,
|
||||
{ id, boards }: BoardsPackage
|
||||
): boolean {
|
||||
if (boards.some((board) => Board.sameAs(board, selectedBoard))) {
|
||||
return true;
|
||||
}
|
||||
if (selectedBoard.fqbn) {
|
||||
const [platform, architecture] = selectedBoard.fqbn.split(':');
|
||||
if (platform && architecture) {
|
||||
return `${platform}:${architecture}` === id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export interface Board {
|
||||
readonly name: string;
|
||||
readonly fqbn?: string;
|
||||
readonly port?: Port;
|
||||
}
|
||||
/**
|
||||
* @deprecated user `BoardIdentifier` instead.
|
||||
*/
|
||||
export type Board = BoardIdentifier;
|
||||
|
||||
export interface BoardUserField {
|
||||
readonly toolId: string;
|
||||
@ -411,14 +298,19 @@ export interface BoardUserField {
|
||||
|
||||
export interface BoardWithPackage extends Board {
|
||||
readonly packageName: string;
|
||||
readonly packageId: string;
|
||||
readonly packageId: PlatformIdentifier;
|
||||
readonly manuallyInstalled: boolean;
|
||||
}
|
||||
export namespace BoardWithPackage {
|
||||
export function is(
|
||||
board: Board & Partial<{ packageName: string; packageId: string }>
|
||||
): board is BoardWithPackage {
|
||||
return !!board.packageId && !!board.packageName;
|
||||
export function is(arg: unknown): arg is BoardWithPackage {
|
||||
return (
|
||||
isBoardIdentifier(arg) &&
|
||||
(<BoardWithPackage>arg).packageName !== undefined &&
|
||||
typeof (<BoardWithPackage>arg).packageName === 'string' &&
|
||||
isPlatformIdentifier((<BoardWithPackage>arg).packageId) &&
|
||||
(<BoardWithPackage>arg).manuallyInstalled !== undefined &&
|
||||
typeof (<BoardWithPackage>arg).manuallyInstalled === 'boolean'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -456,18 +348,6 @@ export interface ConfigOption {
|
||||
readonly values: ConfigValue[];
|
||||
}
|
||||
export namespace ConfigOption {
|
||||
export function is(arg: any): arg is ConfigOption {
|
||||
return (
|
||||
!!arg &&
|
||||
'option' in arg &&
|
||||
'label' in arg &&
|
||||
'values' in arg &&
|
||||
typeof arg['option'] === 'string' &&
|
||||
typeof arg['label'] === 'string' &&
|
||||
Array.isArray(arg['values'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the configuration options to the `fqbn` argument.
|
||||
* Throws an error if the `fqbn` does not have the `segment(':'segment)*` format.
|
||||
@ -555,24 +435,15 @@ export namespace Board {
|
||||
return left.name === right.name && left.fqbn === right.fqbn;
|
||||
}
|
||||
|
||||
export function hardwareIdEquals(left: Board, right: Board): boolean {
|
||||
if (left.port && right.port) {
|
||||
const { hardwareId: leftHardwareId } = left.port;
|
||||
const { hardwareId: rightHardwareId } = right.port;
|
||||
|
||||
if (leftHardwareId && rightHardwareId) {
|
||||
return leftHardwareId === rightHardwareId;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function sameAs(left: Board, right: string | Board): boolean {
|
||||
export function sameAs(
|
||||
left: BoardIdentifier,
|
||||
right: string | BoardIdentifier
|
||||
): boolean {
|
||||
// How to associate a selected board with one of the available cores: https://typefox.slack.com/archives/CJJHJCJSJ/p1571142327059200
|
||||
// 1. How to use the FQBN if any and infer the package ID from it: https://typefox.slack.com/archives/CJJHJCJSJ/p1571147549069100
|
||||
// 2. How to trim the `/Genuino` from the name: https://arduino.slack.com/archives/CJJHJCJSJ/p1571146951066800?thread_ts=1571142327.059200&cid=CJJHJCJSJ
|
||||
const other = typeof right === 'string' ? { name: right } : right;
|
||||
const other: BoardIdentifier =
|
||||
typeof right === 'string' ? { name: right, fqbn: undefined } : right;
|
||||
if (left.fqbn && other.fqbn) {
|
||||
return left.fqbn === other.fqbn;
|
||||
}
|
||||
@ -594,7 +465,7 @@ export namespace Board {
|
||||
}
|
||||
|
||||
export function toString(
|
||||
board: Board,
|
||||
board: BoardIdentifier,
|
||||
options: { useFqbn: boolean } = { useFqbn: true }
|
||||
): string {
|
||||
const fqbn =
|
||||
@ -607,14 +478,15 @@ export namespace Board {
|
||||
selected: boolean;
|
||||
missing: boolean;
|
||||
packageName: string;
|
||||
packageId: string;
|
||||
packageId: PlatformIdentifier;
|
||||
details?: string;
|
||||
manuallyInstalled: boolean;
|
||||
}>;
|
||||
export function decorateBoards(
|
||||
selectedBoard: Board | undefined,
|
||||
selectedBoard: BoardIdentifier | BoardWithPackage | undefined,
|
||||
boards: Array<BoardWithPackage>
|
||||
): Array<Detailed> {
|
||||
let foundSelected = false;
|
||||
// Board names are not unique. We show the corresponding core name as a detail.
|
||||
// https://github.com/arduino/arduino-cli/pull/294#issuecomment-513764948
|
||||
const distinctBoardNames = new Map<string, number>();
|
||||
@ -622,21 +494,42 @@ export namespace Board {
|
||||
const counter = distinctBoardNames.get(name) || 0;
|
||||
distinctBoardNames.set(name, counter + 1);
|
||||
}
|
||||
|
||||
// Due to the non-unique board names, we have to check the package name as well.
|
||||
const selected = (board: BoardWithPackage) => {
|
||||
if (!!selectedBoard) {
|
||||
if (Board.equals(board, selectedBoard)) {
|
||||
if ('packageName' in selectedBoard) {
|
||||
return board.packageName === (selectedBoard as any).packageName;
|
||||
}
|
||||
if ('packageId' in selectedBoard) {
|
||||
return board.packageId === (selectedBoard as any).packageId;
|
||||
}
|
||||
return true;
|
||||
const selectedBoardPackageId = selectedBoard
|
||||
? createPlatformIdentifier(selectedBoard)
|
||||
: undefined;
|
||||
const selectedBoardFqbn = selectedBoard?.fqbn;
|
||||
// Due to the non-unique board names, IDE2 has to check the package name when boards are not installed and the FQBN is absent.
|
||||
const isSelected = (board: BoardWithPackage) => {
|
||||
if (!selectedBoard) {
|
||||
return false;
|
||||
}
|
||||
if (foundSelected) {
|
||||
return false;
|
||||
}
|
||||
let selected = false;
|
||||
if (board.fqbn && selectedBoardFqbn) {
|
||||
if (boardIdentifierEquals(board, selectedBoard)) {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
if (!selected) {
|
||||
if (board.name === selectedBoard.name) {
|
||||
if (selectedBoardPackageId) {
|
||||
const boardPackageId = createPlatformIdentifier(board);
|
||||
if (boardPackageId) {
|
||||
if (
|
||||
platformIdentifierEquals(boardPackageId, selectedBoardPackageId)
|
||||
) {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (selected) {
|
||||
foundSelected = true;
|
||||
}
|
||||
return selected;
|
||||
};
|
||||
return boards.map((board) => ({
|
||||
...board,
|
||||
@ -644,7 +537,7 @@ export namespace Board {
|
||||
(distinctBoardNames.get(board.name) || 0) > 1
|
||||
? ` - ${board.packageName}`
|
||||
: undefined,
|
||||
selected: selected(board),
|
||||
selected: isSelected(board),
|
||||
missing: !installed(board),
|
||||
}));
|
||||
}
|
||||
@ -674,11 +567,267 @@ export function sanitizeFqbn(fqbn: string | undefined): string | undefined {
|
||||
return `${vendor}:${arch}:${id}`;
|
||||
}
|
||||
|
||||
export interface BoardConfig {
|
||||
selectedBoard?: Board;
|
||||
selectedPort?: Port;
|
||||
export type PlatformIdentifier = Readonly<{ vendorId: string; arch: string }>;
|
||||
export function createPlatformIdentifier(
|
||||
board: BoardWithPackage
|
||||
): PlatformIdentifier;
|
||||
export function createPlatformIdentifier(
|
||||
board: BoardIdentifier
|
||||
): PlatformIdentifier | undefined;
|
||||
export function createPlatformIdentifier(
|
||||
fqbn: string
|
||||
): PlatformIdentifier | undefined;
|
||||
export function createPlatformIdentifier(
|
||||
arg: BoardIdentifier | BoardWithPackage | string
|
||||
): PlatformIdentifier | undefined {
|
||||
if (BoardWithPackage.is(arg)) {
|
||||
return arg.packageId;
|
||||
}
|
||||
const toSplit = typeof arg === 'string' ? arg : arg.fqbn;
|
||||
if (toSplit) {
|
||||
const [vendorId, arch] = toSplit.split(':');
|
||||
if (vendorId && arch) {
|
||||
return { vendorId, arch };
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function isPlatformIdentifier(arg: unknown): arg is PlatformIdentifier {
|
||||
return (
|
||||
Boolean(arg) &&
|
||||
typeof arg === 'object' &&
|
||||
(<PlatformIdentifier>arg).vendorId !== undefined &&
|
||||
typeof (<PlatformIdentifier>arg).vendorId === 'string' &&
|
||||
(<PlatformIdentifier>arg).arch !== undefined &&
|
||||
typeof (<PlatformIdentifier>arg).arch === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
export function serializePlatformIdentifier({
|
||||
vendorId,
|
||||
arch,
|
||||
}: PlatformIdentifier): string {
|
||||
return `${vendorId}:${arch}`;
|
||||
}
|
||||
|
||||
export function platformIdentifierEquals(
|
||||
left: PlatformIdentifier,
|
||||
right: PlatformIdentifier
|
||||
) {
|
||||
return left.vendorId === right.vendorId && left.arch === right.arch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bare minimum information to identify port.
|
||||
*/
|
||||
export type PortIdentifier = Readonly<Pick<Port, 'protocol' | 'address'>>;
|
||||
|
||||
export function portIdentifierEquals(
|
||||
left: PortIdentifier | undefined,
|
||||
right: PortIdentifier | undefined
|
||||
): boolean {
|
||||
if (!left) {
|
||||
return !right;
|
||||
}
|
||||
if (!right) {
|
||||
return !left;
|
||||
}
|
||||
return left.protocol === right.protocol && left.address === right.address;
|
||||
}
|
||||
|
||||
export function isPortIdentifier(arg: unknown): arg is PortIdentifier {
|
||||
return (
|
||||
Boolean(arg) &&
|
||||
typeof arg === 'object' &&
|
||||
(<PortIdentifier>arg).protocol !== undefined &&
|
||||
typeof (<PortIdentifier>arg).protocol === 'string' &&
|
||||
(<PortIdentifier>arg).address !== undefined &&
|
||||
typeof (<PortIdentifier>arg).address === 'string'
|
||||
);
|
||||
}
|
||||
|
||||
// the smaller the number, the higher the priority
|
||||
const portProtocolPriorities: Record<string, number> = {
|
||||
serial: 0,
|
||||
network: 1,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* See `boardListItemComparator`.
|
||||
*/
|
||||
export function portProtocolComparator(
|
||||
left: PortIdentifier,
|
||||
right: PortIdentifier
|
||||
): number {
|
||||
const leftPriority =
|
||||
portProtocolPriorities[left.protocol] ?? Number.MAX_SAFE_INTEGER;
|
||||
const rightPriority =
|
||||
portProtocolPriorities[right.protocol] ?? Number.MAX_SAFE_INTEGER;
|
||||
return leftPriority - rightPriority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lightweight information to identify a board.\
|
||||
* \
|
||||
* Note: the `name` property of the board identifier must never participate in the board's identification.
|
||||
* Hence, it should only be used as the final fallback for the UI when the board's platform is not installed and only the board's name is available.
|
||||
*/
|
||||
export interface BoardIdentifier {
|
||||
/**
|
||||
* The name of the board. It's only purpose is to provide a fallback for the UI. Preferably do not use this property for any sophisticated logic. When
|
||||
*/
|
||||
readonly name: string;
|
||||
/**
|
||||
* The FQBN might contain boards config options if selected from the discovered ports (see [arduino/arduino-ide#1588](https://github.com/arduino/arduino-ide/issues/1588)).
|
||||
*/
|
||||
// TODO: decide whether to persist the boards config if any
|
||||
readonly fqbn: string | undefined;
|
||||
}
|
||||
|
||||
export function isBoardIdentifier(arg: unknown): arg is BoardIdentifier {
|
||||
return (
|
||||
Boolean(arg) &&
|
||||
typeof arg === 'object' &&
|
||||
(<BoardIdentifier>arg).name !== undefined &&
|
||||
typeof (<BoardIdentifier>arg).name === 'string' &&
|
||||
((<BoardIdentifier>arg).fqbn === undefined ||
|
||||
((<BoardIdentifier>arg).fqbn !== undefined &&
|
||||
typeof (<BoardIdentifier>arg).fqbn === 'string'))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param options if `looseFqbn` is `true`, FQBN config options are ignored. Hence, `{ name: 'x', fqbn: 'a:b:c:o1=v1 }` equals `{ name: 'y', fqbn: 'a:b:c' }`. It's `true` by default.
|
||||
*/
|
||||
export function boardIdentifierEquals(
|
||||
left: BoardIdentifier | undefined,
|
||||
right: BoardIdentifier | undefined,
|
||||
options: { looseFqbn: boolean } = { looseFqbn: true }
|
||||
): boolean {
|
||||
if (!left) {
|
||||
return !right;
|
||||
}
|
||||
if (!right) {
|
||||
return !left;
|
||||
}
|
||||
if ((left.fqbn && !right.fqbn) || (!left.fqbn && right.fqbn)) {
|
||||
// This can be very tricky when comparing boards
|
||||
// the CLI's board search returns with falsy FQBN when the platform is not installed
|
||||
// the CLI's board list returns with the full FQBN (for detected boards) even if the platform is not installed
|
||||
// when there are multiple boards with the same name (Arduino Nano RP2040) from different platforms (Mbed Nano OS vs. the deprecated global Mbed OS)
|
||||
// maybe add some 3rd party platform overhead (https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json)
|
||||
// and it will get very tricky when comparing a board which has a FQBN and which does not.
|
||||
return false; // TODO: This a strict now. Maybe compare name in the future.
|
||||
}
|
||||
if (left.fqbn && right.fqbn) {
|
||||
const leftFqbn = options.looseFqbn ? sanitizeFqbn(left.fqbn) : left.fqbn;
|
||||
const rightFqbn = options.looseFqbn ? sanitizeFqbn(right.fqbn) : right.fqbn;
|
||||
return leftFqbn === rightFqbn;
|
||||
}
|
||||
// No more Genuino hack.
|
||||
// https://github.com/arduino/arduino-ide/blob/f6a43254f5c416a2e4fa888875358336b42dd4d5/arduino-ide-extension/src/common/protocol/boards-service.ts#L572-L581
|
||||
return left.name === right.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* See `boardListItemComparator`.
|
||||
*/
|
||||
export function boardIdentifierComparator(
|
||||
left: BoardIdentifier | undefined,
|
||||
right: BoardIdentifier | undefined
|
||||
): number {
|
||||
if (!left) {
|
||||
return right ? 1 : 0;
|
||||
}
|
||||
if (!right) {
|
||||
return left ? -1 : 0;
|
||||
}
|
||||
let leftVendor: string | undefined = undefined;
|
||||
let rightVendor: string | undefined = undefined;
|
||||
if (left.fqbn) {
|
||||
const [vendor] = left.fqbn.split(':');
|
||||
leftVendor = vendor;
|
||||
}
|
||||
if (right.fqbn) {
|
||||
const [vendor] = right.fqbn.split(':');
|
||||
rightVendor = vendor;
|
||||
}
|
||||
if (leftVendor === 'arduino' && rightVendor !== 'arduino') {
|
||||
return -1;
|
||||
}
|
||||
if (leftVendor !== 'arduino' && rightVendor === 'arduino') {
|
||||
return 1;
|
||||
}
|
||||
return naturalCompare(left.name, right.name);
|
||||
}
|
||||
|
||||
export function boardIdentifierLabel(
|
||||
board: BoardIdentifier,
|
||||
showFqbn = true
|
||||
): string {
|
||||
const { name, fqbn } = board;
|
||||
let label = name;
|
||||
if (fqbn && showFqbn) {
|
||||
label += ` (${fqbn})`;
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
export interface BoardsConfig {
|
||||
selectedBoard: BoardIdentifier | undefined;
|
||||
selectedPort: PortIdentifier | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new board config object with `undefined` properties.
|
||||
*/
|
||||
export function emptyBoardsConfig(): BoardsConfig {
|
||||
return {
|
||||
selectedBoard: undefined,
|
||||
selectedPort: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export function isDefinedBoardsConfig(
|
||||
boardsConfig: BoardsConfig | undefined
|
||||
): boardsConfig is Defined<BoardsConfig> {
|
||||
if (!boardsConfig) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
boardsConfig.selectedBoard !== undefined &&
|
||||
boardsConfig.selectedPort !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
export interface BoardIdentifierChangeEvent {
|
||||
readonly previousSelectedBoard: BoardIdentifier | undefined;
|
||||
readonly selectedBoard: BoardIdentifier | undefined;
|
||||
}
|
||||
|
||||
export function isBoardIdentifierChangeEvent(
|
||||
event: BoardsConfigChangeEvent
|
||||
): event is BoardIdentifierChangeEvent {
|
||||
return 'previousSelectedBoard' in event && 'selectedBoard' in event;
|
||||
}
|
||||
|
||||
export interface PortIdentifierChangeEvent {
|
||||
readonly previousSelectedPort: PortIdentifier | undefined;
|
||||
readonly selectedPort: PortIdentifier | undefined;
|
||||
}
|
||||
|
||||
export function isPortIdentifierChangeEvent(
|
||||
event: BoardsConfigChangeEvent
|
||||
): event is PortIdentifierChangeEvent {
|
||||
return 'previousSelectedPort' in event && 'selectedPort' in event;
|
||||
}
|
||||
|
||||
export type BoardsConfigChangeEvent =
|
||||
| BoardIdentifierChangeEvent
|
||||
| PortIdentifierChangeEvent
|
||||
| (BoardIdentifierChangeEvent & PortIdentifierChangeEvent);
|
||||
|
||||
export interface BoardInfo {
|
||||
/**
|
||||
* Board name. Could be `'Unknown board`'.
|
||||
@ -714,50 +863,57 @@ export const unknownBoard = nls.localize(
|
||||
'arduino/board/unknownBoard',
|
||||
'Unknown board'
|
||||
);
|
||||
export const unconfirmedBoard = nls.localize(
|
||||
'arduino/board/unconfirmedBoard',
|
||||
'Unconfirmed board'
|
||||
);
|
||||
export const selectBoard = nls.localize(
|
||||
'arduino/board/selectBoard',
|
||||
'Select Board'
|
||||
);
|
||||
export const notConnected = nls.localize(
|
||||
'arduino/common/notConnected',
|
||||
'[not connected]'
|
||||
);
|
||||
|
||||
/**
|
||||
* The returned promise resolves to a `BoardInfo` if available to show in the UI or an info message explaining why showing the board info is not possible.
|
||||
*/
|
||||
export async function getBoardInfo(
|
||||
selectedPort: Port | undefined,
|
||||
availablePorts: MaybePromise<AvailablePorts>
|
||||
boardListProvider: MaybePromise<BoardList>
|
||||
): Promise<BoardInfo | string> {
|
||||
if (!selectedPort) {
|
||||
const boardList = await boardListProvider;
|
||||
const ports = boardList.ports();
|
||||
const detectedPort = ports[ports.matchingIndex];
|
||||
if (!detectedPort) {
|
||||
return selectPortForInfo;
|
||||
}
|
||||
const { port: selectedPort, boards } = detectedPort;
|
||||
// IDE2 must show the board info based on the selected port.
|
||||
// https://github.com/arduino/arduino-ide/issues/1489
|
||||
// IDE 1.x supports only serial port protocol
|
||||
if (selectedPort.protocol !== 'serial') {
|
||||
return nonSerialPort;
|
||||
}
|
||||
const selectedPortKey = Port.keyOf(selectedPort);
|
||||
const state = await availablePorts;
|
||||
const boardListOnSelectedPort = Object.entries(state).filter(
|
||||
([portKey, [port]]) =>
|
||||
portKey === selectedPortKey && isNonNativeSerial(port)
|
||||
);
|
||||
|
||||
if (!boardListOnSelectedPort.length) {
|
||||
if (!isNonNativeSerial(selectedPort)) {
|
||||
return noNativeSerialPort;
|
||||
}
|
||||
|
||||
const [, [port, boards]] = boardListOnSelectedPort[0];
|
||||
if (boardListOnSelectedPort.length > 1 || boards.length > 1) {
|
||||
if (boards && boards.length > 1) {
|
||||
console.warn(
|
||||
`Detected more than one available boards on the selected port : ${JSON.stringify(
|
||||
selectedPort
|
||||
detectedPort
|
||||
)}. Detected boards were: ${JSON.stringify(
|
||||
boardListOnSelectedPort
|
||||
)}. Using the first one: ${JSON.stringify([port, boards])}`
|
||||
boards
|
||||
)}. Using the first one: ${JSON.stringify(boards[0])}`
|
||||
);
|
||||
}
|
||||
|
||||
const board = boards[0];
|
||||
const board = boards ? boards[0] : undefined;
|
||||
const BN = board?.name ?? unknownBoard;
|
||||
const VID = readProperty('vid', port);
|
||||
const PID = readProperty('pid', port);
|
||||
const SN = readProperty('serialNumber', port);
|
||||
const VID = readProperty('vid', selectedPort);
|
||||
const PID = readProperty('pid', selectedPort);
|
||||
const SN = readProperty('serialNumber', selectedPort);
|
||||
return { VID, PID, SN, BN };
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { ApplicationError } from '@theia/core/lib/common/application-error';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import type {
|
||||
Location,
|
||||
Range,
|
||||
Position,
|
||||
Range,
|
||||
} from '@theia/core/shared/vscode-languageserver-protocol';
|
||||
import type { BoardUserField, Port, Installable } from '../../common/protocol/';
|
||||
import type { Programmer } from './boards-service';
|
||||
import type { Sketch } from './sketches-service';
|
||||
import { IndexUpdateSummary } from './notification-service';
|
||||
import type { CompileSummary as ApiCompileSummary } from 'vscode-arduino-api';
|
||||
import type { BoardUserField, Installable } from '../../common/protocol/';
|
||||
import { isPortIdentifier, PortIdentifier, Programmer } from './boards-service';
|
||||
import type { IndexUpdateSummary } from './notification-service';
|
||||
import type { Sketch } from './sketches-service';
|
||||
|
||||
export const CompilerWarningLiterals = [
|
||||
'None',
|
||||
@ -148,11 +148,22 @@ export function isCompileSummary(arg: unknown): arg is CompileSummary {
|
||||
);
|
||||
}
|
||||
|
||||
export interface UploadResponse {
|
||||
readonly portAfterUpload: PortIdentifier;
|
||||
}
|
||||
export function isUploadResponse(arg: unknown): arg is UploadResponse {
|
||||
return (
|
||||
Boolean(arg) &&
|
||||
typeof arg === 'object' &&
|
||||
isPortIdentifier((<UploadResponse>arg).portAfterUpload)
|
||||
);
|
||||
}
|
||||
|
||||
export const CoreServicePath = '/services/core-service';
|
||||
export const CoreService = Symbol('CoreService');
|
||||
export interface CoreService {
|
||||
compile(options: CoreService.Options.Compile): Promise<void>;
|
||||
upload(options: CoreService.Options.Upload): Promise<void>;
|
||||
upload(options: CoreService.Options.Upload): Promise<UploadResponse>;
|
||||
burnBootloader(options: CoreService.Options.Bootloader): Promise<void>;
|
||||
/**
|
||||
* Refreshes the underling core gRPC client for the Arduino CLI.
|
||||
@ -198,7 +209,7 @@ export namespace CoreService {
|
||||
readonly sketch: Sketch;
|
||||
}
|
||||
export interface BoardBased {
|
||||
readonly port?: Port;
|
||||
readonly port?: PortIdentifier;
|
||||
readonly programmer?: Programmer | undefined;
|
||||
/**
|
||||
* For the _Verify after upload_ setting.
|
||||
|
@ -1,5 +1,8 @@
|
||||
import { ApplicationError, Event, JsonRpcServer, nls } from '@theia/core';
|
||||
import { Board, Port } from './boards-service';
|
||||
import { ApplicationError } from '@theia/core/lib/common/application-error';
|
||||
import type { Event } from '@theia/core/lib/common/event';
|
||||
import type { JsonRpcServer } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import type { BoardIdentifier, PortIdentifier } from './boards-service';
|
||||
|
||||
export type PluggableMonitorSettings = Record<string, PluggableMonitorSetting>;
|
||||
export interface MonitorSettings {
|
||||
@ -15,17 +18,20 @@ export const MonitorManagerProxy = Symbol('MonitorManagerProxy');
|
||||
export interface MonitorManagerProxy
|
||||
extends JsonRpcServer<MonitorManagerProxyClient> {
|
||||
startMonitor(
|
||||
board: Board,
|
||||
port: Port,
|
||||
board: BoardIdentifier,
|
||||
port: PortIdentifier,
|
||||
settings?: PluggableMonitorSettings
|
||||
): Promise<void>;
|
||||
changeMonitorSettings(
|
||||
board: Board,
|
||||
port: Port,
|
||||
board: BoardIdentifier,
|
||||
port: PortIdentifier,
|
||||
settings: MonitorSettings
|
||||
): Promise<void>;
|
||||
stopMonitor(board: Board, port: Port): Promise<void>;
|
||||
getCurrentSettings(board: Board, port: Port): Promise<MonitorSettings>;
|
||||
stopMonitor(board: BoardIdentifier, port: PortIdentifier): Promise<void>;
|
||||
getCurrentSettings(
|
||||
board: BoardIdentifier,
|
||||
port: PortIdentifier
|
||||
): Promise<MonitorSettings>;
|
||||
}
|
||||
|
||||
export const MonitorManagerProxyClient = Symbol('MonitorManagerProxyClient');
|
||||
@ -38,7 +44,10 @@ export interface MonitorManagerProxyClient {
|
||||
getWebSocketPort(): number | undefined;
|
||||
isWSConnected(): Promise<boolean>;
|
||||
startMonitor(settings?: PluggableMonitorSettings): Promise<void>;
|
||||
getCurrentSettings(board: Board, port: Port): Promise<MonitorSettings>;
|
||||
getCurrentSettings(
|
||||
board: BoardIdentifier,
|
||||
port: PortIdentifier
|
||||
): Promise<MonitorSettings>;
|
||||
send(message: string): void;
|
||||
changeSettings(settings: MonitorSettings): void;
|
||||
}
|
||||
@ -95,7 +104,7 @@ export const MissingConfigurationError = declareMonitorError(
|
||||
);
|
||||
|
||||
export function createConnectionFailedError(
|
||||
port: Port,
|
||||
port: PortIdentifier,
|
||||
details?: string
|
||||
): ApplicationError<number, PortDescriptor> {
|
||||
const { protocol, address } = port;
|
||||
@ -120,7 +129,7 @@ export function createConnectionFailedError(
|
||||
return ConnectionFailedError(message, { protocol, address });
|
||||
}
|
||||
export function createNotConnectedError(
|
||||
port: Port
|
||||
port: PortIdentifier
|
||||
): ApplicationError<number, PortDescriptor> {
|
||||
const { protocol, address } = port;
|
||||
return NotConnectedError(
|
||||
@ -134,7 +143,7 @@ export function createNotConnectedError(
|
||||
);
|
||||
}
|
||||
export function createAlreadyConnectedError(
|
||||
port: Port
|
||||
port: PortIdentifier
|
||||
): ApplicationError<number, PortDescriptor> {
|
||||
const { protocol, address } = port;
|
||||
return AlreadyConnectedError(
|
||||
@ -148,7 +157,7 @@ export function createAlreadyConnectedError(
|
||||
);
|
||||
}
|
||||
export function createMissingConfigurationError(
|
||||
port: Port
|
||||
port: PortIdentifier
|
||||
): ApplicationError<number, PortDescriptor> {
|
||||
const { protocol, address } = port;
|
||||
return MissingConfigurationError(
|
||||
|
@ -1,11 +1,11 @@
|
||||
import type { JsonRpcServer } from '@theia/core/lib/common/messaging/proxy-factory';
|
||||
import type {
|
||||
AttachedBoardsChangeEvent,
|
||||
BoardsPackage,
|
||||
ConfigState,
|
||||
DetectedPorts,
|
||||
IndexType,
|
||||
ProgressMessage,
|
||||
Sketch,
|
||||
IndexType,
|
||||
} from '../protocol';
|
||||
import type { LibraryPackage } from './library-service';
|
||||
|
||||
@ -68,7 +68,9 @@ export interface NotificationServiceClient {
|
||||
notifyLibraryDidUninstall(event: { item: LibraryPackage }): void;
|
||||
|
||||
// Boards discovery
|
||||
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void;
|
||||
notifyDetectedPortsDidChange(event: { detectedPorts: DetectedPorts }): void;
|
||||
|
||||
// Sketches
|
||||
notifyRecentSketchesDidChange(event: { sketches: Sketch[] }): void;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
export type RecursiveRequired<T> = {
|
||||
[P in keyof T]-?: RecursiveRequired<T[P]>;
|
||||
};
|
||||
|
||||
export type Defined<T> = {
|
||||
[P in keyof T]: NonNullable<T[P]>;
|
||||
};
|
||||
|
@ -13,6 +13,7 @@ import { promises as fs, rm, rmSync } from 'node:fs';
|
||||
import type { MaybePromise, Mutable } from '@theia/core/lib/common/types';
|
||||
import { ElectronSecurityToken } from '@theia/core/lib/electron-common/electron-token';
|
||||
import { FrontendApplicationConfig } from '@theia/application-package/lib/application-props';
|
||||
import { environment } from '@theia/application-package/lib/environment';
|
||||
import {
|
||||
ElectronMainApplication as TheiaElectronMainApplication,
|
||||
ElectronMainExecutionParams,
|
||||
@ -702,6 +703,12 @@ class InterruptWorkspaceRestoreError extends Error {
|
||||
async function updateFrontendApplicationConfigFromPackageJson(
|
||||
config: FrontendApplicationConfig
|
||||
): Promise<FrontendApplicationConfig> {
|
||||
if (environment.electron.isDevMode()) {
|
||||
console.debug(
|
||||
'Skipping frontend application configuration customizations. Running in dev mode.'
|
||||
);
|
||||
return config;
|
||||
}
|
||||
try {
|
||||
const modulePath = __filename;
|
||||
// must go from `./lib/backend/electron-main.js` to `./package.json` when the app is webpacked.
|
||||
|
@ -66,7 +66,7 @@ export class ArduinoFirmwareUploaderImpl implements ArduinoFirmwareUploader {
|
||||
]);
|
||||
return output;
|
||||
} finally {
|
||||
await this.monitorManager.notifyUploadFinished(board.fqbn, port);
|
||||
await this.monitorManager.notifyUploadFinished(board.fqbn, port, port); // here the before and after ports are assumed to be always the same
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,22 @@
|
||||
import { ClientDuplexStream } from '@grpc/grpc-js';
|
||||
import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import type { ClientDuplexStream } from '@grpc/grpc-js';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { Emitter, Event } from '@theia/core/lib/common/event';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { BackendApplicationContribution } from '@theia/core/lib/node';
|
||||
import type { Mutable } from '@theia/core/lib/common/types';
|
||||
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
|
||||
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
||||
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||
import { isDeepStrictEqual } from 'util';
|
||||
import { v4 } from 'uuid';
|
||||
import { Unknown } from '../common/nls';
|
||||
import {
|
||||
AttachedBoardsChangeEvent,
|
||||
AvailablePorts,
|
||||
Board,
|
||||
DetectedPort,
|
||||
DetectedPorts,
|
||||
NotificationServiceServer,
|
||||
Port,
|
||||
} from '../common/protocol';
|
||||
@ -22,7 +26,7 @@ import {
|
||||
DetectedPort as RpcDetectedPort,
|
||||
} from './cli-protocol/cc/arduino/cli/commands/v1/board_pb';
|
||||
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
|
||||
import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import type { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import { CoreClientAware } from './core-client-provider';
|
||||
import { ServiceError } from './service-error';
|
||||
|
||||
@ -57,23 +61,9 @@ export class BoardDiscovery
|
||||
private readonly onStreamDidCancelEmitter = new Emitter<void>(); // when the watcher is canceled by the IDE2
|
||||
private readonly toDisposeOnStopWatch = new DisposableCollection();
|
||||
|
||||
private uploadInProgress = false;
|
||||
|
||||
/**
|
||||
* Keys are the `address` of the ports.
|
||||
*
|
||||
* The `protocol` is ignored because the board detach event does not carry the protocol information,
|
||||
* just the address.
|
||||
* ```json
|
||||
* {
|
||||
* "type": "remove",
|
||||
* "address": "/dev/cu.usbmodem14101"
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
private _availablePorts: AvailablePorts = {};
|
||||
get availablePorts(): AvailablePorts {
|
||||
return this._availablePorts;
|
||||
private _detectedPorts: DetectedPorts = {};
|
||||
get detectedPorts(): DetectedPorts {
|
||||
return this._detectedPorts;
|
||||
}
|
||||
|
||||
onStart(): void {
|
||||
@ -120,10 +110,6 @@ export class BoardDiscovery
|
||||
});
|
||||
}
|
||||
|
||||
setUploadInProgress(uploadInProgress: boolean): void {
|
||||
this.uploadInProgress = uploadInProgress;
|
||||
}
|
||||
|
||||
private createTimeout(
|
||||
after: number,
|
||||
onTimeout: (error: Error) => void
|
||||
@ -202,18 +188,6 @@ export class BoardDiscovery
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private toJson(arg: BoardListWatchRequest | BoardListWatchResponse): string {
|
||||
let object: Record<string, unknown> | undefined = undefined;
|
||||
if (arg instanceof BoardListWatchRequest) {
|
||||
object = BoardListWatchRequest.toObject(false, arg);
|
||||
} else if (arg instanceof BoardListWatchResponse) {
|
||||
object = BoardListWatchResponse.toObject(false, arg);
|
||||
} else {
|
||||
throw new Error(`Unhandled object type: ${arg}`);
|
||||
}
|
||||
return JSON.stringify(object);
|
||||
}
|
||||
|
||||
async start(): Promise<void> {
|
||||
this.logger.info('start');
|
||||
if (this.stopping) {
|
||||
@ -240,9 +214,8 @@ export class BoardDiscovery
|
||||
this.logger.info('start resolved watching');
|
||||
}
|
||||
|
||||
// XXX: make this `protected` and override for tests if IDE2 wants to mock events from the CLI.
|
||||
private onBoardListWatchResponse(resp: BoardListWatchResponse): void {
|
||||
this.logger.info(this.toJson(resp));
|
||||
protected onBoardListWatchResponse(resp: BoardListWatchResponse): void {
|
||||
this.logger.info(JSON.stringify(resp.toObject(false)));
|
||||
const eventType = EventType.parse(resp.getEventType());
|
||||
|
||||
if (eventType === EventType.Quit) {
|
||||
@ -251,69 +224,36 @@ export class BoardDiscovery
|
||||
return;
|
||||
}
|
||||
|
||||
const detectedPort = resp.getPort();
|
||||
if (detectedPort) {
|
||||
const { port, boards } = this.fromRpc(detectedPort);
|
||||
if (!port) {
|
||||
if (!!boards.length) {
|
||||
console.warn(
|
||||
`Could not detect the port, but unexpectedly received discovered boards. This is most likely a bug! Response was: ${this.toJson(
|
||||
resp
|
||||
)}`
|
||||
);
|
||||
}
|
||||
return;
|
||||
const rpcDetectedPort = resp.getPort();
|
||||
if (rpcDetectedPort) {
|
||||
const detectedPort = this.fromRpc(rpcDetectedPort);
|
||||
if (detectedPort) {
|
||||
this.fireSoon({ detectedPort, eventType });
|
||||
} else {
|
||||
this.logger.warn(
|
||||
`Could not extract the detected port from ${rpcDetectedPort.toObject(
|
||||
false
|
||||
)}`
|
||||
);
|
||||
}
|
||||
const oldState = deepClone(this._availablePorts);
|
||||
const newState = deepClone(this._availablePorts);
|
||||
const key = Port.keyOf(port);
|
||||
|
||||
if (eventType === EventType.Add) {
|
||||
if (newState[key]) {
|
||||
const [, knownBoards] = newState[key];
|
||||
this.logger.warn(
|
||||
`Port '${Port.toString(
|
||||
port
|
||||
)}' was already available. Known boards before override: ${JSON.stringify(
|
||||
knownBoards
|
||||
)}`
|
||||
);
|
||||
}
|
||||
newState[key] = [port, boards];
|
||||
} else if (eventType === EventType.Remove) {
|
||||
if (!newState[key]) {
|
||||
this.logger.warn(
|
||||
`Port '${Port.toString(port)}' was not available. Skipping`
|
||||
);
|
||||
return;
|
||||
}
|
||||
delete newState[key];
|
||||
}
|
||||
|
||||
const event: AttachedBoardsChangeEvent = {
|
||||
oldState: {
|
||||
...AvailablePorts.split(oldState),
|
||||
},
|
||||
newState: {
|
||||
...AvailablePorts.split(newState),
|
||||
},
|
||||
uploadInProgress: this.uploadInProgress,
|
||||
};
|
||||
|
||||
this._availablePorts = newState;
|
||||
this.notificationService.notifyAttachedBoardsDidChange(event);
|
||||
} else if (resp.getError()) {
|
||||
this.logger.error(
|
||||
`Could not extract any detected 'port' from the board list watch response. An 'error' has occurred: ${resp.getError()}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private fromRpc(detectedPort: RpcDetectedPort): DetectedPort {
|
||||
private fromRpc(detectedPort: RpcDetectedPort): DetectedPort | undefined {
|
||||
const rpcPort = detectedPort.getPort();
|
||||
const port = rpcPort && this.fromRpcPort(rpcPort);
|
||||
if (!rpcPort) {
|
||||
return undefined;
|
||||
}
|
||||
const port = createApiPort(rpcPort);
|
||||
const boards = detectedPort.getMatchingBoardsList().map(
|
||||
(board) =>
|
||||
({
|
||||
fqbn: board.getFqbn(),
|
||||
fqbn: board.getFqbn() || undefined, // prefer undefined fqbn over empty string
|
||||
name: board.getName() || Unknown,
|
||||
port,
|
||||
} as Board)
|
||||
);
|
||||
return {
|
||||
@ -322,15 +262,55 @@ export class BoardDiscovery
|
||||
};
|
||||
}
|
||||
|
||||
private fromRpcPort(rpcPort: RpcPort): Port {
|
||||
return {
|
||||
address: rpcPort.getAddress(),
|
||||
addressLabel: rpcPort.getLabel(),
|
||||
protocol: rpcPort.getProtocol(),
|
||||
protocolLabel: rpcPort.getProtocolLabel(),
|
||||
properties: Port.Properties.create(rpcPort.getPropertiesMap().toObject()),
|
||||
hardwareId: rpcPort.getHardwareId(),
|
||||
};
|
||||
private fireSoonHandle: NodeJS.Timeout | undefined;
|
||||
private readonly bufferedEvents: DetectedPortChangeEvent[] = [];
|
||||
private fireSoon(event: DetectedPortChangeEvent): void {
|
||||
this.bufferedEvents.push(event);
|
||||
clearTimeout(this.fireSoonHandle);
|
||||
this.fireSoonHandle = setTimeout(() => {
|
||||
const current = deepClone(this.detectedPorts);
|
||||
const newState = this.calculateNewState(this.bufferedEvents, current);
|
||||
if (!isDeepStrictEqual(current, newState)) {
|
||||
this._detectedPorts = newState;
|
||||
this.notificationService.notifyDetectedPortsDidChange({
|
||||
detectedPorts: this._detectedPorts,
|
||||
});
|
||||
}
|
||||
this.bufferedEvents.length = 0;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
private calculateNewState(
|
||||
events: DetectedPortChangeEvent[],
|
||||
prevState: Mutable<DetectedPorts>
|
||||
): DetectedPorts {
|
||||
const newState = deepClone(prevState);
|
||||
for (const { detectedPort, eventType } of events) {
|
||||
const { port, boards } = detectedPort;
|
||||
const key = Port.keyOf(port);
|
||||
if (eventType === EventType.Add) {
|
||||
const alreadyDetectedPort = newState[key];
|
||||
if (alreadyDetectedPort) {
|
||||
console.warn(
|
||||
`Detected a new port that has been already discovered. The old value will be overridden. Old value: ${JSON.stringify(
|
||||
alreadyDetectedPort
|
||||
)}, new value: ${JSON.stringify(detectedPort)}`
|
||||
);
|
||||
}
|
||||
newState[key] = { port, boards };
|
||||
} else if (eventType === EventType.Remove) {
|
||||
const alreadyDetectedPort = newState[key];
|
||||
if (!alreadyDetectedPort) {
|
||||
console.warn(
|
||||
`Detected a port removal but it has not been discovered. This is most likely a bug! Detected port was: ${JSON.stringify(
|
||||
detectedPort
|
||||
)}`
|
||||
);
|
||||
}
|
||||
delete newState[key];
|
||||
}
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
}
|
||||
|
||||
@ -357,7 +337,18 @@ namespace EventType {
|
||||
}
|
||||
}
|
||||
|
||||
interface DetectedPort {
|
||||
port: Port | undefined;
|
||||
boards: Board[];
|
||||
interface DetectedPortChangeEvent {
|
||||
readonly detectedPort: DetectedPort;
|
||||
readonly eventType: EventType.Add | EventType.Remove;
|
||||
}
|
||||
|
||||
export function createApiPort(rpcPort: RpcPort): Port {
|
||||
return {
|
||||
address: rpcPort.getAddress(),
|
||||
addressLabel: rpcPort.getLabel(),
|
||||
protocol: rpcPort.getProtocol(),
|
||||
protocolLabel: rpcPort.getProtocolLabel(),
|
||||
properties: Port.Properties.create(rpcPort.getPropertiesMap().toObject()),
|
||||
hardwareId: rpcPort.getHardwareId() || undefined, // prefer undefined over empty string
|
||||
};
|
||||
}
|
||||
|
@ -12,13 +12,15 @@ import {
|
||||
Programmer,
|
||||
ResponseService,
|
||||
NotificationServiceServer,
|
||||
AvailablePorts,
|
||||
DetectedPorts,
|
||||
BoardWithPackage,
|
||||
BoardUserField,
|
||||
BoardSearch,
|
||||
sortComponents,
|
||||
SortGroup,
|
||||
platformInstallFailed,
|
||||
createPlatformIdentifier,
|
||||
platformIdentifierEquals,
|
||||
} from '../common/protocol';
|
||||
import {
|
||||
PlatformInstallRequest,
|
||||
@ -65,8 +67,8 @@ export class BoardsServiceImpl
|
||||
@inject(BoardDiscovery)
|
||||
protected readonly boardDiscovery: BoardDiscovery;
|
||||
|
||||
async getState(): Promise<AvailablePorts> {
|
||||
return this.boardDiscovery.availablePorts;
|
||||
async getDetectedPorts(): Promise<DetectedPorts> {
|
||||
return this.boardDiscovery.detectedPorts;
|
||||
}
|
||||
|
||||
async getBoardDetails(options: {
|
||||
@ -165,7 +167,7 @@ export class BoardsServiceImpl
|
||||
debuggingSupported,
|
||||
VID,
|
||||
PID,
|
||||
buildProperties
|
||||
buildProperties,
|
||||
};
|
||||
}
|
||||
|
||||
@ -212,6 +214,28 @@ export class BoardsServiceImpl
|
||||
return this.handleListBoards(client.boardListAll.bind(client), req);
|
||||
}
|
||||
|
||||
async getInstalledPlatforms(): Promise<BoardsPackage[]> {
|
||||
const { instance, client } = await this.coreClient;
|
||||
return new Promise<BoardsPackage[]>((resolve, reject) => {
|
||||
client.platformList(
|
||||
new PlatformListRequest().setInstance(instance),
|
||||
(err, response) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
resolve(
|
||||
response
|
||||
.getInstalledPlatformsList()
|
||||
.map((platform, _, installedPlatforms) =>
|
||||
toBoardsPackage(platform, installedPlatforms)
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
private async handleListBoards(
|
||||
getBoards: (
|
||||
request: BoardListAllRequest | BoardSearchRequest,
|
||||
@ -232,10 +256,38 @@ export class BoardsServiceImpl
|
||||
for (const board of resp.getBoardsList()) {
|
||||
const platform = board.getPlatform();
|
||||
if (platform) {
|
||||
const platformId = platform.getId();
|
||||
const fqbn = board.getFqbn() || undefined; // prefer undefined over empty string
|
||||
const parsedPlatformId = createPlatformIdentifier(platformId);
|
||||
if (!parsedPlatformId) {
|
||||
console.warn(
|
||||
`Could not create platform identifier from platform ID input: ${platform.getId()}. Skipping`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (fqbn) {
|
||||
const checkPlatformId = createPlatformIdentifier(board.getFqbn());
|
||||
if (!checkPlatformId) {
|
||||
console.warn(
|
||||
`Could not create platform identifier from FQBN input: ${board.getFqbn()}. Skipping`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if (
|
||||
!platformIdentifierEquals(parsedPlatformId, checkPlatformId)
|
||||
) {
|
||||
console.warn(
|
||||
`Mismatching platform identifiers. Platform: ${JSON.stringify(
|
||||
parsedPlatformId
|
||||
)}, FQBN: ${JSON.stringify(checkPlatformId)}. Skipping`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
boards.push({
|
||||
name: board.getName(),
|
||||
fqbn: board.getFqbn(),
|
||||
packageId: platform.getId(),
|
||||
packageId: parsedPlatformId,
|
||||
packageName: platform.getName(),
|
||||
manuallyInstalled: platform.getManuallyInstalled(),
|
||||
});
|
||||
@ -316,38 +368,6 @@ export class BoardsServiceImpl
|
||||
}
|
||||
);
|
||||
const packages = new Map<string, BoardsPackage>();
|
||||
const toPackage = (platform: Platform) => {
|
||||
let installedVersion: string | undefined;
|
||||
const matchingPlatform = installedPlatforms.find(
|
||||
(ip) => ip.getId() === platform.getId()
|
||||
);
|
||||
if (!!matchingPlatform) {
|
||||
installedVersion = matchingPlatform.getInstalled();
|
||||
}
|
||||
return {
|
||||
id: platform.getId(),
|
||||
name: platform.getName(),
|
||||
author: platform.getMaintainer(),
|
||||
availableVersions: [platform.getLatest()],
|
||||
description: platform
|
||||
.getBoardsList()
|
||||
.map((b) => b.getName())
|
||||
.join(', '),
|
||||
installable: true,
|
||||
types: platform.getTypeList(),
|
||||
deprecated: platform.getDeprecated(),
|
||||
summary: nls.localize(
|
||||
'arduino/component/boardsIncluded',
|
||||
'Boards included in this package:'
|
||||
),
|
||||
installedVersion,
|
||||
boards: platform
|
||||
.getBoardsList()
|
||||
.map((b) => <Board>{ name: b.getName(), fqbn: b.getFqbn() }),
|
||||
moreInfoLink: platform.getWebsite(),
|
||||
};
|
||||
};
|
||||
|
||||
// We must group the cores by ID, and sort platforms by, first the installed version, then version alphabetical order.
|
||||
// Otherwise we lose the FQBN information.
|
||||
const groupedById: Map<string, Platform[]> = new Map();
|
||||
@ -400,7 +420,7 @@ export class BoardsServiceImpl
|
||||
pkg.availableVersions.push(platform.getLatest());
|
||||
pkg.availableVersions.sort(Installable.Version.COMPARATOR).reverse();
|
||||
} else {
|
||||
packages.set(id, toPackage(platform));
|
||||
packages.set(id, toBoardsPackage(platform, installedPlatforms));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -572,3 +592,37 @@ function boardsPackageSortGroup(boardsPackage: BoardsPackage): SortGroup {
|
||||
}
|
||||
return types.join('-') as SortGroup;
|
||||
}
|
||||
|
||||
function toBoardsPackage(
|
||||
platform: Platform,
|
||||
installedPlatforms: Platform[]
|
||||
): BoardsPackage {
|
||||
let installedVersion: string | undefined;
|
||||
const matchingPlatform = installedPlatforms.find(
|
||||
(ip) => ip.getId() === platform.getId()
|
||||
);
|
||||
if (!!matchingPlatform) {
|
||||
installedVersion = matchingPlatform.getInstalled();
|
||||
}
|
||||
return {
|
||||
id: platform.getId(),
|
||||
name: platform.getName(),
|
||||
author: platform.getMaintainer(),
|
||||
availableVersions: [platform.getLatest()],
|
||||
description: platform
|
||||
.getBoardsList()
|
||||
.map((b) => b.getName())
|
||||
.join(', '),
|
||||
types: platform.getTypeList(),
|
||||
deprecated: platform.getDeprecated(),
|
||||
summary: nls.localize(
|
||||
'arduino/component/boardsIncluded',
|
||||
'Boards included in this package:'
|
||||
),
|
||||
installedVersion,
|
||||
boards: platform
|
||||
.getBoardsList()
|
||||
.map((b) => <Board>{ name: b.getName(), fqbn: b.getFqbn() }),
|
||||
moreInfoLink: platform.getWebsite(),
|
||||
};
|
||||
}
|
||||
|
@ -14,14 +14,11 @@ export class BoardDetailsRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardDetailsRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): BoardDetailsRequest;
|
||||
|
||||
getDoNotExpandBuildProperties(): boolean;
|
||||
setDoNotExpandBuildProperties(value: boolean): BoardDetailsRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardDetailsRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardDetailsRequest): BoardDetailsRequest.AsObject;
|
||||
@ -43,66 +40,51 @@ export namespace BoardDetailsRequest {
|
||||
export class BoardDetailsResponse extends jspb.Message {
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): BoardDetailsResponse;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): BoardDetailsResponse;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): BoardDetailsResponse;
|
||||
|
||||
getPropertiesId(): string;
|
||||
setPropertiesId(value: string): BoardDetailsResponse;
|
||||
|
||||
getAlias(): string;
|
||||
setAlias(value: string): BoardDetailsResponse;
|
||||
|
||||
getOfficial(): boolean;
|
||||
setOfficial(value: boolean): BoardDetailsResponse;
|
||||
|
||||
getPinout(): string;
|
||||
setPinout(value: string): BoardDetailsResponse;
|
||||
|
||||
|
||||
hasPackage(): boolean;
|
||||
clearPackage(): void;
|
||||
getPackage(): Package | undefined;
|
||||
setPackage(value?: Package): BoardDetailsResponse;
|
||||
|
||||
|
||||
hasPlatform(): boolean;
|
||||
clearPlatform(): void;
|
||||
getPlatform(): BoardPlatform | undefined;
|
||||
setPlatform(value?: BoardPlatform): BoardDetailsResponse;
|
||||
|
||||
clearToolsDependenciesList(): void;
|
||||
getToolsDependenciesList(): Array<ToolsDependencies>;
|
||||
setToolsDependenciesList(value: Array<ToolsDependencies>): BoardDetailsResponse;
|
||||
addToolsDependencies(value?: ToolsDependencies, index?: number): ToolsDependencies;
|
||||
|
||||
clearConfigOptionsList(): void;
|
||||
getConfigOptionsList(): Array<ConfigOption>;
|
||||
setConfigOptionsList(value: Array<ConfigOption>): BoardDetailsResponse;
|
||||
addConfigOptions(value?: ConfigOption, index?: number): ConfigOption;
|
||||
|
||||
clearProgrammersList(): void;
|
||||
getProgrammersList(): Array<cc_arduino_cli_commands_v1_common_pb.Programmer>;
|
||||
setProgrammersList(value: Array<cc_arduino_cli_commands_v1_common_pb.Programmer>): BoardDetailsResponse;
|
||||
addProgrammers(value?: cc_arduino_cli_commands_v1_common_pb.Programmer, index?: number): cc_arduino_cli_commands_v1_common_pb.Programmer;
|
||||
|
||||
getDebuggingSupported(): boolean;
|
||||
setDebuggingSupported(value: boolean): BoardDetailsResponse;
|
||||
|
||||
clearIdentificationPropertiesList(): void;
|
||||
getIdentificationPropertiesList(): Array<BoardIdentificationProperties>;
|
||||
setIdentificationPropertiesList(value: Array<BoardIdentificationProperties>): BoardDetailsResponse;
|
||||
addIdentificationProperties(value?: BoardIdentificationProperties, index?: number): BoardIdentificationProperties;
|
||||
|
||||
clearBuildPropertiesList(): void;
|
||||
getBuildPropertiesList(): Array<string>;
|
||||
setBuildPropertiesList(value: Array<string>): BoardDetailsResponse;
|
||||
addBuildProperties(value: string, index?: number): string;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardDetailsResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardDetailsResponse): BoardDetailsResponse.AsObject;
|
||||
@ -138,7 +120,6 @@ export class BoardIdentificationProperties extends jspb.Message {
|
||||
getPropertiesMap(): jspb.Map<string, string>;
|
||||
clearPropertiesMap(): void;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardIdentificationProperties.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardIdentificationProperties): BoardIdentificationProperties.AsObject;
|
||||
@ -159,26 +140,20 @@ export namespace BoardIdentificationProperties {
|
||||
export class Package extends jspb.Message {
|
||||
getMaintainer(): string;
|
||||
setMaintainer(value: string): Package;
|
||||
|
||||
getUrl(): string;
|
||||
setUrl(value: string): Package;
|
||||
|
||||
getWebsiteUrl(): string;
|
||||
setWebsiteUrl(value: string): Package;
|
||||
|
||||
getEmail(): string;
|
||||
setEmail(value: string): Package;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): Package;
|
||||
|
||||
|
||||
hasHelp(): boolean;
|
||||
clearHelp(): void;
|
||||
getHelp(): Help | undefined;
|
||||
setHelp(value?: Help): Package;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Package.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Package): Package.AsObject;
|
||||
@ -204,7 +179,6 @@ export class Help extends jspb.Message {
|
||||
getOnline(): string;
|
||||
setOnline(value: string): Help;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Help.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Help): Help.AsObject;
|
||||
@ -224,26 +198,19 @@ export namespace Help {
|
||||
export class BoardPlatform extends jspb.Message {
|
||||
getArchitecture(): string;
|
||||
setArchitecture(value: string): BoardPlatform;
|
||||
|
||||
getCategory(): string;
|
||||
setCategory(value: string): BoardPlatform;
|
||||
|
||||
getUrl(): string;
|
||||
setUrl(value: string): BoardPlatform;
|
||||
|
||||
getArchiveFilename(): string;
|
||||
setArchiveFilename(value: string): BoardPlatform;
|
||||
|
||||
getChecksum(): string;
|
||||
setChecksum(value: string): BoardPlatform;
|
||||
|
||||
getSize(): number;
|
||||
setSize(value: number): BoardPlatform;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): BoardPlatform;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardPlatform.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardPlatform): BoardPlatform.AsObject;
|
||||
@ -269,19 +236,15 @@ export namespace BoardPlatform {
|
||||
export class ToolsDependencies extends jspb.Message {
|
||||
getPackager(): string;
|
||||
setPackager(value: string): ToolsDependencies;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): ToolsDependencies;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): ToolsDependencies;
|
||||
|
||||
clearSystemsList(): void;
|
||||
getSystemsList(): Array<Systems>;
|
||||
setSystemsList(value: Array<Systems>): ToolsDependencies;
|
||||
addSystems(value?: Systems, index?: number): Systems;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ToolsDependencies.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ToolsDependencies): ToolsDependencies.AsObject;
|
||||
@ -304,20 +267,15 @@ export namespace ToolsDependencies {
|
||||
export class Systems extends jspb.Message {
|
||||
getChecksum(): string;
|
||||
setChecksum(value: string): Systems;
|
||||
|
||||
getHost(): string;
|
||||
setHost(value: string): Systems;
|
||||
|
||||
getArchiveFilename(): string;
|
||||
setArchiveFilename(value: string): Systems;
|
||||
|
||||
getUrl(): string;
|
||||
setUrl(value: string): Systems;
|
||||
|
||||
getSize(): number;
|
||||
setSize(value: number): Systems;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Systems.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Systems): Systems.AsObject;
|
||||
@ -341,16 +299,13 @@ export namespace Systems {
|
||||
export class ConfigOption extends jspb.Message {
|
||||
getOption(): string;
|
||||
setOption(value: string): ConfigOption;
|
||||
|
||||
getOptionLabel(): string;
|
||||
setOptionLabel(value: string): ConfigOption;
|
||||
|
||||
clearValuesList(): void;
|
||||
getValuesList(): Array<ConfigValue>;
|
||||
setValuesList(value: Array<ConfigValue>): ConfigOption;
|
||||
addValues(value?: ConfigValue, index?: number): ConfigValue;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ConfigOption.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ConfigOption): ConfigOption.AsObject;
|
||||
@ -372,14 +327,11 @@ export namespace ConfigOption {
|
||||
export class ConfigValue extends jspb.Message {
|
||||
getValue(): string;
|
||||
setValue(value: string): ConfigValue;
|
||||
|
||||
getValueLabel(): string;
|
||||
setValueLabel(value: string): ConfigValue;
|
||||
|
||||
getSelected(): boolean;
|
||||
setSelected(value: boolean): ConfigValue;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ConfigValue.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ConfigValue): ConfigValue.AsObject;
|
||||
@ -404,14 +356,11 @@ export class BoardListRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardListRequest;
|
||||
|
||||
getTimeout(): number;
|
||||
setTimeout(value: number): BoardListRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): BoardListRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListRequest): BoardListRequest.AsObject;
|
||||
@ -436,7 +385,6 @@ export class BoardListResponse extends jspb.Message {
|
||||
setPortsList(value: Array<DetectedPort>): BoardListResponse;
|
||||
addPorts(value?: DetectedPort, index?: number): DetectedPort;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListResponse): BoardListResponse.AsObject;
|
||||
@ -459,13 +407,11 @@ export class DetectedPort extends jspb.Message {
|
||||
setMatchingBoardsList(value: Array<BoardListItem>): DetectedPort;
|
||||
addMatchingBoards(value?: BoardListItem, index?: number): BoardListItem;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): DetectedPort;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DetectedPort.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DetectedPort): DetectedPort.AsObject;
|
||||
@ -489,16 +435,13 @@ export class BoardListAllRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardListAllRequest;
|
||||
|
||||
clearSearchArgsList(): void;
|
||||
getSearchArgsList(): Array<string>;
|
||||
setSearchArgsList(value: Array<string>): BoardListAllRequest;
|
||||
addSearchArgs(value: string, index?: number): string;
|
||||
|
||||
getIncludeHiddenBoards(): boolean;
|
||||
setIncludeHiddenBoards(value: boolean): BoardListAllRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListAllRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListAllRequest): BoardListAllRequest.AsObject;
|
||||
@ -523,7 +466,6 @@ export class BoardListAllResponse extends jspb.Message {
|
||||
setBoardsList(value: Array<BoardListItem>): BoardListAllResponse;
|
||||
addBoards(value?: BoardListItem, index?: number): BoardListItem;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListAllResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListAllResponse): BoardListAllResponse.AsObject;
|
||||
@ -546,11 +488,9 @@ export class BoardListWatchRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardListWatchRequest;
|
||||
|
||||
getInterrupt(): boolean;
|
||||
setInterrupt(value: boolean): BoardListWatchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListWatchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListWatchRequest): BoardListWatchRequest.AsObject;
|
||||
@ -572,16 +512,13 @@ export class BoardListWatchResponse extends jspb.Message {
|
||||
getEventType(): string;
|
||||
setEventType(value: string): BoardListWatchResponse;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): DetectedPort | undefined;
|
||||
setPort(value?: DetectedPort): BoardListWatchResponse;
|
||||
|
||||
getError(): string;
|
||||
setError(value: string): BoardListWatchResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListWatchResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListWatchResponse): BoardListWatchResponse.AsObject;
|
||||
@ -603,20 +540,16 @@ export namespace BoardListWatchResponse {
|
||||
export class BoardListItem extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): BoardListItem;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): BoardListItem;
|
||||
|
||||
getIsHidden(): boolean;
|
||||
setIsHidden(value: boolean): BoardListItem;
|
||||
|
||||
|
||||
hasPlatform(): boolean;
|
||||
clearPlatform(): void;
|
||||
getPlatform(): cc_arduino_cli_commands_v1_common_pb.Platform | undefined;
|
||||
setPlatform(value?: cc_arduino_cli_commands_v1_common_pb.Platform): BoardListItem;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardListItem.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardListItem): BoardListItem.AsObject;
|
||||
@ -642,14 +575,11 @@ export class BoardSearchRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardSearchRequest;
|
||||
|
||||
getSearchArgs(): string;
|
||||
setSearchArgs(value: string): BoardSearchRequest;
|
||||
|
||||
getIncludeHiddenBoards(): boolean;
|
||||
setIncludeHiddenBoards(value: boolean): BoardSearchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardSearchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardSearchRequest): BoardSearchRequest.AsObject;
|
||||
@ -674,7 +604,6 @@ export class BoardSearchResponse extends jspb.Message {
|
||||
setBoardsList(value: Array<BoardListItem>): BoardSearchResponse;
|
||||
addBoards(value?: BoardListItem, index?: number): BoardListItem;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BoardSearchResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BoardSearchResponse): BoardSearchResponse.AsObject;
|
||||
|
@ -5,7 +5,6 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import * as grpc from "@grpc/grpc-js";
|
||||
import {handleClientStreamingCall} from "@grpc/grpc-js/build/src/server-call";
|
||||
import * as cc_arduino_cli_commands_v1_commands_pb from "../../../../../cc/arduino/cli/commands/v1/commands_pb";
|
||||
import * as google_rpc_status_pb from "../../../../../google/rpc/status_pb";
|
||||
import * as cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino/cli/commands/v1/common_pb";
|
||||
@ -26,6 +25,7 @@ interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.Untyped
|
||||
newSketch: IArduinoCoreServiceService_INewSketch;
|
||||
loadSketch: IArduinoCoreServiceService_ILoadSketch;
|
||||
archiveSketch: IArduinoCoreServiceService_IArchiveSketch;
|
||||
setSketchDefaults: IArduinoCoreServiceService_ISetSketchDefaults;
|
||||
boardDetails: IArduinoCoreServiceService_IBoardDetails;
|
||||
boardList: IArduinoCoreServiceService_IBoardList;
|
||||
boardListAll: IArduinoCoreServiceService_IBoardListAll;
|
||||
@ -138,6 +138,15 @@ interface IArduinoCoreServiceService_IArchiveSketch extends grpc.MethodDefinitio
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_ISetSketchDefaults extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/SetSketchDefaults";
|
||||
requestStream: false;
|
||||
responseStream: false;
|
||||
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest>;
|
||||
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest>;
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse>;
|
||||
}
|
||||
interface IArduinoCoreServiceService_IBoardDetails extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse> {
|
||||
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardDetails";
|
||||
requestStream: false;
|
||||
@ -402,7 +411,7 @@ interface IArduinoCoreServiceService_IEnumerateMonitorPortSettings extends grpc.
|
||||
|
||||
export const ArduinoCoreServiceService: IArduinoCoreServiceService;
|
||||
|
||||
export interface IArduinoCoreServiceServer {
|
||||
export interface IArduinoCoreServiceServer extends grpc.UntypedServiceImplementation {
|
||||
create: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.CreateRequest, cc_arduino_cli_commands_v1_commands_pb.CreateResponse>;
|
||||
init: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_commands_pb.InitRequest, cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
|
||||
destroy: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, cc_arduino_cli_commands_v1_commands_pb.DestroyResponse>;
|
||||
@ -412,6 +421,7 @@ export interface IArduinoCoreServiceServer {
|
||||
newSketch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.NewSketchRequest, cc_arduino_cli_commands_v1_commands_pb.NewSketchResponse>;
|
||||
loadSketch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse>;
|
||||
archiveSketch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse>;
|
||||
setSketchDefaults: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse>;
|
||||
boardDetails: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse>;
|
||||
boardList: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_board_pb.BoardListRequest, cc_arduino_cli_commands_v1_board_pb.BoardListResponse>;
|
||||
boardListAll: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse>;
|
||||
@ -468,6 +478,9 @@ export interface IArduinoCoreServiceClient {
|
||||
archiveSketch(request: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
archiveSketch(request: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
archiveSketch(request: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
setSketchDefaults(request: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse) => void): grpc.ClientUnaryCall;
|
||||
setSketchDefaults(request: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse) => void): grpc.ClientUnaryCall;
|
||||
setSketchDefaults(request: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse) => void): grpc.ClientUnaryCall;
|
||||
boardDetails(request: cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse) => void): grpc.ClientUnaryCall;
|
||||
boardDetails(request: cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse) => void): grpc.ClientUnaryCall;
|
||||
boardDetails(request: cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse) => void): grpc.ClientUnaryCall;
|
||||
@ -568,6 +581,9 @@ export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCor
|
||||
public archiveSketch(request: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public archiveSketch(request: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public archiveSketch(request: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse) => void): grpc.ClientUnaryCall;
|
||||
public setSketchDefaults(request: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse) => void): grpc.ClientUnaryCall;
|
||||
public setSketchDefaults(request: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse) => void): grpc.ClientUnaryCall;
|
||||
public setSketchDefaults(request: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse) => void): grpc.ClientUnaryCall;
|
||||
public boardDetails(request: cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse) => void): grpc.ClientUnaryCall;
|
||||
public boardDetails(request: cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse) => void): grpc.ClientUnaryCall;
|
||||
public boardDetails(request: cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse) => void): grpc.ClientUnaryCall;
|
||||
|
@ -709,6 +709,28 @@ function deserialize_cc_arduino_cli_commands_v1_PlatformUpgradeResponse(buffer_a
|
||||
return cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_SetSketchDefaultsRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SetSketchDefaultsRequest');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_SetSketchDefaultsRequest(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_SetSketchDefaultsResponse(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SetSketchDefaultsResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_commands_v1_SetSketchDefaultsResponse(buffer_arg) {
|
||||
return cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_commands_v1_SupportedUserFieldsRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_commands_v1_upload_pb.SupportedUserFieldsRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.commands.v1.SupportedUserFieldsRequest');
|
||||
@ -975,6 +997,20 @@ archiveSketch: {
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_ArchiveSketchResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_ArchiveSketchResponse,
|
||||
},
|
||||
// Sets the sketch default FQBN and Port Address/Protocol in
|
||||
// the sketch project file (sketch.yaml). These metadata can be retrieved
|
||||
// using LoadSketch.
|
||||
setSketchDefaults: {
|
||||
path: '/cc.arduino.cli.commands.v1.ArduinoCoreService/SetSketchDefaults',
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsRequest,
|
||||
responseType: cc_arduino_cli_commands_v1_commands_pb.SetSketchDefaultsResponse,
|
||||
requestSerialize: serialize_cc_arduino_cli_commands_v1_SetSketchDefaultsRequest,
|
||||
requestDeserialize: deserialize_cc_arduino_cli_commands_v1_SetSketchDefaultsRequest,
|
||||
responseSerialize: serialize_cc_arduino_cli_commands_v1_SetSketchDefaultsResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_commands_v1_SetSketchDefaultsResponse,
|
||||
},
|
||||
// BOARD COMMANDS
|
||||
// --------------
|
||||
//
|
||||
|
@ -38,7 +38,6 @@ export class CreateResponse extends jspb.Message {
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): CreateResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): CreateResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: CreateResponse): CreateResponse.AsObject;
|
||||
@ -61,14 +60,11 @@ export class InitRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): InitRequest;
|
||||
|
||||
getProfile(): string;
|
||||
setProfile(value: string): InitRequest;
|
||||
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): InitRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): InitRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: InitRequest): InitRequest.AsObject;
|
||||
@ -94,19 +90,16 @@ export class InitResponse extends jspb.Message {
|
||||
getInitProgress(): InitResponse.Progress | undefined;
|
||||
setInitProgress(value?: InitResponse.Progress): InitResponse;
|
||||
|
||||
|
||||
hasError(): boolean;
|
||||
clearError(): void;
|
||||
getError(): google_rpc_status_pb.Status | undefined;
|
||||
setError(value?: google_rpc_status_pb.Status): InitResponse;
|
||||
|
||||
|
||||
hasProfile(): boolean;
|
||||
clearProfile(): void;
|
||||
getProfile(): cc_arduino_cli_commands_v1_common_pb.Profile | undefined;
|
||||
setProfile(value?: cc_arduino_cli_commands_v1_common_pb.Profile): InitResponse;
|
||||
|
||||
|
||||
getMessageCase(): InitResponse.MessageCase;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
@ -134,13 +127,11 @@ export namespace InitResponse {
|
||||
getDownloadProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setDownloadProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): Progress;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): Progress;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Progress.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Progress): Progress.AsObject;
|
||||
@ -161,13 +152,9 @@ export namespace InitResponse {
|
||||
|
||||
export enum MessageCase {
|
||||
MESSAGE_NOT_SET = 0,
|
||||
|
||||
INIT_PROGRESS = 1,
|
||||
|
||||
ERROR = 2,
|
||||
|
||||
PROFILE = 3,
|
||||
|
||||
INIT_PROGRESS = 1,
|
||||
ERROR = 2,
|
||||
PROFILE = 3,
|
||||
}
|
||||
|
||||
}
|
||||
@ -175,11 +162,9 @@ export namespace InitResponse {
|
||||
export class FailedInstanceInitError extends jspb.Message {
|
||||
getReason(): FailedInstanceInitReason;
|
||||
setReason(value: FailedInstanceInitReason): FailedInstanceInitError;
|
||||
|
||||
getMessage(): string;
|
||||
setMessage(value: string): FailedInstanceInitError;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): FailedInstanceInitError.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: FailedInstanceInitError): FailedInstanceInitError.AsObject;
|
||||
@ -204,7 +189,6 @@ export class DestroyRequest extends jspb.Message {
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): DestroyRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DestroyRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DestroyRequest): DestroyRequest.AsObject;
|
||||
@ -244,11 +228,9 @@ export class UpdateIndexRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): UpdateIndexRequest;
|
||||
|
||||
getIgnoreCustomPackageIndexes(): boolean;
|
||||
setIgnoreCustomPackageIndexes(value: boolean): UpdateIndexRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UpdateIndexRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UpdateIndexRequest): UpdateIndexRequest.AsObject;
|
||||
@ -273,7 +255,6 @@ export class UpdateIndexResponse extends jspb.Message {
|
||||
getDownloadProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setDownloadProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): UpdateIndexResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UpdateIndexResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UpdateIndexResponse): UpdateIndexResponse.AsObject;
|
||||
@ -297,7 +278,6 @@ export class UpdateLibrariesIndexRequest extends jspb.Message {
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): UpdateLibrariesIndexRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UpdateLibrariesIndexRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UpdateLibrariesIndexRequest): UpdateLibrariesIndexRequest.AsObject;
|
||||
@ -321,7 +301,6 @@ export class UpdateLibrariesIndexResponse extends jspb.Message {
|
||||
getDownloadProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setDownloadProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): UpdateLibrariesIndexResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UpdateLibrariesIndexResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UpdateLibrariesIndexResponse): UpdateLibrariesIndexResponse.AsObject;
|
||||
@ -359,7 +338,6 @@ export class VersionResponse extends jspb.Message {
|
||||
getVersion(): string;
|
||||
setVersion(value: string): VersionResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): VersionResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: VersionResponse): VersionResponse.AsObject;
|
||||
@ -377,22 +355,13 @@ export namespace VersionResponse {
|
||||
}
|
||||
|
||||
export class NewSketchRequest extends jspb.Message {
|
||||
|
||||
hasInstance(): boolean;
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): NewSketchRequest;
|
||||
|
||||
getSketchName(): string;
|
||||
setSketchName(value: string): NewSketchRequest;
|
||||
|
||||
getSketchDir(): string;
|
||||
setSketchDir(value: string): NewSketchRequest;
|
||||
|
||||
getOverwrite(): boolean;
|
||||
setOverwrite(value: boolean): NewSketchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): NewSketchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: NewSketchRequest): NewSketchRequest.AsObject;
|
||||
@ -405,7 +374,6 @@ export class NewSketchRequest extends jspb.Message {
|
||||
|
||||
export namespace NewSketchRequest {
|
||||
export type AsObject = {
|
||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||
sketchName: string,
|
||||
sketchDir: string,
|
||||
overwrite: boolean,
|
||||
@ -416,7 +384,6 @@ export class NewSketchResponse extends jspb.Message {
|
||||
getMainFile(): string;
|
||||
setMainFile(value: string): NewSketchResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): NewSketchResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: NewSketchResponse): NewSketchResponse.AsObject;
|
||||
@ -434,16 +401,9 @@ export namespace NewSketchResponse {
|
||||
}
|
||||
|
||||
export class LoadSketchRequest extends jspb.Message {
|
||||
|
||||
hasInstance(): boolean;
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LoadSketchRequest;
|
||||
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): LoadSketchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LoadSketchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LoadSketchRequest): LoadSketchRequest.AsObject;
|
||||
@ -456,7 +416,6 @@ export class LoadSketchRequest extends jspb.Message {
|
||||
|
||||
export namespace LoadSketchRequest {
|
||||
export type AsObject = {
|
||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||
sketchPath: string,
|
||||
}
|
||||
}
|
||||
@ -464,25 +423,26 @@ export namespace LoadSketchRequest {
|
||||
export class LoadSketchResponse extends jspb.Message {
|
||||
getMainFile(): string;
|
||||
setMainFile(value: string): LoadSketchResponse;
|
||||
|
||||
getLocationPath(): string;
|
||||
setLocationPath(value: string): LoadSketchResponse;
|
||||
|
||||
clearOtherSketchFilesList(): void;
|
||||
getOtherSketchFilesList(): Array<string>;
|
||||
setOtherSketchFilesList(value: Array<string>): LoadSketchResponse;
|
||||
addOtherSketchFiles(value: string, index?: number): string;
|
||||
|
||||
clearAdditionalFilesList(): void;
|
||||
getAdditionalFilesList(): Array<string>;
|
||||
setAdditionalFilesList(value: Array<string>): LoadSketchResponse;
|
||||
addAdditionalFiles(value: string, index?: number): string;
|
||||
|
||||
clearRootFolderFilesList(): void;
|
||||
getRootFolderFilesList(): Array<string>;
|
||||
setRootFolderFilesList(value: Array<string>): LoadSketchResponse;
|
||||
addRootFolderFiles(value: string, index?: number): string;
|
||||
|
||||
getDefaultFqbn(): string;
|
||||
setDefaultFqbn(value: string): LoadSketchResponse;
|
||||
getDefaultPort(): string;
|
||||
setDefaultPort(value: string): LoadSketchResponse;
|
||||
getDefaultProtocol(): string;
|
||||
setDefaultProtocol(value: string): LoadSketchResponse;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LoadSketchResponse.AsObject;
|
||||
@ -501,23 +461,22 @@ export namespace LoadSketchResponse {
|
||||
otherSketchFilesList: Array<string>,
|
||||
additionalFilesList: Array<string>,
|
||||
rootFolderFilesList: Array<string>,
|
||||
defaultFqbn: string,
|
||||
defaultPort: string,
|
||||
defaultProtocol: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class ArchiveSketchRequest extends jspb.Message {
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): ArchiveSketchRequest;
|
||||
|
||||
getArchivePath(): string;
|
||||
setArchivePath(value: string): ArchiveSketchRequest;
|
||||
|
||||
getIncludeBuildDir(): boolean;
|
||||
setIncludeBuildDir(value: boolean): ArchiveSketchRequest;
|
||||
|
||||
getOverwrite(): boolean;
|
||||
setOverwrite(value: boolean): ArchiveSketchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ArchiveSketchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ArchiveSketchRequest): ArchiveSketchRequest.AsObject;
|
||||
@ -554,9 +513,65 @@ export namespace ArchiveSketchResponse {
|
||||
}
|
||||
}
|
||||
|
||||
export class SetSketchDefaultsRequest extends jspb.Message {
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): SetSketchDefaultsRequest;
|
||||
getDefaultFqbn(): string;
|
||||
setDefaultFqbn(value: string): SetSketchDefaultsRequest;
|
||||
getDefaultPortAddress(): string;
|
||||
setDefaultPortAddress(value: string): SetSketchDefaultsRequest;
|
||||
getDefaultPortProtocol(): string;
|
||||
setDefaultPortProtocol(value: string): SetSketchDefaultsRequest;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SetSketchDefaultsRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SetSketchDefaultsRequest): SetSketchDefaultsRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: SetSketchDefaultsRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): SetSketchDefaultsRequest;
|
||||
static deserializeBinaryFromReader(message: SetSketchDefaultsRequest, reader: jspb.BinaryReader): SetSketchDefaultsRequest;
|
||||
}
|
||||
|
||||
export namespace SetSketchDefaultsRequest {
|
||||
export type AsObject = {
|
||||
sketchPath: string,
|
||||
defaultFqbn: string,
|
||||
defaultPortAddress: string,
|
||||
defaultPortProtocol: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class SetSketchDefaultsResponse extends jspb.Message {
|
||||
getDefaultFqbn(): string;
|
||||
setDefaultFqbn(value: string): SetSketchDefaultsResponse;
|
||||
getDefaultPortAddress(): string;
|
||||
setDefaultPortAddress(value: string): SetSketchDefaultsResponse;
|
||||
getDefaultPortProtocol(): string;
|
||||
setDefaultPortProtocol(value: string): SetSketchDefaultsResponse;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SetSketchDefaultsResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SetSketchDefaultsResponse): SetSketchDefaultsResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: SetSketchDefaultsResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): SetSketchDefaultsResponse;
|
||||
static deserializeBinaryFromReader(message: SetSketchDefaultsResponse, reader: jspb.BinaryReader): SetSketchDefaultsResponse;
|
||||
}
|
||||
|
||||
export namespace SetSketchDefaultsResponse {
|
||||
export type AsObject = {
|
||||
defaultFqbn: string,
|
||||
defaultPortAddress: string,
|
||||
defaultPortProtocol: string,
|
||||
}
|
||||
}
|
||||
|
||||
export enum FailedInstanceInitReason {
|
||||
FAILED_INSTANCE_INIT_REASON_UNSPECIFIED = 0,
|
||||
FAILED_INSTANCE_INIT_REASON_INVALID_INDEX_URL = 1,
|
||||
FAILED_INSTANCE_INIT_REASON_INDEX_LOAD_ERROR = 2,
|
||||
FAILED_INSTANCE_INIT_REASON_TOOL_LOAD_ERROR = 3,
|
||||
FAILED_INSTANCE_INIT_REASON_INDEX_DOWNLOAD_ERROR = 4,
|
||||
}
|
||||
|
@ -53,6 +53,8 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LoadSketchRequest', null, gl
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.LoadSketchResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.NewSketchRequest', null, global);
|
||||
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.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);
|
||||
@ -479,6 +481,48 @@ if (goog.DEBUG && !COMPILED) {
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.ArchiveSketchResponse.displayName = 'proto.cc.arduino.cli.commands.v1.ArchiveSketchResponse';
|
||||
}
|
||||
/**
|
||||
* 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.SetSketchDefaultsRequest = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.displayName = 'proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest';
|
||||
}
|
||||
/**
|
||||
* 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.SetSketchDefaultsResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.displayName = 'proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse';
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -2733,7 +2777,6 @@ proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.toObject = function(
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||
sketchName: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
sketchDir: jspb.Message.getFieldWithDefault(msg, 3, ""),
|
||||
overwrite: jspb.Message.getBooleanFieldWithDefault(msg, 4, false)
|
||||
@ -2773,11 +2816,6 @@ proto.cc.arduino.cli.commands.v1.NewSketchRequest.deserializeBinaryFromReader =
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.Instance;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
|
||||
msg.setInstance(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setSketchName(value);
|
||||
@ -2819,14 +2857,6 @@ proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.serializeBinary = fu
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getInstance();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
1,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getSketchName();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
@ -2851,43 +2881,6 @@ proto.cc.arduino.cli.commands.v1.NewSketchRequest.serializeBinaryToWriter = func
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Instance instance = 1;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.Instance}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.getInstance = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.Instance} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Instance, 1));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.Instance|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.setInstance = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.NewSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.clearInstance = function() {
|
||||
return this.setInstance(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.NewSketchRequest.prototype.hasInstance = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string sketch_name = 2;
|
||||
* @return {string}
|
||||
@ -3104,7 +3097,6 @@ proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.toObject = function
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||
sketchPath: jspb.Message.getFieldWithDefault(msg, 2, "")
|
||||
};
|
||||
|
||||
@ -3142,11 +3134,6 @@ proto.cc.arduino.cli.commands.v1.LoadSketchRequest.deserializeBinaryFromReader =
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = new cc_arduino_cli_commands_v1_common_pb.Instance;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_common_pb.Instance.deserializeBinaryFromReader);
|
||||
msg.setInstance(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setSketchPath(value);
|
||||
@ -3180,14 +3167,6 @@ proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.serializeBinary = f
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getInstance();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
1,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_common_pb.Instance.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
f = message.getSketchPath();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
@ -3198,43 +3177,6 @@ proto.cc.arduino.cli.commands.v1.LoadSketchRequest.serializeBinaryToWriter = fun
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Instance instance = 1;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.Instance}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.getInstance = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.Instance} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_common_pb.Instance, 1));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.Instance|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.setInstance = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.clearInstance = function() {
|
||||
return this.setInstance(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchRequest.prototype.hasInstance = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string sketch_path = 2;
|
||||
* @return {string}
|
||||
@ -3296,7 +3238,10 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.toObject = function(includeI
|
||||
locationPath: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
otherSketchFilesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f,
|
||||
additionalFilesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f,
|
||||
rootFolderFilesList: (f = jspb.Message.getRepeatedField(msg, 5)) == null ? undefined : f
|
||||
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, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@ -3353,6 +3298,18 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.deserializeBinaryFromReader
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.addRootFolderFiles(value);
|
||||
break;
|
||||
case 6:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultFqbn(value);
|
||||
break;
|
||||
case 7:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultPort(value);
|
||||
break;
|
||||
case 8:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultProtocol(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@ -3417,6 +3374,27 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.serializeBinaryToWriter = fu
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultFqbn();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
6,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultPort();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
7,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultProtocol();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
8,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -3567,6 +3545,60 @@ proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.clearRootFolderFil
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_fqbn = 6;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultFqbn = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultFqbn = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 6, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_port = 7;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultPort = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultPort = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 7, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_protocol = 8;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.getDefaultProtocol = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LoadSketchResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LoadSketchResponse.prototype.setDefaultProtocol = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 8, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -3888,6 +3920,416 @@ proto.cc.arduino.cli.commands.v1.ArchiveSketchResponse.serializeBinaryToWriter =
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.SetSketchDefaultsRequest.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.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.SetSketchDefaultsRequest} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
sketchPath: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
defaultFqbn: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
defaultPortAddress: jspb.Message.getFieldWithDefault(msg, 3, ""),
|
||||
defaultPortProtocol: jspb.Message.getFieldWithDefault(msg, 4, "")
|
||||
};
|
||||
|
||||
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.SetSketchDefaultsRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest;
|
||||
return proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.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.SetSketchDefaultsRequest} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.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.setSketchPath(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultFqbn(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultPortAddress(value);
|
||||
break;
|
||||
case 4:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultPortProtocol(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.SetSketchDefaultsRequest.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.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.SetSketchDefaultsRequest} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getSketchPath();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultFqbn();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultPortAddress();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
3,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultPortProtocol();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
4,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string sketch_path = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.getSketchPath = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.setSketchPath = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_fqbn = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.getDefaultFqbn = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.setDefaultFqbn = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_port_address = 3;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.getDefaultPortAddress = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.setDefaultPortAddress = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 3, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_port_protocol = 4;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.getDefaultPortProtocol = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsRequest.prototype.setDefaultPortProtocol = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 4, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.SetSketchDefaultsResponse.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.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.SetSketchDefaultsResponse} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
defaultFqbn: jspb.Message.getFieldWithDefault(msg, 1, ""),
|
||||
defaultPortAddress: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
defaultPortProtocol: jspb.Message.getFieldWithDefault(msg, 3, "")
|
||||
};
|
||||
|
||||
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.SetSketchDefaultsResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse;
|
||||
return proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.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.SetSketchDefaultsResponse} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.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.setDefaultFqbn(value);
|
||||
break;
|
||||
case 2:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultPortAddress(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setDefaultPortProtocol(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.SetSketchDefaultsResponse.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.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.SetSketchDefaultsResponse} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getDefaultFqbn();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultPortAddress();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getDefaultPortProtocol();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
3,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_fqbn = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.prototype.getDefaultFqbn = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.prototype.setDefaultFqbn = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_port_address = 2;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.prototype.getDefaultPortAddress = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.prototype.setDefaultPortAddress = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 2, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string default_port_protocol = 3;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.prototype.getDefaultPortProtocol = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.SetSketchDefaultsResponse.prototype.setDefaultPortProtocol = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 3, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
@ -3895,7 +4337,8 @@ proto.cc.arduino.cli.commands.v1.FailedInstanceInitReason = {
|
||||
FAILED_INSTANCE_INIT_REASON_UNSPECIFIED: 0,
|
||||
FAILED_INSTANCE_INIT_REASON_INVALID_INDEX_URL: 1,
|
||||
FAILED_INSTANCE_INIT_REASON_INDEX_LOAD_ERROR: 2,
|
||||
FAILED_INSTANCE_INIT_REASON_TOOL_LOAD_ERROR: 3
|
||||
FAILED_INSTANCE_INIT_REASON_TOOL_LOAD_ERROR: 3,
|
||||
FAILED_INSTANCE_INIT_REASON_INDEX_DOWNLOAD_ERROR: 4
|
||||
};
|
||||
|
||||
goog.object.extend(exports, proto.cc.arduino.cli.commands.v1);
|
||||
|
@ -10,7 +10,6 @@ export class Instance extends jspb.Message {
|
||||
getId(): number;
|
||||
setId(value: number): Instance;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Instance.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Instance): Instance.AsObject;
|
||||
@ -34,19 +33,16 @@ export class DownloadProgress extends jspb.Message {
|
||||
getStart(): DownloadProgressStart | undefined;
|
||||
setStart(value?: DownloadProgressStart): DownloadProgress;
|
||||
|
||||
|
||||
hasUpdate(): boolean;
|
||||
clearUpdate(): void;
|
||||
getUpdate(): DownloadProgressUpdate | undefined;
|
||||
setUpdate(value?: DownloadProgressUpdate): DownloadProgress;
|
||||
|
||||
|
||||
hasEnd(): boolean;
|
||||
clearEnd(): void;
|
||||
getEnd(): DownloadProgressEnd | undefined;
|
||||
setEnd(value?: DownloadProgressEnd): DownloadProgress;
|
||||
|
||||
|
||||
getMessageCase(): DownloadProgress.MessageCase;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
@ -68,13 +64,9 @@ export namespace DownloadProgress {
|
||||
|
||||
export enum MessageCase {
|
||||
MESSAGE_NOT_SET = 0,
|
||||
|
||||
START = 1,
|
||||
|
||||
UPDATE = 2,
|
||||
|
||||
END = 3,
|
||||
|
||||
START = 1,
|
||||
UPDATE = 2,
|
||||
END = 3,
|
||||
}
|
||||
|
||||
}
|
||||
@ -82,11 +74,9 @@ export namespace DownloadProgress {
|
||||
export class DownloadProgressStart extends jspb.Message {
|
||||
getUrl(): string;
|
||||
setUrl(value: string): DownloadProgressStart;
|
||||
|
||||
getLabel(): string;
|
||||
setLabel(value: string): DownloadProgressStart;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DownloadProgressStart.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DownloadProgressStart): DownloadProgressStart.AsObject;
|
||||
@ -107,11 +97,9 @@ export namespace DownloadProgressStart {
|
||||
export class DownloadProgressUpdate extends jspb.Message {
|
||||
getDownloaded(): number;
|
||||
setDownloaded(value: number): DownloadProgressUpdate;
|
||||
|
||||
getTotalSize(): number;
|
||||
setTotalSize(value: number): DownloadProgressUpdate;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DownloadProgressUpdate.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DownloadProgressUpdate): DownloadProgressUpdate.AsObject;
|
||||
@ -132,11 +120,9 @@ export namespace DownloadProgressUpdate {
|
||||
export class DownloadProgressEnd extends jspb.Message {
|
||||
getSuccess(): boolean;
|
||||
setSuccess(value: boolean): DownloadProgressEnd;
|
||||
|
||||
getMessage(): string;
|
||||
setMessage(value: string): DownloadProgressEnd;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DownloadProgressEnd.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DownloadProgressEnd): DownloadProgressEnd.AsObject;
|
||||
@ -157,17 +143,13 @@ export namespace DownloadProgressEnd {
|
||||
export class TaskProgress extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): TaskProgress;
|
||||
|
||||
getMessage(): string;
|
||||
setMessage(value: string): TaskProgress;
|
||||
|
||||
getCompleted(): boolean;
|
||||
setCompleted(value: boolean): TaskProgress;
|
||||
|
||||
getPercent(): number;
|
||||
setPercent(value: number): TaskProgress;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): TaskProgress.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: TaskProgress): TaskProgress.AsObject;
|
||||
@ -190,14 +172,11 @@ export namespace TaskProgress {
|
||||
export class Programmer extends jspb.Message {
|
||||
getPlatform(): string;
|
||||
setPlatform(value: string): Programmer;
|
||||
|
||||
getId(): string;
|
||||
setId(value: string): Programmer;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): Programmer;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Programmer.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Programmer): Programmer.AsObject;
|
||||
@ -219,54 +198,40 @@ export namespace Programmer {
|
||||
export class Platform extends jspb.Message {
|
||||
getId(): string;
|
||||
setId(value: string): Platform;
|
||||
|
||||
getInstalled(): string;
|
||||
setInstalled(value: string): Platform;
|
||||
|
||||
getLatest(): string;
|
||||
setLatest(value: string): Platform;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): Platform;
|
||||
|
||||
getMaintainer(): string;
|
||||
setMaintainer(value: string): Platform;
|
||||
|
||||
getWebsite(): string;
|
||||
setWebsite(value: string): Platform;
|
||||
|
||||
getEmail(): string;
|
||||
setEmail(value: string): Platform;
|
||||
|
||||
clearBoardsList(): void;
|
||||
getBoardsList(): Array<Board>;
|
||||
setBoardsList(value: Array<Board>): Platform;
|
||||
addBoards(value?: Board, index?: number): Board;
|
||||
|
||||
getManuallyInstalled(): boolean;
|
||||
setManuallyInstalled(value: boolean): Platform;
|
||||
|
||||
getDeprecated(): boolean;
|
||||
setDeprecated(value: boolean): Platform;
|
||||
|
||||
clearTypeList(): void;
|
||||
getTypeList(): Array<string>;
|
||||
setTypeList(value: Array<string>): Platform;
|
||||
addType(value: string, index?: number): string;
|
||||
|
||||
|
||||
hasHelp(): boolean;
|
||||
clearHelp(): void;
|
||||
getHelp(): HelpResources | undefined;
|
||||
setHelp(value?: HelpResources): Platform;
|
||||
|
||||
getIndexed(): boolean;
|
||||
setIndexed(value: boolean): Platform;
|
||||
|
||||
getMissingMetadata(): boolean;
|
||||
setMissingMetadata(value: boolean): Platform;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Platform.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Platform): Platform.AsObject;
|
||||
@ -299,17 +264,13 @@ export namespace Platform {
|
||||
export class InstalledPlatformReference extends jspb.Message {
|
||||
getId(): string;
|
||||
setId(value: string): InstalledPlatformReference;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): InstalledPlatformReference;
|
||||
|
||||
getInstallDir(): string;
|
||||
setInstallDir(value: string): InstalledPlatformReference;
|
||||
|
||||
getPackageUrl(): string;
|
||||
setPackageUrl(value: string): InstalledPlatformReference;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): InstalledPlatformReference.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: InstalledPlatformReference): InstalledPlatformReference.AsObject;
|
||||
@ -332,11 +293,9 @@ export namespace InstalledPlatformReference {
|
||||
export class Board extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): Board;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): Board;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Board.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Board): Board.AsObject;
|
||||
@ -357,11 +316,9 @@ export namespace Board {
|
||||
export class Profile extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): Profile;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): Profile;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Profile.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Profile): Profile.AsObject;
|
||||
@ -383,7 +340,6 @@ export class HelpResources extends jspb.Message {
|
||||
getOnline(): string;
|
||||
setOnline(value: string): HelpResources;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): HelpResources.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: HelpResources): HelpResources.AsObject;
|
||||
|
@ -15,90 +15,65 @@ export class CompileRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): CompileRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): CompileRequest;
|
||||
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): CompileRequest;
|
||||
|
||||
getShowProperties(): boolean;
|
||||
setShowProperties(value: boolean): CompileRequest;
|
||||
|
||||
getPreprocess(): boolean;
|
||||
setPreprocess(value: boolean): CompileRequest;
|
||||
|
||||
getBuildCachePath(): string;
|
||||
setBuildCachePath(value: string): CompileRequest;
|
||||
|
||||
getBuildPath(): string;
|
||||
setBuildPath(value: string): CompileRequest;
|
||||
|
||||
clearBuildPropertiesList(): void;
|
||||
getBuildPropertiesList(): Array<string>;
|
||||
setBuildPropertiesList(value: Array<string>): CompileRequest;
|
||||
addBuildProperties(value: string, index?: number): string;
|
||||
|
||||
getWarnings(): string;
|
||||
setWarnings(value: string): CompileRequest;
|
||||
|
||||
getVerbose(): boolean;
|
||||
setVerbose(value: boolean): CompileRequest;
|
||||
|
||||
getQuiet(): boolean;
|
||||
setQuiet(value: boolean): CompileRequest;
|
||||
|
||||
getJobs(): number;
|
||||
setJobs(value: number): CompileRequest;
|
||||
|
||||
clearLibrariesList(): void;
|
||||
getLibrariesList(): Array<string>;
|
||||
setLibrariesList(value: Array<string>): CompileRequest;
|
||||
addLibraries(value: string, index?: number): string;
|
||||
|
||||
getOptimizeForDebug(): boolean;
|
||||
setOptimizeForDebug(value: boolean): CompileRequest;
|
||||
|
||||
getExportDir(): string;
|
||||
setExportDir(value: string): CompileRequest;
|
||||
|
||||
getClean(): boolean;
|
||||
setClean(value: boolean): CompileRequest;
|
||||
|
||||
getCreateCompilationDatabaseOnly(): boolean;
|
||||
setCreateCompilationDatabaseOnly(value: boolean): CompileRequest;
|
||||
|
||||
|
||||
getSourceOverrideMap(): jspb.Map<string, string>;
|
||||
clearSourceOverrideMap(): void;
|
||||
|
||||
|
||||
hasExportBinaries(): boolean;
|
||||
clearExportBinaries(): void;
|
||||
getExportBinaries(): google_protobuf_wrappers_pb.BoolValue | undefined;
|
||||
setExportBinaries(value?: google_protobuf_wrappers_pb.BoolValue): CompileRequest;
|
||||
|
||||
clearLibraryList(): void;
|
||||
getLibraryList(): Array<string>;
|
||||
setLibraryList(value: Array<string>): CompileRequest;
|
||||
addLibrary(value: string, index?: number): string;
|
||||
|
||||
getKeysKeychain(): string;
|
||||
setKeysKeychain(value: string): CompileRequest;
|
||||
|
||||
getSignKey(): string;
|
||||
setSignKey(value: string): CompileRequest;
|
||||
|
||||
getEncryptKey(): string;
|
||||
setEncryptKey(value: string): CompileRequest;
|
||||
|
||||
getSkipLibrariesDiscovery(): boolean;
|
||||
setSkipLibrariesDiscovery(value: boolean): CompileRequest;
|
||||
|
||||
getDoNotExpandBuildProperties(): boolean;
|
||||
setDoNotExpandBuildProperties(value: boolean): CompileRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): CompileRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: CompileRequest): CompileRequest.AsObject;
|
||||
@ -145,49 +120,40 @@ export class CompileResponse extends jspb.Message {
|
||||
getOutStream_asU8(): Uint8Array;
|
||||
getOutStream_asB64(): string;
|
||||
setOutStream(value: Uint8Array | string): CompileResponse;
|
||||
|
||||
getErrStream(): Uint8Array | string;
|
||||
getErrStream_asU8(): Uint8Array;
|
||||
getErrStream_asB64(): string;
|
||||
setErrStream(value: Uint8Array | string): CompileResponse;
|
||||
|
||||
getBuildPath(): string;
|
||||
setBuildPath(value: string): CompileResponse;
|
||||
|
||||
clearUsedLibrariesList(): void;
|
||||
getUsedLibrariesList(): Array<cc_arduino_cli_commands_v1_lib_pb.Library>;
|
||||
setUsedLibrariesList(value: Array<cc_arduino_cli_commands_v1_lib_pb.Library>): CompileResponse;
|
||||
addUsedLibraries(value?: cc_arduino_cli_commands_v1_lib_pb.Library, index?: number): cc_arduino_cli_commands_v1_lib_pb.Library;
|
||||
|
||||
clearExecutableSectionsSizeList(): void;
|
||||
getExecutableSectionsSizeList(): Array<ExecutableSectionSize>;
|
||||
setExecutableSectionsSizeList(value: Array<ExecutableSectionSize>): CompileResponse;
|
||||
addExecutableSectionsSize(value?: ExecutableSectionSize, index?: number): ExecutableSectionSize;
|
||||
|
||||
|
||||
hasBoardPlatform(): boolean;
|
||||
clearBoardPlatform(): void;
|
||||
getBoardPlatform(): cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference | undefined;
|
||||
setBoardPlatform(value?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference): CompileResponse;
|
||||
|
||||
|
||||
hasBuildPlatform(): boolean;
|
||||
clearBuildPlatform(): void;
|
||||
getBuildPlatform(): cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference | undefined;
|
||||
setBuildPlatform(value?: cc_arduino_cli_commands_v1_common_pb.InstalledPlatformReference): CompileResponse;
|
||||
|
||||
|
||||
hasProgress(): boolean;
|
||||
clearProgress(): void;
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): CompileResponse;
|
||||
|
||||
clearBuildPropertiesList(): void;
|
||||
getBuildPropertiesList(): Array<string>;
|
||||
setBuildPropertiesList(value: Array<string>): CompileResponse;
|
||||
addBuildProperties(value: string, index?: number): string;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): CompileResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: CompileResponse): CompileResponse.AsObject;
|
||||
@ -215,14 +181,11 @@ export namespace CompileResponse {
|
||||
export class ExecutableSectionSize extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): ExecutableSectionSize;
|
||||
|
||||
getSize(): number;
|
||||
setSize(value: number): ExecutableSectionSize;
|
||||
|
||||
getMaxSize(): number;
|
||||
setMaxSize(value: number): ExecutableSectionSize;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ExecutableSectionSize.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ExecutableSectionSize): ExecutableSectionSize.AsObject;
|
||||
|
@ -13,23 +13,17 @@ export class PlatformInstallRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformInstallRequest;
|
||||
|
||||
getPlatformPackage(): string;
|
||||
setPlatformPackage(value: string): PlatformInstallRequest;
|
||||
|
||||
getArchitecture(): string;
|
||||
setArchitecture(value: string): PlatformInstallRequest;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): PlatformInstallRequest;
|
||||
|
||||
getSkipPostInstall(): boolean;
|
||||
setSkipPostInstall(value: boolean): PlatformInstallRequest;
|
||||
|
||||
getNoOverwrite(): boolean;
|
||||
setNoOverwrite(value: boolean): PlatformInstallRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformInstallRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformInstallRequest): PlatformInstallRequest.AsObject;
|
||||
@ -58,13 +52,11 @@ export class PlatformInstallResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): PlatformInstallResponse;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): PlatformInstallResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformInstallResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformInstallResponse): PlatformInstallResponse.AsObject;
|
||||
@ -105,17 +97,13 @@ export class PlatformDownloadRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformDownloadRequest;
|
||||
|
||||
getPlatformPackage(): string;
|
||||
setPlatformPackage(value: string): PlatformDownloadRequest;
|
||||
|
||||
getArchitecture(): string;
|
||||
setArchitecture(value: string): PlatformDownloadRequest;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): PlatformDownloadRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformDownloadRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformDownloadRequest): PlatformDownloadRequest.AsObject;
|
||||
@ -142,7 +130,6 @@ export class PlatformDownloadResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): PlatformDownloadResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformDownloadResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformDownloadResponse): PlatformDownloadResponse.AsObject;
|
||||
@ -165,14 +152,11 @@ export class PlatformUninstallRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformUninstallRequest;
|
||||
|
||||
getPlatformPackage(): string;
|
||||
setPlatformPackage(value: string): PlatformUninstallRequest;
|
||||
|
||||
getArchitecture(): string;
|
||||
setArchitecture(value: string): PlatformUninstallRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformUninstallRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformUninstallRequest): PlatformUninstallRequest.AsObject;
|
||||
@ -198,7 +182,6 @@ export class PlatformUninstallResponse extends jspb.Message {
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): PlatformUninstallResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformUninstallResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformUninstallResponse): PlatformUninstallResponse.AsObject;
|
||||
@ -238,17 +221,13 @@ export class PlatformUpgradeRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformUpgradeRequest;
|
||||
|
||||
getPlatformPackage(): string;
|
||||
setPlatformPackage(value: string): PlatformUpgradeRequest;
|
||||
|
||||
getArchitecture(): string;
|
||||
setArchitecture(value: string): PlatformUpgradeRequest;
|
||||
|
||||
getSkipPostInstall(): boolean;
|
||||
setSkipPostInstall(value: boolean): PlatformUpgradeRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformUpgradeRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformUpgradeRequest): PlatformUpgradeRequest.AsObject;
|
||||
@ -275,19 +254,16 @@ export class PlatformUpgradeResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): PlatformUpgradeResponse;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): PlatformUpgradeResponse;
|
||||
|
||||
|
||||
hasPlatform(): boolean;
|
||||
clearPlatform(): void;
|
||||
getPlatform(): cc_arduino_cli_commands_v1_common_pb.Platform | undefined;
|
||||
setPlatform(value?: cc_arduino_cli_commands_v1_common_pb.Platform): PlatformUpgradeResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformUpgradeResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformUpgradeResponse): PlatformUpgradeResponse.AsObject;
|
||||
@ -312,14 +288,11 @@ export class PlatformSearchRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformSearchRequest;
|
||||
|
||||
getSearchArgs(): string;
|
||||
setSearchArgs(value: string): PlatformSearchRequest;
|
||||
|
||||
getAllVersions(): boolean;
|
||||
setAllVersions(value: boolean): PlatformSearchRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformSearchRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformSearchRequest): PlatformSearchRequest.AsObject;
|
||||
@ -344,7 +317,6 @@ export class PlatformSearchResponse extends jspb.Message {
|
||||
setSearchOutputList(value: Array<cc_arduino_cli_commands_v1_common_pb.Platform>): PlatformSearchResponse;
|
||||
addSearchOutput(value?: cc_arduino_cli_commands_v1_common_pb.Platform, index?: number): cc_arduino_cli_commands_v1_common_pb.Platform;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformSearchResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformSearchResponse): PlatformSearchResponse.AsObject;
|
||||
@ -367,14 +339,11 @@ export class PlatformListRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): PlatformListRequest;
|
||||
|
||||
getUpdatableOnly(): boolean;
|
||||
setUpdatableOnly(value: boolean): PlatformListRequest;
|
||||
|
||||
getAll(): boolean;
|
||||
setAll(value: boolean): PlatformListRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformListRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformListRequest): PlatformListRequest.AsObject;
|
||||
@ -399,7 +368,6 @@ export class PlatformListResponse extends jspb.Message {
|
||||
setInstalledPlatformsList(value: Array<cc_arduino_cli_commands_v1_common_pb.Platform>): PlatformListResponse;
|
||||
addInstalledPlatforms(value?: cc_arduino_cli_commands_v1_common_pb.Platform, index?: number): cc_arduino_cli_commands_v1_common_pb.Platform;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): PlatformListResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: PlatformListResponse): PlatformListResponse.AsObject;
|
||||
|
@ -13,14 +13,11 @@ export class LibraryDownloadRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryDownloadRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryDownloadRequest;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): LibraryDownloadRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryDownloadRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryDownloadRequest): LibraryDownloadRequest.AsObject;
|
||||
@ -46,7 +43,6 @@ export class LibraryDownloadResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): LibraryDownloadResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryDownloadResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryDownloadResponse): LibraryDownloadResponse.AsObject;
|
||||
@ -69,23 +65,17 @@ export class LibraryInstallRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryInstallRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryInstallRequest;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): LibraryInstallRequest;
|
||||
|
||||
getNoDeps(): boolean;
|
||||
setNoDeps(value: boolean): LibraryInstallRequest;
|
||||
|
||||
getNoOverwrite(): boolean;
|
||||
setNoOverwrite(value: boolean): LibraryInstallRequest;
|
||||
|
||||
getInstallLocation(): LibraryInstallLocation;
|
||||
setInstallLocation(value: LibraryInstallLocation): LibraryInstallRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryInstallRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryInstallRequest): LibraryInstallRequest.AsObject;
|
||||
@ -114,13 +104,11 @@ export class LibraryInstallResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): LibraryInstallResponse;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): LibraryInstallResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryInstallResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryInstallResponse): LibraryInstallResponse.AsObject;
|
||||
@ -144,14 +132,11 @@ export class LibraryUpgradeRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryUpgradeRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryUpgradeRequest;
|
||||
|
||||
getNoDeps(): boolean;
|
||||
setNoDeps(value: boolean): LibraryUpgradeRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUpgradeRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUpgradeRequest): LibraryUpgradeRequest.AsObject;
|
||||
@ -177,13 +162,11 @@ export class LibraryUpgradeResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): LibraryUpgradeResponse;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): LibraryUpgradeResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUpgradeResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUpgradeResponse): LibraryUpgradeResponse.AsObject;
|
||||
@ -207,14 +190,11 @@ export class LibraryUninstallRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryUninstallRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryUninstallRequest;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): LibraryUninstallRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUninstallRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUninstallRequest): LibraryUninstallRequest.AsObject;
|
||||
@ -240,7 +220,6 @@ export class LibraryUninstallResponse extends jspb.Message {
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): LibraryUninstallResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUninstallResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUninstallResponse): LibraryUninstallResponse.AsObject;
|
||||
@ -264,7 +243,6 @@ export class LibraryUpgradeAllRequest extends jspb.Message {
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryUpgradeAllRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUpgradeAllRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUpgradeAllRequest): LibraryUpgradeAllRequest.AsObject;
|
||||
@ -288,13 +266,11 @@ export class LibraryUpgradeAllResponse extends jspb.Message {
|
||||
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
|
||||
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): LibraryUpgradeAllResponse;
|
||||
|
||||
|
||||
hasTaskProgress(): boolean;
|
||||
clearTaskProgress(): void;
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): LibraryUpgradeAllResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryUpgradeAllResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryUpgradeAllResponse): LibraryUpgradeAllResponse.AsObject;
|
||||
@ -318,14 +294,11 @@ export class LibraryResolveDependenciesRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryResolveDependenciesRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryResolveDependenciesRequest;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): LibraryResolveDependenciesRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryResolveDependenciesRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryResolveDependenciesRequest): LibraryResolveDependenciesRequest.AsObject;
|
||||
@ -350,7 +323,6 @@ export class LibraryResolveDependenciesResponse extends jspb.Message {
|
||||
setDependenciesList(value: Array<LibraryDependencyStatus>): LibraryResolveDependenciesResponse;
|
||||
addDependencies(value?: LibraryDependencyStatus, index?: number): LibraryDependencyStatus;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryResolveDependenciesResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryResolveDependenciesResponse): LibraryResolveDependenciesResponse.AsObject;
|
||||
@ -370,14 +342,11 @@ export namespace LibraryResolveDependenciesResponse {
|
||||
export class LibraryDependencyStatus extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): LibraryDependencyStatus;
|
||||
|
||||
getVersionRequired(): string;
|
||||
setVersionRequired(value: string): LibraryDependencyStatus;
|
||||
|
||||
getVersionInstalled(): string;
|
||||
setVersionInstalled(value: string): LibraryDependencyStatus;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryDependencyStatus.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryDependencyStatus): LibraryDependencyStatus.AsObject;
|
||||
@ -402,13 +371,12 @@ export class LibrarySearchRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibrarySearchRequest;
|
||||
|
||||
getQuery(): string;
|
||||
setQuery(value: string): LibrarySearchRequest;
|
||||
|
||||
getOmitReleasesDetails(): boolean;
|
||||
setOmitReleasesDetails(value: boolean): LibrarySearchRequest;
|
||||
|
||||
getSearchArgs(): string;
|
||||
setSearchArgs(value: string): LibrarySearchRequest;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibrarySearchRequest.AsObject;
|
||||
@ -425,6 +393,7 @@ export namespace LibrarySearchRequest {
|
||||
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
|
||||
query: string,
|
||||
omitReleasesDetails: boolean,
|
||||
searchArgs: string,
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,11 +402,9 @@ export class LibrarySearchResponse extends jspb.Message {
|
||||
getLibrariesList(): Array<SearchedLibrary>;
|
||||
setLibrariesList(value: Array<SearchedLibrary>): LibrarySearchResponse;
|
||||
addLibraries(value?: SearchedLibrary, index?: number): SearchedLibrary;
|
||||
|
||||
getStatus(): LibrarySearchStatus;
|
||||
setStatus(value: LibrarySearchStatus): LibrarySearchResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibrarySearchResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibrarySearchResponse): LibrarySearchResponse.AsObject;
|
||||
@ -459,22 +426,18 @@ export class SearchedLibrary extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): SearchedLibrary;
|
||||
|
||||
|
||||
getReleasesMap(): jspb.Map<string, LibraryRelease>;
|
||||
clearReleasesMap(): void;
|
||||
|
||||
|
||||
hasLatest(): boolean;
|
||||
clearLatest(): void;
|
||||
getLatest(): LibraryRelease | undefined;
|
||||
setLatest(value?: LibraryRelease): SearchedLibrary;
|
||||
|
||||
clearAvailableVersionsList(): void;
|
||||
getAvailableVersionsList(): Array<string>;
|
||||
setAvailableVersionsList(value: Array<string>): SearchedLibrary;
|
||||
addAvailableVersions(value: string, index?: number): string;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SearchedLibrary.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SearchedLibrary): SearchedLibrary.AsObject;
|
||||
@ -498,55 +461,42 @@ export namespace SearchedLibrary {
|
||||
export class LibraryRelease extends jspb.Message {
|
||||
getAuthor(): string;
|
||||
setAuthor(value: string): LibraryRelease;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): LibraryRelease;
|
||||
|
||||
getMaintainer(): string;
|
||||
setMaintainer(value: string): LibraryRelease;
|
||||
|
||||
getSentence(): string;
|
||||
setSentence(value: string): LibraryRelease;
|
||||
|
||||
getParagraph(): string;
|
||||
setParagraph(value: string): LibraryRelease;
|
||||
|
||||
getWebsite(): string;
|
||||
setWebsite(value: string): LibraryRelease;
|
||||
|
||||
getCategory(): string;
|
||||
setCategory(value: string): LibraryRelease;
|
||||
|
||||
clearArchitecturesList(): void;
|
||||
getArchitecturesList(): Array<string>;
|
||||
setArchitecturesList(value: Array<string>): LibraryRelease;
|
||||
addArchitectures(value: string, index?: number): string;
|
||||
|
||||
clearTypesList(): void;
|
||||
getTypesList(): Array<string>;
|
||||
setTypesList(value: Array<string>): LibraryRelease;
|
||||
addTypes(value: string, index?: number): string;
|
||||
|
||||
|
||||
hasResources(): boolean;
|
||||
clearResources(): void;
|
||||
getResources(): DownloadResource | undefined;
|
||||
setResources(value?: DownloadResource): LibraryRelease;
|
||||
|
||||
getLicense(): string;
|
||||
setLicense(value: string): LibraryRelease;
|
||||
|
||||
clearProvidesIncludesList(): void;
|
||||
getProvidesIncludesList(): Array<string>;
|
||||
setProvidesIncludesList(value: Array<string>): LibraryRelease;
|
||||
addProvidesIncludes(value: string, index?: number): string;
|
||||
|
||||
clearDependenciesList(): void;
|
||||
getDependenciesList(): Array<LibraryDependency>;
|
||||
setDependenciesList(value: Array<LibraryDependency>): LibraryRelease;
|
||||
addDependencies(value?: LibraryDependency, index?: number): LibraryDependency;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryRelease.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryRelease): LibraryRelease.AsObject;
|
||||
@ -578,11 +528,9 @@ export namespace LibraryRelease {
|
||||
export class LibraryDependency extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): LibraryDependency;
|
||||
|
||||
getVersionConstraint(): string;
|
||||
setVersionConstraint(value: string): LibraryDependency;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryDependency.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryDependency): LibraryDependency.AsObject;
|
||||
@ -603,20 +551,15 @@ export namespace LibraryDependency {
|
||||
export class DownloadResource extends jspb.Message {
|
||||
getUrl(): string;
|
||||
setUrl(value: string): DownloadResource;
|
||||
|
||||
getArchiveFilename(): string;
|
||||
setArchiveFilename(value: string): DownloadResource;
|
||||
|
||||
getChecksum(): string;
|
||||
setChecksum(value: string): DownloadResource;
|
||||
|
||||
getSize(): number;
|
||||
setSize(value: number): DownloadResource;
|
||||
|
||||
getCachePath(): string;
|
||||
setCachePath(value: string): DownloadResource;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DownloadResource.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DownloadResource): DownloadResource.AsObject;
|
||||
@ -643,20 +586,15 @@ export class LibraryListRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): LibraryListRequest;
|
||||
|
||||
getAll(): boolean;
|
||||
setAll(value: boolean): LibraryListRequest;
|
||||
|
||||
getUpdatable(): boolean;
|
||||
setUpdatable(value: boolean): LibraryListRequest;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): LibraryListRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): LibraryListRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryListRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryListRequest): LibraryListRequest.AsObject;
|
||||
@ -683,7 +621,6 @@ export class LibraryListResponse extends jspb.Message {
|
||||
setInstalledLibrariesList(value: Array<InstalledLibrary>): LibraryListResponse;
|
||||
addInstalledLibraries(value?: InstalledLibrary, index?: number): InstalledLibrary;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): LibraryListResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: LibraryListResponse): LibraryListResponse.AsObject;
|
||||
@ -707,13 +644,11 @@ export class InstalledLibrary extends jspb.Message {
|
||||
getLibrary(): Library | undefined;
|
||||
setLibrary(value?: Library): InstalledLibrary;
|
||||
|
||||
|
||||
hasRelease(): boolean;
|
||||
clearRelease(): void;
|
||||
getRelease(): LibraryRelease | undefined;
|
||||
setRelease(value?: LibraryRelease): InstalledLibrary;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): InstalledLibrary.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: InstalledLibrary): InstalledLibrary.AsObject;
|
||||
@ -734,93 +669,67 @@ export namespace InstalledLibrary {
|
||||
export class Library extends jspb.Message {
|
||||
getName(): string;
|
||||
setName(value: string): Library;
|
||||
|
||||
getAuthor(): string;
|
||||
setAuthor(value: string): Library;
|
||||
|
||||
getMaintainer(): string;
|
||||
setMaintainer(value: string): Library;
|
||||
|
||||
getSentence(): string;
|
||||
setSentence(value: string): Library;
|
||||
|
||||
getParagraph(): string;
|
||||
setParagraph(value: string): Library;
|
||||
|
||||
getWebsite(): string;
|
||||
setWebsite(value: string): Library;
|
||||
|
||||
getCategory(): string;
|
||||
setCategory(value: string): Library;
|
||||
|
||||
clearArchitecturesList(): void;
|
||||
getArchitecturesList(): Array<string>;
|
||||
setArchitecturesList(value: Array<string>): Library;
|
||||
addArchitectures(value: string, index?: number): string;
|
||||
|
||||
clearTypesList(): void;
|
||||
getTypesList(): Array<string>;
|
||||
setTypesList(value: Array<string>): Library;
|
||||
addTypes(value: string, index?: number): string;
|
||||
|
||||
getInstallDir(): string;
|
||||
setInstallDir(value: string): Library;
|
||||
|
||||
getSourceDir(): string;
|
||||
setSourceDir(value: string): Library;
|
||||
|
||||
getUtilityDir(): string;
|
||||
setUtilityDir(value: string): Library;
|
||||
|
||||
getContainerPlatform(): string;
|
||||
setContainerPlatform(value: string): Library;
|
||||
|
||||
getDotALinkage(): boolean;
|
||||
setDotALinkage(value: boolean): Library;
|
||||
|
||||
getPrecompiled(): boolean;
|
||||
setPrecompiled(value: boolean): Library;
|
||||
|
||||
getLdFlags(): string;
|
||||
setLdFlags(value: string): Library;
|
||||
|
||||
getIsLegacy(): boolean;
|
||||
setIsLegacy(value: boolean): Library;
|
||||
|
||||
getVersion(): string;
|
||||
setVersion(value: string): Library;
|
||||
|
||||
getLicense(): string;
|
||||
setLicense(value: string): Library;
|
||||
|
||||
|
||||
getPropertiesMap(): jspb.Map<string, string>;
|
||||
clearPropertiesMap(): void;
|
||||
|
||||
getLocation(): LibraryLocation;
|
||||
setLocation(value: LibraryLocation): Library;
|
||||
|
||||
getLayout(): LibraryLayout;
|
||||
setLayout(value: LibraryLayout): Library;
|
||||
|
||||
clearExamplesList(): void;
|
||||
getExamplesList(): Array<string>;
|
||||
setExamplesList(value: Array<string>): Library;
|
||||
addExamples(value: string, index?: number): string;
|
||||
|
||||
clearProvidesIncludesList(): void;
|
||||
getProvidesIncludesList(): Array<string>;
|
||||
setProvidesIncludesList(value: Array<string>): Library;
|
||||
addProvidesIncludes(value: string, index?: number): string;
|
||||
|
||||
|
||||
getCompatibleWithMap(): jspb.Map<string, boolean>;
|
||||
clearCompatibleWithMap(): void;
|
||||
|
||||
getInDevelopment(): boolean;
|
||||
setInDevelopment(value: boolean): Library;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Library.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Library): Library.AsObject;
|
||||
@ -870,14 +779,11 @@ export class ZipLibraryInstallRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): ZipLibraryInstallRequest;
|
||||
|
||||
getPath(): string;
|
||||
setPath(value: string): ZipLibraryInstallRequest;
|
||||
|
||||
getOverwrite(): boolean;
|
||||
setOverwrite(value: boolean): ZipLibraryInstallRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ZipLibraryInstallRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ZipLibraryInstallRequest): ZipLibraryInstallRequest.AsObject;
|
||||
@ -903,7 +809,6 @@ export class ZipLibraryInstallResponse extends jspb.Message {
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): ZipLibraryInstallResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ZipLibraryInstallResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ZipLibraryInstallResponse): ZipLibraryInstallResponse.AsObject;
|
||||
@ -926,14 +831,11 @@ export class GitLibraryInstallRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): GitLibraryInstallRequest;
|
||||
|
||||
getUrl(): string;
|
||||
setUrl(value: string): GitLibraryInstallRequest;
|
||||
|
||||
getOverwrite(): boolean;
|
||||
setOverwrite(value: boolean): GitLibraryInstallRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GitLibraryInstallRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GitLibraryInstallRequest): GitLibraryInstallRequest.AsObject;
|
||||
@ -959,7 +861,6 @@ export class GitLibraryInstallResponse extends jspb.Message {
|
||||
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
|
||||
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): GitLibraryInstallResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GitLibraryInstallResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GitLibraryInstallResponse): GitLibraryInstallResponse.AsObject;
|
||||
|
@ -3209,7 +3209,8 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.toObject = function(includ
|
||||
var f, obj = {
|
||||
instance: (f = msg.getInstance()) && cc_arduino_cli_commands_v1_common_pb.Instance.toObject(includeInstance, f),
|
||||
query: jspb.Message.getFieldWithDefault(msg, 2, ""),
|
||||
omitReleasesDetails: jspb.Message.getBooleanFieldWithDefault(msg, 3, false)
|
||||
omitReleasesDetails: jspb.Message.getBooleanFieldWithDefault(msg, 3, false),
|
||||
searchArgs: jspb.Message.getFieldWithDefault(msg, 4, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@ -3259,6 +3260,10 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.deserializeBinaryFromReade
|
||||
var value = /** @type {boolean} */ (reader.readBool());
|
||||
msg.setOmitReleasesDetails(value);
|
||||
break;
|
||||
case 4:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setSearchArgs(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@ -3310,6 +3315,13 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.serializeBinaryToWriter =
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getSearchArgs();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
4,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -3386,6 +3398,24 @@ proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.setOmitReleasesD
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string search_args = 4;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.getSearchArgs = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.LibrarySearchRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.LibrarySearchRequest.prototype.setSearchArgs = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 4, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* List of repeated fields within this message type.
|
||||
|
@ -15,27 +15,22 @@ export class MonitorRequest extends jspb.Message {
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): MonitorRequest;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): MonitorRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): MonitorRequest;
|
||||
|
||||
getTxData(): Uint8Array | string;
|
||||
getTxData_asU8(): Uint8Array;
|
||||
getTxData_asB64(): string;
|
||||
setTxData(value: Uint8Array | string): MonitorRequest;
|
||||
|
||||
|
||||
hasPortConfiguration(): boolean;
|
||||
clearPortConfiguration(): void;
|
||||
getPortConfiguration(): MonitorPortConfiguration | undefined;
|
||||
setPortConfiguration(value?: MonitorPortConfiguration): MonitorRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): MonitorRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: MonitorRequest): MonitorRequest.AsObject;
|
||||
@ -62,7 +57,6 @@ export class MonitorPortConfiguration extends jspb.Message {
|
||||
setSettingsList(value: Array<MonitorPortSetting>): MonitorPortConfiguration;
|
||||
addSettings(value?: MonitorPortSetting, index?: number): MonitorPortSetting;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): MonitorPortConfiguration.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: MonitorPortConfiguration): MonitorPortConfiguration.AsObject;
|
||||
@ -82,21 +76,17 @@ export namespace MonitorPortConfiguration {
|
||||
export class MonitorResponse extends jspb.Message {
|
||||
getError(): string;
|
||||
setError(value: string): MonitorResponse;
|
||||
|
||||
getRxData(): Uint8Array | string;
|
||||
getRxData_asU8(): Uint8Array;
|
||||
getRxData_asB64(): string;
|
||||
setRxData(value: Uint8Array | string): MonitorResponse;
|
||||
|
||||
clearAppliedSettingsList(): void;
|
||||
getAppliedSettingsList(): Array<MonitorPortSetting>;
|
||||
setAppliedSettingsList(value: Array<MonitorPortSetting>): MonitorResponse;
|
||||
addAppliedSettings(value?: MonitorPortSetting, index?: number): MonitorPortSetting;
|
||||
|
||||
getSuccess(): boolean;
|
||||
setSuccess(value: boolean): MonitorResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): MonitorResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: MonitorResponse): MonitorResponse.AsObject;
|
||||
@ -119,11 +109,9 @@ export namespace MonitorResponse {
|
||||
export class MonitorPortSetting extends jspb.Message {
|
||||
getSettingId(): string;
|
||||
setSettingId(value: string): MonitorPortSetting;
|
||||
|
||||
getValue(): string;
|
||||
setValue(value: string): MonitorPortSetting;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): MonitorPortSetting.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: MonitorPortSetting): MonitorPortSetting.AsObject;
|
||||
@ -147,14 +135,11 @@ export class EnumerateMonitorPortSettingsRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): EnumerateMonitorPortSettingsRequest;
|
||||
|
||||
getPortProtocol(): string;
|
||||
setPortProtocol(value: string): EnumerateMonitorPortSettingsRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): EnumerateMonitorPortSettingsRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): EnumerateMonitorPortSettingsRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: EnumerateMonitorPortSettingsRequest): EnumerateMonitorPortSettingsRequest.AsObject;
|
||||
@ -179,7 +164,6 @@ export class EnumerateMonitorPortSettingsResponse extends jspb.Message {
|
||||
setSettingsList(value: Array<MonitorPortSettingDescriptor>): EnumerateMonitorPortSettingsResponse;
|
||||
addSettings(value?: MonitorPortSettingDescriptor, index?: number): MonitorPortSettingDescriptor;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): EnumerateMonitorPortSettingsResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: EnumerateMonitorPortSettingsResponse): EnumerateMonitorPortSettingsResponse.AsObject;
|
||||
@ -199,22 +183,17 @@ export namespace EnumerateMonitorPortSettingsResponse {
|
||||
export class MonitorPortSettingDescriptor extends jspb.Message {
|
||||
getSettingId(): string;
|
||||
setSettingId(value: string): MonitorPortSettingDescriptor;
|
||||
|
||||
getLabel(): string;
|
||||
setLabel(value: string): MonitorPortSettingDescriptor;
|
||||
|
||||
getType(): string;
|
||||
setType(value: string): MonitorPortSettingDescriptor;
|
||||
|
||||
clearEnumValuesList(): void;
|
||||
getEnumValuesList(): Array<string>;
|
||||
setEnumValuesList(value: Array<string>): MonitorPortSettingDescriptor;
|
||||
addEnumValues(value: string, index?: number): string;
|
||||
|
||||
getValue(): string;
|
||||
setValue(value: string): MonitorPortSettingDescriptor;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): MonitorPortSettingDescriptor.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: MonitorPortSettingDescriptor): MonitorPortSettingDescriptor.AsObject;
|
||||
|
@ -9,24 +9,18 @@ import * as jspb from "google-protobuf";
|
||||
export class Port extends jspb.Message {
|
||||
getAddress(): string;
|
||||
setAddress(value: string): Port;
|
||||
|
||||
getLabel(): string;
|
||||
setLabel(value: string): Port;
|
||||
|
||||
getProtocol(): string;
|
||||
setProtocol(value: string): Port;
|
||||
|
||||
getProtocolLabel(): string;
|
||||
setProtocolLabel(value: string): Port;
|
||||
|
||||
|
||||
getPropertiesMap(): jspb.Map<string, string>;
|
||||
clearPropertiesMap(): void;
|
||||
|
||||
getHardwareId(): string;
|
||||
setHardwareId(value: string): Port;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Port.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Port): Port.AsObject;
|
||||
|
@ -14,42 +14,31 @@ export class UploadRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): UploadRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): UploadRequest;
|
||||
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): UploadRequest;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): UploadRequest;
|
||||
|
||||
getVerbose(): boolean;
|
||||
setVerbose(value: boolean): UploadRequest;
|
||||
|
||||
getVerify(): boolean;
|
||||
setVerify(value: boolean): UploadRequest;
|
||||
|
||||
getImportFile(): string;
|
||||
setImportFile(value: string): UploadRequest;
|
||||
|
||||
getImportDir(): string;
|
||||
setImportDir(value: string): UploadRequest;
|
||||
|
||||
getProgrammer(): string;
|
||||
setProgrammer(value: string): UploadRequest;
|
||||
|
||||
getDryRun(): boolean;
|
||||
setDryRun(value: boolean): UploadRequest;
|
||||
|
||||
|
||||
getUserFieldsMap(): jspb.Map<string, string>;
|
||||
clearUserFieldsMap(): void;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UploadRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UploadRequest): UploadRequest.AsObject;
|
||||
@ -78,16 +67,27 @@ export namespace UploadRequest {
|
||||
}
|
||||
|
||||
export class UploadResponse extends jspb.Message {
|
||||
|
||||
hasOutStream(): boolean;
|
||||
clearOutStream(): void;
|
||||
getOutStream(): Uint8Array | string;
|
||||
getOutStream_asU8(): Uint8Array;
|
||||
getOutStream_asB64(): string;
|
||||
setOutStream(value: Uint8Array | string): UploadResponse;
|
||||
|
||||
hasErrStream(): boolean;
|
||||
clearErrStream(): void;
|
||||
getErrStream(): Uint8Array | string;
|
||||
getErrStream_asU8(): Uint8Array;
|
||||
getErrStream_asB64(): string;
|
||||
setErrStream(value: Uint8Array | string): UploadResponse;
|
||||
|
||||
hasResult(): boolean;
|
||||
clearResult(): void;
|
||||
getResult(): UploadResult | undefined;
|
||||
setResult(value?: UploadResult): UploadResponse;
|
||||
|
||||
getMessageCase(): UploadResponse.MessageCase;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UploadResponse.AsObject;
|
||||
@ -103,6 +103,38 @@ export namespace UploadResponse {
|
||||
export type AsObject = {
|
||||
outStream: Uint8Array | string,
|
||||
errStream: Uint8Array | string,
|
||||
result?: UploadResult.AsObject,
|
||||
}
|
||||
|
||||
export enum MessageCase {
|
||||
MESSAGE_NOT_SET = 0,
|
||||
OUT_STREAM = 1,
|
||||
ERR_STREAM = 2,
|
||||
RESULT = 3,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class UploadResult extends jspb.Message {
|
||||
|
||||
hasUpdatedUploadPort(): boolean;
|
||||
clearUpdatedUploadPort(): void;
|
||||
getUpdatedUploadPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setUpdatedUploadPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): UploadResult;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UploadResult.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UploadResult): UploadResult.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: UploadResult, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): UploadResult;
|
||||
static deserializeBinaryFromReader(message: UploadResult, reader: jspb.BinaryReader): UploadResult;
|
||||
}
|
||||
|
||||
export namespace UploadResult {
|
||||
export type AsObject = {
|
||||
updatedUploadPort?: cc_arduino_cli_commands_v1_port_pb.Port.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
@ -129,42 +161,31 @@ export class UploadUsingProgrammerRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): UploadUsingProgrammerRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): UploadUsingProgrammerRequest;
|
||||
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): UploadUsingProgrammerRequest;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): UploadUsingProgrammerRequest;
|
||||
|
||||
getVerbose(): boolean;
|
||||
setVerbose(value: boolean): UploadUsingProgrammerRequest;
|
||||
|
||||
getVerify(): boolean;
|
||||
setVerify(value: boolean): UploadUsingProgrammerRequest;
|
||||
|
||||
getImportFile(): string;
|
||||
setImportFile(value: string): UploadUsingProgrammerRequest;
|
||||
|
||||
getImportDir(): string;
|
||||
setImportDir(value: string): UploadUsingProgrammerRequest;
|
||||
|
||||
getProgrammer(): string;
|
||||
setProgrammer(value: string): UploadUsingProgrammerRequest;
|
||||
|
||||
getDryRun(): boolean;
|
||||
setDryRun(value: boolean): UploadUsingProgrammerRequest;
|
||||
|
||||
|
||||
getUserFieldsMap(): jspb.Map<string, string>;
|
||||
clearUserFieldsMap(): void;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UploadUsingProgrammerRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UploadUsingProgrammerRequest): UploadUsingProgrammerRequest.AsObject;
|
||||
@ -197,13 +218,11 @@ export class UploadUsingProgrammerResponse extends jspb.Message {
|
||||
getOutStream_asU8(): Uint8Array;
|
||||
getOutStream_asB64(): string;
|
||||
setOutStream(value: Uint8Array | string): UploadUsingProgrammerResponse;
|
||||
|
||||
getErrStream(): Uint8Array | string;
|
||||
getErrStream_asU8(): Uint8Array;
|
||||
getErrStream_asB64(): string;
|
||||
setErrStream(value: Uint8Array | string): UploadUsingProgrammerResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UploadUsingProgrammerResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UploadUsingProgrammerResponse): UploadUsingProgrammerResponse.AsObject;
|
||||
@ -227,33 +246,25 @@ export class BurnBootloaderRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BurnBootloaderRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): BurnBootloaderRequest;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): BurnBootloaderRequest;
|
||||
|
||||
getVerbose(): boolean;
|
||||
setVerbose(value: boolean): BurnBootloaderRequest;
|
||||
|
||||
getVerify(): boolean;
|
||||
setVerify(value: boolean): BurnBootloaderRequest;
|
||||
|
||||
getProgrammer(): string;
|
||||
setProgrammer(value: string): BurnBootloaderRequest;
|
||||
|
||||
getDryRun(): boolean;
|
||||
setDryRun(value: boolean): BurnBootloaderRequest;
|
||||
|
||||
|
||||
getUserFieldsMap(): jspb.Map<string, string>;
|
||||
clearUserFieldsMap(): void;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BurnBootloaderRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BurnBootloaderRequest): BurnBootloaderRequest.AsObject;
|
||||
@ -283,13 +294,11 @@ export class BurnBootloaderResponse extends jspb.Message {
|
||||
getOutStream_asU8(): Uint8Array;
|
||||
getOutStream_asB64(): string;
|
||||
setOutStream(value: Uint8Array | string): BurnBootloaderResponse;
|
||||
|
||||
getErrStream(): Uint8Array | string;
|
||||
getErrStream_asU8(): Uint8Array;
|
||||
getErrStream_asB64(): string;
|
||||
setErrStream(value: Uint8Array | string): BurnBootloaderResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BurnBootloaderResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BurnBootloaderResponse): BurnBootloaderResponse.AsObject;
|
||||
@ -313,11 +322,9 @@ export class ListProgrammersAvailableForUploadRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): ListProgrammersAvailableForUploadRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): ListProgrammersAvailableForUploadRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ListProgrammersAvailableForUploadRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ListProgrammersAvailableForUploadRequest): ListProgrammersAvailableForUploadRequest.AsObject;
|
||||
@ -341,7 +348,6 @@ export class ListProgrammersAvailableForUploadResponse extends jspb.Message {
|
||||
setProgrammersList(value: Array<cc_arduino_cli_commands_v1_common_pb.Programmer>): ListProgrammersAvailableForUploadResponse;
|
||||
addProgrammers(value?: cc_arduino_cli_commands_v1_common_pb.Programmer, index?: number): cc_arduino_cli_commands_v1_common_pb.Programmer;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ListProgrammersAvailableForUploadResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ListProgrammersAvailableForUploadResponse): ListProgrammersAvailableForUploadResponse.AsObject;
|
||||
@ -364,14 +370,11 @@ export class SupportedUserFieldsRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): SupportedUserFieldsRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): SupportedUserFieldsRequest;
|
||||
|
||||
getProtocol(): string;
|
||||
setProtocol(value: string): SupportedUserFieldsRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SupportedUserFieldsRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SupportedUserFieldsRequest): SupportedUserFieldsRequest.AsObject;
|
||||
@ -393,17 +396,13 @@ export namespace SupportedUserFieldsRequest {
|
||||
export class UserField extends jspb.Message {
|
||||
getToolId(): string;
|
||||
setToolId(value: string): UserField;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): UserField;
|
||||
|
||||
getLabel(): string;
|
||||
setLabel(value: string): UserField;
|
||||
|
||||
getSecret(): boolean;
|
||||
setSecret(value: boolean): UserField;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): UserField.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: UserField): UserField.AsObject;
|
||||
@ -429,7 +428,6 @@ export class SupportedUserFieldsResponse extends jspb.Message {
|
||||
setUserFieldsList(value: Array<UserField>): SupportedUserFieldsResponse;
|
||||
addUserFields(value?: UserField, index?: number): UserField;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SupportedUserFieldsResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SupportedUserFieldsResponse): SupportedUserFieldsResponse.AsObject;
|
||||
|
@ -34,6 +34,8 @@ goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SupportedUserFieldsRequest',
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.SupportedUserFieldsResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadResponse.MessageCase', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadResult', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UploadUsingProgrammerResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.commands.v1.UserField', null, global);
|
||||
@ -69,7 +71,7 @@ if (goog.DEBUG && !COMPILED) {
|
||||
* @constructor
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.UploadResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
@ -79,6 +81,27 @@ if (goog.DEBUG && !COMPILED) {
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.displayName = 'proto.cc.arduino.cli.commands.v1.UploadResponse';
|
||||
}
|
||||
/**
|
||||
* 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.UploadResult = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.commands.v1.UploadResult, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.displayName = 'proto.cc.arduino.cli.commands.v1.UploadResult';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
@ -765,6 +788,33 @@ proto.cc.arduino.cli.commands.v1.UploadRequest.prototype.clearUserFieldsMap = fu
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Oneof group definitions for this message. Each group defines the field
|
||||
* numbers belonging to that group. When of these fields' value is set, all
|
||||
* other fields in the group are cleared. During deserialization, if multiple
|
||||
* fields are encountered for a group, only the last value seen will be kept.
|
||||
* @private {!Array<!Array<number>>}
|
||||
* @const
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_ = [[1,2,3]];
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.MessageCase = {
|
||||
MESSAGE_NOT_SET: 0,
|
||||
OUT_STREAM: 1,
|
||||
ERR_STREAM: 2,
|
||||
RESULT: 3
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {proto.cc.arduino.cli.commands.v1.UploadResponse.MessageCase}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.getMessageCase = function() {
|
||||
return /** @type {proto.cc.arduino.cli.commands.v1.UploadResponse.MessageCase} */(jspb.Message.computeOneofCase(this, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_[0]));
|
||||
};
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
@ -797,7 +847,8 @@ proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.toObject = function(op
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
outStream: msg.getOutStream_asB64(),
|
||||
errStream: msg.getErrStream_asB64()
|
||||
errStream: msg.getErrStream_asB64(),
|
||||
result: (f = msg.getResult()) && proto.cc.arduino.cli.commands.v1.UploadResult.toObject(includeInstance, f)
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
@ -842,6 +893,11 @@ proto.cc.arduino.cli.commands.v1.UploadResponse.deserializeBinaryFromReader = fu
|
||||
var value = /** @type {!Uint8Array} */ (reader.readBytes());
|
||||
msg.setErrStream(value);
|
||||
break;
|
||||
case 3:
|
||||
var value = new proto.cc.arduino.cli.commands.v1.UploadResult;
|
||||
reader.readMessage(value,proto.cc.arduino.cli.commands.v1.UploadResult.deserializeBinaryFromReader);
|
||||
msg.setResult(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
@ -871,20 +927,28 @@ proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.serializeBinary = func
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getOutStream_asU8();
|
||||
if (f.length > 0) {
|
||||
f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 1));
|
||||
if (f != null) {
|
||||
writer.writeBytes(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getErrStream_asU8();
|
||||
if (f.length > 0) {
|
||||
f = /** @type {!(string|Uint8Array)} */ (jspb.Message.getField(message, 2));
|
||||
if (f != null) {
|
||||
writer.writeBytes(
|
||||
2,
|
||||
f
|
||||
);
|
||||
}
|
||||
f = message.getResult();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
3,
|
||||
f,
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -926,7 +990,25 @@ proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.getOutStream_asU8 = fu
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.setOutStream = function(value) {
|
||||
return jspb.Message.setProto3BytesField(this, 1, value);
|
||||
return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_[0], value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.clearOutStream = function() {
|
||||
return jspb.Message.setOneofField(this, 1, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_[0], undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.hasOutStream = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
@ -968,7 +1050,213 @@ proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.getErrStream_asU8 = fu
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.setErrStream = function(value) {
|
||||
return jspb.Message.setProto3BytesField(this, 2, value);
|
||||
return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_[0], value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.clearErrStream = function() {
|
||||
return jspb.Message.setOneofField(this, 2, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_[0], undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.hasErrStream = function() {
|
||||
return jspb.Message.getField(this, 2) != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional UploadResult result = 3;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.UploadResult}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.getResult = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.UploadResult} */ (
|
||||
jspb.Message.getWrapperField(this, proto.cc.arduino.cli.commands.v1.UploadResult, 3));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.UploadResult|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.setResult = function(value) {
|
||||
return jspb.Message.setOneofWrapperField(this, 3, proto.cc.arduino.cli.commands.v1.UploadResponse.oneofGroups_[0], value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResponse} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.clearResult = function() {
|
||||
return this.setResult(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResponse.prototype.hasResult = function() {
|
||||
return jspb.Message.getField(this, 3) != null;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.UploadResult.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.commands.v1.UploadResult.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.UploadResult} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
updatedUploadPort: (f = msg.getUpdatedUploadPort()) && cc_arduino_cli_commands_v1_port_pb.Port.toObject(includeInstance, f)
|
||||
};
|
||||
|
||||
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.UploadResult}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.commands.v1.UploadResult;
|
||||
return proto.cc.arduino.cli.commands.v1.UploadResult.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.UploadResult} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResult}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = new cc_arduino_cli_commands_v1_port_pb.Port;
|
||||
reader.readMessage(value,cc_arduino_cli_commands_v1_port_pb.Port.deserializeBinaryFromReader);
|
||||
msg.setUpdatedUploadPort(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.UploadResult.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.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.UploadResult} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getUpdatedUploadPort();
|
||||
if (f != null) {
|
||||
writer.writeMessage(
|
||||
1,
|
||||
f,
|
||||
cc_arduino_cli_commands_v1_port_pb.Port.serializeBinaryToWriter
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional Port updated_upload_port = 1;
|
||||
* @return {?proto.cc.arduino.cli.commands.v1.Port}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.prototype.getUpdatedUploadPort = function() {
|
||||
return /** @type{?proto.cc.arduino.cli.commands.v1.Port} */ (
|
||||
jspb.Message.getWrapperField(this, cc_arduino_cli_commands_v1_port_pb.Port, 1));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?proto.cc.arduino.cli.commands.v1.Port|undefined} value
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResult} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.prototype.setUpdatedUploadPort = function(value) {
|
||||
return jspb.Message.setWrapperField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the message field making it undefined.
|
||||
* @return {!proto.cc.arduino.cli.commands.v1.UploadResult} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.prototype.clearUpdatedUploadPort = function() {
|
||||
return this.setUpdatedUploadPort(undefined);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether this field is set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
proto.cc.arduino.cli.commands.v1.UploadResult.prototype.hasUpdatedUploadPort = function() {
|
||||
return jspb.Message.getField(this, 1) != null;
|
||||
};
|
||||
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import * as grpc from "@grpc/grpc-js";
|
||||
import {handleClientStreamingCall} from "@grpc/grpc-js/build/src/server-call";
|
||||
import * as cc_arduino_cli_debug_v1_debug_pb from "../../../../../cc/arduino/cli/debug/v1/debug_pb";
|
||||
import * as cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino/cli/commands/v1/common_pb";
|
||||
import * as cc_arduino_cli_commands_v1_port_pb from "../../../../../cc/arduino/cli/commands/v1/port_pb";
|
||||
@ -36,7 +35,7 @@ interface IDebugServiceService_IGetDebugConfig extends grpc.MethodDefinition<cc_
|
||||
|
||||
export const DebugServiceService: IDebugServiceService;
|
||||
|
||||
export interface IDebugServiceServer {
|
||||
export interface IDebugServiceServer extends grpc.UntypedServiceImplementation {
|
||||
debug: grpc.handleBidiStreamingCall<cc_arduino_cli_debug_v1_debug_pb.DebugRequest, cc_arduino_cli_debug_v1_debug_pb.DebugResponse>;
|
||||
getDebugConfig: grpc.handleUnaryCall<cc_arduino_cli_debug_v1_debug_pb.DebugConfigRequest, cc_arduino_cli_debug_v1_debug_pb.GetDebugConfigResponse>;
|
||||
}
|
||||
|
@ -14,16 +14,13 @@ export class DebugRequest extends jspb.Message {
|
||||
clearDebugRequest(): void;
|
||||
getDebugRequest(): DebugConfigRequest | undefined;
|
||||
setDebugRequest(value?: DebugConfigRequest): DebugRequest;
|
||||
|
||||
getData(): Uint8Array | string;
|
||||
getData_asU8(): Uint8Array;
|
||||
getData_asB64(): string;
|
||||
setData(value: Uint8Array | string): DebugRequest;
|
||||
|
||||
getSendInterrupt(): boolean;
|
||||
setSendInterrupt(value: boolean): DebugRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DebugRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DebugRequest): DebugRequest.AsObject;
|
||||
@ -48,29 +45,22 @@ export class DebugConfigRequest extends jspb.Message {
|
||||
clearInstance(): void;
|
||||
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
|
||||
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): DebugConfigRequest;
|
||||
|
||||
getFqbn(): string;
|
||||
setFqbn(value: string): DebugConfigRequest;
|
||||
|
||||
getSketchPath(): string;
|
||||
setSketchPath(value: string): DebugConfigRequest;
|
||||
|
||||
|
||||
hasPort(): boolean;
|
||||
clearPort(): void;
|
||||
getPort(): cc_arduino_cli_commands_v1_port_pb.Port | undefined;
|
||||
setPort(value?: cc_arduino_cli_commands_v1_port_pb.Port): DebugConfigRequest;
|
||||
|
||||
getInterpreter(): string;
|
||||
setInterpreter(value: string): DebugConfigRequest;
|
||||
|
||||
getImportDir(): string;
|
||||
setImportDir(value: string): DebugConfigRequest;
|
||||
|
||||
getProgrammer(): string;
|
||||
setProgrammer(value: string): DebugConfigRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DebugConfigRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DebugConfigRequest): DebugConfigRequest.AsObject;
|
||||
@ -98,11 +88,9 @@ export class DebugResponse extends jspb.Message {
|
||||
getData_asU8(): Uint8Array;
|
||||
getData_asB64(): string;
|
||||
setData(value: Uint8Array | string): DebugResponse;
|
||||
|
||||
getError(): string;
|
||||
setError(value: string): DebugResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DebugResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DebugResponse): DebugResponse.AsObject;
|
||||
@ -123,31 +111,23 @@ export namespace DebugResponse {
|
||||
export class GetDebugConfigResponse extends jspb.Message {
|
||||
getExecutable(): string;
|
||||
setExecutable(value: string): GetDebugConfigResponse;
|
||||
|
||||
getToolchain(): string;
|
||||
setToolchain(value: string): GetDebugConfigResponse;
|
||||
|
||||
getToolchainPath(): string;
|
||||
setToolchainPath(value: string): GetDebugConfigResponse;
|
||||
|
||||
getToolchainPrefix(): string;
|
||||
setToolchainPrefix(value: string): GetDebugConfigResponse;
|
||||
|
||||
getServer(): string;
|
||||
setServer(value: string): GetDebugConfigResponse;
|
||||
|
||||
getServerPath(): string;
|
||||
setServerPath(value: string): GetDebugConfigResponse;
|
||||
|
||||
|
||||
getToolchainConfigurationMap(): jspb.Map<string, string>;
|
||||
clearToolchainConfigurationMap(): void;
|
||||
|
||||
|
||||
getServerConfigurationMap(): jspb.Map<string, string>;
|
||||
clearServerConfigurationMap(): void;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetDebugConfigResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetDebugConfigResponse): GetDebugConfigResponse.AsObject;
|
||||
|
@ -5,7 +5,6 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import * as grpc from "@grpc/grpc-js";
|
||||
import {handleClientStreamingCall} from "@grpc/grpc-js/build/src/server-call";
|
||||
import * as cc_arduino_cli_settings_v1_settings_pb from "../../../../../cc/arduino/cli/settings/v1/settings_pb";
|
||||
|
||||
interface ISettingsServiceService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
|
||||
@ -14,6 +13,7 @@ interface ISettingsServiceService extends grpc.ServiceDefinition<grpc.UntypedSer
|
||||
getValue: ISettingsServiceService_IGetValue;
|
||||
setValue: ISettingsServiceService_ISetValue;
|
||||
write: ISettingsServiceService_IWrite;
|
||||
delete: ISettingsServiceService_IDelete;
|
||||
}
|
||||
|
||||
interface ISettingsServiceService_IGetAll extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, cc_arduino_cli_settings_v1_settings_pb.GetAllResponse> {
|
||||
@ -61,15 +61,25 @@ interface ISettingsServiceService_IWrite extends grpc.MethodDefinition<cc_arduin
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.WriteResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.WriteResponse>;
|
||||
}
|
||||
interface ISettingsServiceService_IDelete extends grpc.MethodDefinition<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, cc_arduino_cli_settings_v1_settings_pb.DeleteResponse> {
|
||||
path: "/cc.arduino.cli.settings.v1.SettingsService/Delete";
|
||||
requestStream: false;
|
||||
responseStream: false;
|
||||
requestSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest>;
|
||||
requestDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest>;
|
||||
responseSerialize: grpc.serialize<cc_arduino_cli_settings_v1_settings_pb.DeleteResponse>;
|
||||
responseDeserialize: grpc.deserialize<cc_arduino_cli_settings_v1_settings_pb.DeleteResponse>;
|
||||
}
|
||||
|
||||
export const SettingsServiceService: ISettingsServiceService;
|
||||
|
||||
export interface ISettingsServiceServer {
|
||||
export interface ISettingsServiceServer extends grpc.UntypedServiceImplementation {
|
||||
getAll: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.GetAllRequest, cc_arduino_cli_settings_v1_settings_pb.GetAllResponse>;
|
||||
merge: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.MergeRequest, cc_arduino_cli_settings_v1_settings_pb.MergeResponse>;
|
||||
getValue: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.GetValueRequest, cc_arduino_cli_settings_v1_settings_pb.GetValueResponse>;
|
||||
setValue: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.SetValueRequest, cc_arduino_cli_settings_v1_settings_pb.SetValueResponse>;
|
||||
write: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.WriteRequest, cc_arduino_cli_settings_v1_settings_pb.WriteResponse>;
|
||||
delete: grpc.handleUnaryCall<cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, cc_arduino_cli_settings_v1_settings_pb.DeleteResponse>;
|
||||
}
|
||||
|
||||
export interface ISettingsServiceClient {
|
||||
@ -88,6 +98,9 @@ export interface ISettingsServiceClient {
|
||||
write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
|
||||
write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
|
||||
write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
|
||||
delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
|
||||
delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
|
||||
delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
|
||||
}
|
||||
|
||||
export class SettingsServiceClient extends grpc.Client implements ISettingsServiceClient {
|
||||
@ -107,4 +120,7 @@ export class SettingsServiceClient extends grpc.Client implements ISettingsServi
|
||||
public write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
|
||||
public write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
|
||||
public write(request: cc_arduino_cli_settings_v1_settings_pb.WriteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.WriteResponse) => void): grpc.ClientUnaryCall;
|
||||
public delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
|
||||
public delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
|
||||
public delete(request: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse) => void): grpc.ClientUnaryCall;
|
||||
}
|
||||
|
@ -19,6 +19,28 @@
|
||||
'use strict';
|
||||
var cc_arduino_cli_settings_v1_settings_pb = require('../../../../../cc/arduino/cli/settings/v1/settings_pb.js');
|
||||
|
||||
function serialize_cc_arduino_cli_settings_v1_DeleteRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.DeleteRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.settings.v1.DeleteRequest');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_settings_v1_DeleteRequest(buffer_arg) {
|
||||
return cc_arduino_cli_settings_v1_settings_pb.DeleteRequest.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_settings_v1_DeleteResponse(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.DeleteResponse)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.settings.v1.DeleteResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_cc_arduino_cli_settings_v1_DeleteResponse(buffer_arg) {
|
||||
return cc_arduino_cli_settings_v1_settings_pb.DeleteResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_cc_arduino_cli_settings_v1_GetAllRequest(arg) {
|
||||
if (!(arg instanceof cc_arduino_cli_settings_v1_settings_pb.GetAllRequest)) {
|
||||
throw new Error('Expected argument of type cc.arduino.cli.settings.v1.GetAllRequest');
|
||||
@ -193,5 +215,17 @@ write: {
|
||||
responseSerialize: serialize_cc_arduino_cli_settings_v1_WriteResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_settings_v1_WriteResponse,
|
||||
},
|
||||
// Deletes an entry and rewrites the file settings
|
||||
delete: {
|
||||
path: '/cc.arduino.cli.settings.v1.SettingsService/Delete',
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: cc_arduino_cli_settings_v1_settings_pb.DeleteRequest,
|
||||
responseType: cc_arduino_cli_settings_v1_settings_pb.DeleteResponse,
|
||||
requestSerialize: serialize_cc_arduino_cli_settings_v1_DeleteRequest,
|
||||
requestDeserialize: deserialize_cc_arduino_cli_settings_v1_DeleteRequest,
|
||||
responseSerialize: serialize_cc_arduino_cli_settings_v1_DeleteResponse,
|
||||
responseDeserialize: deserialize_cc_arduino_cli_settings_v1_DeleteResponse,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,6 @@ export class GetAllResponse extends jspb.Message {
|
||||
getJsonData(): string;
|
||||
setJsonData(value: string): GetAllResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetAllResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetAllResponse): GetAllResponse.AsObject;
|
||||
@ -31,7 +30,6 @@ export class MergeRequest extends jspb.Message {
|
||||
getJsonData(): string;
|
||||
setJsonData(value: string): MergeRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): MergeRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: MergeRequest): MergeRequest.AsObject;
|
||||
@ -51,11 +49,9 @@ export namespace MergeRequest {
|
||||
export class GetValueResponse extends jspb.Message {
|
||||
getKey(): string;
|
||||
setKey(value: string): GetValueResponse;
|
||||
|
||||
getJsonData(): string;
|
||||
setJsonData(value: string): GetValueResponse;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetValueResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetValueResponse): GetValueResponse.AsObject;
|
||||
@ -76,11 +72,9 @@ export namespace GetValueResponse {
|
||||
export class SetValueRequest extends jspb.Message {
|
||||
getKey(): string;
|
||||
setKey(value: string): SetValueRequest;
|
||||
|
||||
getJsonData(): string;
|
||||
setJsonData(value: string): SetValueRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SetValueRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SetValueRequest): SetValueRequest.AsObject;
|
||||
@ -119,7 +113,6 @@ export class GetValueRequest extends jspb.Message {
|
||||
getKey(): string;
|
||||
setKey(value: string): GetValueRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetValueRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetValueRequest): GetValueRequest.AsObject;
|
||||
@ -174,7 +167,6 @@ export class WriteRequest extends jspb.Message {
|
||||
getFilePath(): string;
|
||||
setFilePath(value: string): WriteRequest;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): WriteRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: WriteRequest): WriteRequest.AsObject;
|
||||
@ -207,3 +199,40 @@ export namespace WriteResponse {
|
||||
export type AsObject = {
|
||||
}
|
||||
}
|
||||
|
||||
export class DeleteRequest extends jspb.Message {
|
||||
getKey(): string;
|
||||
setKey(value: string): DeleteRequest;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DeleteRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DeleteRequest): DeleteRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: DeleteRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): DeleteRequest;
|
||||
static deserializeBinaryFromReader(message: DeleteRequest, reader: jspb.BinaryReader): DeleteRequest;
|
||||
}
|
||||
|
||||
export namespace DeleteRequest {
|
||||
export type AsObject = {
|
||||
key: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class DeleteResponse extends jspb.Message {
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): DeleteResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: DeleteResponse): DeleteResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: DeleteResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): DeleteResponse;
|
||||
static deserializeBinaryFromReader(message: DeleteResponse, reader: jspb.BinaryReader): DeleteResponse;
|
||||
}
|
||||
|
||||
export namespace DeleteResponse {
|
||||
export type AsObject = {
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ var global = (function() {
|
||||
return Function('return this')();
|
||||
}.call(null));
|
||||
|
||||
goog.exportSymbol('proto.cc.arduino.cli.settings.v1.DeleteRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.settings.v1.DeleteResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetAllRequest', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetAllResponse', null, global);
|
||||
goog.exportSymbol('proto.cc.arduino.cli.settings.v1.GetValueRequest', null, global);
|
||||
@ -241,6 +243,48 @@ if (goog.DEBUG && !COMPILED) {
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.WriteResponse.displayName = 'proto.cc.arduino.cli.settings.v1.WriteResponse';
|
||||
}
|
||||
/**
|
||||
* 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.settings.v1.DeleteRequest = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.settings.v1.DeleteRequest, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.displayName = 'proto.cc.arduino.cli.settings.v1.DeleteRequest';
|
||||
}
|
||||
/**
|
||||
* 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.settings.v1.DeleteResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.cc.arduino.cli.settings.v1.DeleteResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.displayName = 'proto.cc.arduino.cli.settings.v1.DeleteResponse';
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1485,4 +1529,235 @@ proto.cc.arduino.cli.settings.v1.WriteResponse.serializeBinaryToWriter = functio
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.settings.v1.DeleteRequest.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.settings.v1.DeleteRequest.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.settings.v1.DeleteRequest} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
key: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
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.settings.v1.DeleteRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.settings.v1.DeleteRequest;
|
||||
return proto.cc.arduino.cli.settings.v1.DeleteRequest.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.settings.v1.DeleteRequest} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.settings.v1.DeleteRequest}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.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.setKey(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.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.settings.v1.DeleteRequest} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getKey();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string key = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.getKey = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.cc.arduino.cli.settings.v1.DeleteRequest} returns this
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteRequest.prototype.setKey = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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.settings.v1.DeleteResponse.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.cc.arduino.cli.settings.v1.DeleteResponse.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.settings.v1.DeleteResponse} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
|
||||
};
|
||||
|
||||
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.settings.v1.DeleteResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.cc.arduino.cli.settings.v1.DeleteResponse;
|
||||
return proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.cc.arduino.cli.settings.v1.DeleteResponse} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.cc.arduino.cli.settings.v1.DeleteResponse}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.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.settings.v1.DeleteResponse} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.cc.arduino.cli.settings.v1.DeleteResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.cc.arduino.cli.settings.v1);
|
||||
|
@ -10,16 +10,13 @@ import * as google_protobuf_any_pb from "google-protobuf/google/protobuf/any_pb"
|
||||
export class Status extends jspb.Message {
|
||||
getCode(): number;
|
||||
setCode(value: number): Status;
|
||||
|
||||
getMessage(): string;
|
||||
setMessage(value: string): Status;
|
||||
|
||||
clearDetailsList(): void;
|
||||
getDetailsList(): Array<google_protobuf_any_pb.Any>;
|
||||
setDetailsList(value: Array<google_protobuf_any_pb.Any>): Status;
|
||||
addDetails(value?: google_protobuf_any_pb.Any, index?: number): google_protobuf_any_pb.Any;
|
||||
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Status.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Status): Status.AsObject;
|
||||
|
@ -3,13 +3,14 @@ import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { relative } from 'node:path';
|
||||
import * as jspb from 'google-protobuf';
|
||||
import { BoolValue } from 'google-protobuf/google/protobuf/wrappers_pb';
|
||||
import { ClientReadableStream } from '@grpc/grpc-js';
|
||||
import type { ClientReadableStream } from '@grpc/grpc-js';
|
||||
import {
|
||||
CompilerWarnings,
|
||||
CoreService,
|
||||
CoreError,
|
||||
CompileSummary,
|
||||
isCompileSummary,
|
||||
isUploadResponse,
|
||||
} from '../common/protocol/core-service';
|
||||
import {
|
||||
CompileRequest,
|
||||
@ -25,7 +26,13 @@ import {
|
||||
UploadUsingProgrammerResponse,
|
||||
} from './cli-protocol/cc/arduino/cli/commands/v1/upload_pb';
|
||||
import { ResponseService } from '../common/protocol/response-service';
|
||||
import { OutputMessage, Port } from '../common/protocol';
|
||||
import {
|
||||
resolveDetectedPort,
|
||||
OutputMessage,
|
||||
PortIdentifier,
|
||||
Port,
|
||||
UploadResponse as ApiUploadResponse,
|
||||
} from '../common/protocol';
|
||||
import { ArduinoCoreServiceClient } from './cli-protocol/cc/arduino/cli/commands/v1/commands_grpc_pb';
|
||||
import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import { ApplicationError, CommandService, Disposable, nls } from '@theia/core';
|
||||
@ -36,8 +43,8 @@ import { Instance } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
|
||||
import { firstToUpperCase, notEmpty } from '../common/utils';
|
||||
import { ServiceError } from './service-error';
|
||||
import { ExecuteWithProgress, ProgressResponse } from './grpc-progressible';
|
||||
import { BoardDiscovery } from './board-discovery';
|
||||
import { Mutable } from '@theia/core/lib/common/types';
|
||||
import type { Mutable } from '@theia/core/lib/common/types';
|
||||
import { BoardDiscovery, createApiPort } from './board-discovery';
|
||||
|
||||
namespace Uploadable {
|
||||
export type Request = UploadRequest | UploadUsingProgrammerRequest;
|
||||
@ -50,13 +57,10 @@ type CompileSummaryFragment = Partial<Mutable<CompileSummary>>;
|
||||
export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
@inject(ResponseService)
|
||||
private readonly responseService: ResponseService;
|
||||
|
||||
@inject(MonitorManager)
|
||||
private readonly monitorManager: MonitorManager;
|
||||
|
||||
@inject(CommandService)
|
||||
private readonly commandService: CommandService;
|
||||
|
||||
@inject(BoardDiscovery)
|
||||
private readonly boardDiscovery: BoardDiscovery;
|
||||
|
||||
@ -172,7 +176,7 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
return request;
|
||||
}
|
||||
|
||||
upload(options: CoreService.Options.Upload): Promise<void> {
|
||||
upload(options: CoreService.Options.Upload): Promise<ApiUploadResponse> {
|
||||
const { usingProgrammer } = options;
|
||||
return this.doUpload(
|
||||
options,
|
||||
@ -201,14 +205,45 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
) => (request: REQ) => ClientReadableStream<RESP>,
|
||||
errorCtor: ApplicationError.Constructor<number, CoreError.ErrorLocation[]>,
|
||||
task: string
|
||||
): Promise<void> {
|
||||
): Promise<ApiUploadResponse> {
|
||||
const portBeforeUpload = options.port;
|
||||
const uploadResponseFragment: Mutable<Partial<ApiUploadResponse>> = {
|
||||
portAfterUpload: options.port, // assume no port changes during the upload
|
||||
};
|
||||
const coreClient = await this.coreClient;
|
||||
const { client, instance } = coreClient;
|
||||
const progressHandler = this.createProgressHandler(options);
|
||||
const handler = this.createOnDataHandler(progressHandler);
|
||||
// Track responses for port changes. No port changes are expected when uploading using a programmer.
|
||||
const updateUploadResponseFragmentHandler = (response: RESP) => {
|
||||
if (response instanceof UploadResponse) {
|
||||
// TODO: this instanceof should not be here but in `upload`. the upload and upload using programmer gRPC APIs are not symmetric
|
||||
const uploadResult = response.getResult();
|
||||
if (uploadResult) {
|
||||
const port = uploadResult.getUpdatedUploadPort();
|
||||
if (port) {
|
||||
uploadResponseFragment.portAfterUpload = createApiPort(port);
|
||||
console.info(
|
||||
`Received port after upload [${
|
||||
options.port ? Port.keyOf(options.port) : ''
|
||||
}, ${options.fqbn}, ${
|
||||
options.sketch.name
|
||||
}]. Before port: ${JSON.stringify(
|
||||
portBeforeUpload
|
||||
)}, after port: ${JSON.stringify(
|
||||
uploadResponseFragment.portAfterUpload
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const handler = this.createOnDataHandler(
|
||||
progressHandler,
|
||||
updateUploadResponseFragmentHandler
|
||||
);
|
||||
const grpcCall = responseFactory(client);
|
||||
return this.notifyUploadWillStart(options).then(() =>
|
||||
new Promise<void>((resolve, reject) => {
|
||||
new Promise<ApiUploadResponse>((resolve, reject) => {
|
||||
grpcCall(this.initUploadRequest(request, options, instance))
|
||||
.on('data', handler.onData)
|
||||
.on('error', (error) => {
|
||||
@ -234,10 +269,28 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
);
|
||||
}
|
||||
})
|
||||
.on('end', resolve);
|
||||
.on('end', () => {
|
||||
if (isUploadResponse(uploadResponseFragment)) {
|
||||
resolve(uploadResponseFragment);
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
`Could not detect the port after the upload. Upload options were: ${JSON.stringify(
|
||||
options
|
||||
)}, upload response was: ${JSON.stringify(
|
||||
uploadResponseFragment
|
||||
)}`
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
}).finally(async () => {
|
||||
handler.dispose();
|
||||
await this.notifyUploadDidFinish(options);
|
||||
await this.notifyUploadDidFinish(
|
||||
Object.assign(options, {
|
||||
afterPort: uploadResponseFragment.portAfterUpload,
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -302,7 +355,9 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
.on('end', resolve);
|
||||
}).finally(async () => {
|
||||
handler.dispose();
|
||||
await this.notifyUploadDidFinish(options);
|
||||
await this.notifyUploadDidFinish(
|
||||
Object.assign(options, { afterPort: options.port })
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -379,21 +434,25 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
port,
|
||||
}: {
|
||||
fqbn?: string | undefined;
|
||||
port?: Port | undefined;
|
||||
port?: PortIdentifier;
|
||||
}): Promise<void> {
|
||||
this.boardDiscovery.setUploadInProgress(true);
|
||||
return this.monitorManager.notifyUploadStarted(fqbn, port);
|
||||
if (fqbn && port) {
|
||||
return this.monitorManager.notifyUploadStarted(fqbn, port);
|
||||
}
|
||||
}
|
||||
|
||||
private async notifyUploadDidFinish({
|
||||
fqbn,
|
||||
port,
|
||||
afterPort,
|
||||
}: {
|
||||
fqbn?: string | undefined;
|
||||
port?: Port | undefined;
|
||||
port?: PortIdentifier;
|
||||
afterPort?: PortIdentifier;
|
||||
}): Promise<void> {
|
||||
this.boardDiscovery.setUploadInProgress(false);
|
||||
return this.monitorManager.notifyUploadFinished(fqbn, port);
|
||||
if (fqbn && port && afterPort) {
|
||||
return this.monitorManager.notifyUploadFinished(fqbn, port, afterPort);
|
||||
}
|
||||
}
|
||||
|
||||
private mergeSourceOverrides(
|
||||
@ -410,21 +469,28 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
|
||||
}
|
||||
}
|
||||
|
||||
private createPort(port: Port | undefined): RpcPort | undefined {
|
||||
private createPort(
|
||||
port: PortIdentifier | undefined,
|
||||
resolve: (port: PortIdentifier) => Port | undefined = (port) =>
|
||||
resolveDetectedPort(port, this.boardDiscovery.detectedPorts)
|
||||
): RpcPort | undefined {
|
||||
if (!port) {
|
||||
return undefined;
|
||||
}
|
||||
const resolvedPort = resolve(port);
|
||||
const rpcPort = new RpcPort();
|
||||
rpcPort.setAddress(port.address);
|
||||
rpcPort.setLabel(port.addressLabel);
|
||||
rpcPort.setProtocol(port.protocol);
|
||||
rpcPort.setProtocolLabel(port.protocolLabel);
|
||||
if (port.hardwareId !== undefined) {
|
||||
rpcPort.setHardwareId(port.hardwareId);
|
||||
}
|
||||
if (port.properties) {
|
||||
for (const [key, value] of Object.entries(port.properties)) {
|
||||
rpcPort.getPropertiesMap().set(key, value);
|
||||
rpcPort.setAddress(port.address);
|
||||
if (resolvedPort) {
|
||||
rpcPort.setLabel(resolvedPort.addressLabel);
|
||||
rpcPort.setProtocolLabel(resolvedPort.protocolLabel);
|
||||
if (resolvedPort.hardwareId !== undefined) {
|
||||
rpcPort.setHardwareId(resolvedPort.hardwareId);
|
||||
}
|
||||
if (resolvedPort.properties) {
|
||||
for (const [key, value] of Object.entries(resolvedPort.properties)) {
|
||||
rpcPort.getPropertiesMap().set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rpcPort;
|
||||
|
@ -7,6 +7,8 @@ import {
|
||||
MonitorSettings,
|
||||
PluggableMonitorSettings,
|
||||
Port,
|
||||
PortIdentifier,
|
||||
portIdentifierEquals,
|
||||
} from '../common/protocol';
|
||||
import { CoreClientAware } from './core-client-provider';
|
||||
import { MonitorService } from './monitor-service';
|
||||
@ -180,13 +182,7 @@ export class MonitorManager extends CoreClientAware {
|
||||
* @param fqbn the FQBN of the board connected to port
|
||||
* @param port port to monitor
|
||||
*/
|
||||
async notifyUploadStarted(fqbn?: string, port?: Port): Promise<void> {
|
||||
if (!fqbn || !port) {
|
||||
// We have no way of knowing which monitor
|
||||
// to retrieve if we don't have this information.
|
||||
return;
|
||||
}
|
||||
|
||||
async notifyUploadStarted(fqbn: string, port: PortIdentifier): Promise<void> {
|
||||
const monitorID = this.monitorID(fqbn, port);
|
||||
this.addToMonitorIDsByUploadState('uploadInProgress', monitorID);
|
||||
|
||||
@ -204,41 +200,44 @@ export class MonitorManager extends CoreClientAware {
|
||||
* Notifies the monitor service of that board/port combination
|
||||
* that an upload process started on that exact board/port combination.
|
||||
* @param fqbn the FQBN of the board connected to port
|
||||
* @param port port to monitor
|
||||
* @param beforePort port to monitor
|
||||
* @returns a Status object to know if the process has been
|
||||
* started or if there have been errors.
|
||||
*/
|
||||
async notifyUploadFinished(
|
||||
fqbn?: string | undefined,
|
||||
port?: Port
|
||||
fqbn: string | undefined,
|
||||
beforePort: PortIdentifier,
|
||||
afterPort: PortIdentifier
|
||||
): Promise<void> {
|
||||
let portDidChangeOnUpload = false;
|
||||
const beforeMonitorID = this.monitorID(fqbn, beforePort);
|
||||
this.removeFromMonitorIDsByUploadState('uploadInProgress', beforeMonitorID);
|
||||
|
||||
// We have no way of knowing which monitor
|
||||
// to retrieve if we don't have this information.
|
||||
if (fqbn && port) {
|
||||
const monitorID = this.monitorID(fqbn, port);
|
||||
this.removeFromMonitorIDsByUploadState('uploadInProgress', monitorID);
|
||||
|
||||
const monitor = this.monitorServices.get(monitorID);
|
||||
if (monitor) {
|
||||
const monitor = this.monitorServices.get(beforeMonitorID);
|
||||
if (monitor) {
|
||||
if (portIdentifierEquals(beforePort, afterPort)) {
|
||||
await monitor.start();
|
||||
} else {
|
||||
await monitor.stop();
|
||||
}
|
||||
|
||||
// this monitorID will only be present in "disposedForUpload"
|
||||
// if the upload changed the board port
|
||||
portDidChangeOnUpload = this.monitorIDIsInUploadState(
|
||||
'disposedForUpload',
|
||||
monitorID
|
||||
);
|
||||
if (portDidChangeOnUpload) {
|
||||
this.removeFromMonitorIDsByUploadState('disposedForUpload', monitorID);
|
||||
}
|
||||
|
||||
// in case a service was paused but not disposed
|
||||
this.removeFromMonitorIDsByUploadState('pausedForUpload', monitorID);
|
||||
}
|
||||
|
||||
// this monitorID will only be present in "disposedForUpload"
|
||||
// if the upload changed the board port
|
||||
portDidChangeOnUpload = this.monitorIDIsInUploadState(
|
||||
'disposedForUpload',
|
||||
beforeMonitorID
|
||||
);
|
||||
if (portDidChangeOnUpload) {
|
||||
this.removeFromMonitorIDsByUploadState(
|
||||
'disposedForUpload',
|
||||
beforeMonitorID
|
||||
);
|
||||
}
|
||||
|
||||
// in case a service was paused but not disposed
|
||||
this.removeFromMonitorIDsByUploadState('pausedForUpload', beforeMonitorID);
|
||||
|
||||
await this.startQueuedServices(portDidChangeOnUpload);
|
||||
}
|
||||
|
||||
@ -256,7 +255,7 @@ export class MonitorManager extends CoreClientAware {
|
||||
serviceStartParams: [, port],
|
||||
connectToClient,
|
||||
} of queued) {
|
||||
const boardsState = await this.boardsService.getState();
|
||||
const boardsState = await this.boardsService.getDetectedPorts();
|
||||
const boardIsStillOnPort = Object.keys(boardsState)
|
||||
.map((connection: string) => {
|
||||
const portAddress = connection.split('|')[0];
|
||||
@ -355,7 +354,7 @@ export class MonitorManager extends CoreClientAware {
|
||||
* @param port
|
||||
* @returns a unique monitor ID
|
||||
*/
|
||||
private monitorID(fqbn: string | undefined, port: Port): MonitorID {
|
||||
private monitorID(fqbn: string | undefined, port: PortIdentifier): MonitorID {
|
||||
const splitFqbn = fqbn?.split(':') || [];
|
||||
const shortenedFqbn = splitFqbn.slice(0, 3).join(':') || '';
|
||||
return `${shortenedFqbn}-${port.address}-${port.protocol}`;
|
||||
|
@ -2,7 +2,6 @@ import { injectable } from '@theia/core/shared/inversify';
|
||||
import type {
|
||||
NotificationServiceServer,
|
||||
NotificationServiceClient,
|
||||
AttachedBoardsChangeEvent,
|
||||
BoardsPackage,
|
||||
LibraryPackage,
|
||||
ConfigState,
|
||||
@ -11,6 +10,7 @@ import type {
|
||||
IndexUpdateWillStartParams,
|
||||
IndexUpdateDidCompleteParams,
|
||||
IndexUpdateDidFailParams,
|
||||
DetectedPorts,
|
||||
} from '../common/protocol';
|
||||
|
||||
@injectable()
|
||||
@ -69,9 +69,9 @@ export class NotificationServiceServerImpl
|
||||
this.clients.forEach((client) => client.notifyLibraryDidUninstall(event));
|
||||
}
|
||||
|
||||
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void {
|
||||
notifyDetectedPortsDidChange(event: { detectedPorts: DetectedPorts }): void {
|
||||
this.clients.forEach((client) =>
|
||||
client.notifyAttachedBoardsDidChange(event)
|
||||
client.notifyDetectedPortsDidChange(event)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ import path from 'node:path';
|
||||
import glob from 'glob';
|
||||
import crypto from 'node:crypto';
|
||||
import PQueue from 'p-queue';
|
||||
import { Mutable } from '@theia/core/lib/common/types';
|
||||
import type { Mutable } from '@theia/core/lib/common/types';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ILogger } from '@theia/core/lib/common/logger';
|
||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||
@ -128,11 +128,11 @@ export class SketchesServiceImpl
|
||||
uri: string,
|
||||
detectInvalidSketchNameError = true
|
||||
): Promise<SketchWithDetails> {
|
||||
const { client, instance } = await this.coreClient;
|
||||
const { client } = await this.coreClient;
|
||||
const req = new LoadSketchRequest();
|
||||
const requestSketchPath = FileUri.fsPath(uri);
|
||||
req.setSketchPath(requestSketchPath);
|
||||
req.setInstance(instance);
|
||||
// TODO: since the instance is not required on the request, can IDE2 do this faster or have a dedicated client for the sketch loading?
|
||||
const stat = new Deferred<Stats | Error>();
|
||||
lstat(requestSketchPath, (err, result) =>
|
||||
err ? stat.resolve(err) : stat.resolve(result)
|
||||
|
@ -0,0 +1,426 @@
|
||||
import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
||||
const disableJSDOM = enableJSDOM();
|
||||
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
FrontendApplicationConfigProvider.set({});
|
||||
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import {
|
||||
LocalStorageService,
|
||||
StorageService,
|
||||
} from '@theia/core/lib/browser/storage-service';
|
||||
import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { MessageService } from '@theia/core/lib/common/message-service';
|
||||
import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
|
||||
import { Container, ContainerModule } from '@theia/core/shared/inversify';
|
||||
import { expect } from 'chai';
|
||||
import { BoardsDataStore } from '../../browser/boards/boards-data-store';
|
||||
import { BoardsServiceProvider } from '../../browser/boards/boards-service-provider';
|
||||
import { NotificationCenter } from '../../browser/notification-center';
|
||||
import {
|
||||
BoardIdentifierChangeEvent,
|
||||
BoardsConfig,
|
||||
BoardsConfigChangeEvent,
|
||||
BoardsService,
|
||||
DetectedPorts,
|
||||
Port,
|
||||
PortIdentifierChangeEvent,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { NotificationServiceServer } from '../../common/protocol/notification-service';
|
||||
import { bindCommon, ConsoleLogger } from '../common/common-test-bindings';
|
||||
import {
|
||||
detectedPort,
|
||||
esp32S3DevModule,
|
||||
mkr1000,
|
||||
mkr1000SerialPort,
|
||||
undiscoveredSerialPort,
|
||||
uno,
|
||||
unoSerialPort,
|
||||
} from '../common/fixtures';
|
||||
|
||||
disableJSDOM();
|
||||
|
||||
describe('board-service-provider', () => {
|
||||
let toDisposeAfterEach: DisposableCollection;
|
||||
let boardsServiceProvider: BoardsServiceProvider;
|
||||
let notificationCenter: NotificationCenter;
|
||||
|
||||
beforeEach(async () => {
|
||||
const container = createContainer();
|
||||
container.get<FrontendApplicationStateService>(
|
||||
FrontendApplicationStateService
|
||||
).state = 'ready';
|
||||
boardsServiceProvider = container.get<BoardsServiceProvider>(
|
||||
BoardsServiceProvider
|
||||
);
|
||||
notificationCenter = container.get<NotificationCenter>(NotificationCenter);
|
||||
toDisposeAfterEach = new DisposableCollection(
|
||||
Disposable.create(() => boardsServiceProvider.onStop())
|
||||
);
|
||||
boardsServiceProvider.onStart();
|
||||
await boardsServiceProvider.ready;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
toDisposeAfterEach.dispose();
|
||||
});
|
||||
|
||||
it('should update the port (port identifier)', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig(mkr1000SerialPort);
|
||||
expect(didUpdate).to.be.true;
|
||||
const expectedEvent: PortIdentifierChangeEvent = {
|
||||
previousSelectedPort: unoSerialPort,
|
||||
selectedPort: mkr1000SerialPort,
|
||||
};
|
||||
expect(events).deep.equals([expectedEvent]);
|
||||
});
|
||||
|
||||
it('should update the port (boards config)', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig({
|
||||
selectedPort: mkr1000SerialPort,
|
||||
selectedBoard: uno,
|
||||
});
|
||||
expect(didUpdate).to.be.true;
|
||||
const expectedEvent: PortIdentifierChangeEvent = {
|
||||
previousSelectedPort: unoSerialPort,
|
||||
selectedPort: mkr1000SerialPort,
|
||||
};
|
||||
expect(events).deep.equals([expectedEvent]);
|
||||
});
|
||||
|
||||
it('should not update the port if did not change (port identifier)', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig(unoSerialPort);
|
||||
expect(didUpdate).to.be.false;
|
||||
expect(events).to.be.empty;
|
||||
});
|
||||
|
||||
it('should update the board (board identifier)', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig(mkr1000);
|
||||
expect(didUpdate).to.be.true;
|
||||
const expectedEvent: BoardIdentifierChangeEvent = {
|
||||
previousSelectedBoard: uno,
|
||||
selectedBoard: mkr1000,
|
||||
};
|
||||
expect(events).deep.equals([expectedEvent]);
|
||||
});
|
||||
|
||||
it('should update the board (boards config)', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig({
|
||||
selectedBoard: mkr1000,
|
||||
selectedPort: unoSerialPort,
|
||||
});
|
||||
expect(didUpdate).to.be.true;
|
||||
const expectedEvent: BoardIdentifierChangeEvent = {
|
||||
previousSelectedBoard: uno,
|
||||
selectedBoard: mkr1000,
|
||||
};
|
||||
expect(events).deep.equals([expectedEvent]);
|
||||
});
|
||||
|
||||
it('should not update the board if did not change (board identifier)', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig(uno);
|
||||
expect(didUpdate).to.be.false;
|
||||
expect(events).to.be.empty;
|
||||
});
|
||||
|
||||
it('should update both the board and port', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig({
|
||||
selectedBoard: mkr1000,
|
||||
selectedPort: mkr1000SerialPort,
|
||||
});
|
||||
expect(didUpdate).to.be.true;
|
||||
const expectedEvent: BoardIdentifierChangeEvent &
|
||||
PortIdentifierChangeEvent = {
|
||||
previousSelectedBoard: uno,
|
||||
selectedBoard: mkr1000,
|
||||
previousSelectedPort: unoSerialPort,
|
||||
selectedPort: mkr1000SerialPort,
|
||||
};
|
||||
expect(events).deep.equals([expectedEvent]);
|
||||
});
|
||||
|
||||
it('should update neither the board nor the port if did not change', () => {
|
||||
boardsServiceProvider['_boardsConfig'] = {
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
};
|
||||
const events: BoardsConfigChangeEvent[] = [];
|
||||
toDisposeAfterEach.push(
|
||||
boardsServiceProvider.onBoardsConfigDidChange((event) =>
|
||||
events.push(event)
|
||||
)
|
||||
);
|
||||
const didUpdate = boardsServiceProvider.updateConfig({
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
});
|
||||
expect(didUpdate).to.be.false;
|
||||
expect(events).to.be.empty;
|
||||
});
|
||||
|
||||
it('should detect a port change and find selection index', () => {
|
||||
let boardList = boardsServiceProvider.boardList;
|
||||
const didUpdate = boardsServiceProvider.updateConfig({
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
});
|
||||
expect(didUpdate).to.be.true;
|
||||
expect(boardList.selectedIndex).to.be.equal(-1);
|
||||
let selectedItem = boardList.items[boardList.selectedIndex];
|
||||
expect(selectedItem).to.be.undefined;
|
||||
|
||||
// attach board
|
||||
notificationCenter.notifyDetectedPortsDidChange({
|
||||
detectedPorts: {
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
},
|
||||
});
|
||||
boardList = boardsServiceProvider.boardList;
|
||||
expect(boardsServiceProvider.boardList.selectedIndex).to.be.equal(0);
|
||||
selectedItem = boardList.items[boardList.selectedIndex];
|
||||
expect(selectedItem.board).to.be.deep.equal(uno);
|
||||
expect(selectedItem.port).to.be.deep.equal(unoSerialPort);
|
||||
|
||||
// detach board
|
||||
notificationCenter.notifyDetectedPortsDidChange({
|
||||
detectedPorts: {},
|
||||
});
|
||||
boardList = boardsServiceProvider.boardList;
|
||||
expect(boardsServiceProvider.boardList.selectedIndex).to.be.equal(-1);
|
||||
selectedItem = boardList.items[boardList.selectedIndex];
|
||||
expect(selectedItem).to.be.undefined;
|
||||
});
|
||||
|
||||
it('should update the board selection history for the port', () => {
|
||||
notificationCenter.notifyDetectedPortsDidChange({
|
||||
detectedPorts: {
|
||||
...detectedPort(undiscoveredSerialPort),
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
},
|
||||
});
|
||||
|
||||
boardsServiceProvider.updateConfig({
|
||||
selectedBoard: esp32S3DevModule,
|
||||
selectedPort: undiscoveredSerialPort,
|
||||
});
|
||||
|
||||
expect(boardsServiceProvider['_boardListHistory']).to.be.deep.equal({
|
||||
[Port.keyOf(undiscoveredSerialPort)]: esp32S3DevModule,
|
||||
});
|
||||
|
||||
boardsServiceProvider.updateConfig({
|
||||
selectedBoard: esp32S3DevModule,
|
||||
selectedPort: unoSerialPort,
|
||||
});
|
||||
|
||||
expect(boardsServiceProvider['_boardListHistory']).to.be.deep.equal({
|
||||
[Port.keyOf(undiscoveredSerialPort)]: esp32S3DevModule,
|
||||
[Port.keyOf(unoSerialPort)]: esp32S3DevModule,
|
||||
});
|
||||
|
||||
boardsServiceProvider.updateConfig({
|
||||
selectedBoard: uno,
|
||||
selectedPort: unoSerialPort,
|
||||
});
|
||||
|
||||
expect(boardsServiceProvider['_boardListHistory']).to.be.deep.equal({
|
||||
[Port.keyOf(undiscoveredSerialPort)]: esp32S3DevModule,
|
||||
});
|
||||
});
|
||||
|
||||
type UpdateBoardListHistoryParams = Parameters<
|
||||
BoardsServiceProvider['maybeUpdateBoardListHistory']
|
||||
>[0];
|
||||
type BoardListHistoryUpdateResult = ReturnType<
|
||||
BoardsServiceProvider['maybeUpdateBoardListHistory']
|
||||
>;
|
||||
interface BoardListHistoryTestSuite {
|
||||
readonly init: BoardsConfig;
|
||||
readonly detectedPorts?: DetectedPorts;
|
||||
readonly params: UpdateBoardListHistoryParams;
|
||||
readonly expected: BoardListHistoryUpdateResult;
|
||||
/**
|
||||
* Optional test title extension.
|
||||
*/
|
||||
readonly description?: string;
|
||||
/**
|
||||
* Optional test assertions.
|
||||
*/
|
||||
readonly assert?: (
|
||||
actual: BoardListHistoryUpdateResult,
|
||||
service: BoardsServiceProvider
|
||||
) => void;
|
||||
}
|
||||
|
||||
const boardListHistoryTestSuites: BoardListHistoryTestSuite[] = [
|
||||
{
|
||||
description: "'portToSelect' is undefined",
|
||||
init: { selectedBoard: uno, selectedPort: unoSerialPort },
|
||||
params: { boardToSelect: mkr1000, portToSelect: undefined },
|
||||
expected: undefined,
|
||||
},
|
||||
{
|
||||
description: "'boardToSelect' is undefined",
|
||||
init: { selectedBoard: uno, selectedPort: unoSerialPort },
|
||||
params: { boardToSelect: undefined, portToSelect: mkr1000SerialPort },
|
||||
expected: undefined,
|
||||
},
|
||||
{
|
||||
description: "'selectedBoard' fallback when 'ignore-board'",
|
||||
init: { selectedBoard: uno, selectedPort: unoSerialPort },
|
||||
params: {
|
||||
boardToSelect: 'ignore-board',
|
||||
portToSelect: mkr1000SerialPort,
|
||||
},
|
||||
expected: { [Port.keyOf(mkr1000SerialPort)]: uno },
|
||||
},
|
||||
{
|
||||
description: "'selectedPort' fallback when 'ignore-port'",
|
||||
init: { selectedBoard: uno, selectedPort: unoSerialPort },
|
||||
params: {
|
||||
boardToSelect: mkr1000,
|
||||
portToSelect: 'ignore-port',
|
||||
},
|
||||
expected: { [Port.keyOf(unoSerialPort)]: mkr1000 },
|
||||
},
|
||||
{
|
||||
description:
|
||||
'unsets history when board+port is from a detected port from a discovered board',
|
||||
init: { selectedBoard: undefined, selectedPort: undefined },
|
||||
params: {
|
||||
boardToSelect: uno,
|
||||
portToSelect: unoSerialPort,
|
||||
},
|
||||
detectedPorts: {
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
},
|
||||
expected: { [Port.keyOf(unoSerialPort)]: undefined },
|
||||
},
|
||||
];
|
||||
boardListHistoryTestSuites.forEach((suite, index) =>
|
||||
it(`should handle board list history updates (${
|
||||
suite.description ? suite.description : `#${index + 1}`
|
||||
})`, () => {
|
||||
const { init, params, expected, assert, detectedPorts } = suite;
|
||||
boardsServiceProvider['_boardsConfig'] = init;
|
||||
if (detectedPorts) {
|
||||
notificationCenter.notifyDetectedPortsDidChange({ detectedPorts });
|
||||
}
|
||||
const actual =
|
||||
boardsServiceProvider['maybeUpdateBoardListHistory'](params);
|
||||
expect(actual).to.be.deep.equal(expected);
|
||||
assert?.(actual, boardsServiceProvider);
|
||||
})
|
||||
);
|
||||
|
||||
function createContainer(): Container {
|
||||
const container = new Container({ defaultScope: 'Singleton' });
|
||||
container.load(
|
||||
new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bindCommon(bind);
|
||||
bind(MessageService).toConstantValue(<MessageService>{});
|
||||
bind(BoardsService).toConstantValue(<BoardsService>{
|
||||
getDetectedPorts() {
|
||||
return {};
|
||||
},
|
||||
});
|
||||
bind(NotificationCenter).toSelf().inSingletonScope();
|
||||
bind(NotificationServiceServer).toConstantValue(<
|
||||
NotificationServiceServer
|
||||
>{
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
setClient(_) {
|
||||
// nothing
|
||||
},
|
||||
});
|
||||
bind(FrontendApplicationStateService).toSelf().inSingletonScope();
|
||||
bind(BoardsDataStore).toConstantValue(<BoardsDataStore>{});
|
||||
bind(LocalStorageService).toSelf().inSingletonScope();
|
||||
bind(WindowService).toConstantValue(<WindowService>{});
|
||||
bind(StorageService).toService(LocalStorageService);
|
||||
bind(BoardsServiceProvider).toSelf().inSingletonScope();
|
||||
// IDE2's test console logger does not support `Loggable` arg.
|
||||
// Rebind logger to suppress `[Function (anonymous)]` messages in tests when the storage service is initialized without `window.localStorage`.
|
||||
// https://github.com/eclipse-theia/theia/blob/04c8cf07843ea67402131132e033cdd54900c010/packages/core/src/browser/storage-service.ts#L60
|
||||
bind(MockLogger).toSelf().inSingletonScope();
|
||||
rebind(ConsoleLogger).toService(MockLogger);
|
||||
})
|
||||
);
|
||||
return container;
|
||||
}
|
||||
});
|
@ -1,247 +0,0 @@
|
||||
// import { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
||||
// const disableJSDOM = enableJSDOM();
|
||||
|
||||
// import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
// import { ApplicationProps } from '@theia/application-package/lib/application-props';
|
||||
// FrontendApplicationConfigProvider.set({
|
||||
// ...ApplicationProps.DEFAULT.frontend.config,
|
||||
// });
|
||||
|
||||
// import { MessageService } from '@theia/core';
|
||||
// import { BoardsServiceProvider } from '../../browser/boards/boards-service-provider';
|
||||
// import { BoardsListWidgetFrontendContribution } from '../../browser/boards/boards-widget-frontend-contribution';
|
||||
// import {
|
||||
// Board,
|
||||
// BoardsPackage,
|
||||
// BoardsService,
|
||||
// Port,
|
||||
// ResponseServiceArduino,
|
||||
// } from '../../common/protocol';
|
||||
// import { IMock, It, Mock, Times } from 'typemoq';
|
||||
// import { Container, ContainerModule } from '@theia/core/shared/inversify';
|
||||
// import { BoardsAutoInstaller } from '../../browser/boards/boards-auto-installer';
|
||||
// import { BoardsConfig } from '../../browser/boards/boards-config';
|
||||
// import { tick } from '../utils';
|
||||
// import { ListWidget } from '../../browser/widgets/component-list/list-widget';
|
||||
|
||||
// disableJSDOM();
|
||||
|
||||
// const aBoard: Board = {
|
||||
// fqbn: 'some:board:fqbn',
|
||||
// name: 'Some Arduino Board',
|
||||
// port: { address: '/lol/port1234', protocol: 'serial' },
|
||||
// };
|
||||
// const aPort: Port = {
|
||||
// address: aBoard.port!.address,
|
||||
// protocol: aBoard.port!.protocol,
|
||||
// };
|
||||
// const aBoardConfig: BoardsConfig.Config = {
|
||||
// selectedBoard: aBoard,
|
||||
// selectedPort: aPort,
|
||||
// };
|
||||
// const aPackage: BoardsPackage = {
|
||||
// author: 'someAuthor',
|
||||
// availableVersions: ['some.ver.sion', 'some.other.version'],
|
||||
// boards: [aBoard],
|
||||
// deprecated: false,
|
||||
// description: 'Some Arduino Board, Some Other Arduino Board',
|
||||
// id: 'some:arduinoCoreId',
|
||||
// installable: true,
|
||||
// moreInfoLink: 'http://www.some-url.lol/',
|
||||
// name: 'Some Arduino Package',
|
||||
// summary: 'Boards included in this package:',
|
||||
// };
|
||||
|
||||
// const anInstalledPackage: BoardsPackage = {
|
||||
// ...aPackage,
|
||||
// installedVersion: 'some.ver.sion',
|
||||
// };
|
||||
|
||||
// describe('BoardsAutoInstaller', () => {
|
||||
// let subject: BoardsAutoInstaller;
|
||||
// let messageService: IMock<MessageService>;
|
||||
// let boardsService: IMock<BoardsService>;
|
||||
// let boardsServiceClient: IMock<BoardsServiceProvider>;
|
||||
// let responseService: IMock<ResponseServiceArduino>;
|
||||
// let boardsManagerFrontendContribution: IMock<BoardsListWidgetFrontendContribution>;
|
||||
// let boardsManagerWidget: IMock<ListWidget<BoardsPackage>>;
|
||||
|
||||
// let testContainer: Container;
|
||||
|
||||
// beforeEach(() => {
|
||||
// testContainer = new Container();
|
||||
// messageService = Mock.ofType<MessageService>();
|
||||
// boardsService = Mock.ofType<BoardsService>();
|
||||
// boardsServiceClient = Mock.ofType<BoardsServiceProvider>();
|
||||
// responseService = Mock.ofType<ResponseServiceArduino>();
|
||||
// boardsManagerFrontendContribution =
|
||||
// Mock.ofType<BoardsListWidgetFrontendContribution>();
|
||||
// boardsManagerWidget = Mock.ofType<ListWidget<BoardsPackage>>();
|
||||
|
||||
// boardsManagerWidget.setup((b) =>
|
||||
// b.refresh(aPackage.name.toLocaleLowerCase())
|
||||
// );
|
||||
|
||||
// boardsManagerFrontendContribution
|
||||
// .setup((b) => b.openView({ reveal: true }))
|
||||
// .returns(async () => boardsManagerWidget.object);
|
||||
|
||||
// messageService
|
||||
// .setup((m) => m.showProgress(It.isAny(), It.isAny()))
|
||||
// .returns(async () => ({
|
||||
// cancel: () => null,
|
||||
// id: '',
|
||||
// report: () => null,
|
||||
// result: Promise.resolve(''),
|
||||
// }));
|
||||
|
||||
// responseService
|
||||
// .setup((r) => r.onProgressDidChange(It.isAny()))
|
||||
// .returns(() => ({ dispose: () => null }));
|
||||
|
||||
// const module = new ContainerModule((bind) => {
|
||||
// bind(BoardsAutoInstaller).toSelf();
|
||||
// bind(MessageService).toConstantValue(messageService.object);
|
||||
// bind(BoardsService).toConstantValue(boardsService.object);
|
||||
// bind(BoardsServiceProvider).toConstantValue(boardsServiceClient.object);
|
||||
// bind(ResponseServiceArduino).toConstantValue(responseService.object);
|
||||
// bind(BoardsListWidgetFrontendContribution).toConstantValue(
|
||||
// boardsManagerFrontendContribution.object
|
||||
// );
|
||||
// });
|
||||
|
||||
// testContainer.load(module);
|
||||
// subject = testContainer.get(BoardsAutoInstaller);
|
||||
// });
|
||||
|
||||
// context('when it starts', () => {
|
||||
// it('should register to the BoardsServiceClient in order to check the packages every a new board is plugged in', () => {
|
||||
// subject.onStart();
|
||||
// boardsServiceClient.verify(
|
||||
// (b) => b.onBoardsConfigChanged(It.isAny()),
|
||||
// Times.once()
|
||||
// );
|
||||
// });
|
||||
|
||||
// context('and it checks the installable packages', () => {
|
||||
// context(`and a port and a board a selected`, () => {
|
||||
// beforeEach(() => {
|
||||
// boardsServiceClient
|
||||
// .setup((b) => b.boardsConfig)
|
||||
// .returns(() => aBoardConfig);
|
||||
// });
|
||||
// context('if no package for the board is already installed', () => {
|
||||
// context('if a candidate package for the board is found', () => {
|
||||
// beforeEach(() => {
|
||||
// boardsService
|
||||
// .setup((b) => b.search(It.isValue({})))
|
||||
// .returns(async () => [aPackage]);
|
||||
// });
|
||||
// it('should show a notification suggesting to install that package', async () => {
|
||||
// messageService
|
||||
// .setup((m) =>
|
||||
// m.info(It.isAnyString(), It.isAnyString(), It.isAnyString())
|
||||
// )
|
||||
// .returns(() => Promise.resolve('Install Manually'));
|
||||
// subject.onStart();
|
||||
// await tick();
|
||||
// messageService.verify(
|
||||
// (m) =>
|
||||
// m.info(It.isAnyString(), It.isAnyString(), It.isAnyString()),
|
||||
// Times.once()
|
||||
// );
|
||||
// });
|
||||
// context(`if the answer to the message is 'Yes'`, () => {
|
||||
// beforeEach(() => {
|
||||
// messageService
|
||||
// .setup((m) =>
|
||||
// m.info(It.isAnyString(), It.isAnyString(), It.isAnyString())
|
||||
// )
|
||||
// .returns(() => Promise.resolve('Yes'));
|
||||
// });
|
||||
// it('should install the package', async () => {
|
||||
// subject.onStart();
|
||||
|
||||
// await tick();
|
||||
|
||||
// messageService.verify(
|
||||
// (m) => m.showProgress(It.isAny(), It.isAny()),
|
||||
// Times.once()
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
// context(
|
||||
// `if the answer to the message is 'Install Manually'`,
|
||||
// () => {
|
||||
// beforeEach(() => {
|
||||
// messageService
|
||||
// .setup((m) =>
|
||||
// m.info(
|
||||
// It.isAnyString(),
|
||||
// It.isAnyString(),
|
||||
// It.isAnyString()
|
||||
// )
|
||||
// )
|
||||
// .returns(() => Promise.resolve('Install Manually'));
|
||||
// });
|
||||
// it('should open the boards manager widget', () => {
|
||||
// subject.onStart();
|
||||
// });
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
// context('if a candidate package for the board is not found', () => {
|
||||
// beforeEach(() => {
|
||||
// boardsService
|
||||
// .setup((b) => b.search(It.isValue({})))
|
||||
// .returns(async () => []);
|
||||
// });
|
||||
// it('should do nothing', async () => {
|
||||
// subject.onStart();
|
||||
// await tick();
|
||||
// messageService.verify(
|
||||
// (m) =>
|
||||
// m.info(It.isAnyString(), It.isAnyString(), It.isAnyString()),
|
||||
// Times.never()
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// context(
|
||||
// 'if one of the packages for the board is already installed',
|
||||
// () => {
|
||||
// beforeEach(() => {
|
||||
// boardsService
|
||||
// .setup((b) => b.search(It.isValue({})))
|
||||
// .returns(async () => [aPackage, anInstalledPackage]);
|
||||
// messageService
|
||||
// .setup((m) =>
|
||||
// m.info(It.isAnyString(), It.isAnyString(), It.isAnyString())
|
||||
// )
|
||||
// .returns(() => Promise.resolve('Yes'));
|
||||
// });
|
||||
// it('should do nothing', async () => {
|
||||
// subject.onStart();
|
||||
// await tick();
|
||||
// messageService.verify(
|
||||
// (m) =>
|
||||
// m.info(It.isAnyString(), It.isAnyString(), It.isAnyString()),
|
||||
// Times.never()
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
// );
|
||||
// });
|
||||
// context('and there is no selected board or port', () => {
|
||||
// it('should do nothing', async () => {
|
||||
// subject.onStart();
|
||||
// await tick();
|
||||
// messageService.verify(
|
||||
// (m) => m.info(It.isAnyString(), It.isAnyString(), It.isAnyString()),
|
||||
// Times.never()
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// });
|
@ -0,0 +1,8 @@
|
||||
import { Container, ContainerModule } from '@theia/core/shared/inversify';
|
||||
import { bindCommon } from '../common/common-test-bindings';
|
||||
|
||||
export function createBaseContainer(): Container {
|
||||
const container = new Container({ defaultScope: 'Singleton' });
|
||||
container.load(new ContainerModule((bind) => bindCommon(bind)));
|
||||
return container;
|
||||
}
|
@ -1,44 +1,36 @@
|
||||
import { BoardsConfig } from '../../../browser/boards/boards-config';
|
||||
import { Board, BoardsPackage, Port } from '../../../common/protocol';
|
||||
import type {
|
||||
Board,
|
||||
BoardsConfig,
|
||||
BoardsPackage,
|
||||
Port,
|
||||
} from '../../../common/protocol';
|
||||
|
||||
export const aBoard: Board = {
|
||||
fqbn: 'some:board:fqbn',
|
||||
name: 'Some Arduino Board',
|
||||
port: {
|
||||
address: '/lol/port1234',
|
||||
addressLabel: '/lol/port1234',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
},
|
||||
};
|
||||
export const aPort: Port = {
|
||||
address: aBoard.port!.address,
|
||||
addressLabel: aBoard.port!.addressLabel,
|
||||
protocol: aBoard.port!.protocol,
|
||||
protocolLabel: aBoard.port!.protocolLabel,
|
||||
const aPort: Port = {
|
||||
address: '/lol/port1234',
|
||||
addressLabel: '/lol/port1234',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
};
|
||||
export const aBoardConfig: BoardsConfig.Config = {
|
||||
selectedBoard: aBoard,
|
||||
export const aBoardsConfig: BoardsConfig = {
|
||||
selectedBoard: { name: aBoard.name, fqbn: aBoard.fqbn },
|
||||
selectedPort: aPort,
|
||||
};
|
||||
export const anotherBoard: Board = {
|
||||
fqbn: 'another:board:fqbn',
|
||||
name: 'Another Arduino Board',
|
||||
port: {
|
||||
address: '/kek/port5678',
|
||||
addressLabel: '/kek/port5678',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
},
|
||||
};
|
||||
export const anotherPort: Port = {
|
||||
address: anotherBoard.port!.address,
|
||||
addressLabel: anotherBoard.port!.addressLabel,
|
||||
protocol: anotherBoard.port!.protocol,
|
||||
protocolLabel: anotherBoard.port!.protocolLabel,
|
||||
address: '/kek/port5678',
|
||||
addressLabel: '/kek/port5678',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
};
|
||||
export const anotherBoardConfig: BoardsConfig.Config = {
|
||||
selectedBoard: anotherBoard,
|
||||
export const anotherBoardsConfig: BoardsConfig = {
|
||||
selectedBoard: { name: anotherBoard.name, fqbn: anotherBoard.fqbn },
|
||||
selectedPort: anotherPort,
|
||||
};
|
||||
|
||||
|
594
arduino-ide-extension/src/test/common/board-list.test.ts
Normal file
594
arduino-ide-extension/src/test/common/board-list.test.ts
Normal file
@ -0,0 +1,594 @@
|
||||
import { expect } from 'chai';
|
||||
import { Unknown } from '../../common/nls';
|
||||
import {
|
||||
BoardListLabels,
|
||||
createBoardList,
|
||||
EditBoardsConfigActionParams,
|
||||
isInferredBoardListItem,
|
||||
isMultiBoardsBoardListItem,
|
||||
SelectBoardsConfigActionParams,
|
||||
} from '../../common/protocol/board-list';
|
||||
import {
|
||||
emptyBoardsConfig,
|
||||
notConnected,
|
||||
selectBoard,
|
||||
unconfirmedBoard,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import {
|
||||
arduinoNanoEsp32,
|
||||
bluetoothSerialPort,
|
||||
builtinSerialPort,
|
||||
createPort,
|
||||
detectedPort,
|
||||
detectedPorts,
|
||||
esp32NanoEsp32,
|
||||
esp32S3Box,
|
||||
esp32S3DevModule,
|
||||
history,
|
||||
mkr1000,
|
||||
mkr1000NetworkPort,
|
||||
mkr1000SerialPort,
|
||||
nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
|
||||
nanoEsp32SerialPort,
|
||||
undiscoveredSerialPort,
|
||||
undiscoveredUsbToUARTSerialPort,
|
||||
uno,
|
||||
unoSerialPort,
|
||||
} from './fixtures';
|
||||
|
||||
describe('board-list', () => {
|
||||
describe('boardList#labels', () => {
|
||||
it('should handle no selected board+port', () => {
|
||||
const { labels } = createBoardList({});
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: selectBoard,
|
||||
portProtocol: undefined,
|
||||
selected: false,
|
||||
tooltip: selectBoard,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle port selected (port detected)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
},
|
||||
{ selectedBoard: undefined, selectedPort: unoSerialPort }
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: selectBoard,
|
||||
portProtocol: undefined,
|
||||
selected: false,
|
||||
tooltip: unoSerialPort.address,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle port selected (port not detected)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
},
|
||||
{ selectedBoard: undefined, selectedPort: unoSerialPort }
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: selectBoard,
|
||||
portProtocol: undefined,
|
||||
selected: false,
|
||||
tooltip: `${unoSerialPort.address} ${notConnected}`,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle board selected (with FQBN)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{},
|
||||
{ selectedBoard: uno, selectedPort: undefined }
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: uno.name,
|
||||
portProtocol: undefined,
|
||||
selected: false,
|
||||
tooltip: `${uno.name} (${uno.fqbn})`,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle board selected (no FQBN)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{},
|
||||
{
|
||||
selectedBoard: { name: 'my board', fqbn: undefined },
|
||||
selectedPort: undefined,
|
||||
}
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: 'my board',
|
||||
portProtocol: undefined,
|
||||
selected: false,
|
||||
tooltip: 'my board',
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle both selected (port not detected)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
},
|
||||
{ selectedBoard: mkr1000, selectedPort: unoSerialPort }
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: mkr1000.name,
|
||||
portProtocol: 'serial',
|
||||
selected: false,
|
||||
tooltip: `${mkr1000.name} (${mkr1000.fqbn})\n${unoSerialPort.address} ${notConnected}`,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle both selected (board not discovered)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
},
|
||||
{ selectedBoard: mkr1000, selectedPort: unoSerialPort }
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: mkr1000.name,
|
||||
portProtocol: 'serial',
|
||||
selected: false,
|
||||
tooltip: `${mkr1000.name} (${mkr1000.fqbn})\n${unoSerialPort.address}`,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle both selected (no FQBN)', () => {
|
||||
const { labels } = createBoardList(
|
||||
{
|
||||
...detectedPort(unoSerialPort, { name: 'my board', fqbn: undefined }),
|
||||
},
|
||||
{
|
||||
selectedBoard: { name: 'my board', fqbn: undefined },
|
||||
selectedPort: unoSerialPort,
|
||||
}
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: 'my board',
|
||||
portProtocol: 'serial',
|
||||
selected: true,
|
||||
tooltip: `my board\n${unoSerialPort.address}`,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
|
||||
it('should handle both selected', () => {
|
||||
const { labels } = createBoardList(
|
||||
{
|
||||
...detectedPort(mkr1000NetworkPort, mkr1000),
|
||||
},
|
||||
{ selectedBoard: mkr1000, selectedPort: mkr1000NetworkPort }
|
||||
);
|
||||
const expected: BoardListLabels = {
|
||||
boardLabel: mkr1000.name,
|
||||
portProtocol: 'network',
|
||||
selected: true,
|
||||
tooltip: `${mkr1000.name} (${mkr1000.fqbn})\n${mkr1000NetworkPort.address}`,
|
||||
};
|
||||
expect(labels).to.be.deep.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createBoardList', () => {
|
||||
it('should sort the items deterministically', () => {
|
||||
const { items } = createBoardList(detectedPorts);
|
||||
|
||||
expect(items.length).to.be.equal(Object.keys(detectedPorts).length);
|
||||
expect(items[0].board).deep.equal(mkr1000);
|
||||
expect(items[1].board).deep.equal(uno);
|
||||
expect(items[2].board).is.undefined;
|
||||
expect(isMultiBoardsBoardListItem(items[2])).to.be.true;
|
||||
const boards2 = isMultiBoardsBoardListItem(items[2])
|
||||
? items[2].boards
|
||||
: undefined;
|
||||
expect(boards2).deep.equal([arduinoNanoEsp32, esp32NanoEsp32]);
|
||||
expect(items[3].board).is.undefined;
|
||||
expect(isMultiBoardsBoardListItem(items[3])).to.be.true;
|
||||
const boards3 = isMultiBoardsBoardListItem(items[3])
|
||||
? items[3].boards
|
||||
: undefined;
|
||||
expect(boards3).deep.equal([esp32S3Box, esp32S3DevModule]);
|
||||
expect(items[4].port).deep.equal(builtinSerialPort);
|
||||
expect(items[5].port).deep.equal(bluetoothSerialPort);
|
||||
expect(items[6].port).deep.equal(undiscoveredSerialPort);
|
||||
expect(items[7].port).deep.equal(undiscoveredUsbToUARTSerialPort);
|
||||
expect(items[8].port.protocol).equal('network');
|
||||
expect(items[8].board).deep.equal(mkr1000);
|
||||
});
|
||||
|
||||
it('should sort Arduino items before others', () => {
|
||||
const detectedPorts = {
|
||||
...detectedPort(createPort('a'), { name: 'aa', fqbn: 'arduino:a:a' }),
|
||||
...detectedPort(createPort('b'), { name: 'ab', fqbn: 'other:a:b' }),
|
||||
...detectedPort(createPort('c'), { name: 'ac', fqbn: 'arduino:a:c' }),
|
||||
};
|
||||
const { items } = createBoardList(detectedPorts);
|
||||
|
||||
expect(items.length).to.be.equal(3);
|
||||
expect(items[0].board?.name).to.be.equal('aa');
|
||||
expect(items[1].board?.name).to.be.equal('ac');
|
||||
expect(items[2].board?.name).to.be.equal('ab');
|
||||
});
|
||||
|
||||
it('should sort items by inferred board if any', () => {
|
||||
const portA = createPort('portA');
|
||||
const portB = createPort('portB');
|
||||
const detectedPorts = {
|
||||
...detectedPort(portA),
|
||||
...detectedPort(portB),
|
||||
};
|
||||
const boardListHistory = {
|
||||
...history(portA, { name: 'bbb', fqbn: undefined }),
|
||||
...history(portB, { name: 'aaa', fqbn: undefined }),
|
||||
};
|
||||
const { items } = createBoardList(
|
||||
detectedPorts,
|
||||
emptyBoardsConfig(),
|
||||
boardListHistory
|
||||
);
|
||||
|
||||
expect(items.length).to.be.equal(2);
|
||||
expect(items[0].port.address).to.be.equal('portB');
|
||||
expect(items[0].board).to.be.undefined;
|
||||
const inferredBoardA = isInferredBoardListItem(items[0])
|
||||
? items[0].inferredBoard
|
||||
: undefined;
|
||||
expect(inferredBoardA).to.be.not.undefined;
|
||||
expect(inferredBoardA?.name).to.be.equal('aaa');
|
||||
|
||||
expect(items[1].port.address).to.be.equal('portA');
|
||||
expect(items[1].board).to.be.undefined;
|
||||
expect(isInferredBoardListItem(items[1])).to.be.true;
|
||||
const inferredBoardB = isInferredBoardListItem(items[1])
|
||||
? items[1].inferredBoard
|
||||
: undefined;
|
||||
expect(inferredBoardB).to.be.not.undefined;
|
||||
expect(inferredBoardB?.name).to.be.equal('bbb');
|
||||
});
|
||||
|
||||
it('should sort ambiguous boards with unique board name before other ambiguous boards', () => {
|
||||
const portA = createPort('portA');
|
||||
const portB = createPort('portB');
|
||||
const unique_ArduinoZZZ = { fqbn: 'arduino:e:f', name: 'zzz' };
|
||||
const unique_OtherZZZ = { fqbn: 'a:b:c', name: 'zzz' };
|
||||
const nonUnique_AAA = { fqbn: 'g:h:i', name: 'aaa' };
|
||||
const nonUnique_BBB = { fqbn: 'j:k:l', name: 'bbb' };
|
||||
const detectedPorts = {
|
||||
...detectedPort(portA, nonUnique_AAA, nonUnique_BBB),
|
||||
...detectedPort(portB, unique_OtherZZZ, unique_ArduinoZZZ),
|
||||
};
|
||||
const { items } = createBoardList(detectedPorts);
|
||||
|
||||
expect(items.length).to.be.equal(2);
|
||||
expect(isMultiBoardsBoardListItem(items[0])).to.be.true;
|
||||
const ambiguousBoardWithUniqueName = isMultiBoardsBoardListItem(items[0])
|
||||
? items[0]
|
||||
: undefined;
|
||||
expect(ambiguousBoardWithUniqueName).to.be.not.undefined;
|
||||
expect(ambiguousBoardWithUniqueName?.labels.boardLabel).to.be.equal(
|
||||
unique_ArduinoZZZ.name
|
||||
);
|
||||
expect(ambiguousBoardWithUniqueName?.port).to.be.deep.equal(portB);
|
||||
expect(ambiguousBoardWithUniqueName?.boards).to.be.deep.equal([
|
||||
unique_ArduinoZZZ,
|
||||
unique_OtherZZZ,
|
||||
]);
|
||||
|
||||
expect(isMultiBoardsBoardListItem(items[1])).to.be.true;
|
||||
const ambiguousBoardWithoutName = isMultiBoardsBoardListItem(items[1])
|
||||
? items[1]
|
||||
: undefined;
|
||||
expect(ambiguousBoardWithoutName).to.be.not.undefined;
|
||||
expect(ambiguousBoardWithoutName?.labels.boardLabel).to.be.equal(
|
||||
unconfirmedBoard
|
||||
);
|
||||
expect(ambiguousBoardWithoutName?.port).to.be.deep.equal(portA);
|
||||
expect(ambiguousBoardWithoutName?.boards).to.be.deep.equal([
|
||||
nonUnique_AAA,
|
||||
nonUnique_BBB,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should detect when a discovered board is overridden by a historical selection', () => {
|
||||
const otherBoard = { name: 'other', fqbn: 'a:b:c' };
|
||||
const detectedPorts = {
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
};
|
||||
const boardListHistory = {
|
||||
...history(unoSerialPort, otherBoard),
|
||||
};
|
||||
const { items } = createBoardList(
|
||||
detectedPorts,
|
||||
emptyBoardsConfig(),
|
||||
boardListHistory
|
||||
);
|
||||
|
||||
expect(items.length).to.be.equal(1);
|
||||
const inferredBoard = isInferredBoardListItem(items[0])
|
||||
? items[0]
|
||||
: undefined;
|
||||
expect(inferredBoard).is.not.undefined;
|
||||
expect(inferredBoard?.inferredBoard).to.be.deep.equal(otherBoard);
|
||||
expect(inferredBoard?.board).to.be.deep.equal(uno);
|
||||
});
|
||||
|
||||
it(`should use the '${Unknown}' as the board label when no boards were discovered on a detected port`, () => {
|
||||
const { items } = createBoardList({ ...detectedPort(unoSerialPort) });
|
||||
expect(items[0].labels.boardLabel).to.be.equal(Unknown);
|
||||
});
|
||||
|
||||
describe('defaultAction', () => {
|
||||
it("'select' should be the default action for identifier boards", () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item.defaultAction.type).to.be.equal('select-boards-config');
|
||||
expect(item.defaultAction.params).to.be.deep.equal({
|
||||
selectedPort: mkr1000SerialPort,
|
||||
selectedBoard: mkr1000,
|
||||
});
|
||||
});
|
||||
|
||||
it("'select' should be the default action for manually selected items (no discovered boards)", () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(undiscoveredSerialPort),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(undiscoveredSerialPort, uno),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
expect(item.defaultAction.type).to.be.equal('select-boards-config');
|
||||
expect(item.defaultAction.params).to.be.deep.equal({
|
||||
selectedPort: undiscoveredSerialPort,
|
||||
selectedBoard: uno,
|
||||
});
|
||||
});
|
||||
|
||||
it("'select' should be the default action for manually selected items (ambiguous boards)", () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(
|
||||
nanoEsp32SerialPort,
|
||||
arduinoNanoEsp32,
|
||||
esp32NanoEsp32
|
||||
),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(nanoEsp32SerialPort, mkr1000),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
expect(item.defaultAction.type).to.be.equal('select-boards-config');
|
||||
expect(item.defaultAction.params).to.be.deep.equal({
|
||||
selectedBoard: mkr1000,
|
||||
selectedPort: nanoEsp32SerialPort,
|
||||
});
|
||||
});
|
||||
|
||||
it("'edit' should be the default action for ports with no boards", () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(undiscoveredSerialPort),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item).to.be.not.undefined;
|
||||
expect(item.defaultAction.type).to.be.equal('edit-boards-config');
|
||||
const params = <EditBoardsConfigActionParams>item.defaultAction.params;
|
||||
const expectedParams: EditBoardsConfigActionParams = {
|
||||
query: '',
|
||||
portToSelect: undiscoveredSerialPort,
|
||||
};
|
||||
expect(params).to.be.deep.equal(expectedParams);
|
||||
});
|
||||
|
||||
it("'edit' should be the default action for ports with multiple boards (unique board name)", () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(
|
||||
nanoEsp32SerialPort,
|
||||
arduinoNanoEsp32,
|
||||
esp32NanoEsp32
|
||||
),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item).to.be.not.undefined;
|
||||
expect(item.defaultAction.type).to.be.equal('edit-boards-config');
|
||||
const params = <EditBoardsConfigActionParams>item.defaultAction.params;
|
||||
const expectedParams: EditBoardsConfigActionParams = {
|
||||
query: arduinoNanoEsp32.name,
|
||||
portToSelect: nanoEsp32SerialPort,
|
||||
searchSet: [arduinoNanoEsp32, esp32NanoEsp32],
|
||||
};
|
||||
expect(params).to.be.deep.equal(expectedParams);
|
||||
});
|
||||
|
||||
it("'edit' should be the default action for ports with multiple boards (no unique board name)", () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(
|
||||
nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
|
||||
esp32S3DevModule,
|
||||
esp32S3Box
|
||||
),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item).to.be.not.undefined;
|
||||
expect(item.defaultAction.type).to.be.equal('edit-boards-config');
|
||||
const params = <EditBoardsConfigActionParams>item.defaultAction.params;
|
||||
const expectedParams: EditBoardsConfigActionParams = {
|
||||
query: '',
|
||||
portToSelect: nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
|
||||
searchSet: [esp32S3Box, esp32S3DevModule],
|
||||
};
|
||||
expect(params).to.be.deep.equal(expectedParams);
|
||||
});
|
||||
});
|
||||
|
||||
describe('otherActions', () => {
|
||||
it('should provide no other actions for identified board', () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item.otherActions).to.be.empty;
|
||||
});
|
||||
|
||||
it('should provide no other actions for identified board (when historical revision is self)', () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(mkr1000SerialPort, mkr1000),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
expect(item.otherActions).to.be.empty;
|
||||
});
|
||||
|
||||
it('should provide no other actions for unknown boards', () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(undiscoveredSerialPort),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item.otherActions).to.be.empty;
|
||||
});
|
||||
|
||||
it('should provide no other actions for ambiguous boards', () => {
|
||||
const { items } = createBoardList({
|
||||
...detectedPort(
|
||||
nanoEsp32SerialPort,
|
||||
arduinoNanoEsp32,
|
||||
esp32NanoEsp32
|
||||
),
|
||||
});
|
||||
const item = items[0];
|
||||
expect(item.otherActions).to.be.empty;
|
||||
});
|
||||
|
||||
it("should provide 'edit' action for unidentified items with manually selected board", () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(undiscoveredSerialPort),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(undiscoveredSerialPort, uno),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
const expectedParams: EditBoardsConfigActionParams = {
|
||||
query: uno.name,
|
||||
portToSelect: undiscoveredSerialPort,
|
||||
};
|
||||
expect(item.otherActions).to.be.deep.equal({
|
||||
edit: {
|
||||
params: expectedParams,
|
||||
type: 'edit-boards-config',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should provide 'edit' action for ambiguous items with manually selected board (unique board name)", () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(
|
||||
nanoEsp32SerialPort,
|
||||
esp32NanoEsp32,
|
||||
arduinoNanoEsp32
|
||||
),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(nanoEsp32SerialPort, arduinoNanoEsp32),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
const expectedParams: EditBoardsConfigActionParams = {
|
||||
query: arduinoNanoEsp32.name,
|
||||
portToSelect: nanoEsp32SerialPort,
|
||||
searchSet: [arduinoNanoEsp32, esp32NanoEsp32],
|
||||
};
|
||||
expect(item.otherActions).to.be.deep.equal({
|
||||
edit: {
|
||||
params: expectedParams,
|
||||
type: 'edit-boards-config',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should provide 'edit' action for ambiguous items with manually selected board (no unique board name)", () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(
|
||||
nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
|
||||
esp32S3Box,
|
||||
esp32S3DevModule
|
||||
),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(nanoEsp32DetectsMultipleEsp32BoardsSerialPort, uno),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
const expectedParams: EditBoardsConfigActionParams = {
|
||||
query: '',
|
||||
portToSelect: nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
|
||||
searchSet: [esp32S3Box, esp32S3DevModule],
|
||||
};
|
||||
expect(item.otherActions).to.be.deep.equal({
|
||||
edit: {
|
||||
params: expectedParams,
|
||||
type: 'edit-boards-config',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("should provide 'edit' and 'revert' actions for identified items with a manually overridden board", () => {
|
||||
const { items } = createBoardList(
|
||||
{
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
},
|
||||
emptyBoardsConfig(),
|
||||
{
|
||||
...history(mkr1000SerialPort, uno),
|
||||
}
|
||||
);
|
||||
const item = items[0];
|
||||
const expectedEditParams: EditBoardsConfigActionParams = {
|
||||
query: uno.name,
|
||||
portToSelect: mkr1000SerialPort,
|
||||
};
|
||||
const expectedRevertParams: SelectBoardsConfigActionParams = {
|
||||
selectedBoard: mkr1000,
|
||||
selectedPort: item.port,
|
||||
};
|
||||
expect(item.otherActions).to.be.deep.equal({
|
||||
edit: {
|
||||
params: expectedEditParams,
|
||||
type: 'edit-boards-config',
|
||||
},
|
||||
revert: {
|
||||
params: expectedRevertParams,
|
||||
type: 'select-boards-config',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@ -1,8 +1,8 @@
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { Mutable } from '@theia/core/lib/common/types';
|
||||
import type { Mutable } from '@theia/core/lib/common/types';
|
||||
import { expect } from 'chai';
|
||||
import {
|
||||
AttachedBoardsChangeEvent,
|
||||
boardIdentifierEquals,
|
||||
boardIdentifierComparator,
|
||||
BoardInfo,
|
||||
getBoardInfo,
|
||||
noNativeSerialPort,
|
||||
@ -11,86 +11,114 @@ import {
|
||||
selectPortForInfo,
|
||||
unknownBoard,
|
||||
} from '../../common/protocol';
|
||||
import { createBoardList } from '../../common/protocol/board-list';
|
||||
import { firstToUpperCase } from '../../common/utils';
|
||||
|
||||
describe('boards-service', () => {
|
||||
describe('AttachedBoardsChangeEvent', () => {
|
||||
it('should detect one attached port', () => {
|
||||
const event = <AttachedBoardsChangeEvent & any>{
|
||||
oldState: {
|
||||
boards: [
|
||||
{
|
||||
name: 'Arduino MKR1000',
|
||||
fqbn: 'arduino:samd:mkr1000',
|
||||
port: '/dev/cu.usbmodem14601',
|
||||
},
|
||||
{
|
||||
name: 'Arduino Uno',
|
||||
fqbn: 'arduino:avr:uno',
|
||||
port: '/dev/cu.usbmodem14501',
|
||||
},
|
||||
],
|
||||
ports: [
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.usbmodem14501',
|
||||
},
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.usbmodem14601',
|
||||
},
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.Bluetooth-Incoming-Port',
|
||||
},
|
||||
{ protocol: 'serial', address: '/dev/cu.MALS' },
|
||||
{ protocol: 'serial', address: '/dev/cu.SOC' },
|
||||
],
|
||||
},
|
||||
newState: {
|
||||
boards: [
|
||||
{
|
||||
name: 'Arduino MKR1000',
|
||||
fqbn: 'arduino:samd:mkr1000',
|
||||
port: '/dev/cu.usbmodem1460',
|
||||
},
|
||||
{
|
||||
name: 'Arduino Uno',
|
||||
fqbn: 'arduino:avr:uno',
|
||||
port: '/dev/cu.usbmodem14501',
|
||||
},
|
||||
],
|
||||
ports: [
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.SLAB_USBtoUART',
|
||||
},
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.usbmodem14501',
|
||||
},
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.usbmodem14601',
|
||||
},
|
||||
{
|
||||
protocol: 'serial',
|
||||
address: '/dev/cu.Bluetooth-Incoming-Port',
|
||||
},
|
||||
{ protocol: 'serial', address: '/dev/cu.MALS' },
|
||||
{ protocol: 'serial', address: '/dev/cu.SOC' },
|
||||
],
|
||||
},
|
||||
};
|
||||
const diff = AttachedBoardsChangeEvent.diff(event);
|
||||
expect(diff.attached.boards).to.be.empty; // tslint:disable-line:no-unused-expression
|
||||
expect(diff.detached.boards).to.be.empty; // tslint:disable-line:no-unused-expression
|
||||
expect(diff.detached.ports).to.be.empty; // tslint:disable-line:no-unused-expression
|
||||
expect(diff.attached.ports.length).to.be.equal(1);
|
||||
expect(diff.attached.ports[0].address).to.be.equal(
|
||||
'/dev/cu.SLAB_USBtoUART'
|
||||
describe('boardIdentifierEquals', () => {
|
||||
it('should not be equal when the names equal but the FQBNs are different', () => {
|
||||
const actual = boardIdentifierEquals(
|
||||
{ name: 'a', fqbn: 'a:b:c' },
|
||||
{ name: 'a', fqbn: 'x:y:z' }
|
||||
);
|
||||
expect(actual).to.be.false;
|
||||
});
|
||||
|
||||
it('should not be equal when the names equal but the FQBNs are different (undefined)', () => {
|
||||
const actual = boardIdentifierEquals(
|
||||
{ name: 'a', fqbn: 'a:b:c' },
|
||||
{ name: 'a', fqbn: undefined }
|
||||
);
|
||||
expect(actual).to.be.false;
|
||||
});
|
||||
|
||||
it("should be equal when the names do not match but the FQBNs are the same (it's something IDE2 assumes to be handled by the platform or CLI)", () => {
|
||||
const actual = boardIdentifierEquals(
|
||||
{ name: 'a', fqbn: 'a:b:c' },
|
||||
{ name: 'b', fqbn: 'a:b:c' }
|
||||
);
|
||||
expect(actual).to.be.true;
|
||||
});
|
||||
|
||||
it('should be equal when the names equal and the FQBNs are missing', () => {
|
||||
const actual = boardIdentifierEquals(
|
||||
{ name: 'a', fqbn: undefined },
|
||||
{ name: 'a', fqbn: undefined }
|
||||
);
|
||||
expect(actual).to.be.true;
|
||||
});
|
||||
|
||||
it('should be equal when both the name and FQBN are the same, but one of the FQBN has board config options', () => {
|
||||
const actual = boardIdentifierEquals(
|
||||
{ name: 'a', fqbn: 'a:b:c:menu_1=value' },
|
||||
{ name: 'a', fqbn: 'a:b:c' }
|
||||
);
|
||||
expect(actual).to.be.true;
|
||||
});
|
||||
|
||||
it('should not be equal when both the name and FQBN are the same, but one of the FQBN has board config options (looseFqbn: false)', () => {
|
||||
const actual = boardIdentifierEquals(
|
||||
{ name: 'a', fqbn: 'a:b:c:menu_1=value' },
|
||||
{ name: 'a', fqbn: 'a:b:c' },
|
||||
{ looseFqbn: false }
|
||||
);
|
||||
expect(actual).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
describe('boardIdentifierComparator', () => {
|
||||
it('should sort items before falsy', () =>
|
||||
expect(
|
||||
boardIdentifierComparator({ name: 'a', fqbn: 'a:b:c' }, undefined)
|
||||
).to.be.equal(-1));
|
||||
|
||||
it("should sort 'arduino' boards before others", () =>
|
||||
expect(
|
||||
boardIdentifierComparator(
|
||||
{ name: 'b', fqbn: 'arduino:b:c' },
|
||||
{ name: 'a', fqbn: 'x:y:z' }
|
||||
)
|
||||
).to.be.equal(-1));
|
||||
|
||||
it("should sort 'arduino' boards before others (other is falsy)", () =>
|
||||
expect(
|
||||
boardIdentifierComparator(
|
||||
{ name: 'b', fqbn: 'arduino:b:c' },
|
||||
{ name: 'a', fqbn: undefined }
|
||||
)
|
||||
).to.be.equal(-1));
|
||||
|
||||
it("should sort boards by 'name' (with FQBNs)", () =>
|
||||
expect(
|
||||
boardIdentifierComparator(
|
||||
{ name: 'b', fqbn: 'a:b:c' },
|
||||
{ name: 'a', fqbn: 'x:y:z' }
|
||||
)
|
||||
).to.be.equal(1));
|
||||
|
||||
it("should sort boards by 'name' (no FQBNs)", () =>
|
||||
expect(
|
||||
boardIdentifierComparator(
|
||||
{ name: 'b', fqbn: undefined },
|
||||
{ name: 'a', fqbn: undefined }
|
||||
)
|
||||
).to.be.equal(1));
|
||||
|
||||
it("should sort boards by 'name' (one FQBN)", () =>
|
||||
expect(
|
||||
boardIdentifierComparator(
|
||||
{ name: 'b', fqbn: 'a:b:c' },
|
||||
{ name: 'a', fqbn: undefined }
|
||||
)
|
||||
).to.be.equal(1));
|
||||
|
||||
it("should sort boards by 'name' (both 'arduino' vendor)", () =>
|
||||
expect(
|
||||
boardIdentifierComparator(
|
||||
{ name: 'b', fqbn: 'arduino:b:c' },
|
||||
{ name: 'a', fqbn: 'arduino:y:z' }
|
||||
)
|
||||
).to.be.equal(1));
|
||||
});
|
||||
|
||||
describe('getBoardInfo', () => {
|
||||
@ -112,7 +140,7 @@ describe('boards-service', () => {
|
||||
});
|
||||
|
||||
it('should handle when no port is selected', async () => {
|
||||
const info = await getBoardInfo(undefined, never());
|
||||
const info = await getBoardInfo(createBoardList({}));
|
||||
expect(info).to.be.equal(selectPortForInfo);
|
||||
});
|
||||
|
||||
@ -125,7 +153,11 @@ describe('boards-service', () => {
|
||||
protocolLabel: firstToUpperCase(protocol),
|
||||
protocol,
|
||||
};
|
||||
const info = await getBoardInfo(selectedPort, never());
|
||||
const boardList = createBoardList(
|
||||
{ [Port.keyOf(selectedPort)]: { port: selectedPort } },
|
||||
{ selectedPort, selectedBoard: undefined }
|
||||
);
|
||||
const info = await getBoardInfo(boardList);
|
||||
expect(info).to.be.equal(nonSerialPort);
|
||||
})
|
||||
);
|
||||
@ -140,18 +172,26 @@ describe('boards-service', () => {
|
||||
];
|
||||
for (const properties of insufficientProperties) {
|
||||
const port = selectedPort(properties);
|
||||
const info = await getBoardInfo(port, {
|
||||
[Port.keyOf(port)]: [port, []],
|
||||
});
|
||||
const boardList = createBoardList(
|
||||
{
|
||||
[Port.keyOf(port)]: { port },
|
||||
},
|
||||
{ selectedPort: port, selectedBoard: undefined }
|
||||
);
|
||||
const info = await getBoardInfo(boardList);
|
||||
expect(info).to.be.equal(noNativeSerialPort);
|
||||
}
|
||||
});
|
||||
|
||||
it("should detect a port as non-native serial, if protocol is 'serial' and VID/PID are available", async () => {
|
||||
const port = selectedPort({ vid, pid });
|
||||
const info = await getBoardInfo(port, {
|
||||
[Port.keyOf(port)]: [port, []],
|
||||
});
|
||||
const boardList = createBoardList(
|
||||
{
|
||||
[Port.keyOf(port)]: { port },
|
||||
},
|
||||
{ selectedPort: port, selectedBoard: undefined }
|
||||
);
|
||||
const info = await getBoardInfo(boardList);
|
||||
expect(typeof info).to.be.equal('object');
|
||||
const boardInfo = <BoardInfo>info;
|
||||
expect(boardInfo.VID).to.be.equal(vid);
|
||||
@ -162,9 +202,13 @@ describe('boards-service', () => {
|
||||
|
||||
it("should show the 'SN' even if no matching board was detected for the port", async () => {
|
||||
const port = selectedPort({ vid, pid, serialNumber });
|
||||
const info = await getBoardInfo(port, {
|
||||
[Port.keyOf(port)]: [port, []],
|
||||
});
|
||||
const boardList = createBoardList(
|
||||
{
|
||||
[Port.keyOf(port)]: { port },
|
||||
},
|
||||
{ selectedPort: port, selectedBoard: undefined }
|
||||
);
|
||||
const info = await getBoardInfo(boardList);
|
||||
expect(typeof info).to.be.equal('object');
|
||||
const boardInfo = <BoardInfo>info;
|
||||
expect(boardInfo.VID).to.be.equal(vid);
|
||||
@ -175,9 +219,13 @@ describe('boards-service', () => {
|
||||
|
||||
it("should use the name of the matching board as 'BN' if available", async () => {
|
||||
const port = selectedPort({ vid, pid });
|
||||
const info = await getBoardInfo(port, {
|
||||
[Port.keyOf(port)]: [port, [selectedBoard]],
|
||||
});
|
||||
const boardList = createBoardList(
|
||||
{
|
||||
[Port.keyOf(port)]: { port, boards: [selectedBoard] },
|
||||
},
|
||||
{ selectedPort: port, selectedBoard: undefined }
|
||||
);
|
||||
const info = await getBoardInfo(boardList);
|
||||
expect(typeof info).to.be.equal('object');
|
||||
const boardInfo = <BoardInfo>info;
|
||||
expect(boardInfo.VID).to.be.equal(vid);
|
||||
@ -187,7 +235,3 @@ describe('boards-service', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function never<T>(): Promise<T> {
|
||||
return new Deferred<T>().promise;
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
import {
|
||||
CommandContribution,
|
||||
CommandRegistry,
|
||||
CommandService,
|
||||
} from '@theia/core/lib/common/command';
|
||||
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
|
||||
import { ILogger, Loggable } from '@theia/core/lib/common/logger';
|
||||
import { LogLevel } from '@theia/core/lib/common/logger-protocol';
|
||||
import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
|
||||
import { injectable, interfaces } from '@theia/core/shared/inversify';
|
||||
|
||||
export function bindCommon(bind: interfaces.Bind): interfaces.Bind {
|
||||
bind(ConsoleLogger).toSelf().inSingletonScope();
|
||||
bind(ILogger).toService(ConsoleLogger);
|
||||
bind(CommandRegistry).toSelf().inSingletonScope();
|
||||
bind(CommandService).toService(CommandRegistry);
|
||||
bindContributionProvider(bind, CommandContribution);
|
||||
return bind;
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class ConsoleLogger extends MockLogger {
|
||||
override log(
|
||||
logLevel: number,
|
||||
arg2: string | Loggable | Error,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
if (arg2 instanceof Error) {
|
||||
return this.error(String(arg2), params);
|
||||
}
|
||||
switch (logLevel) {
|
||||
case LogLevel.INFO:
|
||||
return this.info(arg2, params);
|
||||
case LogLevel.WARN:
|
||||
return this.warn(arg2, params);
|
||||
case LogLevel.TRACE:
|
||||
return this.trace(arg2, params);
|
||||
case LogLevel.ERROR:
|
||||
return this.error(arg2, params);
|
||||
case LogLevel.FATAL:
|
||||
return this.fatal(arg2, params);
|
||||
default:
|
||||
return this.info(arg2, params);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
override async info(arg: string | Loggable, ...params: any[]): Promise<void> {
|
||||
if (params.length) {
|
||||
console.info(arg, ...params);
|
||||
} else {
|
||||
console.info(arg);
|
||||
}
|
||||
}
|
||||
|
||||
override async trace(
|
||||
arg: string | Loggable,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
if (params.length) {
|
||||
console.trace(arg, ...params);
|
||||
} else {
|
||||
console.trace(arg);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
override async warn(arg: string | Loggable, ...params: any[]): Promise<void> {
|
||||
if (params.length) {
|
||||
console.warn(arg, ...params);
|
||||
} else {
|
||||
console.warn(arg);
|
||||
}
|
||||
}
|
||||
|
||||
override async error(
|
||||
arg: string | Loggable,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
if (params.length) {
|
||||
console.error(arg, ...params);
|
||||
} else {
|
||||
console.error(arg);
|
||||
}
|
||||
}
|
||||
|
||||
override async fatal(
|
||||
arg: string | Loggable,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
return this.error(arg, params);
|
||||
}
|
||||
}
|
176
arduino-ide-extension/src/test/common/fixtures.ts
Normal file
176
arduino-ide-extension/src/test/common/fixtures.ts
Normal file
@ -0,0 +1,176 @@
|
||||
import {
|
||||
BoardIdentifier,
|
||||
DetectedPort,
|
||||
DetectedPorts,
|
||||
Port,
|
||||
} from '../../common/protocol/boards-service';
|
||||
|
||||
export const mkr1000: BoardIdentifier = {
|
||||
name: 'Arduino MKR1000',
|
||||
fqbn: 'arduino:samd:mkr1000',
|
||||
};
|
||||
export const uno: BoardIdentifier = {
|
||||
name: 'Arduino Uno',
|
||||
fqbn: 'arduino:avr:uno',
|
||||
};
|
||||
export const arduinoNanoEsp32: BoardIdentifier = {
|
||||
fqbn: 'arduino:esp32:nano_nora',
|
||||
name: 'Arduino Nano ESP32',
|
||||
};
|
||||
export const esp32NanoEsp32: BoardIdentifier = {
|
||||
fqbn: 'esp32:esp32:nano_nora',
|
||||
name: 'Arduino Nano ESP32',
|
||||
};
|
||||
export const esp32S3DevModule: BoardIdentifier = {
|
||||
name: 'ESP32S3 Dev Module',
|
||||
fqbn: 'esp32:esp32:esp32s3',
|
||||
};
|
||||
export const esp32S3Box: BoardIdentifier = {
|
||||
name: 'ESP32-S3-Box',
|
||||
fqbn: 'esp32:esp32:esp32s3box',
|
||||
};
|
||||
|
||||
export const bluetoothSerialPort: Port = {
|
||||
address: '/dev/cu.Bluetooth-Incoming-Port',
|
||||
addressLabel: '/dev/cu.Bluetooth-Incoming-Port',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port',
|
||||
properties: {},
|
||||
hardwareId: '',
|
||||
};
|
||||
export const builtinSerialPort: Port = {
|
||||
address: '/dev/cu.BLTH',
|
||||
addressLabel: '/dev/cu.BLTH',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port',
|
||||
properties: {},
|
||||
hardwareId: '',
|
||||
};
|
||||
export const undiscoveredSerialPort: Port = {
|
||||
address: '/dev/cu.usbserial-0001',
|
||||
addressLabel: '/dev/cu.usbserial-0001',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
properties: {
|
||||
pid: '0xEA60',
|
||||
serialNumber: '0001',
|
||||
vid: '0x10C4',
|
||||
},
|
||||
hardwareId: '0001',
|
||||
};
|
||||
export const mkr1000NetworkPort: Port = {
|
||||
address: '192.168.0.104',
|
||||
addressLabel: 'Arduino at 192.168.0.104',
|
||||
protocol: 'network',
|
||||
protocolLabel: 'Network Port',
|
||||
properties: {
|
||||
'.': 'mkr1000',
|
||||
auth_upload: 'yes',
|
||||
board: 'mkr1000',
|
||||
hostname: 'Arduino.local.',
|
||||
port: '65280',
|
||||
ssh_upload: 'no',
|
||||
tcp_check: 'no',
|
||||
},
|
||||
hardwareId: '',
|
||||
};
|
||||
export const undiscoveredUsbToUARTSerialPort: Port = {
|
||||
address: '/dev/cu.SLAB_USBtoUART',
|
||||
addressLabel: '/dev/cu.SLAB_USBtoUART',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
properties: {
|
||||
pid: '0xEA60',
|
||||
serialNumber: '0001',
|
||||
vid: '0x10C4',
|
||||
},
|
||||
hardwareId: '0001',
|
||||
};
|
||||
export const mkr1000SerialPort: Port = {
|
||||
address: '/dev/cu.usbmodem14301',
|
||||
addressLabel: '/dev/cu.usbmodem14301',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
properties: {
|
||||
pid: '0x804E',
|
||||
serialNumber: '94A3397C5150435437202020FF150838',
|
||||
vid: '0x2341',
|
||||
},
|
||||
hardwareId: '94A3397C5150435437202020FF150838',
|
||||
};
|
||||
export const unoSerialPort: Port = {
|
||||
address: '/dev/cu.usbmodem14201',
|
||||
addressLabel: '/dev/cu.usbmodem14201',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
properties: {
|
||||
pid: '0x0043',
|
||||
serialNumber: '75830303934351618212',
|
||||
vid: '0x2341',
|
||||
},
|
||||
hardwareId: '75830303934351618212',
|
||||
};
|
||||
export const nanoEsp32SerialPort: Port = {
|
||||
address: '/dev/cu.usbmodem3485187BD9882',
|
||||
addressLabel: '/dev/cu.usbmodem3485187BD9882',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
properties: {
|
||||
pid: '0x0070',
|
||||
serialNumber: '3485187BD988',
|
||||
vid: '0x2341',
|
||||
},
|
||||
hardwareId: '3485187BD988',
|
||||
};
|
||||
export const nanoEsp32DetectsMultipleEsp32BoardsSerialPort: Port = {
|
||||
address: 'COM41',
|
||||
addressLabel: 'COM41',
|
||||
protocol: 'serial',
|
||||
protocolLabel: 'Serial Port (USB)',
|
||||
properties: {
|
||||
pid: '0x1001',
|
||||
serialNumber: '',
|
||||
vid: '0x303A',
|
||||
},
|
||||
};
|
||||
|
||||
export function createPort(address: string, protocol = 'serial'): Port {
|
||||
return {
|
||||
address,
|
||||
addressLabel: `Address label: ${address}`,
|
||||
protocol,
|
||||
protocolLabel: `Protocol label: ${protocol}`,
|
||||
};
|
||||
}
|
||||
|
||||
export function detectedPort(
|
||||
port: Port,
|
||||
...boards: BoardIdentifier[]
|
||||
): { [portKey: string]: DetectedPort } {
|
||||
return { [Port.keyOf(port)]: boards.length ? { port, boards } : { port } };
|
||||
}
|
||||
|
||||
export function history(
|
||||
port: Port,
|
||||
board: BoardIdentifier
|
||||
): { [portKey: string]: BoardIdentifier } {
|
||||
return { [Port.keyOf(port)]: board };
|
||||
}
|
||||
|
||||
export const detectedPorts: DetectedPorts = {
|
||||
...detectedPort(builtinSerialPort),
|
||||
...detectedPort(bluetoothSerialPort),
|
||||
...detectedPort(unoSerialPort, uno),
|
||||
...detectedPort(mkr1000SerialPort, mkr1000),
|
||||
...detectedPort(mkr1000NetworkPort, mkr1000),
|
||||
...detectedPort(undiscoveredSerialPort),
|
||||
...detectedPort(undiscoveredUsbToUARTSerialPort),
|
||||
// multiple discovered on the same port with different board names
|
||||
...detectedPort(
|
||||
nanoEsp32DetectsMultipleEsp32BoardsSerialPort,
|
||||
esp32S3DevModule,
|
||||
esp32S3Box
|
||||
),
|
||||
// multiple discovered on the same port with the same board name
|
||||
...detectedPort(nanoEsp32SerialPort, arduinoNanoEsp32, esp32NanoEsp32),
|
||||
};
|
@ -2,7 +2,7 @@ import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { Container } from '@theia/core/shared/inversify';
|
||||
import { expect } from 'chai';
|
||||
import { BoardSearch, BoardsService } from '../../common/protocol';
|
||||
import { createBaseContainer, startDaemon } from './test-bindings';
|
||||
import { createBaseContainer, startDaemon } from './node-test-bindings';
|
||||
|
||||
describe('boards-service-impl', () => {
|
||||
let boardService: BoardsService;
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
ClangFormatter,
|
||||
} from '../../node/clang-formatter';
|
||||
import { spawnCommand } from '../../node/exec-util';
|
||||
import { createBaseContainer, startDaemon } from './test-bindings';
|
||||
import { createBaseContainer, startDaemon } from './node-test-bindings';
|
||||
|
||||
const unformattedContent = `void setup ( ) { pinMode(LED_BUILTIN, OUTPUT);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ import type { MaybePromise } from '@theia/core/lib/common/types';
|
||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||
import { Container } from '@theia/core/shared/inversify';
|
||||
import { expect } from 'chai';
|
||||
import { dump, load } from 'js-yaml';
|
||||
import { promises as fs } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { sync as deleteSync } from 'rimraf';
|
||||
@ -23,7 +24,7 @@ import {
|
||||
createCliConfig,
|
||||
newTempConfigDirPath,
|
||||
startDaemon,
|
||||
} from './test-bindings';
|
||||
} from './node-test-bindings';
|
||||
|
||||
const timeout = 5 * 60 * 1_000; // five minutes
|
||||
|
||||
@ -66,16 +67,11 @@ describe('core-client-provider', () => {
|
||||
const configDirPath = await prepareTestConfigDir();
|
||||
deleteSync(join(configDirPath, 'data'));
|
||||
|
||||
const now = new Date().toISOString();
|
||||
const container = await startCli(configDirPath, toDispose);
|
||||
await assertFunctionalCli(container, ({ coreClientProvider }) => {
|
||||
const { indexUpdateSummaryBeforeInit } = coreClientProvider;
|
||||
const libUpdateTimestamp = indexUpdateSummaryBeforeInit['library'];
|
||||
expect(libUpdateTimestamp).to.be.not.empty;
|
||||
expect(libUpdateTimestamp.localeCompare(now)).to.be.greaterThan(0);
|
||||
const platformUpdateTimestamp = indexUpdateSummaryBeforeInit['platform'];
|
||||
expect(platformUpdateTimestamp).to.be.not.empty;
|
||||
expect(platformUpdateTimestamp.localeCompare(now)).to.be.greaterThan(0);
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.not.undefined;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.empty;
|
||||
});
|
||||
});
|
||||
|
||||
@ -90,14 +86,11 @@ describe('core-client-provider', () => {
|
||||
);
|
||||
deleteSync(primaryPackageIndexPath);
|
||||
|
||||
const now = new Date().toISOString();
|
||||
const container = await startCli(configDirPath, toDispose);
|
||||
await assertFunctionalCli(container, ({ coreClientProvider }) => {
|
||||
const { indexUpdateSummaryBeforeInit } = coreClientProvider;
|
||||
expect(indexUpdateSummaryBeforeInit['library']).to.be.undefined;
|
||||
const platformUpdateTimestamp = indexUpdateSummaryBeforeInit['platform'];
|
||||
expect(platformUpdateTimestamp).to.be.not.empty;
|
||||
expect(platformUpdateTimestamp.localeCompare(now)).to.be.greaterThan(0);
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.not.undefined;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.empty;
|
||||
});
|
||||
const rawJson = await fs.readFile(primaryPackageIndexPath, {
|
||||
encoding: 'utf8',
|
||||
@ -149,14 +142,11 @@ describe('core-client-provider', () => {
|
||||
);
|
||||
deleteSync(libraryPackageIndexPath);
|
||||
|
||||
const now = new Date().toISOString();
|
||||
const container = await startCli(configDirPath, toDispose);
|
||||
await assertFunctionalCli(container, ({ coreClientProvider }) => {
|
||||
const { indexUpdateSummaryBeforeInit } = coreClientProvider;
|
||||
const libUpdateTimestamp = indexUpdateSummaryBeforeInit['library'];
|
||||
expect(libUpdateTimestamp).to.be.not.empty;
|
||||
expect(libUpdateTimestamp.localeCompare(now)).to.be.greaterThan(0);
|
||||
expect(indexUpdateSummaryBeforeInit['platform']).to.be.undefined;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.not.undefined;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.empty;
|
||||
});
|
||||
const rawJson = await fs.readFile(libraryPackageIndexPath, {
|
||||
encoding: 'utf8',
|
||||
@ -191,20 +181,38 @@ describe('core-client-provider', () => {
|
||||
const container = await startCli(configDirPath, toDispose);
|
||||
await assertFunctionalCli(
|
||||
container,
|
||||
async ({ coreClientProvider, boardsService, coreService }) => {
|
||||
async ({ coreClientProvider, boardsService }) => {
|
||||
const { indexUpdateSummaryBeforeInit } = coreClientProvider;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.not.undefined;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.empty;
|
||||
|
||||
// IDE2 cannot recover from a 3rd party package index issue.
|
||||
// Only when the primary package or library index is corrupt.
|
||||
// https://github.com/arduino/arduino-ide/issues/2021
|
||||
await coreService.updateIndex({ types: ['platform'] });
|
||||
|
||||
await assertTeensyAvailable(boardsService);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("should recover when invalid 3rd package URL is defined in the CLI config and the 'directories.data' folder is missing", async function () {
|
||||
this.timeout(timeout);
|
||||
const configDirPath = await prepareTestConfigDir();
|
||||
deleteSync(join(configDirPath, 'data'));
|
||||
|
||||
// set an invalid URL so the CLI will try to download it
|
||||
const cliConfigPath = join(configDirPath, 'arduino-cli.yaml');
|
||||
const rawYaml = await fs.readFile(cliConfigPath, { encoding: 'utf8' });
|
||||
const config: DefaultCliConfig = load(rawYaml);
|
||||
expect(config.board_manager).to.be.undefined;
|
||||
config.board_manager = { additional_urls: ['https://invalidUrl'] };
|
||||
expect(config.board_manager?.additional_urls?.[0]).to.be.equal(
|
||||
'https://invalidUrl'
|
||||
);
|
||||
await fs.writeFile(cliConfigPath, dump(config));
|
||||
|
||||
const container = await startCli(configDirPath, toDispose);
|
||||
await assertFunctionalCli(container, ({ coreClientProvider }) => {
|
||||
const { indexUpdateSummaryBeforeInit } = coreClientProvider;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.not.undefined;
|
||||
expect(indexUpdateSummaryBeforeInit).to.be.empty;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
interface Services {
|
||||
@ -277,7 +285,7 @@ async function prepareTestConfigDir(
|
||||
const params = { configDirPath: newTempConfigDirPath(), configOverrides };
|
||||
const container = await createContainer(params);
|
||||
const daemon = container.get<ArduinoDaemonImpl>(ArduinoDaemonImpl);
|
||||
const cliPath = await daemon.getExecPath();
|
||||
const cliPath = daemon.getExecPath();
|
||||
const configDirUriProvider =
|
||||
container.get<ConfigDirUriProvider>(ConfigDirUriProvider);
|
||||
const configDirPath = FileUri.fsPath(configDirUriProvider.configDirUri());
|
||||
|
@ -11,7 +11,7 @@ import {
|
||||
SketchesService,
|
||||
isCompileSummary,
|
||||
} from '../../common/protocol';
|
||||
import { createBaseContainer, startDaemon } from './test-bindings';
|
||||
import { createBaseContainer, startDaemon } from './node-test-bindings';
|
||||
|
||||
const testTimeout = 30_000;
|
||||
const setupTimeout = 5 * 60 * 1_000; // five minutes
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { expect } from 'chai';
|
||||
import { Port } from '../../node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import {
|
||||
PortIdentifier,
|
||||
portIdentifierEquals,
|
||||
Port,
|
||||
} from '../../common/protocol/boards-service';
|
||||
import { Port as RpcPort } from '../../node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import { CoreServiceImpl } from '../../node/core-service-impl';
|
||||
|
||||
describe('core-service-impl', () => {
|
||||
@ -22,9 +27,18 @@ describe('core-service-impl', () => {
|
||||
protocolLabel: 'serial port',
|
||||
properties,
|
||||
} as const;
|
||||
const actual = new CoreServiceImpl()['createPort'](port);
|
||||
const resolve = (toResolve: PortIdentifier): Port | undefined => {
|
||||
if (portIdentifierEquals(toResolve, port)) {
|
||||
return port;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
const actual = new CoreServiceImpl()['createPort'](
|
||||
{ protocol: port.protocol, address: port.address },
|
||||
resolve
|
||||
);
|
||||
expect(actual).to.be.not.undefined;
|
||||
const expected = new Port()
|
||||
const expected = new RpcPort()
|
||||
.setAddress(port.address)
|
||||
.setHardwareId(port.hardwareId)
|
||||
.setLabel(port.addressLabel)
|
||||
@ -33,7 +47,7 @@ describe('core-service-impl', () => {
|
||||
Object.entries(properties).forEach(([key, value]) =>
|
||||
expected.getPropertiesMap().set(key, value)
|
||||
);
|
||||
expect((<Port>actual).toObject(false)).to.be.deep.equal(
|
||||
expect((<RpcPort>actual).toObject(false)).to.be.deep.equal(
|
||||
expected.toObject(false)
|
||||
);
|
||||
});
|
||||
|
@ -2,7 +2,7 @@ import { DisposableCollection } from '@theia/core/lib/common/disposable';
|
||||
import { Container } from '@theia/core/shared/inversify';
|
||||
import { expect } from 'chai';
|
||||
import { LibrarySearch, LibraryService } from '../../common/protocol';
|
||||
import { createBaseContainer, startDaemon } from './test-bindings';
|
||||
import { createBaseContainer, startDaemon } from './node-test-bindings';
|
||||
|
||||
describe('library-service-impl', () => {
|
||||
let libraryService: LibraryService;
|
||||
|
@ -1,18 +1,9 @@
|
||||
import {
|
||||
CommandContribution,
|
||||
CommandRegistry,
|
||||
CommandService,
|
||||
} from '@theia/core/lib/common/command';
|
||||
import { bindContributionProvider } from '@theia/core/lib/common/contribution-provider';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { EnvVariablesServer as TheiaEnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||
import { ILogger, Loggable } from '@theia/core/lib/common/logger';
|
||||
import { LogLevel } from '@theia/core/lib/common/logger-protocol';
|
||||
import { waitForEvent } from '@theia/core/lib/common/promise-util';
|
||||
import { MockLogger } from '@theia/core/lib/common/test/mock-logger';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||
import { ProcessUtils } from '@theia/core/lib/node/process-utils';
|
||||
@ -23,19 +14,18 @@ import {
|
||||
interfaces,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import deepmerge from 'deepmerge';
|
||||
import { promises as fs, mkdirSync } from 'node:fs';
|
||||
import { dump as dumpYaml } from 'js-yaml';
|
||||
import { mkdirSync, promises as fs } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { path as tempPath, track } from 'temp';
|
||||
import {
|
||||
ArduinoDaemon,
|
||||
AttachedBoardsChangeEvent,
|
||||
AvailablePorts,
|
||||
BoardsPackage,
|
||||
BoardsService,
|
||||
ConfigService,
|
||||
ConfigState,
|
||||
CoreService,
|
||||
DetectedPorts,
|
||||
IndexUpdateDidCompleteParams,
|
||||
IndexUpdateDidFailParams,
|
||||
IndexUpdateParams,
|
||||
@ -52,7 +42,7 @@ import {
|
||||
import { ArduinoDaemonImpl } from '../../node/arduino-daemon-impl';
|
||||
import { BoardDiscovery } from '../../node/board-discovery';
|
||||
import { BoardsServiceImpl } from '../../node/boards-service-impl';
|
||||
import { CLI_CONFIG, CliConfig, DefaultCliConfig } from '../../node/cli-config';
|
||||
import { CliConfig, CLI_CONFIG, DefaultCliConfig } from '../../node/cli-config';
|
||||
import { ConfigServiceImpl } from '../../node/config-service-impl';
|
||||
import { CoreClientProvider } from '../../node/core-client-provider';
|
||||
import { CoreServiceImpl } from '../../node/core-service-impl';
|
||||
@ -70,87 +60,10 @@ import {
|
||||
ConfigDirUriProvider,
|
||||
EnvVariablesServer,
|
||||
} from '../../node/theia/env-variables/env-variables-server';
|
||||
import { bindCommon } from '../common/common-test-bindings';
|
||||
|
||||
const tracked = track();
|
||||
|
||||
@injectable()
|
||||
class ConsoleLogger extends MockLogger {
|
||||
override log(
|
||||
logLevel: number,
|
||||
arg2: string | Loggable | Error,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
if (arg2 instanceof Error) {
|
||||
return this.error(String(arg2), params);
|
||||
}
|
||||
switch (logLevel) {
|
||||
case LogLevel.INFO:
|
||||
return this.info(arg2, params);
|
||||
case LogLevel.WARN:
|
||||
return this.warn(arg2, params);
|
||||
case LogLevel.TRACE:
|
||||
return this.trace(arg2, params);
|
||||
case LogLevel.ERROR:
|
||||
return this.error(arg2, params);
|
||||
case LogLevel.FATAL:
|
||||
return this.fatal(arg2, params);
|
||||
default:
|
||||
return this.info(arg2, params);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
override async info(arg: string | Loggable, ...params: any[]): Promise<void> {
|
||||
if (params.length) {
|
||||
console.info(arg, ...params);
|
||||
} else {
|
||||
console.info(arg);
|
||||
}
|
||||
}
|
||||
|
||||
override async trace(
|
||||
arg: string | Loggable,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
if (params.length) {
|
||||
console.trace(arg, ...params);
|
||||
} else {
|
||||
console.trace(arg);
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
override async warn(arg: string | Loggable, ...params: any[]): Promise<void> {
|
||||
if (params.length) {
|
||||
console.warn(arg, ...params);
|
||||
} else {
|
||||
console.warn(arg);
|
||||
}
|
||||
}
|
||||
|
||||
override async error(
|
||||
arg: string | Loggable,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
if (params.length) {
|
||||
console.error(arg, ...params);
|
||||
} else {
|
||||
console.error(arg);
|
||||
}
|
||||
}
|
||||
|
||||
override async fatal(
|
||||
arg: string | Loggable,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
...params: any[]
|
||||
): Promise<void> {
|
||||
return this.error(arg, params);
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
class SilentArduinoDaemon extends ArduinoDaemonImpl {
|
||||
protected override onData(): void {
|
||||
@ -160,7 +73,7 @@ class SilentArduinoDaemon extends ArduinoDaemonImpl {
|
||||
|
||||
@injectable()
|
||||
class TestBoardDiscovery extends BoardDiscovery {
|
||||
mutableAvailablePorts: AvailablePorts = {};
|
||||
mutableDetectedPorts: DetectedPorts = {};
|
||||
|
||||
override async start(): Promise<void> {
|
||||
// NOOP
|
||||
@ -168,8 +81,8 @@ class TestBoardDiscovery extends BoardDiscovery {
|
||||
override async stop(): Promise<void> {
|
||||
// NOOP
|
||||
}
|
||||
override get availablePorts(): AvailablePorts {
|
||||
return this.mutableAvailablePorts;
|
||||
override get detectedPorts(): DetectedPorts {
|
||||
return this.mutableDetectedPorts;
|
||||
}
|
||||
}
|
||||
|
||||
@ -221,7 +134,7 @@ class TestNotificationServiceServer implements NotificationServiceServer {
|
||||
notifyLibraryDidUninstall(event: { item: LibraryPackage }): void {
|
||||
this.events.push(`notifyLibraryDidUninstall:${JSON.stringify(event)}`);
|
||||
}
|
||||
notifyAttachedBoardsDidChange(event: AttachedBoardsChangeEvent): void {
|
||||
notifyDetectedPortsDidChange(event: { detectedPorts: DetectedPorts }): void {
|
||||
this.events.push(`notifyAttachedBoardsDidChange:${JSON.stringify(event)}`);
|
||||
}
|
||||
notifyRecentSketchesDidChange(event: { sketches: Sketch[] }): void {
|
||||
@ -309,6 +222,7 @@ export async function createBaseContainer(
|
||||
}
|
||||
const container = new Container({ defaultScope: 'Singleton' });
|
||||
const module = new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bindCommon(bind);
|
||||
bind(CoreClientProvider).toSelf().inSingletonScope();
|
||||
bind(CoreServiceImpl).toSelf().inSingletonScope();
|
||||
bind(CoreService).toService(CoreServiceImpl);
|
||||
@ -336,15 +250,10 @@ export async function createBaseContainer(
|
||||
bind(SilentArduinoDaemon).toSelf().inSingletonScope();
|
||||
bind(ArduinoDaemon).toService(SilentArduinoDaemon);
|
||||
bind(ArduinoDaemonImpl).toService(SilentArduinoDaemon);
|
||||
bind(ConsoleLogger).toSelf().inSingletonScope();
|
||||
bind(ILogger).toService(ConsoleLogger);
|
||||
bind(TestNotificationServiceServer).toSelf().inSingletonScope();
|
||||
bind(NotificationServiceServer).toService(TestNotificationServiceServer);
|
||||
bind(ConfigServiceImpl).toSelf().inSingletonScope();
|
||||
bind(ConfigService).toService(ConfigServiceImpl);
|
||||
bind(CommandRegistry).toSelf().inSingletonScope();
|
||||
bind(CommandService).toService(CommandRegistry);
|
||||
bindContributionProvider(bind, CommandContribution);
|
||||
bind(TestBoardDiscovery).toSelf().inSingletonScope();
|
||||
bind(BoardDiscovery).toService(TestBoardDiscovery);
|
||||
bind(IsTempSketch).toSelf().inSingletonScope();
|
@ -12,7 +12,7 @@ import { sync as rimrafSync } from 'rimraf';
|
||||
import { Sketch, SketchesService } from '../../common/protocol';
|
||||
import { SketchesServiceImpl } from '../../node/sketches-service-impl';
|
||||
import { ErrnoException } from '../../node/utils/errors';
|
||||
import { createBaseContainer, startDaemon } from './test-bindings';
|
||||
import { createBaseContainer, startDaemon } from './node-test-bindings';
|
||||
|
||||
const testTimeout = 10_000;
|
||||
|
||||
|
13
i18n/en.json
13
i18n/en.json
@ -18,24 +18,21 @@
|
||||
"configDialog1": "Select both a Board and a Port if you want to upload a sketch.",
|
||||
"configDialog2": "If you only select a Board you will be able to compile, but not to upload your sketch.",
|
||||
"couldNotFindPreviouslySelected": "Could not find previously selected board '{0}' in installed platform '{1}'. Please manually reselect the board you want to use. Do you want to reselect it now?",
|
||||
"disconnected": "Disconnected",
|
||||
"editBoardsConfig": "Edit Board and Port...",
|
||||
"getBoardInfo": "Get Board Info",
|
||||
"inSketchbook": " (in Sketchbook)",
|
||||
"installNow": "The \"{0} {1}\" core has to be installed for the currently selected \"{2}\" board. Do you want to install it now?",
|
||||
"noBoardsFound": "No boards found for \"{0}\"",
|
||||
"noFQBN": "The FQBN is not available for the selected board \"{0}\". Do you have the corresponding core installed?",
|
||||
"noNativeSerialPort": "Native serial port, can't obtain info.",
|
||||
"noPortsDiscovered": "No ports discovered",
|
||||
"noPortsSelected": "No ports selected for board: '{0}'.",
|
||||
"nonSerialPort": "Non-serial port, can't obtain info.",
|
||||
"noneSelected": "No boards selected.",
|
||||
"openBoardsConfig": "Select other board and port…",
|
||||
"pleasePickBoard": "Please pick a board connected to the port you have selected.",
|
||||
"port": "Port{0}",
|
||||
"portLabel": "Port: {0}",
|
||||
"ports": "ports",
|
||||
"programmer": "Programmer",
|
||||
"reselectLater": "Reselect later",
|
||||
"revertBoardsConfig": "Use '{0}' discovered on '{1}'",
|
||||
"searchBoard": "Search board",
|
||||
"selectBoard": "Select Board",
|
||||
"selectPortForInfo": "Please select a port to obtain board info.",
|
||||
@ -44,6 +41,7 @@
|
||||
"succesfullyInstalledPlatform": "Successfully installed platform {0}:{1}",
|
||||
"succesfullyUninstalledPlatform": "Successfully uninstalled platform {0}:{1}",
|
||||
"typeOfPorts": "{0} ports",
|
||||
"unconfirmedBoard": "Unconfirmed board",
|
||||
"unknownBoard": "Unknown board"
|
||||
},
|
||||
"boardsManager": "Boards Manager",
|
||||
@ -215,6 +213,11 @@
|
||||
"optimizeForDebugging": "Optimize for Debugging",
|
||||
"sketchIsNotCompiled": "Sketch '{0}' must be verified before starting a debug session. Please verify the sketch and start debugging again. Do you want to verify the sketch now?"
|
||||
},
|
||||
"developer": {
|
||||
"clearBoardList": "Clear the Board List History",
|
||||
"clearBoardsConfig": "Clear the Board and Port Selection",
|
||||
"dumpBoardList": "Dump the Board List"
|
||||
},
|
||||
"dialog": {
|
||||
"dontAskAgain": "Don't ask again"
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user