feat: expose Arduino state to VS Code extensions

- Update a shared state on fqbn, port, sketch path, and etc. changes.
VS Code extensions can access it and listen on changes.
 - Force VISX activation order: API VSIX starts first.

Signed-off-by: dankeboy36 <dankeboy36@gmail.com>
This commit is contained in:
dankeboy36 2023-05-13 13:50:41 +02:00 committed by Akos Kitta
parent c66b720509
commit 42d017e876
13 changed files with 569 additions and 38 deletions

View File

@ -104,7 +104,8 @@
"temp": "^0.9.1",
"temp-dir": "^2.0.0",
"tree-kill": "^1.2.1",
"util": "^0.12.5"
"util": "^0.12.5",
"vscode-arduino-api": "^0.1.2"
},
"devDependencies": {
"@octokit/rest": "^18.12.0",

View File

@ -354,6 +354,7 @@ import { FileResourceResolver as TheiaFileResourceResolver } from '@theia/filesy
import { StylingParticipant } from '@theia/core/lib/browser/styling-service';
import { MonacoEditorMenuContribution } from './theia/monaco/monaco-menu';
import { MonacoEditorMenuContribution as TheiaMonacoEditorMenuContribution } from '@theia/monaco/lib/browser/monaco-menu';
import { UpdateArduinoState } from './contributions/update-arduino-state';
// Hack to fix copy/cut/paste issue after electron version update in Theia.
// https://github.com/eclipse-theia/theia/issues/12487
@ -747,6 +748,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
Contribution.configure(bind, Account);
Contribution.configure(bind, CloudSketchbookContribution);
Contribution.configure(bind, CreateCloudCopy);
Contribution.configure(bind, UpdateArduinoState);
bindContributionProvider(bind, StartupTaskProvider);
bind(StartupTaskProvider).toService(BoardsServiceProvider); // to reuse the boards config in another window

View File

@ -0,0 +1,179 @@
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import URI from '@theia/core/lib/common/uri';
import { inject, injectable } from '@theia/core/shared/inversify';
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
import type { ArduinoState } from 'vscode-arduino-api';
import {
BoardsService,
CompileSummary,
Port,
isCompileSummary,
} from '../../common/protocol';
import {
toApiBoardDetails,
toApiCompileSummary,
toApiPort,
} from '../../common/protocol/arduino-context-mapper';
import type { BoardsConfig } from '../boards/boards-config';
import { BoardsDataStore } from '../boards/boards-data-store';
import { BoardsServiceProvider } from '../boards/boards-service-provider';
import { CurrentSketch } from '../sketches-service-client-impl';
import { SketchContribution } from './contribution';
interface UpdateStateParams<T extends ArduinoState> {
readonly key: keyof T;
readonly value: T[keyof T];
}
/**
* Contribution for updating the Arduino state, such as the FQBN, selected port, and sketch path changes via commands, so other VS Code extensions can access it.
* See [`vscode-arduino-api`](https://github.com/dankeboy36/vscode-arduino-api#api) for more details.
*/
@injectable()
export class UpdateArduinoState extends SketchContribution {
@inject(BoardsService)
private readonly boardsService: BoardsService;
@inject(BoardsServiceProvider)
private readonly boardsServiceProvider: BoardsServiceProvider;
@inject(BoardsDataStore)
private readonly boardsDataStore: BoardsDataStore;
@inject(HostedPluginSupport)
private readonly hostedPluginSupport: HostedPluginSupport;
private readonly toDispose = new DisposableCollection();
override onStart(): void {
this.toDispose.pushAll([
this.boardsServiceProvider.onBoardsConfigChanged((config) =>
this.updateBoardsConfig(config)
),
this.sketchServiceClient.onCurrentSketchDidChange((sketch) =>
this.updateSketchPath(sketch)
),
this.configService.onDidChangeDataDirUri((dataDirUri) =>
this.updateDataDirPath(dataDirUri)
),
this.configService.onDidChangeSketchDirUri((userDirUri) =>
this.updateUserDirPath(userDirUri)
),
this.commandService.onDidExecuteCommand(({ commandId, args }) => {
if (
commandId === 'arduino.languageserver.notifyBuildDidComplete' &&
isCompileSummary(args[0])
) {
this.updateCompileSummary(args[0]);
}
}),
this.boardsDataStore.onChanged((fqbn) => {
const selectedFqbn =
this.boardsServiceProvider.boardsConfig.selectedBoard?.fqbn;
if (selectedFqbn && fqbn.includes(selectedFqbn)) {
this.updateBoardDetails(selectedFqbn);
}
}),
]);
}
override onReady(): void {
this.boardsServiceProvider.reconciled.then(() => {
this.updateBoardsConfig(this.boardsServiceProvider.boardsConfig);
});
this.updateSketchPath(this.sketchServiceClient.tryGetCurrentSketch());
this.updateUserDirPath(this.configService.tryGetSketchDirUri());
this.updateDataDirPath(this.configService.tryGetDataDirUri());
}
onStop(): void {
this.toDispose.dispose();
}
private async updateSketchPath(
sketch: CurrentSketch | undefined
): Promise<void> {
const sketchPath = CurrentSketch.isValid(sketch)
? new URI(sketch.uri).path.fsPath()
: undefined;
return this.updateState({ key: 'sketchPath', value: sketchPath });
}
private async updateCompileSummary(
compileSummary: CompileSummary
): Promise<void> {
const apiCompileSummary = toApiCompileSummary(compileSummary);
return this.updateState({
key: 'compileSummary',
value: apiCompileSummary,
});
}
private async updateBoardsConfig(
boardsConfig: BoardsConfig.Config
): Promise<void> {
const fqbn = boardsConfig.selectedBoard?.fqbn;
const port = boardsConfig.selectedPort;
await this.updateFqbn(fqbn);
await this.updateBoardDetails(fqbn);
await this.updatePort(port);
}
private async updateFqbn(fqbn: string | undefined): Promise<void> {
await this.updateState({ key: 'fqbn', value: fqbn });
}
private async updateBoardDetails(fqbn: string | undefined): Promise<void> {
const unset = () =>
this.updateState({ key: 'boardDetails', value: undefined });
if (!fqbn) {
return unset();
}
const [details, persistedData] = await Promise.all([
this.boardsService.getBoardDetails({ fqbn }),
this.boardsDataStore.getData(fqbn),
]);
if (!details) {
return unset();
}
const apiBoardDetails = toApiBoardDetails({
...details,
configOptions:
BoardsDataStore.Data.EMPTY === persistedData
? details.configOptions
: persistedData.configOptions.slice(),
});
return this.updateState({
key: 'boardDetails',
value: apiBoardDetails,
});
}
private async updatePort(port: Port | undefined): Promise<void> {
const apiPort = port && toApiPort(port);
return this.updateState({ key: 'port', value: apiPort });
}
private async updateUserDirPath(userDirUri: URI | undefined): Promise<void> {
const userDirPath = userDirUri?.path.fsPath();
return this.updateState({
key: 'userDirPath',
value: userDirPath,
});
}
private async updateDataDirPath(dataDirUri: URI | undefined): Promise<void> {
const dataDirPath = dataDirUri?.path.fsPath();
return this.updateState({
key: 'dataDirPath',
value: dataDirPath,
});
}
private async updateState<T extends ArduinoState>(
params: UpdateStateParams<T>
): Promise<void> {
await this.hostedPluginSupport.didStart;
return this.commandService.executeCommand(
'arduinoAPI.updateState',
params
);
}
}

View File

@ -1,7 +1,10 @@
import { Emitter, Event, JsonRpcProxy } from '@theia/core';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { Emitter, Event } from '@theia/core/lib/common/event';
import { injectable, interfaces } from '@theia/core/shared/inversify';
import { HostedPluginServer } from '@theia/plugin-ext/lib/common/plugin-protocol';
import { HostedPluginSupport as TheiaHostedPluginSupport } from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
import {
PluginContributions,
HostedPluginSupport as TheiaHostedPluginSupport,
} from '@theia/plugin-ext/lib/hosted/browser/hosted-plugin';
@injectable()
export class HostedPluginSupport extends TheiaHostedPluginSupport {
@ -10,7 +13,7 @@ export class HostedPluginSupport extends TheiaHostedPluginSupport {
override onStart(container: interfaces.Container): void {
super.onStart(container);
this.hostedPluginServer.onDidCloseConnection(() =>
this['server'].onDidCloseConnection(() =>
this.onDidCloseConnectionEmitter.fire()
);
}
@ -28,8 +31,38 @@ export class HostedPluginSupport extends TheiaHostedPluginSupport {
return this.onDidCloseConnectionEmitter.event;
}
private get hostedPluginServer(): JsonRpcProxy<HostedPluginServer> {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return (this as any).server;
protected override startPlugins(
contributionsByHost: Map<string, PluginContributions[]>,
toDisconnect: DisposableCollection
): Promise<void> {
reorderPlugins(contributionsByHost);
return super.startPlugins(contributionsByHost, toDisconnect);
}
}
/**
* Force the `vscode-arduino-ide` API to activate before any Arduino IDE tool VSIX.
*
* Arduino IDE tool VISXs are not forced to declare the `vscode-arduino-api` as a `extensionDependencies`,
* but the API must activate before any tools. This in place sorting helps to bypass Theia's plugin resolution
* without forcing tools developers to add `vscode-arduino-api` to the `extensionDependencies`.
*/
function reorderPlugins(
contributionsByHost: Map<string, PluginContributions[]>
): void {
for (const [, contributions] of contributionsByHost) {
const apiPluginIndex = contributions.findIndex(isArduinoAPI);
if (apiPluginIndex >= 0) {
const apiPlugin = contributions[apiPluginIndex];
contributions.splice(apiPluginIndex, 1);
contributions.unshift(apiPlugin);
}
}
}
function isArduinoAPI(pluginContribution: PluginContributions): boolean {
return (
pluginContribution.plugin.metadata.model.id ===
'dankeboy36.vscode-arduino-api'
);
}

View File

@ -0,0 +1,126 @@
import type {
Port as APIPort,
BoardDetails as ApiBoardDetails,
BuildProperties as ApiBuildProperties,
CompileSummary as ApiCompileSummary,
ConfigOption as ApiConfigOption,
ConfigValue as ApiConfigValue,
Tool as ApiTool,
} from 'vscode-arduino-api';
import type {
BoardDetails,
CompileSummary,
ConfigOption,
ConfigValue,
Port,
Tool,
} from '../protocol';
export function toApiCompileSummary(
compileSummary: CompileSummary
): ApiCompileSummary {
const {
buildPath,
buildProperties,
boardPlatform,
buildPlatform,
executableSectionsSize,
usedLibraries,
} = compileSummary;
return {
buildPath,
buildProperties: toApiBuildProperties(buildProperties),
executableSectionsSize: executableSectionsSize,
boardPlatform,
buildPlatform,
usedLibraries,
};
}
export function toApiPort(port: Port): APIPort | undefined {
const {
hardwareId = '',
properties = {},
address,
protocol,
protocolLabel,
addressLabel: label,
} = port;
return {
label,
address,
hardwareId,
properties,
protocol,
protocolLabel,
};
}
export function toApiBoardDetails(boardDetails: BoardDetails): ApiBoardDetails {
const { fqbn, programmers, configOptions, requiredTools } = boardDetails;
return {
buildProperties: toApiBuildProperties(boardDetails.buildProperties),
configOptions: configOptions.map(toApiConfigOption),
fqbn,
programmers,
toolsDependencies: requiredTools.map(toApiTool),
};
}
function toApiConfigOption(configOption: ConfigOption): ApiConfigOption {
const { label, values, option } = configOption;
return {
optionLabel: label,
option,
values: values.map(toApiConfigValue),
};
}
function toApiConfigValue(configValue: ConfigValue): ApiConfigValue {
const { label, selected, value } = configValue;
return {
selected,
value,
valueLabel: label,
};
}
function toApiTool(toolDependency: Tool): ApiTool {
const { name, packager, version } = toolDependency;
return {
name,
packager,
version,
};
}
const propertySep = '=';
function parseProperty(
property: string
): [key: string, value: string] | undefined {
const segments = property.split(propertySep);
if (segments.length < 2) {
console.warn(`Could not parse build property: ${property}.`);
return undefined;
}
const [key, ...rest] = segments;
if (!key) {
console.warn(`Could not determine property key from raw: ${property}.`);
return undefined;
}
const value = rest.join(propertySep);
return [key, value];
}
export function toApiBuildProperties(properties: string[]): ApiBuildProperties {
return properties.reduce((acc, curr) => {
const entry = parseProperty(curr);
if (entry) {
const [key, value] = entry;
acc[key] = value;
}
return acc;
}, <Record<string, string>>{});
}

View File

@ -441,6 +441,7 @@ export interface BoardDetails {
readonly debuggingSupported: boolean;
readonly VID: string;
readonly PID: string;
readonly buildProperties: string[];
}
export interface Tool {

View File

@ -5,13 +5,11 @@ import type {
Range,
Position,
} from '@theia/core/shared/vscode-languageserver-protocol';
import type {
BoardUserField,
Port,
} from '../../common/protocol/boards-service';
import type { BoardUserField, Port, Installable } from '../../common/protocol/';
import type { Programmer } from './boards-service';
import type { Sketch } from './sketches-service';
import { IndexUpdateSummary } from './notification-service';
import type { CompileSummary as ApiCompileSummary } from 'vscode-arduino-api';
export const CompilerWarningLiterals = [
'None',
@ -19,7 +17,7 @@ export const CompilerWarningLiterals = [
'More',
'All',
] as const;
export type CompilerWarnings = typeof CompilerWarningLiterals[number];
export type CompilerWarnings = (typeof CompilerWarningLiterals)[number];
export namespace CompilerWarnings {
export function labelOf(warning: CompilerWarnings): string {
return CompilerWarningLabels[warning];
@ -103,6 +101,53 @@ export namespace CoreError {
}
}
export interface InstalledPlatformReference {
readonly id: string;
readonly version: Installable.Version;
/**
* Absolute filesystem path.
*/
readonly installDir: string;
readonly packageUrl: string;
}
export interface ExecutableSectionSize {
readonly name: string;
readonly size: number;
readonly maxSize: number;
}
export interface CompileSummary {
readonly buildPath: string;
/**
* To be compatible with the `vscode-arduino-tools` API.
* @deprecated Use `buildPath` instead. Use Theia or VS Code URI to convert to an URI string on the client side.
*/
readonly buildOutputUri: string;
readonly usedLibraries: ApiCompileSummary['usedLibraries'];
readonly executableSectionsSize: ExecutableSectionSize[];
readonly boardPlatform?: InstalledPlatformReference | undefined;
readonly buildPlatform?: InstalledPlatformReference | undefined;
readonly buildProperties: string[];
}
export function isCompileSummary(arg: unknown): arg is CompileSummary {
return (
Boolean(arg) &&
typeof arg === 'object' &&
(<CompileSummary>arg).buildPath !== undefined &&
typeof (<CompileSummary>arg).buildPath === 'string' &&
(<CompileSummary>arg).buildOutputUri !== undefined &&
typeof (<CompileSummary>arg).buildOutputUri === 'string' &&
(<CompileSummary>arg).executableSectionsSize !== undefined &&
Array.isArray((<CompileSummary>arg).executableSectionsSize) &&
(<CompileSummary>arg).usedLibraries !== undefined &&
Array.isArray((<CompileSummary>arg).usedLibraries) &&
(<CompileSummary>arg).buildProperties !== undefined &&
Array.isArray((<CompileSummary>arg).buildProperties)
);
}
export const CoreServicePath = '/services/core-service';
export const CoreService = Symbol('CoreService');
export interface CoreService {
@ -132,7 +177,7 @@ export interface CoreService {
}
export const IndexTypeLiterals = ['platform', 'library'] as const;
export type IndexType = typeof IndexTypeLiterals[number];
export type IndexType = (typeof IndexTypeLiterals)[number];
export namespace IndexType {
export function is(arg: unknown): arg is IndexType {
return (

View File

@ -155,6 +155,7 @@ export class BoardsServiceImpl
VID = prop.get('vid') || '';
PID = prop.get('pid') || '';
}
const buildProperties = detailsResp.getBuildPropertiesList();
return {
fqbn,
@ -164,6 +165,7 @@ export class BoardsServiceImpl
debuggingSupported,
VID,
PID,
buildProperties
};
}

View File

@ -8,6 +8,8 @@ import {
CompilerWarnings,
CoreService,
CoreError,
CompileSummary,
isCompileSummary,
} from '../common/protocol/core-service';
import {
CompileRequest,
@ -35,12 +37,15 @@ import { firstToUpperCase, notEmpty } from '../common/utils';
import { ServiceError } from './service-error';
import { ExecuteWithProgress, ProgressResponse } from './grpc-progressible';
import { BoardDiscovery } from './board-discovery';
import { Mutable } from '@theia/core/lib/common/types';
namespace Uploadable {
export type Request = UploadRequest | UploadUsingProgrammerRequest;
export type Response = UploadResponse | UploadUsingProgrammerResponse;
}
type CompileSummaryFragment = Partial<Mutable<CompileSummary>>;
@injectable()
export class CoreServiceImpl extends CoreClientAware implements CoreService {
@inject(ResponseService)
@ -58,23 +63,13 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
async compile(options: CoreService.Options.Compile): Promise<void> {
const coreClient = await this.coreClient;
const { client, instance } = coreClient;
let buildPath: string | undefined = undefined;
const compileSummary = <CompileSummaryFragment>{};
const progressHandler = this.createProgressHandler(options);
const buildPathHandler = (response: CompileResponse) => {
const currentBuildPath = response.getBuildPath();
if (currentBuildPath) {
buildPath = currentBuildPath;
} else {
if (!!buildPath && currentBuildPath !== buildPath) {
throw new Error(
`The CLI has already provided a build path: <${buildPath}>, and IDE received a new build path value: <${currentBuildPath}>.`
);
}
}
};
const compileSummaryHandler = (response: CompileResponse) =>
updateCompileSummary(compileSummary, response);
const handler = this.createOnDataHandler<CompileResponse>(
progressHandler,
buildPathHandler
compileSummaryHandler
);
const request = this.compileRequest(options, instance);
return new Promise<void>((resolve, reject) => {
@ -111,31 +106,35 @@ export class CoreServiceImpl extends CoreClientAware implements CoreService {
.on('end', resolve);
}).finally(() => {
handler.dispose();
if (!buildPath) {
if (!isCompileSummary(compileSummary)) {
console.error(
`Have not received the build path from the CLI while running the compilation.`
`Have not received the full compile summary from the CLI while running the compilation. ${JSON.stringify(
compileSummary
)}`
);
} else {
this.fireBuildDidComplete(FileUri.create(buildPath).toString());
this.fireBuildDidComplete(compileSummary);
}
});
}
// This executes on the frontend, the VS Code extension receives it, and sends an `ino/buildDidComplete` notification to the language server.
private fireBuildDidComplete(buildOutputUri: string): void {
private fireBuildDidComplete(compileSummary: CompileSummary): void {
const params = {
buildOutputUri,
...compileSummary,
};
console.info(
`Executing 'arduino.languageserver.notifyBuildDidComplete' with ${JSON.stringify(
params
params.buildOutputUri
)}`
);
this.commandService
.executeCommand('arduino.languageserver.notifyBuildDidComplete', params)
.catch((err) =>
console.error(
`Unexpected error when firing event on build did complete. ${buildOutputUri}`,
`Unexpected error when firing event on build did complete. ${JSON.stringify(
params.buildOutputUri
)}`,
err
)
);
@ -465,3 +464,62 @@ namespace StreamingResponse {
readonly handlers?: ((response: R) => void)[];
}
}
function updateCompileSummary(
compileSummary: CompileSummaryFragment,
response: CompileResponse
): CompileSummaryFragment {
const buildPath = response.getBuildPath();
if (buildPath) {
compileSummary.buildPath = buildPath;
compileSummary.buildOutputUri = FileUri.create(buildPath).toString();
}
const executableSectionsSize = response.getExecutableSectionsSizeList();
if (executableSectionsSize) {
compileSummary.executableSectionsSize = executableSectionsSize.map((item) =>
item.toObject(false)
);
}
const usedLibraries = response.getUsedLibrariesList();
if (usedLibraries) {
compileSummary.usedLibraries = usedLibraries.map((item) => {
const object = item.toObject(false);
const library = {
...object,
architectures: object.architecturesList,
types: object.typesList,
examples: object.examplesList,
providesIncludes: object.providesIncludesList,
properties: object.propertiesMap.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {} as Record<string, string>),
compatibleWith: object.compatibleWithMap.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {} as Record<string, boolean>),
} as const;
const mutable = <Partial<Mutable<typeof library>>>library;
delete mutable.architecturesList;
delete mutable.typesList;
delete mutable.examplesList;
delete mutable.providesIncludesList;
delete mutable.propertiesMap;
delete mutable.compatibleWithMap;
return library;
});
}
const boardPlatform = response.getBoardPlatform();
if (boardPlatform) {
compileSummary.buildPlatform = boardPlatform.toObject(false);
}
const buildPlatform = response.getBuildPlatform();
if (buildPlatform) {
compileSummary.buildPlatform = buildPlatform.toObject(false);
}
const buildProperties = response.getBuildPropertiesList();
if (buildProperties) {
compileSummary.buildProperties = buildProperties.slice();
}
return compileSummary;
}

View File

@ -0,0 +1,43 @@
import { expect } from 'chai';
import { toApiBuildProperties } from '../../common/protocol/arduino-context-mapper';
describe('arduino-context-mapper', () => {
describe('toApiBuildProperties', () => {
it('should parse an array of build properties string into a record', () => {
const expected = {
foo: 'alma',
bar: '36',
baz: 'false',
};
const actual = toApiBuildProperties(['foo=alma', 'bar=36', 'baz=false']);
expect(actual).to.be.deep.equal(expected);
});
it('should not skip build property key with empty value', () => {
const expected = {
foo: '',
};
const actual = toApiBuildProperties(['foo=']);
expect(actual).to.be.deep.equal(expected);
});
it('should skip invalid entries', () => {
const expected = {
foo: 'alma',
bar: '36',
baz: '-DARDUINO_USB_CDC_ON_BOOT=0',
};
const actual = toApiBuildProperties([
'foo=alma',
'invalid',
'=invalid2',
'=invalid3=',
'=',
'==',
'bar=36',
'baz=-DARDUINO_USB_CDC_ON_BOOT=0',
]);
expect(actual).to.be.deep.equal(expected);
});
});
});

View File

@ -9,6 +9,7 @@ import {
BoardsService,
CoreService,
SketchesService,
isCompileSummary,
} from '../../common/protocol';
import { createBaseContainer, startDaemon } from './test-bindings';
@ -31,7 +32,7 @@ describe('core-service-impl', () => {
afterEach(() => toDispose.dispose());
describe('compile', () => {
it('should execute a command with the build path', async function () {
it('should execute a command with the compile summary, including the build path', async function () {
this.timeout(testTimeout);
const coreService = container.get<CoreService>(CoreService);
const sketchesService = container.get<SketchesService>(SketchesService);
@ -56,7 +57,7 @@ describe('core-service-impl', () => {
const [, args] = executedBuildDidCompleteCommands[0];
expect(args.length).to.be.equal(1);
const arg = args[0];
expect(typeof arg).to.be.equal('object');
expect(isCompileSummary(arg)).to.be.true;
expect('buildOutputUri' in arg).to.be.true;
expect(arg.buildOutputUri).to.be.not.undefined;

View File

@ -70,6 +70,7 @@
"theiaPluginsDir": "plugins",
"theiaPlugins": {
"vscode-builtin-cpp": "https://open-vsx.org/api/vscode/cpp/1.52.1/file/vscode.cpp-1.52.1.vsix",
"vscode-arduino-api": "https://github.com/dankeboy36/vscode-arduino-api/releases/download/0.1.2/vscode-arduino-api-0.1.2.vsix",
"vscode-arduino-tools": "https://downloads.arduino.cc/vscode-arduino-tools/vscode-arduino-tools-0.0.2-beta.8.vsix",
"vscode-builtin-json": "https://open-vsx.org/api/vscode/json/1.46.1/file/vscode.json-1.46.1.vsix",
"vscode-builtin-json-language-features": "https://open-vsx.org/api/vscode/json-language-features/1.46.1/file/vscode.json-language-features-1.46.1.vsix",

View File

@ -3209,6 +3209,11 @@
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-7.0.5.tgz#b1d2f772142a301538fae9bdf9cf15b9f2573a29"
integrity sha512-hKB88y3YHL8oPOs/CNlaXtjWn93+Bs48sDQR37ZUqG2tLeCS7EA1cmnkKsuQsub9OKEB/y/Rw9zqJqqNSbqVlQ==
"@types/vscode@^1.78.0":
version "1.78.0"
resolved "https://registry.yarnpkg.com/@types/vscode/-/vscode-1.78.0.tgz#b5600abce8855cf21fb32d0857bcd084b1f83069"
integrity sha512-LJZIJpPvKJ0HVQDqfOy6W4sNKUBBwyDu1Bs8chHBZOe9MNuKTJtidgZ2bqjhmmWpUb0TIIqv47BFUcVmAsgaVA==
"@types/which@^1.3.1":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.3.2.tgz#9c246fc0c93ded311c8512df2891fb41f6227fdf"
@ -3991,6 +3996,14 @@ arduino-serial-plotter-webapp@0.2.0:
resolved "https://registry.yarnpkg.com/arduino-serial-plotter-webapp/-/arduino-serial-plotter-webapp-0.2.0.tgz#90d61ad7ed1452f70fd226ff25eccb36c1ab1a4f"
integrity sha512-AxQIsKr6Mf8K1c3kj+ojjFvE9Vz8cUqJqRink6/myp/ranEGwsQQ83hziktkPKZvBQshqrMH8nzoGIY2Z3A2OA==
ardunno-cli@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ardunno-cli/-/ardunno-cli-0.1.2.tgz#145d998231b34b33bf70f7fc6e5be6497191f708"
integrity sha512-8PTBMDS2ofe2LJZZKHw/MgfXgDwpiImXJcBeqeZ6lcTSDqQNMJpEIjcCdPcxbsQbJXRRfZZ4nn6G/gXwEuJPpw==
dependencies:
nice-grpc-common "^2.0.2"
protobufjs "^7.2.3"
are-we-there-yet@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c"
@ -10738,6 +10751,13 @@ nested-error-stacks@^2.1.1:
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5"
integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==
nice-grpc-common@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/nice-grpc-common/-/nice-grpc-common-2.0.2.tgz#e6aeebb2bd19d87114b351e291e30d79dd38acf7"
integrity sha512-7RNWbls5kAL1QVUOXvBsv1uO0wPQK3lHv+cY1gwkTzirnG1Nop4cBJZubpgziNbaVc/bl9QJcyvsf/NQxa3rjQ==
dependencies:
ts-error "^1.0.6"
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
@ -12184,7 +12204,7 @@ proto-list@~1.2.1:
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
protobufjs@^7.0.0:
protobufjs@^7.0.0, protobufjs@^7.2.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2"
integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg==
@ -13083,6 +13103,11 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
safe-stable-stringify@^2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886"
integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==
"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@ -14350,6 +14375,11 @@ trough@^2.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876"
integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==
ts-error@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/ts-error/-/ts-error-1.0.6.tgz#277496f2a28de6c184cfce8dfd5cdd03a4e6b0fc"
integrity sha512-tLJxacIQUM82IR7JO1UUkKlYuUTmoY9HBJAmNWFzheSlDS5SPMcNIepejHJa4BpPQLAcbRhRf3GDJzyj6rbKvA==
ts-md5@^1.2.2:
version "1.3.1"
resolved "https://registry.yarnpkg.com/ts-md5/-/ts-md5-1.3.1.tgz#f5b860c0d5241dd9bb4e909dd73991166403f511"
@ -14947,6 +14977,15 @@ vinyl@^2.2.1:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
vscode-arduino-api@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/vscode-arduino-api/-/vscode-arduino-api-0.1.2.tgz#11d294fd72c36bbea1ccacd101f16c11df490b77"
integrity sha512-FxZllcBIUKxYMiakCSOZ2VSaxscQACxzo0tI5xu8HrbDBU5yvl4zvBzwss4PIYvBG0oZeSKDf950i37Qn7dcmA==
dependencies:
"@types/vscode" "^1.78.0"
ardunno-cli "^0.1.2"
safe-stable-stringify "^2.4.3"
vscode-jsonrpc@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.1.0.tgz#cb9989c65e219e18533cc38e767611272d274c94"