Compare commits

..

57 Commits

Author SHA1 Message Date
Francesco Stasi
cd0f1b3163 Updated to 2.0.0-beta.6 2021-05-12 12:20:55 +02:00
Francesco Stasi
4fa2024266 [atl-1280] Board packages hints
handle cornercase when 2 packages are associated to the same board

updated cli version and grpc

support deprecated cores in the boards manager

bump cli version

Bump ArduinoCLI version to latest release

Add package version in notification
2021-05-11 14:07:54 +02:00
Francesco Stasi
852bf9b73e https://arduino.atlassian.net/browse/ATL-1247 2021-05-11 13:50:27 +02:00
Francesco Stasi
db48ed616b https://arduino.atlassian.net/browse/ATL-1222 2021-05-05 17:44:10 +02:00
per1234
0dd1e45233 Correct sketchbook folder selection button text
The previous text used past tense, which is not appropriate for a button.
2021-04-27 07:29:48 -07:00
Akos Kitta
2a55ddd757 Updated to 2.0.0-beta.5.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-15 12:40:49 +02:00
Akos Kitta
3240bf7f3d [dev]: Fixed the launch config.
So that the IDE correctly loads the VS Code extensions.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
0d0ad9efae Workarond for arduino/arduino-cli#1262.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
9aff90b0af ATL-786: Progress indication for install.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
8071298598 Updated to the 0.18.1 CLI.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
c86d82d273 ATL-1206: Reuse selected board for new sketches.
Closes #95.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
fa9334eb7a ATL-1207: Open editor if file was added to sketch.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
c50d45c663 GH-297: Fixed the open from Sketchbook handler.
When running the handler for the `Sketchbook` menu, do not clone the
sketch.

Closes #297

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
c20f832ddf Notify user if platform/lib install was successful
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
cb2ef78c0a ATL-1195: Show all libraries if no board selected.
Like for the examples, we show all libraries if no board is selected,
or the platform for the selected board is not installed.
Otherwise, we show the libs for the current board.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
68af4c38fe ATL-1195: Show examples if no board is selected.
Show all examples:
 - when no board is selected,
 - when the core is not installed for the selected board.

Otherwise, show examples for the currently selected board only.
Only get libraries from the cores when the FQBN is defined.
Otherwise, we retrieve user installed libraries only.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-04-14 17:44:06 +02:00
Akos Kitta
a8df2444a9 ATL-1145: Suppress error if Git is not on $PATH.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 19:14:56 +02:00
Francesco Stasi
d45dd6beef ATL-1151: settings panel to reflect actual state 2021-03-31 16:35:50 +02:00
Francesco Stasi
1ab5634789 ATL-970: notifications should last longer 2021-03-31 16:29:50 +02:00
Akos Kitta
80bddc238d ATL-988: Aligned the hover size to the expression.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 15:20:56 +02:00
Akos Kitta
8a692d0ce5 ATL-1068: Escape ampersand in the menu label.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 15:20:56 +02:00
Akos Kitta
98671225ac Can edit user-storage files. E.g.: keymaps.json.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 13:47:25 +02:00
Akos Kitta
f106c97f1e Fixed bug when no 3rd party URLs are defined.
Instead of adding an empty string URL, we add nothing.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 13:47:25 +02:00
Akos Kitta
369a8f4307 Update index after modifying the 3rd party URLs.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 13:47:25 +02:00
Akos Kitta
4e7f8291e8 Removed the min window height and width.
Made the boards config dialog slightly smaller.

Closes #216.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 13:47:25 +02:00
Akos Kitta
26a1db3cf8 ATL-1137: Show error when could not connect to CLI
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-31 13:46:04 +02:00
Francesco Stasi
a3f7b795a0 ATL-1128: make the new tab button easier to click 2021-03-30 09:54:57 +02:00
Francesco Stasi
b422fc5298 chore: update CLI version, gRPC and bit of documentation 2021-03-29 14:05:56 +02:00
Akos Kitta
ab320eb0b0 GH-259: Use Ubuntu 18.04 for the build job.
Closes #259

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-29 12:39:46 +02:00
Francesco Stasi
b17b7a6de7 ATL-1136: Add .adoc and .md file support 2021-03-29 10:03:51 +02:00
Francesco Stasi
562b77aec3 Add keymaps customization support 2021-03-26 15:33:38 +01:00
Akos Kitta
cdd5cfdfc1 ATL-1150: Bumped the cortex-debug to 0.3.10.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-25 18:46:34 +01:00
Akos Kitta
f712ec986f ATL-1106: Made all non-workspace editors read-only.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-25 16:45:44 +01:00
per1234
c75b954041 Update development documentation to reflect change in workflow artifacts
The "Arduino IDE" workflow was updated to produce individual artifacts for each operating system, but the development
documentation was not updated accordingly at that time.
2021-03-25 02:34:39 -07:00
per1234
3fb087f1ad Delete job transfer workflow artifact
The "Arduino IDE" GitHub Actions workflow uses a workflow artifact to transfer the build artifacts between jobs. Now that
separate tester build artifacts are produced, the monolithic job transfer artifact is superfluous once the workflow run
is finished. Deleting it avoids potential confusion for beta testers and unnecessary storage space usage.
2021-03-24 02:04:11 -07:00
per1234
27292774d7 Create separate tester artifacts for each build
Previously, a single workflow artifact was created by the "Arduino IDE" GitHub Actions workflow. This artifact contained
the builds for each operating system, including all three versions of the Windows build. This resulted in beta testers
needing to do a >1 GB download for every build, even though they likely needed only ~200 MB of what they downloaded.

Producing separate workflows makes it easier for beta testers to participate in the development and is less wasteful of
resources.
2021-03-24 02:04:11 -07:00
per1234
da424f34cc Don't use magic string for job transfer artifact name
Previously, the build CI/CD workflow had many occurrences of the string "build-artifacts" used for the workflow artifact
name. This made the workflow more difficult to understand and maintain. Now a single workflow scoped environment variable
is used to define the artifact name.
2021-03-24 02:04:11 -07:00
Sebastian Brzuzek
f6e623ca9c Fixed sorting of sketches and examples - ignore case
issue #185
2021-03-18 11:01:10 +01:00
Francesco Stasi
1e0f52bbdd Support toggled state in arduino toolbar items
fix hover state on toolbar items

Improved statemanagement for ToolbarItem and Menus

Disable Upload buttons while a sketch upload is already in progress

toggled state to have override disabled button opacity

doublecheck internal status before verify/upload a sketch

fixes after code review
2021-03-17 17:32:32 +01:00
Francesco Stasi
6dadd1775a editor.quicksSuggestions.other defaults off 2021-03-17 17:31:45 +01:00
Akos Kitta
067cc8766a Bumped version to 2.0.0-beta.4. Use CLI 0.17.0
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-17 17:29:00 +01:00
Akos Kitta
15b0564212 ATL-974: Use board search command from the CLI
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-17 11:41:25 +01:00
Francesco Stasi
e90fa27ebf move settings from sidebar to arduino pref panel
Improved preference Dialog UI
2021-03-17 10:47:53 +01:00
rsora
ef03d3f583 Disable code signing when workflows run from forks
- Skip Mac/Win code signing and Apple notarization only if PR comes from a fork
- Disable workflows entirely if the user enabled Github Actions in
their fork repo
- Add steps to help Mac users to test their forked code in BUILDING.md
2021-03-15 16:01:37 +01:00
Akos Kitta
5c8669d699 Added overwrite confirmation to ZIP lib install
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-15 11:21:58 +01:00
Akos Kitta
9cd91464e3 ATL-941: Fixed recursive folder issue on Save as
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-15 09:15:44 +01:00
Akos Kitta
5a262d42c1 ATL-1063: Integrated search in workspace into IDE
- Reordered the sidebar views.
 - Increased the default sidebar width.

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-15 09:15:18 +01:00
Akos Kitta
eadc993854 ATL-653: Added error handling for core/lib install
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-12 09:35:21 +01:00
Akos Kitta
c64ac48fe3 ATL-1064: Support for nested sketchbook structure
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-11 10:32:24 +01:00
per1234
ac502053d7 Add security policy link to readme 2021-03-09 00:20:39 -08:00
per1234
1d8eb0d544 Update ARM Linux links in download tables
The issue numbers changed when they were transferred from the arduino/arduino-pro-ide to arduino/arduino-ide repositories.
2021-03-08 23:51:04 -08:00
per1234
e94702349b Correct typo in gRPC client creation error message
Previously, when gRPC client creation failed, the incorrect error message was shown:

root ERROR Could create client for gRPC.

When the message is intended to have the opposite meaning.
2021-03-08 13:42:45 -08:00
Akos Kitta
d648159f43 ATL-972: Moved the './theia/launch.json' config into a temp folder.
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-04 11:53:37 +01:00
Akos Kitta
acbd98d0f8 Fixed workspace variable resolver.
Fall back to the current sketch, if `currentWidget` points to a file
outside of the workspace.

Closes: arduino/arduino-ide#46

Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-03-03 11:53:20 +01:00
Alessandro Ranellucci
22e02e19b8 Update README before making the repository public (#49)
* Update README

* Some more changes to README

* Add anchor to link to Arduino Software Download page Section for IDE 2.0

Co-authored-by: Roberto Sora <r.sora@arduino.cc>
2021-03-01 15:59:23 +01:00
Akos Kitta
7ee6d5ad8f Use vscode-arduino-tools VSX.
Ref: arduino/vscode-arduino-tools#14
Signed-off-by: Akos Kitta <kittaakos@typefox.io>
2021-02-26 19:03:37 +01:00
Silvano Cerza
19aa3dd8a5 Update package.json license identifier 2021-02-26 14:54:10 +01:00
159 changed files with 18450 additions and 15995 deletions

View File

@@ -13,14 +13,18 @@ on:
schedule:
- cron: '0 3 * * *' # run every day at 3AM (https://docs.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule)
env:
JOB_TRANSFER_ARTIFACT: build-artifacts
jobs:
build:
if: github.repository == 'arduino/arduino-ide'
strategy:
matrix:
config:
- os: windows-latest
- os: ubuntu-latest
- os: ubuntu-18.04 # https://github.com/arduino/arduino-ide/issues/259
- os: macos-latest
runs-on: ${{ matrix.config.os }}
timeout-minutes: 90
@@ -50,21 +54,26 @@ jobs:
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
IS_NIGHTLY: ${{ github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') }}
IS_RELEASE: ${{ startsWith(github.ref, 'refs/tags/') }}
IS_FORK: ${{ github.event.pull_request.head.repo.fork == true }}
run: |
# See: https://www.electron.build/code-signing
if [ "${{ runner.OS }}" = "macOS" ]; then
export CSC_LINK="${{ runner.temp }}/signing_certificate.p12"
# APPLE_SIGNING_CERTIFICATE_P12 secret was produced by following the procedure from:
# https://www.kencochrane.com/2020/08/01/build-and-sign-golang-binaries-for-macos-with-github-actions/#exporting-the-developer-certificate
echo "${{ secrets.APPLE_SIGNING_CERTIFICATE_P12 }}" | base64 --decode > "$CSC_LINK"
if [ $IS_FORK = true ]; then
echo "Skipping the app signing: building from a fork."
else
if [ "${{ runner.OS }}" = "macOS" ]; then
export CSC_LINK="${{ runner.temp }}/signing_certificate.p12"
# APPLE_SIGNING_CERTIFICATE_P12 secret was produced by following the procedure from:
# https://www.kencochrane.com/2020/08/01/build-and-sign-golang-binaries-for-macos-with-github-actions/#exporting-the-developer-certificate
echo "${{ secrets.APPLE_SIGNING_CERTIFICATE_P12 }}" | base64 --decode > "$CSC_LINK"
export CSC_KEY_PASSWORD="${{ secrets.KEYCHAIN_PASSWORD }}"
export CSC_KEY_PASSWORD="${{ secrets.KEYCHAIN_PASSWORD }}"
elif [ "${{ runner.OS }}" = "Windows" ]; then
export CSC_LINK="${{ runner.temp }}/signing_certificate.pfx"
echo "${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PFX }}" | base64 --decode > "$CSC_LINK"
elif [ "${{ runner.OS }}" = "Windows" ]; then
export CSC_LINK="${{ runner.temp }}/signing_certificate.pfx"
echo "${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PFX }}" | base64 --decode > "$CSC_LINK"
export CSC_KEY_PASSWORD="${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}"
export CSC_KEY_PASSWORD="${{ secrets.WINDOWS_SIGNING_CERTIFICATE_PASSWORD }}"
fi
fi
yarn --cwd ./electron/packager/
@@ -73,9 +82,42 @@ jobs:
- name: Upload [GitHub Actions]
uses: actions/upload-artifact@v2
with:
name: build-artifacts
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
path: electron/build/dist/build-artifacts/
artifacts:
name: ${{ matrix.artifact.name }} artifact
needs: build
if: always() && needs.build.result != 'skipped'
runs-on: ubuntu-latest
strategy:
matrix:
artifact:
- path: "*Linux_64bit.zip"
name: Linux_X86-64
- path: "*macOS_64bit.dmg"
name: macOS
- path: "*Windows_64bit.exe"
name: Windows_X86-64_interactive_installer
- path: "*Windows_64bit.msi"
name: Windows_X86-64_MSI
- path: "*Windows_64bit.zip"
name: Windows_X86-64_zip
steps:
- name: Download job transfer artifact
uses: actions/download-artifact@v2
with:
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
- name: Upload tester build artifact
uses: actions/upload-artifact@v2
with:
name: ${{ matrix.artifact.name }}
path: ${{ env.JOB_TRANSFER_ARTIFACT }}/${{ matrix.artifact.path }}
changelog:
needs: build
runs-on: ubuntu-latest
@@ -115,25 +157,25 @@ jobs:
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')
uses: actions/upload-artifact@v2
with:
name: build-artifacts
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
path: CHANGELOG.txt
publish:
needs: changelog
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')
if: github.repository == 'arduino/arduino-ide' && (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main'))
runs-on: ubuntu-latest
steps:
- name: Download [GitHub Actions]
uses: actions/download-artifact@v2
with:
name: build-artifacts
path: build-artifacts
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
- name: Publish Nightly [S3]
uses: docker://plugins/s3
env:
PLUGIN_SOURCE: "build-artifacts/*"
PLUGIN_STRIP_PREFIX: "build-artifacts/"
PLUGIN_SOURCE: "${{ env.JOB_TRANSFER_ARTIFACT }}/*"
PLUGIN_STRIP_PREFIX: "${{ env.JOB_TRANSFER_ARTIFACT }}/"
PLUGIN_TARGET: "/arduino-ide/nightly"
PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
@@ -141,14 +183,14 @@ jobs:
release:
needs: changelog
if: startsWith(github.ref, 'refs/tags/')
if: github.repository == 'arduino/arduino-ide' && startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- name: Download [GitHub Actions]
uses: actions/download-artifact@v2
with:
name: build-artifacts
path: build-artifacts
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
- name: Get Tag
id: tag_name
@@ -160,7 +202,7 @@ jobs:
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
release_name: ${{ steps.tag_name.outputs.TAG_NAME }}
file: build-artifacts/*
file: ${{ env.JOB_TRANSFER_ARTIFACT }}/*
tag: ${{ github.ref }}
file_glob: true
body: ${{ needs.changelog.outputs.BODY }}
@@ -168,9 +210,25 @@ jobs:
- name: Publish Release [S3]
uses: docker://plugins/s3
env:
PLUGIN_SOURCE: "build-artifacts/*"
PLUGIN_STRIP_PREFIX: "build-artifacts/"
PLUGIN_SOURCE: "${{ env.JOB_TRANSFER_ARTIFACT }}/*"
PLUGIN_STRIP_PREFIX: "${{ env.JOB_TRANSFER_ARTIFACT }}/"
PLUGIN_TARGET: "/arduino-ide"
PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
clean:
# This job must run after all jobs that use the transfer artifact.
needs:
- build
- publish
- release
- artifacts
if: always() && needs.build.result != 'skipped'
runs-on: ubuntu-latest
steps:
- name: Remove unneeded job transfer artifact
uses: geekyeggo/delete-artifact@v1
with:
name: ${{ env.JOB_TRANSFER_ARTIFACT }}

View File

@@ -15,6 +15,11 @@ env:
jobs:
check-certificates:
# Only run when the workflow will have access to the certificate secrets.
if: >
(github.event_name != 'pull_request' && github.repository == 'arduino/arduino-ide') ||
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'arduino/arduino-ide')
runs-on: ubuntu-latest
strategy:

6
.vscode/launch.json vendored
View File

@@ -29,15 +29,17 @@
"NODE_PRESERVE_SYMLINKS": "1"
}
},
"program": "${workspaceRoot}/electron-app/src-gen/frontend/electron-main.js",
"cwd": "${workspaceFolder}/electron-app",
"protocol": "inspector",
"args": [
".",
"--log-level=debug",
"--hostname=localhost",
"--no-cluster",
"--app-project-path=${workspaceRoot}/electron-app",
"--remote-debugging-port=9222",
"--no-app-auto-install",
"--plugins=local-dir:plugins"
"--plugins=local-dir:../plugins"
],
"env": {
"NODE_ENV": "development"

136
BUILDING.md Normal file
View File

@@ -0,0 +1,136 @@
# Development
This page includes technical documentation for developers who want to build the IDE locally and contribute to the project.
## Architecture overview
The IDE consists of three major parts:
- the _Electron main_ process,
- the _backend_, and
- the _frontend_.
The _Electron main_ process is responsible for:
- creating the application,
- managing the application lifecycle via listeners, and
- creating and managing the web pages for the app.
In Electron, the process that runs the main entry JavaScript file is called the main process. The _Electron main_ process can display a GUI by creating web pages. An Electron app always has exactly on main process.
By default, whenever the _Electron main_ process creates a web page, it will instantiate a new `BrowserWindow` instance. Since Electron uses Chromium for displaying web pages, Chromium's multi-process architecture is also used. Each web page in Electron runs in its own process, which is called the renderer process. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process is also terminated. The main process manages all web pages and their corresponding renderer processes. Each renderer process is isolated and only cares about the web page running in it.<sup>[[1]]</sup>
In normal browsers, web pages usually run in a sandboxed environment, and accessing native resources are disallowed. However, Electron has the power to use Node.js APIs in the web pages allowing lower-level OS interactions. Due to security reasons, accessing native resources is an undesired behavior in the IDE. So by convention, we do not use Node.js APIs. (Note: the Node.js integration is [not yet disabled](https://github.com/eclipse-theia/theia/issues/2018) although it is not used). In the IDE, only the _backend_ allows OS interaction.
The _backend_ process is responsible for:
- providing access to the filesystem,
- communicating with the [Arduino CLI](https://github.com/arduino/arduino-cli) via gRPC,
- running your terminal,
- exposing additional RESTful APIs,
- performing the Git commands in the local repositories,
- hosting and running any VS Code extensions, or
- executing VS Code tasks<sup>[[2]]</sup>.
The _Electron main_ process spawns the _backend_ process. There is always exactly one _backend_ process. However, due to performance considerations, the _backend_ spawns several sub-processes for the filesystem watching, Git repository discovery, etc. The communication between the _backend_ process and its sub-processes is established via IPC. Besides spawning sub-processes, the _backend_ will start an HTTP server on a random available port, and serves the web application as static content. When the sub-processes are up and running, and the HTTP server is also listening, the _backend_ process sends the HTTP server port to the _Electron main_ process via IPC. The _Electron main_ process will load the _backend_'s endpoint in the `BrowserWindow`.
The _frontend_ is running as an Electron renderer process and can invoke services implemented on the _backend_. The communication between the _backend_ and the _frontend_ is done via JSON-RPC over a websocket connection. This means, the services running in the _frontend_ are all proxies, and will ask the corresponding service implementation on the _backend_.
[1]: https://www.electronjs.org/docs/tutorial/application-architecture#differences-between-main-process-and-renderer-process
[2]: https://code.visualstudio.com/Docs/editor/tasks
## Build from source
If youre familiar with TypeScript, the [Theia IDE](https://theia-ide.org/), and if you want to contribute to the
project, you should be able to build the Arduino IDE locally. Please refer to the [Theia IDE prerequisites](https://github.com/theia-ide/theia/blob/master/doc/) documentation for the setup instructions.
### Build
```sh
yarn
```
### Rebuild the native dependencies
```sh
yarn rebuild:electron
```
### Start
```sh
yarn start
```
### CI
This project is built on [GitHub Actions](https://github.com/arduino/arduino-ide/actions).
- _Snapshot_ builds run when changes are pushed to the `main` branch, or when a PR is created against the `main` branch. For the sake of the review and verification process, the build artifacts for each operating system can be downloaded from the GitHub Actions page.
- _Nightly_ builds run every day at 03:00 GMT from the `main` branch.
- _Release_ builds run when a new tag is pushed to the remote. The tag must follow the [semver](https://semver.org/). For instance, `1.2.3` is a correct tag, but `v2.3.4` won't work. Steps to trigger a new release build:
- Create a local tag:
```sh
git tag -a 1.2.3 -m "Creating a new tag for the `1.2.3` release."
```
- Push it to the remote:
```sh
git push origin 1.2.3
```
## Notes for macOS contributors
Beginning in macOS 10.14.5, the software [must be notarized to run](https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution). The signing and notarization processes for the Arduino IDE are managed by our Continuous Integration (CI) workflows, implemented with GitHub Actions. On every push and pull request, the Arduino IDE is built and saved to a workflow artifact. These artifacts can be used by contributors and beta testers who don't want to set up a build system locally.
For security reasons, signing and notarization are disabled for workflow runs for pull requests from forks of this repository. This means that macOS will block you from running those artifacts.
Due to this limitation, Mac users have two options for testing contributions from forks:
### The Safe approach (recommended)
Follow [the instructions above](#build-from-source) to create the build environment locally, then build the code you want to test.
### The Risky approach
*Please note that this approach is risky as you are lowering the security on your system, therefore we strongly discourage you from following it.*
1. Use [this guide](https://help.apple.com/xcode/mac/10.2/index.html?localePath=en.lproj#/dev9b7736b0e), in order to disable Gatekeeper (at your own risk!).
1. Download the unsigned artifact provided by the CI workflow run related to the Pull Request at each push.
1. Re-enable Gatekeeper after tests are done, following the guide linked above.
### Creating a release
You will not need to create a new release yourself as the Arduino team takes care of this on a regular basis, but we are documenting the process here. Let's assume the current version is `0.1.3` and you want to release `0.2.0`.
- Make sure the `main` state represents what you want to release and you're on `main`.
- Prepare a release-candidate build on a branch:
```bash
git branch 0.2.0-rc \
&& git checkout 0.2.0-rc
```
- Bump up the version number. It must be a valid [semver](https://semver.org/) and must be greater than the current one:
```bash
yarn update:version 0.2.0
```
- This should generate multiple outgoing changes with the version update.
- Commit your changes and push to the remote:
```bash
git add . \
&& git commit -s -m "Updated versions to 0.2.0" \
&& git push
```
- Create the GH PR the workflow starts automatically.
- Once you're happy with the RC, merge the changes to the `main`.
- Create a tag and push it:
```bash
git tag -a 0.2.0 -m "0.2.0" \
&& git push origin 0.2.0
```
- The release build starts automatically and uploads the artifacts with the changelog to the [release page](https://github.com/arduino/arduino-ide/releases).
- If you do not want to release the `EXE` and `MSI` installers, wipe them manually.
- If you do not like the generated changelog, modify it and update the GH release.
## FAQ
* *Can I manually change the version of the [`arduino-cli`](https://github.com/arduino/arduino-cli/) used by the IDE?*
Yes. It is possible but not recommended. The CLI exposes a set of functionality via [gRPC](https://github.com/arduino/arduino-cli/tree/master/rpc) and the IDE uses this API to communicate with the CLI. Before we build a new version of IDE, we pin a specific version of CLI and use the corresponding `proto` files to generate TypeScript modules for gRPC. This means, a particular version of IDE is compliant only with the pinned version of CLI. Mismatching IDE and CLI versions might not be able to communicate with each other. This could cause unpredictable IDE behavior.
* *I have understood that not all versions of the CLI are compatible with my version of IDE but how can I manually update the `arduino-cli` inside the IDE?*
[Get](https://arduino.github.io/arduino-cli/installation) the desired version of `arduino-cli` for your platform and manually replace the one inside the IDE. The CLI can be found inside the IDE at:
- Windows: `C:\path\to\Arduino IDE\resources\app\node_modules\arduino-ide-extension\build\arduino-cli.exe`,
- macOS: `/path/to/Arduino IDE.app/Contents/Resources/app/node_modules/arduino-ide-extension/build/arduino-cli`, and
- Linux: `/path/to/Arduino IDE/resources/app/node_modules/arduino-ide-extension/build/arduino-cli`.

156
README.md
View File

@@ -1,36 +1,24 @@
# Arduino IDE
<img src="https://content.arduino.cc/website/Arduino_logo_teal.svg" height="100" align="right" />
# Arduino IDE 2.x (beta)
[![Arduino IDE](https://github.com/arduino/arduino-ide/workflows/Arduino%20IDE/badge.svg)](https://github.com/arduino/arduino-ide/actions?query=workflow%3A%22Arduino+IDE%22)
### Download
This repository contains the source code of the Arduino IDE 2.x, which is currently in beta stage. If you're looking for the stable IDE, go to the repository of the 1.x version at https://github.com/arduino/Arduino.
You can download the latest version of the Arduino IDE application for the supported platforms from the [GitHub release page](https://github.com/arduino/arduino-ide/releases) or following the links in the following table.
The Arduino IDE 2.x is a major rewrite, sharing no code with the IDE 1.x. It is based on the [Theia IDE](https://theia-ide.org/) framework and built with [Electron](https://www.electronjs.org/). The backend operations such as compilation and uploading are offloaded to an [arduino-cli](https://github.com/arduino/arduino-cli) instance running in daemon mode. This new IDE was developed with the goal of preserving the same interface and user experience of the previous major version in order to provide a frictionless upgrade.
#### Latest version
> ⚠️ This is **beta** software. Help us test it!
Platform | 32 bit | 64 bit |
--------- | ------------------------ | ------------------------------------------------------------------------------ |
Linux | | [Linux 64 bit] |
Linux ARM | [🚧 Work in progress...] | [🚧 Work in progress...] |
Windows | | [Windows 64 bit installer]<br />[Windows 64 bit MSI]<br />[Windows 64 bit ZIP] |
macOS | | [macOS 64 bit] |
![](static/screenshot.png)
[🚧 Work in progress...]: https://github.com/arduino/arduino-ide/issues/287
[Linux 64 bit]: https://downloads.arduino.cc/arduino-ide/arduino-ide_latest_Linux_64bit.zip
[Windows 64 bit installer]: https://downloads.arduino.cc/arduino-ide/arduino-ide_latest_Windows_64bit.exe
[Windows 64 bit MSI]: https://downloads.arduino.cc/arduino-ide/arduino-ide_latest_Windows_64bit.msi
[Windows 64 bit ZIP]: https://downloads.arduino.cc/arduino-ide/arduino-ide_latest_Windows_64bit.zip
[macOS 64 bit]: https://downloads.arduino.cc/arduino-ide/arduino-ide_latest_macOS_64bit.dmg
## Download
#### Previous versions
These are available from the [GitHub releases page](https://github.com/arduino/arduino-ide/releases).
#### Nightly builds
You can download the latest version from the [software download page on the Arduino website](https://www.arduino.cc/en/software#experimental-software).
### Nightly builds
These builds are generated every day at 03:00 GMT from the `main` branch and
should be considered unstable. In order to get the latest nightly build
available for the supported platform, use the following links:
should be considered unstable:
Platform | 32 bit | 64 bit |
--------- | ------------------------ | ------------------------------------------------------------------------------------------------------ |
@@ -39,7 +27,7 @@ Linux ARM | [🚧 Work in progress...] | [🚧 Work in progress...]
Windows | | [Nightly Windows 64 bit installer]<br />[Nightly Windows 64 bit MSI]<br />[Nightly Windows 64 bit ZIP] |
macOS | | [Nightly macOS 64 bit] |
[🚧 Work in progress...]: https://github.com/arduino/arduino-ide/issues/287
[🚧 Work in progress...]: https://github.com/arduino/arduino-ide/issues/107
[Nightly Linux 64 bit]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Linux_64bit.zip
[Nightly Windows 64 bit installer]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Windows_64bit.exe
[Nightly Windows 64 bit MSI]: https://downloads.arduino.cc/arduino-ide/nightly/arduino-ide_nightly-latest_Windows_64bit.msi
@@ -49,117 +37,41 @@ macOS | | [Nightly macOS 64 bit]
> These links return an HTTP `302: Found` response, redirecting to latest
generated builds by replacing `latest` with the latest available build
date, using the format YYYYMMDD (i.e for 2019/Aug/06 `latest` is
replaced with `20190806` )
replaced with `20190806`)
### Build from source
## Support
If youre familiar with TypeScript, the [Theia IDE](https://theia-ide.org/), and if you want to contribute to the
project, you should be able to build the Arduino IDE locally. Please refer to the [Theia IDE prerequisites](https://github.com/theia-ide/theia/blob/master/doc/) documentation for the setup instructions.
If you need assistance, see the [Help Center](https://support.arduino.cc/hc/en-us/categories/360002212660-Software-and-Downloads) and browse the [forum](https://forum.arduino.cc/index.php?board=150.0).
### Build
```sh
yarn
```
## Bugs & Issues
### Rebuild the native dependencies
```sh
yarn rebuild:electron
```
If you want to report an issue, you can submit it to the [issue tracker](https://github.com/arduino/arduino-ide/issues) of this repository. A few rules apply:
### Start
```sh
yarn start
```
* Before posting, please check if the same problem has been already reported by someone else to avoid duplicates.
* Remember to include as much detail as you can about your hardware set-up, code and steps for reproducing the issue. Make sure you're using an original Arduino board.
### CI
### Security
This project is built on [GitHub Actions](https://github.com/bcmi-labs/arduino-editor/actions?query=workflow%3A%22Arduino+Pro+IDE%22).
If you think you found a vulnerability or other security-related bug in this project, please read our
[security policy](https://github.com/arduino/arduino-ide/security/policy) and report the bug to our Security Team 🛡️
Thank you!
- _Snapshot_ builds run when changes are pushed to the `main` branch, or when a PR is created against the `main` branch. For the sake of the review and verification process, the build artifacts can be downloaded from the GitHub Actions page. Note: [due to a limitation](https://github.com/actions/upload-artifact/issues/80#issuecomment-630030144) with the GH Actions UI, you cannot download a particular build, but you have to get all together inside the `build-artifacts.zip`.
- _Nightly_ builds run every day at 03:00 GMT from the `main` branch.
- _Release_ builds run when a new tag is pushed to the remote. The tag must follow the [semver](https://semver.org/). For instance, `1.2.3` is a correct tag, but `v2.3.4` won't work. Steps to trigger a new release build:
- Create a local tag:
```sh
git tag -a 1.2.3 -m "Creating a new tag for the `1.2.3` release."
```
- Push it to the remote:
```sh
git push origin 1.2.3
```
e-mail contact: security@arduino.cc
### Creating a GH release
This section guides you through how to create a new release. Let's assume the current version is `0.1.3` and you want to release `0.2.0`.
## Contributions and development
- Make sure the `main` state represents what you want to release and you're on `main`.
- Prepare a release-candidate build on a branch:
```bash
git branch 0.2.0-rc \
&& git checkout 0.2.0-rc
```
- Bump up the version number. It must be a valid [semver](https://semver.org/) and must be greater than the current one:
```bash
yarn update:version 0.2.0
```
- This should generate multiple outgoing changes with the version update.
- Commit your changes and push to the remote:
```bash
git add . \
&& git commit -s -m "Updated versions to 0.2.0" \
&& git push
```
- Create the GH PR the workflow starts automatically.
- Once you're happy with the RC, merge the changes to the `main`.
- Create a tag and push it:
```bash
git tag -a 0.2.0 -m "0.2.0" \
&& git push origin 0.2.0
```
- The release build starts automatically and uploads the artifacts with the changelog to the Pro IDE [release page](https://github.com/arduino/arduino-ide/releases).
- If you do not want to release the `EXE` and `MSI` installers, wipe them manually.
- If you do not like the generated changelog, modify it and update the GH release.
Contributions are very welcome! You can browse the list of open issues to see what's needed and then you can submit your code using a Pull Request. Please provide detailed descriptions. We also appreciate any help in testing issues and patches contributed by other users.
This repository contains the main code, but two more repositories are included during the build process:
### FAQ
* [vscode-arduino-tools](https://github.com/arduino/vscode-arduino-tools): provides support for the language server and the debugger
* [arduino-language-server](https://github.com/arduino/arduino-language-server): provides the language server that parses Arduino code
- Q: Can I manually change the version of the [`arduino-cli`](https://github.com/arduino/arduino-cli/) used by the IDE?
- A: Yes. It is possible but not recommended. The CLI exposes a set of functionality via [gRPC](https://github.com/arduino/arduino-cli/tree/master/rpc) and the IDE uses this API to communicate with the CLI. Before we build a new version of IDE, we pin a specific version of CLI and use the corresponding `proto` files to generate TypeScript modules for gRPC. This means, a particular version of IDE is compliant only with the pinned version of CLI. Mismatching IDE and CLI versions might not be able to communicate with each other. This could cause unpredictable IDE behavior.
See the [BUILDING.md](BUILDING.md) for a technical overview of the application and instructions for building the code.
## Donations
- Q: I have understood that not all versions of the CLI is compatible with my version of IDE but how can I manually update the `arduino-cli` inside the IDE?
- A: [Get](https://arduino.github.io/arduino-cli/installation) the desired version of `arduino-cli` for your platform and manually replace the one inside the IDE. The CLI can be found inside the IDE at:
- Windows: `C:\path\to\Arduino IDE\resources\app\node_modules\arduino-ide-extension\build\arduino-cli.exe`,
- macOS: `/path/to/Arduino IDE.app/Contents/Resources/app/node_modules/arduino-ide-extension/build/arduino-cli`, and
- Linux: `/path/to/Arduino IDE/resources/app/node_modules/arduino-ide-extension/build/arduino-cli`.
This open source code was written by the Arduino team and is maintained on a daily basis with the help of the community. We invest a considerable amount of time in development, testing and optimization. Please consider [donating](https://www.arduino.cc/en/donate/) or [sponsoring](https://github.com/sponsors/arduino) to support our work, as well as [buying original Arduino boards](https://store.arduino.cc/) which is the best way to make sure our effort can continue in the long term.
### Architecture overview
## License
The Pro IDE consists of three major parts:
- the _Electron main_ process,
- the _backend_, and
- the _frontend_.
The _Electron main_ process is responsible for:
- creating the application,
- managing the application lifecycle via listeners, and
- creating and managing the web pages for the app.
In Electron, the process that runs the main entry JavaScript file is called the main process. The _Electron main_ process can display a GUI by creating web pages. An Electron app always has exactly on main process.
By default, whenever the _Electron main_ process creates a web page, it will instantiate a new `BrowserWindow` instance. Since Electron uses Chromium for displaying web pages, Chromium's multi-process architecture is also used. Each web page in Electron runs in its own process, which is called the renderer process. Each `BrowserWindow` instance runs the web page in its own renderer process. When a `BrowserWindow` instance is destroyed, the corresponding renderer process is also terminated. The main process manages all web pages and their corresponding renderer processes. Each renderer process is isolated and only cares about the web page running in it.<sup>[[1]]</sup>
In normal browsers, web pages usually run in a sandboxed environment, and accessing native resources are disallowed. However, Electron has the power to use Node.js APIs in the web pages allowing lower-level OS interactions. Due to security reasons, accessing native resources is an undesired behavior in the Pro IDE. So by convention, we do not use Node.js APIs. (Note: the Node.js integration is [not yet disabled](https://github.com/eclipse-theia/theia/issues/2018) although it is not used). In the Pro IDE, only the _backend_ allows OS interaction.
The _backend_ process is responsible for:
- providing access to the filesystem,
- communicating with the Arduino CLI via gRPC,
- running your terminal,
- exposing additional RESTful APIs,
- performing the Git commands in the local repositories,
- hosting and running any VS Code extensions, or
- executing VS Code tasks<sup>[[2]]</sup>.
The _Electron main_ process spawns the _backend_ process. There is always exactly one _backend_ process. However, due to performance considerations, the _backend_ spawns several sub-processes for the filesystem watching, Git repository discovery, etc. The communication between the _backend_ process and its sub-processes is established via IPC. Besides spawning sub-processes, the _backend_ will start an HTTP server on a random available port, and serves the web application as static content. When the sub-processes are up and running, and the HTTP server is also listening, the _backend_ process sends the HTTP server port to the _Electron main_ process via IPC. The _Electron main_ process will load the _backend_'s endpoint in the `BrowserWindow`.
The _frontend_ is running as an Electron renderer process and can invoke services implemented on the _backend_. The communication between the _backend_ and the _frontend_ is done via JSON-RPC over a websocket connection. This means, the services running in the _frontend_ are all proxies, and will ask the corresponding service implementation on the _backend_.
[1]: https://www.electronjs.org/docs/tutorial/application-architecture#differences-between-main-process-and-renderer-process
[2]: https://code.visualstudio.com/Docs/editor/tasks
The code contained in this repository and the executable distributions are licensed under the terms of the GNU AGPLv3. The executable distributions contain third-party code licensed under other compatible licenses such as GPLv2, MIT and BSD-3. If you have questions about licensing please contact us at [license@arduino.cc](mailto:license@arduino.cc).

View File

@@ -54,3 +54,7 @@ The Config Service knows about your system, like for example the default sketch
### `"arduino"` configuration in the `package.json`:
- `"cli"`:
- `"version"` type `string` | `{ owner: string, repo: string, commitish?: string }`: if the type is a `string` and is a valid semver, it will get the corresponding [released](https://github.com/arduino/arduino-cli/releases) CLI. If the type is `string` and is a [date in `YYYYMMDD`](https://arduino.github.io/arduino-cli/latest/installation/#nightly-builds) format, it will get a nightly CLI. If the type is an object, a CLI, build from the sources in the `owner/repo` will be used. If `commitish` is not defined, the HEAD of the default branch will be used. In any other cases an error is thrown.
#### Rebuild gRPC protocol interfaces
- Some CLI updates can bring changes to the gRPC interfaces, as the API might change. gRPC interfaces can be updated running the command
`yarn --cwd arduino-ide-extension generate-protocol`

View File

@@ -1,8 +1,8 @@
{
"name": "arduino-ide-extension",
"version": "2.0.0-beta.3",
"version": "2.0.0-beta.6",
"description": "An extension for Theia building the Arduino IDE",
"license": "MIT",
"license": "AGPL-3.0-or-later",
"scripts": {
"prepare": "yarn download-cli && yarn download-ls && yarn clean && yarn download-examples && yarn build",
"clean": "rimraf lib",
@@ -23,6 +23,7 @@
"@theia/editor": "next",
"@theia/filesystem": "next",
"@theia/git": "next",
"@theia/keymaps": "next",
"@theia/markers": "next",
"@theia/monaco": "next",
"@theia/navigator": "next",
@@ -115,16 +116,13 @@
"frontend": "lib/browser/theia/core/browser-menu-module",
"frontendElectron": "lib/electron-browser/theia/core/electron-menu-module"
},
{
"frontend": "lib/browser/boards/quick-open/boards-quick-open-module"
},
{
"electronMain": "lib/electron-main/arduino-electron-main-module"
}
],
"arduino": {
"cli": {
"version": "0.16.1"
"version": "0.18.2"
}
}
}

View File

@@ -1,5 +1,5 @@
import { Mutex } from 'async-mutex';
import { MAIN_MENU_BAR, MenuContribution, MenuModelRegistry, SelectionService, ILogger } from '@theia/core';
import { MAIN_MENU_BAR, MenuContribution, MenuModelRegistry, SelectionService, ILogger, DisposableCollection } from '@theia/core';
import {
ContextMenuRenderer,
FrontendApplication, FrontendApplicationContribution,
@@ -12,7 +12,7 @@ import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/li
import { CommandContribution, CommandRegistry } from '@theia/core/lib/common/command';
import { MessageService } from '@theia/core/lib/common/message-service';
import URI from '@theia/core/lib/common/uri';
import { EditorMainMenu, EditorManager } from '@theia/editor/lib/browser';
import { EditorMainMenu, EditorManager, EditorOpenerOptions } from '@theia/editor/lib/browser';
import { FileDialogService } from '@theia/filesystem/lib/browser/file-dialog';
import { ProblemContribution } from '@theia/markers/lib/browser/problem/problem-contribution';
import { MonacoMenus } from '@theia/monaco/lib/browser/monaco-menu';
@@ -26,7 +26,7 @@ import { inject, injectable, postConstruct } from 'inversify';
import * as React from 'react';
import { remote } from 'electron';
import { MainMenuManager } from '../common/main-menu-manager';
import { BoardsService, CoreService, Port, SketchesService, ExecutableService } from '../common/protocol';
import { BoardsService, CoreService, Port, SketchesService, ExecutableService, Sketch } from '../common/protocol';
import { ArduinoDaemon } from '../common/protocol/arduino-daemon';
import { ConfigService } from '../common/protocol/config-service';
import { FileSystemExt } from '../common/protocol/filesystem-ext';
@@ -44,10 +44,12 @@ import { WorkspaceService } from './theia/workspace/workspace-service';
import { ArduinoToolbar } from './toolbar/arduino-toolbar';
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { OutputService } from '../common/protocol/output-service';
import { ResponseService } from '../common/protocol/response-service';
import { ArduinoPreferences } from './arduino-preferences';
import { SketchesServiceClientImpl } from '../common/protocol/sketches-service-client-impl';
import { SaveAsSketch } from './contributions/save-as-sketch';
import { FileChangeType } from '@theia/filesystem/lib/browser';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
@injectable()
export class ArduinoFrontendContribution implements FrontendApplicationContribution,
@@ -81,7 +83,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
protected readonly fileDialogService: FileDialogService;
@inject(FileService)
protected readonly fileSystem: FileService;
protected readonly fileService: FileService;
@inject(SketchesService)
protected readonly sketchService: SketchesService;
@@ -149,8 +151,8 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
@inject(ExecutableService)
protected executableService: ExecutableService;
@inject(OutputService)
protected readonly outputService: OutputService;
@inject(ResponseService)
protected readonly responseService: ResponseService;
@inject(ArduinoPreferences)
protected readonly arduinoPreferences: ArduinoPreferences;
@@ -158,7 +160,11 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
@inject(SketchesServiceClientImpl)
protected readonly sketchServiceClient: SketchesServiceClientImpl;
@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;
protected invalidConfigPopup: Promise<void | 'No' | 'Yes' | undefined> | undefined;
protected toDisposeOnStop = new DisposableCollection();
@postConstruct()
protected async init(): Promise<void> {
@@ -182,6 +188,23 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
}
this.boardsServiceClientImpl.onBoardsConfigChanged(updateStatusBar);
updateStatusBar(this.boardsServiceClientImpl.boardsConfig);
this.appStateService.reachedState('ready').then(async () => {
const sketch = await this.sketchServiceClient.currentSketch();
if (sketch && (!await this.sketchService.isTemp(sketch))) {
this.toDisposeOnStop.push(this.fileService.watch(new URI(sketch.uri)));
this.toDisposeOnStop.push(this.fileService.onDidFilesChange(async event => {
for (const { type, resource } of event.changes) {
if (type === FileChangeType.ADDED && resource.parent.toString() === sketch.uri) {
const reloadedSketch = await this.sketchService.loadSketch(sketch.uri)
if (Sketch.isInSketch(resource, reloadedSketch)) {
this.ensureOpened(resource.toString(), true, { mode: 'open' });
}
}
}
}));
}
});
}
onStart(app: FrontendApplication): void {
@@ -222,6 +245,11 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
webContents.setZoomLevel(event.newValue || 0);
}
});
app.shell.leftPanelHandler.removeMenu('settings-menu');
}
onStop(): void {
this.toDisposeOnStop.dispose();
}
protected languageServerFqbn?: string;
@@ -256,14 +284,15 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
if (log) {
const currentSketch = await this.sketchServiceClient.currentSketch();
if (currentSketch) {
currentSketchPath = await this.fileSystem.fsPath(new URI(currentSketch.uri));
currentSketchPath = await this.fileService.fsPath(new URI(currentSketch.uri));
}
}
const { clangdUri, cliUri, lsUri } = await this.executableService.list();
const [clangdPath, cliPath, lsPath] = await Promise.all([
this.fileSystem.fsPath(new URI(clangdUri)),
this.fileSystem.fsPath(new URI(cliUri)),
this.fileSystem.fsPath(new URI(lsUri)),
const [clangdPath, cliPath, lsPath, cliConfigPath] = await Promise.all([
this.fileService.fsPath(new URI(clangdUri)),
this.fileService.fsPath(new URI(cliUri)),
this.fileService.fsPath(new URI(lsUri)),
this.fileService.fsPath(new URI(await this.configService.getCliConfigFileUri()))
]);
this.languageServerFqbn = await Promise.race([
new Promise<undefined>((_, reject) => setTimeout(() => reject(new Error(`Timeout after ${20_000} ms.`)), 20_000)),
@@ -272,6 +301,7 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
cliPath,
clangdPath,
log: currentSketchPath ? currentSketchPath : log,
cliConfigPath,
board: {
fqbn,
name: name ? `"${name}"` : undefined
@@ -366,10 +396,10 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
}
}
protected async ensureOpened(uri: string, forceOpen: boolean = false): Promise<any> {
protected async ensureOpened(uri: string, forceOpen: boolean = false, options?: EditorOpenerOptions | undefined): Promise<any> {
const widget = this.editorManager.all.find(widget => widget.editor.uri.toString() === uri);
if (!widget || forceOpen) {
return this.editorManager.open(new URI(uri));
return this.editorManager.open(new URI(uri), options);
}
}
@@ -413,11 +443,20 @@ export class ArduinoFrontendContribution implements FrontendApplicationContribut
id: 'arduino.toolbar.hoverBackground',
defaults: {
dark: 'button.hoverBackground',
light: 'button.hoverBackground',
hc: 'activityBar.inactiveForeground'
light: 'button.foreground',
hc: 'textLink.foreground'
},
description: 'Background color of the toolbar items when hovering over them. Such as Upload, Verify, etc.'
},
{
id: 'arduino.toolbar.toggleBackground',
defaults: {
dark: 'editor.selectionBackground',
light: 'editor.selectionBackground',
hc: 'textPreformat.foreground'
},
description: 'Toggle color of the toolbar items when they are currently toggled (the command is in progress)'
},
{
id: 'arduino.output.foreground',
defaults: {

View File

@@ -24,6 +24,8 @@ import { ProblemContribution as TheiaProblemContribution } from '@theia/markers/
import { ProblemContribution } from './theia/markers/problem-contribution';
import { FileNavigatorContribution } from './theia/navigator/navigator-contribution';
import { FileNavigatorContribution as TheiaFileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
import { KeymapsFrontendContribution } from './theia/keymaps/keymaps-frontend-contribution';
import { KeymapsFrontendContribution as TheiaKeymapsFrontendContribution } from '@theia/keymaps/lib/browser/keymaps-frontend-contribution';
import { ArduinoToolbarContribution } from './toolbar/arduino-toolbar-contribution';
import { EditorContribution as TheiaEditorContribution } from '@theia/editor/lib/browser/editor-contribution';
import { EditorContribution } from './theia/editor/editor-contribution';
@@ -35,7 +37,9 @@ import {
CommonFrontendContribution as TheiaCommonFrontendContribution,
KeybindingRegistry as TheiaKeybindingRegistry,
TabBarRendererFactory,
ContextMenuRenderer
ContextMenuRenderer,
createTreeContainer,
TreeWidget
} from '@theia/core/lib/browser';
import { MenuContribution } from '@theia/core/lib/common/menu';
import { ApplicationShell } from './theia/core/application-shell';
@@ -65,8 +69,7 @@ import { ListItemRenderer } from './widgets/component-list/list-item-renderer';
import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
import { MonacoThemingService } from '@theia/monaco/lib/browser/monaco-theming-service';
import { ArduinoDaemonPath, ArduinoDaemon } from '../common/protocol/arduino-daemon';
import { EditorManager as TheiaEditorManager, EditorCommandContribution as TheiaEditorCommandContribution } from '@theia/editor/lib/browser';
import { EditorManager } from './theia/editor/editor-manager';
import { EditorCommandContribution as TheiaEditorCommandContribution } from '@theia/editor/lib/browser';
import { FrontendConnectionStatusService, ApplicationConnectionStatusContribution } from './theia/core/connection-status-service';
import {
FrontendConnectionStatusService as TheiaFrontendConnectionStatusService,
@@ -117,8 +120,8 @@ import { OutputChannelRegistryMainImpl as TheiaOutputChannelRegistryMainImpl, Ou
import { ExecutableService, ExecutableServicePath } from '../common/protocol';
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
import { MonacoTextModelService } from './theia/monaco/monaco-text-model-service';
import { OutputServiceImpl } from './output-service-impl';
import { OutputServicePath, OutputService } from '../common/protocol/output-service';
import { ResponseServiceImpl } from './response-service-impl';
import { ResponseServicePath, ResponseService } from '../common/protocol/response-service';
import { NotificationCenter } from './notification-center';
import { NotificationServicePath, NotificationServiceServer } from '../common/protocol';
import { About } from './contributions/about';
@@ -143,6 +146,23 @@ import { ArchiveSketch } from './contributions/archive-sketch';
import { OutputToolbarContribution as TheiaOutputToolbarContribution } from '@theia/output/lib/browser/output-toolbar-contribution';
import { OutputToolbarContribution } from './theia/output/output-toolbar-contribution';
import { AddZipLibrary } from './contributions/add-zip-library';
import { WorkspaceVariableContribution as TheiaWorkspaceVariableContribution } from '@theia/workspace/lib/browser/workspace-variable-contribution';
import { WorkspaceVariableContribution } from './theia/workspace/workspace-variable-contribution';
import { DebugConfigurationManager } from './theia/debug/debug-configuration-manager';
import { DebugConfigurationManager as TheiaDebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager';
import { SearchInWorkspaceWidget as TheiaSearchInWorkspaceWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-widget';
import { SearchInWorkspaceWidget } from './theia/search-in-workspace/search-in-workspace-widget';
import { SearchInWorkspaceResultTreeWidget as TheiaSearchInWorkspaceResultTreeWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-result-tree-widget';
import { SearchInWorkspaceResultTreeWidget } from './theia/search-in-workspace/search-in-workspace-result-tree-widget';
import { MonacoEditorProvider } from './theia/monaco/monaco-editor-provider';
import { MonacoEditorProvider as TheiaMonacoEditorProvider } from '@theia/monaco/lib/browser/monaco-editor-provider';
import { DebugEditorModel } from './theia/debug/debug-editor-model';
import { DebugEditorModelFactory } from '@theia/debug/lib/browser/editor/debug-editor-model';
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';
import { NotificationsRenderer } from './theia/messages/notifications-renderer';
const ElementQueries = require('css-element-queries/src/ElementQueries');
@@ -257,6 +277,8 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(WorkspaceService).toSelf().inSingletonScope();
rebind(TheiaWorkspaceService).toService(WorkspaceService);
bind(WorkspaceVariableContribution).toSelf().inSingletonScope();
rebind(TheiaWorkspaceVariableContribution).toService(WorkspaceVariableContribution);
// Customizing default Theia layout based on the editor mode: `pro-mode` or `classic`.
bind(EditorMode).toSelf().inSingletonScope();
@@ -266,6 +288,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
rebind(TheiaOutlineViewContribution).to(OutlineViewContribution).inSingletonScope();
rebind(TheiaProblemContribution).to(ProblemContribution).inSingletonScope();
rebind(TheiaFileNavigatorContribution).to(FileNavigatorContribution).inSingletonScope();
rebind(TheiaKeymapsFrontendContribution).to(KeymapsFrontendContribution).inSingletonScope();
rebind(TheiaEditorContribution).to(EditorContribution).inSingletonScope();
rebind(TheiaMonacoStatusBarContribution).to(MonacoStatusBarContribution).inSingletonScope();
rebind(TheiaApplicationShell).to(ApplicationShell).inSingletonScope();
@@ -293,6 +316,17 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
rebind(TheiaOutputChannelRegistryMainImpl).toService(OutputChannelRegistryMainImpl);
bind(MonacoTextModelService).toSelf().inSingletonScope();
rebind(TheiaMonacoTextModelService).toService(MonacoTextModelService);
bind(MonacoEditorProvider).toSelf().inSingletonScope();
rebind(TheiaMonacoEditorProvider).toService(MonacoEditorProvider);
bind(SearchInWorkspaceWidget).toSelf();
rebind(TheiaSearchInWorkspaceWidget).toService(SearchInWorkspaceWidget);
rebind(TheiaSearchInWorkspaceResultTreeWidget).toDynamicValue(({ container }) => {
const childContainer = createTreeContainer(container);
childContainer.bind(SearchInWorkspaceResultTreeWidget).toSelf()
childContainer.rebind(TreeWidget).toService(SearchInWorkspaceResultTreeWidget);
return childContainer.get(SearchInWorkspaceResultTreeWidget);
});
// Show a disconnected status bar, when the daemon is not available
bind(ApplicationConnectionStatusContribution).toSelf().inSingletonScope();
@@ -300,10 +334,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(FrontendConnectionStatusService).toSelf().inSingletonScope();
rebind(TheiaFrontendConnectionStatusService).toService(FrontendConnectionStatusService);
// Editor customizations. Sets the editor to `readOnly` if under the data dir.
bind(EditorManager).toSelf().inSingletonScope();
rebind(TheiaEditorManager).toService(EditorManager);
// Decorator customizations
bind(TabBarDecoratorService).toSelf().inSingletonScope();
rebind(TheiaTabBarDecoratorService).toService(TabBarDecoratorService);
@@ -357,11 +387,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
Contribution.configure(bind, ArchiveSketch);
Contribution.configure(bind, AddZipLibrary);
bind(OutputServiceImpl).toSelf().inSingletonScope().onActivation(({ container }, outputService) => {
WebSocketConnectionProvider.createProxy(container, OutputServicePath, outputService);
return outputService;
bind(ResponseServiceImpl).toSelf().inSingletonScope().onActivation(({ container }, responseService) => {
WebSocketConnectionProvider.createProxy(container, ResponseServicePath, responseService);
return responseService;
});
bind(OutputService).toService(OutputServiceImpl);
bind(ResponseService).toService(ResponseServiceImpl);
bind(NotificationCenter).toSelf().inSingletonScope();
bind(FrontendApplicationContribution).toService(NotificationCenter);
@@ -390,6 +420,14 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
// To remove the `Run` menu item from the application menu.
bind(DebugFrontendApplicationContribution).toSelf().inSingletonScope();
rebind(TheiaDebugFrontendApplicationContribution).toService(DebugFrontendApplicationContribution);
// To be able to use a `launch.json` from outside of the workspace.
bind(DebugConfigurationManager).toSelf().inSingletonScope();
rebind(TheiaDebugConfigurationManager).toService(DebugConfigurationManager);
// Patch for the debug hover: https://github.com/eclipse-theia/theia/pull/9256/
rebind(DebugEditorModelFactory).toDynamicValue(({ container }) => <DebugEditorModelFactory>(editor =>
DebugEditorModel.createModel(container, editor)
)).inSingletonScope();
// Preferences
bindArduinoPreferences(bind);
@@ -402,4 +440,12 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(SettingsDialogProps).toConstantValue({
title: 'Preferences'
});
bind(StorageWrapper).toSelf().inSingletonScope();
bind(CommandContribution).toService(StorageWrapper);
bind(NotificationManager).toSelf().inSingletonScope();
rebind(TheiaNotificationManager).toService(NotificationManager);
bind(NotificationsRenderer).toSelf().inSingletonScope();
rebind(TheiaNotificationsRenderer).toService(NotificationsRenderer);
});

View File

@@ -1,11 +1,12 @@
import { injectable, inject } from 'inversify';
import { MessageService } from '@theia/core/lib/common/message-service';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import { BoardsService, BoardsPackage } from '../../common/protocol/boards-service';
import { BoardsService, BoardsPackage, Board } from '../../common/protocol/boards-service';
import { BoardsServiceProvider } from './boards-service-provider';
import { BoardsListWidgetFrontendContribution } from './boards-widget-frontend-contribution';
import { InstallationProgressDialog } from '../widgets/progress-dialog';
import { BoardsConfig } from './boards-config';
import { Installable } from '../../common/protocol';
import { ResponseServiceImpl } from '../response-service-impl';
/**
* Listens on `BoardsConfig.Config` changes, if a board is selected which does not
@@ -23,9 +24,15 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
@inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider;
@inject(ResponseServiceImpl)
protected readonly responseService: ResponseServiceImpl;
@inject(BoardsListWidgetFrontendContribution)
protected readonly boardsManagerFrontendContribution: BoardsListWidgetFrontendContribution;
// Workaround for https://github.com/eclipse-theia/theia/issues/9349
protected notifications: Board[] = [];
onStart(): void {
this.boardsServiceClient.onBoardsConfigChanged(this.ensureCoreExists.bind(this));
this.ensureCoreExists(this.boardsServiceClient.boardsConfig);
@@ -33,22 +40,43 @@ export class BoardsAutoInstaller implements FrontendApplicationContribution {
protected ensureCoreExists(config: BoardsConfig.Config): void {
const { selectedBoard } = config;
if (selectedBoard) {
if (selectedBoard && !this.notifications.find(board => Board.sameAs(board, selectedBoard))) {
this.notifications.push(selectedBoard);
this.boardsService.search({}).then(packages => {
const candidates = packages
.filter(pkg => BoardsPackage.contains(selectedBoard, pkg))
// 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)) { return; }
// 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(({ installable, installedVersion }) => installable && !installedVersion);
for (const candidate of candidates) {
const candidate = candidates[0];
if (candidate) {
const version = candidate.availableVersions[0] ? `[v ${candidate.availableVersions[0]}]` : '';
// tslint:disable-next-line:max-line-length
this.messageService.info(`The \`"${candidate.name}"\` core has to be installed for the currently selected \`"${selectedBoard.name}"\` board. Do you want to install it now?`, 'Install Manually', 'Yes').then(async answer => {
this.messageService.info(`The \`"${candidate.name} ${version}"\` core has to be installed for the currently selected \`"${selectedBoard.name}"\` board. Do you want to install it now?`, 'Install Manually', 'Yes').then(async answer => {
const index = this.notifications.findIndex(board => Board.sameAs(board, selectedBoard));
if (index !== -1) {
this.notifications.splice(index, 1);
}
if (answer === 'Yes') {
const dialog = new InstallationProgressDialog(candidate.name, candidate.availableVersions[0]);
dialog.open();
try {
await this.boardsService.install({ item: candidate });
} finally {
dialog.close();
}
await Installable.installWithProgress({
installable: this.boardsService,
item: candidate,
messageService: this.messageService,
responseService: this.responseService,
version: candidate.availableVersions[0]
});
return
}
if (answer) {
this.boardsManagerFrontendContribution.openView({ reveal: true }).then(widget => widget.refresh(candidate.name.toLocaleLowerCase()));

View File

@@ -69,7 +69,7 @@ export class BoardsConfigDialog extends AbstractDialog<BoardsConfig.Config> {
'Select both a Board and a Port if you want to upload a sketch.',
'If you only select a Board you will be able just to compile, but not to upload your sketch.'
]) {
const p = document.createElement('p');
const p = document.createElement('div');
p.textContent = paragraph;
text.appendChild(p);
}

View File

@@ -281,6 +281,39 @@ export namespace BoardsConfig {
return `${name}${port ? ' at ' + Port.toString(port) : ''}`;
}
export function setConfig(config: Config | undefined, urlToAttachTo: URL): URL {
const copy = new URL(urlToAttachTo.toString());
if (!config) {
copy.searchParams.delete('boards-config');
return copy;
}
const selectedBoard = config.selectedBoard ? { name: config.selectedBoard.name, fqbn: config.selectedBoard.fqbn } : undefined;
const selectedPort = config.selectedPort ? { protocol: config.selectedPort.protocol, address: config.selectedPort.address } : undefined;
const jsonConfig = JSON.stringify({ selectedBoard, selectedPort });
copy.searchParams.set('boards-config', encodeURIComponent(jsonConfig));
return copy;
}
export function getConfig(url: URL): Config | undefined {
const encoded = url.searchParams.get('boards-config');
if (!encoded) {
return undefined;
}
try {
const raw = decodeURIComponent(encoded);
const candidate = JSON.parse(raw);
if (typeof candidate === 'object') {
return candidate;
}
console.warn(`Expected candidate to be an object. It was ${typeof candidate}. URL was: ${url}`);
return undefined;
} catch (e) {
console.log(`Could not get board config from URL: ${url}.`, e);
return undefined;
}
}
}
}

View File

@@ -20,6 +20,7 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
searchable: service,
installable: service,
itemLabel: (item: BoardsPackage) => item.name,
itemDeprecated: (item: BoardsPackage) => item.deprecated,
itemRenderer
});
}
@@ -33,4 +34,14 @@ export class BoardsListWidget extends ListWidget<BoardsPackage> {
]);
}
protected async install({ item, progressId, version }: { item: BoardsPackage, progressId: string, version: string; }): Promise<void> {
await super.install({ item, progressId, version });
this.messageService.info(`Successfully installed platform ${item.name}:${version}`, { timeout: 3000 });
}
protected async uninstall({ item, progressId }: { item: BoardsPackage, progressId: string }): Promise<void> {
await super.uninstall({ item, progressId });
this.messageService.info(`Successfully uninstalled platform ${item.name}:${item.installedVersion}`, { timeout: 3000 });
}
}

View File

@@ -1,8 +1,8 @@
import { injectable, inject } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { ILogger } from '@theia/core/lib/common/logger';
import { CommandService } from '@theia/core/lib/common/command';
import { MessageService } from '@theia/core/lib/common/message-service';
import { StorageService } from '@theia/core/lib/browser/storage-service';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import { RecursiveRequired } from '../../common/types';
import {
@@ -15,15 +15,9 @@ import {
} from '../../common/protocol';
import { BoardsConfig } from './boards-config';
import { naturalCompare } from '../../common/utils';
import { compareAnything } from '../theia/monaco/comparers';
import { NotificationCenter } from '../notification-center';
import { CommandService } from '@theia/core';
import { ArduinoCommands } from '../arduino-commands';
interface BoardMatch {
readonly board: BoardWithPackage;
readonly matches: monaco.filters.IMatch[] | undefined;
}
import { StorageWrapper } from '../storage-wrapper';
@injectable()
export class BoardsServiceProvider implements FrontendApplicationContribution {
@@ -34,8 +28,6 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
@inject(MessageService)
protected messageService: MessageService;
@inject(StorageService)
protected storageService: StorageService;
@inject(BoardsService)
protected boardsService: BoardsService;
@@ -93,7 +85,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
if (!AttachedBoardsChangeEvent.isEmpty(event)) {
this.logger.info('Attached boards and available ports changed:');
this.logger.info(AttachedBoardsChangeEvent.toString(event));
this.logger.info(`------------------------------------------`);
this.logger.info('------------------------------------------');
}
this._attachedBoards = event.newState.boards;
this._availablePorts = event.newState.ports;
@@ -205,38 +197,9 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
}
}
async searchBoards({ query, cores }: { query?: string, cores?: string[] }): Promise<Array<BoardWithPackage>> {
const boards = await this.boardsService.allBoards({});
const coresFilter = !!cores && cores.length
? ((toFilter: BoardWithPackage) => cores.some(core => core === toFilter.packageName || core === toFilter.packageId))
: () => true;
if (!query) {
return boards.filter(coresFilter).sort(Board.compare);
}
const toMatch = ((toFilter: BoardWithPackage) => (({ board: toFilter, matches: monaco.filters.matchesFuzzy(query, toFilter.name, true) })));
const compareEntries = (left: BoardMatch, right: BoardMatch, lookFor: string) => {
const leftMatches = left.matches || [];
const rightMatches = right.matches || [];
if (leftMatches.length && !rightMatches.length) {
return -1;
}
if (!leftMatches.length && rightMatches.length) {
return 1;
}
if (leftMatches.length === 0 && rightMatches.length === 0) {
return 0;
}
const leftLabel = left.board.name.replace(/\r?\n/g, ' ');
const rightLabel = right.board.name.replace(/\r?\n/g, ' ');
return compareAnything(leftLabel, rightLabel, lookFor);
}
const normalizedQuery = query.toLowerCase();
return boards
.filter(coresFilter)
.map(toMatch)
.filter(({ matches }) => !!matches)
.sort((left, right) => compareEntries(left, right, normalizedQuery))
.map(({ board }) => board);
async searchBoards({ query, cores }: { query?: string, cores?: string[] }): Promise<BoardWithPackage[]> {
const boards = await this.boardsService.searchBoards({ query });
return boards;
}
get boardsConfig(): BoardsConfig.Config {
@@ -384,7 +347,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
return undefined;
}
const key = this.getLastSelectedBoardOnPortKey(port);
return this.storageService.getData<Board>(key);
return this.getData<Board>(key);
}
protected async saveState(): Promise<void> {
@@ -395,11 +358,11 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
const { selectedBoard, selectedPort } = this.boardsConfig;
if (selectedBoard && selectedPort) {
const key = this.getLastSelectedBoardOnPortKey(selectedPort);
await this.storageService.setData(key, selectedBoard);
await this.setData(key, selectedBoard);
}
await Promise.all([
this.storageService.setData('latest-valid-boards-config', this.latestValidBoardsConfig),
this.storageService.setData('latest-boards-config', this.latestBoardsConfig)
this.setData('latest-valid-boards-config', this.latestValidBoardsConfig),
this.setData('latest-boards-config', this.latestBoardsConfig)
]);
}
@@ -409,7 +372,7 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
}
protected async loadState(): Promise<void> {
const storedLatestValidBoardsConfig = await this.storageService.getData<RecursiveRequired<BoardsConfig.Config>>('latest-valid-boards-config');
const storedLatestValidBoardsConfig = await this.getData<RecursiveRequired<BoardsConfig.Config>>('latest-valid-boards-config');
if (storedLatestValidBoardsConfig) {
this.latestValidBoardsConfig = storedLatestValidBoardsConfig;
if (this.canUploadTo(this.latestValidBoardsConfig)) {
@@ -417,13 +380,25 @@ export class BoardsServiceProvider implements FrontendApplicationContribution {
}
} else {
// If we could not restore the latest valid config, try to restore something, the board at least.
const storedLatestBoardsConfig = await this.storageService.getData<BoardsConfig.Config | undefined>('latest-boards-config');
let storedLatestBoardsConfig = await this.getData<BoardsConfig.Config | undefined>('latest-boards-config');
// Try to get from the URL if it was not persisted.
if (!storedLatestBoardsConfig) {
storedLatestBoardsConfig = BoardsConfig.Config.getConfig(new URL(window.location.href));
}
if (storedLatestBoardsConfig) {
this.latestBoardsConfig = storedLatestBoardsConfig;
this.boardsConfig = this.latestBoardsConfig;
}
}
}
private setData<T>(key: string, value: T): Promise<void> {
return this.commandService.executeCommand(StorageWrapper.Commands.SET_DATA.id, key, value);
}
private getData<T>(key: string): Promise<T | undefined> {
return this.commandService.executeCommand<T>(StorageWrapper.Commands.GET_DATA.id, key);
}
}
/**

View File

@@ -12,7 +12,7 @@ export class BoardsListWidgetFrontendContribution extends ListWidgetFrontendCont
widgetName: BoardsListWidget.WIDGET_LABEL,
defaultWidgetOptions: {
area: 'left',
rank: 600
rank: 2
},
toggleCommandId: `${BoardsListWidget.WIDGET_ID}:toggle`,
toggleKeybinding: 'CtrlCmd+Shift+B'

View File

@@ -1,16 +0,0 @@
import { ContainerModule } from 'inversify';
import { ILogger } from '@theia/core/lib/common/logger';
import { CommandContribution } from '@theia/core/lib/common/command';
import { QuickOpenContribution } from '@theia/core/lib/browser/quick-open';
import { KeybindingContribution } from '@theia/core/lib/browser/keybinding';
import { BoardsQuickOpenService } from './boards-quick-open-service';
export default new ContainerModule(bind => {
bind(BoardsQuickOpenService).toSelf().inSingletonScope();
bind(CommandContribution).toService(BoardsQuickOpenService);
bind(KeybindingContribution).toService(BoardsQuickOpenService);
bind(QuickOpenContribution).toService(BoardsQuickOpenService);
bind(ILogger).toDynamicValue(({ container }) => container.get<ILogger>(ILogger).child('boards-quick-open'))
.inSingletonScope()
.whenTargetNamed('boards-quick-open');
});

View File

@@ -1,309 +0,0 @@
import * as fuzzy from 'fuzzy';
import { inject, injectable, postConstruct, named } from 'inversify';
import { ILogger } from '@theia/core/lib/common/logger';
import { CommandContribution, CommandRegistry, Command } from '@theia/core/lib/common/command';
import { KeybindingContribution, KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
import { QuickOpenItem, QuickOpenModel, QuickOpenMode, QuickOpenGroupItem } from '@theia/core/lib/common/quick-open-model';
import {
QuickOpenService,
QuickOpenHandler,
QuickOpenOptions,
QuickOpenItemOptions,
QuickOpenContribution,
QuickOpenActionProvider,
QuickOpenHandlerRegistry,
QuickOpenGroupItemOptions
} from '@theia/core/lib/browser/quick-open';
import { naturalCompare } from '../../../common/utils';
import { BoardsService, Port, Board, ConfigOption, ConfigValue } from '../../../common/protocol';
import { BoardsDataStore } from '../boards-data-store';
import { BoardsServiceProvider, AvailableBoard } from '../boards-service-provider';
import { NotificationCenter } from '../../notification-center';
@injectable()
export class BoardsQuickOpenService implements QuickOpenContribution, QuickOpenModel, QuickOpenHandler, CommandContribution, KeybindingContribution, Command {
readonly id = 'arduino-boards-quick-open';
readonly prefix = '|';
readonly description = 'Configure Available Boards';
readonly label: 'Configure Available Boards';
@inject(ILogger)
@named('boards-quick-open')
protected readonly logger: ILogger;
@inject(QuickOpenService)
protected readonly quickOpenService: QuickOpenService;
@inject(BoardsService)
protected readonly boardsService: BoardsService;
@inject(BoardsServiceProvider)
protected readonly boardsServiceClient: BoardsServiceProvider;
@inject(BoardsDataStore)
protected readonly boardsDataStore: BoardsDataStore;
@inject(NotificationCenter)
protected notificationCenter: NotificationCenter;
protected isOpen: boolean = false;
protected currentQuery: string = '';
// Attached boards plus the user's config.
protected availableBoards: AvailableBoard[] = [];
// Only for the `selected` one from the `availableBoards`. Note: the `port` of the `selected` is optional.
protected data: BoardsDataStore.Data = BoardsDataStore.Data.EMPTY;
protected allBoards: Board.Detailed[] = []
protected selectedBoard?: (AvailableBoard & { port: Port });
// `init` name is used by the `QuickOpenHandler`.
@postConstruct()
protected postConstruct(): void {
this.notificationCenter.onIndexUpdated(() => this.update(this.availableBoards));
this.boardsServiceClient.onAvailableBoardsChanged(availableBoards => this.update(availableBoards));
this.update(this.boardsServiceClient.availableBoards);
}
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(this, { execute: () => this.open() });
}
registerKeybindings(registry: KeybindingRegistry): void {
registry.registerKeybinding({ command: this.id, keybinding: 'ctrlCmd+k ctrlCmd+b' });
}
registerQuickOpenHandlers(registry: QuickOpenHandlerRegistry): void {
registry.registerHandler(this);
}
getModel(): QuickOpenModel {
return this;
}
getOptions(): QuickOpenOptions {
let placeholder = '';
if (!this.selectedBoard) {
placeholder += 'No board selected.';
}
placeholder += 'Type to filter boards';
if (this.data.configOptions.length) {
placeholder += ' or use the ↓↑ keys to adjust the board settings...';
} else {
placeholder += '...';
}
return {
placeholder,
fuzzyMatchLabel: true,
onClose: () => this.isOpen = false
};
}
open(): void {
this.isOpen = true;
this.quickOpenService.open(this, this.getOptions());
}
onType(
lookFor: string,
acceptor: (items: QuickOpenItem<QuickOpenItemOptions>[], actionProvider?: QuickOpenActionProvider) => void): void {
this.currentQuery = lookFor;
const fuzzyFilter = this.fuzzyFilter(lookFor);
const availableBoards = this.availableBoards.filter(AvailableBoard.hasPort).filter(({ name }) => fuzzyFilter(name));
const toAccept: QuickOpenItem<QuickOpenItemOptions>[] = [];
// Show the selected attached in a different group.
if (this.selectedBoard && fuzzyFilter(this.selectedBoard.name)) {
toAccept.push(this.toQuickItem(this.selectedBoard, { groupLabel: 'Selected Board' }));
}
// Filter the selected from the attached ones.
toAccept.push(...availableBoards.filter(board => board !== this.selectedBoard).map((board, i) => {
let group: QuickOpenGroupItemOptions | undefined = undefined;
if (i === 0) {
// If no `selectedBoard`, then this item is the top one, no borders required.
group = { groupLabel: 'Attached Boards', showBorder: !!this.selectedBoard };
}
return this.toQuickItem(board, group);
}));
// Show the config only if the `input` is empty.
if (!lookFor.trim().length) {
toAccept.push(...this.data.configOptions.map((config, i) => {
let group: QuickOpenGroupItemOptions | undefined = undefined;
if (i === 0) {
group = { groupLabel: 'Board Settings', showBorder: true };
}
return this.toQuickItem(config, group);
}));
} else {
toAccept.push(...this.allBoards.filter(({ name }) => fuzzyFilter(name)).map((board, i) => {
let group: QuickOpenGroupItemOptions | undefined = undefined;
if (i === 0) {
group = { groupLabel: 'Boards', showBorder: true };
}
return this.toQuickItem(board, group);
}));
}
acceptor(toAccept);
}
private fuzzyFilter(lookFor: string): (inputString: string) => boolean {
const shouldFilter = !!lookFor.trim().length;
return (inputString: string) => shouldFilter ? fuzzy.test(lookFor.toLocaleLowerCase(), inputString.toLocaleLowerCase()) : true;
}
protected async update(availableBoards: AvailableBoard[]): Promise<void> {
// `selectedBoard` is not an attached board, we need to show the board settings for it (TODO: clarify!)
const selectedBoard = availableBoards.filter(AvailableBoard.hasPort).find(({ selected }) => selected);
const [data, boards] = await Promise.all([
selectedBoard && selectedBoard.fqbn ? this.boardsDataStore.getData(selectedBoard.fqbn) : Promise.resolve(BoardsDataStore.Data.EMPTY),
this.boardsService.allBoards({})
]);
this.allBoards = Board.decorateBoards(selectedBoard, boards)
.filter(board => !availableBoards.some(availableBoard => Board.sameAs(availableBoard, board)));
this.availableBoards = availableBoards;
this.data = data;
this.selectedBoard = selectedBoard;
if (this.isOpen) {
// Hack, to update the state without closing and reopening the quick open widget.
(this.quickOpenService as any).onType(this.currentQuery);
}
}
protected toQuickItem(item: BoardsQuickOpenService.Item, group?: QuickOpenGroupItemOptions): QuickOpenItem<QuickOpenItemOptions> {
let options: QuickOpenItemOptions;
if (AvailableBoard.is(item)) {
const description = `on ${Port.toString(item.port)}`
options = {
label: `${item.name}`,
description,
descriptionHighlights: [
{
start: 0,
end: description.length
}
],
run: this.toRun(() => this.boardsServiceClient.boardsConfig = ({ selectedBoard: item, selectedPort: item.port }))
};
} else if (ConfigOption.is(item)) {
const selected = item.values.find(({ selected }) => selected);
const value = selected ? selected.label : 'Not set';
const label = `${item.label}: ${value}`;
options = {
label,
// Intended to match the value part of a board setting.
// NOTE: this does not work, as `fuzzyMatchLabel: true` is set. Manual highlighting is ignored, apparently.
labelHighlights: [
{
start: label.length - value.length,
end: label.length
}
],
run: (mode) => {
if (mode === QuickOpenMode.OPEN) {
this.setConfig(item);
return false;
}
return true;
}
};
if (!selected) {
options.description = 'Not set';
};
} else {
options = {
label: `${item.name}`,
description: `${item.missing ? '' : `[installed with '${item.packageName}']`}`,
run: (mode) => {
if (mode === QuickOpenMode.OPEN) {
this.selectBoard(item);
return false;
}
return true;
}
};
}
if (group) {
return new QuickOpenGroupItem<QuickOpenGroupItemOptions>({ ...options, ...group });
} else {
return new QuickOpenItem<QuickOpenItemOptions>(options);
}
}
protected toRun(run: (() => void)): ((mode: QuickOpenMode) => boolean) {
return (mode) => {
if (mode !== QuickOpenMode.OPEN) {
return false;
}
run();
return true;
};
}
protected async selectBoard(board: Board): Promise<void> {
const allPorts = this.availableBoards.filter(AvailableBoard.hasPort).map(({ port }) => port).sort(Port.compare);
const toItem = (port: Port) => new QuickOpenItem<QuickOpenItemOptions>({
label: Port.toString(port, { useLabel: true }),
run: this.toRun(() => {
this.boardsServiceClient.boardsConfig = {
selectedBoard: board,
selectedPort: port
};
})
});
const options = {
placeholder: `Select a port for '${board.name}'. Press 'Enter' to confirm or 'Escape' to cancel.`,
fuzzyMatchLabel: true
}
this.quickOpenService.open({
onType: (lookFor, acceptor) => {
const fuzzyFilter = this.fuzzyFilter(lookFor);
acceptor(allPorts.filter(({ address }) => fuzzyFilter(address)).map(toItem));
}
}, options);
}
protected async setConfig(config: ConfigOption): Promise<void> {
const toItem = (value: ConfigValue) => new QuickOpenItem<QuickOpenItemOptions>({
label: value.label,
iconClass: value.selected ? 'fa fa-check' : '',
run: this.toRun(() => {
if (!this.selectedBoard) {
this.logger.warn(`Could not alter the boards settings. No board selected. ${JSON.stringify(config)}`);
return;
}
if (!this.selectedBoard.fqbn) {
this.logger.warn(`Could not alter the boards settings. The selected board does not have a FQBN. ${JSON.stringify(this.selectedBoard)}`);
return;
}
const { fqbn } = this.selectedBoard;
this.boardsDataStore.selectConfigOption({
fqbn,
option: config.option,
selectedValue: value.value
});
})
});
const options = {
placeholder: `Configure '${config.label}'. Press 'Enter' to confirm or 'Escape' to cancel.`,
fuzzyMatchLabel: true
}
this.quickOpenService.open({
onType: (lookFor, acceptor) => {
const fuzzyFilter = this.fuzzyFilter(lookFor);
acceptor(config.values
.filter(({ label }) => fuzzyFilter(label))
.sort((left, right) => naturalCompare(left.label, right.label))
.map(toItem));
}
}, options);
}
}
export namespace BoardsQuickOpenService {
export type Item = AvailableBoard & { port: Port } | Board.Detailed | ConfigOption;
}

View File

@@ -1,11 +1,12 @@
import { inject, injectable } from 'inversify';
import { remote } from 'electron';
import { ArduinoMenus } from '../menu/arduino-menus';
import { SketchContribution, Command, CommandRegistry, MenuModelRegistry } from './contribution';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import URI from '@theia/core/lib/common/uri';
import { InstallationProgressDialog } from '../widgets/progress-dialog';
import { LibraryService } from '../../common/protocol';
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
import { ArduinoMenus } from '../menu/arduino-menus';
import { ResponseServiceImpl } from '../response-service-impl';
import { Installable, LibraryService } from '../../common/protocol';
import { SketchContribution, Command, CommandRegistry, MenuModelRegistry } from './contribution';
@injectable()
export class AddZipLibrary extends SketchContribution {
@@ -13,6 +14,9 @@ export class AddZipLibrary extends SketchContribution {
@inject(EnvVariablesServer)
protected readonly envVariableServer: EnvVariablesServer;
@inject(ResponseServiceImpl)
protected readonly responseService: ResponseServiceImpl;
@inject(LibraryService)
protected readonly libraryService: LibraryService;
@@ -49,19 +53,59 @@ export class AddZipLibrary extends SketchContribution {
});
if (!canceled && filePaths.length) {
const zipUri = await this.fileSystemExt.getUri(filePaths[0]);
const dialog = new InstallationProgressDialog('Installing library', 'zip');
try {
this.outputChannelManager.getChannel('Arduino').clear();
dialog.open();
await this.libraryService.installZip({ zipUri });
} catch (e) {
this.messageService.error(e.toString());
} finally {
dialog.close();
await this.doInstall(zipUri);
} catch (error) {
if (error instanceof AlreadyInstalledError) {
const result = await new ConfirmDialog({
msg: error.message,
title: 'Do you want to overwrite the existing library?',
ok: 'Yes',
cancel: 'No'
}).open();
if (result) {
await this.doInstall(zipUri, true);
}
}
}
}
}
private async doInstall(zipUri: string, overwrite?: boolean): Promise<void> {
try {
await Installable.doWithProgress({
messageService: this.messageService,
progressText: `Processing ${new URI(zipUri).path.base}`,
responseService: this.responseService,
run: () => this.libraryService.installZip({ zipUri, overwrite })
});
this.messageService.info(`Successfully installed library from ${new URI(zipUri).path.base} archive`, { timeout: 3000 });
} catch (error) {
if (error instanceof Error) {
const match = error.message.match(/library (.*?) already installed/);
if (match && match.length >= 2) {
const name = match[1].trim();
if (name) {
throw new AlreadyInstalledError(`A library folder named ${name} already exists. Do you want to overwrite it?`, name);
} else {
throw new AlreadyInstalledError('A library already exists. Do you want to overwrite it?');
}
}
}
this.messageService.error(error.toString());
throw error;
}
}
}
class AlreadyInstalledError extends Error {
constructor(message: string, readonly libraryName?: string) {
super(message);
Object.setPrototypeOf(this, AlreadyInstalledError.prototype);
}
}
export namespace AddZipLibrary {

View File

@@ -210,7 +210,7 @@ PID: ${PID}`;
}
protected async installedBoards(): Promise<InstalledBoardWithPackage[]> {
const allBoards = await this.boardsService.allBoards({});
const allBoards = await this.boardsService.searchBoards({});
return allBoards.filter(InstalledBoardWithPackage.is);
}

View File

@@ -61,7 +61,7 @@ export class BurnBootloader extends SketchContribution {
verify,
verbose
});
this.messageService.info('Done burning bootloader.', { timeout: 1000 });
this.messageService.info('Done burning bootloader.', { timeout: 3000 });
} catch (e) {
this.messageService.error(e.toString());
} finally {

View File

@@ -106,9 +106,11 @@ export class Debug extends SketchContribution {
if (!sketch) {
return;
}
const [cliPath, sketchPath] = await Promise.all([
const ideTempFolderUri = await this.sketchService.getIdeTempFolderUri(sketch);
const [cliPath, sketchPath, configPath] = await Promise.all([
this.fileService.fsPath(new URI(executables.cliUri)),
this.fileService.fsPath(new URI(sketch.uri))
this.fileService.fsPath(new URI(sketch.uri)),
this.fileService.fsPath(new URI(ideTempFolderUri)),
])
const config = {
cliPath,
@@ -116,7 +118,8 @@ export class Debug extends SketchContribution {
fqbn,
name
},
sketchPath
sketchPath,
configPath
};
return this.commandService.executeCommand('arduino.debug.start', config);
}

View File

@@ -1,15 +1,16 @@
import * as PQueue from 'p-queue';
import { inject, injectable, postConstruct } from 'inversify';
import { MenuPath, CompositeMenuNode } from '@theia/core/lib/common/menu';
import { CommandHandler } from '@theia/core/lib/common/command';
import { MenuPath, CompositeMenuNode, SubMenuOptions } from '@theia/core/lib/common/menu';
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
import { OpenSketch } from './open-sketch';
import { ArduinoMenus, PlaceholderMenuNode } from '../menu/arduino-menus';
import { MainMenuManager } from '../../common/main-menu-manager';
import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { ExamplesService, ExampleContainer } from '../../common/protocol/examples-service';
import { ExamplesService } from '../../common/protocol/examples-service';
import { SketchContribution, CommandRegistry, MenuModelRegistry } from './contribution';
import { NotificationCenter } from '../notification-center';
import { Board } from '../../common/protocol';
import { Board, Sketch, SketchContainer } from '../../common/protocol';
@injectable()
export abstract class Examples extends SketchContribution {
@@ -59,36 +60,57 @@ export abstract class Examples extends SketchContribution {
}
registerRecursively(
exampleContainerOrPlaceholder: ExampleContainer | string,
sketchContainerOrPlaceholder: SketchContainer | (Sketch | SketchContainer)[] | string,
menuPath: MenuPath,
pushToDispose: DisposableCollection = new DisposableCollection()): void {
pushToDispose: DisposableCollection = new DisposableCollection(),
subMenuOptions?: SubMenuOptions | undefined): void {
if (typeof exampleContainerOrPlaceholder === 'string') {
const placeholder = new PlaceholderMenuNode(menuPath, exampleContainerOrPlaceholder);
if (typeof sketchContainerOrPlaceholder === 'string') {
const placeholder = new PlaceholderMenuNode(menuPath, sketchContainerOrPlaceholder);
this.menuRegistry.registerMenuNode(menuPath, placeholder);
pushToDispose.push(Disposable.create(() => this.menuRegistry.unregisterMenuNode(placeholder.id)));
} else {
const { label, sketches, children } = exampleContainerOrPlaceholder;
const submenuPath = [...menuPath, label];
this.menuRegistry.registerSubmenu(submenuPath, label);
const sketches: Sketch[] = [];
const children: SketchContainer[] = [];
let submenuPath = menuPath;
if (SketchContainer.is(sketchContainerOrPlaceholder)) {
const { label } = sketchContainerOrPlaceholder;
submenuPath = [...menuPath, label];
this.menuRegistry.registerSubmenu(submenuPath, label, subMenuOptions);
sketches.push(...sketchContainerOrPlaceholder.sketches);
children.push(...sketchContainerOrPlaceholder.children);
} else {
for (const sketchOrContainer of sketchContainerOrPlaceholder) {
if (SketchContainer.is(sketchOrContainer)) {
children.push(sketchOrContainer);
} else {
sketches.push(sketchOrContainer);
}
}
}
children.forEach(child => this.registerRecursively(child, submenuPath, pushToDispose));
for (const sketch of sketches) {
const { uri } = sketch;
const commandId = `arduino-open-example-${submenuPath.join(':')}--${uri}`;
const command = { id: commandId };
const handler = {
execute: async () => {
const sketch = await this.sketchService.cloneExample(uri);
this.commandService.executeCommand(OpenSketch.Commands.OPEN_SKETCH.id, sketch);
}
};
const handler = this.createHandler(uri);
pushToDispose.push(this.commandRegistry.registerCommand(command, handler));
this.menuRegistry.registerMenuAction(submenuPath, { commandId, label: sketch.name });
this.menuRegistry.registerMenuAction(submenuPath, { commandId, label: sketch.name, order: sketch.name.toLocaleLowerCase() });
pushToDispose.push(Disposable.create(() => this.menuRegistry.unregisterMenuAction(command)));
}
}
}
protected createHandler(uri: string): CommandHandler {
return {
execute: async () => {
const sketch = await this.sketchService.cloneExample(uri);
return this.commandService.executeCommand(OpenSketch.Commands.OPEN_SKETCH.id, sketch);
}
}
}
}
@injectable()
@@ -98,22 +120,20 @@ export class BuiltInExamples extends Examples {
this.register(); // no `await`
}
protected async register() {
let exampleContainers: ExampleContainer[] | undefined;
protected async register(): Promise<void> {
let sketchContainers: SketchContainer[] | undefined;
try {
exampleContainers = await this.examplesService.builtIns();
sketchContainers = await this.examplesService.builtIns();
} catch (e) {
console.error('Could not initialize built-in examples.', e);
this.messageService.error('Could not initialize built-in examples.');
return;
}
this.toDispose.dispose();
for (const container of ['Built-in examples', ...exampleContainers]) {
for (const container of ['Built-in examples', ...sketchContainers]) {
this.registerRecursively(container, ArduinoMenus.EXAMPLES__BUILT_IN_GROUP, this.toDispose);
}
this.menuManager.update();
// TODO: remove
console.log(typeof this.menuRegistry);
}
}
@@ -136,18 +156,17 @@ export class LibraryExamples extends Examples {
this.register(board);
}
protected async register(board: Board | undefined = this.boardsServiceClient.boardsConfig.selectedBoard) {
protected async register(board: Board | undefined = this.boardsServiceClient.boardsConfig.selectedBoard): Promise<void> {
return this.queue.add(async () => {
this.toDispose.dispose();
if (!board || !board.fqbn) {
return;
}
const { fqbn, name } = board;
const fqbn = board?.fqbn;
const name = board?.name;
// Shows all examples when no board is selected, or the platform of the currently selected board is not installed.
const { user, current, any } = await this.examplesService.installed({ fqbn });
if (user.length) {
(user as any).unshift('Examples from Custom Libraries');
}
if (current.length) {
if (name && fqbn && current.length) {
(current as any).unshift(`Examples for ${name}`);
}
if (any.length) {

View File

@@ -74,10 +74,9 @@ export class IncludeLibrary extends SketchContribution {
this.mainMenuManager.update();
const libraries: LibraryPackage[] = []
const fqbn = this.boardsServiceClient.boardsConfig.selectedBoard?.fqbn;
// Do not show board specific examples, when no board is selected.
if (fqbn) {
libraries.push(...await this.libraryService.list({ fqbn }));
}
// Show all libraries, when no board is selected.
// Otherwise, show libraries only for the selected board.
libraries.push(...await this.libraryService.list({ fqbn }));
const includeLibMenuPath = [...ArduinoMenus.SKETCH__UTILS_GROUP, '0_include'];
// `Add .ZIP Library...`

View File

@@ -8,6 +8,8 @@ import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
import { SketchContribution, Sketch, URI, Command, CommandRegistry, MenuModelRegistry, KeybindingRegistry, TabBarToolbarRegistry } from './contribution';
import { ExamplesService } from '../../common/protocol/examples-service';
import { BuiltInExamples } from './examples';
import { Sketchbook } from './sketchbook';
import { SketchContainer } from '../../common/protocol';
@injectable()
export class OpenSketch extends SketchContribution {
@@ -24,7 +26,10 @@ export class OpenSketch extends SketchContribution {
@inject(ExamplesService)
protected readonly examplesService: ExamplesService;
protected readonly toDisposeBeforeCreateNewContextMenu = new DisposableCollection();
@inject(Sketchbook)
protected readonly sketchbook: Sketchbook;
protected readonly toDispose = new DisposableCollection();
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH, {
@@ -33,11 +38,11 @@ export class OpenSketch extends SketchContribution {
registry.registerCommand(OpenSketch.Commands.OPEN_SKETCH__TOOLBAR, {
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
execute: async (_: Widget, target: EventTarget) => {
const sketches = await this.sketchService.getSketches();
if (!sketches.length) {
const container = await this.sketchService.getSketches({ exclude: ['**/hardware/**'] });
if (SketchContainer.isEmpty(container)) {
this.openSketch();
} else {
this.toDisposeBeforeCreateNewContextMenu.dispose();
this.toDispose.dispose();
if (!(target instanceof HTMLElement)) {
return;
}
@@ -50,21 +55,12 @@ export class OpenSketch extends SketchContribution {
commandId: OpenSketch.Commands.OPEN_SKETCH.id,
label: 'Open...'
});
this.toDisposeBeforeCreateNewContextMenu.push(Disposable.create(() => this.menuRegistry.unregisterMenuAction(OpenSketch.Commands.OPEN_SKETCH)));
for (const sketch of sketches) {
const command = { id: `arduino-open-sketch--${sketch.uri}` };
const handler = { execute: () => this.openSketch(sketch) };
this.toDisposeBeforeCreateNewContextMenu.push(registry.registerCommand(command, handler));
this.menuRegistry.registerMenuAction(ArduinoMenus.OPEN_SKETCH__CONTEXT__RECENT_GROUP, {
commandId: command.id,
label: sketch.name
});
this.toDisposeBeforeCreateNewContextMenu.push(Disposable.create(() => this.menuRegistry.unregisterMenuAction(command)));
}
this.toDispose.push(Disposable.create(() => this.menuRegistry.unregisterMenuAction(OpenSketch.Commands.OPEN_SKETCH)));
this.sketchbook.registerRecursively([...container.children, ...container.sketches], ArduinoMenus.OPEN_SKETCH__CONTEXT__RECENT_GROUP, this.toDispose);
try {
const containers = await this.examplesService.builtIns();
for (const container of containers) {
this.builtInExamples.registerRecursively(container, ArduinoMenus.OPEN_SKETCH__CONTEXT__EXAMPLES_GROUP, this.toDisposeBeforeCreateNewContextMenu);
this.builtInExamples.registerRecursively(container, ArduinoMenus.OPEN_SKETCH__CONTEXT__EXAMPLES_GROUP, this.toDispose);
}
} catch (e) {
console.error('Error when collecting built-in examples.', e);

View File

@@ -33,11 +33,12 @@ export class Settings extends SketchContribution {
}
registerMenus(registry: MenuModelRegistry): void {
registry.registerMenuAction(ArduinoMenus.FILE__SETTINGS_GROUP, {
registry.registerMenuAction(ArduinoMenus.FILE__PREFERENCES_GROUP, {
commandId: Settings.Commands.OPEN.id,
label: 'Preferences...',
order: '0'
});
registry.registerSubmenu(ArduinoMenus.FILE__ADVANCED_SUBMENU, 'Advanced');
}
registerKeybindings(registry: KeybindingRegistry): void {

View File

@@ -1,13 +1,15 @@
import { inject, injectable } from 'inversify';
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
import { SketchContribution, CommandRegistry, MenuModelRegistry, Sketch } from './contribution';
import { CommandHandler } from '@theia/core/lib/common/command';
import { CommandRegistry, MenuModelRegistry } from './contribution';
import { ArduinoMenus } from '../menu/arduino-menus';
import { MainMenuManager } from '../../common/main-menu-manager';
import { NotificationCenter } from '../notification-center';
import { Examples } from './examples';
import { SketchContainer } from '../../common/protocol';
import { OpenSketch } from './open-sketch';
@injectable()
export class Sketchbook extends SketchContribution {
export class Sketchbook extends Examples {
@inject(CommandRegistry)
protected readonly commandRegistry: CommandRegistry;
@@ -21,17 +23,16 @@ export class Sketchbook extends SketchContribution {
@inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter;
protected toDisposePerSketch = new Map<string, DisposableCollection>();
onStart(): void {
this.sketchService.getSketches().then(sketches => {
this.register(sketches);
this.sketchService.getSketches({}).then(container => {
this.register(container);
this.mainMenuManager.update();
});
this.sketchServiceClient.onSketchbookDidChange(({ created, removed }) => {
this.unregister(removed);
this.register(created);
this.mainMenuManager.update();
this.sketchServiceClient.onSketchbookDidChange(() => {
this.sketchService.getSketches({}).then(container => {
this.register(container);
this.mainMenuManager.update();
});
});
}
@@ -39,29 +40,16 @@ export class Sketchbook extends SketchContribution {
registry.registerSubmenu(ArduinoMenus.FILE__SKETCHBOOK_SUBMENU, 'Sketchbook', { order: '3' });
}
protected register(sketches: Sketch[]): void {
for (const sketch of sketches) {
const { uri } = sketch;
const toDispose = this.toDisposePerSketch.get(uri);
if (toDispose) {
toDispose.dispose();
}
const command = { id: `arduino-sketchbook-open--${uri}` };
const handler = { execute: () => this.commandRegistry.executeCommand(OpenSketch.Commands.OPEN_SKETCH.id, sketch) };
this.commandRegistry.registerCommand(command, handler);
this.menuRegistry.registerMenuAction(ArduinoMenus.FILE__SKETCHBOOK_SUBMENU, { commandId: command.id, label: sketch.name });
this.toDisposePerSketch.set(sketch.uri, new DisposableCollection(
Disposable.create(() => this.commandRegistry.unregisterCommand(command)),
Disposable.create(() => this.menuRegistry.unregisterMenuAction(command))
));
}
protected register(container: SketchContainer): void {
this.toDispose.dispose();
this.registerRecursively([...container.children, ...container.sketches], ArduinoMenus.FILE__SKETCHBOOK_SUBMENU, this.toDispose);
}
protected unregister(sketches: Sketch[]): void {
for (const { uri } of sketches) {
const toDispose = this.toDisposePerSketch.get(uri);
if (toDispose) {
toDispose.dispose();
protected createHandler(uri: string): CommandHandler {
return {
execute: async () => {
const sketch = await this.sketchService.loadSketch(uri);
return this.commandService.executeCommand(OpenSketch.Commands.OPEN_SKETCH.id, sketch);
}
}
}

View File

@@ -1,4 +1,5 @@
import { inject, injectable } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { CoreService } from '../../common/protocol';
import { ArduinoMenus } from '../menu/arduino-menus';
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
@@ -22,15 +23,24 @@ export class UploadSketch extends SketchContribution {
@inject(BoardsServiceProvider)
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
protected readonly onDidChangeEmitter = new Emitter<Readonly<void>>();
readonly onDidChange = this.onDidChangeEmitter.event;
protected uploadInProgress = false;
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH, {
execute: () => this.uploadSketch()
execute: () => this.uploadSketch(),
isEnabled: () => !this.uploadInProgress,
});
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_USING_PROGRAMMER, {
execute: () => this.uploadSketch(true)
execute: () => this.uploadSketch(true),
isEnabled: () => !this.uploadInProgress,
});
registry.registerCommand(UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR, {
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: () => !this.uploadInProgress,
isToggled: () => this.uploadInProgress,
execute: () => registry.executeCommand(UploadSketch.Commands.UPLOAD_SKETCH.id)
});
}
@@ -64,11 +74,22 @@ export class UploadSketch extends SketchContribution {
id: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
command: UploadSketch.Commands.UPLOAD_SKETCH_TOOLBAR.id,
tooltip: 'Upload',
priority: 1
priority: 1,
onDidChange: this.onDidChange
});
}
async uploadSketch(usingProgrammer: boolean = false): Promise<void> {
// even with buttons disabled, better to double check if an upload is already in progress
if (this.uploadInProgress) {
return;
}
// toggle the toolbar button and menu item state.
// uploadInProgress will be set to false whether the upload fails or not
this.uploadInProgress = true;
this.onDidChangeEmitter.fire();
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
return;
@@ -127,10 +148,13 @@ export class UploadSketch extends SketchContribution {
} else {
await this.coreService.upload(options);
}
this.messageService.info('Done uploading.', { timeout: 1000 });
this.messageService.info('Done uploading.', { timeout: 3000 });
} catch (e) {
this.messageService.error(e.toString());
} finally {
this.uploadInProgress = false;
this.onDidChangeEmitter.fire();
if (monitorConfig) {
const { board, port } = monitorConfig;
try {

View File

@@ -1,4 +1,5 @@
import { inject, injectable } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { CoreService } from '../../common/protocol';
import { ArduinoMenus } from '../menu/arduino-menus';
import { ArduinoToolbar } from '../toolbar/arduino-toolbar';
@@ -18,15 +19,24 @@ export class VerifySketch extends SketchContribution {
@inject(BoardsServiceProvider)
protected readonly boardsServiceClientImpl: BoardsServiceProvider;
protected readonly onDidChangeEmitter = new Emitter<Readonly<void>>();
readonly onDidChange = this.onDidChangeEmitter.event;
protected verifyInProgress = false;
registerCommands(registry: CommandRegistry): void {
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH, {
execute: () => this.verifySketch()
execute: () => this.verifySketch(),
isEnabled: () => !this.verifyInProgress,
});
registry.registerCommand(VerifySketch.Commands.EXPORT_BINARIES, {
execute: () => this.verifySketch(true)
execute: () => this.verifySketch(true),
isEnabled: () => !this.verifyInProgress,
});
registry.registerCommand(VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR, {
isVisible: widget => ArduinoToolbar.is(widget) && widget.side === 'left',
isEnabled: () => !this.verifyInProgress,
isToggled: () => this.verifyInProgress,
execute: () => registry.executeCommand(VerifySketch.Commands.VERIFY_SKETCH.id)
});
}
@@ -60,12 +70,24 @@ export class VerifySketch extends SketchContribution {
id: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
command: VerifySketch.Commands.VERIFY_SKETCH_TOOLBAR.id,
tooltip: 'Verify',
priority: 0
priority: 0,
onDidChange: this.onDidChange
});
}
async verifySketch(exportBinaries?: boolean): Promise<void> {
// even with buttons disabled, better to double check if a verify is already in progress
if (this.verifyInProgress) {
return;
}
// toggle the toolbar button and menu item state.
// verifyInProgress will be set to false whether the compilation fails or not
this.verifyInProgress = true;
this.onDidChangeEmitter.fire();
const sketch = await this.sketchServiceClient.currentSketch();
if (!sketch) {
return;
}
@@ -87,9 +109,12 @@ export class VerifySketch extends SketchContribution {
sourceOverride,
compilerWarnings
});
this.messageService.info('Done compiling.', { timeout: 1000 });
this.messageService.info('Done compiling.', { timeout: 3000 });
} catch (e) {
this.messageService.error(e.toString());
} finally {
this.verifyInProgress = false;
this.onDidChangeEmitter.fire();
}
}

View File

@@ -28,7 +28,8 @@
"scope": [
"meta.function.c",
"entity.name.function",
"meta.function-call.c"
"meta.function-call.c",
"variable.other"
],
"settings": {
"foreground": "#D35400"
@@ -42,16 +43,19 @@
"meta.block.c",
"meta.function.c",
"entity.name.function.preprocessor.c",
"meta.preprocessor.macro.c"
"meta.preprocessor.macro.c",
"variable",
"variable.name"
],
"settings": {
"foreground": "#434f54"
}
},
{
"name": "strings",
"name": "constants",
"scope": [
"string.quoted.double"
"string.quoted.double",
"constant"
],
"settings": {
"foreground": "#005C5F"
@@ -82,6 +86,7 @@
"colors": {
"list.highlightForeground": "#005c5f",
"list.activeSelectionBackground": "#005c5f",
"progressBar.background": "#005c5f",
"editor.background": "#ffffff",
"editorCursor.foreground": "#434f54",
"editor.foreground": "#434f54",

View File

@@ -24,6 +24,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
searchable: service,
installable: service,
itemLabel: (item: LibraryPackage) => item.name,
itemDeprecated: (item: LibraryPackage) => item.deprecated,
itemRenderer
});
}
@@ -37,7 +38,7 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
]);
}
protected async install({ item, version }: { item: LibraryPackage, version: Installable.Version }): Promise<void> {
protected async install({ item, progressId, version }: { item: LibraryPackage, progressId: string, version: Installable.Version }): Promise<void> {
const dependencies = await this.service.listDependencies({ item, version, filterSelf: true });
let installDependencies: boolean | undefined = undefined;
if (dependencies.length) {
@@ -84,10 +85,16 @@ export class LibraryListWidget extends ListWidget<LibraryPackage> {
}
if (typeof installDependencies === 'boolean') {
return this.service.install({ item, version, installDependencies });
await this.service.install({ item, version, progressId, installDependencies });
this.messageService.info(`Successfully installed library ${item.name}:${version}`, { timeout: 3000 });
}
}
protected async uninstall({ item, progressId }: { item: LibraryPackage, progressId: string }): Promise<void> {
await super.uninstall({ item, progressId });
this.messageService.info(`Successfully uninstalled library ${item.name}:${item.installedVersion}`, { timeout: 3000 });
}
}
class MessageBoxDialog extends AbstractDialog<MessageBoxDialog.Result> {

View File

@@ -14,7 +14,7 @@ export class LibraryListWidgetFrontendContribution extends AbstractViewContribut
widgetName: LibraryListWidget.WIDGET_LABEL,
defaultWidgetOptions: {
area: 'left',
rank: 700
rank: 3
},
toggleCommandId: `${LibraryListWidget.WIDGET_ID}:toggle`,
toggleKeybinding: 'CtrlCmd+Shift+I'

View File

@@ -8,8 +8,12 @@ export namespace ArduinoMenus {
// -- File
export const FILE__SKETCH_GROUP = [...CommonMenus.FILE, '0_sketch'];
export const FILE__PRINT_GROUP = [...CommonMenus.FILE, '1_print'];
// XXX: on macOS, the settings group is not under `File`
export const FILE__SETTINGS_GROUP = [...(isOSX ? MAIN_MENU_BAR : CommonMenus.FILE), '2_settings'];
// XXX: on macOS, the "Preferences" and "Advanced" group is not under `File`
// The empty path ensures no top level menu is created for the preferences, even if they contains sub menus
export const FILE__PREFERENCES_GROUP = [...(isOSX ? [''] : CommonMenus.FILE), '2_preferences'];
export const FILE__ADVANCED_GROUP = [...(isOSX ? [''] : CommonMenus.FILE), '3_advanced'];
export const FILE__ADVANCED_SUBMENU = [...FILE__ADVANCED_GROUP, '0_advanced_sub'];
export const FILE__QUIT_GROUP = [...CommonMenus.FILE, '3_quit'];
// -- File / Open Recent

View File

@@ -1,22 +0,0 @@
import { inject, injectable } from 'inversify';
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
import { OutputChannelManager } from '@theia/output/lib/common/output-channel';
import { OutputService, OutputMessage } from '../common/protocol/output-service';
@injectable()
export class OutputServiceImpl implements OutputService {
@inject(OutputContribution)
protected outputContribution: OutputContribution;
@inject(OutputChannelManager)
protected outputChannelManager: OutputChannelManager;
append(message: OutputMessage): void {
const { chunk } = message;
const channel = this.outputChannelManager.getChannel(`Arduino`);
channel.show({ preserveFocus: true });
channel.append(chunk);
}
}

View File

@@ -0,0 +1,34 @@
import { inject, injectable } from 'inversify';
import { Emitter } from '@theia/core/lib/common/event';
import { OutputContribution } from '@theia/output/lib/browser/output-contribution';
import { OutputChannelManager } from '@theia/output/lib/common/output-channel';
import { ResponseService, OutputMessage, ProgressMessage } from '../common/protocol/response-service';
@injectable()
export class ResponseServiceImpl implements ResponseService {
@inject(OutputContribution)
protected outputContribution: OutputContribution;
@inject(OutputChannelManager)
protected outputChannelManager: OutputChannelManager;
protected readonly progressDidChangeEmitter = new Emitter<ProgressMessage>();
readonly onProgressDidChange = this.progressDidChangeEmitter.event;
appendToOutput(message: OutputMessage): void {
const { chunk } = message;
const channel = this.outputChannelManager.getChannel('Arduino');
channel.show({ preserveFocus: true });
channel.append(chunk);
}
clearArduinoChannel(): void {
this.outputChannelManager.getChannel('Arduino').clear();
}
reportProgress(progress: ProgressMessage): void {
this.progressDidChangeEmitter.fire(progress);
}
}

View File

@@ -24,6 +24,7 @@ export interface Settings extends Index {
editorFontSize: number; // `editor.fontSize`
themeId: string; // `workbench.colorTheme`
autoSave: 'on' | 'off'; // `editor.autoSave`
quickSuggestions: Record<'other' | 'comments' | 'strings', boolean>; // `editor.quickSuggestions`
autoScaleInterface: boolean; // `arduino.window.autoScale`
interfaceScale: number; // `arduino.window.zoomLevel` https://github.com/eclipse-theia/theia/issues/8751
@@ -84,6 +85,7 @@ export class SettingsService {
editorFontSize,
themeId,
autoSave,
quickSuggestions,
autoScaleInterface,
interfaceScale,
// checkForUpdates,
@@ -97,6 +99,11 @@ export class SettingsService {
this.preferenceService.get<number>('editor.fontSize', 12),
this.preferenceService.get<string>('workbench.colorTheme', 'arduino-theme'),
this.preferenceService.get<'on' | 'off'>('editor.autoSave', 'on'),
this.preferenceService.get<object>('editor.quickSuggestion', {
'other': false,
'comments': false,
'strings': false
}),
this.preferenceService.get<boolean>('arduino.window.autoScale', true),
this.preferenceService.get<number>('arduino.window.zoomLevel', 0),
// this.preferenceService.get<string>('arduino.ide.autoUpdate', true),
@@ -113,6 +120,7 @@ export class SettingsService {
editorFontSize,
themeId,
autoSave,
quickSuggestions,
autoScaleInterface,
interfaceScale,
// checkForUpdates,
@@ -155,10 +163,10 @@ export class SettingsService {
return `Invalid sketchbook location: ${sketchbookPath}`;
}
if (editorFontSize <= 0) {
return `Invalid editor font size. It must be a positive integer.`;
return 'Invalid editor font size. It must be a positive integer.';
}
if (!ThemeService.get().getThemes().find(({ id }) => id === themeId)) {
return `Invalid theme.`;
return 'Invalid theme.';
}
return true;
} catch (err) {
@@ -175,6 +183,7 @@ export class SettingsService {
editorFontSize,
themeId,
autoSave,
quickSuggestions,
autoScaleInterface,
interfaceScale,
// checkForUpdates,
@@ -199,6 +208,7 @@ export class SettingsService {
this.preferenceService.set('editor.fontSize', editorFontSize, PreferenceScope.User),
this.preferenceService.set('workbench.colorTheme', themeId, PreferenceScope.User),
this.preferenceService.set('editor.autoSave', autoSave, PreferenceScope.User),
this.preferenceService.set('editor.quickSuggestions', quickSuggestions, PreferenceScope.User),
this.preferenceService.set('arduino.window.autoScale', autoScaleInterface, PreferenceScope.User),
this.preferenceService.set('arduino.window.zoomLevel', interfaceScale, PreferenceScope.User),
// this.preferenceService.set('arduino.ide.autoUpdate', checkForUpdates, PreferenceScope.User),
@@ -360,6 +370,13 @@ export class SettingsComponent extends React.Component<SettingsComponent.Props,
onChange={this.autoSaveDidChange} />
Auto save
</label>
<label className='flex-line'>
<input
type='checkbox'
checked={this.state.quickSuggestions.other === true}
onChange={this.quickSuggestionsOtherDidChange} />
Editor Quick Suggestions
</label>
<label className='flex-line'>
<input
type='checkbox'
@@ -490,7 +507,7 @@ export class SettingsComponent extends React.Component<SettingsComponent.Props,
protected browseSketchbookDidClick = async () => {
const uri = await this.props.fileDialogService.showOpenDialog({
title: 'Select new sketchbook location',
openLabel: 'Chose',
openLabel: 'Choose',
canSelectFiles: false,
canSelectMany: false,
canSelectFolders: true
@@ -551,6 +568,21 @@ export class SettingsComponent extends React.Component<SettingsComponent.Props,
this.setState({ autoSave: event.target.checked ? 'on' : 'off' });
};
protected quickSuggestionsOtherDidChange = (event: React.ChangeEvent<HTMLInputElement>) => {
// need to persist react events through lifecycle https://reactjs.org/docs/events.html#event-pooling
const newVal = event.target.checked ? true : false
this.setState(prevState => {
return {
quickSuggestions: {
...prevState.quickSuggestions,
other: newVal
}
}
});
};
protected themeDidChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const { selectedIndex } = event.target.options;
const theme = ThemeService.get().getThemes()[selectedIndex];
@@ -745,6 +777,11 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
protected onActivateRequest(msg: Message): void {
super.onActivateRequest(msg);
// calling settingsService.reset() in order to reload the settings from the preferenceService
// and update the UI including changes triggerd from the command palette
this.settingsService.reset();
this.widget.activate();
}
@@ -791,7 +828,7 @@ export class AdditionalUrlsDialog extends AbstractDialog<string[]> {
}
get value(): string[] {
return this.textArea.value.split('\n').map(url => url.trim());
return this.textArea.value.split('\n').map(url => url.trim()).filter(url => !!url);
}
protected onAfterAttach(message: Message): void {

View File

@@ -0,0 +1,33 @@
import { injectable, inject } from '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'
};
}
}

View File

@@ -1,5 +1,5 @@
div#select-board-dialog {
margin: 5px 20px 50px 20px;
margin: 5px;
}
div#select-board-dialog .selectBoardContainer .body {
@@ -7,8 +7,8 @@ div#select-board-dialog .selectBoardContainer .body {
overflow: hidden;
}
div.dialogContent.select-board-dialog > div.head {
padding-left: 21px;
.select-board-dialog .head {
margin: 5px;
}
div.dialogContent.select-board-dialog > div.head .title {
@@ -16,11 +16,7 @@ div.dialogContent.select-board-dialog > div.head .title {
letter-spacing: .02em;
font-size: 1.2em;
color: var(--theia-arduino-branding-primary);
margin: 17px 0;
}
div#select-board-dialog .selectBoardContainer .head .text {
margin-bottom: 21px;
margin-bottom: 10px;
}
div#select-board-dialog .selectBoardContainer .body .list .item.selected {
@@ -57,6 +53,8 @@ div#select-board-dialog .selectBoardContainer .body .list .item.selected i {
#select-board-dialog .selectBoardContainer .body .container {
flex: 1;
padding: 0px 10px 0px 0px;
min-width: 240px;
max-width: 240px;
}
#select-board-dialog .selectBoardContainer .body .left.container .content {
@@ -82,15 +80,17 @@ div#select-board-dialog .selectBoardContainer .body .list .item.selected i {
color: var(--theia-arduino-branding-secondary);
padding: 10px 5px 10px 10px;
text-transform: uppercase;
/* The max, min-height comes from `.body .list` 265px + 47px top padding - 2 * 10px top padding */
max-height: 292px;
min-height: 292px;
/* The max, min-height comes from `.body .list` 200px + 47px top padding - 2 * 10px top padding */
max-height: 227px;
min-height: 227px;
}
#select-board-dialog .selectBoardContainer .body .list .item {
padding: 10px 5px 10px 10px;
display: flex;
justify-content: end;
white-space: nowrap;
overflow-x: hidden;
}
#select-board-dialog .selectBoardContainer .body .list .item .selected-icon {
@@ -114,9 +114,17 @@ div#select-board-dialog .selectBoardContainer .body .list .item.selected i {
background: var(--theia-secondaryButton-hoverBackground);
}
#select-board-dialog .selectBoardContainer .body .list .label {
max-width: 215px;
width: 215px;
white-space: pre;
overflow: hidden;
text-overflow: ellipsis;
}
#select-board-dialog .selectBoardContainer .body .list {
max-height: 265px;
min-height: 265px;
max-height: 200px;
min-height: 200px;
overflow-y: auto;
}
@@ -132,14 +140,8 @@ div#select-board-dialog .selectBoardContainer .body .list .item.selected i {
}
.p-Widget.dialogOverlay .dialogContent.select-board-dialog {
width: 740px;
width: 500px;
}
.dialogControl {
margin: 0 20px 30px 0;
}
.arduino-boards-toolbar-item-container {
margin-left: 3px;
}

View File

@@ -0,0 +1,36 @@
/* TODO: remove after https://github.com/eclipse-theia/theia/pull/9256/ */
/* To fix colors in Theia. */
.theia-debug-hover-title.number,
.theia-debug-console-variable.number {
color: var(--theia-variable-number-variable-color);
}
.theia-debug-hover-title.boolean,
.theia-debug-console-variable.boolean {
color: var(--theia-variable-boolean-variable-color);
}
.theia-debug-hover-title.string,
.theia-debug-console-variable.string {
color: var(--theia-variable-string-variable-color);
}
/* To unset the default debug hover dimension. */
.theia-debug-hover {
min-width: unset;
min-height: unset;
width: unset;
height: unset;
}
/* To adjust the left padding in the hover title. */
.theia-debug-hover-title {
padding-left: 5px;
}
/* Use the default Theia dimensions only iff the expression is complex (`!!expression.hasChildren~) */
.theia-debug-hover.complex-value {
min-width: 324px;
min-height: 324px;
width: 324px;
height: 324px;
}

View File

@@ -7,6 +7,7 @@
@import './terminal.css';
@import './editor.css';
@import './settings-dialog.css';
@import './debug.css';
.theia-input.warning:focus {
outline-width: 1px;
@@ -37,8 +38,13 @@
background-color: var(--theia-warningBackground);
}
/* Overrule the default Theia CSS button styles. */
/* Makes the sidepanel a bit wider when opening the widget */
.p-DockPanel-widget {
min-width: 200px;
min-height: 200px;
}
/* Overrule the default Theia CSS button styles. */
button.theia-button,
.theia-button {
border: 1px solid var(--theia-dropdown-border);
@@ -61,3 +67,20 @@ button.theia-button.secondary {
button.theia-button.main {
color: var(--theia-button-foreground);
}
/* To make the progress-bar slightly thicker, and use the color from the status bar */
.theia-progress-bar-container {
width: 100%;
height: 4px;
}
.theia-progress-bar {
height: 4px;
width: 3%;
animation: progress-animation 1.3s 0s infinite cubic-bezier(0.645, 0.045, 0.355, 1);
}
.theia-notification-item-progressbar {
height: 4px;
width: 66%;
}

View File

@@ -15,8 +15,8 @@
background: var(--theia-arduino-toolbar-background);
}
.p-TabBar-toolbar .item.arduino-tool-item > div:hover {
background: (--theia-arduino-toolbar-hoverBackground);
.p-TabBar-toolbar .item.arduino-tool-item.enabled:hover > div {
background: var(--theia-arduino-toolbar-hoverBackground);
}
.arduino-verify-sketch--toolbar,
@@ -24,6 +24,16 @@
border-radius: 12px;
}
.item.arduino-tool-item.toggled {
background-color: unset;
opacity: 1;
border: none;
}
.item.arduino-tool-item.toggled .arduino-verify-sketch--toolbar {
background-color: var(--theia-arduino-toolbar-toggleBackground) !important;
}
.arduino-tool-icon {
height: 24px;
width: 24px;
@@ -165,7 +175,6 @@
#arduino-open-sketch-control--toolbar--container {
background-color: var(--theia-arduino-toolbar-background);
padding: 8px 8px 8px 8px; /* based on pure heuristics */
}
#arduino-open-sketch-control--toolbar {
@@ -173,6 +182,7 @@
width: unset;
line-height: unset;
color: var(--theia-titleBar-activeBackground);
padding: 5px 8px; /* based on pure heuristics */
}
/* Output */

View File

@@ -4,7 +4,7 @@
.arduino-settings-dialog .content {
padding: 5px;
height: 270px;
height: 300px;
}
.arduino-settings-dialog .flex-line {

View File

@@ -0,0 +1,113 @@
import debounce = require('p-debounce');
import { inject, injectable, postConstruct } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { Event, Emitter } from '@theia/core/lib/common/event';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
import { DebugConfigurationModel as TheiaDebugConfigurationModel } from '@theia/debug/lib/browser/debug-configuration-model';
import { DebugConfigurationManager as TheiaDebugConfigurationManager } from '@theia/debug/lib/browser/debug-configuration-manager';
import { SketchesService } from '../../../common/protocol';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
import { DebugConfigurationModel } from './debug-configuration-model';
import { FileOperationError, FileOperationResult } from '@theia/filesystem/lib/common/files';
@injectable()
export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
@inject(SketchesService)
protected readonly sketchesService: SketchesService;
@inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;
protected onTempContentDidChangeEmitter = new Emitter<TheiaDebugConfigurationModel.JsonContent>();
get onTempContentDidChange(): Event<TheiaDebugConfigurationModel.JsonContent> {
return this.onTempContentDidChangeEmitter.event;
}
@postConstruct()
protected async init(): Promise<void> {
super.init();
this.appStateService.reachedState('ready').then(async () => {
const tempContent = await this.getTempLaunchJsonContent();
if (!tempContent) {
// No active sketch.
return;
}
// Watch the file of the container folder.
this.fileService.watch(tempContent instanceof URI ? tempContent : tempContent.uri);
// Use the normalized temp folder name. We cannot compare Theia URIs here.
// /var/folders/k3/d2fkvv1j16v3_rz93k7f74180000gn/T/arduino-ide2-a0337d47f86b24a51df3dbcf2cc17925/launch.json
// /private/var/folders/k3/d2fkvv1j16v3_rz93k7f74180000gn/T/arduino-ide2-A0337D47F86B24A51DF3DBCF2CC17925/launch.json
const tempFolderName = (tempContent instanceof URI ? tempContent : tempContent.uri.parent).path.base.toLowerCase();
this.fileService.onDidFilesChange(event => {
for (const { resource } of event.changes) {
if (resource.path.base === 'launch.json' && resource.parent.path.base.toLowerCase() === tempFolderName) {
this.getTempLaunchJsonContent().then(config => {
if (config && !(config instanceof URI)) {
this.onTempContentDidChangeEmitter.fire(config);
}
});
break;
}
}
});
this.updateModels();
});
}
protected updateModels = debounce(async () => {
await this.appStateService.reachedState('ready');
const roots = await this.workspaceService.roots;
const toDelete = new Set(this.models.keys());
for (const rootStat of roots) {
const key = rootStat.resource.toString();
toDelete.delete(key);
if (!this.models.has(key)) {
const tempContent = await this.getTempLaunchJsonContent();
if (!tempContent) {
continue;
}
const configurations: DebugConfiguration[] = tempContent instanceof URI ? [] : tempContent.configurations;
const uri = tempContent instanceof URI ? undefined : tempContent.uri;
const model = new DebugConfigurationModel(key, this.preferences, configurations, uri, this.onTempContentDidChange);
model.onDidChange(() => this.updateCurrent());
model.onDispose(() => this.models.delete(key));
this.models.set(key, model);
}
}
for (const uri of toDelete) {
const model = this.models.get(uri);
if (model) {
model.dispose();
}
}
this.updateCurrent();
}, 500);
protected async getTempLaunchJsonContent(): Promise<TheiaDebugConfigurationModel.JsonContent & { uri: URI } | URI | undefined> {
const sketch = await this.sketchesServiceClient.currentSketch();
if (!sketch) {
return undefined;
}
const uri = await this.sketchesService.getIdeTempFolderUri(sketch);
const tempFolderUri = new URI(uri);
await this.fileService.createFolder(tempFolderUri);
try {
const uri = tempFolderUri.resolve('launch.json');
const { value } = await this.fileService.read(uri);
const configurations = DebugConfigurationModel.parse(JSON.parse(value));
return { uri, configurations };
} catch (err) {
if (err instanceof FileOperationError && err.fileOperationResult === FileOperationResult.FILE_NOT_FOUND) {
return tempFolderUri;
}
console.error('Could not load debug configuration from IDE2 temp folder.', err);
throw err;
}
}
}

View File

@@ -0,0 +1,50 @@
import { Event } from '@theia/core/lib/common/event';
import URI from '@theia/core/lib/common/uri';
import { PreferenceService } from '@theia/core/lib/browser/preferences/preference-service';
import { DebugConfiguration } from '@theia/debug/lib/common/debug-common';
import { DebugConfigurationModel as TheiaDebugConfigurationModel } from '@theia/debug/lib/browser/debug-configuration-model';
export class DebugConfigurationModel extends TheiaDebugConfigurationModel {
constructor(
readonly workspaceFolderUri: string,
protected readonly preferences: PreferenceService,
protected readonly config: DebugConfiguration[],
protected configUri: URI | undefined,
protected readonly onConfigDidChange: Event<TheiaDebugConfigurationModel.JsonContent>) {
super(workspaceFolderUri, preferences);
this.toDispose.push(onConfigDidChange(content => {
const { uri, configurations } = content;
this.configUri = uri;
this.config.length = 0;
this.config.push(...configurations);
this.reconcile();
}));
this.reconcile();
}
protected parseConfigurations(): TheiaDebugConfigurationModel.JsonContent {
return {
uri: this.configUri,
configurations: this.config
};
}
}
export namespace DebugConfigurationModel {
export function parse(launchConfig: any): DebugConfiguration[] {
const configurations: DebugConfiguration[] = [];
if (launchConfig && typeof launchConfig === 'object' && 'configurations' in launchConfig) {
if (Array.isArray(launchConfig.configurations)) {
for (const configuration of launchConfig.configurations) {
if (DebugConfiguration.is(configuration)) {
configurations.push(configuration);
}
}
}
}
return configurations;
}
}

View File

@@ -0,0 +1,84 @@
import debounce from 'p-debounce';
import { inject, injectable, postConstruct, interfaces, Container } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
import { MonacoConfigurationService } from '@theia/monaco/lib/browser/monaco-frontend-module';
import { INLINE_VALUE_DECORATION_KEY } from '@theia/debug/lib/browser/editor//debug-inline-value-decorator';
import { DebugEditor } from '@theia/debug/lib/browser/editor/debug-editor';
import { DebugExceptionWidget } from '@theia/debug/lib/browser/editor/debug-exception-widget';
import { DebugBreakpointWidget } from '@theia/debug/lib/browser/editor/debug-breakpoint-widget';
import { DebugEditorModel as TheiaDebugEditorModel } from '@theia/debug/lib/browser/editor/debug-editor-model';
import { createDebugHoverWidgetContainer } from './debug-hover-widget'
// TODO: Remove after https://github.com/eclipse-theia/theia/pull/9256/
@injectable()
export class DebugEditorModel extends TheiaDebugEditorModel {
static createContainer(parent: interfaces.Container, editor: DebugEditor): Container {
const child = createDebugHoverWidgetContainer(parent, editor);
child.bind(DebugEditorModel).toSelf();
child.bind(DebugBreakpointWidget).toSelf();
child.bind(DebugExceptionWidget).toSelf();
return child;
}
static createModel(parent: interfaces.Container, editor: DebugEditor): DebugEditorModel {
return DebugEditorModel.createContainer(parent, editor).get(DebugEditorModel);
}
@inject(MonacoConfigurationService)
readonly configurationService: monaco.services.IConfigurationService;
protected readonly toDisposeOnRenderFrames = new DisposableCollection();
@postConstruct()
protected init(): void {
this.toDispose.push(this.toDisposeOnRenderFrames);
super.init();
}
protected async updateEditorHover(): Promise<void> {
if (this.isCurrentEditorFrame(this.uri)) {
const codeEditor = this.editor.getControl();
codeEditor.updateOptions({ hover: { enabled: false } });
this.toDisposeOnRenderFrames.push(Disposable.create(() => {
const model = codeEditor.getModel()!;
const overrides = {
resource: model.uri,
overrideIdentifier: (model as any).getLanguageIdentifier().language,
};
const { enabled, delay, sticky } = this.configurationService._configuration.getValue('editor.hover', overrides, undefined);
codeEditor.updateOptions({
hover: {
enabled,
delay,
sticky
}
});
}));
}
}
private isCurrentEditorFrame(uri: URI): boolean {
return this.sessions.currentFrame?.source?.uri.toString() === uri.toString();
}
protected readonly renderFrames = debounce(async () => {
if (this.toDispose.disposed) {
return;
}
this.toDisposeOnRenderFrames.dispose();
this.toggleExceptionWidget();
const [newFrameDecorations, inlineValueDecorations] = await Promise.all([
this.createFrameDecorations(),
this.createInlineValueDecorations()
]);
const codeEditor = this.editor.getControl();
codeEditor.removeDecorations(INLINE_VALUE_DECORATION_KEY);
codeEditor.setDecorations(INLINE_VALUE_DECORATION_KEY, inlineValueDecorations);
this.frameDecorations = this.deltaDecorations(this.frameDecorations, newFrameDecorations);
this.updateEditorHover();
}, 100);
}

View File

@@ -6,6 +6,11 @@ import { unregisterSubmenu } from '../../menu/arduino-menus';
@injectable()
export class DebugFrontendApplicationContribution extends TheiaDebugFrontendApplicationContribution {
constructor() {
super()
this.options.defaultWidgetOptions.rank = 4;
}
registerMenus(registry: MenuModelRegistry): void {
super.registerMenus(registry);
unregisterSubmenu(DebugMenus.DEBUG, registry);

View File

@@ -0,0 +1,18 @@
import { injectable } from 'inversify';
import { ExpressionItem, DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items';
import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source';
// TODO: remove after https://github.com/eclipse-theia/theia/pull/9256/.
@injectable()
export class DebugHoverSource extends TheiaDebugHoverSource {
async evaluate2(expression: string): Promise<ExpressionItem | DebugVariable | undefined> {
const evaluated = await this.doEvaluate(expression);
const elements = evaluated && await evaluated.getElements();
this._expression = evaluated;
this.elements = elements ? [...elements] : [];
this.fireDidChange();
return evaluated;
}
}

View File

@@ -0,0 +1,96 @@
import { injectable, interfaces, Container } from 'inversify';
import { Widget } from '@phosphor/widgets';
import { SourceTreeWidget } from '@theia/core/lib/browser/source-tree';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { DebugEditor } from '@theia/debug/lib/browser/editor/debug-editor';
import { DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items';
import { DebugExpressionProvider } from '@theia/debug/lib/browser/editor/debug-expression-provider';
import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source';
import { DebugHoverWidget as TheiaDebugHoverWidget, ShowDebugHoverOptions } from '@theia/debug/lib/browser/editor/debug-hover-widget';
import { DebugHoverSource } from './debug-hover-source';
export function createDebugHoverWidgetContainer(parent: interfaces.Container, editor: DebugEditor): Container {
const child = SourceTreeWidget.createContainer(parent, {
virtualized: false
});
child.bind(DebugEditor).toConstantValue(editor);
child.bind(TheiaDebugHoverSource).toSelf();
child.bind(DebugHoverSource).toSelf();
child.rebind(TheiaDebugHoverSource).to(DebugHoverSource);
child.unbind(SourceTreeWidget);
child.bind(DebugExpressionProvider).toSelf();
child.bind(TheiaDebugHoverWidget).toSelf();
child.bind(DebugHoverWidget).toSelf();
child.rebind(TheiaDebugHoverWidget).to(DebugHoverWidget);
return child;
}
// TODO: remove patch after https://github.com/eclipse-theia/theia/pull/9256/
@injectable()
export class DebugHoverWidget extends TheiaDebugHoverWidget {
protected async doShow(options: ShowDebugHoverOptions | undefined = this.options): Promise<void> {
if (!this.isEditorFrame()) {
this.hide();
return;
}
if (!options) {
this.hide();
return;
}
if (this.options && this.options.selection.equalsRange(options.selection)) {
return;
}
if (!this.isAttached) {
Widget.attach(this, this.contentNode);
}
this.options = options;
const matchingExpression = this.expressionProvider.get(this.editor.getControl().getModel()!, options.selection);
if (!matchingExpression) {
this.hide();
return;
}
const toFocus = new DisposableCollection();
if (this.options.focus === true) {
toFocus.push(this.model.onNodeRefreshed(() => {
toFocus.dispose();
this.activate();
}));
}
const expression = await (this.hoverSource as DebugHoverSource).evaluate2(matchingExpression);
if (!expression || !expression.value) {
toFocus.dispose();
this.hide();
return;
}
this.contentNode.hidden = false;
['number', 'boolean', 'string'].forEach(token => this.titleNode.classList.remove(token));
this.domNode.classList.remove('complex-value');
if (expression.hasElements) {
this.domNode.classList.add('complex-value');
} else {
this.contentNode.hidden = true;
if (expression.type === 'number' || expression.type === 'boolean' || expression.type === 'string') {
this.titleNode.classList.add(expression.type);
} else if (!isNaN(+expression.value)) {
this.titleNode.classList.add('number');
} else if (DebugVariable.booleanRegex.test(expression.value)) {
this.titleNode.classList.add('boolean');
} else if (DebugVariable.stringRegex.test(expression.value)) {
this.titleNode.classList.add('string');
}
}
// super.show(); // Here we cannot call `super.show()` but have to call `show` on the `Widget` prototype.
Widget.prototype.show.call(this);
await new Promise<void>(resolve => {
setTimeout(() => window.requestAnimationFrame(() => {
this.editor.getControl().layoutContentWidget(this);
resolve();
}), 0);
});
}
}

View File

@@ -1,31 +0,0 @@
import { inject, injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { EditorManager as TheiaEditorManager, EditorOpenerOptions } from '@theia/editor/lib/browser/editor-manager';
import { ConfigService } from '../../../common/protocol/config-service';
import { EditorWidget } from '@theia/editor/lib/browser';
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
@injectable()
export class EditorManager extends TheiaEditorManager {
@inject(ConfigService)
protected readonly configService: ConfigService;
async open(uri: URI, options?: EditorOpenerOptions): Promise<EditorWidget> {
const [widget, readOnly] = await Promise.all([super.open(uri, options), this.isReadOnly(uri)]);
if (readOnly) {
const { editor } = widget;
if (editor instanceof MonacoEditor) {
const codeEditor = editor.getControl();
codeEditor.updateOptions({ readOnly });
}
}
return widget;
}
protected async isReadOnly(uri: URI): Promise<boolean> {
const config = await this.configService.getConfiguration();
return new URI(config.dataDirUri).isEqualOrParent(uri)
}
}

View File

@@ -0,0 +1,16 @@
import { injectable } from 'inversify';
import { MenuModelRegistry } from '@theia/core';
import { KeymapsFrontendContribution as TheiaKeymapsFrontendContribution, KeymapsCommands } from '@theia/keymaps/lib/browser/keymaps-frontend-contribution';
import { ArduinoMenus } from '../../menu/arduino-menus';
@injectable()
export class KeymapsFrontendContribution extends TheiaKeymapsFrontendContribution {
registerMenus(menus: MenuModelRegistry): void {
menus.registerMenuAction(ArduinoMenus.FILE__ADVANCED_SUBMENU, {
commandId: KeymapsCommands.OPEN_KEYMAPS.id,
label: 'Keyboard Shortcuts',
order: '1'
});
}
}

View File

@@ -0,0 +1,34 @@
import * as React from 'react';
import { NotificationComponent } from './notification-component';
import { NotificationCenterComponent as TheiaNotificationCenterComponent } from '@theia/messages/lib/browser/notification-center-component'
const PerfectScrollbar = require('react-perfect-scrollbar');
export class NotificationCenterComponent extends TheiaNotificationCenterComponent {
render(): React.ReactNode {
const empty = this.state.notifications.length === 0;
const title = empty ? 'NO NEW NOTIFICATIONS' : 'NOTIFICATIONS';
return (
<div className={`theia-notifications-container theia-notification-center ${this.state.visibilityState === 'center' ? 'open' : 'closed'}`}>
<div className='theia-notification-center-header'>
<div className='theia-notification-center-header-title'>{title}</div>
<div className='theia-notification-center-header-actions'>
<ul className='theia-notification-actions'>
<li className='collapse' title='Hide Notification Center' onClick={this.onHide} />
<li className='clear-all' title='Clear All' onClick={this.onClearAll} />
</ul>
</div>
</div>
<PerfectScrollbar className='theia-notification-list-scroll-container'>
<div className='theia-notification-list'>
{this.state.notifications.map(notification =>
<NotificationComponent key={notification.messageId} notification={notification} manager={this.props.manager} />
)}
</div>
</PerfectScrollbar>
</div>
);
}
}

View File

@@ -0,0 +1,62 @@
import * as React from 'react';
import { NotificationComponent as TheiaNotificationComponent } from '@theia/messages/lib/browser/notification-component'
export class NotificationComponent extends TheiaNotificationComponent {
render(): React.ReactNode {
const { messageId, message, type, collapsed, expandable, source, actions } = this.props.notification;
return (<div key={messageId} className='theia-notification-list-item'>
<div className={`theia-notification-list-item-content ${collapsed ? 'collapsed' : ''}`}>
<div className='theia-notification-list-item-content-main'>
<div className={`theia-notification-icon theia-notification-icon-${type}`} />
<div className='theia-notification-message'>
<span dangerouslySetInnerHTML={{ __html: message }} onClick={this.onMessageClick} />
</div>
<ul className='theia-notification-actions'>
{expandable && (
<li className={collapsed ? 'expand' : 'collapse'} title={collapsed ? 'Expand' : 'Collapse'}
data-message-id={messageId} onClick={this.onToggleExpansion} />
)}
{!this.isProgress && (<li className='clear' title='Clear' data-message-id={messageId} onClick={this.onClear} />)}
</ul>
</div>
{(source || !!actions.length) && (
<div className='theia-notification-list-item-content-bottom'>
<div className='theia-notification-source'>
{source && (<span>{source}</span>)}
</div>
<div className='theia-notification-buttons'>
{actions && actions.map((action, index) => (
<button key={messageId + `-action-${index}`} className='theia-button'
data-message-id={messageId} data-action={action}
onClick={this.onAction}>
{action}
</button>
))}
</div>
</div>
)}
</div>
{this.renderProgressBar()}
</div>);
}
private renderProgressBar(): React.ReactNode {
if (!this.isProgress) {
return undefined;
}
if (!Number.isNaN(this.props.notification.progress)) {
return <div className='theia-notification-item-progress'>
<div className='theia-notification-item-progressbar' style={{ width: `${this.props.notification.progress}%` }} />
</div>;
}
return <div className='theia-progress-bar-container'>
<div className='theia-progress-bar' />
</div>
}
private get isProgress(): boolean {
return typeof this.props.notification.progress === 'number';
}
}

View File

@@ -0,0 +1,17 @@
import * as React from 'react';
import { NotificationComponent } from './notification-component';
import { NotificationToastsComponent as TheiaNotificationToastsComponent } from '@theia/messages/lib/browser/notification-toasts-component'
export class NotificationToastsComponent extends TheiaNotificationToastsComponent {
render(): React.ReactNode {
return (
<div className={`theia-notifications-container theia-notification-toasts ${this.state.visibilityState === 'toasts' ? 'open' : 'closed'}`}>
<div className='theia-notification-list'>
{this.state.toasts.map(notification => <NotificationComponent key={notification.messageId} notification={notification} manager={this.props.manager} />)}
</div>
</div>
);
}
}

View File

@@ -0,0 +1,37 @@
import { injectable } from 'inversify';
import { CancellationToken } from '@theia/core/lib/common/cancellation';
import { ProgressMessage, ProgressUpdate } from '@theia/core/lib/common/message-service-protocol';
import { NotificationManager as TheiaNotificationManager } from '@theia/messages/lib/browser/notifications-manager';
@injectable()
export class NotificationManager extends TheiaNotificationManager {
async reportProgress(messageId: string, update: ProgressUpdate, originalMessage: ProgressMessage, cancellationToken: CancellationToken): Promise<void> {
const notification = this.find(messageId);
if (!notification) {
return;
}
if (cancellationToken.isCancellationRequested) {
this.clear(messageId);
} else {
notification.message = originalMessage.text && update.message ? `${originalMessage.text}: ${update.message}` :
originalMessage.text || update?.message || notification.message;
// Unlike in Theia, we allow resetting the progress monitor to NaN to enforce unknown progress.
const candidate = this.toPlainProgress(update);
notification.progress = typeof candidate === 'number' ? candidate : notification.progress;
}
this.fireUpdatedEvent();
}
protected toPlainProgress(update: ProgressUpdate): number | undefined {
if (!update.work) {
return undefined;
}
if (Number.isNaN(update.work.done) || Number.isNaN(update.work.total)) {
return Number.NaN; // This should trigger the unknown monitor.
}
return Math.min(update.work.done / update.work.total * 100, 100);
}
}

View File

@@ -0,0 +1,18 @@
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { injectable } from 'inversify';
import { NotificationCenterComponent } from './notification-center-component';
import { NotificationToastsComponent } from './notification-toasts-component';
import { NotificationsRenderer as TheiaNotificationsRenderer } from '@theia/messages/lib/browser/notifications-renderer';
@injectable()
export class NotificationsRenderer extends TheiaNotificationsRenderer {
protected render(): void {
ReactDOM.render(<div>
<NotificationToastsComponent manager={this.manager} corePreferences={this.corePreferences} />
<NotificationCenterComponent manager={this.manager} />
</div>, this.container);
}
}

View File

@@ -1,368 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// Copied from https://github.com/microsoft/vscode/blob/724c307bf35646ac549a8533a255c51b63fea5c7/src/vs/base/common/comparers.ts
// We cannot customize the monaco loader for Theia: https://github.com/eclipse-theia/theia/issues/8220
import { isWindows } from '@theia/core/lib/common/os';
const sep = (isWindows ? '\\' : '/');
interface IDisposable {
dispose(): void;
}
interface IdleDeadline {
readonly didTimeout: boolean;
timeRemaining(): number;
}
let runWhenIdle: (callback: (idle: IdleDeadline) => void, timeout?: number) => IDisposable;
declare function requestIdleCallback(callback: (args: IdleDeadline) => void, options?: { timeout: number }): number;
declare function cancelIdleCallback(handle: number): void;
(function () {
if (typeof requestIdleCallback !== 'function' || typeof cancelIdleCallback !== 'function') {
const dummyIdle: IdleDeadline = Object.freeze({
didTimeout: true,
timeRemaining() { return 15; }
});
runWhenIdle = (runner) => {
const handle = setTimeout(() => runner(dummyIdle));
let disposed = false;
return {
dispose() {
if (disposed) {
return;
}
disposed = true;
clearTimeout(handle);
}
};
};
} else {
runWhenIdle = (runner, timeout?) => {
const handle: number = requestIdleCallback(runner, typeof timeout === 'number' ? { timeout } : undefined);
let disposed = false;
return {
dispose() {
if (disposed) {
return;
}
disposed = true;
cancelIdleCallback(handle);
}
};
};
}
})();
/**
* An implementation of the "idle-until-urgent"-strategy as introduced
* here: https://philipwalton.com/articles/idle-until-urgent/
*/
class IdleValue<T> {
private readonly _executor: () => void;
private readonly _handle: IDisposable;
private _didRun: boolean = false;
private _value?: T;
private _error: any;
constructor(executor: () => T) {
this._executor = () => {
try {
this._value = executor();
} catch (err) {
this._error = err;
} finally {
this._didRun = true;
}
};
this._handle = runWhenIdle(() => this._executor());
}
dispose(): void {
this._handle.dispose();
}
get value(): T {
if (!this._didRun) {
this._handle.dispose();
this._executor();
}
if (this._error) {
throw this._error;
}
return this._value!;
}
}
// When comparing large numbers of strings, such as in sorting large arrays, is better for
// performance to create an Intl.Collator object and use the function provided by its compare
// property than it is to use String.prototype.localeCompare()
// A collator with numeric sorting enabled, and no sensitivity to case or to accents
const intlFileNameCollatorBaseNumeric: IdleValue<{ collator: Intl.Collator, collatorIsNumeric: boolean }> = new IdleValue(() => {
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
return {
collator: collator,
collatorIsNumeric: collator.resolvedOptions().numeric
};
});
// A collator with numeric sorting enabled.
const intlFileNameCollatorNumeric: IdleValue<{ collator: Intl.Collator }> = new IdleValue(() => {
const collator = new Intl.Collator(undefined, { numeric: true });
return {
collator: collator
};
});
// A collator with numeric sorting enabled, and sensitivity to accents and diacritics but not case.
const intlFileNameCollatorNumericCaseInsenstive: IdleValue<{ collator: Intl.Collator }> = new IdleValue(() => {
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'accent' });
return {
collator: collator
};
});
export function compareFileNames(one: string | null, other: string | null, caseSensitive = false): number {
const a = one || '';
const b = other || '';
const result = intlFileNameCollatorBaseNumeric.value.collator.compare(a, b);
// Using the numeric option in the collator will
// make compare(`foo1`, `foo01`) === 0. We must disambiguate.
if (intlFileNameCollatorBaseNumeric.value.collatorIsNumeric && result === 0 && a !== b) {
return a < b ? -1 : 1;
}
return result;
}
/** Compares filenames by name then extension, sorting numbers numerically instead of alphabetically. */
export function compareFileNamesNumeric(one: string | null, other: string | null): number {
const [oneName, oneExtension] = extractNameAndExtension(one, true);
const [otherName, otherExtension] = extractNameAndExtension(other, true);
const collatorNumeric = intlFileNameCollatorNumeric.value.collator;
const collatorNumericCaseInsensitive = intlFileNameCollatorNumericCaseInsenstive.value.collator;
let result;
// Check for name differences, comparing numbers numerically instead of alphabetically.
result = compareAndDisambiguateByLength(collatorNumeric, oneName, otherName);
if (result !== 0) {
return result;
}
// Check for case insensitive extension differences, comparing numbers numerically instead of alphabetically.
result = compareAndDisambiguateByLength(collatorNumericCaseInsensitive, oneExtension, otherExtension);
if (result !== 0) {
return result;
}
// Disambiguate the extension case if needed.
if (oneExtension !== otherExtension) {
return collatorNumeric.compare(oneExtension, otherExtension);
}
return 0;
}
const FileNameMatch = /^(.*?)(\.([^.]*))?$/;
export function noIntlCompareFileNames(one: string | null, other: string | null, caseSensitive = false): number {
if (!caseSensitive) {
one = one && one.toLowerCase();
other = other && other.toLowerCase();
}
const [oneName, oneExtension] = extractNameAndExtension(one);
const [otherName, otherExtension] = extractNameAndExtension(other);
if (oneName !== otherName) {
return oneName < otherName ? -1 : 1;
}
if (oneExtension === otherExtension) {
return 0;
}
return oneExtension < otherExtension ? -1 : 1;
}
export function compareFileExtensions(one: string | null, other: string | null): number {
const [oneName, oneExtension] = extractNameAndExtension(one);
const [otherName, otherExtension] = extractNameAndExtension(other);
let result = intlFileNameCollatorBaseNumeric.value.collator.compare(oneExtension, otherExtension);
if (result === 0) {
// Using the numeric option in the collator will
// make compare(`foo1`, `foo01`) === 0. We must disambiguate.
if (intlFileNameCollatorBaseNumeric.value.collatorIsNumeric && oneExtension !== otherExtension) {
return oneExtension < otherExtension ? -1 : 1;
}
// Extensions are equal, compare filenames
result = intlFileNameCollatorBaseNumeric.value.collator.compare(oneName, otherName);
if (intlFileNameCollatorBaseNumeric.value.collatorIsNumeric && result === 0 && oneName !== otherName) {
return oneName < otherName ? -1 : 1;
}
}
return result;
}
/** Compares filenames by extenson, then by name. Sorts numbers numerically, not alphabetically. */
export function compareFileExtensionsNumeric(one: string | null, other: string | null): number {
const [oneName, oneExtension] = extractNameAndExtension(one, true);
const [otherName, otherExtension] = extractNameAndExtension(other, true);
const collatorNumeric = intlFileNameCollatorNumeric.value.collator;
const collatorNumericCaseInsensitive = intlFileNameCollatorNumericCaseInsenstive.value.collator;
let result;
// Check for extension differences, ignoring differences in case and comparing numbers numerically.
result = compareAndDisambiguateByLength(collatorNumericCaseInsensitive, oneExtension, otherExtension);
if (result !== 0) {
return result;
}
// Compare names.
result = compareAndDisambiguateByLength(collatorNumeric, oneName, otherName);
if (result !== 0) {
return result;
}
// Disambiguate extension case if needed.
if (oneExtension !== otherExtension) {
return collatorNumeric.compare(oneExtension, otherExtension);
}
return 0;
}
/** Extracts the name and extension from a full filename, with optional special handling for dotfiles */
function extractNameAndExtension(str?: string | null, dotfilesAsNames = false): [string, string] {
const match = str ? FileNameMatch.exec(str) as Array<string> : ([] as Array<string>);
let result: [string, string] = [(match && match[1]) || '', (match && match[3]) || ''];
// if the dotfilesAsNames option is selected, treat an empty filename with an extension,
// or a filename that starts with a dot, as a dotfile name
if (dotfilesAsNames && (!result[0] && result[1] || result[0] && result[0].charAt(0) === '.')) {
result = [result[0] + '.' + result[1], ''];
}
return result;
}
function compareAndDisambiguateByLength(collator: Intl.Collator, one: string, other: string) {
// Check for differences
let result = collator.compare(one, other);
if (result !== 0) {
return result;
}
// In a numeric comparison, `foo1` and `foo01` will compare as equivalent.
// Disambiguate by sorting the shorter string first.
if (one.length !== other.length) {
return one.length < other.length ? -1 : 1;
}
return 0;
}
function comparePathComponents(one: string, other: string, caseSensitive = false): number {
if (!caseSensitive) {
one = one && one.toLowerCase();
other = other && other.toLowerCase();
}
if (one === other) {
return 0;
}
return one < other ? -1 : 1;
}
export function comparePaths(one: string, other: string, caseSensitive = false): number {
const oneParts = one.split(sep);
const otherParts = other.split(sep);
const lastOne = oneParts.length - 1;
const lastOther = otherParts.length - 1;
let endOne: boolean, endOther: boolean;
for (let i = 0; ; i++) {
endOne = lastOne === i;
endOther = lastOther === i;
if (endOne && endOther) {
return compareFileNames(oneParts[i], otherParts[i], caseSensitive);
} else if (endOne) {
return -1;
} else if (endOther) {
return 1;
}
const result = comparePathComponents(oneParts[i], otherParts[i], caseSensitive);
if (result !== 0) {
return result;
}
}
}
export function compareAnything(one: string, other: string, lookFor: string): number {
const elementAName = one.toLowerCase();
const elementBName = other.toLowerCase();
// Sort prefix matches over non prefix matches
const prefixCompare = compareByPrefix(one, other, lookFor);
if (prefixCompare) {
return prefixCompare;
}
// Sort suffix matches over non suffix matches
const elementASuffixMatch = elementAName.endsWith(lookFor);
const elementBSuffixMatch = elementBName.endsWith(lookFor);
if (elementASuffixMatch !== elementBSuffixMatch) {
return elementASuffixMatch ? -1 : 1;
}
// Understand file names
const r = compareFileNames(elementAName, elementBName);
if (r !== 0) {
return r;
}
// Compare by name
return elementAName.localeCompare(elementBName);
}
export function compareByPrefix(one: string, other: string, lookFor: string): number {
const elementAName = one.toLowerCase();
const elementBName = other.toLowerCase();
// Sort prefix matches over non prefix matches
const elementAPrefixMatch = elementAName.startsWith(lookFor);
const elementBPrefixMatch = elementBName.startsWith(lookFor);
if (elementAPrefixMatch !== elementBPrefixMatch) {
return elementAPrefixMatch ? -1 : 1;
}
// Same prefix: Sort shorter matches to the top to have those on top that match more precisely
// tslint:disable-next-line: one-line
else if (elementAPrefixMatch && elementBPrefixMatch) {
if (elementAName.length < elementBName.length) {
return -1;
}
if (elementAName.length > elementBName.length) {
return 1;
}
}
return 0;
}

View File

@@ -0,0 +1,64 @@
import { inject, injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { Disposable, DisposableCollection } from '@theia/core/lib/common/disposable';
import { MonacoEditor } from '@theia/monaco/lib/browser/monaco-editor';
import { MonacoEditorProvider as TheiaMonacoEditorProvider } from '@theia/monaco/lib/browser/monaco-editor-provider';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
type CancelablePromise = Promise<monaco.referenceSearch.ReferencesModel> & { cancel: () => void };
interface EditorFactory {
(override: monaco.editor.IEditorOverrideServices, toDispose: DisposableCollection): Promise<MonacoEditor>;
}
@injectable()
export class MonacoEditorProvider extends TheiaMonacoEditorProvider {
@inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
protected async doCreateEditor(uri: URI, factory: EditorFactory): Promise<MonacoEditor> {
const editor = await super.doCreateEditor(uri, factory);
const toDispose = new DisposableCollection();
toDispose.push(this.installCustomReferencesController(editor));
toDispose.push(editor.onDispose(() => toDispose.dispose()));
return editor;
}
private installCustomReferencesController(editor: MonacoEditor): Disposable {
const control = editor.getControl();
const referencesController = control._contributions['editor.contrib.referencesController'];
const originalToggleWidget = referencesController.toggleWidget;
const toDispose = new DisposableCollection();
const toDisposeBeforeToggleWidget = new DisposableCollection();
referencesController.toggleWidget = (range: monaco.Range, modelPromise: CancelablePromise, peekMode: boolean) => {
toDisposeBeforeToggleWidget.dispose();
originalToggleWidget.bind(referencesController)(range, modelPromise, peekMode);
if (referencesController._widget) {
if ('onDidClose' in referencesController._widget) {
toDisposeBeforeToggleWidget.push((referencesController._widget as any).onDidClose(() => toDisposeBeforeToggleWidget.dispose()));
}
const preview = (referencesController._widget as any)._preview as monaco.editor.ICodeEditor;
if (preview) {
toDisposeBeforeToggleWidget.push(preview.onDidChangeModel(() => this.updateReadOnlyState(preview)))
this.updateReadOnlyState(preview);
}
}
};
toDispose.push(Disposable.create(() => toDisposeBeforeToggleWidget.dispose()));
toDispose.push(Disposable.create(() => referencesController.toggleWidget = originalToggleWidget));
return toDispose;
}
private updateReadOnlyState(editor: monaco.editor.ICodeEditor | undefined): void {
if (!editor) {
return;
}
const model = editor.getModel();
if (!model) {
return;
}
const readOnly = this.sketchesServiceClient.isReadOnly(model.uri);
editor.updateOptions({ readOnly });
}
}

View File

@@ -1,22 +1,29 @@
import { injectable } from 'inversify';
import { inject, injectable } from 'inversify';
import { Resource } from '@theia/core/lib/common/resource';
import { MaybePromise } from '@theia/core/lib/common/types';
import { Log, Loggable } from '@theia/core/lib/common/logger';
import { ILogger, Log, Loggable } from '@theia/core/lib/common/logger';
import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
import { EditorPreferences } from '@theia/editor/lib/browser/editor-preferences';
import { MonacoToProtocolConverter } from '@theia/monaco/lib/browser/monaco-to-protocol-converter';
import { ProtocolToMonacoConverter } from '@theia/monaco/lib/browser/protocol-to-monaco-converter';
import { MonacoTextModelService as TheiaMonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
@injectable()
export class MonacoTextModelService extends TheiaMonacoTextModelService {
protected createModel(resource: Resource): MaybePromise<MonacoEditorModel> {
@inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
protected async createModel(resource: Resource): Promise<MonacoEditorModel> {
const factory = this.factories.getContributions().find(({ scheme }) => resource.uri.scheme === scheme);
return factory ? factory.createModel(resource) : new SilentMonacoEditorModel(resource, this.m2p, this.p2m, this.logger);
const readOnly = this.sketchesServiceClient.isReadOnly(resource.uri);
return factory ? factory.createModel(resource) : new MaybeReadonlyMonacoEditorModel(resource, this.m2p, this.p2m, this.logger, undefined, readOnly);
}
}
// https://github.com/eclipse-theia/theia/pull/8491
export class SilentMonacoEditorModel extends MonacoEditorModel {
class SilentMonacoEditorModel extends MonacoEditorModel {
protected trace(loggable: Loggable): void {
if (this.logger) {
@@ -27,3 +34,41 @@ export class SilentMonacoEditorModel extends MonacoEditorModel {
}
}
class MaybeReadonlyMonacoEditorModel extends SilentMonacoEditorModel {
constructor(
protected readonly resource: Resource,
protected readonly m2p: MonacoToProtocolConverter,
protected readonly p2m: ProtocolToMonacoConverter,
protected readonly logger?: ILogger,
protected readonly editorPreferences?: EditorPreferences,
protected readonly _readOnly?: boolean,
) {
super(resource, m2p, p2m, logger, editorPreferences)
}
get readOnly(): boolean {
if (typeof this._readOnly === 'boolean') {
return this._readOnly;
}
return this.resource.saveContents === undefined;
}
protected setDirty(dirty: boolean): void {
if (this._readOnly === true) {
// NOOP
return;
}
if (dirty === this._dirty) {
return;
}
this._dirty = dirty;
if (dirty === false) {
(this as any).updateSavedVersionId();
}
this.onDirtyChangedEmitter.fire(undefined);
}
}

View File

@@ -1,12 +1,28 @@
import { injectable } from 'inversify';
import { inject, injectable } from 'inversify';
import { WorkspaceCommands } from '@theia/workspace/lib/browser/workspace-commands';
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
import { FileNavigatorContribution as TheiaFileNavigatorContribution } from '@theia/navigator/lib/browser/navigator-contribution';
import { FileNavigatorPreferences } from '@theia/navigator/lib/browser/navigator-preferences';
import { OpenerService } from '@theia/core/lib/browser/opener-service';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { FileNavigatorFilter } from '@theia/navigator/lib/browser/navigator-filter';
import { WorkspacePreferences } from '@theia/workspace/lib/browser/workspace-preferences';
@injectable()
export class FileNavigatorContribution extends TheiaFileNavigatorContribution {
constructor(
@inject(FileNavigatorPreferences) protected readonly fileNavigatorPreferences: FileNavigatorPreferences,
@inject(OpenerService) protected readonly openerService: OpenerService,
@inject(FileNavigatorFilter) protected readonly fileNavigatorFilter: FileNavigatorFilter,
@inject(WorkspaceService) protected readonly workspaceService: WorkspaceService,
@inject(WorkspacePreferences) protected readonly workspacePreferences: WorkspacePreferences
) {
super(fileNavigatorPreferences, openerService, fileNavigatorFilter, workspaceService, workspacePreferences);
this.options.defaultWidgetOptions.rank = 1;
}
async initializeLayout(app: FrontendApplication): Promise<void> {
// NOOP
}

View File

@@ -1,14 +1,14 @@
import { injectable } from 'inversify';
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
import { SearchInWorkspaceFrontendContribution as TheiaSearchInWorkspaceFrontendContribution, SearchInWorkspaceCommands } from '@theia/search-in-workspace/lib/browser/search-in-workspace-frontend-contribution';
@injectable()
export class SearchInWorkspaceFrontendContribution extends TheiaSearchInWorkspaceFrontendContribution {
async initializeLayout(app: FrontendApplication): Promise<void> {
// NOOP
constructor() {
super();
this.options.defaultWidgetOptions.rank = 5;
}
registerMenus(registry: MenuModelRegistry): void {

View File

@@ -0,0 +1,34 @@
import { injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { MEMORY_TEXT } from '@theia/search-in-workspace/lib/browser/in-memory-text-resource';
import { SearchInWorkspaceFileNode, SearchInWorkspaceResultTreeWidget as TheiaSearchInWorkspaceResultTreeWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-result-tree-widget';
/**
* Workaround for https://github.com/eclipse-theia/theia/pull/9192/.
*/
@injectable()
export class SearchInWorkspaceResultTreeWidget extends TheiaSearchInWorkspaceResultTreeWidget {
protected async createReplacePreview(node: SearchInWorkspaceFileNode): Promise<URI> {
const fileUri = new URI(node.fileUri).withScheme('file');
const openedEditor = this.editorManager.all.find(({ editor }) => editor.uri.toString() === fileUri.toString());
let content: string;
if (openedEditor) {
content = openedEditor.editor.document.getText();
} else {
const resource = await this.fileResourceResolver.resolve(fileUri);
content = await resource.readContents();
}
const lines = content.split('\n');
node.children.map(l => {
const leftPositionedNodes = node.children.filter(rl => rl.line === l.line && rl.character < l.character);
const diff = (this._replaceTerm.length - this.searchTerm.length) * leftPositionedNodes.length;
const start = lines[l.line - 1].substr(0, l.character - 1 + diff);
const end = lines[l.line - 1].substr(l.character - 1 + diff + l.length);
lines[l.line - 1] = start + this._replaceTerm + end;
});
return fileUri.withScheme(MEMORY_TEXT).withQuery(lines.join('\n'));
}
}

View File

@@ -0,0 +1,54 @@
import { injectable } from 'inversify';
import * as React from 'react';
import { Key, KeyCode } from '@theia/core/lib/browser';
import { SearchInWorkspaceWidget as TheiaSearchInWorkspaceWidget } from '@theia/search-in-workspace/lib/browser/search-in-workspace-widget';
/**
* Workaround for https://github.com/eclipse-theia/theia/pull/9183.
*/
@injectable()
export class SearchInWorkspaceWidget extends TheiaSearchInWorkspaceWidget {
protected renderGlobField(kind: 'include' | 'exclude'): React.ReactNode {
const currentValue = this.searchInWorkspaceOptions[kind];
const value = currentValue && currentValue.join(', ') || '';
return <div className='glob-field'>
<div className='label'>{'files to ' + kind}</div>
<input
className='theia-input'
type='text'
size={1}
defaultValue={value}
id={kind + '-glob-field'}
onKeyUp={e => {
if (e.target) {
const targetValue = (e.target as HTMLInputElement).value || '';
let shouldSearch = Key.ENTER.keyCode === KeyCode.createKeyCode(e.nativeEvent).key?.keyCode;
const currentOptions = (this.searchInWorkspaceOptions[kind] || []).slice().map(s => s.trim()).sort();
const candidateOptions = this.splitOnComma(targetValue).map(s => s.trim()).sort();
const sameAs = (left: string[], right: string[]) => {
if (left.length !== right.length) {
return false;
}
for (let i = 0; i < left.length; i++) {
if (left[i] !== right[i]) {
return false;
}
}
return true;
};
if (!sameAs(currentOptions, candidateOptions)) {
this.searchInWorkspaceOptions[kind] = this.splitOnComma(targetValue);
shouldSearch = true;
}
if (shouldSearch) {
this.resultTreeWidget.search(this.searchTerm, this.searchInWorkspaceOptions);
}
}
}}
onFocus={kind === 'include' ? this.handleFocusIncludesInputBox : this.handleFocusExcludesInputBox}
onBlur={kind === 'include' ? this.handleBlurIncludesInputBox : this.handleBlurExcludesInputBox}></input>
</div>;
}
}

View File

@@ -6,10 +6,13 @@ import { MessageService } from '@theia/core/lib/common/message-service';
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
import { FrontendApplication } from '@theia/core/lib/browser/frontend-application';
import { FocusTracker, Widget } from '@theia/core/lib/browser';
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
import { WorkspaceService as TheiaWorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { ConfigService } from '../../../common/protocol/config-service';
import { SketchesService, Sketch } from '../../../common/protocol/sketches-service';
import { SketchesService, Sketch, SketchContainer } from '../../../common/protocol/sketches-service';
import { ArduinoWorkspaceRootResolver } from '../../arduino-workspace-resolver';
import { BoardsServiceProvider } from '../../boards/boards-service-provider';
import { BoardsConfig } from '../../boards/boards-config';
@injectable()
export class WorkspaceService extends TheiaWorkspaceService {
@@ -29,10 +32,18 @@ export class WorkspaceService extends TheiaWorkspaceService {
@inject(ApplicationServer)
protected readonly applicationServer: ApplicationServer;
@inject(FrontendApplicationStateService)
protected readonly appStateService: FrontendApplicationStateService;
@inject(BoardsServiceProvider)
protected readonly boardsServiceProvider: BoardsServiceProvider;
private application: FrontendApplication;
private workspaceUri?: Promise<string | undefined>;
private version?: string
private version?: string;
async onStart(application: FrontendApplication): Promise<void> {
this.application = application;
const info = await this.applicationServer.getApplicationInfo();
this.version = info?.version;
application.shell.onDidChangeCurrentWidget(this.onCurrentWidgetChange.bind(this));
@@ -50,7 +61,7 @@ export class WorkspaceService extends TheiaWorkspaceService {
const hash = window.location.hash;
const [recentWorkspaces, recentSketches] = await Promise.all([
this.server.getRecentWorkspaces(),
this.sketchService.getSketches().then(sketches => sketches.map(s => s.uri))
this.sketchService.getSketches({}).then(container => SketchContainer.toArray(container).map(s => s.uri))
]);
const toOpen = await new ArduinoWorkspaceRootResolver({
isValid: this.isValid.bind(this)
@@ -62,17 +73,25 @@ export class WorkspaceService extends TheiaWorkspaceService {
}
return (await this.sketchService.createNewSketch()).uri;
} catch (err) {
this.appStateService.reachedState('ready').then(() => this.application.shell.update());
this.logger.fatal(`Failed to determine the sketch directory: ${err}`)
this.messageService.error(
'There was an error creating the sketch directory. ' +
'See the log for more details. ' +
'The application will probably not work as expected.')
'The application will probably not work as expected.');
return super.getDefaultWorkspaceUri();
}
})();
return this.workspaceUri;
}
protected openNewWindow(workspacePath: string): void {
const { boardsConfig } = this.boardsServiceProvider;
const url = BoardsConfig.Config.setConfig(boardsConfig, new URL(window.location.href)); // Set the current boards config for the new browser window.
url.hash = workspacePath;
this.windowService.openNewWindow(url.toString());
}
private async isValid(uri: string): Promise<boolean> {
const exists = await this.fileService.exists(new URI(uri));
if (!exists) {

View File

@@ -0,0 +1,29 @@
import { inject, injectable, postConstruct } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { WorkspaceVariableContribution as TheiaWorkspaceVariableContribution } from '@theia/workspace/lib/browser/workspace-variable-contribution';
import { Sketch } from '../../../common/protocol';
import { SketchesServiceClientImpl } from '../../../common/protocol/sketches-service-client-impl';
@injectable()
export class WorkspaceVariableContribution extends TheiaWorkspaceVariableContribution {
@inject(SketchesServiceClientImpl)
protected readonly sketchesServiceClient: SketchesServiceClientImpl;
protected currentSketch?: Sketch;
@postConstruct()
protected init(): void {
this.sketchesServiceClient.currentSketch().then().then(sketch => this.currentSketch = sketch);
}
getResourceUri(): URI | undefined {
const resourceUri = super.getResourceUri();
// https://github.com/arduino/arduino-ide/issues/46
// `currentWidget` can be an editor representing a file outside of the workspace. The current sketch should be a fallback.
if (!resourceUri && this.currentSketch?.uri) {
return new URI(this.currentSketch.uri);
}
return resourceUri;
}
}

View File

@@ -1,9 +1,9 @@
import { FrontendApplicationContribution, FrontendApplication, Widget, Message } from "@theia/core/lib/browser";
import { injectable, inject } from "inversify";
import { ArduinoToolbar } from "./arduino-toolbar";
import { TabBarToolbarRegistry } from "@theia/core/lib/browser/shell/tab-bar-toolbar";
import { CommandRegistry } from "@theia/core";
import { LabelParser } from "@theia/core/lib/browser/label-parser";
import { FrontendApplicationContribution, FrontendApplication, Widget, Message } from '@theia/core/lib/browser';
import { injectable, inject } from 'inversify';
import { ArduinoToolbar } from './arduino-toolbar';
import { TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
import { CommandRegistry } from '@theia/core';
import { LabelParser } from '@theia/core/lib/browser/label-parser';
export class ArduinoToolbarContainer extends Widget {

View File

@@ -13,6 +13,7 @@ export namespace ArduinoToolbarComponent {
commands: CommandRegistry,
labelParser: LabelParser,
commandIsEnabled: (id: string) => boolean,
commandIsToggled: (id: string) => boolean,
executeCommand: (e: React.MouseEvent<HTMLElement>) => void
}
export interface State {
@@ -39,7 +40,7 @@ export class ArduinoToolbarComponent extends React.Component<ArduinoToolbarCompo
}
}
const command = this.props.commands.getCommand(item.command);
const cls = `${ARDUINO_TOOLBAR_ITEM_CLASS} ${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} ${command && this.props.commandIsEnabled(command.id) ? 'enabled' : ''}`
const cls = `${ARDUINO_TOOLBAR_ITEM_CLASS} ${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM} ${command && this.props.commandIsEnabled(command.id) ? 'enabled' : ''} ${command && this.props.commandIsToggled(command.id) ? 'toggled' : ''}`
return <div key={item.id} className={cls} >
<div className={item.id}>
<div
@@ -112,6 +113,10 @@ export class ArduinoToolbar extends ReactWidget {
protected commandIsEnabled(command: string): boolean {
return this.commands.isEnabled(command, this);
}
protected readonly doCommandIsToggled = (id: string) => this.commandIsToggled(id);
protected commandIsToggled(command: string): boolean {
return this.commands.isToggled(command, this);
}
protected render(): React.ReactNode {
return <ArduinoToolbarComponent
@@ -121,6 +126,7 @@ export class ArduinoToolbar extends ReactWidget {
items={[...this.items.values()]}
commands={this.commands}
commandIsEnabled={this.doCommandIsEnabled}
commandIsToggled={this.doCommandIsToggled}
executeCommand={this.executeCommand}
/>
}

View File

@@ -42,6 +42,7 @@ export namespace ComponentList {
export interface Props<T extends ArduinoComponent> {
readonly items: T[];
readonly itemLabel: (item: T) => string;
readonly itemDeprecated: (item: T) => boolean;
readonly itemRenderer: ListItemRenderer<T>;
readonly install: (item: T, version?: Installable.Version) => Promise<void>;
readonly uninstall: (item: T) => Promise<void>;

View File

@@ -1,15 +1,17 @@
import * as React from 'react';
import debounce = require('lodash.debounce');
import { Event } from '@theia/core/lib/common/event';
import { CommandService } from '@theia/core/lib/common/command';
import { MessageService } from '@theia/core/lib/common/message-service';
import { ConfirmDialog } from '@theia/core/lib/browser/dialogs';
import { Searchable } from '../../../common/protocol/searchable';
import { Installable } from '../../../common/protocol/installable';
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
import { InstallationProgressDialog, UninstallationProgressDialog } from '../progress-dialog';
import { SearchBar } from './search-bar';
import { ListWidget } from './list-widget';
import { ComponentList } from './component-list';
import { ListItemRenderer } from './list-item-renderer';
import { ResponseServiceImpl } from '../../response-service-impl';
export class FilterableListContainer<T extends ArduinoComponent> extends React.Component<FilterableListContainer.Props<T>, FilterableListContainer.State<T>> {
@@ -54,10 +56,11 @@ export class FilterableListContainer<T extends ArduinoComponent> extends React.C
}
protected renderComponentList(): React.ReactNode {
const { itemLabel, resolveContainer, itemRenderer } = this.props;
const { itemLabel, itemDeprecated, resolveContainer, itemRenderer } = this.props;
return <ComponentList<T>
items={this.state.items}
itemLabel={itemLabel}
itemDeprecated={itemDeprecated}
itemRenderer={itemRenderer}
install={this.install.bind(this)}
uninstall={this.uninstall.bind(this)}
@@ -76,21 +79,28 @@ export class FilterableListContainer<T extends ArduinoComponent> extends React.C
}
protected sort(items: T[]): T[] {
const { itemLabel } = this.props;
return items.sort((left, right) => itemLabel(left).localeCompare(itemLabel(right)));
// debugger;
const { itemLabel, itemDeprecated } = this.props;
return items.sort((left, right) => {
// always put deprecated items at the bottom of the list
if (itemDeprecated(left)) {
return 1;
}
return itemLabel(left).localeCompare(itemLabel(right))
});
}
protected async install(item: T, version: Installable.Version): Promise<void> {
const { install, searchable, itemLabel } = this.props;
const dialog = new InstallationProgressDialog(itemLabel(item), version);
try {
dialog.open();
await install({ item, version });
const items = await searchable.search({ query: this.state.filterText });
this.setState({ items: this.sort(items) });
} finally {
dialog.close();
}
const { install, searchable } = this.props;
await Installable.doWithProgress({
...this.props,
progressText: `Processing ${item.name}:${version}`,
run: ({ progressId }) => install({ item, progressId, version })
});
const items = await searchable.search({ query: this.state.filterText });
this.setState({ items: this.sort(items) });
}
protected async uninstall(item: T): Promise<void> {
@@ -103,16 +113,14 @@ export class FilterableListContainer<T extends ArduinoComponent> extends React.C
if (!ok) {
return;
}
const { uninstall, searchable, itemLabel } = this.props;
const dialog = new UninstallationProgressDialog(itemLabel(item));
try {
dialog.open();
await uninstall({ item });
const items = await searchable.search({ query: this.state.filterText });
this.setState({ items: this.sort(items) });
} finally {
dialog.close();
}
const { uninstall, searchable } = this.props;
await Installable.doWithProgress({
...this.props,
progressText: `Processing ${item.name}${item.installedVersion ? `:${item.installedVersion}` : ''}`,
run: ({ progressId }) => uninstall({ item, progressId })
});
const items = await searchable.search({ query: this.state.filterText });
this.setState({ items: this.sort(items) });
}
}
@@ -123,12 +131,16 @@ export namespace FilterableListContainer {
readonly container: ListWidget<T>;
readonly searchable: Searchable<T>;
readonly itemLabel: (item: T) => string;
readonly itemDeprecated: (item: T) => boolean;
readonly itemRenderer: ListItemRenderer<T>;
readonly resolveContainer: (element: HTMLElement) => void;
readonly resolveFocus: (element: HTMLElement | undefined) => void;
readonly filterTextChangeEvent: Event<string | undefined>;
readonly install: ({ item, version }: { item: T, version: Installable.Version }) => Promise<void>;
readonly uninstall: ({ item }: { item: T }) => Promise<void>;
readonly messageService: MessageService;
readonly responseService: ResponseServiceImpl;
readonly install: ({ item, progressId, version }: { item: T, progressId: string, version: Installable.Version }) => Promise<void>;
readonly uninstall: ({ item, progressId }: { item: T, progressId: string }) => Promise<void>;
readonly commandService: CommandService;
}
export interface State<T> {

View File

@@ -1,20 +1,31 @@
import * as React from 'react';
import { injectable, postConstruct, inject } from 'inversify';
import { Widget } from '@phosphor/widgets';
import { Message } from '@phosphor/messaging';
import { Deferred } from '@theia/core/lib/common/promise-util';
import { Emitter } from '@theia/core/lib/common/event';
import { MaybePromise } from '@theia/core/lib/common/types';
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
import { Installable } from '../../../common/protocol/installable';
import { Searchable } from '../../../common/protocol/searchable';
import { ArduinoComponent } from '../../../common/protocol/arduino-component';
import { CommandService } from '@theia/core/lib/common/command';
import { MessageService } from '@theia/core/lib/common/message-service';
import { Installable, Searchable, ArduinoComponent } from '../../../common/protocol';
import { FilterableListContainer } from './filterable-list-container';
import { ListItemRenderer } from './list-item-renderer';
import { NotificationCenter } from '../../notification-center';
import { ResponseServiceImpl } from '../../response-service-impl';
@injectable()
export abstract class ListWidget<T extends ArduinoComponent> extends ReactWidget {
@inject(MessageService)
protected readonly messageService: MessageService;
@inject(CommandService)
protected readonly commandService: CommandService;
@inject(ResponseServiceImpl)
protected readonly responseService: ResponseServiceImpl;
@inject(NotificationCenter)
protected readonly notificationCenter: NotificationCenter;
@@ -55,26 +66,31 @@ export abstract class ListWidget<T extends ArduinoComponent> extends ReactWidget
return this.deferredContainer.promise;
}
protected onActivateRequest(msg: Message): void {
super.onActivateRequest(msg);
protected onActivateRequest(message: Message): void {
super.onActivateRequest(message);
(this.focusNode || this.node).focus();
}
protected onUpdateRequest(msg: Message): void {
super.onUpdateRequest(msg);
protected onUpdateRequest(message: Message): void {
super.onUpdateRequest(message);
this.render();
}
protected onResize(message: Widget.ResizeMessage): void {
super.onResize(message);
this.updateScrollBar();
}
protected onFocusResolved = (element: HTMLElement | undefined) => {
this.focusNode = element;
};
protected async install({ item, version }: { item: T, version: Installable.Version }): Promise<void> {
return this.options.installable.install({ item, version });
protected async install({ item, progressId, version }: { item: T, progressId: string, version: Installable.Version }): Promise<void> {
return this.options.installable.install({ item, progressId, version });
}
protected async uninstall({ item }: { item: T }): Promise<void> {
return this.options.installable.uninstall({ item });
protected async uninstall({ item, progressId }: { item: T, progressId: string }): Promise<void> {
return this.options.installable.uninstall({ item, progressId });
}
render(): React.ReactNode {
@@ -86,8 +102,12 @@ export abstract class ListWidget<T extends ArduinoComponent> extends ReactWidget
install={this.install.bind(this)}
uninstall={this.uninstall.bind(this)}
itemLabel={this.options.itemLabel}
itemDeprecated={this.options.itemDeprecated}
itemRenderer={this.options.itemRenderer}
filterTextChangeEvent={this.filterTextChangeEmitter.event} />;
filterTextChangeEvent={this.filterTextChangeEmitter.event}
messageService={this.messageService}
commandService={this.commandService}
responseService={this.responseService} />;
}
/**
@@ -114,6 +134,7 @@ export namespace ListWidget {
readonly installable: Installable<T>;
readonly searchable: Searchable<T>;
readonly itemLabel: (item: T) => string;
readonly itemDeprecated: (item: T) => boolean;
readonly itemRenderer: ListItemRenderer<T>;
}
}

View File

@@ -1,23 +0,0 @@
import { AbstractDialog } from '@theia/core/lib/browser';
export class InstallationProgressDialog extends AbstractDialog<undefined> {
readonly value = undefined;
constructor(componentName: string, version: string) {
super({ title: 'Installation in progress' });
this.contentNode.textContent = `Installing ${componentName} [${version}]. Please wait...`;
}
}
export class UninstallationProgressDialog extends AbstractDialog<undefined> {
readonly value = undefined;
constructor(componentName: string) {
super({ title: 'Uninstallation in progress' });
this.contentNode.textContent = `Uninstalling ${componentName}. Please wait...`;
}
}

View File

@@ -2,6 +2,7 @@ import { Installable } from './installable';
export interface ArduinoComponent {
readonly name: string;
readonly deprecated: boolean;
readonly author: string;
readonly summary: string;
readonly description: string;

View File

@@ -121,9 +121,7 @@ export interface BoardsService extends Installable<BoardsPackage>, Searchable<Bo
getBoardDetails(options: { fqbn: string }): Promise<BoardDetails | undefined>;
getBoardPackage(options: { id: string }): Promise<BoardsPackage | undefined>;
getContainerBoardPackage(options: { fqbn: string }): Promise<BoardsPackage | undefined>;
// The CLI cannot do fuzzy search. This method provides all boards and we do the fuzzy search (with monaco) on the frontend.
// https://github.com/arduino/arduino-cli/issues/629
allBoards(options: {}): Promise<Array<BoardWithPackage>>;
searchBoards({ query }: { query?: string }): Promise<BoardWithPackage[]>;
}
export interface Port {

View File

@@ -2,6 +2,7 @@ export const ConfigServicePath = '/services/config-service';
export const ConfigService = Symbol('ConfigService');
export interface ConfigService {
getVersion(): Promise<Readonly<{ version: string, commit: string, status?: string }>>;
getCliConfigFileUri(): Promise<string>;
getConfiguration(): Promise<Config>;
setConfiguration(config: Config): Promise<void>;
isInDataDir(uri: string): Promise<boolean>;

View File

@@ -1,14 +1,10 @@
import { Sketch } from './sketches-service';
import { SketchContainer } from './sketches-service';
export const ExamplesServicePath = '/services/example-service';
export const ExamplesService = Symbol('ExamplesService');
export interface ExamplesService {
builtIns(): Promise<ExampleContainer[]>;
installed(options: { fqbn: string }): Promise<{ user: ExampleContainer[], current: ExampleContainer[], any: ExampleContainer[] }>;
builtIns(): Promise<SketchContainer[]>;
installed(options: { fqbn?: string }): Promise<{ user: SketchContainer[], current: SketchContainer[], any: SketchContainer[] }>;
}
export interface ExampleContainer {
readonly label: string;
readonly children: ExampleContainer[];
readonly sketches: Sketch[];
}

View File

@@ -11,5 +11,5 @@ export * from './searchable';
export * from './sketches-service';
export * from './examples-service';
export * from './executable-service';
export * from './output-service';
export * from './response-service';
export * from './notification-service';

View File

@@ -1,20 +1,26 @@
import * as semver from 'semver';
import { Progress } from '@theia/core/lib/common/message-service-protocol';
import { CancellationToken, CancellationTokenSource } from '@theia/core/lib/common/cancellation';
import { naturalCompare } from './../utils';
import { ArduinoComponent } from './arduino-component';
import { MessageService } from '@theia/core';
import { ResponseServiceImpl } from '../../browser/response-service-impl';
export interface Installable<T extends ArduinoComponent> {
/**
* If `options.version` is specified, that will be installed. Otherwise, `item.availableVersions[0]`.
*/
install(options: { item: T, version?: Installable.Version }): Promise<void>;
install(options: { item: T, progressId?: string, version?: Installable.Version }): Promise<void>;
/**
* Uninstalls the given component. It is a NOOP if not installed.
*/
uninstall(options: { item: T }): Promise<void>;
uninstall(options: { item: T, progressId?: string }): Promise<void>;
}
export namespace Installable {
export type Version = string;
export namespace Version {
/**
* Most recent version comes first, then the previous versions. (`1.8.1`, `1.6.3`, `1.6.2`, `1.6.1` and so on.)
@@ -26,4 +32,70 @@ export namespace Installable {
return naturalCompare(left, right);
};
}
export async function installWithProgress<T extends ArduinoComponent>(options: {
installable: Installable<T>,
messageService: MessageService,
responseService: ResponseServiceImpl,
item: T,
version: Installable.Version
}): Promise<void> {
const { item, version } = options;
return doWithProgress({
...options,
progressText: `Processing ${item.name}:${version}`,
run: ({ progressId }) => options.installable.install({ item: options.item, version: options.version, progressId })
});
}
export async function uninstallWithProgress<T extends ArduinoComponent>(options: {
installable: Installable<T>,
messageService: MessageService,
responseService: ResponseServiceImpl,
item: T
}): Promise<void> {
const { item } = options;
return doWithProgress({
...options,
progressText: `Processing ${item.name}${item.installedVersion ? `:${item.installedVersion}` : ''}`,
run: ({ progressId }) => options.installable.uninstall({ item: options.item, progressId })
});
}
export async function doWithProgress(options: {
run: ({ progressId }: { progressId: string }) => Promise<void>,
messageService: MessageService,
responseService: ResponseServiceImpl,
progressText: string
}): Promise<void> {
return withProgress(options.progressText, options.messageService, async (progress, _) => {
const progressId = progress.id;
const toDispose = options.responseService.onProgressDidChange(progressMessage => {
if (progressId === progressMessage.progressId) {
const { message, work } = progressMessage;
progress.report({ message, work });
}
});
try {
options.responseService.clearArduinoChannel();
await options.run({ progressId });
} finally {
toDispose.dispose();
}
});
}
async function withProgress(text: string, messageService: MessageService, cb: (progress: Progress, token: CancellationToken) => Promise<void>): Promise<void> {
const cancellationSource = new CancellationTokenSource();
const { token } = cancellationSource;
const progress = await messageService.showProgress({ text, options: { cancelable: false } }, () => cancellationSource.cancel());
try {
await cb(progress, token);
} finally {
progress.cancel();
}
}
}

View File

@@ -9,8 +9,8 @@ export interface LibraryService extends Installable<LibraryPackage>, Searchable<
/**
* When `installDependencies` is not set, it is `true` by default. If you want to skip the installation of required dependencies, set it to `false`.
*/
install(options: { item: LibraryPackage, version?: Installable.Version, installDependencies?: boolean }): Promise<void>;
installZip(options: { zipUri: string }): Promise<void>;
install(options: { item: LibraryPackage, progressId?: string, version?: Installable.Version, installDependencies?: boolean }): Promise<void>;
installZip(options: { zipUri: string, progressId?: string, overwrite?: boolean }): Promise<void>;
/**
* Set `filterSelf` to `true` if you want to avoid having `item` in the result set.
* Note: as of today (22.02.2021), the CLI works like this: `./arduino-cli lib deps Adaino@0.1.0 ✕ Adaino 0.1.0 must be installed.`.

View File

@@ -1,10 +0,0 @@
export interface OutputMessage {
readonly chunk: string;
readonly severity?: 'error' | 'warning' | 'info'; // Currently not used!
}
export const OutputServicePath = '/services/output-service';
export const OutputService = Symbol('OutputService');
export interface OutputService {
append(message: OutputMessage): void;
}

View File

@@ -0,0 +1,23 @@
export interface OutputMessage {
readonly chunk: string;
readonly severity?: 'error' | 'warning' | 'info'; // Currently not used!
}
export interface ProgressMessage {
readonly progressId: string;
readonly message: string;
readonly work?: ProgressMessage.Work;
}
export namespace ProgressMessage {
export interface Work {
readonly done: number;
readonly total: number;
}
}
export const ResponseServicePath = '/services/response-service';
export const ResponseService = Symbol('ResponseService');
export interface ResponseService {
appendToOutput(message: OutputMessage): void;
reportProgress(message: ProgressMessage): void;
}

View File

@@ -1,14 +1,16 @@
import { inject, injectable } from 'inversify';
import URI from '@theia/core/lib/common/uri';
import { Emitter } from '@theia/core/lib/common/event';
import { notEmpty } from '@theia/core/lib/common/objects';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { MessageService } from '@theia/core/lib/common/message-service';
import { FileChangeType } from '@theia/filesystem/lib/common/files';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
import { Sketch, SketchesService } from '../../common/protocol';
import { FrontendApplicationContribution } from '@theia/core/lib/browser';
import { ConfigService } from './config-service';
import { DisposableCollection, Emitter } from '@theia/core';
import { FileChangeType } from '@theia/filesystem/lib/browser';
import { SketchContainer } from './sketches-service';
@injectable()
export class SketchesServiceClientImpl implements FrontendApplicationContribution {
@@ -35,9 +37,9 @@ export class SketchesServiceClientImpl implements FrontendApplicationContributio
onStart(): void {
this.configService.getConfiguration().then(({ sketchDirUri }) => {
this.sketchService.getSketches(sketchDirUri).then(sketches => {
this.sketchService.getSketches({ uri: sketchDirUri }).then(container => {
const sketchbookUri = new URI(sketchDirUri);
for (const sketch of sketches) {
for (const sketch of SketchContainer.toArray(container)) {
this.sketches.set(sketch.uri, sketch);
}
this.toDispose.push(this.fileService.watch(new URI(sketchDirUri), { recursive: true, excludes: [] }));
@@ -128,4 +130,16 @@ export class SketchesServiceClientImpl implements FrontendApplicationContributio
}, 100);
}
/**
* `true` if the `uri` is not contained in any of the opened workspaces. Otherwise, `false`.
*/
isReadOnly(uri: URI | monaco.Uri | string): boolean {
const toCheck = uri instanceof URI ? uri : new URI(uri);
if (toCheck.scheme === 'user-storage') {
return false;
}
const readOnly = !this.workspaceService.tryGetRoots().some(({ resource }) => resource.isEqualOrParent(toCheck));
return readOnly;
}
}

View File

@@ -5,10 +5,11 @@ export const SketchesService = Symbol('SketchesService');
export interface SketchesService {
/**
* Returns with the direct sketch folders from the location of the `fileStat`.
* The sketches returns with inverse-chronological order, the first item is the most recent one.
* Resolves to a sketch container representing the hierarchical structure of the sketches.
* If `uri` is not given, `directories.user` will be user instead. Specify `exclude` global patterns to filter folders from the sketch container.
* If `exclude` is not set `['**\/libraries\/**', '**\/hardware\/**']` will be used instead.
*/
getSketches(uri?: string): Promise<Sketch[]>;
getSketches({ uri, exclude }: { uri?: string, exclude?: string[] }): Promise<SketchContainer>;
/**
* This is the TS implementation of `SketchLoad` from the CLI and should be replaced with a gRPC call eventually.
@@ -63,6 +64,12 @@ export interface SketchesService {
*/
archive(sketch: Sketch, destinationUri: string): Promise<string>;
/**
* Counterpart of the CLI's `genBuildPath` functionality.
* Based on https://github.com/arduino/arduino-cli/blob/550179eefd2d2bca299d50a4af9e9bfcfebec649/arduino/builder/builder.go#L30-L38
*/
getIdeTempFolderUri(sketch: Sketch): Promise<string>;
}
export interface Sketch {
@@ -80,7 +87,7 @@ export namespace Sketch {
export namespace Extensions {
export const MAIN = ['.ino', '.pde'];
export const SOURCE = ['.c', '.cpp', '.s'];
export const ADDITIONAL = ['.h', '.c', '.hpp', '.hh', '.cpp', '.s', '.json'];
export const ADDITIONAL = ['.h', '.c', '.hpp', '.hh', '.cpp', '.S', '.json', '.md', '.adoc'];
export const ALL = Array.from(new Set([...MAIN, ...SOURCE, ...ADDITIONAL]));
}
export function isInSketch(uri: string | URI, sketch: Sketch): boolean {
@@ -94,3 +101,51 @@ export namespace Sketch {
return Extensions.MAIN.some(ext => arg.endsWith(ext));
}
}
export interface SketchContainer {
readonly label: string;
readonly children: SketchContainer[];
readonly sketches: Sketch[];
}
export namespace SketchContainer {
export function is(arg: any): arg is SketchContainer {
return !!arg
&& 'label' in arg && typeof arg.label === 'string'
&& 'children' in arg && Array.isArray(arg.children)
&& 'sketches' in arg && Array.isArray(arg.sketches);
}
/**
* `false` if the `container` recursively contains at least one sketch. Otherwise, `true`.
*/
export function isEmpty(container: SketchContainer): boolean {
const hasSketch = (parent: SketchContainer) => {
if (parent.sketches.length || parent.children.some(child => hasSketch(child))) {
return true;
}
return false;
}
return !hasSketch(container);
}
export function prune<T extends SketchContainer>(container: T): T {
for (let i = container.children.length - 1; i >= 0; i--) {
if (isEmpty(container.children[i])) {
container.children.splice(i, 1);
}
}
return container;
}
export function toArray(container: SketchContainer): Sketch[] {
const visit = (parent: SketchContainer, toPushSketch: Sketch[]) => {
toPushSketch.push(...parent.sketches);
parent.children.map(child => visit(child, toPushSketch));
}
const sketches: Sketch[] = [];
visit(container, sketches);
return sketches;
}
}

View File

@@ -1,7 +1,8 @@
import { injectable } from 'inversify'
import { remote } from 'electron';
import { isOSX } from '@theia/core/lib/common/os';
import { Keybinding } from '@theia/core/lib/common/keybinding';
import { CompositeMenuNode } from '@theia/core/lib/common/menu';
import { CompositeMenuNode, MAIN_MENU_BAR, MenuPath } from '@theia/core/lib/common/menu';
import { ElectronMainMenuFactory as TheiaElectronMainMenuFactory, ElectronMenuOptions } from '@theia/core/lib/electron-browser/menu/electron-main-menu-factory';
import { ArduinoMenus, PlaceholderMenuNode } from '../../../browser/menu/arduino-menus';
@@ -10,7 +11,33 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
createMenuBar(): Electron.Menu {
this._toggledCommands.clear(); // https://github.com/eclipse-theia/theia/issues/8977
return super.createMenuBar();
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
const template = this.fillMenuTemplate([], menuModel);
if (isOSX) {
template.unshift(this.createOSXMenu());
}
const menu = remote.Menu.buildFromTemplate(this.escapeAmpersand(template));
this._menu = menu;
return menu;
}
createContextMenu(menuPath: MenuPath, args?: any[]): Electron.Menu {
const menuModel = this.menuProvider.getMenu(menuPath);
const template = this.fillMenuTemplate([], menuModel, args, { showDisabled: false });
return remote.Menu.buildFromTemplate(this.escapeAmpersand(template));
}
// TODO: remove after https://github.com/eclipse-theia/theia/pull/9231
private escapeAmpersand(template: Electron.MenuItemConstructorOptions[]): Electron.MenuItemConstructorOptions[] {
for (const option of template) {
if (option.label) {
option.label = option.label.replace(/\&+/g, '&$&');
}
if (option.submenu) {
this.escapeAmpersand(option.submenu as Electron.MenuItemConstructorOptions[]);
}
}
return template;
}
protected acceleratorFor(keybinding: Keybinding): string {
@@ -26,15 +53,17 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
const { submenu } = super.createOSXMenu();
const label = 'Arduino IDE';
if (!!submenu && !(submenu instanceof remote.Menu)) {
const [/* about */, /* settings */, ...rest] = submenu;
const [/* about */, /* preferences */, ...rest] = submenu;
const about = this.fillMenuTemplate([], this.menuProvider.getMenu(ArduinoMenus.HELP__ABOUT_GROUP));
const settings = this.fillMenuTemplate([], this.menuProvider.getMenu(ArduinoMenus.FILE__SETTINGS_GROUP));
const preferences = this.fillMenuTemplate([], this.menuProvider.getMenu(ArduinoMenus.FILE__PREFERENCES_GROUP));
const advanced = this.fillMenuTemplate([], this.menuProvider.getMenu(ArduinoMenus.FILE__ADVANCED_GROUP));
return {
label,
submenu: [
...about,
{ type: 'separator' },
...settings,
...preferences,
...advanced,
{ type: 'separator' },
...rest
]

View File

@@ -28,7 +28,7 @@ SOFTWARE.
*/
import { Event } from '@theia/core/lib/common/event';
import { BrowserWindow } from "electron";
import { BrowserWindow } from 'electron';
/**
* When splashscreen was shown.
@@ -126,11 +126,11 @@ export const initSplashScreen = (config: Config, onCloseRequested?: Event<void>)
const window = new BrowserWindow(xConfig.windowOpts);
splashScreen = new BrowserWindow(xConfig.splashScreenOpts);
splashScreen.loadURL(`file://${xConfig.templateUrl}`);
xConfig.closeWindow && splashScreen.on("close", () => {
xConfig.closeWindow && splashScreen.on('close', () => {
done || window.close();
});
// Splashscreen is fully loaded and ready to view.
splashScreen.webContents.on("did-finish-load", () => {
splashScreen.webContents.on('did-finish-load', () => {
splashScreenReady = true;
showSplash();
});

View File

@@ -82,16 +82,6 @@ export class ElectronMainApplication extends TheiaElectronMainApplication {
return electronWindow;
}
protected async getDefaultBrowserWindowOptions(): Promise<TheiaBrowserWindowOptions> {
const options = await super.getDefaultBrowserWindowOptions();
return {
...options,
// Set and use a custom minimum window size: https://github.com/arduino/arduino-pro-ide/issues/337#issuecomment-687017281
minWidth: 900,
minHeight: 800
};
}
protected async startBackend(): Promise<number> {
// Check if we should run everything as one process.
const noBackendFork = process.argv.indexOf('--no-cluster') !== -1;

View File

@@ -11,7 +11,8 @@ export class ElectronMainWindowServiceImpl extends TheiaElectronMainWindowServic
openNewWindow(url: string, { external }: NewWindowOptions): undefined {
if (!external) {
const existing = this.app.windows.find(window => window.webContents.getURL() === url);
const sanitizedUrl = this.sanitize(url);
const existing = this.app.windows.find(window => this.sanitize(window.webContents.getURL()) === sanitizedUrl);
if (existing) {
existing.focus();
return;
@@ -20,5 +21,14 @@ export class ElectronMainWindowServiceImpl extends TheiaElectronMainWindowServic
return super.openNewWindow(url, { external });
}
private sanitize(url: string): string {
const copy = new URL(url);
const searchParams: string[] = [];
copy.searchParams.forEach((_, key) => searchParams.push(key));
for (const param of searchParams) {
copy.searchParams.delete(param);
}
return copy.toString();
}
}

View File

@@ -29,11 +29,13 @@ import { ExamplesServiceImpl } from './examples-service-impl';
import { ExamplesService, ExamplesServicePath } from '../common/protocol/examples-service';
import { ExecutableService, ExecutableServicePath } from '../common/protocol/executable-service';
import { ExecutableServiceImpl } from './executable-service-impl';
import { OutputServicePath, OutputService } from '../common/protocol/output-service';
import { ResponseServicePath, ResponseService } from '../common/protocol/response-service';
import { NotificationServiceServerImpl } from './notification-service-server';
import { NotificationServiceServer, NotificationServiceClient, NotificationServicePath } from '../common/protocol';
import { BackendApplication } from './theia/core/backend-application';
import { BoardDiscovery } from './board-discovery';
import { DefaultGitInit } from './theia/git/git-init';
import { GitInit } from '@theia/git/lib/node/init/git-init';
export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(BackendApplication).toSelf().inSingletonScope();
@@ -125,7 +127,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
// Output service per connection.
bind(ConnectionContainerModule).toConstantValue(ConnectionContainerModule.create(({ bindFrontendService }) => {
bindFrontendService(OutputServicePath, OutputService);
bindFrontendService(ResponseServicePath, ResponseService);
}));
// Notify all connected frontend instances
@@ -164,4 +166,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
return parentLogger.child('monitor-service');
}).inSingletonScope().whenTargetNamed('monitor-service');
bind(DefaultGitInit).toSelf();
rebind(GitInit).toService(DefaultGitInit);
});

View File

@@ -2,8 +2,8 @@ import { injectable, inject, postConstruct, named } from 'inversify';
import { ClientDuplexStream } from '@grpc/grpc-js';
import { ILogger } from '@theia/core/lib/common/logger';
import { deepClone } from '@theia/core/lib/common/objects';
import { CoreClientProvider } from './core-client-provider';
import { BoardListWatchReq, BoardListWatchResp } from './cli-protocol/commands/board_pb';
import { CoreClientAware } from './core-client-provider';
import { BoardListWatchRequest, BoardListWatchResponse } from './cli-protocol/cc/arduino/cli/commands/v1/board_pb';
import { Board, Port, NotificationServiceServer, AvailablePorts, AttachedBoardsChangeEvent } from '../common/protocol';
/**
@@ -12,19 +12,16 @@ import { Board, Port, NotificationServiceServer, AvailablePorts, AttachedBoardsC
* Unlike other services, this is not connection scoped.
*/
@injectable()
export class BoardDiscovery {
export class BoardDiscovery extends CoreClientAware {
@inject(ILogger)
@named('discovery')
protected discoveryLogger: ILogger;
@inject(CoreClientProvider)
protected readonly coreClientProvider: CoreClientProvider;
@inject(NotificationServiceServer)
protected readonly notificationService: NotificationServiceServer;
protected boardWatchDuplex: ClientDuplexStream<BoardListWatchReq, BoardListWatchResp> | undefined;
protected boardWatchDuplex: ClientDuplexStream<BoardListWatchRequest, BoardListWatchResponse> | undefined;
/**
* Keys are the `address` of the ports. \
@@ -46,10 +43,10 @@ export class BoardDiscovery {
protected async init(): Promise<void> {
const coreClient = await this.coreClient();
const { client, instance } = coreClient;
const req = new BoardListWatchReq();
const req = new BoardListWatchRequest();
req.setInstance(instance);
this.boardWatchDuplex = client.boardListWatch();
this.boardWatchDuplex.on('data', (resp: BoardListWatchResp) => {
this.boardWatchDuplex.on('data', (resp: BoardListWatchResponse) => {
const detectedPort = resp.getPort();
if (detectedPort) {
@@ -133,23 +130,4 @@ export class BoardDiscovery {
return availablePorts;
}
private async coreClient(): Promise<CoreClientProvider.Client> {
const coreClient = await new Promise<CoreClientProvider.Client>(async resolve => {
const client = await this.coreClientProvider.client();
if (client) {
resolve(client);
return;
}
const toDispose = this.coreClientProvider.onClientReady(async () => {
const client = await this.coreClientProvider.client();
if (client) {
toDispose.dispose();
resolve(client);
return;
}
});
});
return coreClient;
}
}

View File

@@ -4,16 +4,18 @@ import { notEmpty } from '@theia/core/lib/common/objects';
import {
BoardsService,
Installable,
BoardsPackage, Board, Port, BoardDetails, Tool, ConfigOption, ConfigValue, Programmer, OutputService, NotificationServiceServer, AvailablePorts, BoardWithPackage
BoardsPackage, Board, Port, BoardDetails, Tool, ConfigOption, ConfigValue, Programmer, ResponseService, NotificationServiceServer, AvailablePorts, BoardWithPackage
} from '../common/protocol';
import {
PlatformSearchReq, PlatformSearchResp, PlatformInstallReq, PlatformInstallResp, PlatformListReq,
PlatformListResp, Platform, PlatformUninstallResp, PlatformUninstallReq
} from './cli-protocol/commands/core_pb';
PlatformInstallRequest, PlatformListRequest, PlatformListResponse, PlatformSearchRequest,
PlatformSearchResponse, PlatformUninstallRequest
} from './cli-protocol/cc/arduino/cli/commands/v1/core_pb';
import { Platform } from './cli-protocol/cc/arduino/cli/commands/v1/common_pb';
import { BoardDiscovery } from './board-discovery';
import { CoreClientAware } from './core-client-provider';
import { BoardDetailsReq, BoardDetailsResp } from './cli-protocol/commands/board_pb';
import { ListProgrammersAvailableForUploadReq, ListProgrammersAvailableForUploadResp } from './cli-protocol/commands/upload_pb';
import { BoardDetailsRequest, BoardDetailsResponse, BoardSearchRequest } from './cli-protocol/cc/arduino/cli/commands/v1/board_pb';
import { ListProgrammersAvailableForUploadRequest, ListProgrammersAvailableForUploadResponse } from './cli-protocol/cc/arduino/cli/commands/v1/upload_pb';
import { InstallWithProgress } from './grpc-installable';
@injectable()
export class BoardsServiceImpl extends CoreClientAware implements BoardsService {
@@ -25,8 +27,8 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
@named('discovery')
protected discoveryLogger: ILogger;
@inject(OutputService)
protected readonly outputService: OutputService;
@inject(ResponseService)
protected readonly responseService: ResponseService;
@inject(NotificationServiceServer)
protected readonly notificationService: NotificationServiceServer;
@@ -50,10 +52,10 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
const coreClient = await this.coreClient();
const { client, instance } = coreClient;
const { fqbn } = options;
const detailsReq = new BoardDetailsReq();
const detailsReq = new BoardDetailsRequest();
detailsReq.setInstance(instance);
detailsReq.setFqbn(fqbn);
const detailsResp = await new Promise<BoardDetailsResp | undefined>((resolve, reject) => client.boardDetails(detailsReq, (err, resp) => {
const detailsResp = await new Promise<BoardDetailsResponse | undefined>((resolve, reject) => client.boardDetails(detailsReq, (err, resp) => {
if (err) {
// Required cores are not installed manually: https://github.com/arduino/arduino-cli/issues/954
if ((err.message.indexOf('missing platform release') !== -1 && err.message.indexOf('referenced by board') !== -1)
@@ -62,6 +64,11 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
resolve(undefined);
return;
}
// It's a hack to handle https://github.com/arduino/arduino-cli/issues/1262 gracefully.
if (err.message.indexOf('unknown package') !== -1) {
resolve(undefined);
return;
}
reject(err);
return;
}
@@ -74,7 +81,7 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
const debuggingSupported = detailsResp.getDebuggingSupported();
const requiredTools = detailsResp.getToolsdependenciesList().map(t => <Tool>{
const requiredTools = detailsResp.getToolsDependenciesList().map(t => <Tool>{
name: t.getName(),
packager: t.getPackager(),
version: t.getVersion()
@@ -90,10 +97,10 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
})
});
const listReq = new ListProgrammersAvailableForUploadReq();
const listReq = new ListProgrammersAvailableForUploadRequest();
listReq.setInstance(instance);
listReq.setFqbn(fqbn);
const listResp = await new Promise<ListProgrammersAvailableForUploadResp>((resolve, reject) => client.listProgrammersAvailableForUpload(listReq, (err, resp) => {
const listResp = await new Promise<ListProgrammersAvailableForUploadResponse>((resolve, reject) => client.listProgrammersAvailableForUpload(listReq, (err, resp) => {
if (err) {
reject(err);
return;
@@ -109,7 +116,7 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
let VID = 'N/A';
let PID = 'N/A';
const usbId = detailsResp.getIdentificationPrefList().map(item => item.getUsbid()).find(notEmpty);
const usbId = detailsResp.getIdentificationPrefsList().map(item => item.getUsbId()).find(notEmpty);
if (usbId) {
VID = usbId.getVid();
PID = usbId.getPid();
@@ -144,28 +151,51 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
return packages.find(({ boards }) => boards.some(({ fqbn }) => fqbn === expectedFqbn));
}
async allBoards(options: {}): Promise<Array<BoardWithPackage>> {
const results = await this.search(options);
return results.map(item => item.boards.map(board => ({ ...board, packageName: item.name, packageId: item.id })))
.reduce((acc, curr) => acc.concat(curr), []);
async searchBoards({ query }: { query?: string }): Promise<BoardWithPackage[]> {
const { instance, client } = await this.coreClient();
const req = new BoardSearchRequest();
req.setSearchArgs(query || '');
req.setInstance(instance);
const boards = await new Promise<BoardWithPackage[]>((resolve, reject) => {
client.boardSearch(req, (error, resp) => {
if (error) {
reject(error);
return;
}
const boards: Array<BoardWithPackage> = [];
for (const board of resp.getBoardsList()) {
const platform = board.getPlatform();
if (platform) {
boards.push({
name: board.getName(),
fqbn: board.getFqbn(),
packageId: platform.getId(),
packageName: platform.getName()
});
}
}
resolve(boards);
})
});
return boards;
}
async search(options: { query?: string }): Promise<BoardsPackage[]> {
const coreClient = await this.coreClient();
const { client, instance } = coreClient;
const installedPlatformsReq = new PlatformListReq();
const installedPlatformsReq = new PlatformListRequest();
installedPlatformsReq.setInstance(instance);
const installedPlatformsResp = await new Promise<PlatformListResp>((resolve, reject) =>
const installedPlatformsResp = await new Promise<PlatformListResponse>((resolve, reject) =>
client.platformList(installedPlatformsReq, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp))
);
const installedPlatforms = installedPlatformsResp.getInstalledPlatformList();
const installedPlatforms = installedPlatformsResp.getInstalledPlatformsList();
const req = new PlatformSearchReq();
const req = new PlatformSearchRequest();
req.setSearchArgs(options.query || '');
req.setAllVersions(true);
req.setInstance(instance);
const resp = await new Promise<PlatformSearchResp>((resolve, reject) => client.platformSearch(req, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp)));
const resp = await new Promise<PlatformSearchResponse>((resolve, reject) => client.platformSearch(req, (err, resp) => (!!err ? reject : resolve)(!!err ? err : resp)));
const packages = new Map<string, BoardsPackage>();
const toPackage = (platform: Platform) => {
let installedVersion: string | undefined;
@@ -180,6 +210,7 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
availableVersions: [platform.getLatest()],
description: platform.getBoardsList().map(b => b.getName()).join(', '),
installable: true,
deprecated: platform.getDeprecated(),
summary: 'Boards included in this package:',
installedVersion,
boards: platform.getBoardsList().map(b => <Board>{ name: b.getName(), fqbn: b.getFqbn() }),
@@ -230,7 +261,7 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
return [...packages.values()];
}
async install(options: { item: BoardsPackage, version?: Installable.Version }): Promise<void> {
async install(options: { item: BoardsPackage, progressId?: string, version?: Installable.Version }): Promise<void> {
const item = options.item;
const version = !!options.version ? options.version : item.availableVersions[0];
const coreClient = await this.coreClient();
@@ -238,7 +269,7 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
const [platform, architecture] = item.id.split(':');
const req = new PlatformInstallReq();
const req = new PlatformInstallRequest();
req.setInstance(instance);
req.setArchitecture(architecture);
req.setPlatformPackage(platform);
@@ -246,15 +277,14 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
console.info('>>> Starting boards package installation...', item);
const resp = client.platformInstall(req);
resp.on('data', (r: PlatformInstallResp) => {
const prog = r.getProgress();
if (prog && prog.getFile()) {
this.outputService.append({ chunk: `downloading ${prog.getFile()}\n` });
}
});
resp.on('data', InstallWithProgress.createDataCallback({ progressId: options.progressId, responseService: this.responseService }));
await new Promise<void>((resolve, reject) => {
resp.on('end', resolve);
resp.on('error', reject);
resp.on('error', error => {
this.responseService.appendToOutput({ chunk: `Failed to install platform: ${item.id}.\n` });
this.responseService.appendToOutput({ chunk: error.toString() });
reject(error);
});
});
const items = await this.search({});
@@ -263,27 +293,21 @@ export class BoardsServiceImpl extends CoreClientAware implements BoardsService
console.info('<<< Boards package installation done.', item);
}
async uninstall(options: { item: BoardsPackage }): Promise<void> {
const item = options.item;
async uninstall(options: { item: BoardsPackage, progressId?: string }): Promise<void> {
const { item, progressId } = options;
const coreClient = await this.coreClient();
const { client, instance } = coreClient;
const [platform, architecture] = item.id.split(':');
const req = new PlatformUninstallReq();
const req = new PlatformUninstallRequest();
req.setInstance(instance);
req.setArchitecture(architecture);
req.setPlatformPackage(platform);
console.info('>>> Starting boards package uninstallation...', item);
let logged = false;
const resp = client.platformUninstall(req);
resp.on('data', (_: PlatformUninstallResp) => {
if (!logged) {
this.outputService.append({ chunk: `uninstalling ${item.id}\n` });
logged = true;
}
})
resp.on('data', InstallWithProgress.createDataCallback({ progressId, responseService: this.responseService }));
await new Promise<void>((resolve, reject) => {
resp.on('end', resolve);
resp.on('error', reject);

View File

@@ -1,133 +1,133 @@
// package: cc.arduino.cli.commands
// file: commands/board.proto
// package: cc.arduino.cli.commands.v1
// file: cc/arduino/cli/commands/v1/board.proto
/* tslint:disable */
/* eslint-disable */
import * as jspb from "google-protobuf";
import * as commands_common_pb from "../commands/common_pb";
import * as cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino/cli/commands/v1/common_pb";
export class BoardDetailsReq extends jspb.Message {
export class BoardDetailsRequest extends jspb.Message {
hasInstance(): boolean;
clearInstance(): void;
getInstance(): commands_common_pb.Instance | undefined;
setInstance(value?: commands_common_pb.Instance): BoardDetailsReq;
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): BoardDetailsReq;
setFqbn(value: string): BoardDetailsRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardDetailsReq.AsObject;
static toObject(includeInstance: boolean, msg: BoardDetailsReq): BoardDetailsReq.AsObject;
toObject(includeInstance?: boolean): BoardDetailsRequest.AsObject;
static toObject(includeInstance: boolean, msg: BoardDetailsRequest): BoardDetailsRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardDetailsReq, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardDetailsReq;
static deserializeBinaryFromReader(message: BoardDetailsReq, reader: jspb.BinaryReader): BoardDetailsReq;
static serializeBinaryToWriter(message: BoardDetailsRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardDetailsRequest;
static deserializeBinaryFromReader(message: BoardDetailsRequest, reader: jspb.BinaryReader): BoardDetailsRequest;
}
export namespace BoardDetailsReq {
export namespace BoardDetailsRequest {
export type AsObject = {
instance?: commands_common_pb.Instance.AsObject,
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
fqbn: string,
}
}
export class BoardDetailsResp extends jspb.Message {
export class BoardDetailsResponse extends jspb.Message {
getFqbn(): string;
setFqbn(value: string): BoardDetailsResp;
setFqbn(value: string): BoardDetailsResponse;
getName(): string;
setName(value: string): BoardDetailsResp;
setName(value: string): BoardDetailsResponse;
getVersion(): string;
setVersion(value: string): BoardDetailsResp;
setVersion(value: string): BoardDetailsResponse;
getPropertiesid(): string;
setPropertiesid(value: string): BoardDetailsResp;
getPropertiesId(): string;
setPropertiesId(value: string): BoardDetailsResponse;
getAlias(): string;
setAlias(value: string): BoardDetailsResp;
setAlias(value: string): BoardDetailsResponse;
getOfficial(): boolean;
setOfficial(value: boolean): BoardDetailsResp;
setOfficial(value: boolean): BoardDetailsResponse;
getPinout(): string;
setPinout(value: string): BoardDetailsResp;
setPinout(value: string): BoardDetailsResponse;
hasPackage(): boolean;
clearPackage(): void;
getPackage(): Package | undefined;
setPackage(value?: Package): BoardDetailsResp;
setPackage(value?: Package): BoardDetailsResponse;
hasPlatform(): boolean;
clearPlatform(): void;
getPlatform(): BoardPlatform | undefined;
setPlatform(value?: BoardPlatform): BoardDetailsResp;
setPlatform(value?: BoardPlatform): BoardDetailsResponse;
clearToolsdependenciesList(): void;
getToolsdependenciesList(): Array<ToolsDependencies>;
setToolsdependenciesList(value: Array<ToolsDependencies>): BoardDetailsResp;
addToolsdependencies(value?: ToolsDependencies, index?: number): ToolsDependencies;
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>): BoardDetailsResp;
setConfigOptionsList(value: Array<ConfigOption>): BoardDetailsResponse;
addConfigOptions(value?: ConfigOption, index?: number): ConfigOption;
clearIdentificationPrefList(): void;
getIdentificationPrefList(): Array<IdentificationPref>;
setIdentificationPrefList(value: Array<IdentificationPref>): BoardDetailsResp;
addIdentificationPref(value?: IdentificationPref, index?: number): IdentificationPref;
clearIdentificationPrefsList(): void;
getIdentificationPrefsList(): Array<IdentificationPref>;
setIdentificationPrefsList(value: Array<IdentificationPref>): BoardDetailsResponse;
addIdentificationPrefs(value?: IdentificationPref, index?: number): IdentificationPref;
clearProgrammersList(): void;
getProgrammersList(): Array<commands_common_pb.Programmer>;
setProgrammersList(value: Array<commands_common_pb.Programmer>): BoardDetailsResp;
addProgrammers(value?: commands_common_pb.Programmer, index?: number): commands_common_pb.Programmer;
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): BoardDetailsResp;
setDebuggingSupported(value: boolean): BoardDetailsResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardDetailsResp.AsObject;
static toObject(includeInstance: boolean, msg: BoardDetailsResp): BoardDetailsResp.AsObject;
toObject(includeInstance?: boolean): BoardDetailsResponse.AsObject;
static toObject(includeInstance: boolean, msg: BoardDetailsResponse): BoardDetailsResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardDetailsResp, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardDetailsResp;
static deserializeBinaryFromReader(message: BoardDetailsResp, reader: jspb.BinaryReader): BoardDetailsResp;
static serializeBinaryToWriter(message: BoardDetailsResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardDetailsResponse;
static deserializeBinaryFromReader(message: BoardDetailsResponse, reader: jspb.BinaryReader): BoardDetailsResponse;
}
export namespace BoardDetailsResp {
export namespace BoardDetailsResponse {
export type AsObject = {
fqbn: string,
name: string,
version: string,
propertiesid: string,
propertiesId: string,
alias: string,
official: boolean,
pinout: string,
pb_package?: Package.AsObject,
platform?: BoardPlatform.AsObject,
toolsdependenciesList: Array<ToolsDependencies.AsObject>,
toolsDependenciesList: Array<ToolsDependencies.AsObject>,
configOptionsList: Array<ConfigOption.AsObject>,
identificationPrefList: Array<IdentificationPref.AsObject>,
programmersList: Array<commands_common_pb.Programmer.AsObject>,
identificationPrefsList: Array<IdentificationPref.AsObject>,
programmersList: Array<cc_arduino_cli_commands_v1_common_pb.Programmer.AsObject>,
debuggingSupported: boolean,
}
}
export class IdentificationPref extends jspb.Message {
hasUsbid(): boolean;
clearUsbid(): void;
getUsbid(): USBID | undefined;
setUsbid(value?: USBID): IdentificationPref;
hasUsbId(): boolean;
clearUsbId(): void;
getUsbId(): USBID | undefined;
setUsbId(value?: USBID): IdentificationPref;
serializeBinary(): Uint8Array;
@@ -142,7 +142,7 @@ export class IdentificationPref extends jspb.Message {
export namespace IdentificationPref {
export type AsObject = {
usbid?: USBID.AsObject,
usbId?: USBID.AsObject,
}
}
@@ -178,8 +178,8 @@ export class Package extends jspb.Message {
getUrl(): string;
setUrl(value: string): Package;
getWebsiteurl(): string;
setWebsiteurl(value: string): Package;
getWebsiteUrl(): string;
setWebsiteUrl(value: string): Package;
getEmail(): string;
setEmail(value: string): Package;
@@ -208,7 +208,7 @@ export namespace Package {
export type AsObject = {
maintainer: string,
url: string,
websiteurl: string,
websiteUrl: string,
email: string,
name: string,
help?: Help.AsObject,
@@ -246,8 +246,8 @@ export class BoardPlatform extends jspb.Message {
getUrl(): string;
setUrl(value: string): BoardPlatform;
getArchivefilename(): string;
setArchivefilename(value: string): BoardPlatform;
getArchiveFilename(): string;
setArchiveFilename(value: string): BoardPlatform;
getChecksum(): string;
setChecksum(value: string): BoardPlatform;
@@ -274,7 +274,7 @@ export namespace BoardPlatform {
architecture: string,
category: string,
url: string,
archivefilename: string,
archiveFilename: string,
checksum: string,
size: number,
name: string,
@@ -323,8 +323,8 @@ export class Systems extends jspb.Message {
getHost(): string;
setHost(value: string): Systems;
getArchivefilename(): string;
setArchivefilename(value: string): Systems;
getArchiveFilename(): string;
setArchiveFilename(value: string): Systems;
getUrl(): string;
setUrl(value: string): Systems;
@@ -347,7 +347,7 @@ export namespace Systems {
export type AsObject = {
checksum: string,
host: string,
archivefilename: string,
archiveFilename: string,
url: string,
size: number,
}
@@ -413,108 +413,108 @@ export namespace ConfigValue {
}
}
export class BoardAttachReq extends jspb.Message {
export class BoardAttachRequest extends jspb.Message {
hasInstance(): boolean;
clearInstance(): void;
getInstance(): commands_common_pb.Instance | undefined;
setInstance(value?: commands_common_pb.Instance): BoardAttachReq;
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardAttachRequest;
getBoardUri(): string;
setBoardUri(value: string): BoardAttachReq;
setBoardUri(value: string): BoardAttachRequest;
getSketchPath(): string;
setSketchPath(value: string): BoardAttachReq;
setSketchPath(value: string): BoardAttachRequest;
getSearchTimeout(): string;
setSearchTimeout(value: string): BoardAttachReq;
setSearchTimeout(value: string): BoardAttachRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardAttachReq.AsObject;
static toObject(includeInstance: boolean, msg: BoardAttachReq): BoardAttachReq.AsObject;
toObject(includeInstance?: boolean): BoardAttachRequest.AsObject;
static toObject(includeInstance: boolean, msg: BoardAttachRequest): BoardAttachRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardAttachReq, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardAttachReq;
static deserializeBinaryFromReader(message: BoardAttachReq, reader: jspb.BinaryReader): BoardAttachReq;
static serializeBinaryToWriter(message: BoardAttachRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardAttachRequest;
static deserializeBinaryFromReader(message: BoardAttachRequest, reader: jspb.BinaryReader): BoardAttachRequest;
}
export namespace BoardAttachReq {
export namespace BoardAttachRequest {
export type AsObject = {
instance?: commands_common_pb.Instance.AsObject,
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
boardUri: string,
sketchPath: string,
searchTimeout: string,
}
}
export class BoardAttachResp extends jspb.Message {
export class BoardAttachResponse extends jspb.Message {
hasTaskProgress(): boolean;
clearTaskProgress(): void;
getTaskProgress(): commands_common_pb.TaskProgress | undefined;
setTaskProgress(value?: commands_common_pb.TaskProgress): BoardAttachResp;
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): BoardAttachResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardAttachResp.AsObject;
static toObject(includeInstance: boolean, msg: BoardAttachResp): BoardAttachResp.AsObject;
toObject(includeInstance?: boolean): BoardAttachResponse.AsObject;
static toObject(includeInstance: boolean, msg: BoardAttachResponse): BoardAttachResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardAttachResp, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardAttachResp;
static deserializeBinaryFromReader(message: BoardAttachResp, reader: jspb.BinaryReader): BoardAttachResp;
static serializeBinaryToWriter(message: BoardAttachResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardAttachResponse;
static deserializeBinaryFromReader(message: BoardAttachResponse, reader: jspb.BinaryReader): BoardAttachResponse;
}
export namespace BoardAttachResp {
export namespace BoardAttachResponse {
export type AsObject = {
taskProgress?: commands_common_pb.TaskProgress.AsObject,
taskProgress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
}
}
export class BoardListReq extends jspb.Message {
export class BoardListRequest extends jspb.Message {
hasInstance(): boolean;
clearInstance(): void;
getInstance(): commands_common_pb.Instance | undefined;
setInstance(value?: commands_common_pb.Instance): BoardListReq;
getInstance(): cc_arduino_cli_commands_v1_common_pb.Instance | undefined;
setInstance(value?: cc_arduino_cli_commands_v1_common_pb.Instance): BoardListRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardListReq.AsObject;
static toObject(includeInstance: boolean, msg: BoardListReq): BoardListReq.AsObject;
toObject(includeInstance?: boolean): BoardListRequest.AsObject;
static toObject(includeInstance: boolean, msg: BoardListRequest): BoardListRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardListReq, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListReq;
static deserializeBinaryFromReader(message: BoardListReq, reader: jspb.BinaryReader): BoardListReq;
static serializeBinaryToWriter(message: BoardListRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListRequest;
static deserializeBinaryFromReader(message: BoardListRequest, reader: jspb.BinaryReader): BoardListRequest;
}
export namespace BoardListReq {
export namespace BoardListRequest {
export type AsObject = {
instance?: commands_common_pb.Instance.AsObject,
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class BoardListResp extends jspb.Message {
export class BoardListResponse extends jspb.Message {
clearPortsList(): void;
getPortsList(): Array<DetectedPort>;
setPortsList(value: Array<DetectedPort>): BoardListResp;
setPortsList(value: Array<DetectedPort>): BoardListResponse;
addPorts(value?: DetectedPort, index?: number): DetectedPort;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardListResp.AsObject;
static toObject(includeInstance: boolean, msg: BoardListResp): BoardListResp.AsObject;
toObject(includeInstance?: boolean): BoardListResponse.AsObject;
static toObject(includeInstance: boolean, msg: BoardListResponse): BoardListResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardListResp, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListResp;
static deserializeBinaryFromReader(message: BoardListResp, reader: jspb.BinaryReader): BoardListResp;
static serializeBinaryToWriter(message: BoardListResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListResponse;
static deserializeBinaryFromReader(message: BoardListResponse, reader: jspb.BinaryReader): BoardListResponse;
}
export namespace BoardListResp {
export namespace BoardListResponse {
export type AsObject = {
portsList: Array<DetectedPort.AsObject>,
}
@@ -535,6 +535,9 @@ export class DetectedPort extends jspb.Message {
setBoardsList(value: Array<BoardListItem>): DetectedPort;
addBoards(value?: BoardListItem, index?: number): BoardListItem;
getSerialNumber(): string;
setSerialNumber(value: string): DetectedPort;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): DetectedPort.AsObject;
@@ -552,119 +555,120 @@ export namespace DetectedPort {
protocol: string,
protocolLabel: string,
boardsList: Array<BoardListItem.AsObject>,
serialNumber: string,
}
}
export class BoardListAllReq extends jspb.Message {
export class BoardListAllRequest extends jspb.Message {
hasInstance(): boolean;
clearInstance(): void;
getInstance(): commands_common_pb.Instance | undefined;
setInstance(value?: commands_common_pb.Instance): BoardListAllReq;
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>): BoardListAllReq;
setSearchArgsList(value: Array<string>): BoardListAllRequest;
addSearchArgs(value: string, index?: number): string;
getIncludeHiddenBoards(): boolean;
setIncludeHiddenBoards(value: boolean): BoardListAllReq;
setIncludeHiddenBoards(value: boolean): BoardListAllRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardListAllReq.AsObject;
static toObject(includeInstance: boolean, msg: BoardListAllReq): BoardListAllReq.AsObject;
toObject(includeInstance?: boolean): BoardListAllRequest.AsObject;
static toObject(includeInstance: boolean, msg: BoardListAllRequest): BoardListAllRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardListAllReq, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListAllReq;
static deserializeBinaryFromReader(message: BoardListAllReq, reader: jspb.BinaryReader): BoardListAllReq;
static serializeBinaryToWriter(message: BoardListAllRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListAllRequest;
static deserializeBinaryFromReader(message: BoardListAllRequest, reader: jspb.BinaryReader): BoardListAllRequest;
}
export namespace BoardListAllReq {
export namespace BoardListAllRequest {
export type AsObject = {
instance?: commands_common_pb.Instance.AsObject,
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
searchArgsList: Array<string>,
includeHiddenBoards: boolean,
}
}
export class BoardListAllResp extends jspb.Message {
export class BoardListAllResponse extends jspb.Message {
clearBoardsList(): void;
getBoardsList(): Array<BoardListItem>;
setBoardsList(value: Array<BoardListItem>): BoardListAllResp;
setBoardsList(value: Array<BoardListItem>): BoardListAllResponse;
addBoards(value?: BoardListItem, index?: number): BoardListItem;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardListAllResp.AsObject;
static toObject(includeInstance: boolean, msg: BoardListAllResp): BoardListAllResp.AsObject;
toObject(includeInstance?: boolean): BoardListAllResponse.AsObject;
static toObject(includeInstance: boolean, msg: BoardListAllResponse): BoardListAllResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardListAllResp, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListAllResp;
static deserializeBinaryFromReader(message: BoardListAllResp, reader: jspb.BinaryReader): BoardListAllResp;
static serializeBinaryToWriter(message: BoardListAllResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListAllResponse;
static deserializeBinaryFromReader(message: BoardListAllResponse, reader: jspb.BinaryReader): BoardListAllResponse;
}
export namespace BoardListAllResp {
export namespace BoardListAllResponse {
export type AsObject = {
boardsList: Array<BoardListItem.AsObject>,
}
}
export class BoardListWatchReq extends jspb.Message {
export class BoardListWatchRequest extends jspb.Message {
hasInstance(): boolean;
clearInstance(): void;
getInstance(): commands_common_pb.Instance | undefined;
setInstance(value?: commands_common_pb.Instance): BoardListWatchReq;
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): BoardListWatchReq;
setInterrupt(value: boolean): BoardListWatchRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardListWatchReq.AsObject;
static toObject(includeInstance: boolean, msg: BoardListWatchReq): BoardListWatchReq.AsObject;
toObject(includeInstance?: boolean): BoardListWatchRequest.AsObject;
static toObject(includeInstance: boolean, msg: BoardListWatchRequest): BoardListWatchRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardListWatchReq, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListWatchReq;
static deserializeBinaryFromReader(message: BoardListWatchReq, reader: jspb.BinaryReader): BoardListWatchReq;
static serializeBinaryToWriter(message: BoardListWatchRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListWatchRequest;
static deserializeBinaryFromReader(message: BoardListWatchRequest, reader: jspb.BinaryReader): BoardListWatchRequest;
}
export namespace BoardListWatchReq {
export namespace BoardListWatchRequest {
export type AsObject = {
instance?: commands_common_pb.Instance.AsObject,
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
interrupt: boolean,
}
}
export class BoardListWatchResp extends jspb.Message {
export class BoardListWatchResponse extends jspb.Message {
getEventType(): string;
setEventType(value: string): BoardListWatchResp;
setEventType(value: string): BoardListWatchResponse;
hasPort(): boolean;
clearPort(): void;
getPort(): DetectedPort | undefined;
setPort(value?: DetectedPort): BoardListWatchResp;
setPort(value?: DetectedPort): BoardListWatchResponse;
getError(): string;
setError(value: string): BoardListWatchResp;
setError(value: string): BoardListWatchResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): BoardListWatchResp.AsObject;
static toObject(includeInstance: boolean, msg: BoardListWatchResp): BoardListWatchResp.AsObject;
toObject(includeInstance?: boolean): BoardListWatchResponse.AsObject;
static toObject(includeInstance: boolean, msg: BoardListWatchResponse): BoardListWatchResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardListWatchResp, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListWatchResp;
static deserializeBinaryFromReader(message: BoardListWatchResp, reader: jspb.BinaryReader): BoardListWatchResp;
static serializeBinaryToWriter(message: BoardListWatchResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardListWatchResponse;
static deserializeBinaryFromReader(message: BoardListWatchResponse, reader: jspb.BinaryReader): BoardListWatchResponse;
}
export namespace BoardListWatchResp {
export namespace BoardListWatchResponse {
export type AsObject = {
eventType: string,
port?: DetectedPort.AsObject,
@@ -689,6 +693,12 @@ export class BoardListItem extends jspb.Message {
setPid(value: string): 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;
@@ -706,5 +716,61 @@ export namespace BoardListItem {
isHidden: boolean,
vid: string,
pid: string,
platform?: cc_arduino_cli_commands_v1_common_pb.Platform.AsObject,
}
}
export class BoardSearchRequest 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): 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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardSearchRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardSearchRequest;
static deserializeBinaryFromReader(message: BoardSearchRequest, reader: jspb.BinaryReader): BoardSearchRequest;
}
export namespace BoardSearchRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
searchArgs: string,
includeHiddenBoards: boolean,
}
}
export class BoardSearchResponse extends jspb.Message {
clearBoardsList(): void;
getBoardsList(): Array<BoardListItem>;
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: BoardSearchResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): BoardSearchResponse;
static deserializeBinaryFromReader(message: BoardSearchResponse, reader: jspb.BinaryReader): BoardSearchResponse;
}
export namespace BoardSearchResponse {
export type AsObject = {
boardsList: Array<BoardListItem.AsObject>,
}
}

View File

@@ -0,0 +1,619 @@
// package: cc.arduino.cli.commands.v1
// file: cc/arduino/cli/commands/v1/commands.proto
/* tslint:disable */
/* 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 cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino/cli/commands/v1/common_pb";
import * as cc_arduino_cli_commands_v1_board_pb from "../../../../../cc/arduino/cli/commands/v1/board_pb";
import * as cc_arduino_cli_commands_v1_compile_pb from "../../../../../cc/arduino/cli/commands/v1/compile_pb";
import * as cc_arduino_cli_commands_v1_core_pb from "../../../../../cc/arduino/cli/commands/v1/core_pb";
import * as cc_arduino_cli_commands_v1_upload_pb from "../../../../../cc/arduino/cli/commands/v1/upload_pb";
import * as cc_arduino_cli_commands_v1_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
interface IArduinoCoreServiceService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
init: IArduinoCoreServiceService_IInit;
destroy: IArduinoCoreServiceService_IDestroy;
rescan: IArduinoCoreServiceService_IRescan;
updateIndex: IArduinoCoreServiceService_IUpdateIndex;
updateLibrariesIndex: IArduinoCoreServiceService_IUpdateLibrariesIndex;
updateCoreLibrariesIndex: IArduinoCoreServiceService_IUpdateCoreLibrariesIndex;
outdated: IArduinoCoreServiceService_IOutdated;
upgrade: IArduinoCoreServiceService_IUpgrade;
version: IArduinoCoreServiceService_IVersion;
loadSketch: IArduinoCoreServiceService_ILoadSketch;
archiveSketch: IArduinoCoreServiceService_IArchiveSketch;
boardDetails: IArduinoCoreServiceService_IBoardDetails;
boardAttach: IArduinoCoreServiceService_IBoardAttach;
boardList: IArduinoCoreServiceService_IBoardList;
boardListAll: IArduinoCoreServiceService_IBoardListAll;
boardSearch: IArduinoCoreServiceService_IBoardSearch;
boardListWatch: IArduinoCoreServiceService_IBoardListWatch;
compile: IArduinoCoreServiceService_ICompile;
platformInstall: IArduinoCoreServiceService_IPlatformInstall;
platformDownload: IArduinoCoreServiceService_IPlatformDownload;
platformUninstall: IArduinoCoreServiceService_IPlatformUninstall;
platformUpgrade: IArduinoCoreServiceService_IPlatformUpgrade;
upload: IArduinoCoreServiceService_IUpload;
uploadUsingProgrammer: IArduinoCoreServiceService_IUploadUsingProgrammer;
listProgrammersAvailableForUpload: IArduinoCoreServiceService_IListProgrammersAvailableForUpload;
burnBootloader: IArduinoCoreServiceService_IBurnBootloader;
platformSearch: IArduinoCoreServiceService_IPlatformSearch;
platformList: IArduinoCoreServiceService_IPlatformList;
libraryDownload: IArduinoCoreServiceService_ILibraryDownload;
libraryInstall: IArduinoCoreServiceService_ILibraryInstall;
zipLibraryInstall: IArduinoCoreServiceService_IZipLibraryInstall;
gitLibraryInstall: IArduinoCoreServiceService_IGitLibraryInstall;
libraryUninstall: IArduinoCoreServiceService_ILibraryUninstall;
libraryUpgradeAll: IArduinoCoreServiceService_ILibraryUpgradeAll;
libraryResolveDependencies: IArduinoCoreServiceService_ILibraryResolveDependencies;
librarySearch: IArduinoCoreServiceService_ILibrarySearch;
libraryList: IArduinoCoreServiceService_ILibraryList;
}
interface IArduinoCoreServiceService_IInit extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.InitRequest, cc_arduino_cli_commands_v1_commands_pb.InitResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Init";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.InitRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.InitRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
}
interface IArduinoCoreServiceService_IDestroy extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, cc_arduino_cli_commands_v1_commands_pb.DestroyResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Destroy";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.DestroyRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.DestroyRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.DestroyResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.DestroyResponse>;
}
interface IArduinoCoreServiceService_IRescan extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.RescanRequest, cc_arduino_cli_commands_v1_commands_pb.RescanResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Rescan";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.RescanRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.RescanRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.RescanResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.RescanResponse>;
}
interface IArduinoCoreServiceService_IUpdateIndex extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest, cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateIndex";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
}
interface IArduinoCoreServiceService_IUpdateLibrariesIndex extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest, cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateLibrariesIndex";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
}
interface IArduinoCoreServiceService_IUpdateCoreLibrariesIndex extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest, cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/UpdateCoreLibrariesIndex";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
}
interface IArduinoCoreServiceService_IOutdated extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Outdated";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse>;
}
interface IArduinoCoreServiceService_IUpgrade extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Upgrade";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
}
interface IArduinoCoreServiceService_IVersion extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.VersionRequest, cc_arduino_cli_commands_v1_commands_pb.VersionResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Version";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.VersionRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.VersionRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.VersionResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.VersionResponse>;
}
interface IArduinoCoreServiceService_ILoadSketch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LoadSketch";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse>;
}
interface IArduinoCoreServiceService_IArchiveSketch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest, cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/ArchiveSketch";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_commands_pb.ArchiveSketchResponse>;
}
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;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse>;
}
interface IArduinoCoreServiceService_IBoardAttach extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest, cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardAttach";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
}
interface IArduinoCoreServiceService_IBoardList extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_board_pb.BoardListRequest, cc_arduino_cli_commands_v1_board_pb.BoardListResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardList";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardListRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardListRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardListResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardListResponse>;
}
interface IArduinoCoreServiceService_IBoardListAll extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardListAll";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse>;
}
interface IArduinoCoreServiceService_IBoardSearch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardSearch";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse>;
}
interface IArduinoCoreServiceService_IBoardListWatch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BoardListWatch";
requestStream: true;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
}
interface IArduinoCoreServiceService_ICompile extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_compile_pb.CompileRequest, cc_arduino_cli_commands_v1_compile_pb.CompileResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Compile";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_compile_pb.CompileRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_compile_pb.CompileRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
}
interface IArduinoCoreServiceService_IPlatformInstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest, cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformInstall";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
}
interface IArduinoCoreServiceService_IPlatformDownload extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest, cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformDownload";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
}
interface IArduinoCoreServiceService_IPlatformUninstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest, cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformUninstall";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
}
interface IArduinoCoreServiceService_IPlatformUpgrade extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest, cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformUpgrade";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
}
interface IArduinoCoreServiceService_IUpload extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_upload_pb.UploadRequest, cc_arduino_cli_commands_v1_upload_pb.UploadResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/Upload";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.UploadRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.UploadRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
}
interface IArduinoCoreServiceService_IUploadUsingProgrammer extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest, cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/UploadUsingProgrammer";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
}
interface IArduinoCoreServiceService_IListProgrammersAvailableForUpload extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/ListProgrammersAvailableForUpload";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse>;
}
interface IArduinoCoreServiceService_IBurnBootloader extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/BurnBootloader";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
}
interface IArduinoCoreServiceService_IPlatformSearch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformSearch";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse>;
}
interface IArduinoCoreServiceService_IPlatformList extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, cc_arduino_cli_commands_v1_core_pb.PlatformListResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/PlatformList";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
}
interface IArduinoCoreServiceService_ILibraryDownload extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryDownload";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
}
interface IArduinoCoreServiceService_ILibraryInstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryInstall";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
}
interface IArduinoCoreServiceService_IZipLibraryInstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/ZipLibraryInstall";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
}
interface IArduinoCoreServiceService_IGitLibraryInstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/GitLibraryInstall";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
}
interface IArduinoCoreServiceService_ILibraryUninstall extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUninstall";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
}
interface IArduinoCoreServiceService_ILibraryUpgradeAll extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryUpgradeAll";
requestStream: false;
responseStream: true;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
}
interface IArduinoCoreServiceService_ILibraryResolveDependencies extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryResolveDependencies";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse>;
}
interface IArduinoCoreServiceService_ILibrarySearch extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibrarySearch";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse>;
}
interface IArduinoCoreServiceService_ILibraryList extends grpc.MethodDefinition<cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse> {
path: "/cc.arduino.cli.commands.v1.ArduinoCoreService/LibraryList";
requestStream: false;
responseStream: false;
requestSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest>;
requestDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest>;
responseSerialize: grpc.serialize<cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse>;
responseDeserialize: grpc.deserialize<cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse>;
}
export const ArduinoCoreServiceService: IArduinoCoreServiceService;
export interface IArduinoCoreServiceServer {
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>;
rescan: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.RescanRequest, cc_arduino_cli_commands_v1_commands_pb.RescanResponse>;
updateIndex: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest, cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
updateLibrariesIndex: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest, cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
updateCoreLibrariesIndex: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest, cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
outdated: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse>;
upgrade: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
version: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_commands_pb.VersionRequest, cc_arduino_cli_commands_v1_commands_pb.VersionResponse>;
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>;
boardDetails: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_board_pb.BoardDetailsRequest, cc_arduino_cli_commands_v1_board_pb.BoardDetailsResponse>;
boardAttach: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest, cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
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>;
boardSearch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse>;
boardListWatch: grpc.handleBidiStreamingCall<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
compile: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_compile_pb.CompileRequest, cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
platformInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest, cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
platformDownload: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest, cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
platformUninstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest, cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
platformUpgrade: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest, cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
upload: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_upload_pb.UploadRequest, cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
uploadUsingProgrammer: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest, cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
listProgrammersAvailableForUpload: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse>;
burnBootloader: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
platformSearch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse>;
platformList: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, cc_arduino_cli_commands_v1_core_pb.PlatformListResponse>;
libraryDownload: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
libraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
zipLibraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
gitLibraryInstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
libraryUninstall: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
libraryUpgradeAll: grpc.handleServerStreamingCall<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
libraryResolveDependencies: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse>;
librarySearch: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse>;
libraryList: grpc.handleUnaryCall<cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse>;
}
export interface IArduinoCoreServiceClient {
init(request: cc_arduino_cli_commands_v1_commands_pb.InitRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
init(request: cc_arduino_cli_commands_v1_commands_pb.InitRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
destroy(request: cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.DestroyResponse) => void): grpc.ClientUnaryCall;
destroy(request: cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.DestroyResponse) => void): grpc.ClientUnaryCall;
destroy(request: cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.DestroyResponse) => void): grpc.ClientUnaryCall;
rescan(request: cc_arduino_cli_commands_v1_commands_pb.RescanRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.RescanResponse) => void): grpc.ClientUnaryCall;
rescan(request: cc_arduino_cli_commands_v1_commands_pb.RescanRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.RescanResponse) => void): grpc.ClientUnaryCall;
rescan(request: cc_arduino_cli_commands_v1_commands_pb.RescanRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.RescanResponse) => void): grpc.ClientUnaryCall;
updateIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
updateIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
updateLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
updateLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
updateCoreLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
updateCoreLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
outdated(request: cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse) => void): grpc.ClientUnaryCall;
outdated(request: cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse) => void): grpc.ClientUnaryCall;
outdated(request: cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse) => void): grpc.ClientUnaryCall;
upgrade(request: cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
upgrade(request: cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
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;
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;
boardAttach(request: cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
boardAttach(request: cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
boardList(request: cc_arduino_cli_commands_v1_board_pb.BoardListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListResponse) => void): grpc.ClientUnaryCall;
boardList(request: cc_arduino_cli_commands_v1_board_pb.BoardListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListResponse) => void): grpc.ClientUnaryCall;
boardList(request: cc_arduino_cli_commands_v1_board_pb.BoardListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListResponse) => void): grpc.ClientUnaryCall;
boardListAll(request: cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse) => void): grpc.ClientUnaryCall;
boardListAll(request: cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse) => void): grpc.ClientUnaryCall;
boardListAll(request: cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse) => void): grpc.ClientUnaryCall;
boardSearch(request: cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse) => void): grpc.ClientUnaryCall;
boardSearch(request: cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse) => void): grpc.ClientUnaryCall;
boardSearch(request: cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse) => void): grpc.ClientUnaryCall;
boardListWatch(): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
boardListWatch(options: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
boardListWatch(metadata: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
compile(request: cc_arduino_cli_commands_v1_compile_pb.CompileRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
compile(request: cc_arduino_cli_commands_v1_compile_pb.CompileRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
platformInstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
platformInstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
platformDownload(request: cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
platformDownload(request: cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
platformUninstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
platformUninstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
platformUpgrade(request: cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
platformUpgrade(request: cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
upload(request: cc_arduino_cli_commands_v1_upload_pb.UploadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
upload(request: cc_arduino_cli_commands_v1_upload_pb.UploadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
uploadUsingProgrammer(request: cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
uploadUsingProgrammer(request: cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
listProgrammersAvailableForUpload(request: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse) => void): grpc.ClientUnaryCall;
listProgrammersAvailableForUpload(request: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse) => void): grpc.ClientUnaryCall;
listProgrammersAvailableForUpload(request: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse) => void): grpc.ClientUnaryCall;
burnBootloader(request: cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
burnBootloader(request: cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
gitLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
gitLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
libraryUninstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
libraryUninstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
libraryUpgradeAll(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
libraryUpgradeAll(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
libraryResolveDependencies(request: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse) => void): grpc.ClientUnaryCall;
libraryResolveDependencies(request: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse) => void): grpc.ClientUnaryCall;
libraryResolveDependencies(request: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse) => void): grpc.ClientUnaryCall;
librarySearch(request: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse) => void): grpc.ClientUnaryCall;
librarySearch(request: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse) => void): grpc.ClientUnaryCall;
librarySearch(request: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse) => void): grpc.ClientUnaryCall;
libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
}
export class ArduinoCoreServiceClient extends grpc.Client implements IArduinoCoreServiceClient {
constructor(address: string, credentials: grpc.ChannelCredentials, options?: Partial<grpc.ClientOptions>);
public init(request: cc_arduino_cli_commands_v1_commands_pb.InitRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
public init(request: cc_arduino_cli_commands_v1_commands_pb.InitRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.InitResponse>;
public destroy(request: cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.DestroyResponse) => void): grpc.ClientUnaryCall;
public destroy(request: cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.DestroyResponse) => void): grpc.ClientUnaryCall;
public destroy(request: cc_arduino_cli_commands_v1_commands_pb.DestroyRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.DestroyResponse) => void): grpc.ClientUnaryCall;
public rescan(request: cc_arduino_cli_commands_v1_commands_pb.RescanRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.RescanResponse) => void): grpc.ClientUnaryCall;
public rescan(request: cc_arduino_cli_commands_v1_commands_pb.RescanRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.RescanResponse) => void): grpc.ClientUnaryCall;
public rescan(request: cc_arduino_cli_commands_v1_commands_pb.RescanRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.RescanResponse) => void): grpc.ClientUnaryCall;
public updateIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
public updateIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateIndexRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateIndexResponse>;
public updateLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
public updateLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateLibrariesIndexResponse>;
public updateCoreLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
public updateCoreLibrariesIndex(request: cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpdateCoreLibrariesIndexResponse>;
public outdated(request: cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse) => void): grpc.ClientUnaryCall;
public outdated(request: cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse) => void): grpc.ClientUnaryCall;
public outdated(request: cc_arduino_cli_commands_v1_commands_pb.OutdatedRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.OutdatedResponse) => void): grpc.ClientUnaryCall;
public upgrade(request: cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
public upgrade(request: cc_arduino_cli_commands_v1_commands_pb.UpgradeRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_commands_pb.UpgradeResponse>;
public version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
public version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
public version(request: cc_arduino_cli_commands_v1_commands_pb.VersionRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.VersionResponse) => void): grpc.ClientUnaryCall;
public loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
public loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
public loadSketch(request: cc_arduino_cli_commands_v1_commands_pb.LoadSketchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_commands_pb.LoadSketchResponse) => void): grpc.ClientUnaryCall;
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 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;
public boardAttach(request: cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
public boardAttach(request: cc_arduino_cli_commands_v1_board_pb.BoardAttachRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_board_pb.BoardAttachResponse>;
public boardList(request: cc_arduino_cli_commands_v1_board_pb.BoardListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListResponse) => void): grpc.ClientUnaryCall;
public boardList(request: cc_arduino_cli_commands_v1_board_pb.BoardListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListResponse) => void): grpc.ClientUnaryCall;
public boardList(request: cc_arduino_cli_commands_v1_board_pb.BoardListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListResponse) => void): grpc.ClientUnaryCall;
public boardListAll(request: cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse) => void): grpc.ClientUnaryCall;
public boardListAll(request: cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse) => void): grpc.ClientUnaryCall;
public boardListAll(request: cc_arduino_cli_commands_v1_board_pb.BoardListAllRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardListAllResponse) => void): grpc.ClientUnaryCall;
public boardSearch(request: cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse) => void): grpc.ClientUnaryCall;
public boardSearch(request: cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse) => void): grpc.ClientUnaryCall;
public boardSearch(request: cc_arduino_cli_commands_v1_board_pb.BoardSearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_board_pb.BoardSearchResponse) => void): grpc.ClientUnaryCall;
public boardListWatch(options?: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
public boardListWatch(metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientDuplexStream<cc_arduino_cli_commands_v1_board_pb.BoardListWatchRequest, cc_arduino_cli_commands_v1_board_pb.BoardListWatchResponse>;
public compile(request: cc_arduino_cli_commands_v1_compile_pb.CompileRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
public compile(request: cc_arduino_cli_commands_v1_compile_pb.CompileRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_compile_pb.CompileResponse>;
public platformInstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
public platformInstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformInstallResponse>;
public platformDownload(request: cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
public platformDownload(request: cc_arduino_cli_commands_v1_core_pb.PlatformDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformDownloadResponse>;
public platformUninstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
public platformUninstall(request: cc_arduino_cli_commands_v1_core_pb.PlatformUninstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUninstallResponse>;
public platformUpgrade(request: cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
public platformUpgrade(request: cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_core_pb.PlatformUpgradeResponse>;
public upload(request: cc_arduino_cli_commands_v1_upload_pb.UploadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
public upload(request: cc_arduino_cli_commands_v1_upload_pb.UploadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadResponse>;
public uploadUsingProgrammer(request: cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
public uploadUsingProgrammer(request: cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.UploadUsingProgrammerResponse>;
public listProgrammersAvailableForUpload(request: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse) => void): grpc.ClientUnaryCall;
public listProgrammersAvailableForUpload(request: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse) => void): grpc.ClientUnaryCall;
public listProgrammersAvailableForUpload(request: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_upload_pb.ListProgrammersAvailableForUploadResponse) => void): grpc.ClientUnaryCall;
public burnBootloader(request: cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
public burnBootloader(request: cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_upload_pb.BurnBootloaderResponse>;
public platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
public platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
public platformSearch(request: cc_arduino_cli_commands_v1_core_pb.PlatformSearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformSearchResponse) => void): grpc.ClientUnaryCall;
public platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
public platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
public platformList(request: cc_arduino_cli_commands_v1_core_pb.PlatformListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_core_pb.PlatformListResponse) => void): grpc.ClientUnaryCall;
public libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
public libraryDownload(request: cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryDownloadResponse>;
public libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
public libraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryInstallResponse>;
public zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
public zipLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.ZipLibraryInstallResponse>;
public gitLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
public gitLibraryInstall(request: cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.GitLibraryInstallResponse>;
public libraryUninstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
public libraryUninstall(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUninstallResponse>;
public libraryUpgradeAll(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
public libraryUpgradeAll(request: cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllRequest, metadata?: grpc.Metadata, options?: Partial<grpc.CallOptions>): grpc.ClientReadableStream<cc_arduino_cli_commands_v1_lib_pb.LibraryUpgradeAllResponse>;
public libraryResolveDependencies(request: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse) => void): grpc.ClientUnaryCall;
public libraryResolveDependencies(request: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse) => void): grpc.ClientUnaryCall;
public libraryResolveDependencies(request: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryResolveDependenciesResponse) => void): grpc.ClientUnaryCall;
public librarySearch(request: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse) => void): grpc.ClientUnaryCall;
public librarySearch(request: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse) => void): grpc.ClientUnaryCall;
public librarySearch(request: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibrarySearchResponse) => void): grpc.ClientUnaryCall;
public libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
public libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
public libraryList(request: cc_arduino_cli_commands_v1_lib_pb.LibraryListRequest, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: cc_arduino_cli_commands_v1_lib_pb.LibraryListResponse) => void): grpc.ClientUnaryCall;
}

View File

@@ -0,0 +1,585 @@
// package: cc.arduino.cli.commands.v1
// file: cc/arduino/cli/commands/v1/commands.proto
/* tslint:disable */
/* eslint-disable */
import * as jspb from "google-protobuf";
import * as cc_arduino_cli_commands_v1_common_pb from "../../../../../cc/arduino/cli/commands/v1/common_pb";
import * as cc_arduino_cli_commands_v1_board_pb from "../../../../../cc/arduino/cli/commands/v1/board_pb";
import * as cc_arduino_cli_commands_v1_compile_pb from "../../../../../cc/arduino/cli/commands/v1/compile_pb";
import * as cc_arduino_cli_commands_v1_core_pb from "../../../../../cc/arduino/cli/commands/v1/core_pb";
import * as cc_arduino_cli_commands_v1_upload_pb from "../../../../../cc/arduino/cli/commands/v1/upload_pb";
import * as cc_arduino_cli_commands_v1_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
export class InitRequest extends jspb.Message {
getLibraryManagerOnly(): boolean;
setLibraryManagerOnly(value: boolean): InitRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): InitRequest.AsObject;
static toObject(includeInstance: boolean, msg: InitRequest): InitRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: InitRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): InitRequest;
static deserializeBinaryFromReader(message: InitRequest, reader: jspb.BinaryReader): InitRequest;
}
export namespace InitRequest {
export type AsObject = {
libraryManagerOnly: boolean,
}
}
export class InitResponse 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): InitResponse;
clearPlatformsIndexErrorsList(): void;
getPlatformsIndexErrorsList(): Array<string>;
setPlatformsIndexErrorsList(value: Array<string>): InitResponse;
addPlatformsIndexErrors(value: string, index?: number): string;
getLibrariesIndexError(): string;
setLibrariesIndexError(value: string): InitResponse;
hasDownloadProgress(): boolean;
clearDownloadProgress(): void;
getDownloadProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
setDownloadProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): InitResponse;
hasTaskProgress(): boolean;
clearTaskProgress(): void;
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): InitResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): InitResponse.AsObject;
static toObject(includeInstance: boolean, msg: InitResponse): InitResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: InitResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): InitResponse;
static deserializeBinaryFromReader(message: InitResponse, reader: jspb.BinaryReader): InitResponse;
}
export namespace InitResponse {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
platformsIndexErrorsList: Array<string>,
librariesIndexError: string,
downloadProgress?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress.AsObject,
taskProgress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
}
}
export class DestroyRequest 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): DestroyRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): DestroyRequest.AsObject;
static toObject(includeInstance: boolean, msg: DestroyRequest): DestroyRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: DestroyRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): DestroyRequest;
static deserializeBinaryFromReader(message: DestroyRequest, reader: jspb.BinaryReader): DestroyRequest;
}
export namespace DestroyRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class DestroyResponse extends jspb.Message {
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): DestroyResponse.AsObject;
static toObject(includeInstance: boolean, msg: DestroyResponse): DestroyResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: DestroyResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): DestroyResponse;
static deserializeBinaryFromReader(message: DestroyResponse, reader: jspb.BinaryReader): DestroyResponse;
}
export namespace DestroyResponse {
export type AsObject = {
}
}
export class RescanRequest 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): RescanRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): RescanRequest.AsObject;
static toObject(includeInstance: boolean, msg: RescanRequest): RescanRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: RescanRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): RescanRequest;
static deserializeBinaryFromReader(message: RescanRequest, reader: jspb.BinaryReader): RescanRequest;
}
export namespace RescanRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class RescanResponse extends jspb.Message {
clearPlatformsIndexErrorsList(): void;
getPlatformsIndexErrorsList(): Array<string>;
setPlatformsIndexErrorsList(value: Array<string>): RescanResponse;
addPlatformsIndexErrors(value: string, index?: number): string;
getLibrariesIndexError(): string;
setLibrariesIndexError(value: string): RescanResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): RescanResponse.AsObject;
static toObject(includeInstance: boolean, msg: RescanResponse): RescanResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: RescanResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): RescanResponse;
static deserializeBinaryFromReader(message: RescanResponse, reader: jspb.BinaryReader): RescanResponse;
}
export namespace RescanResponse {
export type AsObject = {
platformsIndexErrorsList: Array<string>,
librariesIndexError: string,
}
}
export class UpdateIndexRequest 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): UpdateIndexRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UpdateIndexRequest.AsObject;
static toObject(includeInstance: boolean, msg: UpdateIndexRequest): UpdateIndexRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpdateIndexRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpdateIndexRequest;
static deserializeBinaryFromReader(message: UpdateIndexRequest, reader: jspb.BinaryReader): UpdateIndexRequest;
}
export namespace UpdateIndexRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class UpdateIndexResponse extends jspb.Message {
hasDownloadProgress(): boolean;
clearDownloadProgress(): void;
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpdateIndexResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpdateIndexResponse;
static deserializeBinaryFromReader(message: UpdateIndexResponse, reader: jspb.BinaryReader): UpdateIndexResponse;
}
export namespace UpdateIndexResponse {
export type AsObject = {
downloadProgress?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress.AsObject,
}
}
export class UpdateLibrariesIndexRequest 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): UpdateLibrariesIndexRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UpdateLibrariesIndexRequest.AsObject;
static toObject(includeInstance: boolean, msg: UpdateLibrariesIndexRequest): UpdateLibrariesIndexRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpdateLibrariesIndexRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpdateLibrariesIndexRequest;
static deserializeBinaryFromReader(message: UpdateLibrariesIndexRequest, reader: jspb.BinaryReader): UpdateLibrariesIndexRequest;
}
export namespace UpdateLibrariesIndexRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class UpdateLibrariesIndexResponse extends jspb.Message {
hasDownloadProgress(): boolean;
clearDownloadProgress(): void;
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpdateLibrariesIndexResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpdateLibrariesIndexResponse;
static deserializeBinaryFromReader(message: UpdateLibrariesIndexResponse, reader: jspb.BinaryReader): UpdateLibrariesIndexResponse;
}
export namespace UpdateLibrariesIndexResponse {
export type AsObject = {
downloadProgress?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress.AsObject,
}
}
export class UpdateCoreLibrariesIndexRequest 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): UpdateCoreLibrariesIndexRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UpdateCoreLibrariesIndexRequest.AsObject;
static toObject(includeInstance: boolean, msg: UpdateCoreLibrariesIndexRequest): UpdateCoreLibrariesIndexRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpdateCoreLibrariesIndexRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpdateCoreLibrariesIndexRequest;
static deserializeBinaryFromReader(message: UpdateCoreLibrariesIndexRequest, reader: jspb.BinaryReader): UpdateCoreLibrariesIndexRequest;
}
export namespace UpdateCoreLibrariesIndexRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class UpdateCoreLibrariesIndexResponse extends jspb.Message {
hasDownloadProgress(): boolean;
clearDownloadProgress(): void;
getDownloadProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
setDownloadProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): UpdateCoreLibrariesIndexResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UpdateCoreLibrariesIndexResponse.AsObject;
static toObject(includeInstance: boolean, msg: UpdateCoreLibrariesIndexResponse): UpdateCoreLibrariesIndexResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpdateCoreLibrariesIndexResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpdateCoreLibrariesIndexResponse;
static deserializeBinaryFromReader(message: UpdateCoreLibrariesIndexResponse, reader: jspb.BinaryReader): UpdateCoreLibrariesIndexResponse;
}
export namespace UpdateCoreLibrariesIndexResponse {
export type AsObject = {
downloadProgress?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress.AsObject,
}
}
export class OutdatedRequest 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): OutdatedRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): OutdatedRequest.AsObject;
static toObject(includeInstance: boolean, msg: OutdatedRequest): OutdatedRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: OutdatedRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): OutdatedRequest;
static deserializeBinaryFromReader(message: OutdatedRequest, reader: jspb.BinaryReader): OutdatedRequest;
}
export namespace OutdatedRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
}
}
export class OutdatedResponse extends jspb.Message {
clearOutdatedLibrariesList(): void;
getOutdatedLibrariesList(): Array<cc_arduino_cli_commands_v1_lib_pb.InstalledLibrary>;
setOutdatedLibrariesList(value: Array<cc_arduino_cli_commands_v1_lib_pb.InstalledLibrary>): OutdatedResponse;
addOutdatedLibraries(value?: cc_arduino_cli_commands_v1_lib_pb.InstalledLibrary, index?: number): cc_arduino_cli_commands_v1_lib_pb.InstalledLibrary;
clearOutdatedPlatformsList(): void;
getOutdatedPlatformsList(): Array<cc_arduino_cli_commands_v1_common_pb.Platform>;
setOutdatedPlatformsList(value: Array<cc_arduino_cli_commands_v1_common_pb.Platform>): OutdatedResponse;
addOutdatedPlatforms(value?: cc_arduino_cli_commands_v1_common_pb.Platform, index?: number): cc_arduino_cli_commands_v1_common_pb.Platform;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): OutdatedResponse.AsObject;
static toObject(includeInstance: boolean, msg: OutdatedResponse): OutdatedResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: OutdatedResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): OutdatedResponse;
static deserializeBinaryFromReader(message: OutdatedResponse, reader: jspb.BinaryReader): OutdatedResponse;
}
export namespace OutdatedResponse {
export type AsObject = {
outdatedLibrariesList: Array<cc_arduino_cli_commands_v1_lib_pb.InstalledLibrary.AsObject>,
outdatedPlatformsList: Array<cc_arduino_cli_commands_v1_common_pb.Platform.AsObject>,
}
}
export class UpgradeRequest 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): UpgradeRequest;
getSkipPostInstall(): boolean;
setSkipPostInstall(value: boolean): UpgradeRequest;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UpgradeRequest.AsObject;
static toObject(includeInstance: boolean, msg: UpgradeRequest): UpgradeRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpgradeRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpgradeRequest;
static deserializeBinaryFromReader(message: UpgradeRequest, reader: jspb.BinaryReader): UpgradeRequest;
}
export namespace UpgradeRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
skipPostInstall: boolean,
}
}
export class UpgradeResponse extends jspb.Message {
hasProgress(): boolean;
clearProgress(): void;
getProgress(): cc_arduino_cli_commands_v1_common_pb.DownloadProgress | undefined;
setProgress(value?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress): UpgradeResponse;
hasTaskProgress(): boolean;
clearTaskProgress(): void;
getTaskProgress(): cc_arduino_cli_commands_v1_common_pb.TaskProgress | undefined;
setTaskProgress(value?: cc_arduino_cli_commands_v1_common_pb.TaskProgress): UpgradeResponse;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): UpgradeResponse.AsObject;
static toObject(includeInstance: boolean, msg: UpgradeResponse): UpgradeResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: UpgradeResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): UpgradeResponse;
static deserializeBinaryFromReader(message: UpgradeResponse, reader: jspb.BinaryReader): UpgradeResponse;
}
export namespace UpgradeResponse {
export type AsObject = {
progress?: cc_arduino_cli_commands_v1_common_pb.DownloadProgress.AsObject,
taskProgress?: cc_arduino_cli_commands_v1_common_pb.TaskProgress.AsObject,
}
}
export class VersionRequest extends jspb.Message {
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): VersionRequest.AsObject;
static toObject(includeInstance: boolean, msg: VersionRequest): VersionRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: VersionRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): VersionRequest;
static deserializeBinaryFromReader(message: VersionRequest, reader: jspb.BinaryReader): VersionRequest;
}
export namespace VersionRequest {
export type AsObject = {
}
}
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: VersionResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): VersionResponse;
static deserializeBinaryFromReader(message: VersionResponse, reader: jspb.BinaryReader): VersionResponse;
}
export namespace VersionResponse {
export type AsObject = {
version: string,
}
}
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: LoadSketchRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): LoadSketchRequest;
static deserializeBinaryFromReader(message: LoadSketchRequest, reader: jspb.BinaryReader): LoadSketchRequest;
}
export namespace LoadSketchRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
sketchPath: string,
}
}
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;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): LoadSketchResponse.AsObject;
static toObject(includeInstance: boolean, msg: LoadSketchResponse): LoadSketchResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: LoadSketchResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): LoadSketchResponse;
static deserializeBinaryFromReader(message: LoadSketchResponse, reader: jspb.BinaryReader): LoadSketchResponse;
}
export namespace LoadSketchResponse {
export type AsObject = {
mainFile: string,
locationPath: string,
otherSketchFilesList: Array<string>,
additionalFilesList: Array<string>,
rootFolderFilesList: Array<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;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): ArchiveSketchRequest.AsObject;
static toObject(includeInstance: boolean, msg: ArchiveSketchRequest): ArchiveSketchRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: ArchiveSketchRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): ArchiveSketchRequest;
static deserializeBinaryFromReader(message: ArchiveSketchRequest, reader: jspb.BinaryReader): ArchiveSketchRequest;
}
export namespace ArchiveSketchRequest {
export type AsObject = {
sketchPath: string,
archivePath: string,
includeBuildDir: boolean,
}
}
export class ArchiveSketchResponse extends jspb.Message {
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): ArchiveSketchResponse.AsObject;
static toObject(includeInstance: boolean, msg: ArchiveSketchResponse): ArchiveSketchResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: ArchiveSketchResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): ArchiveSketchResponse;
static deserializeBinaryFromReader(message: ArchiveSketchResponse, reader: jspb.BinaryReader): ArchiveSketchResponse;
}
export namespace ArchiveSketchResponse {
export type AsObject = {
}
}

View File

@@ -1,5 +1,5 @@
// package: cc.arduino.cli.commands
// file: commands/common.proto
// package: cc.arduino.cli.commands.v1
// file: cc/arduino/cli/commands/v1/common.proto
/* tslint:disable */
/* eslint-disable */
@@ -121,3 +121,87 @@ export namespace Programmer {
name: string,
}
}
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;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): Platform.AsObject;
static toObject(includeInstance: boolean, msg: Platform): Platform.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: Platform, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): Platform;
static deserializeBinaryFromReader(message: Platform, reader: jspb.BinaryReader): Platform;
}
export namespace Platform {
export type AsObject = {
id: string,
installed: string,
latest: string,
name: string,
maintainer: string,
website: string,
email: string,
boardsList: Array<Board.AsObject>,
manuallyInstalled: boolean,
deprecated: boolean,
}
}
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: Board, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): Board;
static deserializeBinaryFromReader(message: Board, reader: jspb.BinaryReader): Board;
}
export namespace Board {
export type AsObject = {
name: string,
fqbn: string,
}
}

View File

@@ -0,0 +1,199 @@
// package: cc.arduino.cli.commands.v1
// file: cc/arduino/cli/commands/v1/compile.proto
/* tslint:disable */
/* eslint-disable */
import * as jspb from "google-protobuf";
import * as google_protobuf_wrappers_pb from "google-protobuf/google/protobuf/wrappers_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_lib_pb from "../../../../../cc/arduino/cli/commands/v1/lib_pb";
export class CompileRequest 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): 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;
getVidPid(): string;
setVidPid(value: string): 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;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): CompileRequest.AsObject;
static toObject(includeInstance: boolean, msg: CompileRequest): CompileRequest.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: CompileRequest, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): CompileRequest;
static deserializeBinaryFromReader(message: CompileRequest, reader: jspb.BinaryReader): CompileRequest;
}
export namespace CompileRequest {
export type AsObject = {
instance?: cc_arduino_cli_commands_v1_common_pb.Instance.AsObject,
fqbn: string,
sketchPath: string,
showProperties: boolean,
preprocess: boolean,
buildCachePath: string,
buildPath: string,
buildPropertiesList: Array<string>,
warnings: string,
verbose: boolean,
quiet: boolean,
vidPid: string,
jobs: number,
librariesList: Array<string>,
optimizeForDebug: boolean,
exportDir: string,
clean: boolean,
createCompilationDatabaseOnly: boolean,
sourceOverrideMap: Array<[string, string]>,
exportBinaries?: google_protobuf_wrappers_pb.BoolValue.AsObject,
libraryList: Array<string>,
}
}
export class CompileResponse extends jspb.Message {
getOutStream(): Uint8Array | string;
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;
serializeBinary(): Uint8Array;
toObject(includeInstance?: boolean): CompileResponse.AsObject;
static toObject(includeInstance: boolean, msg: CompileResponse): CompileResponse.AsObject;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: CompileResponse, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): CompileResponse;
static deserializeBinaryFromReader(message: CompileResponse, reader: jspb.BinaryReader): CompileResponse;
}
export namespace CompileResponse {
export type AsObject = {
outStream: Uint8Array | string,
errStream: Uint8Array | string,
buildPath: string,
usedLibrariesList: Array<cc_arduino_cli_commands_v1_lib_pb.Library.AsObject>,
executableSectionsSizeList: Array<ExecutableSectionSize.AsObject>,
}
}
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;
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
static serializeBinaryToWriter(message: ExecutableSectionSize, writer: jspb.BinaryWriter): void;
static deserializeBinary(bytes: Uint8Array): ExecutableSectionSize;
static deserializeBinaryFromReader(message: ExecutableSectionSize, reader: jspb.BinaryReader): ExecutableSectionSize;
}
export namespace ExecutableSectionSize {
export type AsObject = {
name: string,
size: number,
maxSize: number,
}
}

Some files were not shown because too many files have changed in this diff Show More